From 05199e939f7309647abb8e5dda2fe3d2a77042f9 Mon Sep 17 00:00:00 2001 From: Stephane Glondu Date: Tue, 21 Dec 2021 13:47:45 +0100 Subject: [PATCH] New upstream version 4.12.0 --- .depend | 212 +- .gitattributes | 22 +- .github/ISSUE_TEMPLATE/bug_report.md | 28 + .github/ISSUE_TEMPLATE/config.yml | 10 + .github/ISSUE_TEMPLATE/feature_request.md | 24 + .github/workflows/main.yml | 71 + .github/workflows/stale.yml | 15 + .gitignore | 18 +- .mailmap | 1 + .travis.yml | 29 +- CONTRIBUTING.md | 10 +- Changes | 769 +- HACKING.adoc | 97 +- INSTALL.adoc | 29 +- Makefile | 221 +- Makefile.best_binaries | 23 +- Makefile.build_config.in | 36 + Makefile.common.in => Makefile.common | 74 +- Makefile.config.in | 22 +- .../Makefile => Makefile.config_if_required | 29 +- Makefile.tools | 28 +- README.adoc | 31 +- VERSION | 2 +- aclocal.m4 | 18 + asmcomp/CSEgen.ml | 10 +- asmcomp/afl_instrument.ml | 6 +- asmcomp/amd64/arch.ml | 2 - asmcomp/amd64/emit.mlp | 172 +- asmcomp/amd64/proc.ml | 54 +- asmcomp/amd64/reload.ml | 2 +- asmcomp/amd64/selection.ml | 39 +- asmcomp/arm/arch.ml | 2 - asmcomp/arm/emit.mlp | 46 +- asmcomp/arm/proc.ml | 165 +- asmcomp/arm/scheduling.ml | 4 +- asmcomp/arm/selection.ml | 73 +- asmcomp/arm64/NOTES.md | 1 + asmcomp/arm64/arch.ml | 37 +- asmcomp/arm64/emit.mlp | 232 +- asmcomp/arm64/proc.ml | 104 +- asmcomp/arm64/reload.ml | 23 +- asmcomp/arm64/selection.ml | 63 +- asmcomp/asmgen.ml | 104 +- asmcomp/asmgen.mli | 19 +- asmcomp/asmlink.ml | 31 +- asmcomp/branch_relaxation.ml | 17 +- asmcomp/branch_relaxation_intf.ml | 4 +- asmcomp/cmm.ml | 46 +- asmcomp/cmm.mli | 21 +- asmcomp/cmm_helpers.ml | 146 +- asmcomp/cmm_helpers.mli | 9 +- asmcomp/cmmgen.ml | 129 +- asmcomp/cmmgen_state.ml | 3 + asmcomp/cmmgen_state.mli | 2 + asmcomp/comballoc.ml | 10 +- asmcomp/deadcode.ml | 18 +- asmcomp/debug/available_regs.ml | 4 +- asmcomp/emitaux.ml | 2 +- asmcomp/i386/arch.ml | 2 - asmcomp/i386/emit.mlp | 50 +- asmcomp/i386/proc.ml | 12 +- asmcomp/i386/reload.ml | 2 +- asmcomp/i386/selection.ml | 29 +- asmcomp/interf.ml | 4 +- asmcomp/interval.ml | 4 +- asmcomp/linear.ml | 3 +- asmcomp/linear.mli | 1 - asmcomp/linearize.ml | 10 +- asmcomp/liveness.ml | 31 +- asmcomp/mach.ml | 68 +- asmcomp/mach.mli | 45 +- asmcomp/power/arch.ml | 10 +- asmcomp/power/emit.mlp | 76 +- asmcomp/power/proc.ml | 196 +- asmcomp/power/selection.ml | 33 +- asmcomp/printcmm.ml | 25 +- asmcomp/printcmm.mli | 4 +- asmcomp/printlinear.ml | 2 +- asmcomp/printmach.ml | 22 +- asmcomp/proc.mli | 15 +- asmcomp/reg.ml | 3 + asmcomp/reg.mli | 2 +- asmcomp/reloadgen.ml | 6 +- asmcomp/riscv/arch.ml | 3 - asmcomp/riscv/emit.mlp | 48 +- asmcomp/riscv/proc.ml | 75 +- asmcomp/riscv/selection.ml | 35 +- asmcomp/s390x/arch.ml | 2 - asmcomp/s390x/emit.mlp | 44 +- asmcomp/s390x/proc.ml | 18 +- asmcomp/s390x/selection.ml | 37 +- asmcomp/schedgen.ml | 11 +- asmcomp/selectgen.ml | 299 +- asmcomp/selectgen.mli | 47 +- asmcomp/spacetime_profiling.ml | 480 - asmcomp/spill.ml | 11 +- asmcomp/split.ml | 3 +- asmcomp/strmatch.ml | 2 +- boot/menhir/parser.ml | 10447 ++++++++-------- boot/ocamlc | Bin 2754885 -> 2803430 bytes boot/ocamllex | Bin 340174 -> 345643 bytes build-aux/config.guess | 385 +- build-aux/config.sub | 2560 ++-- bytecomp/bytegen.ml | 24 +- bytecomp/bytelink.ml | 36 +- bytecomp/bytelink.mli | 2 +- bytecomp/dll.ml | 63 +- bytecomp/dll.mli | 9 +- bytecomp/emitcode.ml | 17 +- bytecomp/meta.ml | 2 +- bytecomp/meta.mli | 2 +- bytecomp/symtable.ml | 15 +- compilerlibs/Makefile.compilerlibs | 24 +- configure | 1234 +- configure.ac | 442 +- debugger/Makefile | 6 +- debugger/time_travel.ml | 2 +- driver/compenv.ml | 98 +- driver/compenv.mli | 5 +- driver/compile.ml | 7 +- driver/compile.mli | 1 + driver/compile_common.ml | 3 +- driver/compmisc.ml | 5 +- driver/main.ml | 116 +- driver/main_args.ml | 64 +- driver/main_args.mli | 1 + driver/maindriver.ml | 114 + driver/{optmain.mli => maindriver.mli} | 9 +- driver/makedepend.ml | 41 +- driver/optcompile.ml | 13 +- driver/optcompile.mli | 1 + driver/optmain.ml | 139 +- driver/optmaindriver.ml | 139 + driver/optmaindriver.mli | 21 + driver/pparse.ml | 2 +- dune | 7 +- file_formats/linear_format.ml | 101 + file_formats/linear_format.mli | 38 + lambda/debuginfo.ml | 79 +- lambda/debuginfo.mli | 11 +- lambda/lambda.ml | 178 +- lambda/lambda.mli | 35 +- lambda/matching.ml | 1320 +- lambda/matching.mli | 2 +- lambda/printlambda.ml | 12 +- lambda/simplif.ml | 66 +- lambda/simplif.mli | 4 - lambda/translattribute.ml | 103 +- lambda/translattribute.mli | 2 +- lambda/translclass.ml | 39 +- lambda/translcore.ml | 206 +- lambda/translcore.mli | 2 +- lambda/translmod.ml | 143 +- lambda/translprim.ml | 13 +- lex/Makefile | 24 +- man/ocamlc.m | 6 +- man/ocamlopt.m | 9 +- man/ocamlrun.m | 2 +- manual/Makefile | 7 + manual/README.md | 7 - manual/manual/.gitignore | 1 + manual/manual/Makefile | 10 +- manual/manual/allfiles.etex | 14 +- manual/manual/cmds/Makefile | 6 +- manual/manual/cmds/browser.etex | 6 - manual/manual/cmds/debugger.etex | 6 +- manual/manual/cmds/intf-c.etex | 63 +- manual/manual/cmds/native.etex | 37 +- manual/manual/cmds/ocamlbuild.etex | 5 - manual/manual/cmds/ocamldep.etex | 2 +- manual/manual/cmds/runtime.etex | 13 +- manual/manual/cmds/spacetime-chapter.etex | 125 - manual/manual/cmds/unified-options.etex | 44 +- manual/manual/foreword.etex | 4 +- manual/manual/html_processing/.gitignore | 7 + manual/manual/html_processing/Makefile | 137 + manual/manual/html_processing/README.md | 71 + manual/manual/html_processing/dune-project | 1 + .../manual/html_processing/js/navigation.js | 102 + manual/manual/html_processing/js/scroll.js | 104 + manual/manual/html_processing/js/search.js | 248 + .../manual/html_processing/scss/_common.scss | 246 + .../manual/html_processing/scss/manual.scss | 349 + manual/manual/html_processing/scss/style.scss | 1075 ++ manual/manual/html_processing/src/common.ml | 134 + manual/manual/html_processing/src/dune | 14 + .../manual/html_processing/src/process_api.ml | 376 + .../html_processing/src/process_manual.ml | 481 + manual/manual/library/Makefile | 6 +- manual/manual/library/core.etex | 2 + manual/manual/library/libbigarray.etex | 36 - manual/manual/library/libgraph.etex | 18 - manual/manual/library/libnum.etex | 13 - manual/manual/library/libthreads.etex | 37 +- manual/manual/library/libunix.etex | 18 +- manual/manual/library/old.etex | 80 + manual/manual/library/stdlib-blurb.etex | 32 +- manual/manual/macros.hva | 13 - manual/manual/macros.tex | 11 +- manual/manual/manual.inf | 1 - manual/manual/manual.tex | 3 +- manual/manual/refman/exten.etex | 23 +- manual/manual/refman/lex.etex | 4 +- manual/manual/refman/typedecl.etex | 26 +- manual/manual/tutorials/advexamples.etex | 2 +- manual/manual/tutorials/coreexamples.etex | 163 +- manual/manual/tutorials/lablexamples.etex | 4 +- manual/manual/tutorials/moduleexamples.etex | 52 +- manual/tests/check-stdlib-modules | 2 +- middle_end/clambda.ml | 4 - middle_end/clambda.mli | 1 - middle_end/closure/closure.ml | 58 +- middle_end/flambda/build_export_info.ml | 8 +- middle_end/flambda/closure_conversion.ml | 21 +- middle_end/flambda/export_info.ml | 9 +- middle_end/flambda/export_info.mli | 1 - middle_end/flambda/export_info_for_pack.ml | 1 - middle_end/flambda/flambda.ml | 9 +- middle_end/flambda/flambda.mli | 4 - middle_end/flambda/flambda_to_clambda.ml | 7 +- middle_end/flambda/import_approx.ml | 1 - middle_end/flambda/inline_and_simplify.ml | 9 +- middle_end/flambda/remove_unused_arguments.ml | 2 +- middle_end/flambda/simple_value_approx.ml | 54 +- middle_end/flambda/simple_value_approx.mli | 4 - middle_end/flambda/simplify_common.ml | 5 - middle_end/flambda/simplify_common.mli | 5 - middle_end/flambda/simplify_primitives.ml | 24 +- middle_end/printclambda.ml | 1 - ocaml-variants.opam | 6 +- ocamldoc/.depend | 2 + ocamldoc/Makefile | 50 +- ocamldoc/Makefile.docfiles | 2 +- ocamldoc/odoc.ml | 6 - ocamldoc/odoc_analyse.ml | 2 - ocamldoc/odoc_args.ml | 7 +- ocamldoc/odoc_ast.ml | 35 - ocamldoc/odoc_comments.ml | 18 +- ocamldoc/odoc_env.ml | 27 +- ocamldoc/odoc_html.ml | 10 - ocamldoc/odoc_latex.ml | 2 - ocamldoc/odoc_lexer.mll | 8 - ocamldoc/odoc_module.ml | 13 +- ocamldoc/odoc_parameter.ml | 8 +- ocamldoc/odoc_parser.mly | 8 - ocamldoc/odoc_see_lexer.mll | 9 - ocamldoc/odoc_sig.ml | 53 +- ocamldoc/odoc_text_lexer.mll | 8 - ocamldoc/odoc_text_parser.mly | 2 - ocamltest/.depend | 36 +- ocamltest/Makefile | 160 +- ocamltest/actions_helpers.ml | 53 +- ocamltest/builtin_actions.ml | 11 +- ocamltest/dune | 20 +- ocamltest/environments.ml | 21 +- ocamltest/environments.mli | 6 +- ocamltest/filecompare.ml | 173 +- ocamltest/main.ml | 56 +- ocamltest/ocaml_actions.ml | 381 +- ocamltest/ocaml_actions.mli | 2 +- ocamltest/ocaml_commands.ml | 36 +- ocamltest/ocaml_commands.mli | 20 +- ocamltest/ocaml_compilers.ml | 2 +- ocamltest/ocaml_compilers.mli | 2 +- ocamltest/ocaml_directories.ml | 24 +- ocamltest/ocaml_directories.mli | 12 +- ocamltest/ocaml_files.ml | 77 +- ocamltest/ocaml_files.mli | 34 +- ocamltest/ocaml_flags.ml | 24 +- ocamltest/ocaml_flags.mli | 10 +- ocamltest/ocaml_modifiers.ml | 70 +- ocamltest/ocaml_tests.ml | 9 +- ocamltest/ocaml_tools.ml | 2 +- ocamltest/ocaml_tools.mli | 4 +- ocamltest/ocaml_toplevels.ml | 2 +- ocamltest/ocaml_toplevels.mli | 2 +- ocamltest/ocaml_variables.ml | 3 + ocamltest/ocaml_variables.mli | 2 + ocamltest/ocamltest_config.ml.in | 74 +- ocamltest/ocamltest_config.mli | 14 +- ocamltest/ocamltest_stdlib.ml | 125 +- ocamltest/ocamltest_stdlib.mli | 17 +- ocamltest/ocamltest_stdlib_stubs.c | 116 - ocamltest/ocamltest_unix.mli | 20 + .../ocamltest_unix_dummy.ml | 11 +- ocamltest/ocamltest_unix_real.ml | 29 + ocamltest/options.ml | 9 +- ocamltest/options.mli | 12 +- ocamltest/run_command.ml | 2 +- ocamltest/run_stubs.c | 2 + ocamltest/run_unix.c | 2 + ocamltest/tests.ml | 2 +- ocamltest/tsl_lexer.mll | 2 +- ocamltest/tsl_parser.mly | 4 +- otherlibs/Makefile | 5 +- otherlibs/Makefile.otherlibs.common | 28 +- otherlibs/dynlink/Makefile | 28 +- otherlibs/dynlink/dynlink_common.ml | 3 + otherlibs/raw_spacetime_lib/.depend | 22 - .../raw_spacetime_lib/raw_spacetime_lib.ml | 668 - .../raw_spacetime_lib/raw_spacetime_lib.mli | 364 - .../raw_spacetime_lib/spacetime_offline.c | 250 - otherlibs/str/.depend | 7 - otherlibs/str/Makefile | 7 +- otherlibs/systhreads/.depend | 43 +- otherlibs/systhreads/Makefile | 82 +- otherlibs/systhreads/mutex.mli | 15 +- otherlibs/systhreads/semaphore.ml | 86 + otherlibs/systhreads/semaphore.mli | 140 + otherlibs/systhreads/st_posix.h | 41 +- otherlibs/systhreads/st_stubs.c | 109 +- otherlibs/systhreads/st_win32.h | 174 +- otherlibs/systhreads/thread.ml | 11 +- otherlibs/systhreads/thread.mli | 56 +- otherlibs/systhreads/threadUnix.mli | 2 + otherlibs/unix/.depend | 644 - otherlibs/unix/Makefile | 12 +- otherlibs/unix/channels.c | 4 - otherlibs/unix/execvp.c | 107 +- otherlibs/unix/gettimeofday.c | 17 +- otherlibs/unix/kill.c | 1 + otherlibs/unix/mkdir.c | 12 +- otherlibs/unix/mmap.c | 3 +- otherlibs/unix/mmap_ba.c | 2 +- otherlibs/unix/setsid.c | 4 +- otherlibs/unix/signals.c | 2 + otherlibs/unix/socketaddr.h | 10 +- otherlibs/unix/sockopt.c | 6 +- otherlibs/unix/spawn.c | 165 + otherlibs/unix/time.c | 7 +- otherlibs/unix/unix.ml | 180 +- otherlibs/unix/unix.mli | 528 +- otherlibs/unix/unixLabels.mli | 801 +- otherlibs/win32unix/.depend | 550 - otherlibs/win32unix/Makefile | 23 +- otherlibs/win32unix/accept.c | 2 +- otherlibs/win32unix/getpeername.c | 8 +- otherlibs/win32unix/getsockname.c | 8 +- otherlibs/win32unix/gettimeofday.c | 9 +- otherlibs/win32unix/mmap.c | 3 +- otherlibs/win32unix/sendrecv.c | 2 +- otherlibs/win32unix/socketaddr.h | 58 - otherlibs/win32unix/sockopt.c | 6 +- otherlibs/win32unix/stat.c | 1 - otherlibs/win32unix/symlink.c | 55 +- otherlibs/win32unix/unix.ml | 8 +- otherlibs/win32unix/unixsupport.c | 1 + otherlibs/win32unix/utimes.c | 2 +- parsing/ast_helper.mli | 9 +- parsing/asttypes.mli | 6 +- parsing/docstrings.ml | 6 +- parsing/lexer.mll | 10 +- parsing/location.ml | 6 +- parsing/parse.mli | 2 +- parsing/parser.mly | 120 +- parsing/parsetree.mli | 8 +- parsing/pprintast.ml | 62 +- News => release-info/News | 65 + .../howto.md | 176 +- .../markdown-add-pr-links.sh | 16 +- release-info/templates/beta.md | 39 + release-info/templates/production.md | 19 + release-info/templates/rc.md | 40 + runtime/.depend | 2509 ---- runtime/Makefile | 141 +- runtime/afl.c | 2 +- runtime/alloc.c | 37 +- runtime/amd64.S | 57 +- runtime/amd64nt.asm | 51 - runtime/arm.S | 6 +- runtime/arm64.S | 227 +- runtime/array.c | 16 +- runtime/backtrace.c | 33 + runtime/backtrace_byt.c | 27 +- runtime/backtrace_nat.c | 5 + runtime/callback.c | 54 +- runtime/caml/address_class.h | 57 +- runtime/caml/alloc.h | 6 +- runtime/caml/backtrace.h | 5 +- runtime/caml/backtrace_prim.h | 6 + runtime/caml/compatibility.h | 1 - runtime/caml/config.h | 4 +- runtime/caml/custom.h | 5 + runtime/caml/debugger.h | 2 +- runtime/caml/domain_state.tbl | 11 +- runtime/caml/exec.h | 2 +- runtime/caml/fail.h | 2 +- runtime/caml/gc.h | 12 - runtime/caml/instruct.h | 6 +- runtime/caml/interp.h | 6 - runtime/caml/intext.h | 11 - runtime/caml/io.h | 28 +- runtime/caml/m.h.in | 7 +- runtime/caml/major_gc.h | 5 + runtime/caml/memory.h | 20 +- runtime/caml/memprof.h | 19 +- runtime/caml/minor_gc.h | 10 +- runtime/caml/misc.h | 18 +- runtime/caml/mlvalues.h | 36 +- runtime/caml/osdeps.h | 29 +- runtime/caml/printexc.h | 2 + runtime/caml/roots.h | 13 +- runtime/caml/s.h.in | 12 +- runtime/caml/signals.h | 12 +- runtime/caml/spacetime.h | 203 - runtime/caml/stack.h | 3 - runtime/caml/stacks.h | 2 +- runtime/caml/startup.h | 5 +- runtime/caml/sys.h | 1 - runtime/caml/weak.h | 22 +- runtime/compact.c | 306 +- runtime/compare.c | 34 +- runtime/custom.c | 10 +- runtime/debugger.c | 10 +- runtime/domain.c | 5 + runtime/dune | 43 +- runtime/dynlink_nat.c | 12 +- runtime/eventlog.c | 4 +- runtime/extern.c | 453 +- runtime/fail_byt.c | 9 +- runtime/fail_nat.c | 10 +- runtime/finalise.c | 16 - runtime/floats.c | 20 - runtime/freelist.c | 3 +- runtime/gc_ctrl.c | 32 +- runtime/gen_primitives.sh | 2 +- runtime/globroots.c | 6 +- runtime/hash.c | 163 +- runtime/i386.S | 8 +- runtime/i386nt.asm | 10 +- runtime/instrtrace.c | 2 +- runtime/intern.c | 65 +- runtime/interp.c | 88 +- runtime/io.c | 159 +- runtime/main.c | 5 +- runtime/major_gc.c | 627 +- runtime/memory.c | 37 +- runtime/memprof.c | 1160 +- runtime/meta.c | 16 +- runtime/minor_gc.c | 79 +- runtime/misc.c | 3 - runtime/obj.c | 266 +- runtime/printexc.c | 2 +- runtime/riscv.S | 75 +- runtime/roots_byt.c | 23 +- runtime/roots_nat.c | 12 +- runtime/signals.c | 108 +- runtime/signals_byt.c | 9 +- runtime/signals_nat.c | 40 +- runtime/signals_osdep.h | 63 +- runtime/spacetime_byt.c | 38 - runtime/spacetime_nat.c | 1160 -- runtime/spacetime_snapshot.c | 600 - runtime/stacks.c | 3 - runtime/startup_aux.c | 11 +- runtime/startup_byt.c | 22 +- runtime/startup_nat.c | 16 +- runtime/sys.c | 50 + runtime/unix.c | 25 +- runtime/weak.c | 89 +- runtime/win32.c | 40 +- stdlib/.depend | 45 +- stdlib/Compflags | 8 +- stdlib/HACKING.adoc | 2 +- stdlib/Makefile | 27 +- stdlib/StdlibModules | 8 +- stdlib/arg.ml | 11 + stdlib/arg.mli | 41 +- stdlib/array.mli | 188 +- stdlib/arrayLabels.mli | 113 +- driver/main.mli => stdlib/atomic.ml | 8 +- stdlib/atomic.mli | 59 + stdlib/bigarray.ml | 79 +- stdlib/bigarray.mli | 98 +- stdlib/bool.mli | 4 +- stdlib/buffer.mli | 11 +- stdlib/bytes.mli | 125 +- stdlib/bytesLabels.mli | 286 +- stdlib/camlinternalAtomic.ml | 60 + stdlib/camlinternalAtomic.mli | 30 + stdlib/camlinternalFormat.ml | 4 +- stdlib/camlinternalLazy.ml | 12 +- stdlib/camlinternalMod.ml | 38 +- stdlib/digest.mli | 12 +- stdlib/dune | 16 +- stdlib/either.ml | 66 + stdlib/either.mli | 115 + stdlib/ephemeron.mli | 11 +- stdlib/expand_module_aliases.awk | 3 +- stdlib/filename.mli | 1 + stdlib/float.ml | 6 +- stdlib/float.mli | 276 +- stdlib/format.ml | 16 + stdlib/format.mli | 15 +- stdlib/gc.ml | 11 +- stdlib/gc.mli | 30 +- stdlib/genlex.mli | 18 +- stdlib/hashtbl.ml | 83 +- stdlib/hashtbl.mli | 131 +- stdlib/int.mli | 2 +- stdlib/list.ml | 34 + stdlib/list.mli | 379 +- stdlib/listLabels.mli | 248 +- stdlib/map.ml | 16 +- stdlib/map.mli | 83 +- stdlib/moreLabels.mli | 1116 +- stdlib/nativeint.mli | 6 +- stdlib/obj.ml | 35 +- stdlib/obj.mli | 22 +- stdlib/option.mli | 8 +- stdlib/printexc.ml | 46 +- stdlib/printexc.mli | 71 +- stdlib/queue.mli | 2 +- stdlib/result.mli | 4 +- stdlib/seq.mli | 14 +- stdlib/set.ml | 12 + stdlib/set.mli | 49 +- stdlib/spacetime.ml | 91 - stdlib/spacetime.mli | 99 - stdlib/stack.mli | 2 +- stdlib/stdLabels.mli | 17 +- stdlib/stdlib.ml | 30 +- stdlib/stdlib.mli | 29 +- stdlib/stream.mli | 2 +- stdlib/string.ml | 10 +- stdlib/string.mli | 555 +- stdlib/stringLabels.mli | 530 +- stdlib/sys.mli | 12 + stdlib/sys.mlp | 2 + stdlib/templates/README.adoc | 4 + stdlib/templates/float.template.mli | 408 + .../templates/floatarraylabeled.template.mli | 233 + stdlib/templates/hashtbl.template.mli | 508 + stdlib/templates/map.template.mli | 361 + stdlib/templates/moreLabels.template.mli | 45 + stdlib/templates/set.template.mli | 313 + stdlib/uchar.mli | 4 +- stdlib/weak.ml | 2 +- stdlib/weak.mli | 2 +- testsuite/Makefile | 103 +- testsuite/summarize.awk | 146 +- .../asmcomp/0001-test.compilers.reference | 2 +- testsuite/tests/asmcomp/is_static.ml | 3 +- testsuite/tests/asmcomp/is_static_flambda.ml | 3 +- testsuite/tests/asmcomp/optargs.ml | 1 - .../asmcomp/static_float_array_flambda.ml | 3 +- .../static_float_array_flambda_opaque.ml | 3 +- testsuite/tests/asmgen/immediates.cmm | 48 + testsuite/tests/asmgen/immediates.cmmpp | 26 + testsuite/tests/asmgen/immediates.tbl | 37 + testsuite/tests/asmgen/mainimmed.c | 78 + testsuite/tests/asmgen/soli.cmm | 2 +- testsuite/tests/backtrace/backtrace.ml | 2 - testsuite/tests/backtrace/backtrace.reference | 40 +- testsuite/tests/backtrace/backtrace2.ml | 2 - .../tests/backtrace/backtrace2.reference | 76 +- testsuite/tests/backtrace/backtrace3.ml | 2 - .../tests/backtrace/backtrace3.reference | 100 +- .../tests/backtrace/backtrace_deprecated.ml | 2 - .../backtrace/backtrace_deprecated.reference | 40 +- .../tests/backtrace/backtrace_or_exception.ml | 2 - .../backtrace_or_exception.reference | 16 +- testsuite/tests/backtrace/backtrace_slots.ml | 2 - .../tests/backtrace/backtrace_slots.reference | 40 +- .../backtrace/backtraces_and_finalizers.ml | 3 - testsuite/tests/backtrace/callstack.ml | 1 - testsuite/tests/backtrace/callstack.reference | 24 +- testsuite/tests/backtrace/event_after_prim.ml | 2 +- testsuite/tests/backtrace/filter-locations.sh | 5 +- testsuite/tests/backtrace/inline_test.ml | 3 - .../tests/backtrace/inline_test.reference | 20 +- .../tests/backtrace/inline_traversal_test.ml | 7 +- .../backtrace/inline_traversal_test.reference | 10 +- testsuite/tests/backtrace/lazy.ml | 27 + testsuite/tests/backtrace/lazy.reference | 12 + testsuite/tests/backtrace/methods.ml | 2 +- testsuite/tests/backtrace/names.ml | 1 - testsuite/tests/backtrace/names.reference | 52 +- .../backtrace/pr2195-locs.byte.reference | 4 + .../backtrace/pr2195-nolocs.byte.reference | 6 + testsuite/tests/backtrace/pr2195.ml | 29 + .../tests/backtrace/pr2195.opt.reference | 5 + testsuite/tests/backtrace/pr2195.run | 9 + testsuite/tests/backtrace/pr6920_why_at.ml | 2 - .../tests/backtrace/pr6920_why_at.reference | 6 +- .../tests/backtrace/pr6920_why_swallow.ml | 2 - .../backtrace/pr6920_why_swallow.reference | 6 +- testsuite/tests/backtrace/raw_backtrace.ml | 2 - .../tests/backtrace/raw_backtrace.reference | 76 +- .../basic-modules/anonymous.ocamlc.reference | 4 +- .../anonymous.ocamlopt.flambda.reference | 5 +- .../anonymous.ocamlopt.reference | 8 +- .../basic-more/morematch.compilers.reference | 30 +- .../robustmatch.compilers.reference | 56 +- testsuite/tests/basic/equality.ml | 31 +- testsuite/tests/basic/equality.reference | 6 + .../tests/basic/patmatch_for_multiple.ml | 59 + testsuite/tests/basic/patmatch_incoherence.ml | 14 +- testsuite/tests/basic/patmatch_split_no_or.ml | 2 +- testsuite/tests/callback/callbackprim.c | 7 + testsuite/tests/callback/signals_alloc.ml | 9 +- .../tests/callback/signals_alloc.reference | 11 + testsuite/tests/callback/tcallback.ml | 9 +- testsuite/tests/flambda/afl_lazy.ml | 11 + .../float_subst_boxed_number.ml | 1 - ...test_locations.dlocations.ocamlc.reference | 142 +- ...ions.dlocations.ocamlopt.clambda.reference | 31 - ...ions.dlocations.ocamlopt.flambda.reference | 38 - ...t_locations.dno-locations.ocamlc.reference | 23 +- ...s.dno-locations.ocamlopt.clambda.reference | 28 - ...s.dno-locations.ocamlopt.flambda.reference | 31 - testsuite/tests/formatting/test_locations.ml | 29 +- .../tests/generalized-open/accepted_expect.ml | 1 + testsuite/tests/generalized-open/gpr1506.ml | 16 +- testsuite/tests/generalized-open/pr10048.ml | 17 + testsuite/tests/let-syntax/let_syntax.ml | 24 +- .../tests/letrec-check/pr7231.ocaml.reference | 2 +- testsuite/tests/lexing/escape.ocaml.reference | 6 +- .../tests/lexing/uchar_esc.ocaml.reference | 4 +- testsuite/tests/lib-arg/test_rest_all.ml | 80 + testsuite/tests/lib-arg/testarg.ml | 4 +- testsuite/tests/lib-arg/testerror.ml | 1 - testsuite/tests/lib-atomic/test_atomic.ml | 39 + testsuite/tests/lib-bigarray-2/bigarrfml.ml | 4 +- .../tests/lib-bigarray-2/call-gfortran.sh | 7 + testsuite/tests/lib-bigarray/bigarrays.ml | 168 +- .../tests/lib-bigarray/bigarrays.reference | 10 + testsuite/tests/lib-bigarray/change_layout.ml | 4 +- .../tests/lib-channels/in_channel_length.ml | 20 + testsuite/tests/lib-channels/seek_in.ml | 19 + testsuite/tests/lib-dynlink-bytecode/stub2.c | 2 +- testsuite/tests/lib-dynlink-init-info/test.ml | 13 + .../lib-dynlink-init-info/test.reference | 1 + .../test10_main.byte.reference | 6 +- .../test10_main.native.reference | 8 +- testsuite/tests/lib-either/test.ml | 108 + testsuite/tests/lib-floatarray/floatarray.ml | 26 +- testsuite/tests/lib-format/print_seq.ml | 33 + .../tests/lib-format/print_seq.reference | 7 + testsuite/tests/lib-hashtbl/compatibility.ml | 45 + testsuite/tests/lib-hashtbl/htbl.ml | 6 + testsuite/tests/lib-list/test.ml | 33 +- testsuite/tests/lib-marshal/intext.ml | 101 +- testsuite/tests/lib-marshal/intextaux.c | 15 +- testsuite/tests/lib-obj/new_obj.ml | 16 + testsuite/tests/lib-obj/new_obj.reference | 1 + testsuite/tests/lib-obj/reachable_words.ml | 6 - testsuite/tests/lib-obj/reachable_words_np.ml | 21 + testsuite/tests/lib-random/rand.ml | 6 +- testsuite/tests/lib-scanf/tscanf.ml | 1 - testsuite/tests/lib-set/testmap.ml | 15 + testsuite/tests/lib-set/testset.ml | 15 + .../tests/lib-stdlabels/test_stdlabels.ml | 31 +- testsuite/tests/lib-string/test_string.ml | 2 +- testsuite/tests/lib-systhreads/eintr.ml | 91 + .../tests/lib-systhreads/eintr.reference | 4 + testsuite/tests/lib-threads/fileio.ml | 2 +- testsuite/tests/lib-threads/mutex_errors.ml | 68 + .../tests/lib-threads/mutex_errors.reference | 20 + testsuite/tests/lib-threads/pr4466.ml | 2 - testsuite/tests/lib-threads/pr9971.ml | 15 + testsuite/tests/lib-unix/common/channel_of.ml | 6 +- .../tests/lib-unix/common/redirections.ml | 18 + .../lib-unix/common/redirections.reference | 5 + .../tests/lib-unix/common/test_unixlabels.ml | 12 + .../lib-unix/common/test_unixlabels.reference | 0 testsuite/tests/lib-unix/common/uexit.ml | 11 + testsuite/tests/lib-unix/kill/unix_kill.ml | 26 + .../tests/lib-unix/kill/unix_kill.reference | 2 + testsuite/tests/link-test/empty.ml | 29 + .../exhaustiveness_warnings.ml | 12 +- testsuite/tests/messages/precise_locations.ml | 2 +- testsuite/tests/misc/ephe_infix.ml | 26 + testsuite/tests/misc/weaklifetime.ml | 31 +- .../no-alias-deps/aliases.compilers.reference | 4 +- .../locations_test.compilers.reference | 1103 ++ testsuite/tests/parsetree/locations_test.ml | 112 + testsuite/tests/parsetree/source.ml | 42 + .../parsing/attributes.compilers.reference | 107 +- testsuite/tests/parsing/attributes.ml | 10 + .../tests/parsing/extension_operators.ml | 67 + .../parsing/extensions.compilers.reference | 2 +- .../shortcut_ext_attr.compilers.reference | 4 +- .../tests/printing-types/disambiguation.ml | 4 +- .../reproducibility/cmis_on_file_system.ml | 8 +- .../tests/runtime-naked-pointers/cstubs.c | 20 + testsuite/tests/runtime-naked-pointers/np.ml | 11 + testsuite/tests/runtime-naked-pointers/np1.ml | 12 + testsuite/tests/runtime-naked-pointers/np2.ml | 13 + .../tests/runtime-naked-pointers/np2.run | 3 + testsuite/tests/runtime-naked-pointers/np3.ml | 15 + .../tests/runtime-naked-pointers/np3.run | 3 + testsuite/tests/runtime-naked-pointers/np4.ml | 13 + .../tests/runtime-naked-pointers/np4.run | 3 + .../tests/runtime-naked-pointers/runtest.sh | 10 + .../tests/self-contained-toplevel/main.ml | 2 +- testsuite/tests/shadow_include/shadow_all.ml | 24 +- testsuite/tests/statmemprof/alloc_counts.ml | 53 + .../tests/statmemprof/alloc_counts.reference | 0 .../tests/statmemprof/arrays_in_major.ml | 3 +- .../tests/statmemprof/arrays_in_minor.ml | 3 +- .../tests/statmemprof/blocking_in_callback.ml | 40 +- .../callstacks.flat-float-array.reference | 90 +- testsuite/tests/statmemprof/callstacks.ml | 19 +- .../callstacks.no-flat-float-array.reference | 82 +- .../statmemprof/comballoc.byte.reference | 60 +- testsuite/tests/statmemprof/comballoc.ml | 10 +- .../tests/statmemprof/comballoc.opt.reference | 60 +- testsuite/tests/statmemprof/custom.ml | 44 + testsuite/tests/statmemprof/custom.reference | 3 + .../tests/statmemprof/exception_callback.ml | 5 + testsuite/tests/statmemprof/intern.ml | 5 +- testsuite/tests/statmemprof/lists_in_minor.ml | 5 +- .../tests/statmemprof/minor_no_postpone.ml | 5 +- .../tests/statmemprof/moved_while_blocking.ml | 76 + .../moved_while_blocking.reference | 13 + .../statmemprof/thread_exit_in_callback.ml | 22 +- .../thread_exit_in_callback.reference | 1 - .../thread_exit_in_callback_stub.c | 16 - .../tests/tool-caml-tex/ellipses.reference | 64 +- .../tool-caml-tex/redirections.reference | 24 +- ...tool-ocamlc-open-error.compilers.reference | 2 +- ...stop_after_typing_impl.compilers.reference | 14 +- .../stop_after_typing_impl.ml | 2 +- .../tests/tool-ocamlobjinfo/has-lib-bfd.sh | 7 - testsuite/tests/tool-ocamlobjinfo/question.ml | 12 +- .../check_for_pack.compilers.reference | 2 + .../tool-ocamlopt-save-ir/check_for_pack.ml | 19 + .../save_ir_after_scheduling.ml | 14 + .../save_ir_after_scheduling.sh | 14 + .../save_ir_after_typing.compilers.reference | 1 + .../save_ir_after_typing.ml | 15 + .../save_ir_after_typing.sh | 3 + .../tool-ocamlopt-save-ir/start_from_emit.ml | 31 + .../tool-ocamlopt-save-ir/start_from_emit.sh | 14 + testsuite/tests/tool-ocamltest/norm1.ml | 5 + .../tests/tool-ocamltest/norm1.reference | 1 + testsuite/tests/tool-ocamltest/norm2.ml | 5 + .../tests/tool-ocamltest/norm2.reference | 2 + testsuite/tests/tool-ocamltest/norm3.ml | 5 + .../tests/tool-ocamltest/norm3.reference | 2 + testsuite/tests/tool-ocamltest/norm4.ml | 5 + .../tests/tool-ocamltest/norm4.reference | 2 + .../tool-toplevel/pr6468.compilers.reference | 6 +- .../tool-toplevel/pr7060.compilers.reference | 2 +- testsuite/tests/tool-toplevel/printval.ml | 60 + .../comparison_table.compilers.reference | 24 +- testsuite/tests/translprim/locs.ml | 117 + testsuite/tests/translprim/locs.reference | 31 + .../translprim/ref_spec.compilers.reference | 34 +- .../tests/typing-core-bugs/const_int_hint.ml | 6 - .../type_expected_explanation.ml | 11 + testsuite/tests/typing-deprecated/alerts.ml | 6 +- .../tests/typing-deprecated/deprecated.ml | 20 +- .../tests/typing-extensions/disambiguation.ml | 2 +- .../tests/typing-extensions/extensions.ml | 2 +- .../tests/typing-extensions/open_types.ml | 6 +- testsuite/tests/typing-fstclassmod/aliases.ml | 22 + .../typing-fstclassmod/nondep_instance.ml | 51 + testsuite/tests/typing-gadts/didier.ml | 4 +- testsuite/tests/typing-gadts/or_patterns.ml | 38 +- testsuite/tests/typing-gadts/pr5785.ml | 4 +- testsuite/tests/typing-gadts/pr5906.ml | 2 +- testsuite/tests/typing-gadts/pr5981.ml | 4 +- testsuite/tests/typing-gadts/pr5985.ml | 13 +- testsuite/tests/typing-gadts/pr5989.ml | 4 +- testsuite/tests/typing-gadts/pr5997.ml | 4 +- testsuite/tests/typing-gadts/pr6174.ml | 2 +- testsuite/tests/typing-gadts/pr6241.ml | 2 +- testsuite/tests/typing-gadts/pr6690.ml | 20 - testsuite/tests/typing-gadts/pr6993_bad.ml | 2 +- testsuite/tests/typing-gadts/pr7016.ml | 4 +- testsuite/tests/typing-gadts/pr7222.ml | 12 - testsuite/tests/typing-gadts/pr7234.ml | 4 +- testsuite/tests/typing-gadts/pr7269.ml | 6 +- testsuite/tests/typing-gadts/pr7374.ml | 18 +- testsuite/tests/typing-gadts/pr7390.ml | 2 +- testsuite/tests/typing-gadts/pr7432.ml | 2 +- testsuite/tests/typing-gadts/pr7902.ml | 33 + testsuite/tests/typing-gadts/pr9019.ml | 12 +- testsuite/tests/typing-gadts/pr9759.ml | 31 + testsuite/tests/typing-gadts/pr9799.ml | 22 + .../typing-gadts/principality-and-gadts.ml | 442 + testsuite/tests/typing-gadts/test.ml | 24 +- testsuite/tests/typing-gadts/yallop_bugs.ml | 8 +- .../typing-implicit_unpack/implicit_unpack.ml | 8 +- testsuite/tests/typing-misc/build_as_type.ml | 155 + testsuite/tests/typing-misc/constraints.ml | 132 +- .../typing-misc/disambiguate_principality.ml | 104 +- testsuite/tests/typing-misc/empty_variant.ml | 4 +- testsuite/tests/typing-misc/injectivity.ml | 437 + testsuite/tests/typing-misc/labels.ml | 8 +- testsuite/tests/typing-misc/normalize_type.ml | 20 + testsuite/tests/typing-misc/polyvars.ml | 16 +- testsuite/tests/typing-misc/pr6416.ml | 4 +- .../typing-misc/pr6939-flat-float-array.ml | 2 +- .../typing-misc/pr6939-no-flat-float-array.ml | 4 +- testsuite/tests/typing-misc/pr7937.ml | 33 +- testsuite/tests/typing-misc/printing.ml | 17 + testsuite/tests/typing-misc/records.ml | 2 +- .../typing-misc/typecore_nolabel_errors.ml | 6 +- .../tests/typing-missing-cmi-3/middle.ml | 3 + testsuite/tests/typing-missing-cmi-3/user.ml | 42 + testsuite/tests/typing-modules/aliases.ml | 31 +- .../applicative_functor_type.ml | 2 +- testsuite/tests/typing-modules/nondep.ml | 16 + testsuite/tests/typing-modules/pr6633.ml | 69 + testsuite/tests/typing-modules/pr7818.ml | 1 + .../pr7284_bad.compilers.reference | 2 +- testsuite/tests/typing-objects/Exemples.ml | 4 +- testsuite/tests/typing-objects/Tests.ml | 10 +- .../pervasives_leitmotiv.compilers.reference | 2 +- .../pr4791.compilers.reference | 2 +- .../pr6323.compilers.reference | 2 +- .../pr7402.compilers.reference | 2 +- testsuite/tests/typing-poly/poly.ml | 53 +- testsuite/tests/typing-poly/pr9603.ml | 12 - .../tests/typing-polyvariants-bugs/pr7824.ml | 2 +- .../private.compilers.principal.reference | 2 +- .../private.compilers.reference | 2 +- .../b_bad.compilers.reference | 2 +- .../redefine_largefile.ml | 2 +- .../short-paths.compilers.reference | 1 + testsuite/tests/typing-sigsubst/sigsubst.ml | 6 +- testsuite/tests/typing-unboxed/test.ml | 6 +- .../ambiguous_guarded_disjunction.ml | 59 +- .../tests/typing-warnings/application.ml | 30 +- testsuite/tests/typing-warnings/coercions.ml | 4 +- .../tests/typing-warnings/exhaustiveness.ml | 94 +- .../tests/typing-warnings/fragile_matching.ml | 108 + .../tests/typing-warnings/never_returns.ml | 8 +- .../tests/typing-warnings/open_warnings.ml | 40 +- testsuite/tests/typing-warnings/pr5892.ml | 2 +- testsuite/tests/typing-warnings/pr6872.ml | 18 +- testsuite/tests/typing-warnings/pr7085.ml | 2 +- testsuite/tests/typing-warnings/pr7115.ml | 8 +- .../pr7261.compilers.reference | 2 +- testsuite/tests/typing-warnings/pr7297.ml | 2 +- testsuite/tests/typing-warnings/pr7553.ml | 6 +- testsuite/tests/typing-warnings/pr9244.ml | 6 +- testsuite/tests/typing-warnings/records.ml | 192 +- .../unused_functor_parameter.ml | 6 +- testsuite/tests/typing-warnings/unused_rec.ml | 6 +- .../tests/typing-warnings/unused_recmodule.ml | 2 +- .../tests/typing-warnings/unused_types.ml | 34 +- testsuite/tests/typing-warnings/warning16.ml | 58 + .../tests/unboxed-primitive-args/test.ml | 15 +- testsuite/tests/unwind/driver.ml | 11 +- testsuite/tests/unwind/stack_walker.c | 38 +- testsuite/tests/warnings/mnemonics.mll | 84 + testsuite/tests/warnings/mnemonics.reference | 2 + .../tests/warnings/w01.compilers.reference | 12 +- .../tests/warnings/w03.compilers.reference | 2 +- .../tests/warnings/w04.compilers.reference | 2 +- .../warnings/w04_failure.compilers.reference | 6 +- .../tests/warnings/w06.compilers.reference | 4 +- .../tests/warnings/w32.compilers.reference | 38 +- .../tests/warnings/w32b.compilers.reference | 4 +- .../tests/warnings/w33.compilers.reference | 6 +- .../tests/warnings/w45.compilers.reference | 6 +- .../warnings/w47_inline.compilers.reference | 18 +- .../tests/warnings/w50.compilers.reference | 4 +- .../tests/warnings/w51.compilers.reference | 4 - testsuite/tests/warnings/w51.ml | 77 +- .../warnings/w51_bis.compilers.reference | 2 +- testsuite/tests/warnings/w52.ml | 12 +- .../tests/warnings/w53.compilers.reference | 42 +- testsuite/tests/warnings/w53.ml | 6 + .../tests/warnings/w54.compilers.reference | 8 +- .../tests/warnings/w55.flambda.reference | 6 +- testsuite/tests/warnings/w55.native.reference | 12 +- testsuite/tests/warnings/w58.native.reference | 2 +- .../tests/warnings/w59.flambda.reference | 10 +- .../tests/warnings/w60.compilers.reference | 2 +- .../tests/warnings/w68.compilers.reference | 11 + testsuite/tests/warnings/w68.ml | 34 + testsuite/tests/warnings/w68.reference | 2 + testsuite/tools/asmgen_arm64.S | 14 +- testsuite/tools/lexcmm.mll | 3 - testsuite/tools/parsecmm.mly | 5 +- testsuite/tools/parsecmmaux.ml | 6 +- tools/.depend | 70 +- tools/Makefile | 149 +- tools/caml_tex.ml | 22 +- tools/check-typo | 5 +- tools/ci/actions/runner.sh | 133 + tools/ci/appveyor/appveyor_build.cmd | 6 +- tools/ci/appveyor/appveyor_build.sh | 19 +- tools/ci/inria/README.md | 13 + tools/ci/inria/Risc-V/Jenkinsfile | 45 + tools/ci/inria/bootstrap/Jenkinsfile | 46 + .../remove-sinh-primitive.patch | 0 .../ci/inria/{bootstrap => bootstrap/script} | 13 +- tools/ci/inria/check-typo/Jenkinsfile | 50 + tools/ci/inria/dune-build/Jenkinsfile | 44 + .../inria/{dune-build => dune-build/script} | 0 tools/ci/inria/light | 90 + tools/ci/inria/main | 44 +- tools/ci/inria/other-configs/Jenkinsfile | 46 + .../{other-configs => other-configs/script} | 21 +- .../ci/inria/sanitizers/Jenkinsfile | 48 +- .../ci/inria/{ => sanitizers}/lsan-suppr.txt | 0 .../inria/{extra-checks => sanitizers/script} | 164 +- tools/ci/inria/step-by-step-build/Jenkinsfile | 48 + .../ci/inria/step-by-step-build/script | 20 +- tools/ci/travis/travis-ci.sh | 76 +- tools/dumpobj.ml | 9 +- tools/make-package-macosx | 138 - tools/objinfo.ml | 24 +- tools/objinfo_helper.c | 148 - tools/ocaml-objcopy-macosx | 54 - tools/{read_cmt.ml => ocamlcmt.ml} | 7 +- tools/ocamlcp.ml | 5 +- tools/ocamlmktop.ml | 5 +- tools/ocamloptp.ml | 5 +- tools/sync_stdlib_docs | 145 + tools/unlabel-patches/1.mli | 3 + tools/unlabel-patches/2.mli | 3 + tools/unlabel-patches/3.mli | 3 + tools/unlabel-patches/4.mli | 3 + toplevel/dune | 2 +- toplevel/genprintval.ml | 46 +- toplevel/opttopdirs.ml | 2 +- toplevel/opttoploop.ml | 2 +- toplevel/opttopmain.ml | 23 +- toplevel/opttopmain.mli | 2 +- toplevel/opttopstart.ml | 2 +- toplevel/topdirs.ml | 2 +- toplevel/toploop.ml | 22 +- toplevel/topmain.ml | 21 +- toplevel/topmain.mli | 4 +- toplevel/topstart.ml | 2 +- toplevel/trace.ml | 10 +- typing/btype.ml | 20 +- typing/ctype.ml | 209 +- typing/ctype.mli | 32 +- typing/datarepr.ml | 2 +- typing/env.ml | 206 +- typing/env.mli | 25 + typing/ident.ml | 6 +- typing/ident.mli | 2 +- typing/mtype.ml | 2 + typing/oprint.ml | 8 +- typing/outcometree.mli | 8 +- typing/parmatch.ml | 905 +- typing/parmatch.mli | 59 +- typing/patterns.ml | 254 + typing/patterns.mli | 109 + typing/printtyp.ml | 83 +- typing/subst.ml | 4 +- typing/typeclass.ml | 18 +- typing/typecore.ml | 271 +- typing/typecore.mli | 2 - typing/typedecl.ml | 33 +- typing/typedecl.mli | 2 +- typing/typedecl_variance.ml | 54 +- typing/typedecl_variance.mli | 3 +- typing/typedtree.ml | 15 +- typing/typedtree.mli | 11 +- typing/typemod.ml | 136 +- typing/typemod.mli | 3 +- typing/types.ml | 7 +- typing/types.mli | 19 +- typing/typetexp.ml | 19 +- typing/typetexp.mli | 9 +- typing/untypeast.ml | 6 + typing/untypeast.mli | 2 + utils/Makefile | 36 +- utils/binutils.ml | 689 + utils/binutils.mli | 30 + utils/ccomp.ml | 42 +- utils/ccomp.mli | 2 + utils/clflags.ml | 89 +- utils/clflags.mli | 14 +- utils/config.mli | 26 +- utils/config.mlp | 37 +- utils/dune | 1 + utils/load_path.ml | 67 +- utils/load_path.mli | 3 +- utils/local_store.ml | 74 + utils/local_store.mli | 66 + utils/misc.ml | 13 +- utils/misc.mli | 16 +- utils/warnings.ml | 375 +- utils/warnings.mli | 27 +- yacc/Makefile | 3 +- 986 files changed, 39226 insertions(+), 29130 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/stale.yml create mode 100644 Makefile.build_config.in rename Makefile.common.in => Makefile.common (54%) rename otherlibs/raw_spacetime_lib/Makefile => Makefile.config_if_required (60%) delete mode 100644 asmcomp/spacetime_profiling.ml create mode 100644 driver/maindriver.ml rename driver/{optmain.mli => maindriver.mli} (78%) create mode 100644 driver/optmaindriver.ml create mode 100644 driver/optmaindriver.mli create mode 100644 file_formats/linear_format.ml create mode 100644 file_formats/linear_format.mli delete mode 100644 manual/manual/cmds/browser.etex delete mode 100644 manual/manual/cmds/ocamlbuild.etex delete mode 100644 manual/manual/cmds/spacetime-chapter.etex create mode 100644 manual/manual/html_processing/.gitignore create mode 100644 manual/manual/html_processing/Makefile create mode 100644 manual/manual/html_processing/README.md create mode 100644 manual/manual/html_processing/dune-project create mode 100644 manual/manual/html_processing/js/navigation.js create mode 100644 manual/manual/html_processing/js/scroll.js create mode 100644 manual/manual/html_processing/js/search.js create mode 100644 manual/manual/html_processing/scss/_common.scss create mode 100644 manual/manual/html_processing/scss/manual.scss create mode 100644 manual/manual/html_processing/scss/style.scss create mode 100644 manual/manual/html_processing/src/common.ml create mode 100644 manual/manual/html_processing/src/dune create mode 100644 manual/manual/html_processing/src/process_api.ml create mode 100644 manual/manual/html_processing/src/process_manual.ml delete mode 100644 manual/manual/library/libbigarray.etex delete mode 100644 manual/manual/library/libgraph.etex delete mode 100644 manual/manual/library/libnum.etex create mode 100644 manual/manual/library/old.etex delete mode 100644 ocamltest/ocamltest_stdlib_stubs.c create mode 100644 ocamltest/ocamltest_unix.mli rename asmcomp/spacetime_profiling.mli => ocamltest/ocamltest_unix_dummy.ml (72%) create mode 100644 ocamltest/ocamltest_unix_real.ml delete mode 100644 otherlibs/raw_spacetime_lib/.depend delete mode 100644 otherlibs/raw_spacetime_lib/raw_spacetime_lib.ml delete mode 100644 otherlibs/raw_spacetime_lib/raw_spacetime_lib.mli delete mode 100644 otherlibs/raw_spacetime_lib/spacetime_offline.c create mode 100644 otherlibs/systhreads/semaphore.ml create mode 100644 otherlibs/systhreads/semaphore.mli create mode 100644 otherlibs/unix/spawn.c delete mode 100644 otherlibs/win32unix/socketaddr.h rename News => release-info/News (80%) rename tools/release-checklist => release-info/howto.md (82%) rename {tools => release-info}/markdown-add-pr-links.sh (72%) create mode 100644 release-info/templates/beta.md create mode 100644 release-info/templates/production.md create mode 100644 release-info/templates/rc.md delete mode 100644 runtime/.depend delete mode 100644 runtime/caml/spacetime.h delete mode 100644 runtime/spacetime_byt.c delete mode 100644 runtime/spacetime_nat.c delete mode 100644 runtime/spacetime_snapshot.c rename driver/main.mli => stdlib/atomic.ml (82%) create mode 100644 stdlib/atomic.mli create mode 100644 stdlib/camlinternalAtomic.ml create mode 100644 stdlib/camlinternalAtomic.mli create mode 100644 stdlib/either.ml create mode 100644 stdlib/either.mli delete mode 100644 stdlib/spacetime.ml delete mode 100644 stdlib/spacetime.mli create mode 100644 stdlib/templates/README.adoc create mode 100644 stdlib/templates/float.template.mli create mode 100644 stdlib/templates/floatarraylabeled.template.mli create mode 100644 stdlib/templates/hashtbl.template.mli create mode 100644 stdlib/templates/map.template.mli create mode 100644 stdlib/templates/moreLabels.template.mli create mode 100644 stdlib/templates/set.template.mli create mode 100644 testsuite/tests/asmgen/immediates.cmm create mode 100644 testsuite/tests/asmgen/immediates.cmmpp create mode 100644 testsuite/tests/asmgen/immediates.tbl create mode 100644 testsuite/tests/asmgen/mainimmed.c create mode 100644 testsuite/tests/backtrace/lazy.ml create mode 100644 testsuite/tests/backtrace/lazy.reference create mode 100644 testsuite/tests/backtrace/pr2195-locs.byte.reference create mode 100644 testsuite/tests/backtrace/pr2195-nolocs.byte.reference create mode 100644 testsuite/tests/backtrace/pr2195.ml create mode 100644 testsuite/tests/backtrace/pr2195.opt.reference create mode 100755 testsuite/tests/backtrace/pr2195.run create mode 100644 testsuite/tests/basic/patmatch_for_multiple.ml create mode 100644 testsuite/tests/flambda/afl_lazy.ml delete mode 100644 testsuite/tests/formatting/test_locations.dlocations.ocamlopt.clambda.reference delete mode 100644 testsuite/tests/formatting/test_locations.dlocations.ocamlopt.flambda.reference delete mode 100644 testsuite/tests/formatting/test_locations.dno-locations.ocamlopt.clambda.reference delete mode 100644 testsuite/tests/formatting/test_locations.dno-locations.ocamlopt.flambda.reference create mode 100644 testsuite/tests/generalized-open/pr10048.ml create mode 100644 testsuite/tests/lib-arg/test_rest_all.ml create mode 100644 testsuite/tests/lib-atomic/test_atomic.ml create mode 100644 testsuite/tests/lib-bigarray-2/call-gfortran.sh create mode 100644 testsuite/tests/lib-channels/in_channel_length.ml create mode 100644 testsuite/tests/lib-channels/seek_in.ml create mode 100644 testsuite/tests/lib-dynlink-init-info/test.ml create mode 100644 testsuite/tests/lib-dynlink-init-info/test.reference create mode 100644 testsuite/tests/lib-either/test.ml create mode 100644 testsuite/tests/lib-format/print_seq.ml create mode 100644 testsuite/tests/lib-format/print_seq.reference create mode 100644 testsuite/tests/lib-hashtbl/compatibility.ml create mode 100644 testsuite/tests/lib-obj/new_obj.ml create mode 100644 testsuite/tests/lib-obj/new_obj.reference create mode 100644 testsuite/tests/lib-obj/reachable_words_np.ml create mode 100644 testsuite/tests/lib-systhreads/eintr.ml create mode 100644 testsuite/tests/lib-systhreads/eintr.reference create mode 100644 testsuite/tests/lib-threads/mutex_errors.ml create mode 100644 testsuite/tests/lib-threads/mutex_errors.reference create mode 100644 testsuite/tests/lib-threads/pr9971.ml create mode 100644 testsuite/tests/lib-unix/common/test_unixlabels.ml create mode 100644 testsuite/tests/lib-unix/common/test_unixlabels.reference create mode 100644 testsuite/tests/lib-unix/common/uexit.ml create mode 100644 testsuite/tests/lib-unix/kill/unix_kill.ml create mode 100644 testsuite/tests/lib-unix/kill/unix_kill.reference create mode 100644 testsuite/tests/link-test/empty.ml create mode 100644 testsuite/tests/misc/ephe_infix.ml create mode 100644 testsuite/tests/parsetree/locations_test.compilers.reference create mode 100644 testsuite/tests/parsetree/locations_test.ml create mode 100644 testsuite/tests/parsing/extension_operators.ml create mode 100644 testsuite/tests/runtime-naked-pointers/cstubs.c create mode 100644 testsuite/tests/runtime-naked-pointers/np.ml create mode 100644 testsuite/tests/runtime-naked-pointers/np1.ml create mode 100644 testsuite/tests/runtime-naked-pointers/np2.ml create mode 100755 testsuite/tests/runtime-naked-pointers/np2.run create mode 100644 testsuite/tests/runtime-naked-pointers/np3.ml create mode 100755 testsuite/tests/runtime-naked-pointers/np3.run create mode 100644 testsuite/tests/runtime-naked-pointers/np4.ml create mode 100755 testsuite/tests/runtime-naked-pointers/np4.run create mode 100755 testsuite/tests/runtime-naked-pointers/runtest.sh create mode 100644 testsuite/tests/statmemprof/alloc_counts.ml create mode 100644 testsuite/tests/statmemprof/alloc_counts.reference create mode 100644 testsuite/tests/statmemprof/custom.ml create mode 100644 testsuite/tests/statmemprof/custom.reference create mode 100644 testsuite/tests/statmemprof/moved_while_blocking.ml create mode 100644 testsuite/tests/statmemprof/moved_while_blocking.reference delete mode 100644 testsuite/tests/statmemprof/thread_exit_in_callback.reference delete mode 100644 testsuite/tests/statmemprof/thread_exit_in_callback_stub.c delete mode 100644 testsuite/tests/tool-ocamlobjinfo/has-lib-bfd.sh create mode 100644 testsuite/tests/tool-ocamlopt-save-ir/check_for_pack.compilers.reference create mode 100644 testsuite/tests/tool-ocamlopt-save-ir/check_for_pack.ml create mode 100644 testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_scheduling.ml create mode 100755 testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_scheduling.sh create mode 100644 testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.compilers.reference create mode 100644 testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.ml create mode 100755 testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.sh create mode 100644 testsuite/tests/tool-ocamlopt-save-ir/start_from_emit.ml create mode 100755 testsuite/tests/tool-ocamlopt-save-ir/start_from_emit.sh create mode 100644 testsuite/tests/tool-ocamltest/norm1.ml create mode 100644 testsuite/tests/tool-ocamltest/norm1.reference create mode 100644 testsuite/tests/tool-ocamltest/norm2.ml create mode 100644 testsuite/tests/tool-ocamltest/norm2.reference create mode 100644 testsuite/tests/tool-ocamltest/norm3.ml create mode 100644 testsuite/tests/tool-ocamltest/norm3.reference create mode 100644 testsuite/tests/tool-ocamltest/norm4.ml create mode 100644 testsuite/tests/tool-ocamltest/norm4.reference create mode 100644 testsuite/tests/tool-toplevel/printval.ml create mode 100644 testsuite/tests/typing-fstclassmod/aliases.ml create mode 100644 testsuite/tests/typing-fstclassmod/nondep_instance.ml create mode 100644 testsuite/tests/typing-gadts/pr7902.ml create mode 100644 testsuite/tests/typing-gadts/pr9759.ml create mode 100644 testsuite/tests/typing-gadts/pr9799.ml create mode 100644 testsuite/tests/typing-gadts/principality-and-gadts.ml create mode 100644 testsuite/tests/typing-misc/build_as_type.ml create mode 100644 testsuite/tests/typing-misc/injectivity.ml create mode 100644 testsuite/tests/typing-misc/normalize_type.ml create mode 100644 testsuite/tests/typing-modules/pr6633.ml create mode 100644 testsuite/tests/typing-warnings/fragile_matching.ml create mode 100644 testsuite/tests/typing-warnings/warning16.ml create mode 100644 testsuite/tests/warnings/mnemonics.mll create mode 100644 testsuite/tests/warnings/mnemonics.reference delete mode 100644 testsuite/tests/warnings/w51.compilers.reference create mode 100644 testsuite/tests/warnings/w68.compilers.reference create mode 100644 testsuite/tests/warnings/w68.ml create mode 100644 testsuite/tests/warnings/w68.reference create mode 100755 tools/ci/actions/runner.sh create mode 100644 tools/ci/inria/README.md create mode 100644 tools/ci/inria/Risc-V/Jenkinsfile create mode 100644 tools/ci/inria/bootstrap/Jenkinsfile rename tools/ci/inria/{ => bootstrap}/remove-sinh-primitive.patch (100%) rename tools/ci/inria/{bootstrap => bootstrap/script} (96%) create mode 100644 tools/ci/inria/check-typo/Jenkinsfile create mode 100644 tools/ci/inria/dune-build/Jenkinsfile rename tools/ci/inria/{dune-build => dune-build/script} (100%) create mode 100755 tools/ci/inria/light create mode 100644 tools/ci/inria/other-configs/Jenkinsfile rename tools/ci/inria/{other-configs => other-configs/script} (61%) rename otherlibs/win32unix/mkdir.c => tools/ci/inria/sanitizers/Jenkinsfile (50%) rename tools/ci/inria/{ => sanitizers}/lsan-suppr.txt (100%) rename tools/ci/inria/{extra-checks => sanitizers/script} (57%) create mode 100644 tools/ci/inria/step-by-step-build/Jenkinsfile rename ocamldoc/remove_DEBUG => tools/ci/inria/step-by-step-build/script (69%) delete mode 100755 tools/make-package-macosx delete mode 100644 tools/objinfo_helper.c delete mode 100755 tools/ocaml-objcopy-macosx rename tools/{read_cmt.ml => ocamlcmt.ml} (96%) create mode 100755 tools/sync_stdlib_docs create mode 100644 tools/unlabel-patches/1.mli create mode 100644 tools/unlabel-patches/2.mli create mode 100644 tools/unlabel-patches/3.mli create mode 100644 tools/unlabel-patches/4.mli create mode 100644 typing/patterns.ml create mode 100644 typing/patterns.mli create mode 100644 utils/binutils.ml create mode 100644 utils/binutils.mli create mode 100644 utils/local_store.ml create mode 100644 utils/local_store.mli diff --git a/.depend b/.depend index 1c2692e1..48759913 100644 --- a/.depend +++ b/.depend @@ -3,6 +3,11 @@ utils/arg_helper.cmo : \ utils/arg_helper.cmx : \ utils/arg_helper.cmi utils/arg_helper.cmi : +utils/binutils.cmo : \ + utils/binutils.cmi +utils/binutils.cmx : \ + utils/binutils.cmi +utils/binutils.cmi : utils/build_path_prefix_map.cmo : \ utils/build_path_prefix_map.cmi utils/build_path_prefix_map.cmx : \ @@ -72,11 +77,20 @@ utils/int_replace_polymorphic_compare.cmx : \ utils/int_replace_polymorphic_compare.cmi : utils/load_path.cmo : \ utils/misc.cmi \ + utils/local_store.cmi \ + utils/config.cmi \ utils/load_path.cmi utils/load_path.cmx : \ utils/misc.cmx \ + utils/local_store.cmx \ + utils/config.cmx \ utils/load_path.cmi utils/load_path.cmi : +utils/local_store.cmo : \ + utils/local_store.cmi +utils/local_store.cmx : \ + utils/local_store.cmi +utils/local_store.cmi : utils/misc.cmo : \ utils/config.cmi \ utils/build_path_prefix_map.cmi \ @@ -428,12 +442,14 @@ typing/annot.cmi : \ typing/btype.cmo : \ typing/types.cmi \ typing/path.cmi \ + utils/local_store.cmi \ typing/ident.cmi \ parsing/asttypes.cmi \ typing/btype.cmi typing/btype.cmx : \ typing/types.cmx \ typing/path.cmx \ + utils/local_store.cmx \ typing/ident.cmx \ parsing/asttypes.cmi \ typing/btype.cmi @@ -478,6 +494,7 @@ typing/ctype.cmo : \ utils/misc.cmi \ parsing/longident.cmi \ parsing/location.cmi \ + utils/local_store.cmi \ typing/ident.cmi \ typing/env.cmi \ utils/clflags.cmi \ @@ -493,6 +510,7 @@ typing/ctype.cmx : \ utils/misc.cmx \ parsing/longident.cmx \ parsing/location.cmx \ + utils/local_store.cmx \ typing/ident.cmx \ typing/env.cmx \ utils/clflags.cmx \ @@ -537,6 +555,7 @@ typing/env.cmo : \ utils/misc.cmi \ parsing/longident.cmi \ parsing/location.cmi \ + utils/local_store.cmi \ utils/load_path.cmi \ typing/ident.cmi \ typing/datarepr.cmi \ @@ -556,6 +575,7 @@ typing/env.cmx : \ utils/misc.cmx \ parsing/longident.cmx \ parsing/location.cmx \ + utils/local_store.cmx \ utils/load_path.cmx \ typing/ident.cmx \ typing/datarepr.cmx \ @@ -601,11 +621,13 @@ typing/envaux.cmi : \ typing/env.cmi typing/ident.cmo : \ utils/misc.cmi \ + utils/local_store.cmi \ utils/identifiable.cmi \ utils/clflags.cmi \ typing/ident.cmi typing/ident.cmx : \ utils/misc.cmx \ + utils/local_store.cmx \ utils/identifiable.cmx \ utils/clflags.cmx \ typing/ident.cmi @@ -771,6 +793,7 @@ typing/parmatch.cmo : \ typing/subst.cmi \ typing/printpat.cmi \ typing/predef.cmi \ + typing/patterns.cmi \ typing/path.cmi \ parsing/parsetree.cmi \ utils/misc.cmi \ @@ -793,6 +816,7 @@ typing/parmatch.cmx : \ typing/subst.cmx \ typing/printpat.cmx \ typing/predef.cmx \ + typing/patterns.cmx \ typing/path.cmx \ parsing/parsetree.cmi \ utils/misc.cmx \ @@ -821,6 +845,34 @@ typing/path.cmx : \ typing/path.cmi typing/path.cmi : \ typing/ident.cmi +typing/patterns.cmo : \ + typing/types.cmi \ + typing/typedtree.cmi \ + parsing/longident.cmi \ + parsing/location.cmi \ + typing/ident.cmi \ + typing/env.cmi \ + typing/ctype.cmi \ + typing/btype.cmi \ + parsing/asttypes.cmi \ + typing/patterns.cmi +typing/patterns.cmx : \ + typing/types.cmx \ + typing/typedtree.cmx \ + parsing/longident.cmx \ + parsing/location.cmx \ + typing/ident.cmx \ + typing/env.cmx \ + typing/ctype.cmx \ + typing/btype.cmx \ + parsing/asttypes.cmi \ + typing/patterns.cmi +typing/patterns.cmi : \ + typing/types.cmi \ + typing/typedtree.cmi \ + parsing/longident.cmi \ + typing/ident.cmi \ + parsing/asttypes.cmi typing/persistent_env.cmo : \ utils/warnings.cmi \ utils/misc.cmi \ @@ -1031,6 +1083,7 @@ typing/subst.cmo : \ parsing/parsetree.cmi \ utils/misc.cmi \ parsing/location.cmi \ + utils/local_store.cmi \ typing/ident.cmi \ utils/clflags.cmi \ typing/btype.cmi \ @@ -1042,6 +1095,7 @@ typing/subst.cmx : \ parsing/parsetree.cmi \ utils/misc.cmx \ parsing/location.cmx \ + utils/local_store.cmx \ typing/ident.cmx \ utils/clflags.cmx \ typing/btype.cmx \ @@ -1101,7 +1155,6 @@ typing/typeclass.cmo : \ typing/path.cmi \ parsing/parsetree.cmi \ typing/oprint.cmi \ - utils/misc.cmi \ parsing/longident.cmi \ parsing/location.cmi \ typing/includeclass.cmi \ @@ -1129,7 +1182,6 @@ typing/typeclass.cmx : \ typing/path.cmx \ parsing/parsetree.cmi \ typing/oprint.cmx \ - utils/misc.cmx \ parsing/longident.cmx \ parsing/location.cmx \ typing/includeclass.cmx \ @@ -1182,7 +1234,6 @@ typing/typecore.cmo : \ typing/btype.cmi \ parsing/asttypes.cmi \ parsing/ast_helper.cmi \ - typing/annot.cmi \ typing/typecore.cmi typing/typecore.cmx : \ utils/warnings.cmx \ @@ -1213,7 +1264,6 @@ typing/typecore.cmx : \ typing/btype.cmx \ parsing/asttypes.cmi \ parsing/ast_helper.cmx \ - typing/annot.cmi \ typing/typecore.cmi typing/typecore.cmi : \ typing/types.cmi \ @@ -1225,8 +1275,7 @@ typing/typecore.cmi : \ typing/ident.cmi \ typing/env.cmi \ typing/ctype.cmi \ - parsing/asttypes.cmi \ - typing/annot.cmi + parsing/asttypes.cmi typing/typedecl.cmo : \ utils/warnings.cmi \ typing/typetexp.cmi \ @@ -1486,7 +1535,6 @@ typing/typemod.cmo : \ typing/btype.cmi \ parsing/attr_helper.cmi \ parsing/asttypes.cmi \ - typing/annot.cmi \ typing/typemod.cmi typing/typemod.cmx : \ utils/warnings.cmx \ @@ -1519,7 +1567,6 @@ typing/typemod.cmx : \ typing/btype.cmx \ parsing/attr_helper.cmx \ parsing/asttypes.cmi \ - typing/annot.cmi \ typing/typemod.cmi typing/typemod.cmi : \ typing/types.cmi \ @@ -1829,10 +1876,12 @@ bytecomp/bytesections.cmi : bytecomp/dll.cmo : \ utils/misc.cmi \ utils/config.cmi \ + utils/binutils.cmi \ bytecomp/dll.cmi bytecomp/dll.cmx : \ utils/misc.cmx \ utils/config.cmx \ + utils/binutils.cmx \ bytecomp/dll.cmi bytecomp/dll.cmi : bytecomp/emitcode.cmo : \ @@ -2026,6 +2075,7 @@ asmcomp/asmgen.cmo : \ asmcomp/liveness.cmi \ asmcomp/linscan.cmi \ asmcomp/linearize.cmi \ + file_formats/linear_format.cmi \ lambda/lambda.cmi \ asmcomp/interval.cmi \ asmcomp/interf.cmi \ @@ -2066,6 +2116,7 @@ asmcomp/asmgen.cmx : \ asmcomp/liveness.cmx \ asmcomp/linscan.cmx \ asmcomp/linearize.cmx \ + file_formats/linear_format.cmx \ lambda/lambda.cmx \ asmcomp/interval.cmx \ asmcomp/interf.cmx \ @@ -2228,26 +2279,28 @@ asmcomp/branch_relaxation.cmi : \ asmcomp/branch_relaxation_intf.cmo : \ asmcomp/linear.cmi \ lambda/debuginfo.cmi \ - asmcomp/cmm.cmi \ asmcomp/arch.cmo asmcomp/branch_relaxation_intf.cmx : \ asmcomp/linear.cmx \ lambda/debuginfo.cmx \ - asmcomp/cmm.cmx \ asmcomp/arch.cmx asmcomp/cmm.cmo : \ utils/targetint.cmi \ + utils/misc.cmi \ lambda/lambda.cmi \ lambda/debuginfo.cmi \ middle_end/backend_var.cmi \ parsing/asttypes.cmi \ + asmcomp/arch.cmo \ asmcomp/cmm.cmi asmcomp/cmm.cmx : \ utils/targetint.cmx \ + utils/misc.cmx \ lambda/lambda.cmx \ lambda/debuginfo.cmx \ middle_end/backend_var.cmx \ parsing/asttypes.cmi \ + asmcomp/arch.cmx \ asmcomp/cmm.cmi asmcomp/cmm.cmi : \ utils/targetint.cmi \ @@ -2401,7 +2454,6 @@ asmcomp/deadcode.cmo : \ asmcomp/proc.cmi \ utils/numbers.cmi \ asmcomp/mach.cmi \ - utils/config.cmi \ asmcomp/cmm.cmi \ asmcomp/deadcode.cmi asmcomp/deadcode.cmx : \ @@ -2409,7 +2461,6 @@ asmcomp/deadcode.cmx : \ asmcomp/proc.cmx \ utils/numbers.cmx \ asmcomp/mach.cmx \ - utils/config.cmx \ asmcomp/cmm.cmx \ asmcomp/deadcode.cmi asmcomp/deadcode.cmi : \ @@ -2531,7 +2582,6 @@ asmcomp/linearize.cmo : \ asmcomp/mach.cmi \ asmcomp/linear.cmi \ lambda/debuginfo.cmi \ - utils/config.cmi \ asmcomp/cmm.cmi \ asmcomp/linearize.cmi asmcomp/linearize.cmx : \ @@ -2541,7 +2591,6 @@ asmcomp/linearize.cmx : \ asmcomp/mach.cmx \ asmcomp/linear.cmx \ lambda/debuginfo.cmx \ - utils/config.cmx \ asmcomp/cmm.cmx \ asmcomp/linearize.cmi asmcomp/linearize.cmi : \ @@ -2564,7 +2613,6 @@ asmcomp/liveness.cmo : \ asmcomp/printmach.cmi \ utils/misc.cmi \ asmcomp/mach.cmi \ - utils/config.cmi \ asmcomp/cmm.cmi \ asmcomp/liveness.cmi asmcomp/liveness.cmx : \ @@ -2573,7 +2621,6 @@ asmcomp/liveness.cmx : \ asmcomp/printmach.cmx \ utils/misc.cmx \ asmcomp/mach.cmx \ - utils/config.cmx \ asmcomp/cmm.cmx \ asmcomp/liveness.cmi asmcomp/liveness.cmi : \ @@ -2654,7 +2701,6 @@ asmcomp/printmach.cmo : \ lambda/lambda.cmi \ asmcomp/interval.cmi \ lambda/debuginfo.cmi \ - utils/config.cmi \ asmcomp/cmm.cmi \ utils/clflags.cmi \ middle_end/backend_var.cmi \ @@ -2669,7 +2715,6 @@ asmcomp/printmach.cmx : \ lambda/lambda.cmx \ asmcomp/interval.cmx \ lambda/debuginfo.cmx \ - utils/config.cmx \ asmcomp/cmm.cmx \ utils/clflags.cmx \ middle_end/backend_var.cmx \ @@ -2698,7 +2743,8 @@ asmcomp/proc.cmx : \ asmcomp/proc.cmi asmcomp/proc.cmi : \ asmcomp/reg.cmi \ - asmcomp/mach.cmi + asmcomp/mach.cmi \ + asmcomp/cmm.cmi asmcomp/reg.cmo : \ asmcomp/cmm.cmi \ middle_end/backend_var.cmi \ @@ -2771,7 +2817,6 @@ asmcomp/scheduling.cmx : \ asmcomp/scheduling.cmi : \ asmcomp/linear.cmi asmcomp/selectgen.cmo : \ - lambda/simplif.cmi \ asmcomp/reg.cmi \ asmcomp/proc.cmi \ utils/numbers.cmi \ @@ -2779,14 +2824,12 @@ asmcomp/selectgen.cmo : \ asmcomp/mach.cmi \ lambda/lambda.cmi \ lambda/debuginfo.cmi \ - utils/config.cmi \ asmcomp/cmm.cmi \ middle_end/backend_var.cmi \ parsing/asttypes.cmi \ asmcomp/arch.cmo \ asmcomp/selectgen.cmi asmcomp/selectgen.cmx : \ - lambda/simplif.cmx \ asmcomp/reg.cmx \ asmcomp/proc.cmx \ utils/numbers.cmx \ @@ -2794,7 +2837,6 @@ asmcomp/selectgen.cmx : \ asmcomp/mach.cmx \ lambda/lambda.cmx \ lambda/debuginfo.cmx \ - utils/config.cmx \ asmcomp/cmm.cmx \ middle_end/backend_var.cmx \ parsing/asttypes.cmi \ @@ -2809,21 +2851,17 @@ asmcomp/selectgen.cmi : \ parsing/asttypes.cmi \ asmcomp/arch.cmo asmcomp/selection.cmo : \ - asmcomp/spacetime_profiling.cmi \ asmcomp/selectgen.cmi \ asmcomp/proc.cmi \ asmcomp/mach.cmi \ - utils/config.cmi \ asmcomp/cmm.cmi \ utils/clflags.cmi \ asmcomp/arch.cmo \ asmcomp/selection.cmi asmcomp/selection.cmx : \ - asmcomp/spacetime_profiling.cmx \ asmcomp/selectgen.cmx \ asmcomp/proc.cmx \ asmcomp/mach.cmx \ - utils/config.cmx \ asmcomp/cmm.cmx \ utils/clflags.cmx \ asmcomp/arch.cmx \ @@ -2831,34 +2869,6 @@ asmcomp/selection.cmx : \ asmcomp/selection.cmi : \ asmcomp/mach.cmi \ asmcomp/cmm.cmi -asmcomp/spacetime_profiling.cmo : \ - asmcomp/selectgen.cmi \ - asmcomp/proc.cmi \ - utils/misc.cmi \ - asmcomp/mach.cmi \ - lambda/lambda.cmi \ - lambda/debuginfo.cmi \ - utils/config.cmi \ - asmcomp/cmm.cmi \ - middle_end/backend_var.cmi \ - parsing/asttypes.cmi \ - asmcomp/arch.cmo \ - asmcomp/spacetime_profiling.cmi -asmcomp/spacetime_profiling.cmx : \ - asmcomp/selectgen.cmx \ - asmcomp/proc.cmx \ - utils/misc.cmx \ - asmcomp/mach.cmx \ - lambda/lambda.cmx \ - lambda/debuginfo.cmx \ - utils/config.cmx \ - asmcomp/cmm.cmx \ - middle_end/backend_var.cmx \ - parsing/asttypes.cmi \ - asmcomp/arch.cmx \ - asmcomp/spacetime_profiling.cmi -asmcomp/spacetime_profiling.cmi : \ - asmcomp/selectgen.cmi asmcomp/spill.cmo : \ asmcomp/reg.cmi \ asmcomp/proc.cmi \ @@ -3240,6 +3250,7 @@ lambda/lambda.cmo : \ typing/ident.cmi \ typing/env.cmi \ lambda/debuginfo.cmi \ + utils/clflags.cmi \ parsing/asttypes.cmi \ lambda/lambda.cmi lambda/lambda.cmx : \ @@ -3251,6 +3262,7 @@ lambda/lambda.cmx : \ typing/ident.cmx \ typing/env.cmx \ lambda/debuginfo.cmx \ + utils/clflags.cmx \ parsing/asttypes.cmi \ lambda/lambda.cmi lambda/lambda.cmi : \ @@ -3270,6 +3282,7 @@ lambda/matching.cmo : \ lambda/printlambda.cmi \ typing/primitive.cmi \ typing/predef.cmi \ + typing/patterns.cmi \ typing/parmatch.cmi \ utils/misc.cmi \ parsing/longident.cmi \ @@ -3291,6 +3304,7 @@ lambda/matching.cmx : \ lambda/printlambda.cmx \ typing/primitive.cmx \ typing/predef.cmx \ + typing/patterns.cmx \ typing/parmatch.cmx \ utils/misc.cmx \ parsing/longident.cmx \ @@ -3675,6 +3689,23 @@ file_formats/cmx_format.cmi : \ middle_end/clambda.cmi file_formats/cmxs_format.cmi : \ utils/misc.cmi +file_formats/linear_format.cmo : \ + utils/misc.cmi \ + parsing/location.cmi \ + asmcomp/linear.cmi \ + utils/config.cmi \ + asmcomp/cmm.cmi \ + file_formats/linear_format.cmi +file_formats/linear_format.cmx : \ + utils/misc.cmx \ + parsing/location.cmx \ + asmcomp/linear.cmx \ + utils/config.cmx \ + asmcomp/cmm.cmx \ + file_formats/linear_format.cmi +file_formats/linear_format.cmi : \ + asmcomp/linear.cmi \ + asmcomp/cmm.cmi middle_end/closure/closure.cmo : \ utils/warnings.cmi \ lambda/switch.cmi \ @@ -5709,7 +5740,8 @@ driver/compenv.cmx : \ utils/clflags.cmx \ utils/ccomp.cmx \ driver/compenv.cmi -driver/compenv.cmi : +driver/compenv.cmi : \ + utils/clflags.cmi driver/compile.cmo : \ lambda/translmod.cmi \ lambda/simplif.cmi \ @@ -5740,7 +5772,8 @@ driver/compile.cmi : \ typing/typedtree.cmi \ bytecomp/instruct.cmi \ typing/ident.cmi \ - driver/compile_common.cmi + driver/compile_common.cmi \ + utils/clflags.cmi driver/compile_common.cmo : \ utils/warnings.cmi \ typing/typemod.cmi \ @@ -5822,6 +5855,27 @@ driver/errors.cmx : \ driver/errors.cmi driver/errors.cmi : driver/main.cmo : \ + driver/maindriver.cmi +driver/main.cmx : \ + driver/maindriver.cmx +driver/main_args.cmo : \ + utils/warnings.cmi \ + utils/profile.cmi \ + utils/misc.cmi \ + utils/config.cmi \ + driver/compenv.cmi \ + utils/clflags.cmi \ + driver/main_args.cmi +driver/main_args.cmx : \ + utils/warnings.cmx \ + utils/profile.cmx \ + utils/misc.cmx \ + utils/config.cmx \ + driver/compenv.cmx \ + utils/clflags.cmx \ + driver/main_args.cmi +driver/main_args.cmi : +driver/maindriver.cmo : \ utils/warnings.cmi \ utils/profile.cmi \ driver/makedepend.cmi \ @@ -5835,8 +5889,8 @@ driver/main.cmo : \ bytecomp/bytepackager.cmi \ bytecomp/bytelink.cmi \ bytecomp/bytelibrarian.cmi \ - driver/main.cmi -driver/main.cmx : \ + driver/maindriver.cmi +driver/maindriver.cmx : \ utils/warnings.cmx \ utils/profile.cmx \ driver/makedepend.cmx \ @@ -5850,25 +5904,8 @@ driver/main.cmx : \ bytecomp/bytepackager.cmx \ bytecomp/bytelink.cmx \ bytecomp/bytelibrarian.cmx \ - driver/main.cmi -driver/main.cmi : -driver/main_args.cmo : \ - utils/warnings.cmi \ - utils/profile.cmi \ - utils/misc.cmi \ - utils/config.cmi \ - driver/compenv.cmi \ - utils/clflags.cmi \ - driver/main_args.cmi -driver/main_args.cmx : \ - utils/warnings.cmx \ - utils/profile.cmx \ - utils/misc.cmx \ - utils/config.cmx \ - driver/compenv.cmx \ - utils/clflags.cmx \ - driver/main_args.cmi -driver/main_args.cmi : + driver/maindriver.cmi +driver/maindriver.cmi : driver/makedepend.cmo : \ driver/pparse.cmi \ parsing/parsetree.cmi \ @@ -5929,6 +5966,7 @@ driver/optcompile.cmx : \ driver/optcompile.cmi : \ typing/typedtree.cmi \ driver/compile_common.cmi \ + utils/clflags.cmi \ middle_end/backend_intf.cmi driver/opterrors.cmo : \ parsing/location.cmi \ @@ -5938,6 +5976,10 @@ driver/opterrors.cmx : \ driver/opterrors.cmi driver/opterrors.cmi : driver/optmain.cmo : \ + driver/optmaindriver.cmi +driver/optmain.cmx : \ + driver/optmaindriver.cmx +driver/optmaindriver.cmo : \ utils/warnings.cmi \ utils/profile.cmi \ asmcomp/proc.cmi \ @@ -5956,8 +5998,8 @@ driver/optmain.cmo : \ asmcomp/asmlink.cmi \ asmcomp/asmlibrarian.cmi \ asmcomp/arch.cmo \ - driver/optmain.cmi -driver/optmain.cmx : \ + driver/optmaindriver.cmi +driver/optmaindriver.cmx : \ utils/warnings.cmx \ utils/profile.cmx \ asmcomp/proc.cmx \ @@ -5976,8 +6018,8 @@ driver/optmain.cmx : \ asmcomp/asmlink.cmx \ asmcomp/asmlibrarian.cmx \ asmcomp/arch.cmx \ - driver/optmain.cmi -driver/optmain.cmi : + driver/optmaindriver.cmi +driver/optmaindriver.cmi : driver/pparse.cmo : \ utils/warnings.cmi \ utils/profile.cmi \ @@ -6071,6 +6113,7 @@ toplevel/opttopdirs.cmo : \ typing/env.cmi \ typing/ctype.cmi \ utils/config.cmi \ + driver/compenv.cmi \ utils/clflags.cmi \ asmcomp/asmlink.cmi \ toplevel/opttopdirs.cmi @@ -6086,6 +6129,7 @@ toplevel/opttopdirs.cmx : \ typing/env.cmx \ typing/ctype.cmx \ utils/config.cmx \ + driver/compenv.cmx \ utils/clflags.cmx \ asmcomp/asmlink.cmx \ toplevel/opttopdirs.cmi @@ -6201,6 +6245,7 @@ toplevel/opttopmain.cmo : \ driver/main_args.cmi \ parsing/location.cmi \ driver/compmisc.cmi \ + driver/compenv.cmi \ utils/clflags.cmi \ toplevel/opttopmain.cmi toplevel/opttopmain.cmx : \ @@ -6210,6 +6255,7 @@ toplevel/opttopmain.cmx : \ driver/main_args.cmx \ parsing/location.cmx \ driver/compmisc.cmx \ + driver/compenv.cmx \ utils/clflags.cmx \ toplevel/opttopmain.cmi toplevel/opttopmain.cmi : @@ -6239,6 +6285,7 @@ toplevel/topdirs.cmo : \ bytecomp/dll.cmi \ typing/ctype.cmi \ utils/config.cmi \ + driver/compenv.cmi \ file_formats/cmo_format.cmi \ utils/clflags.cmi \ typing/btype.cmi \ @@ -6267,6 +6314,7 @@ toplevel/topdirs.cmx : \ bytecomp/dll.cmx \ typing/ctype.cmx \ utils/config.cmx \ + driver/compenv.cmx \ file_formats/cmo_format.cmi \ utils/clflags.cmx \ typing/btype.cmx \ diff --git a/.gitattributes b/.gitattributes index 200eb49c..5961fef2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -29,9 +29,9 @@ /boot/menhir/parser.ml* -diff -# configure is declared as binary so that it doesn't get included in diffs. -# This also means it will have the correct Unix line-endings, even on Windows. -/configure binary +# configure is a shell-script; the linguist-generated attribute suppresses +# changes being displayed by default in pull requests. +/configure text eol=lf -diff linguist-generated # 'union' merge driver just unions textual content in case of conflict # http://krlmlr.github.io/using-gitattributes-to-avoid-merge-conflicts/ @@ -51,19 +51,22 @@ tools/mantis2gh_stripped.csv typo.missing-header *.adoc typo.long-line=may +# Github templates and scripts lack headers, have long lines +/.github/** typo.missing-header typo.long-line=may typo.very-long-line=may + /.mailmap typo.long-line typo.missing-header typo.non-ascii /.merlin typo.missing-header /Changes typo.utf8 typo.missing-header -/News typo.utf8 typo.missing-header +/release-info/News typo.utf8 typo.missing-header /INSTALL typo.missing-header /LICENSE typo.very-long-line typo.missing-header # tools/ci/appveyor/appveyor_build.cmd only has missing-header because # dra27 too lazy to update check-typo to interpret Cmd-style comments! /tools/ci/appveyor/appveyor_build.cmd typo.very-long-line typo.missing-header typo.non-ascii /tools/ci/appveyor/appveyor_build.sh typo.non-ascii -/tools/ci/inria/remove-sinh-primitive.patch typo.white-at-eol typo.missing-header typo.long-line -/tools/release-checklist typo.missing-header typo.very-long-line - +/tools/ci/inria/bootstrap/remove-sinh-primitive.patch typo.prune +/release-info/howto.md typo.missing-header typo.long-line +/release-info/templates/*.md typo.missing-header typo.very-long-line=may # ignore auto-generated .depend files .depend typo.prune /.depend.menhir typo.prune @@ -106,6 +109,7 @@ testsuite/tests/lib-unix/win-stat/fakeclock.c typo.missing-header=fals testsuite/tests/misc-unsafe/almabench.ml typo.long-line testsuite/tests/tool-toplevel/strings.ml typo.utf8 testsuite/tests/win-unicode/*.ml typo.utf8 +testsuite/tests/asmgen/immediates.cmm typo.very-long-line testsuite/tools/*.S typo.missing-header testsuite/tools/*.asm typo.missing-header testsuite/typing typo.missing-header @@ -116,6 +120,10 @@ testsuite/tests/**/*.reference typo.prune # Expect tests with overly long lines of expected output testsuite/tests/parsing/docstrings.ml typo.very-long-line +# The normalisation tests have very specific line endings which mustn't be +# corrupted by git. +testsuite/tests/tool-ocamltest/norm*.reference binary + tools/magic typo.missing-header tools/eventlog_metadata.in typo.missing-header diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..72076946 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,28 @@ +--- +name: Bug report +about: Please submit bug reports here. +title: '' +labels: '' +assignees: '' + +--- + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..fb253417 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,10 @@ +blank_issues_enabled: false +contact_links: + - name: OCaml Discuss Forum + url: https://discuss.ocaml.org/ + about: This is the best place to start with questions about using OCaml. + - name: opam Package Repository + url: https://github.com/ocaml/opam-repository/issues + about: >- + Virtually all OCaml packages are available in the opam repository - please + report packaging issues there. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..48e6763c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,24 @@ +--- +name: Feature request +about: Suggest a new feature for OCaml. +title: '' +labels: 'feature-wish' +assignees: '' + +--- + diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..5dc0daeb --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,71 @@ +name: main + +on: [push, pull_request] + +jobs: + no-naked-pointers: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: configure tree + run: ./configure --disable-naked-pointers --disable-stdlib-manpages --disable-dependency-generation --enable-ocamltest + - name: Build + run: | + make -j world.opt + - name: Run the testsuite + run: | + make -C testsuite USE_RUNTIME=d all + i386-static: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Packages + run: | + sudo apt-get update -y && sudo apt-get install -y gcc-multilib gfortran-multilib + - name: configure tree + run: | + XARCH=i386 CONFIG_ARG='--disable-stdlib-manpages --disable-shared' bash -xe tools/ci/actions/runner.sh configure + - name: Build + run: | + bash -xe tools/ci/actions/runner.sh build + - name: Run the testsuite + run: | + bash -xe tools/ci/actions/runner.sh test + - name: Install + run: | + bash -xe tools/ci/actions/runner.sh install + - name: Other checks + run: | + bash -xe tools/ci/actions/runner.sh other-checks + full-flambda: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Packages + run: | + sudo apt-get update -y && sudo apt-get install -y texlive-latex-extra texlive-fonts-recommended + # Ensure that make distclean can be run from an empty tree + - name: distclean + run: | + MAKE_ARG=-j make distclean + - name: configure tree + run: | + MAKE_ARG=-j XARCH=x64 CONFIG_ARG='--enable-flambda --enable-dependency-generation' OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh configure + - name: Build + run: | + MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh build + - name: Run the testsuite + run: | + MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh test + - name: Build API Documentation + run: | + MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh api-docs + - name: Install + run: | + MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh install + - name: Other checks + run: | + MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh other-checks diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..27d63bfd --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,15 @@ +name: "Close stale issues" +on: + schedule: + - cron: "15 4 * * 1,3,5" + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.' + days-before-stale: 366 + days-before-close: 30 diff --git a/.gitignore b/.gitignore index ff94e3c7..466edf57 100644 --- a/.gitignore +++ b/.gitignore @@ -40,7 +40,7 @@ _build # local to root directory -/Makefile.common +/Makefile.build_config /Makefile.config /autom4te.cache /ocamlc @@ -114,14 +114,17 @@ _build /ocamldoc/test_latex /ocamldoc/test +/ocamltest/.dep /ocamltest/ocamltest /ocamltest/ocamltest.opt /ocamltest/ocamltest_config.ml +/ocamltest/ocamltest_unix.ml /ocamltest/tsl_lexer.ml /ocamltest/tsl_parser.ml /ocamltest/tsl_parser.mli /ocamltest/ocamltest.html +/otherlibs/*/.dep /otherlibs/dynlink/extract_crc /otherlibs/dynlink/dynlink_platform_intf.mli /otherlibs/dynlink/byte/dynlink.mli @@ -161,6 +164,7 @@ _build /otherlibs/win32unix/time.c /otherlibs/win32unix/unlink.c /otherlibs/win32unix/fsync.c +/otherlibs/win32unix/mkdir.c /parsing/parser.ml /parsing/parser.mli @@ -186,11 +190,8 @@ _build /runtime/ocamlrund /runtime/ocamlruni /runtime/ld.conf -/runtime/interp.a.lst -/runtime/*.[sd]obj /runtime/.gdb_history -/runtime/*.d.c -/runtime/*.pic.c +/runtime/.dep /runtime/domain_state32.inc /runtime/domain_state64.inc @@ -223,7 +224,6 @@ _build /tools/ocamldep /tools/ocamldep.opt -/tools/ocamldep.bak /tools/ocamlprof /tools/ocamlprof.opt /tools/opnames.ml @@ -234,7 +234,6 @@ _build /tools/ocamlobjinfo.opt /tools/cvt_emit /tools/cvt_emit.opt -/tools/cvt_emit.bak /tools/cvt_emit.ml /tools/ocamlcp /tools/ocamlcp.opt @@ -249,9 +248,8 @@ _build /tools/ocamlmklib /tools/ocamlmklib.opt /tools/ocamlmklibconfig.ml -/tools/objinfo_helper -/tools/read_cmt -/tools/read_cmt.opt +/tools/ocamlcmt +/tools/ocamlcmt.opt /tools/cmpbyt /tools/cmpbyt.opt /tools/stripdebug diff --git a/.mailmap b/.mailmap index d83748cc..8eec8afa 100644 --- a/.mailmap +++ b/.mailmap @@ -120,6 +120,7 @@ Christoph Spiel Joris Giovannangeli Wilfred Hughes John Skaller +Eduardo Rafael # These contributors prefer to be referred to pseudonymously whitequark diff --git a/.travis.yml b/.travis.yml index 48bbfb99..a2373e87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,42 +13,17 @@ #* * #************************************************************************** -dist: xenial +dist: bionic language: c git: submodules: false script: tools/ci/travis/travis-ci.sh matrix: include: - - env: CI_KIND=build XARCH=x64 CONFIG_ARG=--enable-flambda OCAMLRUNPARAM=b,v=0 - - env: CI_KIND=build XARCH=i386 CONFIG_ARG=--disable-stdlib-manpages - addons: - apt: - packages: - - gcc:i386 - - cpp:i386 - - binutils:i386 - - binutils-dev:i386 - - libx11-dev:i386 - - libc6-dev:i386 - - env: CI_KIND=build XARCH=x64 - addons: - apt: - packages: - - texlive-latex-extra - - texlive-fonts-recommended - - env: CI_KIND=build XARCH=x64 CONFIG_ARG=--disable-shared - - env: CI_KIND=build XARCH=x64 MIN_BUILD=1 + - env: CI_KIND=check-depend - env: CI_KIND=changes - env: CI_KIND=manual - env: CI_KIND=check-typo -# - env: CI_KIND=tests -# allow_failures: -# - env: CI_KIND=tests -addons: - apt: - packages: - - binutils-dev notifications: email: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ae670072..22e630b9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -224,16 +224,20 @@ better than adding redundant explanations.) ### User documentation Changes affecting the compiler libraries should be reflected in the -documentation comments of the relevant `.mli` files. +documentation comments of the relevant `.mli` files. After running +`make html_doc`, you can find the HTML Standard Library documentation +at `./api_docgen/html/libref/index.html`. -It is recommended to included changes to the OCaml Reference Manual +It is recommended to include changes to the OCaml Reference Manual (in particular for any change in the surface language), which is now -part of the main repository (under `manual/`). +part of the main repository (under `manual/`). To build the full manual, +see the instructions in `manual/README.md`. Finally, changes in command-line options should be integrated in the manual, but also in the man pages present in the `man/` sub-directory of the OCaml distribution. + ### Changelog Any user-visible change should have a `Changes` entry: diff --git a/Changes b/Changes index 880c0125..680451b6 100644 --- a/Changes +++ b/Changes @@ -1,42 +1,710 @@ -OCaml 4.11 maintenance branch ------------------------------ +OCaml 4.12.0 (24 February 2021) +------------------------------- +### Supported platforms (highlights): -OCaml 4.11.2 (24 February 2021) -------------------------------- +- #9699: add support for iOS and macOS on ARM 64 bits + (Eduardo Rafael, review by Xavier Leroy, Nicolás Ojeda Bär + and Anil Madhavapeddy, additional testing by Michael Schmidt) -### Build system: +### Standard library (highlights): -- #9938, #9939: Define __USE_MINGW_ANSI_STDIO=0 for the mingw-w64 ports to - prevent their C99-compliant snprintf conflicting with ours. - (David Allsopp, report by Michael Soegtrop, review by Xavier Leroy) +- #9797: Add Sys.mkdir and Sys.rmdir. + (David Allsopp, review by Nicolás Ojeda Bär, Sébastien Hinderer and + Xavier Leroy) + +* #9765: add init functions to Bigarray. + (Jeremy Yallop, review by Gabriel Scherer, Nicolás Ojeda Bär, and + Xavier Leroy) + +* #9668: List.equal, List.compare + (This could break code using "open List" by shadowing + Stdlib.{equal,compare}.) + (Gabriel Scherer, review by Nicolás Ojeda Bär, Daniel Bünzli and Alain Frisch) + +- #9066: a new Either module with + type 'a Either.t = Left of 'a | Right of 'b + (Gabriel Scherer, review by Daniel Bünzli, Thomas Refis, Jeremy Yallop) + +- #9066: List.partition_map : + ('a -> ('b, 'c) Either.t) -> 'a list -> 'b list * 'c list + (Gabriel Scherer, review by Jeremy Yallop) + +- #9865: add Format.pp_print_seq + (Raphaël Proust, review by Nicolás Ojeda Bär) + +### Compiler user-interface and warnings (highlights): + +- #9657: Warnings can now be referred to by their mnemonic name. The names are + displayed using `-warn-help` and can be utilized anywhere where a warning list + specification is expected. + ocamlc -w +fragile-match + ...[@@ocaml.warning "-fragile-match"] + Note that only a single warning name at a time is supported for now: + "-w +foo-bar" does not work, you must use "-w +foo -w -bar". + (Nicolás Ojeda Bär, review by Gabriel Scherer, Florian Angeletti and + Leo White) + +- #8939: Command-line option to save Linear IR before emit. + (Greta Yorsh, review by Mark Shinwell, Sébastien Hinderer and Frédéric Bour) + +- #9003: Start compilation from Emit when the input file is in Linear IR format. + (Greta Yorsh, review by Jérémie Dimino, Gabriel Scherer and Frédéric Bour) + +### Language features (highlights): + +* #9500, #9727, #9866, #9870, #9873: Injectivity annotations + One can now mark type parameters as injective, which is useful for + abstract types: + module Vec : sig type !'a t end = struct type 'a t = 'a array end + On non-abstract types, this can be used to check the injectivity of + parameters. Since all parameters of record and sum types are by definition + injective, this only makes sense for type abbreviations: + type !'a t = 'a list + Note that this change required making the regularity check stricter. + (Jacques Garrigue, review by Jeremy Yallop and Leo White) + +### Runtime system (highlights): + +- #9534, #9947: Introduce a naked pointers checker mode to the runtime + (configure option --enable-naked-pointers-checker). Alarms are printed + when the garbage collector finds out-of-heap pointers that could + cause a crash in no-naked-pointers mode. + (Enguerrand Decorne, KC Sivaramakrishnan, Xavier Leroy, Stephen Dolan, + David Allsopp, Nicolás Ojeda Bär review by Xavier Leroy, Nicolás Ojeda Bär) + +* #1128, #7503, #9036, #9722, #10069: EINTR-based signal handling. + When a signal arrives, avoid running its OCaml handler in the middle + of a blocking section. Instead, allow control to return quickly to + a polling point where the signal handler can safely run, ensuring that + I/O locks are not held while it runs. A polling point was removed from + caml_leave_blocking_section, and one added to caml_raise. + (Stephen Dolan, review by Goswin von Brederlow, Xavier Leroy, Damien + Doligez, Anil Madhavapeddy, Guillaume Munch-Maccagnoni and Jacques- + Henri Jourdan) + +* #5154, #9569, #9734: Add `Val_none`, `Some_val`, `Is_none`, `Is_some`, + `caml_alloc_some`, and `Tag_some`. As these macros are sometimes defined by + authors of C bindings, this change may cause warnings/errors in case of + redefinition. + (Nicolás Ojeda Bär, review by Stephen Dolan, Gabriel Scherer, Mark Shinwell, + and Xavier Leroy) + +* #9674: Memprof: guarantee that an allocation callback is always run + in the same thread the allocation takes place + (Jacques-Henri Jourdan, review by Stephen Dolan) + +- #10025: Track custom blocks (e.g. Bigarray) with Memprof + (Stephen Dolan, review by Leo White, Gabriel Scherer and Jacques-Henri + Jourdan) + +- #9619: Change representation of function closures so that code pointers + can be easily distinguished from environment variables + (Xavier Leroy, review by Mark Shinwell and Damien Doligez) + +- #9654: More efficient management of code fragments. + (Xavier Leroy, review by Jacques-Henri Jourdan, Damien Doligez, and + Stephen Dolan) + +### Other libraries (highlights): + +- #9573: reimplement Unix.create_process and related functions without + Unix.fork, for better efficiency and compatibility with threads. + (Xavier Leroy, review by Gabriel Scherer and Anil Madhavapeddy) + +- #9575: Add Unix.is_inet6_addr + (Nicolás Ojeda Bär, review by Xavier Leroy) + +- #9930: new module Semaphore in the thread library, implementing + counting semaphores and binary semaphores + (Xavier Leroy, review by Daniel Bünzli and Damien Doligez, + additional suggestions by Stephen Dolan and Craig Ferguson) + +* #9206, #9419: update documentation of the threads library; + deprecate Thread.kill, Thread.wait_read, Thread.wait_write, + and the whole ThreadUnix module. + (Xavier Leroy, review by Florian Angeletti, Guillaume Munch-Maccagnoni, + and Gabriel Scherer) + +### Manual and documentation (highlights): + +- #9755: Manual: post-processing the html generated by ocamldoc and + hevea. Improvements on design and navigation, including a mobile + version, and a quick-search functionality for the API. + (San Vũ Ngọc, review by David Allsopp and Florian Angeletti) + +- #9468: HACKING.adoc: using dune to get merlin support + (Thomas Refis, review by Gabriel Scherer) + +- #9684: document in address_class.h the runtime value model in + naked-pointers and no-naked-pointers mode + (Xavier Leroy and Gabriel Scherer) + +### Internal/compiler-libs changes (highlights): + +- #9464, #9493, #9520, #9563, #9599, #9608, #9647: refactor + the pattern-matching compiler + (Thomas Refis and Gabriel Scherer, review by Florian Angeletti) + +- #9696: ocamltest now shows its log when a test fails. In addition, the log + contains the output of executed programs. + (Nicolás Ojeda Bär, review by David Allsopp, Sébastien Hinderer and Gabriel + Scherer) + +### Build system (highlights): + +- #9824, #9837: Honour the CFLAGS and CPPFLAGS variables. + (Sébastien Hinderer, review by David Allsopp) + +- #10063: (Re-)enable building on illumos (SmartOS, OmniOS, ...) and + Oracle Solaris; x86_64/GCC and 64-bit SPARC/Sun PRO C compilers. + (partially revert #2024). + (Tõivo Leedjärv and Konstantin Romanov, + review by Gabriel Scherer, Sébastien Hinderer and Xavier Leroy) + + +### Language features: + +- #1655: pattern aliases do not ignore type constraints + (Thomas Refis, review by Jacques Garrigue and Gabriel Scherer) + +- #9429: Add unary operators containing `#` to the parser for use in ppx + rewriters + (Leo White, review by Damien Doligez) ### Runtime system: +* #9697: Remove the Is_in_code_area macro and the registration of DLL code + areas in the page table, subsumed by the new code fragment management API + (Xavier Leroy, review by Jacques-Henri Jourdan) + +- #9756: garbage collector colors change + removes the gray color from the major gc + (Sadiq Jaffer and Stephen Dolan reviewed by Xavier Leroy, + KC Sivaramakrishnan, Damien Doligez and Jacques-Henri Jourdan) + +* #9513: Selectively initialise blocks in `Obj.new_block`. Reject `Custom_tag` + objects and zero-length `String_tag` objects. + (KC Sivaramakrishnan, review by David Allsopp, Xavier Leroy, Mark Shinwell + and Leo White) + +- #9564: Add a macro to construct out-of-heap block header. + (KC Sivaramakrishnan, review by Stephen Dolan, Gabriel Scherer, + and Xavier Leroy) + +- #9951: Ensure that the mark stack push optimisation handles naked pointers + (KC Sivaramakrishnan, reported by Enguerrand Decorne, review by Gabriel + Scherer, and Xavier Leroy) + +- #9678: Reimplement `Obj.reachable_words` using a hash table to + detect sharing, instead of temporary in-place modifications. This + is a prerequisite for Multicore OCaml. + (Xavier Leroy, review by Jacques-Henri Jourdan and Sébastien Hinderer) + +- #1795, #9543: modernize signal handling on Linux i386, PowerPC, and s390x, + adding support for Musl ppc64le along the way. + (Xavier Leroy and Anil Madhavapeddy, review by Stephen Dolan) + +- #9648, #9689: Update the generic hash function to take advantage + of the new representation for function closures + (Xavier Leroy, review by Stephen Dolan) + +- #9649: Update the marshaler (output_value) to take advantage + of the new representation for function closures + (Xavier Leroy, review by Damien Doligez) + +- #10050: update {PUSH,}OFFSETCLOSURE* bytecode instructions to match new + representation for closures + (Nathanaël Courant, review by Xavier Leroy) + +- #9728: Take advantage of the new closure representation to simplify the + compaction algorithm and remove its dependence on the page table + (Damien Doligez, review by Jacques-Henri Jourdan and Xavier Leroy) + +- #2195: Improve error message in bytecode stack trace printing and load + debug information during bytecode startup if OCAMLRUNPARAM=b=2. + (David Allsopp, review by Gabriel Scherer and Xavier Leroy) + +- #9466: Memprof: optimize random samples generation. + (Jacques-Henri Jourdan, review by Xavier Leroy and Stephen Dolan) + +- #9628: Memprof: disable sampling when memprof is suspended. + (Jacques-Henri Jourdan, review by Gabriel Scherer and Stephen Dolan) + - #10056: Memprof: ensure young_trigger is within the bounds of the minor heap in caml_memprof_renew_minor_sample (regression from #8684) (David Allsopp, review by Guillaume Munch-Maccagnoni and Jacques-Henri Jourdan) -- #9654: More efficient management of code fragments. - (Xavier Leroy, review by Jacques-Henri Jourdan, Damien Doligez, and - Stephen Dolan) +- #9508: Remove support for FreeBSD prior to 4.0R, that required explicit + floating-point initialization to behave like IEEE standard + (Hannes Mehnert, review by David Allsopp) -### Tools: +- #8807, #9503: Use different symbols for do_local_roots on bytecode and native + (Stephen Dolan, review by David Allsopp and Xavier Leroy) -- #9606, #9635, #9637: fix performance regression in the debugger - (behaviors quadratic in the size of the debugged program) - (Xavier Leroy, report by Jacques Garrigue and Virgile Prevosto, - review by David Allsopp and Jacques-Henri Jourdan) +- #9670: Report full major collections in Gc stats. + (Leo White, review by Gabriel Scherer) + +- #9675: Remove the caml_static_{alloc,free,resize} primitives, now unused. + (Xavier Leroy, review by Gabriel Scherer) + +- #9710: Drop "support" for an hypothetical JIT for OCaml bytecode + which has never existed. + (Jacques-Henri Jourdan, review by Xavier Leroy) + +- #9742, #9989: Ephemerons are now compatible with infix pointers occurring + when using mutually recursive functions. + (Jacques-Henri Jourdan, review by François Bobot) + +- #9888, #9890: Fixes a bug in the `riscv` backend where register t0 was not + saved/restored when performing a GC. This could potentially lead to a + segfault. + (Nicolás Ojeda Bär, report by Xavier Leroy, review by Xavier Leroy) + +- #9907: Fix native toplevel on native Windows. + (David Allsopp, review by Florian Angeletti) + +- #9909: Remove caml_code_area_start and caml_code_area_end globals (no longer + needed as the pagetable heads towards retirement). + (David Allsopp, review by Xavier Leroy) + +- #9949: Clarify documentation of GC message 0x1 and make sure it is + displayed every time a major cycle is forcibly finished. + (Damien Doligez, review by Xavier Leroy) + +- #10062: set ARCH_INT64_PRINTF_FORMAT correctly for both modes of mingw-w64 + (David Allsopp, review by Xavier Leroy) ### Code generation and optimizations: +- #9551: ocamlc no longer loads DLLs at link time to check that + external functions referenced from OCaml code are defined. + Instead, .so/.dll files are parsed directly by pure OCaml code. + (Nicolás Ojeda Bär, review by Daniel Bünzli, Gabriel Scherer, + Anil Madhavapeddy, and Xavier Leroy) + +- #9620: Limit the number of parameters for an uncurried or untupled + function. Functions with more parameters than that are left + partially curried or tupled. + (Xavier Leroy, review by Mark Shinwell) + +- #9752: Revised handling of calling conventions for external C functions. + Provide a more precise description of the types of unboxed arguments, + so that the ARM64 iOS/macOS calling conventions can be honored. + (Xavier Leroy, review by Mark Shinwell and Eduardo Rafael) + +- #9838: Ensure that Cmm immediates are generated as Cconst_int where + possible, improving instruction selection. + (Stephen Dolan, review by Leo White and Xavier Leroy) + +- #9864: Revised recognition of immediate arguments to integer operations. + Fixes several issues that could have led to producing assembly code + that is rejected by the assembler. + (Xavier Leroy, review by Stephen Dolan) + - #9969, #9981: Added mergeable flag to ELF sections containing mergeable constants. Fixes compatibility with the integrated assembler in clang 11.0.0. (Jacob Young, review by Nicolás Ojeda Bär) +### Standard library: + +- #9781: add injectivity annotations to parameterized abstract types + (Jeremy Yallop, review by Nicolás Ojeda Bär) + +* #9554: add primitive __FUNCTION__ that returns the name of the current method + or function, including any enclosing module or class. + (Nicolás Ojeda Bär, Stephen Dolan, review by Stephen Dolan) + +- #9075: define to_rev_seq in Set and Map modules. + (Sébastien Briais, review by Gabriel Scherer and Nicolás Ojeda Bär) + +- #9561: Unbox Unix.gettimeofday and Unix.time + (Stephen Dolan, review by David Allsopp) + +- #9570: Provide an Atomic module with a trivial purely-sequential + implementation, to help write code that is compatible with Multicore + OCaml. + (Gabriel Scherer, review by Xavier Leroy) + +- #10035: Make sure that flambda respects atomicity in the Atomic module. + (Guillaume Munch-Maccagnoni, review by Gabriel Scherer) + +- #9571: Make at_exit and Printexc.register_printer thread-safe. + (Guillaume Munch-Maccagnoni, review by Gabriel Scherer and Xavier Leroy) + +- #9587: Arg: new Rest_all spec to get all rest arguments in a list + (this is similar to Rest, but makes it possible to detect when there + are no arguments (an empty list) after the rest marker) + (Gabriel Scherer, review by Nicolás Ojeda Bär and David Allsopp) + +- #9655: Obj: introduce type raw_data and functions raw_field, set_raw_field + to manipulate out-of-heap pointers in no-naked-pointer mode, + and more generally all other data that is not a well-formed OCaml value + (Xavier Leroy, review by Damien Doligez and Gabriel Scherer) + +- #9663: Extend Printexc API for raw backtrace entries. + (Stephen Dolan, review by Nicolás Ojeda Bär and Gabriel Scherer) + +- #9763: Add function Hashtbl.rebuild to convert from old hash table + formats (that may have been saved to persistent storage) to the + current hash table format. Remove leftover support for the hash + table format and generic hash function that were in use before OCaml 4.00. + (Xavier Leroy, review by Nicolás Ojeda Bär) + +- #10070: Fix Float.Array.blit when source and destination arrays coincide. + (Nicolás Ojeda Bär, review by Alain Frisch and Xavier Leroy) + +### Other libraries: + +- #8796: On Windows, make Unix.utimes use FILE_FLAG_BACKUP_SEMANTICS flag + to allow it to work with directories. + (Daniil Baturin, review by Damien Doligez) + +- #9593: Use new flag for non-elevated symbolic links and test for Developer + Mode on Windows + (Manuel Hornung, review by David Allsopp and Nicolás Ojeda Bär) + +* #9601: Return EPERM for EUNKNOWN -1314 in win32unix (principally affects + error handling when Unix.symlink is unavailable) + (David Allsopp, review by Xavier Leroy) + +- #9338, #9790: Dynlink: make sure *_units () functions report accurate + information before the first load. + (Daniel Bünzli, review by Xavier Leroy and Nicolás Ojeda Bär) + +* #9757, #9846, #10161: check proper ownership when operating over mutexes. + Now, unlocking a mutex held by another thread or not locked at all + reliably raises a Sys_error exception. Before, it was undefined + behavior, but the documentation did not say so. + Likewise, locking a mutex already locked by the current thread + reliably raises a Sys_error exception. Before, it could + deadlock or succeed (and do recursive locking), depending on the OS. + (Xavier Leroy, report by Guillaume Munch-Maccagnoni, review by + Guillaume Munch-Maccagnoni, David Allsopp, and Stephen Dolan) + +- #9802: Ensure signals are handled before Unix.kill returns + (Stephen Dolan, review by Jacques-Henri Jourdan) + +- #9869, #10073: Add Unix.SO_REUSEPORT + (Yishuai Li, review by Xavier Leroy, amended by David Allsopp) + +- #9906, #9914: Add Unix._exit as a way to exit the process immediately, + skipping any finalization action + (Ivan Gotovchits and Xavier Leroy, review by Sébastien Hinderer and + David Allsopp) + +- #9958: Raise exception in case of error in Unix.setsid. + (Nicolás Ojeda Bär, review by Stephen Dolan) + +- #9971, #9973: Make sure the process can terminate when the last thread + calls Thread.exit. + (Xavier Leroy, report by Jacques-Henri Jourdan, review by David Allsopp + and Jacques-Henri Jourdan). + +### Tools: + +- #9551: ocamlobjinfo is now able to display information on .cmxs shared + libraries natively; it no longer requires libbfd to do so + (Nicolás Ojeda Bär, review by Daniel Bünzli, Gabriel Scherer, + Anil Madhavapeddy, and Xavier Leroy) + +* #9299, #9795: ocamldep: do not process files during cli parsing. Fixes + various broken cli behaviours. + (Daniel Bünzli, review by Nicolás Ojeda Bär) + +### Debugging and profiling: + +- #9606, #9635, #9637: fix 4.10 performance regression in the debugger + (behaviors quadratic in the size of the debugged program) + (Xavier Leroy, report by Jacques Garrigue and Virgile Prevosto, + review by David Allsopp and Jacques-Henri Jourdan) + +- #9948: Remove Spacetime. + (Nicolás Ojeda Bär, review by Stephen Dolan and Xavier Leroy) + +### Manual and documentation: + +- #10142, #10154: improved rendering and latex code for toplevel code examples. + (Florian Angeletti, report by John Whitington, review by Gabriel Scherer) + +- #9745: Manual: Standard Library labeled and unlabeled documentation unified + (John Whitington, review by Nicolás Ojeda Bär, David Allsopp, + Thomas Refis, and Florian Angeletti) + +- #9877: manual, warn that multi-index indexing operators should be defined in + conjunction of single-index ones. + (Florian Angeletti, review by Hezekiah M. Carty, Gabriel Scherer, + and Marcello Seri) + +- #10233: Document `-save-ir-after scheduling` and update `-stop-after` options. + (Greta Yorsh, review by Gabriel Scherer and Florian Angeletti) + +### Compiler user-interface and warnings: + +- #1931: rely on levels to enforce principality in patterns + (Thomas Refis and Leo White, review by Jacques Garrigue) + +* #9011: Do not create .a/.lib files when creating a .cmxa with no modules. + macOS ar doesn't support creating empty .a files (#1094) and MSVC doesn't + permit .lib files to contain no objects. When linking with a .cmxa containing + no modules, it is now not an error for there to be no .a/.lib file. + (David Allsopp, review by Xavier Leroy) + +- #9560: Report partial application warnings on type errors in applications. + (Stephen Dolan, report and testcase by whitequark, review by Gabriel Scherer + and Thomas Refis) + +- #9583: when bytecode linking fails due to an unavailable module, the module + that requires it is now included in the error message. + (Nicolás Ojeda Bär, review by Vincent Laviron) + +- #9615: Attach package type attributes to core_type. + When parsing constraints on a first class module, attributes found after the + module type were parsed but ignored. Now they are attached to the + corresponding core_type. + (Etienne Millon, review by Thomas Refis) + +- #6633, #9673: Add hint when a module is used instead of a module type or + when a module type is used instead of a module or when a class type is used + instead of a class. + (Xavier Van de Woestyne, report by whitequark, review by Florian Angeletti + and Gabriel Scherer) + +- #9754: allow [@tailcall true] (equivalent to [@tailcall]) and + [@tailcall false] (warns if on a tailcall) + (Gabriel Scherer, review by Nicolás Ojeda Bär) + +- #9751: Add warning 68. Pattern-matching depending on mutable state + prevents the remaining arguments from being uncurried. + (Hugo Heuzard, review by Leo White) + +- #9783: Widen warning 16 (Unerasable optional argument) to more cases. + (Leo White, review by Florian Angeletti) + +- #10008: Improve error message for aliases to the current compilation unit. + (Leo White, review by Gabriel Scherer) + +- #10046: Link all DLLs with -static-libgcc on mingw32 to prevent dependency + on libgcc_s_sjlj-1.dll with mingw-w64 runtime 8.0.0 (previously this was + only needed for dllunix.dll). + (David Allsopp, report by Andreas Hauptmann, review by Xavier Leroy) + +- #9634: Allow initial and repeated commas in `OCAMLRUNPARAM`. + (Nicolás Ojeda Bär, review by Gabriel Scherer) + +### Internal/compiler-libs changes: + +- #8987: Make some locations more accurate + (Thomas Refis, review by Gabriel Scherer) + +- #9216: add Lambda.duplicate which refreshes bound identifiers + (Gabriel Scherer, review by Pierre Chambart and Vincent Laviron) + +- #9376: Remove spurious Ptop_defs from #use + (Leo White, review by Damien Doligez) + +- #9604: refactoring of the ocamltest codebase. + (Nicolás Ojeda Bär, review by Gabriel Scherer and Sébastien Hinderer) + +- #9498, #9511: make the pattern-matching analyzer more robust to + or-pattern explosion, by stopping after the first counter-example to + exhaustivity + (Gabriel Scherer, review by Luc Maranget, Thomas Refis and Florian Angeletti, + report by Alex Fedoseev through Hongbo Zhang) + +- #9514: optimize pattern-matching exhaustivity analysis in the single-row case + (Gabriel Scherer, review by Stephen DOlan) + +- #9442: refactor the implementation of the [@tailcall] attribute + to allow for a structured attribute payload + (Gabriel Scherer, review by Vladimir Keleshev and Nicolás Ojeda Bär) + +- #9688: Expose the main entrypoint in compilerlibs + (Stephen Dolan, review by Nicolás Ojeda Bär, Greta Yorsh and David Allsopp) + +- #9715: recheck scope escapes after normalising paths + (Matthew Ryan, review by Gabriel Scherer and Thomas Refis) + +- #9778: Fix printing for bindings where polymorphic type annotations and + attributes are present. + (Matthew Ryan, review by Nicolás Ojeda Bär) + +- #9797, #9849: Eliminate the routine use of external commands in ocamltest. + ocamltest no longer calls the mkdir, rm and ln external commands (at present, + the only external command ocamltest uses is diff). + (David Allsopp, review by Nicolás Ojeda Bär, Sébastien Hinderer and + Xavier Leroy) + +- #9801: Don't ignore EOL-at-EOF differences in ocamltest. + (David Allsopp, review by Damien Doligez, much input and thought from + Daniel Bünzli, Damien Doligez, Sébastien Hinderer, and Xavier Leroy) + +- #9889: more caching when printing types with -short-path. + (Florian Angeletti, review by Gabriel Scherer) + +- #9591: fix pprint of polyvariants that start with a core_type, closed, + not low (Chet Murthy, review by Florian Angeletti) + +- #9590: fix pprint of extension constructors (and exceptions) that rebind + (Chet Murthy, review by octachron@) + +- #9963: Centralized tracking of frontend's global state + (Frédéric Bour and Thomas Refis, review by Gabriel Scherer) + +- #9631: Named text sections for caml_system__code_begin/end symbols + (Greta Yorsh, review by Frédéric Bour) + +- #9896: Share the strings representing scopes, fixing some regression + on .cmo/.cma sizes + (Alain Frisch and Xavier Clerc, review by Gabriel Scherer) + +### Build system: + +- #9332, #9518, #9529: Cease storing C dependencies in the codebase. C + dependencies are generated on-the-fly in development mode. For incremental + compilation, the MSVC ports require GCC to be present. + (David Allsopp, review by Sébastien Hinderer, YAML-fu by Stephen Dolan) + +- #7121, #9558: Always have the autoconf-discovered ld in PACKLD, with + extra flags in new variable PACKLD_FLAGS. For + cross-compilation, this means the triplet-prefixed version will always be + used. + (David Allsopp, report by Adrian Nader, review by Sébastien Hinderer) + +- #9527: stop including configuration when running 'clean' rules + to avoid C dependency recomputation. + (Gabriel Scherer, review by David Allsopp) + +- #9804: Build C stubs of libraries in otherlibs/ with debug info. + (Stephen Dolan, review by Sébastien Hinderer and David Allsopp) + +- #9938, #9939: Define __USE_MINGW_ANSI_STDIO=0 for the mingw-w64 ports to + prevent their C99-compliant snprintf conflicting with ours. + (David Allsopp, report by Michael Soegtrop, review by Xavier Leroy) + +- #9895, #9523: Avoid conflict with C++20 by not installing VERSION to the OCaml + Standard Library directory. + (Bernhard Schommer, review by David Allsopp) + +- #10044: Always report the detected ARCH, MODEL and SYSTEM, even for bytecode- + only builds (fixes a "configuration regression" from 4.08 for the Windows + builds) + (David Allsopp, review by Xavier Leroy) + +- #10071: Fix bug in tests/misc/weaklifetime.ml that was reported in #10055 + (Damien Doligez and Gabriel Scherer, report by David Allsopp) + ### Bug fixes: +- #7538, #9669: Check for misplaced attributes on module aliases + (Leo White, report by Thomas Leonard, review by Florian Angeletti) + +- #7813, #9955: make sure the major GC cycle doesn't get stuck in Idle state + (Damien Doligez, report by Anders Fugmann, review by Jacques-Henri Jourdan) + +- #7902, #9556: Type-checker infers recursive type, even though -rectypes is + off. + (Jacques Garrigue, report by Francois Pottier, review by Leo White) + +- #8746: Hashtbl: Restore ongoing traversal status after filter_map_inplace + (Mehdi Bouaziz, review by Alain Frisch) + +- #8747, #9709: incorrect principality warning on functional updates of records + (Jacques Garrigue, report and review by Thomas Refis) + +* #8907, #9878: `Typemod.normalize_signature` uses wrong environment + (Jacques Garrigue, report and review by Leo White) + +- #9421, #9427: fix printing of (::) in ocamldoc + (Florian Angeletti, report by Yawar Amin, review by Damien Doligez) + +- #9440: for a type extension constructor with parameterised arguments, + REPL displayed for each as opposed to the concrete values used. + (Christian Quinn, review by Gabriel Scherer) + +- #9433: Fix package constraints for module aliases + (Leo White, review by Jacques Garrigue) + +- #9469: Better backtraces for lazy values + (Leo White, review by Nicolás Ojeda Bär) + +- #9521, #9522: correctly fail when comparing functions + with Closure and Infix tags. + (Gabriel Scherer and Jeremy Yallop and Xavier Leroy, + report by Twitter user @st_toHKR through Jun Furuse) + +- #9611: maintain order of load path entries in various situations: when passing + them to system linker, ppx contexts, etc. + (Nicolás Ojeda Bär, review by Jérémie Dimino and Gabriel Scherer) + +- #9633: ocamltest: fix a bug when certain variables set in test scripts would + be ignored (eg `ocamlrunparam`). + (Nicolás Ojeda Bär, review by Sébastien Hinderer) + +- #9681, #9690, #9693: small runtime changes + for the new closure representation (#9619) + (Xavier Leroy, Sadiq Jaffer, Gabriel Scherer, + review by Xavier Leroy and Jacques-Henri Jourdan) + +- #9739, #9747: Avoid calling type variables, types that are not variables in + recursive occurrence error messages + (for instance, "Type variable int occurs inside int list") + (Florian Angeletti, report by Stephen Dolan, review by Armaël Guéneau) + +- #9759, #9767: Spurious GADT ambiguity without -principal + (Jacques Garrigue, report by Thomas Refis, + review by Thomas Refis and Gabriel Scherer) + +- #9799, #9803: make pat_env point to the correct environment + (Thomas Refis, report by Alex Fedoseev, review by Gabriel Scherer) + +- #9825, #9830: the C global variable caml_fl_merge and the C function + caml_spacetime_my_profinfo (bytecode version) were declared and + defined with different types. This is undefined behavior and + cancause link-time errors with link-time optimization (LTO). + (Xavier Leroy, report by Richard Jones, review by Nicolás Ojeda Bär) + +- #9753: fix build for Android + (Eduardo Rafael, review by Xavier Leroy) + +- #9848, #9855: Fix double free of bytecode in toplevel + (Stephen Dolan, report by Sampsa Kiiskinen, review by Gabriel Scherer) + +- #9858, #9861: Compiler fails with Ctype.Nondep_cannot_erase exception + (Thomas Refis, report by Philippe Veber, review by Florian Angeletti) + +- #9860: wrong range constraint for subtract immediate on zSystems / s390x + (Xavier Leroy, review by Stephen Dolan) + +- #9868, #9872, #9892: bugs in {in,out}_channel_length and seek_in + for files opened in text mode under Windows + (Xavier Leroy, report by Alain Frisch, review by Nicolás Ojeda Bär + and Alain Frisch) + +- #9925: Correct passing -fdebug-prefix-map to flexlink on Cygwin by prefixing + it with -link. + (David Allsopp, review by Xavier Leroy) + +- #9927: Restore Cygwin64 support. + (David Allsopp, review by Xavier Leroy) + +- #9940: Fix unboxing of allocated constants from other compilation units + (Vincent Laviron, report by Stephen Dolan, review by Xavier Leroy and + Stephen Dolan) + +- #9991: Fix reproducibility for `-no-alias-deps` + (Leo White, review by Gabriel Scherer and Florian Angeletti) + +- #9998: Use Sys.opaque_identity in CamlinternalLazy.force + This removes extra warning 59 messages when compiling afl-instrumented + code with flambda -O3. + (Vincent Laviron, report by Louis Gesbert, review by Gabriel Scherer and + Pierre Chambart) + +- #9999: fix -dsource printing of the pattern (`A as x | (`B as x)). + (Gabriel Scherer, report by Anton Bachin, review by Florian Angeletti) + - #9970, #10010: fix the declaration scope of extensible-datatype constructors. A regression that dates back to 4.08 makes extensible-datatype constructors with inline records very fragile, for example: @@ -44,15 +712,23 @@ OCaml 4.11.2 (24 February 2021) (Gabriel Scherer, review by Thomas Refis and Leo White, report by Nicolás Ojeda Bär) +- #10048: Fix bug with generalized local opens. + (Leo White, review by Thomas Refis) + +- #10106, #10112: some expected-type explanations where forgotten + after some let-bindings + (Gabriel Scherer, review by Thomas Refis and Florian Angeletti, + report by Daniil Baturin) + +OCaml 4.11 maintenance branch +----------------------------- + +### Bug fixes: + - #9096, #10096: fix a 4.11.0 performance regression in classes/objects declared within a function (Gabriel Scherer, review by Leo White, report by Sacha Ayoun) -- #9326, #10125: Gc.set incorrectly handles the three `custom_*` fields, - causing a performance regression - (report by Emilio Jesús Gallego Arias, analysis and fix by Stephen Dolan, - code by Xavier Leroy, review by Hugo Heuzard and Gabriel Scherer) - OCaml 4.11.1 (31 August 2020) ----------------------------- @@ -294,10 +970,6 @@ OCaml 4.11.0 (19 August 2020) from a different (older or newer), incompatible compiler version. (Gabriel Scherer, review by Gabriel Radanne and Damien Doligez) -- #9181: make objinfo work on Cygwin and look for the caml_plugin_header - symbol in both the static and the dynamic symbol tables. - (Sébastien Hinderer, review by Gabriel Scherer and David Allsopp) - * #9197: remove compatibility logic from #244 that was designed to synchronize toplevel printing margins with Format.std_formatter, but also resulted in unpredictable/fragile changes to formatter @@ -319,9 +991,6 @@ OCaml 4.11.0 (19 August 2020) on length of Sys.command argument. (Xavier Leroy, report by Jérémie Dimino, review by David Allsopp) -- #9552: restore ocamloptp build and installation - (Florian Angeletti, review by David Allsopp and Xavier Leroy) - ### Manual and documentation: - #9141: beginning of the ocamltest reference manual @@ -472,6 +1141,9 @@ OCaml 4.11.0 (19 August 2020) compilerlibs, dynlink, ocamltest. (Gabriel Scherer, review by Vincent Laviron and David Allsopp) +- #9275: Short circuit simple inclusion checks + (Leo White, review by Thomas Refis) + - #9305: Avoid polymorphic compare in Ident (Leo White, review by Xavier Leroy and Gabriel Scherer) @@ -595,6 +1267,9 @@ OCaml 4.11.0 (19 August 2020) * #9388: Prohibit signature local types with constraints (Leo White, review by Jacques Garrigue) +- #7141, #9389: returns exit_code for better user response on linking_error + (Anukriti Kumar, review by Gabriel Scherer and Valentin Gatien-Baron) + - #9406, #9409: fix an error with packed module types from missing cmis. (Florian Angeletti, report by Thomas Leonard, review by Gabriel Radanne @@ -653,16 +1328,19 @@ OCaml 4.10 maintenance branch output channels would not be flushed). (Nicolás Ojeda Bär, review by David Allsopp) -- #9714, #9724: Use the C++ alignas keyword when compiling in C++. - Fixes a bug with MSVC C++ 2015/2017. Add a terminator to the - `caml_domain_state` structure to better ensure that members are - correctly spaced. +- #9714, #9724: Use the C++ alignas keyword when compiling in C++ in MSVC. + Fixes a bug with MSVC C++ 2015 onwards. (Antonin Décimo, review by David Allsopp and Xavier Leroy) - #9736, #9749: Compaction must start in a heap where all free blocks are blue, which was not the case with the best-fit allocator. (Damien Doligez, report and review by Leo White) +### Tools: + +- #9552: restore ocamloptp build and installation + (Florian Angeletti, review by David Allsopp and Xavier Leroy) + OCaml 4.10.0 (21 February 2020) ------------------------------- @@ -971,6 +1649,10 @@ OCaml 4.10.0 (21 February 2020) - #9127, #9130: ocamldoc: fix the formatting of closing brace in record types. (David Allsopp, report by San Vu Ngoc) +- #9181: make objinfo work on Cygwin and look for the caml_plugin_header + symbol in both the static and the dynamic symbol tables. + (Sébastien Hinderer, review by Gabriel Scherer and David Allsopp) + ### Build system: - #8840: use ocaml{c,opt}.opt when available to build internal tools @@ -1171,9 +1853,6 @@ OCaml 4.10.0 (21 February 2020) - #9261: Fix a soundness bug in Rec_check, new in 4.10 (from #8908) (Vincent Laviron, review by Jeremy Yallop and Gabriel Scherer) -- #9389: returns exit_code for better user response on linking_error - (Anukriti Kumar, review by Gabriel Scherer and sliquister) - OCaml 4.09 maintenance branch ----------------------------- @@ -1204,15 +1883,15 @@ OCaml 4.09.1 (16 Mars 2020) - #9050, #9076: install missing compilerlibs/ocamlmiddleend archives (Gabriel Scherer, review by Florian Angeletti, report by Olaf Hering) -- #9144, #9180: multiple definitions of global variables in the C runtime, - causing problems with GCC 10.0 and possibly with other C compilers - (Xavier Leroy, report by Jürgen Reuter, review by Mark Shinwell) - - #9180: pass -fno-common option to C compiler when available, so as to detect problematic multiple definitions of global variables in the C runtime (Xavier Leroy, review by Mark Shinwell) +- #9144, #9180: multiple definitions of global variables in the C runtime, + causing problems with GCC 10.0 and possibly with other C compilers + (Xavier Leroy, report by Jürgen Reuter, review by Mark Shinwell) + - #9128: Fix a bug in bytecode mode which could lead to a segmentation fault. The bug was caused by the fact that the atom table shared a page with some bytecode. The fix makes sure both the atom table and @@ -1360,9 +2039,6 @@ OCaml 4.09.0 (19 September 2019) - #8515: manual, precise constraints on reexported types (Florian Angeletti, review by Gabriel Scherer) -- #9327, #9401: manual, fix infix attribute examples - (Florian Angeletti, report by David Cadé, review by Gabriel Scherer) - ### Tools: - #2221: ocamldep will now correctly allow a .ml file in an include directory @@ -1434,9 +2110,6 @@ OCaml 4.09.0 (19 September 2019) (Thomas Refis, review by David Allsopp, Florian Angeletti, Gabriel Radanne, Gabriel Scherer and Xavier Leroy) -- #9275: Short circuit simple inclusion checks - (Leo White, review by Thomas Refis) - ### Compiler distribution build system: - #2267: merge generation of header programs, also fixing parallel build on @@ -1969,9 +2642,6 @@ OCaml 4.08.0 (13 June 2019) - #8508: refresh \moduleref macro (Florian Angeletti, review by Gabriel Scherer) -- 9410: replaced fibonacci example with gcd of coreexamples manual - (Anukriti Kumar, review by San Vu Ngoc, Florian Angeletti, Léo Andrès) - ### Code generation and optimizations: - #7725, #1754: improve AFL instrumentation for objects and lazy values. @@ -2698,9 +3368,6 @@ OCaml 4.07.0 (10 July 2018) platforms, making this option unusable on platforms where it wasn't. (Jérémie Dimino, review by Sébastien Hinderer and Xavier Leroy) -- #9349: Support [@inlined hint] attribute. - (Leo White, review by Stephen Dolan) - ### Runtime system: - #515 #676 #7173: Add a public C API for weak arrays and diff --git a/HACKING.adoc b/HACKING.adoc index 101f3f57..a3212b3c 100644 --- a/HACKING.adoc +++ b/HACKING.adoc @@ -15,6 +15,13 @@ official distribution, please see link:CONTRIBUTING.md[]. ---- git checkout -b my-modification ---- +Usually, this branch wants to be based on `trunk`. If your changes must be on a +specific release, use its release branch (*not* the release tag) instead. For +example, to make a fix for 4.11.1, base your branch on *4.11* (not on *4.11.1*). +The `configure` step for the compiler recognises a development build from the +`+dev` in the version number (see file `VERSION`), and release tarballs and the tagged Git commits do +not have this which causes some important development things to be disabled +(ocamltest and converting C compiler warnings to errors). 2. Consult link:INSTALL.adoc[] for build instructions. Here is the gist of it: + @@ -22,6 +29,9 @@ git checkout -b my-modification ./configure make ---- +If you are on a release build and need development options, you can add +`--enable-ocamltest` (to allow running the testsuite) and `--enable-warn-error` +(so you don't get caught by CI later!). 3. Try the newly built compiler binaries `ocamlc`, `ocamlopt` or their `.opt` version. To try the toplevel, use: @@ -38,31 +48,21 @@ make runtop make tests ---- -6. Install in a new opam switch to try things out. With `opam` v2, create a local -opam switch with the compiler installed from the current source directory: -+ ----- -opam switch create . --empty -opam install . ----- - -7. You did it, Well done! Consult link:CONTRIBUTING.md[] to send your contribution upstream. +6. You did it, Well done! Consult link:CONTRIBUTING.md[] to send your contribution upstream. -See our <> for various helpful details, -for example on how to automatically <> from a compiler branch. +See also our <>, for example on how to +<> to test your modified compiler. === What to do There is always a lot of potential tasks, both for old and newcomers. Here are various potential projects: -* http://caml.inria.fr/mantis/view_all_bug_page.php[The OCaml +* https://github.com/ocaml/ocaml/issues[The OCaml bugtracker] contains reported bugs and feature requests. Some changes that should be accessible to newcomers are marked with the - tag link:++http://caml.inria.fr/mantis/search.php? -project_id=1&sticky_issues=1&sortby=last_updated&dir=DESC&highlight_changed=24&hide_status_id=90&tag_string=junior_job++[ - junior_job]. + tag link:++https://github.com/ocaml/ocaml/issues?q=is%3Aopen+is%3Aissue+label%3Anewcomer-job++[ + newcomer-job]. * The https://github.com/ocamllabs/compiler-hacking/wiki/Things-to-work-on[OCaml @@ -170,7 +170,7 @@ has excellent documentation. Makefile.tools:: used by manual/ and testsuite/ Makefiles README.adoc:: general information on the compiler distribution README.win32.adoc:: general information on the Windows ports of OCaml - VERSION:: version string + VERSION:: version string. Run `make configure` after changing. asmcomp/:: native-code compiler and linker boot/:: bootstrap compiler build-aux/: autotools support scripts @@ -198,6 +198,7 @@ has excellent documentation. utils/:: utility libraries yacc/:: parser generator +[#tips] == Development tips and tricks === Keep merge commits when merging and cherry-picking Github PRs @@ -216,13 +217,23 @@ the original commit in the commit message. git cherry-pick -x -m 1 ---- +[#opam-switch] === Testing with `opam` -To test a particular branch `branch` of a public git repository -`$REPO` of the compiler in an `opam` v2 switch issue: +If you are working on a development version of the compiler, you can create an +opam switch from it by running the following from the development repository: + +----- +-opam switch create . --empty +-opam install . +----- + +If you want to test someone else's development version from a public +git repository, you can build a switch directly (without cloning their +work locally) by pinning: ---- -opam switch create ocaml-branch --empty +opam switch create my-switch-name --empty # Replace $VERSION by the trunk version opam pin add ocaml-variants.$VERSION+branch git+https://$REPO#branch ---- @@ -302,6 +313,52 @@ If `boot/ocamlc` changes (e.g. because you ran `make bootstrap`), then the build will revert to the slower bytecode-compiled `ocamlc` until you do the above step again. +=== Using merlin + +During the development of the compiler, the internal format of compiled object +files evolves, and quickly becomes incompatible with the format of the last +OCaml release. In particular, even an up-to-date merlin will be unable to use +them during most of the development cycle: opening a compiler source file with +merlin gives a frustrating error message. + +To use merlin on the compiler, you want to build the compiler with an older +version of itself. One easy way to do this is to use the experimental build +rules for Dune, which are distributed with the compiler (with no guarantees that +the build will work all the time). Assuming you already have a recent OCaml +version installed with merlin and dune, you can just run the following from the +compiler sources: + +---- +./configure # if not already done +make clean && dune build @libs +---- + +which will do a bytecode build of all the distribution (without linking +the executables), using your OCaml compiler, and generate a .merlin +file. + +Merlin will be looking at the artefacts generated by dune (in `_build`), rather +than trying to open the incompatible artefacts produced by a Makefile build. In +particular, you need to repeat the dune build every time you change the interface +of some compilation unit, so that merlin is aware of the new interface. + +You only need to run `configure` once, but you will need to run `make clean` +every time you want to run `dune` after you built something with `make`; +otherwise dune will complain that build artefacts are present among the sources. + +Finally, there will be times where the compiler simply cannot be built with an +older version of itself. One example of this is when a new primitive is added to +the runtime, and then used in the standard library straight away, since the rest +of the compiler requires the `stdlib` library to build, nothing can be build. In +such situations, you will have to either live without merlin, or develop on an +older branch of the compiler, for example the maintenance branch of the last +released version. Developing a patch from a release branch can later introduce a +substantial amount of extra work, when you rebase to the current development +version. But it also makes it a lot easier to test the impact of your work on +third-party code, by installing a local <>: opam +packages tend to be compatible with released versions of the compiler, whereas +most packages are incompatible with the in-progress development version. + === Continuous integration ==== Github's CI: Travis and AppVeyor diff --git a/INSTALL.adoc b/INSTALL.adoc index 9d63aaf5..0ad38fc6 100644 --- a/INSTALL.adoc +++ b/INSTALL.adoc @@ -2,22 +2,23 @@ == Prerequisites -* The GNU C Compiler (gcc) is recommended, as the bytecode interpreter takes +* A C Compiler is required. + The GNU C Compiler (`gcc`) is recommended as the bytecode interpreter takes advantage of GCC-specific features to enhance performance. gcc is the standard - compiler under Linux, OS X, and many other systems. + compiler under Linux and many other systems. + However `clang` - used in Mac OS, BSDs and others - also works fine. + +* GNU `make`, as well as POSIX-compatible `awk` and `sed` are required. + +* A POSIX-compatible `diff` is necessary to run the test suite. * If you do not have write access to `/tmp`, you should set the environment variable `TMPDIR` to the name of some other temporary directory. -* Under HP/UX, the GNU C Compiler (gcc), the GNU Assembler (gas), and GNU Make - are all *required*. The vendor-provided compiler, assembler and make tools - have major problems. +== Prerequisites (special cases) -* Under Cygwin, the `gcc-core` and `make` packages are required. `flexdll` is - necessary for shared library support. `libX11-devel` is necessary for graph - library support and `libintl-devel` is necessary for the `ocamlobjinfo` tool - to be able to process `.cmxs` files. `diffutils` is necessary to run the test - suite. +* Under Cygwin, the `gcc-core` package is required. `flexdll` is also necessary + for shared library support. == Configuration @@ -56,11 +57,17 @@ By default, build is 32-bit. For 64-bit build, please set environment variable ` for _both_ `configure` and `make world` phases. Note, if this variable is set for only one phase, your build will break (`ocamlrun` segfaults). + +* For Solaris/Illumos on SPARC machines with Sun PRO compiler only 64-bit + bytecode target is supported (32-bit fails due to alignment issues; the optimization + is preset to `-O4` for inlining): + + ./configure CC="cc -m64" ++ If something goes wrong during the automatic configuration, or if the generated files cause errors later on, then look at the template files: Makefile.config.in - Makefile.common.in + Makefile.build_config.in runtime/caml/m.h.in runtime/caml/s.h.in + diff --git a/Makefile b/Makefile index 2984178a..41d8e263 100644 --- a/Makefile +++ b/Makefile @@ -16,22 +16,7 @@ # The main Makefile ROOTDIR = . - -# The configure and *clean targets can all be run without running ./configure -# first. -# If no goals were specified (i.e. `make`), add defaultentry (since it requires -# ./configure to be run) -CAN_BE_UNCONFIGURED := $(strip \ - $(filter-out partialclean clean distclean configure, \ - $(if $(MAKECMDGOALS),$(MAKECMDGOALS),defaultentry))) - -ifeq "$(CAN_BE_UNCONFIGURED)" "" --include Makefile.config --include Makefile.common -else -include Makefile.config include Makefile.common -endif .PHONY: defaultentry ifeq "$(NATIVE_COMPILER)" "true" @@ -40,7 +25,6 @@ else defaultentry: world endif -MKDIR=mkdir -p ifeq "$(UNIX_OR_WIN32)" "win32" LN = cp else @@ -50,7 +34,7 @@ endif include stdlib/StdlibModules CAMLC=$(BOOT_OCAMLC) -g -nostdlib -I boot -use-prims runtime/primitives -CAMLOPT=$(CAMLRUN) ./ocamlopt -g -nostdlib -I stdlib -I otherlibs/dynlink +CAMLOPT=$(CAMLRUN) ./ocamlopt$(EXE) -g -nostdlib -I stdlib -I otherlibs/dynlink ARCHES=amd64 i386 arm arm64 power s390x riscv INCLUDES=-I utils -I parsing -I typing -I bytecomp -I file_formats \ -I lambda -I middle_end -I middle_end/closure \ @@ -69,7 +53,6 @@ else OCAML_NATDYNLINKOPTS = -ccopt "$(NATDYNLINKOPTS)" endif -YACCFLAGS=-v --strict CAMLLEX=$(CAMLRUN) boot/ocamllex CAMLDEP=$(CAMLRUN) boot/ocamlc -depend DEPFLAGS=-slash @@ -93,11 +76,11 @@ LIBFILES=stdlib.cma std_exit.cmo *.cmi camlheader COMPLIBDIR=$(LIBDIR)/compiler-libs TOPINCLUDES=$(addprefix -I otherlibs/,$(filter-out %threads,$(OTHERLIBRARIES))) -RUNTOP=./runtime/ocamlrun ./ocaml \ - -nostdlib -I stdlib \ +RUNTOP=./runtime/ocamlrun$(EXE) ./ocaml$(EXE) \ + -nostdlib -I stdlib -I toplevel \ -noinit $(TOPFLAGS) $(TOPINCLUDES) NATRUNTOP=./ocamlnat$(EXE) \ - -nostdlib -I stdlib \ + -nostdlib -I stdlib -I toplevel \ -noinit $(TOPFLAGS) $(TOPINCLUDES) ifeq "$(UNIX_OR_WIN32)" "unix" EXTRAPATH= @@ -112,11 +95,14 @@ FLEXDLL_SUBMODULE_PRESENT := $(wildcard flexdll/Makefile) ifeq "$(FLEXDLL_SUBMODULE_PRESENT)" "" BOOT_FLEXLINK_CMD = else - BOOT_FLEXLINK_CMD = FLEXLINK_CMD="../boot/ocamlrun ../flexdll/flexlink.exe" + BOOT_FLEXLINK_CMD = \ + FLEXLINK_CMD="../boot/ocamlrun$(EXE) ../flexdll/flexlink.exe" endif else endif +expunge := expunge$(EXE) + # targets for the compilerlibs/*.{cma,cmxa} archives include compilerlibs/Makefile.compilerlibs @@ -145,6 +131,10 @@ partialclean:: .PHONY: beforedepend beforedepend:: utils/config.ml utils/domainstate.ml utils/domainstate.mli +programs := expunge ocaml ocamlc ocamlc.opt ocamlnat ocamlopt ocamlopt.opt + +$(foreach program, $(programs), $(eval $(call PROGRAM_SYNONYM,$(program)))) + # Start up the system from the distribution compiler .PHONY: coldstart coldstart: @@ -163,15 +153,17 @@ coreall: runtime # Build the core system: the minimum needed to make depend and bootstrap .PHONY: core -core: - $(MAKE) coldstart +core: coldstart $(MAKE) coreall # Check if fixpoint reached + +CMPBYT := $(CAMLRUN) tools/cmpbyt$(EXE) + .PHONY: compare compare: - @if $(CAMLRUN) tools/cmpbyt boot/ocamlc ocamlc \ - && $(CAMLRUN) tools/cmpbyt boot/ocamllex lex/ocamllex; \ + @if $(CMPBYT) boot/ocamlc ocamlc$(EXE) \ + && $(CMPBYT) boot/ocamllex lex/ocamllex$(EXE); \ then echo "Fixpoint reached, bootstrap succeeded."; \ else \ echo "Fixpoint not reached, try one more bootstrapping cycle."; \ @@ -184,8 +176,8 @@ PROMOTE ?= cp .PHONY: promote-common promote-common: - $(PROMOTE) ocamlc boot/ocamlc - $(PROMOTE) lex/ocamllex boot/ocamllex + $(PROMOTE) ocamlc$(EXE) boot/ocamlc + $(PROMOTE) lex/ocamllex$(EXE) boot/ocamllex cd stdlib; cp $(LIBFILES) ../boot # Promote the newly compiled system to the rank of cross compiler @@ -245,7 +237,7 @@ coreboot: # Rebuild the library (using runtime/ocamlrun ./ocamlc) $(MAKE) library-cross # Promote the new compiler and the new runtime - $(MAKE) CAMLRUN=runtime/ocamlrun promote + $(MAKE) CAMLRUN=runtime/ocamlrun$(EXE) promote # Rebuild the core system $(MAKE) partialclean $(MAKE) core @@ -307,16 +299,21 @@ flexdll: flexdll/Makefile flexlink MSVC_DETECT=0 CHAINS=$(FLEXDLL_CHAIN) NATDYNLINK=false support # Bootstrapping flexlink - leaves a bytecode image of flexlink.exe in flexdll/ +FLEXLINK_OCAMLOPT = \ + ../boot/ocamlrun$(EXE) ../boot/ocamlc \ + -use-prims ../runtime/primitives -nostdlib -I ../boot + .PHONY: flexlink flexlink: flexdll/Makefile $(MAKE) -C runtime BOOTSTRAPPING_FLEXLINK=yes ocamlrun$(EXE) cp runtime/ocamlrun$(EXE) boot/ocamlrun$(EXE) - $(MAKE) -C stdlib COMPILER=../boot/ocamlc \ - $(filter-out *.cmi,$(LIBFILES)) + $(MAKE) -C stdlib \ + COMPILER="../boot/ocamlc -use-prims ../runtime/primitives" \ + $(filter-out *.cmi,$(LIBFILES)) cd stdlib && cp $(LIBFILES) ../boot/ $(MAKE) -C flexdll MSVC_DETECT=0 OCAML_CONFIG_FILE=../Makefile.config \ CHAINS=$(FLEXDLL_CHAIN) NATDYNLINK=false \ - OCAMLOPT="../boot/ocamlrun ../boot/ocamlc -nostdlib -I ../boot" \ + OCAMLOPT="$(FLEXLINK_OCAMLOPT)" \ flexlink.exe $(MAKE) -C runtime clean $(MAKE) partialclean @@ -325,9 +322,9 @@ flexlink: flexdll/Makefile flexlink.opt: cd flexdll && \ mv flexlink.exe flexlink && \ - ($(MAKE) OCAML_FLEXLINK="../boot/ocamlrun ./flexlink" MSVC_DETECT=0 \ - OCAML_CONFIG_FILE=../Makefile.config \ - OCAMLOPT="../ocamlopt.opt -nostdlib -I ../stdlib" \ + ($(MAKE) OCAML_FLEXLINK="../boot/ocamlrun$(EXE) ./flexlink" \ + MSVC_DETECT=0 OCAML_CONFIG_FILE=../Makefile.config \ + OCAMLOPT="../ocamlopt.opt$(EXE) -nostdlib -I ../stdlib" \ flexlink.exe || \ (mv flexlink flexlink.exe && false)) && \ mv flexlink.exe flexlink.opt && \ @@ -355,19 +352,17 @@ install: $(MKDIR) "$(INSTALL_LIBDIR)" $(MKDIR) "$(INSTALL_STUBLIBDIR)" $(MKDIR) "$(INSTALL_COMPLIBDIR)" - $(INSTALL_DATA) \ - VERSION \ - "$(INSTALL_LIBDIR)" $(MAKE) -C runtime install - $(INSTALL_PROG) ocaml "$(INSTALL_BINDIR)/ocaml$(EXE)" + $(INSTALL_PROG) ocaml$(EXE) "$(INSTALL_BINDIR)" ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" - $(INSTALL_PROG) ocamlc "$(INSTALL_BINDIR)/ocamlc.byte$(EXE)" + $(INSTALL_PROG) ocamlc$(EXE) "$(INSTALL_BINDIR)/ocamlc.byte$(EXE)" endif $(MAKE) -C stdlib install ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" - $(INSTALL_PROG) lex/ocamllex "$(INSTALL_BINDIR)/ocamllex.byte$(EXE)" + $(INSTALL_PROG) lex/ocamllex$(EXE) \ + "$(INSTALL_BINDIR)/ocamllex.byte$(EXE)" endif - $(INSTALL_PROG) yacc/ocamlyacc$(EXE) "$(INSTALL_BINDIR)/ocamlyacc$(EXE)" + $(INSTALL_PROG) yacc/ocamlyacc$(EXE) "$(INSTALL_BINDIR)" $(INSTALL_DATA) \ utils/*.cmi \ parsing/*.cmi \ @@ -396,7 +391,7 @@ endif $(INSTALL_DATA) \ $(BYTESTART) $(TOPLEVELSTART) \ "$(INSTALL_COMPLIBDIR)" - $(INSTALL_PROG) expunge "$(INSTALL_LIBDIR)/expunge$(EXE)" + $(INSTALL_PROG) $(expunge) "$(INSTALL_LIBDIR)" $(INSTALL_DATA) \ toplevel/topdirs.cmi \ "$(INSTALL_LIBDIR)" @@ -414,10 +409,6 @@ endif for i in $(OTHERLIBRARIES); do \ $(MAKE) -C otherlibs/$$i install || exit $$?; \ done -# Transitional: findlib 1.7.3 is confused if leftover num.cm? files remain -# from an previous installation of OCaml before otherlibs/num was removed. - rm -f "$(INSTALL_LIBDIR)"/num.cm? -# End transitional ifneq "$(WITH_OCAMLDOC)" "" $(MAKE) -C ocamldoc install endif @@ -429,15 +420,15 @@ ifeq "$(UNIX_OR_WIN32)" "win32" $(MAKE) install-flexdll; \ fi endif - $(INSTALL_DATA) Makefile.config "$(INSTALL_LIBDIR)/Makefile.config" + $(INSTALL_DATA) Makefile.config "$(INSTALL_LIBDIR)" ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" - if test -f ocamlopt; then $(MAKE) installopt; else \ + if test -f ocamlopt$(EXE); then $(MAKE) installopt; else \ cd "$(INSTALL_BINDIR)"; \ $(LN) ocamlc.byte$(EXE) ocamlc$(EXE); \ $(LN) ocamllex.byte$(EXE) ocamllex$(EXE); \ fi else - if test -f ocamlopt; then $(MAKE) installopt; fi + if test -f ocamlopt$(EXE); then $(MAKE) installopt; fi endif # Installation of the native-code compiler @@ -445,7 +436,7 @@ endif installopt: $(MAKE) -C runtime installopt ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" - $(INSTALL_PROG) ocamlopt "$(INSTALL_BINDIR)/ocamlopt.byte$(EXE)" + $(INSTALL_PROG) ocamlopt$(EXE) "$(INSTALL_BINDIR)/ocamlopt.byte$(EXE)" endif $(MAKE) -C stdlib installopt $(INSTALL_DATA) \ @@ -503,27 +494,26 @@ endif $(MAKE) -C otherlibs/$$i installopt || exit $$?; \ done ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" - if test -f ocamlopt.opt ; then $(MAKE) installoptopt; else \ + if test -f ocamlopt.opt$(EXE); then $(MAKE) installoptopt; else \ cd "$(INSTALL_BINDIR)"; \ $(LN) ocamlc.byte$(EXE) ocamlc$(EXE); \ $(LN) ocamlopt.byte$(EXE) ocamlopt$(EXE); \ $(LN) ocamllex.byte$(EXE) ocamllex$(EXE); \ fi else - if test -f ocamlopt.opt ; then $(MAKE) installoptopt; fi + if test -f ocamlopt.opt$(EXE); then $(MAKE) installoptopt; fi endif $(MAKE) -C tools installopt - if test -f ocamlopt.opt -a -f flexdll/flexlink.opt ; then \ + if test -f ocamlopt.opt$(EXE) -a -f flexdll/flexlink.opt ; then \ $(INSTALL_PROG) \ flexdll/flexlink.opt "$(INSTALL_BINDIR)/flexlink$(EXE)" ; \ fi .PHONY: installoptopt installoptopt: - $(INSTALL_PROG) ocamlc.opt "$(INSTALL_BINDIR)/ocamlc.opt$(EXE)" - $(INSTALL_PROG) ocamlopt.opt "$(INSTALL_BINDIR)/ocamlopt.opt$(EXE)" - $(INSTALL_PROG) \ - lex/ocamllex.opt "$(INSTALL_BINDIR)/ocamllex.opt$(EXE)" + $(INSTALL_PROG) ocamlc.opt$(EXE) "$(INSTALL_BINDIR)" + $(INSTALL_PROG) ocamlopt.opt$(EXE) "$(INSTALL_BINDIR)" + $(INSTALL_PROG) lex/ocamllex.opt$(EXE) "$(INSTALL_BINDIR)" cd "$(INSTALL_BINDIR)"; \ $(LN) ocamlc.opt$(EXE) ocamlc$(EXE); \ $(LN) ocamlopt.opt$(EXE) ocamlopt$(EXE); \ @@ -546,8 +536,7 @@ installoptopt: $(OPTSTART:.cmo=.cmx) $(OPTSTART:.cmo=.$(O)) \ "$(INSTALL_COMPLIBDIR)" if test -f ocamlnat$(EXE) ; then \ - $(INSTALL_PROG) \ - ocamlnat$(EXE) "$(INSTALL_BINDIR)/ocamlnat$(EXE)"; \ + $(INSTALL_PROG) ocamlnat$(EXE) "$(INSTALL_BINDIR)"; \ $(INSTALL_DATA) \ toplevel/opttopdirs.cmi \ "$(INSTALL_LIBDIR)"; \ @@ -593,23 +582,25 @@ manual-pregen: opt.opt # The clean target clean:: partialclean + rm -f $(programs) $(programs:=.exe) # The bytecode compiler -ocamlc: compilerlibs/ocamlcommon.cma compilerlibs/ocamlbytecomp.cma $(BYTESTART) +ocamlc$(EXE): compilerlibs/ocamlcommon.cma \ + compilerlibs/ocamlbytecomp.cma $(BYTESTART) $(CAMLC) $(LINKFLAGS) -compat-32 -o $@ $^ partialclean:: - rm -rf ocamlc + rm -rf ocamlc$(EXE) # The native-code compiler -ocamlopt: compilerlibs/ocamlcommon.cma compilerlibs/ocamloptcomp.cma \ +ocamlopt$(EXE): compilerlibs/ocamlcommon.cma compilerlibs/ocamloptcomp.cma \ $(OPTSTART) $(CAMLC) $(LINKFLAGS) -o $@ $^ partialclean:: - rm -f ocamlopt + rm -f ocamlopt$(EXE) # The toplevel @@ -622,11 +613,11 @@ ocaml_dependencies := \ ocaml.tmp: $(ocaml_dependencies) $(CAMLC) $(LINKFLAGS) -linkall -o $@ $^ -ocaml: expunge ocaml.tmp +ocaml$(EXE): $(expunge) ocaml.tmp - $(CAMLRUN) $^ $@ $(PERVASIVES) partialclean:: - rm -f ocaml + rm -f ocaml$(EXE) .PHONY: runtop runtop: @@ -634,16 +625,14 @@ runtop: $(MAKE) ocamlc $(MAKE) otherlibraries $(MAKE) ocaml - @rlwrap --help 2>/dev/null && $(EXTRAPATH) rlwrap $(RUNTOP) ||\ - $(EXTRAPATH) $(RUNTOP) + @$(EXTRAPATH) $(RLWRAP) $(RUNTOP) .PHONY: natruntop natruntop: $(MAKE) core $(MAKE) opt $(MAKE) ocamlnat - @rlwrap --help 2>/dev/null && $(EXTRAPATH) rlwrap $(NATRUNTOP) ||\ - $(EXTRAPATH) $(NATRUNTOP) + @$(FLEXLINK_ENV) $(EXTRAPATH) $(RLWRAP) $(NATRUNTOP) # Native dynlink @@ -662,21 +651,23 @@ beforedepend:: parsing/lexer.ml # The bytecode compiler compiled with the native-code compiler -ocamlc.opt: compilerlibs/ocamlcommon.cmxa compilerlibs/ocamlbytecomp.cmxa \ - $(BYTESTART:.cmo=.cmx) +ocamlc.opt$(EXE): compilerlibs/ocamlcommon.cmxa \ + compilerlibs/ocamlbytecomp.cmxa $(BYTESTART:.cmo=.cmx) $(CAMLOPT_CMD) $(LINKFLAGS) -o $@ $^ -cclib "$(BYTECCLIBS)" partialclean:: - rm -f ocamlc.opt + rm -f ocamlc.opt$(EXE) # The native-code compiler compiled with itself -ocamlopt.opt: compilerlibs/ocamlcommon.cmxa compilerlibs/ocamloptcomp.cmxa \ - $(OPTSTART:.cmo=.cmx) +ocamlopt.opt$(EXE): \ + compilerlibs/ocamlcommon.cmxa \ + compilerlibs/ocamloptcomp.cmxa \ + $(OPTSTART:.cmo=.cmx) $(CAMLOPT_CMD) $(LINKFLAGS) -o $@ $^ partialclean:: - rm -f ocamlopt.opt + rm -f ocamlopt.opt$(EXE) # The predefined exceptions and primitives @@ -714,9 +705,11 @@ asmcomp/scheduling.ml: asmcomp/$(ARCH)/scheduling.ml # Preprocess the code emitters -asmcomp/emit.ml: asmcomp/$(ARCH)/emit.mlp tools/cvt_emit +cvt_emit := tools/cvt_emit$(EXE) + +asmcomp/emit.ml: asmcomp/$(ARCH)/emit.mlp $(cvt_emit) echo \# 1 \"$(ARCH)/emit.mlp\" > $@ - $(CAMLRUN) tools/cvt_emit < $< >> $@ \ + $(CAMLRUN) $(cvt_emit) < $< >> $@ \ || { rm -f $@; exit 2; } partialclean:: @@ -724,17 +717,17 @@ partialclean:: beforedepend:: asmcomp/emit.ml -tools/cvt_emit: tools/cvt_emit.mll +$(cvt_emit): tools/cvt_emit.mll $(MAKE) -C tools cvt_emit # The "expunge" utility -expunge: compilerlibs/ocamlcommon.cma compilerlibs/ocamlbytecomp.cma \ +$(expunge): compilerlibs/ocamlcommon.cma compilerlibs/ocamlbytecomp.cma \ toplevel/expunge.cmo $(CAMLC) $(LINKFLAGS) -o $@ $^ partialclean:: - rm -f expunge + rm -f $(expunge) # The runtime system for the bytecode compiler @@ -751,21 +744,16 @@ clean:: $(MAKE) -C runtime clean rm -f stdlib/libcamlrun.a stdlib/libcamlrun.lib -otherlibs_all := bigarray dynlink raw_spacetime_lib \ +otherlibs_all := bigarray dynlink \ str systhreads unix win32unix -subdirs := debugger lex ocamldoc ocamltest runtime stdlib tools \ +subdirs := debugger lex ocamldoc ocamltest stdlib tools \ $(addprefix otherlibs/, $(otherlibs_all)) \ .PHONY: alldepend -ifeq "$(TOOLCHAIN)" "msvc" -alldepend: - $(error Dependencies cannot be regenerated using the MSVC ports) -else alldepend: depend for dir in $(subdirs); do \ $(MAKE) -C $$dir depend || exit; \ done -endif # The runtime system for the native-code compiler @@ -789,7 +777,8 @@ library: ocamlc .PHONY: library-cross library-cross: - $(MAKE) -C stdlib $(BOOT_FLEXLINK_CMD) CAMLRUN=../runtime/ocamlrun all + $(MAKE) -C stdlib \ + $(BOOT_FLEXLINK_CMD) CAMLRUN=../runtime/ocamlrun$(EXE) all .PHONY: libraryopt libraryopt: @@ -873,7 +862,7 @@ ocamldoc.opt: ocamlc.opt ocamlyacc ocamllex $(MAKE) -C ocamldoc opt.opt # OCamltest -ocamltest: ocamlc ocamlyacc ocamllex +ocamltest: ocamlc ocamlyacc ocamllex otherlibraries $(MAKE) -C ocamltest all ocamltest.opt: ocamlc.opt ocamlyacc ocamllex @@ -924,22 +913,28 @@ partialclean:: # Check that the native-code compiler is supported .PHONY: checknative checknative: +ifneq "$(NATIVE_COMPILER)" "true" + $(error The source tree was configured with --disable-native-compiler!) +else ifeq "$(ARCH)" "none" -checknative: $(error The native-code compiler is not supported on this platform) else @ endif +endif # Check that the stack limit is reasonable (Unix-only) .PHONY: checkstack -checkstack: ifeq "$(UNIX_OR_WIN32)" "unix" - if $(MKEXE) $(OUTPUTEXE)tools/checkstack$(EXE) tools/checkstack.c; \ - then tools/checkstack$(EXE); \ - fi - rm -f tools/checkstack$(EXE) +checkstack := tools/checkstack +checkstack: $(checkstack)$(EXE) + $< + +.INTERMEDIATE: $(checkstack)$(EXE) $(checkstack).$(O) +$(checkstack)$(EXE): $(checkstack).$(O) + $(MKEXE) $(OUTPUTEXE)$@ $< else +checkstack: @ endif @@ -950,7 +945,7 @@ VERSIONS=$(shell git tag|grep '^[0-9]*.[0-9]*.[0-9]*$$'|grep -v '^[12].') lintapidiff: $(MAKE) -C tools lintapidiff.opt git ls-files -- 'otherlibs/*/*.mli' 'stdlib/*.mli' |\ - grep -Ev internal\|obj\|spacetime\|stdLabels\|moreLabels |\ + grep -Ev internal\|obj\|stdLabels\|moreLabels |\ tools/lintapidiff.opt $(VERSIONS) # Tools @@ -972,6 +967,10 @@ partialclean:: ## Test compilation of backend-specific parts +ARCH_SPECIFIC =\ + asmcomp/arch.ml asmcomp/proc.ml asmcomp/CSE.ml asmcomp/selection.ml \ + asmcomp/scheduling.ml asmcomp/reload.ml + partialclean:: rm -f $(ARCH_SPECIFIC) @@ -1002,14 +1001,6 @@ endif # The native toplevel -# When the native toplevel executable has an extension (e.g. ".exe"), -# provide a phony 'ocamlnat' synonym - -ifneq ($(EXE),) -.PHONY: ocamlnat -ocamlnat: ocamlnat$(EXE) -endif - ocamlnat$(EXE): compilerlibs/ocamlcommon.cmxa compilerlibs/ocamloptcomp.cmxa \ compilerlibs/ocamlbytecomp.cmxa \ otherlibs/dynlink/dynlink.cmxa \ @@ -1024,13 +1015,15 @@ toplevel/opttoploop.cmx: otherlibs/dynlink/dynlink.cmxa # The numeric opcodes -bytecomp/opcodes.ml: runtime/caml/instruct.h tools/make_opcodes - runtime/ocamlrun tools/make_opcodes -opcodes < $< > $@ +make_opcodes := tools/make_opcodes$(EXE) + +bytecomp/opcodes.ml: runtime/caml/instruct.h $(make_opcodes) + runtime/ocamlrun$(EXE) $(make_opcodes) -opcodes < $< > $@ bytecomp/opcodes.mli: bytecomp/opcodes.ml $(CAMLC) -i $< > $@ -tools/make_opcodes: tools/make_opcodes.mll +$(make_opcodes): tools/make_opcodes.mll $(MAKE) -C tools make_opcodes partialclean:: @@ -1076,22 +1069,19 @@ depend: beforedepend .PHONY: distclean distclean: clean - rm -f boot/ocamlrun boot/ocamlrun boot/ocamlrun.exe boot/camlheader \ + rm -f boot/ocamlrun boot/ocamlrun.exe boot/camlheader \ boot/*.cm* boot/libcamlrun.a boot/libcamlrun.lib boot/ocamlc.opt - rm -f Makefile.config Makefile.common runtime/caml/m.h runtime/caml/s.h + rm -f Makefile.config Makefile.build_config + rm -f runtime/caml/m.h runtime/caml/s.h rm -rf autom4te.cache rm -f config.log config.status libtool rm -f tools/eventlog_metadata rm -f tools/*.bak - rm -f ocaml ocamlc rm -f testsuite/_log* include .depend - -ifneq "$(strip $(CAN_BE_UNCONFIGURED))" "" -Makefile.config Makefile.common: config.status - +Makefile.config Makefile.build_config: config.status config.status: @echo "Please refer to the installation instructions:" @echo "- In file INSTALL for Unix systems." @@ -1103,4 +1093,3 @@ config.status: @echo " make install" @echo "should work." @false -endif diff --git a/Makefile.best_binaries b/Makefile.best_binaries index d9f4ec7b..fb3402b2 100644 --- a/Makefile.best_binaries +++ b/Makefile.best_binaries @@ -25,6 +25,9 @@ # native binary, if available. Note that they never use the boot/ # versions: we assume that ocamlc, ocamlopt, etc. have been run first. +# Set this to empty to force use of the bytecode compilers at all times +USE_BEST_BINARIES ?= true + check_not_stale = \ $(if $(shell test $(ROOTDIR)/$1 -nt $(ROOTDIR)/$2 && echo stale), \ $(info Warning: we are not using the native binary $2 \ @@ -34,13 +37,23 @@ or rebuilding it (or `touch`-ing it) if you want it used.), \ ok) choose_best = $(strip $(if \ - $(and $(wildcard $(ROOTDIR)/$1.opt),$(strip \ - $(call check_not_stale,$1,$1.opt))), \ - $(ROOTDIR)/$1.opt, \ - $(CAMLRUN) $(ROOTDIR)/$1)) + $(and $(USE_BEST_BINARIES),$(wildcard $(ROOTDIR)/$1.opt$(EXE)),$(strip \ + $(call check_not_stale,$1$(EXE),$1.opt$(EXE)))), \ + $(ROOTDIR)/$1.opt$(EXE), \ + $(CAMLRUN) $(ROOTDIR)/$1$(EXE))) BEST_OCAMLC := $(call choose_best,ocamlc) BEST_OCAMLOPT := $(call choose_best,ocamlopt) BEST_OCAMLLEX := $(call choose_best,lex/ocamllex) -BEST_OCAMLDEP := $(BEST_OCAMLC) -depend +# We want to be able to compute dependencies even if the bytecode compiler +# is not built yet, using the bootstrap compiler. + +# Unlike other tools, there is no risk of mixing incompatible +# bootrap-compiler and host-compiler object files, as ocamldep only +# produces text output. +BEST_OCAMLDEP := $(strip $(if \ + $(and $(USE_BEST_BINARIES),$(wildcard $(ROOTDIR)/ocamlc.opt$(EXE)),$(strip \ + $(call check_not_stale,boot/ocamlc,ocamlc.opt$(EXE)))), \ + $(ROOTDIR)/ocamlc.opt$(EXE) -depend, \ + $(BOOT_OCAMLC) -depend)) diff --git a/Makefile.build_config.in b/Makefile.build_config.in new file mode 100644 index 00000000..0dce5574 --- /dev/null +++ b/Makefile.build_config.in @@ -0,0 +1,36 @@ +# @configure_input@ + +#************************************************************************** +#* * +#* OCaml * +#* * +#* David Allsopp, OCaml Labs, Cambridge. * +#* * +#* Copyright 2020 MetaStack Solutions Ltd. * +#* * +#* All rights reserved. This file is distributed under the terms of * +#* the GNU Lesser General Public License version 2.1, with the * +#* special exception on linking described in the file LICENSE. * +#* * +#************************************************************************** + +# This Makefile contains configuration gleaned by configure but which should not +# be installed in Makefile.config. The file is designed to be included in +# OCaml's build system and so itself includes Makefile.config. It assumes that +# $(ROOTDIR) has been defined. + +include $(ROOTDIR)/Makefile.config +INSTALL ?= @INSTALL@ +INSTALL_DATA ?= @INSTALL_DATA@ +INSTALL_PROG ?= @INSTALL_PROGRAM@ + +# The command to generate C dependency information +DEP_CC=@DEP_CC@ -MM +COMPUTE_DEPS=@compute_deps@ + +# This is munged into utils/config.ml, not overridable by other parts of +# the build system. +OC_DLL_LDFLAGS=@oc_dll_ldflags@ + +# The rlwrap command (for the *runtop targets) +RLWRAP=@rlwrap@ diff --git a/Makefile.common.in b/Makefile.common similarity index 54% rename from Makefile.common.in rename to Makefile.common index 4087e4ba..f3e428a1 100644 --- a/Makefile.common.in +++ b/Makefile.common @@ -1,5 +1,3 @@ -# @configure_input@ - #************************************************************************** #* * #* OCaml * @@ -17,21 +15,19 @@ # This makefile contains common definitions and rules shared by # other Makefiles -# We assume that Makefile.config has already been included -INSTALL ?= @INSTALL@ -INSTALL_DATA ?= $(INSTALL) -m u=rw,g=rw,o=r -INSTALL_PROG ?= $(INSTALL) -m u=rwx,g=rwx,o=rx +include $(ROOTDIR)/Makefile.config_if_required + +# %(DEPDIR) must be kept in sync with entries in .gitignore +DEPDIR=.dep +D=d +MKDIR=mkdir -p -# note: these are defined by lazy expansions -# as some parts of the makefiles change BINDIR, etc. -# and expect INSTALL_BINDIR, etc. to stay in synch -# (see `shellquote` in tools/Makefile) DESTDIR ?= -INSTALL_BINDIR = $(DESTDIR)$(BINDIR) -INSTALL_LIBDIR = $(DESTDIR)$(LIBDIR) -INSTALL_STUBLIBDIR = $(DESTDIR)$(STUBLIBDIR) -INSTALL_MANDIR = $(DESTDIR)$(MANDIR) +INSTALL_BINDIR := $(DESTDIR)$(BINDIR) +INSTALL_LIBDIR := $(DESTDIR)$(LIBDIR) +INSTALL_STUBLIBDIR := $(DESTDIR)$(STUBLIBDIR) +INSTALL_MANDIR := $(DESTDIR)$(MANDIR) ifeq "$(UNIX_OR_WIN32)" "win32" FLEXDLL_SUBMODULE_PRESENT := $(wildcard $(ROOTDIR)/flexdll/Makefile) @@ -40,7 +36,7 @@ FLEXDLL_SUBMODULE_PRESENT = endif # Use boot/ocamlc.opt if available -CAMLRUN ?= $(ROOTDIR)/boot/ocamlrun +CAMLRUN ?= $(ROOTDIR)/boot/ocamlrun$(EXE) ifeq (0,$(shell \ test $(ROOTDIR)/boot/ocamlc.opt -nt $(ROOTDIR)/boot/ocamlc; \ echo $$?)) @@ -73,10 +69,54 @@ endif # By default, request ocamllex to be quiet OCAMLLEX_FLAGS ?= -q +# Escape special characters in the argument string. +# There are four characters that need escaping: +# - backslash and ampersand, which are special in the replacement text +# of sed's "s" command +# - exclamation mark, which is the delimiter we use for sed's "s" command +# - single quote, which interferes with shell quoting. We are inside +# single quotes already, so the proper escape is '\'' +# (close single quotation, insert single quote character, +# reopen single quotation). +SED_ESCAPE=$(subst ','\'',$(subst !,\!,$(subst &,\&,$(subst \,\\,$1)))) + +# Escape special characters in an OCaml string literal "..." +# There are two: backslash and double quote. +OCAML_ESCAPE=$(subst ",\",$(subst \,\\,$1)) + +# SUBST generates the sed substitution for the variable *named* in $1 +SUBST=-e 's!%%$1%%!$(call SED_ESCAPE,$($1))!' + +# SUBST_STRING does the same, for a variable that occurs between "..." +# in config.mlp. Thus, backslashes and double quotes must be escaped. +SUBST_STRING=-e 's!%%$1%%!$(call SED_ESCAPE,$(call OCAML_ESCAPE,$($1)))!' + # The rule to compile C files # This rule is similar to GNU make's implicit rule, except that it is more # general (it supports both .o and .obj) -%.$(O): %.c - $(CC) -c $(OC_CFLAGS) $(OC_CPPFLAGS) $(OUTPUTOBJ)$@ $< +ifneq "$(COMPUTE_DEPS)" "false" +RUNTIME_HEADERS := +REQUIRED_HEADERS := +else +RUNTIME_HEADERS := $(wildcard $(ROOTDIR)/runtime/caml/*.tbl) \ + $(wildcard $(ROOTDIR)/runtime/caml/*.h) +REQUIRED_HEADERS := $(RUNTIME_HEADERS) $(wildcard *.h) +endif + +%.$(O): %.c $(REQUIRED_HEADERS) + $(CC) -c $(OC_CFLAGS) $(CFLAGS) $(OC_CPPFLAGS) $(CPPFLAGS) \ + $(OUTPUTOBJ)$@ $< + +$(DEPDIR): + $(MKDIR) $@ + +# When executable files have an extension (e.g. ".exe"), +# provide phony synonyms +define PROGRAM_SYNONYM +ifneq ($(EXE),) +.PHONY: $(1) +$(1): $(1)$(EXE) +endif +endef # PROGRAM_SYNONYM diff --git a/Makefile.config.in b/Makefile.config.in index fe9b2331..652a1c5b 100644 --- a/Makefile.config.in +++ b/Makefile.config.in @@ -129,7 +129,7 @@ ARCH=@arch@ # Whether the architecture has 64 bits ARCH64=@arch64@ -# Endianess for this architecture +# Endianness for this architecture ENDIANNESS=@endianness@ ### Name of architecture model for the native-code compiler. @@ -165,7 +165,6 @@ INSTALL_BYTECODE_PROGRAMS=@install_bytecode_programs@ # dynlink Dynamic linking (bytecode and native) # (win32)unix Unix system calls # str Regular expressions and high-level string processing -# raw_spacetime_lib Parsing of spacetime traces # systhreads Same as threads, requires POSIX threads OTHERLIBRARIES=@otherlibraries@ @@ -173,16 +172,16 @@ OTHERLIBRARIES=@otherlibraries@ # Needed for the "systhreads" package PTHREAD_LINK=@pthread_link@ PTHREAD_CAML_LINK=$(addprefix -cclib ,$(PTHREAD_LINK)) +PTHREAD_CFLAGS=@PTHREAD_CFLAGS@ UNIX_OR_WIN32=@unix_or_win32@ UNIXLIB=@unixlib@ -BFD_CPPFLAGS=@bfd_cppflags@ -BFD_LDFLAGS=@bfd_ldflags@ -BFD_LDLIBS=@bfd_ldlibs@ INSTALL_SOURCE_ARTIFACTS=@install_source_artifacts@ OC_CFLAGS=@oc_cflags@ +CFLAGS?=@CFLAGS@ OC_CPPFLAGS=@oc_cppflags@ +CPPFLAGS?=@CPPFLAGS@ OCAMLC_CFLAGS=@ocamlc_cflags@ OCAMLC_CPPFLAGS=@ocamlc_cppflags@ @@ -226,13 +225,8 @@ WITH_OCAMLDOC=@ocamldoc@ WITH_OCAMLTEST=@ocamltest@ ASM_CFI_SUPPORTED=@asm_cfi_supported@ WITH_FRAME_POINTERS=@frame_pointers@ -WITH_SPACETIME=@spacetime@ -ENABLE_CALL_COUNTS=@call_counts@ WITH_PROFINFO=@profinfo@ PROFINFO_WIDTH=@profinfo_width@ -LIBUNWIND_AVAILABLE=@libunwind_available@ -LIBUNWIND_INCLUDE_FLAGS=@libunwind_include_flags@ -LIBUNWIND_LINK_FLAGS=@libunwind_link_flags@ WITH_FPIC=@fpic@ TARGET=@target@ HOST=@host@ @@ -242,12 +236,11 @@ FORCE_SAFE_STRING=@force_safe_string@ DEFAULT_SAFE_STRING=@default_safe_string@ WINDOWS_UNICODE=@windows_unicode@ AFL_INSTRUMENT=@afl@ -MAX_TESTSUITE_DIR_RETRIES=@max_testsuite_dir_retries@ FLAT_FLOAT_ARRAY=@flat_float_array@ FUNCTION_SECTIONS=@function_sections@ AWK=@AWK@ STDLIB_MANPAGES=@stdlib_manpages@ - +NAKED_POINTERS=@naked_pointers@ ### Native command to build ocamlrun.exe @@ -255,10 +248,10 @@ ifeq "$(TOOLCHAIN)" "msvc" MERGEMANIFESTEXE=test ! -f $(1).manifest \ || mt -nologo -outputresource:$(1) -manifest $(1).manifest \ && rm -f $(1).manifest - MKEXE_BOOT=$(CC) $(OC_CFLAGS) $(OUTPUTEXE)$(1) $(2) \ + MKEXE_BOOT=$(CC) $(OC_CFLAGS) $(CFLAGS) $(OUTPUTEXE)$(1) $(2) \ /link /subsystem:console $(OC_LDFLAGS) && ($(MERGEMANIFESTEXE)) else - MKEXE_BOOT=$(CC) $(OC_CFLAGS) $(OC_LDFLAGS) $(OUTPUTEXE)$(1) $(2) + MKEXE_BOOT=$(CC) $(OC_CFLAGS) $(CFLAGS) $(OC_LDFLAGS) $(OUTPUTEXE)$(1) $(2) endif # ifeq "$(TOOLCHAIN)" "msvc" # The following variables were defined only in the Windows-specific makefiles. @@ -276,7 +269,6 @@ ifeq "$(UNIX_OR_WIN32)" "win32" SORT=/usr/bin/sort SET_LD_PATH=PATH="$(PATH):$(LD_PATH)" FLEXLINK_CMD=flexlink - MKEXE_ANSI=$(FLEXLINK) -exe FLEXDLL_CHAIN=@flexdll_chain@ # FLEXLINK_FLAGS must be safe to insert in an OCaml string # (see ocamlmklibconfig.ml in tools/Makefile) diff --git a/otherlibs/raw_spacetime_lib/Makefile b/Makefile.config_if_required similarity index 60% rename from otherlibs/raw_spacetime_lib/Makefile rename to Makefile.config_if_required index 0a87a553..cc84164b 100644 --- a/otherlibs/raw_spacetime_lib/Makefile +++ b/Makefile.config_if_required @@ -2,9 +2,9 @@ #* * #* OCaml * #* * -#* Xavier Leroy, projet Cristal, INRIA Rocquencourt * +#* Gabriel Scherer, projet Parsifal, INRIA Saclay * #* * -#* Copyright 1999 Institut National de Recherche en Informatique et * +#* Copyright 2020 Institut National de Recherche en Informatique et * #* en Automatique. * #* * #* All rights reserved. This file is distributed under the terms of * @@ -13,21 +13,18 @@ #* * #************************************************************************** -# Makefile for Raw_spacetime_lib +ifeq "$(MAKECMDGOALS)" "" +MAKECMDGOALS += defaultentry +endif -LIBNAME=raw_spacetime_lib -COBJS=spacetime_offline.$(O) -CAMLOBJS=raw_spacetime_lib.cmo +CLEAN_TARGET_NAMES=clean partialclean distclean -include ../Makefile.otherlibs.common +# Some special targets ('*clean' and 'configure') do not require configuration. +# REQUIRES_CONFIGURATION is empty if only those targets are requested, +# and non-empty if configuration is required. +REQUIRES_CONFIGURATION := $(strip \ + $(filter-out $(CLEAN_TARGET_NAMES) configure, $(MAKECMDGOALS))) -.PHONY: depend -depend: -ifeq "$(TOOLCHAIN)" "msvc" - $(error Dependencies cannot be regenerated using the MSVC ports) -else - $(CC) -MM $(OC_CPPFLAGS) *.c | sed -e 's/\.o/.$$(O)/g' > .depend - $(CAMLRUN) $(ROOTDIR)/boot/ocamlc -depend -slash *.mli *.ml >> .depend +ifneq "$(REQUIRES_CONFIGURATION)" "" +include $(ROOTDIR)/Makefile.build_config endif - -include .depend diff --git a/Makefile.tools b/Makefile.tools index 49f4d2f6..75fa9bb4 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -47,7 +47,9 @@ SET_LD_PATH=CAML_LD_LIBRARY_PATH="$(LD_PATH)" # variable. Note that for Windows we add Unix-syntax directory names in # PATH, and Cygwin will translate it to Windows syntax. --include $(TOPDIR)/Makefile.config +# TOPDIR is legacy, our makefiles should use ROOTDIR now +ROOTDIR=$(TOPDIR) +include $(ROOTDIR)/Makefile.config_if_required # Make sure USE_RUNTIME is defined USE_RUNTIME ?= @@ -75,7 +77,7 @@ else CUSTOM = endif -OCAML=$(OCAMLRUN) $(OTOPDIR)/ocaml $(OCFLAGS) -noinit +OCAML=$(OCAMLRUN) $(OTOPDIR)/ocaml$(EXE) $(OCFLAGS) -noinit ifeq "$(FLEXLINK)" "" FLEXLINK_PREFIX= else @@ -83,24 +85,24 @@ else FLEXLINK_PREFIX= else EMPTY= - FLEXLINK_PREFIX=OCAML_FLEXLINK="$(WINTOPDIR)/boot/ocamlrun \ + FLEXLINK_PREFIX=OCAML_FLEXLINK="$(WINTOPDIR)/boot/ocamlrun$(EXE) \ $(WINTOPDIR)/flexdll/flexlink.exe" $(EMPTY) endif endif -OCAMLC=$(FLEXLINK_PREFIX)$(OCAMLRUN) $(OTOPDIR)/ocamlc $(CUSTOM) $(OCFLAGS) \ - $(RUNTIME_VARIANT) -OCAMLOPT=$(FLEXLINK_PREFIX)$(OCAMLRUN) $(OTOPDIR)/ocamlopt $(OCFLAGS) \ +OCAMLC=$(FLEXLINK_PREFIX)$(OCAMLRUN) $(OTOPDIR)/ocamlc$(EXE) \ + $(CUSTOM) $(OCFLAGS) $(RUNTIME_VARIANT) +OCAMLOPT=$(FLEXLINK_PREFIX)$(OCAMLRUN) $(OTOPDIR)/ocamlopt$(EXE) $(OCFLAGS) \ $(RUNTIME_VARIANT) -OCAMLDOC=$(OCAMLRUN) $(OTOPDIR)/ocamldoc/ocamldoc -OCAMLLEX=$(OCAMLRUN) $(OTOPDIR)/lex/ocamllex -OCAMLMKLIB=$(FLEXLINK_PREFIX)$(OCAMLRUN) $(OTOPDIR)/tools/ocamlmklib \ +OCAMLDOC=$(OCAMLRUN) $(OTOPDIR)/ocamldoc/ocamldoc$(EXE) +OCAMLLEX=$(OCAMLRUN) $(OTOPDIR)/lex/ocamllex$(EXE) +OCAMLMKLIB=$(FLEXLINK_PREFIX)$(OCAMLRUN) $(OTOPDIR)/tools/ocamlmklib$(EXE) \ -ocamlc "$(OTOPDIR)/runtime/ocamlrun$(USE_RUNTIME)$(EXE) \ - $(OTOPDIR)/ocamlc $(OCFLAGS) $(RUNTIME_VARIANT)" \ + $(OTOPDIR)/ocamlc$(EXE) $(OCFLAGS) $(RUNTIME_VARIANT)" \ -ocamlopt "$(OTOPDIR)/runtime/ocamlrun$(USE_RUNTIME)$(EXE) \ - $(OTOPDIR)/ocamlopt $(OCFLAGS) $(RUNTIME_VARIANT)" + $(OTOPDIR)/ocamlopt$(EXE) $(OCFLAGS) $(RUNTIME_VARIANT)" OCAMLYACC=$(TOPDIR)/yacc/ocamlyacc$(EXE) -DUMPOBJ=$(OCAMLRUN) $(OTOPDIR)/tools/dumpobj -OBJINFO=$(OCAMLRUN) $(OTOPDIR)/tools/ocamlobjinfo +DUMPOBJ=$(OCAMLRUN) $(OTOPDIR)/tools/dumpobj$(EXE) +OBJINFO=$(OCAMLRUN) $(OTOPDIR)/tools/ocamlobjinfo$(EXE) #FORTRAN_COMPILER= #FORTRAN_LIBRARY= diff --git a/README.adoc b/README.adoc index 4365c2f1..e4f5b7ab 100644 --- a/README.adoc +++ b/README.adoc @@ -1,10 +1,14 @@ |===== -| Branch `trunk` | Branch `4.10` | Branch `4.09` | Branch `4.08` | Branch `4.07` | Branch `4.06` | Branch `4.05` +| Branch `trunk` | Branch `4.11` | Branch `4.10` | Branch `4.09` | Branch `4.08` | Branch `4.07` | Branch `4.06` | Branch `4.05` | image:https://travis-ci.org/ocaml/ocaml.svg?branch=trunk["TravisCI Build Status (trunk branch)", link="https://travis-ci.org/ocaml/ocaml"] image:https://ci.appveyor.com/api/projects/status/github/ocaml/ocaml?branch=trunk&svg=true["AppVeyor Build Status (trunk branch)", link="https://ci.appveyor.com/project/avsm/ocaml"] +| image:https://travis-ci.org/ocaml/ocaml.svg?branch=4.11["TravisCI Build Status (4.11 branch)", + link="https://travis-ci.org/ocaml/ocaml"] + image:https://ci.appveyor.com/api/projects/status/github/ocaml/ocaml?branch=4.11&svg=true["AppVeyor Build Status (4.11 branch)", + link="https://ci.appveyor.com/project/avsm/ocaml"] | image:https://travis-ci.org/ocaml/ocaml.svg?branch=4.10["TravisCI Build Status (4.10 branch)", link="https://travis-ci.org/ocaml/ocaml"] image:https://ci.appveyor.com/api/projects/status/github/ocaml/ocaml?branch=4.10&svg=true["AppVeyor Build Status (4.10 branch)", @@ -58,7 +62,7 @@ compiler currently runs on the following platforms: | x86 64 bits | Linux, macOS, Windows, FreeBSD | NetBSD, OpenBSD | x86 32 bits | Linux, Windows | FreeBSD, NetBSD, OpenBSD -| ARM 64 bits | Linux | FreeBSD +| ARM 64 bits | Linux, macOS | FreeBSD | ARM 32 bits | Linux | FreeBSD, NetBSD, OpenBSD | Power 64 bits | Linux | | Power 32 bits | | Linux @@ -72,11 +76,10 @@ the compiler may work under other operating systems with little work. == Copyright -All files marked "Copyright INRIA" in this distribution are copyright 1996, -1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 -Institut National de Recherche en Informatique et en Automatique (INRIA) -and distributed under the conditions stated in file LICENSE. +All files marked "Copyright INRIA" in this distribution are +Copyright (C) 1996-2020 Institut National de Recherche en Informatique et +en Automatique (INRIA) and distributed under the conditions stated in +file LICENSE. == Installation @@ -136,3 +139,17 @@ using (machine type, etc). For information on contributing to OCaml, see link:HACKING.adoc[] and link:CONTRIBUTING.md[]. + +== Separately maintained components + +Some libraries and tools which used to be part of the OCaml distribution are +now maintained separately. Please use the issue trackers at their respective +new homes: + +- https://github.com/ocaml/graphics/issues[The Graphics library] (removed in OCaml 4.09) +- https://github.com/ocaml/num/issues[The Num library] (removed in OCaml 4.06) +- https://github.com/ocaml/ocamlbuild/issues[The OCamlbuild tool] (removed in OCaml 4.03) +- https://github.com/camlp4/camlp4/issues[The camlp4 tool] (removed in OCaml 4.02) +- https://github.com/garrigue/labltk/issues[The LablTk library] (removed in OCaml 4.02) +- https://github.com/ocaml/dbm/issues[The CamlDBM library] (removed in OCaml 4.00) +- https://github.com/xavierleroy/ocamltopwin/issues[The OCamlWinTop Windows toplevel] (removed in OCaml 4.00) diff --git a/VERSION b/VERSION index 571b8216..83d0f498 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ -4.11.2 +4.12.0 # The version string is the first line of this file. # It must be in the format described in stdlib/sys.mli diff --git a/aclocal.m4 b/aclocal.m4 index 5ac1b729..33873178 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -51,6 +51,8 @@ clang __clang_major__ __clang_minor__ gcc __GNUC__ __GNUC_MINOR__ #elif defined(__xlc__) && defined(__xlC__) xlc __xlC__ __xlC_ver__ +#elif defined(__SUNPRO_C) +sunc __SUNPRO_C __SUNPRO_C #else unknown #endif] @@ -94,6 +96,22 @@ AC_DEFUN([OCAML_CC_SUPPORTS_ALIGNED], [ AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])]) +AC_DEFUN([OCAML_CC_SUPPORTS_TREE_VECTORIZE], [ + AC_MSG_CHECKING( + [whether the C compiler supports __attribute__((optimize("tree-vectorize")))]) + saved_CFLAGS="$CFLAGS" + CFLAGS="-Werror $CFLAGS" + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([ + __attribute__((optimize("tree-vectorize"))) void f(void){} + int main() { f(); return 0; } + ])], + [AC_DEFINE([SUPPORTS_TREE_VECTORIZE]) + AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no])]) + CFLAGS="$saved_CFLAGS" +]) + AC_DEFUN([OCAML_CC_HAS_DEBUG_PREFIX_MAP], [ AC_MSG_CHECKING([whether the C compiler supports -fdebug-prefix-map]) saved_CFLAGS="$CFLAGS" diff --git a/asmcomp/CSEgen.ml b/asmcomp/CSEgen.ml index d71198ad..7ba1a1c2 100644 --- a/asmcomp/CSEgen.ml +++ b/asmcomp/CSEgen.ml @@ -222,15 +222,15 @@ method class_of_operation op = match op with | Imove | Ispill | Ireload -> assert false (* treated specially *) | Iconst_int _ | Iconst_float _ | Iconst_symbol _ -> Op_pure - | Icall_ind _ | Icall_imm _ | Itailcall_ind _ | Itailcall_imm _ + | Icall_ind | Icall_imm _ | Itailcall_ind | Itailcall_imm _ | Iextcall _ -> assert false (* treated specially *) | Istackoffset _ -> Op_other | Iload(_,_) -> Op_load | Istore(_,_,asg) -> Op_store asg | Ialloc _ -> assert false (* treated specially *) - | Iintop(Icheckbound _) -> Op_checkbound + | Iintop(Icheckbound) -> Op_checkbound | Iintop _ -> Op_pure - | Iintop_imm(Icheckbound _, _) -> Op_checkbound + | Iintop_imm(Icheckbound, _) -> Op_checkbound | Iintop_imm(_, _) -> Op_pure | Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf | Ifloatofint | Iintoffloat -> Op_pure @@ -255,7 +255,7 @@ method private kill_loads n = method private cse n i = match i.desc with - | Iend | Ireturn | Iop(Itailcall_ind _) | Iop(Itailcall_imm _) + | Iend | Ireturn | Iop(Itailcall_ind) | Iop(Itailcall_imm _) | Iexit _ | Iraise _ -> i | Iop (Imove | Ispill | Ireload) -> @@ -263,7 +263,7 @@ method private cse n i = as to the argument reg. *) let n1 = set_move n i.arg.(0) i.res.(0) in {i with next = self#cse n1 i.next} - | Iop (Icall_ind _ | Icall_imm _ | Iextcall _) -> + | Iop (Icall_ind | Icall_imm _ | Iextcall _) -> (* For function calls, we should at least forget: - equations involving memory loads, since the callee can perform arbitrary memory stores; diff --git a/asmcomp/afl_instrument.ml b/asmcomp/afl_instrument.ml index 7d4b90d2..c493a250 100644 --- a/asmcomp/afl_instrument.ml +++ b/asmcomp/afl_instrument.ml @@ -91,8 +91,8 @@ and instrument = function (* these are base cases and have no logging *) | Cconst_int _ | Cconst_natint _ | Cconst_float _ - | Cconst_symbol _ | Cconst_pointer _ | Cconst_natpointer _ - | Cblockheader _ | Cvar _ as c -> c + | Cconst_symbol _ + | Cvar _ as c -> c let instrument_function c dbg = with_afl_logging c dbg @@ -103,7 +103,7 @@ let instrument_initialiser c dbg = calls *) with_afl_logging (Csequence - (Cop (Cextcall ("caml_setup_afl", typ_int, false, None), + (Cop (Cextcall ("caml_setup_afl", typ_int, [], false), [Cconst_int (0, dbg ())], dbg ()), c)) diff --git a/asmcomp/amd64/arch.ml b/asmcomp/amd64/arch.ml index effe32ed..581db3db 100644 --- a/asmcomp/amd64/arch.ml +++ b/asmcomp/amd64/arch.ml @@ -50,8 +50,6 @@ type specific_operation = and float_operation = Ifloatadd | Ifloatsub | Ifloatmul | Ifloatdiv -let spacetime_node_hole_pointer_is_live_before _specific_op = false - (* Sizes, endianness *) let big_endian = false diff --git a/asmcomp/amd64/emit.mlp b/asmcomp/amd64/emit.mlp index 2ed41755..06988c67 100644 --- a/asmcomp/amd64/emit.mlp +++ b/asmcomp/amd64/emit.mlp @@ -172,16 +172,7 @@ let emit_label lbl = let label s = sym (emit_label s) -(* For Spacetime, keep track of code labels that have been emitted. *) -let used_labels = ref Int.Set.empty - -let mark_used lbl = - if Config.spacetime && not (Int.Set.mem lbl !used_labels) then begin - used_labels := Int.Set.add lbl !used_labels - end - let def_label ?typ s = - mark_used s; D.label ?typ (emit_label s) let emit_Llabel fallthrough lbl = @@ -250,12 +241,8 @@ let addressing addr typ i n = (* Record live pointers at call points -- see Emitaux *) -let record_frame_label ?label live dbg = - let lbl = - match label with - | None -> new_label() - | Some label -> label - in +let record_frame_label live dbg = + let lbl = new_label () in let live_offset = ref [] in Reg.Set.iter (function @@ -272,69 +259,46 @@ let record_frame_label ?label live dbg = ~live_offset:!live_offset dbg; lbl -let record_frame ?label live dbg = - let lbl = record_frame_label ?label live dbg in +let record_frame live dbg = + let lbl = record_frame_label live dbg in def_label lbl -(* Spacetime instrumentation *) - -let spacetime_before_uninstrumented_call ~node_ptr ~index = - (* At the moment, [node_ptr] is pointing at the node for the current - OCaml function. Get hold of the node itself and move the pointer - forwards, saving it into the distinguished register. This is used - for instrumentation of function calls (e.g. caml_call_gc and bounds - check failures) not inserted until this stage of the compiler - pipeline. *) - I.mov node_ptr (reg Proc.loc_spacetime_node_hole); - assert (index >= 2); - I.add (int (index * 8)) (reg Proc.loc_spacetime_node_hole) - (* Record calls to the GC -- we've moved them out of the way *) type gc_call = { gc_lbl: label; (* Entry label *) gc_return_lbl: label; (* Where to branch after GC *) gc_frame: label; (* Label of frame descriptor *) - gc_spacetime : (X86_ast.arg * int) option; - (* Spacetime node hole pointer and index *) } let call_gc_sites = ref ([] : gc_call list) let emit_call_gc gc = def_label gc.gc_lbl; - begin match gc.gc_spacetime with - | None -> assert (not Config.spacetime) - | Some (node_ptr, index) -> - assert Config.spacetime; - spacetime_before_uninstrumented_call ~node_ptr ~index - end; emit_call "caml_call_gc"; def_label gc.gc_frame; I.jmp (label gc.gc_return_lbl) (* Record calls to caml_ml_array_bound_error. - In -g mode, or when using Spacetime profiling, we maintain one call to + In -g mode we maintain one call to caml_ml_array_bound_error per bound check site. Without -g, we can share a single call. *) type bound_error_call = { bd_lbl: label; (* Entry label *) bd_frame: label; (* Label of frame descriptor *) - bd_spacetime : (X86_ast.arg * int) option; (* As for [gc_call]. *) } let bound_error_sites = ref ([] : bound_error_call list) let bound_error_call = ref 0 -let bound_error_label ?label dbg ~spacetime = - if !Clflags.debug || Config.spacetime then begin +let bound_error_label dbg = + if !Clflags.debug then begin let lbl_bound_error = new_label() in - let lbl_frame = record_frame_label ?label Reg.Set.empty (Dbg_other dbg) in + let lbl_frame = record_frame_label Reg.Set.empty (Dbg_other dbg) in bound_error_sites := - { bd_lbl = lbl_bound_error; bd_frame = lbl_frame; - bd_spacetime = spacetime; } :: !bound_error_sites; + { bd_lbl = lbl_bound_error; bd_frame = lbl_frame; } :: !bound_error_sites; lbl_bound_error end else begin if !bound_error_call = 0 then bound_error_call := new_label(); @@ -343,11 +307,6 @@ let bound_error_label ?label dbg ~spacetime = let emit_call_bound_error bd = def_label bd.bd_lbl; - begin match bd.bd_spacetime with - | None -> () - | Some (node_ptr, index) -> - spacetime_before_uninstrumented_call ~node_ptr ~index - end; emit_call "caml_ml_array_bound_error"; def_label bd.bd_frame @@ -575,21 +534,16 @@ let emit_instr fallthrough i = | Lop(Iconst_symbol s) -> add_used_symbol s; load_symbol_addr s (res i 0) - | Lop(Icall_ind { label_after; }) -> + | Lop(Icall_ind) -> I.call (arg i 0); - record_frame i.live (Dbg_other i.dbg) ~label:label_after - | Lop(Icall_imm { func; label_after; }) -> + record_frame i.live (Dbg_other i.dbg) + | Lop(Icall_imm { func; }) -> add_used_symbol func; emit_call func; - record_frame i.live (Dbg_other i.dbg) ~label:label_after - | Lop(Itailcall_ind { label_after; }) -> - output_epilogue begin fun () -> - I.jmp (arg i 0); - if Config.spacetime then begin - record_frame Reg.Set.empty (Dbg_other i.dbg) ~label:label_after - end - end - | Lop(Itailcall_imm { func; label_after; }) -> + record_frame i.live (Dbg_other i.dbg) + | Lop(Itailcall_ind) -> + output_epilogue (fun () -> I.jmp (arg i 0)) + | Lop(Itailcall_imm { func; }) -> begin if func = !function_name then I.jmp (label !tailrec_entry_point) @@ -599,16 +553,13 @@ let emit_instr fallthrough i = emit_jump func end end - end; - if Config.spacetime then begin - record_frame Reg.Set.empty (Dbg_other i.dbg) ~label:label_after end - | Lop(Iextcall { func; alloc; label_after; }) -> + | Lop(Iextcall { func; alloc; }) -> add_used_symbol func; if alloc then begin load_symbol_addr func rax; emit_call "caml_c_call"; - record_frame i.live (Dbg_other i.dbg) ~label:label_after; + record_frame i.live (Dbg_other i.dbg); if system <> S_win64 then begin (* TODO: investigate why such a diff. This comes from: @@ -620,10 +571,7 @@ let emit_instr fallthrough i = I.mov (domain_field Domainstate.Domain_young_ptr) r15 end end else begin - emit_call func; - if Config.spacetime then begin - record_frame Reg.Set.empty (Dbg_other i.dbg) ~label:label_after - end + emit_call func end | Lop(Istackoffset n) -> if n < 0 @@ -671,33 +619,24 @@ let emit_instr fallthrough i = | Double | Double_u -> I.movsd (arg i 0) (addressing addr REAL8 i 1) end - | Lop(Ialloc { bytes = n; label_after_call_gc; spacetime_index; dbginfo }) -> + | Lop(Ialloc { bytes = n; dbginfo }) -> assert (n <= (Config.max_young_wosize + 1) * Arch.size_addr); if !fastcode_flag then begin I.sub (int n) r15; I.cmp (domain_field Domainstate.Domain_young_limit) r15; let lbl_call_gc = new_label() in let lbl_frame = - record_frame_label ?label:label_after_call_gc i.live (Dbg_alloc dbginfo) + record_frame_label i.live (Dbg_alloc dbginfo) in I.jb (label lbl_call_gc); let lbl_after_alloc = new_label() in def_label lbl_after_alloc; I.lea (mem64 NONE 8 R15) (res i 0); - let gc_spacetime = - if not Config.spacetime then None - else Some (arg i 0, spacetime_index) - in call_gc_sites := { gc_lbl = lbl_call_gc; gc_return_lbl = lbl_after_alloc; - gc_frame = lbl_frame; - gc_spacetime; } :: !call_gc_sites + gc_frame = lbl_frame; } :: !call_gc_sites end else begin - if Config.spacetime then begin - spacetime_before_uninstrumented_call ~node_ptr:(arg i 0) - ~index:spacetime_index; - end; begin match n with | 16 -> emit_call "caml_alloc1" | 24 -> emit_call "caml_alloc2" @@ -706,10 +645,7 @@ let emit_instr fallthrough i = I.sub (int n) r15; emit_call "caml_allocN" end; - let label = - record_frame_label ?label:label_after_call_gc i.live - (Dbg_alloc dbginfo) - in + let label = record_frame_label i.live (Dbg_alloc dbginfo) in def_label label; I.lea (mem64 NONE 8 R15) (res i 0) end @@ -721,20 +657,12 @@ let emit_instr fallthrough i = I.cmp (int n) (arg i 0); I.set (cond cmp) al; I.movzx al (res i 0) - | Lop(Iintop (Icheckbound { label_after_error; spacetime_index; } )) -> - let spacetime = - if not Config.spacetime then None - else Some (arg i 2, spacetime_index) - in - let lbl = bound_error_label ?label:label_after_error i.dbg ~spacetime in + | Lop(Iintop (Icheckbound)) -> + let lbl = bound_error_label i.dbg in I.cmp (arg i 1) (arg i 0); I.jbe (label lbl) - | Lop(Iintop_imm(Icheckbound { label_after_error; spacetime_index; }, n)) -> - let spacetime = - if not Config.spacetime then None - else Some (arg i 1, spacetime_index) - in - let lbl = bound_error_label ?label:label_after_error i.dbg ~spacetime in + | Lop(Iintop_imm(Icheckbound, n)) -> + let lbl = bound_error_label i.dbg in I.cmp (int n) (arg i 0); I.jbe (label lbl) | Lop(Iintop(Idiv | Imod)) -> @@ -907,9 +835,6 @@ let emit_instr fallthrough i = cfi_adjust_cfa_offset (-8); stack_offset := !stack_offset - 16 | Lraise k -> - (* No Spacetime instrumentation is required for [caml_raise_exn] and - [caml_reraise_exn]. The only function called that might affect the - trie is [caml_stash_backtrace], and it does not. *) begin match k with | Lambda.Raise_regular -> I.mov (int 0) (domain_field Domainstate.Domain_backtrace_pos); @@ -1013,7 +938,6 @@ let begin_assembly() = reset_imp_table(); float_constants := []; all_functions := []; - used_labels := Int.Set.empty; if system = S_win64 then begin D.extrn "caml_call_gc" NEAR; D.extrn "caml_c_call" NEAR; @@ -1052,44 +976,6 @@ let begin_assembly() = if system = S_macosx then I.nop (); (* PR#4690 *) () -let emit_spacetime_shapes () = - D.data (); - D.align 8; - emit_global_label "spacetime_shapes"; - List.iter (fun fundecl -> - (* CR-someday mshinwell: some of this should be platform independent *) - begin match fundecl.fun_spacetime_shape with - | None -> () - | Some shape -> - (* Instrumentation that refers to dead code may have been eliminated. *) - match List.filter (fun (_, l) -> Int.Set.mem l !used_labels) shape with - | [] -> () - | shape -> - let funsym = emit_symbol fundecl.fun_name in - D.comment ("Shape for " ^ funsym ^ ":"); - D.qword (ConstLabel funsym); - List.iter (fun (part_of_shape, label) -> - let tag = - match part_of_shape with - | Direct_call_point _ -> 1 - | Indirect_call_point -> 2 - | Allocation_point -> 3 - in - D.qword (Const (Int64.of_int tag)); - D.qword (ConstLabel (emit_label label)); - begin match part_of_shape with - | Direct_call_point { callee; } -> - D.qword (ConstLabel (emit_symbol callee)) - | Indirect_call_point -> () - | Allocation_point -> () - end) - shape; - D.qword (Const 0L) - end) - !all_functions; - D.qword (Const 0L); - D.comment "End of Spacetime shapes." - let end_assembly() = if !float_constants <> [] then begin begin match system with @@ -1151,10 +1037,6 @@ let end_assembly() = D.size frametable (ConstSub (ConstThis, ConstLabel frametable)) end; - if Config.spacetime then begin - emit_spacetime_shapes () - end; - if system = S_linux then (* Mark stack as non-executable, PR#4564 *) D.section [".note.GNU-stack"] (Some "") [ "%progbits" ]; diff --git a/asmcomp/amd64/proc.ml b/asmcomp/amd64/proc.ml index 05b9633d..b44dfeb0 100644 --- a/asmcomp/amd64/proc.ml +++ b/asmcomp/amd64/proc.ml @@ -138,7 +138,6 @@ let rax = phys_reg 0 let rdx = phys_reg 4 let r10 = phys_reg 10 let r11 = phys_reg 11 -let r13 = phys_reg 9 let rbp = phys_reg 12 let rxmm15 = phys_reg 115 @@ -165,7 +164,7 @@ let calling_conventions first_int last_int first_float last_float make_stack let float = ref first_float in let ofs = ref 0 in for i = 0 to Array.length arg - 1 do - match arg.(i).typ with + match arg.(i) with | Val | Int | Addr as ty -> if !int <= last_int then begin loc.(i) <- phys_reg !int; @@ -190,21 +189,16 @@ let incoming ofs = Incoming ofs let outgoing ofs = Outgoing ofs let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" -let max_int_args_in_regs () = - if Config.spacetime then 9 else 10 - let loc_arguments arg = - calling_conventions 0 ((max_int_args_in_regs ()) - 1) 100 109 outgoing arg + calling_conventions 0 9 100 109 outgoing arg let loc_parameters arg = let (loc, _ofs) = - calling_conventions 0 ((max_int_args_in_regs ()) - 1) 100 109 incoming arg + calling_conventions 0 9 100 109 incoming arg in loc let loc_results res = let (loc, _ofs) = calling_conventions 0 0 100 100 not_supported res in loc -let loc_spacetime_node_hole = r13 - (* C calling conventions under Unix: first integer args in rdi, rsi, rdx, rcx, r8, r9 first float args in xmm0 ... xmm7 @@ -234,7 +228,7 @@ let win64_loc_external_arguments arg = let reg = ref 0 and ofs = ref 32 in for i = 0 to Array.length arg - 1 do - match arg.(i).typ with + match arg.(i) with | Val | Int | Addr as ty -> if !reg < 4 then begin loc.(i) <- phys_reg win64_int_external_arguments.(!reg); @@ -254,15 +248,14 @@ let win64_loc_external_arguments arg = done; (loc, Misc.align !ofs 16) (* keep stack 16-aligned *) -let loc_external_arguments arg = - let arg = - Array.map (fun regs -> assert (Array.length regs = 1); regs.(0)) arg - in - let loc, alignment = - if win64 then win64_loc_external_arguments arg +let loc_external_arguments ty_args = + let arg = Cmm.machtype_of_exttype_list ty_args in + let loc, stack_ofs = + if win64 + then win64_loc_external_arguments arg else unix_loc_external_arguments arg in - Array.map (fun reg -> [|reg|]) loc, alignment + Array.map (fun reg -> [|reg|]) loc, stack_ofs let loc_exn_bucket = rax @@ -301,23 +294,14 @@ let destroyed_at_c_call = 100;101;102;103;104;105;106;107; 108;109;110;111;112;113;114;115]) -let destroyed_by_spacetime_at_alloc = - if Config.spacetime then - [| loc_spacetime_node_hole |] - else - [| |] - let destroyed_at_alloc = - let regs = - if X86_proc.use_plt then - destroyed_by_plt_stub - else - [| r11 |] - in - Array.concat [regs; destroyed_by_spacetime_at_alloc] + if X86_proc.use_plt then + destroyed_by_plt_stub + else + [| r11 |] let destroyed_at_oper = function - Iop(Icall_ind _ | Icall_imm _ | Iextcall { alloc = true; }) -> + Iop(Icall_ind | Icall_imm _ | Iextcall { alloc = true; }) -> all_phys_regs | Iop(Iextcall { alloc = false; }) -> destroyed_at_c_call | Iop(Iintop(Idiv | Imod)) | Iop(Iintop_imm((Idiv | Imod), _)) @@ -326,10 +310,6 @@ let destroyed_at_oper = function | Iop(Ialloc _) -> destroyed_at_alloc | Iop(Iintop(Imulh | Icomp _) | Iintop_imm((Icomp _), _)) -> [| rax |] - | Iop (Iintop (Icheckbound _)) when Config.spacetime -> - [| loc_spacetime_node_hole |] - | Iop (Iintop_imm(Icheckbound _, _)) when Config.spacetime -> - [| loc_spacetime_node_hole |] | Iswitch(_, _) -> [| rax; rdx |] | Itrywith _ -> [| r11 |] | _ -> @@ -372,9 +352,9 @@ let max_register_pressure = function registers). *) let op_is_pure = function - | Icall_ind _ | Icall_imm _ | Itailcall_ind _ | Itailcall_imm _ + | Icall_ind | Icall_imm _ | Itailcall_ind | Itailcall_imm _ | Iextcall _ | Istackoffset _ | Istore _ | Ialloc _ - | Iintop(Icheckbound _) | Iintop_imm(Icheckbound _, _) -> false + | Iintop(Icheckbound) | Iintop_imm(Icheckbound, _) -> false | Ispecific(Ilea _|Isextend32|Izextend32) -> true | Ispecific _ -> false | _ -> true diff --git a/asmcomp/amd64/reload.ml b/asmcomp/amd64/reload.ml index 16819c09..8939fa03 100644 --- a/asmcomp/amd64/reload.ml +++ b/asmcomp/amd64/reload.ml @@ -65,7 +65,7 @@ inherit Reloadgen.reload_generic as super method! reload_operation op arg res = match op with - | Iintop(Iadd|Isub|Iand|Ior|Ixor|Icomp _|Icheckbound _) -> + | Iintop(Iadd|Isub|Iand|Ior|Ixor|Icomp _|Icheckbound) -> (* One of the two arguments can reside in the stack, but not both *) if stackp arg.(0) && stackp arg.(1) then ([|arg.(0); self#makereg arg.(1)|], res) diff --git a/asmcomp/amd64/selection.ml b/asmcomp/amd64/selection.ml index bd7871cf..7df0d10d 100644 --- a/asmcomp/amd64/selection.ml +++ b/asmcomp/amd64/selection.ml @@ -121,17 +121,24 @@ let inline_ops = [ "sqrt"; "caml_bswap16_direct"; "caml_int32_direct_bswap"; "caml_int64_direct_bswap"; "caml_nativeint_direct_bswap" ] +let is_immediate n = n <= 0x7FFF_FFFF && n >= -0x8000_0000 + +let is_immediate_natint n = n <= 0x7FFF_FFFFn && n >= -0x8000_0000n + (* The selector class *) class selector = object (self) -inherit Spacetime_profiling.instruction_selection as super +inherit Selectgen.selector_generic as super -method is_immediate n = n <= 0x7FFF_FFFF && n >= (-1-0x7FFF_FFFF) - (* -1-.... : hack so that this can be compiled on 32-bit - (cf 'make check_all_arches') *) +method! is_immediate op n = + match op with + | Iadd | Isub | Imul | Iand | Ior | Ixor | Icomp _ | Icheckbound -> + is_immediate n + | _ -> + super#is_immediate op n -method is_immediate_natint n = n <= 0x7FFFFFFFn && n >= -0x80000000n +method is_immediate_test _cmp n = is_immediate n method! is_simple_expr e = match e with @@ -153,7 +160,7 @@ method! effects_of e = method select_addressing _chunk exp = let (a, d) = select_addr exp in (* PR#4625: displacement must be a signed 32-bit immediate *) - if not (self # is_immediate d) + if not (is_immediate d) then (Iindexed 0, exp) else match a with | Asymbol s -> @@ -169,16 +176,9 @@ method select_addressing _chunk exp = method! select_store is_assign addr exp = match exp with - Cconst_int (n, _dbg) when self#is_immediate n -> - (Ispecific(Istore_int(Nativeint.of_int n, addr, is_assign)), Ctuple []) - | (Cconst_natint (n, _dbg)) when self#is_immediate_natint n -> - (Ispecific(Istore_int(n, addr, is_assign)), Ctuple []) - | (Cblockheader(n, _dbg)) - when self#is_immediate_natint n && not Config.spacetime -> - (Ispecific(Istore_int(n, addr, is_assign)), Ctuple []) - | Cconst_pointer (n, _dbg) when self#is_immediate n -> + Cconst_int (n, _dbg) when is_immediate n -> (Ispecific(Istore_int(Nativeint.of_int n, addr, is_assign)), Ctuple []) - | Cconst_natpointer (n, _dbg) when self#is_immediate_natint n -> + | (Cconst_natint (n, _dbg)) when is_immediate_natint n -> (Ispecific(Istore_int(n, addr, is_assign)), Ctuple []) | _ -> super#select_store is_assign addr exp @@ -201,7 +201,7 @@ method! select_operation op args dbg = self#select_floatarith true Imulf Ifloatmul args | Cdivf -> self#select_floatarith false Idivf Ifloatdiv args - | Cextcall("sqrt", _, false, _) -> + | Cextcall("sqrt", _, _, false) -> begin match args with [Cop(Cload ((Double|Double_u as chunk), _), [loc], _dbg)] -> let (addr, arg) = self#select_addressing chunk loc in @@ -215,7 +215,7 @@ method! select_operation op args dbg = | Cstore ((Word_int|Word_val as chunk), _init) -> begin match args with [loc; Cop(Caddi, [Cop(Cload _, [loc'], _); Cconst_int (n, _dbg)], _)] - when loc = loc' && self#is_immediate n -> + when loc = loc' && is_immediate n -> let (addr, arg) = self#select_addressing chunk loc in (Ispecific(Ioffset_loc(n, addr)), [arg]) | _ -> @@ -228,12 +228,9 @@ method! select_operation op args dbg = | Cextcall("caml_int64_direct_bswap", _, _, _) | Cextcall("caml_nativeint_direct_bswap", _, _, _) -> (Ispecific (Ibswap 64), args) - (* AMD64 does not support immediate operands for multiply high signed *) - | Cmulhi -> - (Iintop Imulh, args) + (* Recognize sign extension *) | Casr -> begin match args with - (* Recognize sign extension *) [Cop(Clsl, [k; Cconst_int (32, _)], _); Cconst_int (32, _)] -> (Ispecific Isextend32, [k]) | _ -> super#select_operation op args dbg diff --git a/asmcomp/arm/arch.ml b/asmcomp/arm/arch.ml index becfff38..4b884da6 100644 --- a/asmcomp/arm/arch.ml +++ b/asmcomp/arm/arch.ml @@ -141,8 +141,6 @@ and shift_operation = | Ishiftlogicalright | Ishiftarithmeticright -let spacetime_node_hole_pointer_is_live_before _specific_op = false - (* Sizes, endianness *) let big_endian = false diff --git a/asmcomp/arm/emit.mlp b/asmcomp/arm/emit.mlp index b880319b..e44f7652 100644 --- a/asmcomp/arm/emit.mlp +++ b/asmcomp/arm/emit.mlp @@ -105,12 +105,8 @@ let emit_addressing addr r n = (* Record live pointers at call points *) -let record_frame_label ?label live dbg = - let lbl = - match label with - | None -> new_label() - | Some label -> label - in +let record_frame_label live dbg = + let lbl = new_label () in let live_offset = ref [] in Reg.Set.iter (function @@ -126,8 +122,8 @@ let record_frame_label ?label live dbg = ~live_offset:!live_offset dbg; lbl -let record_frame ?label live dbg = - let lbl = record_frame_label ?label live dbg in `{emit_label lbl}:` +let record_frame live dbg = + let lbl = record_frame_label live dbg in `{emit_label lbl}:` (* Record calls to the GC -- we've moved them out of the way *) @@ -152,10 +148,10 @@ type bound_error_call = let bound_error_sites = ref ([] : bound_error_call list) -let bound_error_label ?label dbg = +let bound_error_label dbg = if !Clflags.debug || !bound_error_sites = [] then begin let lbl_bound_error = new_label() in - let lbl_frame = record_frame_label ?label Reg.Set.empty (Dbg_other dbg) in + let lbl_frame = record_frame_label Reg.Set.empty (Dbg_other dbg) in bound_error_sites := { bd_lbl = lbl_bound_error; bd_frame_lbl = lbl_frame } :: !bound_error_sites; @@ -539,25 +535,25 @@ let emit_instr i = end; 1 | Lop(Iconst_symbol s) -> emit_load_symbol_addr i.res.(0) s - | Lop(Icall_ind { label_after; }) -> + | Lop(Icall_ind) -> if !arch >= ARMv5 then begin ` blx {emit_reg i.arg.(0)}\n`; - `{record_frame i.live (Dbg_other i.dbg) ~label:label_after}\n`; 1 + `{record_frame i.live (Dbg_other i.dbg)}\n`; 1 end else begin ` mov lr, pc\n`; ` bx {emit_reg i.arg.(0)}\n`; - `{record_frame i.live (Dbg_other i.dbg) ~label:label_after}\n`; 2 + `{record_frame i.live (Dbg_other i.dbg)}\n`; 2 end - | Lop(Icall_imm { func; label_after; }) -> + | Lop(Icall_imm { func; }) -> ` {emit_call func}\n`; - `{record_frame i.live (Dbg_other i.dbg) ~label:label_after}\n`; 1 - | Lop(Itailcall_ind { label_after = _; }) -> + `{record_frame i.live (Dbg_other i.dbg)}\n`; 1 + | Lop(Itailcall_ind) -> output_epilogue begin fun () -> if !contains_calls then ` ldr lr, [sp, #{emit_int (-4)}]\n`; ` bx {emit_reg i.arg.(0)}\n`; 2 end - | Lop(Itailcall_imm { func; label_after = _; }) -> + | Lop(Itailcall_imm { func; }) -> if func = !function_name then begin ` b {emit_label !tailrec_entry_point}\n`; 1 end else begin @@ -569,10 +565,10 @@ let emit_instr i = end | Lop(Iextcall { func; alloc = false; }) -> ` {emit_call func}\n`; 1 - | Lop(Iextcall { func; alloc = true; label_after; }) -> + | Lop(Iextcall { func; alloc = true; }) -> let ninstr = emit_load_symbol_addr (phys_reg 7 (* r7 *)) func in ` {emit_call "caml_c_call"}\n`; - `{record_frame i.live (Dbg_other i.dbg) ~label:label_after}\n`; + `{record_frame i.live (Dbg_other i.dbg)}\n`; 1 + ninstr | Lop(Istackoffset n) -> assert (n mod 8 = 0); @@ -642,9 +638,9 @@ let emit_instr i = | Double_u -> "fstd" | _ (* 32-bit quantities *) -> "str" in ` {emit_string instr} {emit_reg r}, {emit_addressing addr i.arg 1}\n`; 1 - | Lop(Ialloc { bytes = n; label_after_call_gc; dbginfo }) -> + | Lop(Ialloc { bytes = n; dbginfo }) -> let lbl_frame = - record_frame_label i.live (Dbg_alloc dbginfo) ?label:label_after_call_gc + record_frame_label i.live (Dbg_alloc dbginfo) in if !fastcode_flag then begin let ninstr = decompose_intconst @@ -682,12 +678,12 @@ let emit_instr i = | Lop(Iintop_imm(Icomp cmp, n)) -> ` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`; 1 + emit_set_condition cmp i.res.(0) - | Lop(Iintop (Icheckbound { label_after_error; } )) -> - let lbl = bound_error_label ?label:label_after_error i.dbg in + | Lop(Iintop (Icheckbound)) -> + let lbl = bound_error_label i.dbg in ` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ` bls {emit_label lbl}\n`; 2 - | Lop(Iintop_imm(Icheckbound { label_after_error; }, n)) -> - let lbl = bound_error_label ?label:label_after_error i.dbg in + | Lop(Iintop_imm(Icheckbound, n)) -> + let lbl = bound_error_label i.dbg in ` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`; ` bls {emit_label lbl}\n`; 2 | Lop(Ispecific(Ishiftcheckbound(shiftop, n))) -> diff --git a/asmcomp/arm/proc.ml b/asmcomp/arm/proc.ml index 9ac9cf13..1da4386b 100644 --- a/asmcomp/arm/proc.ml +++ b/asmcomp/arm/proc.ml @@ -107,71 +107,60 @@ let phys_reg n = let stack_slot slot ty = Reg.at_location ty (Stack slot) -let loc_spacetime_node_hole = Reg.dummy (* Spacetime unsupported *) - (* Calling conventions *) +let loc_int last_int make_stack int ofs = + if !int <= last_int then begin + let l = phys_reg !int in + incr int; l + end else begin + let l = stack_slot (make_stack !ofs) Int in + ofs := !ofs + size_int; l + end + +let loc_float last_float make_stack float ofs = + assert (abi = EABI_HF); + assert (!fpu >= VFPv2); + if !float <= last_float then begin + let l = phys_reg !float in + incr float; l + end else begin + ofs := Misc.align !ofs size_float; + let l = stack_slot (make_stack !ofs) Float in + ofs := !ofs + size_float; l + end + +let loc_int_pair last_int make_stack int ofs = + (* 64-bit quantities split across two registers must either be in a + consecutive pair of registers where the lowest numbered is an + even-numbered register; or in a stack slot that is 8-byte aligned. *) + int := Misc.align !int 2; + if !int <= last_int - 1 then begin + let reg_lower = phys_reg !int in + let reg_upper = phys_reg (1 + !int) in + int := !int + 2; + [| reg_lower; reg_upper |] + end else begin + let size_int64 = size_int * 2 in + ofs := Misc.align !ofs size_int64; + let stack_lower = stack_slot (make_stack !ofs) Int in + let stack_upper = stack_slot (make_stack (size_int + !ofs)) Int in + ofs := !ofs + size_int64; + [| stack_lower; stack_upper |] + end + let calling_conventions first_int last_int first_float last_float make_stack arg = - let loc = Array.make (Array.length arg) [| Reg.dummy |] in + let loc = Array.make (Array.length arg) Reg.dummy in let int = ref first_int in let float = ref first_float in let ofs = ref 0 in for i = 0 to Array.length arg - 1 do match arg.(i) with - | [| arg |] -> - begin match arg.typ with - | Val | Int | Addr as ty -> - if !int <= last_int then begin - loc.(i) <- [| phys_reg !int |]; - incr int - end else begin - loc.(i) <- [| stack_slot (make_stack !ofs) ty |]; - ofs := !ofs + size_int - end - | Float -> - assert (abi = EABI_HF); - assert (!fpu >= VFPv2); - if !float <= last_float then begin - loc.(i) <- [| phys_reg !float |]; - incr float - end else begin - ofs := Misc.align !ofs size_float; - loc.(i) <- [| stack_slot (make_stack !ofs) Float |]; - ofs := !ofs + size_float - end - end - | [| arg1; arg2 |] -> - (* Passing of 64-bit quantities to external functions. *) - begin match arg1.typ, arg2.typ with - | Int, Int -> - (* 64-bit quantities split across two registers must either be in a - consecutive pair of registers where the lowest numbered is an - even-numbered register; or in a stack slot that is 8-byte - aligned. *) - int := Misc.align !int 2; - if !int <= last_int - 1 then begin - let reg_lower = phys_reg !int in - let reg_upper = phys_reg (1 + !int) in - loc.(i) <- [| reg_lower; reg_upper |]; - int := !int + 2 - end else begin - let size_int64 = size_int * 2 in - ofs := Misc.align !ofs size_int64; - let stack_lower = stack_slot (make_stack !ofs) Int in - let stack_upper = stack_slot (make_stack (size_int + !ofs)) Int in - loc.(i) <- [| stack_lower; stack_upper |]; - ofs := !ofs + size_int64 - end - | _, _ -> - let f = function Int -> "I" | Addr -> "A" | Val -> "V" | Float -> "F" in - fatal_error (Printf.sprintf "Proc.calling_conventions: bad register \ - type(s) for multi-register argument: %s, %s" - (f arg1.typ) (f arg2.typ)) - end - | _ -> - fatal_error "Proc.calling_conventions: bad number of registers for \ - multi-register argument" + | Val | Int | Addr -> + loc.(i) <- loc_int last_int make_stack int ofs + | Float -> + loc.(i) <- loc_float last_float make_stack float ofs done; (loc, Misc.align !ofs 8) (* keep stack 8-aligned *) @@ -187,40 +176,50 @@ let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" let max_arguments_for_tailcalls = 8 -let single_regs arg = Array.map (fun arg -> [| arg |]) arg -let ensure_single_regs res = - Array.map (function - | [| res |] -> res - | _ -> failwith "Proc.ensure_single_regs") - res - let loc_arguments arg = - let (loc, alignment) = - calling_conventions 0 7 100 115 outgoing (single_regs arg) - in - ensure_single_regs loc, alignment + calling_conventions 0 7 100 115 outgoing arg + let loc_parameters arg = - let (loc, _) = calling_conventions 0 7 100 115 incoming (single_regs arg) in - ensure_single_regs loc + let (loc, _) = calling_conventions 0 7 100 115 incoming arg in loc + let loc_results res = - let (loc, _) = - calling_conventions 0 7 100 115 not_supported (single_regs res) - in - ensure_single_regs loc + let (loc, _) = calling_conventions 0 7 100 115 not_supported res in loc (* C calling convention: first integer args in r0...r3 + first 64-bit integer args in r0-r1, r2-r3 first float args in d0...d7 (EABI+VFP) + first float args in r0-r1, r2-r3 (soft FP) remaining args on stack. - Return values in r0...r1 or d0. *) + Return values in r0, r0-r1, or d0. *) + +let external_calling_conventions first_int last_int first_float last_float + make_stack ty_args = + let loc = Array.make (List.length ty_args) [| Reg.dummy |] in + let int = ref first_int in + let float = ref first_float in + let ofs = ref 0 in + List.iteri + (fun i ty_arg -> + match ty_arg with + | XInt | XInt32 -> + loc.(i) <- [| loc_int last_int make_stack int ofs |] + | XInt64 -> + loc.(i) <- loc_int_pair last_int make_stack int ofs + | XFloat -> + loc.(i) <- + (if abi = EABI_HF + then [| loc_float last_float make_stack float ofs |] + else loc_int_pair last_int make_stack int ofs)) + ty_args; + (loc, Misc.align !ofs 8) (* keep stack 8-aligned *) + +let loc_external_arguments ty_args = + external_calling_conventions 0 3 100 107 outgoing ty_args -let loc_external_arguments arg = - calling_conventions 0 3 100 107 outgoing arg let loc_external_results res = - let (loc, _) = - calling_conventions 0 1 100 100 not_supported (single_regs res) - in - ensure_single_regs loc + let (loc, _) = calling_conventions 0 1 100 100 not_supported res + in loc let loc_exn_bucket = phys_reg 0 @@ -288,7 +287,7 @@ let destroyed_at_c_call = 124;125;126;127;128;129;130;131])) let destroyed_at_oper = function - Iop(Icall_ind _ | Icall_imm _) + Iop(Icall_ind | Icall_imm _) | Iop(Iextcall { alloc = true; _ }) -> all_phys_regs | Iop(Iextcall { alloc = false; _}) -> @@ -334,9 +333,9 @@ let max_register_pressure = function registers). *) let op_is_pure = function - | Icall_ind _ | Icall_imm _ | Itailcall_ind _ | Itailcall_imm _ + | Icall_ind | Icall_imm _ | Itailcall_ind | Itailcall_imm _ | Iextcall _ | Istackoffset _ | Istore _ | Ialloc _ - | Iintop(Icheckbound _) | Iintop_imm(Icheckbound _, _) + | Iintop(Icheckbound) | Iintop_imm(Icheckbound, _) | Ispecific(Ishiftcheckbound _) -> false | _ -> true diff --git a/asmcomp/arm/scheduling.ml b/asmcomp/arm/scheduling.ml index 4039eaac..9d847d4c 100644 --- a/asmcomp/arm/scheduling.ml +++ b/asmcomp/arm/scheduling.ml @@ -58,8 +58,8 @@ method oper_issue_cycles = function | Iintop(Ilsl | Ilsr | Iasr) -> 2 | Iintop(Icomp _) | Iintop_imm(Icomp _, _) -> 3 - | Iintop(Icheckbound _) - | Iintop_imm(Icheckbound _, _) -> 2 + | Iintop(Icheckbound) + | Iintop_imm(Icheckbound, _) -> 2 | Ispecific(Ishiftcheckbound _) -> 3 | Iintop(Imul | Imulh) | Ispecific(Imuladd | Imulsub | Imulhadd) -> 2 diff --git a/asmcomp/arm/selection.ml b/asmcomp/arm/selection.ml index f43c13d9..7dee0dad 100644 --- a/asmcomp/arm/selection.ml +++ b/asmcomp/arm/selection.ml @@ -78,7 +78,7 @@ let pseudoregs_for_operation op arg res = (arg', res) (* We use __aeabi_idivmod for Cmodi only, and hence we care only for the remainder in r1, so fix up the destination register. *) - | Iextcall { func = "__aeabi_idivmod"; alloc = false; } -> + | Iextcall { func = "__aeabi_idivmod"; _ } -> (arg, [|r1|]) (* Other instructions are regular *) | _ -> raise Use_default @@ -102,8 +102,15 @@ method! regs_for tyv = tyv end) -method is_immediate n = - is_immediate (Int32.of_int n) +method! is_immediate op n = + match op with + | Iadd | Isub | Iand | Ior | Ixor | Icomp _ | Icheckbound -> + Arch.is_immediate (Int32.of_int n) + | _ -> + super#is_immediate op n + +method is_immediate_test _op n = + Arch.is_immediate (Int32.of_int n) method! is_simple_expr = function (* inlined floating-point ops are simple if their arguments are *) @@ -113,7 +120,7 @@ method! is_simple_expr = function | Cop(Cextcall("caml_bswap16_direct", _, _, _), args, _) when !arch >= ARMv6T2 -> List.for_all self#is_simple_expr args - | Cop(Cextcall("caml_int32_direct_bswap",_,_,_), args, _) + | Cop(Cextcall("caml_int32_direct_bswap", _, _, _), args, _) when !arch >= ARMv6 -> List.for_all self#is_simple_expr args | e -> super#is_simple_expr e @@ -125,7 +132,7 @@ method! effects_of e = | Cop(Cextcall("caml_bswap16_direct", _, _, _), args, _) when !arch >= ARMv6T2 -> Selectgen.Effect_and_coeffect.join_list_map args self#effects_of - | Cop(Cextcall("caml_int32_direct_bswap",_,_,_), args, _) + | Cop(Cextcall("caml_int32_direct_bswap",_ ,_ , _), args, _) when !arch >= ARMv6 -> Selectgen.Effect_and_coeffect.join_list_map args self#effects_of | e -> super#effects_of e @@ -179,23 +186,24 @@ method select_shift_arith op dbg arithop arithrevop args = | op_args -> op_args end -method private iextcall (func, alloc) = - Iextcall { func; alloc; label_after = Cmm.new_label (); } +method private iextcall func ty_res ty_args = + Iextcall { func; ty_res; ty_args; alloc = false; } method! select_operation op args dbg = match (op, args) with - (* Recognize special shift arithmetic *) - ((Caddv | Cadda | Caddi), [arg; Cconst_int (n, _)]) - when n < 0 && self#is_immediate (-n) -> + (* Recognize special forms of add immediate / sub immediate *) + | ((Caddv | Cadda | Caddi), [arg; Cconst_int (n, _)]) + when n < 0 && Arch.is_immediate (Int32.of_int (-n)) -> (Iintop_imm(Isub, -n), [arg]) - | ((Caddv | Cadda | Caddi as op), args) -> - self#select_shift_arith op dbg Ishiftadd Ishiftadd args | (Csubi, [arg; Cconst_int (n, _)]) - when n < 0 && self#is_immediate (-n) -> + when n < 0 && Arch.is_immediate (Int32.of_int (-n)) -> (Iintop_imm(Iadd, -n), [arg]) | (Csubi, [Cconst_int (n, _); arg]) - when self#is_immediate n -> + when Arch.is_immediate (Int32.of_int n) -> (Ispecific(Irevsubimm n), [arg]) + (* Recognize special shift arithmetic *) + | ((Caddv | Cadda | Caddi as op), args) -> + self#select_shift_arith op dbg Ishiftadd Ishiftadd args | (Csubi as op, args) -> self#select_shift_arith op dbg Ishiftsub Ishiftsubrev args | (Cand as op, args) -> @@ -208,17 +216,12 @@ method! select_operation op args dbg = [Cop(Clsl | Clsr | Casr as op, [arg1; Cconst_int (n, _)], _); arg2]) when n > 0 && n < 32 -> (Ispecific(Ishiftcheckbound(select_shiftop op, n)), [arg1; arg2]) - (* ARM does not support immediate operands for multiplication *) - | (Cmuli, args) -> - (Iintop Imul, args) - | (Cmulhi, args) -> - (Iintop Imulh, args) (* Turn integer division/modulus into runtime ABI calls *) | (Cdivi, args) -> - (self#iextcall("__aeabi_idiv", false), args) + (self#iextcall "__aeabi_idiv" typ_int [], args) | (Cmodi, args) -> (* See above for fix up of return register *) - (self#iextcall("__aeabi_idivmod", false), args) + (self#iextcall "__aeabi_idivmod" typ_int [], args) (* Recognize 16-bit bswap instruction (ARMv6T2 because we need movt) *) | (Cextcall("caml_bswap16_direct", _, _, _), args) when !arch >= ARMv6T2 -> (Ispecific(Ibswap 16), args) @@ -234,12 +237,18 @@ method! select_operation op args dbg = method private select_operation_softfp op args dbg = match (op, args) with (* Turn floating-point operations into runtime ABI calls *) - | (Caddf, args) -> (self#iextcall("__aeabi_dadd", false), args) - | (Csubf, args) -> (self#iextcall("__aeabi_dsub", false), args) - | (Cmulf, args) -> (self#iextcall("__aeabi_dmul", false), args) - | (Cdivf, args) -> (self#iextcall("__aeabi_ddiv", false), args) - | (Cfloatofint, args) -> (self#iextcall("__aeabi_i2d", false), args) - | (Cintoffloat, args) -> (self#iextcall("__aeabi_d2iz", false), args) + | (Caddf, args) -> + (self#iextcall "__aeabi_dadd" typ_float [XFloat;XFloat], args) + | (Csubf, args) -> + (self#iextcall "__aeabi_dsub" typ_float [XFloat;XFloat], args) + | (Cmulf, args) -> + (self#iextcall "__aeabi_dmul" typ_float [XFloat;XFloat], args) + | (Cdivf, args) -> + (self#iextcall "__aeabi_ddiv" typ_float [XFloat;XFloat], args) + | (Cfloatofint, args) -> + (self#iextcall "__aeabi_i2d" typ_float [XInt], args) + | (Cintoffloat, args) -> + (self#iextcall "__aeabi_d2iz" typ_int [XFloat], args) | (Ccmpf comp, args) -> let comp, func = match comp with @@ -255,14 +264,16 @@ method private select_operation_softfp op args dbg = | CFnge -> Ceq, "__aeabi_dcmpge" in (Iintop_imm(Icomp(Iunsigned comp), 0), - [Cop(Cextcall(func, typ_int, false, None), args, dbg)]) + [Cop(Cextcall(func, typ_int, [XFloat;XFloat], false), + args, dbg)]) (* Add coercions around loads and stores of 32-bit floats *) | (Cload (Single, mut), args) -> - (self#iextcall("__aeabi_f2d", false), + (self#iextcall "__aeabi_f2d" typ_float [XInt], [Cop(Cload (Word_int, mut), args, dbg)]) | (Cstore (Single, init), [arg1; arg2]) -> let arg2' = - Cop(Cextcall("__aeabi_d2f", typ_int, false, None), [arg2], dbg) in + Cop(Cextcall("__aeabi_d2f", typ_int, [XFloat], false), + [arg2], dbg) in self#select_operation (Cstore (Word_int, init)) [arg1; arg2'] dbg (* Other operations are regular *) | (op, args) -> super#select_operation op args dbg @@ -287,7 +298,7 @@ method private select_operation_vfpv3 op args dbg = | (Csubf, [Cop(Cmulf, args, _); arg]) -> (Ispecific Imulsubf, arg :: args) (* Recognize floating-point square root *) - | (Cextcall("sqrt", _, false, _), args) -> + | (Cextcall("sqrt", _, _, false), args) -> (Ispecific Isqrtf, args) (* Other operations are regular *) | (op, args) -> super#select_operation op args dbg diff --git a/asmcomp/arm64/NOTES.md b/asmcomp/arm64/NOTES.md index e2134eb1..68ba2a5a 100644 --- a/asmcomp/arm64/NOTES.md +++ b/asmcomp/arm64/NOTES.md @@ -10,3 +10,4 @@ Debian architecture name: `arm64`. _ARM Architecture Reference Manual, ARMv8_, restricted to the AArch64 subset. * Application binary interface: _Procedure Call Standard for the ARM 64-bit Architecture (AArch64)_ + _Apple ARM64 Function Calling Conventions_ diff --git a/asmcomp/arm64/arch.ml b/asmcomp/arm64/arch.ml index 9cf923c6..8d8561bc 100644 --- a/asmcomp/arm64/arch.ml +++ b/asmcomp/arm64/arch.ml @@ -19,6 +19,10 @@ open Format +let macosx = (Config.system = "macosx") + +(* Machine-specific command-line options *) + let command_line_options = [] (* Addressing modes *) @@ -38,15 +42,12 @@ type cmm_label = int (* Do not introduce a dependency to Cmm *) type specific_operation = - | Ifar_alloc of { bytes : int; label_after_call_gc : cmm_label option; - dbginfo : Debuginfo.alloc_dbginfo } - | Ifar_intop_checkbound of { label_after_error : cmm_label option; } - | Ifar_intop_imm_checkbound of - { bound : int; label_after_error : cmm_label option; } + | Ifar_alloc of { bytes : int; dbginfo : Debuginfo.alloc_dbginfo } + | Ifar_intop_checkbound + | Ifar_intop_imm_checkbound of { bound : int; } | Ishiftarith of arith_operation * int - | Ishiftcheckbound of { shift : int; label_after_error : cmm_label option; } - | Ifar_shiftcheckbound of - { shift : int; label_after_error : cmm_label option; } + | Ishiftcheckbound of { shift : int; } + | Ifar_shiftcheckbound of { shift : int; } | Imuladd (* multiply and add *) | Imulsub (* multiply and subtract *) | Inegmulf (* floating-point negate and multiply *) @@ -56,17 +57,12 @@ type specific_operation = | Inegmulsubf (* floating-point negate, multiply and subtract *) | Isqrtf (* floating-point square root *) | Ibswap of int (* endianness conversion *) + | Imove32 (* 32-bit integer move *) and arith_operation = Ishiftadd | Ishiftsub -let spacetime_node_hole_pointer_is_live_before = function - | Ifar_alloc _ | Ifar_intop_checkbound _ | Ifar_intop_imm_checkbound _ - | Ishiftarith _ | Ishiftcheckbound _ | Ifar_shiftcheckbound _ -> false - | Imuladd | Imulsub | Inegmulf | Imuladdf | Inegmuladdf | Imulsubf - | Inegmulsubf | Isqrtf | Ibswap _ -> false - (* Sizes, endianness *) let big_endian = false @@ -108,11 +104,11 @@ let print_addressing printreg addr ppf arg = let print_specific_operation printreg op ppf arg = match op with - | Ifar_alloc { bytes; label_after_call_gc = _; } -> + | Ifar_alloc { bytes; } -> fprintf ppf "(far) alloc %i" bytes - | Ifar_intop_checkbound _ -> + | Ifar_intop_checkbound -> fprintf ppf "%a (far) check > %a" printreg arg.(0) printreg arg.(1) - | Ifar_intop_imm_checkbound { bound; _ } -> + | Ifar_intop_imm_checkbound { bound; } -> fprintf ppf "%a (far) check > %i" printreg arg.(0) bound | Ishiftarith(op, shift) -> let op_name = function @@ -124,10 +120,10 @@ let print_specific_operation printreg op ppf arg = else sprintf ">> %i" (-shift) in fprintf ppf "%a %s %a %s" printreg arg.(0) (op_name op) printreg arg.(1) shift_mark - | Ishiftcheckbound { shift; _ } -> + | Ishiftcheckbound { shift; } -> fprintf ppf "check %a >> %i > %a" printreg arg.(0) shift printreg arg.(1) - | Ifar_shiftcheckbound { shift; _ } -> + | Ifar_shiftcheckbound { shift; } -> fprintf ppf "(far) check %a >> %i > %a" printreg arg.(0) shift printreg arg.(1) | Imuladd -> @@ -170,3 +166,6 @@ let print_specific_operation printreg op ppf arg = | Ibswap n -> fprintf ppf "bswap%i %a" n printreg arg.(0) + | Imove32 -> + fprintf ppf "move32 %a" + printreg arg.(0) diff --git a/asmcomp/arm64/emit.mlp b/asmcomp/arm64/emit.mlp index cddfc08a..85a951c2 100644 --- a/asmcomp/arm64/emit.mlp +++ b/asmcomp/arm64/emit.mlp @@ -38,18 +38,35 @@ let reg_trap_ptr = phys_reg 23 let reg_alloc_ptr = phys_reg 24 let reg_alloc_limit = phys_reg 25 let reg_tmp1 = phys_reg 26 -let reg_x15 = phys_reg 15 +let reg_x8 = phys_reg 8 (* Output a label *) +let label_prefix = + if macosx then "L" else ".L" + let emit_label lbl = - emit_string ".L"; emit_int lbl + emit_string label_prefix; emit_int lbl (* Symbols *) let emit_symbol s = + if macosx then emit_string "_"; Emitaux.emit_symbol '$' s +(* Object types *) + +let emit_symbol_type emit_lbl_or_sym lbl_or_sym ty = + if not macosx then begin + ` .type {emit_lbl_or_sym lbl_or_sym}, %{emit_string ty}\n` + end + + +let emit_symbol_size sym = + if not macosx then begin + ` .size {emit_symbol sym}, .-{emit_symbol sym}\n` + end + (* Output a pseudo-register *) let emit_reg = function @@ -78,12 +95,15 @@ let prologue_required = ref false let contains_calls = ref false -let frame_size () = - let sz = - !stack_offset + +let initial_stack_offset () = 8 * num_stack_slots.(0) + 8 * num_stack_slots.(1) + (if !contains_calls then 8 else 0) + +let frame_size () = + let sz = + !stack_offset + + initial_stack_offset () in Misc.align sz 16 let slot_offset loc cl = @@ -126,12 +146,8 @@ let emit_addressing addr r = (* Record live pointers at call points *) -let record_frame_label ?label live dbg = - let lbl = - match label with - | None -> new_label() - | Some label -> label - in +let record_frame_label live dbg = + let lbl = new_label () in let live_offset = ref [] in Reg.Set.iter (function @@ -147,8 +163,8 @@ let record_frame_label ?label live dbg = ~live_offset:!live_offset dbg; lbl -let record_frame ?label live dbg = - let lbl = record_frame_label ?label live dbg in `{emit_label lbl}:` +let record_frame live dbg = + let lbl = record_frame_label live dbg in `{emit_label lbl}:` (* Record calls to the GC -- we've moved them out of the way *) @@ -173,10 +189,10 @@ type bound_error_call = let bound_error_sites = ref ([] : bound_error_call list) -let bound_error_label ?label dbg = +let bound_error_label dbg = if !Clflags.debug || !bound_error_sites = [] then begin let lbl_bound_error = new_label() in - let lbl_frame = record_frame_label ?label Reg.Set.empty (Dbg_other dbg) in + let lbl_frame = record_frame_label Reg.Set.empty (Dbg_other dbg) in bound_error_sites := { bd_lbl = lbl_bound_error; bd_frame_lbl = lbl_frame } :: !bound_error_sites; @@ -301,6 +317,37 @@ let output_epilogue f = (* reset CFA back because function body may continue *) if n > 0 then cfi_adjust_cfa_offset n +(* Output add-immediate / sub-immediate / cmp-immediate instructions *) + +let rec emit_addimm rd rs n = + if n < 0 then emit_subimm rd rs (-n) + else if n <= 0xFFF then + ` add {emit_reg rd}, {emit_reg rs}, #{emit_int n}\n` + else begin + assert (n <= 0xFFF_FFF); + let nl = n land 0xFFF and nh = n land 0xFFF_000 in + ` add {emit_reg rd}, {emit_reg rs}, #{emit_int nh}\n`; + if nl <> 0 then + ` add {emit_reg rd}, {emit_reg rd}, #{emit_int nl}\n` + end + +and emit_subimm rd rs n = + if n < 0 then emit_addimm rd rs (-n) + else if n <= 0xFFF then + ` sub {emit_reg rd}, {emit_reg rs}, #{emit_int n}\n` + else begin + assert (n <= 0xFFF_FFF); + let nl = n land 0xFFF and nh = n land 0xFFF_000 in + ` sub {emit_reg rd}, {emit_reg rs}, #{emit_int nh}\n`; + if nl <> 0 then + ` sub {emit_reg rd}, {emit_reg rd}, #{emit_int nl}\n` + end + +let emit_cmpimm rs n = + if n >= 0 + then ` cmp {emit_reg rs}, #{emit_int n}\n` + else ` cmn {emit_reg rs}, #{emit_int (-n)}\n` + (* Name of current function *) let function_name = ref "" (* Entry point for tail recursive calls *) @@ -320,6 +367,8 @@ let float_literal f = (* Emit all pending literals *) let emit_literals() = if !float_literals <> [] then begin + if macosx then + ` .section __TEXT,__literal8,8byte_literals\n`; ` .align 3\n`; List.iter (fun (f, lbl) -> @@ -331,7 +380,10 @@ let emit_literals() = (* Emit code to load the address of a symbol *) let emit_load_symbol_addr dst s = - if not !Clflags.dlcode then begin + if macosx then begin + ` adrp {emit_reg dst}, {emit_symbol s}@GOTPAGE\n`; + ` ldr {emit_reg dst}, [{emit_reg dst}, {emit_symbol s}@GOTPAGEOFF]\n` + end else if not !Clflags.dlcode then begin ` adrp {emit_reg dst}, {emit_symbol s}\n`; ` add {emit_reg dst}, {emit_reg dst}, #:lo12:{emit_symbol s}\n` end else begin @@ -349,8 +401,8 @@ let num_call_gc_and_check_bound_points instr = | Lend -> totals | Lop (Ialloc _) when !fastcode_flag -> loop instr.next (call_gc + 1, check_bound) - | Lop (Iintop Icheckbound _) - | Lop (Iintop_imm (Icheckbound _, _)) + | Lop (Iintop Icheckbound) + | Lop (Iintop_imm (Icheckbound, _)) | Lop (Ispecific (Ishiftcheckbound _)) -> let check_bound = (* When not in debug mode, there is at most one check-bound point. *) @@ -361,7 +413,7 @@ let num_call_gc_and_check_bound_points instr = (* The following four should never be seen, since this function is run before branch relaxation. *) | Lop (Ispecific (Ifar_alloc _)) - | Lop (Ispecific Ifar_intop_checkbound _) + | Lop (Ispecific Ifar_intop_checkbound) | Lop (Ispecific (Ifar_intop_imm_checkbound _)) | Lop (Ispecific (Ifar_shiftcheckbound _)) -> assert false | _ -> loop instr.next totals @@ -407,8 +459,8 @@ module BR = Branch_relaxation.Make (struct let classify_instr = function | Lop (Ialloc _) - | Lop (Iintop Icheckbound _) - | Lop (Iintop_imm (Icheckbound _, _)) + | Lop (Iintop Icheckbound) + | Lop (Iintop_imm (Icheckbound, _)) | Lop (Ispecific (Ishiftcheckbound _)) -> Some Bcc (* The various "far" variants in [specific_operation] don't need to return [Some] here, since their code sequences never contain any @@ -427,7 +479,7 @@ module BR = Branch_relaxation.Make (struct let offset_pc_at_branch = 0 let prologue_size () = - (if frame_size () > 0 then 2 else 0) + (if initial_stack_offset () > 0 then 2 else 0) + (if !contains_calls then 1 else 0) let epilogue_size () = @@ -441,9 +493,9 @@ module BR = Branch_relaxation.Make (struct num_instructions_for_intconst n | Lop (Iconst_float _) -> 2 | Lop (Iconst_symbol _) -> 2 - | Lop (Icall_ind _) -> 1 + | Lop (Icall_ind) -> 1 | Lop (Icall_imm _) -> 1 - | Lop (Itailcall_ind _) -> epilogue_size () + | Lop (Itailcall_ind) -> epilogue_size () | Lop (Itailcall_imm { func; _ }) -> if func = !function_name then 1 else epilogue_size () | Lop (Iextcall { alloc = false; }) -> 1 @@ -464,9 +516,9 @@ module BR = Branch_relaxation.Make (struct end | Lop (Iintop (Icomp _)) -> 2 | Lop (Iintop_imm (Icomp _, _)) -> 2 - | Lop (Iintop (Icheckbound _)) -> 2 - | Lop (Ispecific (Ifar_intop_checkbound _)) -> 3 - | Lop (Iintop_imm (Icheckbound _, _)) -> 2 + | Lop (Iintop (Icheckbound)) -> 2 + | Lop (Ispecific (Ifar_intop_checkbound)) -> 3 + | Lop (Iintop_imm (Icheckbound, _)) -> 2 | Lop (Ispecific (Ifar_intop_imm_checkbound _)) -> 3 | Lop (Ispecific (Ishiftcheckbound _)) -> 2 | Lop (Ispecific (Ifar_shiftcheckbound _)) -> 3 @@ -481,6 +533,7 @@ module BR = Branch_relaxation.Make (struct | Lop (Ispecific (Imuladd | Imulsub)) -> 1 | Lop (Ispecific (Ibswap 16)) -> 2 | Lop (Ispecific (Ibswap _)) -> 1 + | Lop (Ispecific Imove32) -> 1 | Lop (Iname_for_debugger _) -> 0 | Lreloadretaddr -> 0 | Lreturn -> epilogue_size () @@ -512,26 +565,26 @@ module BR = Branch_relaxation.Make (struct | Lambda.Raise_notrace -> 4 end - let relax_allocation ~num_bytes ~label_after_call_gc ~dbginfo = - Lop (Ispecific (Ifar_alloc { bytes = num_bytes; label_after_call_gc; dbginfo })) + let relax_allocation ~num_bytes ~dbginfo = + Lop (Ispecific (Ifar_alloc { bytes = num_bytes; dbginfo })) - let relax_intop_checkbound ~label_after_error = - Lop (Ispecific (Ifar_intop_checkbound { label_after_error; })) + let relax_intop_checkbound () = + Lop (Ispecific (Ifar_intop_checkbound)) - let relax_intop_imm_checkbound ~bound ~label_after_error = - Lop (Ispecific (Ifar_intop_imm_checkbound { bound; label_after_error; })) + let relax_intop_imm_checkbound ~bound = + Lop (Ispecific (Ifar_intop_imm_checkbound { bound; })) let relax_specific_op = function - | Ishiftcheckbound { shift; label_after_error; } -> - Lop (Ispecific (Ifar_shiftcheckbound { shift; label_after_error; })) + | Ishiftcheckbound { shift; } -> + Lop (Ispecific (Ifar_shiftcheckbound { shift; })) | _ -> assert false end) (* Output the assembly code for allocation. *) -let assembly_code_for_allocation ~label_after_call_gc i ~n ~far ~dbginfo = +let assembly_code_for_allocation i ~n ~far ~dbginfo = let lbl_frame = - record_frame_label ?label:label_after_call_gc i.live (Dbg_alloc dbginfo) + record_frame_label i.live (Dbg_alloc dbginfo) in if !fastcode_flag then begin let lbl_after_alloc = new_label() in @@ -561,7 +614,7 @@ let assembly_code_for_allocation ~label_after_call_gc i ~n ~far ~dbginfo = | 16 -> ` bl {emit_symbol "caml_alloc1"}\n` | 24 -> ` bl {emit_symbol "caml_alloc2"}\n` | 32 -> ` bl {emit_symbol "caml_alloc3"}\n` - | _ -> emit_intconst reg_x15 (Nativeint.of_int n); + | _ -> emit_intconst reg_x8 (Nativeint.of_int n); ` bl {emit_symbol "caml_allocN"}\n` end; `{emit_label lbl_frame}: add {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, #8\n` @@ -576,6 +629,17 @@ let emit_named_text_section func_name = else ` .text\n` +(* Emit code to load an emitted literal *) + +let emit_load_literal dst lbl = + if macosx then begin + ` adrp {emit_reg reg_tmp1}, {emit_label lbl}@PAGE\n`; + ` ldr {emit_reg dst}, [{emit_reg reg_tmp1}, {emit_label lbl}@PAGEOFF]\n` + end else begin + ` adrp {emit_reg reg_tmp1}, {emit_label lbl}\n`; + ` ldr {emit_reg dst}, [{emit_reg reg_tmp1}, #:lo12:{emit_label lbl}]\n` + end + (* Output the assembly code for an instruction *) let emit_instr i = @@ -606,6 +670,19 @@ let emit_instr i = | _ -> assert false end + | Lop(Ispecific Imove32) -> + let src = i.arg.(0) and dst = i.res.(0) in + if src.loc <> dst.loc then begin + match (src, dst) with + | {loc = Reg _}, {loc = Reg _} -> + ` mov {emit_wreg dst}, {emit_wreg src}\n` + | {loc = Reg _}, {loc = Stack _} -> + ` str {emit_wreg src}, {emit_stack dst}\n` + | {loc = Stack _}, {loc = Reg _} -> + ` ldr {emit_wreg dst}, {emit_stack src}\n` + | _ -> + assert false + end | Lop(Iconst_int n) -> emit_intconst i.res.(0) n | Lop(Iconst_float f) -> @@ -615,30 +692,29 @@ let emit_instr i = ` fmov {emit_reg i.res.(0)}, #{emit_printf "%.7f" (Int64.float_of_bits f)}\n` else begin let lbl = float_literal f in - ` adrp {emit_reg reg_tmp1}, {emit_label lbl}\n`; - ` ldr {emit_reg i.res.(0)}, [{emit_reg reg_tmp1}, #:lo12:{emit_label lbl}]\n` + emit_load_literal i.res.(0) lbl end | Lop(Iconst_symbol s) -> emit_load_symbol_addr i.res.(0) s - | Lop(Icall_ind { label_after; }) -> + | Lop(Icall_ind) -> ` blr {emit_reg i.arg.(0)}\n`; - `{record_frame i.live (Dbg_other i.dbg) ~label:label_after}\n` - | Lop(Icall_imm { func; label_after; }) -> + `{record_frame i.live (Dbg_other i.dbg)}\n` + | Lop(Icall_imm { func; }) -> ` bl {emit_symbol func}\n`; - `{record_frame i.live (Dbg_other i.dbg) ~label:label_after}\n` - | Lop(Itailcall_ind { label_after = _; }) -> + `{record_frame i.live (Dbg_other i.dbg)}\n` + | Lop(Itailcall_ind) -> output_epilogue (fun () -> ` br {emit_reg i.arg.(0)}\n`) - | Lop(Itailcall_imm { func; label_after = _; }) -> + | Lop(Itailcall_imm { func; }) -> if func = !function_name then ` b {emit_label !tailrec_entry_point}\n` else output_epilogue (fun () -> ` b {emit_symbol func}\n`) - | Lop(Iextcall { func; alloc = false; label_after = _; }) -> + | Lop(Iextcall { func; alloc = false; }) -> ` bl {emit_symbol func}\n` - | Lop(Iextcall { func; alloc = true; label_after; }) -> - emit_load_symbol_addr reg_x15 func; + | Lop(Iextcall { func; alloc = true; }) -> + emit_load_symbol_addr reg_x8 func; ` bl {emit_symbol "caml_c_call"}\n`; - `{record_frame i.live (Dbg_other i.dbg) ~label:label_after}\n` + `{record_frame i.live (Dbg_other i.dbg)}\n` | Lop(Istackoffset n) -> assert (n mod 16 = 0); emit_stack_adjustment (-n); @@ -693,45 +769,49 @@ let emit_instr i = | Word_int | Word_val | Double | Double_u -> ` str {emit_reg src}, {emit_addressing addr base}\n` end - | Lop(Ialloc { bytes = n; label_after_call_gc; dbginfo }) -> - assembly_code_for_allocation i ~n ~far:false ~label_after_call_gc ~dbginfo - | Lop(Ispecific (Ifar_alloc { bytes = n; label_after_call_gc; dbginfo })) -> - assembly_code_for_allocation i ~n ~far:true ~label_after_call_gc ~dbginfo + | Lop(Ialloc { bytes = n; dbginfo }) -> + assembly_code_for_allocation i ~n ~far:false ~dbginfo + | Lop(Ispecific (Ifar_alloc { bytes = n; dbginfo })) -> + assembly_code_for_allocation i ~n ~far:true ~dbginfo + | Lop(Iintop_imm(Iadd, n)) -> + emit_addimm i.res.(0) i.arg.(0) n + | Lop(Iintop_imm(Isub, n)) -> + emit_subimm i.res.(0) i.arg.(0) n | Lop(Iintop(Icomp cmp)) -> ` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ` cset {emit_reg i.res.(0)}, {emit_string (name_for_comparison cmp)}\n` | Lop(Iintop_imm(Icomp cmp, n)) -> - ` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`; + emit_cmpimm i.arg.(0) n; ` cset {emit_reg i.res.(0)}, {emit_string (name_for_comparison cmp)}\n` - | Lop(Iintop (Icheckbound { label_after_error; })) -> - let lbl = bound_error_label i.dbg ?label:label_after_error in + | Lop(Iintop (Icheckbound)) -> + let lbl = bound_error_label i.dbg in ` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ` b.ls {emit_label lbl}\n` - | Lop(Ispecific Ifar_intop_checkbound { label_after_error; }) -> - let lbl = bound_error_label i.dbg ?label:label_after_error in + | Lop(Ispecific Ifar_intop_checkbound) -> + let lbl = bound_error_label i.dbg in let lbl2 = new_label () in ` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ` b.hi {emit_label lbl2}\n`; ` b {emit_label lbl}\n`; `{emit_label lbl2}:\n`; - | Lop(Iintop_imm(Icheckbound { label_after_error; }, n)) -> - let lbl = bound_error_label i.dbg ?label:label_after_error in - ` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`; + | Lop(Iintop_imm(Icheckbound, n)) -> + let lbl = bound_error_label i.dbg in + emit_cmpimm i.arg.(0) n; ` b.ls {emit_label lbl}\n` | Lop(Ispecific( - Ifar_intop_imm_checkbound { bound; label_after_error; })) -> - let lbl = bound_error_label i.dbg ?label:label_after_error in + Ifar_intop_imm_checkbound { bound; })) -> + let lbl = bound_error_label i.dbg in let lbl2 = new_label () in ` cmp {emit_reg i.arg.(0)}, #{emit_int bound}\n`; ` b.hi {emit_label lbl2}\n`; ` b {emit_label lbl}\n`; `{emit_label lbl2}:\n`; - | Lop(Ispecific(Ishiftcheckbound { shift; label_after_error; })) -> - let lbl = bound_error_label i.dbg ?label:label_after_error in + | Lop(Ispecific(Ishiftcheckbound { shift; })) -> + let lbl = bound_error_label i.dbg in ` cmp {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}, lsr #{emit_int shift}\n`; ` b.cs {emit_label lbl}\n` - | Lop(Ispecific(Ifar_shiftcheckbound { shift; label_after_error; })) -> - let lbl = bound_error_label i.dbg ?label:label_after_error in + | Lop(Ispecific(Ifar_shiftcheckbound { shift; })) -> + let lbl = bound_error_label i.dbg in let lbl2 = new_label () in ` cmp {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}, lsr #{emit_int shift}\n`; ` b.lo {emit_label lbl2}\n`; @@ -820,7 +900,7 @@ let emit_instr i = let comp = name_for_comparison cmp in ` b.{emit_string comp} {emit_label lbl}\n` | Iinttest_imm(cmp, n) -> - ` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`; + emit_cmpimm i.arg.(0) n; let comp = name_for_comparison cmp in ` b.{emit_string comp} {emit_label lbl}\n` | Ifloattest cmp -> @@ -936,7 +1016,7 @@ let fundecl fundecl = emit_named_text_section !function_name; ` .align 3\n`; ` .globl {emit_symbol fundecl.fun_name}\n`; - ` .type {emit_symbol fundecl.fun_name}, %function\n`; + emit_symbol_type emit_symbol fundecl.fun_name "function"; `{emit_symbol fundecl.fun_name}:\n`; emit_debug_info fundecl.fun_dbg; cfi_startproc(); @@ -954,8 +1034,8 @@ let fundecl fundecl = assert (List.length !call_gc_sites = num_call_gc); assert (List.length !bound_error_sites = num_check_bound); cfi_endproc(); - ` .type {emit_symbol fundecl.fun_name}, %function\n`; - ` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`; + emit_symbol_type emit_symbol fundecl.fun_name "function"; + emit_symbol_size fundecl.fun_name; emit_literals() (* Emission of data *) @@ -1018,10 +1098,10 @@ let end_assembly () = `{emit_symbol lbl}:\n`; emit_frames { efa_code_label = (fun lbl -> - ` .type {emit_label lbl}, %function\n`; + emit_symbol_type emit_label lbl "function"; ` .quad {emit_label lbl}\n`); efa_data_label = (fun lbl -> - ` .type {emit_label lbl}, %object\n`; + emit_symbol_type emit_label lbl "object"; ` .quad {emit_label lbl}\n`); efa_8 = (fun n -> ` .byte {emit_int n}\n`); efa_16 = (fun n -> ` .short {emit_int n}\n`); @@ -1032,8 +1112,8 @@ let end_assembly () = ` .long {emit_label lbl} - . + {emit_int32 ofs}\n`); efa_def_label = (fun lbl -> `{emit_label lbl}:\n`); efa_string = (fun s -> emit_string_directive " .asciz " s) }; - ` .type {emit_symbol lbl}, %object\n`; - ` .size {emit_symbol lbl}, .-{emit_symbol lbl}\n`; + emit_symbol_type emit_symbol lbl "object"; + emit_symbol_size lbl; begin match Config.system with | "linux" -> (* Mark stack as non-executable *) diff --git a/asmcomp/arm64/proc.ml b/asmcomp/arm64/proc.ml index ff0b785d..7635181a 100644 --- a/asmcomp/arm64/proc.ml +++ b/asmcomp/arm64/proc.ml @@ -99,16 +99,44 @@ let all_phys_regs = let phys_reg n = if n < 100 then hard_int_reg.(n) else hard_float_reg.(n - 100) -let reg_x15 = phys_reg 15 +let reg_x8 = phys_reg 8 let reg_d7 = phys_reg 107 let stack_slot slot ty = Reg.at_location ty (Stack slot) -let loc_spacetime_node_hole = Reg.dummy (* Spacetime unsupported *) - (* Calling conventions *) +let loc_int last_int make_stack int ofs = + if !int <= last_int then begin + let l = phys_reg !int in + incr int; l + end else begin + ofs := Misc.align !ofs size_int; + let l = stack_slot (make_stack !ofs) Int in + ofs := !ofs + size_int; l + end + +let loc_float last_float make_stack float ofs = + if !float <= last_float then begin + let l = phys_reg !float in + incr float; l + end else begin + ofs := Misc.align !ofs size_float; + let l = stack_slot (make_stack !ofs) Float in + ofs := !ofs + size_float; l + end + +let loc_int32 last_int make_stack int ofs = + if !int <= last_int then begin + let l = phys_reg !int in + incr int; l + end else begin + let l = stack_slot (make_stack !ofs) Int in + ofs := !ofs + (if macosx then 4 else 8); + l + end + let calling_conventions first_int last_int first_float last_float make_stack arg = let loc = Array.make (Array.length arg) Reg.dummy in @@ -116,23 +144,11 @@ let calling_conventions let float = ref first_float in let ofs = ref 0 in for i = 0 to Array.length arg - 1 do - match arg.(i).typ with - | Val | Int | Addr as ty -> - if !int <= last_int then begin - loc.(i) <- phys_reg !int; - incr int - end else begin - loc.(i) <- stack_slot (make_stack !ofs) ty; - ofs := !ofs + size_int - end + match arg.(i) with + | Val | Int | Addr -> + loc.(i) <- loc_int last_int make_stack int ofs | Float -> - if !float <= last_float then begin - loc.(i) <- phys_reg !float; - incr float - end else begin - loc.(i) <- stack_slot (make_stack !ofs) Float; - ofs := !ofs + size_float - end + loc.(i) <- loc_float last_float make_stack float ofs done; (loc, Misc.align !ofs 16) (* keep stack 16-aligned *) @@ -147,26 +163,50 @@ let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" Return values in r0...r15 or d0...d15. *) let max_arguments_for_tailcalls = 16 +let last_int_register = if macosx then 7 else 15 let loc_arguments arg = - calling_conventions 0 15 100 115 outgoing arg + calling_conventions 0 last_int_register 100 115 outgoing arg let loc_parameters arg = - let (loc, _) = calling_conventions 0 15 100 115 incoming arg in loc + let (loc, _) = + calling_conventions 0 last_int_register 100 115 incoming arg + in + loc let loc_results res = - let (loc, _) = calling_conventions 0 15 100 115 not_supported res in loc + let (loc, _) = + calling_conventions 0 last_int_register 100 115 not_supported res + in + loc (* C calling convention: first integer args in r0...r7 first float args in d0...d7 remaining args on stack. + macOS/iOS peculiarity: int32 arguments passed on stack occupy 4 bytes, + while the AAPCS64 says 8 bytes. Return values in r0...r1 or d0. *) -let loc_external_arguments arg = - let arg = - Array.map (fun regs -> assert (Array.length regs = 1); regs.(0)) arg - in - let loc, alignment = calling_conventions 0 7 100 107 outgoing arg in - Array.map (fun reg -> [|reg|]) loc, alignment +let external_calling_conventions + first_int last_int first_float last_float make_stack ty_args = + let loc = Array.make (List.length ty_args) [| Reg.dummy |] in + let int = ref first_int in + let float = ref first_float in + let ofs = ref 0 in + List.iteri (fun i ty_arg -> + begin match ty_arg with + | XInt | XInt64 -> + loc.(i) <- [| loc_int last_int make_stack int ofs |] + | XInt32 -> + loc.(i) <- [| loc_int32 last_int make_stack int ofs |] + | XFloat -> + loc.(i) <- [| loc_float last_float make_stack float ofs |] + end) + ty_args; + (loc, Misc.align !ofs 16) (* keep stack 16-aligned *) + +let loc_external_arguments ty_args = + external_calling_conventions 0 7 100 107 outgoing ty_args + let loc_external_results res = let (loc, _) = calling_conventions 0 1 100 100 not_supported res in loc @@ -212,12 +252,12 @@ let destroyed_at_c_call = 124;125;126;127;128;129;130;131]) let destroyed_at_oper = function - | Iop(Icall_ind _ | Icall_imm _) | Iop(Iextcall { alloc = true; }) -> + | Iop(Icall_ind | Icall_imm _) | Iop(Iextcall { alloc = true; }) -> all_phys_regs | Iop(Iextcall { alloc = false; }) -> destroyed_at_c_call | Iop(Ialloc _) -> - [| reg_x15 |] + [| reg_x8 |] | Iop(Iintoffloat | Ifloatofint | Iload(Single, _) | Istore(Single, _, _)) -> [| reg_d7 |] (* d7 / s7 destroyed *) | _ -> [||] @@ -244,9 +284,9 @@ let max_register_pressure = function registers). *) let op_is_pure = function - | Icall_ind _ | Icall_imm _ | Itailcall_ind _ | Itailcall_imm _ + | Icall_ind | Icall_imm _ | Itailcall_ind | Itailcall_imm _ | Iextcall _ | Istackoffset _ | Istore _ | Ialloc _ - | Iintop(Icheckbound _) | Iintop_imm(Icheckbound _, _) + | Iintop(Icheckbound) | Iintop_imm(Icheckbound, _) | Ispecific(Ishiftcheckbound _) -> false | _ -> true diff --git a/asmcomp/arm64/reload.ml b/asmcomp/arm64/reload.ml index 0c342b64..7d27e076 100644 --- a/asmcomp/arm64/reload.ml +++ b/asmcomp/arm64/reload.ml @@ -15,5 +15,26 @@ (* Reloading for the ARM 64 bits *) +open Reg + +class reload = object (self) + +inherit Reloadgen.reload_generic as super + +method! reload_operation op arg res = + match op with + | Ispecific Imove32 -> + (* Like Imove: argument or result can be on stack but not both *) + begin match arg.(0), res.(0) with + | {loc = Stack s1}, {loc = Stack s2} when s1 <> s2 -> + ([| self#makereg arg.(0) |], res) + | _ -> + (arg, res) + end + | _ -> + super#reload_operation op arg res + +end + let fundecl f num_stack_slots = - (new Reloadgen.reload_generic)#fundecl f num_stack_slots + (new reload)#fundecl f num_stack_slots diff --git a/asmcomp/arm64/selection.ml b/asmcomp/arm64/selection.ml index 90166141..d9351075 100644 --- a/asmcomp/arm64/selection.ml +++ b/asmcomp/arm64/selection.ml @@ -76,6 +76,13 @@ let rec run_automata nbits state input = let is_logical_immediate n = n <> 0 && n <> -1 && run_automata 64 0 n +(* Signed immediates are simpler *) + +let is_immediate n = + let mn = -n in + n land 0xFFF = n || n land 0xFFF_000 = n + || mn land 0xFFF = mn || mn land 0xFFF_000 = mn + (* If you update [inline_ops], you may need to update [is_simple_expr] and/or [effects_of], below. *) let inline_ops = @@ -83,7 +90,12 @@ let inline_ops = "caml_int64_direct_bswap"; "caml_nativeint_direct_bswap" ] let use_direct_addressing _symb = - not !Clflags.dlcode + (not !Clflags.dlcode) && (not Arch.macosx) + +let is_stack_slot rv = + Reg.(match rv with + | [| { loc = Stack _ } |] -> true + | _ -> false) (* Instruction selection *) @@ -91,10 +103,15 @@ class selector = object(self) inherit Selectgen.selector_generic as super -method is_immediate n = - let mn = -n in - n land 0xFFF = n || n land 0xFFF_000 = n - || mn land 0xFFF = mn || mn land 0xFFF_000 = mn +method is_immediate_test _cmp n = + is_immediate n + +method! is_immediate op n = + match op with + | Iadd | Isub -> n <= 0xFFF_FFF && n >= -0xFFF_FFF + | Iand | Ior | Ixor -> is_logical_immediate n + | Icomp _ | Icheckbound -> is_immediate n + | _ -> super#is_immediate op n method! is_simple_expr = function (* inlined floating-point ops are simple if their arguments are *) @@ -130,13 +147,6 @@ method! select_operation op args dbg = (* Integer addition *) | Caddi | Caddv | Cadda -> begin match args with - (* Add immediate *) - | [arg; Cconst_int (n, _)] when self#is_immediate n -> - ((if n >= 0 then Iintop_imm(Iadd, n) else Iintop_imm(Isub, -n)), - [arg]) - | [Cconst_int (n, _); arg] when self#is_immediate n -> - ((if n >= 0 then Iintop_imm(Iadd, n) else Iintop_imm(Isub, -n)), - [arg]) (* Shift-add *) | [arg1; Cop(Clsl, [arg2; Cconst_int (n, _)], _)] when n > 0 && n < 64 -> (Ispecific(Ishiftarith(Ishiftadd, n)), [arg1; arg2]) @@ -162,10 +172,6 @@ method! select_operation op args dbg = (* Integer subtraction *) | Csubi -> begin match args with - (* Sub immediate *) - | [arg; Cconst_int (n, _)] when self#is_immediate n -> - ((if n >= 0 then Iintop_imm(Isub, n) else Iintop_imm(Iadd, -n)), - [arg]) (* Shift-sub *) | [arg1; Cop(Clsl, [arg2; Cconst_int (n, _)], _)] when n > 0 && n < 64 -> (Ispecific(Ishiftarith(Ishiftsub, n)), [arg1; arg2]) @@ -188,22 +194,11 @@ method! select_operation op args dbg = | Ccheckbound -> begin match args with | [Cop(Clsr, [arg1; Cconst_int (n, _)], _); arg2] when n > 0 && n < 64 -> - (Ispecific(Ishiftcheckbound { shift = n; label_after_error = None; }), + (Ispecific(Ishiftcheckbound { shift = n; }), [arg1; arg2]) | _ -> super#select_operation op args dbg end - (* Integer multiplication *) - (* ARM does not support immediate operands for multiplication *) - | Cmuli -> - (Iintop Imul, args) - | Cmulhi -> - (Iintop Imulh, args) - (* Bitwise logical operations have a different range of immediate - operands than the other instructions *) - | Cand -> self#select_logical Iand args - | Cor -> self#select_logical Ior args - | Cxor -> self#select_logical Ixor args (* Recognize floating-point negate and multiply *) | Cnegf -> begin match args with @@ -242,14 +237,10 @@ method! select_operation op args dbg = | _ -> super#select_operation op args dbg -method select_logical op = function - | [arg; Cconst_int (n, _)] when is_logical_immediate n -> - (Iintop_imm(op, n), [arg]) - | [Cconst_int (n, _); arg] when is_logical_immediate n -> - (Iintop_imm(op, n), [arg]) - | args -> - (Iintop op, args) - +method! insert_move_extcall_arg env ty_arg src dst = + if macosx && ty_arg = XInt32 && is_stack_slot dst + then self#insert env (Iop (Ispecific Imove32)) src dst + else self#insert_moves env src dst end let fundecl f = (new selector)#emit_fundecl f diff --git a/asmcomp/asmgen.ml b/asmcomp/asmgen.ml index a6468b6c..3bb3a600 100644 --- a/asmcomp/asmgen.ml +++ b/asmcomp/asmgen.ml @@ -23,7 +23,9 @@ open Clflags open Misc open Cmm -type error = Assembler_error of string +type error = + | Assembler_error of string + | Mismatched_for_pack of string option exception Error of error @@ -39,6 +41,44 @@ let pass_dump_linear_if ppf flag message phrase = if !flag then fprintf ppf "*** %s@.%a@." message Printlinear.fundecl phrase; phrase +let start_from_emit = ref true + +let should_save_before_emit () = + should_save_ir_after Compiler_pass.Scheduling && (not !start_from_emit) + +let linear_unit_info = + { Linear_format.unit_name = ""; + items = []; + for_pack = None; + } + +let reset () = + start_from_emit := false; + if should_save_before_emit () then begin + linear_unit_info.unit_name <- Compilenv.current_unit_name (); + linear_unit_info.items <- []; + linear_unit_info.for_pack <- !Clflags.for_package; + end + +let save_data dl = + if should_save_before_emit () then begin + linear_unit_info.items <- Linear_format.(Data dl) :: linear_unit_info.items + end; + dl + +let save_linear f = + if should_save_before_emit () then begin + linear_unit_info.items <- Linear_format.(Func f) :: linear_unit_info.items + end; + f + +let write_linear prefix = + if should_save_before_emit () then begin + let filename = Compiler_pass.(to_output_filename Scheduling ~prefix) in + linear_unit_info.items <- List.rev linear_unit_info.items; + Linear_format.save filename linear_unit_info + end + let should_emit () = not (should_stop_after Compiler_pass.Scheduling) @@ -103,13 +143,19 @@ let compile_fundecl ~ppf_dump fd_cmm = ++ pass_dump_linear_if ppf_dump dump_linear "Linearized code" ++ Profile.record ~accumulate:true "scheduling" Scheduling.fundecl ++ pass_dump_linear_if ppf_dump dump_scheduling "After instruction scheduling" + ++ save_linear ++ emit_fundecl +let compile_data dl = + dl + ++ save_data + ++ emit_data + let compile_phrase ~ppf_dump p = if !dump_cmm then fprintf ppf_dump "%a@." Printcmm.phrase p; match p with | Cfunction fd -> compile_fundecl ~ppf_dump fd - | Cdata dl -> emit_data dl + | Cdata dl -> compile_data dl (* For the native toplevel: generates generic functions unless @@ -122,8 +168,8 @@ let compile_genfuns ~ppf_dump f = | _ -> ()) (Cmm_helpers.generic_functions true [Compilenv.current_unit_infos ()]) -let compile_unit asm_filename keep_asm - obj_filename gen = +let compile_unit ~output_prefix ~asm_filename ~keep_asm ~obj_filename gen = + reset (); let create_asm = should_emit () && (keep_asm || not !Emitaux.binary_backend_available) in Emitaux.create_asm_file := create_asm; @@ -131,7 +177,10 @@ let compile_unit asm_filename keep_asm ~exceptionally:(fun () -> remove_file obj_filename) (fun () -> if create_asm then Emitaux.output_channel := open_out asm_filename; - Misc.try_finally gen + Misc.try_finally + (fun () -> + gen (); + write_linear output_prefix) ~always:(fun () -> if create_asm then close_out !Emitaux.output_channel) ~exceptionally:(fun () -> @@ -176,14 +225,16 @@ type middle_end = -> Lambda.program -> Clambda.with_constants -let compile_implementation ?toplevel ~backend ~filename ~prefixname ~middle_end - ~ppf_dump (program : Lambda.program) = - let asmfile = +let asm_filename output_prefix = if !keep_asm_file || !Emitaux.binary_backend_available - then prefixname ^ ext_asm + then output_prefix ^ ext_asm else Filename.temp_file "camlasm" ext_asm - in - compile_unit asmfile !keep_asm_file (prefixname ^ ext_obj) + +let compile_implementation ?toplevel ~backend ~filename ~prefixname ~middle_end + ~ppf_dump (program : Lambda.program) = + compile_unit ~output_prefix:prefixname + ~asm_filename:(asm_filename prefixname) ~keep_asm:!keep_asm_file + ~obj_filename:(prefixname ^ ext_obj) (fun () -> Ident.Set.iter Compilenv.require_global program.required_globals; let clambda_with_constants = @@ -191,12 +242,43 @@ let compile_implementation ?toplevel ~backend ~filename ~prefixname ~middle_end in end_gen_implementation ?toplevel ~ppf_dump clambda_with_constants) +let linear_gen_implementation filename = + let open Linear_format in + let linear_unit_info, _ = restore filename in + (match !Clflags.for_package, linear_unit_info.for_pack with + | None, None -> () + | Some expected, Some saved when String.equal expected saved -> () + | _, saved -> raise(Error(Mismatched_for_pack saved))); + let emit_item = function + | Data dl -> emit_data dl + | Func f -> emit_fundecl f + in + start_from_emit := true; + emit_begin_assembly (); + Profile.record "Emit" (List.iter emit_item) linear_unit_info.items; + emit_end_assembly () + +let compile_implementation_linear output_prefix ~progname = + compile_unit ~output_prefix + ~asm_filename:(asm_filename output_prefix) ~keep_asm:!keep_asm_file + ~obj_filename:(output_prefix ^ ext_obj) + (fun () -> + linear_gen_implementation progname) + (* Error report *) let report_error ppf = function | Assembler_error file -> fprintf ppf "Assembler error, input left in file %a" Location.print_filename file + | Mismatched_for_pack saved -> + let msg = function + | None -> "without -for-pack" + | Some s -> "with -for-pack "^s + in + fprintf ppf + "This input file cannot be compiled %s: it was generated %s." + (msg !Clflags.for_package) (msg saved) let () = Location.register_error_of_exn diff --git a/asmcomp/asmgen.mli b/asmcomp/asmgen.mli index afbdefd6..f86bd673 100644 --- a/asmcomp/asmgen.mli +++ b/asmcomp/asmgen.mli @@ -35,14 +35,23 @@ val compile_implementation -> Lambda.program -> unit +val compile_implementation_linear : + string -> progname:string -> unit + val compile_phrase : ppf_dump:Format.formatter -> Cmm.phrase -> unit -type error = Assembler_error of string +type error = + | Assembler_error of string + | Mismatched_for_pack of string option + exception Error of error val report_error: Format.formatter -> error -> unit - -val compile_unit: - string(*asm file*) -> bool(*keep asm*) -> - string(*obj file*) -> (unit -> unit) -> unit +val compile_unit + : output_prefix:string + -> asm_filename:string + -> keep_asm:bool + -> obj_filename:string + -> (unit -> unit) + -> unit diff --git a/asmcomp/asmlink.ml b/asmcomp/asmlink.ml index 6236b1ca..697eeb3c 100644 --- a/asmcomp/asmlink.ml +++ b/asmcomp/asmlink.ml @@ -212,13 +212,12 @@ let scan_file obj_name (tolink, objfiles) = match read_file obj_name with reqd) infos.lib_units tolink and objfiles = - if Config.ccomp_type = "msvc" - && infos.lib_units = [] + if infos.lib_units = [] && not (Sys.file_exists (object_file_name obj_name)) then - (* MSVC doesn't support empty .lib files, so there shouldn't be one - if the .cmxa contains no units. The file_exists check is added to - be ultra-defensive for the case where a user has manually added - things to the .lib file *) + (* MSVC doesn't support empty .lib files, and macOS struggles to make + them (#6550), so there shouldn't be one if the .cmxa contains no + units. The file_exists check is added to be ultra-defensive for the + case where a user has manually added things to the .a/.lib file *) objfiles else obj_name :: objfiles @@ -268,9 +267,6 @@ let make_startup_file ~ppf_dump units_list ~crc_interfaces = compile_phrase(Cmm_helpers.code_segment_table("_startup" :: name_list)); let all_names = "_startup" :: "_system" :: name_list in compile_phrase (Cmm_helpers.frame_table all_names); - if Config.spacetime then begin - compile_phrase (Cmm_helpers.spacetime_shapes all_names); - end; if !Clflags.output_complete_object then force_linking_of_startup ~ppf_dump; Emit.end_assembly () @@ -315,8 +311,9 @@ let link_shared ~ppf_dump objfiles output_name = then output_name ^ ".startup" ^ ext_asm else Filename.temp_file "camlstartup" ext_asm in let startup_obj = output_name ^ ".startup" ^ ext_obj in - Asmgen.compile_unit - startup !Clflags.keep_startup_file startup_obj + Asmgen.compile_unit ~output_prefix:output_name + ~asm_filename:startup ~keep_asm:!Clflags.keep_startup_file + ~obj_filename:startup_obj (fun () -> make_shared_startup_file ~ppf_dump (List.map (fun (ui,_,crc) -> (ui,crc)) units_tolink) @@ -331,14 +328,9 @@ let call_linker file_list startup_file output_name = and main_obj_runtime = !Clflags.output_complete_object in let files = startup_file :: (List.rev file_list) in - let libunwind = - if not Config.spacetime then [] - else if not Config.libunwind_available then [] - else String.split_on_char ' ' Config.libunwind_link_flags - in let files, c_lib = if (not !Clflags.output_c_object) || main_dll || main_obj_runtime then - files @ (List.rev !Clflags.ccobjs) @ runtime_lib () @ libunwind, + files @ (List.rev !Clflags.ccobjs) @ runtime_lib (), (if !Clflags.nopervasives || (main_obj_runtime && not main_dll) then "" else Config.native_c_libraries) else @@ -383,8 +375,9 @@ let link ~ppf_dump objfiles output_name = then output_name ^ ".startup" ^ ext_asm else Filename.temp_file "camlstartup" ext_asm in let startup_obj = Filename.temp_file "camlstartup" ext_obj in - Asmgen.compile_unit - startup !Clflags.keep_startup_file startup_obj + Asmgen.compile_unit ~output_prefix:output_name + ~asm_filename:startup ~keep_asm:!Clflags.keep_startup_file + ~obj_filename:startup_obj (fun () -> make_startup_file ~ppf_dump units_tolink ~crc_interfaces); Misc.try_finally (fun () -> diff --git a/asmcomp/branch_relaxation.ml b/asmcomp/branch_relaxation.ml index 74b749ea..c91fb32b 100644 --- a/asmcomp/branch_relaxation.ml +++ b/asmcomp/branch_relaxation.ml @@ -51,8 +51,8 @@ module Make (T : Branch_relaxation_intf.S) = struct in match instr.desc with | Lop (Ialloc _) - | Lop (Iintop (Icheckbound _)) - | Lop (Iintop_imm (Icheckbound _, _)) + | Lop (Iintop (Icheckbound)) + | Lop (Iintop_imm (Icheckbound, _)) | Lop (Ispecific _) -> (* We assume that any branches eligible for relaxation generated by these instructions only branch forward. We further assume @@ -86,16 +86,15 @@ module Make (T : Branch_relaxation_intf.S) = struct fixup did_fix (pc + T.instr_size instr.desc) instr.next else match instr.desc with - | Lop (Ialloc { bytes = num_bytes; label_after_call_gc; dbginfo }) -> - instr.desc <- T.relax_allocation ~num_bytes - ~dbginfo ~label_after_call_gc; + | Lop (Ialloc { bytes = num_bytes; dbginfo }) -> + instr.desc <- T.relax_allocation ~num_bytes ~dbginfo; fixup true (pc + T.instr_size instr.desc) instr.next - | Lop (Iintop (Icheckbound { label_after_error; })) -> - instr.desc <- T.relax_intop_checkbound ~label_after_error; + | Lop (Iintop (Icheckbound)) -> + instr.desc <- T.relax_intop_checkbound (); fixup true (pc + T.instr_size instr.desc) instr.next - | Lop (Iintop_imm (Icheckbound { label_after_error; }, bound)) -> + | Lop (Iintop_imm (Icheckbound, bound)) -> instr.desc - <- T.relax_intop_imm_checkbound ~bound ~label_after_error; + <- T.relax_intop_imm_checkbound ~bound; fixup true (pc + T.instr_size instr.desc) instr.next | Lop (Ispecific specific) -> instr.desc <- T.relax_specific_op specific; diff --git a/asmcomp/branch_relaxation_intf.ml b/asmcomp/branch_relaxation_intf.ml index b7a7271f..57127e51 100644 --- a/asmcomp/branch_relaxation_intf.ml +++ b/asmcomp/branch_relaxation_intf.ml @@ -62,15 +62,13 @@ module type S = sig the size of out-of-line code (cf. branch_relaxation.mli). *) val relax_allocation : num_bytes:int - -> label_after_call_gc:Cmm.label option -> dbginfo:Debuginfo.alloc_dbginfo -> Linear.instruction_desc val relax_intop_checkbound - : label_after_error:Cmm.label option + : unit -> Linear.instruction_desc val relax_intop_imm_checkbound : bound:int - -> label_after_error:Cmm.label option -> Linear.instruction_desc val relax_specific_op : Arch.specific_operation -> Linear.instruction_desc end diff --git a/asmcomp/cmm.ml b/asmcomp/cmm.ml index e9fcbd9b..1aaf5c72 100644 --- a/asmcomp/cmm.ml +++ b/asmcomp/cmm.ml @@ -77,6 +77,21 @@ let ge_component comp1 comp2 = | Float, (Int | Addr | Val) -> assert false +type exttype = + | XInt + | XInt32 + | XInt64 + | XFloat + +let machtype_of_exttype = function + | XInt -> typ_int + | XInt32 -> typ_int + | XInt64 -> if Arch.size_int = 4 then [|Int;Int|] else typ_int + | XFloat -> typ_float + +let machtype_of_exttype_list xtl = + Array.concat (List.map machtype_of_exttype xtl) + type integer_comparison = Lambda.integer_comparison = | Ceq | Cne | Clt | Cgt | Cle | Cge @@ -94,7 +109,18 @@ let negate_float_comparison = Lambda.negate_float_comparison let swap_float_comparison = Lambda.swap_float_comparison type label = int -let label_counter = ref 99 +let init_label = 99 + +let label_counter = ref init_label + +let set_label l = + if (l < !label_counter) then begin + Misc.fatal_errorf "Cannot set label counter to %d, it must be >= %d" + l !label_counter () + end; + label_counter := l + +let cur_label () = !label_counter let new_label() = incr label_counter; !label_counter @@ -124,9 +150,7 @@ type memory_chunk = and operation = Capply of machtype - | Cextcall of string * machtype * bool * label option - (** If specified, the given label will be placed immediately after the - call (at the same place as any frame descriptor would reference). *) + | Cextcall of string * machtype * exttype list * bool | Cload of memory_chunk * Asttypes.mutable_flag | Calloc | Cstore of memory_chunk * Lambda.initialization_or_assignment @@ -147,9 +171,6 @@ type expression = | Cconst_natint of nativeint * Debuginfo.t | Cconst_float of float * Debuginfo.t | Cconst_symbol of string * Debuginfo.t - | Cconst_pointer of int * Debuginfo.t - | Cconst_natpointer of nativeint * Debuginfo.t - | Cblockheader of nativeint * Debuginfo.t | Cvar of Backend_var.t | Clet of Backend_var.With_provenance.t * expression * expression | Clet_mut of Backend_var.With_provenance.t * machtype @@ -207,7 +228,7 @@ let ccatch (i, ids, e1, e2, dbg) = Ccatch(Nonrecursive, [i, ids, e2, dbg], e1) let reset () = - label_counter := 99 + label_counter := init_label let iter_shallow_tail f = function | Clet(_, _, body) | Cphantom_let (_, _, body) | Clet_mut(_, _, _, body) -> @@ -237,9 +258,6 @@ let iter_shallow_tail f = function | Cconst_natint _ | Cconst_float _ | Cconst_symbol _ - | Cconst_pointer _ - | Cconst_natpointer _ - | Cblockheader _ | Cvar _ | Cassign _ | Ctuple _ @@ -276,9 +294,6 @@ let rec map_tail f = function | Cconst_natint _ | Cconst_float _ | Cconst_symbol _ - | Cconst_pointer _ - | Cconst_natpointer _ - | Cblockheader _ | Cvar _ | Cassign _ | Ctuple _ @@ -315,9 +330,6 @@ let map_shallow f = function | Cconst_natint _ | Cconst_float _ | Cconst_symbol _ - | Cconst_pointer _ - | Cconst_natpointer _ - | Cblockheader _ | Cvar _ as c -> c diff --git a/asmcomp/cmm.mli b/asmcomp/cmm.mli index ad8d804e..851da270 100644 --- a/asmcomp/cmm.mli +++ b/asmcomp/cmm.mli @@ -68,6 +68,17 @@ val ge_component -> machtype_component -> bool +type exttype = + | XInt (**r OCaml value, word-sized integer *) + | XInt32 (**r 32-bit integer *) + | XInt64 (**r 64-bit integer *) + | XFloat (**r double-precision FP number *) +(** A variant of [machtype] used to describe arguments + to external C functions *) + +val machtype_of_exttype: exttype -> machtype +val machtype_of_exttype_list: exttype list -> machtype + type integer_comparison = Lambda.integer_comparison = | Ceq | Cne | Clt | Cgt | Cle | Cge @@ -82,6 +93,8 @@ val swap_float_comparison: float_comparison -> float_comparison type label = int val new_label: unit -> label +val set_label: label -> unit +val cur_label: unit -> label type rec_flag = Nonrecursive | Recursive @@ -127,7 +140,10 @@ type memory_chunk = and operation = Capply of machtype - | Cextcall of string * machtype * bool * label option + | Cextcall of string * machtype * exttype list * bool + (** The [machtype] is the machine type of the result. + The [exttype list] describes the unboxing types of the arguments. + An empty list means "all arguments are machine words [XInt]". *) | Cload of memory_chunk * Asttypes.mutable_flag | Calloc | Cstore of memory_chunk * Lambda.initialization_or_assignment @@ -154,9 +170,6 @@ and expression = | Cconst_natint of nativeint * Debuginfo.t | Cconst_float of float * Debuginfo.t | Cconst_symbol of string * Debuginfo.t - | Cconst_pointer of int * Debuginfo.t - | Cconst_natpointer of nativeint * Debuginfo.t - | Cblockheader of nativeint * Debuginfo.t | Cvar of Backend_var.t | Clet of Backend_var.With_provenance.t * expression * expression | Clet_mut of Backend_var.With_provenance.t * machtype diff --git a/asmcomp/cmm_helpers.ml b/asmcomp/cmm_helpers.ml index ff4b794e..ab1445f4 100644 --- a/asmcomp/cmm_helpers.ml +++ b/asmcomp/cmm_helpers.ml @@ -24,9 +24,7 @@ open Arch let bind name arg fn = match arg with - Cvar _ | Cconst_int _ | Cconst_natint _ | Cconst_symbol _ - | Cconst_pointer _ | Cconst_natpointer _ - | Cblockheader _ -> fn arg + Cvar _ | Cconst_int _ | Cconst_natint _ | Cconst_symbol _ -> fn arg | _ -> let id = V.create_local name in Clet(VP.create id, arg, fn (Cvar id)) let bind_load name arg fn = @@ -36,9 +34,7 @@ let bind_load name arg fn = let bind_nonvar name arg fn = match arg with - Cconst_int _ | Cconst_natint _ | Cconst_symbol _ - | Cconst_pointer _ | Cconst_natpointer _ - | Cblockheader _ -> fn arg + Cconst_int _ | Cconst_natint _ | Cconst_symbol _ -> fn arg | _ -> let id = V.create_local name in Clet(VP.create id, arg, fn (Cvar id)) let caml_black = Nativeint.shift_left (Nativeint.of_int 3) 8 @@ -74,14 +70,25 @@ let caml_nativeint_ops = "caml_nativeint_ops" let caml_int32_ops = "caml_int32_ops" let caml_int64_ops = "caml_int64_ops" - -let alloc_float_header dbg = Cblockheader (float_header, dbg) -let alloc_floatarray_header len dbg = Cblockheader (floatarray_header len, dbg) -let alloc_closure_header sz dbg = Cblockheader (white_closure_header sz, dbg) -let alloc_infix_header ofs dbg = Cblockheader (infix_header ofs, dbg) -let alloc_boxedint32_header dbg = Cblockheader (boxedint32_header, dbg) -let alloc_boxedint64_header dbg = Cblockheader (boxedint64_header, dbg) -let alloc_boxedintnat_header dbg = Cblockheader (boxedintnat_header, dbg) +let pos_arity_in_closinfo = 8 * size_addr - 8 + (* arity = the top 8 bits of the closinfo word *) + +let closure_info ~arity ~startenv = + assert (-128 <= arity && arity <= 127); + assert (0 <= startenv && startenv < 1 lsl (pos_arity_in_closinfo - 1)); + Nativeint.(add (shift_left (of_int arity) pos_arity_in_closinfo) + (add (shift_left (of_int startenv) 1) + 1n)) + +let alloc_float_header dbg = Cconst_natint (float_header, dbg) +let alloc_floatarray_header len dbg = Cconst_natint (floatarray_header len, dbg) +let alloc_closure_header sz dbg = Cconst_natint (white_closure_header sz, dbg) +let alloc_infix_header ofs dbg = Cconst_natint (infix_header ofs, dbg) +let alloc_closure_info ~arity ~startenv dbg = + Cconst_natint (closure_info ~arity ~startenv, dbg) +let alloc_boxedint32_header dbg = Cconst_natint (boxedint32_header, dbg) +let alloc_boxedint64_header dbg = Cconst_natint (boxedint64_header, dbg) +let alloc_boxedintnat_header dbg = Cconst_natint (boxedintnat_header, dbg) (* Integers *) @@ -445,7 +452,7 @@ let rec div_int c1 c2 is_safe dbg = res = t + sign-bit(c1) *) bind "dividend" c1 (fun c1 -> - let t = Cop(Cmulhi, [c1; Cconst_natint (m, dbg)], dbg) in + let t = Cop(Cmulhi, [c1; natint_const_untagged dbg m], dbg) in let t = if m < 0n then Cop(Caddi, [t; c1], dbg) else t in let t = if p > 0 then Cop(Casr, [t; Cconst_int (p, dbg)], dbg) else t @@ -554,7 +561,7 @@ let box_float dbg c = Cop(Calloc, [alloc_float_header dbg; c], dbg) let unbox_float dbg = map_tail (function - | Cop(Calloc, [Cblockheader (hdr, _); c], _) + | Cop(Calloc, [Cconst_natint (hdr, _); c], _) when Nativeint.equal hdr float_header -> c | Cconst_symbol (s, _dbg) as cmm -> @@ -579,11 +586,11 @@ let complex_im c dbg = Cop(Cload (Double_u, Immutable), (* Unit *) -let return_unit dbg c = Csequence(c, Cconst_pointer (1, dbg)) +let return_unit dbg c = Csequence(c, Cconst_int (1, dbg)) let rec remove_unit = function - Cconst_pointer (1, _) -> Ctuple [] - | Csequence(c, Cconst_pointer (1, _)) -> c + Cconst_int (1, _) -> Ctuple [] + | Csequence(c, Cconst_int (1, _)) -> c | Csequence(c1, c2) -> Csequence(c1, remove_unit c2) | Cifthenelse(cond, ifso_dbg, ifso, ifnot_dbg, ifnot, dbg) -> @@ -604,8 +611,8 @@ let rec remove_unit = function Clet(id, c1, remove_unit c2) | Cop(Capply _mty, args, dbg) -> Cop(Capply typ_void, args, dbg) - | Cop(Cextcall(proc, _mty, alloc, label_after), args, dbg) -> - Cop(Cextcall(proc, typ_void, alloc, label_after), args, dbg) + | Cop(Cextcall(proc, _ty_res, ty_args, alloc), args, dbg) -> + Cop(Cextcall(proc, typ_void, ty_args, alloc), args, dbg) | Cexit (_,_) as c -> c | Ctuple [] as c -> c | c -> Csequence(c, Ctuple []) @@ -727,10 +734,10 @@ let float_array_ref arr ofs dbg = box_float dbg (unboxed_float_array_ref arr ofs dbg) let addr_array_set arr ofs newval dbg = - Cop(Cextcall("caml_modify", typ_void, false, None), + Cop(Cextcall("caml_modify", typ_void, [], false), [array_indexing log2_size_addr arr ofs dbg; newval], dbg) let addr_array_initialize arr ofs newval dbg = - Cop(Cextcall("caml_initialize", typ_void, false, None), + Cop(Cextcall("caml_initialize", typ_void, [], false), [array_indexing log2_size_addr arr ofs dbg; newval], dbg) let int_array_set arr ofs newval dbg = Cop(Cstore (Word_int, Lambda.Assignment), @@ -766,7 +773,7 @@ let bigstring_length ba dbg = let lookup_tag obj tag dbg = bind "tag" tag (fun tag -> - Cop(Cextcall("caml_get_public_method", typ_val, false, None), + Cop(Cextcall("caml_get_public_method", typ_val, [], false), [obj; tag], dbg)) @@ -788,7 +795,7 @@ let call_cached_method obj tag cache pos args dbg = let make_alloc_generic set_fn dbg tag wordsize args = if wordsize <= Config.max_young_wosize then - Cop(Calloc, Cblockheader(block_header tag wordsize, dbg) :: args, dbg) + Cop(Calloc, Cconst_natint(block_header tag wordsize, dbg) :: args, dbg) else begin let id = V.create_local "*alloc*" in let rec fill_fields idx = function @@ -796,14 +803,14 @@ let make_alloc_generic set_fn dbg tag wordsize args = | e1::el -> Csequence(set_fn (Cvar id) (Cconst_int (idx, dbg)) e1 dbg, fill_fields (idx + 2) el) in Clet(VP.create id, - Cop(Cextcall("caml_alloc", typ_val, true, None), + Cop(Cextcall("caml_alloc", typ_val, [], true), [Cconst_int (wordsize, dbg); Cconst_int (tag, dbg)], dbg), fill_fields 1 args) end let make_alloc dbg tag args = let addr_array_init arr ofs newval dbg = - Cop(Cextcall("caml_initialize", typ_void, false, None), + Cop(Cextcall("caml_initialize", typ_void, [], false), [array_indexing log2_size_addr arr ofs dbg; newval], dbg) in make_alloc_generic addr_array_init dbg tag (List.length args) args @@ -986,7 +993,7 @@ let sign_extend_32 dbg e = (if the word size is 32, this is a no-op) *) let zero_extend_32 dbg e = if size_int = 4 then e else - Cop(Cand, [low_32 dbg e; Cconst_natint(0xFFFFFFFFn, dbg)], dbg) + Cop(Cand, [low_32 dbg e; natint_const_untagged dbg 0xFFFFFFFFn], dbg) (* Boxed integers *) @@ -1023,13 +1030,13 @@ let split_int64_for_32bit_target arg dbg = let alloc_matches_boxed_int bi ~hdr ~ops = match (bi : Primitive.boxed_integer), hdr, ops with - | Pnativeint, Cblockheader (hdr, _dbg), Cconst_symbol (sym, _) -> + | Pnativeint, Cconst_natint (hdr, _dbg), Cconst_symbol (sym, _) -> Nativeint.equal hdr boxedintnat_header && String.equal sym caml_nativeint_ops - | Pint32, Cblockheader (hdr, _dbg), Cconst_symbol (sym, _) -> + | Pint32, Cconst_natint (hdr, _dbg), Cconst_symbol (sym, _) -> Nativeint.equal hdr boxedint32_header && String.equal sym caml_int32_ops - | Pint64, Cblockheader (hdr, _dbg), Cconst_symbol (sym, _) -> + | Pint64, Cconst_natint (hdr, _dbg), Cconst_symbol (sym, _) -> Nativeint.equal hdr boxedint64_header && String.equal sym caml_int64_ops | (Pnativeint | Pint32 | Pint64), _, _ -> false @@ -1065,21 +1072,23 @@ let unbox_int dbg bi = | Cconst_symbol (s, _dbg) as cmm -> begin match Cmmgen_state.structured_constant_of_sym s, bi with | Some (Uconst_nativeint n), Primitive.Pnativeint -> - Cconst_natint (n, dbg) + natint_const_untagged dbg n | Some (Uconst_int32 n), Primitive.Pint32 -> - Cconst_natint (Nativeint.of_int32 n, dbg) + natint_const_untagged dbg (Nativeint.of_int32 n) | Some (Uconst_int64 n), Primitive.Pint64 -> if size_int = 8 then - Cconst_natint (Int64.to_nativeint n, dbg) + natint_const_untagged dbg (Int64.to_nativeint n) else let low = Int64.to_nativeint n in let high = Int64.to_nativeint (Int64.shift_right_logical n 32) in if big_endian then - Ctuple [Cconst_natint (high, dbg); Cconst_natint (low, dbg)] + Ctuple [natint_const_untagged dbg high; + natint_const_untagged dbg low] else - Ctuple [Cconst_natint (low, dbg); Cconst_natint (high, dbg)] + Ctuple [natint_const_untagged dbg low; + natint_const_untagged dbg high] | _ -> default cmm end @@ -1428,11 +1437,9 @@ let make_switch arg cases actions dbg = function (* Constant integers loaded from a table should end in 1, so that Cload never produces untagged integers *) - | Cconst_int (n, _), _dbg - | Cconst_pointer (n, _), _dbg when (n land 1) = 1 -> + | Cconst_int (n, _), _dbg when (n land 1) = 1 -> Some (Cint (Nativeint.of_int n)) | Cconst_natint (n, _), _dbg - | Cconst_natpointer (n, _), _dbg when Nativeint.(to_int (logand n one) = 1) -> Some (Cint n) | Cconst_symbol (s,_), _dbg -> @@ -1803,8 +1810,10 @@ let apply_function_body arity = (args, clos, if arity = 1 then app_fun clos 0 else Cifthenelse( - Cop(Ccmpi Ceq, [get_field_gen Asttypes.Mutable (Cvar clos) 1 (dbg ()); - int_const (dbg ()) arity], dbg ()), + Cop(Ccmpi Ceq, [Cop(Casr, + [get_field_gen Asttypes.Mutable (Cvar clos) 1 (dbg()); + Cconst_int(pos_arity_in_closinfo, dbg())], dbg()); + Cconst_int(arity, dbg())], dbg()), dbg (), Cop(Capply typ_val, get_field_gen Asttypes.Mutable (Cvar clos) 2 (dbg ()) @@ -1991,7 +2000,8 @@ let rec intermediate_curry_functions arity num = Cop(Calloc, [alloc_closure_header 5 (dbg ()); Cconst_symbol(name1 ^ "_" ^ Int.to_string (num+1), dbg ()); - int_const (dbg ()) (arity - num - 1); + alloc_closure_info ~arity:(arity - num - 1) + ~startenv:3 (dbg ()); Cconst_symbol(name1 ^ "_" ^ Int.to_string (num+1) ^ "_app", dbg ()); Cvar arg; Cvar clos], @@ -2000,7 +2010,8 @@ let rec intermediate_curry_functions arity num = Cop(Calloc, [alloc_closure_header 4 (dbg ()); Cconst_symbol(name1 ^ "_" ^ Int.to_string (num+1), dbg ()); - int_const (dbg ()) 1; Cvar arg; Cvar clos], + alloc_closure_info ~arity:1 ~startenv:2 (dbg ()); + Cvar arg; Cvar clos], dbg ()); fun_codegen_options = []; fun_dbg; @@ -2136,18 +2147,18 @@ let arraylength kind arg dbg = Cop(Cor, [float_array_length_shifted hdr dbg; Cconst_int (1, dbg)], dbg) let bbswap bi arg dbg = - let prim = match (bi : Primitive.boxed_integer) with - | Pnativeint -> "nativeint" - | Pint32 -> "int32" - | Pint64 -> "int64" + let prim, tyarg = match (bi : Primitive.boxed_integer) with + | Pnativeint -> "nativeint", XInt + | Pint32 -> "int32", XInt32 + | Pint64 -> "int64", XInt64 in Cop(Cextcall(Printf.sprintf "caml_%s_direct_bswap" prim, - typ_int, false, None), + typ_int, [tyarg], false), [arg], dbg) let bswap16 arg dbg = - (Cop(Cextcall("caml_bswap16_direct", typ_int, false, None), + (Cop(Cextcall("caml_bswap16_direct", typ_int, [], false), [arg], dbg)) @@ -2172,15 +2183,15 @@ let assignment_kind let setfield n ptr init arg1 arg2 dbg = match assignment_kind ptr init with | Caml_modify -> - return_unit dbg (Cop(Cextcall("caml_modify", typ_void, false, None), - [field_address arg1 n dbg; - arg2], - dbg)) + return_unit dbg + (Cop(Cextcall("caml_modify", typ_void, [], false), + [field_address arg1 n dbg; arg2], + dbg)) | Caml_initialize -> - return_unit dbg (Cop(Cextcall("caml_initialize", typ_void, false, None), - [field_address arg1 n dbg; - arg2], - dbg)) + return_unit dbg + (Cop(Cextcall("caml_initialize", typ_void, [], false), + [field_address arg1 n dbg; arg2], + dbg)) | Simple -> return_unit dbg (set_field arg1 n arg2 init dbg) @@ -2615,18 +2626,6 @@ let frame_table namelist = List.map mksym namelist @ [cint_zero]) -(* Generate the master table of Spacetime shapes *) - -let spacetime_shapes namelist = - let mksym name = - Csymbol_address ( - Compilenv.make_symbol ~unitname:name (Some "spacetime_shapes")) - in - Cdata(Cglobal_symbol "caml_spacetime_shapes" :: - Cdefine_symbol "caml_spacetime_shapes" :: - List.map mksym namelist - @ [cint_zero]) - (* Generate the table of module data and code segments *) let segment_table namelist symbol begname endname = @@ -2717,6 +2716,7 @@ let emit_constant_closure ((_, global_symb) as symb) fundecls clos_vars cont = assert (clos_vars = []); cdefine_symbol symb @ clos_vars @ cont | f1 :: remainder -> + let startenv = fundecls_size fundecls in let rec emit_others pos = function [] -> clos_vars @ cont | (f2 : Clambda.ufunction) :: rem -> @@ -2724,13 +2724,13 @@ let emit_constant_closure ((_, global_symb) as symb) fundecls clos_vars cont = Cint(infix_header pos) :: (closure_symbol f2) @ Csymbol_address f2.label :: - cint_const f2.arity :: + Cint(closure_info ~arity:f2.arity ~startenv:(startenv - pos)) :: emit_others (pos + 3) rem else Cint(infix_header pos) :: (closure_symbol f2) @ Csymbol_address(curry_function_sym f2.arity) :: - cint_const f2.arity :: + Cint(closure_info ~arity:f2.arity ~startenv:(startenv - pos)) :: Csymbol_address f2.label :: emit_others (pos + 4) rem in Cint(black_closure_header (fundecls_size fundecls @@ -2739,11 +2739,11 @@ let emit_constant_closure ((_, global_symb) as symb) fundecls clos_vars cont = (closure_symbol f1) @ if f1.arity = 1 || f1.arity = 0 then Csymbol_address f1.label :: - cint_const f1.arity :: + Cint(closure_info ~arity:f1.arity ~startenv) :: emit_others 3 remainder else Csymbol_address(curry_function_sym f1.arity) :: - cint_const f1.arity :: + Cint(closure_info ~arity:f1.arity ~startenv) :: Csymbol_address f1.label :: emit_others 4 remainder diff --git a/asmcomp/cmm_helpers.mli b/asmcomp/cmm_helpers.mli index c1ace961..debc84b4 100644 --- a/asmcomp/cmm_helpers.mli +++ b/asmcomp/cmm_helpers.mli @@ -64,11 +64,16 @@ val boxedint32_header : nativeint val boxedint64_header : nativeint val boxedintnat_header : nativeint +(** Closure info for a closure of given arity and distance to environment *) +val closure_info : arity:int -> startenv:int -> nativeint + (** Wrappers *) val alloc_float_header : Debuginfo.t -> expression val alloc_floatarray_header : int -> Debuginfo.t -> expression val alloc_closure_header : int -> Debuginfo.t -> expression val alloc_infix_header : int -> Debuginfo.t -> expression +val alloc_closure_info : + arity:int -> startenv:int -> Debuginfo.t -> expression val alloc_boxedint32_header : Debuginfo.t -> expression val alloc_boxedint64_header : Debuginfo.t -> expression val alloc_boxedintnat_header : Debuginfo.t -> expression @@ -595,10 +600,6 @@ val globals_map: from the given compilation units *) val frame_table: string list -> phrase -(** Generate the caml_spacetime_shapes table, referencing the spacetime shapes - from the given compilation units *) -val spacetime_shapes: string list -> phrase - (** Generate the tables for data and code positions respectively of the given compilation units *) val data_segment_table: string list -> phrase diff --git a/asmcomp/cmmgen.ml b/asmcomp/cmmgen.ml index 8515e3d6..b8c8389e 100644 --- a/asmcomp/cmmgen.ml +++ b/asmcomp/cmmgen.ml @@ -178,18 +178,15 @@ let rec expr_size env = function let transl_constant dbg = function | Uconst_int n -> int_const dbg n - | Uconst_ptr n -> - if n <= max_repr_int && n >= min_repr_int - then Cconst_pointer((n lsl 1) + 1, dbg) - else Cconst_natpointer - (Nativeint.add (Nativeint.shift_left (Nativeint.of_int n) 1) 1n, - dbg) - | Uconst_ref (label, _) -> + | Uconst_ref (label, def_opt) -> + Option.iter + (fun def -> Cmmgen_state.add_structured_constant label def) + def_opt; Cconst_symbol (label, dbg) let emit_constant cst cont = match cst with - | Uconst_int n | Uconst_ptr n -> + | Uconst_int n -> cint_const n :: cont | Uconst_ref (sym, _) -> @@ -317,10 +314,10 @@ let is_unboxed_number_cmm ~strict cmm = r := join_unboxed_number_kind ~strict !r k in let rec aux = function - | Cop(Calloc, [Cblockheader (hdr, _); _], dbg) + | Cop(Calloc, [Cconst_natint (hdr, _); _], dbg) when Nativeint.equal hdr float_header -> notify (Boxed (Boxed_float dbg, false)) - | Cop(Calloc, [Cblockheader (hdr, _); Cconst_symbol (ops, _); _], dbg) -> + | Cop(Calloc, [Cconst_natint (hdr, _); Cconst_symbol (ops, _); _], dbg) -> if Nativeint.equal hdr boxedintnat_header && String.equal ops caml_nativeint_ops then @@ -379,6 +376,7 @@ let rec transl env e = in Cconst_symbol (sym, dbg) | Uclosure(fundecls, clos_vars) -> + let startenv = fundecls_size fundecls in let rec transl_fundecls pos = function [] -> List.map (transl env) clos_vars @@ -388,16 +386,19 @@ let rec transl env e = let without_header = if f.arity = 1 || f.arity = 0 then Cconst_symbol (f.label, dbg) :: - int_const dbg f.arity :: + alloc_closure_info ~arity:f.arity + ~startenv:(startenv - pos) dbg :: transl_fundecls (pos + 3) rem else Cconst_symbol (curry_function_sym f.arity, dbg) :: - int_const dbg f.arity :: + alloc_closure_info ~arity:f.arity + ~startenv:(startenv - pos) dbg :: Cconst_symbol (f.label, dbg) :: transl_fundecls (pos + 4) rem in - if pos = 0 then without_header - else (alloc_infix_header pos f.dbg) :: without_header + if pos = 0 + then without_header + else alloc_infix_header pos f.dbg :: without_header in let dbg = match fundecls with @@ -435,7 +436,7 @@ let rec transl env e = Cphantom_const_symbol sym | Uphantom_read_symbol_field { sym; field; } -> Cphantom_read_symbol_field { sym; field; } - | Uphantom_const (Uconst_int i) | Uphantom_const (Uconst_ptr i) -> + | Uphantom_const (Uconst_int i) -> Cphantom_const_int (targetint_const i) | Uphantom_var var -> Cphantom_var var | Uphantom_read_field { var; field; } -> @@ -728,7 +729,7 @@ and transl_catch env nfail ids body handler dbg = and transl_make_array dbg env kind args = match kind with | Pgenarray -> - Cop(Cextcall("caml_make_array", typ_val, true, None), + Cop(Cextcall("caml_make_array", typ_val, [], true), [make_alloc dbg 0 (List.map (transl env) args)], dbg) | Paddrarray | Pintarray -> make_alloc dbg 0 (List.map (transl env) args) @@ -739,20 +740,32 @@ and transl_make_array dbg env kind args = and transl_ccall env prim args dbg = let transl_arg native_repr arg = match native_repr with - | Same_as_ocaml_repr -> transl env arg - | Unboxed_float -> transl_unbox_float dbg env arg - | Unboxed_integer bi -> transl_unbox_int dbg env bi arg - | Untagged_int -> untag_int (transl env arg) dbg + | Same_as_ocaml_repr -> + (XInt, transl env arg) + | Unboxed_float -> + (XFloat, transl_unbox_float dbg env arg) + | Unboxed_integer bi -> + let xty = + match bi with + | Pnativeint -> XInt + | Pint32 -> XInt32 + | Pint64 -> XInt64 in + (xty, transl_unbox_int dbg env bi arg) + | Untagged_int -> + (XInt, untag_int (transl env arg) dbg) in let rec transl_args native_repr_args args = match native_repr_args, args with | [], args -> (* We don't require the two lists to be of the same length as [default_prim] always sets the arity to [0]. *) - List.map (transl env) args - | _, [] -> assert false + (List.map (fun _ -> XInt) args, List.map (transl env) args) + | _, [] -> + assert false | native_repr :: native_repr_args, arg :: args -> - transl_arg native_repr arg :: transl_args native_repr_args args + let (ty1, arg') = transl_arg native_repr arg in + let (tys, args') = transl_args native_repr_args args in + (ty1 :: tys, arg' :: args') in let typ_res, wrap_result = match prim.prim_native_repr_res with @@ -763,10 +776,10 @@ and transl_ccall env prim args dbg = | Unboxed_integer bi -> (typ_int, box_int dbg bi) | Untagged_int -> (typ_int, (fun i -> tag_int i dbg)) in - let args = transl_args prim.prim_native_repr_args args in + let typ_args, args = transl_args prim.prim_native_repr_args args in wrap_result (Cop(Cextcall(Primitive.native_name prim, - typ_res, prim.prim_alloc, None), args, dbg)) + typ_res, typ_args, prim.prim_alloc), args, dbg)) and transl_prim_1 env p arg dbg = match p with @@ -810,8 +823,8 @@ and transl_prim_1 env p arg dbg = | Pnot -> transl_if env Then_false_else_true dbg arg - dbg (Cconst_pointer (1, dbg)) - dbg (Cconst_pointer (3, dbg)) + dbg (Cconst_int (1, dbg)) + dbg (Cconst_int (3, dbg)) (* Test integer/block *) | Pisint -> tag_int(Cop(Cand, [transl env arg; Cconst_int (1, dbg)], dbg)) dbg @@ -870,8 +883,8 @@ and transl_prim_2 env p arg1 arg2 dbg = transl_sequand env Then_true_else_false dbg arg1 dbg' arg2 - dbg (Cconst_pointer (3, dbg)) - dbg' (Cconst_pointer (1, dbg)) + dbg (Cconst_int (3, dbg)) + dbg' (Cconst_int (1, dbg)) (* let id = V.create_local "res1" in Clet(id, transl env arg1, Cifthenelse(test_bool dbg (Cvar id), transl env arg2, Cvar id)) *) @@ -880,8 +893,8 @@ and transl_prim_2 env p arg1 arg2 dbg = transl_sequor env Then_true_else_false dbg arg1 dbg' arg2 - dbg (Cconst_pointer (3, dbg)) - dbg' (Cconst_pointer (1, dbg)) + dbg (Cconst_int (3, dbg)) + dbg' (Cconst_int (1, dbg)) (* Integer operations *) | Paddint -> add_int_caml (transl env arg1) (transl env arg2) dbg @@ -965,17 +978,17 @@ and transl_prim_2 env p arg1 arg2 dbg = (* Boxed integers *) | Paddbint bi -> - box_int dbg bi (Cop(Caddi, - [transl_unbox_int_low dbg env bi arg1; - transl_unbox_int_low dbg env bi arg2], dbg)) + box_int dbg bi (add_int + (transl_unbox_int_low dbg env bi arg1) + (transl_unbox_int_low dbg env bi arg2) dbg) | Psubbint bi -> - box_int dbg bi (Cop(Csubi, - [transl_unbox_int_low dbg env bi arg1; - transl_unbox_int_low dbg env bi arg2], dbg)) + box_int dbg bi (sub_int + (transl_unbox_int_low dbg env bi arg1) + (transl_unbox_int_low dbg env bi arg2) dbg) | Pmulbint bi -> - box_int dbg bi (Cop(Cmuli, - [transl_unbox_int_low dbg env bi arg1; - transl_unbox_int_low dbg env bi arg2], dbg)) + box_int dbg bi (mul_int + (transl_unbox_int_low dbg env bi arg1) + (transl_unbox_int_low dbg env bi arg2) dbg) | Pdivbint { size = bi; is_safe } -> box_int dbg bi (safe_div_bi is_safe (transl_unbox_int dbg env bi arg1) @@ -999,18 +1012,18 @@ and transl_prim_2 env p arg1 arg2 dbg = [transl_unbox_int_low dbg env bi arg1; transl_unbox_int_low dbg env bi arg2], dbg)) | Plslbint bi -> - box_int dbg bi (Cop(Clsl, - [transl_unbox_int_low dbg env bi arg1; - untag_int(transl env arg2) dbg], dbg)) + box_int dbg bi (lsl_int + (transl_unbox_int_low dbg env bi arg1) + (untag_int(transl env arg2) dbg) dbg) | Plsrbint bi -> - box_int dbg bi (Cop(Clsr, - [make_unsigned_int bi (transl_unbox_int dbg env bi arg1) - dbg; - untag_int(transl env arg2) dbg], dbg)) + box_int dbg bi (lsr_int + (make_unsigned_int bi (transl_unbox_int dbg env bi arg1) + dbg) + (untag_int(transl env arg2) dbg) dbg) | Pasrbint bi -> - box_int dbg bi (Cop(Casr, - [transl_unbox_int dbg env bi arg1; - untag_int(transl env arg2) dbg], dbg)) + box_int dbg bi (asr_int + (transl_unbox_int dbg env bi arg1) + (untag_int(transl env arg2) dbg) dbg) | Pbintcomp(bi, cmp) -> tag_int (Cop(Ccmpi cmp, [transl_unbox_int dbg env bi arg1; @@ -1178,9 +1191,9 @@ and transl_if env (approx : then_else) (then_dbg : Debuginfo.t) then_ (else_dbg : Debuginfo.t) else_ = match cond with - | Uconst (Uconst_ptr 0) -> else_ - | Uconst (Uconst_ptr 1) -> then_ - | Uifthenelse (arg1, arg2, Uconst (Uconst_ptr 0)) -> + | Uconst (Uconst_int 0) -> else_ + | Uconst (Uconst_int 1) -> then_ + | Uifthenelse (arg1, arg2, Uconst (Uconst_int 0)) -> (* CR mshinwell: These Debuginfos will flow through from Clambda *) let inner_dbg = Debuginfo.none in let ifso_dbg = Debuginfo.none in @@ -1195,7 +1208,7 @@ and transl_if env (approx : then_else) inner_dbg arg2 then_dbg then_ else_dbg else_ - | Uifthenelse (arg1, Uconst (Uconst_ptr 1), arg2) -> + | Uifthenelse (arg1, Uconst (Uconst_int 1), arg2) -> let inner_dbg = Debuginfo.none in let ifnot_dbg = Debuginfo.none in transl_sequor env approx @@ -1214,13 +1227,13 @@ and transl_if env (approx : then_else) dbg arg else_dbg else_ then_dbg then_ - | Uifthenelse (Uconst (Uconst_ptr 1), ifso, _) -> + | Uifthenelse (Uconst (Uconst_int 1), ifso, _) -> let ifso_dbg = Debuginfo.none in transl_if env approx ifso_dbg ifso then_dbg then_ else_dbg else_ - | Uifthenelse (Uconst (Uconst_ptr 0), _, ifnot) -> + | Uifthenelse (Uconst (Uconst_int 0), _, ifnot) -> let ifnot_dbg = Debuginfo.none in transl_if env approx ifnot_dbg ifnot @@ -1306,7 +1319,7 @@ and transl_letrec env bindings cont = bindings in let op_alloc prim args = - Cop(Cextcall(prim, typ_val, true, None), args, dbg) in + Cop(Cextcall(prim, typ_val, [], true), args, dbg) in let rec init_blocks = function | [] -> fill_nonrec bsz | (id, _exp, RHS_block sz) :: rem -> @@ -1332,7 +1345,7 @@ and transl_letrec env bindings cont = | [] -> cont | (id, exp, (RHS_block _ | RHS_infix _ | RHS_floatblock _)) :: rem -> let op = - Cop(Cextcall("caml_update_dummy", typ_void, false, None), + Cop(Cextcall("caml_update_dummy", typ_void, [], false), [Cvar (VP.var id); transl env exp], dbg) in Csequence(op, fill_blocks rem) | (_id, _exp, RHS_nonrec) :: rem -> diff --git a/asmcomp/cmmgen_state.ml b/asmcomp/cmmgen_state.ml index 595aba4d..9d662235 100644 --- a/asmcomp/cmmgen_state.ml +++ b/asmcomp/cmmgen_state.ml @@ -76,6 +76,9 @@ let set_structured_constants l = ) l +let add_structured_constant sym cst = + Hashtbl.replace state.structured_constants sym cst + let get_structured_constant s = Hashtbl.find_opt state.structured_constants s diff --git a/asmcomp/cmmgen_state.mli b/asmcomp/cmmgen_state.mli index 306f55d5..f1007392 100644 --- a/asmcomp/cmmgen_state.mli +++ b/asmcomp/cmmgen_state.mli @@ -41,5 +41,7 @@ val no_more_functions : unit -> bool val set_structured_constants : Clambda.preallocated_constant list -> unit +val add_structured_constant : string -> Clambda.ustructured_constant -> unit + (* Also looks up using Compilenv.structured_constant_of_symbol *) val structured_constant_of_sym : string -> Clambda.ustructured_constant option diff --git a/asmcomp/comballoc.ml b/asmcomp/comballoc.ml index 6d7e536e..f125366d 100644 --- a/asmcomp/comballoc.ml +++ b/asmcomp/comballoc.ml @@ -59,12 +59,11 @@ let rec combine i allocstate = else instr_cons_debug (Iop(Iintop_imm(Iadd, offset))) i.res i.res i.dbg next in - (instr_cons_debug (Iop(Ialloc {bytes = totalsz; spacetime_index = 0; - dbginfo; label_after_call_gc = None; })) + (instr_cons_debug (Iop(Ialloc {bytes = totalsz; dbginfo; })) i.arg i.res i.dbg next, allocstate) end - | Iop(Icall_ind _ | Icall_imm _ | Iextcall _ | - Itailcall_ind _ | Itailcall_imm _) -> + | Iop(Icall_ind | Icall_imm _ | Iextcall _ | + Itailcall_ind | Itailcall_imm _) -> let newnext = combine_restart i.next in (instr_cons_debug i.desc i.arg i.res i.dbg newnext, allocstate) @@ -99,5 +98,4 @@ and combine_restart i = let (newi, _) = combine i No_alloc in newi let fundecl f = - if Config.spacetime then f - else {f with fun_body = combine_restart f.fun_body} + {f with fun_body = combine_restart f.fun_body} diff --git a/asmcomp/deadcode.ml b/asmcomp/deadcode.ml index 2550639d..887580fa 100644 --- a/asmcomp/deadcode.ml +++ b/asmcomp/deadcode.ml @@ -37,28 +37,22 @@ let append a b = | _ -> append a b let rec deadcode i = - let arg = - if Config.spacetime - && Mach.spacetime_node_hole_pointer_is_live_before i - then Array.append i.arg [| Proc.loc_spacetime_node_hole |] - else i.arg - in match i.desc with - | Iend | Ireturn | Iop(Itailcall_ind _) | Iop(Itailcall_imm _) | Iraise _ -> - let regs = Reg.add_set_array i.live arg in + | Iend | Ireturn | Iop(Itailcall_ind) | Iop(Itailcall_imm _) | Iraise _ -> + let regs = Reg.add_set_array i.live i.arg in { i; regs; exits = Int.Set.empty; } | Iop op -> let s = deadcode i.next in if Proc.op_is_pure op (* no side effects *) && Reg.disjoint_set_array s.regs i.res (* results are not used after *) - && not (Proc.regs_are_volatile arg) (* no stack-like hard reg *) + && not (Proc.regs_are_volatile i.arg) (* no stack-like hard reg *) && not (Proc.regs_are_volatile i.res) (* is involved *) then begin assert (Array.length i.res > 0); (* sanity check *) s end else begin { i = {i with next = s.i}; - regs = Reg.add_set_array i.live arg; + regs = Reg.add_set_array i.live i.arg; exits = s.exits; } end @@ -67,7 +61,7 @@ let rec deadcode i = let ifnot' = deadcode ifnot in let s = deadcode i.next in { i = {i with desc = Iifthenelse(test, ifso'.i, ifnot'.i); next = s.i}; - regs = Reg.add_set_array i.live arg; + regs = Reg.add_set_array i.live i.arg; exits = Int.Set.union s.exits (Int.Set.union ifso'.exits ifnot'.exits); } @@ -76,7 +70,7 @@ let rec deadcode i = let cases' = Array.map (fun c -> c.i) dc in let s = deadcode i.next in { i = {i with desc = Iswitch(index, cases'); next = s.i}; - regs = Reg.add_set_array i.live arg; + regs = Reg.add_set_array i.live i.arg; exits = Array.fold_left (fun acc c -> Int.Set.union acc c.exits) s.exits dc; } diff --git a/asmcomp/debug/available_regs.ml b/asmcomp/debug/available_regs.ml index 6ca2544b..67f0bdec 100644 --- a/asmcomp/debug/available_regs.ml +++ b/asmcomp/debug/available_regs.ml @@ -95,7 +95,7 @@ let rec available_regs (instr : M.instruction) match instr.desc with | Iend -> None, ok avail_before | Ireturn -> None, unreachable - | Iop (Itailcall_ind _) | Iop (Itailcall_imm _) -> + | Iop (Itailcall_ind) | Iop (Itailcall_imm _) -> Some (ok Reg_with_debug_info.Set.empty), unreachable | Iop (Iname_for_debugger { ident; which_parameter; provenance; is_assignment; }) -> @@ -197,7 +197,7 @@ let rec available_regs (instr : M.instruction) [Available_ranges.Make_ranges.end_pos_offset]. *) let made_unavailable_2 = match op with - | Icall_ind _ | Icall_imm _ | Ialloc _ -> + | Icall_ind | Icall_imm _ | Ialloc _ -> RD.Set.filter (fun reg -> let holds_immediate = RD.holds_non_pointer reg in let on_stack = RD.assigned_to_stack reg in diff --git a/asmcomp/emitaux.ml b/asmcomp/emitaux.ml index 9a1e6214..2e4664e8 100644 --- a/asmcomp/emitaux.ml +++ b/asmcomp/emitaux.ml @@ -185,7 +185,7 @@ let emit_frames a = | Dbg_other d | Dbg_raise d -> if Debuginfo.is_none d then 0 else 1 | Dbg_alloc dbgs -> - if !Clflags.debug && not Config.spacetime && + if !Clflags.debug && List.exists (fun d -> not (Debuginfo.is_none d.Debuginfo.alloc_dbg)) dbgs then 3 else 2 diff --git a/asmcomp/i386/arch.ml b/asmcomp/i386/arch.ml index ba76a825..17876c46 100644 --- a/asmcomp/i386/arch.ml +++ b/asmcomp/i386/arch.ml @@ -52,8 +52,6 @@ type specific_operation = and float_operation = Ifloatadd | Ifloatsub | Ifloatsubrev | Ifloatmul | Ifloatdiv | Ifloatdivrev -let spacetime_node_hole_pointer_is_live_before _specific_op = false - (* Sizes, endianness *) let big_endian = false diff --git a/asmcomp/i386/emit.mlp b/asmcomp/i386/emit.mlp index 1bad19f9..5444749b 100644 --- a/asmcomp/i386/emit.mlp +++ b/asmcomp/i386/emit.mlp @@ -200,12 +200,8 @@ let addressing addr typ i n = (* Record live pointers at call points *) -let record_frame_label ?label live dbg = - let lbl = - match label with - | None -> new_label() - | Some label -> label - in +let record_frame_label live dbg = + let lbl = new_label () in let live_offset = ref [] in Reg.Set.iter (function @@ -221,8 +217,8 @@ let record_frame_label ?label live dbg = ~live_offset:!live_offset dbg; lbl -let record_frame ?label live dbg = - let lbl = record_frame_label ?label live dbg in +let record_frame live dbg = + let lbl = record_frame_label live dbg in def_label lbl (* Record calls to the GC -- we've moved them out of the way *) @@ -251,10 +247,10 @@ type bound_error_call = let bound_error_sites = ref ([] : bound_error_call list) let bound_error_call = ref 0 -let bound_error_label ?label dbg = +let bound_error_label dbg = if !Clflags.debug then begin let lbl_bound_error = new_label() in - let lbl_frame = record_frame_label ?label Reg.Set.empty (Dbg_other dbg) in + let lbl_frame = record_frame_label Reg.Set.empty (Dbg_other dbg) in bound_error_sites := { bd_lbl = lbl_bound_error; bd_frame = lbl_frame } :: !bound_error_sites; lbl_bound_error @@ -538,18 +534,16 @@ let emit_instr fallthrough i = | Lop(Iconst_symbol s) -> add_used_symbol s; I.mov (immsym s) (reg i.res.(0)) - | Lop(Icall_ind { label_after; }) -> + | Lop(Icall_ind) -> I.call (reg i.arg.(0)); - record_frame i.live (Dbg_other i.dbg) ~label:label_after - | Lop(Icall_imm { func; label_after; }) -> + record_frame i.live (Dbg_other i.dbg) + | Lop(Icall_imm { func; }) -> add_used_symbol func; emit_call func; - record_frame i.live (Dbg_other i.dbg) ~label:label_after - | Lop(Itailcall_ind { label_after = _; }) -> - output_epilogue begin fun () -> - I.jmp (reg i.arg.(0)) - end - | Lop(Itailcall_imm { func; label_after = _; }) -> + record_frame i.live (Dbg_other i.dbg) + | Lop(Itailcall_ind) -> + output_epilogue (fun () -> I.jmp (reg i.arg.(0))) + | Lop(Itailcall_imm { func; }) -> if func = !function_name then I.jmp (label !tailrec_entry_point) else begin @@ -558,12 +552,12 @@ let emit_instr fallthrough i = I.jmp (immsym func) end end - | Lop(Iextcall { func; alloc; label_after; }) -> + | Lop(Iextcall { func; alloc; }) -> add_used_symbol func; if alloc then begin I.mov (immsym func) eax; emit_call "caml_c_call"; - record_frame i.live (Dbg_other i.dbg) ~label:label_after + record_frame i.live (Dbg_other i.dbg) end else begin emit_call func end @@ -614,7 +608,7 @@ let emit_instr fallthrough i = I.fstp (addressing addr REAL8 i 1) end end - | Lop(Ialloc { bytes = n; label_after_call_gc; dbginfo }) -> + | Lop(Ialloc { bytes = n; dbginfo }) -> if !fastcode_flag then begin load_domain_state ebx; I.mov (domain_field Domain_young_ptr RBX) eax; @@ -623,7 +617,7 @@ let emit_instr fallthrough i = I.cmp (domain_field Domain_young_limit RBX) eax; let lbl_call_gc = new_label() in let lbl_frame = - record_frame_label ?label:label_after_call_gc + record_frame_label i.live (Dbg_alloc dbginfo) in I.jb (label lbl_call_gc); let lbl_after_alloc = new_label() in @@ -643,7 +637,7 @@ let emit_instr fallthrough i = emit_call "caml_allocN" end; let label = - record_frame_label ?label:label_after_call_gc + record_frame_label i.live (Dbg_alloc dbginfo) in def_label label; @@ -657,12 +651,12 @@ let emit_instr fallthrough i = I.cmp (int n) (reg i.arg.(0)); I.set (cond cmp) al; I.movzx al (reg i.res.(0)) - | Lop(Iintop (Icheckbound { label_after_error; } )) -> - let lbl = bound_error_label ?label:label_after_error i.dbg in + | Lop(Iintop (Icheckbound)) -> + let lbl = bound_error_label i.dbg in I.cmp (reg i.arg.(1)) (reg i.arg.(0)); I.jbe (label lbl) - | Lop(Iintop_imm(Icheckbound { label_after_error; }, n)) -> - let lbl = bound_error_label ?label:label_after_error i.dbg in + | Lop(Iintop_imm(Icheckbound, n)) -> + let lbl = bound_error_label i.dbg in I.cmp (int n) (reg i.arg.(0)); I.jbe (label lbl) | Lop(Iintop(Idiv | Imod)) -> diff --git a/asmcomp/i386/proc.ml b/asmcomp/i386/proc.ml index e3e114a6..59798ffe 100644 --- a/asmcomp/i386/proc.ml +++ b/asmcomp/i386/proc.ml @@ -95,8 +95,6 @@ let edx = phys_reg 3 let stack_slot slot ty = Reg.at_location ty (Stack slot) -let loc_spacetime_node_hole = Reg.dummy (* Spacetime unsupported *) - (* Instruction selection *) let word_addressed = false @@ -121,7 +119,7 @@ let calling_conventions first_int last_int first_float last_float make_stack let float = ref first_float in let ofs = ref (-64) in for i = 0 to Array.length arg - 1 do - match arg.(i).typ with + match arg.(i) with Val | Int | Addr as ty -> if !int <= last_int then begin loc.(i) <- phys_reg !int; @@ -158,7 +156,7 @@ let loc_external_arguments _arg = fatal_error "Proc.loc_external_arguments" let loc_external_results res = match res with - | [|{typ=Int};{typ=Int}|] -> [|eax; edx|] + | [| Int; Int |] -> [|eax; edx|] | _ -> let (loc, _ofs) = calling_conventions 0 0 100 100 not_supported res in loc @@ -201,7 +199,7 @@ let destroyed_at_c_call = (* ebx, esi, edi, ebp preserved *) [|eax; ecx; edx|] let destroyed_at_oper = function - Iop(Icall_ind _ | Icall_imm _ | Iextcall { alloc = true; _}) -> + Iop(Icall_ind | Icall_imm _ | Iextcall { alloc = true; _}) -> all_phys_regs | Iop(Iextcall { alloc = false; }) -> destroyed_at_c_call | Iop(Iintop(Idiv | Imod)) -> [| eax; edx |] @@ -232,9 +230,9 @@ let max_register_pressure = function registers). *) let op_is_pure = function - | Icall_ind _ | Icall_imm _ | Itailcall_ind _ | Itailcall_imm _ + | Icall_ind | Icall_imm _ | Itailcall_ind | Itailcall_imm _ | Iextcall _ | Istackoffset _ | Istore _ | Ialloc _ - | Iintop(Icheckbound _) | Iintop_imm(Icheckbound _, _) -> false + | Iintop(Icheckbound) | Iintop_imm(Icheckbound, _) -> false | Ispecific(Ilea _) -> true | Ispecific _ -> false | _ -> true diff --git a/asmcomp/i386/reload.ml b/asmcomp/i386/reload.ml index a95e67c6..09497e05 100644 --- a/asmcomp/i386/reload.ml +++ b/asmcomp/i386/reload.ml @@ -40,7 +40,7 @@ method! makereg r = method! reload_operation op arg res = match op with - Iintop(Iadd|Isub|Iand|Ior|Ixor|Icomp _|Icheckbound _) -> + Iintop(Iadd|Isub|Iand|Ior|Ixor|Icomp _|Icheckbound) -> (* One of the two arguments can reside in the stack *) if stackp arg.(0) && stackp arg.(1) then ([|arg.(0); self#makereg arg.(1)|], res) diff --git a/asmcomp/i386/selection.ml b/asmcomp/i386/selection.ml index 59b5e2e2..2300d2c0 100644 --- a/asmcomp/i386/selection.ml +++ b/asmcomp/i386/selection.ml @@ -89,7 +89,7 @@ let rec float_needs = function let n1 = float_needs arg1 in let n2 = float_needs arg2 in if n1 = n2 then 1 + n1 else if n1 > n2 then n1 else n2 - | Cop(Cextcall(fn, _ty_res, _alloc, _label), args, _dbg) + | Cop(Cextcall(fn, _ty_res, _ty_args, _alloc), args, _dbg) when !fast_math && List.mem fn inline_float_ops -> begin match args with [arg] -> float_needs arg @@ -158,11 +158,18 @@ class selector = object (self) inherit Selectgen.selector_generic as super -method is_immediate (_n : int) = true +method! is_immediate op n = + match op with + | Iadd | Isub | Imul | Iand | Ior | Ixor | Icomp _ | Icheckbound -> + true + | _ -> + super#is_immediate op n + +method is_immediate_test _cmp _n = true method! is_simple_expr e = match e with - | Cop(Cextcall(fn, _, _alloc, _), args, _) + | Cop(Cextcall(fn, _, _, _), args, _) when !fast_math && List.mem fn inline_float_ops -> (* inlined float ops are simple if their arguments are *) List.for_all self#is_simple_expr args @@ -194,11 +201,7 @@ method! select_store is_assign addr exp = match exp with Cconst_int (n, _) -> (Ispecific(Istore_int(Nativeint.of_int n, addr, is_assign)), Ctuple []) - | (Cconst_natint (n, _) | Cblockheader (n, _)) -> - (Ispecific(Istore_int(n, addr, is_assign)), Ctuple []) - | Cconst_pointer (n, _) -> - (Ispecific(Istore_int(Nativeint.of_int n, addr, is_assign)), Ctuple []) - | Cconst_natpointer (n, _) -> + | Cconst_natint (n, _) -> (Ispecific(Istore_int(n, addr, is_assign)), Ctuple []) | Cconst_symbol (s, _) -> (Ispecific(Istore_symbol(s, addr, is_assign)), Ctuple []) @@ -237,12 +240,9 @@ method! select_operation op args dbg = super#select_operation op args dbg end (* Recognize inlined floating point operations *) - | Cextcall(fn, _ty_res, false, _label) + | Cextcall(fn, _ty_res, _ty_args, false) when !fast_math && List.mem fn inline_float_ops -> (Ispecific(Ifloatspecial fn), args) - (* i386 does not support immediate operands for multiply high signed *) - | Cmulhi -> - (Iintop Imulh, args) (* Default *) | _ -> super#select_operation op args dbg @@ -289,9 +289,6 @@ method select_push exp = match exp with Cconst_int (n, _) -> (Ispecific(Ipush_int(Nativeint.of_int n)), Ctuple []) | Cconst_natint (n, _) -> (Ispecific(Ipush_int n), Ctuple []) - | Cconst_pointer (n, _) -> - (Ispecific(Ipush_int(Nativeint.of_int n)), Ctuple []) - | Cconst_natpointer (n, _) -> (Ispecific(Ipush_int n), Ctuple []) | Cconst_symbol (s, _) -> (Ispecific(Ipush_symbol s), Ctuple []) | Cop(Cload ((Word_int | Word_val as chunk), _), [loc], _) -> let (addr, arg) = self#select_addressing chunk loc in @@ -304,7 +301,7 @@ method select_push exp = method! mark_c_tailcall = contains_calls := true -method! emit_extcall_args env args = +method! emit_extcall_args env _ty_args args = let rec size_pushes = function | [] -> 0 | e :: el -> Selectgen.size_expr env e + size_pushes el in diff --git a/asmcomp/interf.ml b/asmcomp/interf.ml index 8c848849..c62fa2ce 100644 --- a/asmcomp/interf.ml +++ b/asmcomp/interf.ml @@ -90,7 +90,7 @@ let build_graph fundecl = | Iop(Imove | Ispill | Ireload) -> add_interf_move i.arg.(0) i.res.(0) i.live; interf i.next - | Iop(Itailcall_ind _) -> () + | Iop(Itailcall_ind) -> () | Iop(Itailcall_imm _) -> () | Iop _ -> add_interf_set i.res i.live; @@ -162,7 +162,7 @@ let build_graph fundecl = | Iop(Ireload) -> add_pref (weight / 4) i.res.(0) i.arg.(0); prefer weight i.next - | Iop(Itailcall_ind _) -> () + | Iop(Itailcall_ind) -> () | Iop(Itailcall_imm _) -> () | Iop _ -> prefer weight i.next diff --git a/asmcomp/interval.ml b/asmcomp/interval.ml index 956ac4f7..2e26d169 100644 --- a/asmcomp/interval.ml +++ b/asmcomp/interval.ml @@ -130,8 +130,8 @@ let build_intervals fd = update_interval_position_by_instr intervals i !pos; begin match i.desc with Iend -> () - | Iop(Icall_ind _ | Icall_imm _ | Iextcall{alloc = true; _} - | Itailcall_ind _ | Itailcall_imm _) -> + | Iop(Icall_ind | Icall_imm _ | Iextcall{alloc = true; _} + | Itailcall_ind | Itailcall_imm _) -> walk_instruction i.next | Iop _ -> insert_destroyed_at_oper intervals i !pos; diff --git a/asmcomp/linear.ml b/asmcomp/linear.ml index 37cf9200..1773f4d4 100644 --- a/asmcomp/linear.ml +++ b/asmcomp/linear.ml @@ -44,7 +44,7 @@ and instruction_desc = let has_fallthrough = function | Lreturn | Lbranch _ | Lswitch _ | Lraise _ - | Lop Itailcall_ind _ | Lop (Itailcall_imm _) -> false + | Lop Itailcall_ind | Lop (Itailcall_imm _) -> false | _ -> true type fundecl = @@ -52,7 +52,6 @@ type fundecl = fun_body: instruction; fun_fast: bool; fun_dbg : Debuginfo.t; - fun_spacetime_shape : Mach.spacetime_shape option; fun_tailrec_entry_point_label : label; fun_contains_calls: bool; fun_num_stack_slots: int array; diff --git a/asmcomp/linear.mli b/asmcomp/linear.mli index 2d1ce943..2f52c209 100644 --- a/asmcomp/linear.mli +++ b/asmcomp/linear.mli @@ -53,7 +53,6 @@ type fundecl = fun_body: instruction; fun_fast: bool; fun_dbg : Debuginfo.t; - fun_spacetime_shape : Mach.spacetime_shape option; fun_tailrec_entry_point_label : label; fun_contains_calls: bool; fun_num_stack_slots: int array; diff --git a/asmcomp/linearize.ml b/asmcomp/linearize.ml index 31b992a4..8355b831 100644 --- a/asmcomp/linearize.ml +++ b/asmcomp/linearize.ml @@ -137,11 +137,8 @@ let linear i n contains_calls = let rec linear i n = match i.Mach.desc with Iend -> n - | Iop(Itailcall_ind _ | Itailcall_imm _ as op) -> - if not Config.spacetime then - copy_instr (Lop op) i (discard_dead_code n) - else - copy_instr (Lop op) i (linear i.Mach.next n) + | Iop(Itailcall_ind | Itailcall_imm _ as op) -> + copy_instr (Lop op) i (discard_dead_code n) | Iop(Imove | Ireload | Ispill) when i.Mach.arg.(0).loc = i.Mach.res.(0).loc -> linear i.Mach.next n @@ -248,7 +245,7 @@ let linear i n contains_calls = get_label (cons_instr Lentertrap (linear handler n1)) in incr try_depth; - assert (i.Mach.arg = [| |] || Config.spacetime); + assert (i.Mach.arg = [| |]); let n3 = cons_instr (Lpushtrap { lbl_handler; }) (linear body (cons_instr @@ -331,7 +328,6 @@ let fundecl f = fun_body; fun_fast = not (List.mem Cmm.Reduce_code_size f.Mach.fun_codegen_options); fun_dbg = f.Mach.fun_dbg; - fun_spacetime_shape = f.Mach.fun_spacetime_shape; fun_tailrec_entry_point_label; fun_contains_calls = contains_calls; fun_num_stack_slots = f.Mach.fun_num_stack_slots; diff --git a/asmcomp/liveness.ml b/asmcomp/liveness.ml index 2da5b160..f07944ae 100644 --- a/asmcomp/liveness.ml +++ b/asmcomp/liveness.ml @@ -35,24 +35,18 @@ let rec live i finally = before the instruction sequence. The instruction i is annotated by the set of registers live across the instruction. *) - let arg = - if Config.spacetime - && Mach.spacetime_node_hole_pointer_is_live_before i - then Array.append i.arg [| Proc.loc_spacetime_node_hole |] - else i.arg - in match i.desc with Iend -> i.live <- finally; finally - | Ireturn | Iop(Itailcall_ind _) | Iop(Itailcall_imm _) -> + | Ireturn | Iop(Itailcall_ind) | Iop(Itailcall_imm _) -> i.live <- Reg.Set.empty; (* no regs are live across *) - Reg.set_of_array arg + Reg.set_of_array i.arg | Iop op -> let after = live i.next finally in if Proc.op_is_pure op (* no side effects *) && Reg.disjoint_set_array after i.res (* results are not used after *) - && not (Proc.regs_are_volatile arg) (* no stack-like hard reg *) + && not (Proc.regs_are_volatile i.arg) (* no stack-like hard reg *) && not (Proc.regs_are_volatile i.res) (* is involved *) then begin (* This operation is dead code. Ignore its arguments. *) @@ -62,8 +56,8 @@ let rec live i finally = let across_after = Reg.diff_set_array after i.res in let across = match op with - | Icall_ind _ | Icall_imm _ | Iextcall _ | Ialloc _ - | Iintop (Icheckbound _) | Iintop_imm(Icheckbound _, _) -> + | Icall_ind | Icall_imm _ | Iextcall _ | Ialloc _ + | Iintop (Icheckbound) | Iintop_imm(Icheckbound, _) -> (* The function call may raise an exception, branching to the nearest enclosing try ... with. Similarly for bounds checks and allocation (for the latter: finalizers may throw @@ -74,13 +68,13 @@ let rec live i finally = | _ -> across_after in i.live <- across; - Reg.add_set_array across arg + Reg.add_set_array across i.arg end | Iifthenelse(_test, ifso, ifnot) -> let at_join = live i.next finally in let at_fork = Reg.Set.union (live ifso at_join) (live ifnot at_join) in i.live <- at_fork; - Reg.add_set_array at_fork arg + Reg.add_set_array at_fork i.arg | Iswitch(_index, cases) -> let at_join = live i.next finally in let at_fork = ref Reg.Set.empty in @@ -88,7 +82,7 @@ let rec live i finally = at_fork := Reg.Set.union !at_fork (live cases.(i) at_join) done; i.live <- !at_fork; - Reg.add_set_array !at_fork arg + Reg.add_set_array !at_fork i.arg | Icatch(rec_flag, handlers, body) -> let at_join = live i.next finally in let aux (nfail,handler) (nfail', before_handler) = @@ -140,7 +134,7 @@ let rec live i finally = before_body | Iraise _ -> i.live <- !live_at_raise; - Reg.add_set_array !live_at_raise arg + Reg.add_set_array !live_at_raise i.arg let reset () = live_at_raise := Reg.Set.empty; @@ -148,13 +142,8 @@ let reset () = let fundecl f = let initially_live = live f.fun_body Reg.Set.empty in - (* Sanity check: only function parameters (and the Spacetime node hole - register, if profiling) can be live at entrypoint *) + (* Sanity check: only function parameters can be live at entrypoint *) let wrong_live = Reg.Set.diff initially_live (Reg.set_of_array f.fun_args) in - let wrong_live = - if not Config.spacetime then wrong_live - else Reg.Set.remove Proc.loc_spacetime_node_hole wrong_live - in if not (Reg.Set.is_empty wrong_live) then begin Misc.fatal_errorf "@[Liveness.fundecl:@\n%a@]" Printmach.regset wrong_live diff --git a/asmcomp/mach.ml b/asmcomp/mach.ml index 8518e9da..bb1969ad 100644 --- a/asmcomp/mach.ml +++ b/asmcomp/mach.ml @@ -15,8 +15,6 @@ (* Representation of machine code by sequences of pseudoinstructions *) -type label = Cmm.label - type integer_comparison = Isigned of Cmm.integer_comparison | Iunsigned of Cmm.integer_comparison @@ -25,8 +23,7 @@ type integer_operation = Iadd | Isub | Imul | Imulh | Idiv | Imod | Iand | Ior | Ixor | Ilsl | Ilsr | Iasr | Icomp of integer_comparison - | Icheckbound of { label_after_error : label option; - spacetime_index : int; } + | Icheckbound type float_comparison = Cmm.float_comparison @@ -46,16 +43,17 @@ type operation = | Iconst_int of nativeint | Iconst_float of int64 | Iconst_symbol of string - | Icall_ind of { label_after : label; } - | Icall_imm of { func : string; label_after : label; } - | Itailcall_ind of { label_after : label; } - | Itailcall_imm of { func : string; label_after : label; } - | Iextcall of { func : string; alloc : bool; label_after : label; } + | Icall_ind + | Icall_imm of { func : string; } + | Itailcall_ind + | Itailcall_imm of { func : string; } + | Iextcall of { func : string; + ty_res : Cmm.machtype; ty_args : Cmm.exttype list; + alloc : bool; } | Istackoffset of int | Iload of Cmm.memory_chunk * Arch.addressing_mode | Istore of Cmm.memory_chunk * Arch.addressing_mode * bool - | Ialloc of { bytes : int; label_after_call_gc : label option; - dbginfo : Debuginfo.alloc_dbginfo; spacetime_index : int; } + | Ialloc of { bytes : int; dbginfo : Debuginfo.alloc_dbginfo; } | Iintop of integer_operation | Iintop_imm of integer_operation * int | Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf @@ -86,20 +84,12 @@ and instruction_desc = | Itrywith of instruction * instruction | Iraise of Lambda.raise_kind -type spacetime_part_of_shape = - | Direct_call_point of { callee : string; } - | Indirect_call_point - | Allocation_point - -type spacetime_shape = (spacetime_part_of_shape * Cmm.label) list - type fundecl = { fun_name: string; fun_args: Reg.t array; fun_body: instruction; fun_codegen_options : Cmm.codegen_option list; fun_dbg : Debuginfo.t; - fun_spacetime_shape : spacetime_shape option; fun_num_stack_slots: int array; fun_contains_calls: bool; } @@ -146,7 +136,7 @@ let rec instr_iter f i = f i; match i.desc with Iend -> () - | Ireturn | Iop(Itailcall_ind _) | Iop(Itailcall_imm _) -> () + | Ireturn | Iop Itailcall_ind | Iop(Itailcall_imm _) -> () | Iifthenelse(_tst, ifso, ifnot) -> instr_iter f ifso; instr_iter f ifnot; instr_iter f i.next | Iswitch(_index, cases) -> @@ -165,43 +155,9 @@ let rec instr_iter f i = | _ -> instr_iter f i.next -let spacetime_node_hole_pointer_is_live_before insn = - match insn.desc with - | Iop op -> - begin match op with - | Icall_ind _ | Icall_imm _ | Itailcall_ind _ | Itailcall_imm _ -> true - | Iextcall { alloc; } -> alloc - | Ialloc _ -> - (* Allocations are special: the call to [caml_call_gc] requires some - instrumentation code immediately prior, but this is not inserted until - the emitter (since the call is not visible prior to that in any IR). - As such, none of the Mach / Linearize analyses will ever see that - we use the node hole pointer for these, and we do not need to say - that it is live at such points. *) - false - | Iintop op | Iintop_imm (op, _) -> - begin match op with - | Icheckbound _ - (* [Icheckbound] doesn't need to return [true] for the same reason as - [Ialloc]. *) - | Iadd | Isub | Imul | Imulh | Idiv | Imod - | Iand | Ior | Ixor | Ilsl | Ilsr | Iasr - | Icomp _ -> false - end - | Ispecific specific_op -> - Arch.spacetime_node_hole_pointer_is_live_before specific_op - | Imove | Ispill | Ireload | Iconst_int _ | Iconst_float _ - | Iconst_symbol _ | Istackoffset _ | Iload _ | Istore _ - | Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf - | Ifloatofint | Iintoffloat - | Iname_for_debugger _ -> false - end - | Iend | Ireturn | Iifthenelse _ | Iswitch _ | Icatch _ - | Iexit _ | Itrywith _ | Iraise _ -> false - let operation_can_raise op = match op with - | Icall_ind _ | Icall_imm _ | Iextcall _ - | Iintop (Icheckbound _) | Iintop_imm (Icheckbound _, _) + | Icall_ind | Icall_imm _ | Iextcall _ + | Iintop (Icheckbound) | Iintop_imm (Icheckbound, _) | Ialloc _ -> true | _ -> false diff --git a/asmcomp/mach.mli b/asmcomp/mach.mli index 1141d57d..323a668b 100644 --- a/asmcomp/mach.mli +++ b/asmcomp/mach.mli @@ -15,12 +15,6 @@ (* Representation of machine code by sequences of pseudoinstructions *) -(** N.B. Backends vary in their treatment of call gc and checkbound - points. If the positioning of any labels associated with these is - important for some new feature in the compiler, the relevant backends' - behaviour should be checked. *) -type label = Cmm.label - type integer_comparison = Isigned of Cmm.integer_comparison | Iunsigned of Cmm.integer_comparison @@ -29,11 +23,7 @@ type integer_operation = Iadd | Isub | Imul | Imulh | Idiv | Imod | Iand | Ior | Ixor | Ilsl | Ilsr | Iasr | Icomp of integer_comparison - | Icheckbound of { label_after_error : label option; - spacetime_index : int; } - (** For Spacetime only, [Icheckbound] operations take two arguments, the - second being the pointer to the trie node for the current function - (and the first being as per non-Spacetime mode). *) + | Icheckbound type float_comparison = Cmm.float_comparison @@ -53,19 +43,18 @@ type operation = | Iconst_int of nativeint | Iconst_float of int64 | Iconst_symbol of string - | Icall_ind of { label_after : label; } - | Icall_imm of { func : string; label_after : label; } - | Itailcall_ind of { label_after : label; } - | Itailcall_imm of { func : string; label_after : label; } - | Iextcall of { func : string; alloc : bool; label_after : label; } + | Icall_ind + | Icall_imm of { func : string; } + | Itailcall_ind + | Itailcall_imm of { func : string; } + | Iextcall of { func : string; + ty_res : Cmm.machtype; ty_args : Cmm.exttype list; + alloc : bool; } | Istackoffset of int | Iload of Cmm.memory_chunk * Arch.addressing_mode | Istore of Cmm.memory_chunk * Arch.addressing_mode * bool (* false = initialization, true = assignment *) - | Ialloc of { bytes : int; label_after_call_gc : label option; - dbginfo : Debuginfo.alloc_dbginfo; spacetime_index : int; } - (** For Spacetime only, Ialloc instructions take one argument, being the - pointer to the trie node for the current function. *) + | Ialloc of { bytes : int; dbginfo : Debuginfo.alloc_dbginfo; } | Iintop of integer_operation | Iintop_imm of integer_operation * int | Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf @@ -102,26 +91,12 @@ and instruction_desc = | Itrywith of instruction * instruction | Iraise of Lambda.raise_kind -type spacetime_part_of_shape = - | Direct_call_point of { callee : string; (* the symbol *) } - | Indirect_call_point - | Allocation_point - -(** A description of the layout of a Spacetime profiling node associated with - a given function. Each call and allocation point instrumented within - the function is marked with a label in the code and assigned a place - within the node. This information is stored within the executable and - extracted when the user saves a profile. The aim is to minimise runtime - memory usage within the nodes and increase performance. *) -type spacetime_shape = (spacetime_part_of_shape * Cmm.label) list - type fundecl = { fun_name: string; fun_args: Reg.t array; fun_body: instruction; fun_codegen_options : Cmm.codegen_option list; fun_dbg : Debuginfo.t; - fun_spacetime_shape : spacetime_shape option; fun_num_stack_slots: int array; fun_contains_calls: bool; } @@ -136,6 +111,4 @@ val instr_cons_debug: instruction -> instruction val instr_iter: (instruction -> unit) -> instruction -> unit -val spacetime_node_hole_pointer_is_live_before : instruction -> bool - val operation_can_raise : operation -> bool diff --git a/asmcomp/power/arch.ml b/asmcomp/power/arch.ml index 07bf8dbf..6f5898ed 100644 --- a/asmcomp/power/arch.ml +++ b/asmcomp/power/arch.ml @@ -49,15 +49,7 @@ type specific_operation = Imultaddf (* multiply and add *) | Imultsubf (* multiply and subtract *) | Ialloc_far of (* allocation in large functions *) - { bytes : int; label_after_call_gc : int (*Cmm.label*) option; - dbginfo : Debuginfo.alloc_dbginfo } - -(* note: we avoid introducing a dependency to Cmm since this dep - is not detected when "make depend" is run under amd64 *) - -let spacetime_node_hole_pointer_is_live_before = function - | Imultaddf | Imultsubf -> false - | Ialloc_far _ -> true + { bytes : int; dbginfo : Debuginfo.alloc_dbginfo } (* Addressing modes *) diff --git a/asmcomp/power/emit.mlp b/asmcomp/power/emit.mlp index 5a28f556..08ae3137 100644 --- a/asmcomp/power/emit.mlp +++ b/asmcomp/power/emit.mlp @@ -42,14 +42,16 @@ let prologue_required = ref false let contains_calls = ref false +let initial_stack_offset () = + reserved_stack_space + + size_int * num_stack_slots.(0) + (* Local int variables *) + size_float * num_stack_slots.(1) + (* Local float variables *) + (if !contains_calls && abi = ELF32 then size_int else 0) + (* The return address *) let frame_size () = let size = - reserved_stack_space + !stack_offset + (* Trap frame, outgoing parameters *) - size_int * num_stack_slots.(0) + (* Local int variables *) - size_float * num_stack_slots.(1) + (* Local float variables *) - (if !contains_calls && abi = ELF32 then size_int else 0) in - (* The return address *) + initial_stack_offset () in Misc.align size 16 let slot_offset loc cls = @@ -308,12 +310,8 @@ let adjust_stack_offset delta = (* Record live pointers at call points *) -let record_frame ?label live dbg = - let lbl = - match label with - | None -> new_label() - | Some label -> label - in +let record_frame live dbg = + let lbl = new_label() in let live_offset = ref [] in Reg.Set.iter (function @@ -439,7 +437,7 @@ module BR = Branch_relaxation.Make (struct let prologue_size () = profiling_prologue_size () - + (if frame_size () > 0 then 1 else 0) + + (if initial_stack_offset () > 0 then 1 else 0) + (if !contains_calls then 2 + match abi with @@ -472,9 +470,9 @@ module BR = Branch_relaxation.Make (struct else tocload_size() | Lop(Iconst_float _) -> if abi = ELF32 then 2 else tocload_size() | Lop(Iconst_symbol _) -> if abi = ELF32 then 2 else tocload_size() - | Lop(Icall_ind _) -> size 2 5 4 + | Lop(Icall_ind) -> size 2 5 4 | Lop(Icall_imm _) -> size 1 3 3 - | Lop(Itailcall_ind _) -> size 5 7 6 + | Lop(Itailcall_ind) -> size 5 7 6 | Lop(Itailcall_imm { func; _ }) -> if func = !function_name then 1 @@ -516,14 +514,14 @@ module BR = Branch_relaxation.Make (struct | Lpoptrap -> 2 | Lraise _ -> 6 - let relax_allocation ~num_bytes:bytes ~label_after_call_gc ~dbginfo = - Lop (Ispecific (Ialloc_far { bytes; label_after_call_gc; dbginfo })) + let relax_allocation ~num_bytes:bytes ~dbginfo = + Lop (Ispecific (Ialloc_far { bytes; dbginfo })) (* [classify_addr], above, never identifies these instructions as needing relaxing. As such, these functions should never be called. *) let relax_specific_op _ = assert false - let relax_intop_checkbound ~label_after_error:_ = assert false - let relax_intop_imm_checkbound ~bound:_ ~label_after_error:_ = assert false + let relax_intop_checkbound () = assert false + let relax_intop_imm_checkbound ~bound:_ = assert false end) (* Output the assembly code for an instruction *) @@ -617,31 +615,31 @@ let emit_instr i = | ELF64v1 | ELF64v2 -> emit_tocload emit_reg i.res.(0) (TocSym s) end - | Lop(Icall_ind { label_after; }) -> + | Lop(Icall_ind) -> begin match abi with | ELF32 -> ` mtctr {emit_reg i.arg.(0)}\n`; ` bctrl\n`; - record_frame i.live (Dbg_other i.dbg) ~label:label_after + record_frame i.live (Dbg_other i.dbg) | ELF64v1 -> ` ld 0, 0({emit_reg i.arg.(0)})\n`; (* code pointer *) ` mtctr 0\n`; ` ld 2, 8({emit_reg i.arg.(0)})\n`; (* TOC for callee *) ` bctrl\n`; - record_frame i.live (Dbg_other i.dbg) ~label:label_after; + record_frame i.live (Dbg_other i.dbg); emit_reload_toc() | ELF64v2 -> ` mtctr {emit_reg i.arg.(0)}\n`; ` mr 12, {emit_reg i.arg.(0)}\n`; (* addr of fn in r12 *) ` bctrl\n`; - record_frame i.live (Dbg_other i.dbg) ~label:label_after; + record_frame i.live (Dbg_other i.dbg); emit_reload_toc() end - | Lop(Icall_imm { func; label_after; }) -> + | Lop(Icall_imm { func; }) -> begin match abi with | ELF32 -> emit_call func; - record_frame i.live (Dbg_other i.dbg) ~label:label_after + record_frame i.live (Dbg_other i.dbg) | ELF64v1 | ELF64v2 -> (* For PPC64, we cannot just emit a "bl s; nop" sequence, because of the following scenario: @@ -661,11 +659,11 @@ let emit_instr i = Cost: 3 instructions if same TOC, 7 if different TOC. Let's try option 2. *) emit_call func; - record_frame i.live (Dbg_other i.dbg) ~label:label_after; + record_frame i.live (Dbg_other i.dbg); ` nop\n`; emit_reload_toc() end - | Lop(Itailcall_ind { label_after = _; }) -> + | Lop(Itailcall_ind) -> begin match abi with | ELF32 -> ` mtctr {emit_reg i.arg.(0)}\n` @@ -683,7 +681,7 @@ let emit_instr i = end; emit_free_frame(); ` bctr\n` - | Lop(Itailcall_imm { func; label_after = _; }) -> + | Lop(Itailcall_imm { func; }) -> if func = !function_name then ` b {emit_label !tailrec_entry_point}\n` else begin @@ -756,23 +754,15 @@ let emit_instr i = | Single -> "stfs" | Double | Double_u -> "stfd" in emit_load_store storeinstr addr i.arg 1 i.arg.(0) - | Lop(Ialloc { bytes = n; label_after_call_gc; dbginfo }) -> - if !call_gc_label = 0 then begin - match label_after_call_gc with - | None -> call_gc_label := new_label () - | Some label -> call_gc_label := label - end; + | Lop(Ialloc { bytes = n; dbginfo }) -> + if !call_gc_label = 0 then call_gc_label := new_label (); ` addi 31, 31, {emit_int(-n)}\n`; ` {emit_string cmplg} 31, 30\n`; ` bltl {emit_label !call_gc_label}\n`; record_frame i.live (Dbg_alloc dbginfo); ` addi {emit_reg i.res.(0)}, 31, {emit_int size_addr}\n`; - | Lop(Ispecific(Ialloc_far { bytes = n; label_after_call_gc; dbginfo })) -> - if !call_gc_label = 0 then begin - match label_after_call_gc with - | None -> call_gc_label := new_label () - | Some label -> call_gc_label := label - end; + | Lop(Ispecific(Ialloc_far { bytes = n; dbginfo })) -> + if !call_gc_label = 0 then call_gc_label := new_label (); let lbl = new_label() in ` addi 31, 31, {emit_int(-n)}\n`; ` {emit_string cmplg} 31, 30\n`; @@ -795,9 +785,9 @@ let emit_instr i = ` {emit_string cmplg} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; emit_set_comp c i.res.(0) end - | Lop(Iintop (Icheckbound { label_after_error; })) -> + | Lop(Iintop (Icheckbound)) -> if !Clflags.debug then - record_frame Reg.Set.empty (Dbg_other i.dbg) ?label:label_after_error; + record_frame Reg.Set.empty (Dbg_other i.dbg); ` {emit_string tglle} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` | Lop(Iintop op) -> let instr = name_for_intop op in @@ -813,9 +803,9 @@ let emit_instr i = ` {emit_string cmplg}i {emit_reg i.arg.(0)}, {emit_int n}\n`; emit_set_comp c i.res.(0) end - | Lop(Iintop_imm(Icheckbound { label_after_error; }, n)) -> + | Lop(Iintop_imm(Icheckbound, n)) -> if !Clflags.debug then - record_frame Reg.Set.empty (Dbg_other i.dbg) ?label:label_after_error; + record_frame Reg.Set.empty (Dbg_other i.dbg); ` {emit_string tglle}i {emit_reg i.arg.(0)}, {emit_int n}\n` | Lop(Iintop_imm(op, n)) -> let instr = name_for_intop_imm op in diff --git a/asmcomp/power/proc.ml b/asmcomp/power/proc.ml index 3bcd12fc..eec140db 100644 --- a/asmcomp/power/proc.ml +++ b/asmcomp/power/proc.ml @@ -91,111 +91,83 @@ let phys_reg n = let stack_slot slot ty = Reg.at_location ty (Stack slot) -let loc_spacetime_node_hole = Reg.dummy (* Spacetime unsupported *) - (* Calling conventions *) -let calling_conventions - first_int last_int first_float last_float - make_stack stack_ofs reg_use_stack arg = - let loc = Array.make (Array.length arg) [| Reg.dummy |] in +let loc_int last_int make_stack reg_use_stack int ofs = + if !int <= last_int then begin + let l = phys_reg !int in + incr int; + if reg_use_stack then ofs := !ofs + size_int; + l + end else begin + let l = stack_slot (make_stack !ofs) Int in + ofs := !ofs + size_int; l + end + +let loc_float last_float make_stack reg_use_stack int float ofs = + if !float <= last_float then begin + let l = phys_reg !float in + incr float; + (* On 64-bit platforms, passing a float in a float register + reserves a normal register as well *) + if size_int = 8 then incr int; + if reg_use_stack then ofs := !ofs + size_float; + l + end else begin + ofs := Misc.align !ofs size_float; + let l = stack_slot (make_stack !ofs) Float in + ofs := !ofs + size_float; l + end + +let loc_int_pair last_int make_stack int ofs = + (* 64-bit quantities split across two registers must either be in a + consecutive pair of registers where the lowest numbered is an + even-numbered register; or in a stack slot that is 8-byte aligned. *) + int := Misc.align !int 2; + if !int <= last_int - 1 then begin + let reg_lower = phys_reg !int in + let reg_upper = phys_reg (1 + !int) in + int := !int + 2; + [| reg_lower; reg_upper |] + end else begin + ofs := Misc.align !ofs 8; + let stack_lower = stack_slot (make_stack !ofs) Int in + let stack_upper = stack_slot (make_stack (size_int + !ofs)) Int in + ofs := !ofs + 8; + [| stack_lower; stack_upper |] + end + +let calling_conventions first_int last_int first_float last_float make_stack + arg = + let loc = Array.make (Array.length arg) Reg.dummy in let int = ref first_int in let float = ref first_float in - let ofs = ref stack_ofs in + let ofs = ref 0 in for i = 0 to Array.length arg - 1 do match arg.(i) with - | [| arg |] -> - begin match arg.typ with - | Val | Int | Addr as ty -> - if !int <= last_int then begin - loc.(i) <- [| phys_reg !int |]; - incr int; - if reg_use_stack then ofs := !ofs + size_int - end else begin - loc.(i) <- [| stack_slot (make_stack !ofs) ty |]; - ofs := !ofs + size_int - end - | Float -> - if !float <= last_float then begin - loc.(i) <- [| phys_reg !float |]; - incr float; - (* On 64-bit platforms, passing a float in a float register - reserves a normal register as well *) - if size_int = 8 then incr int; - if reg_use_stack then ofs := !ofs + size_float - end else begin - ofs := Misc.align !ofs size_float; - loc.(i) <- [| stack_slot (make_stack !ofs) Float |]; - ofs := !ofs + size_float - end - end - | [| arg1; arg2 |] -> - (* Passing of 64-bit quantities to external functions - on 32-bit platform. *) - assert (size_int = 4); - begin match arg1.typ, arg2.typ with - | Int, Int -> - (* 64-bit quantities split across two registers must either be in a - consecutive pair of registers where the lowest numbered is an - even-numbered register; or in a stack slot that is 8-byte - aligned. *) - int := Misc.align !int 2; - if !int <= last_int - 1 then begin - let reg_lower = phys_reg !int in - let reg_upper = phys_reg (!int + 1) in - loc.(i) <- [| reg_lower; reg_upper |]; - int := !int + 2 - end else begin - let size_int64 = 8 in - ofs := Misc.align !ofs size_int64; - let ofs_lower = !ofs in - let ofs_upper = !ofs + size_int in - let stack_lower = stack_slot (make_stack ofs_lower) Int in - let stack_upper = stack_slot (make_stack ofs_upper) Int in - loc.(i) <- [| stack_lower; stack_upper |]; - ofs := !ofs + size_int64 - end - | _, _ -> - let f = function Int -> "I" | Addr -> "A" | Val -> "V" | Float -> "F" in - fatal_error (Printf.sprintf "Proc.calling_conventions: bad register \ - type(s) for multi-register argument: %s, %s" - (f arg1.typ) (f arg2.typ)) - end - | _ -> - fatal_error "Proc.calling_conventions: bad number of registers for \ - multi-register argument" + | Val | Int | Addr -> + loc.(i) <- loc_int last_int make_stack false int ofs + | Float -> + loc.(i) <- loc_float last_float make_stack false int float ofs done; - (loc, Misc.align !ofs 16) - (* Keep stack 16-aligned. *) + (loc, Misc.align !ofs 16) (* keep stack 16-aligned *) let incoming ofs = Incoming ofs let outgoing ofs = Outgoing ofs let not_supported _ofs = fatal_error "Proc.loc_results: cannot call" -let single_regs arg = Array.map (fun arg -> [| arg |]) arg -let ensure_single_regs res = - Array.map (function - | [| res |] -> res - | _ -> failwith "Proc.ensure_single_regs") - res - let max_arguments_for_tailcalls = 8 let loc_arguments arg = - let (loc, ofs) = - calling_conventions 0 7 100 112 outgoing 0 false (single_regs arg) - in - (ensure_single_regs loc, ofs) + calling_conventions 0 7 100 112 outgoing arg + let loc_parameters arg = - let (loc, _ofs) = - calling_conventions 0 7 100 112 incoming 0 false (single_regs arg) - in - ensure_single_regs loc + let (loc, _ofs) = calling_conventions 0 7 100 112 incoming arg + in loc + let loc_results res = - let (loc, _ofs) = - calling_conventions 0 7 100 112 not_supported 0 false (single_regs res) - in - ensure_single_regs loc + let (loc, _ofs) = calling_conventions 0 7 100 112 not_supported res + in loc (* C calling conventions for ELF32: use GPR 3-10 and FPR 1-8 just like ML calling conventions. @@ -223,19 +195,43 @@ let loc_results res = and need not appear here. *) -let loc_external_arguments = +let external_calling_conventions + first_int last_int first_float last_float + make_stack stack_ofs reg_use_stack ty_args = + let loc = Array.make (List.length ty_args) [| Reg.dummy |] in + let int = ref first_int in + let float = ref first_float in + let ofs = ref stack_ofs in + List.iteri + (fun i ty_arg -> + match ty_arg with + | XInt | XInt32 -> + loc.(i) <- + [| loc_int last_int make_stack reg_use_stack int ofs |] + | XInt64 -> + if size_int = 4 then begin + assert (not reg_use_stack); + loc.(i) <- loc_int_pair last_int make_stack int ofs + end else + loc.(i) <- + [| loc_int last_int make_stack reg_use_stack int ofs |] + | XFloat -> + loc.(i) <- + [| loc_float last_float make_stack reg_use_stack int float ofs |]) + ty_args; + (loc, Misc.align !ofs 16) (* Keep stack 16-aligned *) + +let loc_external_arguments ty_args = match abi with | ELF32 -> - calling_conventions 0 7 100 107 outgoing 8 false + external_calling_conventions 0 7 100 107 outgoing 8 false ty_args | ELF64v1 -> - fun args -> let (loc, ofs) = - calling_conventions 0 7 100 112 outgoing 0 true args in + external_calling_conventions 0 7 100 112 outgoing 0 true ty_args in (loc, max ofs 64) | ELF64v2 -> - fun args -> let (loc, ofs) = - calling_conventions 0 7 100 112 outgoing 0 true args in + external_calling_conventions 0 7 100 112 outgoing 0 true ty_args in if Array.fold_left (fun stk r -> assert (Array.length r = 1); @@ -249,10 +245,8 @@ let loc_external_arguments = (* Results are in GPR 3 and FPR 1 *) let loc_external_results res = - let (loc, _ofs) = - calling_conventions 0 1 100 100 not_supported 0 false (single_regs res) - in - ensure_single_regs loc + let (loc, _ofs) = calling_conventions 0 1 100 100 not_supported res + in loc (* Exceptions are in GPR 3 *) @@ -307,7 +301,7 @@ let destroyed_at_c_call = 100; 101; 102; 103; 104; 105; 106; 107; 108; 109; 110; 111; 112]) let destroyed_at_oper = function - Iop(Icall_ind _ | Icall_imm _ | Iextcall { alloc = true; _ }) -> + Iop(Icall_ind | Icall_imm _ | Iextcall { alloc = true; _ }) -> all_phys_regs | Iop(Iextcall { alloc = false; _ }) -> destroyed_at_c_call | _ -> [||] @@ -330,9 +324,9 @@ let max_register_pressure = function registers). *) let op_is_pure = function - | Icall_ind _ | Icall_imm _ | Itailcall_ind _ | Itailcall_imm _ + | Icall_ind | Icall_imm _ | Itailcall_ind | Itailcall_imm _ | Iextcall _ | Istackoffset _ | Istore _ | Ialloc _ - | Iintop(Icheckbound _) | Iintop_imm(Icheckbound _, _) -> false + | Iintop(Icheckbound) | Iintop_imm(Icheckbound, _) -> false | Ispecific(Imultaddf | Imultsubf) -> true | Ispecific _ -> false | _ -> true diff --git a/asmcomp/power/selection.ml b/asmcomp/power/selection.ml index 6e97feba..0e8d088a 100644 --- a/asmcomp/power/selection.ml +++ b/asmcomp/power/selection.ml @@ -43,13 +43,29 @@ let rec select_addr = function | exp -> (Alinear exp, 0, Debuginfo.none) +let is_immediate n = n <= 0x7FFF && n >= -0x8000 +let is_immediate_logical n = n <= 0xFFFF && n >= 0 + (* Instruction selection *) class selector = object (self) inherit Selectgen.selector_generic as super -method is_immediate n = (n <= 32767) && (n >= -32768) +method is_immediate_test cmp n = + match cmp with + | Isigned _ -> is_immediate n + | Iunsigned _ -> is_immediate_logical n + +method! is_immediate op n = + match op with + | Iadd | Imul -> is_immediate n + | Isub -> is_immediate (-n) (* turned into add opposite *) + | Iand | Ior | Ixor -> is_immediate_logical n + | Icomp c -> self#is_immediate_test c n + | Icheckbound -> 0 <= n && n <= 0x7FFF + (* twlle takes a 16-bit signed immediate but performs an unsigned compare *) + | _ -> super#is_immediate op n method select_addressing _chunk exp = match select_addr exp with @@ -64,13 +80,6 @@ method select_addressing _chunk exp = method! select_operation op args dbg = match (op, args) with - (* PowerPC does not support immediate operands for multiply high *) - (Cmulhi, _) -> (Iintop Imulh, args) - (* The and, or and xor instructions have a different range of immediate - operands than the other instructions *) - | (Cand, _) -> self#select_logical Iand args - | (Cor, _) -> self#select_logical Ior args - | (Cxor, _) -> self#select_logical Ixor args (* Recognize mult-add and mult-sub instructions *) | (Caddf, [Cop(Cmulf, [arg1; arg2], _); arg3]) -> (Ispecific Imultaddf, [arg1; arg2; arg3]) @@ -81,14 +90,6 @@ method! select_operation op args dbg = | _ -> super#select_operation op args dbg -method select_logical op = function - [arg; Cconst_int (n, _)] when n >= 0 && n <= 0xFFFF -> - (Iintop_imm(op, n), [arg]) - | [Cconst_int (n, _); arg] when n >= 0 && n <= 0xFFFF -> - (Iintop_imm(op, n), [arg]) - | args -> - (Iintop op, args) - end let fundecl f = (new selector)#emit_fundecl f diff --git a/asmcomp/printcmm.ml b/asmcomp/printcmm.ml index 377f9c2d..d54a97d9 100644 --- a/asmcomp/printcmm.ml +++ b/asmcomp/printcmm.ml @@ -39,6 +39,21 @@ let machtype ppf mty = fprintf ppf "*%a" machtype_component mty.(i) done +let exttype ppf = function + | XInt -> fprintf ppf "int" + | XInt32 -> fprintf ppf "int32" + | XInt64 -> fprintf ppf "int64" + | XFloat -> fprintf ppf "float" + +let extcall_signature ppf (ty_res, ty_args) = + begin match ty_args with + | [] -> () + | ty_arg1 :: ty_args -> + exttype ppf ty_arg1; + List.iter (fun ty -> fprintf ppf ",%a" exttype ty) ty_args + end; + fprintf ppf "->%a" machtype ty_res + let integer_comparison = function | Ceq -> "==" | Cne -> "!=" @@ -101,7 +116,7 @@ let location d = let operation d = function | Capply _ty -> "app" ^ location d - | Cextcall(lbl, _ty, _alloc, _) -> + | Cextcall(lbl, _ty_res, _ty_args, _alloc) -> Printf.sprintf "extcall \"%s\"%s" lbl (location d) | Cload (c, Asttypes.Immutable) -> Printf.sprintf "load %s" (chunk c) | Cload (c, Asttypes.Mutable) -> Printf.sprintf "load_mut %s" (chunk c) @@ -146,13 +161,8 @@ let rec expr ppf = function | Cconst_int (n, _dbg) -> fprintf ppf "%i" n | Cconst_natint (n, _dbg) -> fprintf ppf "%s" (Nativeint.to_string n) - | Cblockheader(n, d) -> - fprintf ppf "block-hdr(%s)%s" - (Nativeint.to_string n) (location d) | Cconst_float (n, _dbg) -> fprintf ppf "%F" n | Cconst_symbol (s, _dbg) -> fprintf ppf "\"%s\"" s - | Cconst_pointer (n, _dbg) -> fprintf ppf "%ia" n - | Cconst_natpointer (n, _dbg) -> fprintf ppf "%sa" (Nativeint.to_string n) | Cvar id -> V.print ppf id | Clet(id, def, (Clet(_, _, _) as body)) -> let print_binding id ppf def = @@ -209,7 +219,8 @@ let rec expr ppf = function List.iter (fun e -> fprintf ppf "@ %a" expr e) el; begin match op with | Capply mty -> fprintf ppf "@ %a" machtype mty - | Cextcall(_, mty, _, _) -> fprintf ppf "@ %a" machtype mty + | Cextcall(_, ty_res, ty_args, _) -> + fprintf ppf "@ %a" extcall_signature (ty_res, ty_args) | _ -> () end; fprintf ppf ")@]" diff --git a/asmcomp/printcmm.mli b/asmcomp/printcmm.mli index 462239ac..f88d8866 100644 --- a/asmcomp/printcmm.mli +++ b/asmcomp/printcmm.mli @@ -19,7 +19,9 @@ open Format val rec_flag : formatter -> Cmm.rec_flag -> unit val machtype_component : formatter -> Cmm.machtype_component -> unit -val machtype : formatter -> Cmm.machtype_component array -> unit +val machtype : formatter -> Cmm.machtype -> unit +val exttype : formatter -> Cmm.exttype -> unit +val extcall_signature : formatter -> Cmm.machtype * Cmm.exttype list -> unit val integer_comparison : Cmm.integer_comparison -> string val float_comparison : Cmm.float_comparison -> string val chunk : Cmm.memory_chunk -> string diff --git a/asmcomp/printlinear.ml b/asmcomp/printlinear.ml index 916d2a1a..433366c4 100644 --- a/asmcomp/printlinear.ml +++ b/asmcomp/printlinear.ml @@ -30,7 +30,7 @@ let instr ppf i = fprintf ppf "prologue" | Lop op -> begin match op with - | Ialloc _ | Icall_ind _ | Icall_imm _ | Iextcall _ -> + | Ialloc _ | Icall_ind | Icall_imm _ | Iextcall _ -> fprintf ppf "@[<1>{%a}@]@," regsetaddr i.live | _ -> () end; diff --git a/asmcomp/printmach.ml b/asmcomp/printmach.ml index 39128955..3d6689c4 100644 --- a/asmcomp/printmach.ml +++ b/asmcomp/printmach.ml @@ -90,16 +90,7 @@ let intop = function | Ilsr -> " >>u " | Iasr -> " >>s " | Icomp cmp -> intcomp cmp - | Icheckbound { label_after_error; spacetime_index; } -> - if not Config.spacetime then " check > " - else - Printf.sprintf "check[lbl=%s,index=%d] > " - begin - match label_after_error with - | None -> "" - | Some lbl -> Int.to_string lbl - end - spacetime_index + | Icheckbound -> Printf.sprintf "check > " let test tst ppf arg = match tst with @@ -122,9 +113,9 @@ let operation op arg ppf res = | Iconst_int n -> fprintf ppf "%s" (Nativeint.to_string n) | Iconst_float f -> fprintf ppf "%F" (Int64.float_of_bits f) | Iconst_symbol s -> fprintf ppf "\"%s\"" s - | Icall_ind _ -> fprintf ppf "call %a" regs arg - | Icall_imm { func; _ } -> fprintf ppf "call \"%s\" %a" func regs arg - | Itailcall_ind _ -> fprintf ppf "tailcall %a" regs arg + | Icall_ind -> fprintf ppf "call %a" regs arg + | Icall_imm { func; } -> fprintf ppf "call \"%s\" %a" func regs arg + | Itailcall_ind -> fprintf ppf "tailcall %a" regs arg | Itailcall_imm { func; } -> fprintf ppf "tailcall \"%s\" %a" func regs arg | Iextcall { func; alloc; _ } -> fprintf ppf "extcall \"%s\" %a%s" func regs arg @@ -141,11 +132,8 @@ let operation op arg ppf res = (Array.sub arg 1 (Array.length arg - 1)) reg arg.(0) (if is_assign then "(assign)" else "(init)") - | Ialloc { bytes = n; _ } -> + | Ialloc { bytes = n; } -> fprintf ppf "alloc %i" n; - if Config.spacetime then begin - fprintf ppf "(spacetime node = %a)" reg arg.(0) - end | Iintop(op) -> fprintf ppf "%a%s%a" reg arg.(0) (intop op) reg arg.(1) | Iintop_imm(op, n) -> fprintf ppf "%a%s%i" reg arg.(0) (intop op) n | Inegf -> fprintf ppf "-f %a" reg arg.(0) diff --git a/asmcomp/proc.mli b/asmcomp/proc.mli index 91b15de4..a92b1e9c 100644 --- a/asmcomp/proc.mli +++ b/asmcomp/proc.mli @@ -28,18 +28,15 @@ val phys_reg: int -> Reg.t val rotate_registers: bool (* Calling conventions *) -val loc_arguments: Reg.t array -> Reg.t array * int -val loc_results: Reg.t array -> Reg.t array -val loc_parameters: Reg.t array -> Reg.t array +val loc_arguments: Cmm.machtype -> Reg.t array * int +val loc_results: Cmm.machtype -> Reg.t array +val loc_parameters: Cmm.machtype -> Reg.t array (* For argument number [n] split across multiple registers, the target-specific implementation of [loc_external_arguments] must return [regs] such that - [regs.(n).(0)] is to hold the part of the value at the lowest address. - (All that matters for the input to [loc_external_arguments] is the pattern - of lengths and register types of the various supplied arrays.) *) -val loc_external_arguments: Reg.t array array -> Reg.t array array * int -val loc_external_results: Reg.t array -> Reg.t array + [regs.(n).(0)] is to hold the part of the value at the lowest address. *) +val loc_external_arguments: Cmm.exttype list -> Reg.t array array * int +val loc_external_results: Cmm.machtype -> Reg.t array val loc_exn_bucket: Reg.t -val loc_spacetime_node_hole: Reg.t (* The maximum number of arguments of an OCaml to OCaml function call for which it is guaranteed there will be no arguments passed on the stack. diff --git a/asmcomp/reg.ml b/asmcomp/reg.ml index 145545d9..2311a529 100644 --- a/asmcomp/reg.ml +++ b/asmcomp/reg.ml @@ -117,6 +117,9 @@ let at_location ty loc = incr currstamp; r +let typv rv = + Array.map (fun r -> r.typ) rv + let anonymous t = match Raw_name.to_string t.raw_name with | None -> true diff --git a/asmcomp/reg.mli b/asmcomp/reg.mli index 8e40f431..ad462c20 100644 --- a/asmcomp/reg.mli +++ b/asmcomp/reg.mli @@ -49,7 +49,7 @@ val createv: Cmm.machtype -> t array val createv_like: t array -> t array val clone: t -> t val at_location: Cmm.machtype_component -> location -> t - +val typv: t array -> Cmm.machtype val anonymous : t -> bool (* Name for printing *) diff --git a/asmcomp/reloadgen.ml b/asmcomp/reloadgen.ml index bea7bafa..a3505e15 100644 --- a/asmcomp/reloadgen.ml +++ b/asmcomp/reloadgen.ml @@ -83,13 +83,13 @@ method private reload i = However, something needs to be done for the function pointer in indirect calls. *) Iend | Ireturn | Iop(Itailcall_imm _) | Iraise _ -> i - | Iop(Itailcall_ind _) -> + | Iop(Itailcall_ind) -> let newarg = self#makereg1 i.arg in insert_moves i.arg newarg {i with arg = newarg} | Iop(Icall_imm _ | Iextcall _) -> {i with next = self#reload i.next} - | Iop(Icall_ind _) -> + | Iop(Icall_ind) -> let newarg = self#makereg1 i.arg in insert_moves i.arg newarg {i with arg = newarg; next = self#reload i.next} @@ -128,7 +128,7 @@ method fundecl f num_stack_slots = let new_body = self#reload f.fun_body in ({fun_name = f.fun_name; fun_args = f.fun_args; fun_body = new_body; fun_codegen_options = f.fun_codegen_options; - fun_dbg = f.fun_dbg; fun_spacetime_shape = f.fun_spacetime_shape; + fun_dbg = f.fun_dbg; fun_contains_calls = f.fun_contains_calls; fun_num_stack_slots = Array.copy num_stack_slots; }, diff --git a/asmcomp/riscv/arch.ml b/asmcomp/riscv/arch.ml index c6ade527..415c4792 100644 --- a/asmcomp/riscv/arch.ml +++ b/asmcomp/riscv/arch.ml @@ -27,9 +27,6 @@ type specific_operation = | Imultaddf of bool (* multiply, optionally negate, and add *) | Imultsubf of bool (* multiply, optionally negate, and subtract *) -let spacetime_node_hole_pointer_is_live_before = function - | Imultaddf _ | Imultsubf _ -> false - (* Addressing modes *) type addressing_mode = diff --git a/asmcomp/riscv/emit.mlp b/asmcomp/riscv/emit.mlp index dbfdc2d4..524087f9 100644 --- a/asmcomp/riscv/emit.mlp +++ b/asmcomp/riscv/emit.mlp @@ -143,12 +143,8 @@ let emit_float_store src ofs = (* Record live pointers at call points *) -let record_frame_label ?label live dbg = - let lbl = - match label with - | None -> new_label() - | Some label -> label - in +let record_frame_label live dbg = + let lbl = new_label () in let live_offset = ref [] in Reg.Set.iter (function @@ -165,8 +161,8 @@ let record_frame_label ?label live dbg = ~live_offset:!live_offset dbg; lbl -let record_frame ?label live dbg = - let lbl = record_frame_label ?label live dbg in +let record_frame live dbg = + let lbl = record_frame_label live dbg in `{emit_label lbl}:\n` (* Record calls to the GC -- we've moved them out of the way *) @@ -194,10 +190,10 @@ type bound_error_call = let bound_error_sites = ref ([] : bound_error_call list) -let bound_error_label ?label dbg = +let bound_error_label dbg = if !Clflags.debug || !bound_error_sites = [] then begin let lbl_bound_error = new_label() in - let lbl_frame = record_frame_label ?label Reg.Set.empty (Dbg_other dbg) in + let lbl_frame = record_frame_label Reg.Set.empty (Dbg_other dbg) in bound_error_sites := { bd_lbl = lbl_bound_error; bd_frame_lbl = lbl_frame } :: !bound_error_sites; @@ -311,18 +307,18 @@ let emit_instr i = ` fld {emit_reg i.res.(0)}, {emit_label lbl}, {emit_reg reg_tmp}\n` | Lop(Iconst_symbol s) -> ` la {emit_reg i.res.(0)}, {emit_symbol s}\n` - | Lop(Icall_ind {label_after = label}) -> + | Lop(Icall_ind) -> ` jalr {emit_reg i.arg.(0)}\n`; - record_frame ~label i.live (Dbg_other i.dbg) - | Lop(Icall_imm {func; label_after = label}) -> + record_frame i.live (Dbg_other i.dbg) + | Lop(Icall_imm {func}) -> ` {emit_call func}\n`; - record_frame ~label i.live (Dbg_other i.dbg) - | Lop(Itailcall_ind {label_after = _}) -> + record_frame i.live (Dbg_other i.dbg) + | Lop(Itailcall_ind) -> let n = frame_size() in if !contains_calls then reload_ra n; emit_stack_adjustment n; ` jr {emit_reg i.arg.(0)}\n` - | Lop(Itailcall_imm {func; label_after = _}) -> + | Lop(Itailcall_imm {func}) -> if func = !function_name then begin ` j {emit_label !tailrec_entry_point}\n` end else begin @@ -331,11 +327,11 @@ let emit_instr i = emit_stack_adjustment n; ` {emit_tail func}\n` end - | Lop(Iextcall{func; alloc = true; label_after = label}) -> + | Lop(Iextcall{func; alloc = true}) -> ` la {emit_reg reg_t2}, {emit_symbol func}\n`; ` {emit_call "caml_c_call"}\n`; - record_frame ~label i.live (Dbg_other i.dbg) - | Lop(Iextcall{func; alloc = false; label_after = _}) -> + record_frame i.live (Dbg_other i.dbg) + | Lop(Iextcall{func; alloc = false}) -> ` {emit_call func}\n` | Lop(Istackoffset n) -> assert (n mod 16 = 0); @@ -373,8 +369,8 @@ let emit_instr i = | Double | Double_u -> "fsd" in ` {emit_string instr} {emit_reg i.arg.(0)}, {emit_int ofs}({emit_reg i.arg.(1)})\n` - | Lop(Ialloc {bytes; label_after_call_gc = label; dbginfo}) -> - let lbl_frame_lbl = record_frame_label ?label i.live (Dbg_alloc dbginfo) in + | Lop(Ialloc {bytes; dbginfo}) -> + let lbl_frame_lbl = record_frame_label i.live (Dbg_alloc dbginfo) in let lbl_after_alloc = new_label () in let lbl_call_gc = new_label () in let n = -bytes in @@ -420,20 +416,14 @@ let emit_instr i = ` sltu {emit_reg i.res.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`; ` xori {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, 1\n`; end - | Lop(Iintop (Icheckbound {label_after_error = label; _})) -> - let lbl = bound_error_label ?label i.dbg in + | Lop(Iintop (Icheckbound)) -> + let lbl = bound_error_label i.dbg in ` bleu {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_label lbl}\n` | Lop(Iintop op) -> let instr = name_for_intop op in ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` | Lop(Iintop_imm(Isub, n)) -> ` addi {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_int(-n)}\n` - | Lop(Iintop_imm(Icomp _, _)) -> - Misc.fatal_error "Emit.emit_instr (Iintop_imm (Icomp _, _))" - | Lop(Iintop_imm(Icheckbound {label_after_error = label; _}, n)) -> - let lbl = bound_error_label ?label i.dbg in - ` li {emit_reg reg_tmp}, {emit_int n}\n`; - ` bleu {emit_reg i.arg.(0)}, {emit_reg reg_tmp}, {emit_label lbl}\n` | Lop(Iintop_imm(op, n)) -> let instr = name_for_intop_imm op in ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_int n}\n` diff --git a/asmcomp/riscv/proc.ml b/asmcomp/riscv/proc.ml index 4c7b5861..4e30e02b 100644 --- a/asmcomp/riscv/proc.ml +++ b/asmcomp/riscv/proc.ml @@ -36,7 +36,8 @@ let word_addressed = false a0-a7 0-7 arguments/results s2-s9 8-15 arguments/results (preserved by C) t2-t6 16-20 temporary - t0-t1 21-22 temporary (used by code generator) + t0 21 temporary + t1 22 temporary (used by code generator) s0 23 domain pointer (preserved by C) s1 24 trap pointer (preserved by C) s10 25 allocation pointer (preserved by C) @@ -55,8 +56,8 @@ let word_addressed = false Additional notes ---------------- - - t0-t1 are used by the assembler and code generator, so - not available for register allocation. + - t1 is used by the code generator, so not available for register + allocation. - t0-t6 may be used by PLT stubs, so should not be used to pass arguments and may be clobbered by [Ialloc] in the presence of dynamic @@ -127,7 +128,7 @@ let calling_conventions let float = ref first_float in let ofs = ref 0 in for i = 0 to Array.length arg - 1 do - match arg.(i).typ with + match arg.(i) with | Val | Int | Addr as ty -> if !int <= last_int then begin loc.(i) <- phys_reg !int; @@ -153,21 +154,12 @@ let not_supported _ = fatal_error "Proc.loc_results: cannot call" let max_arguments_for_tailcalls = 16 -let loc_spacetime_node_hole = Reg.dummy (* Spacetime unsupported *) - (* OCaml calling convention: first integer args in a0 .. a7, s2 .. s9 first float args in fa0 .. fa7, fs2 .. fs9 remaining args on stack. Return values in a0 .. a7, s2 .. s9 or fa0 .. fa7, fs2 .. fs9. *) -let single_regs arg = Array.map (fun arg -> [| arg |]) arg -let ensure_single_regs res = - Array.map (function - | [| res |] -> res - | _ -> failwith "proc.ensure_single_regs" - ) res - let loc_arguments arg = calling_conventions 0 15 110 125 outgoing arg @@ -199,42 +191,35 @@ let external_calling_conventions let ofs = ref 0 in for i = 0 to Array.length arg - 1 do match arg.(i) with - | [| arg |] -> - begin match arg.typ with - | Val | Int | Addr as ty -> - if !int <= last_int then begin - loc.(i) <- [| phys_reg !int |]; - incr int - end else begin - loc.(i) <- [| stack_slot (make_stack !ofs) ty |]; - ofs := !ofs + size_int - end - | Float -> - if !float <= last_float then begin - loc.(i) <- [| phys_reg !float |]; - incr float - end else if !int <= last_int then begin - loc.(i) <- [| phys_reg !int |]; - incr int - end else begin - loc.(i) <- [| stack_slot (make_stack !ofs) Float |]; - ofs := !ofs + size_float - end + | Val | Int | Addr as ty -> + if !int <= last_int then begin + loc.(i) <- [| phys_reg !int |]; + incr int + end else begin + loc.(i) <- [| stack_slot (make_stack !ofs) ty |]; + ofs := !ofs + size_int + end + | Float -> + if !float <= last_float then begin + loc.(i) <- [| phys_reg !float |]; + incr float + end else if !int <= last_int then begin + loc.(i) <- [| phys_reg !int |]; + incr int + end else begin + loc.(i) <- [| stack_slot (make_stack !ofs) Float |]; + ofs := !ofs + size_float end - | _ -> - fatal_error "Proc.calling_conventions: bad number of register for \ - multi-register argument" done; (loc, Misc.align !ofs 16) (* Keep stack 16-aligned. *) -let loc_external_arguments arg = +let loc_external_arguments ty_args = + let arg = Cmm.machtype_of_exttype_list ty_args in external_calling_conventions 0 7 110 117 outgoing arg let loc_external_results res = - let (loc, _ofs) = - external_calling_conventions 0 1 110 111 not_supported (single_regs res) - in - ensure_single_regs loc + let (loc, _ofs) = calling_conventions 0 1 110 111 not_supported res + in loc (* Exceptions are in a0 *) @@ -259,7 +244,7 @@ let destroyed_at_alloc = else [| |] let destroyed_at_oper = function - | Iop(Icall_ind _ | Icall_imm _ | Iextcall{alloc = true; _}) -> all_phys_regs + | Iop(Icall_ind | Icall_imm _ | Iextcall{alloc = true; _}) -> all_phys_regs | Iop(Iextcall{alloc = false; _}) -> destroyed_at_c_call | Iop(Ialloc _) -> destroyed_at_alloc | Iop(Istore(Single, _, _)) -> [| phys_reg 100 |] @@ -284,9 +269,9 @@ let max_register_pressure = function registers). *) let op_is_pure = function - | Icall_ind _ | Icall_imm _ | Itailcall_ind _ | Itailcall_imm _ + | Icall_ind | Icall_imm _ | Itailcall_ind | Itailcall_imm _ | Iextcall _ | Istackoffset _ | Istore _ | Ialloc _ - | Iintop(Icheckbound _) | Iintop_imm(Icheckbound _, _) -> false + | Iintop(Icheckbound) | Iintop_imm(Icheckbound, _) -> false | Ispecific(Imultaddf _ | Imultsubf _) -> true | _ -> true diff --git a/asmcomp/riscv/selection.ml b/asmcomp/riscv/selection.ml index 87d3355d..c99e1b3c 100644 --- a/asmcomp/riscv/selection.ml +++ b/asmcomp/riscv/selection.ml @@ -21,17 +21,25 @@ open Mach (* Instruction selection *) -class selector = object (self) +class selector = object inherit Selectgen.selector_generic as super -method is_immediate n = is_immediate n +(* RISC-V does not support immediate operands for comparison operators *) +method is_immediate_test _cmp _n = false + +method! is_immediate op n = + match op with + | Iadd | Iand | Ior | Ixor -> is_immediate n + (* sub immediate is turned into add immediate opposite *) + | Isub -> is_immediate (-n) + | _ -> super#is_immediate op n method select_addressing _ = function - | Cop(Cadda, [arg; Cconst_int (n, _)], _) when self#is_immediate n -> + | Cop(Cadda, [arg; Cconst_int (n, _)], _) when is_immediate n -> (Iindexed n, arg) | Cop(Cadda, [arg1; Cop(Caddi, [arg2; Cconst_int (n, _)], _)], dbg) - when self#is_immediate n -> + when is_immediate n -> (Iindexed n, Cop(Caddi, [arg1; arg2], dbg)) | arg -> (Iindexed 0, arg) @@ -48,28 +56,9 @@ method! select_operation op args dbg = (Ispecific (Imultsubf true), [arg1; arg2; arg3]) | (Cnegf, [Cop(Caddf, [Cop(Cmulf, [arg1; arg2], _); arg3], _)]) -> (Ispecific (Imultaddf true), [arg1; arg2; arg3]) - (* RISC-V does not support immediate operands for comparison operators *) - | (Ccmpi comp, args) -> (Iintop(Icomp (Isigned comp)), args) - | (Ccmpa comp, args) -> (Iintop(Icomp (Iunsigned comp)), args) - (* RISC-V does not support immediate operands for multiply/multiply high *) - | (Cmuli, _) -> (Iintop Imul, args) - | (Cmulhi, _) -> (Iintop Imulh, args) | _ -> super#select_operation op args dbg -(* Instruction selection for conditionals *) - -method! select_condition = function - Cop(Ccmpi cmp, args, _) -> - (Iinttest(Isigned cmp), Ctuple args) - | Cop(Ccmpa cmp, args, _) -> - (Iinttest(Iunsigned cmp), Ctuple args) - | Cop(Ccmpf cmp, args, _) -> - (Ifloattest cmp, Ctuple args) - | Cop(Cand, [arg; Cconst_int (1, _)], _) -> - (Ioddtest, arg) - | arg -> - (Itruetest, arg) end let fundecl f = (new selector)#emit_fundecl f diff --git a/asmcomp/s390x/arch.ml b/asmcomp/s390x/arch.ml index 84d52d64..a6353fdf 100644 --- a/asmcomp/s390x/arch.ml +++ b/asmcomp/s390x/arch.ml @@ -35,8 +35,6 @@ type specific_operation = Imultaddf (* multiply and add *) | Imultsubf (* multiply and subtract *) -let spacetime_node_hole_pointer_is_live_before _specific_op = false - (* Addressing modes *) type addressing_mode = diff --git a/asmcomp/s390x/emit.mlp b/asmcomp/s390x/emit.mlp index 419c43f3..5088075c 100644 --- a/asmcomp/s390x/emit.mlp +++ b/asmcomp/s390x/emit.mlp @@ -168,12 +168,8 @@ let emit_set_comp cmp res = (* Record live pointers at call points *) -let record_frame_label ?label live dbg = - let lbl = - match label with - | None -> new_label() - | Some label -> label - in +let record_frame_label live dbg = + let lbl = new_label() in let live_offset = ref [] in Reg.Set.iter (function @@ -189,8 +185,8 @@ let record_frame_label ?label live dbg = ~live_offset:!live_offset dbg; lbl -let record_frame ?label live dbg = - let lbl = record_frame_label ?label live dbg in +let record_frame live dbg = + let lbl = record_frame_label live dbg in `{emit_label lbl}:` (* Record calls to caml_call_gc, emitted out of line. *) @@ -215,10 +211,10 @@ type bound_error_call = let bound_error_sites = ref ([] : bound_error_call list) let bound_error_call = ref 0 -let bound_error_label ?label dbg = +let bound_error_label dbg = if !Clflags.debug then begin let lbl_bound_error = new_label() in - let lbl_frame = record_frame_label ?label Reg.Set.empty (Dbg_other dbg) in + let lbl_frame = record_frame_label Reg.Set.empty (Dbg_other dbg) in bound_error_sites := { bd_lbl = lbl_bound_error; bd_frame = lbl_frame } :: !bound_error_sites; lbl_bound_error @@ -355,20 +351,20 @@ let emit_instr i = ` ld {emit_reg i.res.(0)}, 0(%r1)\n` | Lop(Iconst_symbol s) -> emit_load_symbol_addr i.res.(0) s - | Lop(Icall_ind { label_after; }) -> + | Lop(Icall_ind) -> ` basr %r14, {emit_reg i.arg.(0)}\n`; - `{record_frame i.live (Dbg_other i.dbg) ~label:label_after}\n` + `{record_frame i.live (Dbg_other i.dbg)}\n` - | Lop(Icall_imm { func; label_after; }) -> + | Lop(Icall_imm { func; }) -> emit_call func; - `{record_frame i.live (Dbg_other i.dbg) ~label:label_after}\n` - | Lop(Itailcall_ind { label_after = _; }) -> + `{record_frame i.live (Dbg_other i.dbg)}\n` + | Lop(Itailcall_ind) -> let n = frame_size() in if !contains_calls then ` lg %r14, {emit_int(n - size_addr)}(%r15)\n`; emit_stack_adjust (-n); ` br {emit_reg i.arg.(0)}\n` - | Lop(Itailcall_imm { func; label_after = _; }) -> + | Lop(Itailcall_imm { func; }) -> if func = !function_name then ` brcl 15, {emit_label !tailrec_entry_point}\n` else begin @@ -382,12 +378,12 @@ let emit_instr i = ` brcl 15, {emit_symbol func}\n` end - | Lop(Iextcall { func; alloc; label_after; }) -> + | Lop(Iextcall { func; alloc; }) -> if not alloc then emit_call func else begin emit_load_symbol_addr reg_r7 func; emit_call "caml_c_call"; - `{record_frame i.live (Dbg_other i.dbg) ~label:label_after}\n` + `{record_frame i.live (Dbg_other i.dbg)}\n` end | Lop(Istackoffset n) -> @@ -424,11 +420,11 @@ let emit_instr i = | Double | Double_u -> "stdy" in emit_load_store storeinstr addr i.arg 1 i.arg.(0) - | Lop(Ialloc { bytes = n; label_after_call_gc; dbginfo }) -> + | Lop(Ialloc { bytes = n; dbginfo }) -> let lbl_after_alloc = new_label() in let lbl_call_gc = new_label() in let lbl_frame = - record_frame_label i.live (Dbg_alloc dbginfo) ?label:label_after_call_gc + record_frame_label i.live (Dbg_alloc dbginfo) in call_gc_sites := { gc_lbl = lbl_call_gc; @@ -483,8 +479,8 @@ let emit_instr i = ` brc {emit_int mask}, {emit_label lbl}\n`; ` lghi {emit_reg i.res.(0)}, 0\n`; `{emit_label lbl}:\n` - | Lop(Iintop (Icheckbound { label_after_error; })) -> - let lbl = bound_error_label i.dbg ?label:label_after_error in + | Lop(Iintop (Icheckbound)) -> + let lbl = bound_error_label i.dbg in ` clgr {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ` brcl 12, {emit_label lbl}\n` (* branch if unsigned le *) | Lop(Iintop op) -> @@ -503,8 +499,8 @@ let emit_instr i = ` brc {emit_int mask}, {emit_label lbl}\n`; ` lghi {emit_reg i.res.(0)}, 0\n`; `{emit_label lbl}:\n` - | Lop(Iintop_imm(Icheckbound { label_after_error; }, n)) -> - let lbl = bound_error_label i.dbg ?label:label_after_error in + | Lop(Iintop_imm(Icheckbound, n)) -> + let lbl = bound_error_label i.dbg in if n >= 0 then begin ` clgfi {emit_reg i.arg.(0)}, {emit_int n}\n`; ` brcl 12, {emit_label lbl}\n` (* branch if unsigned le *) diff --git a/asmcomp/s390x/proc.ml b/asmcomp/s390x/proc.ml index 9f0dff21..d9aa9ea3 100644 --- a/asmcomp/s390x/proc.ml +++ b/asmcomp/s390x/proc.ml @@ -94,8 +94,6 @@ let phys_reg n = let stack_slot slot ty = Reg.at_location ty (Stack slot) -let loc_spacetime_node_hole = Reg.dummy (* Spacetime unsupported *) - (* Calling conventions *) let calling_conventions @@ -105,7 +103,7 @@ let calling_conventions let float = ref first_float in let ofs = ref stack_ofs in for i = 0 to Array.length arg - 1 do - match arg.(i).typ with + match arg.(i) with | Val | Int | Addr as ty -> if !int <= last_int then begin loc.(i) <- phys_reg !int; @@ -145,11 +143,9 @@ let loc_results res = Always reserve 160 bytes at bottom of stack, plus whatever is needed to hold the overflow arguments. *) -let loc_external_arguments arg = - let arg = - Array.map (fun regs -> assert (Array.length regs = 1); regs.(0)) arg in - let (loc, ofs) = - calling_conventions 0 4 100 103 outgoing 160 arg in +let loc_external_arguments ty_args = + let arg = Cmm.machtype_of_exttype_list ty_args in + let (loc, ofs) = calling_conventions 0 4 100 103 outgoing 160 arg in (Array.map (fun reg -> [|reg|]) loc, ofs) (* Results are in GPR 2 and FPR 0 *) @@ -192,7 +188,7 @@ let destroyed_at_c_call = 100; 101; 102; 103; 104; 105; 106; 107]) let destroyed_at_oper = function - Iop(Icall_ind _ | Icall_imm _ | Iextcall { alloc = true; _ }) -> + Iop(Icall_ind | Icall_imm _ | Iextcall { alloc = true; _ }) -> all_phys_regs | Iop(Iextcall { alloc = false; _ }) -> destroyed_at_c_call | _ -> [||] @@ -217,9 +213,9 @@ let max_register_pressure = function registers). *) let op_is_pure = function - | Icall_ind _ | Icall_imm _ | Itailcall_ind _ | Itailcall_imm _ + | Icall_ind | Icall_imm _ | Itailcall_ind | Itailcall_imm _ | Iextcall _ | Istackoffset _ | Istore _ | Ialloc _ - | Iintop(Icheckbound _) | Iintop_imm(Icheckbound _, _) -> false + | Iintop(Icheckbound) | Iintop_imm(Icheckbound, _) -> false | Ispecific(Imultaddf | Imultsubf) -> true | _ -> true diff --git a/asmcomp/s390x/selection.ml b/asmcomp/s390x/selection.ml index 760719b5..604fd7a3 100644 --- a/asmcomp/s390x/selection.ml +++ b/asmcomp/s390x/selection.ml @@ -58,13 +58,27 @@ let pseudoregs_for_operation op arg res = (* Other instructions are regular *) | _ -> raise Use_default +let is_immediate n = n <= 0x7FFF_FFFF && n >= -0x8000_0000 +let is_immediate_logical n = n <= 0xFFFF_FFFF && n >= 0 + class selector = object (self) inherit Selectgen.selector_generic as super -method is_immediate n = n <= 0x7FFF_FFFF && n >= (-1-0x7FFF_FFFF) - (* -1-.... : hack so that this can be compiled on 32-bit - (cf 'make check_all_arches') *) +method is_immediate_test cmp n = + match cmp with + | Isigned _ -> is_immediate n + | Iunsigned _ -> is_immediate_logical n + +method! is_immediate op n = + match op with + | Iadd | Imul -> is_immediate n + | Isub -> is_immediate (-n) + | Iand -> n <= -1 && n >= -0x1_0000_0000 + | Ior | Ixor -> is_immediate_logical n + | Icomp c -> self#is_immediate_test c n + | Icheckbound -> is_immediate_logical n (* unsigned comparison *) + | _ -> super#is_immediate op n method select_addressing _chunk exp = let (a, d) = select_addr exp in @@ -78,14 +92,6 @@ method select_addressing _chunk exp = method! select_operation op args dbg = match (op, args) with - (* Z does not support immediate operands for multiply high *) - (Cmulhi, _) -> (Iintop Imulh, args) - (* The and, or and xor instructions have a different range of immediate - operands than the other instructions *) - | (Cand, _) -> - self#select_logical Iand (-1 lsl 32 (*0x1_0000_0000*)) (-1) args - | (Cor, _) -> self#select_logical Ior 0 (1 lsl 32 - 1 (*0xFFFF_FFFF*)) args - | (Cxor, _) -> self#select_logical Ixor 0 (1 lsl 32 - 1 (*0xFFFF_FFFF*)) args (* Recognize mult-add and mult-sub instructions *) | (Caddf, [Cop(Cmulf, [arg1; arg2], _); arg3]) -> (Ispecific Imultaddf, [arg1; arg2; arg3]) @@ -96,15 +102,6 @@ method! select_operation op args dbg = | _ -> super#select_operation op args dbg -method select_logical op lo hi = function - [arg; Cconst_int (n, _)] when n >= lo && n <= hi -> - (Iintop_imm(op, n), [arg]) - | [Cconst_int (n, _); arg] when n >= lo && n <= hi -> - (Iintop_imm(op, n), [arg]) - | args -> - (Iintop op, args) - - method! insert_op_debug env op dbg rs rd = try let (rsrc, rdst) = pseudoregs_for_operation op rs rd in diff --git a/asmcomp/schedgen.ml b/asmcomp/schedgen.ml index 966dbbec..e138930e 100644 --- a/asmcomp/schedgen.ml +++ b/asmcomp/schedgen.ml @@ -148,9 +148,9 @@ val mutable trywith_nesting = 0 that terminate a basic block. *) method oper_in_basic_block = function - Icall_ind _ -> false + Icall_ind -> false | Icall_imm _ -> false - | Itailcall_ind _ -> false + | Itailcall_ind -> false | Itailcall_imm _ -> false | Iextcall _ -> false | Istackoffset _ -> false @@ -185,8 +185,8 @@ method is_load = function | _ -> false method is_checkbound = function - Iintop (Icheckbound _) -> true - | Iintop_imm(Icheckbound _, _) -> true + Iintop(Icheckbound) -> true + | Iintop_imm(Icheckbound, _) -> true | _ -> false method private instr_is_store instr = @@ -376,7 +376,7 @@ method schedule_fundecl f = else begin let critical_outputs = match i.desc with - Lop(Icall_ind _ | Itailcall_ind _) -> [| i.arg.(0) |] + Lop(Icall_ind | Itailcall_ind) -> [| i.arg.(0) |] | Lop(Icall_imm _ | Itailcall_imm _ | Iextcall _) -> [||] | Lreturn -> [||] | _ -> i.arg in @@ -391,7 +391,6 @@ method schedule_fundecl f = fun_body = new_body; fun_fast = f.fun_fast; fun_dbg = f.fun_dbg; - fun_spacetime_shape = f.fun_spacetime_shape; fun_tailrec_entry_point_label = f.fun_tailrec_entry_point_label; fun_contains_calls = f.fun_contains_calls; fun_num_stack_slots = f.fun_num_stack_slots; diff --git a/asmcomp/selectgen.ml b/asmcomp/selectgen.ml index 20d070dc..4571c340 100644 --- a/asmcomp/selectgen.ml +++ b/asmcomp/selectgen.ml @@ -66,7 +66,7 @@ let env_empty = { let oper_result_type = function Capply ty -> ty - | Cextcall(_s, ty, _alloc, _) -> ty + | Cextcall(_s, ty_res, _ty_args, _alloc) -> ty_res | Cload (c, _) -> begin match c with | Word_val -> typ_val @@ -104,10 +104,9 @@ let size_machtype mty = let size_expr (env:environment) exp = let rec size localenv = function Cconst_int _ | Cconst_natint _ -> Arch.size_int - | Cconst_symbol _ | Cconst_pointer _ | Cconst_natpointer _ -> + | Cconst_symbol _ -> Arch.size_addr | Cconst_float _ -> Arch.size_float - | Cblockheader _ -> Arch.size_int | Cvar id -> begin try V.Map.find id localenv @@ -314,9 +313,6 @@ method is_simple_expr = function | Cconst_natint _ -> true | Cconst_float _ -> true | Cconst_symbol _ -> true - | Cconst_pointer _ -> true - | Cconst_natpointer _ -> true - | Cblockheader _ -> true | Cvar _ -> true | Ctuple el -> List.for_all self#is_simple_expr el | Clet(_id, arg, body) | Clet_mut(_id, _, arg, body) -> @@ -352,7 +348,6 @@ method effects_of exp = let module EC = Effect_and_coeffect in match exp with | Cconst_int _ | Cconst_natint _ | Cconst_float _ | Cconst_symbol _ - | Cconst_pointer _ | Cconst_natpointer _ | Cblockheader _ | Cvar _ -> EC.none | Ctuple el -> EC.join_list_map el self#effects_of | Clet (_id, arg, body) | Clet_mut (_id, _, arg, body) -> @@ -381,9 +376,18 @@ method effects_of exp = | Cassign _ | Cswitch _ | Ccatch _ | Cexit _ | Ctrywith _ -> EC.arbitrary -(* Says whether an integer constant is a suitable immediate argument *) +(* Says whether an integer constant is a suitable immediate argument for + the given integer operation *) -method virtual is_immediate : int -> bool +method is_immediate op n = + match op with + | Ilsl | Ilsr | Iasr -> n >= 0 && n < Arch.size_int * 8 + | _ -> false + +(* Says whether an integer constant is a suitable immediate argument for + the given integer test *) + +method virtual is_immediate_test : integer_comparison -> int -> bool (* Selection of addressing modes *) @@ -406,13 +410,13 @@ method mark_tailcall = () method mark_c_tailcall = () method mark_instr = function - | Iop (Icall_ind _ | Icall_imm _ | Iextcall _) -> + | Iop (Icall_ind | Icall_imm _ | Iextcall _) -> self#mark_call - | Iop (Itailcall_ind _ | Itailcall_imm _) -> + | Iop (Itailcall_ind | Itailcall_imm _) -> self#mark_tailcall | Iop (Ialloc _) -> self#mark_call (* caml_alloc*, caml_garbage_collection *) - | Iop (Iintop (Icheckbound _) | Iintop_imm(Icheckbound _, _)) -> + | Iop (Iintop(Icheckbound) | Iintop_imm(Icheckbound, _)) -> self#mark_c_tailcall (* caml_ml_array_bound_error *) | Iraise raise_kind -> begin match raise_kind with @@ -430,30 +434,14 @@ method mark_instr = function (* Default instruction selection for operators *) -method select_allocation bytes = - Ialloc { bytes; label_after_call_gc = None; - dbginfo = []; spacetime_index = 0; } -method select_allocation_args _env = [| |] - -method select_checkbound () = - Icheckbound { spacetime_index = 0; label_after_error = None; } -method select_checkbound_extra_args () = [] - method select_operation op args _dbg = match (op, args) with | (Capply _, Cconst_symbol (func, _dbg) :: rem) -> - let label_after = Cmm.new_label () in - (Icall_imm { func; label_after; }, rem) + (Icall_imm { func; }, rem) | (Capply _, _) -> - let label_after = Cmm.new_label () in - (Icall_ind { label_after; }, args) - | (Cextcall(func, _ty, alloc, label_after), _) -> - let label_after = - match label_after with - | None -> Cmm.new_label () - | Some label_after -> label_after - in - Iextcall { func; alloc; label_after; }, args + (Icall_ind, args) + | (Cextcall(func, ty_res, ty_args, alloc), _) -> + Iextcall { func; ty_res; ty_args; alloc; }, args | (Cload (chunk, _mut), [arg]) -> let (addr, eloc) = self#select_addressing chunk arg in (Iload(chunk, addr), [eloc]) @@ -472,7 +460,7 @@ method select_operation op args _dbg = (Istore(chunk, addr, is_assign), [arg2; eloc]) (* Inversion addr/datum in Istore *) end - | (Calloc, _) -> (self#select_allocation 0), args + | (Calloc, _) -> (Ialloc {bytes = 0; dbginfo = []}), args | (Caddi, _) -> self#select_arith_comm Iadd args | (Csubi, _) -> self#select_arith Isub args | (Cmuli, _) -> self#select_arith_comm Imul args @@ -482,9 +470,9 @@ method select_operation op args _dbg = | (Cand, _) -> self#select_arith_comm Iand args | (Cor, _) -> self#select_arith_comm Ior args | (Cxor, _) -> self#select_arith_comm Ixor args - | (Clsl, _) -> self#select_shift Ilsl args - | (Clsr, _) -> self#select_shift Ilsr args - | (Casr, _) -> self#select_shift Iasr args + | (Clsl, _) -> self#select_arith Ilsl args + | (Clsr, _) -> self#select_arith Ilsr args + | (Casr, _) -> self#select_arith Iasr args | (Ccmpi comp, _) -> self#select_arith_comp (Isigned comp) args | (Caddv, _) -> self#select_arith_comm Iadd args | (Cadda, _) -> self#select_arith_comm Iadd args @@ -498,45 +486,28 @@ method select_operation op args _dbg = | (Cfloatofint, _) -> (Ifloatofint, args) | (Cintoffloat, _) -> (Iintoffloat, args) | (Ccheckbound, _) -> - let extra_args = self#select_checkbound_extra_args () in - let op = self#select_checkbound () in - self#select_arith op (args @ extra_args) + self#select_arith Icheckbound args | _ -> Misc.fatal_error "Selection.select_oper" method private select_arith_comm op = function - [arg; Cconst_int (n, _)] when self#is_immediate n -> - (Iintop_imm(op, n), [arg]) - | [arg; Cconst_pointer (n, _)] when self#is_immediate n -> + | [arg; Cconst_int (n, _)] when self#is_immediate op n -> (Iintop_imm(op, n), [arg]) - | [Cconst_int (n, _); arg] when self#is_immediate n -> - (Iintop_imm(op, n), [arg]) - | [Cconst_pointer (n, _); arg] when self#is_immediate n -> + | [Cconst_int (n, _); arg] when self#is_immediate op n -> (Iintop_imm(op, n), [arg]) | args -> (Iintop op, args) method private select_arith op = function - [arg; Cconst_int (n, _)] when self#is_immediate n -> - (Iintop_imm(op, n), [arg]) - | [arg; Cconst_pointer (n, _)] when self#is_immediate n -> - (Iintop_imm(op, n), [arg]) - | args -> - (Iintop op, args) - -method private select_shift op = function - [arg; Cconst_int (n, _)] when n >= 0 && n < Arch.size_int * 8 -> + | [arg; Cconst_int (n, _)] when self#is_immediate op n -> (Iintop_imm(op, n), [arg]) | args -> (Iintop op, args) method private select_arith_comp cmp = function - [arg; Cconst_int (n, _)] when self#is_immediate n -> + | [arg; Cconst_int (n, _)] when self#is_immediate (Icomp cmp) n -> (Iintop_imm(Icomp cmp, n), [arg]) - | [arg; Cconst_pointer (n, _)] when self#is_immediate n -> - (Iintop_imm(Icomp cmp, n), [arg]) - | [Cconst_int (n, _); arg] when self#is_immediate n -> - (Iintop_imm(Icomp(swap_intcomp cmp), n), [arg]) - | [Cconst_pointer (n, _); arg] when self#is_immediate n -> + | [Cconst_int (n, _); arg] + when self#is_immediate (Icomp(swap_intcomp cmp)) n -> (Iintop_imm(Icomp(swap_intcomp cmp), n), [arg]) | args -> (Iintop(Icomp cmp), args) @@ -544,23 +515,19 @@ method private select_arith_comp cmp = function (* Instruction selection for conditionals *) method select_condition = function - Cop(Ccmpi cmp, [arg1; Cconst_int (n, _)], _) when self#is_immediate n -> - (Iinttest_imm(Isigned cmp, n), arg1) - | Cop(Ccmpi cmp, [Cconst_int (n, _); arg2], _) when self#is_immediate n -> - (Iinttest_imm(Isigned(swap_integer_comparison cmp), n), arg2) - | Cop(Ccmpi cmp, [arg1; Cconst_pointer (n, _)], _) when self#is_immediate n -> + | Cop(Ccmpi cmp, [arg1; Cconst_int (n, _)], _) + when self#is_immediate_test (Isigned cmp) n -> (Iinttest_imm(Isigned cmp, n), arg1) - | Cop(Ccmpi cmp, [Cconst_pointer (n, _); arg2], _) when self#is_immediate n -> + | Cop(Ccmpi cmp, [Cconst_int (n, _); arg2], _) + when self#is_immediate_test (Isigned (swap_integer_comparison cmp)) n -> (Iinttest_imm(Isigned(swap_integer_comparison cmp), n), arg2) | Cop(Ccmpi cmp, args, _) -> (Iinttest(Isigned cmp), Ctuple args) - | Cop(Ccmpa cmp, [arg1; Cconst_pointer (n, _)], _) when self#is_immediate n -> - (Iinttest_imm(Iunsigned cmp, n), arg1) - | Cop(Ccmpa cmp, [arg1; Cconst_int (n, _)], _) when self#is_immediate n -> + | Cop(Ccmpa cmp, [arg1; Cconst_int (n, _)], _) + when self#is_immediate_test (Iunsigned cmp) n -> (Iinttest_imm(Iunsigned cmp, n), arg1) - | Cop(Ccmpa cmp, [Cconst_pointer (n, _); arg2], _) when self#is_immediate n -> - (Iinttest_imm(Iunsigned(swap_integer_comparison cmp), n), arg2) - | Cop(Ccmpa cmp, [Cconst_int (n, _); arg2], _) when self#is_immediate n -> + | Cop(Ccmpa cmp, [Cconst_int (n, _); arg2], _) + when self#is_immediate_test (Iunsigned (swap_integer_comparison cmp)) n -> (Iinttest_imm(Iunsigned(swap_integer_comparison cmp), n), arg2) | Cop(Ccmpa cmp, args, _) -> (Iinttest(Iunsigned cmp), Ctuple args) @@ -588,15 +555,12 @@ method insert_debug _env desc dbg arg res = method insert _env desc arg res = instr_seq <- instr_cons desc arg res instr_seq -method extract_core ~end_instr = +method extract = let rec extract res i = if i == dummy_instr then res else extract {i with next = res} i.next in - extract end_instr instr_seq - -method extract = - self#extract_core ~end_instr:(end_instr ()) + extract (end_instr ()) instr_seq (* Insert a sequence of moves from one pseudoreg set to another. *) @@ -634,20 +598,6 @@ method insert_op_debug env op dbg rs rd = method insert_op env op rs rd = self#insert_op_debug env op Debuginfo.none rs rd -method emit_blockheader env n _dbg = - let r = self#regs_for typ_int in - Some(self#insert_op env (Iconst_int n) [||] r) - -method about_to_emit_call _env _insn _arg _dbg = None - -(* Prior to a function call, update the Spacetime node hole pointer hard - register. *) - -method private maybe_emit_spacetime_move env ~spacetime_reg = - Option.iter (fun reg -> - self#insert_moves env reg [| Proc.loc_spacetime_node_hole |]) - spacetime_reg - (* Add the instructions for the given expression at the end of the self sequence *) @@ -672,14 +622,6 @@ method emit_expr (env:environment) exp = adding this register to the frame table would be redundant *) let r = self#regs_for typ_int in Some(self#insert_op env (Iconst_symbol n) [||] r) - | Cconst_pointer (n, _dbg) -> - let r = self#regs_for typ_int in - Some(self#insert_op env (Iconst_int(Nativeint.of_int n)) [||] r) - | Cconst_natpointer (n, _dbg) -> - let r = self#regs_for typ_int in - Some(self#insert_op env (Iconst_int n) [||] r) - | Cblockheader(n, dbg) -> - self#emit_blockheader env n dbg | Cvar v -> begin try Some(env_find v env) @@ -739,17 +681,13 @@ method emit_expr (env:environment) exp = let ty = oper_result_type op in let (new_op, new_args) = self#select_operation op simple_args dbg in match new_op with - Icall_ind _ -> + Icall_ind -> let r1 = self#emit_tuple env new_args in let rarg = Array.sub r1 1 (Array.length r1 - 1) in let rd = self#regs_for ty in - let (loc_arg, stack_ofs) = Proc.loc_arguments rarg in - let loc_res = Proc.loc_results rd in - let spacetime_reg = - self#about_to_emit_call env (Iop new_op) [| r1.(0) |] dbg - in + let (loc_arg, stack_ofs) = Proc.loc_arguments (Reg.typv rarg) in + let loc_res = Proc.loc_results (Reg.typv rd) in self#insert_move_args env rarg loc_arg stack_ofs; - self#maybe_emit_spacetime_move env ~spacetime_reg; self#insert_debug env (Iop new_op) dbg (Array.append [|r1.(0)|] loc_arg) loc_res; self#insert_move_results env loc_res rd stack_ofs; @@ -757,39 +695,30 @@ method emit_expr (env:environment) exp = | Icall_imm _ -> let r1 = self#emit_tuple env new_args in let rd = self#regs_for ty in - let (loc_arg, stack_ofs) = Proc.loc_arguments r1 in - let loc_res = Proc.loc_results rd in - let spacetime_reg = - self#about_to_emit_call env (Iop new_op) [| |] dbg - in + let (loc_arg, stack_ofs) = Proc.loc_arguments (Reg.typv r1) in + let loc_res = Proc.loc_results (Reg.typv rd) in self#insert_move_args env r1 loc_arg stack_ofs; - self#maybe_emit_spacetime_move env ~spacetime_reg; self#insert_debug env (Iop new_op) dbg loc_arg loc_res; self#insert_move_results env loc_res rd stack_ofs; Some rd - | Iextcall _ -> - let spacetime_reg = - self#about_to_emit_call env (Iop new_op) [| |] dbg - in - let (loc_arg, stack_ofs) = self#emit_extcall_args env new_args in - self#maybe_emit_spacetime_move env ~spacetime_reg; + | Iextcall { ty_args; _} -> + let (loc_arg, stack_ofs) = + self#emit_extcall_args env ty_args new_args in let rd = self#regs_for ty in let loc_res = self#insert_op_debug env new_op dbg - loc_arg (Proc.loc_external_results rd) in + loc_arg (Proc.loc_external_results (Reg.typv rd)) in self#insert_move_results env loc_res rd stack_ofs; Some rd - | Ialloc { bytes = _; spacetime_index; label_after_call_gc; } -> + | Ialloc { bytes = _; } -> let rd = self#regs_for typ_val in let bytes = size_expr env (Ctuple new_args) in assert (bytes mod Arch.size_addr = 0); let alloc_words = bytes / Arch.size_addr in let op = - Ialloc { bytes; spacetime_index; label_after_call_gc; - dbginfo = [{alloc_words; alloc_dbg = dbg}] } + Ialloc { bytes; dbginfo = [{alloc_words; alloc_dbg = dbg}] } in - let args = self#select_allocation_args env in - self#insert_debug env (Iop op) dbg args rd; + self#insert_debug env (Iop op) dbg [||] rd; self#emit_stores env new_args rd; Some rd | op -> @@ -1024,19 +953,26 @@ method private emit_tuple_not_flattened env exp_list = method private emit_tuple env exp_list = Array.concat (self#emit_tuple_not_flattened env exp_list) -method emit_extcall_args env args = +method emit_extcall_args env ty_args args = let args = self#emit_tuple_not_flattened env args in - let arg_hard_regs, stack_ofs = - Proc.loc_external_arguments (Array.of_list args) - in - (* Flattening [args] and [arg_hard_regs] causes parts of values split - across multiple registers to line up correctly, by virtue of the - semantics of [split_int64_for_32bit_target] in cmmgen.ml, and the - required semantics of [loc_external_arguments] (see proc.mli). *) - let args = Array.concat args in - let arg_hard_regs = Array.concat (Array.to_list arg_hard_regs) in - self#insert_move_args env args arg_hard_regs stack_ofs; - arg_hard_regs, stack_ofs + let ty_args = + if ty_args = [] then List.map (fun _ -> XInt) args else ty_args in + let locs, stack_ofs = Proc.loc_external_arguments ty_args in + let ty_args = Array.of_list ty_args in + if stack_ofs <> 0 then + self#insert env (Iop(Istackoffset stack_ofs)) [||] [||]; + List.iteri + (fun i arg -> + self#insert_move_extcall_arg env ty_args.(i) arg locs.(i)) + args; + Array.concat (Array.to_list locs), stack_ofs + +method insert_move_extcall_arg env _ty_arg src dst = + (* The default implementation is one or two ordinary moves. + (Two in the case of an int64 argument on a 32-bit platform.) + It can be overridden to use special move instructions, + for example a "32-bit move" instruction for int32 arguments. *) + self#insert_moves env src dst method emit_stores env data regs_addr = let a = @@ -1068,7 +1004,7 @@ method private emit_return (env:environment) exp = match self#emit_expr env exp with None -> () | Some r -> - let loc = Proc.loc_results r in + let loc = Proc.loc_results (Reg.typv r) in self#insert_moves env r loc; self#insert env Ireturn loc [||] @@ -1092,60 +1028,40 @@ method emit_tail (env:environment) exp = | Some(simple_args, env) -> let (new_op, new_args) = self#select_operation op simple_args dbg in match new_op with - Icall_ind { label_after; } -> + Icall_ind -> let r1 = self#emit_tuple env new_args in let rarg = Array.sub r1 1 (Array.length r1 - 1) in - let (loc_arg, stack_ofs) = Proc.loc_arguments rarg in + let (loc_arg, stack_ofs) = Proc.loc_arguments (Reg.typv rarg) in if stack_ofs = 0 then begin - let call = Iop (Itailcall_ind { label_after; }) in - let spacetime_reg = - self#about_to_emit_call env call [| r1.(0) |] dbg - in + let call = Iop (Itailcall_ind) in self#insert_moves env rarg loc_arg; - self#maybe_emit_spacetime_move env ~spacetime_reg; self#insert_debug env call dbg (Array.append [|r1.(0)|] loc_arg) [||]; end else begin let rd = self#regs_for ty in - let loc_res = Proc.loc_results rd in - let spacetime_reg = - self#about_to_emit_call env (Iop new_op) [| r1.(0) |] dbg - in + let loc_res = Proc.loc_results (Reg.typv rd) in self#insert_move_args env rarg loc_arg stack_ofs; - self#maybe_emit_spacetime_move env ~spacetime_reg; self#insert_debug env (Iop new_op) dbg (Array.append [|r1.(0)|] loc_arg) loc_res; self#insert env (Iop(Istackoffset(-stack_ofs))) [||] [||]; self#insert env Ireturn loc_res [||] end - | Icall_imm { func; label_after; } -> + | Icall_imm { func; } -> let r1 = self#emit_tuple env new_args in - let (loc_arg, stack_ofs) = Proc.loc_arguments r1 in + let (loc_arg, stack_ofs) = Proc.loc_arguments (Reg.typv r1) in if stack_ofs = 0 then begin - let call = Iop (Itailcall_imm { func; label_after; }) in - let spacetime_reg = - self#about_to_emit_call env call [| |] dbg - in + let call = Iop (Itailcall_imm { func; }) in self#insert_moves env r1 loc_arg; - self#maybe_emit_spacetime_move env ~spacetime_reg; self#insert_debug env call dbg loc_arg [||]; end else if func = !current_function_name then begin - let call = Iop (Itailcall_imm { func; label_after; }) in - let loc_arg' = Proc.loc_parameters r1 in - let spacetime_reg = - self#about_to_emit_call env call [| |] dbg - in + let call = Iop (Itailcall_imm { func; }) in + let loc_arg' = Proc.loc_parameters (Reg.typv r1) in self#insert_moves env r1 loc_arg'; - self#maybe_emit_spacetime_move env ~spacetime_reg; self#insert_debug env call dbg loc_arg' [||]; end else begin let rd = self#regs_for ty in - let loc_res = Proc.loc_results rd in - let spacetime_reg = - self#about_to_emit_call env (Iop new_op) [| |] dbg - in + let loc_res = Proc.loc_results (Reg.typv rd) in self#insert_move_args env r1 loc_arg stack_ofs; - self#maybe_emit_spacetime_move env ~spacetime_reg; self#insert_debug env (Iop new_op) dbg loc_arg loc_res; self#insert env (Iop(Istackoffset(-stack_ofs))) [||] [||]; self#insert env Ireturn loc_res [||] @@ -1215,13 +1131,12 @@ method emit_tail (env:environment) exp = begin match opt_r1 with None -> () | Some r1 -> - let loc = Proc.loc_results r1 in + let loc = Proc.loc_results (Reg.typv r1) in self#insert_moves env r1 loc; self#insert env Ireturn loc [||] end | Cop _ | Cconst_int _ | Cconst_natint _ | Cconst_float _ | Cconst_symbol _ - | Cconst_pointer _ | Cconst_natpointer _ | Cblockheader _ | Cvar _ | Cassign _ | Ctuple _ @@ -1233,16 +1148,8 @@ method private emit_tail_sequence env exp = s#emit_tail env exp; s#extract -(* Insertion of the function prologue *) - -method insert_prologue _f ~loc_arg ~rarg ~spacetime_node_hole:_ ~env = - self#insert_moves env loc_arg rarg; - None - (* Sequentialization of a function definition *) -method initial_env () = env_empty - method emit_fundecl f = current_function_name := f.Cmm.fun_name; let rargs = @@ -1250,57 +1157,25 @@ method emit_fundecl f = (fun (id, ty) -> let r = self#regs_for ty in name_regs id r; r) f.Cmm.fun_args in let rarg = Array.concat rargs in - let loc_arg = Proc.loc_parameters rarg in - (* To make it easier to add the Spacetime instrumentation code, we - first emit the body and extract the resulting instruction sequence; - then we emit the prologue followed by any Spacetime instrumentation. The - sequence resulting from extracting the latter (prologue + instrumentation) - together is then simply prepended to the body. *) + let loc_arg = Proc.loc_parameters (Reg.typv rarg) in let env = List.fold_right2 (fun (id, _ty) r env -> env_add id r env) - f.Cmm.fun_args rargs (self#initial_env ()) in - let spacetime_node_hole, env = - if not Config.spacetime then None, env - else begin - let reg = self#regs_for typ_int in - let node_hole = V.create_local "spacetime_node_hole" in - Some (node_hole, reg), env_add (VP.create node_hole) reg env - end - in + f.Cmm.fun_args rargs env_empty in + self#insert_moves env loc_arg rarg; self#emit_tail env f.Cmm.fun_body; let body = self#extract in - instr_seq <- dummy_instr; - let fun_spacetime_shape = - self#insert_prologue f ~loc_arg ~rarg ~spacetime_node_hole ~env - in - let body = self#extract_core ~end_instr:body in instr_iter (fun instr -> self#mark_instr instr.Mach.desc) body; { fun_name = f.Cmm.fun_name; fun_args = loc_arg; fun_body = body; fun_codegen_options = f.Cmm.fun_codegen_options; fun_dbg = f.Cmm.fun_dbg; - fun_spacetime_shape; fun_num_stack_slots = Array.make Proc.num_register_classes 0; fun_contains_calls = !contains_calls; } end -(* Tail call criterion (estimated). Assumes: -- all arguments are of type "int" (always the case for OCaml function calls) -- one extra argument representing the closure environment (conservative). -*) - -let is_tail_call nargs = - assert (Reg.dummy.typ = Int); - let args = Array.make (nargs + 1) Reg.dummy in - let (_loc_arg, stack_ofs) = Proc.loc_arguments args in - stack_ofs = 0 - -let _ = - Simplif.is_tail_native_heuristic := is_tail_call - let reset () = current_function_name := "" diff --git a/asmcomp/selectgen.mli b/asmcomp/selectgen.mli index 96474564..c657e109 100644 --- a/asmcomp/selectgen.mli +++ b/asmcomp/selectgen.mli @@ -62,9 +62,14 @@ end class virtual selector_generic : object (* The following methods must or can be overridden by the processor description *) - method virtual is_immediate : int -> bool + method is_immediate : Mach.integer_operation -> int -> bool + (* Must be overriden to indicate whether a constant is a suitable + immediate operand to the given integer arithmetic instruction. + The default implementation handles shifts by immediate amounts, + but produces no immediate operations otherwise. *) + method virtual is_immediate_test : Mach.integer_comparison -> int -> bool (* Must be defined to indicate whether a constant is a suitable - immediate operand to arithmetic instructions *) + immediate operand to the given integer test *) method virtual select_addressing : Cmm.memory_chunk -> Cmm.expression -> Arch.addressing_mode * Cmm.expression (* Must be defined to select addressing modes *) @@ -97,8 +102,13 @@ class virtual selector_generic : object -> Reg.t array -> Reg.t array (* Can be overridden to deal with 2-address instructions or instructions with hardwired input/output registers *) + method insert_move_extcall_arg : + environment -> Cmm.exttype -> Reg.t array -> Reg.t array -> unit + (* Can be overridden to deal with unusual unboxed calling conventions, + e.g. on a 64-bit platform, passing unboxed 32-bit arguments + in 32-bit stack slots. *) method emit_extcall_args : - environment -> Cmm.expression list -> Reg.t array * int + environment -> Cmm.exttype list -> Cmm.expression list -> Reg.t array * int (* Can be overridden to deal with stack-based calling conventions *) method emit_stores : environment -> Cmm.expression list -> Reg.t array -> unit @@ -129,15 +139,13 @@ class virtual selector_generic : object above; overloading this is useful if Ispecific instructions need marking *) - (* The following method is the entry point and should not be overridden - (except by [Spacetime_profiling]). *) + (* The following method is the entry point and should not be overridden. *) method emit_fundecl : Cmm.fundecl -> Mach.fundecl (* The following methods should not be overridden. They cannot be declared "private" in the current implementation because they are not always applied to "self", but ideally they should be private. *) method extract : Mach.instruction - method extract_core : end_instr:Mach.instruction -> Mach.instruction method insert : environment -> Mach.instruction_desc -> Reg.t array -> Reg.t array -> unit method insert_debug : @@ -153,33 +161,6 @@ class virtual selector_generic : object environment -> Cmm.expression -> Reg.t array option method emit_tail : environment -> Cmm.expression -> unit - (* Only for the use of [Spacetime_profiling]. *) - method select_allocation : int -> Mach.operation - method select_allocation_args : environment -> Reg.t array - method select_checkbound : unit -> Mach.integer_operation - method select_checkbound_extra_args : unit -> Cmm.expression list - method emit_blockheader - : environment - -> nativeint - -> Debuginfo.t - -> Reg.t array option - method about_to_emit_call - : environment - -> Mach.instruction_desc - -> Reg.t array - -> Debuginfo.t - -> Reg.t array option - method initial_env : unit -> environment - method insert_prologue - : Cmm.fundecl - -> loc_arg:Reg.t array - -> rarg:Reg.t array - -> spacetime_node_hole:(Backend_var.t * Reg.t array) option - -> env:environment - -> Mach.spacetime_shape option - - val mutable instr_seq : Mach.instruction - (* [contains_calls] is declared as a reference instance variable, instead of a mutable boolean instance variable, because the traversal uses functional object copies. *) diff --git a/asmcomp/spacetime_profiling.ml b/asmcomp/spacetime_profiling.ml deleted file mode 100644 index 62e182ab..00000000 --- a/asmcomp/spacetime_profiling.ml +++ /dev/null @@ -1,480 +0,0 @@ -(**************************************************************************) -(* *) -(* OCaml *) -(* *) -(* Mark Shinwell and Leo White, Jane Street Europe *) -(* *) -(* Copyright 2015--2018 Jane Street Group LLC *) -(* *) -(* All rights reserved. This file is distributed under the terms of *) -(* the GNU Lesser General Public License version 2.1, with the *) -(* special exception on linking described in the file LICENSE. *) -(* *) -(**************************************************************************) - -[@@@ocaml.warning "+a-4-30-40-41-42"] - -module V = Backend_var -module VP = Backend_var.With_provenance - -let node_num_header_words = 2 (* [Node_num_header_words] in the runtime. *) -let index_within_node = ref node_num_header_words -(* The [lazy]s are to ensure that we don't create [V.t]s at toplevel - when not using Spacetime profiling. (This could cause stamps to differ - between bytecode and native .cmis when no .mli is present, e.g. - arch.ml.) *) -let spacetime_node = ref (lazy (Cmm.Cvar (V.create_local "dummy"))) -let spacetime_node_ident = ref (lazy (V.create_local "dummy")) -let current_function_label = ref None -let direct_tail_call_point_indexes = ref [] - -let reverse_shape = ref ([] : Mach.spacetime_shape) - -(* CR-someday mshinwell: This code could be updated to use [placeholder_dbg] as - in [Cmmgen]. *) -let cconst_int i = Cmm.Cconst_int (i, Debuginfo.none) -let cconst_natint i = Cmm.Cconst_natint (i, Debuginfo.none) -let cconst_symbol s = Cmm.Cconst_symbol (s, Debuginfo.none) - -let something_was_instrumented () = - !index_within_node > node_num_header_words - -let next_index_within_node ~part_of_shape ~label = - let index = !index_within_node in - begin match part_of_shape with - | Mach.Direct_call_point _ -> - incr index_within_node; - if Config.enable_call_counts then begin - incr index_within_node - end - | Mach.Indirect_call_point -> - incr index_within_node - | Mach.Allocation_point -> - incr index_within_node; - incr index_within_node; - incr index_within_node - end; - reverse_shape := (part_of_shape, label) :: !reverse_shape; - index - -let reset ~spacetime_node_ident:ident ~function_label = - index_within_node := node_num_header_words; - spacetime_node := lazy (Cmm.Cvar ident); - spacetime_node_ident := lazy ident; - direct_tail_call_point_indexes := []; - current_function_label := Some function_label; - reverse_shape := [] - -let code_for_function_prologue ~function_name ~fun_dbg:dbg ~node_hole = - let node = V.create_local "node" in - let new_node = V.create_local "new_node" in - let must_allocate_node = V.create_local "must_allocate_node" in - let is_new_node = V.create_local "is_new_node" in - let no_tail_calls = List.length !direct_tail_call_point_indexes < 1 in - let open Cmm in - let initialize_direct_tail_call_points_and_return_node = - let new_node_encoded = V.create_local "new_node_encoded" in - (* The callee node pointers within direct tail call points must initially - point back at the start of the current node and be marked as per - [Encode_tail_caller_node] in the runtime. *) - let indexes = !direct_tail_call_point_indexes in - let body = - List.fold_left (fun init_code index -> - (* Cf. [Direct_callee_node] in the runtime. *) - let offset_in_bytes = index * Arch.size_addr in - Csequence ( - Cop (Cstore (Word_int, Lambda.Assignment), - [Cop (Caddi, [Cvar new_node; cconst_int offset_in_bytes], dbg); - Cvar new_node_encoded], dbg), - init_code)) - (Cvar new_node) - indexes - in - match indexes with - | [] -> body - | _ -> - Clet (VP.create new_node_encoded, - (* Cf. [Encode_tail_caller_node] in the runtime. *) - Cop (Cor, [Cvar new_node; cconst_int 1], dbg), - body) - in - let pc = V.create_local "pc" in - Clet (VP.create node, - Cop (Cload (Word_int, Asttypes.Mutable), [Cvar node_hole], dbg), - Clet (VP.create must_allocate_node, - Cop (Cand, [Cvar node; cconst_int 1], dbg), - Cifthenelse ( - Cop (Ccmpi Cne, [Cvar must_allocate_node; cconst_int 1], dbg), - dbg, - Cvar node, - dbg, - Clet (VP.create is_new_node, - Clet (VP.create pc, cconst_symbol function_name, - Cop (Cextcall ("caml_spacetime_allocate_node", - [| Int |], false, None), - [cconst_int (1 (* header *) + !index_within_node); - Cvar pc; - Cvar node_hole; - ], - dbg)), - Clet (VP.create new_node, - Cop (Cload (Word_int, Asttypes.Mutable), [Cvar node_hole], dbg), - if no_tail_calls then Cvar new_node - else - Cifthenelse ( - Cop (Ccmpi Ceq, [Cvar is_new_node; cconst_int 0], dbg), - dbg, - Cvar new_node, - dbg, - initialize_direct_tail_call_points_and_return_node, - dbg))), - dbg))) - -let code_for_blockheader ~value's_header ~node ~dbg = - let num_words = Nativeint.shift_right_logical value's_header 10 in - let existing_profinfo = V.create_local "existing_profinfo" in - let existing_count = V.create_local "existing_count" in - let profinfo = V.create_local "profinfo" in - let address_of_profinfo = V.create_local "address_of_profinfo" in - let label = Cmm.new_label () in - let index_within_node = - next_index_within_node ~part_of_shape:Mach.Allocation_point ~label - in - let offset_into_node = Arch.size_addr * index_within_node in - let open Cmm in - let generate_new_profinfo = - (* This will generate a static branch to a function that should usually - be in the cache, which hopefully gives a good code size/performance - balance. - The "Some label" is important: it provides the link between the shape - table, the allocation point, and the frame descriptor table---enabling - the latter table to be used for resolving a program counter at such - a point to a location. - *) - Cop (Cextcall ("caml_spacetime_generate_profinfo", [| Int |], - false, Some label), - [Cvar address_of_profinfo; - cconst_int (index_within_node + 1)], - dbg) - in - (* Check if we have already allocated a profinfo value for this allocation - point with the current backtrace. If so, use that value; if not, - allocate a new one. *) - Clet (VP.create address_of_profinfo, - Cop (Caddi, [ - Cvar node; - cconst_int offset_into_node; - ], dbg), - Clet (VP.create existing_profinfo, - Cop (Cload (Word_int, Asttypes.Mutable), [Cvar address_of_profinfo], - dbg), - Clet (VP.create profinfo, - Cifthenelse ( - Cop (Ccmpi Cne, [Cvar existing_profinfo; cconst_int 1 (* () *)], dbg), - dbg, - Cvar existing_profinfo, - dbg, - generate_new_profinfo, - dbg), - Clet (VP.create existing_count, - Cop (Cload (Word_int, Asttypes.Mutable), [ - Cop (Caddi, - [Cvar address_of_profinfo; cconst_int Arch.size_addr], dbg) - ], dbg), - Csequence ( - Cop (Cstore (Word_int, Lambda.Assignment), - [Cop (Caddi, - [Cvar address_of_profinfo; cconst_int Arch.size_addr], dbg); - Cop (Caddi, [ - Cvar existing_count; - (* N.B. "*2" since the count is an OCaml integer. - The "1 +" is to count the value's header. *) - cconst_int (2 * (1 + Nativeint.to_int num_words)); - ], dbg); - ], dbg), - (* [profinfo] looks like a black [Infix_tag] header. Instead of - having to mask [profinfo] before ORing it with the desired - header, we can use an XOR trick, to keep code size down. *) - let value's_header = - Nativeint.logxor value's_header - (Nativeint.logor - ((Nativeint.logor (Nativeint.of_int Obj.infix_tag) - (Nativeint.shift_left 3n (* <- Caml_black *) 8))) - (Nativeint.shift_left - (* The following is the [Infix_offset_val], in words. *) - (Nativeint.of_int (index_within_node + 1)) 10)) - in - Cop (Cxor, [Cvar profinfo; cconst_natint value's_header], dbg)))))) - -type callee = - | Direct of string - | Indirect of Cmm.expression - -let code_for_call ~node ~callee ~is_tail ~label dbg = - (* We treat self recursive calls as tail calls to avoid blow-ups in the - graph. *) - let is_self_recursive_call = - match callee with - | Direct callee -> - begin match !current_function_label with - | None -> Misc.fatal_error "[current_function_label] not set" - | Some label -> String.equal callee label - end - | Indirect _ -> false - in - let is_tail = is_tail || is_self_recursive_call in - let index_within_node = - match callee with - | Direct callee -> - next_index_within_node - ~part_of_shape:(Mach.Direct_call_point { callee; }) - ~label - | Indirect _ -> - next_index_within_node ~part_of_shape:Mach.Indirect_call_point ~label - in - begin match callee with - (* If this is a direct tail call point, we need to note down its index, - so the correct initialization code can be emitted in the prologue. *) - | Direct _ when is_tail -> - direct_tail_call_point_indexes := - index_within_node::!direct_tail_call_point_indexes - | Direct _ | Indirect _ -> () - end; - let place_within_node = V.create_local "place_within_node" in - let open Cmm in - Clet (VP.create place_within_node, - Cop (Caddi, [node; cconst_int (index_within_node * Arch.size_addr)], dbg), - (* The following code returns the address that is to be moved into the - (hard) node hole pointer register immediately before the call. - (That move is inserted in [Selectgen].) *) - match callee with - | Direct _callee -> - if Config.enable_call_counts then begin - let count_addr = V.create_local "call_count_addr" in - let count = V.create_local "call_count" in - Clet (VP.create count_addr, - Cop (Caddi, [Cvar place_within_node; cconst_int Arch.size_addr], dbg), - Clet (VP.create count, - Cop (Cload (Word_int, Asttypes.Mutable), [Cvar count_addr], dbg), - Csequence ( - Cop (Cstore (Word_int, Lambda.Assignment), - (* Adding 2 really means adding 1; the count is encoded - as an OCaml integer. *) - [Cvar count_addr; Cop (Caddi, [Cvar count; cconst_int 2], dbg)], - dbg), - Cvar place_within_node))) - end else begin - Cvar place_within_node - end - | Indirect callee -> - let caller_node = - if is_tail then node - else cconst_int 1 (* [Val_unit] *) - in - Cop (Cextcall ("caml_spacetime_indirect_node_hole_ptr", - [| Int |], false, None), - [callee; Cvar place_within_node; caller_node], - dbg)) - -class virtual instruction_selection = object (self) - inherit Selectgen.selector_generic as super - - (* [disable_instrumentation] ensures that we don't try to instrument the - instrumentation... *) - val mutable disable_instrumentation = false - - method private instrument_direct_call ~env ~func ~is_tail ~label_after dbg = - let instrumentation = - code_for_call - ~node:(Lazy.force !spacetime_node) - ~callee:(Direct func) - ~is_tail - ~label:label_after - dbg - in - match self#emit_expr env instrumentation with - | None -> assert false - | Some reg -> Some reg - - method private instrument_indirect_call ~env ~callee ~is_tail - ~label_after dbg = - (* [callee] is a pseudoregister, so we have to bind it in the environment - and reference the variable to which it is bound. *) - let callee_ident = V.create_local "callee" in - let env = Selectgen.env_add (VP.create callee_ident) [| callee |] env in - let instrumentation = - code_for_call - ~node:(Lazy.force !spacetime_node) - ~callee:(Indirect (Cmm.Cvar callee_ident)) - ~is_tail - ~label:label_after - dbg - in - match self#emit_expr env instrumentation with - | None -> assert false - | Some reg -> Some reg - - method private can_instrument () = - Config.spacetime && not disable_instrumentation - - method! about_to_emit_call env desc arg dbg = - if not (self#can_instrument ()) then None - else - let module M = Mach in - match desc with - | M.Iop (M.Icall_imm { func; label_after; }) -> - assert (Array.length arg = 0); - self#instrument_direct_call ~env ~func ~is_tail:false ~label_after dbg - | M.Iop (M.Icall_ind { label_after; }) -> - assert (Array.length arg = 1); - self#instrument_indirect_call ~env ~callee:arg.(0) - ~is_tail:false ~label_after dbg - | M.Iop (M.Itailcall_imm { func; label_after; }) -> - assert (Array.length arg = 0); - self#instrument_direct_call ~env ~func ~is_tail:true ~label_after dbg - | M.Iop (M.Itailcall_ind { label_after; }) -> - assert (Array.length arg = 1); - self#instrument_indirect_call ~env ~callee:arg.(0) - ~is_tail:true ~label_after dbg - | M.Iop (M.Iextcall { func; alloc = true; label_after; }) -> - (* N.B. No need to instrument "noalloc" external calls. *) - assert (Array.length arg = 0); - self#instrument_direct_call ~env ~func ~is_tail:false ~label_after dbg - | _ -> None - - method private instrument_blockheader ~env ~value's_header ~dbg = - let instrumentation = - code_for_blockheader - ~node:(Lazy.force !spacetime_node_ident) - ~value's_header ~dbg - in - self#emit_expr env instrumentation - - method private emit_prologue f ~node_hole ~env = - (* We don't need the prologue unless we inserted some instrumentation. - This corresponds to adding the prologue if the function contains one - or more call or allocation points. *) - if something_was_instrumented () then begin - let prologue_cmm = - code_for_function_prologue ~function_name:f.Cmm.fun_name ~node_hole - ~fun_dbg:f.Cmm.fun_dbg - in - disable_instrumentation <- true; - let node_temp_reg = - match self#emit_expr env prologue_cmm with - | None -> - Misc.fatal_error "Spacetime prologue instruction \ - selection did not yield a destination register" - | Some node_temp_reg -> node_temp_reg - in - disable_instrumentation <- false; - let node = Lazy.force !spacetime_node_ident in - let node_reg = Selectgen.env_find node env in - self#insert_moves env node_temp_reg node_reg - end - - method! emit_blockheader env n dbg = - if self#can_instrument () then begin - disable_instrumentation <- true; - let result = self#instrument_blockheader ~env ~value's_header:n ~dbg in - disable_instrumentation <- false; - result - end else begin - super#emit_blockheader env n dbg - end - - method! select_allocation bytes = - if self#can_instrument () then begin - (* Leave space for a direct call point. We cannot easily insert any - instrumentation code, so the fields are filled in instead by - [caml_spacetime_caml_garbage_collection]. *) - let label = Cmm.new_label () in - let index = - next_index_within_node - ~part_of_shape:(Mach.Direct_call_point { callee = "caml_call_gc"; }) - ~label - in - Mach.Ialloc { - bytes; - dbginfo = []; - label_after_call_gc = Some label; - spacetime_index = index; - } - end else begin - super#select_allocation bytes - end - - method! select_allocation_args env = - if self#can_instrument () then begin - let regs = Selectgen.env_find (Lazy.force !spacetime_node_ident) env in - match regs with - | [| reg |] -> [| reg |] - | _ -> failwith "Expected one register only for spacetime_node_ident" - end else begin - super#select_allocation_args env - end - - method! select_checkbound () = - (* This follows [select_allocation], above. *) - if self#can_instrument () then begin - let label = Cmm.new_label () in - let index = - next_index_within_node - ~part_of_shape:( - Mach.Direct_call_point { callee = "caml_ml_array_bound_error"; }) - ~label - in - Mach.Icheckbound { - label_after_error = Some label; - spacetime_index = index; - } - end else begin - super#select_checkbound () - end - - method! select_checkbound_extra_args () = - if self#can_instrument () then begin - (* This follows [select_allocation_args], above. *) - [Cmm.Cvar (Lazy.force !spacetime_node_ident)] - end else begin - super#select_checkbound_extra_args () - end - - method! initial_env () = - let env = super#initial_env () in - if Config.spacetime then - Selectgen.env_add (VP.create (Lazy.force !spacetime_node_ident)) - (self#regs_for Cmm.typ_int) env - else - env - - method! emit_fundecl f = - if Config.spacetime then begin - disable_instrumentation <- false; - let node = V.create_local "spacetime_node" in - reset ~spacetime_node_ident:node ~function_label:f.Cmm.fun_name - end; - super#emit_fundecl f - - method! insert_prologue f ~loc_arg ~rarg ~spacetime_node_hole ~env = - let fun_spacetime_shape = - super#insert_prologue f ~loc_arg ~rarg ~spacetime_node_hole ~env - in - (* CR-soon mshinwell: add check to make sure the node size doesn't exceed - the chunk size of the allocator *) - if not Config.spacetime then fun_spacetime_shape - else begin - let node_hole, node_hole_reg = - match spacetime_node_hole with - | None -> assert false - | Some (node_hole, reg) -> node_hole, reg - in - self#insert_moves env [| Proc.loc_spacetime_node_hole |] node_hole_reg; - self#emit_prologue f ~node_hole ~env; - match !reverse_shape with - | [] -> None - (* N.B. We do not reverse the shape list, since the function that - reconstructs it (caml_spacetime_shape_table) reverses it again. *) - | reverse_shape -> Some reverse_shape - end -end diff --git a/asmcomp/spill.ml b/asmcomp/spill.ml index da739f97..870c46f6 100644 --- a/asmcomp/spill.ml +++ b/asmcomp/spill.ml @@ -139,10 +139,10 @@ let rec reload i before = match i.desc with Iend -> (i, before) - | Ireturn | Iop(Itailcall_ind _) | Iop(Itailcall_imm _) -> + | Ireturn | Iop(Itailcall_ind) | Iop(Itailcall_imm _) -> (add_reloads (Reg.inter_set_array before i.arg) i, Reg.Set.empty) - | Iop(Icall_ind _ | Icall_imm _ | Iextcall { alloc = true; }) -> + | Iop(Icall_ind | Icall_imm _ | Iextcall { alloc = true; }) -> (* All regs live across must be spilled *) let (new_next, finally) = reload i.next i.live in (add_reloads (Reg.inter_set_array before i.arg) @@ -294,7 +294,7 @@ let rec spill i finally = match i.desc with Iend -> (i, finally) - | Ireturn | Iop(Itailcall_ind _) | Iop(Itailcall_imm _) -> + | Ireturn | Iop(Itailcall_ind) | Iop(Itailcall_imm _) -> (i, Reg.Set.empty) | Iop Ireload -> let (new_next, after) = spill i.next finally in @@ -306,8 +306,8 @@ let rec spill i finally = let before1 = Reg.diff_set_array after i.res in let before = match i.desc with - Iop Icall_ind _ | Iop(Icall_imm _) | Iop(Iextcall _) | Iop(Ialloc _) - | Iop(Iintop (Icheckbound _)) | Iop(Iintop_imm((Icheckbound _), _)) -> + Iop(Icall_ind) | Iop(Icall_imm _) | Iop(Iextcall _) | Iop(Ialloc _) + | Iop(Iintop (Icheckbound)) | Iop(Iintop_imm(Icheckbound, _)) -> Reg.Set.union before1 !spill_at_raise | _ -> before1 in @@ -431,7 +431,6 @@ let fundecl f = fun_body = new_body; fun_codegen_options = f.fun_codegen_options; fun_dbg = f.fun_dbg; - fun_spacetime_shape = f.fun_spacetime_shape; fun_num_stack_slots = f.fun_num_stack_slots; fun_contains_calls = f.fun_contains_calls; } diff --git a/asmcomp/split.ml b/asmcomp/split.ml index 87c9c71f..55fe38c3 100644 --- a/asmcomp/split.ml +++ b/asmcomp/split.ml @@ -125,7 +125,7 @@ let rec rename i sub = match i.desc with Iend -> (i, sub) - | Ireturn | Iop(Itailcall_ind _) | Iop(Itailcall_imm _) -> + | Ireturn | Iop(Itailcall_ind) | Iop(Itailcall_imm _) -> (instr_cons_debug i.desc (subst_regs i.arg sub) [||] i.dbg i.next, None) | Iop Ireload when i.res.(0).loc = Unknown -> @@ -219,7 +219,6 @@ let fundecl f = fun_body = new_body; fun_codegen_options = f.fun_codegen_options; fun_dbg = f.fun_dbg; - fun_spacetime_shape = f.fun_spacetime_shape; fun_num_stack_slots = f.fun_num_stack_slots; fun_contains_calls = f.fun_contains_calls; } diff --git a/asmcomp/strmatch.ml b/asmcomp/strmatch.ml index d71a5136..63d8407e 100644 --- a/asmcomp/strmatch.ml +++ b/asmcomp/strmatch.ml @@ -88,7 +88,7 @@ module Make(I:I) = struct let mk_cmp_gen cmp_op id nat ifso ifnot = let dbg = Debuginfo.none in let test = - Cop (Ccmpi cmp_op, [ Cvar id; Cconst_natpointer (nat, dbg) ], dbg) + Cop (Ccmpi cmp_op, [ Cvar id; Cconst_natint (nat, dbg) ], dbg) in Cifthenelse (test, dbg, ifso, dbg, ifnot, dbg) diff --git a/boot/menhir/parser.ml b/boot/menhir/parser.ml index a4a9fc6a..6b6fc220 100644 --- a/boot/menhir/parser.ml +++ b/boot/menhir/parser.ml @@ -16,7 +16,7 @@ module MenhirBasics = struct | VAL | UNDERSCORE | UIDENT of ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) # 22 "parsing/parser.ml" ) @@ -28,7 +28,7 @@ module MenhirBasics = struct | THEN | STRUCT | STRING of ( -# 685 "parsing/parser.mly" +# 689 "parsing/parser.mly" (string * Location.t * string option) # 34 "parsing/parser.ml" ) @@ -41,12 +41,12 @@ module MenhirBasics = struct | RBRACKET | RBRACE | QUOTED_STRING_ITEM of ( -# 689 "parsing/parser.mly" +# 693 "parsing/parser.mly" (string * Location.t * string * Location.t * string option) # 47 "parsing/parser.ml" ) | QUOTED_STRING_EXPR of ( -# 687 "parsing/parser.mly" +# 691 "parsing/parser.mly" (string * Location.t * string * Location.t * string option) # 52 "parsing/parser.ml" ) @@ -54,7 +54,7 @@ module MenhirBasics = struct | QUESTION | PRIVATE | PREFIXOP of ( -# 671 "parsing/parser.mly" +# 675 "parsing/parser.mly" (string) # 60 "parsing/parser.ml" ) @@ -64,7 +64,7 @@ module MenhirBasics = struct | PERCENT | OR | OPTLABEL of ( -# 664 "parsing/parser.mly" +# 668 "parsing/parser.mly" (string) # 70 "parsing/parser.ml" ) @@ -82,12 +82,12 @@ module MenhirBasics = struct | MATCH | LPAREN | LIDENT of ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) # 88 "parsing/parser.ml" ) | LETOP of ( -# 629 "parsing/parser.mly" +# 633 "parsing/parser.mly" (string) # 93 "parsing/parser.ml" ) @@ -107,39 +107,39 @@ module MenhirBasics = struct | LBRACE | LAZY | LABEL of ( -# 634 "parsing/parser.mly" +# 638 "parsing/parser.mly" (string) # 113 "parsing/parser.ml" ) | INT of ( -# 633 "parsing/parser.mly" +# 637 "parsing/parser.mly" (string * char option) # 118 "parsing/parser.ml" ) | INITIALIZER | INHERIT | INFIXOP4 of ( -# 627 "parsing/parser.mly" +# 631 "parsing/parser.mly" (string) # 125 "parsing/parser.ml" ) | INFIXOP3 of ( -# 626 "parsing/parser.mly" +# 630 "parsing/parser.mly" (string) # 130 "parsing/parser.ml" ) | INFIXOP2 of ( -# 625 "parsing/parser.mly" +# 629 "parsing/parser.mly" (string) # 135 "parsing/parser.ml" ) | INFIXOP1 of ( -# 624 "parsing/parser.mly" +# 628 "parsing/parser.mly" (string) # 140 "parsing/parser.ml" ) | INFIXOP0 of ( -# 623 "parsing/parser.mly" +# 627 "parsing/parser.mly" (string) # 145 "parsing/parser.ml" ) @@ -147,7 +147,7 @@ module MenhirBasics = struct | IN | IF | HASHOP of ( -# 682 "parsing/parser.mly" +# 686 "parsing/parser.mly" (string) # 153 "parsing/parser.ml" ) @@ -160,7 +160,7 @@ module MenhirBasics = struct | FUN | FOR | FLOAT of ( -# 612 "parsing/parser.mly" +# 616 "parsing/parser.mly" (string * char option) # 166 "parsing/parser.ml" ) @@ -174,7 +174,7 @@ module MenhirBasics = struct | ELSE | DOWNTO | DOTOP of ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) # 180 "parsing/parser.ml" ) @@ -182,14 +182,14 @@ module MenhirBasics = struct | DOT | DONE | DOCSTRING of ( -# 705 "parsing/parser.mly" +# 709 "parsing/parser.mly" (Docstrings.docstring) # 188 "parsing/parser.ml" ) | DO | CONSTRAINT | COMMENT of ( -# 704 "parsing/parser.mly" +# 708 "parsing/parser.mly" (string * Location.t) # 195 "parsing/parser.ml" ) @@ -200,7 +200,7 @@ module MenhirBasics = struct | COLON | CLASS | CHAR of ( -# 592 "parsing/parser.mly" +# 596 "parsing/parser.mly" (char) # 206 "parsing/parser.ml" ) @@ -213,7 +213,7 @@ module MenhirBasics = struct | ASSERT | AS | ANDOP of ( -# 630 "parsing/parser.mly" +# 634 "parsing/parser.mly" (string) # 219 "parsing/parser.ml" ) @@ -253,7 +253,7 @@ let ghost_loc (startpos, endpos) = { Location.loc_ghost = true; } -let mktyp ~loc d = Typ.mk ~loc:(make_loc loc) d +let mktyp ~loc ?attrs d = Typ.mk ~loc:(make_loc loc) ?attrs d let mkpat ~loc d = Pat.mk ~loc:(make_loc loc) d let mkexp ~loc d = Exp.mk ~loc:(make_loc loc) d let mkmty ~loc ?attrs d = Mty.mk ~loc:(make_loc loc) ?attrs d @@ -425,7 +425,7 @@ let mkexp_opt_constraint ~loc e = function let mkpat_opt_constraint ~loc p = function | None -> p - | Some typ -> mkpat ~loc (Ppat_constraint(p, typ)) + | Some typ -> ghpat ~loc (Ppat_constraint(p, typ)) let syntax_error () = raise Syntaxerr.Escape_error @@ -450,9 +450,7 @@ let bracket = "[", "]" let lident x = Lident x let ldot x y = Ldot(x,y) let dotop_fun ~loc dotop = - (* We could use ghexp here, but sticking to mkexp for parser.mly - compatibility. TODO improve parser.mly *) - mkexp ~loc (Pexp_ident (ghloc ~loc dotop)) + ghexp ~loc (Pexp_ident (ghloc ~loc dotop)) let array_function ~loc str name = ghloc ~loc (Ldot(Lident str, @@ -550,24 +548,27 @@ let lapply ~loc p1 p2 = else raise (Syntaxerr.Error( Syntaxerr.Applicative_path (make_loc loc))) -let exp_of_longident ~loc lid = - mkexp ~loc (Pexp_ident {lid with txt = Lident(Longident.last lid.txt)}) - (* [loc_map] could be [Location.map]. *) let loc_map (f : 'a -> 'b) (x : 'a Location.loc) : 'b Location.loc = { x with txt = f x.txt } +let make_ghost x = { x with loc = { x.loc with loc_ghost = true }} + let loc_last (id : Longident.t Location.loc) : string Location.loc = loc_map Longident.last id let loc_lident (id : string Location.loc) : Longident.t Location.loc = loc_map (fun x -> Lident x) id +let exp_of_longident ~loc lid = + let lid = make_ghost (loc_map (fun id -> Lident (Longident.last id)) lid) in + ghexp ~loc (Pexp_ident lid) + let exp_of_label ~loc lbl = mkexp ~loc (Pexp_ident (loc_lident lbl)) -let pat_of_label ~loc lbl = - mkpat ~loc (Ppat_var (loc_last lbl)) +let pat_of_label lbl = + Pat.mk ~loc:lbl.loc (Ppat_var (loc_last lbl)) let mk_newtypes ~loc newtypes exp = let mkexp = mkexp ~loc in @@ -641,7 +642,8 @@ let text_str pos = Str.text (rhs_text pos) let text_sig pos = Sig.text (rhs_text pos) let text_cstr pos = Cf.text (rhs_text pos) let text_csig pos = Ctf.text (rhs_text pos) -let text_def pos = [Ptop_def (Str.text (rhs_text pos))] +let text_def pos = + List.map (fun def -> Ptop_def [def]) (Str.text (rhs_text pos)) let extra_text startpos endpos text items = match items with @@ -659,7 +661,9 @@ let extra_sig p1 p2 items = extra_text p1 p2 Sig.text items let extra_cstr p1 p2 items = extra_text p1 p2 Cf.text items let extra_csig p1 p2 items = extra_text p1 p2 Ctf.text items let extra_def p1 p2 items = - extra_text p1 p2 (fun txt -> [Ptop_def (Str.text txt)]) items + extra_text p1 p2 + (fun txt -> List.map (fun def -> Ptop_def [def]) (Str.text txt)) + items let extra_rhs_core_type ct ~pos = let docs = rhs_info pos in @@ -769,9 +773,9 @@ let package_type_of_module_type pmty = err pmty.pmty_loc "only 'with type t =' constraints are supported" in match pmty with - | {pmty_desc = Pmty_ident lid} -> (lid, []) + | {pmty_desc = Pmty_ident lid} -> (lid, [], pmty.pmty_attributes) | {pmty_desc = Pmty_with({pmty_desc = Pmty_ident lid}, cstrs)} -> - (lid, List.map map_cstr cstrs) + (lid, List.map map_cstr cstrs, pmty.pmty_attributes) | _ -> err pmty.pmty_loc "only module type identifier and 'with type' constraints are supported" @@ -789,7 +793,7 @@ let mk_directive ~loc name arg = } -# 793 "parsing/parser.ml" +# 797 "parsing/parser.ml" module Tables = struct @@ -1299,22 +1303,22 @@ module Tables = struct Obj.repr () and default_reduction = - (16, "\000\000\000\000\000\000\002\247\002\246\002\245\002\244\002\243\002\198\002\242\002\241\002\240\002\239\002\238\002\237\002\236\002\235\002\234\002\233\002\232\002\231\002\230\002\229\002\228\002\227\002\226\002\225\002\224\002\197\002\223\002\222\002\221\002\220\002\219\002\218\002\217\002\216\002\215\002\214\002\213\002\212\002\211\002\210\002\209\002\208\002\207\002\206\002\205\002\204\002\203\002\202\002\201\002\200\002\199\000\000\000\000\000*\000\186\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0035\001\168\001\147\001\165\001\164\001\163\001\169\001\173\000\000\0036\001\167\001\166\001\148\001\171\001\162\001\161\001\160\001\159\001\158\001\156\001\172\001\170\000\000\000\000\000\000\000\220\000\000\000\000\001\151\000\000\000\000\000\000\001\153\000\000\000\000\000\000\001\155\001\177\001\174\001\157\001\149\001\175\001\176\000\000\0034\0033\0037\000\000\000\000\000\024\001B\000\188\000\000\000\216\000\217\000\023\000\000\000\000\001\199\001\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003/\000\000\0030\000\000\000\000\003-\000\000\003,\003(\0022\000\000\003+\000\000\0023\000\000\000\000\000\000\000\000\000j\000\000\000\000\000h\000\000\000\000\001@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\184\001N\000\000\000\000\000\000\000\000\000\000\000\000\002\029\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000\000\000\000\000\000\001L\000\000\000\000\001O\001M\001U\000A\002\134\000\000\001\018\000\000\000\000\000\000\000\015\000\014\000\000\000\000\000\000\000\000\002\179\000\000\002e\002f\000\000\002c\002d\000\000\000\000\000\000\000\000\000\000\001e\001d\000\000\002\177\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\223\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\016\003\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000g\000\000\000\231\000\000\002h\002g\000\000\000\000\000\000\001\181\000\000\000\000\000%\000\000\000\000\000\000\000\000\000\000\001T\000\000\001S\000\000\001C\001R\000\000\001A\000b\000\030\000\000\000\000\001|\000\025\000\000\000\000\000\000\000\000\003'\000(\000\000\000\000\000\031\000\026\000\000\000\000\000\000\000\201\000\000\000\000\000\000\000\203\002<\002.\000\000\000\"\000\000\002/\000\000\000\000\001\178\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\017\003\017\000\000\003\018\000\000\000y\000\000\000\000\000!\000\000\000\000\000\000\000#\000\000\000$\000\000\000&\000\000\000\000\000'\002$\002#\000\000\000\000\000\000\000\000\000\000\000\000\000c\000\000\002\184\000f\000i\000d\002\173\0038\002\174\001\239\002\176\000\000\000\000\002\181\002b\002\183\000\000\000\000\000\000\002\190\002\187\000\000\000\000\000\000\001\236\001\222\000\000\000\000\000\000\000\000\001\226\000\000\001\221\000\000\001\238\002\196\000\000\001\237\000q\001\229\000\000\000o\000\000\002\189\002\188\000\000\001\232\000\000\000\000\001\228\000\000\000\000\001\224\001\223\000\000\002\186\000\000\002j\002i\000\000\000\000\002F\002\185\002\182\000\000\000\000\000\000\000\000\001\183\001-\001.\002l\000\000\002m\002k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\241\000\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001o\000\000\000\000\000\000\000\000\000\000\000\000\003M\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003*\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002,\000\000\000\000\002-\000\000\000\000\001n\000\000\000\000\000\000\001K\001t\001J\001r\002 \002\031\000\000\001m\001l\000\000\000\205\000\000\000\000\001^\000\000\000\000\001b\000\000\001\203\001\202\000\000\000\000\001\201\001\200\001a\001_\000\000\001c\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\138\001P\002\143\002\141\000\000\000\000\000\000\002\154\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\172\000\000\002\171\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\250\000\000\000\000\000\000\000\000\000\000\000\000\000\239\001\249\000\240\000\000\000\000\000\000\001~\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\234\000\000\000\235\000\000\000\000\000\000\002\151\000\000\000\000\000\000\002r\002q\000\000\000\000\000\000\000\000\0039\002\153\002\140\002\139\000\000\000\000\000\169\000\000\000\000\000\000\000\000\000\000\000\183\000\000\000\000\000\000\000\168\000\000\000\000\000\000\002M\002L\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\243\000\000\002\250\000\000\003$\000\000\000\000\003#\000\000\000\000\000\000\000\000\000\000\000\195\000\194\000\244\000\000\002\251\002\252\000\000\000\000\000p\000\000\002\191\002\175\000\000\002\194\000\000\002\193\002\192\000\000\000\000\000\000\000\000\000\000\000\000\000\248\000\000\000\000\002&\000\000\000\000\000\000\000\247\000\000\000\000\000\246\000\245\000\000\000\000\000\000\000\000\000\250\000\000\000\000\000\249\000\000\001\235\000\000\000\000\001\246\000\000\000\000\001\248\000\000\000\000\001\244\001\243\001\241\001\242\000\000\000\000\000\000\000\000\000\000\001\024\000\018\000\252\000\000\000\000\000\000\002t\002s\000\000\000\000\002\130\002\129\000\000\000\000\000\000\000\000\002~\002}\000\000\000\000\002@\000\000\000\000\002|\002{\000\000\000\000\002\128\002\127\002\147\000\000\000\000\000\000\000\000\000\000\002x\000\000\000\000\000\000\000\000\000\000\002v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\"\002!\000\167\000\000\002w\000\000\000\000\002u\000\000\000\000\002y\000\000\000z\000{\000\000\000\000\000\000\000\000\000\138\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\197\000\000\000\198\000\199\000\131\000\000\000\130\000\000\000\000\0010\000\000\0011\001/\002(\000\000\000\000\002)\002'\000\000\000\000\000\000\000\000\000\000\001\003\000\000\000\000\001\004\000\000\000\000\000\170\000\000\001\006\001\005\000\000\000\000\002\155\002\148\000\000\002\164\000\000\002\165\002\163\000\000\002\169\000\000\002\170\002\168\000\000\000\000\002\150\002\149\000\000\000\000\000\000\002\016\000\000\001\197\000\000\000\000\000\000\002I\002\015\000\000\002\159\002\158\000\000\000\000\000\000\001Q\000\000\002\132\000\000\002\133\002\131\000\000\002\157\002\156\000\000\000\000\000\000\002C\002\146\000\000\002\145\002\144\000\000\002\167\002\166\000\128\000\000\000\000\000\000\000\000\000\127\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}\000\000\001X\000\000\000\000\000\000\000k\000\000\000\000\000l\000\000\000\000\000\000\000\000\001v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000u\000\000\000\228\000\226\000\000\000\000\000\000\000\207\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000~\000m\000\000\000\000\002\014\000\000\000\000\000\251\001\195\000\000\000\237\000\238\001\002\000\000\000\000\000\000\000\000\000\000\001\210\001\204\000\000\001\209\000\000\001\207\000\000\001\208\000\000\001\205\000\000\000\000\001\206\000\000\001\144\000\000\000\000\000\000\001\143\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\014\003\t\000\000\000\000\003\b\000\000\000\000\000\000\000\000\000\000\001\255\000\000\000\000\000\000\000\000\000\000\000\000\003\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\128\000\000\002\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\249\000\000\000\000\002N\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\146\000\000\000\000\000\000\001\145\000\000\000\000\000\000\000\000\000\000\001g\000\000\001f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\016\002\\\000\000\000\000\000\000\002Z\000\000\000\000\000\000\002Y\000\000\001Z\000\000\000\000\000\000\000\000\002_\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003A\000\000\000\000\000\000\000\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000E\000\000\000\000\000\000\000\000\001{\000\000\001z\000\000\000\000\000\000\000\000\000H\000\000\000\000\000\000\002\012\000\000\002\011\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000N\000\000\000\000\000\000\000O\000M\000\000\000R\000\000\000\000\000\000\000\000\000\000\000G\000\000\000\000\000\000\000\000\000\000\000\000\000J\000\000\000Q\000P\000\000\000K\000L\000\000\001!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\012\000a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000^\000\000\000`\000_\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\n\002`\002R\000\000\002X\002S\002^\002]\002[\001\027\000\000\002P\000\000\000\000\000\000\000\000\000\000\002\029\000\000\000\000\001\020\002T\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\139\001\135\000\000\000\000\000\000\000\210\000\000\000\000\002\019\002\029\000\000\000\000\001\022\002\017\002\018\000\000\000\000\000\000\000\000\000\000\001\142\001\138\001\134\000\000\000\000\000\211\000\000\000\000\001\141\001\137\001\133\001\131\002U\002Q\002a\001\026\001\252\002O\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003<\000\000\000\000\003>\000\000\0006\000\000\000\000\003D\000\000\003C\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003;\000\000\000\000\003=\000\000\000\000\000\000\002\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001?\000\000\000\000\001=\001;\000\000\0007\000\000\000\000\003G\000\000\003F\000\000\000\000\000\000\0019\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\000\000\001<\001:\000\000\000\000\000\000\0009\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\254\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000X\000\000\000\000\000\000\000\000\000\000\000\000\0003\000\000\000\000\000W\000\000\0001\000\255\000\000\000@\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\253\000\000\000V\000U\000\000\000\000\000[\000Z\000\000\000\000\001\185\000\000\0005\000\000\000\000\000\000\0004\000\000\000\000\000\000\0008\000\000\000Y\000\\\000\000\000:\000;\000\000\001#\000\000\000\000\000\000\000\000\000\000\000\000\000>\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\b\003\012\003\003\000\000\000\000\003\007\002\248\003\002\003\011\003\n\001\031\000\000\000\000\003\000\000\000\003\004\003\001\003\r\001\251\000\000\000\000\002\254\000\000\000\191\002\253\000\000\000\000\000\222\000\000\000\000\001\030\001\029\000\000\001\\\001[\000\000\000\000\002\195\002\178\000\000\000B\000\000\000\000\000C\000\000\000\000\000\142\000\141\002\162\000\000\002\161\002\160\002\142\000\000\000\000\000\000\000\000\002\135\000\000\002\137\000\000\002\136\000\000\002o\002n\000\000\002p\000\000\000\000\000\134\000\000\000\000\002\004\000\215\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\189\000\000\003\006\002\024\002\025\002\020\002\022\002\021\002\023\000\000\000\000\000\000\000\190\000\000\000\000\002\029\000\000\000\214\000\000\000\000\000\000\000\000\003\005\000\000\000\187\000\000\000\000\000\000\000\000\0018\0012\000\000\000\000\0013\000\029\000\000\000\028\000\000\000\000\000\202\000\000\000\000\000\000\000 \000\027\000\000\000\000\000\000\000\021\000\000\000\000\000\000\000\000\001\140\001\136\000\000\001\132\003&\000\000\002\029\000\000\000\213\000\000\000\000\000\000\000\000\002W\002\028\002\026\002\027\000\000\000\000\000\000\002\029\000\000\000\212\000\000\000\000\000\000\000\000\002V\000\000\001i\001h\000\000\000\022\000\000\003?\000\000\000+\000\000\000\000\000\000\000\000\000\137\000\000\000\218\000\001\000\000\000\000\000\221\000\002\000\000\000\000\000\000\001E\001F\000\003\000\000\000\000\000\000\000\000\001H\001I\001G\000\019\001D\000\020\000\000\001\211\000\000\000\004\000\000\001\212\000\000\000\005\000\000\001\213\000\000\000\000\001\214\000\006\000\000\000\007\000\000\001\215\000\000\000\b\000\000\001\216\000\000\000\t\000\000\001\217\000\000\000\000\001\218\000\n\000\000\000\000\001\219\000\011\000\000\000\000\000\000\000\000\000\000\003\025\003\020\003\021\003\024\003\022\000\000\003\029\000\012\000\000\003\028\000\000\001%\000\000\000\000\003\026\000\000\003\027\000\000\000\000\000\000\000\000\001)\001*\000\000\000\000\001(\001'\000\r\000\000\000\000\000\000\0032\000\000\0031") + (16, "\000\000\000\000\000\000\002\247\002\246\002\245\002\244\002\243\002\198\002\242\002\241\002\240\002\239\002\238\002\237\002\236\002\235\002\234\002\233\002\232\002\231\002\230\002\229\002\228\002\227\002\226\002\225\002\224\002\197\002\223\002\222\002\221\002\220\002\219\002\218\002\217\002\216\002\215\002\214\002\213\002\212\002\211\002\210\002\209\002\208\002\207\002\206\002\205\002\204\002\203\002\202\002\201\002\200\002\199\000\000\000\000\000*\000\186\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003<\001\168\001\147\001\165\001\164\001\163\001\169\001\173\000\000\003=\001\167\001\166\001\148\001\171\001\162\001\161\001\160\001\159\001\158\001\156\001\172\001\170\000\000\000\000\000\000\000\220\000\000\000\000\001\151\000\000\000\000\000\000\001\153\000\000\000\000\000\000\001\155\001\177\001\174\001\157\001\149\001\175\001\176\000\000\003;\003:\003>\000\000\000\000\000\024\001B\000\188\000\000\000\216\000\217\000\023\000\000\000\000\001\199\001\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0037\000\000\0032\000\000\000\000\0034\000\000\0036\000\000\0033\0035\000\000\003-\000\000\003,\003(\0022\000\000\003+\000\000\0023\000\000\000\000\000\000\000\000\000j\000\000\000\000\000h\000\000\000\000\001@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\184\001N\000\000\000\000\000\000\000\000\000\000\000\000\002\029\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000\000\000\000\000\000\001L\000\000\000\000\001O\001M\001U\000A\002\134\000\000\001\018\000\000\000\000\000\000\000\015\000\014\000\000\000\000\000\000\000\000\002\179\000\000\002e\002f\000\000\002c\002d\000\000\000\000\000\000\000\000\000\000\001e\001d\000\000\002\177\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\223\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\016\003\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000g\000\000\000\231\000\000\002h\002g\000\000\000\000\000\000\001\181\000\000\000\000\000%\000\000\000\000\000\000\000\000\000\000\001T\000\000\001S\000\000\001C\001R\000\000\001A\000b\000\030\000\000\000\000\001|\000\025\000\000\000\000\000\000\000\000\003'\000(\000\000\000\000\000\031\000\026\000\000\000\000\000\000\000\201\000\000\000\000\000\000\000\203\002<\002.\000\000\000\"\000\000\002/\000\000\000\000\001\178\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\017\003\017\000\000\003\018\000\000\000y\000\000\000\000\000!\000\000\000\000\000\000\000#\000\000\000$\000\000\000&\000\000\000\000\000'\002$\002#\000\000\000\000\000\000\000\000\000\000\000\000\000c\000\000\002\184\000f\000i\000d\002\173\003?\002\174\001\239\002\176\000\000\000\000\002\181\002b\002\183\000\000\000\000\000\000\002\190\002\187\000\000\000\000\000\000\001\236\001\222\000\000\000\000\000\000\000\000\001\226\000\000\001\221\000\000\001\238\002\196\000\000\001\237\000q\001\229\000\000\000o\000\000\002\189\002\188\000\000\001\232\000\000\000\000\001\228\000\000\000\000\001\224\001\223\000\000\002\186\000\000\002j\002i\000\000\000\000\002F\002\185\002\182\000\000\000\000\000\000\000\000\001\183\001-\001.\002l\000\000\002m\002k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\241\000\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001o\000\000\000\000\000\000\000\000\000\000\000\000\003T\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003*\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002,\000\000\000\000\002-\000\000\000\000\001n\000\000\000\000\000\000\001K\001t\001J\001r\002 \002\031\000\000\001m\001l\000\000\000\205\000\000\000\000\001^\000\000\000\000\001b\000\000\001\203\001\202\000\000\000\000\001\201\001\200\001a\001_\000\000\001c\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\138\001P\002\143\002\141\000\000\000\000\000\000\002\154\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\172\000\000\002\171\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\250\000\000\000\000\000\000\000\000\000\000\000\000\000\239\001\249\000\240\000\000\000\000\000\000\001~\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\234\000\000\000\235\000\000\000\000\000\000\002\151\000\000\000\000\000\000\002r\002q\000\000\000\000\000\000\000\000\003@\002\153\002\140\002\139\000\000\000\000\000\169\000\000\000\000\000\000\000\000\000\000\000\183\000\000\000\000\000\000\000\168\000\000\000\000\000\000\002M\002L\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\243\000\000\002\250\000\000\003$\000\000\000\000\003#\000\000\000\000\000\000\000\000\000\000\000\195\000\194\000\244\000\000\002\251\002\252\000\000\000\000\000p\000\000\002\191\002\175\000\000\002\194\000\000\002\193\002\192\000\000\000\000\000\000\000\000\000\000\000\000\000\248\000\000\000\000\002&\000\000\000\000\000\000\000\247\000\000\000\000\000\246\000\245\000\000\000\000\000\000\000\000\000\250\000\000\000\000\000\249\000\000\001\235\000\000\000\000\001\246\000\000\000\000\001\248\000\000\000\000\001\244\001\243\001\241\001\242\000\000\000\000\000\000\000\000\000\000\001\024\000\018\000\252\000\000\000\000\000\000\002t\002s\000\000\000\000\002\130\002\129\000\000\000\000\000\000\000\000\002~\002}\000\000\000\000\002@\000\000\000\000\002|\002{\000\000\000\000\002\128\002\127\002\147\000\000\000\000\000\000\000\000\000\000\002x\000\000\000\000\000\000\000\000\000\000\002v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\"\002!\000\167\000\000\002w\000\000\000\000\002u\000\000\000\000\002y\000\000\000z\000{\000\000\000\000\000\000\000\000\000\138\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\197\000\000\000\198\000\199\000\131\000\000\000\130\000\000\000\000\0010\000\000\0011\001/\002(\000\000\000\000\002)\002'\000\000\000\000\000\000\000\000\000\000\001\003\000\000\000\000\001\004\000\000\000\000\000\170\000\000\001\006\001\005\000\000\000\000\002\155\002\148\000\000\002\164\000\000\002\165\002\163\000\000\002\169\000\000\002\170\002\168\000\000\000\000\002\150\002\149\000\000\000\000\000\000\002\016\000\000\001\197\000\000\000\000\000\000\002I\002\015\000\000\002\159\002\158\000\000\000\000\000\000\001Q\000\000\002\132\000\000\002\133\002\131\000\000\002\157\002\156\000\000\000\000\000\000\002C\002\146\000\000\002\145\002\144\000\000\002\167\002\166\000\128\000\000\000\000\000\000\000\000\000\127\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}\000\000\001X\000\000\000\000\000\000\000k\000\000\000\000\000l\000\000\000\000\000\000\000\000\001v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000u\000\000\000\228\000\226\000\000\000\000\000\000\000\207\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000~\000m\000\000\000\000\002\014\000\000\000\000\000\251\001\195\000\000\000\237\000\238\001\002\000\000\000\000\000\000\000\000\000\000\001\210\001\204\000\000\001\209\000\000\001\207\000\000\001\208\000\000\001\205\000\000\000\000\001\206\000\000\001\144\000\000\000\000\000\000\001\143\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\014\003\t\000\000\000\000\003\b\000\000\000\000\000\000\000\000\000\000\001\255\000\000\000\000\000\000\000\000\000\000\000\000\003\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\128\000\000\002\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\249\000\000\000\000\002N\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\146\000\000\000\000\000\000\001\145\000\000\000\000\000\000\000\000\000\000\001g\000\000\001f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\016\002\\\000\000\000\000\000\000\002Z\000\000\000\000\000\000\002Y\000\000\001Z\000\000\000\000\000\000\000\000\002_\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003H\000\000\000\000\000\000\000\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000E\000\000\000\000\000\000\000\000\001{\000\000\001z\000\000\000\000\000\000\000\000\000H\000\000\000\000\000\000\002\012\000\000\002\011\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000N\000\000\000\000\000\000\000O\000M\000\000\000R\000\000\000\000\000\000\000\000\000\000\000G\000\000\000\000\000\000\000\000\000\000\000\000\000J\000\000\000Q\000P\000\000\000K\000L\000\000\001!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\012\000a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000^\000\000\000`\000_\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\n\002`\002R\000\000\002X\002S\002^\002]\002[\001\027\000\000\002P\000\000\000\000\000\000\000\000\000\000\002\029\000\000\000\000\001\020\002T\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\139\001\135\000\000\000\000\000\000\000\210\000\000\000\000\002\019\002\029\000\000\000\000\001\022\002\017\002\018\000\000\000\000\000\000\000\000\000\000\001\142\001\138\001\134\000\000\000\000\000\211\000\000\000\000\001\141\001\137\001\133\001\131\002U\002Q\002a\001\026\001\252\002O\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003C\000\000\000\000\003E\000\000\0006\000\000\000\000\003K\000\000\003J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003B\000\000\000\000\003D\000\000\000\000\000\000\002\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001?\000\000\000\000\001=\001;\000\000\0007\000\000\000\000\003N\000\000\003M\000\000\000\000\000\000\0019\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\000\000\001<\001:\000\000\000\000\000\000\0009\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\254\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000X\000\000\000\000\000\000\000\000\000\000\000\000\0003\000\000\000\000\000W\000\000\0001\000\255\000\000\000@\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\253\000\000\000V\000U\000\000\000\000\000[\000Z\000\000\000\000\001\185\000\000\0005\000\000\000\000\000\000\0004\000\000\000\000\000\000\0008\000\000\000Y\000\\\000\000\000:\000;\000\000\001#\000\000\000\000\000\000\000\000\000\000\000\000\000>\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\b\003\012\003\003\000\000\000\000\003\007\002\248\003\002\003\011\003\n\001\031\000\000\000\000\003\000\000\000\003\004\003\001\003\r\001\251\000\000\000\000\002\254\000\000\000\191\002\253\000\000\000\000\000\222\000\000\000\000\001\030\001\029\000\000\001\\\001[\000\000\000\000\002\195\002\178\000\000\000B\000\000\000\000\000C\000\000\000\000\000\142\000\141\002\162\000\000\002\161\002\160\002\142\000\000\000\000\000\000\000\000\002\135\000\000\002\137\000\000\002\136\000\000\002o\002n\000\000\002p\000\000\000\000\000\134\000\000\000\000\002\004\000\215\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\189\000\000\003\006\002\024\002\025\002\020\002\022\002\021\002\023\000\000\000\000\000\000\000\190\000\000\000\000\002\029\000\000\000\214\000\000\000\000\000\000\000\000\003\005\000\000\000\187\000\000\000\000\000\000\000\000\0018\0012\000\000\000\000\0013\000\029\000\000\000\028\000\000\000\000\000\202\000\000\000\000\000\000\000 \000\027\000\000\000\000\000\000\000\021\000\000\000\000\000\000\000\000\001\140\001\136\000\000\001\132\003&\000\000\002\029\000\000\000\213\000\000\000\000\000\000\000\000\002W\002\028\002\026\002\027\000\000\000\000\000\000\002\029\000\000\000\212\000\000\000\000\000\000\000\000\002V\000\000\001i\001h\000\000\000\022\000\000\003F\000\000\000+\000\000\000\000\000\000\000\000\000\137\000\000\000\218\000\001\000\000\000\000\000\221\000\002\000\000\000\000\000\000\001E\001F\000\003\000\000\000\000\000\000\000\000\001H\001I\001G\000\019\001D\000\020\000\000\001\211\000\000\000\004\000\000\001\212\000\000\000\005\000\000\001\213\000\000\000\000\001\214\000\006\000\000\000\007\000\000\001\215\000\000\000\b\000\000\001\216\000\000\000\t\000\000\001\217\000\000\000\000\001\218\000\n\000\000\000\000\001\219\000\011\000\000\000\000\000\000\000\000\000\000\003\025\003\020\003\021\003\024\003\022\000\000\003\029\000\012\000\000\003\028\000\000\001%\000\000\000\000\003\026\000\000\003\027\000\000\000\000\000\000\000\000\001)\001*\000\000\000\000\001(\001'\000\r\000\000\000\000\000\000\0039\000\000\0038") and error = - (124, "'\225 \197\138\173\2433\208\020\015\228\000\003\142\0026\016\004\\(\223\018}\000@\248\000\000\024\224}\246D\b/\227P\000L\028\030\227\139\002\131@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\175\235f\245\155\175\2437\252\021\031\226\017\007\158\007\223d@\130\2545\000\004\193\193\2388\176(4\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241'\208\004\015\128\000\001\142\007\223d@\130\2545\000\004\193\193\2388\176(4'\225\"\213\138\173\2433\208\020\015\224\000\007\142\000\000\000\000\004\000\012\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\192\004\000\000\000\000\000\000\000\000\000\000\000\000\000\012\000\000\000\000\000\000\000\000\000\128\000\128\007\224,$\000\003\226 \016@\016(\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000(\000\000\000\000\000\000\000\000\000\024\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\002\012\\ \000\016\000\000\000\000\000\001\000@@@ \193\004\000\000\016\000\000\000\000\000\016\004\004\000\002\012\016@\000\001\000\000\000\000\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\012H\002\168\000\131\t!\192\001\016\007a\002 \004\132\128 \128\b \002\020\000\016\000b\000\002\000\bH\002\b\000\130\000!\000\001\000\006 \000 \000\003\000\000 \193\004\192\004\000\000\000\000\000\000\000\0000\000\002\b\016L\000@\000\000\000\000\000\000\000\003\000\000 \129\004\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000 \128\004\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000 \128\004\000\000\000\000\000\000\000\000\000\000 \000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\002\b\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\132\128\"\130\b \002\024\000\016\000v\001\018\000@2\000\007\129\000\012\\(\000\016\b\002\000\001\000\132\128\"\128\012 \146\028\000\017\000f\017\006\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003 \000p\016\000\197\194\128\001\000\128 \000\016\0000\000\135\001\002\012\\ \000\016\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012X\011\184\000\131%!\192\193\018\007`\022a\022\003\000\000`\000\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000`\000\000\197\194\000\001 \000 \000\000\000\016\001\000\000\000\004\000\000\000\018\000\000\000@\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\133\000\145\160\000\018B\028\012\001 \018\017 \001\007\223d@\130\2545\000\004\193\193\2388\176(4'\225\"\213\138\173\2433\208\020\015\224\000\007\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\002\012\016L\000@\000\000\000\000\000\000\000\003\000\000 \129\004\192\004\000\000\000\000\000\000\000\0000\000\002\b\016L\000\000\000\000\000\000\000\000\000\003\000\000 \128\004\192\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\132\128\"\130\b \018\024\000\017\000v\001\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\017\000f\001\002\000G\223d@\130\2545\000\004\193\193\2388\176(4'\225\"\213\138\173\2433\208\020\015\224\000\007\142\0026\016\004\\(\223\018}\000@\248\000\000\024\224#a\000E\130\141\241'\208\004\015\128\000\001\142\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\016\004@\b\012\0189\000\000\024\000\000\024\192\001\000\000\000@\000@\004\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000@\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\254\183\127\217\190\255\127\255\193\211\254b\0169\228\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n6\024\132~*\223R=>b\249\004\001\154\235\129!\bD\000\128\193#\144\000\001\128\000\001\140\0026\016\004X(\223\018=\000@\248\000\000\028\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128@\002\130\020\012\000\000\002\001\000\000\b@\000\b\000\000(!@\192\000\000 \016\000\000\132\000\000\128\000\002\130\016\012\000\000\002\001\000\000\0002\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b2\024\132~\002\206R->2\027\004\001\146\203\128\000\b\000\000\000\000\000\016\000\001\000\000\000\000\b0\000\000\004\000\000\000@\000\000\000\000\000\000\000\003\000\000\000\000\000\000\004\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\016 \004\000\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\n~\018\012X\170\2233}\001@\254 \0008\224\167\225 \197\138\173\2433\208\020\015\226\000\003\142\n~\018,X\170\2233=\001@\254`\0008\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016 \004\004\000\b\016@\000\001\000\000\000\000\128\001\002\000@@\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\000P \004\000\000\b\016\000\000\001\000\000\000\000\000#a\000E\130\141\241'\208\004\015\128\000\001\142\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\194\141\241'\208\004\015\128\000\001\142\0026\016\004X(\223\018}\000@\248\000\000\024\224#a\000E\130\141\241#\208\004\015\128\000\001\142\012[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\0002\016\004\b\000L\018-\000\016\024\000\000\016@\003!\000@\128\004\193\"\208\001\001\160\000\001D\0002\016$\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\017\000\000\000\000\000\000\000\000\016\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\004\0000\000'\001\000\012\\ \000\016\000\000\000\001@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000@\003\000\000p\016\000\197\194\000\001\000\000\000\000\020\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\016\000\000\b\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\b\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\004\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\128;\128\b2\018\028\012\017 v\001b\017`0\000\007\001\000\012\\ \000\016\000\000\000\000\000\196\128\187\128\b2\018\028\012\017 v\001b\017`0\000\006\000\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\197\128\187\128\b2R\028\012\017 v\001b\017`\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000`\000\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\197\128\187\128\b2R\028\012\017 v\001b\017`0\000\006\000\000\012\\ \000\016\000\000\000\000\000\197\128\187\128\b2R\028\012\017 v\001b\017`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\004\000\000\004\000\000 \000\000\000\016\0000\000\007\001\000\012\\ \000\016\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\002\000\000\000\000\004\000\000 \000\000\000\016 0\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000@\000\002\000\000\000\001\018\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\004\000\000 \000\000\000\017 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\004\000\000 \000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\128;\128\b2\018\028\012\017 v\001b\017@\000\000 \000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\004\000\000\000 \000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\002\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\002\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\017\000\000\000\000\004\000\000\000\016\000\000\000\b\000\001\016\000\000\000\000\000\000\000\001\000\000\000\000\003!\000@\128\004\193\"\208\001\001\160\000\001\004\0002\016\004\012\000L\018i\000\016\024\000\000\016@\003!\000@\128\004\193&\144\001\001\128\000\001\004\0002\016\004\b\000L\018)\000\016\024\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t2\145\181\t\001L\018k\000\016\025B\006\213P\000\001\000\000\128\004\000\000\016\000\001\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\147)\027P\144\020\193&\240\001\001\180\016mU\000\016\000\000\000\000\b\002(\000\000\000\000\000\000\000\131!\b@\128\004\193\"\208\001\001\160\000\t\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\016\004\012\000L\018m\000\016\026\000\000\016@\003!\000@\128\004\193&\208\001\001\160\000\001\004\0002\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\000\027\000\000\016\000\004\000\000\000\020\000LQ\0002\016\004\b\000L\018-\000\016\026\000\000\016@\144\000\027\000\000\016\000\004\000\000\000\020\000LQ\b2\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\000\001\176\000\001\000\000@\000\000\001@\004\197\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t2\017\180\b\001L\018m\000\016\027@\004\213P\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\147!\027@\128\020\193&\208\001\001\180\000MU\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\000\004\000\000\000\000\000H\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b2\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\000\001\176\000\001\000\000@\000\000\001@\004\197\016\131!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\000\027\000\000\016\000\004\000\000\000\020\000LQ\b\000\000\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003!\002@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\001 \000\000\000\000@\000\000\000\000\004\133\016\131!\002@\128\004\193\"\208\001\001\160\000\001D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\017\000\000\000\000\004\000\000\000\000\000H\017\b\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000\131\000\001\000\000\000@\000\000\000\000\000\000\000\000\b\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\144\005\t\000L\018k\000\016\025\000\004\209P\000\000\000\000\000\000\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\016\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\b\000\000\000\000\004\000\000\000\016\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\003!\004@\200$\193&\208\001\001\160\000\001\004\000\016 \004\004\000\b\016@\000\001\000\000\000\000\128\001\002\000@@\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\000\000\000\000\000\000\b\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\0000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\128\000\000\000\000\000\000\000\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012H\002\168\000\131\001!\192\001\016\007`\002 \004\000\128\000\000\000 \000\000\000\000\000\000\000\000\000\0000\000\002\b\000L\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\001\000\000\003\000\000x\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\012H\002\168\000\131\001!\192\001\016\007`\002 \020\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\012H\002\168\000\131\001!\192\001\016\007`\018 \020\196\128*\128\b0\018\028\000\017\000v\001\"\000@0\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\196\128*\128\b0\018\028\000\017\000v\001\"\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\001\001\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012H\002\168\000\131\t!\192\001\016\007a\002 \004\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\128*\128\b0\146\028\000\017\000v\016\"\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\128*\128\b0\018\028\000\017\000v\000\"\000@\b\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\196\128*\128\b0\018\028\000\017\000v\000\"\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\016\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\196\128*\128\b0\146\028\000\017\000v\016\"\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\000\000\128\000\001\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\b\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\128\000\000\000\000\000\000\000\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012H\002\168\000\131\t!\192\001\144\007`\002`\004\005\002\b@\000\000\129\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\128\004\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\192\000\b\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012H\002\168\000\131\t!\192\001\144\007a\002`\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000@\000\128\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\0026\016$X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000@\000\000\000@\000\000\000\000\b\000\001\000\000\000\000\000\000\000\004\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\018\016\004@\b\012\0189\000\000\024\000\000\024\192\192\000\017\000\000\000\000\000\000\003\000\016P$\000\0026\016\004\\(\223\018}\000@\248 \000\024\224#a\000E\130\141\241'\208\004\015\130\000\001\142\0026\016\004X(\223\018=\000@\248 \000\024\224\001!\000D@\128\193'\144\000\001\128\000\001\140\000\018\016\004@\b\012\018y\000\000\024\000\000\024\192\001!\000D\000\128\193#\144\000\001\128\000\001\140\000\018\016\004@\b\012\0189\000\000\024\000\000\024\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\197\189\187\215\248\190\215?\191\251a\247\219\127\253\240\016\000\000\000\000\012\0028\000\000\000\000\000\000\000\163a\136G\226\173\245#\211\230/\144@\025\174\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\163a\bE\130\141\241#\208\004\015\128\000\001\142\n6\016\132X(\223\018=\000@\248\000\000\024\224\129\002\000@@\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\000\000\000\000\000\000\b\000@\000\000\000\000\000@\000\129\000@@\000 \193\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\b\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\163a\bE\130\141\241#\208\004\015\128\000\001\142\n6\016\132X(\223\018=\000@\248\000\000\024\224\131!\b@\128\004\193\"\208\001\001\128\000\001\004\000\000\000\000\000\000\000\000@\000\000\001\000\004\193\016\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\0026\016\004\\(\223\018}\000@\248\000\000\024\224#a\000E\130\141\241'\208\004\015\128\000\001\142\0026\016\004X(\223\018=\000@\248\000\000\024\224\003!\000@\192\004\193&\208\001\001\160\000\001\020\0002\016\004\b\000L\018m\000\016\026\000\000\017@\003!\000@\128\004\193\"\208\001\001\160\000\001\020\0002\016\004\b\000L\018-\000\016\026\000\000\016@\016\000\000\000\000\016\000\004\000\000\000\000\000H\017\0026\016\004X(\223\018=\000@\248\000\000\024\224\003)\000P\208\004\193&\176\001\001\128\000\001\004\0002\144\005\t\000L\018k\000\016\024\000\000\016@\003)\000P\144\004\193\"\176\001\001\128\000\001\004\000 \000\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\b\000\000\000\000\004\000\000\000\016\000L\017\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\b\000\000\000\000\004\000\000\000\016\000\000\000\000\000\000\128\000\000\000\000\000\000\000\001\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\131\161\136G\224,\229\"\211\227!\176@\025,\176\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000@\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\0002\144\005\t\001L\018+\000\016\024\000\000P@#a\000E\130\141\241#\208\004\015\128\000\001\142\0002\016\004\012\000L\018m\000\016\026\000\000\016@\003!\000@\128\004\193&\208\001\001\160\000\001\004\0002\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\004\000\000\000\016\000H\017\0026\016\004X(\223\018=\000@\248\000\000\024\224\001!\000D@\128\193'\144\000\001\128\000\001\140\000\018\016\004@\b\012\018y\000\000\024\000\000\024\192\001!\000D\000\128\193#\144\000\001\128\000\001\140\012IK\184>\131\225a\192\255\182\007}\183\231\015\001!\000D\000\128\193#\144\000\001\128\000\001\140\012[\219\189\127\139\237s\251\255\182\031}\183\255\223\000\000\000\000\000\000\128\002\128\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224#a\000E\130\141\241#\208\004\015\128\000\001\142\012[\219\189\127\139\237s\251\255\182\031}\183\255\207\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001!\000D\000\128\193#\144\000\001\128\000\001\140\012[\219\189\127\139\237s\251\255\182\031}\183\255\223\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\192\002\128\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\128\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012[\219\189\127\139\237s\251\255\182\031}\183\255\207\196\148\187\131\232>\022\028\015\251`w\219~p\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\004#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\197\189\187\215\248\190\215?\191\251a\247\219\127\252\252IK\184>\131\225a\192\255\182\007}\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\231\245\187\199\234\191\247?\223\253o\247\139\127\254\247\223d@\130\2545\000\004\193\193\2388\176(4#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2402\016\004\b\000L\018m\000\016\024\000\000\016@\003!\000@\128\004\193\"\208\001\001\128\000\001\004\0002\144\005\t\000L\018k\000\016\025\000\006\209P\131\161\136G\224,\229\"\211\227!\176@\025,\176\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\0002\144\005\t\000L\018+\000\016\025\000\002P@\003!\000@\128\004\193\"\144\001\001\128\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\131\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\025\000\000\000\000\004\000\000\000\016\000\000\000\b0\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\001\144\000\000\000\000@\000\000\001\000\002\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\b\000\001\144\000\000\000\000@\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\144\005\t\000L\018+\000\016\025\000\002P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\000\000\016\000\001\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\128\000\000\000\000@\000\000\000\000\004\193\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\131\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b8\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\016\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\004\193\016\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000H\017\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b2\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\004\129\016\131!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000H\017\b2\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\004\129\016\128\000\000\000\000\000\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\004\129\016\003!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000@\000\000\001\000\004\129\016\132\128\"\128\b \018\024\000\025\000f\000\002\000HH\002(\000\130!!\128\193\144\006`\016 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\b\016>\000\192@@>\002\001\000\005\130\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000P\000\000\000\000\000\000\000\000\b\000(\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\155\003\224\012\004\004\003\224 \016\000X`:6\016\180X(\223\018=\000@\248\000\000\028\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\128\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\128\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001!\000D\000\128\193#\144\000\001\128\000\001\140\012[\219\189\127\139\237s\251\255\182\031}\183\255\223\000\000\000\000\000\000\128\002\128\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\128\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\128\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\012[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015\128\000\145\003\224\012\004\004\003\224 \016\000X 0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\192\002\128\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\128\000\b\000\000\000\000\000\000\000\000\000\000\000\000\012[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\128\000\129\003\224\012\004\004\003\224 \016\000X <[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015\000\000\000\000\000\000\000\000\000\000\000\000P\000\000\000\000\000\000\000\000\b\000(\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\128\000\002\000\000\000\000\000\000\000\000\000\000\000\000\012[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\252[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015\197\189\187\215\248\190\215?\191\251a\247\219\127\253\252[\219\189\127\139\237s\251\255\150\031x\183\255\207\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\128\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\131\161\136G\224,\229\"\211\227!\176@\025,\176\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\0002\144\005\t\001L\018+\000\016\024\000\000P@\003\000\000`\000\000\197\194\000\001\000\000\000\000\000\000\016\000\000\000\001\004\000\000\000\016\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003)\000P\144\020\193\"\176\001\001\128\000\005\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003)\000P\144\020\193\"\176\001\001\128\000\005\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\001\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012IK\184>\131\225a\192\255\150\007x\183\231\015\003!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\004\129\016#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\1306\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\016\004\b\000L\018-\000\016\024\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129!\bD\000\128\193#\144\000\001\128\000\001\140\b\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\206\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016$X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001!\000D\000\128\193#\144\000\001\128\000\001\140\004\000\000\000\000\000\000\000\000\0000\000\005\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\017\000\000\000\000\000\000\000\000\016\000$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\017\000\000\000\000\000\000\000\000\016\000\000\000\b\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000\129\000\001\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\003\000\000P\000\000\000\016\000\000\000\000\012\0028\000\000\000\000\000\000\000\192\000\017\000\000\000\000\000\000\003\000\016P$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\148\187\131\232>\022\028\015\251`w\219~p\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\145\003\224\012\004\004\003\224`\016\000X 8\000\001\000\000\000\000\000\000\000\004\000\000\000\000\000\128\000\000\000\000\000@\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\002\000@\000\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\128\004\000\b\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\004\000\000\000@\000\000\000\000\000\000\000\003\000\000\000\000\000\000\004\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\016\000\004\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\132\128\"\128\b \146\028\000\025\000f\000\002\000@\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000@\000\000\000\000\016\000\004\000\000\000\016\000\000\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\132\128\"\128\b \146\028\000\025\000f\000\002\000@\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000\000@\000\128\006\000\000\000\128\000\000\000\000\018\000\000\000\000\b\000`\000\000\b\000\000\000\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\004\000\b\000\000\000\004\000\0000\000\006\000\000\012\\(\000\016\000\000\000\000\000\000\000\000\000\000@@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\001\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\001\016\000\000\000\000@\000\002\000\000\000\000\016\000\000\017\000\000\000\000\004\000\000\000\000\000\000\000\000\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000@@\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\000\000\000\004\000\000 \000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\004\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\006\000\000\012\\ \000\016\000\000\000\000\000\133\128\162\128\b0R\028\000\025\000f\001\002\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\133\128\162\128\b R\028\000\025\000f\001\002\016@0\000\006\000\000\012\\(\000\016\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\0000\000\006\000\000\012\\ \000\016\000\000\000\000\000\133\128\"\128\b R\028\000\025\000f\001\002\016HX\n(\000\131\005!\192\001\144\006`\016!\004\000\000\000\000\000\000\000\004\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\016D\b\000L\018m\000\016\024\000\000\016@\003!\004@\128\004\193\"\208\001\001\128\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003!\000@\128\004\193\"\208\001\001\128\000\001\004\bH\002(\000\130\001!\128\001\144\006`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\148\187\131\232>\022\028\015\249`w\139~p\244\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003!\000@\128\004\193\"\208\001\001\160\000\001\020\012IK\184>\131\225a\192\255\150\007x\183\231\015\128\000\136\003\224\012\004\004\003\224 \016\000| 0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\128\000\001\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\128\000\001\000\000@\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000@\000\b\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \146\028\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\002\000@\000\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\132\128\"\128\b \146\028\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\128\004\000@\000\000\004\000\000\000\000\000\000\000\000\016\000\000\004\000\004\000@\000\000\000\000\000\000\000\001\000\000\000\000\000@\004\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\017\000v\000\002\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\196\128\"\128\b0\018\028\000\017\000f\000\002\000\bH\002(\000\130\001!\128\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000@\000\000\000\000@\000\000\000\000\000\000\000\003\000\004\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\016\000\004\000\bH\002(\000\130\001!\128\001\016\006`\000 \004\132\128\"\128\b \018\016\000\017\000f\000\002\000@0\000\000\000\000\000\000@\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\001\000\000@\000\132\128\"\128\b \018\024\000\017\000f\000\002\000HH\002(\000\130\001!\000\001\016\006`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\016\000\004\000\bH\002(\000\130\001!\128\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\223d@\130\2545\000\004\193\193\2388\176(4'\225\"\213\138\173\2433\208\020\015\224\000\007\142\0002\016\004\b\000L\018-\000\016\026\000\000\016@\016\000\002\000\000\000\000\004\000\000\000\000\000H\017\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\223d@\130\2545\000\004\193\193\2388\176(4'\225\"\213\138\173\2433\208\020\015\224\000\007\142\000\016 \004\004\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\132\128\"\128\b \146\028\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\192\004\000\000\000\000\000\000\000\000\000\000\000\000\000\012\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\018(\000\130\001!\128\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\004\000\b\000`\000\000\b\000\000\000\000\001 \000\000\000\000\128\006\000\000\000\128\000\000\000\000\018\000\000\000\000\b\000 \000\000\b\000\000\000\000\132\128\"\128\012 \018\028\000\017\000v\000\006\000\000\018\000\000\000\000\b\000 \000\000\b\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\b\000\bH\002(\000\130\001!\192\001\016\006a\000!\000\001\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\132\128\"\128\b \018\028\000\017\000f\000\002\000\bH\002(\000\130\001!\128\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\192\001\016\006`\000 \000\132\128\"\128\b \018\024\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\128\"\240\024 \199\210\000\017\000`\000\002\000\bH\002(\000\130\000!\000\001\000\006`\000 \000\001\000\000\000@\000\000\004\000\000\000\000\000\000\b\000\016\000\000\004\000\000\000@\000\000\000\000\000\000\000\001\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \130\024\000\016\000f\016\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \130\024\000\016\000f\016\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\128\004\000@\000\000\004\000\000\000\000\000\000\000\0000\000@\000\000\000\000@\000\000\000\000\000\000\000\003\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\001\000\001@\000\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \130\024\000\016\000f\016\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\012H\002(\000\131\000!\192\001\000\006`\000 \004\132\128\"\128\b \002\016\000\016\000f\000\002\000@0\000\000\000\000\000\000@\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\012H\002(\000\131\000!\192\001\000\006`\000 \004\132\128\"\128\b \002\016\000\016\000f\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\001\000\000@\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\000!\128\001\000\006a\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\196\128\"\128\b0\002\028\000\016\000f\000\002\000\bH\002(\000\130\000!\128\001\000\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\004\004\004\002\012\016@\000\001\000\000\000\000\000\001\000@@\000 \193\004\000\000\016\000\000\000\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\196\128\"\128\b0\002\028\000\016\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000\000@\000\128\006\000\000\000\128\000\000\000\000\018\000\000\000\000\b\000`\000\000\b\000\000\000\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\000\bH\002(\000\194\000!\192\001\000\006`\000`\000\b\128\000\000@\000@\006\000\000\000\000\000\000\000\000\128\000\000\004\000\004\000`\000\000\000\000\000\000\000\b\000\000\000\000\000@\006\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\002\000\000 \128\004\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\016\000\004\000 \005\016 \000\000\000\000\000\000\000\132\000\000\128\000\002\130\020\004\000\000\002\001\000\000\b@\000\b\000\000(!\000@\000\000 \016\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\128\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\000@\000\000 \016\000\000\b\000\000\000\000@@\004\000\000\000\000\000\000\000\000\128\000\000\000\004\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000@@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\b@\000\b\000\000 !\192@\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\128\000\004\000@\000\000\000\000\000\000\000\b\000\000\b\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\016\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\132\000\000\128\000\002\002\028\012\000\000\018\001\000\000\b@\000\b\000\000 !\128@\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\192\192\000\001 \016\000\000\001\000\000@\002\000Q\006\000\000\000\000\000\000\000\000\016\000\004\000 \005\016 \000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\128\001\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\016\000\000\000\016\000\004\000 \005\016 \000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\004\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000 \000\000\000\000@\000\000\000\000\004\000\000\000\000\002\000\000\000\000\004\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002\168\000\130!!\192A\016\007`\016 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\016\000\000\000\016\000\004\000 \005\016 \000\000\000\000\000\000\000\132\128*\128\b\"\018\028\004\017\000v\001\002\000H@\000\b\000\000 !\192@\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\`\000\016\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\b@\000\b\000\000 !\192\192\000\000 \016\000\000\132\000\000\128\000\002\002\024\004\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\128@\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\016\004\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\028\000\017\000f\000\002\000HH\002(\000\130\001!\000\001\016\006`\000 \004\b\000\000\000\000\000@\006\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\016\000\004\000 \005\016 \000\000\000\000\000\000\000\132\128\"\128\b \018\028\000\017\000f\000\002\000HH\002(\000\130\001!\000\001\016\006`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000@\006\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\0000\000\007\001 \r\\ \000\016\000\000\000\000\000\133\128\170\128\b0B\028\000\017\000v\000\006\000@0\000\006\000\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\0000\000\007\001 \r\\ \000\016\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\020\000\000\000 \000\000\000\000@\000\000\000\000\004\001\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\0000\000\007\001 \r\\ \000\016\000\000\000\000\000\003\000\000`\000\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\003\000\000p\018\000\213\194\000\001\000\000\000\000\000\bX\n\168\000\131\004!\192\001\016\007`\000 \004\133\128\170\128\b0B\028\000\017\000v\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128*\128\b \002\028\000\016\000v\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\000!\128\001\000\006`\000 \004\132\128\"\128\b \002\016\000\016\000f\000\002\000@\128\000\000\000\000\004\000`\000\000\000\000\000\000\000\b\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\003\000\000p\018\000\213\194\000\001\000\000\000\000\000\bH\002(\000\130\000!\128\001\000\006`\000 \004\132\128\"\128\b \002\016\000\016\000f\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \002\016\000\016\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\000!\128\001\000\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\000!\000\001\000\006`\000 \004\002\000\000 \128\004\192\004\000\000\000\000\000\000\000\000 \000\002\b\000L\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\016\007`\016 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\016\006`\016 \004\132\128\"\128\b \018\016\000\017\000f\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\000!\000\001\000\006`\000 \004\002\000\000 \128\004\192\004\000\000\000\000\000\000\000\000 \000\002\b\000L\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\003 \000x\016\000\197\194\128\001\000\128 \000\016\0000\000'\001\000\012\\ \000\016\000\000\000\001@\000\000\000\000\000@@\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\133\160\"\128\b \146\026\000\017\000\230\001\002\000HH\002(\000\194\001!\192\001\016\006`\016a\004\132\128\"\128\b \018\028\000\017\000f\001\002\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\017\000f\001\002\016@\018\000\000\000\000\b\000 \000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \002\024\000\016\000f\001\002\000HH\002(\000\130\000!\000\001\000\006`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\192\001\016\007`\016 \004\001 \000\b\000\000\128\002\128\000\000\128 \000\016\000\018\000\000\000\000\b\000(\000\000\b\002\000\001\000\000\000\000\000\000@@\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\194\001!\192\001\016\006`\016a\004\132\128\"\128\b \018\028\000\017\000f\001\002\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@@\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\004\000\000\000\000\000\000\000\000\136\000\000\004\000\004\000`\000\000\000\000\000\000\000\b\000\000\000\000\000@\006\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\003)\000P\144\004\193\"\176\001\001\144\000\005\004\000\016\000\004\000 \r\016 \000\000@\000\000\000\000\132\000\000\128\000\002\130\020\012\000\000\002\001\000\000\b@\000\b\000\000(!\000\192\000\000 \016\000\000\132\000\000\128\000\002\002\016\012\000\000\002\001\000\000\000\128\000\000\000\004\004\000@\000\000\000\000\000\000\128\000\000\000\000\000@@\004\000\000\000\000\000\000\000\000\000\000\000\000\004\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\002@\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\128\192\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\004\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000@@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\b@\000\b\000\000 !\192\192\000\000 \016\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\002@\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\128\000\004\000@\000\000\000\000\000\000\128\000\000\000\b\000\000@\004\000\000\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\003)\000P\144\004\193\"\176\001\001\144\000\005\004\0008\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\024\012\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\b\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\003)\000P\144\004\193\"\176\001\001\144\000\005\004\0008\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241'\208\004\015\128\000\001\142\0026\016\004X(\223\018=\000@\248\000\000\024\224\132\000\000\128\000\002\002\024\012\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000@\002\000\209\006\000\000\004\000\000\000\b\000\016\000\004\000 \r\016`\000\000@\000\000\000\000\001\000\000@\002\000\209\002\000\000\004\000\000\000\000\000\016\000\004\000 \r\016 \000\000@\000\000\000\000\003!\004@\200\004\193&\208\001\001\128\000\001\004\007\223d@\130\2545\000\004\193\193\2388\176(4\003!\004@\128\004\193&\208\001\001\128\000\001\004\0002\016D\b\000L\018-\000\016\024\000\000\016@\003!\000@\128\004\193\"\208\001\001\128\000\001\004\000\000\000\000\000\000\000\000\128\000\128\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\128\001\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\016\000\000\000\016\000\004\000 \r\016 \000\000@\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\004\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003)\000P\144\004\193&\176\001\001\128\000\001\004\0002\144\005\t\000L\018+\000\016\024\000\000\016@\003)\000P\144\020\193\"\176\001\001\128\000\001\004\000\016\000\004\000 \r\016 \000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000@\016\000\004\000 \r\016 \000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bZ\146\173A\138-3\251\193\016\030`\016x\212\133\169*\212\024\162\211?\188\017\001\230\001\007\141@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128*\128\b\"\018\028\012\017\000f\001\006\001@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002\168\000\130!!\192\193\016\006`\016`\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128*\128\b\"\018\028\012\017\000f\001\006\001@\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\016\000\000\000\016\000\004\000 \r\016 \000\000@\000\000\000\000\132\128*\128\b\"\018\028\012\017\000f\001\006\001@2\016D\b\000L\018-\000\016\024\000\000\016@\003!\000@\128\004\193\"\208\001\001\128\000\001\004\000\000\000\000\000\000\000\000\128\000\128\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\128\000\000\000\000@\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\018\000\213\194\000\001\000\000\000\000\000\b\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\028\012\000\000\002\001\000\001\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\128\192\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\004\000 \r\016 \000\000@\000\000\000\000\132\000\000\128\000\002\002\028\012\000\000\002\001\000\001\b@\000\b\000\000 !\128\192\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\`\000\016\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\b@\000\b\000\000 !\128\192\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\024\012\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\000\192\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\192\001\016\006`\000 \004\003\000\000p\018\000\213\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\001\000\000@\002\000\209\002\000\000\004\000\000\000\000\bH\002(\000\130\001!\192\001\016\006`\000 \004\003)\000P\144\004\193\"\176\001\001\144\000\005\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\017\000f\000\002\000HH\002(\000\130\001!\000\001\016\006`\000 \004\b\000\000\000\000\000@\006\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\003)\000P\144\004\193\"\176\001\001\144\000\005\004\bH\002(\000\130\001!\128\001\016\006`\000 \004\132\128\"\128\b \018\016\000\017\000f\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\016\000\016\000f\000\002\000\0002\016D\012\000L\018m\000\016\024\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\016\000\017\000f\000\002\000HH\002(\000\130\001!\128\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\000\001\016\006`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\016\000f\000\002\000\bH\002(\000\130\001!\000\001\000\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\016\000\025\000f\000\002\000@\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\000\006`\000 \000\132\128\"\128\b \018\016\000\016\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\128*\128\b0\146\028\000\017\000v\000\"\000L\000\000\128\000\001\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\004\000\000\000\000\000L\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\128\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\000\192\000\000 \016\000\000\128\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129\002\000@@\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\000\000\000\128\000\000\b\000@\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\128\000\001\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\128\000\000\000\000\000\000\000\000\000\002@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b2\016\004\b\000L\018-\000\016\026\000\000\017@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012IK\184>\131\225a\192\255\150\007x\183\231\015\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\001 \000\b\000\000\128\002\000\000\000\128\000\000\016\000\018\000\000\000\000\b\000 \000\000\b\000\000\001\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\000\bH\002(\000\194\001!\192\001\016\007`\000a\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\000\bH\002(\000\130\001!\192\001\016\006`\000!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\016\006`\000!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\194\001!\192\001\016\007`\000a\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\000\bH\002(\000\130\001!\192\001\016\006`\000!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\132\128\"\130\b \018\024\000\017\000v\001\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\017\000f\001\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\128\000\b\000 \000\000\b\000\000\001\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\016\bH\002(\000\130\001!\128\001\016\006`\000!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\002\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000 \000\000\000\000\0000\000\006\000\000\012\\`\000\018\000\002\000\000\000\003\000\000`\000\000\197\194\000\001 \000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\001\000\000\000\004\000\000\000\018\000\000\000\000\000\003\000\000`\000\000\197\194\000\001 \000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000@\000\000\016\000\000\000\000\004\000\000\000\016\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\b\000\000\000\000\004\000\000\000\000\000@\000\000\000\000\128\000\000\000\000@\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\b\000\000\000\000\004\000\000\000\000\000@\000\000\000\000\000\000\004\004\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\192\001\016\006`\016 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003 \000x\016\000\197\194\128\001\000\128 \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \002\024\000\016\000f\001\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\128\000\b\000 \000\000\b\000\000\001\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\016\bH\002(\000\130\000!\128\001\000\006`\000!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\bH\002( \130\000!\128\001\000\007`\017 \004\003 \000x\016\000\197\194\128\001\000\128 \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \002\024\000\016\000f\001\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\128\000\b\000 \000\000\b\000\000\001\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\016\bH\002(\000\130\000!\128\001\000\006`\000!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\b\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\028\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128 \128\b \002\016\000\016\000d\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000\000\000\000\192\002\000\000\000\128\000\000\000\b\000\b\128~\002\194@\000>\"\001\004\001\130\139\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\016\000\000\000\016\000\000\000\000\012\000\000\000\000\000\000\000\000\000\128\000\128\007\224,$\000\003\226 \016@\024(\176\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000@\000\000\000@\004\129\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\016\000\000\000\000\012\000\000\000\000\000\000\000\000\000'\225 \197\138\173\2433\208\021\015\228\000\003\142\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\005\161 \128\b \210\016\016\017\000\228\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128 \128\b \018\016\000\017\000d\016\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\002\b\000\130\001!\000\001\000\006\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000'\225 \197\138\173\2433\208\021\015\228\000\003\142\002~\018\012X\170\2233=\001P\254@\0008\224\004\128 \128\b \018\016\000\017\000d\000\002\000\000H\002\b\000\130\001!\000\001\016\006@\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128 \128\b \018\024\000\017\000d\000\002\000\000H\002\b\000\130\001!\000\001\016\006@\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\002\b\000\130\001!\128\001\016\006@\000 \000\004\128 \128\b \018\016\000\017\000d\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000") + (124, "'\225 \197\138\173\2433\208\020\015\228\000\003\142\0026\016\004\\(\223\018}\000@\248\000\000\024\224}\246D\b/\227P\000L\028\030\227\139\002\131@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\175\235f\245\155\175\2437\252\149\031\226\017\007\158\007\223d@\130\2545\000\004\193\193\2388\176(4\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241'\208\004\015\128\000\001\142\007\223d@\130\2545\000\004\193\193\2388\176(4'\225\"\213\138\173\2433\208\020\015\224\000\007\142\000\000\000\000\004\000\012\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\192\004\000\000\000\000\000\000\000\000\000\000\000\000\000\012\000\000\000\000\000\000\000\000\000\128\000\128\007\224,$\000\003\226 \016@\016(\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000(\000\000\000\000\000\000\000\000\000\024\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\002\012\\ \000\016\000\000\000\000\000\001\000@@@ \193\004\000\000\016\000\000\000\000\000\016\004\004\000\002\012\016@\000\001\000\000\000\000\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\012H\002\168\000\131\t!\192\001\016\007a\002 \004\132\128 \128\b \002\020\000\016\000b\000\002\000\bH\002\b\000\130\000!\000\001\000\006 \000 \000\003\000\000$\193\004\192\004\000\128\000\000\000\000\b\0000\000\002H\016L\000@\b\000\000\000\000\000\128\003\000\000$\129\004\192\000\000\128\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000 \000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000$\128\004\192\000\000\128\000\000\000\000\b\000 \000\002\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\002H\000@\000\000\b\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\002\b\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000$\128\004\000\000\000\128\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\bH\002( \130\000!\128\001\000\007`\017 \004\003 \000x\016\000\197\194\128\001\000\128 \000\016\bH\002(\000\194\t!\192\001\016\006a\016a\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\000\007\001\000\012\\(\000\016\b\002\000\001\000\003\000\bp\016 \197\194\000\001\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\197\128\187\128\b2R\028\012\017 v\001f\017`0\000\006\000\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\006\000\000\012\\ \000\018\000\002\000\000\000\001\000\016\000\000\000@\000\000\001 \000\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\bP\t\026\000\001$!\192\192\018\001!\018\000\016}\246D\b/\227P\000L\028\030\227\139\002\131B~\018-X\170\2233=\001@\254\000\000x\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000$\193\004\192\004\000\128\000\000\000\000\b\0000\000\002H\016L\000@\b\000\000\000\000\000\128\003\000\000$\129\004\192\000\000\128\000\000\000\000\b\0000\000\002H\000L\000\000\b\000\000\000\000\000\128\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\bH\002( \130\001!\128\001\016\007`\016 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\016\006`\016 \004}\246D\b/\227P\000L\028\030\227\139\002\131B~\018-X\170\2233=\001@\254\000\000x\224#a\000E\194\141\241'\208\004\015\128\000\001\142\0026\016\004X(\223\018}\000@\248\000\000\024\224#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001!\000D\000\128\193#\144\000\001\128\000\001\140\000\016\000\000\004\000\004\000@\000\000\000\000\000\000\000\001\000\000\000\000\000@\004\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\175\235w\253\155\239\247\255\252\157?\230!\003\158@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\163a\136G\226\173\245#\211\230/\144@\025\174\184\018\016\132@\b\012\0189\000\000\024\000\000\024\192#a\000E\130\141\241#\208\004\015\128\000\001\206\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\004\000(!@\192\000\000 \016\000\000\132\000\000\128\000\002\130\020\012\000\000\002\001\000\000\b@\000\b\000\000(!\000\192\000\000 \016\000\000\003!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\131!\136G\224,\229\"\211\227!\176@\025,\184\000\000\128\000\000\000\000\001\000\000\016\000\000\000\000\131\000\000\000@\000\000\004\000\000\000\000\000\000\000\0000\000\000\000\000\000\000@\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\001\002\000@\000\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\167\225 \197\138\173\2437\208\020\015\226\000\003\142\n~\018\012X\170\2233=\001@\254 \0008\224\167\225\"\197\138\173\2433\208\020\015\230\000\003\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\002\000@@\000\129\004\000\000\016\000\000\000\b\000\016 \004\004\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\005\002\000@\000\000\129\000\000\000\016\000\000\000\000\0026\016\004X(\223\018}\000@\248\000\000\024\224#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004\\(\223\018}\000@\248\000\000\024\224#a\000E\130\141\241'\208\004\015\128\000\001\142\0026\016\004X(\223\018=\000@\248\000\000\024\224\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\003!\000@\128\004\193\"\208\001\001\128\000\001\004\0002\016\004\b\000L\018-\000\016\026\000\000\020@\003!\002@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\001\016\000\000\000\000\000\000\000\001\000\000@\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\001@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000@\003\000\002p\016\000\197\194\000\001\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\004\0000\000\007\001\000\012\\ \000\016\000\000\000\001@\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\001\000\000\000\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\128\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000@\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012H\003\184\000\131!!\192\193\018\007`\022!\022\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\012H\011\184\000\131!!\192\193\018\007`\022!\022\003\000\000`\000\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012X\011\184\000\131%!\192\193\018\007`\022!\022\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\006\000\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012X\011\184\000\131%!\192\193\018\007`\022!\022\003\000\000`\000\000\197\194\000\001\000\000\000\000\000\012X\011\184\000\131%!\192\193\018\007`\022!\022\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000@\000\000@\000\002\000\000\000\001\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000 \000\000\000\000@\000\002\000\000\000\001\002\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\004\000\000 \000\000\000\017 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000@\000\002\000\000\000\001\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000@\000\002\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012H\003\184\000\131!!\192\193\018\007`\022!\020\000\000\002\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\0000\000\007\001\000\012\\ \000\016\000\000\000\000@\000\000\002\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000 \000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000 \000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\001\016\000\000\000\000@\000\000\001\000\000\000\000\128\000\017\000\000\000\000\000\000\000\000\016\000\000\000\0002\016\004\b\000L\018-\000\016\026\000\000\016@\003!\000@\192\004\193&\144\001\001\128\000\001\004\0002\016\004\b\000L\018i\000\016\024\000\000\016@\003!\000@\128\004\193\"\144\001\001\128\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\147)\027P\144\020\193&\176\001\001\148 mU\000\000\016\000\b\000@\000\001\000\000\016\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t2\145\181\t\001L\018o\000\016\027A\006\213P\001\000\000\000\000\000\128\"\128\000\000\000\000\000\000\b2\016\132\b\000L\018-\000\016\026\000\000\144@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003!\000@\192\004\193&\208\001\001\160\000\001\004\0002\016\004\b\000L\018m\000\016\026\000\000\016@\003!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\000\001\176\000\001\000\000@\000\000\001@\004\197\016\003!\000@\128\004\193\"\208\001\001\160\000\001\004\t\000\001\176\000\001\000\000@\000\000\001@\004\197\016\131!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\000\027\000\000\016\000\004\000\000\000\020\000LQ\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\147!\027@\128\020\193&\208\001\001\180\000MU\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t2\017\180\b\001L\018m\000\016\027@\004\213P\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\128\000\000\000\000@\000\000\000\000\004\129\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\131!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\000\027\000\000\016\000\004\000\000\000\020\000LQ\b2\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\000\001\176\000\001\000\000@\000\000\001@\004\197\016\128\000\000\000\000\000\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\016$\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\018\000\000\000\000\004\000\000\000\000\000HQ\b2\016$\b\000L\018-\000\016\026\000\000\020@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\001\016\000\000\000\000@\000\000\000\000\004\129\016\128\000\017\000\000\000\000\000\000\000\000\000\000\000\000\b0\000\016\000\000\004\000\000\000\000\000\000\000\000\000\128\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003)\000P\144\004\193&\176\001\001\144\000M\021\000\000\000\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\001\000\000@\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\128\000\000\000\000@\000\000\001\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\0002\016D\012\130L\018m\000\016\026\000\000\016@\001\002\000@@\000\129\004\000\000\016\000\000\000\b\000\016 \004\004\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\003\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\000\000\000\000\000\000\b\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\001\b\000\000\000\000\000\000\000\000\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\128*\128\b0\018\028\000\017\000v\000\"\000@\b\000\000\000\002\000\000\000\000\000\000\000\000\000\000\003\000\000$\128\004\192\000\000\128\000\000\000\000\b\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\016\000\0000\000\007\129\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\196\128*\128\b0\018\028\000\017\000v\000\"\001@0\000\007\001\000\012\\ \000\016\000\000\000\000\000\196\128*\128\b0\018\028\000\017\000v\001\"\001LH\002\168\000\131\001!\192\001\016\007`\018 \004\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\012H\002\168\000\131\001!\192\001\016\007`\018 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\016\016\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\128*\128\b0\146\028\000\017\000v\016\"\000@\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012H\002\168\000\131\t!\192\001\016\007a\002 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012H\002\168\000\131\001!\192\001\016\007`\002 \004\000\128\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\012H\002\168\000\131\001!\192\001\016\007`\002 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\012H\002\168\000\131\t!\192\001\016\007a\002 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\192\000\b\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\128\000\001\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\b\000\000\000\000\000\000\000\000\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\128*\128\b0\146\028\000\025\000v\000&\000@P \132\000\000\b\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\128\000\000\b\000@\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\012\000\000\128\000\001\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\128*\128\b0\146\028\000\025\000v\016&\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\004\000\b\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224#a\002E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\004\000\000\000\004\000\000\000\000\000\128\000\016\000\000\000\000\000\000\000@\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\001!\000D\000\128\193#\144\000\001\128\000\001\140\012\000\001\016\000\000\000\000\000\0000\001\005\002@\000#a\000E\194\141\241'\208\004\015\130\000\001\142\0026\016\004X(\223\018}\000@\248 \000\024\224#a\000E\130\141\241#\208\004\015\130\000\001\142\000\018\016\004D\b\012\018y\000\000\024\000\000\024\192\001!\000D\000\128\193'\144\000\001\128\000\001\140\000\018\016\004@\b\012\0189\000\000\024\000\000\024\192\001!\000D\000\128\193#\144\000\001\128\000\001\140\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012[\219\189\127\139\237s\251\255\182\031}\183\255\223\001\000\000\000\000\000\192#\128\000\000\000\000\000\000\n6\024\132~*\223R=>b\249\004\001\154\235\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n6\016\132X(\223\018=\000@\248\000\000\024\224\163a\bE\130\141\241#\208\004\015\128\000\001\142\b\016 \004\004\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\004\000\b\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\128\000\001\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n6\016\132X(\223\018=\000@\248\000\000\024\224\163a\bE\130\141\241#\208\004\015\128\000\001\142\b2\016\132\b\000L\018-\000\016\024\000\000\016@\000\000\000\000\000\000\000\004\000\000\000\016\000L\017\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224#a\000E\194\141\241'\208\004\015\128\000\001\142\0026\016\004X(\223\018}\000@\248\000\000\024\224#a\000E\130\141\241#\208\004\015\128\000\001\142\0002\016\004\012\000L\018m\000\016\026\000\000\017@\003!\000@\128\004\193&\208\001\001\160\000\001\020\0002\016\004\b\000L\018-\000\016\026\000\000\017@\003!\000@\128\004\193\"\208\001\001\160\000\001\004\001\000\000\000\000\001\000\000@\000\000\000\000\004\129\016#a\000E\130\141\241#\208\004\015\128\000\001\142\0002\144\005\r\000L\018k\000\016\024\000\000\016@\003)\000P\144\004\193&\176\001\001\128\000\001\004\0002\144\005\t\000L\018+\000\016\024\000\000\016@\002\000\000\000\000\000\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\128\000\000\000\000@\000\000\001\000\004\193\016\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\128\000\000\000\000@\000\000\001\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b:\024\132~\002\206R->2\027\004\001\146\203\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\128\000\000\004\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\003)\000P\144\020\193\"\176\001\001\128\000\005\004\0026\016\004X(\223\018=\000@\248\000\000\024\224\003!\000@\192\004\193&\208\001\001\160\000\001\004\0002\016\004\b\000L\018m\000\016\026\000\000\016@\003!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000@\000\000\001\000\004\129\016#a\000E\130\141\241#\208\004\015\128\000\001\142\000\018\016\004D\b\012\018y\000\000\024\000\000\024\192\001!\000D\000\128\193'\144\000\001\128\000\001\140\000\018\016\004@\b\012\0189\000\000\024\000\000\024\192\196\148\187\131\232>\022\028\015\251`w\219~p\240\018\016\004@\b\012\0189\000\000\024\000\000\024\192\197\189\187\215\248\190\215?\191\251a\247\219\127\253\240\000\000\000\000\000\b\000(\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\0026\016\004X(\223\018=\000@\248\000\000\024\224\197\189\187\215\248\190\215?\191\251a\247\219\127\252\240\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\016\004@\b\012\0189\000\000\024\000\000\024\192\197\189\187\215\248\190\215?\191\251a\247\219\127\253\240\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\012\000(\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\197\189\187\215\248\190\215?\191\251a\247\219\127\252\252IK\184>\131\225a\192\255\182\007}\183\231\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000B6\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012[\219\189\127\139\237s\251\255\182\031}\183\255\207\196\148\187\131\232>\022\028\015\251`w\219~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\014\127[\188~\171\255s\253\255\214\255x\183\255\239}\246D\b/\227P\000L\028\030\227\139\002\131B6\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015\003!\000@\128\004\193&\208\001\001\128\000\001\004\0002\016\004\b\000L\018-\000\016\024\000\000\016@\003)\000P\144\004\193&\176\001\001\144\000m\021\b:\024\132~\002\206R->2\027\004\001\146\203\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\003)\000P\144\004\193\"\176\001\001\144\000%\004\0002\016\004\b\000L\018)\000\016\024\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b0\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\001\144\000\000\000\000@\000\000\001\000\000\000\000\131\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\025\000\000\000\000\004\000\000\000\016\000 \000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\128\000\025\000\000\000\000\004\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003)\000P\144\004\193\"\176\001\001\144\000%\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\128\000\000\000\000\001\000\000\016\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\000\004\000\000\000\000\000L\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b0\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\128\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\131\128\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000L\017\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\004\129\016#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\131!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000H\017\b2\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\001\000\004\129\016\131!\000@\128\004\193\"\208\001\001\160\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000H\017\b\000\000\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000H\017\0002\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\004\000\000\000\016\000H\017\bH\002(\000\130\001!\128\001\144\006`\000 \004\132\128\"\128\b\"\018\024\012\025\000f\001\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\128\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\128\000\129\003\224\012\004\004\003\224 \016\000X 0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\000\000\128\002\128\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\128\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\t\176>\000\192@@>\002\001\000\005\134\003\163a\011E\130\141\241#\208\004\015\128\000\001\206\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\016\004@\b\012\0189\000\000\024\000\000\024\192\197\189\187\215\248\190\215?\191\251a\247\219\127\253\240\000\000\000\000\000\b\000(\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\248\000\t\016>\000\192@@>\002\001\000\005\130\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\012\000(\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\128\000\002\000\000\000\000\000\000\000\000\000\000\000\000\012[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\b\016>\000\192@@>\002\001\000\005\130\003\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\240\000\000\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\000\000\128\002\128\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\128\000\b\000\000\000\000\000\000\000\000\000\000\000\000\012[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\128\000\001\000\000\000\000\000\000\000\000\000\000\000\000\012[\219\189\127\139\237\243\251\255\182\031}\183\255\207#a\000E\130\141\241#\208\004\015\128\000\001\142\012IK\184>\131\225a\192\255\150\007x\183\231\015\197\189\187\215\248\190\223?\191\251a\247\219\127\252\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\252[\219\189\127\139\237s\251\255\182\031}\183\255\223\197\189\187\215\248\190\215?\191\249a\247\139\127\252\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\b\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b:\024\132~\002\206R->2\027\004\001\146\203\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\003)\000P\144\020\193\"\176\001\001\128\000\005\004\0000\000\006\000\000\012\\ \000\016\000\000\000\000\000\001\000\000\000\000\016@\000\000\001\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\144\005\t\001L\018+\000\016\024\000\000P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\144\005\t\001L\018+\000\016\024\000\000P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\016\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\148\187\131\232>\022\028\015\249`w\139~p\2402\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\2426\016\004X(\223\018=\000@\248\000\000\024\224\196\148\187\131\232>\022\028\015\249`w\139~p\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000H\017\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\b#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003!\000@\128\004\193\"\208\001\001\128\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\018\016\132@\b\012\0189\000\000\024\000\000\024\192\128\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\028\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000#a\002E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\016\004@\b\012\0189\000\000\024\000\000\024\192@\000\000\000\000\000\000\000\000\003\000\000P\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\001\016\000\000\000\000\000\000\000\001\000\002@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\001\016\000\000\000\000\000\000\000\001\000\000\000\000\128\000\017\000\000\000\000\000\000\000\000\000\000\000\000\b\016\000\016\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\0000\000\005\000\000\000\001\000\000\000\000\000\192#\128\000\000\000\000\000\000\012\000\001\016\000\000\000\000\000\0000\001\005\002@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012IK\184>\131\225a\192\255\182\007}\183\231\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\t\016>\000\192@@>\006\001\000\005\130\003\128\000\016\000\000\000\000\000\000\000@\000\000\000\000\b\000\000\000\000\000\004\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016 \004\000\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\000\000\000\000\000\000\b\000@\000\128\000\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000\000@\000\000\004\000\000\000\000\000\000\000\0000\000\000\000\000\000\000@\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\001\000\000@\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\bH\002(\000\130\t!\192\001\144\006`\000 \004\001\000@@\000 \193\000\000\000\016\000\000\000\000\004\000\000\000\000\001\000\000@\000\000\001\000\000\000\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\bH\002(\000\130\t!\192\001\144\006`\000 \004\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\001\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\004\000\b\000`\000\000\b\000\000\000\000\001 \000\000\000\000\128\006\000\000\000\128\000\000\000\000\018\000\000\000\000\b\000 \000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\128\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000@\000\128\000\000\000@\000\003\000\000`\000\000\197\194\128\001\000\000\000\000\000\000\000\000\000\000\004\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\016\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\017\000\000\000\000\004\000\000 \000\000\000\001\000\000\001\016\000\000\000\000@\000\000\000\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\004\004\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\016\000\000\000\000@\000\002\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000@@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000`\000\000\197\194\000\001\000\000\000\000\000\bX\n(\000\131\005!\192\001\144\006`\016!\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bX\n(\000\130\005!\192\001\144\006`\016!\004\003\000\000`\000\000\197\194\128\001\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\003\000\000`\000\000\197\194\000\001\000\000\000\000\000\bX\002(\000\130\005!\192\001\144\006`\016!\004\133\128\162\128\b0R\028\000\025\000f\001\002\016@\000\000\000\000\000\000\000@\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003!\004@\128\004\193&\208\001\001\128\000\001\004\0002\016D\b\000L\018-\000\016\024\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\016\004\b\000L\018-\000\016\024\000\000\016@\132\128\"\128\b \018\024\000\025\000f\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012IK\184>\131\225a\192\255\150\007x\183\231\015@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\016\004\b\000L\018-\000\016\026\000\000\017@\196\148\187\131\232>\022\028\015\249`w\139~p\248\000\b\128>\000\192@@>\002\001\000\007\194\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000@@\000 \193\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\b\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000@@\000 \193\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\b\000\000\016\000\004\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\004\000\000\128\000\001\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\t!\192\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016 \004\000\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\bH\002(\000\130\t!\192\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0008\000@\004\000\000\000@\000\000\000\000\000\000\000\001\000\000\000@\000@\004\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000@\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\016\007`\000 \000\001\000@@\000 \193\000\000\000\016\000\000\000\000\012H\002(\000\131\001!\192\001\016\006`\000 \000\132\128\"\128\b \018\024\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\004\000\000\000\000\004\000\000\000\000\000\000\000\0000\000@\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\001\000\000@\000\132\128\"\128\b \018\024\000\017\000f\000\002\000HH\002(\000\130\001!\000\001\016\006`\000 \004\003\000\000\000\000\000\000\004\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\016\000\004\000\bH\002(\000\130\001!\128\001\016\006`\000 \004\132\128\"\128\b \018\016\000\017\000f\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\001\000\000@\000\132\128\"\128\b \018\024\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}\246D\b/\227P\000L\028\030\227\139\002\131B~\018-X\170\2233=\001@\254\000\000x\224\003!\000@\128\004\193\"\208\001\001\160\000\001\004\001\000\000 \000\000\000\000@\000\000\000\000\004\129\016#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}\246D\b/\227P\000L\028\030\227\139\002\131B~\018-X\170\2233=\001@\254\000\000x\224\001\002\000@@\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\000\000\000\016\000\000\000\000\bH\002(\000\130\t!\192\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\012\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\192\004\000\000\000\000\000\000\000\000\000\000\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\132\129\"\128\b \018\024\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000\000@\000\128\006\000\000\000\128\000\000\000\000\018\000\000\000\000\b\000`\000\000\b\000\000\000\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\000\bH\002(\000\194\001!\192\001\016\007`\000`\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\128\000\132\128\"\128\b \018\028\000\017\000f\016\002\016\000\016\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\bH\002(\000\130\001!\192\001\016\006`\000 \000\132\128\"\128\b \018\024\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\028\000\017\000f\000\002\000\bH\002(\000\130\001!\128\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000x\002/\001\130\012} \001\016\006\000\000 \000\132\128\"\128\b \002\016\000\016\000f\000\002\000\000\016\000\000\004\000\000\000@\000\000\000\000\000\000\128\001\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\b!\128\001\000\006a\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\b!\128\001\000\006a\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0008\000@\004\000\000\000@\000\000\000\000\000\000\000\003\000\004\000\000\000\000\004\000\000\000\000\000\000\000\0000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\016\000\020\000\b\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\b!\128\001\000\006a\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\196\128\"\128\b0\002\028\000\016\000f\000\002\000HH\002(\000\130\000!\000\001\000\006`\000 \004\003\000\000\000\000\000\000\004\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\016\004\004\000\002\012\016\000\000\001\000\000\000\000\000\196\128\"\128\b0\002\028\000\016\000f\000\002\000HH\002(\000\130\000!\000\001\000\006`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\016\000\004\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \002\024\000\016\000f\016\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\012H\002(\000\131\000!\192\001\000\006`\000 \000\132\128\"\128\b \002\024\000\016\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000@@@ \193\004\000\000\016\000\000\000\000\000\016\004\004\000\002\012\016@\000\001\000\000\000\000\000\001\000@@\000 \193\000\000\000\016\000\000\000\000\012H\002(\000\131\000!\192\001\000\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\004\000\b\000`\000\000\b\000\000\000\000\001 \000\000\000\000\128\006\000\000\000\128\000\000\000\000\018\000\000\000\000\b\000 \000\000\b\000\000\000\000\132\128\"\128\012 \002\028\000\016\000f\000\006\000\000\136\000\000\004\000\004\000`\000\000\000\000\000\000\000\b\000\000\000@\000@\006\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000`\000\000\000\000\000\000\000\b\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000 \000\002H\000@\000\000\b\000\000\000\000\000\128\000\000\002\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\001\000\000@\002\000Q\002\000\000\000\000\000\000\000\b@\000\b\000\000(!@@\000\000 \016\000\000\132\000\000\128\000\002\130\016\004\000\000\002\001\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\b\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\016\004\000\000\002\001\000\000\000\128\000\000\000\004\004\000@\000\000\000\000\000\000\000\b\000\000\000\000@@\000\000\000\000\000\000\000\000\000\000\000\000\000\004\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\132\000\000\128\000\002\002\028\004\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\b\000\000@\004\000\000\000\000\000\000\000\000\128\000\000\128\000\004\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\001\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\b@\000\b\000\000 !\192\192\000\001 \016\000\000\132\000\000\128\000\002\002\024\004\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\028\012\000\000\018\001\000\000\000\016\000\004\000 \005\016`\000\000\000\000\000\000\000\001\000\000@\002\000Q\002\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\004\000\000\000\000\000\000\b\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\001\000\000\000\001\000\000@\002\000Q\002\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000@\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\002\000\000\000\000\004\000\000\000\000\000@\000\000\000\000 \000\000\000\000@\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128*\128\b\"\018\028\004\017\000v\001\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\001\000\000\000\001\000\000@\002\000Q\002\000\000\000\000\000\000\000\bH\002\168\000\130!!\192A\016\007`\016 \004\132\000\000\128\000\002\002\028\004\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\198\000\001\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\132\000\000\128\000\002\002\028\012\000\000\002\001\000\000\b@\000\b\000\000 !\128@\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\024\004\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\000@\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\192\001\016\006`\000 \004\132\128\"\128\b \018\016\000\017\000f\000\002\000@\128\000\000\000\000\004\000`\000\000\000\000\000\000\000\b\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\001\000\000@\002\000Q\002\000\000\000\000\000\000\000\bH\002(\000\130\001!\192\001\016\006`\000 \004\132\128\"\128\b \018\016\000\017\000f\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000`\000\000\000\000\000\000\000\b\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\003\000\000p\018\000\213\194\000\001\000\000\000\000\000\bX\n\168\000\131\004!\192\001\016\007`\000`\004\003\000\000`\000\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\003\000\000p\018\000\213\194\000\001\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\001@\000\000\002\000\000\000\000\004\000\000\000\000\000@\016\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\003\000\000p\018\000\213\194\000\001\000\000\000\000\000\0000\000\006\000\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\0000\000\007\001 \r\\ \000\016\000\000\000\000\000\133\128\170\128\b0B\028\000\017\000v\000\002\000HX\n\168\000\131\004!\192\001\016\007`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002\168\000\130\000!\192\001\000\007`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \002\024\000\016\000f\000\002\000HH\002(\000\130\000!\000\001\000\006`\000 \004\b\000\000\000\000\000@\006\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\0000\000\007\001 \r\\ \000\016\000\000\000\000\000\132\128\"\128\b \002\024\000\016\000f\000\002\000HH\002(\000\130\000!\000\001\000\006`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\000!\000\001\000\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \002\024\000\016\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \002\016\000\016\000f\000\002\000@ \000\002H\000L\000@\b\000\000\000\000\000\128\002\000\000$\128\004\192\000\000\128\000\000\000\000\b\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\017\000v\001\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\017\000f\001\002\000HH\002(\000\130\001!\000\001\016\006`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \002\016\000\016\000f\000\002\000@ \000\002H\000L\000@\b\000\000\000\000\000\128\002\000\000$\128\004\192\000\000\128\000\000\000\000\b\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\0002\000\007\129\000\012\\(\000\016\b\002\000\001\000\003\000\002p\016\000\197\194\000\001\000\000\000\000\020\000\000\000\000\000\004\004\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bZ\002(\000\130\t!\160\001\016\014`\016 \004\132\128\"\128\012 \018\028\000\017\000f\001\006\016HH\002(\000\130\001!\192\001\016\006`\016!\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\016\006`\016!\004\001 \000\000\000\000\128\002\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\000!\128\001\000\006`\016 \004\132\128\"\128\b \002\016\000\016\000f\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\028\000\017\000v\001\002\000@\018\000\000\128\000\b\000(\000\000\b\002\000\001\000\001 \000\000\000\000\128\002\128\000\000\128 \000\016\000\000\000\000\000\004\004\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\012 \018\028\000\017\000f\001\006\016HH\002(\000\130\001!\192\001\016\006`\016!\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\004\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000@\000\000\000\000\000\000\000\b\128\000\000@\000@\006\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000`\000\000\000\000\000\000\000\b\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\0002\144\005\t\000L\018+\000\016\025\000\000P@\001\000\000@\002\000\209\002\000\000\004\000\000\000\000\b@\000\b\000\000(!@\192\000\000 \016\000\000\132\000\000\128\000\002\130\016\012\000\000\002\001\000\000\b@\000\b\000\000 !\000\192\000\000 \016\000\000\b\000\000\000\000@@\004\000\000\000\000\000\000\b\000\000\000\000\000\004\004\000@\000\000\000\000\000\000\000\000\000\000\000\000@@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000$\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\024\012\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000@@\000\000\000\000\000\000\000\000\000\000\000\000\000\004\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\132\000\000\128\000\002\002\028\012\000\000\002\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000$\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\b\000\000@\004\000\000\000\000\000\000\b\000\000\000\000\128\000\004\000@\000\000\000\000\000\000\000\000\000\000\b\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\0002\144\005\t\000L\018+\000\016\025\000\000P@\003\128\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\128\192\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\128\000\004\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\0002\144\005\t\000L\018+\000\016\025\000\000P@\003\128\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\016\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000#a\000E\130\141\241#\208\004\015\128\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018}\000@\248\000\000\024\224#a\000E\130\141\241#\208\004\015\128\000\001\142\b@\000\b\000\000 !\128\192\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\004\000 \r\016`\000\000@\000\000\000\128\001\000\000@\002\000\209\006\000\000\004\000\000\000\000\000\016\000\004\000 \r\016 \000\000@\000\000\000\000\001\000\000@\002\000\209\002\000\000\004\000\000\000\000\0002\016D\012\128L\018m\000\016\024\000\000\016@}\246D\b/\227P\000L\028\030\227\139\002\131@2\016D\b\000L\018m\000\016\024\000\000\016@\003!\004@\128\004\193\"\208\001\001\128\000\001\004\0002\016\004\b\000L\018-\000\016\024\000\000\016@\000\000\000\000\000\000\000\b\000\b\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\004\000\000\000\000\000\000\b\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\001\000\000\000\001\000\000@\002\000\209\002\000\000\004\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000@\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\144\005\t\000L\018k\000\016\024\000\000\016@\003)\000P\144\004\193\"\176\001\001\128\000\001\004\0002\144\005\t\001L\018+\000\016\024\000\000\016@\001\000\000@\002\000\209\002\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\004\001\000\000@\002\000\209\002\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\133\169*\212\024\162\211?\188\017\001\230\001\007\141HZ\146\173A\138-3\251\193\016\030`\016x\212\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002\168\000\130!!\192\193\016\006`\016`\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128*\128\b\"\018\028\012\017\000f\001\006\001@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002\168\000\130!!\192\193\016\006`\016`\020\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\001\000\000\000\001\000\000@\002\000\209\002\000\000\004\000\000\000\000\bH\002\168\000\130!!\192\193\016\006`\016`\020\003!\004@\128\004\193\"\208\001\001\128\000\001\004\0002\016\004\b\000L\018-\000\016\024\000\000\016@\000\000\000\000\000\000\000\b\000\b\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\000\004\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001 \r\\ \000\016\000\000\000\000\000\128\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\192\192\000\000 \016\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\024\012\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000@\002\000\209\002\000\000\004\000\000\000\000\b@\000\b\000\000 !\192\192\000\000 \016\000\016\132\000\000\128\000\002\002\024\012\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\198\000\001\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\132\000\000\128\000\002\002\024\012\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b@\000\b\000\000 !\128\192\000\000 \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\016\012\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\028\000\017\000f\000\002\000@0\000\007\001 \r\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\016\000\004\000 \r\016 \000\000@\000\000\000\000\132\128\"\128\b \018\028\000\017\000f\000\002\000@2\144\005\t\000L\018+\000\016\025\000\000P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\016\006`\000 \004\132\128\"\128\b \018\016\000\017\000f\000\002\000@\128\000\000\000\000\004\000`\000\000\000\000\000\000\000\b\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\0002\144\005\t\000L\018+\000\016\025\000\000P@\132\128\"\128\b \018\024\000\017\000f\000\002\000HH\002(\000\130\001!\000\001\016\006`\000 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\000\001\000\006`\000 \000\003!\004@\192\004\193&\208\001\001\128\000\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\000\001\016\006`\000 \004\132\128\"\128\b \018\024\000\017\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\016\000\017\000f\000\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\000\006`\000 \000\132\128\"\128\b \018\016\000\016\000f\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\000\001\144\006`\000 \004\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\016\000f\000\002\000\bH\002(\000\130\001!\000\001\000\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012H\002\168\000\131\t!\192\001\016\007`\002 \004\192\000\b\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000@\000\000\000\000\004\193\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\b\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\128\000\002\002\016\012\000\000\002\001\000\000\b\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\016 \004\004\000\b\016@\000\001\000\000\000\000\000\001\002\000@\000\000\129\004\000\000\016\000\000\000\000\000\016 \004\000\000\b\016\000\000\001\000\000\000\000\000\000\000\b\000\000\000\128\004\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000@@\000 \193\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\b\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\b\000\000\000\000\000\000\000\000\000\000$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\131!\000@\128\004\193\"\208\001\001\160\000\001\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\148\187\131\232>\022\028\015\249`w\139~p\240\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\128\000\b\000 \000\000\b\000\000\001\000\001 \000\000\000\000\128\002\000\000\000\128\000\000\016\000\018\000\000\000\000\b\000 \000\000\b\000\000\000\000\132\128\"\128\012 \018\028\000\017\000v\000\006\016\000\018\000\000\000\000\b\000 \000\000\b\000\000\000\000\132\128\"\128\b \018\028\000\017\000f\000\002\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\024\000\017\000f\000\002\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\012 \018\028\000\017\000v\000\006\016\000\018\000\000\000\000\b\000 \000\000\b\000\000\000\000\132\128\"\128\b \018\028\000\017\000f\000\002\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\bH\002( \130\001!\128\001\016\007`\016 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\128\001\016\006`\016 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\001 \000\b\000\000\128\002\000\000\000\128\000\000\016\000\018\000\000\000\000\b\000 \000\000\b\000\000\001\000\132\128\"\128\b \018\024\000\017\000f\000\002\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000 \000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\003\000\000`\000\000\197\198\000\001 \000 \000\000\0000\000\006\000\000\012\\ \000\018\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\016\000\000\000@\000\000\001 \000\000\000\000\0000\000\006\000\000\012\\ \000\018\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\004\000\000\001\000\000\000\000\000@\000\000\001\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\128\000\000\000\000@\000\000\000\000\004\000\000\000\000\b\000\000\000\000\004\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\000p\016\000\197\194\000\001\000\000\000\000\000\000\000\000\128\000\000\000\000@\000\000\000\000\004\000\000\000\000\000\000\000@@\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\128\"\128\b \018\028\000\017\000f\001\002\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\000\007\129\000\012\\(\000\016\b\002\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\000!\128\001\000\006`\016 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\001 \000\b\000\000\128\002\000\000\000\128\000\000\016\000\018\000\000\000\000\b\000 \000\000\b\000\000\001\000\132\128\"\128\b \002\024\000\016\000f\000\002\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\132\128\"\130\b \002\024\000\016\000v\001\018\000@2\000\007\129\000\012\\(\000\016\b\002\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\000!\128\001\000\006`\016 \004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\001 \000\b\000\000\128\002\000\000\000\128\000\000\016\000\018\000\000\000\000\b\000 \000\000\b\000\000\001\000\132\128\"\128\b \002\024\000\016\000f\000\002\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\128\000\001\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bH\002(\000\130\001!\192\001\016\006`\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\002\b\000\130\000!\000\001\000\006@\000 \000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\000\000\012\000 \000\000\b\000\000\000\000\128\000\136\007\224,$\000\003\226 \016@\024(\176\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000\192\000\000\000\000\000\000\000\000\b\000\b\000~\002\194@\000>\"\001\004\001\130\139\000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\000\000\000\b\000 \000\000\b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\007\001\000\012\\ \000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0026\016\004X(\223\018=\000@\248\000\000\024\224\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\000\000\000\000\000A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\016\004\b\000L\018-\000\016\026\000\000\016@\000\000\000\000\000\000\000\004\000\000\000\004\000H\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000\192\000\000\000\000\000\000\000\000\002~\018\012X\170\2233=\001P\254@\0008\224\001\000\000\000\000\000@\000\000\000\000\000\000\000\000\000Z\018\b\000\130\r!\001\001\016\014@\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\002\b\000\130\001!\000\001\016\006A\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128 \128\b \018\016\000\016\000`\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\b\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002~\018\012X\170\2233=\001P\254@\0008\224'\225 \197\138\173\2433\208\021\015\228\000\003\142\000H\002\b\000\130\001!\000\001\016\006@\000 \000\004\128 \128\b \018\016\000\017\000d\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\002\b\000\130\001!\128\001\016\006@\000 \000\004\128 \128\b \018\016\000\017\000d\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128 \128\b \018\024\000\017\000d\000\002\000\000H\002\b\000\130\001!\000\001\016\006@\000 \000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000") and start = 13 and action = - ((16, "C\170P\226Ff\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\021HFf\000\000\000\000\020XFfC\170\020\182\000-\000[\\(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\021\238\006\168\000\218\000\000\003\188\t|\000\000\001\208\003\232\nt\000\000\000\244\004\198\011l\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\220\000\000\000\000\000\000\0046T\016\000\000\000\000\000\000\005.\000\000\000\000\000\000\005\022\005\b\000\000\000\000T\016H\254\020X\021\178^\128\020X\\\142Mj\020XB\146\000\000B\146\000\000\027\158\004\246\000\000\005.\000\000\000\000\000\000\002J\000\000\027\158\000\000\006&v\246]\160d\194\000\000\132l\134\028\000\000LP_\014\000\000X\\\026\206K\200\005.p\026FfC\170\000\000\000\000Mj\020XF\138B\146\007\012v\246\000\000\128\178FfC\170P\226\020X\000\000\000\000\016x\025\186\001N\b\198\000\000\002\138\b\252\000\000\000\000\000\000\000\000\000\000\020X\000\000A\206i\164C\170\000\000\000\000P\206\020XZ\024W\200\000\000\004\002\000\000\000\000\005\242\000\000\000\000H\166\004\002\024\138\003\130\0020\000\000\000\000\003\172\000\000\021\178\006f\006\154\020X\028\254\020XC\170C\170\000\000P\212P\148\020X\028\254E\166\020X\000\000\000\000\000\000P\226\020X\000\000\000\248\000\000W\200y\188zJ\000\000\b\198\000\000\n\"\000\000\000\000C,T\016\134h\000\000h\142\134h\000\000h\142h\142\000b\006:\0008\000\000\020\190\000\000\006\220\000\000\000\000\t\014\000\000\000\000\000\000h\142\005.\000\000\000\000V\222T\016T\132_\014\000\000\000\000N*\000b\000\000\000\000_\014\007\026T\016\000\000O _\014P\022\000\000\000\000\000\000\n\198\000\000h\142\000\000\001\000\1310\000\000T\016\005\216T\016\000\000\022\\\b&\005.\000\000\000\000\023\224\000\000\006\208\000\000Y\128\011\190\000\000\007\128h\142\011\230\000\000\012\182\000\000\007\200\000\000\000\000\004\184\000\000\000\000\000\000\021 4W\200P\206\020XW\200\000\000\000b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000M:\027v\000\000\000\000\000\000\001\244&\174t<\000\000\000\000P\206\020XW\200\000\000\000\000{hW\200\136.zJ\000\000\136v\000\000W\200\000\000\000\000X\180\000\000\000\000\000\000\b\162\000\000\022\168\000\000\000\000z\214\000\000\136\208{\030\000\000\137\018\t\002\000\000\000\000z\214\000\000\004\024\000\000\000\000DHt\200\000\000\000\000\000\000Bn\023|\019\252\023\176\000\000\000\000\000\000\000\000\004\250\000\000\000\000Z\204\b\164\t`\000\017T\016\002\204\n\204\000\000\000\000\t\246\t`\007X\000\000i\186P\234P\148\020X\028\254\000-\000\018\0020\000\000\n>\021\178\021\178\000-\000\018\000\018\021\178\000\000jL\0050B\146\b\198\000\236\137`\000\000T\016ebT\016_ f\002T\016\000\144T\016f\156\000\000\000\000\020d\0008_\192\b\130\0008`\024\000\000j\230\0050\000\000\021\178k\128\000\000\007\196\t\190`\184\000\000\000\000\000\000\000\000\000\000\000\000\001B\000\000\000\000\003\144\000\000\007|\028\254\000\000\\\192E\166\000\000\031\138\000\000\000\000\021\178\002\152\000\000\000\000\000\000\000\000[\132\000\000\001\200\000\000UP\001\130\005\"\000\000\0226V\170P\226\020XG,P\226\020X\016x\016x\000\000\000\000\000\000\000\000\001\240\024&B\188\000\000Q\150RJP\212\020X\028\254\007h\021\178\000\000\004*\000\000R\254S\178{\182I\190T\016\002\128\000\000P\226\020X\000\000u\016\020Xy\188W\200E\186\000\000P\226\020Xw\\\004~\000\000W\200A\012T\016\003x\007X\012<\000\000\000\000\000\000H\166\003\138\003\138\000\000\012Bp\156\000\000P\206\020XW\200\025R\000\000P\226\020X\016x\0226\016x\002\232\023\240\000\000\000\000\016x\012\014\000\000\r\000\000\000\016x\003\224\rX\000\000'\166\000\000\b\196\000\000\000\000\026\022\000\000\017p\023.\000\000\000\000\000\000\000\000\005\226\000\000\000\000\027\014\000\000\028\006\000\000\028\254\000\000\018h\024&\000\000\000\000\000\000Ff\000\000\000\000\000\000\000\000\029\246\000\000\030\238\000\000\031\230\000\000 \222\000\000!\214\000\000\"\206\000\000#\198\000\000$\190\000\000%\182\000\000&\174\000\000'\166\000\000(\158\000\000)\150\000\000*\142\000\000+\134\000\000,~\000\000-v\000\000.n\000\000/f\000\0000^\020XW\200ZJI\146\003\138\014 l\012W\200\000\000\000\000\000\000h\142\000\000\028\018\134\028\000\000\026\"T\016\029\220\r\164\000\000\000\000\000\000\000\000l\012\000\000\000\000\005\242\014V\000\000I\128\000\000\000\000\135\176\000\000\007:\000\000\000\000K\200\003\138\r\202T\016\t\148\000\000\000\000\b\188\005.\000\000T\016\n@\000\000\000\000\r\252\000\000\000\000\000\000JjT\016\nP\000\000\000\000\030*\000\000\000\000{\254\000\000\031\"|\138\000\000 \026|\210\000\000!\018\t\250\000\000\000\000\000\000\000\000\"\nW\200#\002p\234p\234\000\000\000\000\000\0001V\000\000\007\204\000\000\000\000\000\000q\140\000\000\000\000\002\138\023\248\000\000\t*\000\000\000\000]bKl\000\000\000\000\t\188\000\000\000\000\000\000\n\128\000\000\000\000\000\000\016x\004\216\024\232\000\000\t`\000\000\005\208\000\0002N\000\000\n\180\000\000\006\200\000\0003F\000\000\014\204\007\192\000\0004>lt\000\000(\158\000\000\t\218\b\184\000\00056\000\000\011\150\t\176\000\0006.\000\000q\150\n\168\000\0007&\t\234\025\016\000\000\n\210\011\160\000\0008\030\000\000\011\216\012\152\000\0009\022\000\000\r\n\r\144\000\000:\014\014\136\000\000;\006\015\128\019`\000\000\000\000\000\000\011\026\000\000\000\000\012\186\000\000\000\000\015n\000\000\012*\000\000\000\000\000\000\014\222\000\000\015\004\000\000\000\000J~\003\138\015\192p\156_\014\000b\000\000\000\000p\156\000\000\000\000\000\000p\156\000\000\015\156\000\000\000\000\000\000\000\000\000\000\000\000;\254W\200\000\000\000\000\015\232\000\000<\246\000\000=\238\000\000#\250\000\000\000\000\n\184\000\000\000\000W\200\000\000\000\000}j\011\202\000\000\000\000G,\000\000\011\238\000\000\000\000V\020\000\000\rh\000\000\000\000\001\130\011\254\000\000\000\000\0226\022\028\b\198\000\000A\214\000\000!,\025\160\021\220\000\000\000\000\r\150\000\000\000\000\001\238\025\030V\180\000\000\025\030\000\000\012\246\000\000\000\000\r\172\000\000\000\000g>\b\n\004H\000\000\000\000\r@\000\000\000\000\r\200\000\000\000\000\000\000\020X\028\254\005\168\000\000\000\000\023Z\003\130\0020\003\136\028\254w\228\021\178\001B\028\254xb\015\144\000\000\000\000\003\136\000\000H\232\019\248\021\204\000\000\t\144\016\002\000\000\016\000\000V_\014\006\196\000\000\015\232\015vK\200\r(T\016\030\128\0204\014\n\004\248\000\000\031x\016N\000\000\006\196\000\000\000\000\016^_\014aX\000\000g\144_\014\016*_\014m\012a\248\001N\015\236\000\000\000\000\000\000\020X\128\252\000\000W\200p\234\000\000\000\000\016b\000\000\000\000\000\000>\230\016\146y\188?\222h<\000\000\000\000HJ\000\000\005\128\000\000L\136\000\000\022\222\000\000\021\178\006\026\000\000\128\178\000\000\020X\028\254\128\178\000\000\025D\025\186\001N\005.\130\144\021\178}\248p\234\000\000\005r\b\176\0020\003\136p\234\132\224\003\130\0020\003\136p\234\132\224\000\000\000\000\003\136p\234\000\000FfC\170W\200\027B\000\000\000\000FfC\170P\148\020X\028\254\128\178\000\000\020\182\000-\000[\015\200T\016\012\142\016\146\131P\000\000p\234\000\000H\232\019\248\021\204x\186\023\228\t\236~,\b\130\015\234\020Xp\234\000\000\020Xp\234\000\000h\142ff\019\134\002\222\001N\0008N\234\000\000\001N\0008N\234\000\000\025D\005r\t\168\0212\012\180\000\000N\234\000\000\0020\015\234\021\178p\234\134\222\003\130\0020\015\236\021\178p\234\134\222\000\000\000\000\b`\000\000O\224\000\000\021\178\131\132N\234\000\000\b`\000\000H\254\020X\021\178p\234\000\000H\232\019\248\021\204rFC\186\026\222\019\170\002\142\000\000\r\216\027\158\000\017\000\000\016h\016 \024\196\020XT\184T\016\0118\000\000W\150\001N\005\204\011\246\000\000\011\228\000\000\016~\016\014T\016O(\000\000\0032\004\212\r\200\000\000\r6\000\000\016\136\016 K\200\r\206T\016K\182O(\000\000UP\020X\024\196\016\202\n$\001N\000\000\r\200\024\196T\016\012~\000b\000\000T\016\007\152\t,\000\000\000\000mf\000\000\000\000\r\228\024\196m\228O(\000\000\020XT\016\r(T\016V\\O(\000\000\014<\000\000\000\000O(\000\000\000\000W\150\000\000p\234\132\238\019\170\002\142\r\216\016\182\016h\024\196p\234\132\238\000\000\000\000\019\170\002\142\r\216\016\190\016HM\252LZ_\014\016\206M\252h\142\020\184\016\218M\252_\014\016\230M\252n\132o\004\000\000\129\140\000\000\000\000p\234\134\236\019\170\002\142\r\216\016\224\016nM\252p\234\134\236\000\000\000\000\000\000ff\000\000\000\000\000\000\000\000\000\000\000\000N\234\000\000\133\128\020\026A\228\017\002v\246\000\000\128\178\133\128\000\000\000\000\1358\020\026A\228\017\004\016\158]\160\135\176\006\196\017H\000\000\000\000o\130rF\020X\000\000~\200\021\204\000\000\000\000\128\178\1358\000\000\000\000\000\000y6DlD\228\006\196\017J\000\000\000\000\000\000rF\020X\000\000\006\196\017N\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\014`C\186\019\170\002\142\r\216\017 r\182\023\204\020XZ\024j\190\020(\001N\006\196\017*\nt\000\000\000\000\016\220\000\000\000\000a\152\000\000\b\022\014\132\000\000\r\212\000\000\0178\016\202T\016d\240\017F\n\158\000\000\000\000\017\004\000\000\000\000\020F\0032\014\210\000\000\017Zs8\137\172\003\138\016\248T\016\014r\000\000\000\000\017\012\000\000\000\000\000\000a\152\000\000\0070\014\234\000\000\014\204\000\000\017l\016\250K\200\000\000\017vs\186\137\248\003\138\017\026T\016\015\024\000\000\000\000\017,\000\000\000\000\000\000\020X\000\000a\152\000\000\020z\020X\023\204\023\204u\168Ff\020X\128\252W\200\021\162\000\000\012\020\001N\000\000\014\012\023\204T\016\014n\b\198\000\000\020XW\200r\182\023\204\014\154\023\204\000\000D\142Et\000\000bR\000\000\000\000b\238\000\000\000\000c\138\000\000\014\192\023\204d&\128\252W\200\021\162\000\000\000\"\000\000\000\000M\252\r\026\000\000\000\000d.\017\144\000\000a\152\000\000\023\204d.a\152\000\000\020XT\016a\152\000\000\015\136\000\000\000\000a\152\000\000\000\000j\190\000\000\129\192M\252\017T\023\204\130\\r\182\000\000p\234\133\142\019\170\002\142\r\216\017\174r\182p\234\133\142\000\000\000\000\000\000\135\248P\206\000\000\000\000\000\000\000\000\000\000\000\000\132\022p\234\000\000\133\128\000\000\000\000\000\000\000\000p\234\135\248\000\000\017\234\000\000\000\000\132\022\017\236\000\000p\234\135\248\000\000\000\000\015\222\000\000\000\000i4\0032\000\000\000\000DH\000\000T\016\015\242\000\000j\190\015\240\000\000\000\000\000\000\014\192\000\000\000\000\000\000P\212\020X\028\254\006\178\000\000Mt\000\000\007p\000\000\000*\000\000\000\000\017\242\000\000\018\026y\188\000\000@\214\017\252\000\000\000\000\017\248\026R\028B\021\204v0\023\228\020X\000\000\128\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000v8\023\228\020X\000\000\015\"v\246\000\000\128\178\000\000\017\254\026R\028B\128\178\000\000\018\020\000\000\000\238\t\214\020X`\226\000\000\000\000\028\190y\242\000\000\000\000\017\184\000\000\018\bT\016\000\000\r\234\011\174\000b\000\000\000\000T\016\004R\006B\000\000T\016\012\018\006\196\018>\000\000\000\000\127\"\000\000\000\000]\160\000\000\128\178\000\000\0182\026R\029:N\234\000\000\000\000\000\000\000\000\015h\127\188]\160\000\000\128\178\000\000\0184\026R\029:N\234\000\000\016 \000\000\000\000\b\n\000\000p\234\000\000\018H\000\000\000\000\017\174\000\000\017\188\000\000\017\208\000\000\000\000\\\142\017\216\000\000\000\000%\182\\(\018t\000\000\000\000\000\000\014\242\011D]\232\018x\000\000\000\000\000\000\000\000\000\000\000\000\017\248\000\000\023\228\000\000\017\250\000\000T\016\000\000\014\250\000\000\000\000\017\252\000\000\000\000\0008\000\000\003\210\000\000\000\000\000\000\001\214\000\000\015\196\000\000\018\000\000\000W\200\022\168\000\000\000\000\012<\018\012\000\000\000\000\018\006\r$G,\005.\128:\000\000\000\000\000\000\000\000\000\000YL\000\000\000\000\018\172\000\000\138<\000\000\015\192\018\180\000\000\018\182\000\000G\224G\224[\190[\190\000\000\000\000p\234[\190\000\000\000\000\000\000p\234[\190\0180\000\000\018H\000\000"), (16, "\t)\t)\000\006\001\002\001\190\t)\002\158\002\162\t)\002\206\002f\t)\003\145\t)\018\130\002\218\t)\023\130\t)\t)\t)\025*\t)\t)\t)\001\210\004A\004A\004*\002\222\t)\003\"\003&\t\214\t)\001\206\t)\023\134\003*\000\238\002\226\025.\t)\t)\003\186\003\190\t)\003\194\003\022\003\206\003\214\006\186\006\246\t)\t)\002\150\001\206\006\214\003\030\t)\t)\t)\007\254\b\002\b\014\b\"\001*\005Z\t)\t)\t)\t)\t)\t)\t)\t)\t)\b\150\000\238\t)\015~\t)\t)\003\145\b\162\b\186\t\014\005f\005j\t)\t)\t)\r\162\t)\t)\t)\t)\002N\002~\r\210\t)\006\150\t)\t)\0035\t)\t)\t)\t)\t)\t)\005n\b\022\t)\t)\t)\b.\004V\t\"\0035\t)\t)\t)\t)\012\217\012\217\023\138\n\178\004~\012\217\n\190\012\217\012\217\000\238\012\217\012\217\012\217\012\217\004A\012\217\012\217\001f\012\217\012\217\012\217\003i\012\217\012\217\012\217\012\217\004A\012\217\015\222\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\007\162\007\002\0076\012\217\004\198\012\217\012\217\012\217\012\217\012\217\004A\012\217\012\217\004A\012\217\003\210\012\217\012\217\012\217\000\238\007\166\012\217\012\217\012\217\012\217\012\217\012\217\012\217\000\238\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\004A\012\217\012\217\007n\012\217\012\217\001j\004A\007\018\004A\012\217\012\217\012\217\012\217\012\217\004A\012\217\012\217\012\217\012\217\012\217\000\238\012\217\012\217\007\026\012\217\012\217\000\238\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\012\217\b\006\004A\012\217\012\217\012\217\012\217\001\181\001\181\001\181\001f\015>\001\181\003i\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\014\234\001\181\007\194\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\003j\003n\001\181\000\238\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\006\218\001\181\001\181\001\181\007\250\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\002J\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\027\159\001\181\001\181\018r\007\222\007\002\007R\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\014\174\bF\001\181\005\158\001\181\001\181\007\226\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\182\001\181\001\181\001\181\001\181\001\181\n]\n]\002\225\007n\012\253\n]\003\149\n]\n]\000\238\n]\n]\n]\n]\001\186\n]\n]\012\253\n]\n]\n]\000\238\n]\n]\n]\n]\002N\n]\000\n\n]\n]\n]\n]\n]\n]\n]\n]\024\194\007\002\b\146\n]\004A\n]\n]\n]\n]\n]\000\238\n]\n]\012\006\n]\002\246\n]\n]\n]\002\225\024\198\n]\n]\n]\n]\n]\n]\n]\004A\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\003\149\n]\n]\007n\n]\n]\004A\004A\007\002\004A\n]\n]\n]\n]\n]\004\001\n]\n]\n]\n]\t:\000\238\tj\n]\005\241\n]\n]\007\174\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\003v\n]\n]\n]\n]\n]\003\173\003\173\001r\007n\006\214\003\173\b\250\003\173\003\173\000\238\003\173\003\173\003\173\003\173\000\238\003\173\003\173\006\137\003\173\003\173\003\173\000\238\003\173\003\173\003\173\003\173\001\130\003\173\006>\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\006\137\007\002\004\001\003\173\004&\003\173\003\173\003\173\003\173\003\173\015.\003\173\003\173\006B\003\173\t\005\003\173\003\173\003\173\005\241\bv\003\173\003\173\003\173\003\173\003\173\003\173\003\173\0156\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\b\213\t2\tb\007n\003\173\003\173\003z\003B\b\202\027\143\003\173\003\173\003\173\003\173\003\173\0046\003\173\003\173\003\173\003\173\t:\000\238\tj\003\173\b\006\003\173\003\173\003F\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\000\238\003\173\003\173\003\173\003\173\003\173\003\161\003\161\018\222\b\206\b\234\003\161\0056\003\161\003\161\t\005\003\161\003\161\003\161\003\161\001\146\003\161\003\161\006~\003\161\003\161\003\161\0022\003\161\003\161\003\161\003\161\018\230\003\161\001\198\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\006\237\b\213\004A\003\161\0026\003\161\003\161\003\161\003\161\003\161\b\029\003\161\003\161\001\218\003\161\007\006\003\161\003\161\003\161\006\237\004A\003\161\003\161\003\161\003\161\003\161\003\161\003\161\004A\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\000\238\t2\tb\001\234\003\161\003\161\004A\004A\007\002\007B\003\161\003\161\003\161\003\161\003\161\001\222\003\161\003\161\003\161\003\161\t:\004A\tj\003\161\004V\003\161\003\161\016Z\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\006\237\003\161\003\161\003\161\003\161\003\161\t\217\t\217\018\178\007n\b\n\t\217\006\130\t\217\t\217\001\238\t\217\t\217\t\217\t\217\000\238\t\217\t\217\006\149\t\217\t\217\t\217\000\238\t\217\t\217\t\217\t\217\004A\t\217\007\194\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\006\149\007\002\018\186\t\217\000\238\t\217\t\217\t\217\t\217\t\217\005\217\t\217\t\217\001\206\t\217\012f\t\217\t\217\t\217\015\022\016v\t\217\t\217\t\217\t\217\t\217\t\217\t\217\000\238\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\0262\t\217\t\217\007n\t\217\t\217\003\130\003N\t\162\004A\t\217\t\217\t\217\t\217\t\217\002Z\t\217\t\217\t\217\t\217\t\217\000\238\t\217\t\217\004&\t\217\t\217\003R\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\000\238\004A\t\217\t\217\t\217\t\217\t\209\t\209\004\214\001f\003i\t\209\n\134\t\209\t\209\025\018\t\209\t\209\t\209\t\209\003\134\t\209\t\209\004:\t\209\t\209\t\209\003\137\t\209\t\209\t\209\t\209\b\241\t\209\004B\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\007\194\0266\015\134\t\209\001\206\t\209\t\209\t\209\t\209\t\209\005\209\t\209\t\209\000\238\t\209\012~\t\209\t\209\t\209\022f\011\022\t\209\t\209\t\209\t\209\t\209\t\209\t\209\000\238\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\011\026\t\209\t\209\022n\t\209\t\209\002\186\004\146\007\002\b\241\t\209\t\209\t\209\t\209\t\209\007\005\t\209\t\209\t\209\t\209\t\209\025\022\t\209\t\209\b\021\t\209\t\209\025\"\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\000\238\b\241\t\209\t\209\t\209\t\209\t\225\t\225\b\193\007n\007\194\t\225\011\234\t\225\t\225\007\182\t\225\t\225\t\225\t\225\006\214\t\225\t\225\000\238\t\225\t\225\t\225\000\238\t\225\t\225\t\225\t\225\005*\t\225\011\238\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\001\007\002\006\182\t\225\000\238\t\225\t\225\t\225\t\225\t\225\021\218\t\225\t\225\004&\t\225\012\146\t\225\t\225\t\225\014\226\026\198\t\225\t\225\t\225\t\225\t\225\t\225\t\225\bj\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\004\230\t\225\t\225\007n\t\225\t\225\005\018\021\226\b\193\005.\t\225\t\225\t\225\t\225\t\225\005\209\t\225\t\225\t\225\t\225\t\225\000\238\t\225\t\225\007~\t\225\t\225\002\250\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\001\004\186\t\225\t\225\t\225\t\225\t\193\t\193\003j\003n\006\214\t\193\tv\t\193\t\193\005\254\t\193\t\193\t\193\t\193\002\162\t\193\t\193\016\190\t\193\t\193\t\193\017v\t\193\t\193\t\193\t\193\tz\t\193\011>\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\006*\006\142\006\166\t\193\002\250\t\193\t\193\t\193\t\193\t\193\018\026\t\193\t\193\004:\t\193\012\178\t\193\t\193\t\193\002\238\012\018\t\193\t\193\t\193\t\193\t\193\t\193\t\193\018&\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\012\022\t\193\t\193\b\189\t\193\t\193\002\254\012^\001\002\001\190\t\193\t\193\t\193\t\193\t\193\004F\t\193\t\193\t\193\t\193\t\193\006U\t\193\t\193\011F\t\193\t\193\012b\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\006U\000\238\t\193\t\193\t\193\t\193\t\201\t\201\003j\017\206\002r\t\201\012.\t\201\t\201\006\146\t\201\t\201\t\201\t\201\007\130\t\201\t\201\017\226\t\201\t\201\t\201\tv\t\201\t\201\t\201\t\201\001v\t\201\0122\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\011\174\025\222\b\189\t\201\012\174\t\201\t\201\t\201\t\201\t\201\000\238\t\201\t\201\002r\t\201\012\198\t\201\t\201\t\201\001\222\003\242\t\201\t\201\t\201\t\201\t\201\t\201\t\201\004A\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\0112\t\201\t\201\003\246\t\201\t\201\006\174\016*\001\002\001\190\t\201\t\201\t\201\t\201\t\201\015n\t\201\t\201\t\201\t\201\t\201\006]\t\201\t\201\004\213\t\201\t\201\012>\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\006]\000\238\t\201\t\201\t\201\t\201\n\001\n\001\012\230\012B\002\246\n\001\012v\n\001\n\001\000\238\n\001\n\001\n\001\n\001\n\246\n\001\n\001\000\238\n\001\n\001\n\001\012\018\n\001\n\001\n\001\n\001\001\134\n\001\012z\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\004\182\006\162\011N\n\001\012\242\n\001\n\001\n\001\n\001\n\001\011r\n\001\n\001\019\"\n\001\012\218\n\001\n\001\n\001\006\226\012^\n\001\n\001\n\001\n\001\n\001\n\001\n\001\021\186\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\rJ\n\001\n\001\n\178\n\001\n\001\n\190\014\022\007\130\022\002\n\001\n\001\n\001\n\001\n\001\018\162\n\001\n\001\n\001\n\001\n\001\006e\n\001\n\001\n\178\n\001\n\001\n\190\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\006e\011\234\n\001\n\001\n\001\n\001\t\241\t\241\027*\001\222\014\030\t\241\004\186\t\241\t\241\000\238\t\241\t\241\t\241\t\241\001\206\t\241\t\241\012\194\t\241\t\241\t\241\0142\t\241\t\241\t\241\t\241\001\150\t\241\012.\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\005\n\018\190\014F\t\241\0146\t\241\t\241\t\241\t\241\t\241\014j\t\241\t\241\r\006\t\241\012\246\t\241\t\241\t\241\002~\005\026\t\241\t\241\t\241\t\241\t\241\t\241\t\241\004A\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\b\217\t\241\t\241\rj\t\241\t\241\005\221\018\182\002\162\026\026\t\241\t\241\t\241\t\241\t\241\005\225\t\241\t\241\t\241\t\241\t\241\b\230\t\241\t\241\t\006\t\241\t\241\tN\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\000\238\000\238\t\241\t\241\t\241\t\241\t\233\t\233\001\002\001\190\014n\t\233\b\237\t\233\t\233\019:\t\233\t\233\t\233\t\233\017\214\t\233\t\233\012v\t\233\t\233\t\233\001\206\t\233\t\233\t\233\t\233\004\186\t\233\014J\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\005\"\b\217\rV\t\233\rn\t\233\t\233\t\233\t\233\t\233\014\198\t\233\t\233\022\250\t\233\r\n\t\233\t\233\t\233\000\238\012>\t\233\t\233\t\233\t\233\t\233\t\233\t\233\023\146\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\002\250\t\233\t\233\r\026\t\233\t\233\018\234\014\242\023\150\017B\t\233\t\233\t\233\t\233\t\233\019B\t\233\t\233\t\233\t\233\t\233\011>\t\233\t\233\tV\t\233\t\233\014Z\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\001\002\001\190\t\233\t\233\t\233\t\233\t\249\t\249\014^\014\162\b!\t\249\004\186\t\249\t\249\000\238\t\249\t\249\t\249\t\249\014\210\t\249\t\249\014\202\t\249\t\249\t\249\tf\t\249\t\249\t\249\t\249\014\166\t\249\014\254\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\014\214\021\230\019\130\t\249\014\246\t\249\t\249\t\249\t\249\t\249\015\154\t\249\t\249\015\002\t\249\r\030\t\249\t\249\t\249\018\226\011>\t\249\t\249\t\249\t\249\t\249\t\249\t\249\026\022\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\b%\t\249\t\249\015\170\t\249\t\249\005\213\003}\002\253\019\150\t\249\t\249\t\249\t\249\t\249\n\158\t\249\t\249\t\249\t\249\t\249\018z\t\249\t\249\n\214\t\249\t\249\019.\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\019f\n\250\t\249\t\249\t\249\t\249\nI\nI\007\241\007R\011*\nI\018\254\nI\nI\023\018\nI\nI\nI\nI\023\006\nI\nI\007R\nI\nI\nI\011Z\nI\nI\nI\nI\026&\nI\024\246\nI\nI\nI\nI\nI\nI\nI\nI\007R\022r\021\222\nI\000\238\nI\nI\nI\nI\nI\r\005\nI\nI\000\238\nI\r*\nI\nI\nI\019\154\012\142\nI\nI\nI\nI\nI\nI\nI\022\"\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\022j\nI\nI\022B\nI\nI\b\025\001\206\023.\b\021\nI\nI\nI\nI\nI\019B\nI\nI\nI\nI\nI\r\017\nI\nI\004&\nI\nI\023f\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\000\238\001\206\nI\nI\nI\nI\003\157\003\157\025\170\007R\023\210\003\157\n\134\003\157\003\157\000\238\003\157\003\157\003\157\003\157\rb\003\157\003\157\024\250\003\157\003\157\003\157\rz\003\157\003\157\003\157\003\157\027o\003\157\027&\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\026\142\r\130\022\162\003\157\002\006\003\157\003\157\003\157\003\157\003\157\024\178\003\157\003\157\004Y\003\157\r\150\003\157\003\157\003\157\024\230\r\198\003\157\003\157\003\157\003\157\003\157\003\157\003\157\r\242\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\024\218\t2\tb\026\186\003\157\003\157\001\222\015J\015r\003\226\003\157\003\157\003\157\003\157\003\157\002\198\003\157\003\157\003\157\003\157\t:\023\214\tj\003\157\015\142\003\157\003\157\015\146\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\000\238\003\157\003\157\003\157\003\157\003\157\001\237\001\237\015\186\015\206\015\230\001\237\015\250\002\162\001\237\016&\002f\001\237\tJ\001\237\016:\002\218\001\237\024\182\001\237\001\237\001\237\017:\001\237\001\237\001\237\001\210\024\234\tR\017F\002\222\001\237\001\237\001\237\001\237\001\237\tZ\001\237\005\250\017\234\018\002\002\226\018\138\001\237\001\237\001\237\001\237\001\237\018\142\003\022\001\190\026\190\001\237\018\198\001\237\001\237\002\150\018\202\018\242\003\030\001\237\001\237\001\237\007\254\b\002\b\014\018\246\012J\005Z\001\237\001\237\001\237\001\237\001\237\001\237\001\237\001\237\001\237\019\030\t2\tb\019\202\001\237\001\237\019\206\019\242\019\246\020\006\005f\005j\001\237\001\237\001\237\020\022\001\237\001\237\001\237\001\237\012R\020\"\012\162\001\237\020V\001\237\001\237\020Z\001\237\001\237\001\237\001\237\001\237\001\237\005n\b\022\001\237\001\237\001\237\b.\004V\020\166\020\206\001\237\001\237\001\237\001\237\n1\n1\020\210\020\226\0212\n1\021R\002\162\n1\021\146\002f\n1\n1\n1\021\182\002\218\n1\021\198\n1\n1\n1\021\238\n1\n1\n1\001\210\021\242\n1\021\254\002\222\n1\n1\n1\n1\n1\n1\n1\022\014\022*\022:\002\226\022N\n1\n1\n1\n1\n1\022z\003\022\001\190\022~\n1\022\138\n1\n1\002\150\022\154\022\174\003\030\n1\n1\n1\007\254\b\002\b\014\023\162\n1\005Z\n1\n1\n1\n1\n1\n1\n1\n1\n1\023\250\n1\n1\024\"\n1\n1\024\138\024\154\0256\025>\005f\005j\n1\n1\n1\025N\n1\n1\n1\n1\n1\025Z\n1\n1\025\190\n1\n1\025\210\n1\n1\n1\n1\n1\n1\005n\b\022\n1\n1\n1\b.\004V\026\002\026\n\n1\n1\n1\n1\n-\n-\026F\026n\026\166\n-\026\214\002\162\n-\026\226\002f\n-\n-\n-\026\234\002\218\n-\026\243\n-\n-\n-\027\003\n-\n-\n-\001\210\027\022\n-\0272\002\222\n-\n-\n-\n-\n-\n-\n-\027O\027_\027{\002\226\027\175\n-\n-\n-\n-\n-\027\203\003\022\001\190\027\214\n-\028\011\n-\n-\002\150\028\031\028'\003\030\n-\n-\n-\007\254\b\002\b\014\028c\n-\005Z\n-\n-\n-\n-\n-\n-\n-\n-\n-\028k\n-\n-\000\000\n-\n-\000\000\000\000\000\000\000\000\005f\005j\n-\n-\n-\000\000\n-\n-\n-\n-\n-\000\000\n-\n-\000\000\n-\n-\000\000\n-\n-\n-\n-\n-\n-\005n\b\022\n-\n-\n-\b.\004V\000\000\000\000\n-\n-\n-\n-\0029\0029\000\000\000\000\000\000\0029\000\000\002\162\0029\000\000\002f\0029\tJ\0029\000\000\002\218\0029\000\000\0029\0029\0029\000\000\0029\0029\0029\001\210\002\225\tR\000\000\002\222\0029\0029\0029\0029\0029\tZ\0029\000\000\000\000\000\000\002\226\004A\0029\0029\0029\0029\0029\000\000\003\022\001\190\000\000\0029\000\n\0029\0029\002\150\000\000\000\000\003\030\0029\0029\0029\007\254\b\002\b\014\000\000\012J\005Z\0029\0029\0029\0029\0029\0029\0029\0029\0029\000\000\004\173\0029\002\225\0029\0029\004A\006f\002\162\004A\005f\005j\0029\0029\0029\000\000\0029\0029\0029\0029\000\000\000\238\004A\0029\004\173\0029\0029\004A\0029\0029\0029\0029\0029\0029\005n\b\022\0029\0029\0029\b.\004V\000\000\004A\0029\0029\0029\0029\004A\004A\004A\002\238\004A\004A\004A\004A\004A\004A\004A\017\158\004A\000\238\004A\004A\000\000\004A\004A\004A\000\000\004A\004A\004A\004A\004A\004A\004A\004A\004A\000\238\004A\004A\000\000\000\000\004A\004A\000\238\004A\004A\004A\004A\004A\000\238\004A\004A\004A\004A\004A\004A\004A\004A\000\238\004A\004A\004A\004A\004A\004A\004A\004A\000\238\004A\004A\004A\004A\004A\004A\004A\004A\b\189\0042\004A\000\000\000\000\004A\004A\004A\000\238\004A\000\n\000\000\004A\004A\004A\004A\004A\004A\004A\004A\004A\000\000\021\170\004A\004A\002\225\002\225\007J\004A\004&\006\233\000\000\004A\004A\000\000\007R\000\000\022\026\002\225\000\238\004A\004A\004A\007V\000\000\004A\004A\004A\004A\006\233\000\161\004A\000\161\006\233\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\000\000\161\022\206\000\161\000\161\000\000\000\161\000\161\000\000\000\000\000\161\000\161\000\000\000\161\000\161\000\161\000\161\000\000\000\161\0046\000\161\000\161\b\189\000\000\000\161\000\161\005\141\000\161\000\161\000\161\000\238\000\161\b\241\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\000\bn\000\161\000\161\000\000\000\000\000\161\000\161\002\006\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\161\002\n\006\233\000\000\015f\t\029\000\161\002f\000\161\001\210\000\161\005\141\002\162\000\000\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\000\000\000\000\000\000\161\003~\017\210\t\029\005\141\000\222\000\000\006\230\001\222\000\161\000\000\002\198\000\000\014z\002\150\000\161\000\161\000\161\000\161\000\000\015j\000\161\000\161\000\161\000\161\002)\002)\004Y\000\000\002\238\002)\000\000\002\162\002)\015v\002f\002)\001b\002)\000\000\002\218\002)\006\234\002)\002)\002)\000\000\002)\002)\002)\001\210\001z\000\000\001\138\002\222\002)\002)\002)\002)\002)\005j\002)\000\000\000\000\000\000\002\226\b\169\002)\002)\002)\002)\002)\004Y\003\022\b\018\000\000\002)\000\000\002)\002)\002\150\000\000\006\006\003\030\002)\002)\002)\007\254\b\002\b\014\t2\tb\005Z\002)\002)\002)\002)\002)\002)\002)\002)\002)\006\n\t2\tb\b\169\002)\002)\000\000\t:\007\002\tj\005f\005j\002)\002)\002)\000\000\002)\002)\002)\002)\t:\000\000\tj\002)\b\169\002)\002)\016j\002)\002)\002)\002)\002)\002)\005n\b\022\002)\002)\002)\b.\004V\000\238\000\000\002)\002)\002)\002)\002E\002E\000\000\007n\000\000\002E\000\000\000\000\002E\000\000\b\169\002E\000\000\002E\004\226\000\000\002E\b\169\002E\002E\002E\000\238\002E\002E\002E\000\000\027\187\000\000\002\225\002\225\002E\002E\002E\002E\002E\000\000\002E\000\000\006\014\004\169\000\000\005\206\002E\002E\002E\002E\002E\000\000\006\026\000\000\000\000\002E\006&\002E\002E\000\n\000\000\000\000\006b\002E\002E\002E\004\169\000\000\000\000\006\213\016n\000\000\002E\002E\002E\002E\002E\002E\002E\002E\002E\000\000\t2\tb\000\000\002E\002E\002\225\006j\000\000\002\162\000\000\006\213\002E\002E\002E\000\000\002E\002E\002E\002E\t:\002\162\tj\002E\002f\002E\002E\001\210\002E\002E\002E\002E\002E\002E\b\165\000\000\002E\002E\002E\000\000\021\154\000\000\000\000\002E\002E\002E\002E\002A\002A\000\000\022\214\002\238\002A\022\218\002\250\002A\000\000\002\150\002A\000\000\002A\000\000\017j\002A\023\n\002A\002A\002A\t>\002A\002A\002A\012\n\b\165\000\000\000\000\015v\002A\002A\002A\002A\002A\rN\002A\rZ\000\000\012&\023\026\0126\002A\002A\002A\002A\002A\b\165\bJ\001\190\001*\002A\000\000\002A\002A\005j\002\225\002\225\014:\002A\002A\002A\014N\014b\014r\000\000\000\000\000\000\002A\002A\002A\002A\002A\002A\002A\002A\002A\000\000\t2\tb\b\165\002A\002A\000\n\004\226\000\000\001\206\b\165\000\000\002A\002A\002A\000\000\002A\002A\002A\002A\t:\000\000\tj\002A\000\000\002A\002A\001\210\002A\002A\002A\002A\002A\002A\002\225\000\000\002A\002A\002A\000\000\018\146\000\000\000\000\002A\002A\002A\002A\002-\002-\000\000\000\000\002~\002-\019\026\002\250\002-\000\000\002\150\002-\000\000\002-\000\000\000\000\002-\0192\002-\002-\002-\012V\002-\002-\002-\002\225\002\225\016\150\000\000\000\000\002-\002-\002-\002-\002-\012n\002-\012\134\000\000\000\000\002\225\012\234\002-\002-\002-\002-\002-\000\000\bJ\014\178\000\000\002-\000\n\002-\002-\012\254\000\000\r\018\014:\002-\002-\002-\014N\014b\014r\t\025\000\000\000\000\002-\002-\002-\002-\002-\002-\002-\002-\002-\000\000\t2\tb\002\225\002-\002-\000\000\014\146\002\225\000\000\000\238\t\025\002-\002-\002-\000\000\002-\002-\002-\002-\t:\000\000\tj\002-\000\000\002-\002-\000\000\002-\002-\002-\002-\002-\002-\000\n\000\000\002-\002-\002-\000\000\t\030\000\000\000\000\002-\002-\002-\002-\002=\002=\000\000\002\225\000\000\002=\012}\006\014\002=\000\000\005\206\002=\000\000\002=\000\000\002\225\002=\006\026\002=\002=\002=\006&\002=\002=\002=\012}\012}\000\000\000\000\012}\002=\002=\002=\002=\002=\000\000\002=\b\021\000\000\000\000\b\021\000\000\002=\002=\002=\002=\002=\000\000\000\000\000\000\000\000\002=\000\000\002=\002=\000\000\000\000\000\000\022\"\002=\002=\002=\000\000\000\000\000\000\000\000\000\000\000\238\002=\002=\002=\002=\002=\002=\002=\002=\002=\000\000\b\021\002=\000\000\002=\002=\000\000\000\000\000\000\000\000\000\000\000\000\002=\002=\002=\b\021\002=\002=\002=\002=\012}\000\000\004\253\002=\000\000\002=\002=\002\225\t\130\002=\002=\002=\002=\002=\004\253\n\202\002=\002=\002=\000\000\000\000\b\021\000\000\002=\002=\002=\002=\t%\t%\000\000\000\000\000\000\t%\000\000\000\000\t%\000\n\000\000\t%\000\000\t%\000\000\000\000\t\174\004\253\t%\t\210\t%\b\021\t%\t%\t%\002\225\000\000\000\000\000\000\017\006\t\230\t\254\n\006\t\238\n\014\000\000\t%\002\225\002\225\000\000\000\000\000\000\t%\t%\n\022\n\030\t%\004\253\007\245\000\000\004\253\t%\000\000\n&\t%\000\000\000\000\000\000\000\000\t%\t%\000\238\000\000\000\000\000\000\000\000\000\000\002\218\t%\t%\t\182\t\246\n.\n6\nF\t%\t%\002\138\012\181\t%\000\000\t%\nN\000\000\003>\000\000\000\000\000\238\000\000\t%\t%\nV\000\000\t%\t%\t%\t%\003J\012\181\000\000\t%\000\000\t%\t%\002\030\nv\t%\n~\n>\t%\t%\000\000\000\000\t%\n^\t%\000\000\002&\000\000\005Z\t%\t%\nf\nn\002q\002q\000\000\000\000\000\000\002q\012\133\006\014\002q\000\000\005\206\002q\000\000\002q\000\000\005f\002q\006\026\002q\002q\002q\006&\002q\002q\002q\012\133\012\133\000\000\000\000\012\133\002q\002q\002q\002q\002q\000\000\002q\015f\000\000\005n\002f\000\000\002q\002q\002q\002q\002q\000\000\000\000\000\000\000\000\002q\000\000\002q\002q\000\000\000\000\000\000\000\000\002q\002q\002q\000\000\000\000\000\000\000\000\000\000\000\238\002q\002q\t\182\002q\002q\002q\002q\002q\002q\000\000\015j\002q\000\000\002q\002q\000\000\000\000\000\000\000\000\000\000\000\000\002q\002q\002q\015v\002q\002q\002q\002q\012\133\000\000\001\206\002q\000\000\002q\002q\000\000\002q\002q\002q\002q\002q\002q\025\242\000\000\002q\002q\002q\000\000\000\000\005j\000\000\002q\002q\002q\002q\002Y\002Y\000\000\000\000\000\000\002Y\000\000\002\162\002Y\000\000\000\000\002Y\000\000\002Y\003\142\000\000\002Y\002~\002Y\002Y\002Y\025b\002Y\002Y\002Y\001\210\000\000\000\000\000\000\000\000\002Y\002Y\002Y\002Y\002Y\000\000\002Y\015f\000\000\000\000\002f\000\000\002Y\002Y\002Y\002Y\002Y\004~\003\174\000\000\004\217\002Y\000\000\002Y\002Y\002\150\000\000\000\000\000\000\002Y\002Y\002Y\000\000\000\000\000\000\000\000\000\000\000\000\002Y\002Y\t\182\002Y\002Y\002Y\002Y\002Y\002Y\000\000\015j\002Y\000\000\002Y\002Y\006\206\000\000\000\000\000\000\000\000\000\000\002Y\002Y\002Y\015v\002Y\002Y\002Y\002Y\000\000\000\000\000\000\002Y\000\000\002Y\002Y\000\000\002Y\002Y\002Y\002Y\002Y\002Y\012\129\000\000\002Y\002Y\002Y\000\000\000\000\005j\000\000\002Y\002Y\002Y\002Y\002e\002e\000\000\000\000\000\000\002e\012\129\012\129\002e\000\000\012\129\002e\000\000\002e\000\000\000\000\t\174\000\000\002e\002e\002e\020\254\002e\002e\002e\000\000\000\000\000\000\000\000\000\000\002e\002e\002e\t\238\002e\000\000\002e\000\000\000\000\000\000\000\000\000\000\002e\002e\002e\002e\002e\000\000\000\238\000\000\000\000\002e\000\000\002e\002e\000\000\000\000\000\000\000\000\002e\002e\002e\000\000\000\000\000\000\000\000\000\000\000\000\002e\002e\t\182\t\246\002e\002e\002e\002e\002e\000\000\012\129\002e\000\000\002e\002e\000\000\000\000\000\000\000\000\000\238\b\t\002e\002e\002e\b\t\002e\002e\002e\002e\000\000\000\000\000\000\002e\000\000\002e\002e\000\000\002e\002e\002e\002e\002e\002e\000\000\000\000\002e\002e\002e\000\000\011~\000\000\000\000\002e\002e\002e\002e\002u\002u\000\000\000\000\000\000\002u\b\t\011\134\002u\000\000\011\146\002u\000\000\002u\000\000\000\000\002u\011\158\002u\002u\002u\011\170\002u\002u\002u\000\000\000\000\b\t\000\000\000\000\002u\002u\002u\002u\002u\000\000\002u\000\000\000\000\000\000\000\000\000\000\002u\002u\002u\002u\002u\000\000\000\000\000\000\000\000\002u\000\000\002u\002u\000\000\000\000\000\000\000\000\002u\002u\002u\000\000\000\000\004\226\000\000\000\000\000\000\002u\002u\t\182\002u\002u\002u\002u\002u\002u\000\000\007\206\002u\000\000\002u\002u\000\000\000\000\000\000\000\000\000\238\b\005\002u\002u\002u\b\005\002u\002u\002u\002u\000\000\007\210\000\000\002u\000\000\002u\002u\000\000\002u\002u\002u\002u\002u\002u\000\000\000\000\002u\002u\002u\000\000\007\165\000\000\000\000\002u\002u\002u\002u\002U\002U\007\194\000\000\000\000\002U\b\005\007\165\002U\000\000\005\206\002U\000\000\002U\000\000\000\238\002U\007\165\002U\002U\002U\007\165\002U\002U\002U\000\000\000\000\b\005\000\000\000\000\002U\002U\002U\002U\002U\000\000\002U\000\000\000\000\006\253\000\000\000\000\002U\002U\002U\002U\002U\000\000\000\000\000\000\000\000\002U\000\000\002U\002U\000\000\000\000\000\000\006\253\002U\002U\002U\006\253\007\214\004\226\000\000\000\000\000\000\002U\002U\t\182\002U\002U\002U\002U\002U\002U\000\000\000\000\002U\000\000\002U\002U\000\000\000\000\000\000\000\000\007\189\000\000\002U\002U\002U\000\000\002U\002U\002U\002U\000\000\000\000\000\000\002U\000\000\002U\002U\000\000\002U\002U\002U\002U\002U\002U\000\000\000\000\002U\002U\002U\000\000\007\189\000\000\000\000\002U\002U\002U\002U\002a\002a\000\000\000\000\000\000\002a\005J\007\189\002a\000\000\005\206\002a\000\000\002a\000\000\000\000\t\174\007\189\002a\002a\002a\007\189\002a\002a\002a\000\000\000\000\000\000\000\000\000\000\002a\002a\002a\t\238\002a\000\000\002a\000\000\000\000\006\237\000\000\000\000\002a\002a\002a\002a\002a\000\000\000\000\000\000\000\000\002a\000\000\002a\002a\000\000\000\000\000\000\006\237\002a\002a\002a\006\237\000\000\000\000\000\000\000\000\000\000\002a\002a\t\182\t\246\002a\002a\002a\002a\002a\000\000\000\000\002a\000\000\002a\002a\000\000\000\000\000\000\000\000\000\238\000\000\002a\002a\002a\000\000\002a\002a\002a\002a\000\000\000\000\000\000\002a\000\000\002a\002a\000\000\002a\002a\002a\002a\002a\002a\000\000\000\000\002a\002a\002a\000\000\007\217\000\000\000\000\002a\002a\002a\002a\002]\002]\000\000\000\000\000\000\002]\b\n\006\014\002]\000\000\005\206\002]\000\000\002]\000\000\000\000\t\174\007\217\002]\002]\002]\007\217\002]\002]\002]\000\000\000\000\000\000\000\000\000\000\002]\002]\002]\t\238\002]\000\000\002]\000\000\000\000\000\000\000\000\000\000\002]\002]\002]\002]\002]\000\000\000\000\000\000\000\000\002]\000\000\002]\002]\000\000\000\000\000\000\000\000\002]\002]\002]\000\000\000\000\000\000\000\000\000\000\000\000\002]\002]\t\182\t\246\002]\002]\002]\002]\002]\000\000\000\000\002]\000\000\002]\002]\000\000\000\000\000\000\000\000\007\209\000\000\002]\002]\002]\000\000\002]\002]\002]\002]\000\000\000\000\000\000\002]\000\000\002]\002]\000\000\002]\002]\002]\002]\002]\002]\000\000\000\000\002]\002]\002]\000\000\007\209\000\000\000\000\002]\002]\002]\002]\002\133\002\133\000\000\000\000\000\000\002\133\000\000\011\194\002\133\000\000\007\209\002\133\000\000\002\133\000\000\000\000\t\174\007\209\002\133\002\133\002\133\007\209\002\133\002\133\002\133\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\133\000\000\000\000\000\000\000\000\000\000\002\133\002\133\n\022\n\030\002\133\000\000\000\000\000\000\000\000\002\133\000\000\n&\002\133\000\000\000\000\000\000\000\000\002\133\002\133\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\133\002\133\t\182\t\246\n.\n6\nF\002\133\002\133\000\000\000\000\002\133\000\000\002\133\nN\000\000\000\000\000\000\000\000\000\238\000\000\002\133\002\133\nV\000\000\002\133\002\133\002\133\002\133\000\000\000\000\000\000\002\133\000\000\002\133\002\133\000\000\002\133\002\133\002\133\n>\002\133\002\133\000\000\000\000\002\133\n^\002\133\000\000\007\161\000\000\000\000\002\133\002\133\nf\nn\002m\002m\000\000\000\000\000\000\002m\000\000\007\161\002m\000\000\005\206\002m\000\000\002m\000\000\000\000\t\174\007\161\002m\002m\002m\007\161\002m\002m\002m\000\000\000\000\000\000\000\000\000\000\002m\002m\002m\t\238\002m\000\000\002m\000\000\000\000\000\000\000\000\000\000\002m\002m\002m\002m\002m\000\000\000\000\000\000\000\000\002m\000\000\002m\002m\000\000\000\000\000\000\000\000\002m\002m\002m\000\000\000\000\000\000\000\000\000\000\000\000\002m\002m\t\182\t\246\002m\002m\002m\002m\002m\000\000\000\000\002m\000\000\002m\002m\000\000\000\000\000\000\000\000\000\238\000\000\002m\002m\002m\000\000\002m\002m\002m\002m\000\000\000\000\000\000\002m\000\000\002m\002m\000\000\002m\002m\002m\002m\002m\002m\000\000\000\000\002m\002m\002m\000\000\014\n\000\000\000\000\002m\002m\002m\002m\002i\002i\000\000\000\000\000\000\002i\000\000\011\134\002i\000\000\011\146\002i\000\000\002i\000\000\000\000\t\174\011\158\002i\002i\002i\011\170\002i\002i\002i\000\000\000\000\000\000\000\000\000\000\002i\002i\002i\t\238\002i\000\000\002i\000\000\000\000\000\000\000\000\000\000\002i\002i\002i\002i\002i\000\000\000\000\000\000\000\000\002i\000\000\002i\002i\000\000\000\000\000\000\000\000\002i\002i\002i\000\000\000\000\000\000\000\000\000\000\000\000\002i\002i\t\182\t\246\002i\002i\002i\002i\002i\000\000\000\000\002i\000\000\002i\002i\000\000\000\000\000\000\000\000\000\000\000\000\002i\002i\002i\000\000\002i\002i\002i\002i\000\000\000\000\000\000\002i\000\000\002i\002i\000\000\002i\002i\002i\002i\002i\002i\000\000\000\000\002i\002i\002i\000\000\000\000\000\000\000\000\002i\002i\002i\002i\002}\002}\000\000\000\000\000\000\002}\000\000\002\006\002}\000\000\002f\002}\000\000\002}\000\000\000\000\t\174\000\000\002}\002}\002}\000\000\002}\002}\002}\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\002}\000\000\002}\000\000\000\000\000\000\000\000\000\000\002}\002}\n\022\n\030\002}\000\000\027\014\001\222\000\000\002}\000\000\002}\002}\000\000\000\000\000\000\000\000\002}\002}\000\238\015v\000\000\000\000\000\000\000\000\000\000\002}\002}\t\182\t\246\n.\n6\002}\002}\002}\000\000\000\000\002}\000\000\002}\002}\000\000\000\000\000\000\000\000\000\000\005j\002}\002}\002}\000\000\002}\002}\002}\002}\000\000\000\000\000\000\002}\000\000\002}\002}\000\000\002}\002}\002}\n>\002}\002}\000\000\000\000\002}\002}\002}\000\000\000\000\000\000\000\000\002}\002}\002}\002}\002Q\002Q\000\000\000\000\000\000\002Q\000\000\002\250\002Q\000\000\000\000\002Q\000\000\002Q\000\000\000\000\t\174\000\000\002Q\002Q\002Q\000\000\002Q\002Q\002Q\000\000\000\000\000\000\000\000\000\000\002Q\002Q\002Q\t\238\002Q\000\000\002Q\000\000\000\000\000\000\000\000\000\000\002Q\002Q\002Q\002Q\002Q\000\000\005\162\000\000\000\000\002Q\000\000\002Q\002Q\000\000\000\000\000\000\003\218\002Q\002Q\002Q\0062\000\000\003\230\000\000\000\000\000\000\002Q\002Q\t\182\t\246\002Q\002Q\002Q\002Q\002Q\000\000\000\000\002Q\000\000\002Q\002Q\000\000\000\000\000\000\000\000\000\000\000\000\002Q\002Q\002Q\000\000\002Q\002Q\002Q\002Q\000\000\000\000\000\000\002Q\000\000\002Q\002Q\000\000\002Q\002Q\002Q\002Q\002Q\002Q\000\000\000\000\002Q\002Q\002Q\000\000\000\000\000\000\000\000\002Q\002Q\002Q\002Q\002M\002M\000\000\000\000\000\000\002M\000\000\002\162\002M\000\000\000\000\002M\000\000\002M\000\000\000\000\t\174\000\000\002M\002M\002M\000\000\002M\002M\002M\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\002M\000\000\002M\000\000\000\000\000\000\000\000\000\000\002M\002M\n\022\n\030\002M\000\000\tn\002\238\000\000\002M\000\000\002M\002M\000\000\000\000\000\000\000\000\002M\002M\000\238\011\226\000\000\011\242\000\000\000\000\000\000\002M\002M\t\182\t\246\n.\n6\002M\002M\002M\000\000\000\000\002M\000\000\002M\002M\000\000\000\000\000\000\000\000\000\000\000\000\002M\002M\002M\000\000\002M\002M\002M\002M\000\000\000\000\000\000\002M\000\000\002M\002M\000\000\002M\002M\002M\n>\002M\002M\000\000\000\000\002M\002M\002M\000\000\000\000\000\000\000\000\002M\002M\002M\002M\002\169\002\169\000\000\000\000\000\000\002\169\000\000\002\162\002\169\000\000\000\000\002\169\000\000\002\169\000\000\000\000\t\174\000\000\002\169\002\169\002\169\000\000\002\169\002\169\002\169\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\002\169\000\000\002\169\000\000\000\000\000\000\000\000\000\000\002\169\002\169\n\022\n\030\002\169\000\000\012\166\002\238\000\000\002\169\000\000\002\169\002\169\000\000\000\000\000\000\000\000\002\169\002\169\002\169\012\186\000\000\012\206\000\000\000\000\000\000\002\169\002\169\t\182\t\246\n.\002\169\002\169\002\169\002\169\000\000\000\000\002\169\000\000\002\169\002\169\000\000\000\000\000\000\000\000\000\000\000\000\002\169\002\169\002\169\000\000\002\169\002\169\002\169\002\169\000\000\000\000\000\000\002\169\000\000\002\169\002\169\000\000\002\169\002\169\002\169\n>\002\169\002\169\000\000\000\000\002\169\002\169\002\169\000\000\000\000\000\000\000\000\002\169\002\169\002\169\002\169\002I\002I\000\000\000\000\000\000\002I\000\000\000\000\002I\000\000\000\000\002I\000\000\002I\000\000\000\000\t\174\000\000\002I\002I\002I\000\000\002I\002I\002I\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\002I\000\000\002I\000\000\000\000\000\000\000\000\000\000\002I\002I\n\022\n\030\002I\000\000\000\000\000\000\000\000\002I\000\000\002I\002I\000\000\000\000\000\000\000\000\002I\002I\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002I\002I\t\182\t\246\n.\n6\002I\002I\002I\000\000\000\000\002I\000\000\002I\002I\000\000\000\000\000\000\000\000\000\000\000\000\002I\002I\002I\000\000\002I\002I\002I\002I\000\000\000\000\000\000\002I\000\000\002I\002I\000\000\002I\002I\002I\n>\002I\002I\000\000\000\000\002I\002I\002I\000\000\000\000\000\000\000\000\002I\002I\002I\002I\002\129\002\129\000\000\000\000\000\000\002\129\000\000\000\000\002\129\000\000\000\000\002\129\000\000\002\129\000\000\000\000\t\174\000\000\002\129\002\129\002\129\000\000\002\129\002\129\002\129\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\002\129\000\000\002\129\000\000\000\000\000\000\000\000\000\000\002\129\002\129\n\022\n\030\002\129\000\000\000\000\000\000\000\000\002\129\000\000\002\129\002\129\000\000\000\000\000\000\000\000\002\129\002\129\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\129\002\129\t\182\t\246\n.\n6\002\129\002\129\002\129\000\000\000\000\002\129\000\000\002\129\002\129\000\000\000\000\000\000\000\000\000\000\000\000\002\129\002\129\002\129\000\000\002\129\002\129\002\129\002\129\000\000\000\000\000\000\002\129\000\000\002\129\002\129\000\000\002\129\002\129\002\129\n>\002\129\002\129\000\000\000\000\002\129\002\129\002\129\000\000\000\000\000\000\000\000\002\129\002\129\002\129\002\129\002y\002y\000\000\000\000\000\000\002y\000\000\000\000\002y\000\000\000\000\002y\000\000\002y\000\000\000\000\t\174\000\000\002y\002y\002y\000\000\002y\002y\002y\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\002y\000\000\002y\000\000\000\000\000\000\000\000\000\000\002y\002y\n\022\n\030\002y\000\000\000\000\000\000\000\000\002y\000\000\002y\002y\000\000\000\000\000\000\000\000\002y\002y\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002y\002y\t\182\t\246\n.\n6\002y\002y\002y\000\000\000\000\002y\000\000\002y\002y\000\000\000\000\000\000\000\000\000\000\000\000\002y\002y\002y\000\000\002y\002y\002y\002y\000\000\000\000\000\000\002y\000\000\002y\002y\000\000\002y\002y\002y\n>\002y\002y\000\000\000\000\002y\002y\002y\000\000\000\000\000\000\000\000\002y\002y\002y\002y\002\137\002\137\000\000\000\000\000\000\002\137\000\000\000\000\002\137\000\000\000\000\002\137\000\000\002\137\000\000\000\000\t\174\000\000\002\137\002\137\002\137\000\000\002\137\002\137\002\137\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\137\000\000\000\000\000\000\000\000\000\000\002\137\002\137\n\022\n\030\002\137\000\000\000\000\000\000\000\000\002\137\000\000\n&\002\137\000\000\000\000\000\000\000\000\002\137\002\137\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\137\002\137\t\182\t\246\n.\n6\nF\002\137\002\137\000\000\000\000\002\137\000\000\002\137\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\137\002\137\nV\000\000\002\137\002\137\002\137\002\137\000\000\000\000\000\000\002\137\000\000\002\137\002\137\000\000\002\137\002\137\002\137\n>\002\137\002\137\000\000\000\000\002\137\n^\002\137\000\000\000\000\000\000\000\000\002\137\002\137\nf\nn\002\141\002\141\000\000\000\000\000\000\002\141\000\000\000\000\002\141\000\000\000\000\002\141\000\000\002\141\000\000\000\000\t\174\000\000\002\141\002\141\002\141\000\000\002\141\002\141\002\141\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\002\141\000\000\002\141\000\000\000\000\000\000\000\000\000\000\002\141\002\141\n\022\n\030\002\141\000\000\000\000\000\000\000\000\002\141\000\000\n&\002\141\000\000\000\000\000\000\000\000\002\141\002\141\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\141\002\141\t\182\t\246\n.\n6\nF\002\141\002\141\000\000\000\000\002\141\000\000\002\141\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\141\002\141\nV\000\000\002\141\002\141\002\141\002\141\000\000\000\000\000\000\002\141\000\000\002\141\002\141\000\000\002\141\002\141\002\141\n>\002\141\002\141\000\000\000\000\002\141\002\141\002\141\000\000\000\000\000\000\000\000\002\141\002\141\nf\nn\002\145\002\145\000\000\000\000\000\000\002\145\000\000\000\000\002\145\000\000\000\000\002\145\000\000\002\145\000\000\000\000\t\174\000\000\002\145\002\145\002\145\000\000\002\145\002\145\002\145\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\002\145\000\000\002\145\000\000\000\000\000\000\000\000\000\000\002\145\002\145\n\022\n\030\002\145\000\000\000\000\000\000\000\000\002\145\000\000\n&\002\145\000\000\000\000\000\000\000\000\002\145\002\145\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\145\002\145\t\182\t\246\n.\n6\nF\002\145\002\145\000\000\000\000\002\145\000\000\002\145\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\145\002\145\nV\000\000\002\145\002\145\002\145\002\145\000\000\000\000\000\000\002\145\000\000\002\145\002\145\000\000\002\145\002\145\002\145\n>\002\145\002\145\000\000\000\000\002\145\002\145\002\145\000\000\000\000\000\000\000\000\002\145\002\145\nf\nn\b\225\b\225\000\000\000\000\000\000\b\225\000\000\000\000\b\225\000\000\000\000\b\225\000\000\b\225\000\000\000\000\t\174\000\000\b\225\b\225\b\225\000\000\b\225\b\225\b\225\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\b\225\000\000\000\000\000\000\000\000\000\000\b\225\b\225\n\022\n\030\b\225\000\000\000\000\000\000\000\000\b\225\000\000\n&\b\225\000\000\000\000\000\000\000\000\b\225\b\225\000\238\000\000\000\000\000\000\000\000\000\000\000\000\b\225\b\225\t\182\t\246\n.\n6\nF\b\225\b\225\000\000\000\000\b\225\000\000\b\225\nN\000\000\000\000\000\000\000\000\000\000\000\000\b\225\b\225\nV\000\000\b\225\b\225\b\225\b\225\000\000\000\000\000\000\b\225\000\000\b\225\b\225\000\000\b\225\b\225\b\225\n>\b\225\b\225\000\000\000\000\b\225\n^\b\225\000\000\000\000\000\000\000\000\b\225\b\225\nf\nn\002\149\002\149\000\000\000\000\000\000\002\149\000\000\000\000\002\149\000\000\000\000\002\149\000\000\002\149\000\000\000\000\t\174\000\000\002\149\002\149\002\149\000\000\002\149\002\149\002\149\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\149\000\000\000\000\000\000\000\000\000\000\002\149\002\149\n\022\n\030\002\149\000\000\000\000\000\000\000\000\002\149\000\000\n&\002\149\000\000\000\000\000\000\000\000\002\149\002\149\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\149\002\149\t\182\t\246\n.\n6\nF\002\149\002\149\000\000\000\000\002\149\000\000\002\149\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\149\002\149\nV\000\000\002\149\002\149\002\149\002\149\000\000\000\000\000\000\002\149\000\000\002\149\002\149\000\000\nv\002\149\n~\n>\002\149\002\149\000\000\000\000\002\149\n^\002\149\000\000\000\000\000\000\000\000\002\149\002\149\nf\nn\b\221\b\221\000\000\000\000\000\000\b\221\000\000\000\000\b\221\000\000\000\000\b\221\000\000\b\221\000\000\000\000\t\174\000\000\b\221\b\221\b\221\000\000\b\221\b\221\b\221\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\b\221\000\000\000\000\000\000\000\000\000\000\b\221\b\221\n\022\n\030\b\221\000\000\000\000\000\000\000\000\b\221\000\000\n&\b\221\000\000\000\000\000\000\000\000\b\221\b\221\000\238\000\000\000\000\000\000\000\000\000\000\000\000\b\221\b\221\t\182\t\246\n.\n6\nF\b\221\b\221\000\000\000\000\b\221\000\000\b\221\nN\000\000\000\000\000\000\000\000\000\000\000\000\b\221\b\221\nV\000\000\b\221\b\221\b\221\b\221\000\000\000\000\000\000\b\221\000\000\b\221\b\221\000\000\b\221\b\221\b\221\n>\b\221\b\221\000\000\000\000\b\221\n^\b\221\000\000\000\000\000\000\000\000\b\221\b\221\nf\nn\002\197\002\197\000\000\000\000\000\000\002\197\000\000\000\000\002\197\000\000\000\000\002\197\000\000\002\197\000\000\000\000\t\174\000\000\002\197\002\197\002\197\000\000\002\197\002\197\002\197\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\197\000\000\000\000\000\000\000\000\000\000\002\197\002\197\n\022\n\030\002\197\000\000\000\000\000\000\000\000\002\197\000\000\n&\002\197\000\000\000\000\000\000\000\000\002\197\002\197\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\197\002\197\t\182\t\246\n.\n6\nF\002\197\002\197\000\000\000\000\002\197\000\000\002\197\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\197\002\197\nV\000\000\002\197\002\197\002\197\002\197\000\000\000\000\000\000\002\197\000\000\002\197\002\197\000\000\nv\002\197\n~\n>\002\197\002\197\000\000\000\000\002\197\n^\002\197\000\000\000\000\000\000\000\000\002\197\002\197\nf\nn\002\193\002\193\000\000\000\000\000\000\002\193\000\000\000\000\002\193\000\000\000\000\002\193\000\000\002\193\000\000\000\000\t\174\000\000\002\193\002\193\002\193\000\000\002\193\002\193\002\193\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\193\000\000\000\000\000\000\000\000\000\000\002\193\002\193\n\022\n\030\002\193\000\000\000\000\000\000\000\000\002\193\000\000\n&\002\193\000\000\000\000\000\000\000\000\002\193\002\193\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\193\002\193\t\182\t\246\n.\n6\nF\002\193\002\193\000\000\000\000\002\193\000\000\002\193\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\193\002\193\nV\000\000\002\193\002\193\002\193\002\193\000\000\000\000\000\000\002\193\000\000\002\193\002\193\000\000\nv\002\193\n~\n>\002\193\002\193\000\000\000\000\002\193\n^\002\193\000\000\000\000\000\000\000\000\002\193\002\193\nf\nn\002\201\002\201\000\000\000\000\000\000\002\201\000\000\000\000\002\201\000\000\000\000\002\201\000\000\002\201\000\000\000\000\t\174\000\000\002\201\002\201\002\201\000\000\002\201\002\201\002\201\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\201\000\000\000\000\000\000\000\000\000\000\002\201\002\201\n\022\n\030\002\201\000\000\000\000\000\000\000\000\002\201\000\000\n&\002\201\000\000\000\000\000\000\000\000\002\201\002\201\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\201\002\201\t\182\t\246\n.\n6\nF\002\201\002\201\000\000\000\000\002\201\000\000\002\201\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\201\002\201\nV\000\000\002\201\002\201\002\201\002\201\000\000\000\000\000\000\002\201\000\000\002\201\002\201\000\000\nv\002\201\n~\n>\002\201\002\201\000\000\000\000\002\201\n^\002\201\000\000\000\000\000\000\000\000\002\201\002\201\nf\nn\002\181\002\181\000\000\000\000\000\000\002\181\000\000\000\000\002\181\000\000\000\000\002\181\000\000\002\181\000\000\000\000\t\174\000\000\002\181\002\181\002\181\000\000\002\181\002\181\002\181\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\181\000\000\000\000\000\000\000\000\000\000\002\181\002\181\n\022\n\030\002\181\000\000\000\000\000\000\000\000\002\181\000\000\n&\002\181\000\000\000\000\000\000\000\000\002\181\002\181\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\181\002\181\t\182\t\246\n.\n6\nF\002\181\002\181\000\000\000\000\002\181\000\000\002\181\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\181\002\181\nV\000\000\002\181\002\181\002\181\002\181\000\000\000\000\000\000\002\181\000\000\002\181\002\181\000\000\nv\002\181\n~\n>\002\181\002\181\000\000\000\000\002\181\n^\002\181\000\000\000\000\000\000\000\000\002\181\002\181\nf\nn\002\185\002\185\000\000\000\000\000\000\002\185\000\000\000\000\002\185\000\000\000\000\002\185\000\000\002\185\000\000\000\000\t\174\000\000\002\185\002\185\002\185\000\000\002\185\002\185\002\185\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\185\000\000\000\000\000\000\000\000\000\000\002\185\002\185\n\022\n\030\002\185\000\000\000\000\000\000\000\000\002\185\000\000\n&\002\185\000\000\000\000\000\000\000\000\002\185\002\185\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\185\002\185\t\182\t\246\n.\n6\nF\002\185\002\185\000\000\000\000\002\185\000\000\002\185\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\185\002\185\nV\000\000\002\185\002\185\002\185\002\185\000\000\000\000\000\000\002\185\000\000\002\185\002\185\000\000\nv\002\185\n~\n>\002\185\002\185\000\000\000\000\002\185\n^\002\185\000\000\000\000\000\000\000\000\002\185\002\185\nf\nn\002\189\002\189\000\000\000\000\000\000\002\189\000\000\000\000\002\189\000\000\000\000\002\189\000\000\002\189\000\000\000\000\t\174\000\000\002\189\002\189\002\189\000\000\002\189\002\189\002\189\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\189\000\000\000\000\000\000\000\000\000\000\002\189\002\189\n\022\n\030\002\189\000\000\000\000\000\000\000\000\002\189\000\000\n&\002\189\000\000\000\000\000\000\000\000\002\189\002\189\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\189\002\189\t\182\t\246\n.\n6\nF\002\189\002\189\000\000\000\000\002\189\000\000\002\189\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\189\002\189\nV\000\000\002\189\002\189\002\189\002\189\000\000\000\000\000\000\002\189\000\000\002\189\002\189\000\000\nv\002\189\n~\n>\002\189\002\189\000\000\000\000\002\189\n^\002\189\000\000\000\000\000\000\000\000\002\189\002\189\nf\nn\002\209\002\209\000\000\000\000\000\000\002\209\000\000\000\000\002\209\000\000\000\000\002\209\000\000\002\209\000\000\000\000\t\174\000\000\002\209\002\209\002\209\000\000\002\209\002\209\002\209\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\209\000\000\000\000\000\000\000\000\000\000\002\209\002\209\n\022\n\030\002\209\000\000\000\000\000\000\000\000\002\209\000\000\n&\002\209\000\000\000\000\000\000\000\000\002\209\002\209\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\209\002\209\t\182\t\246\n.\n6\nF\002\209\002\209\000\000\000\000\002\209\000\000\002\209\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\209\002\209\nV\000\000\002\209\002\209\002\209\002\209\000\000\000\000\000\000\002\209\000\000\002\209\002\209\000\000\nv\002\209\n~\n>\002\209\002\209\000\000\000\000\002\209\n^\002\209\000\000\000\000\000\000\000\000\002\209\002\209\nf\nn\002\205\002\205\000\000\000\000\000\000\002\205\000\000\000\000\002\205\000\000\000\000\002\205\000\000\002\205\000\000\000\000\t\174\000\000\002\205\002\205\002\205\000\000\002\205\002\205\002\205\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\205\000\000\000\000\000\000\000\000\000\000\002\205\002\205\n\022\n\030\002\205\000\000\000\000\000\000\000\000\002\205\000\000\n&\002\205\000\000\000\000\000\000\000\000\002\205\002\205\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\205\002\205\t\182\t\246\n.\n6\nF\002\205\002\205\000\000\000\000\002\205\000\000\002\205\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\205\002\205\nV\000\000\002\205\002\205\002\205\002\205\000\000\000\000\000\000\002\205\000\000\002\205\002\205\000\000\nv\002\205\n~\n>\002\205\002\205\000\000\000\000\002\205\n^\002\205\000\000\000\000\000\000\000\000\002\205\002\205\nf\nn\002\213\002\213\000\000\000\000\000\000\002\213\000\000\000\000\002\213\000\000\000\000\002\213\000\000\002\213\000\000\000\000\t\174\000\000\002\213\002\213\002\213\000\000\002\213\002\213\002\213\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\213\000\000\000\000\000\000\000\000\000\000\002\213\002\213\n\022\n\030\002\213\000\000\000\000\000\000\000\000\002\213\000\000\n&\002\213\000\000\000\000\000\000\000\000\002\213\002\213\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\213\002\213\t\182\t\246\n.\n6\nF\002\213\002\213\000\000\000\000\002\213\000\000\002\213\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\213\002\213\nV\000\000\002\213\002\213\002\213\002\213\000\000\000\000\000\000\002\213\000\000\002\213\002\213\000\000\nv\002\213\n~\n>\002\213\002\213\000\000\000\000\002\213\n^\002\213\000\000\000\000\000\000\000\000\002\213\002\213\nf\nn\002\177\002\177\000\000\000\000\000\000\002\177\000\000\000\000\002\177\000\000\000\000\002\177\000\000\002\177\000\000\000\000\t\174\000\000\002\177\002\177\002\177\000\000\002\177\002\177\002\177\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\177\000\000\000\000\000\000\000\000\000\000\002\177\002\177\n\022\n\030\002\177\000\000\000\000\000\000\000\000\002\177\000\000\n&\002\177\000\000\000\000\000\000\000\000\002\177\002\177\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\177\002\177\t\182\t\246\n.\n6\nF\002\177\002\177\000\000\000\000\002\177\000\000\002\177\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\177\002\177\nV\000\000\002\177\002\177\002\177\002\177\000\000\000\000\000\000\002\177\000\000\002\177\002\177\000\000\nv\002\177\n~\n>\002\177\002\177\000\000\000\000\002\177\n^\002\177\000\000\000\000\000\000\000\000\002\177\002\177\nf\nn\002\001\002\001\000\000\000\000\000\000\002\001\000\000\000\000\002\001\000\000\000\000\002\001\000\000\002\001\000\000\000\000\002\001\000\000\002\001\002\001\002\001\000\000\002\001\002\001\002\001\000\000\000\000\000\000\000\000\000\000\002\001\002\001\002\001\002\001\002\001\000\000\002\001\000\000\000\000\000\000\000\000\000\000\002\001\002\001\002\001\002\001\002\001\000\000\000\000\000\000\000\000\002\001\000\000\002\001\002\001\000\000\000\000\000\000\000\000\002\001\002\001\002\001\000\000\000\000\000\000\000\000\000\000\000\000\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\000\000\000\000\002\001\000\000\002\001\002\001\000\000\000\000\000\000\000\000\000\000\000\000\002\001\002\001\002\001\000\000\002\001\002\001\002\001\002\001\000\000\000\000\000\000\002\001\000\000\002\001\002\001\000\000\002\001\002\001\002\001\002\001\002\001\002\001\000\000\000\000\002\001\002\001\r\226\000\000\000\000\000\000\000\000\002\001\002\001\002\001\002\001\002\029\002\029\000\000\000\000\000\000\002\029\000\000\000\000\002\029\000\000\000\000\002\029\000\000\002\029\000\000\000\000\t\174\000\000\002\029\002\029\002\029\000\000\002\029\002\029\002\029\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\029\000\000\000\000\000\000\000\000\000\000\002\029\002\029\n\022\n\030\002\029\000\000\000\000\000\000\000\000\002\029\000\000\n&\002\029\000\000\000\000\000\000\000\000\002\029\002\029\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\029\002\029\t\182\t\246\n.\n6\nF\002\029\002\029\000\000\000\000\002\029\000\000\002\029\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\029\002\029\nV\000\000\002\029\002\029\r\250\002\029\000\000\000\000\000\000\002\029\000\000\002\029\002\029\000\000\nv\002\029\n~\n>\002\029\002\029\000\000\000\000\002\029\n^\002\029\000\000\000\000\000\000\000\000\002\029\002\029\nf\nn\002\025\002\025\000\000\000\000\000\000\002\025\000\000\000\000\002\025\000\000\000\000\002\025\000\000\002\025\000\000\000\000\t\174\000\000\002\025\002\025\002\025\000\000\002\025\002\025\002\025\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\025\000\000\000\000\000\000\000\000\000\000\002\025\002\025\n\022\n\030\002\025\000\000\000\000\000\000\000\000\002\025\000\000\n&\002\025\000\000\000\000\000\000\000\000\002\025\002\025\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\025\002\025\t\182\t\246\n.\n6\nF\002\025\002\025\000\000\000\000\002\025\000\000\002\025\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\025\002\025\nV\000\000\002\025\002\025\002\025\002\025\000\000\000\000\000\000\002\025\000\000\002\025\002\025\000\000\nv\002\025\n~\n>\002\025\002\025\000\000\000\000\002\025\n^\002\025\000\000\000\000\000\000\000\000\002\025\002\025\nf\nn\002\173\002\173\000\000\000\000\000\000\002\173\000\000\000\000\002\173\000\000\000\000\002\173\000\000\002\173\000\000\000\000\t\174\000\000\002\173\002\173\002\173\000\000\002\173\002\173\002\173\000\000\000\000\000\000\000\000\000\000\t\230\t\254\n\006\t\238\n\014\000\000\002\173\000\000\000\000\000\000\000\000\000\000\002\173\002\173\n\022\n\030\002\173\000\000\000\000\000\000\000\000\002\173\000\000\n&\002\173\000\000\000\000\000\000\000\000\002\173\002\173\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\173\002\173\t\182\t\246\n.\n6\nF\002\173\002\173\000\000\000\000\002\173\000\000\002\173\nN\000\000\000\000\000\000\000\000\000\000\000\000\002\173\002\173\nV\000\000\002\173\002\173\002\173\002\173\000\000\000\000\000\000\002\173\000\000\002\173\002\173\000\000\nv\002\173\n~\n>\002\173\002\173\000\000\000\000\002\173\n^\002\173\000\000\000\000\000\000\000\000\002\173\002\173\nf\nn\002\r\002\r\000\000\000\000\000\000\002\r\000\000\000\000\002\r\000\000\000\000\002\r\000\000\002\r\000\000\000\000\002\r\000\000\002\r\002\r\002\r\000\000\002\r\002\r\002\r\000\000\000\000\000\000\000\000\000\000\002\r\002\r\002\r\002\r\002\r\000\000\002\r\000\000\000\000\000\000\000\000\000\000\002\r\002\r\002\r\002\r\002\r\000\000\000\000\000\000\000\000\002\r\000\000\002\r\002\r\000\000\000\000\000\000\000\000\002\r\002\r\002\r\000\000\000\000\000\000\000\000\000\000\000\000\002\r\002\r\002\r\002\r\002\r\002\r\002\r\002\r\002\r\000\000\000\000\002\r\000\000\002\r\002\r\000\000\000\000\000\000\000\000\000\000\000\000\002\r\002\r\002\r\000\000\002\r\002\r\002\r\002\r\000\000\000\000\000\000\002\r\000\000\002\r\002\r\000\000\002\r\002\r\002\r\002\r\002\r\002\r\000\000\000\000\002\r\002\r\r\226\000\000\000\000\000\000\000\000\002\r\002\r\002\r\002\r\002\017\002\017\000\000\000\000\000\000\002\017\000\000\000\000\002\017\000\000\000\000\002\017\000\000\002\017\000\000\000\000\002\017\000\000\002\017\002\017\002\017\000\000\002\017\002\017\002\017\000\000\000\000\000\000\000\000\000\000\002\017\002\017\002\017\002\017\002\017\000\000\002\017\000\000\000\000\000\000\000\000\000\000\002\017\002\017\002\017\002\017\002\017\003\253\000\000\000\000\000\000\002\017\000\000\002\017\002\017\000\000\000\000\000\000\000\000\002\017\002\017\002\017\000\000\000\000\000\000\000\000\000\000\000\000\002\017\002\017\002\017\002\017\002\017\002\017\002\017\002\017\002\017\000\000\000\000\002\017\000\000\002\017\002\017\000\000\000\000\000\000\000\000\000\000\000\238\002\017\002\017\002\017\000\000\002\017\002\017\002\017\002\017\000\000\000\000\000\000\002\017\000\000\002\017\002\017\000\000\002\017\002\017\002\017\002\017\002\017\002\017\000\000\000\000\002\017\002\017\r\226\000\000\000\000\003\253\000\000\002\017\002\017\002\017\002\017\001\006\000\000\000\006\000\000\007\r\000\000\002\158\002\162\006\014\002\206\002f\005\206\b\214\000\000\000\000\002\218\001\n\012\181\006\026\000\000\002r\000\000\006&\007\r\000\000\001\210\000\000\007\r\000\000\003\026\001\018\bR\bV\001\030\001\"\000\000\000\000\012\181\003*\000\000\002\226\000\000\025\002\002\030\bz\b~\000\000\003\194\003\022\003\206\b\130\006\186\000\000\001:\000\000\002\150\002&\000\000\003\030\002*\012\161\000\000\007\254\b\002\b\014\b\"\000\000\005Z\000\000\000\000\001>\001B\001F\001J\001N\000\000\000\000\b\150\001R\000\000\007\001\000\000\001V\000\000\b\162\b\186\t\014\005f\005j\000\000\000\000\001Z\000\000\000\000\000\000\007\r\000\000\001^\000\000\007\001\000\000\000\000\000\000\007\001\012\181\012\161\000\000\001\154\n\246\000\000\n\178\005n\b\022\n\190\001\158\000\000\014*\004V\t\"\001\006\001\166\000\006\001\170\001\174\012\181\002\158\002\162\000\000\002\206\002f\002\030\000\000\000\000\000\000\002\218\001\n\000\000\002\"\000\000\bN\000\000\000\238\000\000\002&\001\210\000\000\002*\012\161\003\026\001\018\bR\bV\001\030\001\"\000\000\000\000\000\000\003*\000\000\002\226\000\000\bZ\000\000\bz\b~\000\000\003\194\003\022\003\206\b\130\006\186\000\000\001:\000\000\002\150\006\229\000\000\003\030\000\000\000\000\000\000\007\254\b\002\b\014\b\"\006\014\005Z\000\000\005\206\001>\001B\001F\001J\001N\006\229\006\026\b\150\001R\006\229\006&\000\000\001V\000\000\b\162\b\186\t\014\005f\005j\000\000\000\000\001Z\000\000\000\000\000\000\000\000\000\000\001^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\154\005\250\000\000\000\000\005n\b\022\000\000\001\158\000\000\014*\004V\t\"\004m\001\166\000\006\001\170\001\174\000\246\002\158\002\162\002\166\002\206\002f\000\000\002\225\000\000\000\000\002\218\018f\000\000\003\150\000\000\000\000\000\000\004m\000\000\003\154\001\210\000\000\016\254\006\229\002\222\000\000\003\"\003&\000\000\000\000\000\000\003\158\000\000\003*\000\000\002\226\000\n\016\146\000\000\003\186\003\190\003\254\003\194\003\022\003\206\003\214\006\186\000\000\000\000\016\246\002\150\000\000\002\225\003\030\017\014\000\000\000\000\007\254\b\002\b\014\b\"\000\000\005Z\000\000\002\225\002\225\000\000\000\000\000\000\000\000\017\022\000\000\b\150\000\000\t\r\000\000\000\000\000\000\000\000\b\162\b\186\t\014\005f\005j\017*\017V\000\000\000\000\004m\004m\000\000\000\000\000\000\006J\024\206\000\000\t\r\000\000\000\000\015f\000\000\000\000\002f\000\000\017\146\021~\005n\b\022\024\238\000\173\000\000\b.\004V\t\"\000\173\000\000\002\162\000\173\000\000\002f\021&\tJ\000\000\000\000\002\218\000\000\000\000\000\173\000\000\000\173\000\000\000\173\000\000\000\173\001\210\000\238\tR\000\000\002\222\000\000\015j\000\000\000\000\000\000\tZ\000\173\000\000\000\000\000\000\002\226\000\000\000\173\000\000\000\000\015v\000\173\021J\003\022\001\190\015f\000\173\000\000\002f\000\173\002\150\000\000\000\000\003\030\000\173\000\173\000\173\007\254\b\002\b\014\000\000\012J\005Z\000\173\000\173\006\014\005j\000\000\005\206\024\210\000\173\000\000\000\000\t\r\000\173\006\026\021V\000\000\000\000\006&\000\000\000\000\005f\005j\000\173\000\173\015j\000\000\000\173\000\173\000\000\000\000\000\000\020\234\000\000\000\000\000\000\000\000\000\173\000\000\015v\000\000\021*\000\000\000\173\000\173\005n\b\022\000\000\000\000\000\197\b.\004V\000\000\000\173\000\197\000\173\002\162\000\197\000\000\002f\000\000\tJ\000\000\000\000\002\218\005j\000\000\000\197\000\000\000\197\000\000\000\197\000\000\000\197\001\210\0216\tR\000\000\002\222\003\178\000\000\002\162\000\000\000\000\tZ\000\197\000\000\b\182\003\142\002\226\000\000\000\197\020\234\000\000\007\198\000\197\000\000\003\022\001\190\001\210\000\197\000\000\000\000\000\197\002\150\000\000\000\000\003\030\000\197\000\197\000\197\007\254\b\002\b\014\000\000\012J\005Z\000\197\000\197\000\000\000\000\000\000\003\174\000\000\000\197\000\000\000\000\r\206\000\197\002\150\000\000\000\000\000\000\000\000\000\000\000\000\005f\005j\000\197\000\197\000\000\000\000\000\197\000\197\000\000\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\197\000\000\000\000\000\000\000\000\006\206\000\197\000\197\005n\b\022\000\000\000\000\000\000\b.\004V\000\000\000\197\000\000\000\197\000\014\000\018\000\022\000\026\000\030\000\000\000\"\000&\000*\000.\0002\000\000\0006\000:\000\000\000\000\000>\000\000\006\014\000\000\000B\005\206\000\000\012\181\012\161\000\000\000\000\000F\006\026\000\000\000\000\000\000\006&\000J\000\000\000N\000R\000V\000Z\000^\000b\000f\000\000\012\181\000\000\000j\000n\000\000\000r\002\030\000v\000\000\000\000\000\000\000\000\000\000\002\178\000\000\000\000\000\000\000\000\000\000\002&\000\000\000z\002*\012\161\000~\000\130\000\000\000\000\000\000\000\000\000\000\000\134\000\138\000\142\000\000\000\000\000\000\000\000\000\000\000\146\000\150\000\154\000\158\000\000\000\162\000\166\000\170\000\000\000\000\000\000\000\174\000\178\000\182\000\000\000\000\000\000\000\186\000\006\000\190\000\194\000\246\002\158\002\162\002\166\002\206\002f\000\198\000\000\000\202\000\000\002\218\000\000\000\000\004\141\000\206\000\210\000\000\000\214\000\000\003\154\001\210\000\000\000\000\000\000\002\222\000\000\003\"\003&\000\000\000\000\000\000\003\158\000\000\003*\000\000\002\226\000\000\016\146\000\000\003\186\003\190\000\000\003\194\003\022\003\206\003\214\006\186\000\000\000\000\016\246\002\150\000\000\000\000\003\030\017\014\000\000\000\000\007\254\b\002\b\014\b\"\000\000\005Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\022\000\000\b\150\000\000\027\222\000\000\000\000\000\000\000\000\b\162\b\186\t\014\005f\005j\017*\017V\000\000\000\006\027\255\014\190\000\246\002\158\002\162\002\166\002\206\002f\000\000\000\000\000\000\000\000\002\218\000\000\000\000\028.\000\000\021~\005n\b\022\014>\003\154\001\210\b.\004V\t\"\002\222\000\000\003\"\003&\000\000\000\000\000\000\003\158\000\000\003*\000\000\002\226\000\000\016\146\000\000\003\186\003\190\000\000\003\194\003\022\003\206\003\214\006\186\000\000\016R\016\246\002\150\000\000\000\000\003\030\017\014\002\006\000\000\007\254\b\002\b\014\b\"\000\000\005Z\000\000\000\000\002\n\000\000\000\000\000\000\000\000\017\022\000\000\b\150\001\210\027\222\000\000\000\000\000\000\000\000\b\162\b\186\t\014\005f\005j\017*\017V\000\000\000\000\004\149\000\000\003~\000\000\000\000\000\000\001\006\000\000\006\230\001\222\000\000\000\000\003:\002\162\b\246\002\150\002f\021~\005n\b\022\000\000\002\218\001\n\b.\004V\t\"\002r\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\000\001\014\001\018\001\022\003Z\001\030\001\"\000\000\000\000\006\234\000\000\000\000\002\225\000\000\003^\002\225\001.\n\242\000\000\000\000\003V\001\190\0016\002\225\000\000\001:\000\000\002\150\000\000\000\000\003\218\000\000\000\000\002\225\003\222\000\000\003\230\005N\000\n\005Z\000\000\002\225\001>\001B\001F\001J\001N\000\000\000\000\000\n\001R\005^\000\000\002\225\001V\000\000\000\000\000\000\002\225\005f\005j\000\000\005\174\001Z\002\225\002\225\002\225\002\225\000\000\001^\000\000\002\225\000\000\000\000\000\000\000\000\000\000\002\225\000\000\001\154\n\246\011\002\000\000\005n\000\000\000\000\001\158\000\000\001\162\004V\001\006\000\000\001\166\002\225\001\170\001\174\003:\002\162\n\150\002\225\002f\011\006\000\000\000\000\000\000\002\218\001\n\000\000\000\000\000\000\002r\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\000\001\014\001\018\001\022\003Z\001\030\001\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003^\000\000\001.\n\242\000\000\000\000\003V\001\190\0016\000\000\000\238\001:\000\000\002\150\000\000\000\000\003\218\000\000\000\000\000\000\003\222\000\000\003\230\005N\000\000\005Z\000\000\000\000\001>\001B\001F\001J\001N\000\000\000\000\000\000\001R\005^\000\000\000\000\001V\007\173\000\000\000\000\000\000\005f\005j\000\000\005\174\001Z\000\000\000\000\000\000\000\000\006\014\001^\000\000\005\206\011\n\000\000\000\000\000\000\000\000\000\000\006\026\001\154\n\246\000\000\006&\005n\000\000\007\173\001\158\000\000\001\162\004V\001\006\000\000\001\166\000\000\001\170\001\174\003:\002\162\r\142\007\173\002f\000\000\007\173\b\138\000\000\002\218\001\n\000\000\000\000\007\173\002r\000\000\000\000\007\173\000\000\001\210\000\000\000\000\000\000\001\014\001\018\001\022\003Z\001\030\001\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003^\000\000\001.\n\242\000\000\000\000\003V\001\190\0016\n\181\000\000\001:\000\000\002\150\000\000\000\000\003\218\000\000\000\000\000\000\003\222\000\000\003\230\005N\000\000\005Z\000\000\000\000\001>\001B\001F\001J\001N\000\000\000\000\000\000\001R\005^\000\000\n\181\001V\000\000\000\000\000\000\000\000\005f\005j\000\000\005\174\001Z\000\000\000\000\000\000\n\181\000\000\001^\n\181\011j\000\000\000\000\000\000\000\000\000\000\n\181\000\000\001\154\n\246\n\181\000\000\005n\000\000\000\000\001\158\000\000\001\162\004V\000\000\b\249\001\166\000\006\001\170\001\174\000\000\002\158\002\162\000\000\002\206\002f\000\000\000\000\000\000\000\000\002\218\000\000\000\000\000\000\000\000\b\249\000\000\b\249\b\249\000\000\001\210\000\000\000\000\000\000\002\222\000\000\003\"\003&\000\000\000\000\000\000\000\000\b\001\003*\000\000\002\226\000\000\b\001\000\000\003\186\003\190\n\194\003\194\003\022\003\206\003\214\006\186\001\202\001\206\011\"\002\150\000\000\000\000\003\030\000\000\000\000\b\001\007\254\b\002\b\014\b\"\000\000\005Z\000\000\000\000\000\000\001\210\002\142\001\230\000\000\000\000\000\000\b\150\000\000\000\000\000\000\001\242\000\000\b\001\b\162\b\186\t\014\005f\005j\000\000\000\000\b\001\000\000\000\000\001\246\002v\b\001\b\001\000\238\002\130\000\000\002\150\004\002\004\014\000\000\b\001\b\001\000\000\004\026\000\000\000\000\005n\b\022\b\249\004\253\004\253\b.\004V\t\"\004\253\000\000\004\253\004\253\000\000\004\253\004\030\004\253\004\253\b\001\000\000\004\253\b\001\004\253\004\253\004\253\004\253\004\253\004\253\004\253\004\253\b\001\004\253\016b\004\253\000\000\000\000\000\000\000\000\000\000\002\006\004\253\000\000\000\000\000\000\000\000\004\253\004\253\004\253\000\000\002\n\004\253\004\253\004\253\004\253\000\000\004\253\000\000\001\210\004\253\000\000\000\000\000\000\000\000\004\253\004\253\004\253\000\000\000\000\004\253\004\253\004\253\000\000\004\253\004\253\003~\000\000\000\000\000\000\000\000\004\253\006\230\001\222\000\000\004\253\004\253\000\000\004\253\002\150\004\253\000\000\000\000\000\000\000\000\004\253\004\253\004\253\000\000\004\253\004\253\004\253\004\253\000\000\004\253\004\253\000\000\000\000\000\000\004\253\000\000\004\253\004\253\000\000\000\000\002z\004\253\006\234\000\000\000\000\019\254\004\253\000\000\n\205\000\000\004\253\n\205\004\253\004\253\n\205\n\205\000\000\004\253\n\205\000\000\n\205\000\000\000\000\n\205\000\000\000\000\000\000\n\205\n\205\000\000\n\205\n\205\000\000\n\205\000\000\n\205\000\000\025\026\002\225\002\225\n\205\000\000\000\000\n\205\002\006\000\000\000\000\000\000\000\000\000\000\000\000\n\205\000\000\n\205\002\n\000\000\n\205\n\205\002\225\000\000\000\000\000\000\001\210\n\205\002\225\000\n\n\205\000\000\000\000\n\205\n\205\002\225\n\205\000\000\n\205\n\205\000\000\002\225\000\000\003~\002\225\002\225\000\000\000\000\000\000\006\230\001\222\n\205\000\000\000\000\000\000\000\000\002\150\002\225\000\000\n\205\n\205\000\000\000\000\n\205\000\000\n\205\000\000\000\000\000\000\000\000\005\138\000\000\000\000\000\000\000\000\001\202\001\206\n\205\n\205\000\000\n\205\n\205\000\000\n\205\006\234\n\205\000\000\n\205\000\000\n\205\000\000\n\205\b\229\b\229\001\210\001\214\001\230\b\229\000\000\001\206\b\229\000\000\000\000\000\000\001\242\000\000\000\000\018\146\b\229\000\000\b\229\b\229\b\229\000\000\b\229\b\229\b\229\001\246\019\250\000\000\019\026\000\000\002\130\000\000\002\150\004\002\004\014\000\000\b\229\000\000\000\000\020\n\000\000\000\000\b\229\b\229\000\000\000\000\b\229\000\000\000\000\002~\000\000\b\229\000\000\000\000\b\229\000\000\004\030\000\000\000\000\b\229\b\229\b\229\000\000\000\000\000\000\000\000\000\000\000\000\b\229\b\229\000\000\000\000\000\000\000\000\000\000\b\229\000\000\000\000\000\000\004~\000\000\000\000\b\229\000\000\000\000\000\000\000\000\000\000\000\000\b\229\b\229\b\229\000\000\b\229\b\229\000\000\004Y\000\000\000\000\000\000\000\000\004Y\000\000\b\229\004Y\b\229\b\229\000\000\000\000\000\000\b\229\000\000\000\000\000\000\004Y\b\229\000\000\000\000\004Y\b\229\004Y\b\229\b\229\012u\012u\000\000\000\000\004Y\012u\000\000\001\206\012u\004Y\000\000\000\000\000\000\000\000\000\000\004Y\004\158\000\000\012u\012u\012u\004&\012u\012u\012u\000\000\000\000\004Y\004Y\000\000\000\000\000\000\004Y\002\198\000\000\000\000\012u\000\000\000\000\000\000\000\000\000\000\012u\012u\000\000\000\000\012u\000\000\004Y\002~\004Y\012u\000\000\000\000\012u\000\000\000\000\000\000\004Y\012u\012u\012u\004Y\004Y\002\198\000\238\004Y\004Y\012u\012u\000\000\000\000\0046\004Y\000\000\012u\000\000\000\000\000\000\004~\000\000\000\000\012u\004Y\000\000\000\000\000\000\000\000\020\254\012u\012u\012u\000\000\012u\012u\000\000\004Y\000\000\004Y\000\000\000\000\004Y\000\000\012u\004Y\012u\012u\004Y\000\000\000\000\012u\000\000\000\000\000\000\004Y\012u\000\000\000\000\004Y\012u\004Y\012u\012u\b\233\b\233\000\000\000\000\000\000\b\233\000\000\001\206\b\233\004Y\000\000\000\000\000\000\000\000\000\000\004Y\b\233\000\000\b\233\b\233\b\233\000\000\b\233\b\233\b\233\000\000\000\000\004Y\000\000\000\000\000\000\000\000\004Y\002\198\000\000\000\000\b\233\000\000\000\000\000\000\000\000\000\000\b\233\b\233\000\000\000\000\b\233\000\000\004Y\002~\000\000\b\233\000\000\000\000\b\233\000\000\000\000\000\000\000\000\b\233\b\233\b\233\004Y\004Y\000\000\000\000\004Y\004Y\b\233\b\233\002\225\000\000\007R\000\000\000\000\b\233\000\000\002\225\000\000\004~\000\000\000\000\b\233\004Y\000\000\000\000\000\000\000\000\002\225\b\233\b\233\b\233\002\225\b\233\b\233\001*\000\n\002\225\002\225\002\225\000\000\000\000\002\225\b\233\002\225\b\233\b\233\002\225\002\225\002\225\b\233\002\225\002\225\002\225\002\225\b\233\002\225\002\225\002\225\b\233\002\225\b\233\b\233\000\000\002\225\000\n\000\000\002\225\000\n\002\225\000\000\002\225\000\000\002\225\002\225\000\n\000\000\002\225\002\225\000\n\002\225\002\225\002\225\002\225\000\000\000\000\002\225\002\225\000\000\002\225\002\225\002\225\002\225\002\225\002\225\000\000\002\225\002\225\000\000\002\225\002\225\002\225\000\000\002\225\002\225\002\225\002\225\002\225\002\225\002\225\000\000\002\225\000\000\000\000\000\000\000\000\000\000\000\000\002\225\002\225\002\225\002\225\002\225\000\000\000\000\000\000\002\225\002\225\002\225\002\225\002\225\000\000\006\141\000\000\0009\002\225\002\225\000\000\0009\0009\000\000\0009\0009\002\225\000\000\000\000\000\000\0009\000\000\002\225\000\000\003\162\006\141\002\225\002\225\000\000\000\000\0009\002\225\002\225\002\225\0009\006\194\0009\0009\000\000\000\000\000\000\000\000\000\000\0009\000\000\0009\000\000\000\000\000\000\0009\0009\000\000\0009\0009\0009\0009\0009\000\000\000\000\000\000\0009\000\000\000\000\0009\000\000\000\000\000\000\0009\0009\0009\0009\000\000\0009\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0009\000\000\000\000\000\000\000\000\000\000\000\000\0009\0009\0009\0009\0009\000\000\006\137\000\000\0005\000\000\000\000\000\000\0005\0005\000\000\0005\0005\000\000\000\000\000\000\000\000\0005\000\000\000\000\000\000\000\000\006\137\0009\0009\000\000\000\000\0005\0009\0009\0009\0005\000\000\0005\0005\000\000\000\000\000\000\000\000\000\000\0005\000\000\0005\000\000\000\000\000\000\0005\0005\000\000\0005\0005\0005\0005\0005\000\000\000\000\000\000\0005\000\000\000\000\0005\000\000\000\000\000\000\0005\0005\0005\0005\000\000\0005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0005\000\000\000\000\000\000\000\000\000\000\000\000\0005\0005\0005\0005\0005\000\000\006\153\000\000\012=\000\000\000\000\000\000\012=\012=\000\000\012=\012=\000\000\000\000\000\000\000\000\012=\000\000\000\000\000\000\000\000\006\153\0005\0005\000\000\000\000\012=\0005\0005\0005\012=\000\000\012=\012=\000\000\000\000\000\000\000\000\000\000\012=\000\000\012=\000\000\000\000\000\000\012=\012=\000\000\012=\012=\012=\012=\012=\000\000\000\000\000\000\012=\000\000\000\000\012=\000\000\000\000\000\000\012=\012=\012=\012=\000\000\012=\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012=\000\000\000\000\000\000\000\000\000\000\000\000\012=\012=\012=\012=\012=\000\000\006\149\000\000\0129\000\000\000\000\000\000\0129\0129\000\000\0129\0129\000\000\000\000\000\000\000\000\0129\000\000\000\000\000\000\000\000\006\149\012=\012=\000\000\000\000\0129\012=\012=\012=\0129\000\000\0129\0129\000\000\000\000\000\000\000\000\000\000\0129\000\000\0129\000\000\000\000\000\000\0129\0129\000\000\0129\0129\0129\0129\0129\000\000\001\202\001\206\0129\000\000\000\000\0129\000\000\000\000\000\000\0129\0129\0129\0129\000\000\0129\000\000\000\000\000\000\000\000\001\210\001\214\001\230\000\000\000\000\0129\000\000\000\000\000\000\000\000\001\242\000\000\0129\0129\0129\0129\0129\001\250\000\000\000\000\000\000\000\000\000\000\001\246\002v\000\000\000\000\000\000\002\130\000\000\002\150\004\002\004\014\012y\012y\000\000\000\000\004\026\012y\0129\0129\012y\000\000\000\000\0129\0129\0129\000\000\000\000\004n\000\000\012y\012y\012y\004\030\012y\012y\012y\000\000\001\021\000\000\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\012y\000\000\000\000\000\000\000\000\000\000\012y\012y\000\000\000\000\012y\000\000\000\000\000\000\001\021\012y\000\000\000\000\012y\000\000\000\000\000\000\000\000\012y\012y\012y\000\000\000\000\000\000\000\000\000\000\000\000\012y\012y\000\000\000\000\001\021\000\000\018\154\012y\000\000\000\000\000\000\012y\001\021\000\000\012y\000\000\000\000\001\021\000\000\000\000\000\000\012y\012y\012y\000\000\012y\012y\001\021\000\000\000\000\000\000\000\000\000\000\000\000\007\253\012y\000\006\012y\012y\007\253\002\158\002\162\012y\002\206\002f\000\000\000\000\012y\000\000\002\218\000\000\012y\001\021\012y\012y\000\000\003\226\000\000\007\253\001\210\000\000\001\021\000\000\002\222\000\000\003\"\003&\000\000\000\000\000\000\000\000\000\000\003*\000\000\002\226\000\000\000\000\000\000\003\186\003\190\007\253\003\194\003\022\003\206\003\214\006\186\000\000\000\000\007\253\002\150\000\000\000\000\003\030\007\253\007\253\000\238\007\254\b\002\b\014\b\"\000\000\005Z\007\253\007\253\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\150\000\000\000\000\000\000\000\000\000\000\000\000\b\162\b\186\t\014\005f\005j\000\000\000\000\007\253\000\000\000\000\007\253\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\000\007\253\002\158\002\162\000\000\002\206\002f\000\000\000\000\005n\b\022\002\218\000\000\000\000\b.\004V\t\"\000\000\014R\000\000\000\000\001\210\000\000\000\000\000\000\002\222\000\000\003\"\003&\000\000\000\000\000\000\001\197\000\000\003*\000\000\002\226\001\197\000\000\000\000\003\186\003\190\000\000\003\194\003\022\003\206\003\214\006\186\000\000\000\000\000\000\002\150\000\000\000\000\003\030\000\000\001\197\000\000\007\254\b\002\b\014\b\"\000\000\005Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005-\012\217\b\150\000\000\000\000\0051\012\217\001\197\000\000\b\162\b\186\t\014\005f\005j\000\000\001\197\000\000\000\000\000\000\005-\001\197\001\197\000\238\005-\0051\000\000\003\029\003\029\0051\001\197\001\197\003\029\000\000\000\000\003\029\000\000\005n\b\022\000\000\000\000\000\000\b.\004V\t\"\003\029\003\029\003\029\000\000\003\029\003\029\003\029\000\000\000\000\000\000\000\000\001\197\000\000\000\000\000\000\000\000\000\000\000\000\003\029\000\000\001\197\000\000\000\000\000\000\003\029\004f\000\000\000\000\003\029\000\000\000\000\000\000\000\000\003\029\012\217\012\217\003\029\000\000\000\000\012\217\012\217\003\029\003\029\003\029\000\000\000\000\000\000\005-\000\000\000\000\003\029\003\029\0051\012\217\000\000\012\217\000\000\003\029\012\217\000\000\012\217\003\029\005-\000\000\003\029\005-\000\000\0051\000\000\000\000\0051\003\029\003\029\003\029\004}\003\029\003\029\000\000\000\000\018\170\000\000\000\000\000\000\000\000\000\000\003\029\000\000\003\029\003\029\000\000\000\000\000\000\003\029\000\000\000\000\000\000\000\000\003\029\003\154\n\217\000\000\003\029\n\217\003\029\003\029\003:\002\162\000\000\000\000\002f\000\000\006\138\000\000\000\000\002\218\000\000\000\000\000\000\n\217\n\217\018\214\n\217\n\217\000\000\001\210\000\000\006\170\000\000\016\246\000\000\000\000\003>\000\000\017\014\b\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\217\019\018\003J\000\000\000\000\003V\001\190\000\000\000\000\000\000\000\000\000\000\002\150\000\000\000\000\003\218\000\000\000\000\n\217\003\222\000\000\003\230\005N\n\162\005Z\000\000\004}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\019v\005^\001\202\001\206\000\000\000\000\000\000\000\000\000\000\005f\005j\000\000\005\174\n\217\000\000\n\217\000\000\000\000\000\000\000\000\000\000\001\210\001\214\000\000\000\000\000\000\000\000\n\217\000\000\000\000\n\217\n\217\000\000\005n\000\000\n\217\000\000\n\217\000\000\004V\n\213\n\217\000\000\n\213\001\246\002\134\003:\002\162\000\000\002\130\002f\002\150\004\002\004\014\000\000\002\218\000\000\000\000\004\026\n\213\n\213\000\000\n\213\n\213\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003>\000\000\000\000\004\030\000\000\000\000\025\250\000\000\000\000\000\000\000\000\n\213\000\000\003J\000\000\000\000\003V\001\190\000\000\000\000\000\000\000\000\025\230\002\150\000\000\000\000\003\218\000\000\000\000\n\213\003\222\000\000\003\230\005N\000\000\005Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005^\000\000\012Y\000\000\000\000\012Y\000\000\000\000\005f\005j\000\000\005\174\n\213\000\000\n\213\012Y\000\000\000\000\000\000\000\000\000\000\012Y\000\000\001\221\001\221\000\000\n\213\000\000\001\221\n\213\n\213\001\221\005n\012Y\n\213\000\000\n\213\000\000\004V\012Y\n\213\001\221\001\221\001\221\000\000\001\221\001\221\001\221\012Y\000\000\000\000\012Y\000\000\000\000\000\000\000\000\012Y\000\000\000\000\001\221\000\000\000\000\000\000\000\000\000\000\001\221\001\221\000\000\000\000\001\221\000\000\000\000\012Y\000\000\001\221\000\000\012Y\001\221\000\000\000\000\000\000\000\000\001\221\001\221\001\221\000\000\012Y\012Y\000\000\000\000\012Y\001\221\001\221\000\000\000\000\000\000\027\214\000\000\001\221\001\r\000\000\000\000\001\221\000\000\001\r\001\221\000\000\012Y\000\000\000\000\000\000\000\000\001\221\001\221\001\221\000\000\001\221\001\221\000\000\000\000\000\000\000\000\000\000\001\r\000\000\000\000\001\221\000\000\001\221\001\221\003:\002\162\000\000\001\221\002f\000\000\006\138\000\000\001\221\002\218\000\000\000\000\004\226\000\000\001\221\001\r\000\000\0036\000\000\001\210\000\000\006\170\000\000\001\r\000\000\000\000\003>\000\000\001\r\b\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\r\001\r\003J\000\000\000\000\n\146\001\190\000\000\000\000\000\000\000\000\000\000\002\150\000\000\000\000\003\218\000\000\000\000\n\177\003\222\000\000\003\230\000\000\n\162\005Z\000\000\001\r\000\000\003:\002\162\000\000\000\000\002f\000\000\006\138\001\r\005^\002\218\000\000\000\000\000\000\000\000\000\000\000\000\005f\005j\000\000\001\210\n\170\006\170\000\000\000\000\000\000\000\000\003>\000\000\000\000\b\198\000\000\000\000\000\000\000\000\n\177\n\178\000\000\n\177\011\030\003J\005n\000\000\n\146\001\190\n\177\000\000\004V\000\000\n\177\002\150\000\000\000\000\003\218\000\000\000\000\n\177\003\222\000\000\003\230\000\000\n\162\005Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005f\005j\000\000\000\000\n\170\005}\005}\000\000\000\000\000\000\005}\000\000\000\000\005}\000\000\000\000\000\000\000\000\n\177\000\000\000\000\n\177\n\177\005}\005n\005}\000\000\005}\n\177\005}\004V\000\000\n\177\000\000\000\000\000\000\000\000\000\000\000\000\000\246\000\000\005}\002\166\000\000\000\000\000\000\000\000\005}\005}\000\000\000\000\000\000\028.\005}\000\000\000\000\005}\000\000\003\154\005}\000\000\000\000\000\000\000\000\005}\005}\005}\000\000\000\000\000\000\003\158\000\000\000\000\000\000\000\000\000\000\016\146\000\000\000\000\000\000\005}\005}\000\000\000\000\005}\024>\000\000\001\006\016\246\000\000\000\000\000\000\000\000\017\014\005}\005}\005}\000\000\005}\005}\000\000\000\000\000\000\001\n\007R\000\000\000\000\002r\000\000\017\022\000\000\005}\000\000\027\222\005}\005}\001\014\001\018\001\022\001\026\001\030\001\"\000\000\017*\017V\000\000\005}\004\149\000\000\001&\000\000\001.\0012\000\000\000\000\000\000\000\000\0016\004a\000\000\001:\000\000\000\000\000\246\021~\000\000\002\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\150\001>\001B\001F\001J\001N\003\154\005q\005q\001R\000\000\000\000\005q\001V\000\000\005q\000\000\000\000\017\154\000\000\000\000\000\000\001Z\000\000\017\194\005q\000\000\005q\001^\005q\000\000\005q\000\000\000\000\000\000\000\000\016\246\000\000\001\154\027\018\000\000\017\014\000\000\005q\000\000\001\158\000\000\001\162\000\000\005q\005q\001\166\000\000\001\170\001\174\007\194\000\000\018>\005q\000\000\000\000\005q\000\000\000\000\000\000\000\000\005q\005q\000\238\000\000\000\000\017*\018R\000\000\000\000\004a\004a\000\000\000\000\000\000\000\000\000\000\005q\005q\000\000\000\000\005q\000\000\b\245\000\000\000\000\000\000\018b\000\000\000\000\000\000\005q\005q\005q\000\000\005q\005q\000\000\000\000\t\174\000\000\000\000\012\030\b\245\000\000\b\245\b\245\000\000\005q\000\000\000\000\005q\005q\t\230\t\254\n\006\t\238\n\014\000\000\000\000\001\202\002b\000\000\005q\002f\000\000\000\000\n\022\n\030\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n&\000\000\000\000\001\210\001\214\001\230\002j\000\000\000\238\000\000\000\000\000\000\000\000\001\242\001\006\000\000\000\000\t\182\t\246\n.\n6\nF\000\000\000\000\000\000\000\000\002n\002v\000\000\nN\001\n\002\130\000\000\002\150\004\002\004\014\000\000\000\000\nV\000\000\020\214\000\000\020\218\001\014\001\018\001\022\001\026\001\030\001\"\000\000\000\000\000\000\nv\000\000\n~\n>\001&\004\030\001.\0012\b\245\n^\000\000\000\000\0016\000\000\005j\001:\000\000\nf\nn\000\000\000\000\000\000\000\000\000\000\020\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001>\001B\001F\001J\001N\000\000\003]\003]\001R\020\234\000\000\003]\001V\000\000\003]\000\000\000\000\000\000\000\000\000\000\000\000\001Z\000\000\000\000\003]\000\000\003]\001^\003]\000\000\003]\000\000\000\000\000\000\000\000\000\000\000\000\001\154\027.\000\000\000\000\000\000\003]\000\000\001\158\000\000\001\162\000\000\003]\003]\001\166\000\000\001\170\001\174\005\005\000\000\000\000\003]\000\000\000\000\003]\000\000\000\000\000\000\000\000\003]\003]\003]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003]\000\000\001\202\001\206\003]\bq\bq\000\000\000\000\000\000\bq\000\000\000\000\bq\003]\003]\003]\000\000\003]\003]\000\000\001\210\001\214\bq\005\005\bq\000\000\bq\000\000\bq\000\000\003]\000\000\000\000\000\000\003]\000\000\000\000\000\000\000\000\000\000\bq\000\000\000\000\001\246\002~\003]\bq\bq\002\130\000\000\002\150\004\002\004\014\000\000\000\000\bq\000\000\004\026\bq\015\130\000\000\000\000\000\000\bq\bq\bq\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\030\000\000\000\000\000\000\000\000\bq\000\000\000\000\000\000\bq\r%\r%\000\000\000\000\000\000\r%\000\000\000\000\r%\bq\bq\bq\000\000\bq\bq\000\000\000\000\000\000\r%\000\000\r%\000\000\r%\bq\r%\000\000\bq\000\000\000\000\000\000\bq\000\000\000\000\000\000\000\000\000\000\r%\000\000\000\000\004\226\000\000\bq\r%\r%\r)\r)\000\000\000\000\004&\r)\000\000\r%\r)\000\000\r%\000\000\000\000\000\000\000\000\r%\r%\r%\r)\000\000\r)\000\000\r)\000\000\r)\000\000\000\000\000\000\000\000\000\000\000\000\r%\000\000\000\000\000\000\r%\r)\000\000\000\000\000\000\000\000\000\000\r)\r)\000\000\r%\r%\r%\004&\r%\r%\r)\000\000\000\000\r)\0046\000\000\000\000\000\000\r)\r)\r)\r%\000\000\000\000\000\000\r%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\r)\000\000\r%\000\000\r)\003]\003]\000\000\000\000\000\000\003]\000\000\000\000\003]\r)\r)\r)\000\000\r)\r)\000\000\000\000\000\000\003]\0046\003]\000\000\003]\000\000\003]\000\000\r)\001\202\001\206\000\000\r)\000\000\000\000\000\000\000\000\000\000\003]\000\000\000\000\000\000\000\000\r)\003]\003]\000\000\000\000\001\210\001\214\005\t\000\000\000\000\003]\000\000\000\000\003]\000\000\000\000\000\000\000\000\003]\003]\003]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\246\002\134\000\000\000\000\000\000\002\130\003]\002\150\004\002\004\014\003]\001\205\000\000\000\000\004\026\000\000\001\205\000\000\001\206\001\205\003]\003]\003]\000\000\003]\003]\000\000\b\209\000\000\001\205\005\t\004\030\000\000\001\205\004\205\001\205\000\000\003]\000\000\000\000\000\000\003]\000\000\004Y\000\000\000\000\000\000\001\205\004Y\000\000\025\230\000\000\003]\001\205\001\205\000\000\000\000\000\000\000\000\000\000\002~\000\000\001\205\000\000\000\000\001\205\000\000\004Y\000\000\000\000\001\205\001\205\001\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\205\001\205\000\000\004Y\004~\003A\000\000\000\000\000\000\000\000\003A\004Y\001\206\003A\001\205\001\205\004Y\002\198\001\205\001\205\000\000\b\205\000\000\003A\000\000\004Y\004Y\003A\001\205\003A\000\000\000\000\000\000\000\000\000\000\001\205\000\000\000\000\000\000\000\000\001\205\003A\000\000\000\000\000\000\000\000\001\205\003A\001\201\000\000\000\181\004Y\000\000\000\000\002~\000\181\003A\000\000\000\181\003A\004Y\000\000\000\000\000\000\003A\003A\003A\000\000\000\181\000\000\000\181\000\000\000\181\000\000\000\181\000\000\000\000\000\000\000\000\000\000\003A\003A\000\000\000\000\004~\000\000\000\181\000\000\000\000\000\000\000\000\000\000\000\181\000\000\003A\003A\000\181\000\000\003A\003A\000\000\000\181\000\000\000\000\000\181\000\000\000\000\000\000\003A\000\181\000\181\000\238\000\000\000\000\000\000\003A\000\000\000\000\000\181\000\181\003A\000\000\000\000\000\000\000\000\000\181\003A\000\000\000\249\000\181\000\000\000\000\000\000\000\249\000\000\000\000\000\249\000\000\000\000\000\181\000\181\000\000\000\000\000\181\000\181\000\000\000\249\000\000\000\249\000\000\000\249\000\000\000\249\000\181\000\000\000\000\000\000\000\000\000\000\000\181\000\181\000\000\000\000\000\000\000\249\000\000\000\000\000\000\000\000\000\181\000\249\000\181\000\000\000\000\000\249\000\000\000\000\000\000\000\000\000\249\000\000\000\000\000\249\000\000\000\000\000\000\000\000\000\249\000\249\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\249\000\249\000\000\000\000\000\000\000\000\000\000\000\249\000\000\000\000\000\189\000\249\000\000\000\000\000\000\000\189\000\000\000\000\000\189\000\000\000\000\000\249\000\249\000\000\000\000\000\249\000\249\000\000\000\189\000\000\000\189\000\000\000\189\000\000\000\189\000\249\000\000\000\000\000\000\000\000\000\000\000\249\000\249\000\000\000\000\000\000\000\189\000\000\000\000\000\000\000\000\000\249\000\189\000\249\000\000\000\000\000\189\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\189\000\000\000\000\000\000\000\000\000\189\000\189\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\189\000\189\000\000\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\185\000\189\000\000\000\000\006\221\000\185\000\000\000\000\000\185\006\221\000\000\000\189\000\189\000\000\000\000\000\189\000\189\000\000\000\185\000\000\000\185\000\000\000\185\000\000\000\185\000\189\000\000\000\000\006\221\000\000\000\000\000\189\000\189\000\000\000\000\000\000\000\185\000\000\000\000\000\000\000\000\000\189\000\185\000\189\000\000\000\000\000\185\000\000\000\000\000\000\006\221\000\185\000\000\000\000\000\185\000\000\000\000\000\000\006\221\000\185\000\185\000\238\000\000\006\221\006\221\000\238\000\000\000\000\000\185\000\185\000\000\000\000\006\221\006\221\000\000\000\185\000\000\000\000\001\169\000\185\000\000\000\000\000\000\001\169\000\000\000\000\001\169\000\000\000\000\000\185\000\185\000\000\000\000\000\185\000\185\000\000\001\169\000\000\006\221\000\000\001\169\012\229\001\169\000\185\000\000\000\000\012\229\006\221\000\000\000\185\000\185\000\000\000\000\000\000\001\169\001\169\000\000\000\000\000\000\000\185\001\169\000\185\000\000\023\158\000\000\012\229\005\005\000\000\000\000\001\169\000\000\000\000\001\169\000\000\000\000\000\000\000\000\001\169\001\169\001\169\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\229\000\000\000\000\000\000\000\000\000\000\001\169\000\000\012\229\000\000\001\169\r!\r!\012\229\012\229\000\238\r!\000\000\000\000\r!\001\169\001\169\012\229\012\229\001\169\001\169\000\000\000\000\000\000\r!\005\005\r!\000\000\r!\001\169\r!\000\000\000\000\000\000\000\000\001\169\001\169\000\000\000\000\000\000\000\000\001\169\r!\012\229\000\000\000\000\000\000\001\169\r!\r!\000\000\000\000\012\229\000\000\000\000\000\000\000\000\r!\000\000\000\000\r!\000\000\000\000\000\000\000\000\r!\r!\r!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\r!\000\000\000\000\000\000\r!\r\029\r\029\000\000\000\000\000\000\r\029\000\000\000\000\r\029\r!\r!\r!\000\000\r!\r!\000\000\000\000\000\000\r\029\000\000\r\029\000\000\r\029\000\000\r\029\000\000\r!\000\000\000\000\000\000\r!\000\000\000\000\000\000\000\000\000\000\r\029\000\000\000\000\004\226\000\000\r!\r\029\r\029\000\000\000\000\000\000\000\000\000\000\000\000\004a\r\029\000\000\000\000\r\029\000\246\000\000\000\000\002\018\r\029\r\029\r\029\000\000\000\000\000\000\000\000\000\000\000\000\017\150\000\000\000\000\000\000\004a\000\000\003\154\r\029\000\000\bu\bu\r\029\000\000\000\000\bu\000\000\000\000\bu\017\154\000\000\000\000\r\029\r\029\r\029\017\194\r\029\r\029\bu\000\000\bu\000\000\bu\000\000\bu\000\000\007.\016\246\000\000\r\029\000\000\000\000\017\014\r\029\000\000\000\000\bu\000\000\000\000\000\000\000\000\000\000\bu\bu\r\029\000\000\000\000\000\000\018>\000\000\000\000\bu\000\000\000\000\bu\000\000\000\000\000\000\000\000\bu\bu\000\238\017*\018R\000\000\000\000\004a\004a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bu\000\000\000\000\000\000\bu\000\000\006\241\000\000\018b\000\000\000\000\000\000\000\000\000\000\bu\bu\bu\000\000\bu\bu\000\000\000\000\t\174\000\000\000\000\006\241\000\000\000\000\bu\006\241\000\000\bu\000\000\000\000\000\000\bu\t\230\t\254\n\006\t\238\n\014\000\000\000\000\000\000\000\000\000\000\bu\001\201\000\000\000\000\n\022\n\030\001\201\000\000\001\206\001\201\000\000\000\000\000\000\n&\000\000\000\000\000\000\b\205\000\000\001\201\000\000\000\238\000\000\001\201\000\000\001\201\000\000\000\000\000\000\000\000\t\182\t\246\n.\n6\nF\000\000\000\000\001\201\000\000\000\000\000\000\006\241\nN\001\201\000\000\000\000\000\000\000\000\000\000\000\000\002~\nV\001\201\000\000\000\000\001\201\000\000\000\000\000\000\000\000\001\201\001\201\001\201\000\000\000\000\nv\000\000\n~\n>\000\000\000\000\000\000\000\000\000\000\n^\000\000\001\201\001\201\000\000\000\000\004~\000\000\nf\nn\000\000\000\000\000\000\016F\000\000\000\000\001\201\001\201\000\000\000\000\001\201\001\201\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\174\001\201\000\000\000\000\016J\000\000\000\000\000\000\001\201\000\000\000\000\000\000\000\000\001\201\t\230\t\254\n\006\t\238\n\014\001\201\000\000\000\000\000\000\000\000\000\000\n\182\000\000\000\000\n\022\n\030\000\246\001\202\001\206\002\018\000\000\000\000\000\000\n&\000\000\000\000\000\000\000\000\000\000\017\150\000\000\000\238\000\000\004a\000\000\003\154\001\210\001\214\001\230\000\000\t\182\t\246\n.\n6\nF\000\000\001\242\017\154\000\000\000\000\000\000\000\000\nN\017\194\000\000\000\000\000\000\000\000\000\000\001\246\002v\nV\000\000\000\000\002\130\016\246\002\150\004\002\004\014\000\000\017\014\000\000\000\000\004\026\000\000\nv\016N\n~\n>\016^\000\000\000\000\000\000\000\000\n^\000\000\018>\000\000\000\000\000\000\004\030\000\000\nf\nn\005\169\005\169\000\000\000\000\000\000\005\169\017*\018R\005\169\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\169\000\000\005\169\000\000\005\169\000\000\005\169\000\000\000\000\018b\000\000\000\000\000\000\000\000\004R\000\000\004V\000\000\005\169\000\000\000\000\000\000\000\000\000\000\005\169\005\169\000\000\000\000\000\000\000\000\007\194\000\000\000\000\005\169\000\000\000\000\005\169\000\000\006I\000\000\000\000\005\169\005\169\000\238\000\000\002\162\000\000\000\000\002f\000\000\000\000\000\000\000\000\002\218\000\000\002\225\002\225\005\169\006I\002\225\000\000\005\169\000\000\001\210\002\225\000\000\000\000\002\222\000\000\000\000\002\225\005\169\005\169\005\169\002\225\005\169\005\169\000\000\002\226\000\000\000\000\002\225\000\n\000\000\000\000\006\190\003\022\001\190\005\169\000\000\000\000\015\030\005\169\002\150\002\225\000\000\003\030\002\225\002\225\000\000\007\254\b\002\b\014\005\169\002\225\005Z\000\000\002\225\000\000\000\000\002\225\002\225\000\000\002\225\002\225\000\000\002\225\000\000\000\000\000\000\000\000\000\000\005\165\007\002\000\000\005f\005j\005\165\002\225\000\000\005\165\000\000\000\000\000\000\000\000\000\000\002\225\002\225\000\000\015Z\005\165\000\000\005\165\000\000\005\165\000\000\005\165\000\000\000\000\005n\b\022\000\000\000\000\000\000\b.\004V\000\000\000\000\005\165\000\000\002\225\000\000\000\000\000\000\005\165\007n\002\225\000\000\000\000\000\000\000\000\000\000\000\000\005\165\000\000\000\000\005\165\000\000\000\000\004\133\000\000\005\165\005\165\000\238\021\166\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\165\000\000\005\193\005\193\005\165\000\000\003\154\005\193\000\000\000\000\005\193\000\000\000\000\000\000\005\165\005\165\005\165\000\000\005\165\005\165\005\193\000\000\005\193\000\000\005\193\000\000\005\193\000\000\022\022\000\000\000\000\005\165\000\000\000\000\000\000\005\165\016\246\000\000\005\193\000\000\000\000\017\014\000\000\000\000\005\193\005\193\005\165\000\000\000\000\000\000\022\186\022\202\000\000\005\193\000\000\000\000\005\193\000\000\000\000\000\000\000\000\005\193\005\193\005\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\133\005\193\000\000\005\189\007\002\005\193\000\000\000\000\005\189\023\190\000\000\005\189\000\000\000\000\000\000\005\193\005\193\005\193\000\000\005\193\005\193\005\189\000\000\005\189\000\000\005\189\000\000\005\189\000\000\000\000\000\000\000\000\005\193\000\000\000\000\000\000\005\193\000\000\000\000\005\189\000\000\000\000\000\000\000\000\000\000\005\189\007n\007f\000\000\000\000\000\000\000\000\000\000\000\000\005\189\000\000\000\000\005\189\000\000\000\000\000\000\000\000\005\189\005\189\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\189\003:\002\162\000\000\005\189\002f\000\000\006\138\000\000\000\000\002\218\000\000\000\000\000\000\005\189\005\189\005\189\000\000\005\189\005\189\001\210\000\000\006\170\000\000\000\000\000\000\000\000\003>\000\000\000\000\b\198\005\189\000\000\000\000\000\000\005\189\000\000\000\000\000\000\000\000\003J\000\000\000\000\n\146\001\190\000\000\005\189\012\158\000\000\000\000\002\150\000\000\000\000\003\218\000\000\000\000\000\000\003\222\000\000\003\230\000\000\n\162\005Z\t\174\000\000\000\000\012\030\000\000\000\000\000\000\b\245\000\000\000\000\000\000\005^\000\000\000\000\t\230\t\254\n\006\t\238\n\014\005f\005j\000\000\000\000\n\170\000\000\000\000\000\000\000\000\n\022\n\030\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n&\n\178\000\000\000\000\n\190\000\000\005n\000\000\000\238\000\000\000\000\000\000\004V\000\000\000\000\000\000\000\000\t\182\t\246\n.\n6\nF\000\000\003=\000\000\000\000\000\000\000\000\003=\nN\001\206\003=\000\000\000\000\000\000\000\000\000\000\000\000\nV\000\000\000\000\003=\000\000\000\000\000\000\003=\000\000\003=\000\000\000\000\000\000\000\000\nv\000\000\n~\n>\000\000\000\000\000\000\003=\000\000\n^\000\000\000\000\000\000\003=\000\000\000\000\001M\nf\nn\000\000\002~\001M\003=\000\000\001M\003=\000\000\000\000\000\000\000\000\003=\003=\003=\000\000\001M\000\000\001M\000\000\001M\000\000\001M\000\000\000\000\000\000\000\000\000\000\003=\003=\000\000\000\000\004~\000\000\001M\000\000\000\000\000\000\000\000\000\000\001M\000\000\003=\003=\001M\000\000\003=\003=\000\000\001M\000\000\000\000\001M\000\000\000\000\000\000\003=\001M\001M\000\238\000\000\001I\000\000\003=\000\000\000\000\001I\001M\003=\001I\000\000\000\000\000\000\001M\003=\000\000\000\000\001M\000\000\001I\000\000\001I\000\000\001I\000\000\001I\000\000\001M\001M\001M\000\000\001M\001M\000\000\000\000\000\000\000\000\001I\000\000\000\000\000\000\001M\000\000\001I\000\000\000\000\000\000\001I\001M\000\000\000\000\000\000\001I\000\000\000\000\001I\000\000\000\000\000\000\001M\001I\001I\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001I\000\000\000\000\000\000\000\000\000\000\001I\000\000\000\000\000\000\001I\001\133\000\000\000\000\000\000\000\000\001\133\000\000\012\153\001\133\001I\001I\001I\000\000\001I\001I\000\000\012\153\000\000\001\133\000\000\001\133\000\000\001\133\001I\001\133\000\000\000\000\000\000\000\000\000\000\001I\000\000\000\000\000\000\000\000\000\000\001\133\000\000\000\000\000\000\000\000\001I\001\133\012\153\000\000\000\000\000\000\000\000\000\000\012\153\000\000\000\000\000\000\000\000\001\133\000\000\000\000\000\000\000\000\001\133\001\133\001\133\000\000\000\000\0019\000\000\000\000\000\000\000\000\0019\000\000\000\157\0019\000\000\000\000\001\133\000\000\000\000\000\000\012\153\000\157\000\000\0019\000\000\0019\000\000\0019\000\000\0019\001\133\001\133\001\133\000\000\001\133\001\133\000\000\000\000\000\000\000\000\000\000\0019\000\000\000\000\000\000\000\000\000\000\0019\000\157\000\000\000\000\001\133\000\000\000\000\000\157\000\000\000\000\000\000\000\000\0019\000\000\000\000\001\133\000\000\0019\0019\0019\000\000\001\213\000\000\000\000\000\000\000\000\001\213\000\000\015f\001\213\000\000\002f\000\000\0019\000\000\000\000\000\000\000\157\000\000\001\213\000\000\000\000\000\000\001\213\000\000\001\213\000\000\0019\0019\0019\000\000\0019\0019\000\000\000\000\000\000\000\000\001\213\000\000\000\000\000\000\000\000\000\000\001\213\000\000\000\000\000\000\000\000\0019\015j\000\000\000\000\001\213\000\000\000\000\001\213\000\000\000\000\000\000\0019\001\213\001\213\000\000\015v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\213\000Y\000\000\000\000\001\213\000\000\000Y\000\000\000Y\000\000\000\000\000\000\000\000\005j\001\213\001\213\000\000\000Y\001\213\001\213\000Y\000\000\000\000\000\000\000Y\000Y\000\000\b\145\001\213\000\000\000\000\000\000\000\000\000\000\000\000\001\213\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000Y\000\000\001\213\000Y\000\000\000\000\000Y\000\000\000\000\000\000\000\000\000Y\000\000\000\000\000\000\000\000\000Y\000Y\000Y\000\000\000\000\000\000\000\000\000\000\000\000\000Y\000Y\000\000\003:\002\162\000\000\000\000\002f\000\000\006\138\000\000\000Y\002\218\000\000\000Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\210\000Y\006\170\000\000\000Y\000\000\000\000\003>\000\000\b\145\b\198\000\000\000\000\000Y\004Y\007\002\000Y\000\000\t\n\004Y\003J\000\000\004Y\r\138\001\190\000\000\000\000\000\000\000\000\000Y\002\150\000\000\004Y\003\218\000\000\000\000\004Y\003\222\004Y\003\230\000\000\n\162\005Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Y\000\000\000\000\000\000\005^\000\000\004Y\007n\000\000\000\000\004Y\000\000\005f\005j\000\000\004Y\000\000\000\000\004Y\000\000\000\000\000\000\000\000\004Y\002\198\000\238\000\000\000\000\000\000\000\000\000\000\000\000\004Y\004Y\r\154\000\000\005n\000\000\000\000\004Y\004Y\000\000\004V\004Y\000\000\011\250\000\000\000\000\000\000\000\000\011\250\000\000\000\000\004Y\004Y\000\000\000\000\004Y\004Y\000\000\000\000\t\174\000\000\000\000\000\000\000\000\t\174\004Y\011\254\000\000\000\000\000\000\000\000\012\214\004Y\t\230\t\254\n\006\t\238\n\014\t\230\t\254\n\006\t\238\n\014\004Y\000\000\000\000\000\000\n\022\n\030\000\000\000\000\000\000\n\022\n\030\000\000\000\000\n&\000\000\000\000\000\000\000\000\n&\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\t\182\t\246\n.\n6\nF\t\182\t\246\n.\n6\nF\000\000\000\000\nN\000\000\000\000\000\000\000\000\nN\000\000\000\000\000\000\nV\000\000\0035\000\000\000\000\nV\000\000\0035\000\000\000\000\0035\000\000\000\000\000\000\nv\000\000\n~\n>\000\000\nv\0035\n~\n>\n^\0035\000\000\0035\000\000\n^\000\000\000\000\nf\nn\000\000\000\000\000\000\nf\nn\0035\015~\000\000\000\000\000\000\000\000\0035\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0035\000\000\000\000\0035\000\000\000\000\000\000\000\000\0035\0035\0035\003:\002\162\000\000\000\000\002f\000\000\006\138\000\000\000\000\002\218\000\000\000\000\000\000\0035\000\000\000\000\000\000\0035\000\000\001\210\000\000\006\170\000\000\000\000\000\000\000\000\003>\0035\0035\b\198\000\000\0035\0035\000\000\000\000\000\000\000\000\023&\000\000\003J\000\000\0035\003V\001\190\000\000\000\000\000\000\015\222\0035\002\150\000\000\000\000\003\218\0035\000\000\000\000\003\222\000\000\003\230\0035\n\162\005Z\000\000\000\000\000\000\003:\002\162\000\000\000\000\002f\000\000\006\138\000\000\005^\002\218\000\000\000\000\000\000\000\000\000\000\000\000\005f\005j\000\000\001\210\021\150\006\170\000\000\000\000\000\000\000\000\003>\000\000\000\000\b\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\023\242\003J\005n\000\000\n\146\001\190\000\000\000\000\004V\000\000\000\000\002\150\000\000\000\000\003\218\000\000\000\000\000\000\003\222\000\000\003\230\000\000\n\162\005Z\000\000\000\000\000\000\003:\002\162\000\000\000\000\002f\000\000\006\138\000\000\005^\002\218\000\000\000\000\000\000\000\000\000\000\000\000\005f\005j\000\000\001\210\n\170\006\170\000\000\000\000\000\000\000\000\003>\000\000\000\000\b\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\022.\003J\005n\000\000\n\146\001\190\000\000\000\000\004V\000\000\000\000\002\150\000\000\000\000\003\218\000\000\000\000\000\000\003\222\000\000\003\230\005\166\n\162\005Z\000\000\000\000\000\000\003:\002\162\000\000\000\000\002f\000\000\000\000\000\000\005^\002\218\000\000\000\000\000\000\000\000\005\170\000\000\005f\005j\000\000\001\210\n\170\000\000\000\000\000\000\000\000\000\000\003>\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\022\142\003J\005n\000\000\003V\001\190\000\000\000\000\004V\000\000\000\000\002\150\000\000\000\000\003\218\000\000\000\000\000\000\003\222\000\000\003\230\005N\000\000\005Z\000\000\000\000\t\017\000\000\000\000\000\000\000\000\000\000\003:\002\162\000\000\005^\002f\000\000\000\000\000\000\000\000\002\218\000\000\005f\005j\000\000\005\174\000\000\t\017\000\000\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003>\000\000\000\000\000\000\000\000\000\000\005\250\000\000\000\000\005n\002\225\002\225\000\000\003J\002\225\004V\003V\001\190\000\000\002\225\000\000\000\000\000\000\002\150\000\000\000\000\003\218\000\000\000\000\002\225\003\222\000\000\003\230\005N\000\000\005Z\002\225\000\n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005^\000\000\002\225\000\000\000\000\002\225\002\225\000\000\005f\005j\000\000\005\174\002\225\000\000\000\000\002\225\000\000\000\000\002\225\002\225\000\000\002\225\002\225\000\000\002\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005n\000\000\t\017\000\000\002\225\000\000\004V\004A\004A\000\000\000\000\004A\002\225\002\225\000\000\002\225\004A\000\000\000\000\000\000\000\000\000\000\004A\000\000\000\000\000\000\004A\000\000\000\000\000\000\000\000\000\000\000\000\004A\022\222\000\000\002\225\022\246\000\000\000\000\002\225\000\000\002\225\000\000\000\000\000\000\004A\000\000\000\000\004A\004A\000\000\000\000\000\000\000\000\000\000\004A\000\000\000\000\004A\000\000\000\000\000\238\004A\000\000\004A\004A\000\000\004A\0035\000\000\000\000\000\000\0035\0035\000\000\000\000\0035\0035\000\000\004A\0035\000\000\000\000\000\000\000\000\000\000\0035\004A\004A\000\000\0035\000\000\0035\000\000\0035\000\000\0035\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0035\015~\000\000\000\000\0035\015~\0035\004A\000\000\000\000\0035\000\000\000\000\004A\000\000\0035\000\000\000\000\0035\0035\000\000\000\000\0035\0035\0035\0035\000\000\0035\0035\0035\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0035\000\000\000\000\000\000\0035\000\000\000\000\000\000\0035\000\000\000\000\000\000\000\000\000\000\0035\0035\025j\000\000\0035\0035\025\154\000\000\0035\0035\012\145\000\000\000\000\000\000\000\000\012\145\000\000\000\000\012\145\000\000\015\222\0035\000\000\000\000\015\222\0035\0035\000\000\012\145\000\000\0035\000\000\012\145\000\000\012\145\000\000\000\000\000\000\000\000\000\000\004\253\000\000\000\000\000\000\000\000\000\000\012\145\000\000\000\000\000\000\000\000\000\000\012\145\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\145\000\000\000\000\012\145\000\000\000\000\003:\002\162\012\145\012\145\002f\000\000\006\138\000\000\000\000\002\218\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\145\001\210\000\000\006\170\012\145\000\000\000\000\000\000\003>\000\000\000\000\b\198\000\000\000\000\012\145\012\145\002^\000\000\012\145\012\145\000\000\003J\000\000\000\000\b\242\001\190\000\000\000\000\012\145\000\000\000\000\002\150\026Z\000\000\003\218\012\145\000\000\000\000\003\222\000\000\003\230\000\000\n\162\005Z\005U\000\000\012\145\000\000\000\000\005U\000\000\000\000\005U\000\000\000\000\005^\000\000\000\000\000\000\000\000\000\000\000\000\005U\005f\005j\000\000\005U\000\000\005U\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005U\000\000\000\000\000\000\000\000\000\000\005U\005n\000\000\000\000\000\000\000\000\007\194\004V\000\000\005U\000\000\000\000\005U\000\000\000\000\000\000\000\000\005U\005U\000\238\000\000\005Y\000\000\000\000\000\000\000\000\005Y\000\000\000\000\005Y\000\000\000\000\000\000\005U\005U\000\000\000\000\005U\000\000\005Y\000\000\000\000\000\000\005Y\000\000\005Y\000\000\005U\005U\000\000\000\000\005U\005U\000\000\000\000\000\000\000\000\005Y\000\000\000\000\000\000\000\000\000\000\005Y\000\000\0035\000\000\000\000\005U\007\194\0035\000\000\005Y\0035\000\000\005Y\000\000\000\000\000\000\005U\005Y\005Y\000\238\0035\000\000\000\000\000\000\0035\000\000\0035\000\000\000\000\000\000\000\000\000\000\000\000\005Y\005Y\000\000\000\000\005Y\0035\015~\000\000\000\000\000\000\000\000\0035\000\000\000\000\005Y\005Y\000\000\000\000\005Y\005Y\0035\000\000\000\000\0035\000\000\000\000\000\000\000\000\0035\0035\0035\006\001\000\000\000\000\000\000\005Y\006\001\000\000\000\000\006\001\000\000\000\000\000\000\000\000\0035\000\000\005Y\000\000\0035\006\001\000\000\000\000\000\000\006\001\000\000\006\001\000\000\000\000\0035\0035\017f\000\000\0035\0035\000\000\000\000\000\000\006\001\000\000\000\000\000\000\000\000\000\000\006\001\000\000\000\000\000\000\000\000\015\222\0035\000\000\000\000\006\001\000\000\000\000\006\001\000\000\000\000\000\000\000\000\006\001\006\001\000\238\000\000\000\000\000\000\000\000\000\000\025B\000\000\000\000\000\000\000\000\000\000\003:\002\162\006\001\000\000\002f\000\000\006\001\000\000\000\000\002\218\000\000\000\000\000\000\000\000\000\000\000\000\006\001\006\001\021\"\001\210\006\001\006\001\000\000\000\000\000\000\000\000\003>\001\202\001\206\000\000\006\001\000\000\000\000\000\000\000\000\000\000\000\000\006\001\000\000\003J\000\000\000\000\003V\001\190\000\000\000\000\001\210\001\214\006\001\002\150\000\000\000\000\003\218\000\000\000\000\000\000\003\222\000\000\003\230\005N\000\000\005Z\000\000\000\000\000\000\005\210\000\000\000\000\000\000\001\246\002\134\003:\002\162\005^\002\130\002f\002\150\004\002\004\014\000\000\002\218\005f\005j\004\026\005\174\000\000\000\000\003\226\000\000\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003>\000\000\000\000\004\030\000\000\000\000\004\209\000\000\005n\000\000\006v\000\000\b\174\003J\004V\000\000\003V\001\190\000\000\000\000\000\000\000\000\025\230\002\150\000\000\000\000\003\218\000\000\000\000\000\000\003\222\000\000\003\230\005N\000\000\005Z\000\000\000\000\006\018\000\000\000\000\000\000\000\000\000\000\003:\002\162\000\000\005^\002f\000\000\000\000\000\000\000\000\002\218\000\000\005f\005j\000\000\005\174\000\000\0066\000\000\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003>\000\000\000\000\000\000\006\030\000\000\000\000\000\000\000\000\005n\003:\002\162\000\000\003J\002f\004V\003V\001\190\000\000\002\218\000\000\000\000\000\000\002\150\000\000\000\000\003\218\000\000\000\000\001\210\003\222\000\000\003\230\005N\000\000\005Z\003>\000\000\000\000\000\000\000\000\007\129\000\000\000\000\007\129\000\000\000\000\005^\000\000\003J\000\000\000\000\003V\001\190\000\000\005f\005j\000\000\005\174\002\150\007\129\007\129\003\218\007\129\007\129\000\000\003\222\000\000\003\230\005N\000\000\005Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005n\006M\000\000\000\000\005^\007\129\004V\003:\002\162\000\000\000\000\002f\005f\005j\000\000\005\174\002\218\000\000\000\000\000\000\000\000\006M\000\000\007\129\000\000\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003>\000\000\000\000\005n\011\138\000\000\000\000\000\000\000\000\004V\003:\002\162\000\000\003J\002f\000\000\003V\001\190\000\000\002\218\007\129\000\000\007\129\002\150\000\000\000\000\003\218\000\000\000\000\001\210\003\222\000\000\003\230\005N\005\198\005Z\003>\007\129\007\129\000\000\000\000\000\000\007\129\000\000\007\129\000\000\000\000\005^\007\129\003J\000\000\000\000\003V\001\190\000\000\005f\005j\000\000\000\000\002\150\000\000\000\000\003\218\000\000\000\000\000\000\003\222\000\000\003\230\005N\000\000\005Z\000\000\000\000\011\150\000\000\000\000\000\000\000\000\005n\003:\002\162\000\000\005^\002f\004V\000\000\000\000\000\000\002\218\000\000\005f\005j\000\000\005\174\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003>\000\000\000\000\000\000\011\162\000\000\000\000\000\000\000\000\005n\003:\002\162\000\000\003J\002f\004V\003V\001\190\000\000\002\218\000\000\000\000\000\000\002\150\000\000\000\000\003\218\000\000\000\000\001\210\003\222\000\000\003\230\005N\000\000\005Z\003>\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005^\000\000\003J\000\000\000\000\003V\001\190\000\000\005f\005j\000\000\005\174\002\150\000\000\000\000\003\218\000\000\000\000\000\000\003\222\000\000\003\230\005N\000\000\005Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005n\006q\000\000\000\000\005^\000\000\004V\000\000\002\162\000\000\000\000\002f\005f\005j\000\000\005\174\002\218\000\000\000\000\000\000\000\000\006q\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\000\002\222\000\000\000\000\000\000\000\000\000\000\005n\000\000\000\000\000\000\000\000\002\226\004V\000\000\000\000\000\000\000\000\000\000\000\000\003\022\001\190\000\000\000\000\000\000\000\000\000\000\002\150\000\000\000\000\003\030\000\000\000\000\000\000\007\254\b\002\b\014\000\000\000\000\005Z\000\000\000\000\000\000\006\249\007\002\000\000\000\000\000\000\006\249\000\000\000\000\006\249\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005f\005j\006\249\000\000\000\000\000\000\006\249\000\000\006\249\000\000\001\181\000\000\000\000\000\000\000\000\001\181\000\000\000\000\001\181\000\000\006\249\000\000\000\000\000\000\005n\b\022\006\249\007n\001\181\b.\004V\000\000\001\181\000\000\001\181\006\249\000\000\000\000\006\249\000\000\000\000\000\000\000\000\006\249\006\249\000\238\001\181\000\000\000\000\000\000\000\000\000\000\001\181\000\000\000\000\000\000\000\000\000\000\000\000\006\249\000\000\001\181\000\000\006\249\001\181\000\000\000\000\000\000\000\000\001\181\001\181\001\181\000\000\006\249\006\249\000\000\000\000\006\249\006\249\000\000\000\000\000\000\000\000\000\000\000\000\001\181\000\000\000\000\001\217\001\181\000\000\000\000\000\000\001\217\006\249\000\000\001\217\000\000\000\000\001\181\001\181\000\000\000\000\001\181\001\181\000\000\001\217\000\000\000\000\017r\001\217\000\000\001\217\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\181\000\000\000\000\000\000\001\217\001\181\000\000\000\000\000\000\000\000\001\217\000\000\000\000\006\005\000\000\000\000\000\000\000\000\006\005\001\217\000\000\006\005\001\217\000\000\000\000\000\000\000\000\001\217\001\217\000\000\000\000\006\005\000\000\000\000\000\000\006\005\000\000\006\005\000\000\000\000\000\000\000\000\000\000\001\217\000\000\000\000\000\000\001\217\000\000\006\005\000\000\000\000\000\000\000\000\000\000\006\005\000\000\001\217\001\217\000\000\000\000\001\217\001\217\000\000\006\005\000\000\000\000\006\005\000\000\000\000\000\000\001\217\006\005\006\005\000\238\000\000\000\000\000\000\001\217\000\000\000\000\000\000\000\000\020\254\000\000\000\000\000\000\000\000\006\005\001\217\012\145\000\000\006\005\000\000\000\000\012\145\000\000\000\000\012\145\000\000\000\000\000\000\006\005\006\005\000\000\000\000\006\005\006\005\012\145\000\000\000\000\000\000\012\145\000\000\012\145\000\000\006\005\000\000\000\000\000\000\004\253\000\000\000\000\006\005\000\000\000\000\012\145\000\000\000\000\000\000\000\000\000\000\012\145\000\000\006\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\145\000\000\000\000\000\000\000\000\012\145\012\145\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012I\000\000\002\162\012I\000\000\027\230\000\000\012\145\000\000\000\000\027\234\000\000\000\000\012I\000\000\000\000\000\000\000\000\000\000\012I\000\000\012\145\012\145\002^\000\000\012\145\012\145\000\000\000\000\000\000\000\000\012I\000\000\000\000\000\000\012\145\000\000\012I\000\000\026\146\000\000\000\000\012\145\001\002\001\190\000\000\012I\000\000\000\000\012I\000\000\000\000\000\000\012\145\012I\004Y\000\000\000\000\000\000\000\000\004Y\000\000\027\238\004Y\000\000\000\000\000\000\000\000\000\000\000\000\012I\000\000\000\000\004Y\012I\000\000\000\000\004Y\000\000\004Y\000\000\000\000\000\000\027\242\012I\012I\000\000\000\000\012I\000\000\000\000\004Y\000\000\000\000\000\000\000\000\000\000\004Y\b1\b1\000\000\000\000\b1\007\194\000\000\012I\004Y\b1\000\000\004Y\000\000\000\000\000\000\016\014\004Y\002\198\000\238\b1\000\000\000\000\000\000\000\000\000\000\000\000\b1\000\000\000\000\000\000\000\000\000\000\004Y\000\000\000\000\000\000\004Y\000\000\000\000\b1\000\000\000\000\b1\b1\000\000\000\000\004Y\004Y\000\000\b1\004Y\004Y\b1\000\000\000\000\000\000\b1\000\000\b1\b1\007.\b1\000\000\000\000\000\000\000\000\001q\004Y\000\000\000\000\000\000\001q\025b\b1\001q\000\000\000\000\000\000\004Y\000\000\000\000\b1\b1\000\000\001q\000\000\001q\000\000\001q\000\000\001q\000\000\000\237\000\000\000\000\000\000\000\000\000\237\000\000\000\000\000\237\000\000\001q\000\000\000\000\b1\000\000\000\000\001q\000\000\000\237\b1\000\000\000\000\000\237\000\000\000\237\000\000\000\000\000\000\001q\000\000\000\000\000\000\000\000\001q\001q\000\238\000\237\000\000\000\000\000\000\000\000\000\000\000\237\000\000\000\000\000\000\000\000\000\000\000\000\001q\000\000\000\237\000\000\000\000\000\237\000\000\000\000\000\000\000\000\000\237\000\237\000\238\000\000\001q\001q\001q\000\000\001q\001q\000\000\000\000\000\000\000\000\000\000\000\000\000\237\000\000\000\000\000\241\000\237\000\000\000\000\000\000\000\241\001q\000\000\000\241\000\000\000\000\000\237\000\237\000\000\000\000\000\237\000\237\001q\000\241\000\000\000\000\000\000\000\241\000\000\000\241\000\000\006\245\000\000\000\000\000\000\000\000\006\245\000\237\000\000\006\245\000\000\000\241\000\000\000\000\000\000\000\000\000\000\000\241\000\237\006\245\000\000\000\000\000\000\006\245\000\000\006\245\000\241\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\241\000\241\000\238\006\245\000\000\000\000\000\000\000\000\000\000\006\245\000\000\000\000\000\000\000\000\000\000\000\000\000\241\000\000\006\245\000\000\000\241\006\245\000\000\000\000\000\000\000\000\006\245\006\245\000\000\000\000\000\241\000\241\000\000\000\000\000\241\000\241\000\000\000\000\000\000\000\000\000\000\000\000\006\245\000\000\000\000\000\000\006\245\000\000\000\000\000\000\000\000\000\241\000\000\006\201\006\201\000\000\006\245\006\245\016\166\000\000\006\245\006\245\000\241\005\249\000\000\000\000\000\000\000\000\005\249\000\000\000\000\005\249\006\201\006\201\006\201\000\000\000\000\006\245\017F\000\000\000\000\005\249\006\201\000\000\000\000\005\249\000\000\005\249\000\000\005a\007\002\000\000\000\000\000\000\005a\006\201\006\201\005a\000\000\005\249\006\201\000\000\006\201\006\201\006\201\005\249\000\000\005a\000\000\006\201\000\000\005a\000\000\005a\005\249\000\000\000\000\005\249\000\000\000\000\000\000\000\000\005\249\005\249\000\000\005a\006\201\000\000\000\000\000\000\000\000\005a\007n\000\000\000\000\000\000\000\000\000\000\005\249\000\000\000\000\000\000\005\249\005a\000\000\000\000\000\000\000\000\005a\005a\000\238\000\000\005\249\005\249\000\000\000\000\005\249\005\249\000\000\000\000\000\000\000\000\011\249\000\000\005a\000\000\000\000\011\249\000\000\004\202\011\249\000\000\000\000\005\249\000\000\000\000\000\000\000\000\005a\005a\011\249\000\000\005a\005a\011\249\000\000\011\249\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\249\005a\000\000\000\000\000\000\000\000\011\249\000\000\000\000\000\000\000\000\000\000\000\000\001\202\002b\011\249\000\000\002f\011\249\000\000\000\000\000\000\000\000\011\249\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\210\001\214\001\230\000\000\000\000\000\000\000\000\011\249\t\162\000\000\001\242\011\249\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\249\011\249\002n\002v\011\249\011\249\000\000\002\130\000\000\002\150\004\002\004\014\0041\000\000\000\000\000\000\020\214\0041\026>\004)\0041\011\249\000\000\000\000\004)\000\000\000\000\004)\000\000\000\000\0041\000\000\n\134\004\030\0041\000\000\0041\004)\000\000\000\000\000\000\004)\005j\004)\000\000\000\000\000\000\000\000\0041\000\000\000\000\000\000\026J\000\000\0041\004)\000\000\000\000\000\000\000\000\000\000\004)\000\000\0041\000\000\000\000\0041\000\000\000\000\020\234\004)\0041\000\000\004)\000\000\000\000\000\000\000\000\004)\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0041\000\000\000\000\000\000\0041\004I\000\000\004)\000\000\000\000\004I\004)\004\025\004I\0041\0041\000\000\004\025\0041\0041\004\025\004)\004)\004I\000\000\004)\004)\004I\000\000\004I\004\025\000\000\000\000\000\000\004\025\0041\004\025\000\000\000\000\000\000\000\000\004I\004)\000\000\000\000\000\000\016\206\004I\004\025\000\000\000\000\000\000\000\000\019\186\004\025\000\000\004I\000\000\000\000\004I\000\000\000\000\000\000\004\025\004I\000\000\004\025\000\000\000\000\000\000\000\000\004\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004I\000\000\000\000\n\194\004I\000\000\000\000\004\025\000\000\001\202\001\206\004\025\000\000\000\000\004I\004I\000\000\000\000\004I\004I\000\000\004\025\004\025\002r\000\000\004\025\004\025\000\000\001\210\001\214\001\230\000\000\000\000\000\000\000\000\004I\000\000\000\000\001\242\000\000\000\000\000\000\004\025\000\000\000\000\001\250\020\154\006\205\006\205\000\000\000\000\001\246\002v\024\018\000\000\000\000\002\130\000\000\002\150\004\002\004\014\000\000\000\000\004\018\000\000\004\026\006\205\006\205\006\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\205\000\000\000\000\000\000\000\000\000\000\004\030\000\000\000\000\000\000\000\000\000\000\000\000\006\205\006\205\000\000\000\000\000\000\006\205\000\000\006\205\006\205\006\205\000\000\0049\000\000\000\000\006\205\000\000\0049\000\000\004!\0049\000\000\000\000\015n\004!\000\000\000\000\004!\000\000\000\000\0049\000\000\006\205\000\000\0049\000\000\0049\004!\000\000\000\000\000\000\004!\000\000\004!\000\000\000\000\000\000\000\000\0049\000\000\000\000\000\000\000\000\000\000\0049\004!\000\000\004Q\000\000\000\000\000\000\004!\004Q\000\000\000\000\004Q\0049\000\000\004\006\000\000\006\205\0049\000\000\004!\000\000\004Q\000\000\000\000\004!\004Q\000\000\004Q\000\000\000\000\000\000\000\000\000\000\0049\000\000\000\000\000\000\000\000\000\000\004Q\004!\000\000\000\000\000\000\000\000\004Q\000\000\0049\0049\000\000\000\000\0049\0049\000\000\004!\004!\000\000\004Q\004!\004!\000\000\000\000\004Q\011\014\000\000\000\000\000\000\000\000\0049\001\202\001\206\000\000\000\000\000\000\000\000\004!\000\000\000\000\004Q\017\246\000\000\000\000\000\000\000\000\000\000\003\226\020F\000\000\001\210\001\214\001\230\000\000\004Q\004Q\000\000\000\000\004Q\004Q\001\242\004m\000\000\000\000\000\000\000\000\000\246\000\000\000\000\002\166\000\000\000\000\000\000\001\246\002v\004Q\000\000\000\000\002\130\003\150\002\150\004\002\004\014\004m\000\000\003\154\020\194\004\026\007\149\000\000\000\000\007\149\000\000\000\000\000\000\000\000\000\000\003\158\000\000\000\000\000\000\000\000\000\000\016\146\004\030\000\000\000\000\007\149\007\149\000\000\007\149\007\149\024>\000\000\000\000\016\246\000\000\000\000\000\000\000\000\017\014\000\000\000\000\000\000\007m\000\000\000\000\007m\000\000\000\000\000\000\007\149\000\000\000\000\000\000\000\000\017\022\000\000\000\000\000\000\004R\000\000\004V\007m\007m\000\000\007m\007m\000\000\000\238\017*\017V\000\000\000\000\004m\004m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007m\000\000\007\153\000\000\021~\007\153\000\000\000\000\000\000\000\000\000\000\000\000\007\149\000\000\007\149\000\000\000\000\000\000\007m\000\000\000\000\007\153\007\153\000\000\007\153\007\153\007\149\000\000\000\000\005\206\007\149\000\000\000\000\000\000\007\149\007\137\007\149\000\000\007\137\000\000\007\149\000\000\000\000\000\000\000\000\007\153\000\000\000\000\007m\000\000\007m\000\000\000\000\000\000\007\137\007\137\000\000\007\137\007\137\000\000\000\000\000\000\007m\000\238\000\000\005\206\007m\000\000\000\000\000\000\007m\000\000\007m\000\000\000\000\000\000\007m\000\000\007\137\000\000\r-\r-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\153\000\000\007\153\000\238\000\000\000\000\r-\r-\r-\007\022\000\000\000\000\000\000\000\000\007\153\000\000\r-\005\206\007\153\000\000\000\000\000\000\007\153\000\000\007\153\001\202\001\206\0222\007\153\r-\r-\000\000\000\000\007\137\r-\007\137\r-\r-\r-\000\000\000\000\000\000\000\000\r-\001\210\002\142\001\230\006\014\000\000\000\000\005\206\007\137\000\000\000\000\001\242\007\137\000\000\007\137\000\000\000\000\r-\007\137\000\000\001\202\001\206\022\146\000\000\001\246\002v\000\000\000\000\000\000\002\130\000\000\002\150\004\002\004\014\000\000\000\000\000\000\000\000\004\026\001\210\002\142\001\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\242\000\000\000\000\000\000\000\246\000\000\004\030\002\166\000\000\000\000\000\000\000\000\000\000\001\246\002v\000\000\000\000\004\141\002\130\000\000\002\150\004\002\004\014\003\154\000\000\000\000\000\000\004\026\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\158\000\000\000\000\000\000\000\000\000\000\016\146\000\000\000\000\004\030\000\000\000\000\000\000\000\000\000\000\024>\000\000\000\000\016\246\000\000\000\000\000\000\000\000\017\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\022\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017*\017V\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\021~")) + ((16, "C\170P\226Ff\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\021HFf\000\000\000\000\020XFfC\170\020\182\000-\000[\\(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\021\238\006\168\000\218\000\000\003\188\t|\000\000\001\208\003\232\nt\000\000\000\244\004\198\011l\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\220\000\000\000\000\000\000\0046T\016\000\000\000\000\000\000\005.\000\000\000\000\000\000\005\022\005\b\000\000\000\000T\016H\254\020X\021\178^\128\020X\\\142P\226\020XR,\000\000\007\168\000\000Dp\007\214\000\000C\146\000\000\027\158\000\000\000\000\004\246\000\000\005.\000\000\000\000\000\000\002J\000\000C\146\000\000\006&v\246]\160d\194\000\000\132l\134\028\000\000LP_\014\000\000X\\\026\206K\200\005.p\026FfC\170\000\000\000\000P\226\020XS\148Dp\007\012v\246\000\000\128\178FfC\170P\226\020X\000\000\000\000\016x\023\022\001N\b\004\000\000\002\138\b\022\000\000\000\000\000\000\000\000\000\000\020X\000\000A\206i\164C\170\000\000\000\000P\206\020XZ\024W\200\000\000\004\002\000\000\000\000\005\242\000\000\000\000H\166\004\002\024\138\003\130\0020\000\000\000\000\003\172\000\000\021\178\006\212\006\160\020X\028\254\020XC\170C\170\000\000M\\M\\\020X\028\254A\248\020X\000\000\000\000\000\000P\226\020X\000\000\000\248\000\000W\200y\188zJ\000\000\b\004\000\000\n\196\000\000\000\000A\214T\016\134h\000\000h\142\134h\000\000h\142h\142\000b\006:\0008\000\000\020\190\000\000\007b\000\000\000\000\b\198\000\000\000\000\000\000h\142\005.\000\000\000\000V\222T\016T\132_\014\000\000\000\000N*\000b\000\000\000\000_\014\007\162T\016\000\000O _\014P\022\000\000\000\000\000\000\011\190\000\000h\142\000\000\001\000\1310\000\000T\016\005\216T\016\000\000\022\\\b\150\005.\000\000\000\000\023\224\000\000\006\208\000\000Y\128\011\230\000\000\b\162h\142\012\182\000\000\012\222\000\000\007\200\000\000\000\000\004\184\000\000\000\000\000\000\021 4W\200P\206\020XW\200\000\000\000b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000M:\027v\000\000\000\000\000\000\001\244&\174t<\000\000\000\000P\206\020XW\200\000\000\000\000{hW\200\136.zJ\000\000\136v\000\000W\200\000\000\000\000X\180\000\000\000\000\000\000\n.\000\000\022\168\000\000\000\000z\214\000\000\136\208{\030\000\000\137\018\t\002\000\000\000\000z\214\000\000\004\024\000\000\000\000DHt\200\000\000\000\000\000\000Bn\023|\019\252\023\174\000\000\000\000\000\000\000\000\004\250\000\000\000\000Z\204\b\254\011F\000\017T\016\002\204\011\148\000\000\000\000\t\156\011F\006\172\000\000i\186P\234M\\\020X\028\254\000-\000\018\0020\000\000\n\240\021\178\021\178\000-\000\018\000\018\021\178\000\000jL\0050Dp\b\004\000\236\137`\000\000T\016ebT\016_ f\002T\016\000\144T\016f\156\000\000\000\000\020d\0008_\192\b\022\0008`\024\000\000j\230\0050\000\000\021\178k\128\000\000\b*\t\014`\184\000\000\000\000\000\000\000\000\000\000\000\000\001B\000\000\000\000\003\144\000\000\007r\028\254\000\000\\\192A\248\000\000\031\138\000\000\000\000\021\178\002\152\000\000\000\000\000\000\000\000[\132\000\000\001\200\000\000UP\001\130\005\"\000\000\0226V\170P\226\020XG,P\226\020X\016x\016x\000\000\000\000\000\000\000\000\001\240\024&B\188\000\000Q\150RJM\\\020X\028\254\b`\021\178\000\000\004*\000\000R\254S\178{\182I~T\016\002\128\000\000P\226\020X\000\000u\016\020Xy\188W\200E\178\000\000P\226\020Xw\\\004~\000\000W\200A\012T\016\003x\006\172\011\196\000\000\000\000\000\000H\166\003\138\003\138\000\000\012\154p\156\000\000P\206\020XW\200\025R\000\000P\226\020X\016x\0226\016x\002\232\023\240\000\000\000\000\016x\012\148\000\000\r\000\000\000\016x\003\224\rX\000\000'\166\000\000\b\196\000\000\000\000\026\022\000\000\017p\023.\000\000\000\000\000\000\000\000\b\020\000\000\000\000\027\014\000\000\028\006\000\000\028\254\000\000\018h\024&\000\000\000\000\000\000Ff\000\000\000\000\000\000\000\000\029\246\000\000\030\238\000\000\031\230\000\000 \222\000\000!\214\000\000\"\206\000\000#\198\000\000$\190\000\000%\182\000\000&\174\000\000'\166\000\000(\158\000\000)\150\000\000*\142\000\000+\134\000\000,~\000\000-v\000\000.n\000\000/f\000\0000^\020XW\200ZJI\146\003\138\014,l\012W\200\000\000\000\000\000\000h\142\000\000\028\018\134\028\000\000\026\"T\016\029\220\r\198\000\000\000\000\000\000\000\000l\012\000\000\000\000\005\242\014\208\000\000B\170\000\000\000\000\135\176\000\000\bB\000\000\000\000K\200\003\138\014\140T\016\b`\000\000\000\000\007\006\005.\000\000T\016\n\146\000\000\000\000\014\244\000\000\000\000\000\000I\190T\016\0118\000\000\000\000\030*\000\000\000\000{\254\000\000\031\"|\138\000\000 \026|\210\000\000!\018\t\250\000\000\000\000\000\000\000\000\"\nW\200#\002p\234p\234\000\000\000\000\000\0001V\000\000\t\188\000\000\000\000\000\000q\140\000\000\000\000\002\138\023\248\000\000\b\226\000\000\000\000]bKl\000\000\000\000\n\180\000\000\000\000\000\000\rh\000\000\000\000\000\000\016x\004\216\024\232\000\000\t\218\000\000\005\208\000\0002N\000\000\012\142\000\000\006\200\000\0003F\000\000\015\138\007\192\000\0004>lt\000\000(\158\000\000\n\"\b\184\000\00056\000\000\r\178\t\176\000\0006.\000\000q\150\n\168\000\0007&\005\180\025\016\000\000\nX\011\160\000\0008\030\000\000\r\200\012\152\000\0009\022\000\000\r\172\r\144\000\000:\014\014\136\000\000;\006\015\128\019`\000\000\000\000\000\000\n\210\000\000\000\000\014`\000\000\000\000\015\156\000\000\011\002\000\000\000\000\000\000\015\028\000\000\015*\000\000\000\000J~\003\138\015\218p\156_\014\000b\000\000\000\000p\156\000\000\000\000\000\000p\156\000\000\015\208\000\000\000\000\000\000\000\000\000\000\000\000;\254W\200\000\000\000\000\016\014\000\000<\246\000\000=\238\000\000#\250\000\000\000\000\n\130\000\000\000\000W\200\000\000\000\000}j\011P\000\000\000\000G,\000\000\014\148\000\000\000\000V\020\000\000\014~\000\000\000\000\001\130\011\254\000\000\000\000\0226\022\028\b\004\000\000B>\000\000!,\023\176\021\220\000\000\000\000\014\002\000\000\000\000\001\238\025\030V\180\000\000\025\030\000\000\tX\000\000\000\000\014\142\000\000\000\000g>\t\004\004H\000\000\000\000\012H\000\000\000\000\014\192\000\000\000\000\000\000\020X\028\254\005\168\000\000\000\000\023&\003\130\0020\003\136\028\254w\228\021\178\001B\028\254xb\015\146\000\000\000\000\003\136\000\000H\232\019\248\021\204\000\000\007X\016\"\000\000\016$\000V_\014\006\196\000\000\016\n\015\170K\200\n|T\016\030\128\020F\r\018\004\248\000\000\031x\016\\\000\000\006\196\000\000\000\000\016\130_\014aX\000\000g\144_\014\016Z_\014m\012a\248\001N\016*\000\000\000\000\000\000\020X\128\252\000\000W\200p\234\000\000\000\000\016\156\000\000\000\000\000\000>\230\016\196y\188?\222h<\000\000\000\000HJ\000\000\005\128\000\000L\136\000\000\020X\000\000\021\178\006\026\000\000\128\178\000\000\020X\028\254\128\178\000\000\025D\023\022\001N\005.\130\144\021\178}\248p\234\000\000\005r\t\168\0020\003\136p\234\132\224\003\130\0020\003\136p\234\132\224\000\000\000\000\003\136p\234\000\000FfC\170W\200\027B\000\000\000\000FfC\170M\\\020X\028\254\128\178\000\000\020\182\000-\000[\015\240T\016\0120\016\190\131P\000\000p\234\000\000H\232\019\248\021\204x\186\023\228\0118~,\nZ\016\b\020Xp\234\000\000\020Xp\234\000\000h\142ff\019\134\002\222\001N\0008N\234\000\000\001N\0008N\234\000\000\025D\005r\n\160\0212\bZ\000\000N\234\000\000\0020\016\016\021\178p\234\134\222\003\130\0020\016 \021\178p\234\134\222\000\000\000\000\tX\000\000O\224\000\000\021\178\131\132N\234\000\000\b\242\000\000H\254\020X\021\178p\234\000\000H\232\019\248\021\204rFB\138\026\222\019\170\002\142\000\000\011vC\146\000\017\000\000\016\176\016b\024\196\020XT\184T\016\0120\000\000W\150\001N\005\204\r\216\000\000\n\024\000\000\016\188\016FT\016O(\000\000\0032\004\212\r\218\000\000\n\236\000\000\016\192\016JK\200\r\028T\016K\182O(\000\000UP\020X\024\196\016\232\011\028\001N\000\000\014\012\024\196T\016\012\208\000b\000\000T\016\n$\n\218\000\000\000\000mf\000\000\000\000\014b\024\196m\228O(\000\000\020XT\016\012\226T\016V\\O(\000\000\014\144\000\000\000\000O(\000\000\000\000W\150\000\000p\234\132\238\019\170\002\142\011v\016\218\016\140\024\196p\234\132\238\000\000\000\000\019\170\002\142\011v\016\230\016\138M\252LZ_\014\017\016M\252h\142\020\184\017\030M\252_\014\017 M\252n\132o\004\000\000\129\140\000\000\000\000p\234\134\236\019\170\002\142\011v\017\022\016\162M\252p\234\134\236\000\000\000\000\000\000ff\000\000\000\000\000\000\000\000\000\000\000\000N\234\000\000\133\128\020XDp\017 v\246\000\000\128\178\133\128\000\000\000\000\1358\020XDp\017*\016\188]\160\135\176\006\196\017l\000\000\000\000o\130rF\020X\000\000~\200\021\204\000\000\000\000\128\178\1358\000\000\000\000\000\000y6D\228I\154\006\196\017v\000\000\000\000\000\000rF\020X\000\000\006\196\017z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\014\168B\138\019\170\002\142\011v\017Xr\182\023\204\020XZ\024j\190\020(\001N\006\196\017Z\011l\000\000\000\000\017\b\000\000\000\000a\152\000\000\007\188\r\230\000\000\r\140\000\000\017`\016\244T\016d\240\017r\011\150\000\000\000\000\017\"\000\000\000\000\020F\0032\014\210\000\000\017~s8\137\172\003\138\017\028T\016\014 \000\000\000\000\017<\000\000\000\000\000\000a\152\000\000\0070\014\246\000\000\r\212\000\000\017\168\0176K\200\000\000\017\180s\186\137\248\003\138\017RT\016\015\024\000\000\000\000\017d\000\000\000\000\000\000\020X\000\000a\152\000\000\020z\020X\023\204\023\204u\168Ff\020X\128\252W\200\021\162\000\000\012V\001N\000\000\014\220\023\204T\016\014\186\b\004\000\000\020XW\200r\182\023\204\rh\023\204\000\000D\142Et\000\000bR\000\000\000\000b\238\000\000\000\000c\138\000\000\014\238\023\204d&\128\252W\200\021\162\000\000\000\"\000\000\000\000M\252\r\026\000\000\000\000d.\017\186\000\000a\152\000\000\023\204d.a\152\000\000\020XT\016a\152\000\000\015\136\000\000\000\000a\152\000\000\000\000j\190\000\000\129\192M\252\017r\023\204\130\\r\182\000\000p\234\133\142\019\170\002\142\011v\017\210r\182p\234\133\142\000\000\000\000\000\000\135\248P\206\000\000\000\000\000\000\000\000\000\000\000\000\132\022p\234\000\000\133\128\000\000\000\000\000\000\000\000p\234\135\248\000\000\018\014\000\000\000\000\132\022\018\020\000\000p\234\135\248\000\000\000\000\015\222\000\000\000\000i4\0032\000\000\000\000DH\000\000T\016\015\n\000\000j\190\015\240\000\000\000\000\000\000\015\156\000\000\000\000\000\000M\\\020X\028\254\006\178\000\000Z8\000\000\007p\000\000\000*\000\000\000\000\0184\000\000\018\\y\188\000\000@\214\018@\000\000\000\000\0182\026R\028B\021\204v0\023\228\020X\000\000\128\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000v8\023\228\020X\000\000\015\190v\246\000\000\128\178\000\000\0184\026R\028B\128\178\000\000\018H\000\000\000\238\014\140\020X`\226\000\000\000\000\028\190y\242\000\000\000\000\017\214\000\000\018.T\016\000\000\015\170\012\166\000b\000\000\000\000T\016\004R\006B\000\000T\016\012\018\006\196\018\\\000\000\000\000\127\"\000\000\000\000]\160\000\000\128\178\000\000\018V\026R\029:N\234\000\000\000\000\000\000\000\000\015\214\127\188]\160\000\000\128\178\000\000\018`\026R\029:N\234\000\000\016\026\000\000\000\000\b\n\000\000p\234\000\000\018t\000\000\000\000\017\230\000\000\017\236\000\000\017\252\000\000\000\000\\\142\018\000\000\000\000\000%\182\\(\018\158\000\000\000\000\000\000\014z\011D]\232\018\164\000\000\000\000\000\000\000\000\000\000\000\000\018\022\000\000\023\228\000\000\018\030\000\000T\016\000\000\t\b\000\000\000\000\018 \000\000\000\000\0008\000\000\003\210\000\000\000\000\000\000\001\214\000\000\016\030\000\000\0180\000\000W\200\022\168\000\000\000\000\012<\018H\000\000\000\000\018B\r$G,\005.\128:\000\000\000\000\000\000\000\000\000\000YL\000\000\000\000\018\234\000\000\138<\000\000\016p\018\236\000\000\018\238\000\000G\224G\224[\190[\190\000\000\000\000p\234[\190\000\000\000\000\000\000p\234[\190\018Z\000\000\018f\000\000"), (16, "\t)\t)\000\006\001\002\001\190\t)\002\186\002\190\t)\002\234\002\130\t)\003\145\t)\018\158\002\246\t)\023\158\t)\t)\t)\025F\t)\t)\t)\001\210\004A\004A\004F\002\250\t)\003>\003B\t\242\t)\001\206\t)\023\162\003F\000\238\002\254\025J\t)\t)\003\214\003\218\t)\003\222\0032\003\234\003\242\006\214\007\018\t)\t)\002\178\001\206\006\242\003:\t)\t)\t)\b\026\b\030\b*\b>\001*\005v\t)\t)\t)\t)\t)\t)\t)\t)\t)\b\178\000\238\t)\015\154\t)\t)\003\145\b\190\b\214\t*\005\130\005\134\t)\t)\t)\r\190\t)\t)\t)\t)\002j\002\154\r\238\t)\006\178\t)\t)\0035\t)\t)\t)\t)\t)\t)\005\138\b2\t)\t)\t)\bJ\004r\t>\0035\t)\t)\t)\t)\012\245\012\245\023\166\n\206\004\154\012\245\n\218\012\245\012\245\000\238\012\245\012\245\012\245\012\245\004A\012\245\012\245\001f\012\245\012\245\012\245\003i\012\245\012\245\012\245\012\245\004A\012\245\015\250\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\007\190\007\030\007R\012\245\004\226\012\245\012\245\012\245\012\245\012\245\004A\012\245\012\245\004A\012\245\003\238\012\245\012\245\012\245\000\238\007\194\012\245\012\245\012\245\012\245\012\245\012\245\012\245\000\238\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\004A\012\245\012\245\007\138\012\245\012\245\001j\004A\007.\004A\012\245\012\245\012\245\012\245\012\245\004A\012\245\012\245\012\245\012\245\012\245\000\238\012\245\012\245\0076\012\245\012\245\000\238\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\012\245\b\"\004A\012\245\012\245\012\245\012\245\001\181\001\181\001\181\001f\015Z\001\181\003i\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\015\006\001\181\007\222\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\003\134\003\138\001\181\000\238\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\006\246\001\181\001\181\001\181\b\022\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\002f\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\027\187\001\181\001\181\018\142\007\250\007\030\007n\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\014\202\bb\001\181\005\186\001\181\001\181\007\254\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\181\001\182\001\181\001\181\001\181\001\181\001\181\n]\n]\002\225\007\138\r\025\n]\003\149\n]\n]\000\238\n]\n]\n]\n]\001\186\n]\n]\r\025\n]\n]\n]\000\238\n]\n]\n]\n]\002j\n]\000\n\n]\n]\n]\n]\n]\n]\n]\n]\024\222\007\030\b\174\n]\004A\n]\n]\n]\n]\n]\000\238\n]\n]\012\"\n]\003\018\n]\n]\n]\002\225\024\226\n]\n]\n]\n]\n]\n]\n]\004A\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\003\149\n]\n]\007\138\n]\n]\004A\004A\007\030\004A\n]\n]\n]\n]\n]\004\001\n]\n]\n]\n]\tV\000\238\t\134\n]\005\241\n]\n]\007\202\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\n]\003\146\n]\n]\n]\n]\n]\003\173\003\173\001r\007\138\006\242\003\173\t\022\003\173\003\173\000\238\003\173\003\173\003\173\003\173\000\238\003\173\003\173\006\137\003\173\003\173\003\173\000\238\003\173\003\173\003\173\003\173\001\130\003\173\006Z\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\006\137\007\030\004\001\003\173\004B\003\173\003\173\003\173\003\173\003\173\015J\003\173\003\173\006^\003\173\t\005\003\173\003\173\003\173\005\241\b\146\003\173\003\173\003\173\003\173\003\173\003\173\003\173\015R\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\b\213\tN\t~\007\138\003\173\003\173\003\150\003^\b\230\027\171\003\173\003\173\003\173\003\173\003\173\004R\003\173\003\173\003\173\003\173\tV\000\238\t\134\003\173\b\"\003\173\003\173\003b\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\003\173\000\238\003\173\003\173\003\173\003\173\003\173\003\161\003\161\018\250\b\234\t\006\003\161\005R\003\161\003\161\t\005\003\161\003\161\003\161\003\161\001\146\003\161\003\161\006\154\003\161\003\161\003\161\002N\003\161\003\161\003\161\003\161\019\002\003\161\001\198\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\006\237\b\213\004A\003\161\002R\003\161\003\161\003\161\003\161\003\161\b\029\003\161\003\161\001\218\003\161\007\"\003\161\003\161\003\161\006\237\004A\003\161\003\161\003\161\003\161\003\161\003\161\003\161\004A\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\000\238\tN\t~\001\234\003\161\003\161\004A\004A\007\030\007^\003\161\003\161\003\161\003\161\003\161\001\222\003\161\003\161\003\161\003\161\tV\004A\t\134\003\161\004r\003\161\003\161\016v\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\003\161\006\237\003\161\003\161\003\161\003\161\003\161\t\217\t\217\018\206\007\138\b&\t\217\006\158\t\217\t\217\001\238\t\217\t\217\t\217\t\217\000\238\t\217\t\217\006\149\t\217\t\217\t\217\000\238\t\217\t\217\t\217\t\217\004A\t\217\007\222\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\006\149\007\030\018\214\t\217\000\238\t\217\t\217\t\217\t\217\t\217\005\217\t\217\t\217\001\206\t\217\012\130\t\217\t\217\t\217\0152\016\146\t\217\t\217\t\217\t\217\t\217\t\217\t\217\000\238\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\026N\t\217\t\217\007\138\t\217\t\217\r\002\003j\003\018\004A\t\217\t\217\t\217\t\217\t\217\002v\t\217\t\217\t\217\t\217\t\217\000\238\t\217\t\217\004B\t\217\t\217\003n\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\t\217\000\238\004A\t\217\t\217\t\217\t\217\t\209\t\209\004\242\001f\003i\t\209\007\005\t\209\t\209\025.\t\209\t\209\t\209\t\209\003\158\t\209\t\209\003\162\t\209\t\209\t\209\003\137\t\209\t\209\t\209\t\209\b\241\t\209\004^\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\007\222\026R\015\162\t\209\001\206\t\209\t\209\t\209\t\209\t\209\005\209\t\209\t\209\000\238\t\209\012\154\t\209\t\209\t\209\022\130\011Z\t\209\t\209\t\209\t\209\t\209\t\209\t\209\000\238\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\006\210\t\209\t\209\022\138\t\209\t\209\002\214\004V\007\030\b\241\t\209\t\209\t\209\t\209\t\209\002\142\t\209\t\209\t\209\t\209\t\209\0252\t\209\t\209\b\021\t\209\t\209\025>\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\t\209\012\185\b\241\t\209\t\209\t\209\t\209\t\225\t\225\021\246\007\138\007\210\t\225\011b\t\225\t\225\006\242\t\225\t\225\t\225\t\225\012\185\t\225\t\225\012\189\t\225\t\225\t\225\000\238\t\225\t\225\t\225\t\225\005F\t\225\004\174\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\012\189\007\030\021\254\t\225\002\190\t\225\t\225\t\225\t\225\t\225\005\209\t\225\t\225\003\022\t\225\012\174\t\225\t\225\t\225\015\138\026\226\t\225\t\225\t\225\t\225\t\225\t\225\t\225\0112\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\017\242\t\225\t\225\007\138\t\225\t\225\003\n\001\206\0116\005J\t\225\t\225\t\225\t\225\t\225\003\026\t\225\t\225\t\225\t\225\t\225\000\238\t\225\t\225\004B\t\225\t\225\002&\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\225\t\190\004\214\t\225\t\225\t\225\t\225\t\193\t\193\000\238\0022\007\222\t\193\t\146\t\193\t\193\005\002\t\193\t\193\t\193\t\193\004V\t\193\t\193\000\238\t\193\t\193\t\193\012.\t\193\t\193\t\193\t\193\t\150\t\193\007\154\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\006F\t\001\n\162\t\193\0122\t\193\t\193\t\193\t\193\t\193\011N\t\193\t\193\007\158\t\193\012\206\t\193\t\193\t\193\004b\014\254\t\193\t\193\t\193\t\193\t\193\t\193\t\193\b\134\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\006\242\t\193\t\193\014\226\t\193\t\193\006\170\006\194\001\002\001\190\t\193\t\193\t\193\t\193\t\193\001\222\t\193\t\193\t\193\t\193\t\193\006U\t\193\t\193\000\238\t\193\t\193\005.\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\t\193\006U\t\001\t\193\t\193\t\193\t\193\t\201\t\201\003\134\003\138\006\242\t\201\012\006\t\201\t\201\027\139\t\201\t\201\t\201\t\201\018B\t\201\t\201\016\218\t\201\t\201\t\201\012z\t\201\t\201\t\201\t\201\001v\t\201\012\n\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\011\202\006\202\016F\t\201\012~\t\201\t\201\t\201\t\201\t\201\0186\t\201\t\201\014\230\t\201\012\226\t\201\t\201\t\201\018\218\t\146\t\201\t\201\t\201\t\201\t\201\t\201\t\201\018B\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\012\202\t\201\t\201\b\193\t\201\t\201\006\026\012.\001\002\001\190\t\201\t\201\t\201\t\201\t\201\003\022\t\201\t\201\t\201\t\201\t\201\006]\t\201\t\201\005\221\t\201\t\201\r\014\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\t\201\006]\000\238\t\201\t\201\t\201\t\201\n\001\n\001\003\134\017\234\011Z\n\001\012J\n\001\n\001\017\146\n\001\n\001\n\001\n\001\004\014\n\001\n\001\017\254\n\001\n\001\n\001\012z\n\001\n\001\n\001\n\001\001\134\n\001\012N\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\004\018\019\006\b\193\n\001\rf\n\001\n\001\n\001\n\001\n\001\b\189\n\001\n\001\000\238\n\001\012\246\n\001\n\001\n\001\r\134\0142\n\001\n\001\n\001\n\001\n\001\n\001\n\001\004A\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\015\182\n\001\n\001\011j\n\001\n\001\b!\014N\007\158\000\238\n\001\n\001\n\001\n\001\n\001\002\142\n\001\n\001\n\001\n\001\n\001\006e\n\001\n\001\014:\n\001\n\001\014R\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\n\001\006e\000\238\n\001\n\001\n\001\n\001\t\241\t\241\027F\001\222\006\174\t\241\b\189\t\241\t\241\000\238\t\241\t\241\t\241\t\241\006\190\t\241\t\241\r\138\t\241\t\241\t\241\006\254\t\241\t\241\t\241\t\241\001\150\t\241\002\253\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\004\210\t\002\011\142\t\241\018\150\t\241\t\241\t\241\t\241\t\241\014\134\t\241\t\241\019>\t\241\r\018\t\241\t\241\t\241\011\018\005&\t\241\t\241\t\241\t\241\t\241\t\241\t\241\021\214\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\b\217\t\241\t\241\n\206\t\241\t\241\n\218\015\014\002\190\022\030\t\241\t\241\t\241\t\241\t\241\018\190\t\241\t\241\t\241\t\241\t\241\004A\t\241\t\241\n\206\t\241\t\241\n\218\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\t\241\000\238\012\146\t\241\t\241\t\241\t\241\t\233\t\233\001\002\001\190\014\138\t\233\004\214\t\233\t\233\000\238\t\233\t\233\t\233\t\233\001\206\t\233\t\233\012\150\t\233\t\233\t\233\t\"\t\233\t\233\t\233\t\233\b\237\t\233\000\238\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\0056\b\217\017^\t\233\015\018\t\233\t\233\t\233\t\233\t\233\tj\t\233\t\233\019V\t\233\r&\t\233\t\233\t\233\002\154\005>\t\233\t\233\t\233\t\233\t\233\t\233\t\233\023\174\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\003\022\t\233\t\233\015\198\t\233\t\233\023\022\003}\023\178\0266\t\233\t\233\t\233\t\233\t\233\011Z\t\233\t\233\t\233\t\233\t\233\000\238\t\233\t\233\tr\t\233\t\233\012Z\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\t\233\001\002\001\190\t\233\t\233\t\233\t\233\t\249\t\249\022\002\012^\019\158\t\249\004\214\t\249\t\249\019^\t\249\t\249\t\249\t\249\012Z\t\249\t\249\012\006\t\249\t\249\t\249\t\130\t\249\t\249\t\249\t\249\004\214\t\249\012J\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\r6\022\142\012\222\t\249\019\026\t\249\t\249\t\249\t\249\t\249\005\213\t\249\t\249\r\"\t\249\r:\t\249\t\249\t\249\023J\014\190\t\249\t\249\t\249\t\249\t\249\t\249\t\249\018\254\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\018\210\t\249\t\249\014\194\t\249\t\249\b\025\021\250\005\225\b%\t\249\t\249\t\249\t\249\t\249\r!\t\249\t\249\t\249\t\249\t\249\n\186\t\249\t\249\n\162\t\249\t\249\012\146\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\t\249\n\242\014v\t\249\t\249\t\249\t\249\nI\nI\rr\014\238\019\178\nI\014b\nI\nI\000\238\nI\nI\nI\nI\019J\nI\nI\014z\nI\nI\nI\025\250\nI\nI\nI\nI\014\242\nI\015\026\nI\nI\nI\nI\nI\nI\nI\nI\007n\007\241\022^\nI\004B\nI\nI\nI\nI\nI\023.\nI\nI\015\030\nI\rF\nI\nI\nI\011\022\019\130\nI\nI\nI\nI\nI\nI\nI\022>\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\000\238\nI\nI\007n\nI\nI\022\134\004\213\024\246\b\021\nI\nI\nI\nI\nI\027B\nI\nI\nI\nI\nI\019\182\nI\nI\011F\nI\nI\r-\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\nI\023\"\014f\nI\nI\nI\nI\003\157\003\157\000\238\023\130\023\238\003\157\019^\003\157\003\157\000\238\003\157\003\157\003\157\003\157\025\018\003\157\003\157\007n\003\157\003\157\003\157\011v\003\157\003\157\003\157\003\157\007n\003\157\012\170\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\r~\001\206\022\190\003\157\0262\003\157\003\157\003\157\003\157\003\157\024\206\003\157\003\157\001\206\003\157\r\150\003\157\003\157\003\157\025\002\r\158\003\157\003\157\003\157\003\157\003\157\003\157\003\157\r\178\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\026\214\tN\t~\025\198\003\157\003\157\r\226\014\014\015f\002\006\003\157\003\157\003\157\003\157\003\157\026\170\003\157\003\157\003\157\003\157\tV\023\242\t\134\003\157\015\142\003\157\003\157\003\254\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\003\157\015\170\003\157\003\157\003\157\003\157\003\157\001\237\001\237\026B\025\022\001\222\001\237\015\174\002\190\001\237\015\214\002\130\001\237\tf\001\237\004Y\002\246\001\237\024\210\001\237\001\237\001\237\015\234\001\237\001\237\001\237\001\210\025\006\tn\016\002\002\250\001\237\001\237\001\237\001\237\001\237\tv\001\237\016\022\016B\016V\002\254\017V\001\237\001\237\001\237\001\237\001\237\026\218\0032\001\190\017b\001\237\006\022\001\237\001\237\002\178\002\226\018\006\003:\001\237\001\237\001\237\b\026\b\030\b*\018\030\012f\005v\001\237\001\237\001\237\001\237\001\237\001\237\001\237\001\237\001\237\018\166\tN\t~\018\170\001\237\001\237\018\226\018\230\019\014\019\018\005\130\005\134\001\237\001\237\001\237\019:\001\237\001\237\001\237\001\237\012n\019\230\012\190\001\237\019\234\001\237\001\237\020\014\001\237\001\237\001\237\001\237\001\237\001\237\005\138\b2\001\237\001\237\001\237\bJ\004r\020\018\020\"\001\237\001\237\001\237\001\237\n1\n1\0202\020>\020r\n1\020v\002\190\n1\020\194\002\130\n1\n1\n1\020\234\002\246\n1\020\238\n1\n1\n1\020\254\n1\n1\n1\001\210\021N\n1\021n\002\250\n1\n1\n1\n1\n1\n1\n1\021\174\021\210\021\226\002\254\022\n\n1\n1\n1\n1\n1\022\014\0032\001\190\022\026\n1\022*\n1\n1\002\178\022F\022V\003:\n1\n1\n1\b\026\b\030\b*\022j\n1\005v\n1\n1\n1\n1\n1\n1\n1\n1\n1\022\150\n1\n1\022\154\n1\n1\022\166\022\182\022\202\023\190\005\130\005\134\n1\n1\n1\024\022\n1\n1\n1\n1\n1\024>\n1\n1\024\166\n1\n1\024\182\n1\n1\n1\n1\n1\n1\005\138\b2\n1\n1\n1\bJ\004r\025R\025Z\n1\n1\n1\n1\n-\n-\025j\025v\025\218\n-\025\238\002\190\n-\026\030\002\130\n-\n-\n-\026&\002\246\n-\026b\n-\n-\n-\026\138\n-\n-\n-\001\210\026\194\n-\026\242\002\250\n-\n-\n-\n-\n-\n-\n-\026\254\027\006\027\015\002\254\027\031\n-\n-\n-\n-\n-\0272\0032\001\190\027N\n-\027k\n-\n-\002\178\027{\027\151\003:\n-\n-\n-\b\026\b\030\b*\027\203\n-\005v\n-\n-\n-\n-\n-\n-\n-\n-\n-\027\231\n-\n-\027\242\n-\n-\028'\028;\028C\028\127\005\130\005\134\n-\n-\n-\028\135\n-\n-\n-\n-\n-\000\000\n-\n-\000\000\n-\n-\000\000\n-\n-\n-\n-\n-\n-\005\138\b2\n-\n-\n-\bJ\004r\000\000\000\000\n-\n-\n-\n-\0029\0029\000\000\000\000\000\000\0029\000\000\002\190\0029\000\000\002\130\0029\tf\0029\000\000\002\246\0029\000\000\0029\0029\0029\000\000\0029\0029\0029\001\210\002\225\tn\000\000\002\250\0029\0029\0029\0029\0029\tv\0029\000\000\000\000\000\000\002\254\004A\0029\0029\0029\0029\0029\000\000\0032\001\190\000\000\0029\000\n\0029\0029\002\178\000\000\000\000\003:\0029\0029\0029\b\026\b\030\b*\000\000\012f\005v\0029\0029\0029\0029\0029\0029\0029\0029\0029\000\000\004\173\0029\002\225\0029\0029\004A\006\130\002\190\004A\005\130\005\134\0029\0029\0029\000\000\0029\0029\0029\0029\000\000\000\238\004A\0029\004\173\0029\0029\004A\0029\0029\0029\0029\0029\0029\005\138\b2\0029\0029\0029\bJ\004r\000\000\004A\0029\0029\0029\0029\004A\007\030\004A\003\n\004A\004A\004A\004A\004A\004A\004A\017\186\004A\000\238\004A\004A\000\000\004A\004A\004A\016\134\004A\004A\004A\004A\004A\004A\004A\004A\004A\000\000\004A\004A\000\000\000\000\004A\004A\000\238\004A\004A\004A\004A\004A\007\138\004A\004A\004A\004A\004A\004A\004A\004A\000\238\004A\004A\004A\004A\004A\004A\004A\004A\000\238\004A\004A\004A\004A\004A\004A\004A\004A\b\189\004N\004A\000\000\000\000\004A\004A\004A\000\238\004A\000\n\000\000\004A\004A\004A\004A\004A\004A\004A\004A\004A\000\000\021\198\004A\004A\002\225\002\225\007f\004A\004B\006\233\000\000\004A\004A\000\000\007n\016\138\0226\002\225\000\238\004A\004A\004A\007r\000\000\004A\004A\004A\004A\006\233\000\161\004A\000\161\006\233\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\000\000\161\022\234\000\161\000\161\000\000\000\161\000\161\000\000\000\000\000\161\000\161\000\000\000\161\000\161\000\161\000\161\000\000\000\161\004R\000\161\000\161\b\189\000\000\000\161\000\161\005\141\000\161\000\161\000\161\000\238\000\161\b\241\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\000\b\138\000\161\000\161\000\000\000\000\000\161\000\161\002\006\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\161\002\n\006\233\000\161\015\130\t\029\000\161\002\130\000\161\001\210\000\161\005\141\002\190\000\000\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\161\000\000\000\000\000\000\000\161\003\154\017\238\t\029\005\141\000\222\000\000\007\002\001\222\000\161\000\000\002\226\000\000\014\150\002\178\000\161\000\161\000\161\000\161\000\000\015\134\000\161\000\161\000\161\000\161\002)\002)\004Y\000\000\003\n\002)\000\000\002\190\002)\015\146\002\130\002)\001b\002)\000\000\002\246\002)\007\006\002)\002)\002)\000\000\002)\002)\002)\001\210\001z\000\000\001\138\002\250\002)\002)\002)\002)\002)\005\134\002)\000\000\000\000\000\000\002\254\b\169\002)\002)\002)\002)\002)\004Y\0032\b.\000\000\002)\000\000\002)\002)\002\178\000\000\006\"\003:\002)\002)\002)\b\026\b\030\b*\tN\t~\005v\002)\002)\002)\002)\002)\002)\002)\002)\002)\006&\tN\t~\b\169\002)\002)\000\000\tV\000\000\t\134\005\130\005\134\002)\002)\002)\000\000\002)\002)\002)\002)\tV\000\000\t\134\002)\b\169\002)\002)\000\000\002)\002)\002)\002)\002)\002)\005\138\b2\002)\002)\002)\bJ\004r\000\238\002\225\002)\002)\002)\002)\002E\002E\002\225\002\225\000\000\002E\000\000\000\000\002E\000\000\b\169\002E\000\000\002E\004\254\000\000\002E\b\169\002E\002E\002E\000\n\002E\002E\002E\000\000\027\215\000\000\000\000\000\n\002E\002E\002E\002E\002E\000\000\002E\002\225\006*\004\169\000\000\005\234\002E\002E\002E\002E\002E\000\000\0066\002\225\000\000\002E\006B\002E\002E\000\000\000\000\002\225\006~\002E\002E\002E\004\169\000\000\006\213\t\025\000\000\000\000\002E\002E\002E\002E\002E\002E\002E\002E\002E\000\000\tN\t~\000\000\002E\002E\006\134\014\174\000\000\002\190\006\213\t\025\002E\002E\002E\000\000\002E\002E\002E\002E\tV\002\190\t\134\002E\002\130\002E\002E\001\210\002E\002E\002E\002E\002E\002E\b\165\000\000\002E\002E\002E\000\000\021\182\000\000\000\000\002E\002E\002E\002E\002A\002A\000\000\022\242\003\n\002A\022\246\003\022\002A\000\000\002\178\002A\000\000\002A\000\000\017\134\002A\023&\002A\002A\002A\tZ\002A\002A\002A\012&\b\165\000\000\000\000\015\146\002A\002A\002A\002A\002A\rj\002A\rv\000\000\012B\0236\012R\002A\002A\002A\002A\002A\b\165\bf\001\190\001*\002A\000\000\002A\002A\005\134\002\225\002\225\014V\002A\002A\002A\014j\014~\014\142\000\000\000\000\000\000\002A\002A\002A\002A\002A\002A\002A\002A\002A\000\000\tN\t~\b\165\002A\002A\000\n\004\254\000\000\001\206\b\165\000\000\002A\002A\002A\000\000\002A\002A\002A\002A\tV\000\000\t\134\002A\000\000\002A\002A\001\210\002A\002A\002A\002A\002A\002A\002\225\000\000\002A\002A\002A\000\000\018\174\000\000\000\000\002A\002A\002A\002A\002-\002-\000\000\000\000\002\154\002-\0196\003\022\002-\000\000\002\178\002-\000\000\002-\000\000\000\000\002-\019N\002-\002-\002-\012r\002-\002-\002-\002\225\002\225\016\178\000\000\000\000\002-\002-\002-\002-\002-\012\138\002-\012\162\000\000\000\000\002\225\r\006\002-\002-\002-\002-\002-\000\000\bf\014\206\000\000\002-\000\n\002-\002-\r\026\000\000\r.\014V\002-\002-\002-\014j\014~\014\142\000\000\000\000\000\000\002-\002-\002-\002-\002-\002-\002-\002-\002-\000\000\tN\t~\002\225\002-\002-\000\000\000\000\000\000\000\000\000\238\000\000\002-\002-\002-\000\000\002-\002-\002-\002-\tV\000\000\t\134\002-\000\000\002-\002-\000\000\002-\002-\002-\002-\002-\002-\000\000\000\000\002-\002-\002-\000\000\t:\000\000\000\000\002-\002-\002-\002-\002=\002=\000\000\000\000\000\000\002=\012}\006*\002=\000\000\005\234\002=\000\000\002=\000\000\000\000\002=\0066\002=\002=\002=\006B\002=\002=\002=\012}\012}\000\000\000\000\012}\002=\002=\002=\002=\002=\000\000\002=\b\021\000\000\000\000\b\021\000\000\002=\002=\002=\002=\002=\000\000\000\000\000\000\000\000\002=\000\000\002=\002=\000\000\000\000\000\000\022>\002=\002=\002=\000\000\000\000\000\000\000\000\000\000\000\238\002=\002=\002=\002=\002=\002=\002=\002=\002=\000\000\b\021\002=\000\000\002=\002=\000\000\000\000\000\000\000\000\000\000\000\000\002=\002=\002=\b\021\002=\002=\002=\002=\012}\000\000\004\253\002=\000\000\002=\002=\002\225\t\158\002=\002=\002=\002=\002=\004\253\n\230\002=\002=\002=\000\000\000\000\b\021\000\000\002=\002=\002=\002=\t%\t%\000\000\000\000\000\000\t%\000\000\000\000\t%\000\n\000\000\t%\000\000\t%\000\000\000\000\t\202\004\253\t%\t\238\t%\b\021\t%\t%\t%\002\225\000\000\000\000\000\000\017\"\n\002\n\026\n\"\n\n\n*\000\000\t%\002\225\002\225\000\000\000\000\000\000\t%\t%\n2\n:\t%\004\253\007\245\000\000\004\253\t%\000\000\nB\t%\000\000\000\000\000\000\000\000\t%\t%\000\238\000\000\000\000\000\000\000\000\000\000\002\246\t%\t%\t\210\n\018\nJ\nR\nb\t%\t%\002\166\012\193\t%\000\000\t%\nj\000\000\003Z\000\000\000\000\000\238\000\000\t%\t%\nr\000\000\t%\t%\t%\t%\003f\012\193\000\000\t%\000\000\t%\t%\002B\n\146\t%\n\154\nZ\t%\t%\000\000\000\000\t%\nz\t%\000\000\002F\000\000\005v\t%\t%\n\130\n\138\002q\002q\000\000\000\000\000\000\002q\012\133\006*\002q\000\000\005\234\002q\000\000\002q\000\000\005\130\002q\0066\002q\002q\002q\006B\002q\002q\002q\012\133\012\133\000\000\000\000\012\133\002q\002q\002q\002q\002q\000\000\002q\015\130\000\000\005\138\002\130\000\000\002q\002q\002q\002q\002q\000\000\000\000\000\000\000\000\002q\000\000\002q\002q\000\000\000\000\000\000\000\000\002q\002q\002q\000\000\000\000\000\000\000\000\000\000\000\238\002q\002q\t\210\002q\002q\002q\002q\002q\002q\000\000\015\134\002q\000\000\002q\002q\000\000\000\000\000\000\000\000\000\000\000\000\002q\002q\002q\015\146\002q\002q\002q\002q\012\133\000\000\001\206\002q\000\000\002q\002q\000\000\002q\002q\002q\002q\002q\002q\026\014\000\000\002q\002q\002q\000\000\000\000\005\134\000\000\002q\002q\002q\002q\002Y\002Y\000\000\000\000\000\000\002Y\000\000\002\190\002Y\000\000\000\000\002Y\000\000\002Y\003\170\000\000\002Y\002\154\002Y\002Y\002Y\025~\002Y\002Y\002Y\001\210\000\000\000\000\000\000\000\000\002Y\002Y\002Y\002Y\002Y\000\000\002Y\015\130\000\000\000\000\002\130\000\000\002Y\002Y\002Y\002Y\002Y\004\154\003\202\000\000\004\217\002Y\000\000\002Y\002Y\002\178\000\000\000\000\000\000\002Y\002Y\002Y\000\000\000\000\000\000\000\000\000\000\000\000\002Y\002Y\t\210\002Y\002Y\002Y\002Y\002Y\002Y\000\000\015\134\002Y\000\000\002Y\002Y\006\234\000\000\000\000\000\000\000\000\000\000\002Y\002Y\002Y\015\146\002Y\002Y\002Y\002Y\000\000\000\000\000\000\002Y\000\000\002Y\002Y\000\000\002Y\002Y\002Y\002Y\002Y\002Y\012\129\000\000\002Y\002Y\002Y\000\000\000\000\005\134\000\000\002Y\002Y\002Y\002Y\002e\002e\000\000\000\000\000\000\002e\012\129\012\129\002e\000\000\012\129\002e\000\000\002e\000\000\000\000\t\202\000\000\002e\002e\002e\021\026\002e\002e\002e\000\000\000\000\000\000\000\000\000\000\002e\002e\002e\n\n\002e\000\000\002e\000\000\000\000\000\000\000\000\000\000\002e\002e\002e\002e\002e\000\000\000\238\000\000\000\000\002e\000\000\002e\002e\000\000\000\000\000\000\000\000\002e\002e\002e\000\000\000\000\000\000\000\000\000\000\000\000\002e\002e\t\210\n\018\002e\002e\002e\002e\002e\000\000\012\129\002e\000\000\002e\002e\000\000\000\000\000\000\000\000\000\238\b\t\002e\002e\002e\b\t\002e\002e\002e\002e\000\000\000\000\000\000\002e\000\000\002e\002e\000\000\002e\002e\002e\002e\002e\002e\000\000\000\000\002e\002e\002e\000\000\011\154\000\000\000\000\002e\002e\002e\002e\002u\002u\000\000\000\000\000\000\002u\b\t\011\162\002u\000\000\011\174\002u\000\000\002u\000\000\000\000\002u\011\186\002u\002u\002u\011\198\002u\002u\002u\000\000\000\000\b\t\000\000\000\000\002u\002u\002u\002u\002u\000\000\002u\000\000\000\000\000\000\000\000\000\000\002u\002u\002u\002u\002u\000\000\000\000\000\000\000\000\002u\000\000\002u\002u\000\000\000\000\000\000\000\000\002u\002u\002u\000\000\000\000\004\254\000\000\000\000\000\000\002u\002u\t\210\002u\002u\002u\002u\002u\002u\000\000\007\234\002u\000\000\002u\002u\000\000\000\000\000\000\000\000\000\238\b\005\002u\002u\002u\b\005\002u\002u\002u\002u\000\000\007\238\000\000\002u\000\000\002u\002u\000\000\002u\002u\002u\002u\002u\002u\000\000\000\000\002u\002u\002u\000\000\007\165\000\000\000\000\002u\002u\002u\002u\002U\002U\007\222\000\000\000\000\002U\b\005\007\165\002U\000\000\005\234\002U\000\000\002U\000\000\000\238\002U\007\165\002U\002U\002U\007\165\002U\002U\002U\000\000\000\000\b\005\000\000\000\000\002U\002U\002U\002U\002U\000\000\002U\000\000\000\000\006\253\000\000\000\000\002U\002U\002U\002U\002U\000\000\000\000\000\000\000\000\002U\000\000\002U\002U\000\000\000\000\000\000\006\253\002U\002U\002U\006\253\007\242\004\254\000\000\000\000\000\000\002U\002U\t\210\002U\002U\002U\002U\002U\002U\000\000\000\000\002U\000\000\002U\002U\000\000\000\000\000\000\000\000\007\189\000\000\002U\002U\002U\000\000\002U\002U\002U\002U\000\000\000\000\000\000\002U\000\000\002U\002U\000\000\002U\002U\002U\002U\002U\002U\000\000\000\000\002U\002U\002U\000\000\007\189\000\000\000\000\002U\002U\002U\002U\002a\002a\000\000\000\000\000\000\002a\005f\007\189\002a\000\000\005\234\002a\000\000\002a\000\000\000\000\t\202\007\189\002a\002a\002a\007\189\002a\002a\002a\000\000\000\000\000\000\000\000\000\000\002a\002a\002a\n\n\002a\000\000\002a\000\000\000\000\006\237\000\000\000\000\002a\002a\002a\002a\002a\000\000\000\000\000\000\000\000\002a\000\000\002a\002a\000\000\000\000\000\000\006\237\002a\002a\002a\006\237\000\000\000\000\000\000\000\000\000\000\002a\002a\t\210\n\018\002a\002a\002a\002a\002a\000\000\000\000\002a\000\000\002a\002a\000\000\000\000\000\000\000\000\000\238\000\000\002a\002a\002a\000\000\002a\002a\002a\002a\000\000\000\000\000\000\002a\000\000\002a\002a\000\000\002a\002a\002a\002a\002a\002a\000\000\000\000\002a\002a\002a\000\000\007\217\000\000\000\000\002a\002a\002a\002a\002]\002]\000\000\000\000\000\000\002]\b&\006*\002]\000\000\005\234\002]\000\000\002]\000\000\000\000\t\202\007\217\002]\002]\002]\007\217\002]\002]\002]\000\000\000\000\000\000\000\000\000\000\002]\002]\002]\n\n\002]\000\000\002]\000\000\000\000\000\000\000\000\000\000\002]\002]\002]\002]\002]\000\000\000\000\000\000\000\000\002]\000\000\002]\002]\000\000\000\000\000\000\000\000\002]\002]\002]\000\000\000\000\000\000\000\000\000\000\000\000\002]\002]\t\210\n\018\002]\002]\002]\002]\002]\000\000\000\000\002]\000\000\002]\002]\000\000\000\000\000\000\000\000\007\209\000\000\002]\002]\002]\000\000\002]\002]\002]\002]\000\000\000\000\000\000\002]\000\000\002]\002]\000\000\002]\002]\002]\002]\002]\002]\000\000\000\000\002]\002]\002]\000\000\007\209\000\000\000\000\002]\002]\002]\002]\002\133\002\133\000\000\000\000\000\000\002\133\000\000\011\222\002\133\000\000\007\209\002\133\000\000\002\133\000\000\000\000\t\202\007\209\002\133\002\133\002\133\007\209\002\133\002\133\002\133\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\133\000\000\000\000\000\000\000\000\000\000\002\133\002\133\n2\n:\002\133\000\000\000\000\000\000\000\000\002\133\000\000\nB\002\133\000\000\000\000\000\000\000\000\002\133\002\133\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\133\002\133\t\210\n\018\nJ\nR\nb\002\133\002\133\000\000\000\000\002\133\000\000\002\133\nj\000\000\000\000\000\000\000\000\000\238\000\000\002\133\002\133\nr\000\000\002\133\002\133\002\133\002\133\000\000\000\000\000\000\002\133\000\000\002\133\002\133\000\000\002\133\002\133\002\133\nZ\002\133\002\133\000\000\000\000\002\133\nz\002\133\000\000\007\161\000\000\000\000\002\133\002\133\n\130\n\138\002m\002m\000\000\000\000\000\000\002m\000\000\007\161\002m\000\000\005\234\002m\000\000\002m\000\000\000\000\t\202\007\161\002m\002m\002m\007\161\002m\002m\002m\000\000\000\000\000\000\000\000\000\000\002m\002m\002m\n\n\002m\000\000\002m\000\000\000\000\000\000\000\000\000\000\002m\002m\002m\002m\002m\000\000\000\000\000\000\000\000\002m\000\000\002m\002m\000\000\000\000\000\000\000\000\002m\002m\002m\000\000\000\000\000\000\000\000\000\000\000\000\002m\002m\t\210\n\018\002m\002m\002m\002m\002m\000\000\000\000\002m\000\000\002m\002m\000\000\000\000\000\000\000\000\000\238\000\000\002m\002m\002m\000\000\002m\002m\002m\002m\000\000\000\000\000\000\002m\000\000\002m\002m\000\000\002m\002m\002m\002m\002m\002m\000\000\000\000\002m\002m\002m\000\000\014&\000\000\000\000\002m\002m\002m\002m\002i\002i\000\000\000\000\000\000\002i\000\000\011\162\002i\000\000\011\174\002i\000\000\002i\000\000\000\000\t\202\011\186\002i\002i\002i\011\198\002i\002i\002i\000\000\000\000\000\000\000\000\000\000\002i\002i\002i\n\n\002i\000\000\002i\000\000\000\000\000\000\000\000\000\000\002i\002i\002i\002i\002i\000\000\000\000\000\000\000\000\002i\000\000\002i\002i\000\000\000\000\000\000\000\000\002i\002i\002i\000\000\000\000\000\000\000\000\000\000\000\000\002i\002i\t\210\n\018\002i\002i\002i\002i\002i\000\000\000\000\002i\000\000\002i\002i\000\000\000\000\000\000\000\000\000\000\000\000\002i\002i\002i\000\000\002i\002i\002i\002i\000\000\000\000\000\000\002i\000\000\002i\002i\000\000\002i\002i\002i\002i\002i\002i\000\000\000\000\002i\002i\002i\000\000\000\000\000\000\000\000\002i\002i\002i\002i\002}\002}\000\000\000\000\000\000\002}\000\000\002\006\002}\000\000\002\130\002}\000\000\002}\000\000\000\000\t\202\000\000\002}\002}\002}\000\000\002}\002}\002}\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\002}\000\000\002}\000\000\000\000\000\000\000\000\000\000\002}\002}\n2\n:\002}\000\000\027*\001\222\000\000\002}\000\000\002}\002}\000\000\000\000\000\000\000\000\002}\002}\000\238\015\146\000\000\000\000\000\000\000\000\000\000\002}\002}\t\210\n\018\nJ\nR\002}\002}\002}\000\000\000\000\002}\000\000\002}\002}\000\000\000\000\000\000\000\000\000\000\005\134\002}\002}\002}\000\000\002}\002}\002}\002}\000\000\000\000\000\000\002}\000\000\002}\002}\000\000\002}\002}\002}\nZ\002}\002}\000\000\000\000\002}\002}\002}\000\000\000\000\000\000\000\000\002}\002}\002}\002}\002Q\002Q\000\000\000\000\000\000\002Q\000\000\003\022\002Q\000\000\000\000\002Q\000\000\002Q\000\000\000\000\t\202\000\000\002Q\002Q\002Q\000\000\002Q\002Q\002Q\000\000\000\000\000\000\000\000\000\000\002Q\002Q\002Q\n\n\002Q\000\000\002Q\000\000\000\000\000\000\000\000\000\000\002Q\002Q\002Q\002Q\002Q\000\000\005\190\000\000\000\000\002Q\000\000\002Q\002Q\000\000\000\000\000\000\003\246\002Q\002Q\002Q\006N\000\000\004\002\000\000\000\000\000\000\002Q\002Q\t\210\n\018\002Q\002Q\002Q\002Q\002Q\000\000\000\000\002Q\000\000\002Q\002Q\000\000\000\000\000\000\000\000\000\000\000\000\002Q\002Q\002Q\000\000\002Q\002Q\002Q\002Q\000\000\000\000\000\000\002Q\000\000\002Q\002Q\000\000\002Q\002Q\002Q\002Q\002Q\002Q\000\000\000\000\002Q\002Q\002Q\000\000\000\000\000\000\000\000\002Q\002Q\002Q\002Q\002M\002M\000\000\000\000\000\000\002M\000\000\002\190\002M\000\000\000\000\002M\000\000\002M\000\000\000\000\t\202\000\000\002M\002M\002M\000\000\002M\002M\002M\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\002M\000\000\002M\000\000\000\000\000\000\000\000\000\000\002M\002M\n2\n:\002M\000\000\t\138\003\n\000\000\002M\000\000\002M\002M\000\000\000\000\000\000\000\000\002M\002M\000\238\011\254\000\000\012\014\000\000\000\000\000\000\002M\002M\t\210\n\018\nJ\nR\002M\002M\002M\000\000\000\000\002M\000\000\002M\002M\000\000\000\000\000\000\000\000\000\000\000\000\002M\002M\002M\000\000\002M\002M\002M\002M\000\000\000\000\000\000\002M\000\000\002M\002M\000\000\002M\002M\002M\nZ\002M\002M\000\000\000\000\002M\002M\002M\000\000\000\000\000\000\000\000\002M\002M\002M\002M\002\169\002\169\000\000\000\000\000\000\002\169\000\000\002\190\002\169\000\000\000\000\002\169\000\000\002\169\000\000\000\000\t\202\000\000\002\169\002\169\002\169\000\000\002\169\002\169\002\169\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\002\169\000\000\002\169\000\000\000\000\000\000\000\000\000\000\002\169\002\169\n2\n:\002\169\000\000\012\194\003\n\000\000\002\169\000\000\002\169\002\169\000\000\000\000\000\000\000\000\002\169\002\169\002\169\012\214\000\000\012\234\000\000\000\000\000\000\002\169\002\169\t\210\n\018\nJ\002\169\002\169\002\169\002\169\000\000\000\000\002\169\000\000\002\169\002\169\000\000\000\000\000\000\000\000\000\000\000\000\002\169\002\169\002\169\000\000\002\169\002\169\002\169\002\169\000\000\000\000\000\000\002\169\000\000\002\169\002\169\000\000\002\169\002\169\002\169\nZ\002\169\002\169\000\000\000\000\002\169\002\169\002\169\000\000\000\000\000\000\000\000\002\169\002\169\002\169\002\169\002I\002I\000\000\000\000\000\000\002I\000\000\000\000\002I\000\000\000\000\002I\000\000\002I\000\000\000\000\t\202\000\000\002I\002I\002I\000\000\002I\002I\002I\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\002I\000\000\002I\000\000\000\000\000\000\000\000\000\000\002I\002I\n2\n:\002I\000\000\000\000\000\000\000\000\002I\000\000\002I\002I\000\000\000\000\000\000\000\000\002I\002I\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002I\002I\t\210\n\018\nJ\nR\002I\002I\002I\000\000\000\000\002I\000\000\002I\002I\000\000\000\000\000\000\000\000\000\000\000\000\002I\002I\002I\000\000\002I\002I\002I\002I\000\000\000\000\000\000\002I\000\000\002I\002I\000\000\002I\002I\002I\nZ\002I\002I\000\000\000\000\002I\002I\002I\000\000\000\000\000\000\000\000\002I\002I\002I\002I\002\129\002\129\000\000\000\000\000\000\002\129\000\000\000\000\002\129\000\000\000\000\002\129\000\000\002\129\000\000\000\000\t\202\000\000\002\129\002\129\002\129\000\000\002\129\002\129\002\129\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\002\129\000\000\002\129\000\000\000\000\000\000\000\000\000\000\002\129\002\129\n2\n:\002\129\000\000\000\000\000\000\000\000\002\129\000\000\002\129\002\129\000\000\000\000\000\000\000\000\002\129\002\129\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\129\002\129\t\210\n\018\nJ\nR\002\129\002\129\002\129\000\000\000\000\002\129\000\000\002\129\002\129\000\000\000\000\000\000\000\000\000\000\000\000\002\129\002\129\002\129\000\000\002\129\002\129\002\129\002\129\000\000\000\000\000\000\002\129\000\000\002\129\002\129\000\000\002\129\002\129\002\129\nZ\002\129\002\129\000\000\000\000\002\129\002\129\002\129\000\000\000\000\000\000\000\000\002\129\002\129\002\129\002\129\002y\002y\000\000\000\000\000\000\002y\000\000\000\000\002y\000\000\000\000\002y\000\000\002y\000\000\000\000\t\202\000\000\002y\002y\002y\000\000\002y\002y\002y\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\002y\000\000\002y\000\000\000\000\000\000\000\000\000\000\002y\002y\n2\n:\002y\000\000\000\000\000\000\000\000\002y\000\000\002y\002y\000\000\000\000\000\000\000\000\002y\002y\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002y\002y\t\210\n\018\nJ\nR\002y\002y\002y\000\000\000\000\002y\000\000\002y\002y\000\000\000\000\000\000\000\000\000\000\000\000\002y\002y\002y\000\000\002y\002y\002y\002y\000\000\000\000\000\000\002y\000\000\002y\002y\000\000\002y\002y\002y\nZ\002y\002y\000\000\000\000\002y\002y\002y\000\000\000\000\000\000\000\000\002y\002y\002y\002y\002\137\002\137\000\000\000\000\000\000\002\137\000\000\000\000\002\137\000\000\000\000\002\137\000\000\002\137\000\000\000\000\t\202\000\000\002\137\002\137\002\137\000\000\002\137\002\137\002\137\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\137\000\000\000\000\000\000\000\000\000\000\002\137\002\137\n2\n:\002\137\000\000\000\000\000\000\000\000\002\137\000\000\nB\002\137\000\000\000\000\000\000\000\000\002\137\002\137\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\137\002\137\t\210\n\018\nJ\nR\nb\002\137\002\137\000\000\000\000\002\137\000\000\002\137\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\137\002\137\nr\000\000\002\137\002\137\002\137\002\137\000\000\000\000\000\000\002\137\000\000\002\137\002\137\000\000\002\137\002\137\002\137\nZ\002\137\002\137\000\000\000\000\002\137\nz\002\137\000\000\000\000\000\000\000\000\002\137\002\137\n\130\n\138\002\141\002\141\000\000\000\000\000\000\002\141\000\000\000\000\002\141\000\000\000\000\002\141\000\000\002\141\000\000\000\000\t\202\000\000\002\141\002\141\002\141\000\000\002\141\002\141\002\141\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\002\141\000\000\002\141\000\000\000\000\000\000\000\000\000\000\002\141\002\141\n2\n:\002\141\000\000\000\000\000\000\000\000\002\141\000\000\nB\002\141\000\000\000\000\000\000\000\000\002\141\002\141\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\141\002\141\t\210\n\018\nJ\nR\nb\002\141\002\141\000\000\000\000\002\141\000\000\002\141\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\141\002\141\nr\000\000\002\141\002\141\002\141\002\141\000\000\000\000\000\000\002\141\000\000\002\141\002\141\000\000\002\141\002\141\002\141\nZ\002\141\002\141\000\000\000\000\002\141\002\141\002\141\000\000\000\000\000\000\000\000\002\141\002\141\n\130\n\138\002\145\002\145\000\000\000\000\000\000\002\145\000\000\000\000\002\145\000\000\000\000\002\145\000\000\002\145\000\000\000\000\t\202\000\000\002\145\002\145\002\145\000\000\002\145\002\145\002\145\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\002\145\000\000\002\145\000\000\000\000\000\000\000\000\000\000\002\145\002\145\n2\n:\002\145\000\000\000\000\000\000\000\000\002\145\000\000\nB\002\145\000\000\000\000\000\000\000\000\002\145\002\145\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\145\002\145\t\210\n\018\nJ\nR\nb\002\145\002\145\000\000\000\000\002\145\000\000\002\145\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\145\002\145\nr\000\000\002\145\002\145\002\145\002\145\000\000\000\000\000\000\002\145\000\000\002\145\002\145\000\000\002\145\002\145\002\145\nZ\002\145\002\145\000\000\000\000\002\145\002\145\002\145\000\000\000\000\000\000\000\000\002\145\002\145\n\130\n\138\b\225\b\225\000\000\000\000\000\000\b\225\000\000\000\000\b\225\000\000\000\000\b\225\000\000\b\225\000\000\000\000\t\202\000\000\b\225\b\225\b\225\000\000\b\225\b\225\b\225\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\b\225\000\000\000\000\000\000\000\000\000\000\b\225\b\225\n2\n:\b\225\000\000\000\000\000\000\000\000\b\225\000\000\nB\b\225\000\000\000\000\000\000\000\000\b\225\b\225\000\238\000\000\000\000\000\000\000\000\000\000\000\000\b\225\b\225\t\210\n\018\nJ\nR\nb\b\225\b\225\000\000\000\000\b\225\000\000\b\225\nj\000\000\000\000\000\000\000\000\000\000\000\000\b\225\b\225\nr\000\000\b\225\b\225\b\225\b\225\000\000\000\000\000\000\b\225\000\000\b\225\b\225\000\000\b\225\b\225\b\225\nZ\b\225\b\225\000\000\000\000\b\225\nz\b\225\000\000\000\000\000\000\000\000\b\225\b\225\n\130\n\138\002\149\002\149\000\000\000\000\000\000\002\149\000\000\000\000\002\149\000\000\000\000\002\149\000\000\002\149\000\000\000\000\t\202\000\000\002\149\002\149\002\149\000\000\002\149\002\149\002\149\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\149\000\000\000\000\000\000\000\000\000\000\002\149\002\149\n2\n:\002\149\000\000\000\000\000\000\000\000\002\149\000\000\nB\002\149\000\000\000\000\000\000\000\000\002\149\002\149\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\149\002\149\t\210\n\018\nJ\nR\nb\002\149\002\149\000\000\000\000\002\149\000\000\002\149\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\149\002\149\nr\000\000\002\149\002\149\002\149\002\149\000\000\000\000\000\000\002\149\000\000\002\149\002\149\000\000\n\146\002\149\n\154\nZ\002\149\002\149\000\000\000\000\002\149\nz\002\149\000\000\000\000\000\000\000\000\002\149\002\149\n\130\n\138\b\221\b\221\000\000\000\000\000\000\b\221\000\000\000\000\b\221\000\000\000\000\b\221\000\000\b\221\000\000\000\000\t\202\000\000\b\221\b\221\b\221\000\000\b\221\b\221\b\221\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\b\221\000\000\000\000\000\000\000\000\000\000\b\221\b\221\n2\n:\b\221\000\000\000\000\000\000\000\000\b\221\000\000\nB\b\221\000\000\000\000\000\000\000\000\b\221\b\221\000\238\000\000\000\000\000\000\000\000\000\000\000\000\b\221\b\221\t\210\n\018\nJ\nR\nb\b\221\b\221\000\000\000\000\b\221\000\000\b\221\nj\000\000\000\000\000\000\000\000\000\000\000\000\b\221\b\221\nr\000\000\b\221\b\221\b\221\b\221\000\000\000\000\000\000\b\221\000\000\b\221\b\221\000\000\b\221\b\221\b\221\nZ\b\221\b\221\000\000\000\000\b\221\nz\b\221\000\000\000\000\000\000\000\000\b\221\b\221\n\130\n\138\002\197\002\197\000\000\000\000\000\000\002\197\000\000\000\000\002\197\000\000\000\000\002\197\000\000\002\197\000\000\000\000\t\202\000\000\002\197\002\197\002\197\000\000\002\197\002\197\002\197\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\197\000\000\000\000\000\000\000\000\000\000\002\197\002\197\n2\n:\002\197\000\000\000\000\000\000\000\000\002\197\000\000\nB\002\197\000\000\000\000\000\000\000\000\002\197\002\197\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\197\002\197\t\210\n\018\nJ\nR\nb\002\197\002\197\000\000\000\000\002\197\000\000\002\197\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\197\002\197\nr\000\000\002\197\002\197\002\197\002\197\000\000\000\000\000\000\002\197\000\000\002\197\002\197\000\000\n\146\002\197\n\154\nZ\002\197\002\197\000\000\000\000\002\197\nz\002\197\000\000\000\000\000\000\000\000\002\197\002\197\n\130\n\138\002\193\002\193\000\000\000\000\000\000\002\193\000\000\000\000\002\193\000\000\000\000\002\193\000\000\002\193\000\000\000\000\t\202\000\000\002\193\002\193\002\193\000\000\002\193\002\193\002\193\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\193\000\000\000\000\000\000\000\000\000\000\002\193\002\193\n2\n:\002\193\000\000\000\000\000\000\000\000\002\193\000\000\nB\002\193\000\000\000\000\000\000\000\000\002\193\002\193\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\193\002\193\t\210\n\018\nJ\nR\nb\002\193\002\193\000\000\000\000\002\193\000\000\002\193\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\193\002\193\nr\000\000\002\193\002\193\002\193\002\193\000\000\000\000\000\000\002\193\000\000\002\193\002\193\000\000\n\146\002\193\n\154\nZ\002\193\002\193\000\000\000\000\002\193\nz\002\193\000\000\000\000\000\000\000\000\002\193\002\193\n\130\n\138\002\201\002\201\000\000\000\000\000\000\002\201\000\000\000\000\002\201\000\000\000\000\002\201\000\000\002\201\000\000\000\000\t\202\000\000\002\201\002\201\002\201\000\000\002\201\002\201\002\201\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\201\000\000\000\000\000\000\000\000\000\000\002\201\002\201\n2\n:\002\201\000\000\000\000\000\000\000\000\002\201\000\000\nB\002\201\000\000\000\000\000\000\000\000\002\201\002\201\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\201\002\201\t\210\n\018\nJ\nR\nb\002\201\002\201\000\000\000\000\002\201\000\000\002\201\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\201\002\201\nr\000\000\002\201\002\201\002\201\002\201\000\000\000\000\000\000\002\201\000\000\002\201\002\201\000\000\n\146\002\201\n\154\nZ\002\201\002\201\000\000\000\000\002\201\nz\002\201\000\000\000\000\000\000\000\000\002\201\002\201\n\130\n\138\002\181\002\181\000\000\000\000\000\000\002\181\000\000\000\000\002\181\000\000\000\000\002\181\000\000\002\181\000\000\000\000\t\202\000\000\002\181\002\181\002\181\000\000\002\181\002\181\002\181\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\181\000\000\000\000\000\000\000\000\000\000\002\181\002\181\n2\n:\002\181\000\000\000\000\000\000\000\000\002\181\000\000\nB\002\181\000\000\000\000\000\000\000\000\002\181\002\181\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\181\002\181\t\210\n\018\nJ\nR\nb\002\181\002\181\000\000\000\000\002\181\000\000\002\181\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\181\002\181\nr\000\000\002\181\002\181\002\181\002\181\000\000\000\000\000\000\002\181\000\000\002\181\002\181\000\000\n\146\002\181\n\154\nZ\002\181\002\181\000\000\000\000\002\181\nz\002\181\000\000\000\000\000\000\000\000\002\181\002\181\n\130\n\138\002\185\002\185\000\000\000\000\000\000\002\185\000\000\000\000\002\185\000\000\000\000\002\185\000\000\002\185\000\000\000\000\t\202\000\000\002\185\002\185\002\185\000\000\002\185\002\185\002\185\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\185\000\000\000\000\000\000\000\000\000\000\002\185\002\185\n2\n:\002\185\000\000\000\000\000\000\000\000\002\185\000\000\nB\002\185\000\000\000\000\000\000\000\000\002\185\002\185\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\185\002\185\t\210\n\018\nJ\nR\nb\002\185\002\185\000\000\000\000\002\185\000\000\002\185\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\185\002\185\nr\000\000\002\185\002\185\002\185\002\185\000\000\000\000\000\000\002\185\000\000\002\185\002\185\000\000\n\146\002\185\n\154\nZ\002\185\002\185\000\000\000\000\002\185\nz\002\185\000\000\000\000\000\000\000\000\002\185\002\185\n\130\n\138\002\189\002\189\000\000\000\000\000\000\002\189\000\000\000\000\002\189\000\000\000\000\002\189\000\000\002\189\000\000\000\000\t\202\000\000\002\189\002\189\002\189\000\000\002\189\002\189\002\189\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\189\000\000\000\000\000\000\000\000\000\000\002\189\002\189\n2\n:\002\189\000\000\000\000\000\000\000\000\002\189\000\000\nB\002\189\000\000\000\000\000\000\000\000\002\189\002\189\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\189\002\189\t\210\n\018\nJ\nR\nb\002\189\002\189\000\000\000\000\002\189\000\000\002\189\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\189\002\189\nr\000\000\002\189\002\189\002\189\002\189\000\000\000\000\000\000\002\189\000\000\002\189\002\189\000\000\n\146\002\189\n\154\nZ\002\189\002\189\000\000\000\000\002\189\nz\002\189\000\000\000\000\000\000\000\000\002\189\002\189\n\130\n\138\002\209\002\209\000\000\000\000\000\000\002\209\000\000\000\000\002\209\000\000\000\000\002\209\000\000\002\209\000\000\000\000\t\202\000\000\002\209\002\209\002\209\000\000\002\209\002\209\002\209\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\209\000\000\000\000\000\000\000\000\000\000\002\209\002\209\n2\n:\002\209\000\000\000\000\000\000\000\000\002\209\000\000\nB\002\209\000\000\000\000\000\000\000\000\002\209\002\209\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\209\002\209\t\210\n\018\nJ\nR\nb\002\209\002\209\000\000\000\000\002\209\000\000\002\209\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\209\002\209\nr\000\000\002\209\002\209\002\209\002\209\000\000\000\000\000\000\002\209\000\000\002\209\002\209\000\000\n\146\002\209\n\154\nZ\002\209\002\209\000\000\000\000\002\209\nz\002\209\000\000\000\000\000\000\000\000\002\209\002\209\n\130\n\138\002\205\002\205\000\000\000\000\000\000\002\205\000\000\000\000\002\205\000\000\000\000\002\205\000\000\002\205\000\000\000\000\t\202\000\000\002\205\002\205\002\205\000\000\002\205\002\205\002\205\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\205\000\000\000\000\000\000\000\000\000\000\002\205\002\205\n2\n:\002\205\000\000\000\000\000\000\000\000\002\205\000\000\nB\002\205\000\000\000\000\000\000\000\000\002\205\002\205\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\205\002\205\t\210\n\018\nJ\nR\nb\002\205\002\205\000\000\000\000\002\205\000\000\002\205\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\205\002\205\nr\000\000\002\205\002\205\002\205\002\205\000\000\000\000\000\000\002\205\000\000\002\205\002\205\000\000\n\146\002\205\n\154\nZ\002\205\002\205\000\000\000\000\002\205\nz\002\205\000\000\000\000\000\000\000\000\002\205\002\205\n\130\n\138\002\213\002\213\000\000\000\000\000\000\002\213\000\000\000\000\002\213\000\000\000\000\002\213\000\000\002\213\000\000\000\000\t\202\000\000\002\213\002\213\002\213\000\000\002\213\002\213\002\213\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\213\000\000\000\000\000\000\000\000\000\000\002\213\002\213\n2\n:\002\213\000\000\000\000\000\000\000\000\002\213\000\000\nB\002\213\000\000\000\000\000\000\000\000\002\213\002\213\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\213\002\213\t\210\n\018\nJ\nR\nb\002\213\002\213\000\000\000\000\002\213\000\000\002\213\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\213\002\213\nr\000\000\002\213\002\213\002\213\002\213\000\000\000\000\000\000\002\213\000\000\002\213\002\213\000\000\n\146\002\213\n\154\nZ\002\213\002\213\000\000\000\000\002\213\nz\002\213\000\000\000\000\000\000\000\000\002\213\002\213\n\130\n\138\002\177\002\177\000\000\000\000\000\000\002\177\000\000\000\000\002\177\000\000\000\000\002\177\000\000\002\177\000\000\000\000\t\202\000\000\002\177\002\177\002\177\000\000\002\177\002\177\002\177\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\177\000\000\000\000\000\000\000\000\000\000\002\177\002\177\n2\n:\002\177\000\000\000\000\000\000\000\000\002\177\000\000\nB\002\177\000\000\000\000\000\000\000\000\002\177\002\177\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\177\002\177\t\210\n\018\nJ\nR\nb\002\177\002\177\000\000\000\000\002\177\000\000\002\177\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\177\002\177\nr\000\000\002\177\002\177\002\177\002\177\000\000\000\000\000\000\002\177\000\000\002\177\002\177\000\000\n\146\002\177\n\154\nZ\002\177\002\177\000\000\000\000\002\177\nz\002\177\000\000\000\000\000\000\000\000\002\177\002\177\n\130\n\138\002\001\002\001\000\000\000\000\000\000\002\001\000\000\000\000\002\001\000\000\000\000\002\001\000\000\002\001\000\000\000\000\002\001\000\000\002\001\002\001\002\001\000\000\002\001\002\001\002\001\000\000\000\000\000\000\000\000\000\000\002\001\002\001\002\001\002\001\002\001\000\000\002\001\000\000\000\000\000\000\000\000\000\000\002\001\002\001\002\001\002\001\002\001\000\000\000\000\000\000\000\000\002\001\000\000\002\001\002\001\000\000\000\000\000\000\000\000\002\001\002\001\002\001\000\000\000\000\000\000\000\000\000\000\000\000\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\000\000\000\000\002\001\000\000\002\001\002\001\000\000\000\000\000\000\000\000\000\000\000\000\002\001\002\001\002\001\000\000\002\001\002\001\002\001\002\001\000\000\000\000\000\000\002\001\000\000\002\001\002\001\000\000\002\001\002\001\002\001\002\001\002\001\002\001\000\000\000\000\002\001\002\001\r\254\000\000\000\000\000\000\000\000\002\001\002\001\002\001\002\001\002\029\002\029\000\000\000\000\000\000\002\029\000\000\000\000\002\029\000\000\000\000\002\029\000\000\002\029\000\000\000\000\t\202\000\000\002\029\002\029\002\029\000\000\002\029\002\029\002\029\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\029\000\000\000\000\000\000\000\000\000\000\002\029\002\029\n2\n:\002\029\000\000\000\000\000\000\000\000\002\029\000\000\nB\002\029\000\000\000\000\000\000\000\000\002\029\002\029\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\029\002\029\t\210\n\018\nJ\nR\nb\002\029\002\029\000\000\000\000\002\029\000\000\002\029\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\029\002\029\nr\000\000\002\029\002\029\014\022\002\029\000\000\000\000\000\000\002\029\000\000\002\029\002\029\000\000\n\146\002\029\n\154\nZ\002\029\002\029\000\000\000\000\002\029\nz\002\029\000\000\000\000\000\000\000\000\002\029\002\029\n\130\n\138\002\025\002\025\000\000\000\000\000\000\002\025\000\000\000\000\002\025\000\000\000\000\002\025\000\000\002\025\000\000\000\000\t\202\000\000\002\025\002\025\002\025\000\000\002\025\002\025\002\025\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\025\000\000\000\000\000\000\000\000\000\000\002\025\002\025\n2\n:\002\025\000\000\000\000\000\000\000\000\002\025\000\000\nB\002\025\000\000\000\000\000\000\000\000\002\025\002\025\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\025\002\025\t\210\n\018\nJ\nR\nb\002\025\002\025\000\000\000\000\002\025\000\000\002\025\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\025\002\025\nr\000\000\002\025\002\025\002\025\002\025\000\000\000\000\000\000\002\025\000\000\002\025\002\025\000\000\n\146\002\025\n\154\nZ\002\025\002\025\000\000\000\000\002\025\nz\002\025\000\000\000\000\000\000\000\000\002\025\002\025\n\130\n\138\002\173\002\173\000\000\000\000\000\000\002\173\000\000\000\000\002\173\000\000\000\000\002\173\000\000\002\173\000\000\000\000\t\202\000\000\002\173\002\173\002\173\000\000\002\173\002\173\002\173\000\000\000\000\000\000\000\000\000\000\n\002\n\026\n\"\n\n\n*\000\000\002\173\000\000\000\000\000\000\000\000\000\000\002\173\002\173\n2\n:\002\173\000\000\000\000\000\000\000\000\002\173\000\000\nB\002\173\000\000\000\000\000\000\000\000\002\173\002\173\000\238\000\000\000\000\000\000\000\000\000\000\000\000\002\173\002\173\t\210\n\018\nJ\nR\nb\002\173\002\173\000\000\000\000\002\173\000\000\002\173\nj\000\000\000\000\000\000\000\000\000\000\000\000\002\173\002\173\nr\000\000\002\173\002\173\002\173\002\173\000\000\000\000\000\000\002\173\000\000\002\173\002\173\000\000\n\146\002\173\n\154\nZ\002\173\002\173\000\000\000\000\002\173\nz\002\173\000\000\000\000\000\000\000\000\002\173\002\173\n\130\n\138\002\r\002\r\000\000\000\000\000\000\002\r\000\000\000\000\002\r\000\000\000\000\002\r\000\000\002\r\000\000\000\000\002\r\000\000\002\r\002\r\002\r\000\000\002\r\002\r\002\r\000\000\000\000\000\000\000\000\000\000\002\r\002\r\002\r\002\r\002\r\000\000\002\r\000\000\000\000\000\000\000\000\000\000\002\r\002\r\002\r\002\r\002\r\000\000\000\000\000\000\000\000\002\r\000\000\002\r\002\r\000\000\000\000\000\000\000\000\002\r\002\r\002\r\000\000\000\000\000\000\000\000\000\000\000\000\002\r\002\r\002\r\002\r\002\r\002\r\002\r\002\r\002\r\000\000\000\000\002\r\000\000\002\r\002\r\000\000\000\000\000\000\000\000\000\000\000\000\002\r\002\r\002\r\000\000\002\r\002\r\002\r\002\r\000\000\000\000\000\000\002\r\000\000\002\r\002\r\000\000\002\r\002\r\002\r\002\r\002\r\002\r\000\000\000\000\002\r\002\r\r\254\000\000\000\000\000\000\000\000\002\r\002\r\002\r\002\r\002\017\002\017\000\000\000\000\000\000\002\017\000\000\000\000\002\017\000\000\000\000\002\017\000\000\002\017\000\000\000\000\002\017\000\000\002\017\002\017\002\017\000\000\002\017\002\017\002\017\000\000\000\000\000\000\000\000\000\000\002\017\002\017\002\017\002\017\002\017\000\000\002\017\000\000\000\000\000\000\000\000\000\000\002\017\002\017\002\017\002\017\002\017\003\253\000\000\000\000\000\000\002\017\000\000\002\017\002\017\000\000\000\000\000\000\000\000\002\017\002\017\002\017\000\000\000\000\000\000\000\000\000\000\000\000\002\017\002\017\002\017\002\017\002\017\002\017\002\017\002\017\002\017\000\000\000\000\002\017\000\000\002\017\002\017\000\000\000\000\000\000\000\000\000\000\000\238\002\017\002\017\002\017\000\000\002\017\002\017\002\017\002\017\000\000\000\000\000\000\002\017\000\000\002\017\002\017\000\000\002\017\002\017\002\017\002\017\002\017\002\017\000\000\000\000\002\017\002\017\r\254\000\000\000\000\003\253\000\000\002\017\002\017\002\017\002\017\001\006\000\000\000\006\000\000\006\229\000\000\002\186\002\190\006*\002\234\002\130\005\234\b\242\000\000\000\000\002\246\001\n\000\000\0066\000\000\002\142\000\000\006B\006\229\000\000\001\210\003\206\006\229\002\190\0036\001\018\bn\br\001\030\001\"\003\170\000\000\000\000\003F\000\000\002\254\007\226\025\030\000\000\b\150\b\154\001\210\003\222\0032\003\234\b\158\006\214\000\000\001:\000\000\002\178\007\r\000\000\003:\000\000\000\000\000\000\b\026\b\030\b*\b>\000\000\005v\000\000\003\202\001>\001B\001F\001J\001N\007\r\002\178\b\178\001R\007\r\007\001\000\000\001V\000\000\b\190\b\214\t*\005\130\005\134\000\000\000\000\001Z\000\000\000\000\000\000\006\229\000\000\001^\002\225\007\001\000\000\000\000\018\130\007\001\006\234\000\000\000\000\001\154\011\018\000\000\011\030\005\138\b2\004\026\001\158\000\000\014F\004r\t>\001\006\001\166\000\006\001\170\001\174\000\000\002\186\002\190\000\n\002\234\002\130\011\"\000\000\000\000\000\000\002\246\001\n\000\000\000\000\000\000\bj\000\000\000\238\000\000\002\225\001\210\000\000\000\000\007\r\0036\001\018\bn\br\001\030\001\"\000\000\002\225\002\225\003F\000\000\002\254\000\000\bv\n\206\b\150\b\154\n\218\003\222\0032\003\234\b\158\006\214\000\238\001:\000\000\002\178\000\000\000\000\003:\000\000\000\000\000\000\b\026\b\030\b*\b>\006*\005v\000\000\005\234\001>\001B\001F\001J\001N\000\000\0066\b\178\001R\000\000\006B\000\000\001V\000\000\b\190\b\214\t*\005\130\005\134\000\000\000\000\001Z\000\000\000\000\000\000\000\000\006*\001^\000\000\005\234\011&\000\000\000\000\000\000\000\000\000\000\0066\001\154\006\022\000\000\006B\005\138\b2\012\181\001\158\000\000\014F\004r\t>\004m\001\166\000\006\001\170\001\174\000\246\002\186\002\190\002\194\002\234\002\130\000\000\000\000\000\000\012\181\002\246\000\000\002\030\003\178\000\000\002\"\000\000\004m\000\000\003\182\001\210\000\000\017\026\000\000\002\250\000\000\003>\003B\002.\000\000\000\000\003\186\000\000\003F\000\000\002\254\000\000\016\174\000\000\003\214\003\218\000\000\003\222\0032\003\234\003\242\006\214\000\000\000\000\017\018\002\178\000\000\000\000\003:\017*\002:\000\000\b\026\b\030\b*\b>\000\000\005v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0172\000\000\b\178\000\000\t\r\000\000\000\000\000\000\000\000\b\190\b\214\t*\005\130\005\134\017F\017r\000\000\000\000\004m\004m\000\000\000\000\000\000\006f\024\234\000\000\t\r\000\000\000\000\002>\012\181\012\161\000\000\000\000\017\174\021\154\005\138\b2\025\n\000\173\000\000\bJ\004r\t>\000\173\000\000\002\190\000\173\000\000\002\130\012\181\tf\000\000\002\030\002\246\000\000\002\"\000\173\000\000\000\173\000\000\000\173\000\000\000\173\001\210\000\238\tn\000\000\002\250\002.\000\000\000\000\0026\012\161\tv\000\173\000\000\000\000\000\000\002\254\000\000\000\173\000\000\000\000\000\000\000\173\000\000\0032\001\190\015\130\000\173\000\000\002\130\000\173\002\178\000\000\002:\003:\000\173\000\173\000\173\b\026\b\030\b*\000\000\012f\005v\000\173\000\173\006*\021B\000\000\005\234\024\238\000\173\000\000\000\000\t\r\000\173\0066\000\000\000\000\000\000\006B\000\000\000\000\005\130\005\134\000\173\000\173\015\134\000\000\000\173\000\173\000\000\000\000\000\000\000\000\000\000\000\000\002>\000\000\000\173\000\000\015\146\000\000\021f\000\000\000\173\000\173\005\138\b2\000\000\000\000\000\197\bJ\004r\000\000\000\173\000\197\000\173\002\190\000\197\000\000\002\130\000\000\tf\000\000\000\000\002\246\005\134\000\000\000\197\000\000\000\197\000\000\000\197\000\000\000\197\001\210\021r\tn\000\000\002\250\000\000\000\000\000\000\000\000\b\210\tv\000\197\000\000\000\000\000\000\002\254\000\000\000\197\021\006\000\000\000\000\000\197\000\000\0032\001\190\000\000\000\197\000\000\000\000\000\197\002\178\000\000\000\000\003:\000\197\000\197\000\197\b\026\b\030\b*\000\000\012f\005v\000\197\000\197\000\000\000\000\000\000\000\000\r\234\000\197\000\000\000\000\000\000\000\197\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\130\005\134\000\197\000\197\000\000\000\238\000\197\000\197\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\197\000\000\000\000\000\000\000\000\000\000\000\197\000\197\005\138\b2\000\000\000\000\000\000\bJ\004r\000\000\000\197\000\000\000\197\000\014\000\018\000\022\000\026\000\030\000\000\000\"\000&\000*\000.\0002\000\000\0006\000:\006*\000\000\000>\005\234\000\000\000\000\000B\000\000\000\000\000\000\0066\000\000\000\000\000F\006B\000\000\000\000\000\000\000\000\000J\000\000\000N\000R\000V\000Z\000^\000b\000f\000\000\000\000\000\000\000j\000n\000\000\000r\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\000\000\000\000\000~\000\130\000\000\000\000\000\000\000\000\000\000\000\134\000\138\000\142\000\000\000\000\000\000\000\000\000\000\000\146\000\150\000\154\000\158\000\000\000\162\000\166\000\170\000\000\000\000\000\000\000\174\000\178\000\182\000\000\000\000\000\000\000\186\000\006\000\190\000\194\000\246\002\186\002\190\002\194\002\234\002\130\000\198\000\000\000\202\000\000\002\246\000\000\000\000\004\141\000\206\000\210\000\000\000\214\000\000\003\182\001\210\000\000\000\000\000\000\002\250\000\000\003>\003B\000\000\000\000\000\000\003\186\000\000\003F\000\000\002\254\000\000\016\174\000\000\003\214\003\218\000\000\003\222\0032\003\234\003\242\006\214\000\000\000\000\017\018\002\178\000\000\000\000\003:\017*\000\000\000\000\b\026\b\030\b*\b>\000\000\005v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0172\000\000\b\178\000\000\027\250\000\000\000\000\000\000\000\000\b\190\b\214\t*\005\130\005\134\017F\017r\000\000\000\006\028\027\014\218\000\246\002\186\002\190\002\194\002\234\002\130\000\000\000\000\000\000\000\000\002\246\000\000\000\000\028J\000\000\021\154\005\138\b2\014Z\003\182\001\210\bJ\004r\t>\002\250\000\000\003>\003B\000\000\000\000\000\000\003\186\000\000\003F\000\000\002\254\000\000\016\174\000\000\003\214\003\218\000\000\003\222\0032\003\234\003\242\006\214\000\000\016n\017\018\002\178\000\000\000\000\003:\017*\002\006\000\000\b\026\b\030\b*\b>\000\000\005v\000\000\000\000\002\n\000\000\000\000\000\000\000\000\0172\000\000\b\178\001\210\027\250\000\000\000\000\000\000\000\000\b\190\b\214\t*\005\130\005\134\017F\017r\000\000\000\000\004\149\000\000\003\154\000\000\000\000\000\000\001\006\000\000\007\002\001\222\000\000\000\000\003V\002\190\t\018\002\178\002\130\021\154\005\138\b2\000\000\002\246\001\n\bJ\004r\t>\002\142\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\000\001\014\001\018\001\022\003v\001\030\001\"\000\000\000\000\007\006\000\000\000\000\002\225\000\000\003z\002\225\001.\011\014\000\000\000\000\003r\001\190\0016\002\225\000\000\001:\000\000\002\178\000\000\000\000\003\246\000\000\000\000\002\225\003\250\000\000\004\002\005j\000\n\005v\000\000\002\225\001>\001B\001F\001J\001N\000\000\000\000\000\n\001R\005z\000\000\002\225\001V\000\000\000\000\000\000\002\225\005\130\005\134\000\000\005\202\001Z\002\225\002\225\002\225\002\225\000\000\001^\000\000\002\225\000\000\000\000\000\000\000\000\000\000\002\225\000\000\001\154\011\018\000\000\000\000\005\138\000\000\000\000\001\158\000\000\001\162\004r\001\006\000\000\001\166\002\225\001\170\001\174\003V\002\190\n\178\002\225\002\130\015\130\000\000\000\000\002\130\002\246\001\n\000\000\000\000\000\000\002\142\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\000\001\014\001\018\001\022\003v\001\030\001\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003z\000\000\001.\011\014\000\000\000\000\003r\001\190\0016\007\173\015\134\001:\000\000\002\178\000\000\000\000\003\246\000\000\000\000\000\000\003\250\000\000\004\002\005j\015\146\005v\021F\000\000\001>\001B\001F\001J\001N\000\000\000\000\000\000\001R\005z\000\000\007\173\001V\n\181\000\000\000\000\000\000\005\130\005\134\000\000\005\202\001Z\005\134\000\000\000\000\007\173\000\000\001^\007\173\b\166\000\000\000\000\021R\000\000\000\000\007\173\000\000\001\154\011\018\007\173\000\000\005\138\000\000\n\181\001\158\000\000\001\162\004r\001\006\021\006\001\166\000\000\001\170\001\174\003V\002\190\r\170\n\181\002\130\000\000\n\181\011\134\000\000\002\246\001\n\000\000\000\000\n\181\002\142\000\000\000\000\n\181\000\000\001\210\000\000\000\000\000\000\001\014\001\018\001\022\003v\001\030\001\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003z\000\000\001.\011\014\000\000\000\000\003r\001\190\0016\000\000\000\000\001:\000\000\002\178\000\000\000\000\003\246\000\000\000\000\000\000\003\250\000\000\004\002\005j\000\000\005v\000\000\000\000\001>\001B\001F\001J\001N\000\000\000\000\000\000\001R\005z\000\000\000\000\001V\000\000\000\000\000\000\000\000\005\130\005\134\000\000\005\202\001Z\000\000\000\000\000\000\000\000\000\000\001^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\154\011\018\000\000\000\000\005\138\000\000\000\000\001\158\000\000\001\162\004r\000\000\b\249\001\166\000\006\001\170\001\174\000\000\002\186\002\190\000\000\002\234\002\130\000\000\000\000\000\000\000\000\002\246\000\000\000\000\000\000\000\000\b\249\000\000\b\249\b\249\000\000\001\210\000\000\000\000\000\000\002\250\000\000\003>\003B\000\000\000\000\000\000\000\000\b\001\003F\000\000\002\254\000\000\b\001\000\000\003\214\003\218\n\222\003\222\0032\003\234\003\242\006\214\001\202\001\206\011>\002\178\000\000\000\000\003:\000\000\000\000\b\001\b\026\b\030\b*\b>\000\000\005v\000\000\000\000\000\000\001\210\002\170\001\230\000\000\000\000\000\000\b\178\000\000\000\000\000\000\001\242\000\000\b\001\b\190\b\214\t*\005\130\005\134\000\000\000\000\b\001\000\000\000\000\001\246\002\146\b\001\b\001\000\238\002\158\000\000\002\178\004\030\004*\000\000\b\001\b\001\000\000\0046\000\000\000\000\005\138\b2\b\249\004\253\004\253\bJ\004r\t>\004\253\000\000\004\253\004\253\000\000\004\253\004:\004\253\004\253\b\001\000\000\004\253\b\001\004\253\004\253\004\253\004\253\004\253\004\253\004\253\004\253\b\001\004\253\016~\004\253\000\000\000\000\000\000\000\000\000\000\002\006\004\253\000\000\000\000\000\000\000\000\004\253\004\253\004\253\000\000\002\n\004\253\004\253\004\253\004\253\000\000\004\253\000\000\001\210\004\253\000\000\000\000\000\000\000\000\004\253\004\253\004\253\000\000\000\000\004\253\004\253\004\253\000\000\004\253\004\253\003\154\000\000\000\000\000\000\000\000\004\253\007\002\001\222\000\000\004\253\004\253\000\000\004\253\002\178\004\253\000\000\000\000\000\000\000\000\004\253\004\253\004\253\000\000\004\253\004\253\004\253\004\253\000\000\004\253\004\253\000\000\000\000\000\000\004\253\000\000\004\253\004\253\000\000\000\000\002\150\004\253\007\006\000\000\000\000\020\026\004\253\000\000\n\205\000\000\004\253\n\205\004\253\004\253\n\205\n\205\000\000\004\253\n\205\000\000\n\205\000\000\000\000\n\205\000\000\001*\000\000\n\205\n\205\000\000\n\205\n\205\002\225\n\205\000\000\n\205\000\000\000\000\000\000\002\225\n\205\000\000\000\000\n\205\000\000\000\000\000\000\000\000\000\000\000\000\002\225\n\205\000\000\n\205\000\000\000\000\n\205\n\205\000\n\000\000\000\000\000\000\000\000\n\205\000\000\000\000\n\205\000\000\000\000\n\205\n\205\000\000\n\205\002\225\n\205\n\205\000\000\000\000\000\000\000\000\002\225\000\000\000\000\000\000\000\000\000\000\002\225\n\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\205\n\205\000\000\000\000\n\205\000\000\n\205\000\000\000\000\000\000\000\000\005\166\000\000\002\225\000\000\000\000\001\202\001\206\n\205\n\205\000\000\n\205\n\205\000\000\n\205\000\000\n\205\000\000\n\205\000\000\n\205\000\000\n\205\b\229\b\229\001\210\001\214\001\230\b\229\000\000\001\206\b\229\000\000\000\000\000\000\001\242\003\190\000\000\018\174\b\229\000\000\b\229\b\229\b\229\000\000\b\229\b\229\b\229\001\246\020\022\000\000\0196\000\000\002\158\000\000\002\178\004\030\004*\000\000\b\229\000\000\000\000\020&\000\000\000\000\b\229\b\229\000\000\000\000\b\229\000\000\000\000\002\154\000\000\b\229\000\000\000\000\b\229\000\000\004:\000\000\000\000\b\229\b\229\b\229\000\000\000\000\000\000\000\000\000\000\000\000\b\229\b\229\000\000\000\000\000\000\000\000\000\000\b\229\000\000\000\000\000\000\004\154\000\000\000\000\b\229\000\000\000\000\000\000\000\000\000\000\000\000\b\229\b\229\b\229\000\000\b\229\b\229\000\000\004Y\000\000\000\000\000\000\000\000\004Y\000\000\b\229\004Y\b\229\b\229\000\000\000\000\000\000\b\229\000\000\000\000\000\000\004Y\b\229\000\000\000\000\004Y\b\229\004Y\b\229\b\229\012u\012u\000\000\000\000\004Y\012u\000\000\001\206\012u\004Y\000\000\000\000\000\000\000\000\000\000\004Y\004\186\000\000\012u\012u\012u\004B\012u\012u\012u\000\000\000\000\004Y\004Y\000\000\000\000\000\000\004Y\002\226\000\000\000\000\012u\000\000\000\000\000\000\000\000\000\000\012u\012u\000\000\000\000\012u\000\000\004Y\002\154\004Y\012u\000\000\000\000\012u\000\000\000\000\000\000\004Y\012u\012u\012u\004Y\004Y\002\226\000\238\004Y\004Y\012u\012u\000\000\000\000\004R\004Y\000\000\012u\000\000\000\000\000\000\004\154\000\000\000\000\012u\004Y\000\000\000\000\000\000\000\000\021\026\012u\012u\012u\000\000\012u\012u\000\000\004Y\000\000\004Y\000\000\000\000\004Y\000\000\012u\004Y\012u\012u\004Y\000\000\000\000\012u\000\000\000\000\000\000\004Y\012u\000\000\000\000\004Y\012u\004Y\012u\012u\b\233\b\233\000\000\000\000\000\000\b\233\000\000\001\206\b\233\004Y\000\000\000\000\000\000\000\000\000\000\004Y\b\233\000\000\b\233\b\233\b\233\000\000\b\233\b\233\b\233\000\000\000\000\004Y\000\000\000\000\000\000\000\000\004Y\002\226\000\000\000\000\b\233\000\000\000\000\000\000\000\000\000\000\b\233\b\233\000\000\000\000\b\233\000\000\004Y\002\154\000\000\b\233\000\000\000\000\b\233\000\000\000\000\000\000\000\000\b\233\b\233\b\233\004Y\004Y\000\000\000\000\004Y\004Y\b\233\b\233\000\000\000\000\007n\000\000\000\000\b\233\000\000\000\000\000\000\004\154\000\000\000\000\b\233\004Y\000\000\000\000\000\000\000\000\000\000\b\233\b\233\b\233\002\225\b\233\b\233\000\000\000\000\002\225\002\225\002\225\000\000\000\000\002\225\b\233\002\225\b\233\b\233\002\225\002\225\002\225\b\233\002\225\002\225\002\225\002\225\b\233\002\225\002\225\000\000\b\233\002\225\b\233\b\233\000\000\002\225\000\n\000\000\002\225\002\225\002\225\000\000\002\225\000\000\002\225\002\225\000\n\000\000\002\225\002\225\000\n\002\225\002\225\002\225\000\000\000\000\000\000\002\225\002\225\000\000\002\225\002\225\002\225\002\225\002\225\002\225\000\000\002\225\002\225\000\000\002\225\002\225\002\225\000\000\002\225\002\225\002\225\002\225\002\225\002\225\002\225\000\000\002\225\000\000\000\000\002\225\000\000\000\000\000\000\000\000\002\225\002\225\002\225\002\225\000\000\000\000\000\000\002\225\002\225\002\225\002\225\002\225\000\000\006\141\000\000\0009\002\225\002\225\000\000\0009\0009\000\000\0009\0009\002\225\000\000\000\000\000\000\0009\000\000\002\225\000\000\000\000\006\141\002\225\002\225\000\000\000\000\0009\002\225\002\225\002\225\0009\006\222\0009\0009\000\000\000\000\000\000\000\000\000\000\0009\000\000\0009\000\000\000\000\000\000\0009\0009\000\000\0009\0009\0009\0009\0009\000\000\000\000\000\000\0009\000\000\000\000\0009\000\000\000\000\000\000\0009\0009\0009\0009\000\000\0009\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0009\000\000\000\000\000\000\012\181\012\161\000\000\0009\0009\0009\0009\0009\000\000\006\137\000\000\0005\000\000\000\000\000\000\0005\0005\000\000\0005\0005\012\181\000\000\000\000\002\030\0005\000\000\002\"\000\000\000\000\006\137\0009\0009\000\000\002*\0005\0009\0009\0009\0005\002.\0005\0005\0026\012\161\000\000\000\000\000\000\0005\000\000\0005\000\000\000\000\000\000\0005\0005\000\000\0005\0005\0005\0005\0005\000\000\000\000\000\000\0005\000\000\002:\0005\000\000\000\000\000\000\0005\0005\0005\0005\000\000\0005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0005\000\000\000\000\000\000\000\000\000\000\000\000\0005\0005\0005\0005\0005\000\000\006\153\000\000\012=\000\000\000\000\000\000\012=\012=\000\000\012=\012=\002>\000\000\000\000\000\000\012=\000\000\000\000\000\000\000\000\006\153\0005\0005\000\000\000\000\012=\0005\0005\0005\012=\000\000\012=\012=\000\000\000\000\000\000\000\000\000\000\012=\000\000\012=\000\000\000\000\000\000\012=\012=\000\000\012=\012=\012=\012=\012=\000\000\000\000\000\000\012=\000\000\000\000\012=\000\000\000\000\000\000\012=\012=\012=\012=\000\000\012=\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012=\000\000\000\000\000\000\012\181\012\161\000\000\012=\012=\012=\012=\012=\000\000\006\149\000\000\0129\000\000\000\000\000\000\0129\0129\000\000\0129\0129\012\181\000\000\000\000\002\030\0129\000\000\002\"\000\000\000\000\006\149\012=\012=\000\000\002\206\0129\012=\012=\012=\0129\002.\0129\0129\0026\012\161\000\000\000\000\000\000\0129\000\000\0129\000\000\000\000\000\000\0129\0129\000\000\0129\0129\0129\0129\0129\000\000\001\202\001\206\0129\000\000\002:\0129\000\000\000\000\000\000\0129\0129\0129\0129\000\000\0129\000\000\000\000\000\000\000\000\001\210\001\214\001\230\000\000\000\000\0129\000\000\000\000\000\000\000\000\001\242\000\000\0129\0129\0129\0129\0129\001\250\000\000\000\000\000\000\000\000\000\000\001\246\002\146\000\000\000\000\000\000\002\158\002>\002\178\004\030\004*\012y\012y\000\000\000\000\0046\012y\0129\0129\012y\000\000\000\000\0129\0129\0129\000\000\000\000\004\138\000\000\012y\012y\012y\004:\012y\012y\012y\000\000\001\021\000\000\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\012y\000\000\000\000\000\000\000\000\000\000\012y\012y\000\000\000\000\012y\000\000\000\000\000\000\001\021\012y\000\000\000\000\012y\000\000\000\000\000\000\000\000\012y\012y\012y\000\000\000\000\000\000\000\000\000\000\000\000\012y\012y\000\000\000\000\001\021\000\000\018\182\012y\000\000\000\000\000\000\012y\001\021\000\000\012y\000\000\000\000\001\021\000\000\000\000\000\000\012y\012y\012y\000\000\012y\012y\001\021\000\000\000\000\000\000\000\000\000\000\000\000\007\253\012y\000\006\012y\012y\007\253\002\186\002\190\012y\002\234\002\130\000\000\000\000\012y\000\000\002\246\000\000\012y\001\021\012y\012y\000\000\003\254\000\000\007\253\001\210\000\000\001\021\000\000\002\250\000\000\003>\003B\000\000\000\000\000\000\000\000\000\000\003F\000\000\002\254\000\000\000\000\000\000\003\214\003\218\007\253\003\222\0032\003\234\003\242\006\214\000\000\000\000\007\253\002\178\000\000\000\000\003:\007\253\007\253\000\238\b\026\b\030\b*\b>\000\000\005v\007\253\007\253\000\000\000\000\000\000\000\000\000\000\000\000\000\000\b\178\000\000\000\000\000\000\000\000\000\000\000\000\b\190\b\214\t*\005\130\005\134\000\000\000\000\007\253\000\000\000\000\007\253\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\000\007\253\002\186\002\190\000\000\002\234\002\130\000\000\000\000\005\138\b2\002\246\000\000\000\000\bJ\004r\t>\000\000\014n\000\000\000\000\001\210\000\000\000\000\000\000\002\250\000\000\003>\003B\000\000\000\000\000\000\001\197\000\000\003F\000\000\002\254\001\197\000\000\000\000\003\214\003\218\000\000\003\222\0032\003\234\003\242\006\214\000\000\000\000\000\000\002\178\000\000\000\000\003:\000\000\001\197\000\000\b\026\b\030\b*\b>\000\000\005v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005-\012\245\b\178\000\000\000\000\0051\012\245\001\197\000\000\b\190\b\214\t*\005\130\005\134\000\000\001\197\000\000\000\000\000\000\005-\001\197\001\197\000\238\005-\0051\000\000\003\029\003\029\0051\001\197\001\197\003\029\000\000\000\000\003\029\000\000\005\138\b2\000\000\000\000\000\000\bJ\004r\t>\003\029\003\029\003\029\000\000\003\029\003\029\003\029\000\000\000\000\000\000\000\000\001\197\000\000\000\000\000\000\000\000\000\000\000\000\003\029\000\000\001\197\000\000\000\000\000\000\003\029\004\130\000\000\000\000\003\029\000\000\000\000\000\000\000\000\003\029\012\245\012\245\003\029\000\000\000\000\012\245\012\245\003\029\003\029\003\029\000\000\000\000\000\000\005-\000\000\000\000\003\029\003\029\0051\012\245\000\000\012\245\000\000\003\029\012\245\000\000\012\245\003\029\005-\000\000\003\029\005-\000\000\0051\000\000\000\000\0051\003\029\003\029\003\029\004}\003\029\003\029\000\000\000\000\018\198\000\000\000\000\000\000\000\000\000\000\003\029\000\000\003\029\003\029\000\000\000\000\000\000\003\029\000\000\000\000\000\000\000\000\003\029\003\182\n\217\000\000\003\029\n\217\003\029\003\029\003V\002\190\000\000\000\000\002\130\000\000\006\166\000\000\000\000\002\246\000\000\000\000\000\000\n\217\n\217\018\242\n\217\n\217\000\000\001\210\000\000\006\198\000\000\017\018\000\000\000\000\003Z\000\000\017*\b\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\217\019.\003f\000\000\000\000\003r\001\190\000\000\000\000\000\000\000\000\000\000\002\178\000\000\000\000\003\246\000\000\000\000\n\217\003\250\000\000\004\002\005j\n\190\005v\000\000\004}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\019\146\005z\001\202\001\206\000\000\000\000\000\000\000\000\000\000\005\130\005\134\000\000\005\202\n\217\000\000\n\217\000\000\000\000\000\000\000\000\000\000\001\210\001\214\000\000\000\000\000\000\000\000\n\217\000\000\000\000\n\217\n\217\000\000\005\138\000\000\n\217\000\000\n\217\000\000\004r\n\213\n\217\000\000\n\213\001\246\002\162\003V\002\190\000\000\002\158\002\130\002\178\004\030\004*\000\000\002\246\000\000\000\000\0046\n\213\n\213\000\000\n\213\n\213\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003Z\000\000\000\000\004:\000\000\000\000\026\022\000\000\000\000\000\000\000\000\n\213\000\000\003f\000\000\000\000\003r\001\190\000\000\000\000\000\000\000\000\026\002\002\178\000\000\000\000\003\246\000\000\000\000\n\213\003\250\000\000\004\002\005j\000\000\005v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005z\000\000\012Y\000\000\000\000\012Y\000\000\000\000\005\130\005\134\000\000\005\202\n\213\000\000\n\213\012Y\000\000\000\000\000\000\000\000\000\000\012Y\000\000\001\221\001\221\000\000\n\213\000\000\001\221\n\213\n\213\001\221\005\138\012Y\n\213\000\000\n\213\000\000\004r\012Y\n\213\001\221\001\221\001\221\000\000\001\221\001\221\001\221\012Y\000\000\000\000\012Y\000\000\000\000\000\000\000\000\012Y\000\000\000\000\001\221\000\000\000\000\000\000\000\000\000\000\001\221\001\221\000\000\000\000\001\221\000\000\000\000\012Y\000\000\001\221\000\000\012Y\001\221\000\000\000\000\000\000\000\000\001\221\001\221\001\221\000\000\012Y\012Y\000\000\000\000\012Y\001\221\001\221\000\000\000\000\000\000\027\242\000\000\001\221\001\r\000\000\000\000\001\221\000\000\001\r\001\221\000\000\012Y\000\000\000\000\000\000\000\000\001\221\001\221\001\221\0256\001\221\001\221\000\000\000\000\000\000\000\000\002\006\001\r\000\000\000\000\001\221\000\000\001\221\001\221\003V\002\190\002\n\001\221\002\130\000\000\006\166\000\000\001\221\002\246\001\210\000\000\004\254\000\000\001\221\001\r\000\000\003R\000\000\001\210\000\000\006\198\000\000\001\r\000\000\000\000\003Z\003\154\001\r\b\226\000\000\000\000\000\000\007\002\001\222\000\000\000\000\001\r\001\r\003f\002\178\000\000\n\174\001\190\000\000\000\000\000\000\000\000\000\000\002\178\000\000\000\000\003\246\000\000\000\000\n\177\003\250\000\000\004\002\000\000\n\190\005v\000\000\001\r\000\000\003V\002\190\000\000\007\006\002\130\000\000\006\166\001\r\005z\002\246\000\000\000\000\000\000\000\000\000\000\000\000\005\130\005\134\000\000\001\210\n\198\006\198\000\000\000\000\000\000\000\000\003Z\000\000\000\000\b\226\000\000\000\000\000\000\000\000\n\177\n\206\000\000\n\177\011:\003f\005\138\000\000\n\174\001\190\n\177\000\000\004r\000\000\n\177\002\178\000\000\000\000\003\246\000\000\000\000\n\177\003\250\000\000\004\002\000\000\n\190\005v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\130\005\134\000\000\000\000\n\198\005}\005}\000\000\000\000\000\000\005}\000\000\000\000\005}\000\000\000\000\000\000\000\000\n\177\000\000\000\000\n\177\n\177\005}\005\138\005}\000\000\005}\n\177\005}\004r\000\000\n\177\000\000\000\000\000\000\000\000\000\000\000\000\000\246\000\000\005}\002\194\000\000\000\000\000\000\000\000\005}\005}\000\000\000\000\000\000\028J\005}\000\000\000\000\005}\000\000\003\182\005}\000\000\000\000\000\000\000\000\005}\005}\005}\000\000\000\000\000\000\003\186\000\000\000\000\000\000\000\000\000\000\016\174\000\000\000\000\000\000\005}\005}\000\000\000\000\005}\024Z\000\000\001\006\017\018\000\000\000\000\000\000\000\000\017*\005}\005}\005}\000\000\005}\005}\000\000\000\000\000\000\001\n\007n\000\000\000\000\002\142\000\000\0172\000\000\005}\000\000\027\250\005}\005}\001\014\001\018\001\022\001\026\001\030\001\"\000\000\017F\017r\000\000\005}\004\149\000\000\001&\000\000\001.\0012\000\000\000\000\000\000\000\000\0016\004a\000\000\001:\000\000\000\000\000\246\021\154\000\000\002\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\178\001>\001B\001F\001J\001N\003\182\005q\005q\001R\000\000\000\000\005q\001V\000\000\005q\000\000\000\000\017\182\000\000\000\000\000\000\001Z\000\000\017\222\005q\000\000\005q\001^\005q\000\000\005q\000\000\000\000\000\000\000\000\017\018\000\000\001\154\027.\000\000\017*\000\000\005q\000\000\001\158\000\000\001\162\000\000\005q\005q\001\166\000\000\001\170\001\174\007\222\000\000\018Z\005q\000\000\000\000\005q\000\000\000\000\000\000\000\000\005q\005q\000\238\000\000\000\000\017F\018n\000\000\000\000\004a\004a\000\000\000\000\000\000\000\000\000\000\005q\005q\000\000\000\000\005q\000\000\b\245\000\000\000\000\000\000\018~\000\000\000\000\000\000\005q\005q\005q\000\000\005q\005q\000\000\000\000\t\202\000\000\000\000\012:\b\245\000\000\b\245\b\245\000\000\005q\000\000\000\000\005q\005q\n\002\n\026\n\"\n\n\n*\000\000\000\000\001\202\002~\000\000\005q\002\130\000\000\000\000\n2\n:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\nB\000\000\000\000\001\210\001\214\001\230\002\134\000\000\000\238\000\000\000\000\000\000\000\000\001\242\001\006\000\000\000\000\t\210\n\018\nJ\nR\nb\000\000\000\000\000\000\000\000\002\138\002\146\000\000\nj\001\n\002\158\000\000\002\178\004\030\004*\000\000\000\000\nr\000\000\020\242\000\000\020\246\001\014\001\018\001\022\001\026\001\030\001\"\000\000\000\000\000\000\n\146\000\000\n\154\nZ\001&\004:\001.\0012\b\245\nz\000\000\000\000\0016\000\000\005\134\001:\000\000\n\130\n\138\000\000\000\000\000\000\000\000\000\000\021\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001>\001B\001F\001J\001N\000\000\003]\003]\001R\021\006\000\000\003]\001V\000\000\003]\000\000\000\000\000\000\000\000\000\000\000\000\001Z\000\000\000\000\003]\000\000\003]\001^\003]\000\000\003]\000\000\000\000\000\000\000\000\000\000\000\000\001\154\027J\000\000\000\000\000\000\003]\000\000\001\158\000\000\001\162\000\000\003]\003]\001\166\000\000\001\170\001\174\005\005\000\000\000\000\003]\000\000\000\000\003]\000\000\000\000\000\000\000\000\003]\003]\003]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003]\000\000\001\202\001\206\003]\bq\bq\000\000\000\000\000\000\bq\000\000\000\000\bq\003]\003]\003]\000\000\003]\003]\000\000\001\210\001\214\bq\005\005\bq\000\000\bq\000\000\bq\000\000\003]\000\000\000\000\000\000\003]\000\000\000\000\000\000\000\000\000\000\bq\000\000\000\000\001\246\002\154\003]\bq\bq\002\158\000\000\002\178\004\030\004*\000\000\000\000\bq\000\000\0046\bq\015\158\000\000\000\000\000\000\bq\bq\bq\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004:\000\000\000\000\000\000\000\000\bq\000\000\000\000\000\000\bq\rA\rA\000\000\000\000\000\000\rA\000\000\000\000\rA\bq\bq\bq\000\000\bq\bq\000\000\000\000\000\000\rA\000\000\rA\000\000\rA\bq\rA\000\000\bq\000\000\000\000\000\000\bq\000\000\000\000\000\000\000\000\000\000\rA\000\000\000\000\004\254\000\000\bq\rA\rA\rE\rE\000\000\000\000\004B\rE\000\000\rA\rE\000\000\rA\000\000\000\000\000\000\000\000\rA\rA\rA\rE\000\000\rE\000\000\rE\000\000\rE\000\000\000\000\000\000\000\000\000\000\000\000\rA\000\000\000\000\000\000\rA\rE\000\000\000\000\000\000\000\000\000\000\rE\rE\000\000\rA\rA\rA\004B\rA\rA\rE\000\000\000\000\rE\004R\000\000\000\000\000\000\rE\rE\rE\rA\000\000\000\000\000\000\rA\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\rE\000\000\rA\000\000\rE\003]\003]\000\000\000\000\000\000\003]\000\000\000\000\003]\rE\rE\rE\000\000\rE\rE\000\000\000\000\000\000\003]\004R\003]\000\000\003]\000\000\003]\000\000\rE\001\202\001\206\000\000\rE\000\000\000\000\000\000\000\000\000\000\003]\000\000\000\000\000\000\000\000\rE\003]\003]\000\000\000\000\001\210\001\214\005\t\000\000\000\000\003]\000\000\000\000\003]\000\000\000\000\000\000\000\000\003]\003]\003]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\246\002\162\000\000\000\000\000\000\002\158\003]\002\178\004\030\004*\003]\001\205\000\000\000\000\0046\000\000\001\205\000\000\001\206\001\205\003]\003]\003]\000\000\003]\003]\000\000\b\209\000\000\001\205\005\t\004:\000\000\001\205\004\205\001\205\000\000\003]\000\000\000\000\000\000\003]\000\000\004Y\000\000\000\000\000\000\001\205\004Y\000\000\026\002\000\000\003]\001\205\001\205\000\000\000\000\000\000\000\000\000\000\002\154\000\000\001\205\000\000\000\000\001\205\000\000\004Y\000\000\000\000\001\205\001\205\001\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\205\001\205\000\000\004Y\004\154\003A\000\000\000\000\000\000\000\000\003A\004Y\001\206\003A\001\205\001\205\004Y\002\226\001\205\001\205\000\000\b\205\000\000\003A\000\000\004Y\004Y\003A\001\205\003A\000\000\000\000\000\000\000\000\000\000\001\205\000\000\000\000\000\000\000\000\001\205\003A\000\000\000\000\000\000\000\000\001\205\003A\001\201\000\000\000\181\004Y\000\000\000\000\002\154\000\181\003A\000\000\000\181\003A\004Y\000\000\000\000\000\000\003A\003A\003A\000\000\000\181\000\000\000\181\000\000\000\181\000\000\000\181\000\000\000\000\000\000\000\000\000\000\003A\003A\000\000\000\000\004\154\000\000\000\181\000\000\000\000\000\000\000\000\000\000\000\181\000\000\003A\003A\000\181\000\000\003A\003A\000\000\000\181\000\000\000\000\000\181\000\000\000\000\000\000\003A\000\181\000\181\000\238\000\000\000\000\000\000\003A\000\000\000\000\000\181\000\181\003A\000\000\000\000\000\000\000\000\000\181\003A\000\000\000\249\000\181\000\000\000\000\000\000\000\249\000\000\000\000\000\249\000\000\000\000\000\181\000\181\000\000\000\000\000\181\000\181\000\000\000\249\000\000\000\249\000\000\000\249\000\000\000\249\000\181\000\000\000\000\000\000\000\000\000\000\000\181\000\181\000\000\000\000\000\000\000\249\000\000\000\000\000\000\000\000\000\181\000\249\000\181\000\000\000\000\000\249\000\000\000\000\000\000\000\000\000\249\000\000\000\000\000\249\000\000\000\000\000\000\000\000\000\249\000\249\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\249\000\249\000\000\000\000\000\000\000\000\000\000\000\249\000\000\000\000\000\189\000\249\000\000\000\000\000\000\000\189\000\000\000\000\000\189\000\000\000\000\000\249\000\249\000\000\000\000\000\249\000\249\000\000\000\189\000\000\000\189\000\000\000\189\000\000\000\189\000\249\000\000\000\000\000\000\000\000\000\000\000\249\000\249\000\000\000\000\000\000\000\189\000\000\000\000\000\000\000\000\000\249\000\189\000\249\000\000\000\000\000\189\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\189\000\000\000\000\000\000\000\000\000\189\000\189\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\189\000\189\000\000\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\185\000\189\000\000\000\000\006\221\000\185\000\000\000\000\000\185\006\221\000\000\000\189\000\189\000\000\000\000\000\189\000\189\000\000\000\185\000\000\000\185\000\000\000\185\000\000\000\185\000\189\000\000\000\000\006\221\000\000\000\000\000\189\000\189\000\000\000\000\000\000\000\185\000\000\000\000\000\000\000\000\000\189\000\185\000\189\000\000\000\000\000\185\000\000\000\000\000\000\006\221\000\185\000\000\000\000\000\185\000\000\000\000\000\000\006\221\000\185\000\185\000\238\000\000\006\221\006\221\000\238\000\000\000\000\000\185\000\185\000\000\000\000\006\221\006\221\000\000\000\185\000\000\000\000\001\169\000\185\000\000\000\000\000\000\001\169\000\000\000\000\001\169\000\000\000\000\000\185\000\185\000\000\000\000\000\185\000\185\000\000\001\169\000\000\006\221\000\000\001\169\r\001\001\169\000\185\000\000\000\000\r\001\006\221\000\000\000\185\000\185\000\000\000\000\000\000\001\169\001\169\000\000\000\000\000\000\000\185\001\169\000\185\000\000\023\186\000\000\r\001\005\005\000\000\000\000\001\169\000\000\000\000\001\169\000\000\000\000\000\000\000\000\001\169\001\169\001\169\000\000\000\000\000\000\000\000\000\000\000\000\000\000\r\001\000\000\000\000\000\000\000\000\000\000\001\169\000\000\r\001\000\000\001\169\r=\r=\r\001\r\001\000\238\r=\000\000\000\000\r=\001\169\001\169\r\001\r\001\001\169\001\169\000\000\000\000\000\000\r=\005\005\r=\000\000\r=\001\169\r=\000\000\000\000\000\000\000\000\001\169\001\169\000\000\000\000\000\000\000\000\001\169\r=\r\001\000\000\000\000\000\000\001\169\r=\r=\000\000\000\000\r\001\000\000\000\000\000\000\000\000\r=\000\000\000\000\r=\000\000\000\000\000\000\000\000\r=\r=\r=\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\r=\000\000\000\000\000\000\r=\r9\r9\000\000\000\000\000\000\r9\000\000\000\000\r9\r=\r=\r=\000\000\r=\r=\000\000\000\000\000\000\r9\000\000\r9\000\000\r9\000\000\r9\000\000\r=\000\000\000\000\000\000\r=\000\000\000\000\000\000\000\000\000\000\r9\000\000\000\000\004\254\000\000\r=\r9\r9\000\000\000\000\000\000\000\000\000\000\000\000\004a\r9\000\000\000\000\r9\000\246\000\000\000\000\002\018\r9\r9\r9\000\000\000\000\000\000\000\000\000\000\000\000\017\178\000\000\000\000\000\000\004a\000\000\003\182\r9\000\000\bu\bu\r9\000\000\000\000\bu\000\000\000\000\bu\017\182\000\000\000\000\r9\r9\r9\017\222\r9\r9\bu\000\000\bu\000\000\bu\000\000\bu\000\000\007J\017\018\000\000\r9\000\000\000\000\017*\r9\000\000\000\000\bu\000\000\000\000\000\000\000\000\000\000\bu\bu\r9\000\000\000\000\000\000\018Z\000\000\000\000\bu\000\000\000\000\bu\000\000\000\000\000\000\000\000\bu\bu\000\238\017F\018n\000\000\000\000\004a\004a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\bu\000\000\000\000\000\000\bu\000\000\006\241\000\000\018~\000\000\000\000\000\000\000\000\000\000\bu\bu\bu\000\000\bu\bu\000\000\000\000\t\202\000\000\000\000\006\241\000\000\000\000\bu\006\241\000\000\bu\000\000\000\000\000\000\bu\n\002\n\026\n\"\n\n\n*\000\000\000\000\000\000\000\000\000\000\bu\001\201\000\000\000\000\n2\n:\001\201\000\000\001\206\001\201\000\000\000\000\000\000\nB\000\000\000\000\000\000\b\205\000\000\001\201\000\000\000\238\000\000\001\201\000\000\001\201\000\000\000\000\000\000\000\000\t\210\n\018\nJ\nR\nb\000\000\000\000\001\201\000\000\000\000\000\000\006\241\nj\001\201\000\000\000\000\000\000\000\000\000\000\000\000\002\154\nr\001\201\000\000\000\000\001\201\000\000\000\000\000\000\000\000\001\201\001\201\001\201\000\000\000\000\n\146\000\000\n\154\nZ\000\000\000\000\000\000\000\000\000\000\nz\000\000\001\201\001\201\000\000\000\000\004\154\000\000\n\130\n\138\000\000\000\000\000\000\016b\000\000\000\000\001\201\001\201\000\000\000\000\001\201\001\201\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\202\001\201\000\000\000\000\016f\000\000\000\000\000\000\001\201\000\000\000\000\000\000\000\000\001\201\n\002\n\026\n\"\n\n\n*\001\201\000\000\000\000\000\000\000\000\000\000\n\210\000\000\000\000\n2\n:\000\246\001\202\001\206\002\018\000\000\000\000\000\000\nB\000\000\000\000\000\000\000\000\000\000\017\178\000\000\000\238\000\000\004a\000\000\003\182\001\210\001\214\001\230\000\000\t\210\n\018\nJ\nR\nb\000\000\001\242\017\182\000\000\000\000\000\000\000\000\nj\017\222\000\000\000\000\000\000\000\000\000\000\001\246\002\146\nr\000\000\000\000\002\158\017\018\002\178\004\030\004*\000\000\017*\000\000\000\000\0046\000\000\n\146\016j\n\154\nZ\016z\000\000\000\000\000\000\000\000\nz\000\000\018Z\000\000\000\000\000\000\004:\000\000\n\130\n\138\005\169\005\169\000\000\000\000\000\000\005\169\017F\018n\005\169\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\169\000\000\005\169\000\000\005\169\000\000\005\169\000\000\000\000\018~\000\000\000\000\000\000\000\000\004n\000\000\004r\000\000\005\169\000\000\000\000\000\000\000\000\000\000\005\169\005\169\000\000\000\000\000\000\000\000\007\222\000\000\000\000\005\169\000\000\000\000\005\169\000\000\006I\000\000\000\000\005\169\005\169\000\238\000\000\002\190\000\000\000\000\002\130\000\000\000\000\000\000\000\000\002\246\000\000\002\225\002\225\005\169\006I\002\225\000\000\005\169\000\000\001\210\002\225\000\000\000\000\002\250\000\000\000\000\002\225\005\169\005\169\005\169\002\225\005\169\005\169\000\000\002\254\000\000\000\000\002\225\000\n\000\000\000\000\006\218\0032\001\190\005\169\000\000\000\000\015:\005\169\002\178\002\225\000\000\003:\002\225\002\225\000\000\b\026\b\030\b*\005\169\002\225\005v\000\000\002\225\000\000\000\000\002\225\002\225\000\000\002\225\002\225\000\000\002\225\000\000\000\000\000\000\000\000\000\000\005\165\007\030\000\000\005\130\005\134\005\165\002\225\000\000\005\165\000\000\000\000\000\000\000\000\000\000\002\225\002\225\000\000\015v\005\165\000\000\005\165\000\000\005\165\000\000\005\165\000\000\000\000\005\138\b2\000\000\000\000\000\000\bJ\004r\000\000\000\000\005\165\000\000\002\225\000\000\000\000\000\000\005\165\007\138\002\225\000\000\000\000\000\000\000\000\000\000\000\000\005\165\000\000\000\000\005\165\000\000\000\000\004\133\000\000\005\165\005\165\000\238\021\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\165\000\000\005\193\005\193\005\165\000\000\003\182\005\193\000\000\000\000\005\193\000\000\000\000\000\000\005\165\005\165\005\165\000\000\005\165\005\165\005\193\000\000\005\193\000\000\005\193\000\000\005\193\000\000\0222\000\000\000\000\005\165\000\000\000\000\000\000\005\165\017\018\000\000\005\193\000\000\000\000\017*\000\000\000\000\005\193\005\193\005\165\000\000\000\000\000\000\022\214\022\230\000\000\005\193\000\000\000\000\005\193\000\000\000\000\000\000\000\000\005\193\005\193\005\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\133\005\193\000\000\005\189\007\030\005\193\000\000\000\000\005\189\023\218\000\000\005\189\000\000\000\000\000\000\005\193\005\193\005\193\000\000\005\193\005\193\005\189\000\000\005\189\000\000\005\189\000\000\005\189\000\000\000\000\000\000\000\000\005\193\000\000\000\000\000\000\005\193\000\000\000\000\005\189\000\000\000\000\000\000\000\000\000\000\005\189\007\138\007\130\000\000\000\000\000\000\000\000\000\000\000\000\005\189\000\000\000\000\005\189\000\000\000\000\000\000\000\000\005\189\005\189\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\189\003V\002\190\000\000\005\189\002\130\000\000\006\166\000\000\000\000\002\246\000\000\000\000\000\000\005\189\005\189\005\189\000\000\005\189\005\189\001\210\000\000\006\198\000\000\000\000\000\000\000\000\003Z\000\000\000\000\b\226\005\189\000\000\000\000\000\000\005\189\000\000\000\000\000\000\000\000\003f\000\000\000\000\n\174\001\190\000\000\005\189\012\186\000\000\000\000\002\178\000\000\000\000\003\246\000\000\000\000\000\000\003\250\000\000\004\002\000\000\n\190\005v\t\202\000\000\000\000\012:\000\000\000\000\000\000\b\245\000\000\000\000\000\000\005z\000\000\000\000\n\002\n\026\n\"\n\n\n*\005\130\005\134\000\000\000\000\n\198\000\000\000\000\000\000\000\000\n2\n:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\nB\n\206\000\000\000\000\n\218\000\000\005\138\000\000\000\238\000\000\000\000\000\000\004r\000\000\000\000\000\000\000\000\t\210\n\018\nJ\nR\nb\000\000\003=\000\000\000\000\000\000\000\000\003=\nj\001\206\003=\000\000\000\000\000\000\000\000\000\000\000\000\nr\000\000\000\000\003=\000\000\000\000\000\000\003=\000\000\003=\000\000\000\000\000\000\000\000\n\146\000\000\n\154\nZ\000\000\000\000\000\000\003=\000\000\nz\000\000\000\000\000\000\003=\000\000\000\000\001M\n\130\n\138\000\000\002\154\001M\003=\000\000\001M\003=\000\000\000\000\000\000\000\000\003=\003=\003=\000\000\001M\000\000\001M\000\000\001M\000\000\001M\000\000\000\000\000\000\000\000\000\000\003=\003=\000\000\000\000\004\154\000\000\001M\000\000\000\000\000\000\000\000\000\000\001M\000\000\003=\003=\001M\000\000\003=\003=\000\000\001M\000\000\000\000\001M\000\000\000\000\000\000\003=\001M\001M\000\238\000\000\001I\000\000\003=\000\000\000\000\001I\001M\003=\001I\000\000\000\000\000\000\001M\003=\000\000\000\000\001M\000\000\001I\000\000\001I\000\000\001I\000\000\001I\000\000\001M\001M\001M\000\000\001M\001M\000\000\000\000\000\000\000\000\001I\000\000\000\000\000\000\001M\000\000\001I\000\000\000\000\000\000\001I\001M\000\000\000\000\000\000\001I\000\000\000\000\001I\000\000\000\000\000\000\001M\001I\001I\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001I\000\000\000\000\000\000\000\000\000\000\001I\000\000\000\000\000\000\001I\001\133\000\000\000\000\000\000\000\000\001\133\000\000\012\153\001\133\001I\001I\001I\000\000\001I\001I\000\000\012\153\000\000\001\133\000\000\001\133\000\000\001\133\001I\001\133\000\000\000\000\000\000\000\000\000\000\001I\000\000\000\000\000\000\000\000\000\000\001\133\000\000\000\000\000\000\000\000\001I\001\133\012\153\000\000\000\000\000\000\000\000\000\000\012\153\000\000\000\000\000\000\000\000\001\133\000\000\000\000\000\000\000\000\001\133\001\133\001\133\000\000\000\000\0019\000\000\000\000\000\000\000\000\0019\000\000\000\157\0019\000\000\000\000\001\133\000\000\000\000\000\000\012\153\000\157\000\000\0019\000\000\0019\000\000\0019\000\000\0019\001\133\001\133\001\133\000\000\001\133\001\133\000\000\000\000\000\000\000\000\000\000\0019\000\000\000\000\000\000\000\000\000\000\0019\000\157\000\000\000\000\001\133\000\000\000\000\000\157\000\000\000\000\000\000\000\000\0019\000\000\000\000\001\133\000\000\0019\0019\0019\000\000\001\213\000\000\000\000\000\000\000\000\001\213\000\000\015\130\001\213\000\000\002\130\000\000\0019\000\000\000\000\000\000\000\157\000\000\001\213\000\000\000\000\000\000\001\213\000\000\001\213\000\000\0019\0019\0019\000\000\0019\0019\000\000\000\000\000\000\000\000\001\213\000\000\000\000\000\000\000\000\000\000\001\213\000\000\000\000\000\000\000\000\0019\015\134\000\000\000\000\001\213\000\000\000\000\001\213\000\000\000\000\000\000\0019\001\213\001\213\000\000\015\146\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\213\000Y\000\000\000\000\001\213\000\000\000Y\000\000\000Y\000\000\000\000\000\000\000\000\005\134\001\213\001\213\000\000\000Y\001\213\001\213\000Y\000\000\000\000\000\000\000Y\000Y\000\000\b\145\001\213\000\000\000\000\000\000\000\000\000\000\000\000\001\213\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000Y\000\000\001\213\000Y\000\000\000\000\000Y\000\000\000\000\000\000\000\000\000Y\000\000\000\000\000\000\000\000\000Y\000Y\000Y\000\000\000\000\000\000\000\000\000\000\000\000\000Y\000Y\000\000\003V\002\190\000\000\000\000\002\130\000\000\006\166\000\000\000Y\002\246\000\000\000Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\210\000Y\006\198\000\000\000Y\000\000\000\000\003Z\000\000\b\145\b\226\000\000\000\000\000Y\004Y\007\030\000Y\000\000\t&\004Y\003f\000\000\004Y\r\166\001\190\000\000\000\000\000\000\000\000\000Y\002\178\000\000\004Y\003\246\000\000\000\000\004Y\003\250\004Y\004\002\000\000\n\190\005v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Y\000\000\000\000\000\000\005z\000\000\004Y\007\138\000\000\000\000\004Y\000\000\005\130\005\134\000\000\004Y\000\000\000\000\004Y\000\000\000\000\000\000\000\000\004Y\002\226\000\238\000\000\000\000\000\000\000\000\000\000\000\000\004Y\004Y\r\182\000\000\005\138\000\000\000\000\004Y\004Y\000\000\004r\004Y\000\000\012\022\000\000\000\000\000\000\000\000\012\022\000\000\000\000\004Y\004Y\000\000\000\000\004Y\004Y\000\000\000\000\t\202\000\000\000\000\000\000\000\000\t\202\004Y\012\026\000\000\000\000\000\000\000\000\012\242\004Y\n\002\n\026\n\"\n\n\n*\n\002\n\026\n\"\n\n\n*\004Y\000\000\000\000\000\000\n2\n:\000\000\000\000\000\000\n2\n:\000\000\000\000\nB\000\000\000\000\000\000\000\000\nB\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\t\210\n\018\nJ\nR\nb\t\210\n\018\nJ\nR\nb\000\000\000\000\nj\000\000\000\000\000\000\000\000\nj\000\000\000\000\000\000\nr\000\000\0035\000\000\000\000\nr\000\000\0035\000\000\000\000\0035\000\000\000\000\000\000\n\146\000\000\n\154\nZ\000\000\n\146\0035\n\154\nZ\nz\0035\000\000\0035\000\000\nz\000\000\000\000\n\130\n\138\000\000\000\000\000\000\n\130\n\138\0035\015\154\000\000\000\000\000\000\000\000\0035\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0035\000\000\000\000\0035\000\000\000\000\000\000\000\000\0035\0035\0035\003V\002\190\000\000\000\000\002\130\000\000\006\166\000\000\000\000\002\246\000\000\000\000\000\000\0035\000\000\000\000\000\000\0035\000\000\001\210\000\000\006\198\000\000\000\000\000\000\000\000\003Z\0035\0035\b\226\000\000\0035\0035\000\000\000\000\000\000\000\000\023B\000\000\003f\000\000\0035\003r\001\190\000\000\000\000\000\000\015\250\0035\002\178\000\000\000\000\003\246\0035\000\000\000\000\003\250\000\000\004\002\0035\n\190\005v\000\000\000\000\000\000\003V\002\190\000\000\000\000\002\130\000\000\006\166\000\000\005z\002\246\000\000\000\000\000\000\000\000\000\000\000\000\005\130\005\134\000\000\001\210\021\178\006\198\000\000\000\000\000\000\000\000\003Z\000\000\000\000\b\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\024\014\003f\005\138\000\000\n\174\001\190\000\000\000\000\004r\000\000\000\000\002\178\000\000\000\000\003\246\000\000\000\000\000\000\003\250\000\000\004\002\000\000\n\190\005v\000\000\000\000\000\000\003V\002\190\000\000\000\000\002\130\000\000\006\166\000\000\005z\002\246\000\000\000\000\000\000\000\000\000\000\000\000\005\130\005\134\000\000\001\210\n\198\006\198\000\000\000\000\000\000\000\000\003Z\000\000\000\000\b\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\022J\003f\005\138\000\000\n\174\001\190\000\000\000\000\004r\000\000\000\000\002\178\000\000\000\000\003\246\000\000\000\000\000\000\003\250\000\000\004\002\005\194\n\190\005v\000\000\000\000\000\000\003V\002\190\000\000\000\000\002\130\000\000\000\000\000\000\005z\002\246\000\000\000\000\000\000\000\000\005\198\000\000\005\130\005\134\000\000\001\210\n\198\000\000\000\000\000\000\000\000\000\000\003Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\022\170\003f\005\138\000\000\003r\001\190\000\000\000\000\004r\000\000\000\000\002\178\000\000\000\000\003\246\000\000\000\000\000\000\003\250\000\000\004\002\005j\000\000\005v\000\000\000\000\t\017\000\000\000\000\000\000\000\000\000\000\003V\002\190\000\000\005z\002\130\000\000\000\000\000\000\000\000\002\246\000\000\005\130\005\134\000\000\005\202\000\000\t\017\000\000\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003Z\000\000\000\000\000\000\000\000\000\000\006\022\000\000\000\000\005\138\002\225\002\225\000\000\003f\002\225\004r\003r\001\190\000\000\002\225\000\000\000\000\000\000\002\178\000\000\000\000\003\246\000\000\000\000\002\225\003\250\000\000\004\002\005j\000\000\005v\002\225\000\n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005z\000\000\002\225\000\000\000\000\002\225\002\225\000\000\005\130\005\134\000\000\005\202\002\225\000\000\000\000\002\225\000\000\000\000\002\225\002\225\000\000\002\225\002\225\000\000\002\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\138\000\000\t\017\000\000\002\225\000\000\004r\004A\004A\000\000\000\000\004A\002\225\002\225\000\000\002\225\004A\000\000\000\000\000\000\000\000\000\000\004A\000\000\000\000\000\000\004A\000\000\000\000\000\000\000\000\000\000\000\000\004A\022\250\000\000\002\225\023\018\000\000\000\000\002\225\000\000\002\225\000\000\000\000\000\000\004A\000\000\000\000\004A\004A\000\000\000\000\000\000\000\000\000\000\004A\000\000\000\000\004A\000\000\000\000\000\238\004A\000\000\004A\004A\000\000\004A\0035\000\000\000\000\000\000\0035\0035\000\000\000\000\0035\0035\000\000\004A\0035\000\000\000\000\000\000\000\000\000\000\0035\004A\004A\000\000\0035\000\000\0035\000\000\0035\000\000\0035\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0035\015\154\000\000\000\000\0035\015\154\0035\004A\000\000\000\000\0035\000\000\000\000\004A\000\000\0035\000\000\000\000\0035\0035\000\000\000\000\0035\0035\0035\0035\000\000\0035\0035\0035\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0035\000\000\000\000\000\000\0035\000\000\000\000\000\000\0035\000\000\000\000\000\000\000\000\000\000\0035\0035\025\134\000\000\0035\0035\025\182\000\000\0035\0035\012\145\000\000\000\000\000\000\000\000\012\145\000\000\000\000\012\145\000\000\015\250\0035\000\000\000\000\015\250\0035\0035\000\000\012\145\000\000\0035\000\000\012\145\000\000\012\145\000\000\000\000\000\000\000\000\000\000\004\253\000\000\000\000\000\000\000\000\000\000\012\145\000\000\000\000\000\000\000\000\000\000\012\145\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\145\000\000\000\000\012\145\000\000\000\000\003V\002\190\012\145\012\145\002\130\000\000\006\166\000\000\000\000\002\246\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\145\001\210\000\000\006\198\012\145\000\000\000\000\000\000\003Z\000\000\000\000\b\226\000\000\000\000\012\145\012\145\002z\000\000\012\145\012\145\000\000\003f\000\000\000\000\t\014\001\190\000\000\000\000\012\145\000\000\000\000\002\178\026v\000\000\003\246\012\145\000\000\000\000\003\250\000\000\004\002\000\000\n\190\005v\005U\000\000\012\145\000\000\000\000\005U\000\000\000\000\005U\000\000\000\000\005z\000\000\000\000\000\000\000\000\000\000\000\000\005U\005\130\005\134\000\000\005U\000\000\005U\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005U\000\000\000\000\000\000\000\000\000\000\005U\005\138\000\000\000\000\000\000\000\000\007\222\004r\000\000\005U\000\000\000\000\005U\000\000\000\000\000\000\000\000\005U\005U\000\238\000\000\005Y\000\000\000\000\000\000\000\000\005Y\000\000\000\000\005Y\000\000\000\000\000\000\005U\005U\000\000\000\000\005U\000\000\005Y\000\000\000\000\000\000\005Y\000\000\005Y\000\000\005U\005U\000\000\000\000\005U\005U\000\000\000\000\000\000\000\000\005Y\000\000\000\000\000\000\000\000\000\000\005Y\000\000\0035\000\000\000\000\005U\007\222\0035\000\000\005Y\0035\000\000\005Y\000\000\000\000\000\000\005U\005Y\005Y\000\238\0035\000\000\000\000\000\000\0035\000\000\0035\000\000\000\000\000\000\000\000\000\000\000\000\005Y\005Y\000\000\000\000\005Y\0035\015\154\000\000\000\000\000\000\000\000\0035\000\000\000\000\005Y\005Y\000\000\000\000\005Y\005Y\0035\000\000\000\000\0035\000\000\000\000\000\000\000\000\0035\0035\0035\006\001\000\000\000\000\000\000\005Y\006\001\000\000\000\000\006\001\000\000\000\000\000\000\000\000\0035\000\000\005Y\000\000\0035\006\001\000\000\000\000\000\000\006\001\000\000\006\001\000\000\000\000\0035\0035\017\130\000\000\0035\0035\000\000\000\000\000\000\006\001\000\000\000\000\000\000\000\000\000\000\006\001\000\000\000\000\000\000\000\000\015\250\0035\000\000\000\000\006\001\000\000\000\000\006\001\000\000\000\000\000\000\000\000\006\001\006\001\000\238\000\000\000\000\000\000\000\000\000\000\025^\000\000\000\000\000\000\000\000\000\000\003V\002\190\006\001\000\000\002\130\000\000\006\001\000\000\000\000\002\246\000\000\000\000\000\000\000\000\000\000\000\000\006\001\006\001\021>\001\210\006\001\006\001\000\000\000\000\000\000\000\000\003Z\001\202\001\206\000\000\006\001\000\000\000\000\000\000\000\000\000\000\000\000\006\001\000\000\003f\000\000\000\000\003r\001\190\000\000\000\000\001\210\001\214\006\001\002\178\000\000\000\000\003\246\000\000\000\000\000\000\003\250\000\000\004\002\005j\000\000\005v\000\000\000\000\000\000\005\238\000\000\000\000\000\000\001\246\002\162\003V\002\190\005z\002\158\002\130\002\178\004\030\004*\000\000\002\246\005\130\005\134\0046\005\202\000\000\000\000\003\254\000\000\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003Z\000\000\000\000\004:\000\000\000\000\004\209\000\000\005\138\000\000\006\146\000\000\b\202\003f\004r\000\000\003r\001\190\000\000\000\000\000\000\000\000\026\002\002\178\000\000\000\000\003\246\000\000\000\000\000\000\003\250\000\000\004\002\005j\000\000\005v\000\000\000\000\006.\000\000\000\000\000\000\000\000\000\000\003V\002\190\000\000\005z\002\130\000\000\000\000\000\000\000\000\002\246\000\000\005\130\005\134\000\000\005\202\000\000\006R\000\000\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003Z\000\000\000\000\000\000\006:\000\000\000\000\000\000\000\000\005\138\003V\002\190\000\000\003f\002\130\004r\003r\001\190\000\000\002\246\000\000\000\000\000\000\002\178\000\000\000\000\003\246\000\000\000\000\001\210\003\250\000\000\004\002\005j\000\000\005v\003Z\000\000\000\000\000\000\000\000\007\129\000\000\000\000\007\129\000\000\000\000\005z\000\000\003f\000\000\000\000\003r\001\190\000\000\005\130\005\134\000\000\005\202\002\178\007\129\007\129\003\246\007\129\007\129\000\000\003\250\000\000\004\002\005j\000\000\005v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\138\006M\000\000\000\000\005z\007\129\004r\003V\002\190\000\000\000\000\002\130\005\130\005\134\000\000\005\202\002\246\000\000\000\000\000\000\000\000\006M\000\000\007\129\000\000\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003Z\000\000\000\000\005\138\011\166\000\000\000\000\000\000\000\000\004r\003V\002\190\000\000\003f\002\130\000\000\003r\001\190\000\000\002\246\007\129\000\000\007\129\002\178\000\000\000\000\003\246\000\000\000\000\001\210\003\250\000\000\004\002\005j\005\226\005v\003Z\007\129\007\129\000\000\000\000\000\000\007\129\000\000\007\129\000\000\000\000\005z\007\129\003f\000\000\000\000\003r\001\190\000\000\005\130\005\134\000\000\000\000\002\178\000\000\000\000\003\246\000\000\000\000\000\000\003\250\000\000\004\002\005j\000\000\005v\000\000\000\000\011\178\000\000\000\000\000\000\000\000\005\138\003V\002\190\000\000\005z\002\130\004r\000\000\000\000\000\000\002\246\000\000\005\130\005\134\000\000\005\202\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\000\000\000\000\000\000\000\003Z\000\000\000\000\000\000\011\190\000\000\000\000\000\000\000\000\005\138\003V\002\190\000\000\003f\002\130\004r\003r\001\190\000\000\002\246\000\000\000\000\000\000\002\178\000\000\000\000\003\246\000\000\000\000\001\210\003\250\000\000\004\002\005j\000\000\005v\003Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005z\000\000\003f\000\000\000\000\003r\001\190\000\000\005\130\005\134\000\000\005\202\002\178\000\000\000\000\003\246\000\000\000\000\000\000\003\250\000\000\004\002\005j\000\000\005v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\138\006q\000\000\000\000\005z\000\000\004r\000\000\002\190\000\000\000\000\002\130\005\130\005\134\000\000\005\202\002\246\000\000\000\000\000\000\000\000\006q\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\000\002\250\000\000\000\000\000\000\000\000\000\000\005\138\000\000\000\000\000\000\000\000\002\254\004r\000\000\000\000\000\000\000\000\000\000\000\000\0032\001\190\000\000\000\000\000\000\000\000\000\000\002\178\000\000\000\000\003:\000\000\000\000\000\000\b\026\b\030\b*\000\000\000\000\005v\000\000\000\000\000\000\006\249\007\030\000\000\000\000\000\000\006\249\000\000\000\000\006\249\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\130\005\134\006\249\000\000\000\000\000\000\006\249\000\000\006\249\000\000\001\181\000\000\000\000\000\000\000\000\001\181\000\000\000\000\001\181\000\000\006\249\000\000\000\000\000\000\005\138\b2\006\249\007\138\001\181\bJ\004r\000\000\001\181\000\000\001\181\006\249\000\000\000\000\006\249\000\000\000\000\000\000\000\000\006\249\006\249\000\238\001\181\000\000\000\000\000\000\000\000\000\000\001\181\000\000\000\000\000\000\000\000\000\000\000\000\006\249\000\000\001\181\000\000\006\249\001\181\000\000\000\000\000\000\000\000\001\181\001\181\001\181\000\000\006\249\006\249\000\000\000\000\006\249\006\249\000\000\000\000\000\000\000\000\000\000\000\000\001\181\000\000\000\000\001\217\001\181\000\000\000\000\000\000\001\217\006\249\000\000\001\217\000\000\000\000\001\181\001\181\000\000\000\000\001\181\001\181\000\000\001\217\000\000\000\000\017\142\001\217\000\000\001\217\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\181\000\000\000\000\000\000\001\217\001\181\000\000\000\000\000\000\000\000\001\217\000\000\000\000\006\005\000\000\000\000\000\000\000\000\006\005\001\217\000\000\006\005\001\217\000\000\000\000\000\000\000\000\001\217\001\217\000\000\000\000\006\005\000\000\000\000\000\000\006\005\000\000\006\005\000\000\000\000\000\000\000\000\000\000\001\217\000\000\000\000\000\000\001\217\000\000\006\005\000\000\000\000\000\000\000\000\000\000\006\005\000\000\001\217\001\217\000\000\000\000\001\217\001\217\000\000\006\005\000\000\000\000\006\005\000\000\000\000\000\000\001\217\006\005\006\005\000\238\000\000\000\000\000\000\001\217\000\000\000\000\000\000\000\000\021\026\000\000\000\000\000\000\000\000\006\005\001\217\012\145\000\000\006\005\000\000\000\000\012\145\000\000\000\000\012\145\000\000\000\000\000\000\006\005\006\005\000\000\000\000\006\005\006\005\012\145\000\000\000\000\000\000\012\145\000\000\012\145\000\000\006\005\000\000\000\000\000\000\004\253\000\000\000\000\006\005\000\000\000\000\012\145\000\000\000\000\000\000\000\000\000\000\012\145\000\000\006\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\145\000\000\000\000\000\000\000\000\012\145\012\145\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012I\000\000\002\190\012I\000\000\028\002\000\000\012\145\000\000\000\000\028\006\000\000\000\000\012I\000\000\000\000\000\000\000\000\000\000\012I\000\000\012\145\012\145\002z\000\000\012\145\012\145\000\000\000\000\000\000\000\000\012I\000\000\000\000\000\000\012\145\000\000\012I\000\000\026\174\000\000\000\000\012\145\001\002\001\190\000\000\012I\000\000\000\000\012I\000\000\000\000\000\000\012\145\012I\004Y\000\000\000\000\000\000\000\000\004Y\000\000\028\n\004Y\000\000\000\000\000\000\000\000\000\000\000\000\012I\000\000\000\000\004Y\012I\000\000\000\000\004Y\000\000\004Y\000\000\000\000\000\000\028\014\012I\012I\000\000\000\000\012I\000\000\000\000\004Y\000\000\000\000\000\000\000\000\000\000\004Y\b1\b1\000\000\000\000\b1\007\222\000\000\012I\004Y\b1\000\000\004Y\000\000\000\000\000\000\016*\004Y\002\226\000\238\b1\000\000\000\000\000\000\000\000\000\000\000\000\b1\000\000\000\000\000\000\000\000\000\000\004Y\000\000\000\000\000\000\004Y\000\000\000\000\b1\000\000\000\000\b1\b1\000\000\000\000\004Y\004Y\000\000\b1\004Y\004Y\b1\000\000\000\000\000\000\b1\000\000\b1\b1\007J\b1\000\000\000\000\000\000\000\000\001q\004Y\000\000\000\000\000\000\001q\025~\b1\001q\000\000\000\000\000\000\004Y\000\000\000\000\b1\b1\000\000\001q\000\000\001q\000\000\001q\000\000\001q\000\000\000\237\000\000\000\000\000\000\000\000\000\237\000\000\000\000\000\237\000\000\001q\000\000\000\000\b1\000\000\000\000\001q\000\000\000\237\b1\000\000\000\000\000\237\000\000\000\237\000\000\000\000\000\000\001q\000\000\000\000\000\000\000\000\001q\001q\000\238\000\237\000\000\000\000\000\000\000\000\000\000\000\237\000\000\000\000\000\000\000\000\000\000\000\000\001q\000\000\000\237\000\000\000\000\000\237\000\000\000\000\000\000\000\000\000\237\000\237\000\238\000\000\001q\001q\001q\000\000\001q\001q\000\000\000\000\000\000\000\000\000\000\000\000\000\237\000\000\000\000\000\241\000\237\000\000\000\000\000\000\000\241\001q\000\000\000\241\000\000\000\000\000\237\000\237\000\000\000\000\000\237\000\237\001q\000\241\000\000\000\000\000\000\000\241\000\000\000\241\000\000\006\245\000\000\000\000\000\000\000\000\006\245\000\237\000\000\006\245\000\000\000\241\000\000\000\000\000\000\000\000\000\000\000\241\000\237\006\245\000\000\000\000\000\000\006\245\000\000\006\245\000\241\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\241\000\241\000\238\006\245\000\000\000\000\000\000\000\000\000\000\006\245\000\000\000\000\000\000\000\000\000\000\000\000\000\241\000\000\006\245\000\000\000\241\006\245\000\000\000\000\000\000\000\000\006\245\006\245\000\000\000\000\000\241\000\241\000\000\000\000\000\241\000\241\000\000\000\000\000\000\000\000\000\000\000\000\006\245\000\000\000\000\000\000\006\245\000\000\000\000\000\000\000\000\000\241\000\000\006\201\006\201\000\000\006\245\006\245\016\194\000\000\006\245\006\245\000\241\005\249\000\000\000\000\000\000\000\000\005\249\000\000\000\000\005\249\006\201\006\201\006\201\000\000\000\000\006\245\017b\000\000\000\000\005\249\006\201\000\000\000\000\005\249\000\000\005\249\000\000\005a\007\030\000\000\000\000\000\000\005a\006\201\006\201\005a\000\000\005\249\006\201\000\000\006\201\006\201\006\201\005\249\000\000\005a\000\000\006\201\000\000\005a\000\000\005a\005\249\000\000\000\000\005\249\000\000\000\000\000\000\000\000\005\249\005\249\000\000\005a\006\201\000\000\000\000\000\000\000\000\005a\007\138\000\000\000\000\000\000\000\000\000\000\005\249\000\000\000\000\000\000\005\249\005a\000\000\000\000\000\000\000\000\005a\005a\000\238\000\000\005\249\005\249\000\000\000\000\005\249\005\249\000\000\000\000\000\000\000\000\011\249\000\000\005a\000\000\000\000\011\249\000\000\004\230\011\249\000\000\000\000\005\249\000\000\000\000\000\000\000\000\005a\005a\011\249\000\000\005a\005a\011\249\000\000\011\249\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\249\005a\000\000\000\000\000\000\000\000\011\249\000\000\000\000\000\000\000\000\000\000\000\000\001\202\002~\011\249\000\000\002\130\011\249\000\000\000\000\000\000\000\000\011\249\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\210\001\214\001\230\000\000\000\000\000\000\000\000\011\249\t\190\000\000\001\242\011\249\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\249\011\249\002\138\002\146\011\249\011\249\000\000\002\158\000\000\002\178\004\030\004*\0041\000\000\000\000\000\000\020\242\0041\026Z\004)\0041\011\249\000\000\000\000\004)\000\000\000\000\004)\000\000\000\000\0041\000\000\n\162\004:\0041\000\000\0041\004)\000\000\000\000\000\000\004)\005\134\004)\000\000\000\000\000\000\000\000\0041\000\000\000\000\000\000\026f\000\000\0041\004)\000\000\000\000\000\000\000\000\000\000\004)\000\000\0041\000\000\000\000\0041\000\000\000\000\021\006\004)\0041\000\000\004)\000\000\000\000\000\000\000\000\004)\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0041\000\000\000\000\000\000\0041\004I\000\000\004)\000\000\000\000\004I\004)\004\025\004I\0041\0041\000\000\004\025\0041\0041\004\025\004)\004)\004I\000\000\004)\004)\004I\000\000\004I\004\025\000\000\000\000\000\000\004\025\0041\004\025\000\000\000\000\000\000\000\000\004I\004)\000\000\000\000\000\000\016\234\004I\004\025\000\000\000\000\000\000\000\000\019\214\004\025\000\000\004I\000\000\000\000\004I\000\000\000\000\000\000\004\025\004I\000\000\004\025\000\000\000\000\000\000\000\000\004\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004I\000\000\000\000\n\222\004I\000\000\000\000\004\025\000\000\001\202\001\206\004\025\000\000\000\000\004I\004I\000\000\000\000\004I\004I\000\000\004\025\004\025\002\142\000\000\004\025\004\025\000\000\001\210\001\214\001\230\000\000\000\000\000\000\000\000\004I\000\000\000\000\001\242\000\000\000\000\000\000\004\025\000\000\000\000\001\250\020\182\006\205\006\205\000\000\000\000\001\246\002\146\024.\000\000\000\000\002\158\000\000\002\178\004\030\004*\000\000\000\000\004.\000\000\0046\006\205\006\205\006\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\205\000\000\000\000\000\000\000\000\000\000\004:\000\000\000\000\000\000\000\000\000\000\000\000\006\205\006\205\000\000\000\000\000\000\006\205\000\000\006\205\006\205\006\205\000\000\0049\000\000\000\000\006\205\000\000\0049\000\000\004!\0049\000\000\000\000\015\138\004!\000\000\000\000\004!\000\000\000\000\0049\000\000\006\205\000\000\0049\000\000\0049\004!\000\000\000\000\000\000\004!\000\000\004!\000\000\000\000\000\000\000\000\0049\000\000\000\000\000\000\000\000\000\000\0049\004!\000\000\004Q\000\000\000\000\000\000\004!\004Q\000\000\000\000\004Q\0049\000\000\004\"\000\000\006\205\0049\000\000\004!\000\000\004Q\000\000\000\000\004!\004Q\000\000\004Q\000\000\000\000\000\000\000\000\000\000\0049\000\000\000\000\000\000\000\000\000\000\004Q\004!\000\000\000\000\000\000\000\000\004Q\000\000\0049\0049\000\000\000\000\0049\0049\000\000\004!\004!\000\000\004Q\004!\004!\000\000\000\000\004Q\011*\000\000\000\000\000\000\000\000\0049\001\202\001\206\000\000\000\000\000\000\000\000\004!\000\000\000\000\004Q\018\018\000\000\000\000\000\000\000\000\000\000\003\254\020b\000\000\001\210\001\214\001\230\000\000\004Q\004Q\000\000\000\000\004Q\004Q\001\242\004m\000\000\000\000\000\000\000\000\000\246\000\000\000\000\002\194\000\000\000\000\000\000\001\246\002\146\004Q\000\000\000\000\002\158\003\178\002\178\004\030\004*\004m\000\000\003\182\020\222\0046\007\149\000\000\000\000\007\149\000\000\000\000\000\000\000\000\000\000\003\186\000\000\000\000\000\000\000\000\000\000\016\174\004:\000\000\000\000\007\149\007\149\000\000\007\149\007\149\024Z\000\000\000\000\017\018\000\000\000\000\000\000\000\000\017*\000\000\000\000\000\000\007m\000\000\000\000\007m\000\000\000\000\000\000\007\149\000\000\000\000\000\000\000\000\0172\000\000\000\000\000\000\004n\000\000\004r\007m\007m\000\000\007m\007m\000\000\000\238\017F\017r\000\000\000\000\004m\004m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007m\000\000\007\153\000\000\021\154\007\153\000\000\000\000\000\000\000\000\000\000\000\000\007\149\000\000\007\149\000\000\000\000\000\000\007m\000\000\000\000\007\153\007\153\000\000\007\153\007\153\007\149\000\000\000\000\005\234\007\149\000\000\000\000\000\000\007\149\007\137\007\149\000\000\007\137\000\000\007\149\000\000\000\000\000\000\000\000\007\153\000\000\000\000\007m\000\000\007m\000\000\000\000\000\000\007\137\007\137\000\000\007\137\007\137\000\000\000\000\000\000\007m\000\238\000\000\005\234\007m\000\000\000\000\000\000\007m\000\000\007m\000\000\000\000\000\000\007m\000\000\007\137\000\000\rI\rI\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\153\000\000\007\153\000\238\000\000\000\000\rI\rI\rI\0072\000\000\000\000\000\000\000\000\007\153\000\000\rI\005\234\007\153\000\000\000\000\000\000\007\153\000\000\007\153\001\202\001\206\022N\007\153\rI\rI\000\000\000\000\007\137\rI\007\137\rI\rI\rI\000\000\000\000\000\000\000\000\rI\001\210\002\170\001\230\006*\000\000\000\000\005\234\007\137\000\000\000\000\001\242\007\137\000\000\007\137\000\000\000\000\rI\007\137\000\000\001\202\001\206\022\174\000\000\001\246\002\146\000\000\000\000\000\000\002\158\000\000\002\178\004\030\004*\000\000\000\000\000\000\000\000\0046\001\210\002\170\001\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\242\000\000\000\000\000\000\000\246\000\000\004:\002\194\000\000\000\000\000\000\000\000\000\000\001\246\002\146\000\000\000\000\004\141\002\158\000\000\002\178\004\030\004*\003\182\000\000\000\000\000\000\0046\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\186\000\000\000\000\000\000\000\000\000\000\016\174\000\000\000\000\004:\000\000\000\000\000\000\000\000\000\000\024Z\000\000\000\000\017\018\000\000\000\000\000\000\000\000\017*\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0172\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017F\017r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\021\154")) and lhs = - (8, "\012\011\n\t\b\007\006\005\004\003\002\001\000\216\216\215\215\214\213\213\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\211\211\210\209\209\209\209\209\209\209\209\208\208\208\208\208\208\208\208\207\207\207\206\206\205\204\204\204\203\203\202\202\202\202\202\202\201\201\201\201\201\201\201\201\200\200\200\200\200\200\200\200\199\199\199\199\198\197\196\196\196\196\195\195\195\195\194\194\194\193\193\193\193\192\191\191\191\190\190\189\189\188\188\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\186\186\185\185\184\183\182\181\181\180\180\179\179\179\179\178\178\178\178\177\177\176\176\176\176\175\174\173\173\172\172\171\171\170\169\169\168\167\167\166\165\164\164\164\163\163\162\161\161\161\161\161\160\160\160\160\160\160\160\160\159\159\159\159\159\159\158\158\157\157\157\156\156\155\155\155\154\154\153\153\152\152\151\151\150\150\149\149\148\148\147\147\146\146\145\145\144\144\144\143\143\143\143\142\142\141\141\140\140\139\139\139\139\139\138\138\138\138\137\137\137\136\136\136\136\136\136\136\135\135\135\135\135\135\135\134\134\133\133\132\132\132\132\132\132\131\131\130\130\129\129\128\128\127\127\127~}}}||{{{{{{{{{zzyyxxxxxxxxxxxwvuutttttsrrqqppppppppppppppoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmllkkjjiihhggffeeddccbbaaaaaaaaaaa`_^]\\[ZYXWWWWWWWWWWVVVUUUTTTTSSSSSSSSSRRQQQQQPPOONMLLKKKKKJJIIHHHGGGGGGFFFEEDDCCBBAA@@@??>>==<<;;::9988776655544433322211110/..................-----,,,,,,,+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++**))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((''&&&%%$$$$$$$$$$$$$$$$##\"\"!!!!!!! \031\031\030\030\030\030\030\029\029\028\027\026\026\026\025\025\024\024\024\023\023\022\022\022\022\021\021\020\019\019\019\019\019\018\017\017\016\016\016\015\015\015\014\014\014\014\r\r") + (8, "\012\011\n\t\b\007\006\005\004\003\002\001\000\216\216\215\215\214\213\213\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\212\211\211\210\209\209\209\209\209\209\209\209\208\208\208\208\208\208\208\208\207\207\207\206\206\205\204\204\204\203\203\202\202\202\202\202\202\201\201\201\201\201\201\201\201\200\200\200\200\200\200\200\200\199\199\199\199\198\197\196\196\196\196\195\195\195\195\194\194\194\193\193\193\193\192\191\191\191\190\190\189\189\188\188\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\186\186\185\185\184\183\182\181\181\180\180\179\179\179\179\178\178\178\178\177\177\176\176\176\176\175\174\173\173\172\172\171\171\170\169\169\168\167\167\166\165\164\164\164\163\163\162\161\161\161\161\161\160\160\160\160\160\160\160\160\159\159\159\159\159\159\158\158\157\157\157\156\156\155\155\155\154\154\153\153\152\152\151\151\150\150\149\149\148\148\147\147\146\146\145\145\144\144\144\143\143\143\143\142\142\141\141\140\140\139\139\139\139\139\138\138\138\138\137\137\137\136\136\136\136\136\136\136\135\135\135\135\135\135\135\134\134\133\133\132\132\132\132\132\132\131\131\130\130\129\129\128\128\127\127\127~}}}||{{{{{{{{{zzyyxxxxxxxxxxxwvuutttttsrrqqppppppppppppppoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmllkkjjiihhggffeeddccbbaaaaaaaaaaa`_^]\\[ZYXWWWWWWWWWWVVVUUUTTTTSSSSSSSSSRRQQQQQPPOONMLLKKKKKJJIIHHHGGGGGGFFFEEDDCCBBAA@@@??>>==<<;;::9988776655544433322211110/..................-----,,,,,,,+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++**))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((''&&&%%$$$$$$$$$$$$$$$$##\"\"!!!!!!! \031\031\030\030\030\030\030\029\029\028\027\026\026\026\025\025\024\024\024\024\024\024\024\024\024\024\023\023\022\022\022\022\021\021\020\019\019\019\019\019\018\017\017\016\016\016\015\015\015\014\014\014\014\r\r") and goto = - ((16, "\000%\000\193\000G\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\012\000\000\000\000\000\129\001\152\000\030\0003\000#\000\004\000\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000b\000\000\000\000\000\000\000\000\000\000\000t\000\000\000\000\000\000\000\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=2\000\000\000\000\000\000\000\254\000\000\000\000\000\000\000\000\000\000\000\000\000\000'\238\001T\001>\000\223\000\000\001B9\220\001\236\001\218\000:\000\000\001x\000\000\000\182\003\156\000\000\002\150\000\000\000\000\000\000\000\000\000\000\001\022\000\000\000\218\003\202\bf\000\000\000\000\011\018'\238\000\000\000\000\001\254\000\000\000\027\000\000:~\002\184\000\000\001\156\001r\000\000\000\000\002\172\002\142\002\208\003b\001\226\003\202\004\142\000f\001\194\0022\003\216\002\152\011b\000\000\005(\003\244\003\188\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004r\000\000\t>\005(\011\194\000\000\000\000\004.\005d\004\0301\236\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\148\000\000\004\168\005l\005@\000\000\000\000\000\000\000\000\000\173\000\000\000\000\005\144\000\167\006\018\006(\007\214\000\000\0050\005H\006*\000Q\004\228\006L \232\000\000\000\000\005X\006\254\011\204\000\000!\b\001\244!\026\"V\000\000\003B\000\000\000\000\000\000\000\000\006\018=F\006\020\000\000\001\012\0064\000\000\004P6\150\000\131\000\000\001\172\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002:\005\190\000\000\000\000\000\000\000\192\000\000\tD\000\000\000\000\002\164\000o\000\000\000\000\003\248\000\000\006n\000\000\002\164\t\148\002\164\000\000\000\000\000\000\000\000\000\0007 \000\000\007\"\006@\000\000=\168\007N\030`\000\000\000\000\000\000\0062\000\000\000\000\000\000\000\000\006F\000\000\000\000\000\000\000\000\000\0002L\000\000\000\000\000\000\000\000\000\000\000\000\001\158\007N\000\000\000\000\000\000\006F\007\1342\146\006\224\007p\015\214\000\000\003\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000(\000\000\000\000\000\000\000\000\b\0122\160\000\000\000\000\007\030\b\0042\214\000\000\000\000\000\00038\007\0143\152\000\000\007\014\000\0003\164\007\014\000\0003\228\007\014\000\000\007\014\000\000\000\000\007\014\000\000\000\0004J\000\000\007\0144\138\000\000\007\014\002|\000\000\000\000\"V\000\000\000\000\000\000\000\000\007\014\"z\000\000\000\000\000\000\007\014\000\000\006F\007\246\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\016\000\000\007\136\000\000=\132\006F\000\000\000\000\000\000\000\000\b\b\b\184\012$\b\026\b\030\b@\b\028\005\014\b`\0001\t\006\000\000\000\000\000\029\005\136\b\160\001\172\b\200\bL\000\000\000\145\004\138\005\180\007\136\n\"\000\000\000\000C\158\000\000C\224\t\212\000\000=\198\006F>@\006F\000\000\003\"\000\000\003x\000\000\000\000\003\220\000\000\000\000\000\000\nt\000\000\n\030\000\145\000\000\000\000\t>\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\145\000\000\000\000\000\145\000\000\b\200\007\014\000\000\002\182\004\228\000\000\002\182\000\000\000\000\n\206\000\145\000\000\000\000\000\000\000\000\000\000\000\000\002\182\012\132\rL\n4\t\218\"\152\000n\000\000\t\130\b\182\r\158\t\234\b\228\025X1N\000\000\000\000\000\000\000\000\000\000\0032\t\188\000\000\000\000\000\000\t\250\b\244\007V\002\182\011\240\000\000\000\145\000\000\000\000\000\000\001\244\000\000>T\006F\r\166\n\018\t\030\r\254\n \t0\014\180\"\186\007\014\015\024\n\"\t89\190\n\244\000\000#\002\007\014>x\006F\n\238\000\000\000\000\000\000\000\000\007\148\011&\011L\000\000\000\000\b\176\015 \n\208\t>4\172\007\014\015t\n\222\tF6(\000\000>\172\000\000\000\000\015|\"\244\018\\\000\000\000\000\000\000\000\000>\208\000\000\000\000\000\000\007\172\016B\000\000\000\000\000\000\000\000#^>\222\000\000\000\000\000\000\000\000\000\000\n\170\016\150\000\000\n\180$\"\n\180$,\n\180\000\000?\026\000\000$\128\n\180\016\234\004\152\016\244\000\000\000\000$\136\n\180%\022\n\180%\030\n\180%\250\n\180&\002\n\180&\026\n\180&\152\n\180&\246\n\180&\254\n\180'\140\n\180'\148\n\180'\232\n\180(v\n\180(\128\n\180)\014\n\180)^\n\180)h\n\180)\246\n\180*F\n\180*\212\n\180\t\170*\2484\232\007\148\011x\000\000+8;l\000\000\017N\000\000?,\000\000\006F;\166\000\000\006F?P\006F\000\000\017\184\000\000\000\000\000\000+\\\000\000\000\000\000\000\000\000\000\000\007\014\000\000\000\000?\210\000\000\006F\000\000\000\000;\166\011\136\000\000@6\006F\018\018\000\000\000\000\011\"\000\000@H\006F\018\160\000\000\000\000\018\196\000\000\000\000\000\000@Z\006F\019\028\000\000\n\252\019\132\000\0005J\000\000\007\0145\142\000\000\007\0145\176\000\000\007\014\003d\000\000\000\000\000\000\000\000\000\0005\240\007\014\004\222\005\022\000\000\000\000\000\000\n\180\019\222\000\000\000\000\000\000+\150\n\180\000\000\000\000\000\000\000\000\0206\000\000\000\000\000\000\n\180\020D\000\000\020\158\000\000\000\000\000\000\021\004\000\000\000\000\000\000\000\000@\146\000\000\000\000\021^\000\000\000\000\000\000,H\n\180\021l\000\000\000\000\000\000,\138\n\180\021\196\000\000\000\000,\176\n\180\n\180\000\000\007\228\022\030\000\000\000\000-\b\n\180\022l\000\000\000\000-(\n\180-v\n\180\000\000.\004\n\180\000\000\000\000\022\250\000\000\000\000.\152\n\180\023,\000\000\000\000.\200\n\180\023\\\000\000\000\000.\232\n\180\000\000/\000\n\180\000\000;\138\000\000\000\000\n\180\000\000\000\000\023\142\000\000\000\000\023\192\000\000\000\000\011D\000\000\000\000\024\028\000\000\024$\000\000\000\000\000\000\007\148\011\226\000\0007\022\n<\002\164\025\004\000\0007r\000\000\000\000\000\0007\194\000\000\000\000\025$\000\000\025\146\000\000\000\000\000\000\000\000/\n\000\000\000\000\000\000/f\n\1800r\n\180\000\000\n\252\025\156\000\000\000\000\025\236\000\0000T\000\000\000\0001N\000\000\000\000\000\000\026\134\000\000\000\000\000\000\000\000\026\144\000\000\000\000\000\000\000\000\012\152\000\000\000\000\000\000\003\154\000\000\000<\000\000\000;\000\000\0128\000\000\004\144\000\000\000\000\000\000\000\000\000\000\000\000\0032\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\180\000\000\012\164\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\184\007\232\002\182\027T\000\000\011\166\t\224\012*\001\144\t\136\002\182\r@\000\145\t\176\002\182\000\000\027x\000\000\004\142\000\000\011\194\t\238\004X\000\000\000\000\000\000\000\000\000\000\011\218\001.\000\146\000\000\000\000\000\000;\222\000\000C\240\000\000\t\246\000\000\n\016\000\000\000\000\000\000\000\000\002\158\000\000\000\000\000\000\011*\002\164\000\000\002\164\001\178\000\000\rv\002\164\002\164\n\024\000\000\027\186\000\000\000\000\n8\012\172\000\0000\180\005$\000\000\000\000\000\000\000\000\000\000\000\000\n\180\000\000\028\180\000\000\n\180\000\000\000\000\014\242\000\000\000\145\000\000\016H\000\000\000\145\000\000\017\012\000\145\000\000\003Z\000\000\n<\n\022\005`\000\000\011\226\011\234\nV\012\024\012\164\017T\000\145\006\012\000\000\nZ\012\134\012\188\005\024\006\184\012\150\n\130\r\014\006\146\b\132\012\228\000\000\000\000\007\188\b\148\000\000\004\168\002\2426N\007\014\028\028\000\000\007X\003\178\012\158\n\154\011^\005\224\000\000\012\168\n\158\006\200\000\000@\172\006F\rZ\r\132\000\000\t:\000\000\012\244\n\166\006>\r2\003V\000\000\000\000\000\000\000\000\n\216\tZ\000\000\n\222\tl\000\000\bb\0164\rF\rP\n\228\006\216\t\172\000\000\n\230\007\138\n\018\000\000\rR\n\238\r\220\000\000\t\028\000\000\n\132\000\000\r\252\000\000\018\024\000\145\r\216\011\002\014\022\000\000\018\202\0056\r\236\000\000\000\000\003j\006\160\011$\000\000\019\228\000\145\011F\000\000\004\022\000\000\r\210\011\016\0212\006\154\000\000\r\222\011>\007\176\r2\r\230\r\240\011L\015F\000\000\014\000\001\200\000\000\000\000\000\000\000\000\000\171\011X\r\226@\190\006F\000\000\002\200\011\142\014\148\000\000\000\000\000\000\000\000\000\000\000\000A\000\006\164\000\000\011\182\014\246\000\000\000\000\000\000\000\000\000\000\000\000\006\174\000\000A\030\006F\011\226\000\000\006F\011\218\000\184\000\000\011\230\011\232\007\024\000\000\001\004\004L\000\000\002\190\000\000A\"\006F\006F\000\000\000\000\007\b\000\000\b\252\000\000\001\186\007\b\007\b\000\000\011\236;\204\006FA\152\006F\012\b\000\000\000\000\000\000\000\000\012\014\000\000\000\000\007N\000\000\007l\014`\011\240\015p\014*\000\000\000\000\001\196\b|\014h\000\000\000\000\011\250\015\128\014@\000\000\000\000\029\018\000\000\012\222\000\000!(6H\006F\000\000,N\018\132\000\000A\252\000\000\000\000\000\000\007\b\000\000\000\000\012:\014|\012\000\015\144\014J\000\000\000\000B\014\012\144\014\140\000\000\000\000\000\000<:\000\000\000\000\000\000\000\000\000\000\000\000\012\146\000\000\014\152\012\020\006\162\000\000\015\134\015>\012\180\014\166\000\000\000\000\014\170\012>\b*\000\000\000\000\tl6\150\005|\000\000\000\000\000\000\bL\014p\012p\000\000\014z\bL\000\000\015V\012\188\014\196\000\000\000\000\000\000\006F\003v\004(\005\180\000\000\000\000\000\000\000\000\014\138\012t\000\000\006\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006F\014z\012\128\015\208\014\138\000\0007\224\000\237\012\146\014^\003\156\000\019\012\150\015\016\000\000\015\200\028\130\000\000\000\000\029J\000\000\012\208\000\000\nL\000\000\000\000\000\000\000\000\000\000\000\000B\018\006F\000\000\015\204\029l\000\000\000\000\030\002\000\000\000\245\012\156\015r\000\000\000\0007\250:\020\015(\000\000B0\006F\0302\000\000\000\000\030T\000\000\000\000\r0\000\000\000\\\000\000\000\000\000\000\000\000\000\000\000\000:\204\000\000\000\0008\188:\208\015*\000\000BP\006F\030\234\000\000\000\000\031\028\000\000\000\000\012\184\031<\r<\000\000\012\190\012\198\002\016\002\208\012\200\t&\012\214\015|0\214\r\\\000\000\r\016\r2\tf\000\000\004*\002\026\006\026\001\152\001\252\001U\001'\000\193\000\140\001A\0053\001\208\006\028\001\149\001\t\002e\004\236\002k\000m\006\019\001\016\001\029\001<\002q\001x\001}\002g\001\253\006\029\000\189\005\028\004o\000\193\000\251\004\238\001g\001m\001\016\000\193\001V\001\024\004\232\001\024\001\025\000\196\001\025\002s\003\001\001\239\004\215\000\193\000\251\001w\006\020\004<\001\024\004\234\002b\005\029\005]\005\030\006\021\000\196\001\253\001\156\001\196\001\168\001\027\002\017\001\027\002d\000\193\001]\001^\003\197\0039\004\235\001\252\000\193\000\251\000\193\001\t\0069\003\018\000\196\006+\005?\001\016\001\019\005\031\004E\001\t\001_\002\185\001z\001a\001b\001\016\001\029\004\215\006%\000\196\001{\002\244\001}\001e\003\213\002\244\005\247\006\024\001#\003J\001#\001n\006\026\002\244\002\244\004\152\004\001\001\191\003\227\001\192\005 \005\249\006\028\001\179\006\150\002e\001\223\002k\001\173\005!\001\227\005\"\001\016\002q\001\253\001}\002g\001\t\006\029\001\t\002\r\002\014\001^\001\016\001\029\001\016\001\029\005\250\0007\006\136\002\244\001\024\001\t\004\t\005^\002Q\002s\001\181\001\016\001\029\004\002\006~\003\195\002R\001f\006\145\003\240\003\242\004\246\006J\001\228\001\024\0048\000\196\001\025\001g\002`\005$\000\193\001\178\004=\006s\005&\0050\001\229\000\196\005F\005G\0017\001\188\0017\001\024\005Z\005<\004\001\001\030\002\244\001\030\001\027\005_\002\b\005H\005X\002\r\002\014\001^\005P\004\001\005[\003k\001\030\006`\002\244\004\217\001\184\005?\000\193\006\180\002Q\000\196\006a\002\244\001'\002\011\001'\001A\002R\001A\003n\000m\004w\002\025\003\140\004\215\001z\002b\001\016\006|\001\230\002`\001\024\001#\001\150\001\025\001}\001e\002\017\001\201\002d\000\193\001\t\000\196\002(\002\244\001\239\005B\001\016\001\029\002\r\002\014\001^\002+\000\196\004U\001\203\0021\005\193\001\027\002F\000\193\001\t\005{\002K\002Q\001\239\001\024\001\016\001\029\002h\004a\003\205\002R\001@\001\252\005?\000\196\000\193\006\222\004d\001\219\001\t\001\226\000m\000\196\002`\003\188\001\016\001\029\002b\001\024\003\209\003\184\001\025\001\252\002\244\002e\000\193\002k\001\030\002\017\001#\002d\000\193\002q\000\196\001}\002g\005F\005G\005\185\004l\0017\002\163\000\196\006\152\001\239\001\027\000\196\001\030\003\196\000\196\006\224\005H\005X\000\196\001\031\002s\005P\004\001\001\t\002\007\002h\001\253\005?\005\217\001\016\001\029\000\193\001\030\003\202\001\191\004#\001\221\002b\001\252\001'\003\217\000\193\001A\001\223\003\234\002\244\001\253\001\227\002\017\001\016\002d\000\193\002e\001#\002k\004p\005\127\003\236\001\t\001)\002q\003\254\001}\002g\001\016\001\029\001\024\006\166\000\196\001\025\005F\005G\006Z\004\001\0017\000\196\002\n\004\003\001\024\004\"\002h\001\030\001\t\002s\002\024\005H\005X\001\228\001\016\001\029\005P\004\001\004(\001\027\004/\000\196\002'\001\253\002\r\002\014\001^\001\229\000\196\002*\0020\002<\000\196\002e\001'\002k\005?\001A\004x\002Q\0045\002q\001\030\001}\002g\000\196\0029\002R\001\191\000\196\001\247\002\244\004H\006O\004M\005F\005G\001\223\004X\0017\002`\001\227\001#\001\016\002s\000\196\001\030\000\196\002\244\003h\005H\005X\002\r\002\014\001^\005P\004\001\002\r\002\014\001^\000\196\000\189\000\196\004`\000\193\000\194\004c\002Q\002A\004j\004n\001\t\002Q\001'\004s\002R\001A\001\016\001\029\001\239\002R\001\228\000\196\001\t\004\127\006=\004\014\002@\002`\001\016\001\029\004\146\005\203\002`\000\196\001\229\000\196\002E\004\137\002b\000\196\002\r\002\014\001^\002J\004I\002\247\002p\001\252\002\167\002\017\000\193\002d\000\193\004\151\004\141\002Q\002\202\005F\005G\005\205\004\156\0017\002\209\002R\000\196\002\244\004\166\000\196\001\030\004\b\000\196\000\196\006\148\006\149\005\206\000\196\002`\005P\004\001\005\208\001\030\002h\002\238\005\219\002\244\000\196\002b\002\244\002\r\002\014\001^\002b\000\196\004\172\001\239\001'\003]\002\017\001A\002d\000\193\003e\002\017\002Q\002d\000\193\001\253\003\245\002e\002\244\002k\002R\001\191\004\183\002\029\000\196\002q\003\194\001}\002g\006D\001\223\000\196\001\252\002`\001\227\000\193\001\016\000\196\002h\003\154\004\198\004\195\003\164\002h\002b\003\186\004\216\004\202\002s\004\223\001\024\004\240\003\201\005\001\003\203\002\017\004\250\002d\000\193\005\019\004\228\002\244\002\244\004\233\000\196\002e\003\216\003\007\003\253\005(\002e\004\005\002k\002q\001\228\001}\002g\001\027\002q\002\244\001}\002g\004.\002\244\000\196\005\017\004'\002h\001\229\006\014\0052\001\253\002b\002\244\004)\004,\002s\002\r\002\014\001^\004;\002s\000\196\002\017\007\r\002d\000\193\007\014\000\196\000\196\006\017\000\196\002Q\000\196\002e\005>\002k\005R\000\196\006\018\002R\000\196\002q\005b\001}\002g\001\024\0041\005\025\005%\003\191\000\196\005h\002`\005l\002h\004:\005\136\002\r\002\014\001^\002\244\002\r\002\014\001^\002s\005-\002\244\006\019\001\t\005D\005\176\000\196\002Q\005\236\001\016\001\029\002Q\005\181\005\220\005u\002R\002e\002\244\002k\002R\005\186\003\177\0046\002\244\002q\003\129\001}\002g\002`\0049\004G\000\196\002`\000\196\000\189\004L\006\020\000\193\000\194\000\196\002\r\002\014\001^\001\191\006\021\003\207\002b\002s\000\196\005\216\000\196\004T\001\223\000\196\002\244\002Q\001\227\002\017\001\016\002d\000\193\001\030\005\152\002R\007\016\005\203\005\192\000\196\005\178\003|\000\196\002\244\004S\004W\000\196\000\196\002`\005\200\005\241\001\t\006\006\006C\000\196\006\023\005\189\001\016\001\029\002b\001'\002h\005\223\002b\006\024\005\205\004b\002\244\001\228\006\026\002\017\002\244\002d\000\193\002\017\002\244\002d\000\193\002\244\006\028\005\206\002\244\001\229\000\196\002\244\005\208\004m\006]\002e\005\237\003\007\004i\004r\005\235\002\244\006\029\002q\004\134\001}\002g\000\196\006i\002h\006w\001]\001^\002h\002b\002\244\001\030\005\239\000\196\000\196\004z\000\196\000\196\006y\002\244\002\017\002s\002d\000\193\004\133\002\244\001_\001o\004\128\001a\001b\002e\002\244\002k\004\132\002e\005\243\002k\003\251\002q\005\248\001}\002g\002q\006\004\001}\002g\006\011\002\244\003x\006\025\000\196\002h\006 \002\244\002\r\002\014\001^\004\145\002\r\002\014\001^\002s\006)\004\150\000\196\002s\000\196\004\249\001p\002Q\001q\002-\004\155\002Q\004\158\004\162\006n\002R\002e\000\196\002k\002R\004\170\003q\004\177\006\154\002q\003b\001}\002g\002`\006\168\004\188\004\248\002`\004\241\004\242\004\247\007\007\001x\002\r\002\014\001^\004\251\002\r\002\014\001^\004\252\005\027\002s\001g\005\020\005\021\000\193\007\018\002Q\005\026\005/\005+\002Q\007\023\003{\005,\002R\005.\005Y\005=\002R\000\189\003Z\005A\000\193\000\194\001\191\005C\004\022\002`\003R\005E\005Q\002`\005a\001\223\005c\005d\005i\001\227\005m\001\016\002b\001]\001^\005q\002b\005\131\005\138\005\142\005\166\005\187\005\203\002\017\005\211\002d\000\193\002\017\005\221\002d\000\193\006\r\001z\001_\001`\006\007\001a\001b\006\b\006\012\001{\006\027\001}\001e\006B\006M\006X\006l\006m\001\228\005\205\006q\006\153\006\157\006\167\002h\006\171\005\028\002b\002h\006\249\000\000\002b\001\229\000\000\005\206\002\r\002\014\001^\002\017\005\208\002d\000\193\002\017\006\000\002d\000\193\000\000\000\000\000\000\000\000\002Q\002e\000\000\002k\005\029\002e\005\030\002k\002R\002q\000\000\001}\002g\002q\002]\001}\002g\000\000\000\000\000\000\002h\002`\000\000\000\000\002h\000\000\001f\002\r\002\014\001^\000\000\000\000\002s\000\000\000\000\005\031\002s\001g\000\000\000\000\000\193\000\000\002Q\000\000\000\000\000\000\000\000\002e\000\000\002k\002R\002e\000\000\003\007\000\000\002q\002j\001}\002g\002q\000\000\001}\002g\002`\000\000\000\000\000\000\000\000\005 \002\r\002\014\001^\000\000\000\000\002\r\002\014\001^\005!\002s\005\"\002b\000\000\002s\000\000\002Q\000\000\001\191\000\000\004\026\002Q\000\000\002\017\002R\002d\000\193\001\223\001z\002R\002y\001\227\000\000\001\016\005\\\002x\001\150\002`\001}\001e\000\000\000\000\002`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\r\002\014\001^\002b\002h\000\000\005$\000\000\000\000\000\000\000\000\005&\0050\000\000\002\017\002Q\002d\000\193\000\000\000\000\001\228\005Z\000\000\002R\000\000\000\000\000\000\000\000\000\000\002\172\000\000\002e\000\000\002k\001\229\000\000\002`\005[\000\000\002q\000\000\001}\002g\000\000\000\000\002b\002h\000\000\000\000\000\000\002b\000\000\000\000\002\r\002\014\001^\002\017\000\000\002d\000\193\000\000\002\017\002s\002d\000\193\001\191\000\000\004\029\002Q\000\000\000\000\000\000\000\000\002e\001\223\002k\002R\000\000\001\227\000\000\001\016\002q\002\183\001}\002g\000\000\000\000\000\000\002h\002`\000\000\000\000\000\000\002h\000\000\002b\000\000\000\000\002\r\002\014\001^\001\191\000\000\004+\002s\000\000\002\017\000\000\002d\000\193\001\223\000\000\000\000\002Q\001\227\002e\001\016\002k\001\228\000\000\002e\002R\002k\002q\000\000\001}\002g\002\206\002q\000\000\001}\002g\001\229\000\000\002`\002\r\002\014\001^\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002s\000\000\002b\000\000\000\000\002s\000\000\000\000\001\228\000\000\000\000\000\000\003M\002\017\000\000\002d\000\193\001\024\000\000\002e\005\b\002k\001\229\002\r\002\014\001^\000\000\002q\000\000\001}\002g\000\000\000\000\000\000\000\000\000\000\003N\000\000\002Q\000\000\000\000\002\r\002\014\001^\001\027\002h\002R\002b\000\000\000\000\002s\000\000\002\213\001\191\000\000\004|\002Q\000\000\002\017\002`\002d\000\193\001\223\000\000\002R\000\000\001\227\000\000\001\016\000\000\002\216\000\000\002e\000\000\002k\006\014\000\000\002`\000\000\000\000\002q\000\000\001}\002g\002\016\002\r\002\014\001^\000\000\000\000\002h\000\000\000\000\006\015\000\000\002\017\006\017\002d\000\193\000\000\002Q\000\000\000\000\002s\000\000\006\018\001\228\000\000\002R\000\000\000\000\000\000\000\000\000\000\002\222\000\000\001\t\002e\002b\002k\001\229\002`\001\016\001\029\000\000\002q\000\000\001}\002g\002\017\003P\002d\000\193\000\000\006\019\000\000\002b\002\r\002\014\001^\000\000\000\000\001\191\000\000\004\130\000\000\000\000\002\017\002s\002d\000\193\001\223\002Q\000\000\002e\001\227\000\000\001\016\000\000\000\000\002R\002h\002f\000\000\001}\002g\002\225\000\000\006\020\000\000\000\000\000\000\000\000\002`\001\030\000\000\006\021\000\000\000\000\002h\002b\000\000\002\r\002\014\001^\000\000\000\000\000\000\002e\000\000\002k\002\017\000\000\002d\000\193\001\228\002q\002Q\001}\002g\006\022\001'\000\000\000\000\000\000\002R\002e\000\000\002k\001\229\000\000\002\250\000\000\000\000\002q\006\023\001}\002g\002`\002s\000\000\000\000\000\000\002h\006\024\000\000\002\r\002\014\001^\006\026\000\000\000\000\002b\002\r\002\014\001^\000\000\002s\000\000\006\028\000\000\002Q\000\000\002\017\000\000\002d\000\193\000\000\002Q\002R\002e\000\000\002k\000\000\000\000\006\029\002R\000\000\002q\003\004\001}\002g\002`\000\000\000\000\000\000\003\t\000\000\000\000\002`\000\000\002\r\002\014\001^\000\000\002h\000\000\002b\002\r\002\014\001^\002s\000\000\001\191\000\000\004\139\000\000\000\000\002\017\000\000\002d\000\193\001\223\002Q\003M\000\000\001\227\000\000\001\016\000\000\000\000\002R\002e\000\000\002k\000\000\000\000\000\000\000\000\000\000\002q\003\011\001}\002g\002`\000\000\000\000\000\000\005\207\000\000\002h\002b\000\000\000\000\000\000\000\000\000\000\000\000\002b\002\r\002\014\001^\002\017\002s\002d\000\193\001\228\000\000\000\000\002\017\000\000\002d\000\193\000\000\002Q\000\000\000\000\002e\000\000\002k\001\229\000\000\002R\000\000\000\000\002q\000\000\001}\002g\000\000\000\000\000\000\003\015\000\000\002h\002`\002\016\000\000\000\000\000\000\000\000\002h\000\000\002b\002\r\002\014\001^\002\017\002s\002d\000\193\002\r\002\014\001^\002\017\000\000\002d\000\193\000\000\002Q\000\000\002e\000\000\003\007\000\000\000\000\002Q\002R\002e\002q\003\007\001}\002g\000\000\002R\000\000\002q\003\023\001}\002g\002`\000\000\003P\000\000\003\029\000\000\002h\002`\000\000\000\000\000\000\000\000\002s\000\000\002b\002\r\002\014\001^\000\000\002s\000\000\000\000\000\000\000\000\000\000\002\017\002e\002d\000\193\000\000\002Q\000\000\000\000\002e\002f\003\007\001}\002g\002R\000\000\001\191\002q\004\147\001}\002g\000\000\000\000\000\000\003#\001\223\000\000\002`\000\000\001\227\000\000\001\016\000\000\002h\000\000\002b\002\r\002\014\001^\000\000\002s\000\000\002b\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\002Q\000\000\002\017\000\000\002d\000\193\000\000\000\000\002R\002e\000\000\003\007\000\000\000\000\003+\000\000\000\000\002q\001\228\001}\002g\002`\000\000\000\000\002\r\002\014\001^\002h\000\000\000\000\000\000\000\000\001\229\000\000\002h\002b\000\000\000\000\000\000\002Q\002s\000\000\000\000\000\000\000\000\000\000\002\017\002R\002d\000\193\000\000\000\000\000\000\0030\002e\000\000\003\007\000\000\000\000\000\000\002`\002e\002q\003\007\001}\002g\000\000\000\000\000\000\002q\000\000\001}\002g\001\191\000\000\006H\000\000\000\000\002h\000\000\002b\000\000\001\223\000\000\000\000\002s\001\227\000\000\001\016\000\000\000\000\002\017\002s\002d\000\193\002\r\002\014\001^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\000\000\003'\000\000\000\000\002Q\000\000\000\000\002q\000\000\001}\002g\000\000\002R\002b\002\r\002\014\001^\002h\000\000\000\000\001\228\000\000\003<\000\000\002\017\002`\002d\000\193\000\000\002Q\002s\000\000\000\000\000\000\001\229\000\000\000\000\002R\002\r\002\014\001^\000\000\000\000\000\000\002e\000\000\002k\003A\000\000\000\000\002`\000\000\002q\002Q\001}\002g\002h\000\000\000\000\000\000\000\000\002R\000\000\002\r\002\014\001^\000\000\000\000\000\000\000\000\000\000\003F\000\000\000\000\002`\002s\000\000\000\000\002Q\000\000\000\000\000\000\000\000\002e\002b\002k\002R\000\000\002\r\002\014\001^\002q\000\000\001}\002g\002\017\003U\002d\000\193\002`\000\000\000\000\000\000\002Q\000\000\000\000\000\000\000\000\000\000\002b\000\000\002R\000\000\000\000\002s\000\000\000\000\000\000\000\000\000\000\002\017\003X\002d\000\193\002`\000\000\000\000\002h\000\000\000\000\000\000\000\000\000\000\002b\002\r\002\014\001^\000\000\002\r\002\014\001^\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\002Q\000\000\000\000\002h\002Q\002e\000\000\003\007\002R\002b\000\000\000\000\002R\002q\003^\001}\002g\000\000\003`\000\000\002\017\002`\002d\000\193\000\000\002`\000\000\002h\000\000\000\000\002e\000\000\003\007\000\000\002b\000\000\002s\000\000\002q\000\000\001}\002g\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\000\000\000\000\002h\000\000\002e\000\000\003\007\000\000\000\000\000\000\000\000\002s\002q\000\000\001}\002g\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002h\000\000\002e\002b\003\007\000\000\000\000\002b\002s\000\000\002q\000\000\001}\002g\002\017\000\000\002d\000\193\002\017\000\000\002d\000\193\000\000\000\000\002\r\002\014\001^\002e\000\000\003'\000\000\000\000\000\000\002s\000\000\002q\000\000\001}\002g\002Q\002\r\002\014\001^\000\000\000\000\000\000\002h\002R\000\000\000\000\002h\000\000\000\000\003j\000\000\002Q\000\000\000\000\002s\000\000\002`\000\000\000\000\002R\000\000\000\000\002\r\002\014\001^\003s\000\000\000\000\000\000\002e\000\000\002k\002`\002e\000\000\002k\000\000\002q\000\000\001}\002g\002q\000\000\001}\002g\003\175\000\000\000\000\000\000\000\000\000\000\002\r\002\014\001^\000\000\000\000\002\r\002\014\001^\000\000\002s\000\000\000\000\000\000\002s\000\000\002Q\000\000\000\000\000\000\000\000\002Q\000\000\000\000\002R\002b\000\000\000\000\000\000\002R\003v\000\000\000\000\000\000\000\000\003\132\002\017\002`\002d\000\193\000\000\002b\002`\000\000\000\000\000\000\002\r\002\014\001^\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\000\000\000\000\000\000\000\000\002Q\000\000\000\000\000\000\000\000\000\000\002\016\002h\002R\000\000\000\000\000\000\000\000\000\000\003\135\000\000\000\000\002\017\000\000\002d\000\193\002`\000\000\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\002b\002k\000\000\000\000\000\000\002b\000\000\002q\000\000\001}\002g\002\017\000\000\002d\000\193\002e\002\017\002k\002d\000\193\000\000\000\000\000\000\002q\000\000\001}\002g\002\r\002\014\001^\002s\000\000\002\r\002\014\001^\000\000\000\000\000\000\000\000\000\000\000\000\002e\002Q\002h\000\000\002b\002s\002Q\002h\002f\002R\001}\002g\000\000\000\000\002R\002\017\000\000\002d\000\193\003\145\000\000\000\000\002`\000\000\003\150\000\000\000\000\002`\000\000\002e\000\000\002k\000\000\000\000\002e\000\000\002k\002q\000\000\001}\002g\000\000\002q\000\000\001}\002g\000\000\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002s\000\000\000\000\000\000\000\000\002s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\000\000\002k\000\000\000\000\000\000\006\014\002b\002q\000\000\001}\002g\002b\000\000\000\000\002\r\002\014\001^\002\017\000\000\002d\000\193\000\000\002\017\006\015\002d\000\193\006\017\000\000\000\000\002Q\002s\000\000\002\r\002\014\001^\006\018\000\000\002R\000\000\000\000\000\000\000\000\000\000\003\199\000\000\000\000\000\000\002Q\000\000\002h\002`\000\000\000\000\000\000\002h\002R\000\000\000\000\000\000\000\000\000\000\003\212\000\000\000\000\006\019\002\r\002\014\001^\002`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\000\000\003\007\000\000\002Q\002e\000\000\003\007\002q\000\000\001}\002g\002R\002q\000\000\001}\002g\000\000\004\000\000\000\000\000\000\000\006\020\000\000\000\000\002`\000\000\000\000\000\000\000\000\006\021\002s\000\000\002b\000\000\000\000\002s\000\000\002\r\002\014\001^\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\000\000\000\000\002b\000\000\002Q\006!\000\000\000\000\000\000\000\000\000\000\000\000\002R\002\017\000\000\002d\000\193\000\000\004C\000\000\006\023\000\000\000\000\000\000\000\000\002`\000\000\002h\000\000\006\024\000\000\000\000\000\000\000\000\006\026\002b\000\000\000\000\000\000\000\000\002\r\002\014\001^\000\000\006\028\002h\002\017\000\000\002d\000\193\000\000\000\000\000\000\000\000\002e\002Q\002k\000\000\000\000\000\000\006\029\000\000\002q\002R\001}\002g\001]\001^\000\000\005p\000\000\000\000\002e\000\000\002k\000\000\002`\000\000\002h\000\000\002q\000\000\001}\002g\002b\002s\001_\001o\000\000\001a\001b\000\000\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\000\000\000\000\000\000\002s\000\000\002e\000\000\002k\000\000\004\016\000\000\000\000\000\000\002q\000\000\001}\002g\000\000\000\000\000\000\001\024\000\000\000\000\005\005\000\000\000\000\000\000\002h\000\000\001p\000\000\001q\002-\000\000\000\000\002b\002s\000\000\000\000\000\000\002\r\002\014\001^\000\000\000\000\000\000\002\017\001\027\002d\000\193\000\000\000\000\000\000\000\000\002e\002Q\002k\002\r\002\014\001^\001x\000\000\002q\002R\001}\002g\000\000\000\000\000\000\005s\000\000\001g\002Q\000\000\000\193\000\000\002`\000\000\002h\000\000\002R\000\000\003{\000\000\000\000\002s\005\130\000\000\000\000\000\000\005\007\000\000\000\000\002`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\000\000\002k\000\000\000\000\000\000\000\000\000\000\002q\000\000\001}\002g\000\000\000\000\001\t\000\000\000\000\000\000\000\000\000\000\001\016\005\n\000\000\000\000\000\000\001z\000\000\002\r\002\014\001^\002b\002s\000\000\001{\000\000\001}\001e\000\000\000\000\000\000\000\000\002\017\002Q\002d\000\193\000\000\000\000\002b\000\000\000\000\002R\002\r\002\014\001^\000\000\000\000\005\133\000\000\002\017\000\000\002d\000\193\000\000\002`\000\000\000\000\002Q\000\000\002\r\002\014\001^\000\000\005\011\002h\002R\000\000\000\000\000\000\000\000\000\000\005\146\000\000\001\024\002Q\004\213\001\025\005\016\002`\005\r\000\000\002h\002R\000\000\000\000\000\000\000\000\000\000\005\149\000\000\001'\002e\000\000\002k\000\000\002`\000\000\000\000\000\000\002q\001\027\001}\002g\000\000\000\000\000\000\000\000\000\000\002e\000\000\002k\000\000\000\000\002b\000\000\000\000\002q\000\000\001}\002g\000\000\000\000\002s\000\000\002\017\000\000\002d\000\193\000\000\000\000\000\000\000\000\000\000\000\000\002\r\002\014\001^\002b\000\000\002s\000\000\000\000\000\000\001#\000\000\000\000\000\000\000\000\002\017\002Q\002d\000\193\000\000\000\000\002b\000\000\002h\002R\000\000\002\r\002\014\001^\000\000\005\170\000\000\002\017\000\000\002d\000\193\000\000\002`\000\000\001\t\000\000\002Q\002\r\002\014\001^\001\016\001\029\002h\000\000\002R\002e\000\000\002k\000\000\000\000\005\173\000\000\002Q\002q\000\000\001}\002g\002`\000\000\002h\002R\000\000\000\000\000\000\000\000\000\000\005\177\000\000\000\000\002e\000\000\002k\000\000\002`\000\000\000\000\002s\002q\000\000\001}\002g\000\000\000\000\000\000\000\000\0017\002e\000\000\002k\000\000\006\014\002b\001\030\000\000\002q\000\000\001}\002g\000\000\000\000\002s\000\000\002\017\000\000\002d\000\193\000\000\000\000\006\015\000\000\000\000\006\017\000\000\000\000\000\000\000\000\002b\002s\000\000\001'\006\018\000\000\0018\000\000\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\002b\000\000\002h\000\000\000\000\002\r\002\014\001^\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\000\000\006\019\000\000\000\000\002Q\000\000\000\000\000\000\001]\001^\000\000\002h\002R\002e\000\000\002k\000\000\000\000\006\184\000\000\000\000\002q\000\000\001}\002g\002`\000\000\002h\001_\001o\000\000\001a\001b\000\000\000\000\006\020\000\000\000\000\002e\000\000\002k\000\000\000\000\006\021\002s\000\000\002q\000\000\001}\002g\000\000\006R\000\000\000\000\002e\000\000\002k\000\000\000\000\000\000\000\000\000\000\002q\000\000\001}\002g\000\000\006*\000\000\002s\000\000\001p\000\000\001q\002-\000\000\000\000\000\000\002\r\002\014\001^\000\000\006\023\000\000\002b\002s\000\000\000\000\000\000\000\000\000\000\006\024\000\000\002Q\000\000\002\017\006\026\002d\000\193\000\000\000\000\002R\001x\002\r\002\014\001^\006\028\006\186\000\000\000\000\000\000\000\000\000\000\001g\002`\000\000\000\193\000\000\002Q\002\r\002\014\001^\006\029\000\000\003{\000\000\002R\002h\000\000\001]\001^\000\000\000\000\000\000\002Q\000\000\000\000\000\000\000\000\002`\000\000\000\000\002R\001\024\000\000\000\000\005\005\000\000\000\000\001_\001o\000\000\001a\001b\002e\002`\002k\000\000\000\000\001\159\000\000\000\000\002q\000\000\001}\002g\000\000\000\000\000\000\000\000\001\027\000\000\001z\002b\000\000\000\000\000\000\000\000\000\000\000\000\001{\000\000\001}\001e\002\017\002s\002d\000\193\000\000\000\000\000\000\000\000\001p\000\000\001q\001\146\000\000\000\000\002b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002d\000\193\005\007\002b\000\000\002h\000\000\000\000\000\000\000\000\000\000\000\000\001x\000\000\002\017\000\000\002d\000\193\000\000\000\000\000\000\000\000\000\000\001g\000\000\000\000\000\193\000\000\000\000\000\000\002h\001\t\002e\000\000\002k\000\000\000\000\001\016\005\n\000\000\002q\000\000\001}\002g\000\000\000\000\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\000\000\004\017\000\000\000\000\000\000\002s\000\000\002q\000\000\001}\002g\000\000\000\000\000\000\000\000\002e\000\000\004\r\001]\001^\000\000\000\000\000\000\002q\001z\001}\002g\000\000\000\000\000\000\002s\005\011\001{\000\000\001}\001e\001]\001^\001_\001o\000\000\001a\001b\004\213\000\000\005\015\002s\005\r\001\143\000\000\002\r\002\014\001^\000\000\000\000\000\000\001_\001o\001'\001a\001b\000\000\000\000\000\000\000\000\002Q\001\148\000\000\001]\001^\000\000\000\000\000\000\002R\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001p\000\000\001q\001\146\000\000\002`\000\000\001_\001o\000\000\001a\001b\000\000\000\000\000\000\002\r\002\014\001^\001p\000\000\001q\001\146\000\000\001]\001^\000\000\000\000\000\000\000\000\000\000\002Q\001x\000\000\000\000\000\000\000\000\000\000\000\000\002R\000\000\000\000\000\000\001g\001_\001o\000\193\001a\001b\000\000\001x\001p\002`\001q\002-\000\000\000\000\000\000\000\000\000\000\000\000\001g\000\000\000\000\000\193\002b\000\000\000\000\000\000\002\r\002\014\001^\000\000\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\000\000\001x\000\000\002Q\000\000\000\000\001p\000\000\001q\0025\000\000\002R\001g\000\000\000\000\000\193\000\000\000\000\000\000\000\000\000\000\001z\000\000\003w\002`\000\000\000\000\002h\000\000\001{\002b\001}\001e\000\000\000\000\000\000\000\000\001x\000\000\001z\000\000\002\017\000\000\002d\000\193\000\000\000\000\001{\001g\001}\001e\000\193\000\000\000\000\002e\000\000\003\183\000\000\000\000\000\000\000\000\000\000\002q\000\000\001}\002g\000\000\000\000\000\000\000\000\000\000\001z\000\000\002h\000\000\000\000\000\000\000\000\0028\001{\000\000\001}\001e\002b\000\000\002s\002\r\002\014\001^\000\000\000\000\002\r\002\014\001^\002\017\000\000\002d\000\193\000\000\000\000\002e\002Q\003Q\000\000\000\000\000\000\002Q\001z\002q\002R\001}\002g\000\000\000\000\002R\001{\000\000\001}\001e\000\000\000\000\000\000\002`\000\000\000\000\000\000\002h\002`\000\000\000\000\000\000\002s\000\000\002\r\002\014\001^\000\000\002\r\002\014\001^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002Q\000\000\000\000\000\000\002Q\002e\000\000\002\248\002R\000\000\000\000\000\000\002R\002q\000\000\001}\002g\000\000\000\000\000\000\000\000\002`\000\000\000\000\000\000\002`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002b\000\000\000\000\002s\000\000\002b\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\002\017\000\000\002d\000\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\r\002\014\001^\000\000\002\r\002\014\001^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002Q\002h\000\000\000\000\002Q\002b\002h\000\000\002R\002b\000\000\000\000\002R\000\000\000\000\000\000\002\017\000\000\002d\000\193\002\017\002`\002d\000\193\000\000\002`\000\000\000\000\002e\000\000\002m\000\000\000\000\002e\000\000\002o\002q\000\000\001}\002g\000\000\002q\000\000\001}\002g\000\000\000\000\000\000\002h\000\000\000\000\000\000\002h\000\000\000\000\000\000\000\000\000\000\000\000\002s\000\000\000\000\000\000\000\000\002s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\000\000\002t\000\000\002e\002b\002{\000\000\002q\002b\001}\002g\002q\000\000\001}\002g\002\017\000\000\002d\000\193\002\017\000\000\002d\000\193\002\r\002\014\001^\000\000\002\r\002\014\001^\002s\000\000\000\000\000\000\002s\000\000\000\000\000\000\002Q\002\r\002\014\001^\002Q\000\000\000\000\000\000\002R\002h\000\000\000\000\002R\002h\000\000\000\000\002Q\000\000\000\000\000\000\000\000\002`\000\000\000\000\002R\002`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\002`\002}\000\000\002e\000\000\002\127\000\000\002q\000\000\001}\002g\002q\000\000\001}\002g\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\r\002\014\001^\002s\000\000\000\000\000\000\002s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002Q\002b\000\000\000\000\000\000\002b\000\000\000\000\002R\000\000\000\000\000\000\002\017\000\000\002d\000\193\002\017\002b\002d\000\193\000\000\002`\000\000\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002d\000\193\002\r\002\014\001^\000\000\002\r\002\014\001^\000\000\000\000\000\000\000\000\000\000\002h\000\000\000\000\002Q\002h\000\000\000\000\002Q\000\000\000\000\000\000\002R\000\000\000\000\000\000\002R\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002`\000\000\000\000\002e\002`\002\129\000\000\002e\000\000\002\131\000\000\002q\002b\001}\002g\002q\000\000\001}\002g\002e\000\000\002\133\000\000\002\017\000\000\002d\000\193\002q\000\000\001}\002g\000\000\000\000\000\000\002s\000\000\000\000\000\000\002s\002\r\002\014\001^\000\000\002\r\002\014\001^\000\000\000\000\000\000\000\000\002s\000\000\000\000\000\000\002Q\002h\000\000\000\000\002Q\002b\000\000\000\000\002R\002b\000\000\000\000\002R\000\000\000\000\000\000\002\017\000\000\002d\000\193\002\017\002`\002d\000\193\000\000\002`\000\000\000\000\002e\000\000\002\135\002\r\002\014\001^\000\000\000\000\002q\000\000\001}\002g\000\000\000\000\001\024\000\000\000\000\001\025\002Q\000\000\002h\000\000\000\000\000\000\002h\000\000\002R\000\000\000\000\000\000\000\000\002s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002`\000\000\001\027\000\000\006\133\000\000\000\000\000\000\002e\000\000\002\137\000\000\002e\002b\002\139\000\000\002q\002b\001}\002g\002q\000\000\001}\002g\002\017\000\000\002d\000\193\002\017\000\000\002d\000\193\000\000\000\000\000\000\002\r\002\014\001^\000\000\002s\002\r\002\014\001^\002s\000\000\001#\000\000\000\000\000\000\000\000\002Q\000\000\000\000\000\000\000\000\002Q\002h\000\000\002R\002b\002h\000\000\000\000\002R\000\000\000\000\000\000\000\000\000\000\000\000\002\017\002`\002d\000\193\001\t\000\000\002`\000\000\000\000\000\000\001\016\001\029\000\000\002e\000\000\002\141\000\000\002e\000\000\002\143\000\000\002q\000\000\001}\002g\002q\000\000\001}\002g\000\000\000\000\000\000\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\r\002\014\001^\002s\000\000\000\000\000\000\002s\000\000\000\000\000\000\000\000\000\000\000\000\0017\002Q\000\000\000\000\002e\002b\002\145\001\030\000\000\002R\002b\006\140\002q\000\000\001}\002g\002\017\000\000\002d\000\193\000\000\002\017\002`\002d\000\193\000\000\002\r\002\014\001^\000\000\000\000\002\r\002\014\001^\001'\002s\000\000\001A\000\000\000\000\000\000\002Q\000\000\000\000\000\000\000\000\002Q\000\000\002h\002R\000\000\000\000\000\000\002h\002R\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002`\000\000\000\000\000\000\000\000\002`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\000\000\002\147\000\000\000\000\002e\002b\002\149\002q\000\000\001}\002g\000\000\002q\000\000\001}\002g\002\017\000\000\002d\000\193\000\000\000\000\000\000\000\000\000\000\000\000\002\r\002\014\001^\000\000\002s\000\000\000\000\000\000\000\000\002s\000\000\000\000\000\000\000\000\000\000\002Q\000\000\000\000\000\000\002b\000\000\000\000\002h\002R\002b\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\002\017\002`\002d\000\193\000\000\002\r\002\014\001^\000\000\000\000\000\000\000\000\000\000\000\000\002e\000\000\002\151\000\000\000\000\000\000\002Q\000\000\002q\000\000\001}\002g\000\000\002h\002R\000\000\000\000\000\000\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002`\000\000\000\000\000\000\002s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\000\000\002\153\000\000\000\000\002e\002b\002\155\002q\000\000\001}\002g\000\000\002q\000\000\001}\002g\002\017\000\000\002d\000\193\000\000\002\r\002\014\001^\000\000\000\000\000\000\000\000\000\000\000\000\002s\000\000\000\000\000\000\000\000\002s\002Q\000\000\000\000\000\000\002\164\001^\000\000\000\000\002R\002b\000\000\000\000\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\002`\002d\000\193\002\218\001o\000\000\001a\001b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001]\001^\000\000\002e\000\000\002\157\000\000\000\000\000\000\002\181\000\000\002q\000\000\001}\002g\000\000\002h\002\184\001]\001^\001_\002\185\000\000\001a\001b\000\000\000\000\002\181\000\000\000\000\002\223\002\239\002\240\000\000\002s\002\184\000\000\000\000\001_\002\185\000\000\001a\001b\002e\002b\002\159\002\r\002\014\001^\000\000\000\000\002q\000\000\001}\002g\002\017\000\000\002d\000\193\000\000\006\014\002Q\001x\000\000\000\000\000\000\000\000\000\000\000\000\002R\000\000\000\000\000\000\001g\002s\007\r\000\193\000\000\007\014\000\000\000\000\006\017\002`\000\000\000\000\000\000\000\000\002h\000\000\000\000\006\018\000\000\000\000\000\000\001f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001g\002\243\000\000\000\193\000\000\000\000\000\000\001f\000\000\002e\000\000\002\161\000\000\000\000\006\019\000\000\000\000\002q\001g\001}\002g\000\193\000\000\000\000\000\000\000\000\000\000\001z\000\000\000\000\002\r\002\014\001^\000\000\002\186\001{\002b\001}\001e\000\000\002s\001\024\000\000\000\000\005\005\002Q\000\000\002\017\006\020\002d\000\193\000\000\002\186\002R\002\188\000\000\006\021\000\000\000\000\001z\000\000\000\000\000\000\002\r\002\014\001^\002`\001\150\001\027\001}\001e\000\000\002\187\000\000\000\000\000\000\007\015\001z\002Q\002h\000\000\000\000\002\r\002\014\001^\001\150\002R\001}\001e\000\000\000\000\000\000\000\000\000\000\000\000\006\023\000\000\002Q\000\000\002`\000\000\000\000\000\000\000\000\006\024\002R\002e\000\000\002\254\006\026\000\000\005\007\000\000\000\000\002q\000\000\001}\002g\002`\006\028\000\000\000\000\000\000\000\000\000\000\002b\002\r\002\014\001^\000\000\000\000\000\000\000\000\000\000\000\000\006\029\002\017\002s\002d\000\193\001\t\002Q\002\r\002\014\001^\000\000\001\016\005\n\000\000\002R\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002Q\002b\000\000\000\000\000\000\002`\000\000\000\000\002R\000\000\000\000\002h\002\017\000\000\002d\000\193\000\000\000\000\000\000\000\000\002b\002`\000\000\000\000\002\r\002\014\001^\000\000\000\000\000\000\000\000\002\017\000\000\002d\000\193\000\000\000\000\000\000\002e\002Q\003\027\005\011\000\000\000\000\002h\000\000\002q\002R\001}\002g\000\000\000\000\000\000\004\213\000\000\005\014\000\000\005\r\000\000\000\000\002`\000\000\000\000\002h\002b\000\000\000\000\000\000\001'\002s\000\000\002e\000\000\003!\000\000\002\017\005\028\002d\000\193\002q\002b\001}\002g\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\002\017\003&\002d\000\193\002\r\002\014\001^\002q\000\000\001}\002g\002s\000\000\005\029\006\192\005\030\002h\000\000\000\000\002Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002R\002b\000\000\002s\000\000\002h\000\000\000\000\000\000\000\000\000\000\000\000\002\017\002`\002d\000\193\002e\005\031\003.\000\000\000\000\000\000\000\000\000\000\002q\000\000\001}\002g\000\000\000\000\000\000\000\000\002e\000\000\0033\000\000\000\000\000\000\000\000\000\000\002q\000\000\001}\002g\002h\000\000\000\000\002s\000\000\000\000\005 \002\r\002\014\001^\000\000\000\000\000\000\000\000\000\000\005!\000\000\005\"\000\000\002s\000\000\000\000\002Q\000\000\000\000\000\000\000\000\002e\002b\0035\002R\002\r\002\014\001^\000\000\002q\000\000\001}\002g\002\017\005^\002d\000\193\002`\000\000\000\000\002Q\002\r\002\014\001^\000\000\000\000\001\024\000\000\002R\001\025\000\000\000\000\002s\002\r\002\014\001^\002Q\005$\006\194\001]\001^\002`\005&\0050\002R\002h\000\000\000\000\002Q\000\000\000\000\000\000\005Z\001\027\000\000\000\000\002R\002`\000\000\001_\001o\000\000\001a\001b\000\000\000\000\000\000\000\000\005[\002`\000\000\000\000\002e\000\000\0038\000\000\002b\000\000\000\000\000\000\002q\000\000\001}\002g\002\r\002\014\001^\002\017\000\000\002d\000\193\000\000\000\000\000\000\006\014\000\000\001#\000\000\000\000\002Q\002b\000\000\001p\002s\001q\002-\000\000\002R\000\000\007\r\000\000\002\017\007\014\002d\000\193\006\017\002b\000\000\000\000\002h\002`\000\000\000\000\000\000\006\018\001\t\000\000\002\017\002b\002d\000\193\001\016\001\029\001x\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002d\000\193\002h\001g\000\000\002e\000\193\003?\000\000\000\000\000\000\000\000\006\019\002q\003z\001}\002g\000\000\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002e\002h\003D\000\000\000\000\000\000\006\132\002s\002q\002b\001}\002g\000\000\001\030\000\000\000\000\002e\006\020\003I\000\000\002\017\000\000\002d\000\193\002q\006\021\001}\002g\002e\000\000\003L\002s\000\000\001z\002\164\001^\002q\000\000\001}\002g\001'\001{\000\000\001}\001e\007\019\000\000\002s\002\r\002\014\001^\000\000\002h\000\000\002\218\001o\000\000\001a\001b\002s\000\000\000\000\000\000\002Q\006\023\000\000\000\000\000\000\000\000\000\000\000\000\002R\000\000\006\024\000\000\000\000\000\000\000\000\006\026\002e\000\000\003~\002\164\001^\002`\000\000\000\000\002q\006\028\001}\002g\000\000\000\000\000\000\000\000\000\000\002\223\002\239\002\240\002\164\001^\000\000\002\218\001o\006\029\001a\001b\000\000\000\000\000\000\002s\002\164\001^\000\000\000\000\000\000\000\000\001]\001^\002\218\001o\000\000\001a\001b\000\000\000\000\000\000\000\000\001x\000\000\000\000\002\218\001o\000\000\001a\001b\000\000\001_\001o\001g\001a\001b\000\193\002b\002\223\002\239\002\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002d\000\193\002\r\002\014\001^\002\223\002\239\002\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\137\002\223\002\239\002\240\001x\000\000\000\000\000\000\001p\002\015\001q\006\238\000\000\006\240\002h\001g\000\000\000\000\000\193\000\000\000\000\001x\000\000\000\000\000\000\000\000\001z\000\000\000\000\000\000\000\000\000\000\001g\001x\001{\000\193\001}\001e\000\000\001x\000\000\002e\000\000\003\128\001g\000\000\000\000\000\193\004\006\002q\001g\001}\002g\000\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\188\001]\001^\000\000\000\000\000\000\000\000\002s\000\000\001z\000\000\000\000\005\222\000\000\000\000\000\000\002\016\001{\000\000\001}\001e\001_\001o\000\000\001a\001b\001z\002\017\000\000\002d\000\193\000\000\000\000\000\000\001{\000\000\001}\001e\001z\000\000\000\000\000\000\000\000\000\000\001z\000\000\001{\001\024\001}\001e\001\025\000\000\001{\001+\001}\001e\001\024\000\000\000\000\001\025\000\000\000\000\001+\000\000\001p\000\000\001q\0063\000\000\000\000\000\000\000\000\000\000\001,\001\027\000\000\000\000\000\000\000\000\000\000\001-\000\000\001,\001\027\001]\001^\002e\000\000\000\000\001F\000\000\001]\001^\000\000\002f\001x\001}\002g\000\000\000\000\000\000\000\000\000\000\000\000\001_\001o\001g\001a\001b\000\193\000\000\001_\001o\000\000\001a\001b\000\000\001#\001]\001^\000\000\000\000\000\000\000\000\000\000\000\000\001#\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0011\000\000\000\000\000\000\001_\001o\000\000\001a\001b\0011\000\000\000\000\001\t\001p\000\000\001q\001\151\000\000\001\016\001\029\001p\001\t\001q\001\129\000\000\000\000\000\000\001\016\001\029\000\000\000\000\001z\000\000\001]\001^\000\000\000\000\000\000\000\000\001{\000\000\001}\001e\000\000\001x\000\000\000\000\001p\000\000\001q\001~\001x\000\000\001_\001o\001g\001a\001b\000\193\000\000\000\000\000\000\001g\0017\000\000\000\193\000\000\000\000\000\000\000\000\001\030\000\000\0017\000\000\001?\000\000\000\000\000\000\001x\001\030\000\000\001]\001^\001?\000\000\000\000\000\000\001]\001^\001g\000\000\000\000\000\193\000\000\000\000\000\000\001p\001'\001q\001s\001A\001_\001o\000\000\001a\001b\001'\001_\001o\001A\001a\001b\000\000\000\000\001z\000\000\000\000\000\000\000\000\001]\001^\001z\001{\000\000\001}\001e\000\000\001x\000\000\001{\000\000\001}\001e\000\000\000\000\000\000\000\000\000\000\001g\001_\001o\000\193\001a\001b\001p\000\000\001q\001v\001z\000\000\001p\000\000\001q\001y\000\000\000\000\001{\000\000\001}\001e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001]\001^\000\000\000\000\000\000\001x\000\000\000\000\000\000\000\000\000\000\001x\001p\000\000\001q\001|\001g\000\000\000\000\000\193\001_\001o\001g\001a\001b\000\193\000\000\001z\000\000\000\000\000\000\000\000\001]\001^\000\000\001{\000\000\001}\001e\000\000\000\000\000\000\000\000\001x\000\000\000\000\000\000\000\000\000\000\001]\001^\000\000\001_\001o\001g\001a\001b\000\193\000\000\000\000\000\000\000\000\000\000\001p\000\000\001q\001\134\000\000\000\000\001_\001o\000\000\001a\001b\000\000\001z\000\000\000\000\000\000\001]\001^\001z\000\000\001{\000\000\001}\001e\000\000\002\214\001{\000\000\001}\001e\000\000\001x\001p\002\217\001q\001\137\001_\002\185\000\000\001a\001b\000\000\001g\000\000\000\000\000\193\000\000\000\000\000\000\001p\001z\001q\002G\000\000\000\000\000\000\000\000\000\000\001{\000\000\001}\001e\000\000\001x\000\000\001]\001^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001g\000\000\000\000\000\193\000\000\000\000\001x\000\000\000\000\000\000\000\000\001_\001o\000\000\001a\001b\000\000\001g\000\000\000\000\000\193\000\000\000\000\000\000\000\000\001]\001^\001z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001{\001f\001}\001e\000\000\000\000\000\000\001]\001^\000\000\001_\001o\001g\001a\001b\000\193\000\000\000\000\000\000\001p\000\000\001q\002\228\000\000\001z\000\000\000\000\001_\001o\000\000\001a\001b\001{\000\000\001}\001e\000\000\000\000\000\000\001]\001^\001z\000\000\000\000\000\000\000\000\002\186\000\000\000\000\001{\001x\001}\001e\001p\000\000\001q\002\231\000\000\000\000\001_\001o\001g\001a\001b\000\193\000\000\002\r\002\014\001^\000\000\001p\001z\001q\002\234\000\000\000\000\000\000\000\000\000\000\001\150\000\000\001}\001e\000\000\001x\000\000\001]\001^\000\000\002L\001\024\000\000\000\000\001\025\000\000\001g\001B\000\000\000\193\000\000\000\000\001x\001p\000\000\001q\002\242\001_\001o\000\000\001a\001b\000\000\001g\000\000\000\000\000\193\001D\001\027\000\000\000\000\001z\000\000\004\206\000\000\000\000\000\000\000\000\000\000\001{\001\024\001}\001e\001\025\001x\000\000\001B\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001g\000\000\000\000\000\193\000\000\001p\000\000\001q\004A\000\000\001z\001D\001\027\000\000\000\000\000\000\001#\002\016\001{\000\000\001}\001e\000\000\000\000\000\000\000\000\000\000\001z\002\017\000\000\002d\000\193\000\000\0011\000\000\001{\001x\001}\001e\000\000\000\000\000\000\001]\001^\000\000\001\t\000\000\001g\000\000\000\000\000\193\001\016\001\029\000\000\001\024\001#\000\000\001\025\000\000\001z\001+\000\000\001_\002\185\000\000\001a\001b\001{\000\000\001}\001e\000\000\0011\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0010\001\027\000\000\000\000\001\t\000\000\000\000\002e\001]\001^\001\016\001\029\000\000\000\000\000\000\002f\0017\001}\002g\000\000\000\000\000\000\000\000\001\030\000\000\000\000\001z\005\004\001_\002\185\000\000\001a\001b\000\000\001{\000\000\001}\001e\000\000\000\000\000\000\000\000\000\000\000\000\001#\000\000\000\000\000\000\001]\001^\001'\000\000\000\000\001A\000\000\0017\001f\000\000\000\000\000\000\000\000\0011\001\030\001]\001^\000\000\001?\001g\001_\002\185\000\193\001a\001b\001\t\000\000\000\000\001]\001^\000\000\001\016\001\029\000\000\000\000\001_\002\185\000\000\001a\001b\000\000\001'\000\000\000\000\001A\005\150\000\000\000\000\001_\002\185\000\000\001a\001b\003k\001f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001g\000\000\000\000\000\193\000\000\000\000\000\000\003m\000\000\000\000\000\000\0017\000\000\001z\000\000\000\000\000\000\000\000\001\030\000\000\000\000\001\150\001?\001}\001e\000\000\000\000\000\000\000\000\001f\000\000\000\000\000\000\000\000\003k\000\000\000\000\000\000\000\000\000\000\001g\000\000\000\000\000\193\001f\001'\000\000\000\000\001A\000\000\000\000\000\000\000\000\003l\000\000\001g\000\000\001f\000\193\001z\001]\001^\000\000\000\000\000\000\000\000\000\000\001\150\001g\001}\001e\000\193\000\000\000\000\003k\000\000\000\000\005\174\000\000\000\000\001_\002\185\000\000\001a\001b\000\000\000\000\000\000\000\000\006\001\000\000\000\000\000\000\003p\000\000\000\000\000\000\001]\001^\001z\000\000\000\000\002\186\000\000\000\000\000\000\000\000\001\150\000\000\001}\001e\000\000\000\000\000\000\001z\000\000\000\000\001_\002\185\000\000\001a\001b\001\150\000\000\001}\001e\000\000\001z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\150\006\003\001}\001e\001]\001^\000\000\000\000\000\000\000\000\000\000\001]\001^\000\000\000\000\000\000\001]\001^\000\000\001f\000\000\000\000\000\000\000\000\001_\002\185\000\000\001a\001b\000\000\001g\001_\002\185\000\193\001a\001b\001_\002\185\000\000\001a\001b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001]\001^\001f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\186\000\000\005\028\001g\000\000\000\000\000\193\000\000\000\000\000\000\001_\002\185\000\000\001a\001b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\000\000\000\000\000\000\000\000\005\029\006\174\005\030\001\150\001f\001}\001e\005\201\000\000\000\000\001\024\001f\000\000\001\025\000\000\001g\001f\000\000\000\193\000\000\000\000\000\000\001g\000\000\000\000\000\193\000\000\001g\000\000\000\000\000\193\005\031\001z\000\000\000\000\000\000\000\000\001\027\000\000\000\000\001\150\000\000\001}\001e\000\000\000\000\000\000\004\191\000\000\005\201\000\000\000\000\000\000\005\214\001f\000\000\006\001\000\000\000\000\000\000\000\000\006\001\005\147\001\024\005 \001g\001\025\000\000\000\193\000\000\000\000\000\000\000\000\005!\001z\005\"\000\000\000\000\000\000\000\000\001#\001z\001\150\000\000\001}\001e\001z\000\000\000\000\001\150\001\027\001}\001e\000\000\001\150\005\213\001}\001e\005^\003o\003\230\000\000\001\024\006\002\001\024\001\025\000\000\001\025\006\n\001\t\000\000\000\000\000\000\000\000\006v\001\016\001\029\000\000\000\000\000\000\000\000\005$\000\000\000\000\001z\000\000\005&\0050\006\014\001\027\000\000\001\027\001\150\001#\001}\001e\005Z\000\000\000\000\004\191\000\000\004\191\000\000\007\r\000\000\000\000\007\014\000\000\000\000\006\017\000\000\000\000\005[\000\000\005\161\000\000\005\171\000\000\006\018\000\000\0017\000\000\001\t\000\000\000\000\000\000\000\000\001\030\001\016\001\029\000\000\004\196\001#\000\000\001#\001]\001^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\019\000\000\002\r\002\014\001^\000\000\000\000\001'\001_\002\170\001A\001a\001b\000\000\001\t\000\000\001\t\000\000\000\000\000\000\001\016\001\029\001\016\001\029\001\024\003M\0017\001\025\000\000\000\000\000\000\000\000\000\000\001\030\006\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\021\001\024\000\000\000\000\001\025\000\000\000\000\000\000\000\000\001\027\001\024\000\000\000\000\001\025\000\000\000\000\000\000\000\000\001'\002\207\007\024\003\237\000\000\0017\000\000\0017\000\000\000\000\001\027\000\000\001\030\000\000\001\030\000\000\004\196\000\000\004\196\001\027\000\000\006\023\001f\000\000\000\000\000\000\000\000\000\000\005\028\003\230\006\024\000\000\000\000\001g\001#\006\026\000\193\002\016\000\000\001'\000\000\001'\001A\003\233\001A\006\028\000\000\000\000\002\017\000\000\002d\000\193\000\000\001#\001\024\000\000\005\029\001\025\005\030\000\000\000\000\006\029\001#\001\t\000\000\000\000\000\000\000\000\000\000\001\016\001\029\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\027\001\t\003O\000\000\000\000\005\196\005\031\001\016\001\029\000\000\001\t\001z\000\000\000\000\000\000\001\024\001\016\001\029\001\025\001\150\000\000\001}\001e\000\000\000\000\000\000\002e\001\024\000\000\000\000\001\025\000\000\000\000\0017\002f\000\000\001}\002g\000\000\005 \001\030\000\000\001\027\001#\002\178\000\000\000\000\000\000\005!\000\000\005\"\000\000\0017\000\000\001\027\000\000\000\000\000\000\000\000\001\030\000\000\0017\000\000\004\224\000\000\000\000\004\227\001'\001\030\006\014\001A\000\000\001\t\005#\000\000\000\000\000\000\000\000\001\016\001\029\000\000\001\024\000\000\000\000\001\025\001#\001'\007\004\000\000\001A\006\017\001\024\000\000\006\218\001\025\001'\005$\001#\003\237\006\018\000\000\005&\0050\000\000\000\000\000\000\000\000\000\000\001\027\000\000\000\000\005Z\000\000\000\000\001\t\000\000\000\000\000\000\001\027\000\000\001\016\001\029\001\024\0017\000\000\001\025\001\t\005[\006\019\000\000\001\030\000\000\001\016\001\029\004\211\000\000\000\000\000\000\000\000\000\000\001\024\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\001\027\000\000\001#\000\000\000\000\000\000\001\024\000\000\001'\001\025\000\000\001A\001#\006\020\000\000\000\000\0017\000\000\001\027\000\000\000\000\006\021\000\000\001\030\000\000\000\000\0015\004\224\0017\000\000\005\242\001\t\000\000\001\027\000\000\001\030\000\000\001\016\001\029\006\219\000\000\001\t\007\005\001#\000\000\000\000\000\000\001\016\001\029\000\000\001'\000\000\000\000\001A\000\000\000\000\000\000\000\000\000\000\000\000\006\023\001#\001'\000\000\000\000\001A\000\000\001\024\000\000\006\024\001\025\000\000\001\t\000\000\006\026\000\000\001#\001\024\001\016\001\029\001\025\000\000\0017\000\000\006\028\000\000\000\000\000\000\000\000\001\030\001\t\000\000\0017\006\179\001\027\001\024\001\016\001\029\001\025\001\030\006\029\000\000\000\000\001Q\001\027\001\t\000\000\000\000\000\000\000\000\000\000\001\016\001\029\002\r\002\014\001^\001'\000\000\000\000\001A\000\000\000\000\001\027\0017\000\000\000\000\001'\000\000\000\000\001A\001\030\002\r\002\014\001^\001\167\000\000\002N\001#\002\r\002\014\001^\0017\000\000\000\000\000\000\000\000\000\000\001#\001\030\000\000\000\000\000\000\000\000\000\000\002X\000\000\0017\001'\000\000\000\000\001A\002c\000\000\001\030\000\000\001#\001\t\001\205\002\r\002\014\001^\000\000\001\016\001\029\000\000\001'\001\t\000\000\001=\000\000\000\000\000\000\001\016\001\029\000\000\001\024\000\000\000\000\001\025\000\000\001'\002r\000\000\001A\001\t\000\000\000\000\000\000\000\000\000\000\001\016\001\029\000\000\001\024\000\000\000\000\001\025\000\000\002\016\000\000\000\000\000\000\001\027\000\000\000\000\000\000\000\000\0017\000\000\002\017\000\000\002d\000\193\000\000\001\030\000\000\002\016\0017\001\207\000\000\001\027\000\000\000\000\002\016\001\030\000\000\000\000\002\017\002$\002d\000\193\000\000\000\000\000\000\002\017\0017\002d\000\193\000\000\000\000\000\000\001'\001\030\000\000\001A\001#\0027\000\000\000\000\000\000\000\000\001'\000\000\002\016\001A\000\000\000\000\000\000\001\024\000\000\000\000\001\025\000\000\001#\002\017\000\000\002d\000\193\002e\001'\000\000\000\000\001A\000\000\001\t\000\000\002f\000\000\001}\002g\001\016\001\029\000\000\000\000\000\000\001\027\002e\000\000\000\000\000\000\000\000\000\000\001\t\002e\002f\000\000\001}\002g\001\016\001\029\000\000\002f\000\000\001}\002g\000\000\000\000\000\000\001\024\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\001\024\000\000\000\000\001\025\000\000\000\000\002e\000\000\0017\001\024\000\000\001#\001\025\000\000\002f\001\030\001}\002g\001\027\002\175\000\000\000\000\000\000\000\000\000\000\000\000\0017\001\027\000\000\002\r\002\014\001^\000\000\001\030\000\000\000\000\001\027\002\180\000\000\000\000\001\t\000\000\001'\000\000\000\000\001A\001\016\001\029\000\000\000\000\001\024\000\000\003\020\001\025\000\000\000\000\000\000\000\000\000\000\001\024\001'\001#\001\025\001A\000\000\000\000\000\000\000\000\000\000\000\000\001#\000\000\000\000\000\000\000\000\000\000\000\000\001\027\000\000\001#\000\000\000\000\000\000\000\000\000\000\000\000\001\027\000\000\000\000\000\000\001\t\0017\001\024\000\000\000\000\001\025\001\016\001\029\001\030\001\t\000\000\000\000\002\197\000\000\000\000\001\016\001\029\001\024\001\t\001\024\001\025\000\000\001\025\000\000\001\016\001\029\000\000\000\000\000\000\001\027\001#\000\000\000\000\000\000\002\016\001'\000\000\000\000\001A\001#\000\000\000\000\000\000\000\000\001\027\002\017\001\027\002d\000\193\000\000\000\000\0017\000\000\000\000\000\000\000\000\000\000\000\000\001\030\001\t\0017\000\000\002\204\000\000\000\000\001\016\001\029\001\030\001\t\0017\000\000\002\211\001#\000\000\001\016\001\029\001\030\000\000\001\024\000\000\002\220\001\025\000\000\000\000\000\000\001'\000\000\001#\001A\001#\000\000\000\000\000\000\000\000\001'\000\000\000\000\001A\000\000\000\000\000\000\001\t\000\000\001'\002e\001\027\001A\001\016\001\029\000\000\0017\000\000\002f\000\000\001}\002g\001\t\001\030\001\t\0017\000\000\004P\001\016\001\029\001\016\001\029\001\030\000\000\001\024\000\000\004\168\005\005\000\000\000\000\000\000\000\000\000\000\001\024\000\000\001\024\005\005\000\000\001\025\000\000\001'\000\000\000\000\001A\001#\000\000\000\000\000\000\0017\001'\001\024\001\027\001A\001\025\000\000\001\030\000\000\000\000\000\000\004\180\001\027\000\000\001\027\0017\000\000\0017\001\024\000\000\000\000\001\025\001\030\000\000\001\030\001\t\004\193\000\000\004\210\001\027\000\000\001\016\001\029\001\024\001'\001\024\001\025\001A\005\005\000\000\000\000\000\000\000\000\000\000\000\000\001\027\005\007\000\000\000\000\001'\000\000\001'\001A\000\000\001A\005\007\000\000\001#\000\000\000\000\001\027\000\000\001\027\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001#\000\000\000\000\001\t\0017\000\000\000\000\000\000\000\000\001\016\005\n\001\030\001\t\000\000\001\t\004\226\001#\000\000\001\016\005\n\001\016\001\029\001\024\000\000\000\000\005\005\000\000\000\000\000\000\001\t\000\000\001#\000\000\005\007\000\000\001\016\001\029\000\000\001'\000\000\000\000\001A\000\000\000\000\000\000\001\t\000\000\000\000\000\000\001\027\000\000\001\016\001\029\000\000\001\024\000\000\000\000\001\025\000\000\000\000\001\t\005\011\001\t\000\000\000\000\0017\001\016\001\029\001\016\005\n\005\011\001\024\001\030\004\213\001\025\005\012\005~\005\r\000\000\000\000\0017\001\027\004\213\000\000\005\024\000\000\005\r\001\030\001'\000\000\000\000\005\144\005\007\000\000\000\000\000\000\0017\001'\001\027\001'\000\000\000\000\001A\001\030\000\000\000\000\000\000\005\168\000\000\000\000\000\000\0017\000\000\001\024\001'\000\000\001\025\001A\001\030\000\000\005\011\001\t\0066\000\000\001#\000\000\000\000\001\016\005\n\000\000\001'\000\000\004\213\001A\005\228\000\000\005\r\000\000\000\000\000\000\001\027\001#\000\000\000\000\000\000\001'\001\024\001'\001A\001\025\000\000\000\000\000\000\001\t\001\024\000\000\000\000\001\025\000\000\001\016\001\029\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\000\000\001\027\000\000\000\000\001\016\001\029\000\000\005\011\000\000\001\027\000\000\001#\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\213\000\000\005\254\000\000\005\r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0017\000\000\001'\000\000\000\000\000\000\000\000\001\030\001\t\000\000\000\000\006\139\001#\000\000\001\016\001\029\000\000\0017\000\000\000\000\001#\000\000\000\000\000\000\001\030\000\000\000\000\000\000\006\143\000\000\000\000\000\000\000\000\000\000\001'\000\000\000\000\001A\000\000\000\000\000\000\001\t\000\000\000\000\000\000\000\000\000\000\001\016\001\029\001\t\000\000\001'\000\000\000\000\001A\001\016\001\029\000\000\000\000\0017\000\000\000\000\000\000\000\000\000\000\000\000\001\030\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0017\001'\000\000\000\000\001\200\000\000\000\000\001\030\0017\000\000\000\000\000\000\000\000\000\000\000\000\001\030\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001'\000\000\000\000\001\202\000\000\000\000\000\000\000\000\001'\000\000\000\000\003\232")) + ((16, "\000%\000\193\000G\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\012\000\000\000\000\000\129\001\152\000\030\0003\000#\000\004\000\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000b\000\000\000\000\000\000\000\000\000\000\000t\000\000\000\000\000\000\000\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=2\000\000\000\000\000\000\000\254\000\000\000\000\000\000\000\000\000\000\000\000\000\000'\238\001T\001>\000\223\000\000\001B9\220\001\236\001\218\000:\000\000\000\000\000\000\001x\000\000\000\000\000\182\000\000\000\000\000\000\000\000\003\156\000\000\002\150\000\000\000\000\000\000\000\000\000\000\001\022\000\000\000\218\003\202\bf\000\000\000\000\011\018'\238\000\000\000\000\001\254\000\000\000\027\000\000:~\002\184\000\000\001\156\001r\000\000\000\000\002\172\002\142\002\208\003b\001\226\003\202\004\142\000f\001\194\0022\003\216\002\152\011b\000\000\005(\003\244\003\188\002h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004r\000\000\t>\005(\011\194\000\000\000\000\004.\005d\004\0301\236\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\148\000\000\004\168\005l\005@\000\000\000\000\000\000\000\000\000\173\000\000\000\000\005\144\000\167\006\018\006(\007\214\000\000\0050\005H\006*\000Q\004\228\006L \232\000\000\000\000\005X\006\254\011\204\000\000!\b\001\244!\026\"V\000\000\003B\000\000\000\000\000\000\000\000\006\018=F\006\020\000\000\001\012\0064\000\000\004P6\150\000\131\000\000\001\172\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002:\005\190\000\000\000\000\000\000\000\192\000\000\tD\000\000\000\000\002\164\000o\000\000\000\000\003\248\000\000\006n\000\000\002\164\t\148\002\164\000\000\000\000\000\000\000\000\000\0007 \000\000\007\"\006@\000\000=\168\007N\030`\000\000\000\000\000\000\0062\000\000\000\000\000\000\000\000\006F\000\000\000\000\000\000\000\000\000\0002L\000\000\000\000\000\000\000\000\000\000\000\000\001\158\007N\000\000\000\000\000\000\006F\007\1342\146\006\224\007p\015\214\000\000\003\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000(\000\000\000\000\000\000\000\000\b\0122\160\000\000\000\000\007\030\b\0042\214\000\000\000\000\000\00038\007\0143\152\000\000\007\014\000\0003\164\007\014\000\0003\228\007\014\000\000\007\014\000\000\000\000\007\014\000\000\000\0004J\000\000\007\0144\138\000\000\007\014\002|\000\000\000\000\"V\000\000\000\000\000\000\000\000\007\014\"z\000\000\000\000\000\000\007\014\000\000\006F\007\246\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\016\000\000\007\136\000\000=\132\006F\000\000\000\000\000\000\000\000\b\b\b\184\012$\b\026\b\030\b@\b\028\005\014\b`\0001\t\006\000\000\000\000\000\029\005\136\b\160\001\172\b\200\bL\000\000\000\145\004\138\005\180\007\136\n\"\000\000\000\000C\158\000\000C\224\t\212\000\000=\198\006F>@\006F\000\000\003\"\000\000\003x\000\000\000\000\003\220\000\000\000\000\000\000\nt\000\000\n\030\000\145\000\000\000\000\t>\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\145\000\000\000\000\000\145\000\000\b\200\007\014\000\000\002\182\004\228\000\000\002\182\000\000\000\000\n\206\000\145\000\000\000\000\000\000\000\000\000\000\000\000\002\182\012\132\rL\n4\t\218\"\152\000n\000\000\t\130\b\182\r\158\t\234\b\228\025X1N\000\000\000\000\000\000\000\000\000\000\0032\t\188\000\000\000\000\000\000\t\250\b\244\007V\002\182\011\240\000\000\000\145\000\000\000\000\000\000\001\244\000\000>T\006F\r\166\n\018\t\030\r\254\n \t0\014\180\"\186\007\014\015\024\n\"\t89\190\n\244\000\000#\002\007\014>x\006F\n\238\000\000\000\000\000\000\000\000\007\148\011&\011L\000\000\000\000\b\176\015 \n\208\t>4\172\007\014\015t\n\222\tF6(\000\000>\172\000\000\000\000\015|\"\244\018\\\000\000\000\000\000\000\000\000>\208\000\000\000\000\000\000\007\172\016B\000\000\000\000\000\000\000\000#^>\222\000\000\000\000\000\000\000\000\000\000\n\170\016\150\000\000\n\180$\"\n\180$,\n\180\000\000?\026\000\000$\128\n\180\016\234\004\152\016\244\000\000\000\000$\136\n\180%\022\n\180%\030\n\180%\250\n\180&\002\n\180&\026\n\180&\152\n\180&\246\n\180&\254\n\180'\140\n\180'\148\n\180'\232\n\180(v\n\180(\128\n\180)\014\n\180)^\n\180)h\n\180)\246\n\180*F\n\180*\212\n\180\t\170*\2484\232\007\148\011x\000\000+8;l\000\000\017N\000\000?,\000\000\006F;\166\000\000\006F?P\006F\000\000\017\184\000\000\000\000\000\000+\\\000\000\000\000\000\000\000\000\000\000\007\014\000\000\000\000?\210\000\000\006F\000\000\000\000;\166\011\136\000\000@6\006F\018\018\000\000\000\000\011\"\000\000@H\006F\018\160\000\000\000\000\018\196\000\000\000\000\000\000@Z\006F\019\028\000\000\n\252\019\132\000\0005J\000\000\007\0145\142\000\000\007\0145\176\000\000\007\014\003d\000\000\000\000\000\000\000\000\000\0005\240\007\014\004\222\005\022\000\000\000\000\000\000\n\180\019\222\000\000\000\000\000\000+\150\n\180\000\000\000\000\000\000\000\000\0206\000\000\000\000\000\000\n\180\020D\000\000\020\158\000\000\000\000\000\000\021\004\000\000\000\000\000\000\000\000@\146\000\000\000\000\021^\000\000\000\000\000\000,H\n\180\021l\000\000\000\000\000\000,\138\n\180\021\196\000\000\000\000,\176\n\180\n\180\000\000\007\228\022\030\000\000\000\000-\b\n\180\022l\000\000\000\000-(\n\180-v\n\180\000\000.\004\n\180\000\000\000\000\022\250\000\000\000\000.\152\n\180\023,\000\000\000\000.\200\n\180\023\\\000\000\000\000.\232\n\180\000\000/\000\n\180\000\000;\138\000\000\000\000\n\180\000\000\000\000\023\142\000\000\000\000\023\192\000\000\000\000\011D\000\000\000\000\024\028\000\000\024$\000\000\000\000\000\000\007\148\011\226\000\0007\022\n<\002\164\025\004\000\0007r\000\000\000\000\000\0007\194\000\000\000\000\025$\000\000\025\146\000\000\000\000\000\000\000\000/\n\000\000\000\000\000\000/f\n\1800r\n\180\000\000\n\252\025\156\000\000\000\000\025\236\000\0000T\000\000\000\0001N\000\000\000\000\000\000\026\134\000\000\000\000\000\000\000\000\026\144\000\000\000\000\000\000\000\000\012\152\000\000\000\000\000\000\003\154\000\000\000<\000\000\000;\000\000\0128\000\000\004\144\000\000\000\000\000\000\000\000\000\000\000\000\0032\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\180\000\000\012\164\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\184\007\232\002\182\027T\000\000\011\166\t\224\012*\001\144\t\136\002\182\r@\000\145\t\176\002\182\000\000\027x\000\000\004\142\000\000\011\194\t\238\004X\000\000\000\000\000\000\000\000\000\000\011\218\001.\000\146\000\000\000\000\000\000;\222\000\000C\240\000\000\t\246\000\000\n\016\000\000\000\000\000\000\000\000\002\158\000\000\000\000\000\000\011*\002\164\000\000\002\164\001\178\000\000\rv\002\164\002\164\n\024\000\000\027\186\000\000\000\000\n8\012\172\000\0000\180\005$\000\000\000\000\000\000\000\000\000\000\000\000\n\180\000\000\028\180\000\000\n\180\000\000\000\000\014\242\000\000\000\145\000\000\016H\000\000\000\145\000\000\017\012\000\145\000\000\003Z\000\000\n<\n\022\005`\000\000\011\226\011\234\nV\012\024\012\164\017T\000\145\006\012\000\000\nZ\012\134\012\188\005\024\006\184\012\150\n\130\r\014\006\146\b\132\012\228\000\000\000\000\007\188\b\148\000\000\004\168\002\2426N\007\014\028\028\000\000\007X\003\178\012\158\n\154\011^\005\224\000\000\012\168\n\158\006\200\000\000@\172\006F\rZ\r\132\000\000\t:\000\000\012\244\n\166\006>\r2\003V\000\000\000\000\000\000\000\000\n\216\tZ\000\000\n\222\tl\000\000\bb\0164\rF\rP\n\228\006\216\t\172\000\000\n\230\007\138\n\018\000\000\rR\n\238\r\220\000\000\t\028\000\000\n\132\000\000\r\252\000\000\018\024\000\145\r\216\011\002\014\022\000\000\018\202\0056\r\236\000\000\000\000\003j\006\160\011$\000\000\019\228\000\145\011F\000\000\004\022\000\000\r\210\011\016\0212\006\154\000\000\r\222\011>\007\176\r2\r\230\r\240\011L\015F\000\000\014\000\001\200\000\000\000\000\000\000\000\000\000\171\011X\r\226@\190\006F\000\000\002\200\011\142\014\148\000\000\000\000\000\000\000\000\000\000\000\000A\000\006\164\000\000\011\182\014\246\000\000\000\000\000\000\000\000\000\000\000\000\006\174\000\000A\030\006F\011\226\000\000\006F\011\218\000\184\000\000\011\230\011\232\007\024\000\000\001\004\004L\000\000\002\190\000\000A\"\006F\006F\000\000\000\000\007\b\000\000\b\252\000\000\001\186\007\b\007\b\000\000\011\236;\204\006FA\152\006F\012\b\000\000\000\000\000\000\000\000\012\014\000\000\000\000\007N\000\000\007l\014`\011\240\015p\014*\000\000\000\000\001\196\b|\014h\000\000\000\000\011\250\015\128\014@\000\000\000\000\029\018\000\000\012\222\000\000!(6H\006F\000\000,N\018\132\000\000A\252\000\000\000\000\000\000\007\b\000\000\000\000\012:\014|\012\000\015\144\014J\000\000\000\000B\014\012\144\014\140\000\000\000\000\000\000<:\000\000\000\000\000\000\000\000\000\000\000\000\012\146\000\000\014\152\012\020\006\162\000\000\015\134\015>\012\180\014\166\000\000\000\000\014\170\012>\b*\000\000\000\000\tl6\150\005|\000\000\000\000\000\000\bL\014p\012p\000\000\014z\bL\000\000\015V\012\188\014\196\000\000\000\000\000\000\006F\003v\004(\005\180\000\000\000\000\000\000\000\000\014\138\012t\000\000\006\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006F\014z\012\128\015\208\014\138\000\0007\224\000\237\012\146\014^\003\156\000\019\012\150\015\016\000\000\015\200\028\130\000\000\000\000\029J\000\000\012\208\000\000\nL\000\000\000\000\000\000\000\000\000\000\000\000B\018\006F\000\000\015\204\029l\000\000\000\000\030\002\000\000\000\245\012\156\015r\000\000\000\0007\250:\020\015(\000\000B0\006F\0302\000\000\000\000\030T\000\000\000\000\r0\000\000\000\\\000\000\000\000\000\000\000\000\000\000\000\000:\204\000\000\000\0008\188:\208\015*\000\000BP\006F\030\234\000\000\000\000\031\028\000\000\000\000\012\184\031<\r<\000\000\012\190\012\198\002\016\002\208\012\200\t&\012\214\015|0\214\r\\\000\000\r\016\r2\tf\000\000\004*\002k\000\200\004\219\002X\006\022\006%\001%\006\024\006\213\001W\001F\002Y\003\217\006\237\004\220\006+\006\025\006&\004\221\006\131\003\137\002\246\002\247\001%\002g\006e\001\147\001e\001\019\003\253\006,\001\016\0009\001.\001\023\001\016\001H\001\023\001$\006\031\001\016\001\023\001\026\000\128\006!\006\026\001\023\001\026\006\238\006Z\003\254\000\200\001\127\001)\006#\001\016\000\203\002l\000\203\002r\006\166\001\023\001$\001n\003\220\002x\000\200\001\132\002n\001\016\006$\000\147\000\135\006q\001\215\001\023\001$\000\196\001\238\006\027\000\200\000\201\006\021\002i\002\020\002\021\001e\006\028\002z\001%\006\167\003\140\003\145\004\219\002\024\004\000\002k\000\200\004\219\002X\006\022\006%\000=\006\024\000\174\004\220\001`\002Y\005\210\004\226\004\220\006+\006\025\006&\004\252\006y\004\003\003\181\001e\000\134\002g\000\196\001\129\000\186\000\200\000\201\006,\001%\006i\006j\001\130\002\001\001\132\001l\000\203\006\031\005\212\006k\006l\003\234\006!\006\026\002\244\001e\000\147\006-\000\181\001\215\006m\004\b\006#\005\213\001\016\002l\001.\002r\005\215\006\214\001\023\001$\005\238\002x\000\179\001\132\002n\001\016\006$\000\189\002\020\002\021\001e\001\023\001\026\000\196\000\151\006\027\000\200\000\201\006\021\002i\002\020\002\021\001e\006\028\002z\004\236\003\248\003\247\003\249\000\150\002\024\003\165\002k\000\200\002\251\002X\006\022\006%\003\174\006\024\000\202\000\183\005F\002Y\005\210\001\016\000\172\006+\006\025\006&\004\239\001\023\001$\002\001\001\217\000\178\002g\000\200\006i\006j\002\251\003\175\006,\001\031\000\203\004\241\001+\006k\006l\000\203\000\196\006\031\005\212\000\200\001\002\004\215\006!\006\026\006m\004\b\004c\006)\001\003\000\200\002\002\004\242\006#\005\213\004\147\002l\001\"\002r\005\215\007\005\002\021\001e\005\231\002x\001\219\001\132\002n\004'\006$\002\023\001\023\001\031\001\006\001\031\001 \004c\001 \006\027\000\200\0012\003\178\002i\002k\000\200\001\002\006\028\002z\006\021\001\223\002\020\002\021\001e\002\024\006\180\002k\000\200\005\251\005F\001\"\0013\001\"\007\b\007\t\004\213\002X\007\011\001O\004\149\006\024\006+\005M\005N\002Y\004f\001\222\001\132\003\168\006\025\007\r\000\194\001\023\0007\005\254\006\167\006,\002g\005^\003\173\001\016\0007\005W\004\b\002\002\006\031\001\023\001$\001\224\006\000\006!\002l\004\150\001*\006c\001*\001\132\000\184\006\026\002m\006#\001\132\002n\002l\000\196\002r\000\196\000\200\000\201\000\200\000\201\002x\0018\001\132\002n\006\001\006$\007\006\006\206\002k\000\200\006\179\001\016\000\188\001\016\002\020\002\021\001e\001\023\001$\001\023\001$\006\027\000\203\002z\005\210\002i\000\193\001%\006\021\006\028\002\020\002\021\001e\007\028\004\149\002\251\002\024\006G\002k\000\200\005M\005N\003\221\007\020\000\196\002X\007\021\000\200\001\002\006\024\007\016\000\204\005\212\002Y\001.\000\211\005V\001\246\006\025\007\029\005W\004\b\001>\002\251\001>\006?\002g\005\213\006,\001%\002\251\001%\005\215\004\218\005\205\001F\005\222\006\031\001\246\002\251\003\168\006\207\006!\001\250\003\230\004\b\002\003\006\026\000\147\000\200\001\202\001\215\006#\006\221\003\220\002l\001.\002r\001.\001H\002\251\001H\002\253\002x\002\005\001\132\002n\002\003\006$\002\023\000\200\0049\006\208\000\203\006\168\006\169\000\224\006\215\001\023\002\001\002\024\006\027\002k\000\200\004c\002i\002z\000\200\000\228\006\028\002\252\001d\001e\002~\005W\004\b\002\024\004\014\002k\000\200\006\021\004F\002\020\002\021\001e\002\004\004\138\004c\004\019\007!\000\200\001f\002\192\003\234\001h\001i\006\216\002X\006\022\0063\001\198\006\024\001\239\003\220\002\251\002Y\002\004\004+\006,\001\230\006\025\006&\000\212\001\234\005\245\001\023\000\225\006\031\002g\002l\006\217\003\234\006!\002\001\004(\001\031\002\251\002m\001 \001\132\002n\006\222\006#\001\132\000\234\002l\000\241\002r\006\218\006\026\005?\003\247\003\249\002x\000\249\001\132\002n\000\147\006$\0050\001\215\001\229\001\"\001\235\006o\001Y\001\132\001\031\000\196\001\n\001 \000\200\000\201\004U\001e\001m\002z\001\236\005S\003\247\003\249\004Q\002\002\006\027\000\203\001\r\001n\002i\000\203\000\200\001\030\006\028\001;\006\021\001\"\002\020\002\021\001e\002\024\005\210\002k\000\200\006\002\0044\004\198\001*\000\203\002\251\007\020\000\236\002X\007\021\002\251\000\196\006\024\006+\000\200\001\002\002Y\004\201\002\193\000\242\002\251\006\025\007\024\001\164\006v\005\212\005\254\005\217\006,\002g\000\196\003\234\001\016\000\200\000\201\001*\000\245\006\031\001\023\001$\005\213\006\000\006!\001\129\002\002\005\215\001B\001\006\004>\005\219\006\026\001\157\006#\001\132\001l\002l\004\143\002r\006\144\000\200\002\251\005\210\0007\002x\001\016\001\132\002n\006\001\006$\000\203\001\023\001$\004\155\001d\001e\004`\004\b\004\188\005[\003\247\003\249\000\203\001\246\001-\006\027\004r\002z\004:\002i\005\212\001%\001\023\006\028\001f\001v\001G\001h\001i\000\203\002\024\003\220\002k\000\200\006\021\005\213\002\020\002\021\001e\001\247\005\215\002\251\002\003\007\027\005\216\000\200\001>\004\210\001.\001\246\000\200\002X\006\022\001%\001\016\006\024\000\250\004\203\004\228\002Y\001\023\001$\006,\001V\006\025\006/\006\176\001w\001\229\001x\002\199\006\031\002g\001G\001E\002!\006!\001\159\002\003\001\\\001.\000\200\000\147\001H\005:\001\215\006#\001\156\001\016\002l\004\243\002r\000m\006\026\001\023\001$\001C\002x\001\127\001\132\002n\002\004\006$\000\196\005#\004v\000\200\001\002\004\245\001n\001t\001\023\000\200\001]\001\031\004\239\001\031\001 \000\203\001 \002z\003\b\001\246\004\222\000\200\001\002\001~\006\027\004C\001\031\004\241\002i\005$\005d\005%\006\028\000\203\002\004\001\163\001\203\001\175\001\"\002\024\001\"\002k\000\200\001d\001e\003\204\003@\004\242\002\003\000\200\001\002\000\200\001\016\006@\003\025\000\203\0062\005F\001\023\001\026\005&\004L\001\016\001f\002\192\001\129\001h\001i\001\023\001$\004\222\006,\000\203\001\130\002\251\001\132\001l\003\220\002\251\005\254\006\031\001*\003Q\001*\001u\006!\002\251\002\251\004\159\004\b\001\198\003\234\001\199\005'\006\000\006#\001\186\006\157\002l\001\230\002r\001\180\005(\001\234\005)\001\023\002x\002\004\001\132\002n\001\016\006$\001\016\002\020\002\021\001e\001\023\001$\001\023\001$\006\001\0007\006\143\002\251\001\031\001\016\004\016\005e\002X\002z\001\188\001\023\001$\004\t\006\133\003\202\002Y\001m\006\152\003\247\003\249\004\253\006Q\001\235\001\031\004?\000\203\001 \001n\002g\005+\000\200\001\185\004D\006z\005-\0057\001\236\000\203\005M\005N\001>\001\195\001>\001\031\005a\005C\004\b\001%\002\251\001%\001\"\005f\002\015\005O\005_\002\020\002\021\001e\005W\004\b\005b\003r\001%\006g\002\251\004\224\001\191\005F\000\200\006\187\002X\000\203\006h\002\251\001.\002\018\001.\001H\002Y\001H\003u\000m\004~\002 \003\147\004\222\001\129\002i\001\023\006\131\001\237\002g\001\031\001*\001\157\001 \001\132\001l\002\024\001\208\002k\000\200\001\016\000\203\002/\002\251\001\246\005I\001\023\001$\002\020\002\021\001e\0022\000\203\004\\\001\210\0028\005\200\001\"\002M\000\200\001\016\005\130\002R\002X\001\246\001\031\001\023\001$\002o\004h\003\212\002Y\001G\002\003\005F\000\203\000\200\006\229\004k\001\226\001\016\001\233\000m\000\203\002g\003\195\001\023\001$\002i\001\031\003\216\003\191\001 \002\003\002\251\002l\000\200\002r\001%\002\024\001*\002k\000\200\002x\000\203\001\132\002n\005M\005N\005\192\004s\001>\002\170\000\203\006\159\001\246\001\"\000\203\001%\003\203\000\203\006\231\005O\005_\000\203\001&\002z\005W\004\b\001\016\002\014\002o\002\004\005F\005\224\001\023\001$\000\200\001%\003\209\001\198\004*\001\228\002i\002\003\001.\003\224\000\200\001H\001\230\003\241\002\251\002\004\001\234\002\024\001\023\002k\000\200\002l\001*\002r\004w\005\134\003\243\001\016\0010\002x\004\005\001\132\002n\001\023\001$\001\031\006\173\000\203\001 \005M\005N\006a\004\b\001>\000\203\002\017\004\n\001\031\004)\002o\001%\001\016\002z\002\031\005O\005_\001\235\001\023\001$\005W\004\b\004/\001\"\0046\000\203\002.\002\004\002\020\002\021\001e\001\236\000\203\0021\0027\002C\000\203\002l\001.\002r\005F\001H\004\127\002X\004<\002x\001%\001\132\002n\000\203\002@\002Y\001\198\000\203\001\254\002\251\004O\006V\004T\005M\005N\001\230\004_\001>\002g\001\234\001*\001\023\002z\000\203\001%\000\203\002\251\003o\005O\005_\002\020\002\021\001e\005W\004\b\002\020\002\021\001e\000\203\000\196\000\203\004g\000\200\000\201\004j\002X\002H\004q\004u\001\016\002X\001.\004z\002Y\001H\001\023\001$\001\246\002Y\001\235\000\203\001\016\004\134\006D\004\021\002G\002g\001\023\001$\004\153\005\210\002g\000\203\001\236\000\203\002L\004\144\002i\000\203\002\020\002\021\001e\002Q\004P\002\254\002w\002\003\002\174\002\024\000\200\002k\000\200\004\158\004\148\002X\002\209\005M\005N\005\212\004\163\001>\002\216\002Y\000\203\002\251\004\173\000\203\001%\004\015\000\203\000\203\006\155\006\156\005\213\000\203\002g\005W\004\b\005\215\001%\002o\002\245\005\226\002\251\000\203\002i\002\251\002\020\002\021\001e\002i\000\203\004\179\001\246\001.\003d\002\024\001H\002k\000\200\003l\002\024\002X\002k\000\200\002\004\003\252\002l\002\251\002r\002Y\001\198\004\190\002$\000\203\002x\003\201\001\132\002n\006K\001\230\000\203\002\003\002g\001\234\000\200\001\023\000\203\002o\003\161\004\205\004\202\003\171\002o\002i\003\193\004\223\004\209\002z\004\230\001\031\004\247\003\208\005\b\003\210\002\024\005\001\002k\000\200\005\026\004\235\002\251\002\251\004\240\000\203\002l\003\223\003\014\004\004\005/\002l\004\012\002r\002x\001\235\001\132\002n\001\"\002x\002\251\001\132\002n\0045\002\251\000\203\005\024\004.\002o\001\236\006\021\0059\002\004\002i\002\251\0040\0043\002z\002\020\002\021\001e\004B\002z\000\203\002\024\007\020\002k\000\200\007\021\000\203\000\203\006\024\000\203\002X\000\203\002l\005E\002r\005Y\000\203\006\025\002Y\000\203\002x\005i\001\132\002n\001\031\0048\005 \005,\003\198\000\203\005o\002g\005s\002o\004A\005\143\002\020\002\021\001e\002\251\002\020\002\021\001e\002z\0054\002\251\006\026\001\016\005K\005\183\000\203\002X\005\243\001\023\001$\002X\005\188\005\227\005|\002Y\002l\002\251\002r\002Y\005\193\003\184\004=\002\251\002x\003\136\001\132\002n\002g\004@\004N\000\203\002g\000\203\000\196\004S\006\027\000\200\000\201\000\203\002\020\002\021\001e\001\198\006\028\003\214\002i\002z\000\203\005\223\000\203\004[\001\230\000\203\002\251\002X\001\234\002\024\001\023\002k\000\200\001%\005\159\002Y\007\023\005\210\005\199\000\203\005\185\003\131\000\203\002\251\004Z\004^\000\203\000\203\002g\005\207\005\248\001\016\006\r\006J\000\203\006\030\005\196\001\023\001$\002i\001.\002o\005\230\002i\006\031\005\212\004i\002\251\001\235\006!\002\024\002\251\002k\000\200\002\024\002\251\002k\000\200\002\251\006#\005\213\002\251\001\236\000\203\002\251\005\215\004t\006d\002l\005\244\003\014\004p\004y\005\242\002\251\006$\002x\004\141\001\132\002n\000\203\006p\002o\006~\001d\001e\002o\002i\002\251\001%\005\246\000\203\000\203\004\129\000\203\000\203\006\128\002\251\002\024\002z\002k\000\200\004\140\002\251\001f\001v\004\135\001h\001i\002l\002\251\002r\004\139\002l\005\250\002r\004\002\002x\005\255\001\132\002n\002x\006\011\001\132\002n\006\018\002\251\003\127\006 \000\203\002o\006'\002\251\002\020\002\021\001e\004\152\002\020\002\021\001e\002z\0060\004\157\000\203\002z\000\203\005\000\001w\002X\001x\0024\004\162\002X\004\165\004\169\006u\002Y\002l\000\203\002r\002Y\004\177\003x\004\184\006\161\002x\003i\001\132\002n\002g\006\175\004\195\004\255\002g\004\248\004\249\004\254\007\014\001\127\002\020\002\021\001e\005\002\002\020\002\021\001e\005\003\005\"\002z\001n\005\027\005\028\000\200\007\025\002X\005!\0056\0052\002X\007\030\003\130\0053\002Y\0055\005`\005D\002Y\000\196\003a\005H\000\200\000\201\001\198\005J\004\029\002g\003Y\005L\005X\002g\005h\001\230\005j\005k\005p\001\234\005t\001\023\002i\001d\001e\005x\002i\005\138\005\145\005\149\005\173\005\194\005\210\002\024\005\218\002k\000\200\002\024\005\228\002k\000\200\006\020\001\129\001f\001g\006\014\001h\001i\006\015\006\019\001\130\006\"\001\132\001l\006I\006T\006_\006s\006t\001\235\005\212\006x\006\160\006\164\006\174\002o\006\178\005#\002i\002o\007\000\000\000\002i\001\236\000\000\005\213\002\020\002\021\001e\002\024\005\215\002k\000\200\002\024\006\007\002k\000\200\000\000\000\000\000\000\000\000\002X\002l\000\000\002r\005$\002l\005%\002r\002Y\002x\000\000\001\132\002n\002x\002d\001\132\002n\000\000\000\000\000\000\002o\002g\000\000\000\000\002o\000\000\001m\002\020\002\021\001e\000\000\000\000\002z\000\000\000\000\005&\002z\001n\000\000\000\000\000\200\000\000\002X\000\000\000\000\000\000\000\000\002l\000\000\002r\002Y\002l\000\000\003\014\000\000\002x\002q\001\132\002n\002x\000\000\001\132\002n\002g\000\000\000\000\000\000\000\000\005'\002\020\002\021\001e\000\000\000\000\002\020\002\021\001e\005(\002z\005)\002i\000\000\002z\000\000\002X\000\000\001\198\000\000\004!\002X\000\000\002\024\002Y\002k\000\200\001\230\001\129\002Y\002\128\001\234\000\000\001\023\005c\002\127\001\157\002g\001\132\001l\000\000\000\000\002g\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\020\002\021\001e\002i\002o\000\000\005+\000\000\000\000\000\000\000\000\005-\0057\000\000\002\024\002X\002k\000\200\000\000\000\000\001\235\005a\000\000\002Y\000\000\000\000\000\000\000\000\000\000\002\179\000\000\002l\000\000\002r\001\236\000\000\002g\005b\000\000\002x\000\000\001\132\002n\000\000\000\000\002i\002o\000\000\000\000\000\000\002i\000\000\000\000\002\020\002\021\001e\002\024\000\000\002k\000\200\000\000\002\024\002z\002k\000\200\001\198\000\000\004$\002X\000\000\000\000\000\000\000\000\002l\001\230\002r\002Y\000\000\001\234\000\000\001\023\002x\002\190\001\132\002n\000\000\000\000\000\000\002o\002g\000\000\000\000\000\000\002o\000\000\002i\000\000\000\000\002\020\002\021\001e\001\198\000\000\0042\002z\000\000\002\024\000\000\002k\000\200\001\230\000\000\000\000\002X\001\234\002l\001\023\002r\001\235\000\000\002l\002Y\002r\002x\000\000\001\132\002n\002\213\002x\000\000\001\132\002n\001\236\000\000\002g\002\020\002\021\001e\002o\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002z\000\000\002i\000\000\000\000\002z\000\000\000\000\001\235\000\000\000\000\000\000\003T\002\024\000\000\002k\000\200\001\031\000\000\002l\005\015\002r\001\236\002\020\002\021\001e\000\000\002x\000\000\001\132\002n\000\000\000\000\000\000\000\000\000\000\003U\000\000\002X\000\000\000\000\002\020\002\021\001e\001\"\002o\002Y\002i\000\000\000\000\002z\000\000\002\220\001\198\000\000\004\131\002X\000\000\002\024\002g\002k\000\200\001\230\000\000\002Y\000\000\001\234\000\000\001\023\000\000\002\223\000\000\002l\000\000\002r\006\021\000\000\002g\000\000\000\000\002x\000\000\001\132\002n\002\023\002\020\002\021\001e\000\000\000\000\002o\000\000\000\000\006\022\000\000\002\024\006\024\002k\000\200\000\000\002X\000\000\000\000\002z\000\000\006\025\001\235\000\000\002Y\000\000\000\000\000\000\000\000\000\000\002\229\000\000\001\016\002l\002i\002r\001\236\002g\001\023\001$\000\000\002x\000\000\001\132\002n\002\024\003W\002k\000\200\000\000\006\026\000\000\002i\002\020\002\021\001e\000\000\000\000\001\198\000\000\004\137\000\000\000\000\002\024\002z\002k\000\200\001\230\002X\000\000\002l\001\234\000\000\001\023\000\000\000\000\002Y\002o\002m\000\000\001\132\002n\002\232\000\000\006\027\000\000\000\000\000\000\000\000\002g\001%\000\000\006\028\000\000\000\000\002o\002i\000\000\002\020\002\021\001e\000\000\000\000\000\000\002l\000\000\002r\002\024\000\000\002k\000\200\001\235\002x\002X\001\132\002n\006\029\001.\000\000\000\000\000\000\002Y\002l\000\000\002r\001\236\000\000\003\001\000\000\000\000\002x\006\030\001\132\002n\002g\002z\000\000\000\000\000\000\002o\006\031\000\000\002\020\002\021\001e\006!\000\000\000\000\002i\002\020\002\021\001e\000\000\002z\000\000\006#\000\000\002X\000\000\002\024\000\000\002k\000\200\000\000\002X\002Y\002l\000\000\002r\000\000\000\000\006$\002Y\000\000\002x\003\011\001\132\002n\002g\000\000\000\000\000\000\003\016\000\000\000\000\002g\000\000\002\020\002\021\001e\000\000\002o\000\000\002i\002\020\002\021\001e\002z\000\000\001\198\000\000\004\146\000\000\000\000\002\024\000\000\002k\000\200\001\230\002X\003T\000\000\001\234\000\000\001\023\000\000\000\000\002Y\002l\000\000\002r\000\000\000\000\000\000\000\000\000\000\002x\003\018\001\132\002n\002g\000\000\000\000\000\000\005\214\000\000\002o\002i\000\000\000\000\000\000\000\000\000\000\000\000\002i\002\020\002\021\001e\002\024\002z\002k\000\200\001\235\000\000\000\000\002\024\000\000\002k\000\200\000\000\002X\000\000\000\000\002l\000\000\002r\001\236\000\000\002Y\000\000\000\000\002x\000\000\001\132\002n\000\000\000\000\000\000\003\022\000\000\002o\002g\002\023\000\000\000\000\000\000\000\000\002o\000\000\002i\002\020\002\021\001e\002\024\002z\002k\000\200\002\020\002\021\001e\002\024\000\000\002k\000\200\000\000\002X\000\000\002l\000\000\003\014\000\000\000\000\002X\002Y\002l\002x\003\014\001\132\002n\000\000\002Y\000\000\002x\003\030\001\132\002n\002g\000\000\003W\000\000\003$\000\000\002o\002g\000\000\000\000\000\000\000\000\002z\000\000\002i\002\020\002\021\001e\000\000\002z\000\000\000\000\000\000\000\000\000\000\002\024\002l\002k\000\200\000\000\002X\000\000\000\000\002l\002m\003\014\001\132\002n\002Y\000\000\001\198\002x\004\154\001\132\002n\000\000\000\000\000\000\003*\001\230\000\000\002g\000\000\001\234\000\000\001\023\000\000\002o\000\000\002i\002\020\002\021\001e\000\000\002z\000\000\002i\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\002X\000\000\002\024\000\000\002k\000\200\000\000\000\000\002Y\002l\000\000\003\014\000\000\000\000\0032\000\000\000\000\002x\001\235\001\132\002n\002g\000\000\000\000\002\020\002\021\001e\002o\000\000\000\000\000\000\000\000\001\236\000\000\002o\002i\000\000\000\000\000\000\002X\002z\000\000\000\000\000\000\000\000\000\000\002\024\002Y\002k\000\200\000\000\000\000\000\000\0037\002l\000\000\003\014\000\000\000\000\000\000\002g\002l\002x\003\014\001\132\002n\000\000\000\000\000\000\002x\000\000\001\132\002n\001\198\000\000\006O\000\000\000\000\002o\000\000\002i\000\000\001\230\000\000\000\000\002z\001\234\000\000\001\023\000\000\000\000\002\024\002z\002k\000\200\002\020\002\021\001e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\000\000\003.\000\000\000\000\002X\000\000\000\000\002x\000\000\001\132\002n\000\000\002Y\002i\002\020\002\021\001e\002o\000\000\000\000\001\235\000\000\003C\000\000\002\024\002g\002k\000\200\000\000\002X\002z\000\000\000\000\000\000\001\236\000\000\000\000\002Y\002\020\002\021\001e\000\000\000\000\000\000\002l\000\000\002r\003H\000\000\000\000\002g\000\000\002x\002X\001\132\002n\002o\000\000\000\000\000\000\000\000\002Y\000\000\002\020\002\021\001e\000\000\000\000\000\000\000\000\000\000\003M\000\000\000\000\002g\002z\000\000\000\000\002X\000\000\000\000\000\000\000\000\002l\002i\002r\002Y\000\000\002\020\002\021\001e\002x\000\000\001\132\002n\002\024\003\\\002k\000\200\002g\000\000\000\000\000\000\002X\000\000\000\000\000\000\000\000\000\000\002i\000\000\002Y\000\000\000\000\002z\000\000\000\000\000\000\000\000\000\000\002\024\003_\002k\000\200\002g\000\000\000\000\002o\000\000\000\000\000\000\000\000\000\000\002i\002\020\002\021\001e\000\000\002\020\002\021\001e\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\002X\000\000\000\000\002o\002X\002l\000\000\003\014\002Y\002i\000\000\000\000\002Y\002x\003e\001\132\002n\000\000\003g\000\000\002\024\002g\002k\000\200\000\000\002g\000\000\002o\000\000\000\000\002l\000\000\003\014\000\000\002i\000\000\002z\000\000\002x\000\000\001\132\002n\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\000\000\000\000\002o\000\000\002l\000\000\003\014\000\000\000\000\000\000\000\000\002z\002x\000\000\001\132\002n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002o\000\000\002l\002i\003\014\000\000\000\000\002i\002z\000\000\002x\000\000\001\132\002n\002\024\000\000\002k\000\200\002\024\000\000\002k\000\200\000\000\000\000\002\020\002\021\001e\002l\000\000\003.\000\000\000\000\000\000\002z\000\000\002x\000\000\001\132\002n\002X\002\020\002\021\001e\000\000\000\000\000\000\002o\002Y\000\000\000\000\002o\000\000\000\000\003q\000\000\002X\000\000\000\000\002z\000\000\002g\000\000\000\000\002Y\000\000\000\000\002\020\002\021\001e\003z\000\000\000\000\000\000\002l\000\000\002r\002g\002l\000\000\002r\000\000\002x\000\000\001\132\002n\002x\000\000\001\132\002n\003\182\000\000\000\000\000\000\000\000\000\000\002\020\002\021\001e\000\000\000\000\002\020\002\021\001e\000\000\002z\000\000\000\000\000\000\002z\000\000\002X\000\000\000\000\000\000\000\000\002X\000\000\000\000\002Y\002i\000\000\000\000\000\000\002Y\003}\000\000\000\000\000\000\000\000\003\139\002\024\002g\002k\000\200\000\000\002i\002g\000\000\000\000\000\000\002\020\002\021\001e\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\000\000\000\000\000\000\000\000\002X\000\000\000\000\000\000\000\000\000\000\002\023\002o\002Y\000\000\000\000\000\000\000\000\000\000\003\142\000\000\000\000\002\024\000\000\002k\000\200\002g\000\000\002o\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\002i\002r\000\000\000\000\000\000\002i\000\000\002x\000\000\001\132\002n\002\024\000\000\002k\000\200\002l\002\024\002r\002k\000\200\000\000\000\000\000\000\002x\000\000\001\132\002n\002\020\002\021\001e\002z\000\000\002\020\002\021\001e\000\000\000\000\000\000\000\000\000\000\000\000\002l\002X\002o\000\000\002i\002z\002X\002o\002m\002Y\001\132\002n\000\000\000\000\002Y\002\024\000\000\002k\000\200\003\152\000\000\000\000\002g\000\000\003\157\000\000\000\000\002g\000\000\002l\000\000\002r\000\000\000\000\002l\000\000\002r\002x\000\000\001\132\002n\000\000\002x\000\000\001\132\002n\000\000\002o\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\000\000\002r\000\000\000\000\000\000\006\021\002i\002x\000\000\001\132\002n\002i\000\000\000\000\002\020\002\021\001e\002\024\000\000\002k\000\200\000\000\002\024\006\022\002k\000\200\006\024\000\000\000\000\002X\002z\000\000\002\020\002\021\001e\006\025\000\000\002Y\000\000\000\000\000\000\000\000\000\000\003\206\000\000\000\000\000\000\002X\000\000\002o\002g\000\000\000\000\000\000\002o\002Y\000\000\000\000\000\000\000\000\000\000\003\219\000\000\000\000\006\026\002\020\002\021\001e\002g\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\000\000\003\014\000\000\002X\002l\000\000\003\014\002x\000\000\001\132\002n\002Y\002x\000\000\001\132\002n\000\000\004\007\000\000\000\000\000\000\006\027\000\000\000\000\002g\000\000\000\000\000\000\000\000\006\028\002z\000\000\002i\000\000\000\000\002z\000\000\002\020\002\021\001e\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\000\000\000\000\002i\000\000\002X\006(\000\000\000\000\000\000\000\000\000\000\000\000\002Y\002\024\000\000\002k\000\200\000\000\004J\000\000\006\030\000\000\000\000\000\000\000\000\002g\000\000\002o\000\000\006\031\000\000\000\000\000\000\000\000\006!\002i\000\000\000\000\000\000\000\000\002\020\002\021\001e\000\000\006#\002o\002\024\000\000\002k\000\200\000\000\000\000\000\000\000\000\002l\002X\002r\000\000\000\000\000\000\006$\000\000\002x\002Y\001\132\002n\001d\001e\000\000\005w\000\000\000\000\002l\000\000\002r\000\000\002g\000\000\002o\000\000\002x\000\000\001\132\002n\002i\002z\001f\001v\000\000\001h\001i\000\000\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\000\000\000\000\000\000\002z\000\000\002l\000\000\002r\000\000\004\023\000\000\000\000\000\000\002x\000\000\001\132\002n\000\000\000\000\000\000\001\031\000\000\000\000\005\012\000\000\000\000\000\000\002o\000\000\001w\000\000\001x\0024\000\000\000\000\002i\002z\000\000\000\000\000\000\002\020\002\021\001e\000\000\000\000\000\000\002\024\001\"\002k\000\200\000\000\000\000\000\000\000\000\002l\002X\002r\002\020\002\021\001e\001\127\000\000\002x\002Y\001\132\002n\000\000\000\000\000\000\005z\000\000\001n\002X\000\000\000\200\000\000\002g\000\000\002o\000\000\002Y\000\000\003\130\000\000\000\000\002z\005\137\000\000\000\000\000\000\005\014\000\000\000\000\002g\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\000\000\002r\000\000\000\000\000\000\000\000\000\000\002x\000\000\001\132\002n\000\000\000\000\001\016\000\000\000\000\000\000\000\000\000\000\001\023\005\017\000\000\000\000\000\000\001\129\000\000\002\020\002\021\001e\002i\002z\000\000\001\130\000\000\001\132\001l\000\000\000\000\000\000\000\000\002\024\002X\002k\000\200\000\000\000\000\002i\000\000\000\000\002Y\002\020\002\021\001e\000\000\000\000\005\140\000\000\002\024\000\000\002k\000\200\000\000\002g\000\000\000\000\002X\000\000\002\020\002\021\001e\000\000\005\018\002o\002Y\000\000\000\000\000\000\000\000\000\000\005\153\000\000\001\031\002X\004\220\001 \005\023\002g\005\020\000\000\002o\002Y\000\000\000\000\000\000\000\000\000\000\005\156\000\000\001.\002l\000\000\002r\000\000\002g\000\000\000\000\000\000\002x\001\"\001\132\002n\000\000\000\000\000\000\000\000\000\000\002l\000\000\002r\000\000\000\000\002i\000\000\000\000\002x\000\000\001\132\002n\000\000\000\000\002z\000\000\002\024\000\000\002k\000\200\000\000\000\000\000\000\000\000\000\000\000\000\002\020\002\021\001e\002i\000\000\002z\000\000\000\000\000\000\001*\000\000\000\000\000\000\000\000\002\024\002X\002k\000\200\000\000\000\000\002i\000\000\002o\002Y\000\000\002\020\002\021\001e\000\000\005\177\000\000\002\024\000\000\002k\000\200\000\000\002g\000\000\001\016\000\000\002X\002\020\002\021\001e\001\023\001$\002o\000\000\002Y\002l\000\000\002r\000\000\000\000\005\180\000\000\002X\002x\000\000\001\132\002n\002g\000\000\002o\002Y\000\000\000\000\000\000\000\000\000\000\005\184\000\000\000\000\002l\000\000\002r\000\000\002g\000\000\000\000\002z\002x\000\000\001\132\002n\000\000\000\000\000\000\000\000\001>\002l\000\000\002r\000\000\006\021\002i\001%\000\000\002x\000\000\001\132\002n\000\000\000\000\002z\000\000\002\024\000\000\002k\000\200\000\000\000\000\006\022\000\000\000\000\006\024\000\000\000\000\000\000\000\000\002i\002z\000\000\001.\006\025\000\000\001?\000\000\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\002i\000\000\002o\000\000\000\000\002\020\002\021\001e\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\000\000\006\026\000\000\000\000\002X\000\000\000\000\000\000\001d\001e\000\000\002o\002Y\002l\000\000\002r\000\000\000\000\006\191\000\000\000\000\002x\000\000\001\132\002n\002g\000\000\002o\001f\001v\000\000\001h\001i\000\000\000\000\006\027\000\000\000\000\002l\000\000\002r\000\000\000\000\006\028\002z\000\000\002x\000\000\001\132\002n\000\000\006Y\000\000\000\000\002l\000\000\002r\000\000\000\000\000\000\000\000\000\000\002x\000\000\001\132\002n\000\000\0061\000\000\002z\000\000\001w\000\000\001x\0024\000\000\000\000\000\000\002\020\002\021\001e\000\000\006\030\000\000\002i\002z\000\000\000\000\000\000\000\000\000\000\006\031\000\000\002X\000\000\002\024\006!\002k\000\200\000\000\000\000\002Y\001\127\002\020\002\021\001e\006#\006\193\000\000\000\000\000\000\000\000\000\000\001n\002g\000\000\000\200\000\000\002X\002\020\002\021\001e\006$\000\000\003\130\000\000\002Y\002o\000\000\001d\001e\000\000\000\000\000\000\002X\000\000\000\000\000\000\000\000\002g\000\000\000\000\002Y\001\031\000\000\000\000\005\012\000\000\000\000\001f\001v\000\000\001h\001i\002l\002g\002r\000\000\000\000\001\166\000\000\000\000\002x\000\000\001\132\002n\000\000\000\000\000\000\000\000\001\"\000\000\001\129\002i\000\000\000\000\000\000\000\000\000\000\000\000\001\130\000\000\001\132\001l\002\024\002z\002k\000\200\000\000\000\000\000\000\000\000\001w\000\000\001x\001\153\000\000\000\000\002i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\024\000\000\002k\000\200\005\014\002i\000\000\002o\000\000\000\000\000\000\000\000\000\000\000\000\001\127\000\000\002\024\000\000\002k\000\200\000\000\000\000\000\000\000\000\000\000\001n\000\000\000\000\000\200\000\000\000\000\000\000\002o\001\016\002l\000\000\002r\000\000\000\000\001\023\005\017\000\000\002x\000\000\001\132\002n\000\000\000\000\002o\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\000\000\004\024\000\000\000\000\000\000\002z\000\000\002x\000\000\001\132\002n\000\000\000\000\000\000\000\000\002l\000\000\004\020\001d\001e\000\000\000\000\000\000\002x\001\129\001\132\002n\000\000\000\000\000\000\002z\005\018\001\130\000\000\001\132\001l\001d\001e\001f\001v\000\000\001h\001i\004\220\000\000\005\022\002z\005\020\001\150\000\000\002\020\002\021\001e\000\000\000\000\000\000\001f\001v\001.\001h\001i\000\000\000\000\000\000\000\000\002X\001\155\000\000\001d\001e\000\000\000\000\000\000\002Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001w\000\000\001x\001\153\000\000\002g\000\000\001f\001v\000\000\001h\001i\000\000\000\000\000\000\002\020\002\021\001e\001w\000\000\001x\001\153\000\000\001d\001e\000\000\000\000\000\000\000\000\000\000\002X\001\127\000\000\000\000\000\000\000\000\000\000\000\000\002Y\000\000\000\000\000\000\001n\001f\001v\000\200\001h\001i\000\000\001\127\001w\002g\001x\0024\000\000\000\000\000\000\000\000\000\000\000\000\001n\000\000\000\000\000\200\002i\000\000\000\000\000\000\002\020\002\021\001e\000\000\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\000\000\001\127\000\000\002X\000\000\000\000\001w\000\000\001x\002<\000\000\002Y\001n\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\001\129\000\000\003~\002g\000\000\000\000\002o\000\000\001\130\002i\001\132\001l\000\000\000\000\000\000\000\000\001\127\000\000\001\129\000\000\002\024\000\000\002k\000\200\000\000\000\000\001\130\001n\001\132\001l\000\200\000\000\000\000\002l\000\000\003\190\000\000\000\000\000\000\000\000\000\000\002x\000\000\001\132\002n\000\000\000\000\000\000\000\000\000\000\001\129\000\000\002o\000\000\000\000\000\000\000\000\002?\001\130\000\000\001\132\001l\002i\000\000\002z\002\020\002\021\001e\000\000\000\000\002\020\002\021\001e\002\024\000\000\002k\000\200\000\000\000\000\002l\002X\003X\000\000\000\000\000\000\002X\001\129\002x\002Y\001\132\002n\000\000\000\000\002Y\001\130\000\000\001\132\001l\000\000\000\000\000\000\002g\000\000\000\000\000\000\002o\002g\000\000\000\000\000\000\002z\000\000\002\020\002\021\001e\000\000\002\020\002\021\001e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002X\000\000\000\000\000\000\002X\002l\000\000\002\255\002Y\000\000\000\000\000\000\002Y\002x\000\000\001\132\002n\000\000\000\000\000\000\000\000\002g\000\000\000\000\000\000\002g\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002i\000\000\000\000\002z\000\000\002i\000\000\000\000\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\002\024\000\000\002k\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\020\002\021\001e\000\000\002\020\002\021\001e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002X\002o\000\000\000\000\002X\002i\002o\000\000\002Y\002i\000\000\000\000\002Y\000\000\000\000\000\000\002\024\000\000\002k\000\200\002\024\002g\002k\000\200\000\000\002g\000\000\000\000\002l\000\000\002t\000\000\000\000\002l\000\000\002v\002x\000\000\001\132\002n\000\000\002x\000\000\001\132\002n\000\000\000\000\000\000\002o\000\000\000\000\000\000\002o\000\000\000\000\000\000\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\000\000\002{\000\000\002l\002i\002\130\000\000\002x\002i\001\132\002n\002x\000\000\001\132\002n\002\024\000\000\002k\000\200\002\024\000\000\002k\000\200\002\020\002\021\001e\000\000\002\020\002\021\001e\002z\000\000\000\000\000\000\002z\000\000\000\000\000\000\002X\002\020\002\021\001e\002X\000\000\000\000\000\000\002Y\002o\000\000\000\000\002Y\002o\000\000\000\000\002X\000\000\000\000\000\000\000\000\002g\000\000\000\000\002Y\002g\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\002g\002\132\000\000\002l\000\000\002\134\000\000\002x\000\000\001\132\002n\002x\000\000\001\132\002n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\020\002\021\001e\002z\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002X\002i\000\000\000\000\000\000\002i\000\000\000\000\002Y\000\000\000\000\000\000\002\024\000\000\002k\000\200\002\024\002i\002k\000\200\000\000\002g\000\000\000\000\000\000\000\000\000\000\000\000\002\024\000\000\002k\000\200\002\020\002\021\001e\000\000\002\020\002\021\001e\000\000\000\000\000\000\000\000\000\000\002o\000\000\000\000\002X\002o\000\000\000\000\002X\000\000\000\000\000\000\002Y\000\000\000\000\000\000\002Y\002o\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002g\000\000\000\000\002l\002g\002\136\000\000\002l\000\000\002\138\000\000\002x\002i\001\132\002n\002x\000\000\001\132\002n\002l\000\000\002\140\000\000\002\024\000\000\002k\000\200\002x\000\000\001\132\002n\000\000\000\000\000\000\002z\000\000\000\000\000\000\002z\002\020\002\021\001e\000\000\002\020\002\021\001e\000\000\000\000\000\000\000\000\002z\000\000\000\000\000\000\002X\002o\000\000\000\000\002X\002i\000\000\000\000\002Y\002i\000\000\000\000\002Y\000\000\000\000\000\000\002\024\000\000\002k\000\200\002\024\002g\002k\000\200\000\000\002g\000\000\000\000\002l\000\000\002\142\002\020\002\021\001e\000\000\000\000\002x\000\000\001\132\002n\000\000\000\000\001\031\000\000\000\000\001 \002X\000\000\002o\000\000\000\000\000\000\002o\000\000\002Y\000\000\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002g\000\000\001\"\000\000\006\140\000\000\000\000\000\000\002l\000\000\002\144\000\000\002l\002i\002\146\000\000\002x\002i\001\132\002n\002x\000\000\001\132\002n\002\024\000\000\002k\000\200\002\024\000\000\002k\000\200\000\000\000\000\000\000\002\020\002\021\001e\000\000\002z\002\020\002\021\001e\002z\000\000\001*\000\000\000\000\000\000\000\000\002X\000\000\000\000\000\000\000\000\002X\002o\000\000\002Y\002i\002o\000\000\000\000\002Y\000\000\000\000\000\000\000\000\000\000\000\000\002\024\002g\002k\000\200\001\016\000\000\002g\000\000\000\000\000\000\001\023\001$\000\000\002l\000\000\002\148\000\000\002l\000\000\002\150\000\000\002x\000\000\001\132\002n\002x\000\000\001\132\002n\000\000\000\000\000\000\002o\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\020\002\021\001e\002z\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\000\000\000\000\001>\002X\000\000\000\000\002l\002i\002\152\001%\000\000\002Y\002i\006\147\002x\000\000\001\132\002n\002\024\000\000\002k\000\200\000\000\002\024\002g\002k\000\200\000\000\002\020\002\021\001e\000\000\000\000\002\020\002\021\001e\001.\002z\000\000\001H\000\000\000\000\000\000\002X\000\000\000\000\000\000\000\000\002X\000\000\002o\002Y\000\000\000\000\000\000\002o\002Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002g\000\000\000\000\000\000\000\000\002g\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\000\000\002\154\000\000\000\000\002l\002i\002\156\002x\000\000\001\132\002n\000\000\002x\000\000\001\132\002n\002\024\000\000\002k\000\200\000\000\000\000\000\000\000\000\000\000\000\000\002\020\002\021\001e\000\000\002z\000\000\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\000\000\002X\000\000\000\000\000\000\002i\000\000\000\000\002o\002Y\002i\000\000\000\000\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\002\024\002g\002k\000\200\000\000\002\020\002\021\001e\000\000\000\000\000\000\000\000\000\000\000\000\002l\000\000\002\158\000\000\000\000\000\000\002X\000\000\002x\000\000\001\132\002n\000\000\002o\002Y\000\000\000\000\000\000\002o\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002g\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\000\000\002\160\000\000\000\000\002l\002i\002\162\002x\000\000\001\132\002n\000\000\002x\000\000\001\132\002n\002\024\000\000\002k\000\200\000\000\002\020\002\021\001e\000\000\000\000\000\000\000\000\000\000\000\000\002z\000\000\000\000\000\000\000\000\002z\002X\000\000\000\000\000\000\002\171\001e\000\000\000\000\002Y\002i\000\000\000\000\002o\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\024\002g\002k\000\200\002\225\001v\000\000\001h\001i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001d\001e\000\000\002l\000\000\002\164\000\000\000\000\000\000\002\188\000\000\002x\000\000\001\132\002n\000\000\002o\002\191\001d\001e\001f\002\192\000\000\001h\001i\000\000\000\000\002\188\000\000\000\000\002\230\002\246\002\247\000\000\002z\002\191\000\000\000\000\001f\002\192\000\000\001h\001i\002l\002i\002\166\002\020\002\021\001e\000\000\000\000\002x\000\000\001\132\002n\002\024\000\000\002k\000\200\000\000\006\021\002X\001\127\000\000\000\000\000\000\000\000\000\000\000\000\002Y\000\000\000\000\000\000\001n\002z\007\020\000\200\000\000\007\021\000\000\000\000\006\024\002g\000\000\000\000\000\000\000\000\002o\000\000\000\000\006\025\000\000\000\000\000\000\001m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001n\002\250\000\000\000\200\000\000\000\000\000\000\001m\000\000\002l\000\000\002\168\000\000\000\000\006\026\000\000\000\000\002x\001n\001\132\002n\000\200\000\000\000\000\000\000\000\000\000\000\001\129\000\000\000\000\002\020\002\021\001e\000\000\002\193\001\130\002i\001\132\001l\000\000\002z\001\031\000\000\000\000\005\012\002X\000\000\002\024\006\027\002k\000\200\000\000\002\193\002Y\002\195\000\000\006\028\000\000\000\000\001\129\000\000\000\000\000\000\002\020\002\021\001e\002g\001\157\001\"\001\132\001l\000\000\002\194\000\000\000\000\000\000\007\022\001\129\002X\002o\000\000\000\000\002\020\002\021\001e\001\157\002Y\001\132\001l\000\000\000\000\000\000\000\000\000\000\000\000\006\030\000\000\002X\000\000\002g\000\000\000\000\000\000\000\000\006\031\002Y\002l\000\000\003\005\006!\000\000\005\014\000\000\000\000\002x\000\000\001\132\002n\002g\006#\000\000\000\000\000\000\000\000\000\000\002i\002\020\002\021\001e\000\000\000\000\000\000\000\000\000\000\000\000\006$\002\024\002z\002k\000\200\001\016\002X\002\020\002\021\001e\000\000\001\023\005\017\000\000\002Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002X\002i\000\000\000\000\000\000\002g\000\000\000\000\002Y\000\000\000\000\002o\002\024\000\000\002k\000\200\000\000\000\000\000\000\000\000\002i\002g\000\000\000\000\002\020\002\021\001e\000\000\000\000\000\000\000\000\002\024\000\000\002k\000\200\000\000\000\000\000\000\002l\002X\003\"\005\018\000\000\000\000\002o\000\000\002x\002Y\001\132\002n\000\000\000\000\000\000\004\220\000\000\005\021\000\000\005\020\000\000\000\000\002g\000\000\000\000\002o\002i\000\000\000\000\000\000\001.\002z\000\000\002l\000\000\003(\000\000\002\024\005#\002k\000\200\002x\002i\001\132\002n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\002\024\003-\002k\000\200\002\020\002\021\001e\002x\000\000\001\132\002n\002z\000\000\005$\006\199\005%\002o\000\000\000\000\002X\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002Y\002i\000\000\002z\000\000\002o\000\000\000\000\000\000\000\000\000\000\000\000\002\024\002g\002k\000\200\002l\005&\0035\000\000\000\000\000\000\000\000\000\000\002x\000\000\001\132\002n\000\000\000\000\000\000\000\000\002l\000\000\003:\000\000\000\000\000\000\000\000\000\000\002x\000\000\001\132\002n\002o\000\000\000\000\002z\000\000\000\000\005'\002\020\002\021\001e\000\000\000\000\000\000\000\000\000\000\005(\000\000\005)\000\000\002z\000\000\000\000\002X\000\000\000\000\000\000\000\000\002l\002i\003<\002Y\002\020\002\021\001e\000\000\002x\000\000\001\132\002n\002\024\005e\002k\000\200\002g\000\000\000\000\002X\002\020\002\021\001e\000\000\000\000\001\031\000\000\002Y\001 \000\000\000\000\002z\002\020\002\021\001e\002X\005+\006\201\001d\001e\002g\005-\0057\002Y\002o\000\000\000\000\002X\000\000\000\000\000\000\005a\001\"\000\000\000\000\002Y\002g\000\000\001f\001v\000\000\001h\001i\000\000\000\000\000\000\000\000\005b\002g\000\000\000\000\002l\000\000\003?\000\000\002i\000\000\000\000\000\000\002x\000\000\001\132\002n\002\020\002\021\001e\002\024\000\000\002k\000\200\000\000\000\000\000\000\006\021\000\000\001*\000\000\000\000\002X\002i\000\000\001w\002z\001x\0024\000\000\002Y\000\000\007\020\000\000\002\024\007\021\002k\000\200\006\024\002i\000\000\000\000\002o\002g\000\000\000\000\000\000\006\025\001\016\000\000\002\024\002i\002k\000\200\001\023\001$\001\127\000\000\000\000\000\000\000\000\000\000\002\024\000\000\002k\000\200\002o\001n\000\000\002l\000\200\003F\000\000\000\000\000\000\000\000\006\026\002x\003\129\001\132\002n\000\000\002o\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002l\002o\003K\000\000\000\000\000\000\006\139\002z\002x\002i\001\132\002n\000\000\001%\000\000\000\000\002l\006\027\003P\000\000\002\024\000\000\002k\000\200\002x\006\028\001\132\002n\002l\000\000\003S\002z\000\000\001\129\002\171\001e\002x\000\000\001\132\002n\001.\001\130\000\000\001\132\001l\007\026\000\000\002z\002\020\002\021\001e\000\000\002o\000\000\002\225\001v\000\000\001h\001i\002z\000\000\000\000\000\000\002X\006\030\000\000\000\000\000\000\000\000\000\000\000\000\002Y\000\000\006\031\000\000\000\000\000\000\000\000\006!\002l\000\000\003\133\002\171\001e\002g\000\000\000\000\002x\006#\001\132\002n\000\000\000\000\000\000\000\000\000\000\002\230\002\246\002\247\002\171\001e\000\000\002\225\001v\006$\001h\001i\000\000\000\000\000\000\002z\002\171\001e\000\000\000\000\000\000\000\000\001d\001e\002\225\001v\000\000\001h\001i\000\000\000\000\000\000\000\000\001\127\000\000\000\000\002\225\001v\000\000\001h\001i\000\000\001f\001v\001n\001h\001i\000\200\002i\002\230\002\246\002\247\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\024\000\000\002k\000\200\002\020\002\021\001e\002\230\002\246\002\247\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\144\002\230\002\246\002\247\001\127\000\000\000\000\000\000\001w\002\022\001x\006\245\000\000\006\247\002o\001n\000\000\000\000\000\200\000\000\000\000\001\127\000\000\000\000\000\000\000\000\001\129\000\000\000\000\000\000\000\000\000\000\001n\001\127\001\130\000\200\001\132\001l\000\000\001\127\000\000\002l\000\000\003\135\001n\000\000\000\000\000\200\004\r\002x\001n\001\132\002n\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\195\001d\001e\000\000\000\000\000\000\000\000\002z\000\000\001\129\000\000\000\000\005\229\000\000\000\000\000\000\002\023\001\130\000\000\001\132\001l\001f\001v\000\000\001h\001i\001\129\002\024\000\000\002k\000\200\000\000\000\000\000\000\001\130\000\000\001\132\001l\001\129\000\000\000\000\000\000\000\000\000\000\001\129\000\000\001\130\001\031\001\132\001l\001 \000\000\001\130\0012\001\132\001l\001\031\000\000\000\000\001 \000\000\000\000\0012\000\000\001w\000\000\001x\006:\000\000\000\000\000\000\000\000\000\000\0013\001\"\000\000\000\000\000\000\000\000\000\000\0014\000\000\0013\001\"\001d\001e\002l\000\000\000\000\001M\000\000\001d\001e\000\000\002m\001\127\001\132\002n\000\000\000\000\000\000\000\000\000\000\000\000\001f\001v\001n\001h\001i\000\200\000\000\001f\001v\000\000\001h\001i\000\000\001*\001d\001e\000\000\000\000\000\000\000\000\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0018\000\000\000\000\000\000\001f\001v\000\000\001h\001i\0018\000\000\000\000\001\016\001w\000\000\001x\001\158\000\000\001\023\001$\001w\001\016\001x\001\136\000\000\000\000\000\000\001\023\001$\000\000\000\000\001\129\000\000\001d\001e\000\000\000\000\000\000\000\000\001\130\000\000\001\132\001l\000\000\001\127\000\000\000\000\001w\000\000\001x\001\133\001\127\000\000\001f\001v\001n\001h\001i\000\200\000\000\000\000\000\000\001n\001>\000\000\000\200\000\000\000\000\000\000\000\000\001%\000\000\001>\000\000\001F\000\000\000\000\000\000\001\127\001%\000\000\001d\001e\001F\000\000\000\000\000\000\001d\001e\001n\000\000\000\000\000\200\000\000\000\000\000\000\001w\001.\001x\001z\001H\001f\001v\000\000\001h\001i\001.\001f\001v\001H\001h\001i\000\000\000\000\001\129\000\000\000\000\000\000\000\000\001d\001e\001\129\001\130\000\000\001\132\001l\000\000\001\127\000\000\001\130\000\000\001\132\001l\000\000\000\000\000\000\000\000\000\000\001n\001f\001v\000\200\001h\001i\001w\000\000\001x\001}\001\129\000\000\001w\000\000\001x\001\128\000\000\000\000\001\130\000\000\001\132\001l\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001d\001e\000\000\000\000\000\000\001\127\000\000\000\000\000\000\000\000\000\000\001\127\001w\000\000\001x\001\131\001n\000\000\000\000\000\200\001f\001v\001n\001h\001i\000\200\000\000\001\129\000\000\000\000\000\000\000\000\001d\001e\000\000\001\130\000\000\001\132\001l\000\000\000\000\000\000\000\000\001\127\000\000\000\000\000\000\000\000\000\000\001d\001e\000\000\001f\001v\001n\001h\001i\000\200\000\000\000\000\000\000\000\000\000\000\001w\000\000\001x\001\141\000\000\000\000\001f\001v\000\000\001h\001i\000\000\001\129\000\000\000\000\000\000\001d\001e\001\129\000\000\001\130\000\000\001\132\001l\000\000\002\221\001\130\000\000\001\132\001l\000\000\001\127\001w\002\224\001x\001\144\001f\002\192\000\000\001h\001i\000\000\001n\000\000\000\000\000\200\000\000\000\000\000\000\001w\001\129\001x\002N\000\000\000\000\000\000\000\000\000\000\001\130\000\000\001\132\001l\000\000\001\127\000\000\001d\001e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001n\000\000\000\000\000\200\000\000\000\000\001\127\000\000\000\000\000\000\000\000\001f\001v\000\000\001h\001i\000\000\001n\000\000\000\000\000\200\000\000\000\000\000\000\000\000\001d\001e\001\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\130\001m\001\132\001l\000\000\000\000\000\000\001d\001e\000\000\001f\001v\001n\001h\001i\000\200\000\000\000\000\000\000\001w\000\000\001x\002\235\000\000\001\129\000\000\000\000\001f\001v\000\000\001h\001i\001\130\000\000\001\132\001l\000\000\000\000\000\000\001d\001e\001\129\000\000\000\000\000\000\000\000\002\193\000\000\000\000\001\130\001\127\001\132\001l\001w\000\000\001x\002\238\000\000\000\000\001f\001v\001n\001h\001i\000\200\000\000\002\020\002\021\001e\000\000\001w\001\129\001x\002\241\000\000\000\000\000\000\000\000\000\000\001\157\000\000\001\132\001l\000\000\001\127\000\000\001d\001e\000\000\002S\001\031\000\000\000\000\001 \000\000\001n\001I\000\000\000\200\000\000\000\000\001\127\001w\000\000\001x\002\249\001f\001v\000\000\001h\001i\000\000\001n\000\000\000\000\000\200\001K\001\"\000\000\000\000\001\129\000\000\004\213\000\000\000\000\000\000\000\000\000\000\001\130\001\031\001\132\001l\001 \001\127\000\000\001I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001n\000\000\000\000\000\200\000\000\001w\000\000\001x\004H\000\000\001\129\001K\001\"\000\000\000\000\000\000\001*\002\023\001\130\000\000\001\132\001l\000\000\000\000\000\000\000\000\000\000\001\129\002\024\000\000\002k\000\200\000\000\0018\000\000\001\130\001\127\001\132\001l\000\000\000\000\000\000\001d\001e\000\000\001\016\000\000\001n\000\000\000\000\000\200\001\023\001$\000\000\001\031\001*\000\000\001 \000\000\001\129\0012\000\000\001f\002\192\000\000\001h\001i\001\130\000\000\001\132\001l\000\000\0018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0017\001\"\000\000\000\000\001\016\000\000\000\000\002l\001d\001e\001\023\001$\000\000\000\000\000\000\002m\001>\001\132\002n\000\000\000\000\000\000\000\000\001%\000\000\000\000\001\129\005\011\001f\002\192\000\000\001h\001i\000\000\001\130\000\000\001\132\001l\000\000\000\000\000\000\000\000\000\000\000\000\001*\000\000\000\000\000\000\001d\001e\001.\000\000\000\000\001H\000\000\001>\001m\000\000\000\000\000\000\000\000\0018\001%\001d\001e\000\000\001F\001n\001f\002\192\000\200\001h\001i\001\016\000\000\000\000\001d\001e\000\000\001\023\001$\000\000\000\000\001f\002\192\000\000\001h\001i\000\000\001.\000\000\000\000\001H\005\157\000\000\000\000\001f\002\192\000\000\001h\001i\003r\001m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001n\000\000\000\000\000\200\000\000\000\000\000\000\003t\000\000\000\000\000\000\001>\000\000\001\129\000\000\000\000\000\000\000\000\001%\000\000\000\000\001\157\001F\001\132\001l\000\000\000\000\000\000\000\000\001m\000\000\000\000\000\000\000\000\003r\000\000\000\000\000\000\000\000\000\000\001n\000\000\000\000\000\200\001m\001.\000\000\000\000\001H\000\000\000\000\000\000\000\000\003s\000\000\001n\000\000\001m\000\200\001\129\001d\001e\000\000\000\000\000\000\000\000\000\000\001\157\001n\001\132\001l\000\200\000\000\000\000\003r\000\000\000\000\005\181\000\000\000\000\001f\002\192\000\000\001h\001i\000\000\000\000\000\000\000\000\006\b\000\000\000\000\000\000\003w\000\000\000\000\000\000\001d\001e\001\129\000\000\000\000\002\193\000\000\000\000\000\000\000\000\001\157\000\000\001\132\001l\000\000\000\000\000\000\001\129\000\000\000\000\001f\002\192\000\000\001h\001i\001\157\000\000\001\132\001l\000\000\001\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\157\006\n\001\132\001l\001d\001e\000\000\000\000\000\000\000\000\000\000\001d\001e\000\000\000\000\000\000\001d\001e\000\000\001m\000\000\000\000\000\000\000\000\001f\002\192\000\000\001h\001i\000\000\001n\001f\002\192\000\200\001h\001i\001f\002\192\000\000\001h\001i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001d\001e\001m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\193\000\000\005#\001n\000\000\000\000\000\200\000\000\000\000\000\000\001f\002\192\000\000\001h\001i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\129\000\000\000\000\000\000\000\000\005$\006\181\005%\001\157\001m\001\132\001l\005\208\000\000\000\000\001\031\001m\000\000\001 \000\000\001n\001m\000\000\000\200\000\000\000\000\000\000\001n\000\000\000\000\000\200\000\000\001n\000\000\000\000\000\200\005&\001\129\000\000\000\000\000\000\000\000\001\"\000\000\000\000\001\157\000\000\001\132\001l\000\000\000\000\000\000\004\198\000\000\005\208\000\000\000\000\000\000\005\221\001m\000\000\006\b\000\000\000\000\000\000\000\000\006\b\005\154\001\031\005'\001n\001 \000\000\000\200\000\000\000\000\000\000\000\000\005(\001\129\005)\000\000\000\000\000\000\000\000\001*\001\129\001\157\000\000\001\132\001l\001\129\000\000\000\000\001\157\001\"\001\132\001l\000\000\001\157\005\220\001\132\001l\005e\003v\003\237\000\000\001\031\006\t\001\031\001 \000\000\001 \006\017\001\016\000\000\000\000\000\000\000\000\006}\001\023\001$\000\000\000\000\000\000\000\000\005+\000\000\000\000\001\129\000\000\005-\0057\006\021\001\"\000\000\001\"\001\157\001*\001\132\001l\005a\000\000\000\000\004\198\000\000\004\198\000\000\007\020\000\000\000\000\007\021\000\000\000\000\006\024\000\000\000\000\005b\000\000\005\168\000\000\005\178\000\000\006\025\000\000\001>\000\000\001\016\000\000\000\000\000\000\000\000\001%\001\023\001$\000\000\004\203\001*\000\000\001*\001d\001e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\026\000\000\002\020\002\021\001e\000\000\000\000\001.\001f\002\177\001H\001h\001i\000\000\001\016\000\000\001\016\000\000\000\000\000\000\001\023\001$\001\023\001$\001\031\003T\001>\001 \000\000\000\000\000\000\000\000\000\000\001%\006\027\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\028\001\031\000\000\000\000\001 \000\000\000\000\000\000\000\000\001\"\001\031\000\000\000\000\001 \000\000\000\000\000\000\000\000\001.\002\214\007\031\003\244\000\000\001>\000\000\001>\000\000\000\000\001\"\000\000\001%\000\000\001%\000\000\004\203\000\000\004\203\001\"\000\000\006\030\001m\000\000\000\000\000\000\000\000\000\000\005#\003\237\006\031\000\000\000\000\001n\001*\006!\000\200\002\023\000\000\001.\000\000\001.\001H\003\240\001H\006#\000\000\000\000\002\024\000\000\002k\000\200\000\000\001*\001\031\000\000\005$\001 \005%\000\000\000\000\006$\001*\001\016\000\000\000\000\000\000\000\000\000\000\001\023\001$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\001\016\003V\000\000\000\000\005\203\005&\001\023\001$\000\000\001\016\001\129\000\000\000\000\000\000\001\031\001\023\001$\001 \001\157\000\000\001\132\001l\000\000\000\000\000\000\002l\001\031\000\000\000\000\001 \000\000\000\000\001>\002m\000\000\001\132\002n\000\000\005'\001%\000\000\001\"\001*\002\185\000\000\000\000\000\000\005(\000\000\005)\000\000\001>\000\000\001\"\000\000\000\000\000\000\000\000\001%\000\000\001>\000\000\004\231\000\000\000\000\004\234\001.\001%\006\021\001H\000\000\001\016\005*\000\000\000\000\000\000\000\000\001\023\001$\000\000\001\031\000\000\000\000\001 \001*\001.\007\011\000\000\001H\006\024\001\031\000\000\006\225\001 \001.\005+\001*\003\244\006\025\000\000\005-\0057\000\000\000\000\000\000\000\000\000\000\001\"\000\000\000\000\005a\000\000\000\000\001\016\000\000\000\000\000\000\001\"\000\000\001\023\001$\001\031\001>\000\000\001 \001\016\005b\006\026\000\000\001%\000\000\001\023\001$\004\218\000\000\000\000\000\000\000\000\000\000\001\031\000\000\000\000\001 \000\000\000\000\000\000\000\000\000\000\001\"\000\000\001*\000\000\000\000\000\000\001\031\000\000\001.\001 \000\000\001H\001*\006\027\000\000\000\000\001>\000\000\001\"\000\000\000\000\006\028\000\000\001%\000\000\000\000\001<\004\231\001>\000\000\005\249\001\016\000\000\001\"\000\000\001%\000\000\001\023\001$\006\226\000\000\001\016\007\012\001*\000\000\000\000\000\000\001\023\001$\000\000\001.\000\000\000\000\001H\000\000\000\000\000\000\000\000\000\000\000\000\006\030\001*\001.\000\000\000\000\001H\000\000\001\031\000\000\006\031\001 \000\000\001\016\000\000\006!\000\000\001*\001\031\001\023\001$\001 \000\000\001>\000\000\006#\000\000\000\000\000\000\000\000\001%\001\016\000\000\001>\006\186\001\"\001\031\001\023\001$\001 \001%\006$\000\000\000\000\001X\001\"\001\016\000\000\000\000\000\000\000\000\000\000\001\023\001$\002\020\002\021\001e\001.\000\000\000\000\001H\000\000\000\000\001\"\001>\000\000\000\000\001.\000\000\000\000\001H\001%\002\020\002\021\001e\001\174\000\000\002U\001*\002\020\002\021\001e\001>\000\000\000\000\000\000\000\000\000\000\001*\001%\000\000\000\000\000\000\000\000\000\000\002_\000\000\001>\001.\000\000\000\000\001H\002j\000\000\001%\000\000\001*\001\016\001\212\002\020\002\021\001e\000\000\001\023\001$\000\000\001.\001\016\000\000\001D\000\000\000\000\000\000\001\023\001$\000\000\001\031\000\000\000\000\001 \000\000\001.\002y\000\000\001H\001\016\000\000\000\000\000\000\000\000\000\000\001\023\001$\000\000\001\031\000\000\000\000\001 \000\000\002\023\000\000\000\000\000\000\001\"\000\000\000\000\000\000\000\000\001>\000\000\002\024\000\000\002k\000\200\000\000\001%\000\000\002\023\001>\001\214\000\000\001\"\000\000\000\000\002\023\001%\000\000\000\000\002\024\002+\002k\000\200\000\000\000\000\000\000\002\024\001>\002k\000\200\000\000\000\000\000\000\001.\001%\000\000\001H\001*\002>\000\000\000\000\000\000\000\000\001.\000\000\002\023\001H\000\000\000\000\000\000\001\031\000\000\000\000\001 \000\000\001*\002\024\000\000\002k\000\200\002l\001.\000\000\000\000\001H\000\000\001\016\000\000\002m\000\000\001\132\002n\001\023\001$\000\000\000\000\000\000\001\"\002l\000\000\000\000\000\000\000\000\000\000\001\016\002l\002m\000\000\001\132\002n\001\023\001$\000\000\002m\000\000\001\132\002n\000\000\000\000\000\000\001\031\000\000\000\000\001 \000\000\000\000\000\000\000\000\000\000\001\031\000\000\000\000\001 \000\000\000\000\002l\000\000\001>\001\031\000\000\001*\001 \000\000\002m\001%\001\132\002n\001\"\002\182\000\000\000\000\000\000\000\000\000\000\000\000\001>\001\"\000\000\002\020\002\021\001e\000\000\001%\000\000\000\000\001\"\002\187\000\000\000\000\001\016\000\000\001.\000\000\000\000\001H\001\023\001$\000\000\000\000\001\031\000\000\003\027\001 \000\000\000\000\000\000\000\000\000\000\001\031\001.\001*\001 \001H\000\000\000\000\000\000\000\000\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001*\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\000\000\000\000\001\016\001>\001\031\000\000\000\000\001 \001\023\001$\001%\001\016\000\000\000\000\002\204\000\000\000\000\001\023\001$\001\031\001\016\001\031\001 \000\000\001 \000\000\001\023\001$\000\000\000\000\000\000\001\"\001*\000\000\000\000\000\000\002\023\001.\000\000\000\000\001H\001*\000\000\000\000\000\000\000\000\001\"\002\024\001\"\002k\000\200\000\000\000\000\001>\000\000\000\000\000\000\000\000\000\000\000\000\001%\001\016\001>\000\000\002\211\000\000\000\000\001\023\001$\001%\001\016\001>\000\000\002\218\001*\000\000\001\023\001$\001%\000\000\001\031\000\000\002\227\001 \000\000\000\000\000\000\001.\000\000\001*\001H\001*\000\000\000\000\000\000\000\000\001.\000\000\000\000\001H\000\000\000\000\000\000\001\016\000\000\001.\002l\001\"\001H\001\023\001$\000\000\001>\000\000\002m\000\000\001\132\002n\001\016\001%\001\016\001>\000\000\004W\001\023\001$\001\023\001$\001%\000\000\001\031\000\000\004\175\005\012\000\000\000\000\000\000\000\000\000\000\001\031\000\000\001\031\005\012\000\000\001 \000\000\001.\000\000\000\000\001H\001*\000\000\000\000\000\000\001>\001.\001\031\001\"\001H\001 \000\000\001%\000\000\000\000\000\000\004\187\001\"\000\000\001\"\001>\000\000\001>\001\031\000\000\000\000\001 \001%\000\000\001%\001\016\004\200\000\000\004\217\001\"\000\000\001\023\001$\001\031\001.\001\031\001 \001H\005\012\000\000\000\000\000\000\000\000\000\000\000\000\001\"\005\014\000\000\000\000\001.\000\000\001.\001H\000\000\001H\005\014\000\000\001*\000\000\000\000\001\"\000\000\001\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001*\000\000\000\000\001\016\001>\000\000\000\000\000\000\000\000\001\023\005\017\001%\001\016\000\000\001\016\004\233\001*\000\000\001\023\005\017\001\023\001$\001\031\000\000\000\000\005\012\000\000\000\000\000\000\001\016\000\000\001*\000\000\005\014\000\000\001\023\001$\000\000\001.\000\000\000\000\001H\000\000\000\000\000\000\001\016\000\000\000\000\000\000\001\"\000\000\001\023\001$\000\000\001\031\000\000\000\000\001 \000\000\000\000\001\016\005\018\001\016\000\000\000\000\001>\001\023\001$\001\023\005\017\005\018\001\031\001%\004\220\001 \005\019\005\133\005\020\000\000\000\000\001>\001\"\004\220\000\000\005\031\000\000\005\020\001%\001.\000\000\000\000\005\151\005\014\000\000\000\000\000\000\001>\001.\001\"\001.\000\000\000\000\001H\001%\000\000\000\000\000\000\005\175\000\000\000\000\000\000\001>\000\000\001\031\001.\000\000\001 \001H\001%\000\000\005\018\001\016\006=\000\000\001*\000\000\000\000\001\023\005\017\000\000\001.\000\000\004\220\001H\005\235\000\000\005\020\000\000\000\000\000\000\001\"\001*\000\000\000\000\000\000\001.\001\031\001.\001H\001 \000\000\000\000\000\000\001\016\001\031\000\000\000\000\001 \000\000\001\023\001$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\016\000\000\000\000\001\"\000\000\000\000\001\023\001$\000\000\005\018\000\000\001\"\000\000\001*\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\220\000\000\006\005\000\000\005\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\001.\000\000\000\000\000\000\000\000\001%\001\016\000\000\000\000\006\146\001*\000\000\001\023\001$\000\000\001>\000\000\000\000\001*\000\000\000\000\000\000\001%\000\000\000\000\000\000\006\150\000\000\000\000\000\000\000\000\000\000\001.\000\000\000\000\001H\000\000\000\000\000\000\001\016\000\000\000\000\000\000\000\000\000\000\001\023\001$\001\016\000\000\001.\000\000\000\000\001H\001\023\001$\000\000\000\000\001>\000\000\000\000\000\000\000\000\000\000\000\000\001%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001>\001.\000\000\000\000\001\207\000\000\000\000\001%\001>\000\000\000\000\000\000\000\000\000\000\000\000\001%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001.\000\000\000\000\001\209\000\000\000\000\000\000\000\000\001.\000\000\000\000\003\239")) and semantic_action = [| @@ -1332,9 +1336,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3641 "parsing/parser.mly" +# 3657 "parsing/parser.mly" ( "+" ) -# 1338 "parsing/parser.ml" +# 1342 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1357,9 +1361,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3642 "parsing/parser.mly" +# 3658 "parsing/parser.mly" ( "+." ) -# 1363 "parsing/parser.ml" +# 1367 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1382,9 +1386,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.core_type) = -# 3198 "parsing/parser.mly" +# 3214 "parsing/parser.mly" ( _1 ) -# 1388 "parsing/parser.ml" +# 1392 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1429,24 +1433,24 @@ module Tables = struct let _endpos = _endpos_tyvar_ in let _v : (Parsetree.core_type) = let _1 = let _1 = -# 3201 "parsing/parser.mly" +# 3217 "parsing/parser.mly" ( Ptyp_alias(ty, tyvar) ) -# 1435 "parsing/parser.ml" +# 1439 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_tyvar_, _startpos_ty_) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 1444 "parsing/parser.ml" +# 1448 "parsing/parser.ml" in -# 3203 "parsing/parser.mly" +# 3219 "parsing/parser.mly" ( _1 ) -# 1450 "parsing/parser.ml" +# 1454 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1492,30 +1496,30 @@ module Tables = struct let _v : (let_binding) = let attrs2 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 1498 "parsing/parser.ml" +# 1502 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined2_ in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 1507 "parsing/parser.ml" +# 1511 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2478 "parsing/parser.mly" +# 2480 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in mklb ~loc:_sloc false body attrs ) -# 1519 "parsing/parser.ml" +# 1523 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1538,9 +1542,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3528 "parsing/parser.mly" +# 3544 "parsing/parser.mly" ( _1 ) -# 1544 "parsing/parser.ml" +# 1548 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1563,9 +1567,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3529 "parsing/parser.mly" +# 3545 "parsing/parser.mly" ( Lident _1 ) -# 1569 "parsing/parser.ml" +# 1573 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1602,9 +1606,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.core_type) = -# 3259 "parsing/parser.mly" +# 3275 "parsing/parser.mly" ( _2 ) -# 1608 "parsing/parser.ml" +# 1612 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1663,25 +1667,15 @@ module Tables = struct let _endpos = _endpos__5_ in let _v : (Parsetree.core_type) = let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined3_, _startpos__1_inlined3_, _1_inlined3) in - let _1 = - let _1 = -# 3320 "parsing/parser.mly" - ( Ptyp_package (package_type_of_module_type _1) ) -# 1671 "parsing/parser.ml" - in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 850 "parsing/parser.mly" - ( mktyp ~loc:_sloc _1 ) -# 1679 "parsing/parser.ml" - - in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in -# 3321 "parsing/parser.mly" - ( _1 ) -# 1685 "parsing/parser.ml" +# 3335 "parsing/parser.mly" + ( let (lid, cstrs, attrs) = package_type_of_module_type _1 in + let descr = Ptyp_package (lid, cstrs) in + mktyp ~loc:_sloc ~attrs descr ) +# 1679 "parsing/parser.ml" in let _3 = @@ -1689,24 +1683,24 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 1695 "parsing/parser.ml" +# 1689 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 1701 "parsing/parser.ml" +# 1695 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3261 "parsing/parser.mly" +# 3277 "parsing/parser.mly" ( wrap_typ_attrs ~loc:_sloc (reloc_typ ~loc:_sloc _4) _3 ) -# 1710 "parsing/parser.ml" +# 1704 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1737,24 +1731,24 @@ module Tables = struct let _endpos = _endpos__2_ in let _v : (Parsetree.core_type) = let _1 = let _1 = -# 3264 "parsing/parser.mly" +# 3280 "parsing/parser.mly" ( Ptyp_var _2 ) -# 1743 "parsing/parser.ml" +# 1737 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 1752 "parsing/parser.ml" +# 1746 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 1758 "parsing/parser.ml" +# 1752 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1778,23 +1772,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.core_type) = let _1 = let _1 = -# 3266 "parsing/parser.mly" +# 3282 "parsing/parser.mly" ( Ptyp_any ) -# 1784 "parsing/parser.ml" +# 1778 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 1792 "parsing/parser.ml" +# 1786 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 1798 "parsing/parser.ml" +# 1792 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1823,35 +1817,35 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 1829 "parsing/parser.ml" +# 1823 "parsing/parser.ml" in let tys = -# 3311 "parsing/parser.mly" +# 3327 "parsing/parser.mly" ( [] ) -# 1835 "parsing/parser.ml" +# 1829 "parsing/parser.ml" in -# 3269 "parsing/parser.mly" +# 3285 "parsing/parser.mly" ( Ptyp_constr(tid, tys) ) -# 1840 "parsing/parser.ml" +# 1834 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 1849 "parsing/parser.ml" +# 1843 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 1855 "parsing/parser.ml" +# 1849 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1887,20 +1881,20 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 1893 "parsing/parser.ml" +# 1887 "parsing/parser.ml" in let tys = -# 3313 "parsing/parser.mly" +# 3329 "parsing/parser.mly" ( [ty] ) -# 1899 "parsing/parser.ml" +# 1893 "parsing/parser.ml" in -# 3269 "parsing/parser.mly" +# 3285 "parsing/parser.mly" ( Ptyp_constr(tid, tys) ) -# 1904 "parsing/parser.ml" +# 1898 "parsing/parser.ml" in let _startpos__1_ = _startpos_ty_ in @@ -1908,15 +1902,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 1914 "parsing/parser.ml" +# 1908 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 1920 "parsing/parser.ml" +# 1914 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -1967,9 +1961,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 1973 "parsing/parser.ml" +# 1967 "parsing/parser.ml" in let tys = @@ -1977,24 +1971,24 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 1981 "parsing/parser.ml" +# 1975 "parsing/parser.ml" in -# 975 "parsing/parser.mly" +# 979 "parsing/parser.mly" ( xs ) -# 1986 "parsing/parser.ml" +# 1980 "parsing/parser.ml" in -# 3315 "parsing/parser.mly" +# 3331 "parsing/parser.mly" ( tys ) -# 1992 "parsing/parser.ml" +# 1986 "parsing/parser.ml" in -# 3269 "parsing/parser.mly" +# 3285 "parsing/parser.mly" ( Ptyp_constr(tid, tys) ) -# 1998 "parsing/parser.ml" +# 1992 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined1_ in @@ -2002,15 +1996,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2008 "parsing/parser.ml" +# 2002 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2014 "parsing/parser.ml" +# 2008 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2048,24 +2042,24 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Parsetree.core_type) = let _1 = let _1 = -# 3271 "parsing/parser.mly" +# 3287 "parsing/parser.mly" ( let (f, c) = _2 in Ptyp_object (f, c) ) -# 2054 "parsing/parser.ml" +# 2048 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2063 "parsing/parser.ml" +# 2057 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2069 "parsing/parser.ml" +# 2063 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2096,24 +2090,24 @@ module Tables = struct let _endpos = _endpos__2_ in let _v : (Parsetree.core_type) = let _1 = let _1 = -# 3273 "parsing/parser.mly" +# 3289 "parsing/parser.mly" ( Ptyp_object ([], Closed) ) -# 2102 "parsing/parser.ml" +# 2096 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2111 "parsing/parser.ml" +# 2105 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2117 "parsing/parser.ml" +# 2111 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2149,20 +2143,20 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 2155 "parsing/parser.ml" +# 2149 "parsing/parser.ml" in let tys = -# 3311 "parsing/parser.mly" +# 3327 "parsing/parser.mly" ( [] ) -# 2161 "parsing/parser.ml" +# 2155 "parsing/parser.ml" in -# 3277 "parsing/parser.mly" +# 3293 "parsing/parser.mly" ( Ptyp_class(cid, tys) ) -# 2166 "parsing/parser.ml" +# 2160 "parsing/parser.ml" in let _startpos__1_ = _startpos__2_ in @@ -2170,15 +2164,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2176 "parsing/parser.ml" +# 2170 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2182 "parsing/parser.ml" +# 2176 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2221,20 +2215,20 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 2227 "parsing/parser.ml" +# 2221 "parsing/parser.ml" in let tys = -# 3313 "parsing/parser.mly" +# 3329 "parsing/parser.mly" ( [ty] ) -# 2233 "parsing/parser.ml" +# 2227 "parsing/parser.ml" in -# 3277 "parsing/parser.mly" +# 3293 "parsing/parser.mly" ( Ptyp_class(cid, tys) ) -# 2238 "parsing/parser.ml" +# 2232 "parsing/parser.ml" in let _startpos__1_ = _startpos_ty_ in @@ -2242,15 +2236,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2248 "parsing/parser.ml" +# 2242 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2254 "parsing/parser.ml" +# 2248 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2308,9 +2302,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 2314 "parsing/parser.ml" +# 2308 "parsing/parser.ml" in let tys = @@ -2318,24 +2312,24 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 2322 "parsing/parser.ml" +# 2316 "parsing/parser.ml" in -# 975 "parsing/parser.mly" +# 979 "parsing/parser.mly" ( xs ) -# 2327 "parsing/parser.ml" +# 2321 "parsing/parser.ml" in -# 3315 "parsing/parser.mly" +# 3331 "parsing/parser.mly" ( tys ) -# 2333 "parsing/parser.ml" +# 2327 "parsing/parser.ml" in -# 3277 "parsing/parser.mly" +# 3293 "parsing/parser.mly" ( Ptyp_class(cid, tys) ) -# 2339 "parsing/parser.ml" +# 2333 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined1_ in @@ -2343,15 +2337,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2349 "parsing/parser.ml" +# 2343 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2355 "parsing/parser.ml" +# 2349 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2389,24 +2383,24 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Parsetree.core_type) = let _1 = let _1 = -# 3280 "parsing/parser.mly" +# 3296 "parsing/parser.mly" ( Ptyp_variant([_2], Closed, None) ) -# 2395 "parsing/parser.ml" +# 2389 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2404 "parsing/parser.ml" +# 2398 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2410 "parsing/parser.ml" +# 2404 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2456,24 +2450,24 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 2460 "parsing/parser.ml" +# 2454 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 2465 "parsing/parser.ml" +# 2459 "parsing/parser.ml" in -# 3325 "parsing/parser.mly" +# 3341 "parsing/parser.mly" ( _1 ) -# 2471 "parsing/parser.ml" +# 2465 "parsing/parser.ml" in -# 3282 "parsing/parser.mly" +# 3298 "parsing/parser.mly" ( Ptyp_variant(_3, Closed, None) ) -# 2477 "parsing/parser.ml" +# 2471 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -2481,15 +2475,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2487 "parsing/parser.ml" +# 2481 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2493 "parsing/parser.ml" +# 2487 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2546,24 +2540,24 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 2550 "parsing/parser.ml" +# 2544 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 2555 "parsing/parser.ml" +# 2549 "parsing/parser.ml" in -# 3325 "parsing/parser.mly" +# 3341 "parsing/parser.mly" ( _1 ) -# 2561 "parsing/parser.ml" +# 2555 "parsing/parser.ml" in -# 3284 "parsing/parser.mly" +# 3300 "parsing/parser.mly" ( Ptyp_variant(_2 :: _4, Closed, None) ) -# 2567 "parsing/parser.ml" +# 2561 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -2571,15 +2565,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2577 "parsing/parser.ml" +# 2571 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2583 "parsing/parser.ml" +# 2577 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2629,24 +2623,24 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 2633 "parsing/parser.ml" +# 2627 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 2638 "parsing/parser.ml" +# 2632 "parsing/parser.ml" in -# 3325 "parsing/parser.mly" +# 3341 "parsing/parser.mly" ( _1 ) -# 2644 "parsing/parser.ml" +# 2638 "parsing/parser.ml" in -# 3286 "parsing/parser.mly" +# 3302 "parsing/parser.mly" ( Ptyp_variant(_3, Open, None) ) -# 2650 "parsing/parser.ml" +# 2644 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -2654,15 +2648,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2660 "parsing/parser.ml" +# 2654 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2666 "parsing/parser.ml" +# 2660 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2693,24 +2687,24 @@ module Tables = struct let _endpos = _endpos__2_ in let _v : (Parsetree.core_type) = let _1 = let _1 = -# 3288 "parsing/parser.mly" +# 3304 "parsing/parser.mly" ( Ptyp_variant([], Open, None) ) -# 2699 "parsing/parser.ml" +# 2693 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2708 "parsing/parser.ml" +# 2702 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2714 "parsing/parser.ml" +# 2708 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2760,24 +2754,24 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 2764 "parsing/parser.ml" +# 2758 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 2769 "parsing/parser.ml" +# 2763 "parsing/parser.ml" in -# 3325 "parsing/parser.mly" +# 3341 "parsing/parser.mly" ( _1 ) -# 2775 "parsing/parser.ml" +# 2769 "parsing/parser.ml" in -# 3290 "parsing/parser.mly" +# 3306 "parsing/parser.mly" ( Ptyp_variant(_3, Closed, Some []) ) -# 2781 "parsing/parser.ml" +# 2775 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -2785,15 +2779,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2791 "parsing/parser.ml" +# 2785 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2797 "parsing/parser.ml" +# 2791 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2858,18 +2852,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 2862 "parsing/parser.ml" +# 2856 "parsing/parser.ml" in -# 915 "parsing/parser.mly" +# 919 "parsing/parser.mly" ( xs ) -# 2867 "parsing/parser.ml" +# 2861 "parsing/parser.ml" in -# 3353 "parsing/parser.mly" +# 3369 "parsing/parser.mly" ( _1 ) -# 2873 "parsing/parser.ml" +# 2867 "parsing/parser.ml" in let _3 = @@ -2877,24 +2871,24 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 2881 "parsing/parser.ml" +# 2875 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 2886 "parsing/parser.ml" +# 2880 "parsing/parser.ml" in -# 3325 "parsing/parser.mly" +# 3341 "parsing/parser.mly" ( _1 ) -# 2892 "parsing/parser.ml" +# 2886 "parsing/parser.ml" in -# 3292 "parsing/parser.mly" +# 3308 "parsing/parser.mly" ( Ptyp_variant(_3, Closed, Some _5) ) -# 2898 "parsing/parser.ml" +# 2892 "parsing/parser.ml" in let _endpos__1_ = _endpos__6_ in @@ -2902,15 +2896,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2908 "parsing/parser.ml" +# 2902 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2914 "parsing/parser.ml" +# 2908 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2934,23 +2928,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.core_type) = let _1 = let _1 = -# 3294 "parsing/parser.mly" +# 3310 "parsing/parser.mly" ( Ptyp_extension _1 ) -# 2940 "parsing/parser.ml" +# 2934 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 2948 "parsing/parser.ml" +# 2942 "parsing/parser.ml" in -# 3296 "parsing/parser.mly" +# 3312 "parsing/parser.mly" ( _1 ) -# 2954 "parsing/parser.ml" +# 2948 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -2974,23 +2968,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (string Asttypes.loc) = let _1 = let _1 = -# 3708 "parsing/parser.mly" +# 3724 "parsing/parser.mly" ( _1 ) -# 2980 "parsing/parser.ml" +# 2974 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 843 "parsing/parser.mly" +# 847 "parsing/parser.mly" ( mkloc _1 (make_loc _sloc) ) -# 2988 "parsing/parser.ml" +# 2982 "parsing/parser.ml" in -# 3710 "parsing/parser.mly" +# 3726 "parsing/parser.mly" ( _1 ) -# 2994 "parsing/parser.ml" +# 2988 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3028,24 +3022,24 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (string Asttypes.loc) = let _1 = let _1 = -# 3709 "parsing/parser.mly" +# 3725 "parsing/parser.mly" ( _1 ^ "." ^ _3.txt ) -# 3034 "parsing/parser.ml" +# 3028 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 843 "parsing/parser.mly" +# 847 "parsing/parser.mly" ( mkloc _1 (make_loc _sloc) ) -# 3043 "parsing/parser.ml" +# 3037 "parsing/parser.ml" in -# 3710 "parsing/parser.mly" +# 3726 "parsing/parser.mly" ( _1 ) -# 3049 "parsing/parser.ml" +# 3043 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3092,9 +3086,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3714 "parsing/parser.mly" +# 3730 "parsing/parser.mly" ( Attr.mk ~loc:(make_loc _sloc) _2 _3 ) -# 3098 "parsing/parser.ml" +# 3092 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3117,9 +3111,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.class_expr) = -# 1762 "parsing/parser.mly" +# 1768 "parsing/parser.mly" ( _1 ) -# 3123 "parsing/parser.ml" +# 3117 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3158,18 +3152,18 @@ module Tables = struct let _v : (Parsetree.class_expr) = let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 3164 "parsing/parser.ml" +# 3158 "parsing/parser.ml" in let _endpos = _endpos__3_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1764 "parsing/parser.mly" +# 1770 "parsing/parser.mly" ( wrap_class_attrs ~loc:_sloc _3 _2 ) -# 3173 "parsing/parser.ml" +# 3167 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3209,9 +3203,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1766 "parsing/parser.mly" +# 1772 "parsing/parser.mly" ( class_of_let_bindings ~loc:_sloc _1 _3 ) -# 3215 "parsing/parser.ml" +# 3209 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3274,34 +3268,34 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 3280 "parsing/parser.ml" +# 3274 "parsing/parser.ml" in + let _endpos__5_ = _endpos__1_inlined2_ in let _4 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 3288 "parsing/parser.ml" +# 3283 "parsing/parser.ml" in - let _endpos__4_ = _endpos__1_inlined1_ in let _3 = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 3295 "parsing/parser.ml" +# 3289 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1768 "parsing/parser.mly" - ( let loc = (_startpos__2_, _endpos__4_) in +# 1774 "parsing/parser.mly" + ( let loc = (_startpos__2_, _endpos__5_) in let od = Opn.mk ~override:_3 ~loc:(make_loc loc) _5 in mkclass ~loc:_sloc ~attrs:_4 (Pcl_open(od, _7)) ) -# 3305 "parsing/parser.ml" +# 3299 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3371,37 +3365,37 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 3377 "parsing/parser.ml" +# 3371 "parsing/parser.ml" in + let _endpos__5_ = _endpos__1_inlined3_ in let _4 = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 3385 "parsing/parser.ml" +# 3380 "parsing/parser.ml" in - let _endpos__4_ = _endpos__1_inlined2_ in let _3 = let _1 = _1_inlined1 in -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 3394 "parsing/parser.ml" +# 3388 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1768 "parsing/parser.mly" - ( let loc = (_startpos__2_, _endpos__4_) in +# 1774 "parsing/parser.mly" + ( let loc = (_startpos__2_, _endpos__5_) in let od = Opn.mk ~override:_3 ~loc:(make_loc loc) _5 in mkclass ~loc:_sloc ~attrs:_4 (Pcl_open(od, _7)) ) -# 3405 "parsing/parser.ml" +# 3399 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3431,9 +3425,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.class_expr) = -# 1772 "parsing/parser.mly" +# 1778 "parsing/parser.mly" ( Cl.attr _1 _2 ) -# 3437 "parsing/parser.ml" +# 3431 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3468,18 +3462,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 3472 "parsing/parser.ml" +# 3466 "parsing/parser.ml" in -# 915 "parsing/parser.mly" +# 919 "parsing/parser.mly" ( xs ) -# 3477 "parsing/parser.ml" +# 3471 "parsing/parser.ml" in -# 1775 "parsing/parser.mly" +# 1781 "parsing/parser.mly" ( Pcl_apply(_1, _2) ) -# 3483 "parsing/parser.ml" +# 3477 "parsing/parser.ml" in let _endpos__1_ = _endpos_xs_ in @@ -3487,15 +3481,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 3493 "parsing/parser.ml" +# 3487 "parsing/parser.ml" in -# 1778 "parsing/parser.mly" +# 1784 "parsing/parser.mly" ( _1 ) -# 3499 "parsing/parser.ml" +# 3493 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3519,23 +3513,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.class_expr) = let _1 = let _1 = -# 1777 "parsing/parser.mly" +# 1783 "parsing/parser.mly" ( Pcl_extension _1 ) -# 3525 "parsing/parser.ml" +# 3519 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 3533 "parsing/parser.ml" +# 3527 "parsing/parser.ml" in -# 1778 "parsing/parser.mly" +# 1784 "parsing/parser.mly" ( _1 ) -# 3539 "parsing/parser.ml" +# 3533 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3588,33 +3582,33 @@ module Tables = struct let _v : (Parsetree.class_field) = let _6 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 3594 "parsing/parser.ml" +# 3588 "parsing/parser.ml" in let _endpos__6_ = _endpos__1_inlined2_ in let _3 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 3603 "parsing/parser.ml" +# 3597 "parsing/parser.ml" in let _2 = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 3609 "parsing/parser.ml" +# 3603 "parsing/parser.ml" in let _endpos = _endpos__6_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1827 "parsing/parser.mly" +# 1833 "parsing/parser.mly" ( let docs = symbol_docs _sloc in mkcf ~loc:_sloc (Pcf_inherit (_2, _4, self)) ~attrs:(_3@_6) ~docs ) -# 3618 "parsing/parser.ml" +# 3612 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3674,36 +3668,36 @@ module Tables = struct let _v : (Parsetree.class_field) = let _6 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 3680 "parsing/parser.ml" +# 3674 "parsing/parser.ml" in let _endpos__6_ = _endpos__1_inlined3_ in let _3 = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 3689 "parsing/parser.ml" +# 3683 "parsing/parser.ml" in let _2 = let _1 = _1_inlined1 in -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 3697 "parsing/parser.ml" +# 3691 "parsing/parser.ml" in let _endpos = _endpos__6_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1827 "parsing/parser.mly" +# 1833 "parsing/parser.mly" ( let docs = symbol_docs _sloc in mkcf ~loc:_sloc (Pcf_inherit (_2, _4, self)) ~attrs:(_3@_6) ~docs ) -# 3707 "parsing/parser.ml" +# 3701 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3744,9 +3738,9 @@ module Tables = struct let _v : (Parsetree.class_field) = let _3 = let _1 = _1_inlined1 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 3750 "parsing/parser.ml" +# 3744 "parsing/parser.ml" in let _endpos__3_ = _endpos__1_inlined1_ in @@ -3754,11 +3748,11 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1830 "parsing/parser.mly" +# 1836 "parsing/parser.mly" ( let v, attrs = _2 in let docs = symbol_docs _sloc in mkcf ~loc:_sloc (Pcf_val v) ~attrs:(attrs@_3) ~docs ) -# 3762 "parsing/parser.ml" +# 3756 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3799,9 +3793,9 @@ module Tables = struct let _v : (Parsetree.class_field) = let _3 = let _1 = _1_inlined1 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 3805 "parsing/parser.ml" +# 3799 "parsing/parser.ml" in let _endpos__3_ = _endpos__1_inlined1_ in @@ -3809,11 +3803,11 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1834 "parsing/parser.mly" +# 1840 "parsing/parser.mly" ( let meth, attrs = _2 in let docs = symbol_docs _sloc in mkcf ~loc:_sloc (Pcf_method meth) ~attrs:(attrs@_3) ~docs ) -# 3817 "parsing/parser.ml" +# 3811 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3859,28 +3853,28 @@ module Tables = struct let _v : (Parsetree.class_field) = let _4 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 3865 "parsing/parser.ml" +# 3859 "parsing/parser.ml" in let _endpos__4_ = _endpos__1_inlined2_ in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 3874 "parsing/parser.ml" +# 3868 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1838 "parsing/parser.mly" +# 1844 "parsing/parser.mly" ( let docs = symbol_docs _sloc in mkcf ~loc:_sloc (Pcf_constraint _3) ~attrs:(_2@_4) ~docs ) -# 3884 "parsing/parser.ml" +# 3878 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3926,28 +3920,28 @@ module Tables = struct let _v : (Parsetree.class_field) = let _4 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 3932 "parsing/parser.ml" +# 3926 "parsing/parser.ml" in let _endpos__4_ = _endpos__1_inlined2_ in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 3941 "parsing/parser.ml" +# 3935 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1841 "parsing/parser.mly" +# 1847 "parsing/parser.mly" ( let docs = symbol_docs _sloc in mkcf ~loc:_sloc (Pcf_initializer _3) ~attrs:(_2@_4) ~docs ) -# 3951 "parsing/parser.ml" +# 3945 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -3979,9 +3973,9 @@ module Tables = struct let _v : (Parsetree.class_field) = let _2 = let _1 = _1_inlined1 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 3985 "parsing/parser.ml" +# 3979 "parsing/parser.ml" in let _endpos__2_ = _endpos__1_inlined1_ in @@ -3989,10 +3983,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1844 "parsing/parser.mly" +# 1850 "parsing/parser.mly" ( let docs = symbol_docs _sloc in mkcf ~loc:_sloc (Pcf_extension _1) ~attrs:_2 ~docs ) -# 3996 "parsing/parser.ml" +# 3990 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4016,23 +4010,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.class_field) = let _1 = let _1 = -# 1847 "parsing/parser.mly" +# 1853 "parsing/parser.mly" ( Pcf_attribute _1 ) -# 4022 "parsing/parser.ml" +# 4016 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 864 "parsing/parser.mly" +# 868 "parsing/parser.mly" ( mkcf ~loc:_sloc _1 ) -# 4030 "parsing/parser.ml" +# 4024 "parsing/parser.ml" in -# 1848 "parsing/parser.mly" +# 1854 "parsing/parser.mly" ( _1 ) -# 4036 "parsing/parser.ml" +# 4030 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4062,9 +4056,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.class_expr) = -# 1742 "parsing/parser.mly" +# 1748 "parsing/parser.mly" ( _2 ) -# 4068 "parsing/parser.ml" +# 4062 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4109,24 +4103,24 @@ module Tables = struct let _endpos = _endpos__4_ in let _v : (Parsetree.class_expr) = let _1 = let _1 = -# 1745 "parsing/parser.mly" +# 1751 "parsing/parser.mly" ( Pcl_constraint(_4, _2) ) -# 4115 "parsing/parser.ml" +# 4109 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 4124 "parsing/parser.ml" +# 4118 "parsing/parser.ml" in -# 1748 "parsing/parser.mly" +# 1754 "parsing/parser.mly" ( _1 ) -# 4130 "parsing/parser.ml" +# 4124 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4157,24 +4151,24 @@ module Tables = struct let _endpos = _endpos__2_ in let _v : (Parsetree.class_expr) = let _1 = let _1 = -# 1747 "parsing/parser.mly" +# 1753 "parsing/parser.mly" ( let (l,o,p) = _1 in Pcl_fun(l, o, p, _2) ) -# 4163 "parsing/parser.ml" +# 4157 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 4172 "parsing/parser.ml" +# 4166 "parsing/parser.ml" in -# 1748 "parsing/parser.mly" +# 1754 "parsing/parser.mly" ( _1 ) -# 4178 "parsing/parser.ml" +# 4172 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4212,24 +4206,24 @@ module Tables = struct let _endpos = _endpos_e_ in let _v : (Parsetree.class_expr) = let _1 = let _1 = -# 1803 "parsing/parser.mly" +# 1809 "parsing/parser.mly" ( let (l,o,p) = _1 in Pcl_fun(l, o, p, e) ) -# 4218 "parsing/parser.ml" +# 4212 "parsing/parser.ml" in let _endpos__1_ = _endpos_e_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 4227 "parsing/parser.ml" +# 4221 "parsing/parser.ml" in -# 1804 "parsing/parser.mly" +# 1810 "parsing/parser.mly" ( _1 ) -# 4233 "parsing/parser.ml" +# 4227 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4260,24 +4254,24 @@ module Tables = struct let _endpos = _endpos_e_ in let _v : (Parsetree.class_expr) = let _1 = let _1 = -# 1803 "parsing/parser.mly" +# 1809 "parsing/parser.mly" ( let (l,o,p) = _1 in Pcl_fun(l, o, p, e) ) -# 4266 "parsing/parser.ml" +# 4260 "parsing/parser.ml" in let _endpos__1_ = _endpos_e_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 4275 "parsing/parser.ml" +# 4269 "parsing/parser.ml" in -# 1804 "parsing/parser.mly" +# 1810 "parsing/parser.mly" ( _1 ) -# 4281 "parsing/parser.ml" +# 4275 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4300,9 +4294,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3519 "parsing/parser.mly" +# 3535 "parsing/parser.mly" ( _1 ) -# 4306 "parsing/parser.ml" +# 4300 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4342,9 +4336,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1812 "parsing/parser.mly" +# 1818 "parsing/parser.mly" ( reloc_pat ~loc:_sloc _2 ) -# 4348 "parsing/parser.ml" +# 4342 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4396,24 +4390,24 @@ module Tables = struct let _endpos = _endpos__5_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 1814 "parsing/parser.mly" +# 1820 "parsing/parser.mly" ( Ppat_constraint(_2, _4) ) -# 4402 "parsing/parser.ml" +# 4396 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 4411 "parsing/parser.ml" +# 4405 "parsing/parser.ml" in -# 1815 "parsing/parser.mly" +# 1821 "parsing/parser.mly" ( _1 ) -# 4417 "parsing/parser.ml" +# 4411 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4432,9 +4426,9 @@ module Tables = struct let _symbolstartpos = _endpos in let _sloc = (_symbolstartpos, _endpos) in -# 1817 "parsing/parser.mly" +# 1823 "parsing/parser.mly" ( ghpat ~loc:_sloc Ppat_any ) -# 4438 "parsing/parser.ml" +# 4432 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4471,9 +4465,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.core_type) = -# 1942 "parsing/parser.mly" +# 1948 "parsing/parser.mly" ( _2 ) -# 4477 "parsing/parser.ml" +# 4471 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4490,24 +4484,24 @@ module Tables = struct let _endpos = _startpos in let _v : (Parsetree.core_type) = let _1 = let _1 = -# 1943 "parsing/parser.mly" +# 1949 "parsing/parser.mly" ( Ptyp_any ) -# 4496 "parsing/parser.ml" +# 4490 "parsing/parser.ml" in let _endpos__1_ = _endpos__0_ in let _endpos = _endpos__1_ in let _symbolstartpos = _endpos in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 4505 "parsing/parser.ml" +# 4499 "parsing/parser.ml" in -# 1944 "parsing/parser.mly" +# 1950 "parsing/parser.mly" ( _1 ) -# 4511 "parsing/parser.ml" +# 4505 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4553,28 +4547,28 @@ module Tables = struct let _v : (Parsetree.class_type_field) = let _4 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 4559 "parsing/parser.ml" +# 4553 "parsing/parser.ml" in let _endpos__4_ = _endpos__1_inlined2_ in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 4568 "parsing/parser.ml" +# 4562 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1952 "parsing/parser.mly" +# 1958 "parsing/parser.mly" ( let docs = symbol_docs _sloc in mkctf ~loc:_sloc (Pctf_inherit _3) ~attrs:(_2@_4) ~docs ) -# 4578 "parsing/parser.ml" +# 4572 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4632,9 +4626,9 @@ module Tables = struct let ty : (Parsetree.core_type) = Obj.magic ty in let _3 : unit = Obj.magic _3 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 4638 "parsing/parser.ml" +# 4632 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let flags : (Asttypes.mutable_flag * Asttypes.virtual_flag) = Obj.magic flags in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in @@ -4645,9 +4639,9 @@ module Tables = struct let _v : (Parsetree.class_type_field) = let _4 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 4651 "parsing/parser.ml" +# 4645 "parsing/parser.ml" in let _endpos__4_ = _endpos__1_inlined3_ in @@ -4655,44 +4649,44 @@ module Tables = struct let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let label = let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 4661 "parsing/parser.ml" +# 4655 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 4669 "parsing/parser.ml" +# 4663 "parsing/parser.ml" in -# 1977 "parsing/parser.mly" +# 1983 "parsing/parser.mly" ( let mut, virt = flags in label, mut, virt, ty ) -# 4678 "parsing/parser.ml" +# 4672 "parsing/parser.ml" in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 4686 "parsing/parser.ml" +# 4680 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1955 "parsing/parser.mly" +# 1961 "parsing/parser.mly" ( let docs = symbol_docs _sloc in mkctf ~loc:_sloc (Pctf_val _3) ~attrs:(_2@_4) ~docs ) -# 4696 "parsing/parser.ml" +# 4690 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4750,9 +4744,9 @@ module Tables = struct let _1_inlined3 : (Parsetree.core_type) = Obj.magic _1_inlined3 in let _5 : unit = Obj.magic _5 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 4756 "parsing/parser.ml" +# 4750 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let _3 : (Asttypes.private_flag * Asttypes.virtual_flag) = Obj.magic _3 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in @@ -4763,53 +4757,53 @@ module Tables = struct let _v : (Parsetree.class_type_field) = let _7 = let _1 = _1_inlined4 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 4769 "parsing/parser.ml" +# 4763 "parsing/parser.ml" in let _endpos__7_ = _endpos__1_inlined4_ in let _6 = let _1 = _1_inlined3 in -# 3164 "parsing/parser.mly" +# 3180 "parsing/parser.mly" ( _1 ) -# 4778 "parsing/parser.ml" +# 4772 "parsing/parser.ml" in let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 4786 "parsing/parser.ml" +# 4780 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 4794 "parsing/parser.ml" +# 4788 "parsing/parser.ml" in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 4802 "parsing/parser.ml" +# 4796 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1959 "parsing/parser.mly" +# 1965 "parsing/parser.mly" ( let (p, v) = _3 in let docs = symbol_docs _sloc in mkctf ~loc:_sloc (Pctf_method (_4, p, v, _6)) ~attrs:(_2@_7) ~docs ) -# 4813 "parsing/parser.ml" +# 4807 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4855,28 +4849,28 @@ module Tables = struct let _v : (Parsetree.class_type_field) = let _4 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 4861 "parsing/parser.ml" +# 4855 "parsing/parser.ml" in let _endpos__4_ = _endpos__1_inlined2_ in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 4870 "parsing/parser.ml" +# 4864 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1963 "parsing/parser.mly" +# 1969 "parsing/parser.mly" ( let docs = symbol_docs _sloc in mkctf ~loc:_sloc (Pctf_constraint _3) ~attrs:(_2@_4) ~docs ) -# 4880 "parsing/parser.ml" +# 4874 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4908,9 +4902,9 @@ module Tables = struct let _v : (Parsetree.class_type_field) = let _2 = let _1 = _1_inlined1 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 4914 "parsing/parser.ml" +# 4908 "parsing/parser.ml" in let _endpos__2_ = _endpos__1_inlined1_ in @@ -4918,10 +4912,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1966 "parsing/parser.mly" +# 1972 "parsing/parser.mly" ( let docs = symbol_docs _sloc in mkctf ~loc:_sloc (Pctf_extension _1) ~attrs:_2 ~docs ) -# 4925 "parsing/parser.ml" +# 4919 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4945,23 +4939,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.class_type_field) = let _1 = let _1 = -# 1969 "parsing/parser.mly" +# 1975 "parsing/parser.mly" ( Pctf_attribute _1 ) -# 4951 "parsing/parser.ml" +# 4945 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 862 "parsing/parser.mly" +# 866 "parsing/parser.mly" ( mkctf ~loc:_sloc _1 ) -# 4959 "parsing/parser.ml" +# 4953 "parsing/parser.ml" in -# 1970 "parsing/parser.mly" +# 1976 "parsing/parser.mly" ( _1 ) -# 4965 "parsing/parser.ml" +# 4959 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -4990,42 +4984,42 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 4996 "parsing/parser.ml" +# 4990 "parsing/parser.ml" in let tys = let tys = -# 1928 "parsing/parser.mly" +# 1934 "parsing/parser.mly" ( [] ) -# 5003 "parsing/parser.ml" +# 4997 "parsing/parser.ml" in -# 1934 "parsing/parser.mly" +# 1940 "parsing/parser.mly" ( tys ) -# 5008 "parsing/parser.ml" +# 5002 "parsing/parser.ml" in -# 1911 "parsing/parser.mly" +# 1917 "parsing/parser.mly" ( Pcty_constr (cid, tys) ) -# 5014 "parsing/parser.ml" +# 5008 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 860 "parsing/parser.mly" +# 864 "parsing/parser.mly" ( mkcty ~loc:_sloc _1 ) -# 5023 "parsing/parser.ml" +# 5017 "parsing/parser.ml" in -# 1914 "parsing/parser.mly" +# 1920 "parsing/parser.mly" ( _1 ) -# 5029 "parsing/parser.ml" +# 5023 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5076,9 +5070,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 5082 "parsing/parser.ml" +# 5076 "parsing/parser.ml" in let tys = @@ -5087,30 +5081,30 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 5091 "parsing/parser.ml" +# 5085 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 5096 "parsing/parser.ml" +# 5090 "parsing/parser.ml" in -# 1930 "parsing/parser.mly" +# 1936 "parsing/parser.mly" ( params ) -# 5102 "parsing/parser.ml" +# 5096 "parsing/parser.ml" in -# 1934 "parsing/parser.mly" +# 1940 "parsing/parser.mly" ( tys ) -# 5108 "parsing/parser.ml" +# 5102 "parsing/parser.ml" in -# 1911 "parsing/parser.mly" +# 1917 "parsing/parser.mly" ( Pcty_constr (cid, tys) ) -# 5114 "parsing/parser.ml" +# 5108 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined1_ in @@ -5118,15 +5112,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 860 "parsing/parser.mly" +# 864 "parsing/parser.mly" ( mkcty ~loc:_sloc _1 ) -# 5124 "parsing/parser.ml" +# 5118 "parsing/parser.ml" in -# 1914 "parsing/parser.mly" +# 1920 "parsing/parser.mly" ( _1 ) -# 5130 "parsing/parser.ml" +# 5124 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5150,23 +5144,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.class_type) = let _1 = let _1 = -# 1913 "parsing/parser.mly" +# 1919 "parsing/parser.mly" ( Pcty_extension _1 ) -# 5156 "parsing/parser.ml" +# 5150 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 860 "parsing/parser.mly" +# 864 "parsing/parser.mly" ( mkcty ~loc:_sloc _1 ) -# 5164 "parsing/parser.ml" +# 5158 "parsing/parser.ml" in -# 1914 "parsing/parser.mly" +# 1920 "parsing/parser.mly" ( _1 ) -# 5170 "parsing/parser.ml" +# 5164 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5223,44 +5217,44 @@ module Tables = struct let _1 = # 260 "" ( List.flatten xss ) -# 5227 "parsing/parser.ml" +# 5221 "parsing/parser.ml" in -# 1948 "parsing/parser.mly" +# 1954 "parsing/parser.mly" ( _1 ) -# 5232 "parsing/parser.ml" +# 5226 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_xss_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 808 "parsing/parser.mly" +# 812 "parsing/parser.mly" ( extra_csig _startpos _endpos _1 ) -# 5241 "parsing/parser.ml" +# 5235 "parsing/parser.ml" in -# 1938 "parsing/parser.mly" +# 1944 "parsing/parser.mly" ( Csig.mk _1 _2 ) -# 5247 "parsing/parser.ml" +# 5241 "parsing/parser.ml" in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 5255 "parsing/parser.ml" +# 5249 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1916 "parsing/parser.mly" +# 1922 "parsing/parser.mly" ( mkcty ~loc:_sloc ~attrs:_2 (Pcty_signature _3) ) -# 5264 "parsing/parser.ml" +# 5258 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5317,43 +5311,43 @@ module Tables = struct let _1 = # 260 "" ( List.flatten xss ) -# 5321 "parsing/parser.ml" +# 5315 "parsing/parser.ml" in -# 1948 "parsing/parser.mly" +# 1954 "parsing/parser.mly" ( _1 ) -# 5326 "parsing/parser.ml" +# 5320 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_xss_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 808 "parsing/parser.mly" +# 812 "parsing/parser.mly" ( extra_csig _startpos _endpos _1 ) -# 5335 "parsing/parser.ml" +# 5329 "parsing/parser.ml" in -# 1938 "parsing/parser.mly" +# 1944 "parsing/parser.mly" ( Csig.mk _1 _2 ) -# 5341 "parsing/parser.ml" +# 5335 "parsing/parser.ml" in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 5349 "parsing/parser.ml" +# 5343 "parsing/parser.ml" in let _loc__4_ = (_startpos__4_, _endpos__4_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1918 "parsing/parser.mly" +# 1924 "parsing/parser.mly" ( unclosed "object" _loc__1_ "end" _loc__4_ ) -# 5357 "parsing/parser.ml" +# 5351 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5383,9 +5377,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.class_type) = -# 1920 "parsing/parser.mly" +# 1926 "parsing/parser.mly" ( Cty.attr _1 _2 ) -# 5389 "parsing/parser.ml" +# 5383 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5448,34 +5442,34 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 5454 "parsing/parser.ml" +# 5448 "parsing/parser.ml" in + let _endpos__5_ = _endpos__1_inlined2_ in let _4 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 5462 "parsing/parser.ml" +# 5457 "parsing/parser.ml" in - let _endpos__4_ = _endpos__1_inlined1_ in let _3 = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 5469 "parsing/parser.ml" +# 5463 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1922 "parsing/parser.mly" - ( let loc = (_startpos__2_, _endpos__4_) in +# 1928 "parsing/parser.mly" + ( let loc = (_startpos__2_, _endpos__5_) in let od = Opn.mk ~override:_3 ~loc:(make_loc loc) _5 in mkcty ~loc:_sloc ~attrs:_4 (Pcty_open(od, _7)) ) -# 5479 "parsing/parser.ml" +# 5473 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5545,37 +5539,37 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 5551 "parsing/parser.ml" +# 5545 "parsing/parser.ml" in + let _endpos__5_ = _endpos__1_inlined3_ in let _4 = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 5559 "parsing/parser.ml" +# 5554 "parsing/parser.ml" in - let _endpos__4_ = _endpos__1_inlined2_ in let _3 = let _1 = _1_inlined1 in -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 5568 "parsing/parser.ml" +# 5562 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1922 "parsing/parser.mly" - ( let loc = (_startpos__2_, _endpos__4_) in +# 1928 "parsing/parser.mly" + ( let loc = (_startpos__2_, _endpos__5_) in let od = Opn.mk ~override:_3 ~loc:(make_loc loc) _5 in mkcty ~loc:_sloc ~attrs:_4 (Pcty_open(od, _7)) ) -# 5579 "parsing/parser.ml" +# 5573 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5612,9 +5606,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.class_expr) = -# 1782 "parsing/parser.mly" +# 1788 "parsing/parser.mly" ( _2 ) -# 5618 "parsing/parser.ml" +# 5612 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5653,9 +5647,9 @@ module Tables = struct let _v : (Parsetree.class_expr) = let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1784 "parsing/parser.mly" +# 1790 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__3_ ) -# 5659 "parsing/parser.ml" +# 5653 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5684,42 +5678,42 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 5690 "parsing/parser.ml" +# 5684 "parsing/parser.ml" in let tys = let tys = -# 1928 "parsing/parser.mly" +# 1934 "parsing/parser.mly" ( [] ) -# 5697 "parsing/parser.ml" +# 5691 "parsing/parser.ml" in -# 1934 "parsing/parser.mly" +# 1940 "parsing/parser.mly" ( tys ) -# 5702 "parsing/parser.ml" +# 5696 "parsing/parser.ml" in -# 1787 "parsing/parser.mly" +# 1793 "parsing/parser.mly" ( Pcl_constr(cid, tys) ) -# 5708 "parsing/parser.ml" +# 5702 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 5717 "parsing/parser.ml" +# 5711 "parsing/parser.ml" in -# 1794 "parsing/parser.mly" +# 1800 "parsing/parser.mly" ( _1 ) -# 5723 "parsing/parser.ml" +# 5717 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5770,9 +5764,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 5776 "parsing/parser.ml" +# 5770 "parsing/parser.ml" in let tys = @@ -5781,30 +5775,30 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 5785 "parsing/parser.ml" +# 5779 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 5790 "parsing/parser.ml" +# 5784 "parsing/parser.ml" in -# 1930 "parsing/parser.mly" +# 1936 "parsing/parser.mly" ( params ) -# 5796 "parsing/parser.ml" +# 5790 "parsing/parser.ml" in -# 1934 "parsing/parser.mly" +# 1940 "parsing/parser.mly" ( tys ) -# 5802 "parsing/parser.ml" +# 5796 "parsing/parser.ml" in -# 1787 "parsing/parser.mly" +# 1793 "parsing/parser.mly" ( Pcl_constr(cid, tys) ) -# 5808 "parsing/parser.ml" +# 5802 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined1_ in @@ -5812,15 +5806,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 5818 "parsing/parser.ml" +# 5812 "parsing/parser.ml" in -# 1794 "parsing/parser.mly" +# 1800 "parsing/parser.mly" ( _1 ) -# 5824 "parsing/parser.ml" +# 5818 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5879,43 +5873,43 @@ module Tables = struct let _1 = # 260 "" ( List.flatten xss ) -# 5883 "parsing/parser.ml" +# 5877 "parsing/parser.ml" in -# 1821 "parsing/parser.mly" +# 1827 "parsing/parser.mly" ( _1 ) -# 5888 "parsing/parser.ml" +# 5882 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_xss_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 807 "parsing/parser.mly" +# 811 "parsing/parser.mly" ( extra_cstr _startpos _endpos _1 ) -# 5897 "parsing/parser.ml" +# 5891 "parsing/parser.ml" in -# 1808 "parsing/parser.mly" +# 1814 "parsing/parser.mly" ( Cstr.mk _1 _2 ) -# 5903 "parsing/parser.ml" +# 5897 "parsing/parser.ml" in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 5911 "parsing/parser.ml" +# 5905 "parsing/parser.ml" in let _loc__4_ = (_startpos__4_, _endpos__4_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1789 "parsing/parser.mly" +# 1795 "parsing/parser.mly" ( unclosed "object" _loc__1_ "end" _loc__4_ ) -# 5919 "parsing/parser.ml" +# 5913 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -5923,15 +5917,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 5929 "parsing/parser.ml" +# 5923 "parsing/parser.ml" in -# 1794 "parsing/parser.mly" +# 1800 "parsing/parser.mly" ( _1 ) -# 5935 "parsing/parser.ml" +# 5929 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -5983,24 +5977,24 @@ module Tables = struct let _endpos = _endpos__5_ in let _v : (Parsetree.class_expr) = let _1 = let _1 = -# 1791 "parsing/parser.mly" +# 1797 "parsing/parser.mly" ( Pcl_constraint(_2, _4) ) -# 5989 "parsing/parser.ml" +# 5983 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 5998 "parsing/parser.ml" +# 5992 "parsing/parser.ml" in -# 1794 "parsing/parser.mly" +# 1800 "parsing/parser.mly" ( _1 ) -# 6004 "parsing/parser.ml" +# 5998 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6055,9 +6049,9 @@ module Tables = struct let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1793 "parsing/parser.mly" +# 1799 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__5_ ) -# 6061 "parsing/parser.ml" +# 6055 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -6065,15 +6059,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 866 "parsing/parser.mly" +# 870 "parsing/parser.mly" ( mkclass ~loc:_sloc _1 ) -# 6071 "parsing/parser.ml" +# 6065 "parsing/parser.ml" in -# 1794 "parsing/parser.mly" +# 1800 "parsing/parser.mly" ( _1 ) -# 6077 "parsing/parser.ml" +# 6071 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6130,44 +6124,44 @@ module Tables = struct let _1 = # 260 "" ( List.flatten xss ) -# 6134 "parsing/parser.ml" +# 6128 "parsing/parser.ml" in -# 1821 "parsing/parser.mly" +# 1827 "parsing/parser.mly" ( _1 ) -# 6139 "parsing/parser.ml" +# 6133 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_xss_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 807 "parsing/parser.mly" +# 811 "parsing/parser.mly" ( extra_cstr _startpos _endpos _1 ) -# 6148 "parsing/parser.ml" +# 6142 "parsing/parser.ml" in -# 1808 "parsing/parser.mly" +# 1814 "parsing/parser.mly" ( Cstr.mk _1 _2 ) -# 6154 "parsing/parser.ml" +# 6148 "parsing/parser.ml" in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 6162 "parsing/parser.ml" +# 6156 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1796 "parsing/parser.mly" +# 1802 "parsing/parser.mly" ( mkclass ~loc:_sloc ~attrs:_2 (Pcl_structure _3) ) -# 6171 "parsing/parser.ml" +# 6165 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6190,9 +6184,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.class_type) = -# 1899 "parsing/parser.mly" +# 1905 "parsing/parser.mly" ( _1 ) -# 6196 "parsing/parser.ml" +# 6190 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6238,14 +6232,14 @@ module Tables = struct let _v : (Parsetree.class_type) = let _1 = let _1 = let label = -# 3227 "parsing/parser.mly" +# 3243 "parsing/parser.mly" ( Optional label ) -# 6244 "parsing/parser.ml" +# 6238 "parsing/parser.ml" in -# 1905 "parsing/parser.mly" +# 1911 "parsing/parser.mly" ( Pcty_arrow(label, domain, codomain) ) -# 6249 "parsing/parser.ml" +# 6243 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_codomain_, _startpos_label_) in @@ -6253,15 +6247,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 860 "parsing/parser.mly" +# 864 "parsing/parser.mly" ( mkcty ~loc:_sloc _1 ) -# 6259 "parsing/parser.ml" +# 6253 "parsing/parser.ml" in -# 1906 "parsing/parser.mly" +# 1912 "parsing/parser.mly" ( _1 ) -# 6265 "parsing/parser.ml" +# 6259 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6308,9 +6302,9 @@ module Tables = struct let domain : (Parsetree.core_type) = Obj.magic domain in let _2 : unit = Obj.magic _2 in let label : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 6314 "parsing/parser.ml" +# 6308 "parsing/parser.ml" ) = Obj.magic label in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_label_ in @@ -6318,14 +6312,14 @@ module Tables = struct let _v : (Parsetree.class_type) = let _1 = let _1 = let label = -# 3229 "parsing/parser.mly" +# 3245 "parsing/parser.mly" ( Labelled label ) -# 6324 "parsing/parser.ml" +# 6318 "parsing/parser.ml" in -# 1905 "parsing/parser.mly" +# 1911 "parsing/parser.mly" ( Pcty_arrow(label, domain, codomain) ) -# 6329 "parsing/parser.ml" +# 6323 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_codomain_, _startpos_label_) in @@ -6333,15 +6327,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 860 "parsing/parser.mly" +# 864 "parsing/parser.mly" ( mkcty ~loc:_sloc _1 ) -# 6339 "parsing/parser.ml" +# 6333 "parsing/parser.ml" in -# 1906 "parsing/parser.mly" +# 1912 "parsing/parser.mly" ( _1 ) -# 6345 "parsing/parser.ml" +# 6339 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6380,14 +6374,14 @@ module Tables = struct let _v : (Parsetree.class_type) = let _1 = let _1 = let label = -# 3231 "parsing/parser.mly" +# 3247 "parsing/parser.mly" ( Nolabel ) -# 6386 "parsing/parser.ml" +# 6380 "parsing/parser.ml" in -# 1905 "parsing/parser.mly" +# 1911 "parsing/parser.mly" ( Pcty_arrow(label, domain, codomain) ) -# 6391 "parsing/parser.ml" +# 6385 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_codomain_, _startpos_domain_) in @@ -6395,15 +6389,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 860 "parsing/parser.mly" +# 864 "parsing/parser.mly" ( mkcty ~loc:_sloc _1 ) -# 6401 "parsing/parser.ml" +# 6395 "parsing/parser.ml" in -# 1906 "parsing/parser.mly" +# 1912 "parsing/parser.mly" ( _1 ) -# 6407 "parsing/parser.ml" +# 6401 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6486,11 +6480,11 @@ module Tables = struct let csig : (Parsetree.class_type) = Obj.magic csig in let _8 : unit = Obj.magic _8 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 6492 "parsing/parser.ml" +# 6486 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let virt : (Asttypes.virtual_flag) = Obj.magic virt in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in @@ -6504,9 +6498,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 6510 "parsing/parser.ml" +# 6504 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -6516,24 +6510,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 6522 "parsing/parser.ml" +# 6516 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 6530 "parsing/parser.ml" +# 6524 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2044 "parsing/parser.mly" +# 2050 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in @@ -6541,19 +6535,19 @@ module Tables = struct ext, Ci.mk id csig ~virt ~params ~attrs ~loc ~docs ) -# 6545 "parsing/parser.ml" +# 6539 "parsing/parser.ml" in -# 1044 "parsing/parser.mly" +# 1048 "parsing/parser.mly" ( let (x, b) = a in x, b :: bs ) -# 6551 "parsing/parser.ml" +# 6545 "parsing/parser.ml" in -# 2032 "parsing/parser.mly" +# 2038 "parsing/parser.mly" ( _1 ) -# 6557 "parsing/parser.ml" +# 6551 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6576,9 +6570,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3516 "parsing/parser.mly" +# 3532 "parsing/parser.mly" ( _1 ) -# 6582 "parsing/parser.ml" +# 6576 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6597,17 +6591,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 633 "parsing/parser.mly" +# 637 "parsing/parser.mly" (string * char option) -# 6603 "parsing/parser.ml" +# 6597 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.constant) = -# 3399 "parsing/parser.mly" +# 3415 "parsing/parser.mly" ( let (n, m) = _1 in Pconst_integer (n, m) ) -# 6611 "parsing/parser.ml" +# 6605 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6626,17 +6620,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 592 "parsing/parser.mly" +# 596 "parsing/parser.mly" (char) -# 6632 "parsing/parser.ml" +# 6626 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.constant) = -# 3400 "parsing/parser.mly" +# 3416 "parsing/parser.mly" ( Pconst_char _1 ) -# 6640 "parsing/parser.ml" +# 6634 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6655,17 +6649,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 685 "parsing/parser.mly" +# 689 "parsing/parser.mly" (string * Location.t * string option) -# 6661 "parsing/parser.ml" +# 6655 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.constant) = -# 3401 "parsing/parser.mly" +# 3417 "parsing/parser.mly" ( let (s, strloc, d) = _1 in Pconst_string (s, strloc, d) ) -# 6669 "parsing/parser.ml" +# 6663 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6684,17 +6678,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 612 "parsing/parser.mly" +# 616 "parsing/parser.mly" (string * char option) -# 6690 "parsing/parser.ml" +# 6684 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.constant) = -# 3402 "parsing/parser.mly" +# 3418 "parsing/parser.mly" ( let (f, m) = _1 in Pconst_float (f, m) ) -# 6698 "parsing/parser.ml" +# 6692 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6724,9 +6718,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.label) = -# 3473 "parsing/parser.mly" +# 3489 "parsing/parser.mly" ( "[]" ) -# 6730 "parsing/parser.ml" +# 6724 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6756,9 +6750,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.label) = -# 3474 "parsing/parser.mly" +# 3490 "parsing/parser.mly" ( "()" ) -# 6762 "parsing/parser.ml" +# 6756 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6781,9 +6775,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3475 "parsing/parser.mly" +# 3491 "parsing/parser.mly" ( "false" ) -# 6787 "parsing/parser.ml" +# 6781 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6806,9 +6800,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3476 "parsing/parser.mly" +# 3492 "parsing/parser.mly" ( "true" ) -# 6812 "parsing/parser.ml" +# 6806 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6827,17 +6821,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) -# 6833 "parsing/parser.ml" +# 6827 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3479 "parsing/parser.mly" +# 3495 "parsing/parser.mly" ( _1 ) -# 6841 "parsing/parser.ml" +# 6835 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6874,14 +6868,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Asttypes.label) = let _1 = -# 3470 "parsing/parser.mly" +# 3486 "parsing/parser.mly" ( "::" ) -# 6880 "parsing/parser.ml" +# 6874 "parsing/parser.ml" in -# 3480 "parsing/parser.mly" +# 3496 "parsing/parser.mly" ( _1 ) -# 6885 "parsing/parser.ml" +# 6879 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6904,9 +6898,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3481 "parsing/parser.mly" +# 3497 "parsing/parser.mly" ( _1 ) -# 6910 "parsing/parser.ml" +# 6904 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6929,9 +6923,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3484 "parsing/parser.mly" +# 3500 "parsing/parser.mly" ( _1 ) -# 6935 "parsing/parser.ml" +# 6929 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -6984,15 +6978,15 @@ module Tables = struct let _v : (Longident.t) = let _3 = let (_2, _1) = (_2_inlined1, _1_inlined1) in -# 3470 "parsing/parser.mly" +# 3486 "parsing/parser.mly" ( "::" ) -# 6990 "parsing/parser.ml" +# 6984 "parsing/parser.ml" in -# 3485 "parsing/parser.mly" +# 3501 "parsing/parser.mly" ( Ldot(_1,_3) ) -# 6996 "parsing/parser.ml" +# 6990 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7029,14 +7023,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Longident.t) = let _1 = -# 3470 "parsing/parser.mly" +# 3486 "parsing/parser.mly" ( "::" ) -# 7035 "parsing/parser.ml" +# 7029 "parsing/parser.ml" in -# 3486 "parsing/parser.mly" +# 3502 "parsing/parser.mly" ( Lident _1 ) -# 7040 "parsing/parser.ml" +# 7034 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7059,9 +7053,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3487 "parsing/parser.mly" +# 3503 "parsing/parser.mly" ( Lident _1 ) -# 7065 "parsing/parser.ml" +# 7059 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7098,9 +7092,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.core_type * Parsetree.core_type) = -# 1988 "parsing/parser.mly" +# 1994 "parsing/parser.mly" ( _1, _3 ) -# 7104 "parsing/parser.ml" +# 7098 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7125,26 +7119,26 @@ module Tables = struct let _v : (Parsetree.constructor_arguments) = let tys = let xs = let xs = -# 931 "parsing/parser.mly" +# 935 "parsing/parser.mly" ( [ x ] ) -# 7131 "parsing/parser.ml" +# 7125 "parsing/parser.ml" in # 253 "" ( List.rev xs ) -# 7136 "parsing/parser.ml" +# 7130 "parsing/parser.ml" in -# 951 "parsing/parser.mly" +# 955 "parsing/parser.mly" ( xs ) -# 7142 "parsing/parser.ml" +# 7136 "parsing/parser.ml" in -# 3034 "parsing/parser.mly" +# 3050 "parsing/parser.mly" ( Pcstr_tuple tys ) -# 7148 "parsing/parser.ml" +# 7142 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7183,26 +7177,26 @@ module Tables = struct let _v : (Parsetree.constructor_arguments) = let tys = let xs = let xs = -# 935 "parsing/parser.mly" +# 939 "parsing/parser.mly" ( x :: xs ) -# 7189 "parsing/parser.ml" +# 7183 "parsing/parser.ml" in # 253 "" ( List.rev xs ) -# 7194 "parsing/parser.ml" +# 7188 "parsing/parser.ml" in -# 951 "parsing/parser.mly" +# 955 "parsing/parser.mly" ( xs ) -# 7200 "parsing/parser.ml" +# 7194 "parsing/parser.ml" in -# 3034 "parsing/parser.mly" +# 3050 "parsing/parser.mly" ( Pcstr_tuple tys ) -# 7206 "parsing/parser.ml" +# 7200 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7239,9 +7233,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.constructor_arguments) = -# 3036 "parsing/parser.mly" +# 3052 "parsing/parser.mly" ( Pcstr_record _2 ) -# 7245 "parsing/parser.ml" +# 7239 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7264,9 +7258,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.constructor_declaration list) = -# 2955 "parsing/parser.mly" +# 2971 "parsing/parser.mly" ( [] ) -# 7270 "parsing/parser.ml" +# 7264 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7289,14 +7283,14 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_xs_ in let _v : (Parsetree.constructor_declaration list) = let cs = -# 1036 "parsing/parser.mly" +# 1040 "parsing/parser.mly" ( List.rev xs ) -# 7295 "parsing/parser.ml" +# 7289 "parsing/parser.ml" in -# 2957 "parsing/parser.mly" +# 2973 "parsing/parser.mly" ( cs ) -# 7300 "parsing/parser.ml" +# 7294 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7319,14 +7313,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.core_type) = let _1 = -# 3189 "parsing/parser.mly" +# 3205 "parsing/parser.mly" ( _1 ) -# 7325 "parsing/parser.ml" +# 7319 "parsing/parser.ml" in -# 3179 "parsing/parser.mly" +# 3195 "parsing/parser.mly" ( _1 ) -# 7330 "parsing/parser.ml" +# 7324 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7356,9 +7350,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.core_type) = -# 3181 "parsing/parser.mly" +# 3197 "parsing/parser.mly" ( Typ.attr _1 _2 ) -# 7362 "parsing/parser.ml" +# 7356 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7381,9 +7375,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.direction_flag) = -# 3578 "parsing/parser.mly" +# 3594 "parsing/parser.mly" ( Upto ) -# 7387 "parsing/parser.ml" +# 7381 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7406,9 +7400,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.direction_flag) = -# 3579 "parsing/parser.mly" +# 3595 "parsing/parser.mly" ( Downto ) -# 7412 "parsing/parser.ml" +# 7406 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7431,9 +7425,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.expression) = -# 2135 "parsing/parser.mly" +# 2141 "parsing/parser.mly" ( _1 ) -# 7437 "parsing/parser.ml" +# 7431 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7511,9 +7505,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 7517 "parsing/parser.ml" +# 7511 "parsing/parser.ml" in let _3 = @@ -7521,21 +7515,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 7527 "parsing/parser.ml" +# 7521 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 7533 "parsing/parser.ml" +# 7527 "parsing/parser.ml" in -# 2183 "parsing/parser.mly" +# 2189 "parsing/parser.mly" ( Pexp_letmodule(_4, _5, _7), _3 ) -# 7539 "parsing/parser.ml" +# 7533 "parsing/parser.ml" in let _endpos__1_ = _endpos__7_ in @@ -7543,10 +7537,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 7550 "parsing/parser.ml" +# 7544 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7630,9 +7624,9 @@ module Tables = struct let _3 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 7636 "parsing/parser.ml" +# 7630 "parsing/parser.ml" in let _endpos__3_ = _endpos__1_inlined1_ in @@ -7641,19 +7635,19 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 7647 "parsing/parser.ml" +# 7641 "parsing/parser.ml" in let _endpos = _endpos__3_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3019 "parsing/parser.mly" +# 3035 "parsing/parser.mly" ( let args, res = _2 in Te.decl _1 ~args ?res ~attrs:_3 ~loc:(make_loc _sloc) ) -# 7657 "parsing/parser.ml" +# 7651 "parsing/parser.ml" in let _3 = @@ -7661,21 +7655,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 7667 "parsing/parser.ml" +# 7661 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 7673 "parsing/parser.ml" +# 7667 "parsing/parser.ml" in -# 2185 "parsing/parser.mly" +# 2191 "parsing/parser.mly" ( Pexp_letexception(_4, _6), _3 ) -# 7679 "parsing/parser.ml" +# 7673 "parsing/parser.ml" in let _endpos__1_ = _endpos__6_ in @@ -7683,10 +7677,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 7690 "parsing/parser.ml" +# 7684 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7756,28 +7750,28 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 7762 "parsing/parser.ml" +# 7756 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 7768 "parsing/parser.ml" +# 7762 "parsing/parser.ml" in let _3 = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 7774 "parsing/parser.ml" +# 7768 "parsing/parser.ml" in -# 2187 "parsing/parser.mly" +# 2193 "parsing/parser.mly" ( let open_loc = make_loc (_startpos__2_, _endpos__5_) in let od = Opn.mk _5 ~override:_3 ~loc:open_loc in Pexp_open(od, _7), _4 ) -# 7781 "parsing/parser.ml" +# 7775 "parsing/parser.ml" in let _endpos__1_ = _endpos__7_ in @@ -7785,10 +7779,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 7792 "parsing/parser.ml" +# 7786 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7865,31 +7859,31 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 7871 "parsing/parser.ml" +# 7865 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 7877 "parsing/parser.ml" +# 7871 "parsing/parser.ml" in let _3 = let _1 = _1_inlined1 in -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 7885 "parsing/parser.ml" +# 7879 "parsing/parser.ml" in -# 2187 "parsing/parser.mly" +# 2193 "parsing/parser.mly" ( let open_loc = make_loc (_startpos__2_, _endpos__5_) in let od = Opn.mk _5 ~override:_3 ~loc:open_loc in Pexp_open(od, _7), _4 ) -# 7893 "parsing/parser.ml" +# 7887 "parsing/parser.ml" in let _endpos__1_ = _endpos__7_ in @@ -7897,10 +7891,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 7904 "parsing/parser.ml" +# 7898 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -7949,18 +7943,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 7953 "parsing/parser.ml" +# 7947 "parsing/parser.ml" in -# 1008 "parsing/parser.mly" +# 1012 "parsing/parser.mly" ( xs ) -# 7958 "parsing/parser.ml" +# 7952 "parsing/parser.ml" in -# 2519 "parsing/parser.mly" +# 2521 "parsing/parser.mly" ( xs ) -# 7964 "parsing/parser.ml" +# 7958 "parsing/parser.ml" in let _2 = @@ -7968,21 +7962,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 7974 "parsing/parser.ml" +# 7968 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 7980 "parsing/parser.ml" +# 7974 "parsing/parser.ml" in -# 2191 "parsing/parser.mly" +# 2197 "parsing/parser.mly" ( Pexp_function _3, _2 ) -# 7986 "parsing/parser.ml" +# 7980 "parsing/parser.ml" in let _endpos__1_ = _endpos_xs_ in @@ -7990,10 +7984,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 7997 "parsing/parser.ml" +# 7991 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -8049,22 +8043,22 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 8055 "parsing/parser.ml" +# 8049 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 8061 "parsing/parser.ml" +# 8055 "parsing/parser.ml" in -# 2193 "parsing/parser.mly" +# 2199 "parsing/parser.mly" ( let (l,o,p) = _3 in Pexp_fun(l, o, p, _4), _2 ) -# 8068 "parsing/parser.ml" +# 8062 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -8072,10 +8066,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 8079 "parsing/parser.ml" +# 8073 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -8148,33 +8142,33 @@ module Tables = struct let _endpos = _endpos__7_ in let _v : (Parsetree.expression) = let _1 = let _5 = -# 2414 "parsing/parser.mly" +# 2416 "parsing/parser.mly" ( xs ) -# 8154 "parsing/parser.ml" +# 8148 "parsing/parser.ml" in let _2 = let (_1_inlined1, _1) = (_1_inlined2, _1_inlined1) in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 8163 "parsing/parser.ml" +# 8157 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 8169 "parsing/parser.ml" +# 8163 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2196 "parsing/parser.mly" +# 2202 "parsing/parser.mly" ( (mk_newtypes ~loc:_sloc _5 _7).pexp_desc, _2 ) -# 8178 "parsing/parser.ml" +# 8172 "parsing/parser.ml" in let _endpos__1_ = _endpos__7_ in @@ -8182,10 +8176,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 8189 "parsing/parser.ml" +# 8183 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -8248,18 +8242,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 8252 "parsing/parser.ml" +# 8246 "parsing/parser.ml" in -# 1008 "parsing/parser.mly" +# 1012 "parsing/parser.mly" ( xs ) -# 8257 "parsing/parser.ml" +# 8251 "parsing/parser.ml" in -# 2519 "parsing/parser.mly" +# 2521 "parsing/parser.mly" ( xs ) -# 8263 "parsing/parser.ml" +# 8257 "parsing/parser.ml" in let _2 = @@ -8267,21 +8261,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 8273 "parsing/parser.ml" +# 8267 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 8279 "parsing/parser.ml" +# 8273 "parsing/parser.ml" in -# 2198 "parsing/parser.mly" +# 2204 "parsing/parser.mly" ( Pexp_match(_3, _5), _2 ) -# 8285 "parsing/parser.ml" +# 8279 "parsing/parser.ml" in let _endpos__1_ = _endpos_xs_ in @@ -8289,10 +8283,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 8296 "parsing/parser.ml" +# 8290 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -8355,18 +8349,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 8359 "parsing/parser.ml" +# 8353 "parsing/parser.ml" in -# 1008 "parsing/parser.mly" +# 1012 "parsing/parser.mly" ( xs ) -# 8364 "parsing/parser.ml" +# 8358 "parsing/parser.ml" in -# 2519 "parsing/parser.mly" +# 2521 "parsing/parser.mly" ( xs ) -# 8370 "parsing/parser.ml" +# 8364 "parsing/parser.ml" in let _2 = @@ -8374,21 +8368,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 8380 "parsing/parser.ml" +# 8374 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 8386 "parsing/parser.ml" +# 8380 "parsing/parser.ml" in -# 2200 "parsing/parser.mly" +# 2206 "parsing/parser.mly" ( Pexp_try(_3, _5), _2 ) -# 8392 "parsing/parser.ml" +# 8386 "parsing/parser.ml" in let _endpos__1_ = _endpos_xs_ in @@ -8396,10 +8390,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 8403 "parsing/parser.ml" +# 8397 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -8462,21 +8456,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 8468 "parsing/parser.ml" +# 8462 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 8474 "parsing/parser.ml" +# 8468 "parsing/parser.ml" in -# 2202 "parsing/parser.mly" +# 2208 "parsing/parser.mly" ( syntax_error() ) -# 8480 "parsing/parser.ml" +# 8474 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -8484,10 +8478,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 8491 "parsing/parser.ml" +# 8485 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -8564,21 +8558,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 8570 "parsing/parser.ml" +# 8564 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 8576 "parsing/parser.ml" +# 8570 "parsing/parser.ml" in -# 2204 "parsing/parser.mly" +# 2210 "parsing/parser.mly" ( Pexp_ifthenelse(_3, _5, Some _7), _2 ) -# 8582 "parsing/parser.ml" +# 8576 "parsing/parser.ml" in let _endpos__1_ = _endpos__7_ in @@ -8586,10 +8580,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 8593 "parsing/parser.ml" +# 8587 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -8652,21 +8646,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 8658 "parsing/parser.ml" +# 8652 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 8664 "parsing/parser.ml" +# 8658 "parsing/parser.ml" in -# 2206 "parsing/parser.mly" +# 2212 "parsing/parser.mly" ( Pexp_ifthenelse(_3, _5, None), _2 ) -# 8670 "parsing/parser.ml" +# 8664 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -8674,10 +8668,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 8681 "parsing/parser.ml" +# 8675 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -8747,21 +8741,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 8753 "parsing/parser.ml" +# 8747 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 8759 "parsing/parser.ml" +# 8753 "parsing/parser.ml" in -# 2208 "parsing/parser.mly" +# 2214 "parsing/parser.mly" ( Pexp_while(_3, _5), _2 ) -# 8765 "parsing/parser.ml" +# 8759 "parsing/parser.ml" in let _endpos__1_ = _endpos__6_ in @@ -8769,10 +8763,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 8776 "parsing/parser.ml" +# 8770 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -8870,21 +8864,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 8876 "parsing/parser.ml" +# 8870 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 8882 "parsing/parser.ml" +# 8876 "parsing/parser.ml" in -# 2211 "parsing/parser.mly" +# 2217 "parsing/parser.mly" ( Pexp_for(_3, _5, _7, _6, _9), _2 ) -# 8888 "parsing/parser.ml" +# 8882 "parsing/parser.ml" in let _endpos__1_ = _endpos__10_ in @@ -8892,10 +8886,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 8899 "parsing/parser.ml" +# 8893 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -8944,21 +8938,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 8950 "parsing/parser.ml" +# 8944 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 8956 "parsing/parser.ml" +# 8950 "parsing/parser.ml" in -# 2213 "parsing/parser.mly" +# 2219 "parsing/parser.mly" ( Pexp_assert _3, _2 ) -# 8962 "parsing/parser.ml" +# 8956 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -8966,10 +8960,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 8973 "parsing/parser.ml" +# 8967 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9018,21 +9012,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 9024 "parsing/parser.ml" +# 9018 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 9030 "parsing/parser.ml" +# 9024 "parsing/parser.ml" in -# 2215 "parsing/parser.mly" +# 2221 "parsing/parser.mly" ( Pexp_lazy _3, _2 ) -# 9036 "parsing/parser.ml" +# 9030 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -9040,10 +9034,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 9047 "parsing/parser.ml" +# 9041 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9108,27 +9102,27 @@ module Tables = struct let _1 = # 260 "" ( List.flatten xss ) -# 9112 "parsing/parser.ml" +# 9106 "parsing/parser.ml" in -# 1821 "parsing/parser.mly" +# 1827 "parsing/parser.mly" ( _1 ) -# 9117 "parsing/parser.ml" +# 9111 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_xss_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 807 "parsing/parser.mly" +# 811 "parsing/parser.mly" ( extra_cstr _startpos _endpos _1 ) -# 9126 "parsing/parser.ml" +# 9120 "parsing/parser.ml" in -# 1808 "parsing/parser.mly" +# 1814 "parsing/parser.mly" ( Cstr.mk _1 _2 ) -# 9132 "parsing/parser.ml" +# 9126 "parsing/parser.ml" in let _2 = @@ -9136,21 +9130,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 9142 "parsing/parser.ml" +# 9136 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 9148 "parsing/parser.ml" +# 9142 "parsing/parser.ml" in -# 2217 "parsing/parser.mly" +# 2223 "parsing/parser.mly" ( Pexp_object _3, _2 ) -# 9154 "parsing/parser.ml" +# 9148 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -9158,10 +9152,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 9165 "parsing/parser.ml" +# 9159 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9226,27 +9220,27 @@ module Tables = struct let _1 = # 260 "" ( List.flatten xss ) -# 9230 "parsing/parser.ml" +# 9224 "parsing/parser.ml" in -# 1821 "parsing/parser.mly" +# 1827 "parsing/parser.mly" ( _1 ) -# 9235 "parsing/parser.ml" +# 9229 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_xss_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 807 "parsing/parser.mly" +# 811 "parsing/parser.mly" ( extra_cstr _startpos _endpos _1 ) -# 9244 "parsing/parser.ml" +# 9238 "parsing/parser.ml" in -# 1808 "parsing/parser.mly" +# 1814 "parsing/parser.mly" ( Cstr.mk _1 _2 ) -# 9250 "parsing/parser.ml" +# 9244 "parsing/parser.ml" in let _2 = @@ -9254,23 +9248,23 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 9260 "parsing/parser.ml" +# 9254 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 9266 "parsing/parser.ml" +# 9260 "parsing/parser.ml" in let _loc__4_ = (_startpos__4_, _endpos__4_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2219 "parsing/parser.mly" +# 2225 "parsing/parser.mly" ( unclosed "object" _loc__1_ "end" _loc__4_ ) -# 9274 "parsing/parser.ml" +# 9268 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -9278,10 +9272,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2137 "parsing/parser.mly" +# 2143 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 9285 "parsing/parser.ml" +# 9279 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9316,18 +9310,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 9320 "parsing/parser.ml" +# 9314 "parsing/parser.ml" in -# 915 "parsing/parser.mly" +# 919 "parsing/parser.mly" ( xs ) -# 9325 "parsing/parser.ml" +# 9319 "parsing/parser.ml" in -# 2223 "parsing/parser.mly" +# 2229 "parsing/parser.mly" ( Pexp_apply(_1, _2) ) -# 9331 "parsing/parser.ml" +# 9325 "parsing/parser.ml" in let _endpos__1_ = _endpos_xs_ in @@ -9335,15 +9329,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 9341 "parsing/parser.ml" +# 9335 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 9347 "parsing/parser.ml" +# 9341 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9372,24 +9366,24 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 9376 "parsing/parser.ml" +# 9370 "parsing/parser.ml" in -# 975 "parsing/parser.mly" +# 979 "parsing/parser.mly" ( xs ) -# 9381 "parsing/parser.ml" +# 9375 "parsing/parser.ml" in -# 2546 "parsing/parser.mly" +# 2548 "parsing/parser.mly" ( es ) -# 9387 "parsing/parser.ml" +# 9381 "parsing/parser.ml" in -# 2225 "parsing/parser.mly" +# 2231 "parsing/parser.mly" ( Pexp_tuple(_1) ) -# 9393 "parsing/parser.ml" +# 9387 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xs_, _startpos_xs_) in @@ -9397,15 +9391,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 9403 "parsing/parser.ml" +# 9397 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 9409 "parsing/parser.ml" +# 9403 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9441,15 +9435,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 9447 "parsing/parser.ml" +# 9441 "parsing/parser.ml" in -# 2227 "parsing/parser.mly" +# 2233 "parsing/parser.mly" ( Pexp_construct(_1, Some _2) ) -# 9453 "parsing/parser.ml" +# 9447 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in @@ -9457,15 +9451,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 9463 "parsing/parser.ml" +# 9457 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 9469 "parsing/parser.ml" +# 9463 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9496,24 +9490,24 @@ module Tables = struct let _endpos = _endpos__2_ in let _v : (Parsetree.expression) = let _1 = let _1 = -# 2229 "parsing/parser.mly" +# 2235 "parsing/parser.mly" ( Pexp_variant(_1, Some _2) ) -# 9502 "parsing/parser.ml" +# 9496 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 9511 "parsing/parser.ml" +# 9505 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 9517 "parsing/parser.ml" +# 9511 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9545,9 +9539,9 @@ module Tables = struct } = _menhir_stack in let e2 : (Parsetree.expression) = Obj.magic e2 in let op : ( -# 623 "parsing/parser.mly" +# 627 "parsing/parser.mly" (string) -# 9551 "parsing/parser.ml" +# 9545 "parsing/parser.ml" ) = Obj.magic op in let e1 : (Parsetree.expression) = Obj.magic e1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -9557,24 +9551,24 @@ module Tables = struct let _1 = let op = let _1 = -# 3443 "parsing/parser.mly" +# 3459 "parsing/parser.mly" ( op ) -# 9563 "parsing/parser.ml" +# 9557 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_op_, _startpos_op_) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 9572 "parsing/parser.ml" +# 9566 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 9578 "parsing/parser.ml" +# 9572 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -9582,15 +9576,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 9588 "parsing/parser.ml" +# 9582 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 9594 "parsing/parser.ml" +# 9588 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9622,9 +9616,9 @@ module Tables = struct } = _menhir_stack in let e2 : (Parsetree.expression) = Obj.magic e2 in let op : ( -# 624 "parsing/parser.mly" +# 628 "parsing/parser.mly" (string) -# 9628 "parsing/parser.ml" +# 9622 "parsing/parser.ml" ) = Obj.magic op in let e1 : (Parsetree.expression) = Obj.magic e1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -9634,24 +9628,24 @@ module Tables = struct let _1 = let op = let _1 = -# 3444 "parsing/parser.mly" +# 3460 "parsing/parser.mly" ( op ) -# 9640 "parsing/parser.ml" +# 9634 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_op_, _startpos_op_) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 9649 "parsing/parser.ml" +# 9643 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 9655 "parsing/parser.ml" +# 9649 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -9659,15 +9653,92 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) +# 9659 "parsing/parser.ml" + + in + +# 2146 "parsing/parser.mly" + ( _1 ) # 9665 "parsing/parser.ml" + in + { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = Obj.repr _v; + MenhirLib.EngineTypes.startp = _startpos; + MenhirLib.EngineTypes.endp = _endpos; + MenhirLib.EngineTypes.next = _menhir_stack; + }); + (fun _menhir_env -> + let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in + let { + MenhirLib.EngineTypes.state = _; + MenhirLib.EngineTypes.semv = e2; + MenhirLib.EngineTypes.startp = _startpos_e2_; + MenhirLib.EngineTypes.endp = _endpos_e2_; + MenhirLib.EngineTypes.next = { + MenhirLib.EngineTypes.state = _; + MenhirLib.EngineTypes.semv = op; + MenhirLib.EngineTypes.startp = _startpos_op_; + MenhirLib.EngineTypes.endp = _endpos_op_; + MenhirLib.EngineTypes.next = { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = e1; + MenhirLib.EngineTypes.startp = _startpos_e1_; + MenhirLib.EngineTypes.endp = _endpos_e1_; + MenhirLib.EngineTypes.next = _menhir_stack; + }; + }; + } = _menhir_stack in + let e2 : (Parsetree.expression) = Obj.magic e2 in + let op : ( +# 629 "parsing/parser.mly" + (string) +# 9699 "parsing/parser.ml" + ) = Obj.magic op in + let e1 : (Parsetree.expression) = Obj.magic e1 in + let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in + let _startpos = _startpos_e1_ in + let _endpos = _endpos_e2_ in + let _v : (Parsetree.expression) = let _1 = + let _1 = + let op = + let _1 = +# 3461 "parsing/parser.mly" + ( op ) +# 9711 "parsing/parser.ml" + in + let (_endpos__1_, _startpos__1_) = (_endpos_op_, _startpos_op_) in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in + +# 844 "parsing/parser.mly" + ( mkoperator ~loc:_sloc _1 ) +# 9720 "parsing/parser.ml" + + in + +# 2237 "parsing/parser.mly" + ( mkinfix e1 op e2 ) +# 9726 "parsing/parser.ml" + + in + let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in + +# 850 "parsing/parser.mly" + ( mkexp ~loc:_sloc _1 ) +# 9736 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 9671 "parsing/parser.ml" +# 9742 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9699,9 +9770,9 @@ module Tables = struct } = _menhir_stack in let e2 : (Parsetree.expression) = Obj.magic e2 in let op : ( -# 625 "parsing/parser.mly" +# 630 "parsing/parser.mly" (string) -# 9705 "parsing/parser.ml" +# 9776 "parsing/parser.ml" ) = Obj.magic op in let e1 : (Parsetree.expression) = Obj.magic e1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -9711,101 +9782,24 @@ module Tables = struct let _1 = let op = let _1 = -# 3445 "parsing/parser.mly" +# 3462 "parsing/parser.mly" ( op ) -# 9717 "parsing/parser.ml" +# 9788 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_op_, _startpos_op_) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 9726 "parsing/parser.ml" +# 9797 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 9732 "parsing/parser.ml" - - in - let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 846 "parsing/parser.mly" - ( mkexp ~loc:_sloc _1 ) -# 9742 "parsing/parser.ml" - - in - -# 2140 "parsing/parser.mly" - ( _1 ) -# 9748 "parsing/parser.ml" - in - { - MenhirLib.EngineTypes.state = _menhir_s; - MenhirLib.EngineTypes.semv = Obj.repr _v; - MenhirLib.EngineTypes.startp = _startpos; - MenhirLib.EngineTypes.endp = _endpos; - MenhirLib.EngineTypes.next = _menhir_stack; - }); - (fun _menhir_env -> - let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in - let { - MenhirLib.EngineTypes.state = _; - MenhirLib.EngineTypes.semv = e2; - MenhirLib.EngineTypes.startp = _startpos_e2_; - MenhirLib.EngineTypes.endp = _endpos_e2_; - MenhirLib.EngineTypes.next = { - MenhirLib.EngineTypes.state = _; - MenhirLib.EngineTypes.semv = op; - MenhirLib.EngineTypes.startp = _startpos_op_; - MenhirLib.EngineTypes.endp = _endpos_op_; - MenhirLib.EngineTypes.next = { - MenhirLib.EngineTypes.state = _menhir_s; - MenhirLib.EngineTypes.semv = e1; - MenhirLib.EngineTypes.startp = _startpos_e1_; - MenhirLib.EngineTypes.endp = _endpos_e1_; - MenhirLib.EngineTypes.next = _menhir_stack; - }; - }; - } = _menhir_stack in - let e2 : (Parsetree.expression) = Obj.magic e2 in - let op : ( -# 626 "parsing/parser.mly" - (string) -# 9782 "parsing/parser.ml" - ) = Obj.magic op in - let e1 : (Parsetree.expression) = Obj.magic e1 in - let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in - let _startpos = _startpos_e1_ in - let _endpos = _endpos_e2_ in - let _v : (Parsetree.expression) = let _1 = - let _1 = - let op = - let _1 = -# 3446 "parsing/parser.mly" - ( op ) -# 9794 "parsing/parser.ml" - in - let (_endpos__1_, _startpos__1_) = (_endpos_op_, _startpos_op_) in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 840 "parsing/parser.mly" - ( mkoperator ~loc:_sloc _1 ) # 9803 "parsing/parser.ml" - - in - -# 2231 "parsing/parser.mly" - ( mkinfix e1 op e2 ) -# 9809 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -9813,15 +9807,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 9819 "parsing/parser.ml" +# 9813 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 9825 "parsing/parser.ml" +# 9819 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9853,9 +9847,9 @@ module Tables = struct } = _menhir_stack in let e2 : (Parsetree.expression) = Obj.magic e2 in let op : ( -# 627 "parsing/parser.mly" +# 631 "parsing/parser.mly" (string) -# 9859 "parsing/parser.ml" +# 9853 "parsing/parser.ml" ) = Obj.magic op in let e1 : (Parsetree.expression) = Obj.magic e1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -9865,24 +9859,24 @@ module Tables = struct let _1 = let op = let _1 = -# 3447 "parsing/parser.mly" +# 3463 "parsing/parser.mly" ( op ) -# 9871 "parsing/parser.ml" +# 9865 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_op_, _startpos_op_) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 9880 "parsing/parser.ml" +# 9874 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 9886 "parsing/parser.ml" +# 9880 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -9890,15 +9884,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 9896 "parsing/parser.ml" +# 9890 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 9902 "parsing/parser.ml" +# 9896 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -9938,23 +9932,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3448 "parsing/parser.mly" +# 3464 "parsing/parser.mly" ("+") -# 9944 "parsing/parser.ml" +# 9938 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 9952 "parsing/parser.ml" +# 9946 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 9958 "parsing/parser.ml" +# 9952 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -9962,15 +9956,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 9968 "parsing/parser.ml" +# 9962 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 9974 "parsing/parser.ml" +# 9968 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10010,23 +10004,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3449 "parsing/parser.mly" +# 3465 "parsing/parser.mly" ("+.") -# 10016 "parsing/parser.ml" +# 10010 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10024 "parsing/parser.ml" +# 10018 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10030 "parsing/parser.ml" +# 10024 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10034,15 +10028,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10040 "parsing/parser.ml" +# 10034 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10046 "parsing/parser.ml" +# 10040 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10082,23 +10076,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3450 "parsing/parser.mly" +# 3466 "parsing/parser.mly" ("+=") -# 10088 "parsing/parser.ml" +# 10082 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10096 "parsing/parser.ml" +# 10090 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10102 "parsing/parser.ml" +# 10096 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10106,15 +10100,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10112 "parsing/parser.ml" +# 10106 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10118 "parsing/parser.ml" +# 10112 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10154,23 +10148,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3451 "parsing/parser.mly" +# 3467 "parsing/parser.mly" ("-") -# 10160 "parsing/parser.ml" +# 10154 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10168 "parsing/parser.ml" +# 10162 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10174 "parsing/parser.ml" +# 10168 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10178,15 +10172,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10184 "parsing/parser.ml" +# 10178 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10190 "parsing/parser.ml" +# 10184 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10226,23 +10220,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3452 "parsing/parser.mly" +# 3468 "parsing/parser.mly" ("-.") -# 10232 "parsing/parser.ml" +# 10226 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10240 "parsing/parser.ml" +# 10234 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10246 "parsing/parser.ml" +# 10240 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10250,15 +10244,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10256 "parsing/parser.ml" +# 10250 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10262 "parsing/parser.ml" +# 10256 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10298,23 +10292,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3453 "parsing/parser.mly" +# 3469 "parsing/parser.mly" ("*") -# 10304 "parsing/parser.ml" +# 10298 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10312 "parsing/parser.ml" +# 10306 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10318 "parsing/parser.ml" +# 10312 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10322,15 +10316,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10328 "parsing/parser.ml" +# 10322 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10334 "parsing/parser.ml" +# 10328 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10370,23 +10364,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3454 "parsing/parser.mly" +# 3470 "parsing/parser.mly" ("%") -# 10376 "parsing/parser.ml" +# 10370 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10384 "parsing/parser.ml" +# 10378 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10390 "parsing/parser.ml" +# 10384 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10394,15 +10388,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10400 "parsing/parser.ml" +# 10394 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10406 "parsing/parser.ml" +# 10400 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10442,23 +10436,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3455 "parsing/parser.mly" +# 3471 "parsing/parser.mly" ("=") -# 10448 "parsing/parser.ml" +# 10442 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10456 "parsing/parser.ml" +# 10450 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10462 "parsing/parser.ml" +# 10456 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10466,15 +10460,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10472 "parsing/parser.ml" +# 10466 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10478 "parsing/parser.ml" +# 10472 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10514,23 +10508,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3456 "parsing/parser.mly" +# 3472 "parsing/parser.mly" ("<") -# 10520 "parsing/parser.ml" +# 10514 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10528 "parsing/parser.ml" +# 10522 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10534 "parsing/parser.ml" +# 10528 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10538,15 +10532,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10544 "parsing/parser.ml" +# 10538 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10550 "parsing/parser.ml" +# 10544 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10586,23 +10580,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3457 "parsing/parser.mly" +# 3473 "parsing/parser.mly" (">") -# 10592 "parsing/parser.ml" +# 10586 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10600 "parsing/parser.ml" +# 10594 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10606 "parsing/parser.ml" +# 10600 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10610,15 +10604,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10616 "parsing/parser.ml" +# 10610 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10622 "parsing/parser.ml" +# 10616 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10658,23 +10652,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3458 "parsing/parser.mly" +# 3474 "parsing/parser.mly" ("or") -# 10664 "parsing/parser.ml" +# 10658 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10672 "parsing/parser.ml" +# 10666 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10678 "parsing/parser.ml" +# 10672 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10682,15 +10676,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10688 "parsing/parser.ml" +# 10682 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10694 "parsing/parser.ml" +# 10688 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10730,23 +10724,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3459 "parsing/parser.mly" +# 3475 "parsing/parser.mly" ("||") -# 10736 "parsing/parser.ml" +# 10730 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10744 "parsing/parser.ml" +# 10738 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10750 "parsing/parser.ml" +# 10744 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10754,15 +10748,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10760 "parsing/parser.ml" +# 10754 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10766 "parsing/parser.ml" +# 10760 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10802,23 +10796,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3460 "parsing/parser.mly" +# 3476 "parsing/parser.mly" ("&") -# 10808 "parsing/parser.ml" +# 10802 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10816 "parsing/parser.ml" +# 10810 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10822 "parsing/parser.ml" +# 10816 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10826,15 +10820,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10832 "parsing/parser.ml" +# 10826 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10838 "parsing/parser.ml" +# 10832 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10874,23 +10868,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3461 "parsing/parser.mly" +# 3477 "parsing/parser.mly" ("&&") -# 10880 "parsing/parser.ml" +# 10874 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10888 "parsing/parser.ml" +# 10882 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10894 "parsing/parser.ml" +# 10888 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10898,15 +10892,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10904 "parsing/parser.ml" +# 10898 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10910 "parsing/parser.ml" +# 10904 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -10946,23 +10940,23 @@ module Tables = struct let _1 = let op = let _1 = -# 3462 "parsing/parser.mly" +# 3478 "parsing/parser.mly" (":=") -# 10952 "parsing/parser.ml" +# 10946 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 10960 "parsing/parser.ml" +# 10954 "parsing/parser.ml" in -# 2231 "parsing/parser.mly" +# 2237 "parsing/parser.mly" ( mkinfix e1 op e2 ) -# 10966 "parsing/parser.ml" +# 10960 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_e2_, _startpos_e1_) in @@ -10970,15 +10964,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 10976 "parsing/parser.ml" +# 10970 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 10982 "parsing/parser.ml" +# 10976 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11011,9 +11005,9 @@ module Tables = struct let _1 = let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2233 "parsing/parser.mly" +# 2239 "parsing/parser.mly" ( mkuminus ~oploc:_loc__1_ _1 _2 ) -# 11017 "parsing/parser.ml" +# 11011 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in @@ -11021,15 +11015,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 11027 "parsing/parser.ml" +# 11021 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 11033 "parsing/parser.ml" +# 11027 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11062,9 +11056,9 @@ module Tables = struct let _1 = let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2235 "parsing/parser.mly" +# 2241 "parsing/parser.mly" ( mkuplus ~oploc:_loc__1_ _1 _2 ) -# 11068 "parsing/parser.ml" +# 11062 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in @@ -11072,15 +11066,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 11078 "parsing/parser.ml" +# 11072 "parsing/parser.ml" in -# 2140 "parsing/parser.mly" +# 2146 "parsing/parser.mly" ( _1 ) -# 11084 "parsing/parser.ml" +# 11078 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11120,9 +11114,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2142 "parsing/parser.mly" +# 2148 "parsing/parser.mly" ( expr_of_let_bindings ~loc:_sloc _1 _3 ) -# 11126 "parsing/parser.ml" +# 11120 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11162,9 +11156,9 @@ module Tables = struct let _3 : unit = Obj.magic _3 in let bindings : (Parsetree.pattern * Parsetree.expression * Parsetree.binding_op list) = Obj.magic bindings in let _1 : ( -# 629 "parsing/parser.mly" +# 633 "parsing/parser.mly" (string) -# 11168 "parsing/parser.ml" +# 11162 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -11174,9 +11168,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 11180 "parsing/parser.ml" +# 11174 "parsing/parser.ml" in let _startpos_pbop_op_ = _startpos__1_ in @@ -11184,13 +11178,13 @@ module Tables = struct let _symbolstartpos = _startpos_pbop_op_ in let _sloc = (_symbolstartpos, _endpos) in -# 2144 "parsing/parser.mly" +# 2150 "parsing/parser.mly" ( let (pbop_pat, pbop_exp, rev_ands) = bindings in let ands = List.rev rev_ands in let pbop_loc = make_loc _sloc in let let_ = {pbop_op; pbop_pat; pbop_exp; pbop_loc} in mkexp ~loc:_sloc (Pexp_letop{ let_; ands; body}) ) -# 11194 "parsing/parser.ml" +# 11188 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11231,9 +11225,9 @@ module Tables = struct let _loc__2_ = (_startpos__2_, _endpos__2_) in let _sloc = (_symbolstartpos, _endpos) in -# 2150 "parsing/parser.mly" +# 2156 "parsing/parser.mly" ( mkexp_cons ~loc:_sloc _loc__2_ (ghexp ~loc:_sloc (Pexp_tuple[_1;_3])) ) -# 11237 "parsing/parser.ml" +# 11231 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11266,35 +11260,35 @@ module Tables = struct let _3 : (Parsetree.expression) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 11272 "parsing/parser.ml" +# 11266 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.expression) = let _1 = let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 11281 "parsing/parser.ml" +# 11275 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 11289 "parsing/parser.ml" +# 11283 "parsing/parser.ml" in let _endpos = _endpos__3_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2152 "parsing/parser.mly" +# 2158 "parsing/parser.mly" ( mkexp ~loc:_sloc (Pexp_setinstvar(_1, _3)) ) -# 11298 "parsing/parser.ml" +# 11292 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11350,18 +11344,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 11356 "parsing/parser.ml" +# 11350 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2154 "parsing/parser.mly" +# 2160 "parsing/parser.mly" ( mkexp ~loc:_sloc (Pexp_setfield(_1, _3, _5)) ) -# 11365 "parsing/parser.ml" +# 11359 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11429,9 +11423,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2156 "parsing/parser.mly" +# 2162 "parsing/parser.mly" ( array_set ~loc:_sloc _1 _4 _7 ) -# 11435 "parsing/parser.ml" +# 11429 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11499,9 +11493,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2158 "parsing/parser.mly" +# 2164 "parsing/parser.mly" ( string_set ~loc:_sloc _1 _4 _7 ) -# 11505 "parsing/parser.ml" +# 11499 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11569,9 +11563,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2160 "parsing/parser.mly" +# 2166 "parsing/parser.mly" ( bigarray_set ~loc:_sloc _1 _4 _7 ) -# 11575 "parsing/parser.ml" +# 11569 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11631,26 +11625,26 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _3 : unit = Obj.magic _3 in let _2 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 11637 "parsing/parser.ml" +# 11631 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : (Parsetree.expression) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__7_ in let _v : (Parsetree.expression) = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 11646 "parsing/parser.ml" +# 11640 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2162 "parsing/parser.mly" +# 2168 "parsing/parser.mly" ( dotop_set ~loc:_sloc lident bracket _2 _1 _4 _7 ) -# 11654 "parsing/parser.ml" +# 11648 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11710,26 +11704,26 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _3 : unit = Obj.magic _3 in let _2 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 11716 "parsing/parser.ml" +# 11710 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : (Parsetree.expression) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__7_ in let _v : (Parsetree.expression) = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 11725 "parsing/parser.ml" +# 11719 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2164 "parsing/parser.mly" +# 2170 "parsing/parser.mly" ( dotop_set ~loc:_sloc lident paren _2 _1 _4 _7 ) -# 11733 "parsing/parser.ml" +# 11727 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11789,26 +11783,26 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _3 : unit = Obj.magic _3 in let _2 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 11795 "parsing/parser.ml" +# 11789 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : (Parsetree.expression) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__7_ in let _v : (Parsetree.expression) = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 11804 "parsing/parser.ml" +# 11798 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2166 "parsing/parser.mly" +# 2172 "parsing/parser.mly" ( dotop_set ~loc:_sloc lident brace _2 _1 _4 _7 ) -# 11812 "parsing/parser.ml" +# 11806 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11880,9 +11874,9 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _5 : unit = Obj.magic _5 in let _4 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 11886 "parsing/parser.ml" +# 11880 "parsing/parser.ml" ) = Obj.magic _4 in let _3 : (Longident.t) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in @@ -11891,17 +11885,17 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__9_ in let _v : (Parsetree.expression) = let _6 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 11897 "parsing/parser.ml" +# 11891 "parsing/parser.ml" in let _endpos = _endpos__9_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2169 "parsing/parser.mly" +# 2175 "parsing/parser.mly" ( dotop_set ~loc:_sloc (ldot _3) bracket _4 _1 _6 _9 ) -# 11905 "parsing/parser.ml" +# 11899 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -11973,9 +11967,9 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _5 : unit = Obj.magic _5 in let _4 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 11979 "parsing/parser.ml" +# 11973 "parsing/parser.ml" ) = Obj.magic _4 in let _3 : (Longident.t) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in @@ -11984,17 +11978,17 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__9_ in let _v : (Parsetree.expression) = let _6 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 11990 "parsing/parser.ml" +# 11984 "parsing/parser.ml" in let _endpos = _endpos__9_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2172 "parsing/parser.mly" +# 2178 "parsing/parser.mly" ( dotop_set ~loc:_sloc (ldot _3) paren _4 _1 _6 _9 ) -# 11998 "parsing/parser.ml" +# 11992 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12066,9 +12060,9 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _5 : unit = Obj.magic _5 in let _4 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 12072 "parsing/parser.ml" +# 12066 "parsing/parser.ml" ) = Obj.magic _4 in let _3 : (Longident.t) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in @@ -12077,17 +12071,17 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__9_ in let _v : (Parsetree.expression) = let _6 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 12083 "parsing/parser.ml" +# 12077 "parsing/parser.ml" in let _endpos = _endpos__9_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2175 "parsing/parser.mly" +# 2181 "parsing/parser.mly" ( dotop_set ~loc:_sloc (ldot _3) brace _4 _1 _6 _9 ) -# 12091 "parsing/parser.ml" +# 12085 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12117,9 +12111,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.expression) = -# 2177 "parsing/parser.mly" +# 2183 "parsing/parser.mly" ( Exp.attr _1 _2 ) -# 12123 "parsing/parser.ml" +# 12117 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12143,9 +12137,9 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.expression) = let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2179 "parsing/parser.mly" +# 2185 "parsing/parser.mly" ( not_expecting _loc__1_ "wildcard \"_\"" ) -# 12149 "parsing/parser.ml" +# 12143 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12161,9 +12155,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (string Asttypes.loc option) = -# 3734 "parsing/parser.mly" +# 3750 "parsing/parser.mly" ( None ) -# 12167 "parsing/parser.ml" +# 12161 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12193,9 +12187,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (string Asttypes.loc option) = -# 3735 "parsing/parser.mly" +# 3751 "parsing/parser.mly" ( Some _2 ) -# 12199 "parsing/parser.ml" +# 12193 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12239,9 +12233,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : (Parsetree.extension) = -# 3745 "parsing/parser.mly" +# 3761 "parsing/parser.mly" ( (_2, _3) ) -# 12245 "parsing/parser.ml" +# 12239 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12260,9 +12254,9 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 687 "parsing/parser.mly" +# 691 "parsing/parser.mly" (string * Location.t * string * Location.t * string option) -# 12266 "parsing/parser.ml" +# 12260 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -12271,9 +12265,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3747 "parsing/parser.mly" +# 3763 "parsing/parser.mly" ( mk_quotedext ~loc:_sloc _1 ) -# 12277 "parsing/parser.ml" +# 12271 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12326,9 +12320,9 @@ module Tables = struct let _v : (Parsetree.extension_constructor) = let attrs = let _1 = _1_inlined3 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 12332 "parsing/parser.ml" +# 12326 "parsing/parser.ml" in let _endpos_attrs_ = _endpos__1_inlined3_ in @@ -12338,9 +12332,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 12344 "parsing/parser.ml" +# 12338 "parsing/parser.ml" in let cid = @@ -12349,19 +12343,19 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 12355 "parsing/parser.ml" +# 12349 "parsing/parser.ml" in let _endpos = _endpos_attrs_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3103 "parsing/parser.mly" +# 3119 "parsing/parser.mly" ( let info = symbol_info _endpos in Te.rebind cid lid ~attrs ~loc:(make_loc _sloc) ~info ) -# 12365 "parsing/parser.ml" +# 12359 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12407,9 +12401,9 @@ module Tables = struct let _v : (Parsetree.extension_constructor) = let attrs = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 12413 "parsing/parser.ml" +# 12407 "parsing/parser.ml" in let _endpos_attrs_ = _endpos__1_inlined2_ in @@ -12419,9 +12413,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 12425 "parsing/parser.ml" +# 12419 "parsing/parser.ml" in let cid = @@ -12429,25 +12423,25 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 12435 "parsing/parser.ml" +# 12429 "parsing/parser.ml" in let _startpos_cid_ = _startpos__1_ in let _1 = -# 3554 "parsing/parser.mly" +# 3570 "parsing/parser.mly" ( () ) -# 12442 "parsing/parser.ml" +# 12436 "parsing/parser.ml" in let _endpos = _endpos_attrs_ in let _symbolstartpos = _startpos_cid_ in let _sloc = (_symbolstartpos, _endpos) in -# 3103 "parsing/parser.mly" +# 3119 "parsing/parser.mly" ( let info = symbol_info _endpos in Te.rebind cid lid ~attrs ~loc:(make_loc _sloc) ~info ) -# 12451 "parsing/parser.ml" +# 12445 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12494,10 +12488,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3722 "parsing/parser.mly" +# 3738 "parsing/parser.mly" ( mark_symbol_docs _sloc; Attr.mk ~loc:(make_loc _sloc) _2 _3 ) -# 12501 "parsing/parser.ml" +# 12495 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12512,15 +12506,15 @@ module Tables = struct let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in - let _v : ((Parsetree.core_type * Asttypes.variance) list) = let params = -# 1928 "parsing/parser.mly" + let _v : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = let params = +# 1934 "parsing/parser.mly" ( [] ) -# 12519 "parsing/parser.ml" +# 12513 "parsing/parser.ml" in -# 1753 "parsing/parser.mly" +# 1759 "parsing/parser.mly" ( params ) -# 12524 "parsing/parser.ml" +# 12518 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12551,34 +12545,34 @@ module Tables = struct }; } = _menhir_stack in let _3 : unit = Obj.magic _3 in - let xs : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic xs in + let xs : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic xs in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in - let _v : ((Parsetree.core_type * Asttypes.variance) list) = let params = + let _v : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = let params = let params = let xs = # 253 "" ( List.rev xs ) -# 12565 "parsing/parser.ml" +# 12559 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 12570 "parsing/parser.ml" +# 12564 "parsing/parser.ml" in -# 1930 "parsing/parser.mly" +# 1936 "parsing/parser.mly" ( params ) -# 12576 "parsing/parser.ml" +# 12570 "parsing/parser.ml" in -# 1753 "parsing/parser.mly" +# 1759 "parsing/parser.mly" ( params ) -# 12582 "parsing/parser.ml" +# 12576 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12601,9 +12595,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.expression) = -# 2505 "parsing/parser.mly" +# 2507 "parsing/parser.mly" ( _1 ) -# 12607 "parsing/parser.ml" +# 12601 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12643,9 +12637,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2507 "parsing/parser.mly" +# 2509 "parsing/parser.mly" ( mkexp_constraint ~loc:_sloc _3 _1 ) -# 12649 "parsing/parser.ml" +# 12643 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12675,9 +12669,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.expression) = -# 2531 "parsing/parser.mly" +# 2533 "parsing/parser.mly" ( _2 ) -# 12681 "parsing/parser.ml" +# 12675 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12722,24 +12716,24 @@ module Tables = struct let _endpos = _endpos__4_ in let _v : (Parsetree.expression) = let _1 = let _1 = -# 2533 "parsing/parser.mly" +# 2535 "parsing/parser.mly" ( Pexp_constraint (_4, _2) ) -# 12728 "parsing/parser.ml" +# 12722 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 12737 "parsing/parser.ml" +# 12731 "parsing/parser.ml" in -# 2534 "parsing/parser.mly" +# 2536 "parsing/parser.mly" ( _1 ) -# 12743 "parsing/parser.ml" +# 12737 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12772,12 +12766,12 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2537 "parsing/parser.mly" +# 2539 "parsing/parser.mly" ( let (l,o,p) = _1 in ghexp ~loc:_sloc (Pexp_fun(l, o, p, _2)) ) -# 12781 "parsing/parser.ml" +# 12775 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12828,17 +12822,17 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.expression) = let _3 = -# 2414 "parsing/parser.mly" +# 2416 "parsing/parser.mly" ( xs ) -# 12834 "parsing/parser.ml" +# 12828 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2542 "parsing/parser.mly" +# 2544 "parsing/parser.mly" ( mk_newtypes ~loc:_sloc _3 _5 ) -# 12842 "parsing/parser.ml" +# 12836 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12861,9 +12855,9 @@ module Tables = struct let _startpos = _startpos_ty_ in let _endpos = _endpos_ty_ in let _v : (Parsetree.core_type) = -# 3215 "parsing/parser.mly" +# 3231 "parsing/parser.mly" ( ty ) -# 12867 "parsing/parser.ml" +# 12861 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12909,19 +12903,19 @@ module Tables = struct let _v : (Parsetree.core_type) = let _1 = let _1 = let domain = -# 811 "parsing/parser.mly" +# 815 "parsing/parser.mly" ( extra_rhs_core_type _1 ~pos:_endpos__1_ ) -# 12915 "parsing/parser.ml" +# 12909 "parsing/parser.ml" in let label = -# 3227 "parsing/parser.mly" +# 3243 "parsing/parser.mly" ( Optional label ) -# 12920 "parsing/parser.ml" +# 12914 "parsing/parser.ml" in -# 3221 "parsing/parser.mly" +# 3237 "parsing/parser.mly" ( Ptyp_arrow(label, domain, codomain) ) -# 12925 "parsing/parser.ml" +# 12919 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_codomain_, _startpos_label_) in @@ -12929,15 +12923,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 12935 "parsing/parser.ml" +# 12929 "parsing/parser.ml" in -# 3223 "parsing/parser.mly" +# 3239 "parsing/parser.mly" ( _1 ) -# 12941 "parsing/parser.ml" +# 12935 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -12984,9 +12978,9 @@ module Tables = struct let _1 : (Parsetree.core_type) = Obj.magic _1 in let _2 : unit = Obj.magic _2 in let label : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 12990 "parsing/parser.ml" +# 12984 "parsing/parser.ml" ) = Obj.magic label in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_label_ in @@ -12994,19 +12988,19 @@ module Tables = struct let _v : (Parsetree.core_type) = let _1 = let _1 = let domain = -# 811 "parsing/parser.mly" +# 815 "parsing/parser.mly" ( extra_rhs_core_type _1 ~pos:_endpos__1_ ) -# 13000 "parsing/parser.ml" +# 12994 "parsing/parser.ml" in let label = -# 3229 "parsing/parser.mly" +# 3245 "parsing/parser.mly" ( Labelled label ) -# 13005 "parsing/parser.ml" +# 12999 "parsing/parser.ml" in -# 3221 "parsing/parser.mly" +# 3237 "parsing/parser.mly" ( Ptyp_arrow(label, domain, codomain) ) -# 13010 "parsing/parser.ml" +# 13004 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_codomain_, _startpos_label_) in @@ -13014,15 +13008,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 13020 "parsing/parser.ml" +# 13014 "parsing/parser.ml" in -# 3223 "parsing/parser.mly" +# 3239 "parsing/parser.mly" ( _1 ) -# 13026 "parsing/parser.ml" +# 13020 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13061,19 +13055,19 @@ module Tables = struct let _v : (Parsetree.core_type) = let _1 = let _1 = let domain = -# 811 "parsing/parser.mly" +# 815 "parsing/parser.mly" ( extra_rhs_core_type _1 ~pos:_endpos__1_ ) -# 13067 "parsing/parser.ml" +# 13061 "parsing/parser.ml" in let label = -# 3231 "parsing/parser.mly" +# 3247 "parsing/parser.mly" ( Nolabel ) -# 13072 "parsing/parser.ml" +# 13066 "parsing/parser.ml" in -# 3221 "parsing/parser.mly" +# 3237 "parsing/parser.mly" ( Ptyp_arrow(label, domain, codomain) ) -# 13077 "parsing/parser.ml" +# 13071 "parsing/parser.ml" in let _endpos__1_ = _endpos_codomain_ in @@ -13081,15 +13075,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 13087 "parsing/parser.ml" +# 13081 "parsing/parser.ml" in -# 3223 "parsing/parser.mly" +# 3239 "parsing/parser.mly" ( _1 ) -# 13093 "parsing/parser.ml" +# 13087 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13118,10 +13112,11 @@ module Tables = struct let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in - let _v : (Parsetree.functor_parameter) = -# 1186 "parsing/parser.mly" - ( Unit ) -# 13125 "parsing/parser.ml" + let _v : (Lexing.position * Parsetree.functor_parameter) = let _startpos = _startpos__1_ in + +# 1190 "parsing/parser.mly" + ( _startpos, Unit ) +# 13120 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13171,21 +13166,22 @@ module Tables = struct let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in - let _v : (Parsetree.functor_parameter) = let x = + let _v : (Lexing.position * Parsetree.functor_parameter) = let x = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 13183 "parsing/parser.ml" +# 13178 "parsing/parser.ml" in + let _startpos = _startpos__1_ in -# 1189 "parsing/parser.mly" - ( Named (x, mty) ) -# 13189 "parsing/parser.ml" +# 1193 "parsing/parser.mly" + ( _startpos, Named (x, mty) ) +# 13185 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13201,9 +13197,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (Parsetree.constructor_arguments * Parsetree.core_type option) = -# 3023 "parsing/parser.mly" +# 3039 "parsing/parser.mly" ( (Pcstr_tuple [],None) ) -# 13207 "parsing/parser.ml" +# 13203 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13233,9 +13229,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.constructor_arguments * Parsetree.core_type option) = -# 3024 "parsing/parser.mly" +# 3040 "parsing/parser.mly" ( (_2,None) ) -# 13239 "parsing/parser.ml" +# 13235 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13279,9 +13275,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : (Parsetree.constructor_arguments * Parsetree.core_type option) = -# 3026 "parsing/parser.mly" +# 3042 "parsing/parser.mly" ( (_2,Some _4) ) -# 13285 "parsing/parser.ml" +# 13281 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13311,9 +13307,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.constructor_arguments * Parsetree.core_type option) = -# 3028 "parsing/parser.mly" +# 3044 "parsing/parser.mly" ( (Pcstr_tuple [],Some _2) ) -# 13317 "parsing/parser.ml" +# 13313 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13361,9 +13357,9 @@ module Tables = struct Docstrings.info) = let attrs = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 13367 "parsing/parser.ml" +# 13363 "parsing/parser.ml" in let _endpos_attrs_ = _endpos__1_inlined2_ in @@ -13373,23 +13369,23 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 13379 "parsing/parser.ml" +# 13375 "parsing/parser.ml" in let _endpos = _endpos_attrs_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2971 "parsing/parser.mly" +# 2987 "parsing/parser.mly" ( let args, res = args_res in let info = symbol_info _endpos in let loc = make_loc _sloc in cid, args, res, attrs, loc, info ) -# 13393 "parsing/parser.ml" +# 13389 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13430,9 +13426,9 @@ module Tables = struct Docstrings.info) = let attrs = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 13436 "parsing/parser.ml" +# 13432 "parsing/parser.ml" in let _endpos_attrs_ = _endpos__1_inlined1_ in @@ -13441,29 +13437,29 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 13447 "parsing/parser.ml" +# 13443 "parsing/parser.ml" in let _startpos_cid_ = _startpos__1_ in let _1 = -# 3554 "parsing/parser.mly" +# 3570 "parsing/parser.mly" ( () ) -# 13454 "parsing/parser.ml" +# 13450 "parsing/parser.ml" in let _endpos = _endpos_attrs_ in let _symbolstartpos = _startpos_cid_ in let _sloc = (_symbolstartpos, _endpos) in -# 2971 "parsing/parser.mly" +# 2987 "parsing/parser.mly" ( let args, res = args_res in let info = symbol_info _endpos in let loc = make_loc _sloc in cid, args, res, attrs, loc, info ) -# 13467 "parsing/parser.ml" +# 13463 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13534,11 +13530,11 @@ module Tables = struct let _2 : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = Obj.magic _2 in let _1_inlined3 : unit = Obj.magic _1_inlined3 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 13540 "parsing/parser.ml" +# 13536 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in let _1 : unit = Obj.magic _1 in @@ -13549,9 +13545,9 @@ module Tables = struct Parsetree.type_declaration) = let attrs2 = let _1 = _1_inlined4 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 13555 "parsing/parser.ml" +# 13551 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined4_ in @@ -13560,26 +13556,26 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 13564 "parsing/parser.ml" +# 13560 "parsing/parser.ml" in -# 897 "parsing/parser.mly" +# 901 "parsing/parser.mly" ( xs ) -# 13569 "parsing/parser.ml" +# 13565 "parsing/parser.ml" in -# 2887 "parsing/parser.mly" +# 2892 "parsing/parser.mly" ( _1 ) -# 13575 "parsing/parser.ml" +# 13571 "parsing/parser.ml" in let kind_priv_manifest = let _1 = _1_inlined3 in -# 2922 "parsing/parser.mly" +# 2927 "parsing/parser.mly" ( _2 ) -# 13583 "parsing/parser.ml" +# 13579 "parsing/parser.ml" in let id = @@ -13588,29 +13584,29 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 13594 "parsing/parser.ml" +# 13590 "parsing/parser.ml" in let flag = -# 3574 "parsing/parser.mly" +# 3590 "parsing/parser.mly" ( Recursive ) -# 13600 "parsing/parser.ml" +# 13596 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 13607 "parsing/parser.ml" +# 13603 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2859 "parsing/parser.mly" +# 2864 "parsing/parser.mly" ( let (kind, priv, manifest) = kind_priv_manifest in let docs = symbol_docs _sloc in @@ -13619,7 +13615,7 @@ module Tables = struct (flag, ext), Type.mk id ~params ~cstrs ~kind ~priv ?manifest ~attrs ~loc ~docs ) -# 13623 "parsing/parser.ml" +# 13619 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13696,11 +13692,11 @@ module Tables = struct let _2 : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = Obj.magic _2 in let _1_inlined4 : unit = Obj.magic _1_inlined4 in let _1_inlined3 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 13702 "parsing/parser.ml" +# 13698 "parsing/parser.ml" ) = Obj.magic _1_inlined3 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let _1_inlined2 : unit = Obj.magic _1_inlined2 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in @@ -13712,9 +13708,9 @@ module Tables = struct Parsetree.type_declaration) = let attrs2 = let _1 = _1_inlined5 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 13718 "parsing/parser.ml" +# 13714 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined5_ in @@ -13723,26 +13719,26 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 13727 "parsing/parser.ml" +# 13723 "parsing/parser.ml" in -# 897 "parsing/parser.mly" +# 901 "parsing/parser.mly" ( xs ) -# 13732 "parsing/parser.ml" +# 13728 "parsing/parser.ml" in -# 2887 "parsing/parser.mly" +# 2892 "parsing/parser.mly" ( _1 ) -# 13738 "parsing/parser.ml" +# 13734 "parsing/parser.ml" in let kind_priv_manifest = let _1 = _1_inlined4 in -# 2922 "parsing/parser.mly" +# 2927 "parsing/parser.mly" ( _2 ) -# 13746 "parsing/parser.ml" +# 13742 "parsing/parser.ml" in let id = @@ -13751,9 +13747,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 13757 "parsing/parser.ml" +# 13753 "parsing/parser.ml" in let flag = @@ -13762,24 +13758,24 @@ module Tables = struct let _startpos = _startpos__1_ in let _loc = (_startpos, _endpos) in -# 3575 "parsing/parser.mly" +# 3591 "parsing/parser.mly" ( not_expecting _loc "nonrec flag" ) -# 13768 "parsing/parser.ml" +# 13764 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 13776 "parsing/parser.ml" +# 13772 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2859 "parsing/parser.mly" +# 2864 "parsing/parser.mly" ( let (kind, priv, manifest) = kind_priv_manifest in let docs = symbol_docs _sloc in @@ -13788,7 +13784,7 @@ module Tables = struct (flag, ext), Type.mk id ~params ~cstrs ~kind ~priv ?manifest ~attrs ~loc ~docs ) -# 13792 "parsing/parser.ml" +# 13788 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13852,11 +13848,11 @@ module Tables = struct let xs : ((Parsetree.core_type * Parsetree.core_type * Ast_helper.loc) list) = Obj.magic xs in let kind_priv_manifest : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = Obj.magic kind_priv_manifest in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 13858 "parsing/parser.ml" +# 13854 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in let _1 : unit = Obj.magic _1 in @@ -13867,9 +13863,9 @@ module Tables = struct Parsetree.type_declaration) = let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 13873 "parsing/parser.ml" +# 13869 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -13878,18 +13874,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 13882 "parsing/parser.ml" +# 13878 "parsing/parser.ml" in -# 897 "parsing/parser.mly" +# 901 "parsing/parser.mly" ( xs ) -# 13887 "parsing/parser.ml" +# 13883 "parsing/parser.ml" in -# 2887 "parsing/parser.mly" +# 2892 "parsing/parser.mly" ( _1 ) -# 13893 "parsing/parser.ml" +# 13889 "parsing/parser.ml" in let id = @@ -13898,29 +13894,29 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 13904 "parsing/parser.ml" +# 13900 "parsing/parser.ml" in let flag = -# 3570 "parsing/parser.mly" +# 3586 "parsing/parser.mly" ( Recursive ) -# 13910 "parsing/parser.ml" +# 13906 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 13917 "parsing/parser.ml" +# 13913 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2859 "parsing/parser.mly" +# 2864 "parsing/parser.mly" ( let (kind, priv, manifest) = kind_priv_manifest in let docs = symbol_docs _sloc in @@ -13929,7 +13925,7 @@ module Tables = struct (flag, ext), Type.mk id ~params ~cstrs ~kind ~priv ?manifest ~attrs ~loc ~docs ) -# 13933 "parsing/parser.ml" +# 13929 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -13999,11 +13995,11 @@ module Tables = struct let xs : ((Parsetree.core_type * Parsetree.core_type * Ast_helper.loc) list) = Obj.magic xs in let kind_priv_manifest : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = Obj.magic kind_priv_manifest in let _1_inlined3 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 14005 "parsing/parser.ml" +# 14001 "parsing/parser.ml" ) = Obj.magic _1_inlined3 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let _1_inlined2 : unit = Obj.magic _1_inlined2 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in @@ -14015,9 +14011,9 @@ module Tables = struct Parsetree.type_declaration) = let attrs2 = let _1 = _1_inlined4 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 14021 "parsing/parser.ml" +# 14017 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined4_ in @@ -14026,18 +14022,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 14030 "parsing/parser.ml" +# 14026 "parsing/parser.ml" in -# 897 "parsing/parser.mly" +# 901 "parsing/parser.mly" ( xs ) -# 14035 "parsing/parser.ml" +# 14031 "parsing/parser.ml" in -# 2887 "parsing/parser.mly" +# 2892 "parsing/parser.mly" ( _1 ) -# 14041 "parsing/parser.ml" +# 14037 "parsing/parser.ml" in let id = @@ -14046,32 +14042,32 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 14052 "parsing/parser.ml" +# 14048 "parsing/parser.ml" in let flag = let _1 = _1_inlined2 in -# 3571 "parsing/parser.mly" +# 3587 "parsing/parser.mly" ( Nonrecursive ) -# 14060 "parsing/parser.ml" +# 14056 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 14068 "parsing/parser.ml" +# 14064 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2859 "parsing/parser.mly" +# 2864 "parsing/parser.mly" ( let (kind, priv, manifest) = kind_priv_manifest in let docs = symbol_docs _sloc in @@ -14080,7 +14076,7 @@ module Tables = struct (flag, ext), Type.mk id ~params ~cstrs ~kind ~priv ?manifest ~attrs ~loc ~docs ) -# 14084 "parsing/parser.ml" +# 14080 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14099,17 +14095,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) -# 14105 "parsing/parser.ml" +# 14101 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3415 "parsing/parser.mly" +# 3431 "parsing/parser.mly" ( _1 ) -# 14113 "parsing/parser.ml" +# 14109 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14128,17 +14124,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 14134 "parsing/parser.ml" +# 14130 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3416 "parsing/parser.mly" +# 3432 "parsing/parser.mly" ( _1 ) -# 14142 "parsing/parser.ml" +# 14138 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14168,13 +14164,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 777 "parsing/parser.mly" +# 781 "parsing/parser.mly" (Parsetree.structure) -# 14174 "parsing/parser.ml" +# 14170 "parsing/parser.ml" ) = -# 1068 "parsing/parser.mly" +# 1072 "parsing/parser.mly" ( _1 ) -# 14178 "parsing/parser.ml" +# 14174 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14190,9 +14186,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (string) = -# 3465 "parsing/parser.mly" +# 3481 "parsing/parser.mly" ( "" ) -# 14196 "parsing/parser.ml" +# 14192 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14222,9 +14218,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (string) = -# 3466 "parsing/parser.mly" +# 3482 "parsing/parser.mly" ( ";.." ) -# 14228 "parsing/parser.ml" +# 14224 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14254,13 +14250,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 779 "parsing/parser.mly" +# 783 "parsing/parser.mly" (Parsetree.signature) -# 14260 "parsing/parser.ml" +# 14256 "parsing/parser.ml" ) = -# 1074 "parsing/parser.mly" +# 1078 "parsing/parser.mly" ( _1 ) -# 14264 "parsing/parser.ml" +# 14260 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14304,9 +14300,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : (Parsetree.extension) = -# 3750 "parsing/parser.mly" +# 3766 "parsing/parser.mly" ( (_2, _3) ) -# 14310 "parsing/parser.ml" +# 14306 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14325,9 +14321,9 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 689 "parsing/parser.mly" +# 693 "parsing/parser.mly" (string * Location.t * string * Location.t * string option) -# 14331 "parsing/parser.ml" +# 14327 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -14336,9 +14332,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3752 "parsing/parser.mly" +# 3768 "parsing/parser.mly" ( mk_quotedext ~loc:_sloc _1 ) -# 14342 "parsing/parser.ml" +# 14338 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14384,9 +14380,9 @@ module Tables = struct let _1_inlined2 : (Parsetree.core_type) = Obj.magic _1_inlined2 in let _3 : unit = Obj.magic _3 in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 14390 "parsing/parser.ml" +# 14386 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _1 : (Asttypes.mutable_flag) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -14395,34 +14391,34 @@ module Tables = struct let _v : (Parsetree.label_declaration) = let _5 = let _1 = _1_inlined3 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 14401 "parsing/parser.ml" +# 14397 "parsing/parser.ml" in let _endpos__5_ = _endpos__1_inlined3_ in let _4 = let _1 = _1_inlined2 in -# 3168 "parsing/parser.mly" +# 3184 "parsing/parser.mly" ( _1 ) -# 14410 "parsing/parser.ml" +# 14406 "parsing/parser.ml" in let _2 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 14418 "parsing/parser.ml" +# 14414 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 14426 "parsing/parser.ml" +# 14422 "parsing/parser.ml" in let _startpos__2_ = _startpos__1_inlined1_ in @@ -14433,10 +14429,10 @@ module Tables = struct _startpos__2_ in let _sloc = (_symbolstartpos, _endpos) in -# 3045 "parsing/parser.mly" +# 3061 "parsing/parser.mly" ( let info = symbol_info _endpos in Type.field _2 _4 ~mut:_1 ~attrs:_5 ~loc:(make_loc _sloc) ~info ) -# 14440 "parsing/parser.ml" +# 14436 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14496,9 +14492,9 @@ module Tables = struct let _1_inlined2 : (Parsetree.core_type) = Obj.magic _1_inlined2 in let _3 : unit = Obj.magic _3 in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 14502 "parsing/parser.ml" +# 14498 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _1 : (Asttypes.mutable_flag) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -14507,43 +14503,43 @@ module Tables = struct let _v : (Parsetree.label_declaration) = let _7 = let _1 = _1_inlined4 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 14513 "parsing/parser.ml" +# 14509 "parsing/parser.ml" in let _endpos__7_ = _endpos__1_inlined4_ in let _5 = let _1 = _1_inlined3 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 14522 "parsing/parser.ml" +# 14518 "parsing/parser.ml" in let _endpos__5_ = _endpos__1_inlined3_ in let _4 = let _1 = _1_inlined2 in -# 3168 "parsing/parser.mly" +# 3184 "parsing/parser.mly" ( _1 ) -# 14531 "parsing/parser.ml" +# 14527 "parsing/parser.ml" in let _2 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 14539 "parsing/parser.ml" +# 14535 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 14547 "parsing/parser.ml" +# 14543 "parsing/parser.ml" in let _startpos__2_ = _startpos__1_inlined1_ in @@ -14554,14 +14550,14 @@ module Tables = struct _startpos__2_ in let _sloc = (_symbolstartpos, _endpos) in -# 3050 "parsing/parser.mly" +# 3066 "parsing/parser.mly" ( let info = match rhs_info _endpos__5_ with | Some _ as info_before_semi -> info_before_semi | None -> symbol_info _endpos in Type.field _2 _4 ~mut:_1 ~attrs:(_5 @ _7) ~loc:(make_loc _sloc) ~info ) -# 14565 "parsing/parser.ml" +# 14561 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14584,9 +14580,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.label_declaration list) = -# 3039 "parsing/parser.mly" +# 3055 "parsing/parser.mly" ( [_1] ) -# 14590 "parsing/parser.ml" +# 14586 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14609,9 +14605,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.label_declaration list) = -# 3040 "parsing/parser.mly" +# 3056 "parsing/parser.mly" ( [_1] ) -# 14615 "parsing/parser.ml" +# 14611 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14641,9 +14637,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.label_declaration list) = -# 3041 "parsing/parser.mly" +# 3057 "parsing/parser.mly" ( _1 :: _2 ) -# 14647 "parsing/parser.ml" +# 14643 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14662,9 +14658,9 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 14668 "parsing/parser.ml" +# 14664 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -14675,24 +14671,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 14681 "parsing/parser.ml" +# 14677 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2123 "parsing/parser.mly" +# 2129 "parsing/parser.mly" ( (_1.Location.txt, mkpat ~loc:_sloc (Ppat_var _1)) ) -# 14690 "parsing/parser.ml" +# 14686 "parsing/parser.ml" in -# 2115 "parsing/parser.mly" +# 2121 "parsing/parser.mly" ( x ) -# 14696 "parsing/parser.ml" +# 14692 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14725,9 +14721,9 @@ module Tables = struct let cty : (Parsetree.core_type) = Obj.magic cty in let _2 : unit = Obj.magic _2 in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 14731 "parsing/parser.ml" +# 14727 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -14738,18 +14734,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 14744 "parsing/parser.ml" +# 14740 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2123 "parsing/parser.mly" +# 2129 "parsing/parser.mly" ( (_1.Location.txt, mkpat ~loc:_sloc (Ppat_var _1)) ) -# 14753 "parsing/parser.ml" +# 14749 "parsing/parser.ml" in let _startpos_x_ = _startpos__1_ in @@ -14757,11 +14753,11 @@ module Tables = struct let _symbolstartpos = _startpos_x_ in let _sloc = (_symbolstartpos, _endpos) in -# 2117 "parsing/parser.mly" +# 2123 "parsing/parser.mly" ( let lab, pat = x in lab, mkpat ~loc:_sloc (Ppat_constraint (pat, cty)) ) -# 14765 "parsing/parser.ml" +# 14761 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14784,9 +14780,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3497 "parsing/parser.mly" +# 3513 "parsing/parser.mly" ( _1 ) -# 14790 "parsing/parser.ml" +# 14786 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14809,9 +14805,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.arg_label * Parsetree.expression) = -# 2400 "parsing/parser.mly" +# 2402 "parsing/parser.mly" ( (Nolabel, _1) ) -# 14815 "parsing/parser.ml" +# 14811 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14837,17 +14833,17 @@ module Tables = struct } = _menhir_stack in let _2 : (Parsetree.expression) = Obj.magic _2 in let _1 : ( -# 634 "parsing/parser.mly" +# 638 "parsing/parser.mly" (string) -# 14843 "parsing/parser.ml" +# 14839 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.arg_label * Parsetree.expression) = -# 2402 "parsing/parser.mly" +# 2404 "parsing/parser.mly" ( (Labelled _1, _2) ) -# 14851 "parsing/parser.ml" +# 14847 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14872,9 +14868,9 @@ module Tables = struct }; } = _menhir_stack in let label : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 14878 "parsing/parser.ml" +# 14874 "parsing/parser.ml" ) = Obj.magic label in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -14882,10 +14878,10 @@ module Tables = struct let _endpos = _endpos_label_ in let _v : (Asttypes.arg_label * Parsetree.expression) = let _loc_label_ = (_startpos_label_, _endpos_label_) in -# 2404 "parsing/parser.mly" +# 2406 "parsing/parser.mly" ( let loc = _loc_label_ in (Labelled label, mkexpvar ~loc label) ) -# 14889 "parsing/parser.ml" +# 14885 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14910,9 +14906,9 @@ module Tables = struct }; } = _menhir_stack in let label : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 14916 "parsing/parser.ml" +# 14912 "parsing/parser.ml" ) = Obj.magic label in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -14920,10 +14916,10 @@ module Tables = struct let _endpos = _endpos_label_ in let _v : (Asttypes.arg_label * Parsetree.expression) = let _loc_label_ = (_startpos_label_, _endpos_label_) in -# 2407 "parsing/parser.mly" +# 2409 "parsing/parser.mly" ( let loc = _loc_label_ in (Optional label, mkexpvar ~loc label) ) -# 14927 "parsing/parser.ml" +# 14923 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -14949,17 +14945,17 @@ module Tables = struct } = _menhir_stack in let _2 : (Parsetree.expression) = Obj.magic _2 in let _1 : ( -# 664 "parsing/parser.mly" +# 668 "parsing/parser.mly" (string) -# 14955 "parsing/parser.ml" +# 14951 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.arg_label * Parsetree.expression) = -# 2410 "parsing/parser.mly" +# 2412 "parsing/parser.mly" ( (Optional _1, _2) ) -# 14963 "parsing/parser.ml" +# 14959 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15012,15 +15008,15 @@ module Tables = struct let _v : (Asttypes.arg_label * Parsetree.expression option * Parsetree.pattern) = let _4 = let _1 = _1_inlined1 in -# 2111 "parsing/parser.mly" +# 2117 "parsing/parser.mly" ( _1 ) -# 15018 "parsing/parser.ml" +# 15014 "parsing/parser.ml" in -# 2085 "parsing/parser.mly" +# 2091 "parsing/parser.mly" ( (Optional (fst _3), _4, snd _3) ) -# 15024 "parsing/parser.ml" +# 15020 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15045,9 +15041,9 @@ module Tables = struct }; } = _menhir_stack in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 15051 "parsing/parser.ml" +# 15047 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -15060,24 +15056,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 15066 "parsing/parser.ml" +# 15062 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2123 "parsing/parser.mly" +# 2129 "parsing/parser.mly" ( (_1.Location.txt, mkpat ~loc:_sloc (Ppat_var _1)) ) -# 15075 "parsing/parser.ml" +# 15071 "parsing/parser.ml" in -# 2087 "parsing/parser.mly" +# 2093 "parsing/parser.mly" ( (Optional (fst _2), None, snd _2) ) -# 15081 "parsing/parser.ml" +# 15077 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15124,9 +15120,9 @@ module Tables = struct let _3 : (Parsetree.pattern) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 664 "parsing/parser.mly" +# 668 "parsing/parser.mly" (string) -# 15130 "parsing/parser.ml" +# 15126 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -15134,15 +15130,15 @@ module Tables = struct let _v : (Asttypes.arg_label * Parsetree.expression option * Parsetree.pattern) = let _4 = let _1 = _1_inlined1 in -# 2111 "parsing/parser.mly" +# 2117 "parsing/parser.mly" ( _1 ) -# 15140 "parsing/parser.ml" +# 15136 "parsing/parser.ml" in -# 2089 "parsing/parser.mly" +# 2095 "parsing/parser.mly" ( (Optional _1, _4, _3) ) -# 15146 "parsing/parser.ml" +# 15142 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15168,17 +15164,17 @@ module Tables = struct } = _menhir_stack in let _2 : (Parsetree.pattern) = Obj.magic _2 in let _1 : ( -# 664 "parsing/parser.mly" +# 668 "parsing/parser.mly" (string) -# 15174 "parsing/parser.ml" +# 15170 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.arg_label * Parsetree.expression option * Parsetree.pattern) = -# 2091 "parsing/parser.mly" +# 2097 "parsing/parser.mly" ( (Optional _1, None, _2) ) -# 15182 "parsing/parser.ml" +# 15178 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15222,9 +15218,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : (Asttypes.arg_label * Parsetree.expression option * Parsetree.pattern) = -# 2093 "parsing/parser.mly" +# 2099 "parsing/parser.mly" ( (Labelled (fst _3), None, snd _3) ) -# 15228 "parsing/parser.ml" +# 15224 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15249,9 +15245,9 @@ module Tables = struct }; } = _menhir_stack in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 15255 "parsing/parser.ml" +# 15251 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -15264,24 +15260,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 15270 "parsing/parser.ml" +# 15266 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2123 "parsing/parser.mly" +# 2129 "parsing/parser.mly" ( (_1.Location.txt, mkpat ~loc:_sloc (Ppat_var _1)) ) -# 15279 "parsing/parser.ml" +# 15275 "parsing/parser.ml" in -# 2095 "parsing/parser.mly" +# 2101 "parsing/parser.mly" ( (Labelled (fst _2), None, snd _2) ) -# 15285 "parsing/parser.ml" +# 15281 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15307,17 +15303,17 @@ module Tables = struct } = _menhir_stack in let _2 : (Parsetree.pattern) = Obj.magic _2 in let _1 : ( -# 634 "parsing/parser.mly" +# 638 "parsing/parser.mly" (string) -# 15313 "parsing/parser.ml" +# 15309 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.arg_label * Parsetree.expression option * Parsetree.pattern) = -# 2097 "parsing/parser.mly" +# 2103 "parsing/parser.mly" ( (Labelled _1, None, _2) ) -# 15321 "parsing/parser.ml" +# 15317 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15340,9 +15336,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.arg_label * Parsetree.expression option * Parsetree.pattern) = -# 2099 "parsing/parser.mly" +# 2105 "parsing/parser.mly" ( (Nolabel, None, _1) ) -# 15346 "parsing/parser.ml" +# 15342 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15376,15 +15372,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2417 "parsing/parser.mly" +# 2419 "parsing/parser.mly" ( mkpatvar ~loc:_sloc _1 ) -# 15382 "parsing/parser.ml" +# 15378 "parsing/parser.ml" in -# 2421 "parsing/parser.mly" +# 2423 "parsing/parser.mly" ( (_1, _2) ) -# 15388 "parsing/parser.ml" +# 15384 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15432,16 +15428,16 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2417 "parsing/parser.mly" +# 2419 "parsing/parser.mly" ( mkpatvar ~loc:_sloc _1 ) -# 15438 "parsing/parser.ml" +# 15434 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2423 "parsing/parser.mly" +# 2425 "parsing/parser.mly" ( let v = _1 in (* PR#7344 *) let t = match _2 with @@ -15454,7 +15450,7 @@ module Tables = struct let patloc = (_startpos__1_, _endpos__2_) in (ghpat ~loc:patloc (Ppat_constraint(v, typ)), mkexp_constraint ~loc:_sloc _4 _2) ) -# 15458 "parsing/parser.ml" +# 15454 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15523,18 +15519,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 15527 "parsing/parser.ml" +# 15523 "parsing/parser.ml" in -# 915 "parsing/parser.mly" +# 919 "parsing/parser.mly" ( xs ) -# 15532 "parsing/parser.ml" +# 15528 "parsing/parser.ml" in -# 3150 "parsing/parser.mly" +# 3166 "parsing/parser.mly" ( _1 ) -# 15538 "parsing/parser.ml" +# 15534 "parsing/parser.ml" in let _startpos__3_ = _startpos_xs_ in @@ -15543,19 +15539,19 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2417 "parsing/parser.mly" +# 2419 "parsing/parser.mly" ( mkpatvar ~loc:_sloc _1 ) -# 15549 "parsing/parser.ml" +# 15545 "parsing/parser.ml" in -# 2439 "parsing/parser.mly" +# 2441 "parsing/parser.mly" ( let typloc = (_startpos__3_, _endpos__5_) in let patloc = (_startpos__1_, _endpos__5_) in (ghpat ~loc:patloc (Ppat_constraint(_1, ghtyp ~loc:typloc (Ptyp_poly(_3,_5)))), _7) ) -# 15559 "parsing/parser.ml" +# 15555 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15627,30 +15623,30 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__8_ in let _v : (Parsetree.pattern * Parsetree.expression) = let _4 = -# 2414 "parsing/parser.mly" +# 2416 "parsing/parser.mly" ( xs ) -# 15633 "parsing/parser.ml" +# 15629 "parsing/parser.ml" in let _1 = let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2417 "parsing/parser.mly" +# 2419 "parsing/parser.mly" ( mkpatvar ~loc:_sloc _1 ) -# 15642 "parsing/parser.ml" +# 15638 "parsing/parser.ml" in let _endpos = _endpos__8_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2445 "parsing/parser.mly" +# 2447 "parsing/parser.mly" ( let exp, poly = wrap_type_annotation ~loc:_sloc _4 _6 _8 in let loc = (_startpos__1_, _endpos__6_) in (ghpat ~loc (Ppat_constraint(_1, poly)), exp) ) -# 15654 "parsing/parser.ml" +# 15650 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15687,9 +15683,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.pattern * Parsetree.expression) = -# 2450 "parsing/parser.mly" +# 2452 "parsing/parser.mly" ( (_1, _3) ) -# 15693 "parsing/parser.ml" +# 15689 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15740,10 +15736,10 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.pattern * Parsetree.expression) = -# 2452 "parsing/parser.mly" +# 2454 "parsing/parser.mly" ( let loc = (_startpos__1_, _endpos__3_) in (ghpat ~loc (Ppat_constraint(_1, _3)), _5) ) -# 15747 "parsing/parser.ml" +# 15743 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15804,36 +15800,36 @@ module Tables = struct let attrs2 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 15810 "parsing/parser.ml" +# 15806 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined2_ in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 15819 "parsing/parser.ml" +# 15815 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2468 "parsing/parser.mly" +# 2470 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in mklbs ~loc:_sloc ext rec_flag (mklb ~loc:_sloc true body attrs) ) -# 15831 "parsing/parser.ml" +# 15827 "parsing/parser.ml" in -# 2458 "parsing/parser.mly" +# 2460 "parsing/parser.mly" ( _1 ) -# 15837 "parsing/parser.ml" +# 15833 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15863,9 +15859,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (let_bindings) = -# 2459 "parsing/parser.mly" +# 2461 "parsing/parser.mly" ( addlb _1 _2 ) -# 15869 "parsing/parser.ml" +# 15865 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -15919,41 +15915,41 @@ module Tables = struct let attrs2 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 15925 "parsing/parser.ml" +# 15921 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined2_ in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 15934 "parsing/parser.ml" +# 15930 "parsing/parser.ml" in let ext = -# 3738 "parsing/parser.mly" +# 3754 "parsing/parser.mly" ( None ) -# 15940 "parsing/parser.ml" +# 15936 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2468 "parsing/parser.mly" +# 2470 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in mklbs ~loc:_sloc ext rec_flag (mklb ~loc:_sloc true body attrs) ) -# 15951 "parsing/parser.ml" +# 15947 "parsing/parser.ml" in -# 2458 "parsing/parser.mly" +# 2460 "parsing/parser.mly" ( _1 ) -# 15957 "parsing/parser.ml" +# 15953 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16021,18 +16017,18 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 16027 "parsing/parser.ml" +# 16023 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in let attrs1 = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 16036 "parsing/parser.ml" +# 16032 "parsing/parser.ml" in let ext = @@ -16041,27 +16037,27 @@ module Tables = struct let _startpos = _startpos__1_ in let _loc = (_startpos, _endpos) in -# 3739 "parsing/parser.mly" +# 3755 "parsing/parser.mly" ( not_expecting _loc "extension" ) -# 16047 "parsing/parser.ml" +# 16043 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2468 "parsing/parser.mly" +# 2470 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in mklbs ~loc:_sloc ext rec_flag (mklb ~loc:_sloc true body attrs) ) -# 16059 "parsing/parser.ml" +# 16055 "parsing/parser.ml" in -# 2458 "parsing/parser.mly" +# 2460 "parsing/parser.mly" ( _1 ) -# 16065 "parsing/parser.ml" +# 16061 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16091,9 +16087,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (let_bindings) = -# 2459 "parsing/parser.mly" +# 2461 "parsing/parser.mly" ( addlb _1 _2 ) -# 16097 "parsing/parser.ml" +# 16093 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16116,9 +16112,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = -# 2127 "parsing/parser.mly" +# 2133 "parsing/parser.mly" ( _1 ) -# 16122 "parsing/parser.ml" +# 16118 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16156,24 +16152,24 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 2129 "parsing/parser.mly" +# 2135 "parsing/parser.mly" ( Ppat_constraint(_1, _3) ) -# 16162 "parsing/parser.ml" +# 16158 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 16171 "parsing/parser.ml" +# 16167 "parsing/parser.ml" in -# 2130 "parsing/parser.mly" +# 2136 "parsing/parser.mly" ( _1 ) -# 16177 "parsing/parser.ml" +# 16173 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16207,15 +16203,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2417 "parsing/parser.mly" +# 2419 "parsing/parser.mly" ( mkpatvar ~loc:_sloc _1 ) -# 16213 "parsing/parser.ml" +# 16209 "parsing/parser.ml" in -# 2485 "parsing/parser.mly" +# 2487 "parsing/parser.mly" ( (pat, exp) ) -# 16219 "parsing/parser.ml" +# 16215 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16266,10 +16262,10 @@ module Tables = struct let _startpos = _startpos_pat_ in let _endpos = _endpos_exp_ in let _v : (Parsetree.pattern * Parsetree.expression) = -# 2487 "parsing/parser.mly" +# 2489 "parsing/parser.mly" ( let loc = (_startpos_pat_, _endpos_typ_) in (ghpat ~loc (Ppat_constraint(pat, typ)), exp) ) -# 16273 "parsing/parser.ml" +# 16269 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16306,9 +16302,9 @@ module Tables = struct let _startpos = _startpos_pat_ in let _endpos = _endpos_exp_ in let _v : (Parsetree.pattern * Parsetree.expression) = -# 2490 "parsing/parser.mly" +# 2492 "parsing/parser.mly" ( (pat, exp) ) -# 16312 "parsing/parser.ml" +# 16308 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16331,10 +16327,10 @@ module Tables = struct let _startpos = _startpos_body_ in let _endpos = _endpos_body_ in let _v : (Parsetree.pattern * Parsetree.expression * Parsetree.binding_op list) = -# 2494 "parsing/parser.mly" +# 2496 "parsing/parser.mly" ( let let_pat, let_exp = body in let_pat, let_exp, [] ) -# 16338 "parsing/parser.ml" +# 16334 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16366,9 +16362,9 @@ module Tables = struct } = _menhir_stack in let body : (Parsetree.pattern * Parsetree.expression) = Obj.magic body in let _1 : ( -# 630 "parsing/parser.mly" +# 634 "parsing/parser.mly" (string) -# 16372 "parsing/parser.ml" +# 16368 "parsing/parser.ml" ) = Obj.magic _1 in let bindings : (Parsetree.pattern * Parsetree.expression * Parsetree.binding_op list) = Obj.magic bindings in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -16379,22 +16375,22 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 16385 "parsing/parser.ml" +# 16381 "parsing/parser.ml" in let _endpos = _endpos_body_ in let _symbolstartpos = _startpos_bindings_ in let _sloc = (_symbolstartpos, _endpos) in -# 2497 "parsing/parser.mly" +# 2499 "parsing/parser.mly" ( let let_pat, let_exp, rev_ands = bindings in let pbop_pat, pbop_exp = body in let pbop_loc = make_loc _sloc in let and_ = {pbop_op; pbop_pat; pbop_exp; pbop_loc} in let_pat, let_exp, and_ :: rev_ands ) -# 16398 "parsing/parser.ml" +# 16394 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16412,7 +16408,7 @@ module Tables = struct let _v : (Parsetree.class_declaration list) = # 211 "" ( [] ) -# 16416 "parsing/parser.ml" +# 16412 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16476,11 +16472,11 @@ module Tables = struct let _1_inlined3 : (Parsetree.attributes) = Obj.magic _1_inlined3 in let body : (Parsetree.class_expr) = Obj.magic body in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 16482 "parsing/parser.ml" +# 16478 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let virt : (Asttypes.virtual_flag) = Obj.magic virt in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in @@ -16491,9 +16487,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 16497 "parsing/parser.ml" +# 16493 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -16503,24 +16499,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 16509 "parsing/parser.ml" +# 16505 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 16517 "parsing/parser.ml" +# 16513 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1731 "parsing/parser.mly" +# 1737 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in @@ -16528,13 +16524,13 @@ module Tables = struct let text = symbol_text _symbolstartpos in Ci.mk id body ~virt ~params ~attrs ~loc ~text ~docs ) -# 16532 "parsing/parser.ml" +# 16528 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 16538 "parsing/parser.ml" +# 16534 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16552,7 +16548,7 @@ module Tables = struct let _v : (Parsetree.class_description list) = # 211 "" ( [] ) -# 16556 "parsing/parser.ml" +# 16552 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16623,11 +16619,11 @@ module Tables = struct let cty : (Parsetree.class_type) = Obj.magic cty in let _6 : unit = Obj.magic _6 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 16629 "parsing/parser.ml" +# 16625 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let virt : (Asttypes.virtual_flag) = Obj.magic virt in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in @@ -16638,9 +16634,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 16644 "parsing/parser.ml" +# 16640 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -16650,24 +16646,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 16656 "parsing/parser.ml" +# 16652 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 16664 "parsing/parser.ml" +# 16660 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2022 "parsing/parser.mly" +# 2028 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in @@ -16675,13 +16671,13 @@ module Tables = struct let text = symbol_text _symbolstartpos in Ci.mk id cty ~virt ~params ~attrs ~loc ~text ~docs ) -# 16679 "parsing/parser.ml" +# 16675 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 16685 "parsing/parser.ml" +# 16681 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16699,7 +16695,7 @@ module Tables = struct let _v : (Parsetree.class_type_declaration list) = # 211 "" ( [] ) -# 16703 "parsing/parser.ml" +# 16699 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16770,11 +16766,11 @@ module Tables = struct let csig : (Parsetree.class_type) = Obj.magic csig in let _6 : unit = Obj.magic _6 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 16776 "parsing/parser.ml" +# 16772 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let virt : (Asttypes.virtual_flag) = Obj.magic virt in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in @@ -16785,9 +16781,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 16791 "parsing/parser.ml" +# 16787 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -16797,24 +16793,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 16803 "parsing/parser.ml" +# 16799 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 16811 "parsing/parser.ml" +# 16807 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2061 "parsing/parser.mly" +# 2067 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in @@ -16822,13 +16818,13 @@ module Tables = struct let text = symbol_text _symbolstartpos in Ci.mk id csig ~virt ~params ~attrs ~loc ~text ~docs ) -# 16826 "parsing/parser.ml" +# 16822 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 16832 "parsing/parser.ml" +# 16828 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16846,7 +16842,7 @@ module Tables = struct let _v : (Parsetree.module_binding list) = # 211 "" ( [] ) -# 16850 "parsing/parser.ml" +# 16846 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16907,9 +16903,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 16913 "parsing/parser.ml" +# 16909 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -16919,24 +16915,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 16925 "parsing/parser.ml" +# 16921 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 16933 "parsing/parser.ml" +# 16929 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1413 "parsing/parser.mly" +# 1418 "parsing/parser.mly" ( let loc = make_loc _sloc in let attrs = attrs1 @ attrs2 in @@ -16944,13 +16940,13 @@ module Tables = struct let text = symbol_text _symbolstartpos in Mb.mk name body ~attrs ~loc ~text ~docs ) -# 16948 "parsing/parser.ml" +# 16944 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 16954 "parsing/parser.ml" +# 16950 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -16968,7 +16964,7 @@ module Tables = struct let _v : (Parsetree.module_declaration list) = # 211 "" ( [] ) -# 16972 "parsing/parser.ml" +# 16968 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17036,9 +17032,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 17042 "parsing/parser.ml" +# 17038 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -17048,24 +17044,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 17054 "parsing/parser.ml" +# 17050 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 17062 "parsing/parser.ml" +# 17058 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1689 "parsing/parser.mly" +# 1695 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let docs = symbol_docs _sloc in @@ -17073,13 +17069,13 @@ module Tables = struct let text = symbol_text _symbolstartpos in Md.mk name mty ~attrs ~loc ~text ~docs ) -# 17077 "parsing/parser.ml" +# 17073 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 17083 "parsing/parser.ml" +# 17079 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17097,7 +17093,7 @@ module Tables = struct let _v : (Parsetree.attributes) = # 211 "" ( [] ) -# 17101 "parsing/parser.ml" +# 17097 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17129,7 +17125,7 @@ module Tables = struct let _v : (Parsetree.attributes) = # 213 "" ( x :: xs ) -# 17133 "parsing/parser.ml" +# 17129 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17147,7 +17143,7 @@ module Tables = struct let _v : (Parsetree.type_declaration list) = # 211 "" ( [] ) -# 17151 "parsing/parser.ml" +# 17147 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17212,11 +17208,11 @@ module Tables = struct let xs_inlined1 : ((Parsetree.core_type * Parsetree.core_type * Ast_helper.loc) list) = Obj.magic xs_inlined1 in let kind_priv_manifest : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = Obj.magic kind_priv_manifest in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 17218 "parsing/parser.ml" +# 17214 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -17227,9 +17223,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 17233 "parsing/parser.ml" +# 17229 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -17238,18 +17234,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 17242 "parsing/parser.ml" +# 17238 "parsing/parser.ml" in -# 897 "parsing/parser.mly" +# 901 "parsing/parser.mly" ( xs ) -# 17247 "parsing/parser.ml" +# 17243 "parsing/parser.ml" in -# 2887 "parsing/parser.mly" +# 2892 "parsing/parser.mly" ( _1 ) -# 17253 "parsing/parser.ml" +# 17249 "parsing/parser.ml" in let id = @@ -17258,24 +17254,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 17264 "parsing/parser.ml" +# 17260 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 17272 "parsing/parser.ml" +# 17268 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2876 "parsing/parser.mly" +# 2881 "parsing/parser.mly" ( let (kind, priv, manifest) = kind_priv_manifest in let docs = symbol_docs _sloc in @@ -17284,13 +17280,13 @@ module Tables = struct let text = symbol_text _symbolstartpos in Type.mk id ~params ~cstrs ~kind ~priv ?manifest ~attrs ~loc ~docs ~text ) -# 17288 "parsing/parser.ml" +# 17284 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 17294 "parsing/parser.ml" +# 17290 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17308,7 +17304,7 @@ module Tables = struct let _v : (Parsetree.type_declaration list) = # 211 "" ( [] ) -# 17312 "parsing/parser.ml" +# 17308 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17380,11 +17376,11 @@ module Tables = struct let _2 : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = Obj.magic _2 in let _1_inlined3 : unit = Obj.magic _1_inlined3 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 17386 "parsing/parser.ml" +# 17382 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -17395,9 +17391,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined4 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 17401 "parsing/parser.ml" +# 17397 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined4_ in @@ -17406,26 +17402,26 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 17410 "parsing/parser.ml" +# 17406 "parsing/parser.ml" in -# 897 "parsing/parser.mly" +# 901 "parsing/parser.mly" ( xs ) -# 17415 "parsing/parser.ml" +# 17411 "parsing/parser.ml" in -# 2887 "parsing/parser.mly" +# 2892 "parsing/parser.mly" ( _1 ) -# 17421 "parsing/parser.ml" +# 17417 "parsing/parser.ml" in let kind_priv_manifest = let _1 = _1_inlined3 in -# 2922 "parsing/parser.mly" +# 2927 "parsing/parser.mly" ( _2 ) -# 17429 "parsing/parser.ml" +# 17425 "parsing/parser.ml" in let id = @@ -17434,24 +17430,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 17440 "parsing/parser.ml" +# 17436 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 17448 "parsing/parser.ml" +# 17444 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2876 "parsing/parser.mly" +# 2881 "parsing/parser.mly" ( let (kind, priv, manifest) = kind_priv_manifest in let docs = symbol_docs _sloc in @@ -17460,13 +17456,13 @@ module Tables = struct let text = symbol_text _symbolstartpos in Type.mk id ~params ~cstrs ~kind ~priv ?manifest ~attrs ~loc ~docs ~text ) -# 17464 "parsing/parser.ml" +# 17460 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 17470 "parsing/parser.ml" +# 17466 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17484,7 +17480,7 @@ module Tables = struct let _v : (Parsetree.attributes) = # 211 "" ( [] ) -# 17488 "parsing/parser.ml" +# 17484 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17516,7 +17512,7 @@ module Tables = struct let _v : (Parsetree.attributes) = # 213 "" ( x :: xs ) -# 17520 "parsing/parser.ml" +# 17516 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17534,7 +17530,7 @@ module Tables = struct let _v : (Parsetree.signature_item list list) = # 211 "" ( [] ) -# 17538 "parsing/parser.ml" +# 17534 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17567,21 +17563,21 @@ module Tables = struct let _1 = let _startpos = _startpos__1_ in -# 823 "parsing/parser.mly" +# 827 "parsing/parser.mly" ( text_sig _startpos ) -# 17573 "parsing/parser.ml" +# 17569 "parsing/parser.ml" in -# 1551 "parsing/parser.mly" +# 1556 "parsing/parser.mly" ( _1 ) -# 17579 "parsing/parser.ml" +# 17575 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 17585 "parsing/parser.ml" +# 17581 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17614,21 +17610,21 @@ module Tables = struct let _1 = let _startpos = _startpos__1_ in -# 821 "parsing/parser.mly" +# 825 "parsing/parser.mly" ( text_sig _startpos @ [_1] ) -# 17620 "parsing/parser.ml" +# 17616 "parsing/parser.ml" in -# 1551 "parsing/parser.mly" +# 1556 "parsing/parser.mly" ( _1 ) -# 17626 "parsing/parser.ml" +# 17622 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 17632 "parsing/parser.ml" +# 17628 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17646,7 +17642,7 @@ module Tables = struct let _v : (Parsetree.structure_item list list) = # 211 "" ( [] ) -# 17650 "parsing/parser.ml" +# 17646 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17679,40 +17675,40 @@ module Tables = struct let _1 = let ys = let items = -# 883 "parsing/parser.mly" +# 887 "parsing/parser.mly" ( [] ) -# 17685 "parsing/parser.ml" +# 17681 "parsing/parser.ml" in -# 1297 "parsing/parser.mly" +# 1301 "parsing/parser.mly" ( items ) -# 17690 "parsing/parser.ml" +# 17686 "parsing/parser.ml" in let xs = let _startpos = _startpos__1_ in -# 819 "parsing/parser.mly" +# 823 "parsing/parser.mly" ( text_str _startpos ) -# 17698 "parsing/parser.ml" +# 17694 "parsing/parser.ml" in # 267 "" ( xs @ ys ) -# 17704 "parsing/parser.ml" +# 17700 "parsing/parser.ml" in -# 1313 "parsing/parser.mly" +# 1317 "parsing/parser.mly" ( _1 ) -# 17710 "parsing/parser.ml" +# 17706 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 17716 "parsing/parser.ml" +# 17712 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17764,70 +17760,70 @@ module Tables = struct let _1 = let _1 = let attrs = -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 17770 "parsing/parser.ml" +# 17766 "parsing/parser.ml" in -# 1304 "parsing/parser.mly" +# 1308 "parsing/parser.mly" ( mkstrexp e attrs ) -# 17775 "parsing/parser.ml" +# 17771 "parsing/parser.ml" in let _startpos__1_ = _startpos_e_ in let _startpos = _startpos__1_ in -# 817 "parsing/parser.mly" +# 821 "parsing/parser.mly" ( text_str _startpos @ [_1] ) -# 17783 "parsing/parser.ml" +# 17779 "parsing/parser.ml" in let _startpos__1_ = _startpos_e_ in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 836 "parsing/parser.mly" +# 840 "parsing/parser.mly" ( mark_rhs_docs _startpos _endpos; _1 ) -# 17793 "parsing/parser.ml" +# 17789 "parsing/parser.ml" in -# 885 "parsing/parser.mly" +# 889 "parsing/parser.mly" ( x ) -# 17799 "parsing/parser.ml" +# 17795 "parsing/parser.ml" in -# 1297 "parsing/parser.mly" +# 1301 "parsing/parser.mly" ( items ) -# 17805 "parsing/parser.ml" +# 17801 "parsing/parser.ml" in let xs = let _startpos = _startpos__1_ in -# 819 "parsing/parser.mly" +# 823 "parsing/parser.mly" ( text_str _startpos ) -# 17813 "parsing/parser.ml" +# 17809 "parsing/parser.ml" in # 267 "" ( xs @ ys ) -# 17819 "parsing/parser.ml" +# 17815 "parsing/parser.ml" in -# 1313 "parsing/parser.mly" +# 1317 "parsing/parser.mly" ( _1 ) -# 17825 "parsing/parser.ml" +# 17821 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 17831 "parsing/parser.ml" +# 17827 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17860,21 +17856,21 @@ module Tables = struct let _1 = let _startpos = _startpos__1_ in -# 817 "parsing/parser.mly" +# 821 "parsing/parser.mly" ( text_str _startpos @ [_1] ) -# 17866 "parsing/parser.ml" +# 17862 "parsing/parser.ml" in -# 1313 "parsing/parser.mly" +# 1317 "parsing/parser.mly" ( _1 ) -# 17872 "parsing/parser.ml" +# 17868 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 17878 "parsing/parser.ml" +# 17874 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17892,7 +17888,7 @@ module Tables = struct let _v : (Parsetree.class_type_field list list) = # 211 "" ( [] ) -# 17896 "parsing/parser.ml" +# 17892 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17924,15 +17920,15 @@ module Tables = struct let _v : (Parsetree.class_type_field list list) = let x = let _startpos = _startpos__1_ in -# 831 "parsing/parser.mly" +# 835 "parsing/parser.mly" ( text_csig _startpos @ [_1] ) -# 17930 "parsing/parser.ml" +# 17926 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 17936 "parsing/parser.ml" +# 17932 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17950,7 +17946,7 @@ module Tables = struct let _v : (Parsetree.class_field list list) = # 211 "" ( [] ) -# 17954 "parsing/parser.ml" +# 17950 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -17982,15 +17978,15 @@ module Tables = struct let _v : (Parsetree.class_field list list) = let x = let _startpos = _startpos__1_ in -# 829 "parsing/parser.mly" +# 833 "parsing/parser.mly" ( text_cstr _startpos @ [_1] ) -# 17988 "parsing/parser.ml" +# 17984 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 17994 "parsing/parser.ml" +# 17990 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18008,7 +18004,7 @@ module Tables = struct let _v : (Parsetree.structure_item list list) = # 211 "" ( [] ) -# 18012 "parsing/parser.ml" +# 18008 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18040,15 +18036,15 @@ module Tables = struct let _v : (Parsetree.structure_item list list) = let x = let _startpos = _startpos__1_ in -# 817 "parsing/parser.mly" +# 821 "parsing/parser.mly" ( text_str _startpos @ [_1] ) -# 18046 "parsing/parser.ml" +# 18042 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 18052 "parsing/parser.ml" +# 18048 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18066,7 +18062,7 @@ module Tables = struct let _v : (Parsetree.toplevel_phrase list list) = # 211 "" ( [] ) -# 18070 "parsing/parser.ml" +# 18066 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18099,32 +18095,32 @@ module Tables = struct let _1 = let x = let _1 = -# 883 "parsing/parser.mly" +# 887 "parsing/parser.mly" ( [] ) -# 18105 "parsing/parser.ml" +# 18101 "parsing/parser.ml" in -# 1113 "parsing/parser.mly" +# 1117 "parsing/parser.mly" ( _1 ) -# 18110 "parsing/parser.ml" +# 18106 "parsing/parser.ml" in # 183 "" ( x ) -# 18116 "parsing/parser.ml" +# 18112 "parsing/parser.ml" in -# 1125 "parsing/parser.mly" +# 1129 "parsing/parser.mly" ( _1 ) -# 18122 "parsing/parser.ml" +# 18118 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 18128 "parsing/parser.ml" +# 18124 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18176,58 +18172,58 @@ module Tables = struct let _1 = let _1 = let attrs = -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 18182 "parsing/parser.ml" +# 18178 "parsing/parser.ml" in -# 1304 "parsing/parser.mly" +# 1308 "parsing/parser.mly" ( mkstrexp e attrs ) -# 18187 "parsing/parser.ml" +# 18183 "parsing/parser.ml" in -# 827 "parsing/parser.mly" +# 831 "parsing/parser.mly" ( Ptop_def [_1] ) -# 18193 "parsing/parser.ml" +# 18189 "parsing/parser.ml" in let _startpos__1_ = _startpos_e_ in let _startpos = _startpos__1_ in -# 825 "parsing/parser.mly" +# 829 "parsing/parser.mly" ( text_def _startpos @ [_1] ) -# 18201 "parsing/parser.ml" +# 18197 "parsing/parser.ml" in -# 885 "parsing/parser.mly" +# 889 "parsing/parser.mly" ( x ) -# 18207 "parsing/parser.ml" +# 18203 "parsing/parser.ml" in -# 1113 "parsing/parser.mly" +# 1117 "parsing/parser.mly" ( _1 ) -# 18213 "parsing/parser.ml" +# 18209 "parsing/parser.ml" in # 183 "" ( x ) -# 18219 "parsing/parser.ml" +# 18215 "parsing/parser.ml" in -# 1125 "parsing/parser.mly" +# 1129 "parsing/parser.mly" ( _1 ) -# 18225 "parsing/parser.ml" +# 18221 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 18231 "parsing/parser.ml" +# 18227 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18259,27 +18255,27 @@ module Tables = struct let _v : (Parsetree.toplevel_phrase list list) = let x = let _1 = let _1 = -# 827 "parsing/parser.mly" +# 831 "parsing/parser.mly" ( Ptop_def [_1] ) -# 18265 "parsing/parser.ml" +# 18261 "parsing/parser.ml" in let _startpos = _startpos__1_ in -# 825 "parsing/parser.mly" +# 829 "parsing/parser.mly" ( text_def _startpos @ [_1] ) -# 18271 "parsing/parser.ml" +# 18267 "parsing/parser.ml" in -# 1125 "parsing/parser.mly" +# 1129 "parsing/parser.mly" ( _1 ) -# 18277 "parsing/parser.ml" +# 18273 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 18283 "parsing/parser.ml" +# 18279 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18314,29 +18310,29 @@ module Tables = struct let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 836 "parsing/parser.mly" +# 840 "parsing/parser.mly" ( mark_rhs_docs _startpos _endpos; _1 ) -# 18321 "parsing/parser.ml" +# 18317 "parsing/parser.ml" in let _startpos = _startpos__1_ in -# 825 "parsing/parser.mly" +# 829 "parsing/parser.mly" ( text_def _startpos @ [_1] ) -# 18328 "parsing/parser.ml" +# 18324 "parsing/parser.ml" in -# 1125 "parsing/parser.mly" +# 1129 "parsing/parser.mly" ( _1 ) -# 18334 "parsing/parser.ml" +# 18330 "parsing/parser.ml" in # 213 "" ( x :: xs ) -# 18340 "parsing/parser.ml" +# 18336 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18375,7 +18371,7 @@ module Tables = struct let _v : ((Longident.t Asttypes.loc * Parsetree.pattern) list * unit option) = let _2 = # 124 "" ( None ) -# 18379 "parsing/parser.ml" +# 18375 "parsing/parser.ml" in let x = let label = @@ -18383,9 +18379,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 18389 "parsing/parser.ml" +# 18385 "parsing/parser.ml" in let _startpos_label_ = _startpos__1_ in @@ -18393,24 +18389,27 @@ module Tables = struct let _symbolstartpos = _startpos_label_ in let _sloc = (_symbolstartpos, _endpos) in -# 2765 "parsing/parser.mly" - ( let pat = +# 2767 "parsing/parser.mly" + ( let label, pat = match opat with | None -> - (* No pattern; this is a pun. Desugar it. *) - pat_of_label ~loc:_sloc label + (* No pattern; this is a pun. Desugar it. + But that the pattern was there and the label reconstructed (which + piece of AST is marked as ghost is important for warning + emission). *) + make_ghost label, pat_of_label label | Some pat -> - pat + label, pat in label, mkpat_opt_constraint ~loc:_sloc pat octy ) -# 18408 "parsing/parser.ml" +# 18407 "parsing/parser.ml" in -# 1052 "parsing/parser.mly" +# 1056 "parsing/parser.mly" ( [x], None ) -# 18414 "parsing/parser.ml" +# 18413 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18456,7 +18455,7 @@ module Tables = struct let _v : ((Longident.t Asttypes.loc * Parsetree.pattern) list * unit option) = let _2 = # 126 "" ( Some x ) -# 18460 "parsing/parser.ml" +# 18459 "parsing/parser.ml" in let x = let label = @@ -18464,9 +18463,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 18470 "parsing/parser.ml" +# 18469 "parsing/parser.ml" in let _startpos_label_ = _startpos__1_ in @@ -18474,24 +18473,27 @@ module Tables = struct let _symbolstartpos = _startpos_label_ in let _sloc = (_symbolstartpos, _endpos) in -# 2765 "parsing/parser.mly" - ( let pat = +# 2767 "parsing/parser.mly" + ( let label, pat = match opat with | None -> - (* No pattern; this is a pun. Desugar it. *) - pat_of_label ~loc:_sloc label + (* No pattern; this is a pun. Desugar it. + But that the pattern was there and the label reconstructed (which + piece of AST is marked as ghost is important for warning + emission). *) + make_ghost label, pat_of_label label | Some pat -> - pat + label, pat in label, mkpat_opt_constraint ~loc:_sloc pat octy ) -# 18489 "parsing/parser.ml" +# 18491 "parsing/parser.ml" in -# 1052 "parsing/parser.mly" +# 1056 "parsing/parser.mly" ( [x], None ) -# 18495 "parsing/parser.ml" +# 18497 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18554,9 +18556,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 18560 "parsing/parser.ml" +# 18562 "parsing/parser.ml" in let _startpos_label_ = _startpos__1_ in @@ -18564,24 +18566,27 @@ module Tables = struct let _symbolstartpos = _startpos_label_ in let _sloc = (_symbolstartpos, _endpos) in -# 2765 "parsing/parser.mly" - ( let pat = +# 2767 "parsing/parser.mly" + ( let label, pat = match opat with | None -> - (* No pattern; this is a pun. Desugar it. *) - pat_of_label ~loc:_sloc label + (* No pattern; this is a pun. Desugar it. + But that the pattern was there and the label reconstructed (which + piece of AST is marked as ghost is important for warning + emission). *) + make_ghost label, pat_of_label label | Some pat -> - pat + label, pat in label, mkpat_opt_constraint ~loc:_sloc pat octy ) -# 18579 "parsing/parser.ml" +# 18584 "parsing/parser.ml" in -# 1054 "parsing/parser.mly" +# 1058 "parsing/parser.mly" ( [x], Some y ) -# 18585 "parsing/parser.ml" +# 18590 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18637,9 +18642,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 18643 "parsing/parser.ml" +# 18648 "parsing/parser.ml" in let _startpos_label_ = _startpos__1_ in @@ -18647,25 +18652,28 @@ module Tables = struct let _symbolstartpos = _startpos_label_ in let _sloc = (_symbolstartpos, _endpos) in -# 2765 "parsing/parser.mly" - ( let pat = +# 2767 "parsing/parser.mly" + ( let label, pat = match opat with | None -> - (* No pattern; this is a pun. Desugar it. *) - pat_of_label ~loc:_sloc label + (* No pattern; this is a pun. Desugar it. + But that the pattern was there and the label reconstructed (which + piece of AST is marked as ghost is important for warning + emission). *) + make_ghost label, pat_of_label label | Some pat -> - pat + label, pat in label, mkpat_opt_constraint ~loc:_sloc pat octy ) -# 18662 "parsing/parser.ml" +# 18670 "parsing/parser.ml" in -# 1058 "parsing/parser.mly" +# 1062 "parsing/parser.mly" ( let xs, y = tail in x :: xs, y ) -# 18669 "parsing/parser.ml" +# 18677 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18702,9 +18710,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.case) = -# 2523 "parsing/parser.mly" +# 2525 "parsing/parser.mly" ( Exp.case _1 _3 ) -# 18708 "parsing/parser.ml" +# 18716 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18755,9 +18763,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.case) = -# 2525 "parsing/parser.mly" +# 2527 "parsing/parser.mly" ( Exp.case _1 ~guard:_3 _5 ) -# 18761 "parsing/parser.ml" +# 18769 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18795,9 +18803,9 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Parsetree.case) = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2527 "parsing/parser.mly" +# 2529 "parsing/parser.mly" ( Exp.case _1 (Exp.unreachable ~loc:(make_loc _loc__3_) ()) ) -# 18801 "parsing/parser.ml" +# 18809 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18858,9 +18866,9 @@ module Tables = struct let _1_inlined1 : (Parsetree.core_type) = Obj.magic _1_inlined1 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 18864 "parsing/parser.ml" +# 18872 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -18869,49 +18877,49 @@ module Tables = struct let _6 = let _1 = _1_inlined3 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 18875 "parsing/parser.ml" +# 18883 "parsing/parser.ml" in let _endpos__6_ = _endpos__1_inlined3_ in let _4 = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 18884 "parsing/parser.ml" +# 18892 "parsing/parser.ml" in let _endpos__4_ = _endpos__1_inlined2_ in let _3 = let _1 = _1_inlined1 in -# 3168 "parsing/parser.mly" +# 3184 "parsing/parser.mly" ( _1 ) -# 18893 "parsing/parser.ml" +# 18901 "parsing/parser.ml" in let _1 = let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 18900 "parsing/parser.ml" +# 18908 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 18908 "parsing/parser.ml" +# 18916 "parsing/parser.ml" in let _endpos = _endpos__6_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3378 "parsing/parser.mly" +# 3394 "parsing/parser.mly" ( let info = match rhs_info _endpos__4_ with | Some _ as info_before_semi -> info_before_semi @@ -18919,13 +18927,13 @@ module Tables = struct in let attrs = add_info_attrs info (_4 @ _6) in Of.tag ~loc:(make_loc _sloc) ~attrs _1 _3 ) -# 18923 "parsing/parser.ml" +# 18931 "parsing/parser.ml" in -# 3359 "parsing/parser.mly" +# 3375 "parsing/parser.mly" ( let (f, c) = tail in (head :: f, c) ) -# 18929 "parsing/parser.ml" +# 18937 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -18966,15 +18974,15 @@ module Tables = struct let _symbolstartpos = _startpos_ty_ in let _sloc = (_symbolstartpos, _endpos) in -# 3389 "parsing/parser.mly" +# 3405 "parsing/parser.mly" ( Of.inherit_ ~loc:(make_loc _sloc) ty ) -# 18972 "parsing/parser.ml" +# 18980 "parsing/parser.ml" in -# 3359 "parsing/parser.mly" +# 3375 "parsing/parser.mly" ( let (f, c) = tail in (head :: f, c) ) -# 18978 "parsing/parser.ml" +# 18986 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19028,9 +19036,9 @@ module Tables = struct let _1_inlined1 : (Parsetree.core_type) = Obj.magic _1_inlined1 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 19034 "parsing/parser.ml" +# 19042 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -19039,49 +19047,49 @@ module Tables = struct let _6 = let _1 = _1_inlined3 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 19045 "parsing/parser.ml" +# 19053 "parsing/parser.ml" in let _endpos__6_ = _endpos__1_inlined3_ in let _4 = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 19054 "parsing/parser.ml" +# 19062 "parsing/parser.ml" in let _endpos__4_ = _endpos__1_inlined2_ in let _3 = let _1 = _1_inlined1 in -# 3168 "parsing/parser.mly" +# 3184 "parsing/parser.mly" ( _1 ) -# 19063 "parsing/parser.ml" +# 19071 "parsing/parser.ml" in let _1 = let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 19070 "parsing/parser.ml" +# 19078 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 19078 "parsing/parser.ml" +# 19086 "parsing/parser.ml" in let _endpos = _endpos__6_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3378 "parsing/parser.mly" +# 3394 "parsing/parser.mly" ( let info = match rhs_info _endpos__4_ with | Some _ as info_before_semi -> info_before_semi @@ -19089,13 +19097,13 @@ module Tables = struct in let attrs = add_info_attrs info (_4 @ _6) in Of.tag ~loc:(make_loc _sloc) ~attrs _1 _3 ) -# 19093 "parsing/parser.ml" +# 19101 "parsing/parser.ml" in -# 3362 "parsing/parser.mly" +# 3378 "parsing/parser.mly" ( [head], Closed ) -# 19099 "parsing/parser.ml" +# 19107 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19129,15 +19137,15 @@ module Tables = struct let _symbolstartpos = _startpos_ty_ in let _sloc = (_symbolstartpos, _endpos) in -# 3389 "parsing/parser.mly" +# 3405 "parsing/parser.mly" ( Of.inherit_ ~loc:(make_loc _sloc) ty ) -# 19135 "parsing/parser.ml" +# 19143 "parsing/parser.ml" in -# 3362 "parsing/parser.mly" +# 3378 "parsing/parser.mly" ( [head], Closed ) -# 19141 "parsing/parser.ml" +# 19149 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19177,9 +19185,9 @@ module Tables = struct let _1_inlined1 : (Parsetree.core_type) = Obj.magic _1_inlined1 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 19183 "parsing/parser.ml" +# 19191 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -19188,50 +19196,50 @@ module Tables = struct let _4 = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 19194 "parsing/parser.ml" +# 19202 "parsing/parser.ml" in let _endpos__4_ = _endpos__1_inlined2_ in let _3 = let _1 = _1_inlined1 in -# 3168 "parsing/parser.mly" +# 3184 "parsing/parser.mly" ( _1 ) -# 19203 "parsing/parser.ml" +# 19211 "parsing/parser.ml" in let _1 = let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 19210 "parsing/parser.ml" +# 19218 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 19218 "parsing/parser.ml" +# 19226 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3371 "parsing/parser.mly" +# 3387 "parsing/parser.mly" ( let info = symbol_info _endpos in let attrs = add_info_attrs info _4 in Of.tag ~loc:(make_loc _sloc) ~attrs _1 _3 ) -# 19229 "parsing/parser.ml" +# 19237 "parsing/parser.ml" in -# 3365 "parsing/parser.mly" +# 3381 "parsing/parser.mly" ( [head], Closed ) -# 19235 "parsing/parser.ml" +# 19243 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19258,15 +19266,15 @@ module Tables = struct let _symbolstartpos = _startpos_ty_ in let _sloc = (_symbolstartpos, _endpos) in -# 3389 "parsing/parser.mly" +# 3405 "parsing/parser.mly" ( Of.inherit_ ~loc:(make_loc _sloc) ty ) -# 19264 "parsing/parser.ml" +# 19272 "parsing/parser.ml" in -# 3365 "parsing/parser.mly" +# 3381 "parsing/parser.mly" ( [head], Closed ) -# 19270 "parsing/parser.ml" +# 19278 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19289,9 +19297,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.object_field list * Asttypes.closed_flag) = -# 3367 "parsing/parser.mly" +# 3383 "parsing/parser.mly" ( [], Open ) -# 19295 "parsing/parser.ml" +# 19303 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19336,9 +19344,9 @@ module Tables = struct let _1_inlined2 : (Parsetree.core_type) = Obj.magic _1_inlined2 in let _5 : unit = Obj.magic _5 in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 19342 "parsing/parser.ml" +# 19350 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let private_ : (Asttypes.private_flag) = Obj.magic private_ in let _1 : (Parsetree.attributes) = Obj.magic _1 in @@ -19350,41 +19358,41 @@ module Tables = struct Parsetree.attributes) = let ty = let _1 = _1_inlined2 in -# 3164 "parsing/parser.mly" +# 3180 "parsing/parser.mly" ( _1 ) -# 19356 "parsing/parser.ml" +# 19364 "parsing/parser.ml" in let label = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 19364 "parsing/parser.ml" +# 19372 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 19372 "parsing/parser.ml" +# 19380 "parsing/parser.ml" in let attrs = -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 19378 "parsing/parser.ml" +# 19386 "parsing/parser.ml" in let _1 = -# 3630 "parsing/parser.mly" +# 3646 "parsing/parser.mly" ( Fresh ) -# 19383 "parsing/parser.ml" +# 19391 "parsing/parser.ml" in -# 1869 "parsing/parser.mly" +# 1875 "parsing/parser.mly" ( (label, private_, Cfk_virtual ty), attrs ) -# 19388 "parsing/parser.ml" +# 19396 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19422,9 +19430,9 @@ module Tables = struct } = _menhir_stack in let _5 : (Parsetree.expression) = Obj.magic _5 in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 19428 "parsing/parser.ml" +# 19436 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _3 : (Asttypes.private_flag) = Obj.magic _3 in let _1 : (Parsetree.attributes) = Obj.magic _1 in @@ -19436,36 +19444,36 @@ module Tables = struct Parsetree.attributes) = let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 19442 "parsing/parser.ml" +# 19450 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 19450 "parsing/parser.ml" +# 19458 "parsing/parser.ml" in let _2 = -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 19456 "parsing/parser.ml" +# 19464 "parsing/parser.ml" in let _1 = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 19461 "parsing/parser.ml" +# 19469 "parsing/parser.ml" in -# 1871 "parsing/parser.mly" +# 1877 "parsing/parser.mly" ( let e = _5 in let loc = Location.(e.pexp_loc.loc_start, e.pexp_loc.loc_end) in (_4, _3, Cfk_concrete (_1, ghexp ~loc (Pexp_poly (e, None)))), _2 ) -# 19469 "parsing/parser.ml" +# 19477 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19509,9 +19517,9 @@ module Tables = struct } = _menhir_stack in let _5 : (Parsetree.expression) = Obj.magic _5 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 19515 "parsing/parser.ml" +# 19523 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let _3 : (Asttypes.private_flag) = Obj.magic _3 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in @@ -19524,39 +19532,39 @@ module Tables = struct Parsetree.attributes) = let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 19530 "parsing/parser.ml" +# 19538 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 19538 "parsing/parser.ml" +# 19546 "parsing/parser.ml" in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 19546 "parsing/parser.ml" +# 19554 "parsing/parser.ml" in let _1 = -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 19552 "parsing/parser.ml" +# 19560 "parsing/parser.ml" in -# 1871 "parsing/parser.mly" +# 1877 "parsing/parser.mly" ( let e = _5 in let loc = Location.(e.pexp_loc.loc_start, e.pexp_loc.loc_end) in (_4, _3, Cfk_concrete (_1, ghexp ~loc (Pexp_poly (e, None)))), _2 ) -# 19560 "parsing/parser.ml" +# 19568 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19615,9 +19623,9 @@ module Tables = struct let _1_inlined2 : (Parsetree.core_type) = Obj.magic _1_inlined2 in let _5 : unit = Obj.magic _5 in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 19621 "parsing/parser.ml" +# 19629 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _3 : (Asttypes.private_flag) = Obj.magic _3 in let _1 : (Parsetree.attributes) = Obj.magic _1 in @@ -19629,45 +19637,45 @@ module Tables = struct Parsetree.attributes) = let _6 = let _1 = _1_inlined2 in -# 3164 "parsing/parser.mly" +# 3180 "parsing/parser.mly" ( _1 ) -# 19635 "parsing/parser.ml" +# 19643 "parsing/parser.ml" in let _startpos__6_ = _startpos__1_inlined2_ in let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 19644 "parsing/parser.ml" +# 19652 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 19652 "parsing/parser.ml" +# 19660 "parsing/parser.ml" in let _2 = -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 19658 "parsing/parser.ml" +# 19666 "parsing/parser.ml" in let _1 = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 19663 "parsing/parser.ml" +# 19671 "parsing/parser.ml" in -# 1877 "parsing/parser.mly" +# 1883 "parsing/parser.mly" ( let poly_exp = let loc = (_startpos__6_, _endpos__8_) in ghexp ~loc (Pexp_poly(_8, Some _6)) in (_4, _3, Cfk_concrete (_1, poly_exp)), _2 ) -# 19671 "parsing/parser.ml" +# 19679 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19732,9 +19740,9 @@ module Tables = struct let _1_inlined3 : (Parsetree.core_type) = Obj.magic _1_inlined3 in let _5 : unit = Obj.magic _5 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 19738 "parsing/parser.ml" +# 19746 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let _3 : (Asttypes.private_flag) = Obj.magic _3 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in @@ -19747,48 +19755,48 @@ module Tables = struct Parsetree.attributes) = let _6 = let _1 = _1_inlined3 in -# 3164 "parsing/parser.mly" +# 3180 "parsing/parser.mly" ( _1 ) -# 19753 "parsing/parser.ml" +# 19761 "parsing/parser.ml" in let _startpos__6_ = _startpos__1_inlined3_ in let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 19762 "parsing/parser.ml" +# 19770 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 19770 "parsing/parser.ml" +# 19778 "parsing/parser.ml" in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 19778 "parsing/parser.ml" +# 19786 "parsing/parser.ml" in let _1 = -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 19784 "parsing/parser.ml" +# 19792 "parsing/parser.ml" in -# 1877 "parsing/parser.mly" +# 1883 "parsing/parser.mly" ( let poly_exp = let loc = (_startpos__6_, _endpos__8_) in ghexp ~loc (Pexp_poly(_8, Some _6)) in (_4, _3, Cfk_concrete (_1, poly_exp)), _2 ) -# 19792 "parsing/parser.ml" +# 19800 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -19868,9 +19876,9 @@ module Tables = struct let _6 : unit = Obj.magic _6 in let _5 : unit = Obj.magic _5 in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 19874 "parsing/parser.ml" +# 19882 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _3 : (Asttypes.private_flag) = Obj.magic _3 in let _1 : (Parsetree.attributes) = Obj.magic _1 in @@ -19880,38 +19888,38 @@ module Tables = struct let _v : ((Asttypes.label Asttypes.loc * Asttypes.private_flag * Parsetree.class_field_kind) * Parsetree.attributes) = let _7 = -# 2414 "parsing/parser.mly" +# 2416 "parsing/parser.mly" ( xs ) -# 19886 "parsing/parser.ml" +# 19894 "parsing/parser.ml" in let _startpos__7_ = _startpos_xs_ in let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 19894 "parsing/parser.ml" +# 19902 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 19902 "parsing/parser.ml" +# 19910 "parsing/parser.ml" in let _startpos__4_ = _startpos__1_inlined1_ in let _2 = -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 19909 "parsing/parser.ml" +# 19917 "parsing/parser.ml" in let (_endpos__2_, _startpos__2_) = (_endpos__1_, _startpos__1_) in let _1 = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 19915 "parsing/parser.ml" +# 19923 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos__0_, _endpos__0_) in let _endpos = _endpos__11_ in @@ -19927,7 +19935,7 @@ module Tables = struct _startpos__4_ in let _sloc = (_symbolstartpos, _endpos) in -# 1883 "parsing/parser.mly" +# 1889 "parsing/parser.mly" ( let poly_exp_loc = (_startpos__7_, _endpos__11_) in let poly_exp = let exp, poly = @@ -19938,7 +19946,7 @@ module Tables = struct ghexp ~loc:poly_exp_loc (Pexp_poly(exp, Some poly)) in (_4, _3, Cfk_concrete (_1, poly_exp)), _2 ) -# 19942 "parsing/parser.ml" +# 19950 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20024,9 +20032,9 @@ module Tables = struct let _6 : unit = Obj.magic _6 in let _5 : unit = Obj.magic _5 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 20030 "parsing/parser.ml" +# 20038 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let _3 : (Asttypes.private_flag) = Obj.magic _3 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in @@ -20037,41 +20045,41 @@ module Tables = struct let _v : ((Asttypes.label Asttypes.loc * Asttypes.private_flag * Parsetree.class_field_kind) * Parsetree.attributes) = let _7 = -# 2414 "parsing/parser.mly" +# 2416 "parsing/parser.mly" ( xs ) -# 20043 "parsing/parser.ml" +# 20051 "parsing/parser.ml" in let _startpos__7_ = _startpos_xs_ in let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 20051 "parsing/parser.ml" +# 20059 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 20059 "parsing/parser.ml" +# 20067 "parsing/parser.ml" in let _startpos__4_ = _startpos__1_inlined2_ in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 20068 "parsing/parser.ml" +# 20076 "parsing/parser.ml" in let (_endpos__2_, _startpos__2_) = (_endpos__1_inlined1_, _startpos__1_inlined1_) in let _1 = -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 20075 "parsing/parser.ml" +# 20083 "parsing/parser.ml" in let _endpos = _endpos__11_ in let _symbolstartpos = if _startpos__1_ != _endpos__1_ then @@ -20086,7 +20094,7 @@ module Tables = struct _startpos__4_ in let _sloc = (_symbolstartpos, _endpos) in -# 1883 "parsing/parser.mly" +# 1889 "parsing/parser.mly" ( let poly_exp_loc = (_startpos__7_, _endpos__11_) in let poly_exp = let exp, poly = @@ -20097,7 +20105,7 @@ module Tables = struct ghexp ~loc:poly_exp_loc (Pexp_poly(exp, Some poly)) in (_4, _3, Cfk_concrete (_1, poly_exp)), _2 ) -# 20101 "parsing/parser.ml" +# 20109 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20116,17 +20124,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 20122 "parsing/parser.ml" +# 20130 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3490 "parsing/parser.mly" +# 3506 "parsing/parser.mly" ( Lident _1 ) -# 20130 "parsing/parser.ml" +# 20138 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20157,9 +20165,9 @@ module Tables = struct }; } = _menhir_stack in let _3 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 20163 "parsing/parser.ml" +# 20171 "parsing/parser.ml" ) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : (Longident.t) = Obj.magic _1 in @@ -20167,9 +20175,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Longident.t) = -# 3491 "parsing/parser.mly" +# 3507 "parsing/parser.mly" ( Ldot(_1,_3) ) -# 20173 "parsing/parser.ml" +# 20181 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20188,17 +20196,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) -# 20194 "parsing/parser.ml" +# 20202 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3490 "parsing/parser.mly" +# 3506 "parsing/parser.mly" ( Lident _1 ) -# 20202 "parsing/parser.ml" +# 20210 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20229,9 +20237,9 @@ module Tables = struct }; } = _menhir_stack in let _3 : ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) -# 20235 "parsing/parser.ml" +# 20243 "parsing/parser.ml" ) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : (Longident.t) = Obj.magic _1 in @@ -20239,9 +20247,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Longident.t) = -# 3491 "parsing/parser.mly" +# 3507 "parsing/parser.mly" ( Ldot(_1,_3) ) -# 20245 "parsing/parser.ml" +# 20253 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20264,14 +20272,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = let _1 = -# 3527 "parsing/parser.mly" +# 3543 "parsing/parser.mly" ( _1 ) -# 20270 "parsing/parser.ml" +# 20278 "parsing/parser.ml" in -# 3490 "parsing/parser.mly" +# 3506 "parsing/parser.mly" ( Lident _1 ) -# 20275 "parsing/parser.ml" +# 20283 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20309,20 +20317,20 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Longident.t) = let _1 = let _1 = -# 3470 "parsing/parser.mly" +# 3486 "parsing/parser.mly" ( "::" ) -# 20315 "parsing/parser.ml" +# 20323 "parsing/parser.ml" in -# 3527 "parsing/parser.mly" +# 3543 "parsing/parser.mly" ( _1 ) -# 20320 "parsing/parser.ml" +# 20328 "parsing/parser.ml" in -# 3490 "parsing/parser.mly" +# 3506 "parsing/parser.mly" ( Lident _1 ) -# 20326 "parsing/parser.ml" +# 20334 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20345,14 +20353,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = let _1 = -# 3527 "parsing/parser.mly" +# 3543 "parsing/parser.mly" ( _1 ) -# 20351 "parsing/parser.ml" +# 20359 "parsing/parser.ml" in -# 3490 "parsing/parser.mly" +# 3506 "parsing/parser.mly" ( Lident _1 ) -# 20356 "parsing/parser.ml" +# 20364 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20391,15 +20399,15 @@ module Tables = struct let _v : (Longident.t) = let _3 = let _1 = _1_inlined1 in -# 3527 "parsing/parser.mly" +# 3543 "parsing/parser.mly" ( _1 ) -# 20397 "parsing/parser.ml" +# 20405 "parsing/parser.ml" in -# 3491 "parsing/parser.mly" +# 3507 "parsing/parser.mly" ( Ldot(_1,_3) ) -# 20403 "parsing/parser.ml" +# 20411 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20452,20 +20460,20 @@ module Tables = struct let _v : (Longident.t) = let _3 = let (_2, _1) = (_2_inlined1, _1_inlined1) in let _1 = -# 3470 "parsing/parser.mly" +# 3486 "parsing/parser.mly" ( "::" ) -# 20458 "parsing/parser.ml" +# 20466 "parsing/parser.ml" in -# 3527 "parsing/parser.mly" +# 3543 "parsing/parser.mly" ( _1 ) -# 20463 "parsing/parser.ml" +# 20471 "parsing/parser.ml" in -# 3491 "parsing/parser.mly" +# 3507 "parsing/parser.mly" ( Ldot(_1,_3) ) -# 20469 "parsing/parser.ml" +# 20477 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20504,15 +20512,15 @@ module Tables = struct let _v : (Longident.t) = let _3 = let _1 = _1_inlined1 in -# 3527 "parsing/parser.mly" +# 3543 "parsing/parser.mly" ( _1 ) -# 20510 "parsing/parser.ml" +# 20518 "parsing/parser.ml" in -# 3491 "parsing/parser.mly" +# 3507 "parsing/parser.mly" ( Ldot(_1,_3) ) -# 20516 "parsing/parser.ml" +# 20524 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20535,9 +20543,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3490 "parsing/parser.mly" +# 3506 "parsing/parser.mly" ( Lident _1 ) -# 20541 "parsing/parser.ml" +# 20549 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20574,9 +20582,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Longident.t) = -# 3491 "parsing/parser.mly" +# 3507 "parsing/parser.mly" ( Ldot(_1,_3) ) -# 20580 "parsing/parser.ml" +# 20588 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20595,17 +20603,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 20601 "parsing/parser.ml" +# 20609 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3490 "parsing/parser.mly" +# 3506 "parsing/parser.mly" ( Lident _1 ) -# 20609 "parsing/parser.ml" +# 20617 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20636,9 +20644,9 @@ module Tables = struct }; } = _menhir_stack in let _3 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 20642 "parsing/parser.ml" +# 20650 "parsing/parser.ml" ) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : (Longident.t) = Obj.magic _1 in @@ -20646,9 +20654,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Longident.t) = -# 3491 "parsing/parser.mly" +# 3507 "parsing/parser.mly" ( Ldot(_1,_3) ) -# 20652 "parsing/parser.ml" +# 20660 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20667,17 +20675,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) -# 20673 "parsing/parser.ml" +# 20681 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3490 "parsing/parser.mly" +# 3506 "parsing/parser.mly" ( Lident _1 ) -# 20681 "parsing/parser.ml" +# 20689 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20708,9 +20716,9 @@ module Tables = struct }; } = _menhir_stack in let _3 : ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) -# 20714 "parsing/parser.ml" +# 20722 "parsing/parser.ml" ) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : (Longident.t) = Obj.magic _1 in @@ -20718,9 +20726,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Longident.t) = -# 3491 "parsing/parser.mly" +# 3507 "parsing/parser.mly" ( Ldot(_1,_3) ) -# 20724 "parsing/parser.ml" +# 20732 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20743,9 +20751,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3490 "parsing/parser.mly" +# 3506 "parsing/parser.mly" ( Lident _1 ) -# 20749 "parsing/parser.ml" +# 20757 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20782,9 +20790,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Longident.t) = -# 3491 "parsing/parser.mly" +# 3507 "parsing/parser.mly" ( Ldot(_1,_3) ) -# 20788 "parsing/parser.ml" +# 20796 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20807,9 +20815,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3506 "parsing/parser.mly" +# 3522 "parsing/parser.mly" ( _1 ) -# 20813 "parsing/parser.ml" +# 20821 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20856,9 +20864,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3508 "parsing/parser.mly" +# 3524 "parsing/parser.mly" ( lapply ~loc:_sloc _1 _3 ) -# 20862 "parsing/parser.ml" +# 20870 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20896,9 +20904,9 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Longident.t) = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 3510 "parsing/parser.mly" +# 3526 "parsing/parser.mly" ( expecting _loc__3_ "module path" ) -# 20902 "parsing/parser.ml" +# 20910 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20921,9 +20929,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3503 "parsing/parser.mly" +# 3519 "parsing/parser.mly" ( _1 ) -# 20927 "parsing/parser.ml" +# 20935 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -20953,9 +20961,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos_me_ in let _v : (Parsetree.module_expr) = -# 1373 "parsing/parser.mly" +# 1377 "parsing/parser.mly" ( me ) -# 20959 "parsing/parser.ml" +# 20967 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21000,24 +21008,24 @@ module Tables = struct let _endpos = _endpos_me_ in let _v : (Parsetree.module_expr) = let _1 = let _1 = -# 1376 "parsing/parser.mly" +# 1380 "parsing/parser.mly" ( Pmod_constraint(me, mty) ) -# 21006 "parsing/parser.ml" +# 21014 "parsing/parser.ml" in let _endpos__1_ = _endpos_me_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 856 "parsing/parser.mly" +# 860 "parsing/parser.mly" ( mkmod ~loc:_sloc _1 ) -# 21015 "parsing/parser.ml" +# 21023 "parsing/parser.ml" in -# 1379 "parsing/parser.mly" +# 1384 "parsing/parser.mly" ( _1 ) -# 21021 "parsing/parser.ml" +# 21029 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21035,37 +21043,38 @@ module Tables = struct MenhirLib.EngineTypes.endp = _endpos_body_; MenhirLib.EngineTypes.next = { MenhirLib.EngineTypes.state = _menhir_s; - MenhirLib.EngineTypes.semv = arg; - MenhirLib.EngineTypes.startp = _startpos_arg_; - MenhirLib.EngineTypes.endp = _endpos_arg_; + MenhirLib.EngineTypes.semv = arg_and_pos; + MenhirLib.EngineTypes.startp = _startpos_arg_and_pos_; + MenhirLib.EngineTypes.endp = _endpos_arg_and_pos_; MenhirLib.EngineTypes.next = _menhir_stack; }; } = _menhir_stack in let body : (Parsetree.module_expr) = Obj.magic body in - let arg : (Parsetree.functor_parameter) = Obj.magic arg in + let arg_and_pos : (Lexing.position * Parsetree.functor_parameter) = Obj.magic arg_and_pos in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in - let _startpos = _startpos_arg_ in + let _startpos = _startpos_arg_and_pos_ in let _endpos = _endpos_body_ in let _v : (Parsetree.module_expr) = let _1 = let _1 = -# 1378 "parsing/parser.mly" - ( Pmod_functor(arg, body) ) -# 21054 "parsing/parser.ml" +# 1382 "parsing/parser.mly" + ( let (_, arg) = arg_and_pos in + Pmod_functor(arg, body) ) +# 21063 "parsing/parser.ml" in - let (_endpos__1_, _startpos__1_) = (_endpos_body_, _startpos_arg_) in + let (_endpos__1_, _startpos__1_) = (_endpos_body_, _startpos_arg_and_pos_) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 856 "parsing/parser.mly" +# 860 "parsing/parser.mly" ( mkmod ~loc:_sloc _1 ) -# 21063 "parsing/parser.ml" +# 21072 "parsing/parser.ml" in -# 1379 "parsing/parser.mly" +# 1384 "parsing/parser.mly" ( _1 ) -# 21069 "parsing/parser.ml" +# 21078 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21095,9 +21104,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos_mty_ in let _v : (Parsetree.module_type) = -# 1616 "parsing/parser.mly" +# 1621 "parsing/parser.mly" ( mty ) -# 21101 "parsing/parser.ml" +# 21110 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21115,37 +21124,38 @@ module Tables = struct MenhirLib.EngineTypes.endp = _endpos_body_; MenhirLib.EngineTypes.next = { MenhirLib.EngineTypes.state = _menhir_s; - MenhirLib.EngineTypes.semv = arg; - MenhirLib.EngineTypes.startp = _startpos_arg_; - MenhirLib.EngineTypes.endp = _endpos_arg_; + MenhirLib.EngineTypes.semv = arg_and_pos; + MenhirLib.EngineTypes.startp = _startpos_arg_and_pos_; + MenhirLib.EngineTypes.endp = _endpos_arg_and_pos_; MenhirLib.EngineTypes.next = _menhir_stack; }; } = _menhir_stack in let body : (Parsetree.module_type) = Obj.magic body in - let arg : (Parsetree.functor_parameter) = Obj.magic arg in + let arg_and_pos : (Lexing.position * Parsetree.functor_parameter) = Obj.magic arg_and_pos in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in - let _startpos = _startpos_arg_ in + let _startpos = _startpos_arg_and_pos_ in let _endpos = _endpos_body_ in let _v : (Parsetree.module_type) = let _1 = let _1 = -# 1619 "parsing/parser.mly" - ( Pmty_functor(arg, body) ) -# 21134 "parsing/parser.ml" +# 1624 "parsing/parser.mly" + ( let (_, arg) = arg_and_pos in + Pmty_functor(arg, body) ) +# 21144 "parsing/parser.ml" in - let (_endpos__1_, _startpos__1_) = (_endpos_body_, _startpos_arg_) in + let (_endpos__1_, _startpos__1_) = (_endpos_body_, _startpos_arg_and_pos_) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 858 "parsing/parser.mly" +# 862 "parsing/parser.mly" ( mkmty ~loc:_sloc _1 ) -# 21143 "parsing/parser.ml" +# 21153 "parsing/parser.ml" in -# 1621 "parsing/parser.mly" +# 1627 "parsing/parser.mly" ( _1 ) -# 21149 "parsing/parser.ml" +# 21159 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21191,18 +21201,18 @@ module Tables = struct let _v : (Parsetree.module_expr) = let attrs = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 21197 "parsing/parser.ml" +# 21207 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1212 "parsing/parser.mly" +# 1216 "parsing/parser.mly" ( mkmod ~loc:_sloc ~attrs (Pmod_structure s) ) -# 21206 "parsing/parser.ml" +# 21216 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21248,17 +21258,17 @@ module Tables = struct let _v : (Parsetree.module_expr) = let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 21254 "parsing/parser.ml" +# 21264 "parsing/parser.ml" in let _loc__4_ = (_startpos__4_, _endpos__4_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1214 "parsing/parser.mly" +# 1218 "parsing/parser.mly" ( unclosed "struct" _loc__1_ "end" _loc__4_ ) -# 21262 "parsing/parser.ml" +# 21272 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21302,7 +21312,7 @@ module Tables = struct } = _menhir_stack in let me : (Parsetree.module_expr) = Obj.magic me in let _4 : unit = Obj.magic _4 in - let _1_inlined2 : (Parsetree.functor_parameter list) = Obj.magic _1_inlined2 in + let _1_inlined2 : ((Lexing.position * Parsetree.functor_parameter) list) = Obj.magic _1_inlined2 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -21311,30 +21321,30 @@ module Tables = struct let _v : (Parsetree.module_expr) = let args = let _1 = _1_inlined2 in -# 1178 "parsing/parser.mly" +# 1182 "parsing/parser.mly" ( _1 ) -# 21317 "parsing/parser.ml" +# 21327 "parsing/parser.ml" in let attrs = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 21325 "parsing/parser.ml" +# 21335 "parsing/parser.ml" in let _endpos = _endpos_me_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1216 "parsing/parser.mly" +# 1220 "parsing/parser.mly" ( wrap_mod_attrs ~loc:_sloc attrs ( - List.fold_left (fun acc arg -> - mkmod ~loc:_sloc (Pmod_functor (arg, acc)) + List.fold_left (fun acc (startpos, arg) -> + mkmod ~loc:(startpos, _endpos) (Pmod_functor (arg, acc)) ) me args ) ) -# 21338 "parsing/parser.ml" +# 21348 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21357,9 +21367,9 @@ module Tables = struct let _startpos = _startpos_me_ in let _endpos = _endpos_me_ in let _v : (Parsetree.module_expr) = -# 1222 "parsing/parser.mly" +# 1226 "parsing/parser.mly" ( me ) -# 21363 "parsing/parser.ml" +# 21373 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21389,9 +21399,9 @@ module Tables = struct let _startpos = _startpos_me_ in let _endpos = _endpos_attr_ in let _v : (Parsetree.module_expr) = -# 1224 "parsing/parser.mly" +# 1228 "parsing/parser.mly" ( Mod.attr me attr ) -# 21395 "parsing/parser.ml" +# 21405 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21420,30 +21430,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 21426 "parsing/parser.ml" +# 21436 "parsing/parser.ml" in -# 1228 "parsing/parser.mly" +# 1232 "parsing/parser.mly" ( Pmod_ident x ) -# 21432 "parsing/parser.ml" +# 21442 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 856 "parsing/parser.mly" +# 860 "parsing/parser.mly" ( mkmod ~loc:_sloc _1 ) -# 21441 "parsing/parser.ml" +# 21451 "parsing/parser.ml" in -# 1240 "parsing/parser.mly" +# 1244 "parsing/parser.mly" ( _1 ) -# 21447 "parsing/parser.ml" +# 21457 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21474,24 +21484,24 @@ module Tables = struct let _endpos = _endpos_me2_ in let _v : (Parsetree.module_expr) = let _1 = let _1 = -# 1231 "parsing/parser.mly" +# 1235 "parsing/parser.mly" ( Pmod_apply(me1, me2) ) -# 21480 "parsing/parser.ml" +# 21490 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_me2_, _startpos_me1_) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 856 "parsing/parser.mly" +# 860 "parsing/parser.mly" ( mkmod ~loc:_sloc _1 ) -# 21489 "parsing/parser.ml" +# 21499 "parsing/parser.ml" in -# 1240 "parsing/parser.mly" +# 1244 "parsing/parser.mly" ( _1 ) -# 21495 "parsing/parser.ml" +# 21505 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21533,10 +21543,10 @@ module Tables = struct let _symbolstartpos = _startpos_me1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1234 "parsing/parser.mly" +# 1238 "parsing/parser.mly" ( (* TODO review mkmod location *) Pmod_apply(me1, mkmod ~loc:_sloc (Pmod_structure [])) ) -# 21540 "parsing/parser.ml" +# 21550 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos__3_, _startpos_me1_) in @@ -21544,15 +21554,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 856 "parsing/parser.mly" +# 860 "parsing/parser.mly" ( mkmod ~loc:_sloc _1 ) -# 21550 "parsing/parser.ml" +# 21560 "parsing/parser.ml" in -# 1240 "parsing/parser.mly" +# 1244 "parsing/parser.mly" ( _1 ) -# 21556 "parsing/parser.ml" +# 21566 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21576,24 +21586,24 @@ module Tables = struct let _endpos = _endpos_ex_ in let _v : (Parsetree.module_expr) = let _1 = let _1 = -# 1238 "parsing/parser.mly" +# 1242 "parsing/parser.mly" ( Pmod_extension ex ) -# 21582 "parsing/parser.ml" +# 21592 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_ex_, _startpos_ex_) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 856 "parsing/parser.mly" +# 860 "parsing/parser.mly" ( mkmod ~loc:_sloc _1 ) -# 21591 "parsing/parser.ml" +# 21601 "parsing/parser.ml" in -# 1240 "parsing/parser.mly" +# 1244 "parsing/parser.mly" ( _1 ) -# 21597 "parsing/parser.ml" +# 21607 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21612,17 +21622,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let x : ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) -# 21618 "parsing/parser.ml" +# 21628 "parsing/parser.ml" ) = Obj.magic x in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_x_ in let _endpos = _endpos_x_ in let _v : (string option) = -# 1195 "parsing/parser.mly" +# 1199 "parsing/parser.mly" ( Some x ) -# 21626 "parsing/parser.ml" +# 21636 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21645,9 +21655,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string option) = -# 1198 "parsing/parser.mly" +# 1202 "parsing/parser.mly" ( None ) -# 21651 "parsing/parser.ml" +# 21661 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21705,9 +21715,9 @@ module Tables = struct let _1_inlined3 : (Longident.t) = Obj.magic _1_inlined3 in let _5 : unit = Obj.magic _5 in let _1_inlined2 : ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) -# 21711 "parsing/parser.ml" +# 21721 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in @@ -21718,9 +21728,9 @@ module Tables = struct let _v : (Parsetree.module_substitution * string Asttypes.loc option) = let attrs2 = let _1 = _1_inlined4 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 21724 "parsing/parser.ml" +# 21734 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined4_ in @@ -21730,9 +21740,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 21736 "parsing/parser.ml" +# 21746 "parsing/parser.ml" in let uid = @@ -21741,31 +21751,31 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 21747 "parsing/parser.ml" +# 21757 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 21755 "parsing/parser.ml" +# 21765 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1651 "parsing/parser.mly" +# 1657 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Ms.mk uid body ~attrs ~loc ~docs, ext ) -# 21769 "parsing/parser.ml" +# 21779 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21816,9 +21826,9 @@ module Tables = struct let _6 : unit = Obj.magic _6 in let _5 : unit = Obj.magic _5 in let _1_inlined2 : ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) -# 21822 "parsing/parser.ml" +# 21832 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let _2 : (string Asttypes.loc option) = Obj.magic _2 in @@ -21832,24 +21842,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 21838 "parsing/parser.ml" +# 21848 "parsing/parser.ml" in let _3 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 21846 "parsing/parser.ml" +# 21856 "parsing/parser.ml" in let _loc__6_ = (_startpos__6_, _endpos__6_) in -# 1658 "parsing/parser.mly" +# 1664 "parsing/parser.mly" ( expecting _loc__6_ "module path" ) -# 21853 "parsing/parser.ml" +# 21863 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21895,18 +21905,18 @@ module Tables = struct let _v : (Parsetree.module_type) = let attrs = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 21901 "parsing/parser.ml" +# 21911 "parsing/parser.ml" in let _endpos = _endpos__4_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1504 "parsing/parser.mly" +# 1509 "parsing/parser.mly" ( mkmty ~loc:_sloc ~attrs (Pmty_signature s) ) -# 21910 "parsing/parser.ml" +# 21920 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -21952,17 +21962,17 @@ module Tables = struct let _v : (Parsetree.module_type) = let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 21958 "parsing/parser.ml" +# 21968 "parsing/parser.ml" in let _loc__4_ = (_startpos__4_, _endpos__4_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1506 "parsing/parser.mly" +# 1511 "parsing/parser.mly" ( unclosed "sig" _loc__1_ "end" _loc__4_ ) -# 21966 "parsing/parser.ml" +# 21976 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22006,7 +22016,7 @@ module Tables = struct } = _menhir_stack in let mty : (Parsetree.module_type) = Obj.magic mty in let _4 : unit = Obj.magic _4 in - let _1_inlined2 : (Parsetree.functor_parameter list) = Obj.magic _1_inlined2 in + let _1_inlined2 : ((Lexing.position * Parsetree.functor_parameter) list) = Obj.magic _1_inlined2 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -22015,30 +22025,30 @@ module Tables = struct let _v : (Parsetree.module_type) = let args = let _1 = _1_inlined2 in -# 1178 "parsing/parser.mly" +# 1182 "parsing/parser.mly" ( _1 ) -# 22021 "parsing/parser.ml" +# 22031 "parsing/parser.ml" in let attrs = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 22029 "parsing/parser.ml" +# 22039 "parsing/parser.ml" in let _endpos = _endpos_mty_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1510 "parsing/parser.mly" +# 1515 "parsing/parser.mly" ( wrap_mty_attrs ~loc:_sloc attrs ( - List.fold_left (fun acc arg -> - mkmty ~loc:_sloc (Pmty_functor (arg, acc)) + List.fold_left (fun acc (startpos, arg) -> + mkmty ~loc:(startpos, _endpos) (Pmty_functor (arg, acc)) ) mty args ) ) -# 22042 "parsing/parser.ml" +# 22052 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22091,18 +22101,18 @@ module Tables = struct let _v : (Parsetree.module_type) = let _4 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 22097 "parsing/parser.ml" +# 22107 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1516 "parsing/parser.mly" +# 1521 "parsing/parser.mly" ( mkmty ~loc:_sloc ~attrs:_4 (Pmty_typeof _5) ) -# 22106 "parsing/parser.ml" +# 22116 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22139,9 +22149,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.module_type) = -# 1518 "parsing/parser.mly" +# 1523 "parsing/parser.mly" ( _2 ) -# 22145 "parsing/parser.ml" +# 22155 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22180,9 +22190,9 @@ module Tables = struct let _v : (Parsetree.module_type) = let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1520 "parsing/parser.mly" +# 1525 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__3_ ) -# 22186 "parsing/parser.ml" +# 22196 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22212,9 +22222,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.module_type) = -# 1522 "parsing/parser.mly" +# 1527 "parsing/parser.mly" ( Mty.attr _1 _2 ) -# 22218 "parsing/parser.ml" +# 22228 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22243,30 +22253,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 22249 "parsing/parser.ml" +# 22259 "parsing/parser.ml" in -# 1525 "parsing/parser.mly" +# 1530 "parsing/parser.mly" ( Pmty_ident _1 ) -# 22255 "parsing/parser.ml" +# 22265 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 858 "parsing/parser.mly" +# 862 "parsing/parser.mly" ( mkmty ~loc:_sloc _1 ) -# 22264 "parsing/parser.ml" +# 22274 "parsing/parser.ml" in -# 1536 "parsing/parser.mly" +# 1541 "parsing/parser.mly" ( _1 ) -# 22270 "parsing/parser.ml" +# 22280 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22304,24 +22314,24 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Parsetree.module_type) = let _1 = let _1 = -# 1528 "parsing/parser.mly" +# 1533 "parsing/parser.mly" ( Pmty_functor(Named (mknoloc None, _1), _3) ) -# 22310 "parsing/parser.ml" +# 22320 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 858 "parsing/parser.mly" +# 862 "parsing/parser.mly" ( mkmty ~loc:_sloc _1 ) -# 22319 "parsing/parser.ml" +# 22329 "parsing/parser.ml" in -# 1536 "parsing/parser.mly" +# 1541 "parsing/parser.mly" ( _1 ) -# 22325 "parsing/parser.ml" +# 22335 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22363,18 +22373,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 22367 "parsing/parser.ml" +# 22377 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 22372 "parsing/parser.ml" +# 22382 "parsing/parser.ml" in -# 1530 "parsing/parser.mly" +# 1535 "parsing/parser.mly" ( Pmty_with(_1, _3) ) -# 22378 "parsing/parser.ml" +# 22388 "parsing/parser.ml" in let _endpos__1_ = _endpos_xs_ in @@ -22382,15 +22392,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 858 "parsing/parser.mly" +# 862 "parsing/parser.mly" ( mkmty ~loc:_sloc _1 ) -# 22388 "parsing/parser.ml" +# 22398 "parsing/parser.ml" in -# 1536 "parsing/parser.mly" +# 1541 "parsing/parser.mly" ( _1 ) -# 22394 "parsing/parser.ml" +# 22404 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22414,23 +22424,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.module_type) = let _1 = let _1 = -# 1534 "parsing/parser.mly" +# 1539 "parsing/parser.mly" ( Pmty_extension _1 ) -# 22420 "parsing/parser.ml" +# 22430 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 858 "parsing/parser.mly" +# 862 "parsing/parser.mly" ( mkmty ~loc:_sloc _1 ) -# 22428 "parsing/parser.ml" +# 22438 "parsing/parser.ml" in -# 1536 "parsing/parser.mly" +# 1541 "parsing/parser.mly" ( _1 ) -# 22434 "parsing/parser.ml" +# 22444 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22497,9 +22507,9 @@ module Tables = struct let _v : (Parsetree.module_type_declaration * string Asttypes.loc option) = let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 22503 "parsing/parser.ml" +# 22513 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -22509,31 +22519,31 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 22515 "parsing/parser.ml" +# 22525 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 22523 "parsing/parser.ml" +# 22533 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1450 "parsing/parser.mly" +# 1455 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Mtd.mk id ?typ ~attrs ~loc ~docs, ext ) -# 22537 "parsing/parser.ml" +# 22547 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22556,9 +22566,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3513 "parsing/parser.mly" +# 3529 "parsing/parser.mly" ( _1 ) -# 22562 "parsing/parser.ml" +# 22572 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22574,9 +22584,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (Asttypes.mutable_flag) = -# 3590 "parsing/parser.mly" +# 3606 "parsing/parser.mly" ( Immutable ) -# 22580 "parsing/parser.ml" +# 22590 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22599,9 +22609,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.mutable_flag) = -# 3591 "parsing/parser.mly" +# 3607 "parsing/parser.mly" ( Mutable ) -# 22605 "parsing/parser.ml" +# 22615 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22617,9 +22627,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (Asttypes.mutable_flag * Asttypes.virtual_flag) = -# 3599 "parsing/parser.mly" +# 3615 "parsing/parser.mly" ( Immutable, Concrete ) -# 22623 "parsing/parser.ml" +# 22633 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22642,9 +22652,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.mutable_flag * Asttypes.virtual_flag) = -# 3601 "parsing/parser.mly" +# 3617 "parsing/parser.mly" ( Mutable, Concrete ) -# 22648 "parsing/parser.ml" +# 22658 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22667,9 +22677,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.mutable_flag * Asttypes.virtual_flag) = -# 3603 "parsing/parser.mly" +# 3619 "parsing/parser.mly" ( Immutable, Virtual ) -# 22673 "parsing/parser.ml" +# 22683 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22699,9 +22709,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.mutable_flag * Asttypes.virtual_flag) = -# 3606 "parsing/parser.mly" +# 3622 "parsing/parser.mly" ( Mutable, Virtual ) -# 22705 "parsing/parser.ml" +# 22715 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22731,9 +22741,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.mutable_flag * Asttypes.virtual_flag) = -# 3606 "parsing/parser.mly" +# 3622 "parsing/parser.mly" ( Mutable, Virtual ) -# 22737 "parsing/parser.ml" +# 22747 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22763,9 +22773,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.label) = -# 3563 "parsing/parser.mly" +# 3579 "parsing/parser.mly" ( _2 ) -# 22769 "parsing/parser.ml" +# 22779 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22784,9 +22794,9 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 22790 "parsing/parser.ml" +# 22800 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -22796,15 +22806,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 22802 "parsing/parser.ml" +# 22812 "parsing/parser.ml" in # 221 "" ( [ x ] ) -# 22808 "parsing/parser.ml" +# 22818 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22830,9 +22840,9 @@ module Tables = struct } = _menhir_stack in let xs : (string Asttypes.loc list) = Obj.magic xs in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 22836 "parsing/parser.ml" +# 22846 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -22842,15 +22852,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 22848 "parsing/parser.ml" +# 22858 "parsing/parser.ml" in # 223 "" ( x :: xs ) -# 22854 "parsing/parser.ml" +# 22864 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22869,22 +22879,22 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let s : ( -# 685 "parsing/parser.mly" +# 689 "parsing/parser.mly" (string * Location.t * string option) -# 22875 "parsing/parser.ml" +# 22885 "parsing/parser.ml" ) = Obj.magic s in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_s_ in let _endpos = _endpos_s_ in let _v : (string list) = let x = -# 3559 "parsing/parser.mly" +# 3575 "parsing/parser.mly" ( let body, _, _ = s in body ) -# 22883 "parsing/parser.ml" +# 22893 "parsing/parser.ml" in # 221 "" ( [ x ] ) -# 22888 "parsing/parser.ml" +# 22898 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22910,22 +22920,22 @@ module Tables = struct } = _menhir_stack in let xs : (string list) = Obj.magic xs in let s : ( -# 685 "parsing/parser.mly" +# 689 "parsing/parser.mly" (string * Location.t * string option) -# 22916 "parsing/parser.ml" +# 22926 "parsing/parser.ml" ) = Obj.magic s in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_s_ in let _endpos = _endpos_xs_ in let _v : (string list) = let x = -# 3559 "parsing/parser.mly" +# 3575 "parsing/parser.mly" ( let body, _, _ = s in body ) -# 22924 "parsing/parser.ml" +# 22934 "parsing/parser.ml" in # 223 "" ( x :: xs ) -# 22929 "parsing/parser.ml" +# 22939 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22948,14 +22958,14 @@ module Tables = struct let _startpos = _startpos_ty_ in let _endpos = _endpos_ty_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3586 "parsing/parser.mly" +# 3602 "parsing/parser.mly" ( Public ) -# 22954 "parsing/parser.ml" +# 22964 "parsing/parser.ml" in -# 2896 "parsing/parser.mly" +# 2901 "parsing/parser.mly" ( (Ptype_abstract, priv, Some ty) ) -# 22959 "parsing/parser.ml" +# 22969 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -22985,14 +22995,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos_ty_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3587 "parsing/parser.mly" +# 3603 "parsing/parser.mly" ( Private ) -# 22991 "parsing/parser.ml" +# 23001 "parsing/parser.ml" in -# 2896 "parsing/parser.mly" +# 2901 "parsing/parser.mly" ( (Ptype_abstract, priv, Some ty) ) -# 22996 "parsing/parser.ml" +# 23006 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23015,26 +23025,26 @@ module Tables = struct let _startpos = _startpos_cs_ in let _endpos = _endpos_cs_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3586 "parsing/parser.mly" +# 3602 "parsing/parser.mly" ( Public ) -# 23021 "parsing/parser.ml" +# 23031 "parsing/parser.ml" in let oty = let _1 = # 124 "" ( None ) -# 23027 "parsing/parser.ml" +# 23037 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23032 "parsing/parser.ml" +# 23042 "parsing/parser.ml" in -# 2900 "parsing/parser.mly" +# 2905 "parsing/parser.mly" ( (Ptype_variant cs, priv, oty) ) -# 23038 "parsing/parser.ml" +# 23048 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23064,26 +23074,26 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos_cs_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3587 "parsing/parser.mly" +# 3603 "parsing/parser.mly" ( Private ) -# 23070 "parsing/parser.ml" +# 23080 "parsing/parser.ml" in let oty = let _1 = # 124 "" ( None ) -# 23076 "parsing/parser.ml" +# 23086 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23081 "parsing/parser.ml" +# 23091 "parsing/parser.ml" in -# 2900 "parsing/parser.mly" +# 2905 "parsing/parser.mly" ( (Ptype_variant cs, priv, oty) ) -# 23087 "parsing/parser.ml" +# 23097 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23120,33 +23130,33 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos_cs_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3586 "parsing/parser.mly" +# 3602 "parsing/parser.mly" ( Public ) -# 23126 "parsing/parser.ml" +# 23136 "parsing/parser.ml" in let oty = let _1 = let x = # 191 "" ( x ) -# 23133 "parsing/parser.ml" +# 23143 "parsing/parser.ml" in # 126 "" ( Some x ) -# 23138 "parsing/parser.ml" +# 23148 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23144 "parsing/parser.ml" +# 23154 "parsing/parser.ml" in -# 2900 "parsing/parser.mly" +# 2905 "parsing/parser.mly" ( (Ptype_variant cs, priv, oty) ) -# 23150 "parsing/parser.ml" +# 23160 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23190,33 +23200,33 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos_cs_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3587 "parsing/parser.mly" +# 3603 "parsing/parser.mly" ( Private ) -# 23196 "parsing/parser.ml" +# 23206 "parsing/parser.ml" in let oty = let _1 = let x = # 191 "" ( x ) -# 23203 "parsing/parser.ml" +# 23213 "parsing/parser.ml" in # 126 "" ( Some x ) -# 23208 "parsing/parser.ml" +# 23218 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23214 "parsing/parser.ml" +# 23224 "parsing/parser.ml" in -# 2900 "parsing/parser.mly" +# 2905 "parsing/parser.mly" ( (Ptype_variant cs, priv, oty) ) -# 23220 "parsing/parser.ml" +# 23230 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23239,26 +23249,26 @@ module Tables = struct let _startpos = _startpos__3_ in let _endpos = _endpos__3_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3586 "parsing/parser.mly" +# 3602 "parsing/parser.mly" ( Public ) -# 23245 "parsing/parser.ml" +# 23255 "parsing/parser.ml" in let oty = let _1 = # 124 "" ( None ) -# 23251 "parsing/parser.ml" +# 23261 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23256 "parsing/parser.ml" +# 23266 "parsing/parser.ml" in -# 2904 "parsing/parser.mly" +# 2909 "parsing/parser.mly" ( (Ptype_open, priv, oty) ) -# 23262 "parsing/parser.ml" +# 23272 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23288,26 +23298,26 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3587 "parsing/parser.mly" +# 3603 "parsing/parser.mly" ( Private ) -# 23294 "parsing/parser.ml" +# 23304 "parsing/parser.ml" in let oty = let _1 = # 124 "" ( None ) -# 23300 "parsing/parser.ml" +# 23310 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23305 "parsing/parser.ml" +# 23315 "parsing/parser.ml" in -# 2904 "parsing/parser.mly" +# 2909 "parsing/parser.mly" ( (Ptype_open, priv, oty) ) -# 23311 "parsing/parser.ml" +# 23321 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23344,33 +23354,33 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos__3_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3586 "parsing/parser.mly" +# 3602 "parsing/parser.mly" ( Public ) -# 23350 "parsing/parser.ml" +# 23360 "parsing/parser.ml" in let oty = let _1 = let x = # 191 "" ( x ) -# 23357 "parsing/parser.ml" +# 23367 "parsing/parser.ml" in # 126 "" ( Some x ) -# 23362 "parsing/parser.ml" +# 23372 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23368 "parsing/parser.ml" +# 23378 "parsing/parser.ml" in -# 2904 "parsing/parser.mly" +# 2909 "parsing/parser.mly" ( (Ptype_open, priv, oty) ) -# 23374 "parsing/parser.ml" +# 23384 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23414,33 +23424,33 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos__3_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3587 "parsing/parser.mly" +# 3603 "parsing/parser.mly" ( Private ) -# 23420 "parsing/parser.ml" +# 23430 "parsing/parser.ml" in let oty = let _1 = let x = # 191 "" ( x ) -# 23427 "parsing/parser.ml" +# 23437 "parsing/parser.ml" in # 126 "" ( Some x ) -# 23432 "parsing/parser.ml" +# 23442 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23438 "parsing/parser.ml" +# 23448 "parsing/parser.ml" in -# 2904 "parsing/parser.mly" +# 2909 "parsing/parser.mly" ( (Ptype_open, priv, oty) ) -# 23444 "parsing/parser.ml" +# 23454 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23477,26 +23487,26 @@ module Tables = struct let _startpos = _startpos__3_ in let _endpos = _endpos__5_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3586 "parsing/parser.mly" +# 3602 "parsing/parser.mly" ( Public ) -# 23483 "parsing/parser.ml" +# 23493 "parsing/parser.ml" in let oty = let _1 = # 124 "" ( None ) -# 23489 "parsing/parser.ml" +# 23499 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23494 "parsing/parser.ml" +# 23504 "parsing/parser.ml" in -# 2908 "parsing/parser.mly" +# 2913 "parsing/parser.mly" ( (Ptype_record ls, priv, oty) ) -# 23500 "parsing/parser.ml" +# 23510 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23540,26 +23550,26 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3587 "parsing/parser.mly" +# 3603 "parsing/parser.mly" ( Private ) -# 23546 "parsing/parser.ml" +# 23556 "parsing/parser.ml" in let oty = let _1 = # 124 "" ( None ) -# 23552 "parsing/parser.ml" +# 23562 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23557 "parsing/parser.ml" +# 23567 "parsing/parser.ml" in -# 2908 "parsing/parser.mly" +# 2913 "parsing/parser.mly" ( (Ptype_record ls, priv, oty) ) -# 23563 "parsing/parser.ml" +# 23573 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23610,33 +23620,33 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos__5_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3586 "parsing/parser.mly" +# 3602 "parsing/parser.mly" ( Public ) -# 23616 "parsing/parser.ml" +# 23626 "parsing/parser.ml" in let oty = let _1 = let x = # 191 "" ( x ) -# 23623 "parsing/parser.ml" +# 23633 "parsing/parser.ml" in # 126 "" ( Some x ) -# 23628 "parsing/parser.ml" +# 23638 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23634 "parsing/parser.ml" +# 23644 "parsing/parser.ml" in -# 2908 "parsing/parser.mly" +# 2913 "parsing/parser.mly" ( (Ptype_record ls, priv, oty) ) -# 23640 "parsing/parser.ml" +# 23650 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23694,33 +23704,33 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos__5_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = let priv = -# 3587 "parsing/parser.mly" +# 3603 "parsing/parser.mly" ( Private ) -# 23700 "parsing/parser.ml" +# 23710 "parsing/parser.ml" in let oty = let _1 = let x = # 191 "" ( x ) -# 23707 "parsing/parser.ml" +# 23717 "parsing/parser.ml" in # 126 "" ( Some x ) -# 23712 "parsing/parser.ml" +# 23722 "parsing/parser.ml" in -# 2912 "parsing/parser.mly" +# 2917 "parsing/parser.mly" ( _1 ) -# 23718 "parsing/parser.ml" +# 23728 "parsing/parser.ml" in -# 2908 "parsing/parser.mly" +# 2913 "parsing/parser.mly" ( (Ptype_record ls, priv, oty) ) -# 23724 "parsing/parser.ml" +# 23734 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23773,37 +23783,37 @@ module Tables = struct let _v : (Parsetree.open_declaration * string Asttypes.loc option) = let attrs2 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 23779 "parsing/parser.ml" +# 23789 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined2_ in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 23788 "parsing/parser.ml" +# 23798 "parsing/parser.ml" in let override = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 23794 "parsing/parser.ml" +# 23804 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1469 "parsing/parser.mly" +# 1474 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Opn.mk me ~override ~attrs ~loc ~docs, ext ) -# 23807 "parsing/parser.ml" +# 23817 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23863,40 +23873,40 @@ module Tables = struct let _v : (Parsetree.open_declaration * string Asttypes.loc option) = let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 23869 "parsing/parser.ml" +# 23879 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in let attrs1 = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 23878 "parsing/parser.ml" +# 23888 "parsing/parser.ml" in let override = let _1 = _1_inlined1 in -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 23886 "parsing/parser.ml" +# 23896 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1469 "parsing/parser.mly" +# 1474 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Opn.mk me ~override ~attrs ~loc ~docs, ext ) -# 23900 "parsing/parser.ml" +# 23910 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -23949,9 +23959,9 @@ module Tables = struct let _v : (Parsetree.open_description * string Asttypes.loc option) = let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 23955 "parsing/parser.ml" +# 23965 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -23961,36 +23971,36 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 23967 "parsing/parser.ml" +# 23977 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 23975 "parsing/parser.ml" +# 23985 "parsing/parser.ml" in let override = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 23981 "parsing/parser.ml" +# 23991 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1484 "parsing/parser.mly" +# 1489 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Opn.mk id ~override ~attrs ~loc ~docs, ext ) -# 23994 "parsing/parser.ml" +# 24004 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24050,9 +24060,9 @@ module Tables = struct let _v : (Parsetree.open_description * string Asttypes.loc option) = let attrs2 = let _1 = _1_inlined4 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 24056 "parsing/parser.ml" +# 24066 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined4_ in @@ -24062,39 +24072,39 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 24068 "parsing/parser.ml" +# 24078 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined2 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 24076 "parsing/parser.ml" +# 24086 "parsing/parser.ml" in let override = let _1 = _1_inlined1 in -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 24084 "parsing/parser.ml" +# 24094 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1484 "parsing/parser.mly" +# 1489 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Opn.mk id ~override ~attrs ~loc ~docs, ext ) -# 24098 "parsing/parser.ml" +# 24108 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24113,17 +24123,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 671 "parsing/parser.mly" +# 675 "parsing/parser.mly" (string) -# 24119 "parsing/parser.ml" +# 24129 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3429 "parsing/parser.mly" +# 3445 "parsing/parser.mly" ( _1 ) -# 24127 "parsing/parser.ml" +# 24137 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24142,17 +24152,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 629 "parsing/parser.mly" +# 633 "parsing/parser.mly" (string) -# 24148 "parsing/parser.ml" +# 24158 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3430 "parsing/parser.mly" +# 3446 "parsing/parser.mly" ( _1 ) -# 24156 "parsing/parser.ml" +# 24166 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24171,17 +24181,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 630 "parsing/parser.mly" +# 634 "parsing/parser.mly" (string) -# 24177 "parsing/parser.ml" +# 24187 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3431 "parsing/parser.mly" +# 3447 "parsing/parser.mly" ( _1 ) -# 24185 "parsing/parser.ml" +# 24195 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24221,17 +24231,17 @@ module Tables = struct let _3 : (string) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 24227 "parsing/parser.ml" +# 24237 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : (Asttypes.label) = -# 3432 "parsing/parser.mly" +# 3448 "parsing/parser.mly" ( "."^ _1 ^"(" ^ _3 ^ ")" ) -# 24235 "parsing/parser.ml" +# 24245 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24278,17 +24288,17 @@ module Tables = struct let _3 : (string) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 24284 "parsing/parser.ml" +# 24294 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Asttypes.label) = -# 3433 "parsing/parser.mly" +# 3449 "parsing/parser.mly" ( "."^ _1 ^ "(" ^ _3 ^ ")<-" ) -# 24292 "parsing/parser.ml" +# 24302 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24328,17 +24338,17 @@ module Tables = struct let _3 : (string) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 24334 "parsing/parser.ml" +# 24344 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : (Asttypes.label) = -# 3434 "parsing/parser.mly" +# 3450 "parsing/parser.mly" ( "."^ _1 ^"[" ^ _3 ^ "]" ) -# 24342 "parsing/parser.ml" +# 24352 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24385,17 +24395,17 @@ module Tables = struct let _3 : (string) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 24391 "parsing/parser.ml" +# 24401 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Asttypes.label) = -# 3435 "parsing/parser.mly" +# 3451 "parsing/parser.mly" ( "."^ _1 ^ "[" ^ _3 ^ "]<-" ) -# 24399 "parsing/parser.ml" +# 24409 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24435,17 +24445,17 @@ module Tables = struct let _3 : (string) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 24441 "parsing/parser.ml" +# 24451 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : (Asttypes.label) = -# 3436 "parsing/parser.mly" +# 3452 "parsing/parser.mly" ( "."^ _1 ^"{" ^ _3 ^ "}" ) -# 24449 "parsing/parser.ml" +# 24459 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24492,17 +24502,17 @@ module Tables = struct let _3 : (string) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in let _1 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 24498 "parsing/parser.ml" +# 24508 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Asttypes.label) = -# 3437 "parsing/parser.mly" +# 3453 "parsing/parser.mly" ( "."^ _1 ^ "{" ^ _3 ^ "}<-" ) -# 24506 "parsing/parser.ml" +# 24516 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24521,17 +24531,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 682 "parsing/parser.mly" +# 686 "parsing/parser.mly" (string) -# 24527 "parsing/parser.ml" +# 24537 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3438 "parsing/parser.mly" +# 3454 "parsing/parser.mly" ( _1 ) -# 24535 "parsing/parser.ml" +# 24545 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24554,9 +24564,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3439 "parsing/parser.mly" +# 3455 "parsing/parser.mly" ( "!" ) -# 24560 "parsing/parser.ml" +# 24570 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24575,22 +24585,22 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let op : ( -# 623 "parsing/parser.mly" +# 627 "parsing/parser.mly" (string) -# 24581 "parsing/parser.ml" +# 24591 "parsing/parser.ml" ) = Obj.magic op in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_op_ in let _endpos = _endpos_op_ in let _v : (Asttypes.label) = let _1 = -# 3443 "parsing/parser.mly" +# 3459 "parsing/parser.mly" ( op ) -# 24589 "parsing/parser.ml" +# 24599 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24594 "parsing/parser.ml" +# 24604 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24609,22 +24619,22 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let op : ( -# 624 "parsing/parser.mly" +# 628 "parsing/parser.mly" (string) -# 24615 "parsing/parser.ml" +# 24625 "parsing/parser.ml" ) = Obj.magic op in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_op_ in let _endpos = _endpos_op_ in let _v : (Asttypes.label) = let _1 = -# 3444 "parsing/parser.mly" +# 3460 "parsing/parser.mly" ( op ) -# 24623 "parsing/parser.ml" +# 24633 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24628 "parsing/parser.ml" +# 24638 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24643,22 +24653,22 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let op : ( -# 625 "parsing/parser.mly" +# 629 "parsing/parser.mly" (string) -# 24649 "parsing/parser.ml" +# 24659 "parsing/parser.ml" ) = Obj.magic op in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_op_ in let _endpos = _endpos_op_ in let _v : (Asttypes.label) = let _1 = -# 3445 "parsing/parser.mly" +# 3461 "parsing/parser.mly" ( op ) -# 24657 "parsing/parser.ml" +# 24667 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24662 "parsing/parser.ml" +# 24672 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24677,22 +24687,22 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let op : ( -# 626 "parsing/parser.mly" +# 630 "parsing/parser.mly" (string) -# 24683 "parsing/parser.ml" +# 24693 "parsing/parser.ml" ) = Obj.magic op in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_op_ in let _endpos = _endpos_op_ in let _v : (Asttypes.label) = let _1 = -# 3446 "parsing/parser.mly" +# 3462 "parsing/parser.mly" ( op ) -# 24691 "parsing/parser.ml" +# 24701 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24696 "parsing/parser.ml" +# 24706 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24711,22 +24721,22 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let op : ( -# 627 "parsing/parser.mly" +# 631 "parsing/parser.mly" (string) -# 24717 "parsing/parser.ml" +# 24727 "parsing/parser.ml" ) = Obj.magic op in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_op_ in let _endpos = _endpos_op_ in let _v : (Asttypes.label) = let _1 = -# 3447 "parsing/parser.mly" +# 3463 "parsing/parser.mly" ( op ) -# 24725 "parsing/parser.ml" +# 24735 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24730 "parsing/parser.ml" +# 24740 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24749,14 +24759,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3448 "parsing/parser.mly" +# 3464 "parsing/parser.mly" ("+") -# 24755 "parsing/parser.ml" +# 24765 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24760 "parsing/parser.ml" +# 24770 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24779,14 +24789,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3449 "parsing/parser.mly" +# 3465 "parsing/parser.mly" ("+.") -# 24785 "parsing/parser.ml" +# 24795 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24790 "parsing/parser.ml" +# 24800 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24809,14 +24819,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3450 "parsing/parser.mly" +# 3466 "parsing/parser.mly" ("+=") -# 24815 "parsing/parser.ml" +# 24825 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24820 "parsing/parser.ml" +# 24830 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24839,14 +24849,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3451 "parsing/parser.mly" +# 3467 "parsing/parser.mly" ("-") -# 24845 "parsing/parser.ml" +# 24855 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24850 "parsing/parser.ml" +# 24860 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24869,14 +24879,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3452 "parsing/parser.mly" +# 3468 "parsing/parser.mly" ("-.") -# 24875 "parsing/parser.ml" +# 24885 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24880 "parsing/parser.ml" +# 24890 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24899,14 +24909,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3453 "parsing/parser.mly" +# 3469 "parsing/parser.mly" ("*") -# 24905 "parsing/parser.ml" +# 24915 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24910 "parsing/parser.ml" +# 24920 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24929,14 +24939,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3454 "parsing/parser.mly" +# 3470 "parsing/parser.mly" ("%") -# 24935 "parsing/parser.ml" +# 24945 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24940 "parsing/parser.ml" +# 24950 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24959,14 +24969,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3455 "parsing/parser.mly" +# 3471 "parsing/parser.mly" ("=") -# 24965 "parsing/parser.ml" +# 24975 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 24970 "parsing/parser.ml" +# 24980 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -24989,14 +24999,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3456 "parsing/parser.mly" +# 3472 "parsing/parser.mly" ("<") -# 24995 "parsing/parser.ml" +# 25005 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 25000 "parsing/parser.ml" +# 25010 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25019,14 +25029,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3457 "parsing/parser.mly" +# 3473 "parsing/parser.mly" (">") -# 25025 "parsing/parser.ml" +# 25035 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 25030 "parsing/parser.ml" +# 25040 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25049,14 +25059,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3458 "parsing/parser.mly" +# 3474 "parsing/parser.mly" ("or") -# 25055 "parsing/parser.ml" +# 25065 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 25060 "parsing/parser.ml" +# 25070 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25079,14 +25089,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3459 "parsing/parser.mly" +# 3475 "parsing/parser.mly" ("||") -# 25085 "parsing/parser.ml" +# 25095 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 25090 "parsing/parser.ml" +# 25100 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25109,14 +25119,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3460 "parsing/parser.mly" +# 3476 "parsing/parser.mly" ("&") -# 25115 "parsing/parser.ml" +# 25125 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 25120 "parsing/parser.ml" +# 25130 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25139,14 +25149,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3461 "parsing/parser.mly" +# 3477 "parsing/parser.mly" ("&&") -# 25145 "parsing/parser.ml" +# 25155 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 25150 "parsing/parser.ml" +# 25160 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25169,14 +25179,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = let _1 = -# 3462 "parsing/parser.mly" +# 3478 "parsing/parser.mly" (":=") -# 25175 "parsing/parser.ml" +# 25185 "parsing/parser.ml" in -# 3440 "parsing/parser.mly" +# 3456 "parsing/parser.mly" ( _1 ) -# 25180 "parsing/parser.ml" +# 25190 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25199,9 +25209,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (bool) = -# 3344 "parsing/parser.mly" +# 3360 "parsing/parser.mly" ( true ) -# 25205 "parsing/parser.ml" +# 25215 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25217,9 +25227,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (bool) = -# 3345 "parsing/parser.mly" +# 3361 "parsing/parser.mly" ( false ) -# 25223 "parsing/parser.ml" +# 25233 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25237,7 +25247,7 @@ module Tables = struct let _v : (unit option) = # 114 "" ( None ) -# 25241 "parsing/parser.ml" +# 25251 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25262,7 +25272,7 @@ module Tables = struct let _v : (unit option) = # 116 "" ( Some x ) -# 25266 "parsing/parser.ml" +# 25276 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25280,7 +25290,7 @@ module Tables = struct let _v : (unit option) = # 114 "" ( None ) -# 25284 "parsing/parser.ml" +# 25294 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25305,7 +25315,7 @@ module Tables = struct let _v : (unit option) = # 116 "" ( Some x ) -# 25309 "parsing/parser.ml" +# 25319 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25323,7 +25333,7 @@ module Tables = struct let _v : (string Asttypes.loc option) = # 114 "" ( None ) -# 25327 "parsing/parser.ml" +# 25337 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25348,9 +25358,9 @@ module Tables = struct }; } = _menhir_stack in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 25354 "parsing/parser.ml" +# 25364 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -25363,21 +25373,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 25369 "parsing/parser.ml" +# 25379 "parsing/parser.ml" in # 183 "" ( x ) -# 25375 "parsing/parser.ml" +# 25385 "parsing/parser.ml" in # 116 "" ( Some x ) -# 25381 "parsing/parser.ml" +# 25391 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25395,7 +25405,7 @@ module Tables = struct let _v : (Parsetree.core_type option) = # 114 "" ( None ) -# 25399 "parsing/parser.ml" +# 25409 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25427,12 +25437,12 @@ module Tables = struct let _v : (Parsetree.core_type option) = let x = # 183 "" ( x ) -# 25431 "parsing/parser.ml" +# 25441 "parsing/parser.ml" in # 116 "" ( Some x ) -# 25436 "parsing/parser.ml" +# 25446 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25450,7 +25460,7 @@ module Tables = struct let _v : (Parsetree.expression option) = # 114 "" ( None ) -# 25454 "parsing/parser.ml" +# 25464 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25482,12 +25492,12 @@ module Tables = struct let _v : (Parsetree.expression option) = let x = # 183 "" ( x ) -# 25486 "parsing/parser.ml" +# 25496 "parsing/parser.ml" in # 116 "" ( Some x ) -# 25491 "parsing/parser.ml" +# 25501 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25505,7 +25515,7 @@ module Tables = struct let _v : (Parsetree.module_type option) = # 114 "" ( None ) -# 25509 "parsing/parser.ml" +# 25519 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25537,12 +25547,12 @@ module Tables = struct let _v : (Parsetree.module_type option) = let x = # 183 "" ( x ) -# 25541 "parsing/parser.ml" +# 25551 "parsing/parser.ml" in # 116 "" ( Some x ) -# 25546 "parsing/parser.ml" +# 25556 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25560,7 +25570,7 @@ module Tables = struct let _v : (Parsetree.pattern option) = # 114 "" ( None ) -# 25564 "parsing/parser.ml" +# 25574 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25592,12 +25602,12 @@ module Tables = struct let _v : (Parsetree.pattern option) = let x = # 183 "" ( x ) -# 25596 "parsing/parser.ml" +# 25606 "parsing/parser.ml" in # 116 "" ( Some x ) -# 25601 "parsing/parser.ml" +# 25611 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25615,7 +25625,7 @@ module Tables = struct let _v : (Parsetree.expression option) = # 114 "" ( None ) -# 25619 "parsing/parser.ml" +# 25629 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25647,12 +25657,12 @@ module Tables = struct let _v : (Parsetree.expression option) = let x = # 183 "" ( x ) -# 25651 "parsing/parser.ml" +# 25661 "parsing/parser.ml" in # 116 "" ( Some x ) -# 25656 "parsing/parser.ml" +# 25666 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25670,7 +25680,7 @@ module Tables = struct let _v : ((Parsetree.core_type option * Parsetree.core_type option) option) = # 114 "" ( None ) -# 25674 "parsing/parser.ml" +# 25684 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25695,7 +25705,7 @@ module Tables = struct let _v : ((Parsetree.core_type option * Parsetree.core_type option) option) = # 116 "" ( Some x ) -# 25699 "parsing/parser.ml" +# 25709 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25714,17 +25724,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 664 "parsing/parser.mly" +# 668 "parsing/parser.mly" (string) -# 25720 "parsing/parser.ml" +# 25730 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3645 "parsing/parser.mly" +# 3661 "parsing/parser.mly" ( _1 ) -# 25728 "parsing/parser.ml" +# 25738 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25756,18 +25766,18 @@ module Tables = struct } = _menhir_stack in let _3 : unit = Obj.magic _3 in let _2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 25762 "parsing/parser.ml" +# 25772 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (string) = -# 3646 "parsing/parser.mly" +# 3662 "parsing/parser.mly" ( _2 ) -# 25771 "parsing/parser.ml" +# 25781 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25821,9 +25831,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1249 "parsing/parser.mly" +# 1253 "parsing/parser.mly" ( mkmod ~loc:_sloc (Pmod_constraint(me, mty)) ) -# 25827 "parsing/parser.ml" +# 25837 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25876,9 +25886,9 @@ module Tables = struct let _v : (Parsetree.module_expr) = let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1251 "parsing/parser.mly" +# 1255 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__5_ ) -# 25882 "parsing/parser.ml" +# 25892 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25915,9 +25925,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.module_expr) = -# 1254 "parsing/parser.mly" +# 1258 "parsing/parser.mly" ( me (* TODO consider reloc *) ) -# 25921 "parsing/parser.ml" +# 25931 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -25956,9 +25966,9 @@ module Tables = struct let _v : (Parsetree.module_expr) = let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1256 "parsing/parser.mly" +# 1260 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__3_ ) -# 25962 "parsing/parser.ml" +# 25972 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26009,25 +26019,25 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.module_expr) = let e = -# 1273 "parsing/parser.mly" +# 1277 "parsing/parser.mly" ( e ) -# 26015 "parsing/parser.ml" +# 26025 "parsing/parser.ml" in let attrs = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 26022 "parsing/parser.ml" +# 26032 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1260 "parsing/parser.mly" +# 1264 "parsing/parser.mly" ( mkmod ~loc:_sloc ~attrs (Pmod_unpack e) ) -# 26031 "parsing/parser.ml" +# 26041 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26094,24 +26104,14 @@ module Tables = struct let _v : (Parsetree.module_expr) = let e = let (_endpos__1_, _startpos__1_, _1, _2) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2, _2_inlined1) in let ty = - let _1 = - let _1 = -# 3320 "parsing/parser.mly" - ( Ptyp_package (package_type_of_module_type _1) ) -# 26102 "parsing/parser.ml" - in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 850 "parsing/parser.mly" - ( mktyp ~loc:_sloc _1 ) -# 26110 "parsing/parser.ml" - - in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in -# 3321 "parsing/parser.mly" - ( _1 ) +# 3335 "parsing/parser.mly" + ( let (lid, cstrs, attrs) = package_type_of_module_type _1 in + let descr = Ptyp_package (lid, cstrs) in + mktyp ~loc:_sloc ~attrs descr ) # 26116 "parsing/parser.ml" in @@ -26120,7 +26120,7 @@ module Tables = struct let _startpos = _startpos_e_ in let _loc = (_startpos, _endpos) in -# 1275 "parsing/parser.mly" +# 1279 "parsing/parser.mly" ( ghexp ~loc:_loc (Pexp_constraint (e, ty)) ) # 26126 "parsing/parser.ml" @@ -26128,7 +26128,7 @@ module Tables = struct let attrs = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) # 26134 "parsing/parser.ml" @@ -26137,7 +26137,7 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1260 "parsing/parser.mly" +# 1264 "parsing/parser.mly" ( mkmod ~loc:_sloc ~attrs (Pmod_unpack e) ) # 26143 "parsing/parser.ml" in @@ -26221,74 +26221,54 @@ module Tables = struct let (_endpos__1_inlined1_, _startpos__1_inlined1_, _endpos__1_, _startpos__1_, _1_inlined1, _1, _2) = (_endpos__1_inlined3_, _startpos__1_inlined3_, _endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined3, _1_inlined2, _2_inlined1) in let ty2 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in - let _1 = - let _1 = -# 3320 "parsing/parser.mly" - ( Ptyp_package (package_type_of_module_type _1) ) -# 26229 "parsing/parser.ml" - in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 850 "parsing/parser.mly" - ( mktyp ~loc:_sloc _1 ) -# 26237 "parsing/parser.ml" - - in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in -# 3321 "parsing/parser.mly" - ( _1 ) -# 26243 "parsing/parser.ml" +# 3335 "parsing/parser.mly" + ( let (lid, cstrs, attrs) = package_type_of_module_type _1 in + let descr = Ptyp_package (lid, cstrs) in + mktyp ~loc:_sloc ~attrs descr ) +# 26233 "parsing/parser.ml" in let _endpos_ty2_ = _endpos__1_inlined1_ in let ty1 = - let _1 = - let _1 = -# 3320 "parsing/parser.mly" - ( Ptyp_package (package_type_of_module_type _1) ) -# 26252 "parsing/parser.ml" - in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 850 "parsing/parser.mly" - ( mktyp ~loc:_sloc _1 ) -# 26260 "parsing/parser.ml" - - in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in -# 3321 "parsing/parser.mly" - ( _1 ) -# 26266 "parsing/parser.ml" +# 3335 "parsing/parser.mly" + ( let (lid, cstrs, attrs) = package_type_of_module_type _1 in + let descr = Ptyp_package (lid, cstrs) in + mktyp ~loc:_sloc ~attrs descr ) +# 26246 "parsing/parser.ml" in let _endpos = _endpos_ty2_ in let _startpos = _startpos_e_ in let _loc = (_startpos, _endpos) in -# 1277 "parsing/parser.mly" +# 1281 "parsing/parser.mly" ( ghexp ~loc:_loc (Pexp_coerce (e, Some ty1, ty2)) ) -# 26275 "parsing/parser.ml" +# 26255 "parsing/parser.ml" in let attrs = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 26283 "parsing/parser.ml" +# 26263 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1260 "parsing/parser.mly" +# 1264 "parsing/parser.mly" ( mkmod ~loc:_sloc ~attrs (Pmod_unpack e) ) -# 26292 "parsing/parser.ml" +# 26272 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26355,25 +26335,15 @@ module Tables = struct let _v : (Parsetree.module_expr) = let e = let (_endpos__1_, _startpos__1_, _1, _2) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2, _2_inlined1) in let ty2 = - let _1 = - let _1 = -# 3320 "parsing/parser.mly" - ( Ptyp_package (package_type_of_module_type _1) ) -# 26363 "parsing/parser.ml" - in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 850 "parsing/parser.mly" - ( mktyp ~loc:_sloc _1 ) -# 26371 "parsing/parser.ml" - - in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in -# 3321 "parsing/parser.mly" - ( _1 ) -# 26377 "parsing/parser.ml" +# 3335 "parsing/parser.mly" + ( let (lid, cstrs, attrs) = package_type_of_module_type _1 in + let descr = Ptyp_package (lid, cstrs) in + mktyp ~loc:_sloc ~attrs descr ) +# 26347 "parsing/parser.ml" in let _endpos_ty2_ = _endpos__1_ in @@ -26381,26 +26351,26 @@ module Tables = struct let _startpos = _startpos_e_ in let _loc = (_startpos, _endpos) in -# 1279 "parsing/parser.mly" +# 1283 "parsing/parser.mly" ( ghexp ~loc:_loc (Pexp_coerce (e, None, ty2)) ) -# 26387 "parsing/parser.ml" +# 26357 "parsing/parser.ml" in let attrs = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 26395 "parsing/parser.ml" +# 26365 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1260 "parsing/parser.mly" +# 1264 "parsing/parser.mly" ( mkmod ~loc:_sloc ~attrs (Pmod_unpack e) ) -# 26404 "parsing/parser.ml" +# 26374 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26460,17 +26430,17 @@ module Tables = struct let _v : (Parsetree.module_expr) = let _3 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 26466 "parsing/parser.ml" +# 26436 "parsing/parser.ml" in let _loc__6_ = (_startpos__6_, _endpos__6_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1262 "parsing/parser.mly" +# 1266 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__6_ ) -# 26474 "parsing/parser.ml" +# 26444 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26530,17 +26500,17 @@ module Tables = struct let _v : (Parsetree.module_expr) = let _3 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 26536 "parsing/parser.ml" +# 26506 "parsing/parser.ml" in let _loc__6_ = (_startpos__6_, _endpos__6_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1264 "parsing/parser.mly" +# 1268 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__6_ ) -# 26544 "parsing/parser.ml" +# 26514 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26593,17 +26563,17 @@ module Tables = struct let _v : (Parsetree.module_expr) = let _3 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 26599 "parsing/parser.ml" +# 26569 "parsing/parser.ml" in let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1266 "parsing/parser.mly" +# 1270 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__5_ ) -# 26607 "parsing/parser.ml" +# 26577 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26633,13 +26603,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 801 "parsing/parser.mly" +# 805 "parsing/parser.mly" (Longident.t) -# 26639 "parsing/parser.ml" +# 26609 "parsing/parser.ml" ) = -# 1170 "parsing/parser.mly" +# 1174 "parsing/parser.mly" ( _1 ) -# 26643 "parsing/parser.ml" +# 26613 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26669,13 +26639,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 791 "parsing/parser.mly" +# 795 "parsing/parser.mly" (Longident.t) -# 26675 "parsing/parser.ml" +# 26645 "parsing/parser.ml" ) = -# 1155 "parsing/parser.mly" +# 1159 "parsing/parser.mly" ( _1 ) -# 26679 "parsing/parser.ml" +# 26649 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26705,13 +26675,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 785 "parsing/parser.mly" +# 789 "parsing/parser.mly" (Parsetree.core_type) -# 26711 "parsing/parser.ml" +# 26681 "parsing/parser.ml" ) = -# 1130 "parsing/parser.mly" +# 1134 "parsing/parser.mly" ( _1 ) -# 26715 "parsing/parser.ml" +# 26685 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26741,13 +26711,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 787 "parsing/parser.mly" +# 791 "parsing/parser.mly" (Parsetree.expression) -# 26747 "parsing/parser.ml" +# 26717 "parsing/parser.ml" ) = -# 1135 "parsing/parser.mly" +# 1139 "parsing/parser.mly" ( _1 ) -# 26751 "parsing/parser.ml" +# 26721 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26777,13 +26747,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 797 "parsing/parser.mly" +# 801 "parsing/parser.mly" (Longident.t) -# 26783 "parsing/parser.ml" +# 26753 "parsing/parser.ml" ) = -# 1160 "parsing/parser.mly" +# 1164 "parsing/parser.mly" ( _1 ) -# 26787 "parsing/parser.ml" +# 26757 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26813,13 +26783,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 799 "parsing/parser.mly" +# 803 "parsing/parser.mly" (Longident.t) -# 26819 "parsing/parser.ml" +# 26789 "parsing/parser.ml" ) = -# 1165 "parsing/parser.mly" +# 1169 "parsing/parser.mly" ( _1 ) -# 26823 "parsing/parser.ml" +# 26793 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26849,13 +26819,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 795 "parsing/parser.mly" +# 799 "parsing/parser.mly" (Longident.t) -# 26855 "parsing/parser.ml" +# 26825 "parsing/parser.ml" ) = -# 1145 "parsing/parser.mly" +# 1149 "parsing/parser.mly" ( _1 ) -# 26859 "parsing/parser.ml" +# 26829 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26885,13 +26855,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 789 "parsing/parser.mly" +# 793 "parsing/parser.mly" (Parsetree.pattern) -# 26891 "parsing/parser.ml" +# 26861 "parsing/parser.ml" ) = -# 1140 "parsing/parser.mly" +# 1144 "parsing/parser.mly" ( _1 ) -# 26895 "parsing/parser.ml" +# 26865 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26921,13 +26891,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 793 "parsing/parser.mly" +# 797 "parsing/parser.mly" (Longident.t) -# 26927 "parsing/parser.ml" +# 26897 "parsing/parser.ml" ) = -# 1150 "parsing/parser.mly" +# 1154 "parsing/parser.mly" ( _1 ) -# 26931 "parsing/parser.ml" +# 26901 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -26969,15 +26939,15 @@ module Tables = struct let _loc__2_ = (_startpos__2_, _endpos__2_) in let _sloc = (_symbolstartpos, _endpos) in -# 2631 "parsing/parser.mly" +# 2633 "parsing/parser.mly" ( mkpat_cons ~loc:_sloc _loc__2_ (ghpat ~loc:_sloc (Ppat_tuple[_1;_3])) ) -# 26975 "parsing/parser.ml" +# 26945 "parsing/parser.ml" in -# 2619 "parsing/parser.mly" +# 2621 "parsing/parser.mly" ( _1 ) -# 26981 "parsing/parser.ml" +# 26951 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27007,14 +26977,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.pattern) = let _1 = -# 2633 "parsing/parser.mly" +# 2635 "parsing/parser.mly" ( Pat.attr _1 _2 ) -# 27013 "parsing/parser.ml" +# 26983 "parsing/parser.ml" in -# 2619 "parsing/parser.mly" +# 2621 "parsing/parser.mly" ( _1 ) -# 27018 "parsing/parser.ml" +# 26988 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27037,14 +27007,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = let _1 = -# 2635 "parsing/parser.mly" +# 2637 "parsing/parser.mly" ( _1 ) -# 27043 "parsing/parser.ml" +# 27013 "parsing/parser.ml" in -# 2619 "parsing/parser.mly" +# 2621 "parsing/parser.mly" ( _1 ) -# 27048 "parsing/parser.ml" +# 27018 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27089,15 +27059,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 27095 "parsing/parser.ml" +# 27065 "parsing/parser.ml" in -# 2638 "parsing/parser.mly" +# 2640 "parsing/parser.mly" ( Ppat_alias(_1, _3) ) -# 27101 "parsing/parser.ml" +# 27071 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined1_ in @@ -27105,21 +27075,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 27111 "parsing/parser.ml" +# 27081 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 27117 "parsing/parser.ml" +# 27087 "parsing/parser.ml" in -# 2619 "parsing/parser.mly" +# 2621 "parsing/parser.mly" ( _1 ) -# 27123 "parsing/parser.ml" +# 27093 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27160,9 +27130,9 @@ module Tables = struct let _1 = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2640 "parsing/parser.mly" +# 2642 "parsing/parser.mly" ( expecting _loc__3_ "identifier" ) -# 27166 "parsing/parser.ml" +# 27136 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -27170,21 +27140,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 27176 "parsing/parser.ml" +# 27146 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 27182 "parsing/parser.ml" +# 27152 "parsing/parser.ml" in -# 2619 "parsing/parser.mly" +# 2621 "parsing/parser.mly" ( _1 ) -# 27188 "parsing/parser.ml" +# 27158 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27209,29 +27179,29 @@ module Tables = struct let _v : (Parsetree.pattern) = let _1 = let _1 = let _1 = -# 2642 "parsing/parser.mly" +# 2644 "parsing/parser.mly" ( Ppat_tuple(List.rev _1) ) -# 27215 "parsing/parser.ml" +# 27185 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 27223 "parsing/parser.ml" +# 27193 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 27229 "parsing/parser.ml" +# 27199 "parsing/parser.ml" in -# 2619 "parsing/parser.mly" +# 2621 "parsing/parser.mly" ( _1 ) -# 27235 "parsing/parser.ml" +# 27205 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27272,9 +27242,9 @@ module Tables = struct let _1 = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2644 "parsing/parser.mly" +# 2646 "parsing/parser.mly" ( expecting _loc__3_ "pattern" ) -# 27278 "parsing/parser.ml" +# 27248 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -27282,21 +27252,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 27288 "parsing/parser.ml" +# 27258 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 27294 "parsing/parser.ml" +# 27264 "parsing/parser.ml" in -# 2619 "parsing/parser.mly" +# 2621 "parsing/parser.mly" ( _1 ) -# 27300 "parsing/parser.ml" +# 27270 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27335,30 +27305,30 @@ module Tables = struct let _v : (Parsetree.pattern) = let _1 = let _1 = let _1 = -# 2646 "parsing/parser.mly" +# 2648 "parsing/parser.mly" ( Ppat_or(_1, _3) ) -# 27341 "parsing/parser.ml" +# 27311 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 27350 "parsing/parser.ml" +# 27320 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 27356 "parsing/parser.ml" +# 27326 "parsing/parser.ml" in -# 2619 "parsing/parser.mly" +# 2621 "parsing/parser.mly" ( _1 ) -# 27362 "parsing/parser.ml" +# 27332 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27399,9 +27369,9 @@ module Tables = struct let _1 = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2648 "parsing/parser.mly" +# 2650 "parsing/parser.mly" ( expecting _loc__3_ "pattern" ) -# 27405 "parsing/parser.ml" +# 27375 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -27409,21 +27379,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 27415 "parsing/parser.ml" +# 27385 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 27421 "parsing/parser.ml" +# 27391 "parsing/parser.ml" in -# 2619 "parsing/parser.mly" +# 2621 "parsing/parser.mly" ( _1 ) -# 27427 "parsing/parser.ml" +# 27397 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27471,24 +27441,24 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 27477 "parsing/parser.ml" +# 27447 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 27483 "parsing/parser.ml" +# 27453 "parsing/parser.ml" in let _endpos = _endpos__3_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2621 "parsing/parser.mly" +# 2623 "parsing/parser.mly" ( mkpat_attrs ~loc:_sloc (Ppat_exception _3) _2) -# 27492 "parsing/parser.ml" +# 27462 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27525,9 +27495,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.pattern list) = -# 2745 "parsing/parser.mly" +# 2747 "parsing/parser.mly" ( _3 :: _1 ) -# 27531 "parsing/parser.ml" +# 27501 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27564,9 +27534,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.pattern list) = -# 2746 "parsing/parser.mly" +# 2748 "parsing/parser.mly" ( [_3; _1] ) -# 27570 "parsing/parser.ml" +# 27540 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27604,9 +27574,9 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Parsetree.pattern list) = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2747 "parsing/parser.mly" +# 2749 "parsing/parser.mly" ( expecting _loc__3_ "pattern" ) -# 27610 "parsing/parser.ml" +# 27580 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27643,9 +27613,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.pattern list) = -# 2745 "parsing/parser.mly" +# 2747 "parsing/parser.mly" ( _3 :: _1 ) -# 27649 "parsing/parser.ml" +# 27619 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27682,9 +27652,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Parsetree.pattern list) = -# 2746 "parsing/parser.mly" +# 2748 "parsing/parser.mly" ( [_3; _1] ) -# 27688 "parsing/parser.ml" +# 27658 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27722,9 +27692,9 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Parsetree.pattern list) = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2747 "parsing/parser.mly" +# 2749 "parsing/parser.mly" ( expecting _loc__3_ "pattern" ) -# 27728 "parsing/parser.ml" +# 27698 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27747,9 +27717,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = -# 2654 "parsing/parser.mly" +# 2656 "parsing/parser.mly" ( _1 ) -# 27753 "parsing/parser.ml" +# 27723 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27785,15 +27755,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 27791 "parsing/parser.ml" +# 27761 "parsing/parser.ml" in -# 2657 "parsing/parser.mly" +# 2659 "parsing/parser.mly" ( Ppat_construct(_1, Some _2) ) -# 27797 "parsing/parser.ml" +# 27767 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in @@ -27801,15 +27771,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 27807 "parsing/parser.ml" +# 27777 "parsing/parser.ml" in -# 2660 "parsing/parser.mly" +# 2662 "parsing/parser.mly" ( _1 ) -# 27813 "parsing/parser.ml" +# 27783 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27840,24 +27810,24 @@ module Tables = struct let _endpos = _endpos__2_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 2659 "parsing/parser.mly" +# 2661 "parsing/parser.mly" ( Ppat_variant(_1, Some _2) ) -# 27846 "parsing/parser.ml" +# 27816 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 27855 "parsing/parser.ml" +# 27825 "parsing/parser.ml" in -# 2660 "parsing/parser.mly" +# 2662 "parsing/parser.mly" ( _1 ) -# 27861 "parsing/parser.ml" +# 27831 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27905,24 +27875,24 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 27911 "parsing/parser.ml" +# 27881 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 27917 "parsing/parser.ml" +# 27887 "parsing/parser.ml" in let _endpos = _endpos__3_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2662 "parsing/parser.mly" +# 2664 "parsing/parser.mly" ( mkpat_attrs ~loc:_sloc (Ppat_lazy _3) _2) -# 27926 "parsing/parser.ml" +# 27896 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -27964,15 +27934,15 @@ module Tables = struct let _loc__2_ = (_startpos__2_, _endpos__2_) in let _sloc = (_symbolstartpos, _endpos) in -# 2631 "parsing/parser.mly" +# 2633 "parsing/parser.mly" ( mkpat_cons ~loc:_sloc _loc__2_ (ghpat ~loc:_sloc (Ppat_tuple[_1;_3])) ) -# 27970 "parsing/parser.ml" +# 27940 "parsing/parser.ml" in -# 2626 "parsing/parser.mly" +# 2628 "parsing/parser.mly" ( _1 ) -# 27976 "parsing/parser.ml" +# 27946 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28002,14 +27972,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.pattern) = let _1 = -# 2633 "parsing/parser.mly" +# 2635 "parsing/parser.mly" ( Pat.attr _1 _2 ) -# 28008 "parsing/parser.ml" +# 27978 "parsing/parser.ml" in -# 2626 "parsing/parser.mly" +# 2628 "parsing/parser.mly" ( _1 ) -# 28013 "parsing/parser.ml" +# 27983 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28032,14 +28002,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = let _1 = -# 2635 "parsing/parser.mly" +# 2637 "parsing/parser.mly" ( _1 ) -# 28038 "parsing/parser.ml" +# 28008 "parsing/parser.ml" in -# 2626 "parsing/parser.mly" +# 2628 "parsing/parser.mly" ( _1 ) -# 28043 "parsing/parser.ml" +# 28013 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28084,15 +28054,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 28090 "parsing/parser.ml" +# 28060 "parsing/parser.ml" in -# 2638 "parsing/parser.mly" +# 2640 "parsing/parser.mly" ( Ppat_alias(_1, _3) ) -# 28096 "parsing/parser.ml" +# 28066 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined1_ in @@ -28100,21 +28070,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 28106 "parsing/parser.ml" +# 28076 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 28112 "parsing/parser.ml" +# 28082 "parsing/parser.ml" in -# 2626 "parsing/parser.mly" +# 2628 "parsing/parser.mly" ( _1 ) -# 28118 "parsing/parser.ml" +# 28088 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28155,9 +28125,9 @@ module Tables = struct let _1 = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2640 "parsing/parser.mly" +# 2642 "parsing/parser.mly" ( expecting _loc__3_ "identifier" ) -# 28161 "parsing/parser.ml" +# 28131 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -28165,21 +28135,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 28171 "parsing/parser.ml" +# 28141 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 28177 "parsing/parser.ml" +# 28147 "parsing/parser.ml" in -# 2626 "parsing/parser.mly" +# 2628 "parsing/parser.mly" ( _1 ) -# 28183 "parsing/parser.ml" +# 28153 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28204,29 +28174,29 @@ module Tables = struct let _v : (Parsetree.pattern) = let _1 = let _1 = let _1 = -# 2642 "parsing/parser.mly" +# 2644 "parsing/parser.mly" ( Ppat_tuple(List.rev _1) ) -# 28210 "parsing/parser.ml" +# 28180 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 28218 "parsing/parser.ml" +# 28188 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 28224 "parsing/parser.ml" +# 28194 "parsing/parser.ml" in -# 2626 "parsing/parser.mly" +# 2628 "parsing/parser.mly" ( _1 ) -# 28230 "parsing/parser.ml" +# 28200 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28267,9 +28237,9 @@ module Tables = struct let _1 = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2644 "parsing/parser.mly" +# 2646 "parsing/parser.mly" ( expecting _loc__3_ "pattern" ) -# 28273 "parsing/parser.ml" +# 28243 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -28277,21 +28247,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 28283 "parsing/parser.ml" +# 28253 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 28289 "parsing/parser.ml" +# 28259 "parsing/parser.ml" in -# 2626 "parsing/parser.mly" +# 2628 "parsing/parser.mly" ( _1 ) -# 28295 "parsing/parser.ml" +# 28265 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28330,30 +28300,30 @@ module Tables = struct let _v : (Parsetree.pattern) = let _1 = let _1 = let _1 = -# 2646 "parsing/parser.mly" +# 2648 "parsing/parser.mly" ( Ppat_or(_1, _3) ) -# 28336 "parsing/parser.ml" +# 28306 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 28345 "parsing/parser.ml" +# 28315 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 28351 "parsing/parser.ml" +# 28321 "parsing/parser.ml" in -# 2626 "parsing/parser.mly" +# 2628 "parsing/parser.mly" ( _1 ) -# 28357 "parsing/parser.ml" +# 28327 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28394,9 +28364,9 @@ module Tables = struct let _1 = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2648 "parsing/parser.mly" +# 2650 "parsing/parser.mly" ( expecting _loc__3_ "pattern" ) -# 28400 "parsing/parser.ml" +# 28370 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -28404,21 +28374,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 28410 "parsing/parser.ml" +# 28380 "parsing/parser.ml" in -# 2649 "parsing/parser.mly" +# 2651 "parsing/parser.mly" ( _1 ) -# 28416 "parsing/parser.ml" +# 28386 "parsing/parser.ml" in -# 2626 "parsing/parser.mly" +# 2628 "parsing/parser.mly" ( _1 ) -# 28422 "parsing/parser.ml" +# 28392 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28437,9 +28407,9 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 28443 "parsing/parser.ml" +# 28413 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -28451,30 +28421,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 28457 "parsing/parser.ml" +# 28427 "parsing/parser.ml" in -# 2104 "parsing/parser.mly" +# 2110 "parsing/parser.mly" ( Ppat_var _1 ) -# 28463 "parsing/parser.ml" +# 28433 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 28472 "parsing/parser.ml" +# 28442 "parsing/parser.ml" in -# 2106 "parsing/parser.mly" +# 2112 "parsing/parser.mly" ( _1 ) -# 28478 "parsing/parser.ml" +# 28448 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28498,23 +28468,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 2105 "parsing/parser.mly" +# 2111 "parsing/parser.mly" ( Ppat_any ) -# 28504 "parsing/parser.ml" +# 28474 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 28512 "parsing/parser.ml" +# 28482 "parsing/parser.ml" in -# 2106 "parsing/parser.mly" +# 2112 "parsing/parser.mly" ( _1 ) -# 28518 "parsing/parser.ml" +# 28488 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28537,9 +28507,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.payload) = -# 3755 "parsing/parser.mly" +# 3771 "parsing/parser.mly" ( PStr _1 ) -# 28543 "parsing/parser.ml" +# 28513 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28569,9 +28539,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.payload) = -# 3756 "parsing/parser.mly" +# 3772 "parsing/parser.mly" ( PSig _2 ) -# 28575 "parsing/parser.ml" +# 28545 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28601,9 +28571,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.payload) = -# 3757 "parsing/parser.mly" +# 3773 "parsing/parser.mly" ( PTyp _2 ) -# 28607 "parsing/parser.ml" +# 28577 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28633,9 +28603,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.payload) = -# 3758 "parsing/parser.mly" +# 3774 "parsing/parser.mly" ( PPat (_2, None) ) -# 28639 "parsing/parser.ml" +# 28609 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28679,9 +28649,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : (Parsetree.payload) = -# 3759 "parsing/parser.mly" +# 3775 "parsing/parser.mly" ( PPat (_2, Some _4) ) -# 28685 "parsing/parser.ml" +# 28655 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28704,9 +28674,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.core_type) = -# 3158 "parsing/parser.mly" +# 3174 "parsing/parser.mly" ( _1 ) -# 28710 "parsing/parser.ml" +# 28680 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28749,24 +28719,24 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 28753 "parsing/parser.ml" +# 28723 "parsing/parser.ml" in -# 915 "parsing/parser.mly" +# 919 "parsing/parser.mly" ( xs ) -# 28758 "parsing/parser.ml" +# 28728 "parsing/parser.ml" in -# 3150 "parsing/parser.mly" +# 3166 "parsing/parser.mly" ( _1 ) -# 28764 "parsing/parser.ml" +# 28734 "parsing/parser.ml" in -# 3154 "parsing/parser.mly" +# 3170 "parsing/parser.mly" ( Ptyp_poly(_1, _3) ) -# 28770 "parsing/parser.ml" +# 28740 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos__3_, _startpos_xs_) in @@ -28774,15 +28744,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 28780 "parsing/parser.ml" +# 28750 "parsing/parser.ml" in -# 3160 "parsing/parser.mly" +# 3176 "parsing/parser.mly" ( _1 ) -# 28786 "parsing/parser.ml" +# 28756 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28805,14 +28775,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.core_type) = let _1 = -# 3189 "parsing/parser.mly" +# 3205 "parsing/parser.mly" ( _1 ) -# 28811 "parsing/parser.ml" +# 28781 "parsing/parser.ml" in -# 3158 "parsing/parser.mly" +# 3174 "parsing/parser.mly" ( _1 ) -# 28816 "parsing/parser.ml" +# 28786 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28851,33 +28821,33 @@ module Tables = struct let _v : (Parsetree.core_type) = let _1 = let _1 = let _3 = -# 3189 "parsing/parser.mly" +# 3205 "parsing/parser.mly" ( _1 ) -# 28857 "parsing/parser.ml" +# 28827 "parsing/parser.ml" in let _1 = let _1 = let xs = # 253 "" ( List.rev xs ) -# 28864 "parsing/parser.ml" +# 28834 "parsing/parser.ml" in -# 915 "parsing/parser.mly" +# 919 "parsing/parser.mly" ( xs ) -# 28869 "parsing/parser.ml" +# 28839 "parsing/parser.ml" in -# 3150 "parsing/parser.mly" +# 3166 "parsing/parser.mly" ( _1 ) -# 28875 "parsing/parser.ml" +# 28845 "parsing/parser.ml" in -# 3154 "parsing/parser.mly" +# 3170 "parsing/parser.mly" ( Ptyp_poly(_1, _3) ) -# 28881 "parsing/parser.ml" +# 28851 "parsing/parser.ml" in let _startpos__1_ = _startpos_xs_ in @@ -28885,15 +28855,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 28891 "parsing/parser.ml" +# 28861 "parsing/parser.ml" in -# 3160 "parsing/parser.mly" +# 3176 "parsing/parser.mly" ( _1 ) -# 28897 "parsing/parser.ml" +# 28867 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -28940,9 +28910,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3718 "parsing/parser.mly" +# 3734 "parsing/parser.mly" ( Attr.mk ~loc:(make_loc _sloc) _2 _3 ) -# 28946 "parsing/parser.ml" +# 28916 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29023,9 +28993,9 @@ module Tables = struct let _v : (Parsetree.value_description * string Asttypes.loc option) = let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 29029 "parsing/parser.ml" +# 28999 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -29035,30 +29005,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 29041 "parsing/parser.ml" +# 29011 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 29049 "parsing/parser.ml" +# 29019 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2806 "parsing/parser.mly" +# 2811 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Val.mk id ty ~prim ~attrs ~loc ~docs, ext ) -# 29062 "parsing/parser.ml" +# 29032 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29074,14 +29044,14 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (Asttypes.private_flag) = let _1 = -# 3586 "parsing/parser.mly" +# 3602 "parsing/parser.mly" ( Public ) -# 29080 "parsing/parser.ml" +# 29050 "parsing/parser.ml" in -# 3583 "parsing/parser.mly" +# 3599 "parsing/parser.mly" ( _1 ) -# 29085 "parsing/parser.ml" +# 29055 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29104,14 +29074,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.private_flag) = let _1 = -# 3587 "parsing/parser.mly" +# 3603 "parsing/parser.mly" ( Private ) -# 29110 "parsing/parser.ml" +# 29080 "parsing/parser.ml" in -# 3583 "parsing/parser.mly" +# 3599 "parsing/parser.mly" ( _1 ) -# 29115 "parsing/parser.ml" +# 29085 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29127,9 +29097,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (Asttypes.private_flag * Asttypes.virtual_flag) = -# 3609 "parsing/parser.mly" +# 3625 "parsing/parser.mly" ( Public, Concrete ) -# 29133 "parsing/parser.ml" +# 29103 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29152,9 +29122,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.private_flag * Asttypes.virtual_flag) = -# 3610 "parsing/parser.mly" +# 3626 "parsing/parser.mly" ( Private, Concrete ) -# 29158 "parsing/parser.ml" +# 29128 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29177,9 +29147,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.private_flag * Asttypes.virtual_flag) = -# 3611 "parsing/parser.mly" +# 3627 "parsing/parser.mly" ( Public, Virtual ) -# 29183 "parsing/parser.ml" +# 29153 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29209,9 +29179,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.private_flag * Asttypes.virtual_flag) = -# 3612 "parsing/parser.mly" +# 3628 "parsing/parser.mly" ( Private, Virtual ) -# 29215 "parsing/parser.ml" +# 29185 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29241,9 +29211,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.private_flag * Asttypes.virtual_flag) = -# 3613 "parsing/parser.mly" +# 3629 "parsing/parser.mly" ( Private, Virtual ) -# 29247 "parsing/parser.ml" +# 29217 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29259,9 +29229,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (Asttypes.rec_flag) = -# 3566 "parsing/parser.mly" +# 3582 "parsing/parser.mly" ( Nonrecursive ) -# 29265 "parsing/parser.ml" +# 29235 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29284,9 +29254,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.rec_flag) = -# 3567 "parsing/parser.mly" +# 3583 "parsing/parser.mly" ( Recursive ) -# 29290 "parsing/parser.ml" +# 29260 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29312,12 +29282,12 @@ module Tables = struct (Longident.t Asttypes.loc * Parsetree.expression) list) = let eo = # 124 "" ( None ) -# 29316 "parsing/parser.ml" +# 29286 "parsing/parser.ml" in -# 2551 "parsing/parser.mly" +# 2553 "parsing/parser.mly" ( eo, fields ) -# 29321 "parsing/parser.ml" +# 29291 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29358,18 +29328,18 @@ module Tables = struct let x = # 191 "" ( x ) -# 29362 "parsing/parser.ml" +# 29332 "parsing/parser.ml" in # 126 "" ( Some x ) -# 29367 "parsing/parser.ml" +# 29337 "parsing/parser.ml" in -# 2551 "parsing/parser.mly" +# 2553 "parsing/parser.mly" ( eo, fields ) -# 29373 "parsing/parser.ml" +# 29343 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29394,17 +29364,17 @@ module Tables = struct let _startpos = _startpos_d_ in let _endpos = _endpos_d_ in let _v : (Parsetree.constructor_declaration list) = let x = -# 2980 "parsing/parser.mly" +# 2996 "parsing/parser.mly" ( let cid, args, res, attrs, loc, info = d in Type.constructor cid ~args ?res ~attrs ~loc ~info ) -# 29403 "parsing/parser.ml" +# 29373 "parsing/parser.ml" in -# 1025 "parsing/parser.mly" +# 1029 "parsing/parser.mly" ( [x] ) -# 29408 "parsing/parser.ml" +# 29378 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29429,17 +29399,17 @@ module Tables = struct let _startpos = _startpos_d_ in let _endpos = _endpos_d_ in let _v : (Parsetree.constructor_declaration list) = let x = -# 2980 "parsing/parser.mly" +# 2996 "parsing/parser.mly" ( let cid, args, res, attrs, loc, info = d in Type.constructor cid ~args ?res ~attrs ~loc ~info ) -# 29438 "parsing/parser.ml" +# 29408 "parsing/parser.ml" in -# 1028 "parsing/parser.mly" +# 1032 "parsing/parser.mly" ( [x] ) -# 29443 "parsing/parser.ml" +# 29413 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29471,17 +29441,17 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_d_ in let _v : (Parsetree.constructor_declaration list) = let x = -# 2980 "parsing/parser.mly" +# 2996 "parsing/parser.mly" ( let cid, args, res, attrs, loc, info = d in Type.constructor cid ~args ?res ~attrs ~loc ~info ) -# 29480 "parsing/parser.ml" +# 29450 "parsing/parser.ml" in -# 1032 "parsing/parser.mly" +# 1036 "parsing/parser.mly" ( x :: xs ) -# 29485 "parsing/parser.ml" +# 29455 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29507,23 +29477,23 @@ module Tables = struct let _endpos = _endpos_d_ in let _v : (Parsetree.extension_constructor list) = let x = let _1 = -# 3092 "parsing/parser.mly" +# 3108 "parsing/parser.mly" ( let cid, args, res, attrs, loc, info = d in Te.decl cid ~args ?res ~attrs ~loc ~info ) -# 29516 "parsing/parser.ml" +# 29486 "parsing/parser.ml" in -# 3086 "parsing/parser.mly" +# 3102 "parsing/parser.mly" ( _1 ) -# 29521 "parsing/parser.ml" +# 29491 "parsing/parser.ml" in -# 1025 "parsing/parser.mly" +# 1029 "parsing/parser.mly" ( [x] ) -# 29527 "parsing/parser.ml" +# 29497 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29546,14 +29516,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.extension_constructor list) = let x = -# 3088 "parsing/parser.mly" +# 3104 "parsing/parser.mly" ( _1 ) -# 29552 "parsing/parser.ml" +# 29522 "parsing/parser.ml" in -# 1025 "parsing/parser.mly" +# 1029 "parsing/parser.mly" ( [x] ) -# 29557 "parsing/parser.ml" +# 29527 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29579,23 +29549,23 @@ module Tables = struct let _endpos = _endpos_d_ in let _v : (Parsetree.extension_constructor list) = let x = let _1 = -# 3092 "parsing/parser.mly" +# 3108 "parsing/parser.mly" ( let cid, args, res, attrs, loc, info = d in Te.decl cid ~args ?res ~attrs ~loc ~info ) -# 29588 "parsing/parser.ml" +# 29558 "parsing/parser.ml" in -# 3086 "parsing/parser.mly" +# 3102 "parsing/parser.mly" ( _1 ) -# 29593 "parsing/parser.ml" +# 29563 "parsing/parser.ml" in -# 1028 "parsing/parser.mly" +# 1032 "parsing/parser.mly" ( [x] ) -# 29599 "parsing/parser.ml" +# 29569 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29618,14 +29588,14 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.extension_constructor list) = let x = -# 3088 "parsing/parser.mly" +# 3104 "parsing/parser.mly" ( _1 ) -# 29624 "parsing/parser.ml" +# 29594 "parsing/parser.ml" in -# 1028 "parsing/parser.mly" +# 1032 "parsing/parser.mly" ( [x] ) -# 29629 "parsing/parser.ml" +# 29599 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29658,23 +29628,23 @@ module Tables = struct let _endpos = _endpos_d_ in let _v : (Parsetree.extension_constructor list) = let x = let _1 = -# 3092 "parsing/parser.mly" +# 3108 "parsing/parser.mly" ( let cid, args, res, attrs, loc, info = d in Te.decl cid ~args ?res ~attrs ~loc ~info ) -# 29667 "parsing/parser.ml" +# 29637 "parsing/parser.ml" in -# 3086 "parsing/parser.mly" +# 3102 "parsing/parser.mly" ( _1 ) -# 29672 "parsing/parser.ml" +# 29642 "parsing/parser.ml" in -# 1032 "parsing/parser.mly" +# 1036 "parsing/parser.mly" ( x :: xs ) -# 29678 "parsing/parser.ml" +# 29648 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29704,14 +29674,14 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos__1_ in let _v : (Parsetree.extension_constructor list) = let x = -# 3088 "parsing/parser.mly" +# 3104 "parsing/parser.mly" ( _1 ) -# 29710 "parsing/parser.ml" +# 29680 "parsing/parser.ml" in -# 1032 "parsing/parser.mly" +# 1036 "parsing/parser.mly" ( x :: xs ) -# 29715 "parsing/parser.ml" +# 29685 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29736,17 +29706,17 @@ module Tables = struct let _startpos = _startpos_d_ in let _endpos = _endpos_d_ in let _v : (Parsetree.extension_constructor list) = let x = -# 3092 "parsing/parser.mly" +# 3108 "parsing/parser.mly" ( let cid, args, res, attrs, loc, info = d in Te.decl cid ~args ?res ~attrs ~loc ~info ) -# 29745 "parsing/parser.ml" +# 29715 "parsing/parser.ml" in -# 1025 "parsing/parser.mly" +# 1029 "parsing/parser.mly" ( [x] ) -# 29750 "parsing/parser.ml" +# 29720 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29771,17 +29741,17 @@ module Tables = struct let _startpos = _startpos_d_ in let _endpos = _endpos_d_ in let _v : (Parsetree.extension_constructor list) = let x = -# 3092 "parsing/parser.mly" +# 3108 "parsing/parser.mly" ( let cid, args, res, attrs, loc, info = d in Te.decl cid ~args ?res ~attrs ~loc ~info ) -# 29780 "parsing/parser.ml" +# 29750 "parsing/parser.ml" in -# 1028 "parsing/parser.mly" +# 1032 "parsing/parser.mly" ( [x] ) -# 29785 "parsing/parser.ml" +# 29755 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29813,17 +29783,17 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_d_ in let _v : (Parsetree.extension_constructor list) = let x = -# 3092 "parsing/parser.mly" +# 3108 "parsing/parser.mly" ( let cid, args, res, attrs, loc, info = d in Te.decl cid ~args ?res ~attrs ~loc ~info ) -# 29822 "parsing/parser.ml" +# 29792 "parsing/parser.ml" in -# 1032 "parsing/parser.mly" +# 1036 "parsing/parser.mly" ( x :: xs ) -# 29827 "parsing/parser.ml" +# 29797 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29839,9 +29809,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : ((Parsetree.core_type * Parsetree.core_type * Ast_helper.loc) list) = -# 891 "parsing/parser.mly" +# 895 "parsing/parser.mly" ( [] ) -# 29845 "parsing/parser.ml" +# 29815 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29898,21 +29868,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1984 "parsing/parser.mly" +# 1990 "parsing/parser.mly" ( _1, _3, make_loc _sloc ) -# 29904 "parsing/parser.ml" +# 29874 "parsing/parser.ml" in # 183 "" ( x ) -# 29910 "parsing/parser.ml" +# 29880 "parsing/parser.ml" in -# 893 "parsing/parser.mly" +# 897 "parsing/parser.mly" ( x :: xs ) -# 29916 "parsing/parser.ml" +# 29886 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29930,14 +29900,14 @@ module Tables = struct MenhirLib.EngineTypes.endp = _endpos_x_; MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in - let x : (Parsetree.functor_parameter) = Obj.magic x in + let x : (Lexing.position * Parsetree.functor_parameter) = Obj.magic x in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_x_ in let _endpos = _endpos_x_ in - let _v : (Parsetree.functor_parameter list) = -# 905 "parsing/parser.mly" + let _v : ((Lexing.position * Parsetree.functor_parameter) list) = +# 909 "parsing/parser.mly" ( [ x ] ) -# 29941 "parsing/parser.ml" +# 29911 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29961,15 +29931,15 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; }; } = _menhir_stack in - let x : (Parsetree.functor_parameter) = Obj.magic x in - let xs : (Parsetree.functor_parameter list) = Obj.magic xs in + let x : (Lexing.position * Parsetree.functor_parameter) = Obj.magic x in + let xs : ((Lexing.position * Parsetree.functor_parameter) list) = Obj.magic xs in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in - let _v : (Parsetree.functor_parameter list) = -# 907 "parsing/parser.mly" + let _v : ((Lexing.position * Parsetree.functor_parameter) list) = +# 911 "parsing/parser.mly" ( x :: xs ) -# 29973 "parsing/parser.ml" +# 29943 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -29992,9 +29962,9 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos_x_ in let _v : ((Asttypes.arg_label * Parsetree.expression) list) = -# 905 "parsing/parser.mly" +# 909 "parsing/parser.mly" ( [ x ] ) -# 29998 "parsing/parser.ml" +# 29968 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30024,9 +29994,9 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in let _v : ((Asttypes.arg_label * Parsetree.expression) list) = -# 907 "parsing/parser.mly" +# 911 "parsing/parser.mly" ( x :: xs ) -# 30030 "parsing/parser.ml" +# 30000 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30049,9 +30019,9 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos_x_ in let _v : (Asttypes.label list) = -# 905 "parsing/parser.mly" +# 909 "parsing/parser.mly" ( [ x ] ) -# 30055 "parsing/parser.ml" +# 30025 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30081,9 +30051,9 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in let _v : (Asttypes.label list) = -# 907 "parsing/parser.mly" +# 911 "parsing/parser.mly" ( x :: xs ) -# 30087 "parsing/parser.ml" +# 30057 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30119,21 +30089,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 30125 "parsing/parser.ml" +# 30095 "parsing/parser.ml" in -# 3146 "parsing/parser.mly" +# 3162 "parsing/parser.mly" ( _2 ) -# 30131 "parsing/parser.ml" +# 30101 "parsing/parser.ml" in -# 905 "parsing/parser.mly" +# 909 "parsing/parser.mly" ( [ x ] ) -# 30137 "parsing/parser.ml" +# 30107 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30176,21 +30146,21 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 30182 "parsing/parser.ml" +# 30152 "parsing/parser.ml" in -# 3146 "parsing/parser.mly" +# 3162 "parsing/parser.mly" ( _2 ) -# 30188 "parsing/parser.ml" +# 30158 "parsing/parser.ml" in -# 907 "parsing/parser.mly" +# 911 "parsing/parser.mly" ( x :: xs ) -# 30194 "parsing/parser.ml" +# 30164 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30215,12 +30185,12 @@ module Tables = struct let _v : (Parsetree.case list) = let _1 = # 124 "" ( None ) -# 30219 "parsing/parser.ml" +# 30189 "parsing/parser.ml" in -# 996 "parsing/parser.mly" +# 1000 "parsing/parser.mly" ( [x] ) -# 30224 "parsing/parser.ml" +# 30194 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30254,13 +30224,13 @@ module Tables = struct # 126 "" ( Some x ) -# 30258 "parsing/parser.ml" +# 30228 "parsing/parser.ml" in -# 996 "parsing/parser.mly" +# 1000 "parsing/parser.mly" ( [x] ) -# 30264 "parsing/parser.ml" +# 30234 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30297,9 +30267,9 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in let _v : (Parsetree.case list) = -# 1000 "parsing/parser.mly" +# 1004 "parsing/parser.mly" ( x :: xs ) -# 30303 "parsing/parser.ml" +# 30273 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30323,20 +30293,20 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.core_type list) = let xs = let x = -# 3189 "parsing/parser.mly" +# 3205 "parsing/parser.mly" ( _1 ) -# 30329 "parsing/parser.ml" +# 30299 "parsing/parser.ml" in -# 931 "parsing/parser.mly" +# 935 "parsing/parser.mly" ( [ x ] ) -# 30334 "parsing/parser.ml" +# 30304 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30340 "parsing/parser.ml" +# 30310 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30374,20 +30344,20 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.core_type list) = let xs = let x = -# 3189 "parsing/parser.mly" +# 3205 "parsing/parser.mly" ( _1 ) -# 30380 "parsing/parser.ml" +# 30350 "parsing/parser.ml" in -# 935 "parsing/parser.mly" +# 939 "parsing/parser.mly" ( x :: xs ) -# 30385 "parsing/parser.ml" +# 30355 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30391 "parsing/parser.ml" +# 30361 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30410,14 +30380,14 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos_x_ in let _v : (Parsetree.with_constraint list) = let xs = -# 931 "parsing/parser.mly" +# 935 "parsing/parser.mly" ( [ x ] ) -# 30416 "parsing/parser.ml" +# 30386 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30421 "parsing/parser.ml" +# 30391 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30454,14 +30424,14 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in let _v : (Parsetree.with_constraint list) = let xs = -# 935 "parsing/parser.mly" +# 939 "parsing/parser.mly" ( x :: xs ) -# 30460 "parsing/parser.ml" +# 30430 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30465 "parsing/parser.ml" +# 30435 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30484,14 +30454,14 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos_x_ in let _v : (Parsetree.row_field list) = let xs = -# 931 "parsing/parser.mly" +# 935 "parsing/parser.mly" ( [ x ] ) -# 30490 "parsing/parser.ml" +# 30460 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30495 "parsing/parser.ml" +# 30465 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30528,14 +30498,14 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in let _v : (Parsetree.row_field list) = let xs = -# 935 "parsing/parser.mly" +# 939 "parsing/parser.mly" ( x :: xs ) -# 30534 "parsing/parser.ml" +# 30504 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30539 "parsing/parser.ml" +# 30509 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30558,14 +30528,14 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos_x_ in let _v : (Parsetree.core_type list) = let xs = -# 931 "parsing/parser.mly" +# 935 "parsing/parser.mly" ( [ x ] ) -# 30564 "parsing/parser.ml" +# 30534 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30569 "parsing/parser.ml" +# 30539 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30602,14 +30572,14 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in let _v : (Parsetree.core_type list) = let xs = -# 935 "parsing/parser.mly" +# 939 "parsing/parser.mly" ( x :: xs ) -# 30608 "parsing/parser.ml" +# 30578 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30613 "parsing/parser.ml" +# 30583 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30627,19 +30597,19 @@ module Tables = struct MenhirLib.EngineTypes.endp = _endpos_x_; MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in - let x : (Parsetree.core_type * Asttypes.variance) = Obj.magic x in + let x : (Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) = Obj.magic x in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_x_ in let _endpos = _endpos_x_ in - let _v : ((Parsetree.core_type * Asttypes.variance) list) = let xs = -# 931 "parsing/parser.mly" + let _v : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = let xs = +# 935 "parsing/parser.mly" ( [ x ] ) -# 30638 "parsing/parser.ml" +# 30608 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30643 "parsing/parser.ml" +# 30613 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30669,21 +30639,21 @@ module Tables = struct }; }; } = _menhir_stack in - let x : (Parsetree.core_type * Asttypes.variance) = Obj.magic x in + let x : (Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) = Obj.magic x in let _2 : unit = Obj.magic _2 in - let xs : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic xs in + let xs : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic xs in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in - let _v : ((Parsetree.core_type * Asttypes.variance) list) = let xs = -# 935 "parsing/parser.mly" + let _v : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = let xs = +# 939 "parsing/parser.mly" ( x :: xs ) -# 30682 "parsing/parser.ml" +# 30652 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30687 "parsing/parser.ml" +# 30657 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30706,14 +30676,14 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos_x_ in let _v : (Parsetree.core_type list) = let xs = -# 931 "parsing/parser.mly" +# 935 "parsing/parser.mly" ( [ x ] ) -# 30712 "parsing/parser.ml" +# 30682 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30717 "parsing/parser.ml" +# 30687 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30750,14 +30720,14 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in let _v : (Parsetree.core_type list) = let xs = -# 935 "parsing/parser.mly" +# 939 "parsing/parser.mly" ( x :: xs ) -# 30756 "parsing/parser.ml" +# 30726 "parsing/parser.ml" in -# 939 "parsing/parser.mly" +# 943 "parsing/parser.mly" ( xs ) -# 30761 "parsing/parser.ml" +# 30731 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30794,9 +30764,9 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in let _v : (Parsetree.core_type list) = -# 962 "parsing/parser.mly" +# 966 "parsing/parser.mly" ( x :: xs ) -# 30800 "parsing/parser.ml" +# 30770 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30833,9 +30803,9 @@ module Tables = struct let _startpos = _startpos_x1_ in let _endpos = _endpos_x2_ in let _v : (Parsetree.core_type list) = -# 966 "parsing/parser.mly" +# 970 "parsing/parser.mly" ( [ x2; x1 ] ) -# 30839 "parsing/parser.ml" +# 30809 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30872,9 +30842,9 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in let _v : (Parsetree.expression list) = -# 962 "parsing/parser.mly" +# 966 "parsing/parser.mly" ( x :: xs ) -# 30878 "parsing/parser.ml" +# 30848 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30911,9 +30881,9 @@ module Tables = struct let _startpos = _startpos_x1_ in let _endpos = _endpos_x2_ in let _v : (Parsetree.expression list) = -# 966 "parsing/parser.mly" +# 970 "parsing/parser.mly" ( [ x2; x1 ] ) -# 30917 "parsing/parser.ml" +# 30887 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30950,9 +30920,9 @@ module Tables = struct let _startpos = _startpos_xs_ in let _endpos = _endpos_x_ in let _v : (Parsetree.core_type list) = -# 962 "parsing/parser.mly" +# 966 "parsing/parser.mly" ( x :: xs ) -# 30956 "parsing/parser.ml" +# 30926 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -30989,9 +30959,9 @@ module Tables = struct let _startpos = _startpos_x1_ in let _endpos = _endpos_x2_ in let _v : (Parsetree.core_type list) = -# 966 "parsing/parser.mly" +# 970 "parsing/parser.mly" ( [ x2; x1 ] ) -# 30995 "parsing/parser.ml" +# 30965 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31014,9 +30984,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.row_field) = -# 3329 "parsing/parser.mly" +# 3345 "parsing/parser.mly" ( _1 ) -# 31020 "parsing/parser.ml" +# 30990 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31042,9 +31012,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3331 "parsing/parser.mly" +# 3347 "parsing/parser.mly" ( Rf.inherit_ ~loc:(make_loc _sloc) _1 ) -# 31048 "parsing/parser.ml" +# 31018 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31069,12 +31039,12 @@ module Tables = struct let _v : (Parsetree.expression list) = let _2 = # 124 "" ( None ) -# 31073 "parsing/parser.ml" +# 31043 "parsing/parser.ml" in -# 983 "parsing/parser.mly" +# 987 "parsing/parser.mly" ( [x] ) -# 31078 "parsing/parser.ml" +# 31048 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31108,13 +31078,13 @@ module Tables = struct # 126 "" ( Some x ) -# 31112 "parsing/parser.ml" +# 31082 "parsing/parser.ml" in -# 983 "parsing/parser.mly" +# 987 "parsing/parser.mly" ( [x] ) -# 31118 "parsing/parser.ml" +# 31088 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31151,9 +31121,9 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos_xs_ in let _v : (Parsetree.expression list) = -# 987 "parsing/parser.mly" +# 991 "parsing/parser.mly" ( x :: xs ) -# 31157 "parsing/parser.ml" +# 31127 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31179,9 +31149,9 @@ module Tables = struct } = _menhir_stack in let oe : (Parsetree.expression option) = Obj.magic oe in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 31185 "parsing/parser.ml" +# 31155 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -31189,22 +31159,22 @@ module Tables = struct let _v : ((Asttypes.label Asttypes.loc * Parsetree.expression) list) = let _2 = # 124 "" ( None ) -# 31193 "parsing/parser.ml" +# 31163 "parsing/parser.ml" in let x = let label = let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 31200 "parsing/parser.ml" +# 31170 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 31208 "parsing/parser.ml" +# 31178 "parsing/parser.ml" in let _startpos_label_ = _startpos__1_ in @@ -31212,7 +31182,7 @@ module Tables = struct let _symbolstartpos = _startpos_label_ in let _sloc = (_symbolstartpos, _endpos) in -# 2574 "parsing/parser.mly" +# 2576 "parsing/parser.mly" ( let e = match oe with | None -> @@ -31222,13 +31192,13 @@ module Tables = struct e in label, e ) -# 31226 "parsing/parser.ml" +# 31196 "parsing/parser.ml" in -# 983 "parsing/parser.mly" +# 987 "parsing/parser.mly" ( [x] ) -# 31232 "parsing/parser.ml" +# 31202 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31261,9 +31231,9 @@ module Tables = struct let x : unit = Obj.magic x in let oe : (Parsetree.expression option) = Obj.magic oe in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 31267 "parsing/parser.ml" +# 31237 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -31271,22 +31241,22 @@ module Tables = struct let _v : ((Asttypes.label Asttypes.loc * Parsetree.expression) list) = let _2 = # 126 "" ( Some x ) -# 31275 "parsing/parser.ml" +# 31245 "parsing/parser.ml" in let x = let label = let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 31282 "parsing/parser.ml" +# 31252 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 31290 "parsing/parser.ml" +# 31260 "parsing/parser.ml" in let _startpos_label_ = _startpos__1_ in @@ -31294,7 +31264,7 @@ module Tables = struct let _symbolstartpos = _startpos_label_ in let _sloc = (_symbolstartpos, _endpos) in -# 2574 "parsing/parser.mly" +# 2576 "parsing/parser.mly" ( let e = match oe with | None -> @@ -31304,13 +31274,13 @@ module Tables = struct e in label, e ) -# 31308 "parsing/parser.ml" +# 31278 "parsing/parser.ml" in -# 983 "parsing/parser.mly" +# 987 "parsing/parser.mly" ( [x] ) -# 31314 "parsing/parser.ml" +# 31284 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31350,9 +31320,9 @@ module Tables = struct let _2 : unit = Obj.magic _2 in let oe : (Parsetree.expression option) = Obj.magic oe in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 31356 "parsing/parser.ml" +# 31326 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -31360,17 +31330,17 @@ module Tables = struct let _v : ((Asttypes.label Asttypes.loc * Parsetree.expression) list) = let x = let label = let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 31366 "parsing/parser.ml" +# 31336 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 31374 "parsing/parser.ml" +# 31344 "parsing/parser.ml" in let _startpos_label_ = _startpos__1_ in @@ -31378,7 +31348,7 @@ module Tables = struct let _symbolstartpos = _startpos_label_ in let _sloc = (_symbolstartpos, _endpos) in -# 2574 "parsing/parser.mly" +# 2576 "parsing/parser.mly" ( let e = match oe with | None -> @@ -31388,13 +31358,13 @@ module Tables = struct e in label, e ) -# 31392 "parsing/parser.ml" +# 31362 "parsing/parser.ml" in -# 987 "parsing/parser.mly" +# 991 "parsing/parser.mly" ( x :: xs ) -# 31398 "parsing/parser.ml" +# 31368 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31419,12 +31389,12 @@ module Tables = struct let _v : (Parsetree.pattern list) = let _2 = # 124 "" ( None ) -# 31423 "parsing/parser.ml" +# 31393 "parsing/parser.ml" in -# 983 "parsing/parser.mly" +# 987 "parsing/parser.mly" ( [x] ) -# 31428 "parsing/parser.ml" +# 31398 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31458,13 +31428,13 @@ module Tables = struct # 126 "" ( Some x ) -# 31462 "parsing/parser.ml" +# 31432 "parsing/parser.ml" in -# 983 "parsing/parser.mly" +# 987 "parsing/parser.mly" ( [x] ) -# 31468 "parsing/parser.ml" +# 31438 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31501,9 +31471,9 @@ module Tables = struct let _startpos = _startpos_x_ in let _endpos = _endpos_xs_ in let _v : (Parsetree.pattern list) = -# 987 "parsing/parser.mly" +# 991 "parsing/parser.mly" ( x :: xs ) -# 31507 "parsing/parser.ml" +# 31477 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31542,7 +31512,7 @@ module Tables = struct let _v : ((Longident.t Asttypes.loc * Parsetree.expression) list) = let _2 = # 124 "" ( None ) -# 31546 "parsing/parser.ml" +# 31516 "parsing/parser.ml" in let x = let label = @@ -31550,9 +31520,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 31556 "parsing/parser.ml" +# 31526 "parsing/parser.ml" in let _startpos_label_ = _startpos__1_ in @@ -31560,7 +31530,7 @@ module Tables = struct let _symbolstartpos = _startpos_label_ in let _sloc = (_symbolstartpos, _endpos) in -# 2557 "parsing/parser.mly" +# 2559 "parsing/parser.mly" ( let e = match eo with | None -> @@ -31570,13 +31540,13 @@ module Tables = struct e in label, mkexp_opt_constraint ~loc:_sloc e c ) -# 31574 "parsing/parser.ml" +# 31544 "parsing/parser.ml" in -# 983 "parsing/parser.mly" +# 987 "parsing/parser.mly" ( [x] ) -# 31580 "parsing/parser.ml" +# 31550 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31622,7 +31592,7 @@ module Tables = struct let _v : ((Longident.t Asttypes.loc * Parsetree.expression) list) = let _2 = # 126 "" ( Some x ) -# 31626 "parsing/parser.ml" +# 31596 "parsing/parser.ml" in let x = let label = @@ -31630,9 +31600,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 31636 "parsing/parser.ml" +# 31606 "parsing/parser.ml" in let _startpos_label_ = _startpos__1_ in @@ -31640,7 +31610,7 @@ module Tables = struct let _symbolstartpos = _startpos_label_ in let _sloc = (_symbolstartpos, _endpos) in -# 2557 "parsing/parser.mly" +# 2559 "parsing/parser.mly" ( let e = match eo with | None -> @@ -31650,13 +31620,13 @@ module Tables = struct e in label, mkexp_opt_constraint ~loc:_sloc e c ) -# 31654 "parsing/parser.ml" +# 31624 "parsing/parser.ml" in -# 983 "parsing/parser.mly" +# 987 "parsing/parser.mly" ( [x] ) -# 31660 "parsing/parser.ml" +# 31630 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31712,9 +31682,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 31718 "parsing/parser.ml" +# 31688 "parsing/parser.ml" in let _startpos_label_ = _startpos__1_ in @@ -31722,7 +31692,7 @@ module Tables = struct let _symbolstartpos = _startpos_label_ in let _sloc = (_symbolstartpos, _endpos) in -# 2557 "parsing/parser.mly" +# 2559 "parsing/parser.mly" ( let e = match eo with | None -> @@ -31732,13 +31702,13 @@ module Tables = struct e in label, mkexp_opt_constraint ~loc:_sloc e c ) -# 31736 "parsing/parser.ml" +# 31706 "parsing/parser.ml" in -# 987 "parsing/parser.mly" +# 991 "parsing/parser.mly" ( x :: xs ) -# 31742 "parsing/parser.ml" +# 31712 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31761,9 +31731,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.expression) = -# 2073 "parsing/parser.mly" +# 2079 "parsing/parser.mly" ( _1 ) -# 31767 "parsing/parser.ml" +# 31737 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31793,9 +31763,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.expression) = -# 2074 "parsing/parser.mly" +# 2080 "parsing/parser.mly" ( _1 ) -# 31799 "parsing/parser.ml" +# 31769 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31833,24 +31803,24 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Parsetree.expression) = let _1 = let _1 = -# 2076 "parsing/parser.mly" +# 2082 "parsing/parser.mly" ( Pexp_sequence(_1, _3) ) -# 31839 "parsing/parser.ml" +# 31809 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 31848 "parsing/parser.ml" +# 31818 "parsing/parser.ml" in -# 2077 "parsing/parser.mly" +# 2083 "parsing/parser.mly" ( _1 ) -# 31854 "parsing/parser.ml" +# 31824 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31904,11 +31874,11 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2079 "parsing/parser.mly" +# 2085 "parsing/parser.mly" ( let seq = mkexp ~loc:_sloc (Pexp_sequence (_1, _5)) in let payload = PStr [mkstrexp seq []] in mkexp ~loc:_sloc (Pexp_extension (_4, payload)) ) -# 31912 "parsing/parser.ml" +# 31882 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -31975,51 +31945,53 @@ module Tables = struct let _v : (Parsetree.type_exception * string Asttypes.loc option) = let attrs = let _1 = _1_inlined4 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 31981 "parsing/parser.ml" +# 31951 "parsing/parser.ml" in let _endpos_attrs_ = _endpos__1_inlined4_ in let attrs2 = let _1 = _1_inlined3 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 31990 "parsing/parser.ml" +# 31960 "parsing/parser.ml" in + let _endpos_attrs2_ = _endpos__1_inlined3_ in let id = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 32001 "parsing/parser.ml" +# 31972 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 32009 "parsing/parser.ml" +# 31980 "parsing/parser.ml" in let _endpos = _endpos_attrs_ in + let _startpos = _startpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3010 "parsing/parser.mly" +# 3026 "parsing/parser.mly" ( let args, res = args_res in - let loc = make_loc _sloc in + let loc = make_loc (_startpos, _endpos_attrs2_) in let docs = symbol_docs _sloc in Te.mk_exception ~attrs (Te.decl id ~args ?res ~attrs:(attrs1 @ attrs2) ~loc ~docs) , ext ) -# 32023 "parsing/parser.ml" +# 31995 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32045,21 +32017,21 @@ module Tables = struct let _1 = # 260 "" ( List.flatten xss ) -# 32049 "parsing/parser.ml" +# 32021 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_xss_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 806 "parsing/parser.mly" +# 810 "parsing/parser.mly" ( extra_sig _startpos _endpos _1 ) -# 32057 "parsing/parser.ml" +# 32029 "parsing/parser.ml" in -# 1542 "parsing/parser.mly" +# 1547 "parsing/parser.mly" ( _1 ) -# 32063 "parsing/parser.ml" +# 32035 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32091,9 +32063,9 @@ module Tables = struct let _v : (Parsetree.signature_item) = let _2 = let _1 = _1_inlined1 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 32097 "parsing/parser.ml" +# 32069 "parsing/parser.ml" in let _endpos__2_ = _endpos__1_inlined1_ in @@ -32101,10 +32073,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1557 "parsing/parser.mly" +# 1562 "parsing/parser.mly" ( let docs = symbol_docs _sloc in mksig ~loc:_sloc (Psig_extension (_1, (add_docs_attrs docs _2))) ) -# 32108 "parsing/parser.ml" +# 32080 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32128,23 +32100,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.signature_item) = let _1 = let _1 = -# 1561 "parsing/parser.mly" +# 1566 "parsing/parser.mly" ( Psig_attribute _1 ) -# 32134 "parsing/parser.ml" +# 32106 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 854 "parsing/parser.mly" +# 858 "parsing/parser.mly" ( mksig ~loc:_sloc _1 ) -# 32142 "parsing/parser.ml" +# 32114 "parsing/parser.ml" in -# 1563 "parsing/parser.mly" +# 1568 "parsing/parser.mly" ( _1 ) -# 32148 "parsing/parser.ml" +# 32120 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32168,23 +32140,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.signature_item) = let _1 = let _1 = -# 1566 "parsing/parser.mly" +# 1571 "parsing/parser.mly" ( psig_value _1 ) -# 32174 "parsing/parser.ml" +# 32146 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 32182 "parsing/parser.ml" +# 32154 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 32188 "parsing/parser.ml" +# 32160 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32208,23 +32180,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.signature_item) = let _1 = let _1 = -# 1568 "parsing/parser.mly" +# 1573 "parsing/parser.mly" ( psig_value _1 ) -# 32214 "parsing/parser.ml" +# 32186 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 32222 "parsing/parser.ml" +# 32194 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 32228 "parsing/parser.ml" +# 32200 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32259,26 +32231,26 @@ module Tables = struct let _1 = let _1 = let _1 = -# 1044 "parsing/parser.mly" +# 1048 "parsing/parser.mly" ( let (x, b) = a in x, b :: bs ) -# 32265 "parsing/parser.ml" +# 32237 "parsing/parser.ml" in -# 2842 "parsing/parser.mly" +# 2847 "parsing/parser.mly" ( _1 ) -# 32270 "parsing/parser.ml" +# 32242 "parsing/parser.ml" in -# 2825 "parsing/parser.mly" +# 2830 "parsing/parser.mly" ( _1 ) -# 32276 "parsing/parser.ml" +# 32248 "parsing/parser.ml" in -# 1570 "parsing/parser.mly" +# 1575 "parsing/parser.mly" ( psig_type _1 ) -# 32282 "parsing/parser.ml" +# 32254 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_bs_, _startpos_a_) in @@ -32286,15 +32258,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 32292 "parsing/parser.ml" +# 32264 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 32298 "parsing/parser.ml" +# 32270 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32329,26 +32301,26 @@ module Tables = struct let _1 = let _1 = let _1 = -# 1044 "parsing/parser.mly" +# 1048 "parsing/parser.mly" ( let (x, b) = a in x, b :: bs ) -# 32335 "parsing/parser.ml" +# 32307 "parsing/parser.ml" in -# 2842 "parsing/parser.mly" +# 2847 "parsing/parser.mly" ( _1 ) -# 32340 "parsing/parser.ml" +# 32312 "parsing/parser.ml" in -# 2830 "parsing/parser.mly" +# 2835 "parsing/parser.mly" ( _1 ) -# 32346 "parsing/parser.ml" +# 32318 "parsing/parser.ml" in -# 1572 "parsing/parser.mly" +# 1577 "parsing/parser.mly" ( psig_typesubst _1 ) -# 32352 "parsing/parser.ml" +# 32324 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_bs_, _startpos_a_) in @@ -32356,15 +32328,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 32362 "parsing/parser.ml" +# 32334 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 32368 "parsing/parser.ml" +# 32340 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32435,7 +32407,7 @@ module Tables = struct let priv : (Asttypes.private_flag) = Obj.magic priv in let _7 : unit = Obj.magic _7 in let _1_inlined2 : (Longident.t) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in let _1 : unit = Obj.magic _1 in @@ -32449,16 +32421,16 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 32455 "parsing/parser.ml" +# 32427 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in let cs = -# 1036 "parsing/parser.mly" +# 1040 "parsing/parser.mly" ( List.rev xs ) -# 32462 "parsing/parser.ml" +# 32434 "parsing/parser.ml" in let tid = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in @@ -32466,46 +32438,46 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 32472 "parsing/parser.ml" +# 32444 "parsing/parser.ml" in let _4 = -# 3574 "parsing/parser.mly" +# 3590 "parsing/parser.mly" ( Recursive ) -# 32478 "parsing/parser.ml" +# 32450 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 32485 "parsing/parser.ml" +# 32457 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3079 "parsing/parser.mly" +# 3095 "parsing/parser.mly" ( let docs = symbol_docs _sloc in let attrs = attrs1 @ attrs2 in Te.mk tid cs ~params ~priv ~attrs ~docs, ext ) -# 32497 "parsing/parser.ml" +# 32469 "parsing/parser.ml" in -# 3066 "parsing/parser.mly" +# 3082 "parsing/parser.mly" ( _1 ) -# 32503 "parsing/parser.ml" +# 32475 "parsing/parser.ml" in -# 1574 "parsing/parser.mly" +# 1579 "parsing/parser.mly" ( psig_typext _1 ) -# 32509 "parsing/parser.ml" +# 32481 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined3_ in @@ -32513,15 +32485,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 32519 "parsing/parser.ml" +# 32491 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 32525 "parsing/parser.ml" +# 32497 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32598,7 +32570,7 @@ module Tables = struct let priv : (Asttypes.private_flag) = Obj.magic priv in let _7 : unit = Obj.magic _7 in let _1_inlined3 : (Longident.t) = Obj.magic _1_inlined3 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let _1_inlined2 : unit = Obj.magic _1_inlined2 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in @@ -32613,16 +32585,16 @@ module Tables = struct let attrs2 = let _1 = _1_inlined4 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 32619 "parsing/parser.ml" +# 32591 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined4_ in let cs = -# 1036 "parsing/parser.mly" +# 1040 "parsing/parser.mly" ( List.rev xs ) -# 32626 "parsing/parser.ml" +# 32598 "parsing/parser.ml" in let tid = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined3_, _startpos__1_inlined3_, _1_inlined3) in @@ -32630,9 +32602,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 32636 "parsing/parser.ml" +# 32608 "parsing/parser.ml" in let _4 = @@ -32641,41 +32613,41 @@ module Tables = struct let _startpos = _startpos__1_ in let _loc = (_startpos, _endpos) in -# 3575 "parsing/parser.mly" +# 3591 "parsing/parser.mly" ( not_expecting _loc "nonrec flag" ) -# 32647 "parsing/parser.ml" +# 32619 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 32655 "parsing/parser.ml" +# 32627 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3079 "parsing/parser.mly" +# 3095 "parsing/parser.mly" ( let docs = symbol_docs _sloc in let attrs = attrs1 @ attrs2 in Te.mk tid cs ~params ~priv ~attrs ~docs, ext ) -# 32667 "parsing/parser.ml" +# 32639 "parsing/parser.ml" in -# 3066 "parsing/parser.mly" +# 3082 "parsing/parser.mly" ( _1 ) -# 32673 "parsing/parser.ml" +# 32645 "parsing/parser.ml" in -# 1574 "parsing/parser.mly" +# 1579 "parsing/parser.mly" ( psig_typext _1 ) -# 32679 "parsing/parser.ml" +# 32651 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined4_ in @@ -32683,15 +32655,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 32689 "parsing/parser.ml" +# 32661 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 32695 "parsing/parser.ml" +# 32667 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32715,23 +32687,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.signature_item) = let _1 = let _1 = -# 1576 "parsing/parser.mly" +# 1581 "parsing/parser.mly" ( psig_exception _1 ) -# 32721 "parsing/parser.ml" +# 32693 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 32729 "parsing/parser.ml" +# 32701 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 32735 "parsing/parser.ml" +# 32707 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32794,9 +32766,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 32800 "parsing/parser.ml" +# 32772 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -32806,37 +32778,37 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 32812 "parsing/parser.ml" +# 32784 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 32820 "parsing/parser.ml" +# 32792 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1605 "parsing/parser.mly" +# 1610 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Md.mk name body ~attrs ~loc ~docs, ext ) -# 32834 "parsing/parser.ml" +# 32806 "parsing/parser.ml" in -# 1578 "parsing/parser.mly" +# 1583 "parsing/parser.mly" ( let (body, ext) = _1 in (Psig_module body, ext) ) -# 32840 "parsing/parser.ml" +# 32812 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined3_ in @@ -32844,15 +32816,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 32850 "parsing/parser.ml" +# 32822 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 32856 "parsing/parser.ml" +# 32828 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -32922,9 +32894,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined4 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 32928 "parsing/parser.ml" +# 32900 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined4_ in @@ -32935,9 +32907,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 32941 "parsing/parser.ml" +# 32913 "parsing/parser.ml" in let (_endpos_id_, _startpos_id_) = (_endpos__1_, _startpos__1_) in @@ -32945,9 +32917,9 @@ module Tables = struct let _symbolstartpos = _startpos_id_ in let _sloc = (_symbolstartpos, _endpos) in -# 1641 "parsing/parser.mly" +# 1647 "parsing/parser.mly" ( Mty.alias ~loc:(make_loc _sloc) id ) -# 32951 "parsing/parser.ml" +# 32923 "parsing/parser.ml" in let name = @@ -32956,37 +32928,37 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 32962 "parsing/parser.ml" +# 32934 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 32970 "parsing/parser.ml" +# 32942 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1632 "parsing/parser.mly" +# 1638 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Md.mk name body ~attrs ~loc ~docs, ext ) -# 32984 "parsing/parser.ml" +# 32956 "parsing/parser.ml" in -# 1580 "parsing/parser.mly" +# 1585 "parsing/parser.mly" ( let (body, ext) = _1 in (Psig_module body, ext) ) -# 32990 "parsing/parser.ml" +# 32962 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined4_ in @@ -32994,15 +32966,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 33000 "parsing/parser.ml" +# 32972 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 33006 "parsing/parser.ml" +# 32978 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33026,23 +32998,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.signature_item) = let _1 = let _1 = -# 1582 "parsing/parser.mly" +# 1587 "parsing/parser.mly" ( let (body, ext) = _1 in (Psig_modsubst body, ext) ) -# 33032 "parsing/parser.ml" +# 33004 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 33040 "parsing/parser.ml" +# 33012 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 33046 "parsing/parser.ml" +# 33018 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33128,9 +33100,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 33134 "parsing/parser.ml" +# 33106 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -33140,49 +33112,49 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 33146 "parsing/parser.ml" +# 33118 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 33154 "parsing/parser.ml" +# 33126 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1675 "parsing/parser.mly" +# 1681 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in ext, Md.mk name mty ~attrs ~loc ~docs ) -# 33168 "parsing/parser.ml" +# 33140 "parsing/parser.ml" in -# 1044 "parsing/parser.mly" +# 1048 "parsing/parser.mly" ( let (x, b) = a in x, b :: bs ) -# 33174 "parsing/parser.ml" +# 33146 "parsing/parser.ml" in -# 1664 "parsing/parser.mly" +# 1670 "parsing/parser.mly" ( _1 ) -# 33180 "parsing/parser.ml" +# 33152 "parsing/parser.ml" in -# 1584 "parsing/parser.mly" +# 1589 "parsing/parser.mly" ( let (ext, l) = _1 in (Psig_recmodule l, ext) ) -# 33186 "parsing/parser.ml" +# 33158 "parsing/parser.ml" in let _endpos__1_ = _endpos_bs_ in @@ -33190,15 +33162,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 33196 "parsing/parser.ml" +# 33168 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 33202 "parsing/parser.ml" +# 33174 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33222,23 +33194,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.signature_item) = let _1 = let _1 = -# 1586 "parsing/parser.mly" +# 1591 "parsing/parser.mly" ( let (body, ext) = _1 in (Psig_modtype body, ext) ) -# 33228 "parsing/parser.ml" +# 33200 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 33236 "parsing/parser.ml" +# 33208 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 33242 "parsing/parser.ml" +# 33214 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33262,23 +33234,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.signature_item) = let _1 = let _1 = -# 1588 "parsing/parser.mly" +# 1593 "parsing/parser.mly" ( let (body, ext) = _1 in (Psig_open body, ext) ) -# 33268 "parsing/parser.ml" +# 33240 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 33276 "parsing/parser.ml" +# 33248 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 33282 "parsing/parser.ml" +# 33254 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33334,38 +33306,38 @@ module Tables = struct let attrs2 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 33340 "parsing/parser.ml" +# 33312 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined2_ in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 33349 "parsing/parser.ml" +# 33321 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1434 "parsing/parser.mly" +# 1439 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Incl.mk thing ~attrs ~loc ~docs, ext ) -# 33363 "parsing/parser.ml" +# 33335 "parsing/parser.ml" in -# 1590 "parsing/parser.mly" +# 1595 "parsing/parser.mly" ( psig_include _1 ) -# 33369 "parsing/parser.ml" +# 33341 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined2_ in @@ -33373,15 +33345,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 33379 "parsing/parser.ml" +# 33351 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 33385 "parsing/parser.ml" +# 33357 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33458,11 +33430,11 @@ module Tables = struct let cty : (Parsetree.class_type) = Obj.magic cty in let _7 : unit = Obj.magic _7 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 33464 "parsing/parser.ml" +# 33436 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let virt : (Asttypes.virtual_flag) = Obj.magic virt in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in @@ -33478,9 +33450,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 33484 "parsing/parser.ml" +# 33456 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -33490,24 +33462,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 33496 "parsing/parser.ml" +# 33468 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 33504 "parsing/parser.ml" +# 33476 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2005 "parsing/parser.mly" +# 2011 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in @@ -33515,25 +33487,25 @@ module Tables = struct ext, Ci.mk id cty ~virt ~params ~attrs ~loc ~docs ) -# 33519 "parsing/parser.ml" +# 33491 "parsing/parser.ml" in -# 1044 "parsing/parser.mly" +# 1048 "parsing/parser.mly" ( let (x, b) = a in x, b :: bs ) -# 33525 "parsing/parser.ml" +# 33497 "parsing/parser.ml" in -# 1993 "parsing/parser.mly" +# 1999 "parsing/parser.mly" ( _1 ) -# 33531 "parsing/parser.ml" +# 33503 "parsing/parser.ml" in -# 1592 "parsing/parser.mly" +# 1597 "parsing/parser.mly" ( let (ext, l) = _1 in (Psig_class l, ext) ) -# 33537 "parsing/parser.ml" +# 33509 "parsing/parser.ml" in let _endpos__1_ = _endpos_bs_ in @@ -33541,15 +33513,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 33547 "parsing/parser.ml" +# 33519 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 33553 "parsing/parser.ml" +# 33525 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33573,23 +33545,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.signature_item) = let _1 = let _1 = -# 1594 "parsing/parser.mly" +# 1599 "parsing/parser.mly" ( let (ext, l) = _1 in (Psig_class_type l, ext) ) -# 33579 "parsing/parser.ml" +# 33551 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 871 "parsing/parser.mly" +# 875 "parsing/parser.mly" ( wrap_mksig_ext ~loc:_sloc _1 ) -# 33587 "parsing/parser.ml" +# 33559 "parsing/parser.ml" in -# 1596 "parsing/parser.mly" +# 1601 "parsing/parser.mly" ( _1 ) -# 33593 "parsing/parser.ml" +# 33565 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33612,9 +33584,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.constant) = -# 3405 "parsing/parser.mly" +# 3421 "parsing/parser.mly" ( _1 ) -# 33618 "parsing/parser.ml" +# 33590 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33639,18 +33611,18 @@ module Tables = struct }; } = _menhir_stack in let _2 : ( -# 633 "parsing/parser.mly" +# 637 "parsing/parser.mly" (string * char option) -# 33645 "parsing/parser.ml" +# 33617 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.constant) = -# 3406 "parsing/parser.mly" +# 3422 "parsing/parser.mly" ( let (n, m) = _2 in Pconst_integer("-" ^ n, m) ) -# 33654 "parsing/parser.ml" +# 33626 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33675,18 +33647,18 @@ module Tables = struct }; } = _menhir_stack in let _2 : ( -# 612 "parsing/parser.mly" +# 616 "parsing/parser.mly" (string * char option) -# 33681 "parsing/parser.ml" +# 33653 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.constant) = -# 3407 "parsing/parser.mly" +# 3423 "parsing/parser.mly" ( let (f, m) = _2 in Pconst_float("-" ^ f, m) ) -# 33690 "parsing/parser.ml" +# 33662 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33711,18 +33683,18 @@ module Tables = struct }; } = _menhir_stack in let _2 : ( -# 633 "parsing/parser.mly" +# 637 "parsing/parser.mly" (string * char option) -# 33717 "parsing/parser.ml" +# 33689 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.constant) = -# 3408 "parsing/parser.mly" +# 3424 "parsing/parser.mly" ( let (n, m) = _2 in Pconst_integer (n, m) ) -# 33726 "parsing/parser.ml" +# 33698 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33747,18 +33719,18 @@ module Tables = struct }; } = _menhir_stack in let _2 : ( -# 612 "parsing/parser.mly" +# 616 "parsing/parser.mly" (string * char option) -# 33753 "parsing/parser.ml" +# 33725 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.constant) = -# 3409 "parsing/parser.mly" +# 3425 "parsing/parser.mly" ( let (f, m) = _2 in Pconst_float(f, m) ) -# 33762 "parsing/parser.ml" +# 33734 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33799,18 +33771,18 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 2757 "parsing/parser.mly" +# 2759 "parsing/parser.mly" ( let fields, closed = _1 in let closed = match closed with Some () -> Open | None -> Closed in fields, closed ) -# 33807 "parsing/parser.ml" +# 33779 "parsing/parser.ml" in -# 2728 "parsing/parser.mly" +# 2730 "parsing/parser.mly" ( let (fields, closed) = _2 in Ppat_record(fields, closed) ) -# 33814 "parsing/parser.ml" +# 33786 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -33818,15 +33790,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 33824 "parsing/parser.ml" +# 33796 "parsing/parser.ml" in -# 2742 "parsing/parser.mly" +# 2744 "parsing/parser.mly" ( _1 ) -# 33830 "parsing/parser.ml" +# 33802 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33867,19 +33839,19 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 2757 "parsing/parser.mly" +# 2759 "parsing/parser.mly" ( let fields, closed = _1 in let closed = match closed with Some () -> Open | None -> Closed in fields, closed ) -# 33875 "parsing/parser.ml" +# 33847 "parsing/parser.ml" in let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2731 "parsing/parser.mly" +# 2733 "parsing/parser.mly" ( unclosed "{" _loc__1_ "}" _loc__3_ ) -# 33883 "parsing/parser.ml" +# 33855 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -33887,15 +33859,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 33893 "parsing/parser.ml" +# 33865 "parsing/parser.ml" in -# 2742 "parsing/parser.mly" +# 2744 "parsing/parser.mly" ( _1 ) -# 33899 "parsing/parser.ml" +# 33871 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33934,15 +33906,15 @@ module Tables = struct let _v : (Parsetree.pattern) = let _1 = let _1 = let _2 = -# 2751 "parsing/parser.mly" +# 2753 "parsing/parser.mly" ( ps ) -# 33940 "parsing/parser.ml" +# 33912 "parsing/parser.ml" in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2733 "parsing/parser.mly" +# 2735 "parsing/parser.mly" ( fst (mktailpat _loc__3_ _2) ) -# 33946 "parsing/parser.ml" +# 33918 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -33950,15 +33922,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 33956 "parsing/parser.ml" +# 33928 "parsing/parser.ml" in -# 2742 "parsing/parser.mly" +# 2744 "parsing/parser.mly" ( _1 ) -# 33962 "parsing/parser.ml" +# 33934 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -33997,16 +33969,16 @@ module Tables = struct let _v : (Parsetree.pattern) = let _1 = let _1 = let _2 = -# 2751 "parsing/parser.mly" +# 2753 "parsing/parser.mly" ( ps ) -# 34003 "parsing/parser.ml" +# 33975 "parsing/parser.ml" in let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2735 "parsing/parser.mly" +# 2737 "parsing/parser.mly" ( unclosed "[" _loc__1_ "]" _loc__3_ ) -# 34010 "parsing/parser.ml" +# 33982 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -34014,15 +33986,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 34020 "parsing/parser.ml" +# 33992 "parsing/parser.ml" in -# 2742 "parsing/parser.mly" +# 2744 "parsing/parser.mly" ( _1 ) -# 34026 "parsing/parser.ml" +# 33998 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34061,14 +34033,14 @@ module Tables = struct let _v : (Parsetree.pattern) = let _1 = let _1 = let _2 = -# 2751 "parsing/parser.mly" +# 2753 "parsing/parser.mly" ( ps ) -# 34067 "parsing/parser.ml" +# 34039 "parsing/parser.ml" in -# 2737 "parsing/parser.mly" +# 2739 "parsing/parser.mly" ( Ppat_array _2 ) -# 34072 "parsing/parser.ml" +# 34044 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -34076,15 +34048,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 34082 "parsing/parser.ml" +# 34054 "parsing/parser.ml" in -# 2742 "parsing/parser.mly" +# 2744 "parsing/parser.mly" ( _1 ) -# 34088 "parsing/parser.ml" +# 34060 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34115,24 +34087,24 @@ module Tables = struct let _endpos = _endpos__2_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 2739 "parsing/parser.mly" +# 2741 "parsing/parser.mly" ( Ppat_array [] ) -# 34121 "parsing/parser.ml" +# 34093 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 34130 "parsing/parser.ml" +# 34102 "parsing/parser.ml" in -# 2742 "parsing/parser.mly" +# 2744 "parsing/parser.mly" ( _1 ) -# 34136 "parsing/parser.ml" +# 34108 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34171,16 +34143,16 @@ module Tables = struct let _v : (Parsetree.pattern) = let _1 = let _1 = let _2 = -# 2751 "parsing/parser.mly" +# 2753 "parsing/parser.mly" ( ps ) -# 34177 "parsing/parser.ml" +# 34149 "parsing/parser.ml" in let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2741 "parsing/parser.mly" +# 2743 "parsing/parser.mly" ( unclosed "[|" _loc__1_ "|]" _loc__3_ ) -# 34184 "parsing/parser.ml" +# 34156 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -34188,15 +34160,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 34194 "parsing/parser.ml" +# 34166 "parsing/parser.ml" in -# 2742 "parsing/parser.mly" +# 2744 "parsing/parser.mly" ( _1 ) -# 34200 "parsing/parser.ml" +# 34172 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34236,9 +34208,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2240 "parsing/parser.mly" +# 2246 "parsing/parser.mly" ( reloc_exp ~loc:_sloc _2 ) -# 34242 "parsing/parser.ml" +# 34214 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34277,9 +34249,9 @@ module Tables = struct let _v : (Parsetree.expression) = let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2242 "parsing/parser.mly" +# 2248 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__3_ ) -# 34283 "parsing/parser.ml" +# 34255 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34326,9 +34298,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2244 "parsing/parser.mly" +# 2250 "parsing/parser.mly" ( mkexp_constraint ~loc:_sloc _2 _3 ) -# 34332 "parsing/parser.ml" +# 34304 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34382,9 +34354,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2246 "parsing/parser.mly" +# 2252 "parsing/parser.mly" ( array_get ~loc:_sloc _1 _4 ) -# 34388 "parsing/parser.ml" +# 34360 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34437,9 +34409,9 @@ module Tables = struct let _v : (Parsetree.expression) = let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2248 "parsing/parser.mly" +# 2254 "parsing/parser.mly" ( unclosed "(" _loc__3_ ")" _loc__5_ ) -# 34443 "parsing/parser.ml" +# 34415 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34493,9 +34465,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2250 "parsing/parser.mly" +# 2256 "parsing/parser.mly" ( string_get ~loc:_sloc _1 _4 ) -# 34499 "parsing/parser.ml" +# 34471 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34548,9 +34520,9 @@ module Tables = struct let _v : (Parsetree.expression) = let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2252 "parsing/parser.mly" +# 2258 "parsing/parser.mly" ( unclosed "[" _loc__3_ "]" _loc__5_ ) -# 34554 "parsing/parser.ml" +# 34526 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34596,26 +34568,26 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _3 : unit = Obj.magic _3 in let _2 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 34602 "parsing/parser.ml" +# 34574 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : (Parsetree.expression) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.expression) = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 34611 "parsing/parser.ml" +# 34583 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2254 "parsing/parser.mly" +# 2260 "parsing/parser.mly" ( dotop_get ~loc:_sloc lident bracket _2 _1 _4 ) -# 34619 "parsing/parser.ml" +# 34591 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34661,25 +34633,25 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _3 : unit = Obj.magic _3 in let _2 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 34667 "parsing/parser.ml" +# 34639 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : (Parsetree.expression) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.expression) = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 34676 "parsing/parser.ml" +# 34648 "parsing/parser.ml" in let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2256 "parsing/parser.mly" +# 2262 "parsing/parser.mly" ( unclosed "[" _loc__3_ "]" _loc__5_ ) -# 34683 "parsing/parser.ml" +# 34655 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34725,26 +34697,26 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _3 : unit = Obj.magic _3 in let _2 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 34731 "parsing/parser.ml" +# 34703 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : (Parsetree.expression) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.expression) = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 34740 "parsing/parser.ml" +# 34712 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2258 "parsing/parser.mly" +# 2264 "parsing/parser.mly" ( dotop_get ~loc:_sloc lident paren _2 _1 _4 ) -# 34748 "parsing/parser.ml" +# 34720 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34790,25 +34762,25 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _3 : unit = Obj.magic _3 in let _2 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 34796 "parsing/parser.ml" +# 34768 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : (Parsetree.expression) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.expression) = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 34805 "parsing/parser.ml" +# 34777 "parsing/parser.ml" in let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2260 "parsing/parser.mly" +# 2266 "parsing/parser.mly" ( unclosed "(" _loc__3_ ")" _loc__5_ ) -# 34812 "parsing/parser.ml" +# 34784 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34854,26 +34826,26 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _3 : unit = Obj.magic _3 in let _2 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 34860 "parsing/parser.ml" +# 34832 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : (Parsetree.expression) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.expression) = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 34869 "parsing/parser.ml" +# 34841 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2262 "parsing/parser.mly" +# 2268 "parsing/parser.mly" ( dotop_get ~loc:_sloc lident brace _2 _1 _4 ) -# 34877 "parsing/parser.ml" +# 34849 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34919,9 +34891,9 @@ module Tables = struct let _4 : (Parsetree.expression) = Obj.magic _4 in let _3 : unit = Obj.magic _3 in let _2 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 34925 "parsing/parser.ml" +# 34897 "parsing/parser.ml" ) = Obj.magic _2 in let _1 : (Parsetree.expression) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -34930,9 +34902,9 @@ module Tables = struct let _v : (Parsetree.expression) = let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2264 "parsing/parser.mly" +# 2270 "parsing/parser.mly" ( unclosed "{" _loc__3_ "}" _loc__5_ ) -# 34936 "parsing/parser.ml" +# 34908 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -34990,9 +34962,9 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _5 : unit = Obj.magic _5 in let _4 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 34996 "parsing/parser.ml" +# 34968 "parsing/parser.ml" ) = Obj.magic _4 in let _3 : (Longident.t) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in @@ -35001,17 +34973,17 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__7_ in let _v : (Parsetree.expression) = let _6 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 35007 "parsing/parser.ml" +# 34979 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2266 "parsing/parser.mly" +# 2272 "parsing/parser.mly" ( dotop_get ~loc:_sloc (ldot _3) bracket _4 _1 _6 ) -# 35015 "parsing/parser.ml" +# 34987 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35069,9 +35041,9 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _5 : unit = Obj.magic _5 in let _4 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 35075 "parsing/parser.ml" +# 35047 "parsing/parser.ml" ) = Obj.magic _4 in let _3 : (Longident.t) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in @@ -35080,16 +35052,16 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__7_ in let _v : (Parsetree.expression) = let _6 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 35086 "parsing/parser.ml" +# 35058 "parsing/parser.ml" in let _loc__7_ = (_startpos__7_, _endpos__7_) in let _loc__5_ = (_startpos__5_, _endpos__5_) in -# 2269 "parsing/parser.mly" +# 2275 "parsing/parser.mly" ( unclosed "[" _loc__5_ "]" _loc__7_ ) -# 35093 "parsing/parser.ml" +# 35065 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35147,9 +35119,9 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _5 : unit = Obj.magic _5 in let _4 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 35153 "parsing/parser.ml" +# 35125 "parsing/parser.ml" ) = Obj.magic _4 in let _3 : (Longident.t) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in @@ -35158,17 +35130,17 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__7_ in let _v : (Parsetree.expression) = let _6 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 35164 "parsing/parser.ml" +# 35136 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2271 "parsing/parser.mly" +# 2277 "parsing/parser.mly" ( dotop_get ~loc:_sloc (ldot _3) paren _4 _1 _6 ) -# 35172 "parsing/parser.ml" +# 35144 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35226,9 +35198,9 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _5 : unit = Obj.magic _5 in let _4 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 35232 "parsing/parser.ml" +# 35204 "parsing/parser.ml" ) = Obj.magic _4 in let _3 : (Longident.t) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in @@ -35237,16 +35209,16 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__7_ in let _v : (Parsetree.expression) = let _6 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 35243 "parsing/parser.ml" +# 35215 "parsing/parser.ml" in let _loc__7_ = (_startpos__7_, _endpos__7_) in let _loc__5_ = (_startpos__5_, _endpos__5_) in -# 2274 "parsing/parser.mly" +# 2280 "parsing/parser.mly" ( unclosed "(" _loc__5_ ")" _loc__7_ ) -# 35250 "parsing/parser.ml" +# 35222 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35304,9 +35276,9 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _5 : unit = Obj.magic _5 in let _4 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 35310 "parsing/parser.ml" +# 35282 "parsing/parser.ml" ) = Obj.magic _4 in let _3 : (Longident.t) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in @@ -35315,17 +35287,17 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__7_ in let _v : (Parsetree.expression) = let _6 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 35321 "parsing/parser.ml" +# 35293 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2276 "parsing/parser.mly" +# 2282 "parsing/parser.mly" ( dotop_get ~loc:_sloc (ldot _3) brace _4 _1 _6 ) -# 35329 "parsing/parser.ml" +# 35301 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35383,9 +35355,9 @@ module Tables = struct let es : (Parsetree.expression list) = Obj.magic es in let _5 : unit = Obj.magic _5 in let _4 : ( -# 628 "parsing/parser.mly" +# 632 "parsing/parser.mly" (string) -# 35389 "parsing/parser.ml" +# 35361 "parsing/parser.ml" ) = Obj.magic _4 in let _3 : (Longident.t) = Obj.magic _3 in let _2 : unit = Obj.magic _2 in @@ -35394,16 +35366,16 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__7_ in let _v : (Parsetree.expression) = let _6 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 35400 "parsing/parser.ml" +# 35372 "parsing/parser.ml" in let _loc__7_ = (_startpos__7_, _endpos__7_) in let _loc__5_ = (_startpos__5_, _endpos__5_) in -# 2279 "parsing/parser.mly" +# 2285 "parsing/parser.mly" ( unclosed "{" _loc__5_ "}" _loc__7_ ) -# 35407 "parsing/parser.ml" +# 35379 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35457,9 +35429,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2281 "parsing/parser.mly" +# 2287 "parsing/parser.mly" ( bigarray_get ~loc:_sloc _1 _4 ) -# 35463 "parsing/parser.ml" +# 35435 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35512,9 +35484,9 @@ module Tables = struct let _v : (Parsetree.expression) = let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2283 "parsing/parser.mly" +# 2289 "parsing/parser.mly" ( unclosed "{" _loc__3_ "}" _loc__5_ ) -# 35518 "parsing/parser.ml" +# 35490 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35568,15 +35540,15 @@ module Tables = struct let attrs = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 35574 "parsing/parser.ml" +# 35546 "parsing/parser.ml" in -# 2292 "parsing/parser.mly" +# 2298 "parsing/parser.mly" ( e.pexp_desc, (ext, attrs @ e.pexp_attributes) ) -# 35580 "parsing/parser.ml" +# 35552 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -35584,10 +35556,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2285 "parsing/parser.mly" +# 2291 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 35591 "parsing/parser.ml" +# 35563 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35636,24 +35608,24 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 35642 "parsing/parser.ml" +# 35614 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 35648 "parsing/parser.ml" +# 35620 "parsing/parser.ml" in let _endpos = _endpos__3_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2294 "parsing/parser.mly" +# 2300 "parsing/parser.mly" ( Pexp_construct (mkloc (Lident "()") (make_loc _sloc), None), _2 ) -# 35657 "parsing/parser.ml" +# 35629 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -35661,10 +35633,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2285 "parsing/parser.mly" +# 2291 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 35668 "parsing/parser.ml" +# 35640 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35720,23 +35692,23 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 35726 "parsing/parser.ml" +# 35698 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 35732 "parsing/parser.ml" +# 35704 "parsing/parser.ml" in let _loc__4_ = (_startpos__4_, _endpos__4_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2296 "parsing/parser.mly" +# 2302 "parsing/parser.mly" ( unclosed "begin" _loc__1_ "end" _loc__4_ ) -# 35740 "parsing/parser.ml" +# 35712 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -35744,10 +35716,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2285 "parsing/parser.mly" +# 2291 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 35751 "parsing/parser.ml" +# 35723 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35797,9 +35769,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 35803 "parsing/parser.ml" +# 35775 "parsing/parser.ml" in let _2 = @@ -35807,21 +35779,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 35813 "parsing/parser.ml" +# 35785 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 35819 "parsing/parser.ml" +# 35791 "parsing/parser.ml" in -# 2298 "parsing/parser.mly" +# 2304 "parsing/parser.mly" ( Pexp_new(_3), _2 ) -# 35825 "parsing/parser.ml" +# 35797 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined3_ in @@ -35829,10 +35801,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2285 "parsing/parser.mly" +# 2291 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 35836 "parsing/parser.ml" +# 35808 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35895,21 +35867,21 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 35901 "parsing/parser.ml" +# 35873 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 35907 "parsing/parser.ml" +# 35879 "parsing/parser.ml" in -# 2300 "parsing/parser.mly" +# 2306 "parsing/parser.mly" ( Pexp_pack _4, _3 ) -# 35913 "parsing/parser.ml" +# 35885 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -35917,10 +35889,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2285 "parsing/parser.mly" +# 2291 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 35924 "parsing/parser.ml" +# 35896 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -35994,25 +35966,15 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _6 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined3_, _startpos__1_inlined3_, _1_inlined3) in - let _1 = - let _1 = -# 3320 "parsing/parser.mly" - ( Ptyp_package (package_type_of_module_type _1) ) -# 36002 "parsing/parser.ml" - in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 850 "parsing/parser.mly" - ( mktyp ~loc:_sloc _1 ) -# 36010 "parsing/parser.ml" - - in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in -# 3321 "parsing/parser.mly" - ( _1 ) -# 36016 "parsing/parser.ml" +# 3335 "parsing/parser.mly" + ( let (lid, cstrs, attrs) = package_type_of_module_type _1 in + let descr = Ptyp_package (lid, cstrs) in + mktyp ~loc:_sloc ~attrs descr ) +# 35978 "parsing/parser.ml" in let _3 = @@ -36020,24 +35982,24 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 36026 "parsing/parser.ml" +# 35988 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 36032 "parsing/parser.ml" +# 35994 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2302 "parsing/parser.mly" +# 2308 "parsing/parser.mly" ( Pexp_constraint (ghexp ~loc:_sloc (Pexp_pack _4), _6), _3 ) -# 36041 "parsing/parser.ml" +# 36003 "parsing/parser.ml" in let _endpos__1_ = _endpos__7_ in @@ -36045,10 +36007,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2285 "parsing/parser.mly" +# 2291 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 36052 "parsing/parser.ml" +# 36014 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36118,23 +36080,23 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 36124 "parsing/parser.ml" +# 36086 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 36130 "parsing/parser.ml" +# 36092 "parsing/parser.ml" in let _loc__6_ = (_startpos__6_, _endpos__6_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2304 "parsing/parser.mly" +# 2310 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__6_ ) -# 36138 "parsing/parser.ml" +# 36100 "parsing/parser.ml" in let _endpos__1_ = _endpos__6_ in @@ -36142,10 +36104,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2285 "parsing/parser.mly" +# 2291 "parsing/parser.mly" ( let desc, attrs = _1 in mkexp_attrs ~loc:_sloc desc attrs ) -# 36149 "parsing/parser.ml" +# 36111 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36174,30 +36136,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 36180 "parsing/parser.ml" +# 36142 "parsing/parser.ml" in -# 2308 "parsing/parser.mly" +# 2314 "parsing/parser.mly" ( Pexp_ident (_1) ) -# 36186 "parsing/parser.ml" +# 36148 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36195 "parsing/parser.ml" +# 36157 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36201 "parsing/parser.ml" +# 36163 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36221,23 +36183,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.expression) = let _1 = let _1 = -# 2310 "parsing/parser.mly" +# 2316 "parsing/parser.mly" ( Pexp_constant _1 ) -# 36227 "parsing/parser.ml" +# 36189 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36235 "parsing/parser.ml" +# 36197 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36241 "parsing/parser.ml" +# 36203 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36266,30 +36228,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 36272 "parsing/parser.ml" +# 36234 "parsing/parser.ml" in -# 2312 "parsing/parser.mly" +# 2318 "parsing/parser.mly" ( Pexp_construct(_1, None) ) -# 36278 "parsing/parser.ml" +# 36240 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36287 "parsing/parser.ml" +# 36249 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36293 "parsing/parser.ml" +# 36255 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36313,23 +36275,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.expression) = let _1 = let _1 = -# 2314 "parsing/parser.mly" +# 2320 "parsing/parser.mly" ( Pexp_variant(_1, None) ) -# 36319 "parsing/parser.ml" +# 36281 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36327 "parsing/parser.ml" +# 36289 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36333 "parsing/parser.ml" +# 36295 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36355,9 +36317,9 @@ module Tables = struct } = _menhir_stack in let _2 : (Parsetree.expression) = Obj.magic _2 in let _1 : ( -# 671 "parsing/parser.mly" +# 675 "parsing/parser.mly" (string) -# 36361 "parsing/parser.ml" +# 36323 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -36369,15 +36331,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 36375 "parsing/parser.ml" +# 36337 "parsing/parser.ml" in -# 2316 "parsing/parser.mly" +# 2322 "parsing/parser.mly" ( Pexp_apply(_1, [Nolabel,_2]) ) -# 36381 "parsing/parser.ml" +# 36343 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in @@ -36385,15 +36347,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36391 "parsing/parser.ml" +# 36353 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36397 "parsing/parser.ml" +# 36359 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36426,23 +36388,23 @@ module Tables = struct let _1 = let _1 = let _1 = -# 2317 "parsing/parser.mly" +# 2323 "parsing/parser.mly" ("!") -# 36432 "parsing/parser.ml" +# 36394 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 36440 "parsing/parser.ml" +# 36402 "parsing/parser.ml" in -# 2318 "parsing/parser.mly" +# 2324 "parsing/parser.mly" ( Pexp_apply(_1, [Nolabel,_2]) ) -# 36446 "parsing/parser.ml" +# 36408 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in @@ -36450,15 +36412,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36456 "parsing/parser.ml" +# 36418 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36462 "parsing/parser.ml" +# 36424 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36497,14 +36459,14 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _2 = -# 2569 "parsing/parser.mly" +# 2571 "parsing/parser.mly" ( xs ) -# 36503 "parsing/parser.ml" +# 36465 "parsing/parser.ml" in -# 2320 "parsing/parser.mly" +# 2326 "parsing/parser.mly" ( Pexp_override _2 ) -# 36508 "parsing/parser.ml" +# 36470 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -36512,15 +36474,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36518 "parsing/parser.ml" +# 36480 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36524 "parsing/parser.ml" +# 36486 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36559,16 +36521,16 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _2 = -# 2569 "parsing/parser.mly" +# 2571 "parsing/parser.mly" ( xs ) -# 36565 "parsing/parser.ml" +# 36527 "parsing/parser.ml" in let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2322 "parsing/parser.mly" +# 2328 "parsing/parser.mly" ( unclosed "{<" _loc__1_ ">}" _loc__3_ ) -# 36572 "parsing/parser.ml" +# 36534 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -36576,15 +36538,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36582 "parsing/parser.ml" +# 36544 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36588 "parsing/parser.ml" +# 36550 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36615,24 +36577,24 @@ module Tables = struct let _endpos = _endpos__2_ in let _v : (Parsetree.expression) = let _1 = let _1 = -# 2324 "parsing/parser.mly" +# 2330 "parsing/parser.mly" ( Pexp_override [] ) -# 36621 "parsing/parser.ml" +# 36583 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36630 "parsing/parser.ml" +# 36592 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36636 "parsing/parser.ml" +# 36598 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36676,15 +36638,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 36682 "parsing/parser.ml" +# 36644 "parsing/parser.ml" in -# 2326 "parsing/parser.mly" +# 2332 "parsing/parser.mly" ( Pexp_field(_1, _3) ) -# 36688 "parsing/parser.ml" +# 36650 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined1_ in @@ -36692,15 +36654,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36698 "parsing/parser.ml" +# 36660 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36704 "parsing/parser.ml" +# 36666 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36758,24 +36720,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 36764 "parsing/parser.ml" +# 36726 "parsing/parser.ml" in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1493 "parsing/parser.mly" +# 1498 "parsing/parser.mly" ( let loc = make_loc _loc__1_ in let me = Mod.ident ~loc _1 in Opn.mk ~loc me ) -# 36773 "parsing/parser.ml" +# 36735 "parsing/parser.ml" in -# 2328 "parsing/parser.mly" +# 2334 "parsing/parser.mly" ( Pexp_open(od, _4) ) -# 36779 "parsing/parser.ml" +# 36741 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -36783,15 +36745,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36789 "parsing/parser.ml" +# 36751 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36795 "parsing/parser.ml" +# 36757 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36844,9 +36806,9 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _4 = -# 2569 "parsing/parser.mly" +# 2571 "parsing/parser.mly" ( xs ) -# 36850 "parsing/parser.ml" +# 36812 "parsing/parser.ml" in let od = let _1 = @@ -36854,18 +36816,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 36860 "parsing/parser.ml" +# 36822 "parsing/parser.ml" in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1493 "parsing/parser.mly" +# 1498 "parsing/parser.mly" ( let loc = make_loc _loc__1_ in let me = Mod.ident ~loc _1 in Opn.mk ~loc me ) -# 36869 "parsing/parser.ml" +# 36831 "parsing/parser.ml" in let _startpos_od_ = _startpos__1_ in @@ -36873,10 +36835,10 @@ module Tables = struct let _symbolstartpos = _startpos_od_ in let _sloc = (_symbolstartpos, _endpos) in -# 2330 "parsing/parser.mly" +# 2336 "parsing/parser.mly" ( (* TODO: review the location of Pexp_override *) Pexp_open(od, mkexp ~loc:_sloc (Pexp_override _4)) ) -# 36880 "parsing/parser.ml" +# 36842 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -36884,15 +36846,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36890 "parsing/parser.ml" +# 36852 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36896 "parsing/parser.ml" +# 36858 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -36945,16 +36907,16 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _4 = -# 2569 "parsing/parser.mly" +# 2571 "parsing/parser.mly" ( xs ) -# 36951 "parsing/parser.ml" +# 36913 "parsing/parser.ml" in let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2333 "parsing/parser.mly" +# 2339 "parsing/parser.mly" ( unclosed "{<" _loc__3_ ">}" _loc__5_ ) -# 36958 "parsing/parser.ml" +# 36920 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -36962,15 +36924,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 36968 "parsing/parser.ml" +# 36930 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 36974 "parsing/parser.ml" +# 36936 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37001,9 +36963,9 @@ module Tables = struct }; } = _menhir_stack in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 37007 "parsing/parser.ml" +# 36969 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _2 : unit = Obj.magic _2 in let _1 : (Parsetree.expression) = Obj.magic _1 in @@ -37015,23 +36977,23 @@ module Tables = struct let _3 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 37021 "parsing/parser.ml" +# 36983 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 37029 "parsing/parser.ml" +# 36991 "parsing/parser.ml" in -# 2335 "parsing/parser.mly" +# 2341 "parsing/parser.mly" ( Pexp_send(_1, _3) ) -# 37035 "parsing/parser.ml" +# 36997 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined1_ in @@ -37039,15 +37001,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37045 "parsing/parser.ml" +# 37007 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37051 "parsing/parser.ml" +# 37013 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37079,9 +37041,9 @@ module Tables = struct } = _menhir_stack in let _3 : (Parsetree.expression) = Obj.magic _3 in let _1_inlined1 : ( -# 682 "parsing/parser.mly" +# 686 "parsing/parser.mly" (string) -# 37085 "parsing/parser.ml" +# 37047 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _1 : (Parsetree.expression) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in @@ -37095,15 +37057,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 840 "parsing/parser.mly" +# 844 "parsing/parser.mly" ( mkoperator ~loc:_sloc _1 ) -# 37101 "parsing/parser.ml" +# 37063 "parsing/parser.ml" in -# 2337 "parsing/parser.mly" +# 2343 "parsing/parser.mly" ( mkinfix _1 _2 _3 ) -# 37107 "parsing/parser.ml" +# 37069 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -37111,15 +37073,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37117 "parsing/parser.ml" +# 37079 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37123 "parsing/parser.ml" +# 37085 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37143,23 +37105,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.expression) = let _1 = let _1 = -# 2339 "parsing/parser.mly" +# 2345 "parsing/parser.mly" ( Pexp_extension _1 ) -# 37149 "parsing/parser.ml" +# 37111 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37157 "parsing/parser.ml" +# 37119 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37163 "parsing/parser.ml" +# 37125 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37207,50 +37169,46 @@ module Tables = struct let _3 = let (_endpos__2_, _startpos__1_, _2, _1) = (_endpos__2_inlined1_, _startpos__1_inlined1_, _2_inlined1, _1_inlined1) in let _1 = -# 2340 "parsing/parser.mly" +# 2346 "parsing/parser.mly" (Lident "()") -# 37213 "parsing/parser.ml" +# 37175 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 37222 "parsing/parser.ml" +# 37184 "parsing/parser.ml" in - let _endpos__3_ = _endpos__2_inlined1_ in + let (_endpos__3_, _startpos__3_) = (_endpos__2_inlined1_, _startpos__1_inlined1_) in let od = let _1 = let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 37234 "parsing/parser.ml" +# 37196 "parsing/parser.ml" in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1493 "parsing/parser.mly" +# 1498 "parsing/parser.mly" ( let loc = make_loc _loc__1_ in let me = Mod.ident ~loc _1 in Opn.mk ~loc me ) -# 37243 "parsing/parser.ml" +# 37205 "parsing/parser.ml" in - let _startpos_od_ = _startpos__1_ in - let _endpos = _endpos__3_ in - let _symbolstartpos = _startpos_od_ in - let _sloc = (_symbolstartpos, _endpos) in + let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2341 "parsing/parser.mly" - ( (* TODO: review the location of Pexp_construct *) - Pexp_open(od, mkexp ~loc:_sloc (Pexp_construct(_3, None))) ) -# 37254 "parsing/parser.ml" +# 2347 "parsing/parser.mly" + ( Pexp_open(od, mkexp ~loc:(_loc__3_) (Pexp_construct(_3, None))) ) +# 37212 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_inlined1_ in @@ -37258,15 +37216,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37264 "parsing/parser.ml" +# 37222 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37270 "parsing/parser.ml" +# 37228 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37321,9 +37279,9 @@ module Tables = struct let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2344 "parsing/parser.mly" +# 2349 "parsing/parser.mly" ( unclosed "(" _loc__3_ ")" _loc__5_ ) -# 37327 "parsing/parser.ml" +# 37285 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -37331,15 +37289,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37337 "parsing/parser.ml" +# 37295 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37343 "parsing/parser.ml" +# 37301 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37378,25 +37336,25 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Parsetree.expression) = let _1 = let _1 = -# 2346 "parsing/parser.mly" +# 2351 "parsing/parser.mly" ( let (exten, fields) = _2 in Pexp_record(fields, exten) ) -# 37385 "parsing/parser.ml" +# 37343 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37394 "parsing/parser.ml" +# 37352 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37400 "parsing/parser.ml" +# 37358 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37438,9 +37396,9 @@ module Tables = struct let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2349 "parsing/parser.mly" +# 2354 "parsing/parser.mly" ( unclosed "{" _loc__1_ "}" _loc__3_ ) -# 37444 "parsing/parser.ml" +# 37402 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -37448,15 +37406,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37454 "parsing/parser.ml" +# 37412 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37460 "parsing/parser.ml" +# 37418 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37515,30 +37473,27 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 37521 "parsing/parser.ml" +# 37479 "parsing/parser.ml" in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1493 "parsing/parser.mly" +# 1498 "parsing/parser.mly" ( let loc = make_loc _loc__1_ in let me = Mod.ident ~loc _1 in Opn.mk ~loc me ) -# 37530 "parsing/parser.ml" +# 37488 "parsing/parser.ml" in - let _startpos_od_ = _startpos__1_ in let _endpos = _endpos__5_ in - let _symbolstartpos = _startpos_od_ in - let _sloc = (_symbolstartpos, _endpos) in -# 2351 "parsing/parser.mly" +# 2356 "parsing/parser.mly" ( let (exten, fields) = _4 in - (* TODO: review the location of Pexp_construct *) - Pexp_open(od, mkexp ~loc:_sloc (Pexp_record(fields, exten))) ) -# 37542 "parsing/parser.ml" + Pexp_open(od, mkexp ~loc:(_startpos__3_, _endpos) + (Pexp_record(fields, exten))) ) +# 37497 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -37546,15 +37501,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37552 "parsing/parser.ml" +# 37507 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37558 "parsing/parser.ml" +# 37513 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37610,9 +37565,9 @@ module Tables = struct let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2355 "parsing/parser.mly" +# 2360 "parsing/parser.mly" ( unclosed "{" _loc__3_ "}" _loc__5_ ) -# 37616 "parsing/parser.ml" +# 37571 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -37620,15 +37575,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37626 "parsing/parser.ml" +# 37581 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37632 "parsing/parser.ml" +# 37587 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37667,14 +37622,14 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _2 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 37673 "parsing/parser.ml" +# 37628 "parsing/parser.ml" in -# 2357 "parsing/parser.mly" +# 2362 "parsing/parser.mly" ( Pexp_array(_2) ) -# 37678 "parsing/parser.ml" +# 37633 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -37682,15 +37637,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37688 "parsing/parser.ml" +# 37643 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37694 "parsing/parser.ml" +# 37649 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37729,16 +37684,16 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _2 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 37735 "parsing/parser.ml" +# 37690 "parsing/parser.ml" in let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2359 "parsing/parser.mly" +# 2364 "parsing/parser.mly" ( unclosed "[|" _loc__1_ "|]" _loc__3_ ) -# 37742 "parsing/parser.ml" +# 37697 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -37746,15 +37701,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37752 "parsing/parser.ml" +# 37707 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37758 "parsing/parser.ml" +# 37713 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37785,24 +37740,24 @@ module Tables = struct let _endpos = _endpos__2_ in let _v : (Parsetree.expression) = let _1 = let _1 = -# 2361 "parsing/parser.mly" +# 2366 "parsing/parser.mly" ( Pexp_array [] ) -# 37791 "parsing/parser.ml" +# 37746 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37800 "parsing/parser.ml" +# 37755 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37806 "parsing/parser.ml" +# 37761 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37855,9 +37810,9 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 37861 "parsing/parser.ml" +# 37816 "parsing/parser.ml" in let od = let _1 = @@ -37865,29 +37820,25 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 37871 "parsing/parser.ml" +# 37826 "parsing/parser.ml" in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1493 "parsing/parser.mly" +# 1498 "parsing/parser.mly" ( let loc = make_loc _loc__1_ in let me = Mod.ident ~loc _1 in Opn.mk ~loc me ) -# 37880 "parsing/parser.ml" +# 37835 "parsing/parser.ml" in - let _startpos_od_ = _startpos__1_ in let _endpos = _endpos__5_ in - let _symbolstartpos = _startpos_od_ in - let _sloc = (_symbolstartpos, _endpos) in -# 2363 "parsing/parser.mly" - ( (* TODO: review the location of Pexp_array *) - Pexp_open(od, mkexp ~loc:_sloc (Pexp_array(_4))) ) -# 37891 "parsing/parser.ml" +# 2368 "parsing/parser.mly" + ( Pexp_open(od, mkexp ~loc:(_startpos__3_, _endpos) (Pexp_array(_4))) ) +# 37842 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -37895,15 +37846,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37901 "parsing/parser.ml" +# 37852 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37907 "parsing/parser.ml" +# 37858 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -37954,29 +37905,26 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 37960 "parsing/parser.ml" +# 37911 "parsing/parser.ml" in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1493 "parsing/parser.mly" +# 1498 "parsing/parser.mly" ( let loc = make_loc _loc__1_ in let me = Mod.ident ~loc _1 in Opn.mk ~loc me ) -# 37969 "parsing/parser.ml" +# 37920 "parsing/parser.ml" in - let _startpos_od_ = _startpos__1_ in let _endpos = _endpos__4_ in - let _symbolstartpos = _startpos_od_ in - let _sloc = (_symbolstartpos, _endpos) in -# 2366 "parsing/parser.mly" +# 2370 "parsing/parser.mly" ( (* TODO: review the location of Pexp_array *) - Pexp_open(od, mkexp ~loc:_sloc (Pexp_array [])) ) -# 37980 "parsing/parser.ml" + Pexp_open(od, mkexp ~loc:(_startpos__3_, _endpos) (Pexp_array [])) ) +# 37928 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -37984,15 +37932,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 37990 "parsing/parser.ml" +# 37938 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 37996 "parsing/parser.ml" +# 37944 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38045,16 +37993,16 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 38051 "parsing/parser.ml" +# 37999 "parsing/parser.ml" in let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2370 "parsing/parser.mly" +# 2374 "parsing/parser.mly" ( unclosed "[|" _loc__3_ "|]" _loc__5_ ) -# 38058 "parsing/parser.ml" +# 38006 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -38062,15 +38010,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 38068 "parsing/parser.ml" +# 38016 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 38074 "parsing/parser.ml" +# 38022 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38109,15 +38057,15 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _2 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 38115 "parsing/parser.ml" +# 38063 "parsing/parser.ml" in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2372 "parsing/parser.mly" +# 2376 "parsing/parser.mly" ( fst (mktailexp _loc__3_ _2) ) -# 38121 "parsing/parser.ml" +# 38069 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -38125,15 +38073,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 38131 "parsing/parser.ml" +# 38079 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 38137 "parsing/parser.ml" +# 38085 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38172,16 +38120,16 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _2 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 38178 "parsing/parser.ml" +# 38126 "parsing/parser.ml" in let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2374 "parsing/parser.mly" +# 2378 "parsing/parser.mly" ( unclosed "[" _loc__1_ "]" _loc__3_ ) -# 38185 "parsing/parser.ml" +# 38133 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -38189,15 +38137,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 38195 "parsing/parser.ml" +# 38143 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 38201 "parsing/parser.ml" +# 38149 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38250,9 +38198,9 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 38256 "parsing/parser.ml" +# 38204 "parsing/parser.ml" in let od = let _1 = @@ -38260,33 +38208,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 38266 "parsing/parser.ml" +# 38214 "parsing/parser.ml" in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1493 "parsing/parser.mly" +# 1498 "parsing/parser.mly" ( let loc = make_loc _loc__1_ in let me = Mod.ident ~loc _1 in Opn.mk ~loc me ) -# 38275 "parsing/parser.ml" +# 38223 "parsing/parser.ml" in - let _startpos_od_ = _startpos__1_ in let _endpos = _endpos__5_ in - let _symbolstartpos = _startpos_od_ in let _loc__5_ = (_startpos__5_, _endpos__5_) in - let _sloc = (_symbolstartpos, _endpos) in -# 2376 "parsing/parser.mly" +# 2380 "parsing/parser.mly" ( let list_exp = (* TODO: review the location of list_exp *) let tail_exp, _tail_loc = mktailexp _loc__5_ _4 in - mkexp ~loc:_sloc tail_exp in + mkexp ~loc:(_startpos__3_, _endpos) tail_exp in Pexp_open(od, list_exp) ) -# 38290 "parsing/parser.ml" +# 38235 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -38294,15 +38239,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 38300 "parsing/parser.ml" +# 38245 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 38306 "parsing/parser.ml" +# 38251 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38350,50 +38295,46 @@ module Tables = struct let _3 = let (_endpos__2_, _startpos__1_, _2, _1) = (_endpos__2_inlined1_, _startpos__1_inlined1_, _2_inlined1, _1_inlined1) in let _1 = -# 2381 "parsing/parser.mly" +# 2385 "parsing/parser.mly" (Lident "[]") -# 38356 "parsing/parser.ml" +# 38301 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 38365 "parsing/parser.ml" +# 38310 "parsing/parser.ml" in - let _endpos__3_ = _endpos__2_inlined1_ in + let (_endpos__3_, _startpos__3_) = (_endpos__2_inlined1_, _startpos__1_inlined1_) in let od = let _1 = let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 38377 "parsing/parser.ml" +# 38322 "parsing/parser.ml" in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1493 "parsing/parser.mly" +# 1498 "parsing/parser.mly" ( let loc = make_loc _loc__1_ in let me = Mod.ident ~loc _1 in Opn.mk ~loc me ) -# 38386 "parsing/parser.ml" +# 38331 "parsing/parser.ml" in - let _startpos_od_ = _startpos__1_ in - let _endpos = _endpos__3_ in - let _symbolstartpos = _startpos_od_ in - let _sloc = (_symbolstartpos, _endpos) in + let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2382 "parsing/parser.mly" - ( (* TODO: review the location of Pexp_construct *) - Pexp_open(od, mkexp ~loc:_sloc (Pexp_construct(_3, None))) ) -# 38397 "parsing/parser.ml" +# 2386 "parsing/parser.mly" + ( Pexp_open(od, mkexp ~loc:_loc__3_ (Pexp_construct(_3, None))) ) +# 38338 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_inlined1_ in @@ -38401,15 +38342,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 38407 "parsing/parser.ml" +# 38348 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 38413 "parsing/parser.ml" +# 38354 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38462,16 +38403,16 @@ module Tables = struct let _v : (Parsetree.expression) = let _1 = let _1 = let _4 = -# 2586 "parsing/parser.mly" +# 2588 "parsing/parser.mly" ( es ) -# 38468 "parsing/parser.ml" +# 38409 "parsing/parser.ml" in let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2386 "parsing/parser.mly" +# 2389 "parsing/parser.mly" ( unclosed "[" _loc__3_ "]" _loc__5_ ) -# 38475 "parsing/parser.ml" +# 38416 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -38479,15 +38420,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 38485 "parsing/parser.ml" +# 38426 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 38491 "parsing/parser.ml" +# 38432 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38576,25 +38517,15 @@ module Tables = struct let _1 = let _8 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined3_, _startpos__1_inlined3_, _1_inlined3) in - let _1 = - let _1 = -# 3320 "parsing/parser.mly" - ( Ptyp_package (package_type_of_module_type _1) ) -# 38584 "parsing/parser.ml" - in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 850 "parsing/parser.mly" - ( mktyp ~loc:_sloc _1 ) -# 38592 "parsing/parser.ml" - - in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in -# 3321 "parsing/parser.mly" - ( _1 ) -# 38598 "parsing/parser.ml" +# 3335 "parsing/parser.mly" + ( let (lid, cstrs, attrs) = package_type_of_module_type _1 in + let descr = Ptyp_package (lid, cstrs) in + mktyp ~loc:_sloc ~attrs descr ) +# 38529 "parsing/parser.ml" in let _5 = @@ -38602,15 +38533,15 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 38608 "parsing/parser.ml" +# 38539 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 38614 "parsing/parser.ml" +# 38545 "parsing/parser.ml" in let od = @@ -38619,18 +38550,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 38625 "parsing/parser.ml" +# 38556 "parsing/parser.ml" in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 1493 "parsing/parser.mly" +# 1498 "parsing/parser.mly" ( let loc = make_loc _loc__1_ in let me = Mod.ident ~loc _1 in Opn.mk ~loc me ) -# 38634 "parsing/parser.ml" +# 38565 "parsing/parser.ml" in let _startpos_od_ = _startpos__1_ in @@ -38638,13 +38569,12 @@ module Tables = struct let _symbolstartpos = _startpos_od_ in let _sloc = (_symbolstartpos, _endpos) in -# 2389 "parsing/parser.mly" - ( (* TODO: review the location of Pexp_constraint *) - let modexp = - mkexp_attrs ~loc:_sloc +# 2392 "parsing/parser.mly" + ( let modexp = + mkexp_attrs ~loc:(_startpos__3_, _endpos) (Pexp_constraint (ghexp ~loc:_sloc (Pexp_pack _6), _8)) _5 in Pexp_open(od, modexp) ) -# 38648 "parsing/parser.ml" +# 38578 "parsing/parser.ml" in let _endpos__1_ = _endpos__9_ in @@ -38652,15 +38582,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 38658 "parsing/parser.ml" +# 38588 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 38664 "parsing/parser.ml" +# 38594 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38745,23 +38675,23 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 38751 "parsing/parser.ml" +# 38681 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 38757 "parsing/parser.ml" +# 38687 "parsing/parser.ml" in let _loc__8_ = (_startpos__8_, _endpos__8_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2396 "parsing/parser.mly" +# 2398 "parsing/parser.mly" ( unclosed "(" _loc__3_ ")" _loc__8_ ) -# 38765 "parsing/parser.ml" +# 38695 "parsing/parser.ml" in let _endpos__1_ = _endpos__8_ in @@ -38769,15 +38699,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 846 "parsing/parser.mly" +# 850 "parsing/parser.mly" ( mkexp ~loc:_sloc _1 ) -# 38775 "parsing/parser.ml" +# 38705 "parsing/parser.ml" in -# 2288 "parsing/parser.mly" +# 2294 "parsing/parser.mly" ( _1 ) -# 38781 "parsing/parser.ml" +# 38711 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38806,30 +38736,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 38812 "parsing/parser.ml" +# 38742 "parsing/parser.ml" in -# 2666 "parsing/parser.mly" +# 2668 "parsing/parser.mly" ( Ppat_var (_1) ) -# 38818 "parsing/parser.ml" +# 38748 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 38827 "parsing/parser.ml" +# 38757 "parsing/parser.ml" in -# 2667 "parsing/parser.mly" +# 2669 "parsing/parser.mly" ( _1 ) -# 38833 "parsing/parser.ml" +# 38763 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38852,9 +38782,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = -# 2668 "parsing/parser.mly" +# 2670 "parsing/parser.mly" ( _1 ) -# 38858 "parsing/parser.ml" +# 38788 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38894,9 +38824,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2673 "parsing/parser.mly" +# 2675 "parsing/parser.mly" ( reloc_pat ~loc:_sloc _2 ) -# 38900 "parsing/parser.ml" +# 38830 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38919,9 +38849,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = -# 2675 "parsing/parser.mly" +# 2677 "parsing/parser.mly" ( _1 ) -# 38925 "parsing/parser.ml" +# 38855 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -38984,9 +38914,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 38990 "parsing/parser.ml" +# 38920 "parsing/parser.ml" in let _3 = @@ -38994,24 +38924,24 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 39000 "parsing/parser.ml" +# 38930 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 39006 "parsing/parser.ml" +# 38936 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2677 "parsing/parser.mly" +# 2679 "parsing/parser.mly" ( mkpat_attrs ~loc:_sloc (Ppat_unpack _4) _3 ) -# 39015 "parsing/parser.ml" +# 38945 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39084,25 +39014,15 @@ module Tables = struct let _endpos = _endpos__7_ in let _v : (Parsetree.pattern) = let _6 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined4_, _startpos__1_inlined4_, _1_inlined4) in - let _1 = - let _1 = -# 3320 "parsing/parser.mly" - ( Ptyp_package (package_type_of_module_type _1) ) -# 39092 "parsing/parser.ml" - in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 850 "parsing/parser.mly" - ( mktyp ~loc:_sloc _1 ) -# 39100 "parsing/parser.ml" - - in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in -# 3321 "parsing/parser.mly" - ( _1 ) -# 39106 "parsing/parser.ml" +# 3335 "parsing/parser.mly" + ( let (lid, cstrs, attrs) = package_type_of_module_type _1 in + let descr = Ptyp_package (lid, cstrs) in + mktyp ~loc:_sloc ~attrs descr ) +# 39026 "parsing/parser.ml" in let _4 = @@ -39111,36 +39031,38 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 39117 "parsing/parser.ml" +# 39037 "parsing/parser.ml" in + let (_endpos__4_, _startpos__4_) = (_endpos__1_inlined3_, _startpos__1_inlined3_) in let _3 = let (_1_inlined1, _1) = (_1_inlined2, _1_inlined1) in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 39127 "parsing/parser.ml" +# 39048 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 39133 "parsing/parser.ml" +# 39054 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = _startpos__1_ in + let _loc__4_ = (_startpos__4_, _endpos__4_) in let _sloc = (_symbolstartpos, _endpos) in -# 2679 "parsing/parser.mly" +# 2681 "parsing/parser.mly" ( mkpat_attrs ~loc:_sloc - (Ppat_constraint(mkpat ~loc:_sloc (Ppat_unpack _4), _6)) + (Ppat_constraint(mkpat ~loc:_loc__4_ (Ppat_unpack _4), _6)) _3 ) -# 39144 "parsing/parser.ml" +# 39066 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39164,23 +39086,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 2687 "parsing/parser.mly" +# 2689 "parsing/parser.mly" ( Ppat_any ) -# 39170 "parsing/parser.ml" +# 39092 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39178 "parsing/parser.ml" +# 39100 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39184 "parsing/parser.ml" +# 39106 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39204,23 +39126,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 2689 "parsing/parser.mly" +# 2691 "parsing/parser.mly" ( Ppat_constant _1 ) -# 39210 "parsing/parser.ml" +# 39132 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39218 "parsing/parser.ml" +# 39140 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39224 "parsing/parser.ml" +# 39146 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39258,24 +39180,24 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 2691 "parsing/parser.mly" +# 2693 "parsing/parser.mly" ( Ppat_interval (_1, _3) ) -# 39264 "parsing/parser.ml" +# 39186 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39273 "parsing/parser.ml" +# 39195 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39279 "parsing/parser.ml" +# 39201 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39304,30 +39226,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 39310 "parsing/parser.ml" +# 39232 "parsing/parser.ml" in -# 2693 "parsing/parser.mly" +# 2695 "parsing/parser.mly" ( Ppat_construct(_1, None) ) -# 39316 "parsing/parser.ml" +# 39238 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39325 "parsing/parser.ml" +# 39247 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39331 "parsing/parser.ml" +# 39253 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39351,23 +39273,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 2695 "parsing/parser.mly" +# 2697 "parsing/parser.mly" ( Ppat_variant(_1, None) ) -# 39357 "parsing/parser.ml" +# 39279 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39365 "parsing/parser.ml" +# 39287 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39371 "parsing/parser.ml" +# 39293 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39404,15 +39326,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 39410 "parsing/parser.ml" +# 39332 "parsing/parser.ml" in -# 2697 "parsing/parser.mly" +# 2699 "parsing/parser.mly" ( Ppat_type (_2) ) -# 39416 "parsing/parser.ml" +# 39338 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined1_ in @@ -39420,15 +39342,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39426 "parsing/parser.ml" +# 39348 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39432 "parsing/parser.ml" +# 39354 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39471,15 +39393,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 39477 "parsing/parser.ml" +# 39399 "parsing/parser.ml" in -# 2699 "parsing/parser.mly" +# 2701 "parsing/parser.mly" ( Ppat_open(_1, _3) ) -# 39483 "parsing/parser.ml" +# 39405 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -39487,15 +39409,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39493 "parsing/parser.ml" +# 39415 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39499 "parsing/parser.ml" +# 39421 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39543,18 +39465,18 @@ module Tables = struct let _3 = let (_endpos__2_, _startpos__1_, _2, _1) = (_endpos__2_inlined1_, _startpos__1_inlined1_, _2_inlined1, _1_inlined1) in let _1 = -# 2700 "parsing/parser.mly" +# 2702 "parsing/parser.mly" (Lident "[]") -# 39549 "parsing/parser.ml" +# 39471 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 39558 "parsing/parser.ml" +# 39480 "parsing/parser.ml" in let _endpos__3_ = _endpos__2_inlined1_ in @@ -39563,18 +39485,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 39569 "parsing/parser.ml" +# 39491 "parsing/parser.ml" in let _endpos = _endpos__3_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2701 "parsing/parser.mly" +# 2703 "parsing/parser.mly" ( Ppat_open(_1, mkpat ~loc:_sloc (Ppat_construct(_3, None))) ) -# 39578 "parsing/parser.ml" +# 39500 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_inlined1_ in @@ -39582,15 +39504,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39588 "parsing/parser.ml" +# 39510 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39594 "parsing/parser.ml" +# 39516 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39638,18 +39560,18 @@ module Tables = struct let _3 = let (_endpos__2_, _startpos__1_, _2, _1) = (_endpos__2_inlined1_, _startpos__1_inlined1_, _2_inlined1, _1_inlined1) in let _1 = -# 2702 "parsing/parser.mly" +# 2704 "parsing/parser.mly" (Lident "()") -# 39644 "parsing/parser.ml" +# 39566 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 39653 "parsing/parser.ml" +# 39575 "parsing/parser.ml" in let _endpos__3_ = _endpos__2_inlined1_ in @@ -39658,18 +39580,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 39664 "parsing/parser.ml" +# 39586 "parsing/parser.ml" in let _endpos = _endpos__3_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2703 "parsing/parser.mly" +# 2705 "parsing/parser.mly" ( Ppat_open(_1, mkpat ~loc:_sloc (Ppat_construct(_3, None))) ) -# 39673 "parsing/parser.ml" +# 39595 "parsing/parser.ml" in let _endpos__1_ = _endpos__2_inlined1_ in @@ -39677,15 +39599,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39683 "parsing/parser.ml" +# 39605 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39689 "parsing/parser.ml" +# 39611 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39742,15 +39664,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 39748 "parsing/parser.ml" +# 39670 "parsing/parser.ml" in -# 2705 "parsing/parser.mly" +# 2707 "parsing/parser.mly" ( Ppat_open (_1, _4) ) -# 39754 "parsing/parser.ml" +# 39676 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -39758,15 +39680,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39764 "parsing/parser.ml" +# 39686 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39770 "parsing/parser.ml" +# 39692 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39821,9 +39743,9 @@ module Tables = struct let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 2707 "parsing/parser.mly" +# 2709 "parsing/parser.mly" ( unclosed "(" _loc__3_ ")" _loc__5_ ) -# 39827 "parsing/parser.ml" +# 39749 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -39831,15 +39753,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39837 "parsing/parser.ml" +# 39759 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39843 "parsing/parser.ml" +# 39765 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39886,9 +39808,9 @@ module Tables = struct let _1 = let _loc__4_ = (_startpos__4_, _endpos__4_) in -# 2709 "parsing/parser.mly" +# 2711 "parsing/parser.mly" ( expecting _loc__4_ "pattern" ) -# 39892 "parsing/parser.ml" +# 39814 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -39896,15 +39818,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39902 "parsing/parser.ml" +# 39824 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39908 "parsing/parser.ml" +# 39830 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -39945,9 +39867,9 @@ module Tables = struct let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2711 "parsing/parser.mly" +# 2713 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__3_ ) -# 39951 "parsing/parser.ml" +# 39873 "parsing/parser.ml" in let _endpos__1_ = _endpos__3_ in @@ -39955,15 +39877,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 39961 "parsing/parser.ml" +# 39883 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 39967 "parsing/parser.ml" +# 39889 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40015,24 +39937,24 @@ module Tables = struct let _endpos = _endpos__5_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 2713 "parsing/parser.mly" +# 2715 "parsing/parser.mly" ( Ppat_constraint(_2, _4) ) -# 40021 "parsing/parser.ml" +# 39943 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 40030 "parsing/parser.ml" +# 39952 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 40036 "parsing/parser.ml" +# 39958 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40087,9 +40009,9 @@ module Tables = struct let _loc__5_ = (_startpos__5_, _endpos__5_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2715 "parsing/parser.mly" +# 2717 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__5_ ) -# 40093 "parsing/parser.ml" +# 40015 "parsing/parser.ml" in let _endpos__1_ = _endpos__5_ in @@ -40097,15 +40019,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 40103 "parsing/parser.ml" +# 40025 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 40109 "parsing/parser.ml" +# 40031 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40152,9 +40074,9 @@ module Tables = struct let _1 = let _loc__4_ = (_startpos__4_, _endpos__4_) in -# 2717 "parsing/parser.mly" +# 2719 "parsing/parser.mly" ( expecting _loc__4_ "type" ) -# 40158 "parsing/parser.ml" +# 40080 "parsing/parser.ml" in let _endpos__1_ = _endpos__4_ in @@ -40162,15 +40084,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 40168 "parsing/parser.ml" +# 40090 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 40174 "parsing/parser.ml" +# 40096 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40245,25 +40167,15 @@ module Tables = struct let _1 = let _6 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined3_, _startpos__1_inlined3_, _1_inlined3) in - let _1 = - let _1 = -# 3320 "parsing/parser.mly" - ( Ptyp_package (package_type_of_module_type _1) ) -# 40253 "parsing/parser.ml" - in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 850 "parsing/parser.mly" - ( mktyp ~loc:_sloc _1 ) -# 40261 "parsing/parser.ml" - - in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in -# 3321 "parsing/parser.mly" - ( _1 ) -# 40267 "parsing/parser.ml" +# 3335 "parsing/parser.mly" + ( let (lid, cstrs, attrs) = package_type_of_module_type _1 in + let descr = Ptyp_package (lid, cstrs) in + mktyp ~loc:_sloc ~attrs descr ) +# 40179 "parsing/parser.ml" in let _3 = @@ -40271,23 +40183,23 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 40277 "parsing/parser.ml" +# 40189 "parsing/parser.ml" in -# 3742 "parsing/parser.mly" +# 3758 "parsing/parser.mly" ( _1, _2 ) -# 40283 "parsing/parser.ml" +# 40195 "parsing/parser.ml" in let _loc__7_ = (_startpos__7_, _endpos__7_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 2720 "parsing/parser.mly" +# 2722 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__7_ ) -# 40291 "parsing/parser.ml" +# 40203 "parsing/parser.ml" in let _endpos__1_ = _endpos__7_ in @@ -40295,15 +40207,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 40301 "parsing/parser.ml" +# 40213 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 40307 "parsing/parser.ml" +# 40219 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40327,23 +40239,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.pattern) = let _1 = let _1 = -# 2722 "parsing/parser.mly" +# 2724 "parsing/parser.mly" ( Ppat_extension _1 ) -# 40333 "parsing/parser.ml" +# 40245 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 848 "parsing/parser.mly" +# 852 "parsing/parser.mly" ( mkpat ~loc:_sloc _1 ) -# 40341 "parsing/parser.ml" +# 40253 "parsing/parser.ml" in -# 2683 "parsing/parser.mly" +# 2685 "parsing/parser.mly" ( _1 ) -# 40347 "parsing/parser.ml" +# 40259 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40362,17 +40274,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 40368 "parsing/parser.ml" +# 40280 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3652 "parsing/parser.mly" +# 3668 "parsing/parser.mly" ( _1 ) -# 40376 "parsing/parser.ml" +# 40288 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40391,17 +40303,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 697 "parsing/parser.mly" +# 701 "parsing/parser.mly" (string) -# 40397 "parsing/parser.ml" +# 40309 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3653 "parsing/parser.mly" +# 3669 "parsing/parser.mly" ( _1 ) -# 40405 "parsing/parser.ml" +# 40317 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40424,9 +40336,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3654 "parsing/parser.mly" +# 3670 "parsing/parser.mly" ( "and" ) -# 40430 "parsing/parser.ml" +# 40342 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40449,9 +40361,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3655 "parsing/parser.mly" +# 3671 "parsing/parser.mly" ( "as" ) -# 40455 "parsing/parser.ml" +# 40367 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40474,9 +40386,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3656 "parsing/parser.mly" +# 3672 "parsing/parser.mly" ( "assert" ) -# 40480 "parsing/parser.ml" +# 40392 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40499,9 +40411,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3657 "parsing/parser.mly" +# 3673 "parsing/parser.mly" ( "begin" ) -# 40505 "parsing/parser.ml" +# 40417 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40524,9 +40436,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3658 "parsing/parser.mly" +# 3674 "parsing/parser.mly" ( "class" ) -# 40530 "parsing/parser.ml" +# 40442 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40549,9 +40461,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3659 "parsing/parser.mly" +# 3675 "parsing/parser.mly" ( "constraint" ) -# 40555 "parsing/parser.ml" +# 40467 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40574,9 +40486,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3660 "parsing/parser.mly" +# 3676 "parsing/parser.mly" ( "do" ) -# 40580 "parsing/parser.ml" +# 40492 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40599,9 +40511,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3661 "parsing/parser.mly" +# 3677 "parsing/parser.mly" ( "done" ) -# 40605 "parsing/parser.ml" +# 40517 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40624,9 +40536,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3662 "parsing/parser.mly" +# 3678 "parsing/parser.mly" ( "downto" ) -# 40630 "parsing/parser.ml" +# 40542 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40649,9 +40561,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3663 "parsing/parser.mly" +# 3679 "parsing/parser.mly" ( "else" ) -# 40655 "parsing/parser.ml" +# 40567 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40674,9 +40586,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3664 "parsing/parser.mly" +# 3680 "parsing/parser.mly" ( "end" ) -# 40680 "parsing/parser.ml" +# 40592 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40699,9 +40611,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3665 "parsing/parser.mly" +# 3681 "parsing/parser.mly" ( "exception" ) -# 40705 "parsing/parser.ml" +# 40617 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40724,9 +40636,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3666 "parsing/parser.mly" +# 3682 "parsing/parser.mly" ( "external" ) -# 40730 "parsing/parser.ml" +# 40642 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40749,9 +40661,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3667 "parsing/parser.mly" +# 3683 "parsing/parser.mly" ( "false" ) -# 40755 "parsing/parser.ml" +# 40667 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40774,9 +40686,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3668 "parsing/parser.mly" +# 3684 "parsing/parser.mly" ( "for" ) -# 40780 "parsing/parser.ml" +# 40692 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40799,9 +40711,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3669 "parsing/parser.mly" +# 3685 "parsing/parser.mly" ( "fun" ) -# 40805 "parsing/parser.ml" +# 40717 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40824,9 +40736,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3670 "parsing/parser.mly" +# 3686 "parsing/parser.mly" ( "function" ) -# 40830 "parsing/parser.ml" +# 40742 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40849,9 +40761,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3671 "parsing/parser.mly" +# 3687 "parsing/parser.mly" ( "functor" ) -# 40855 "parsing/parser.ml" +# 40767 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40874,9 +40786,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3672 "parsing/parser.mly" +# 3688 "parsing/parser.mly" ( "if" ) -# 40880 "parsing/parser.ml" +# 40792 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40899,9 +40811,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3673 "parsing/parser.mly" +# 3689 "parsing/parser.mly" ( "in" ) -# 40905 "parsing/parser.ml" +# 40817 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40924,9 +40836,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3674 "parsing/parser.mly" +# 3690 "parsing/parser.mly" ( "include" ) -# 40930 "parsing/parser.ml" +# 40842 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40949,9 +40861,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3675 "parsing/parser.mly" +# 3691 "parsing/parser.mly" ( "inherit" ) -# 40955 "parsing/parser.ml" +# 40867 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40974,9 +40886,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3676 "parsing/parser.mly" +# 3692 "parsing/parser.mly" ( "initializer" ) -# 40980 "parsing/parser.ml" +# 40892 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -40999,9 +40911,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3677 "parsing/parser.mly" +# 3693 "parsing/parser.mly" ( "lazy" ) -# 41005 "parsing/parser.ml" +# 40917 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41024,9 +40936,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3678 "parsing/parser.mly" +# 3694 "parsing/parser.mly" ( "let" ) -# 41030 "parsing/parser.ml" +# 40942 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41049,9 +40961,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3679 "parsing/parser.mly" +# 3695 "parsing/parser.mly" ( "match" ) -# 41055 "parsing/parser.ml" +# 40967 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41074,9 +40986,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3680 "parsing/parser.mly" +# 3696 "parsing/parser.mly" ( "method" ) -# 41080 "parsing/parser.ml" +# 40992 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41099,9 +41011,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3681 "parsing/parser.mly" +# 3697 "parsing/parser.mly" ( "module" ) -# 41105 "parsing/parser.ml" +# 41017 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41124,9 +41036,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3682 "parsing/parser.mly" +# 3698 "parsing/parser.mly" ( "mutable" ) -# 41130 "parsing/parser.ml" +# 41042 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41149,9 +41061,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3683 "parsing/parser.mly" +# 3699 "parsing/parser.mly" ( "new" ) -# 41155 "parsing/parser.ml" +# 41067 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41174,9 +41086,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3684 "parsing/parser.mly" +# 3700 "parsing/parser.mly" ( "nonrec" ) -# 41180 "parsing/parser.ml" +# 41092 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41199,9 +41111,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3685 "parsing/parser.mly" +# 3701 "parsing/parser.mly" ( "object" ) -# 41205 "parsing/parser.ml" +# 41117 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41224,9 +41136,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3686 "parsing/parser.mly" +# 3702 "parsing/parser.mly" ( "of" ) -# 41230 "parsing/parser.ml" +# 41142 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41249,9 +41161,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3687 "parsing/parser.mly" +# 3703 "parsing/parser.mly" ( "open" ) -# 41255 "parsing/parser.ml" +# 41167 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41274,9 +41186,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3688 "parsing/parser.mly" +# 3704 "parsing/parser.mly" ( "or" ) -# 41280 "parsing/parser.ml" +# 41192 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41299,9 +41211,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3689 "parsing/parser.mly" +# 3705 "parsing/parser.mly" ( "private" ) -# 41305 "parsing/parser.ml" +# 41217 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41324,9 +41236,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3690 "parsing/parser.mly" +# 3706 "parsing/parser.mly" ( "rec" ) -# 41330 "parsing/parser.ml" +# 41242 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41349,9 +41261,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3691 "parsing/parser.mly" +# 3707 "parsing/parser.mly" ( "sig" ) -# 41355 "parsing/parser.ml" +# 41267 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41374,9 +41286,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3692 "parsing/parser.mly" +# 3708 "parsing/parser.mly" ( "struct" ) -# 41380 "parsing/parser.ml" +# 41292 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41399,9 +41311,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3693 "parsing/parser.mly" +# 3709 "parsing/parser.mly" ( "then" ) -# 41405 "parsing/parser.ml" +# 41317 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41424,9 +41336,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3694 "parsing/parser.mly" +# 3710 "parsing/parser.mly" ( "to" ) -# 41430 "parsing/parser.ml" +# 41342 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41449,9 +41361,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3695 "parsing/parser.mly" +# 3711 "parsing/parser.mly" ( "true" ) -# 41455 "parsing/parser.ml" +# 41367 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41474,9 +41386,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3696 "parsing/parser.mly" +# 3712 "parsing/parser.mly" ( "try" ) -# 41480 "parsing/parser.ml" +# 41392 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41499,9 +41411,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3697 "parsing/parser.mly" +# 3713 "parsing/parser.mly" ( "type" ) -# 41505 "parsing/parser.ml" +# 41417 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41524,9 +41436,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3698 "parsing/parser.mly" +# 3714 "parsing/parser.mly" ( "val" ) -# 41530 "parsing/parser.ml" +# 41442 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41549,9 +41461,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3699 "parsing/parser.mly" +# 3715 "parsing/parser.mly" ( "virtual" ) -# 41555 "parsing/parser.ml" +# 41467 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41574,9 +41486,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3700 "parsing/parser.mly" +# 3716 "parsing/parser.mly" ( "when" ) -# 41580 "parsing/parser.ml" +# 41492 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41599,9 +41511,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3701 "parsing/parser.mly" +# 3717 "parsing/parser.mly" ( "while" ) -# 41605 "parsing/parser.ml" +# 41517 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41624,9 +41536,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3702 "parsing/parser.mly" +# 3718 "parsing/parser.mly" ( "with" ) -# 41630 "parsing/parser.ml" +# 41542 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41649,9 +41561,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Parsetree.type_exception * string Asttypes.loc option) = -# 2987 "parsing/parser.mly" +# 3003 "parsing/parser.mly" ( _1 ) -# 41655 "parsing/parser.ml" +# 41567 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41725,18 +41637,18 @@ module Tables = struct let _v : (Parsetree.type_exception * string Asttypes.loc option) = let attrs = let _1 = _1_inlined5 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 41731 "parsing/parser.ml" +# 41643 "parsing/parser.ml" in let _endpos_attrs_ = _endpos__1_inlined5_ in let attrs2 = let _1 = _1_inlined4 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 41740 "parsing/parser.ml" +# 41652 "parsing/parser.ml" in let lid = @@ -41745,9 +41657,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 41751 "parsing/parser.ml" +# 41663 "parsing/parser.ml" in let id = @@ -41756,30 +41668,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 41762 "parsing/parser.ml" +# 41674 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 41770 "parsing/parser.ml" +# 41682 "parsing/parser.ml" in let _endpos = _endpos_attrs_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2996 "parsing/parser.mly" +# 3012 "parsing/parser.mly" ( let loc = make_loc _sloc in let docs = symbol_docs _sloc in Te.mk_exception ~attrs (Te.rebind id lid ~attrs:(attrs1 @ attrs2) ~loc ~docs) , ext ) -# 41783 "parsing/parser.ml" +# 41695 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41809,9 +41721,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.expression) = -# 2511 "parsing/parser.mly" +# 2513 "parsing/parser.mly" ( _2 ) -# 41815 "parsing/parser.ml" +# 41727 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41844,9 +41756,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2513 "parsing/parser.mly" +# 2515 "parsing/parser.mly" ( let (l, o, p) = _1 in ghexp ~loc:_sloc (Pexp_fun(l, o, p, _2)) ) -# 41850 "parsing/parser.ml" +# 41762 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41897,17 +41809,17 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : (Parsetree.expression) = let _3 = -# 2414 "parsing/parser.mly" +# 2416 "parsing/parser.mly" ( xs ) -# 41903 "parsing/parser.ml" +# 41815 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2515 "parsing/parser.mly" +# 2517 "parsing/parser.mly" ( mk_newtypes ~loc:_sloc _3 _5 ) -# 41911 "parsing/parser.ml" +# 41823 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -41934,39 +41846,39 @@ module Tables = struct let ys = # 260 "" ( List.flatten xss ) -# 41938 "parsing/parser.ml" +# 41850 "parsing/parser.ml" in let xs = let items = -# 883 "parsing/parser.mly" +# 887 "parsing/parser.mly" ( [] ) -# 41944 "parsing/parser.ml" +# 41856 "parsing/parser.ml" in -# 1297 "parsing/parser.mly" +# 1301 "parsing/parser.mly" ( items ) -# 41949 "parsing/parser.ml" +# 41861 "parsing/parser.ml" in # 267 "" ( xs @ ys ) -# 41955 "parsing/parser.ml" +# 41867 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_xss_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 805 "parsing/parser.mly" +# 809 "parsing/parser.mly" ( extra_str _startpos _endpos _1 ) -# 41964 "parsing/parser.ml" +# 41876 "parsing/parser.ml" in -# 1290 "parsing/parser.mly" +# 1294 "parsing/parser.mly" ( _1 ) -# 41970 "parsing/parser.ml" +# 41882 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42007,7 +41919,7 @@ module Tables = struct let ys = # 260 "" ( List.flatten xss ) -# 42011 "parsing/parser.ml" +# 41923 "parsing/parser.ml" in let xs = let items = @@ -42015,65 +41927,65 @@ module Tables = struct let _1 = let _1 = let attrs = -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 42021 "parsing/parser.ml" +# 41933 "parsing/parser.ml" in -# 1304 "parsing/parser.mly" +# 1308 "parsing/parser.mly" ( mkstrexp e attrs ) -# 42026 "parsing/parser.ml" +# 41938 "parsing/parser.ml" in let _startpos__1_ = _startpos_e_ in let _startpos = _startpos__1_ in -# 817 "parsing/parser.mly" +# 821 "parsing/parser.mly" ( text_str _startpos @ [_1] ) -# 42034 "parsing/parser.ml" +# 41946 "parsing/parser.ml" in let _startpos__1_ = _startpos_e_ in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 836 "parsing/parser.mly" +# 840 "parsing/parser.mly" ( mark_rhs_docs _startpos _endpos; _1 ) -# 42044 "parsing/parser.ml" +# 41956 "parsing/parser.ml" in -# 885 "parsing/parser.mly" +# 889 "parsing/parser.mly" ( x ) -# 42050 "parsing/parser.ml" +# 41962 "parsing/parser.ml" in -# 1297 "parsing/parser.mly" +# 1301 "parsing/parser.mly" ( items ) -# 42056 "parsing/parser.ml" +# 41968 "parsing/parser.ml" in # 267 "" ( xs @ ys ) -# 42062 "parsing/parser.ml" +# 41974 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_e_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 805 "parsing/parser.mly" +# 809 "parsing/parser.mly" ( extra_str _startpos _endpos _1 ) -# 42071 "parsing/parser.ml" +# 41983 "parsing/parser.ml" in -# 1290 "parsing/parser.mly" +# 1294 "parsing/parser.mly" ( _1 ) -# 42077 "parsing/parser.ml" +# 41989 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42099,9 +42011,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1319 "parsing/parser.mly" +# 1323 "parsing/parser.mly" ( val_of_let_bindings ~loc:_sloc _1 ) -# 42105 "parsing/parser.ml" +# 42017 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42135,9 +42047,9 @@ module Tables = struct let _2 = let _1 = _1_inlined1 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 42141 "parsing/parser.ml" +# 42053 "parsing/parser.ml" in let _endpos__2_ = _endpos__1_inlined1_ in @@ -42145,10 +42057,10 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1322 "parsing/parser.mly" +# 1326 "parsing/parser.mly" ( let docs = symbol_docs _sloc in Pstr_extension (_1, add_docs_attrs docs _2) ) -# 42152 "parsing/parser.ml" +# 42064 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined1_ in @@ -42156,15 +42068,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 852 "parsing/parser.mly" +# 856 "parsing/parser.mly" ( mkstr ~loc:_sloc _1 ) -# 42162 "parsing/parser.ml" +# 42074 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 42168 "parsing/parser.ml" +# 42080 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42188,23 +42100,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.structure_item) = let _1 = let _1 = -# 1325 "parsing/parser.mly" +# 1329 "parsing/parser.mly" ( Pstr_attribute _1 ) -# 42194 "parsing/parser.ml" +# 42106 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 852 "parsing/parser.mly" +# 856 "parsing/parser.mly" ( mkstr ~loc:_sloc _1 ) -# 42202 "parsing/parser.ml" +# 42114 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 42208 "parsing/parser.ml" +# 42120 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42228,23 +42140,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.structure_item) = let _1 = let _1 = -# 1329 "parsing/parser.mly" +# 1333 "parsing/parser.mly" ( pstr_primitive _1 ) -# 42234 "parsing/parser.ml" +# 42146 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 42242 "parsing/parser.ml" +# 42154 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 42248 "parsing/parser.ml" +# 42160 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42268,23 +42180,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.structure_item) = let _1 = let _1 = -# 1331 "parsing/parser.mly" +# 1335 "parsing/parser.mly" ( pstr_primitive _1 ) -# 42274 "parsing/parser.ml" +# 42186 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 42282 "parsing/parser.ml" +# 42194 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 42288 "parsing/parser.ml" +# 42200 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42319,26 +42231,26 @@ module Tables = struct let _1 = let _1 = let _1 = -# 1044 "parsing/parser.mly" +# 1048 "parsing/parser.mly" ( let (x, b) = a in x, b :: bs ) -# 42325 "parsing/parser.ml" +# 42237 "parsing/parser.ml" in -# 2842 "parsing/parser.mly" +# 2847 "parsing/parser.mly" ( _1 ) -# 42330 "parsing/parser.ml" +# 42242 "parsing/parser.ml" in -# 2825 "parsing/parser.mly" +# 2830 "parsing/parser.mly" ( _1 ) -# 42336 "parsing/parser.ml" +# 42248 "parsing/parser.ml" in -# 1333 "parsing/parser.mly" +# 1337 "parsing/parser.mly" ( pstr_type _1 ) -# 42342 "parsing/parser.ml" +# 42254 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_bs_, _startpos_a_) in @@ -42346,15 +42258,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 42352 "parsing/parser.ml" +# 42264 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 42358 "parsing/parser.ml" +# 42270 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42425,7 +42337,7 @@ module Tables = struct let priv : (Asttypes.private_flag) = Obj.magic priv in let _7 : unit = Obj.magic _7 in let _1_inlined2 : (Longident.t) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in let _1 : unit = Obj.magic _1 in @@ -42439,16 +42351,16 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 42445 "parsing/parser.ml" +# 42357 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in let cs = -# 1036 "parsing/parser.mly" +# 1040 "parsing/parser.mly" ( List.rev xs ) -# 42452 "parsing/parser.ml" +# 42364 "parsing/parser.ml" in let tid = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in @@ -42456,46 +42368,46 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 42462 "parsing/parser.ml" +# 42374 "parsing/parser.ml" in let _4 = -# 3574 "parsing/parser.mly" +# 3590 "parsing/parser.mly" ( Recursive ) -# 42468 "parsing/parser.ml" +# 42380 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 42475 "parsing/parser.ml" +# 42387 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3079 "parsing/parser.mly" +# 3095 "parsing/parser.mly" ( let docs = symbol_docs _sloc in let attrs = attrs1 @ attrs2 in Te.mk tid cs ~params ~priv ~attrs ~docs, ext ) -# 42487 "parsing/parser.ml" +# 42399 "parsing/parser.ml" in -# 3062 "parsing/parser.mly" +# 3078 "parsing/parser.mly" ( _1 ) -# 42493 "parsing/parser.ml" +# 42405 "parsing/parser.ml" in -# 1335 "parsing/parser.mly" +# 1339 "parsing/parser.mly" ( pstr_typext _1 ) -# 42499 "parsing/parser.ml" +# 42411 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined3_ in @@ -42503,15 +42415,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 42509 "parsing/parser.ml" +# 42421 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 42515 "parsing/parser.ml" +# 42427 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42588,7 +42500,7 @@ module Tables = struct let priv : (Asttypes.private_flag) = Obj.magic priv in let _7 : unit = Obj.magic _7 in let _1_inlined3 : (Longident.t) = Obj.magic _1_inlined3 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let _1_inlined2 : unit = Obj.magic _1_inlined2 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in @@ -42603,16 +42515,16 @@ module Tables = struct let attrs2 = let _1 = _1_inlined4 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 42609 "parsing/parser.ml" +# 42521 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined4_ in let cs = -# 1036 "parsing/parser.mly" +# 1040 "parsing/parser.mly" ( List.rev xs ) -# 42616 "parsing/parser.ml" +# 42528 "parsing/parser.ml" in let tid = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined3_, _startpos__1_inlined3_, _1_inlined3) in @@ -42620,9 +42532,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 42626 "parsing/parser.ml" +# 42538 "parsing/parser.ml" in let _4 = @@ -42631,41 +42543,41 @@ module Tables = struct let _startpos = _startpos__1_ in let _loc = (_startpos, _endpos) in -# 3575 "parsing/parser.mly" +# 3591 "parsing/parser.mly" ( not_expecting _loc "nonrec flag" ) -# 42637 "parsing/parser.ml" +# 42549 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 42645 "parsing/parser.ml" +# 42557 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3079 "parsing/parser.mly" +# 3095 "parsing/parser.mly" ( let docs = symbol_docs _sloc in let attrs = attrs1 @ attrs2 in Te.mk tid cs ~params ~priv ~attrs ~docs, ext ) -# 42657 "parsing/parser.ml" +# 42569 "parsing/parser.ml" in -# 3062 "parsing/parser.mly" +# 3078 "parsing/parser.mly" ( _1 ) -# 42663 "parsing/parser.ml" +# 42575 "parsing/parser.ml" in -# 1335 "parsing/parser.mly" +# 1339 "parsing/parser.mly" ( pstr_typext _1 ) -# 42669 "parsing/parser.ml" +# 42581 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined4_ in @@ -42673,15 +42585,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 42679 "parsing/parser.ml" +# 42591 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 42685 "parsing/parser.ml" +# 42597 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42705,23 +42617,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.structure_item) = let _1 = let _1 = -# 1337 "parsing/parser.mly" +# 1341 "parsing/parser.mly" ( pstr_exception _1 ) -# 42711 "parsing/parser.ml" +# 42623 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 42719 "parsing/parser.ml" +# 42631 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 42725 "parsing/parser.ml" +# 42637 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42784,9 +42696,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 42790 "parsing/parser.ml" +# 42702 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -42796,36 +42708,36 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 42802 "parsing/parser.ml" +# 42714 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 42810 "parsing/parser.ml" +# 42722 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1363 "parsing/parser.mly" +# 1367 "parsing/parser.mly" ( let docs = symbol_docs _sloc in let loc = make_loc _sloc in let attrs = attrs1 @ attrs2 in let body = Mb.mk name body ~attrs ~loc ~docs in Pstr_module body, ext ) -# 42823 "parsing/parser.ml" +# 42735 "parsing/parser.ml" in -# 1339 "parsing/parser.mly" +# 1343 "parsing/parser.mly" ( _1 ) -# 42829 "parsing/parser.ml" +# 42741 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined3_ in @@ -42833,15 +42745,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 42839 "parsing/parser.ml" +# 42751 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 42845 "parsing/parser.ml" +# 42757 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -42920,9 +42832,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 42926 "parsing/parser.ml" +# 42838 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -42932,24 +42844,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 42938 "parsing/parser.ml" +# 42850 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 42946 "parsing/parser.ml" +# 42858 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1397 "parsing/parser.mly" +# 1402 "parsing/parser.mly" ( let loc = make_loc _sloc in let attrs = attrs1 @ attrs2 in @@ -42957,25 +42869,25 @@ module Tables = struct ext, Mb.mk name body ~attrs ~loc ~docs ) -# 42961 "parsing/parser.ml" +# 42873 "parsing/parser.ml" in -# 1044 "parsing/parser.mly" +# 1048 "parsing/parser.mly" ( let (x, b) = a in x, b :: bs ) -# 42967 "parsing/parser.ml" +# 42879 "parsing/parser.ml" in -# 1385 "parsing/parser.mly" +# 1390 "parsing/parser.mly" ( _1 ) -# 42973 "parsing/parser.ml" +# 42885 "parsing/parser.ml" in -# 1341 "parsing/parser.mly" +# 1345 "parsing/parser.mly" ( pstr_recmodule _1 ) -# 42979 "parsing/parser.ml" +# 42891 "parsing/parser.ml" in let _endpos__1_ = _endpos_bs_ in @@ -42983,15 +42895,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 42989 "parsing/parser.ml" +# 42901 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 42995 "parsing/parser.ml" +# 42907 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43015,23 +42927,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.structure_item) = let _1 = let _1 = -# 1343 "parsing/parser.mly" +# 1347 "parsing/parser.mly" ( let (body, ext) = _1 in (Pstr_modtype body, ext) ) -# 43021 "parsing/parser.ml" +# 42933 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 43029 "parsing/parser.ml" +# 42941 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 43035 "parsing/parser.ml" +# 42947 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43055,23 +42967,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.structure_item) = let _1 = let _1 = -# 1345 "parsing/parser.mly" +# 1349 "parsing/parser.mly" ( let (body, ext) = _1 in (Pstr_open body, ext) ) -# 43061 "parsing/parser.ml" +# 42973 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 43069 "parsing/parser.ml" +# 42981 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 43075 "parsing/parser.ml" +# 42987 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43141,11 +43053,11 @@ module Tables = struct let _1_inlined3 : (Parsetree.attributes) = Obj.magic _1_inlined3 in let body : (Parsetree.class_expr) = Obj.magic body in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 43147 "parsing/parser.ml" +# 43059 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in - let params : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic params in + let params : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic params in let virt : (Asttypes.virtual_flag) = Obj.magic virt in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in let ext : (string Asttypes.loc option) = Obj.magic ext in @@ -43161,9 +43073,9 @@ module Tables = struct let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 43167 "parsing/parser.ml" +# 43079 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -43173,24 +43085,24 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 43179 "parsing/parser.ml" +# 43091 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 43187 "parsing/parser.ml" +# 43099 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1715 "parsing/parser.mly" +# 1721 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in @@ -43198,25 +43110,25 @@ module Tables = struct ext, Ci.mk id body ~virt ~params ~attrs ~loc ~docs ) -# 43202 "parsing/parser.ml" +# 43114 "parsing/parser.ml" in -# 1044 "parsing/parser.mly" +# 1048 "parsing/parser.mly" ( let (x, b) = a in x, b :: bs ) -# 43208 "parsing/parser.ml" +# 43120 "parsing/parser.ml" in -# 1704 "parsing/parser.mly" +# 1710 "parsing/parser.mly" ( _1 ) -# 43214 "parsing/parser.ml" +# 43126 "parsing/parser.ml" in -# 1347 "parsing/parser.mly" +# 1351 "parsing/parser.mly" ( let (ext, l) = _1 in (Pstr_class l, ext) ) -# 43220 "parsing/parser.ml" +# 43132 "parsing/parser.ml" in let _endpos__1_ = _endpos_bs_ in @@ -43224,15 +43136,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 43230 "parsing/parser.ml" +# 43142 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 43236 "parsing/parser.ml" +# 43148 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43256,23 +43168,23 @@ module Tables = struct let _endpos = _endpos__1_ in let _v : (Parsetree.structure_item) = let _1 = let _1 = -# 1349 "parsing/parser.mly" +# 1353 "parsing/parser.mly" ( let (ext, l) = _1 in (Pstr_class_type l, ext) ) -# 43262 "parsing/parser.ml" +# 43174 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 43270 "parsing/parser.ml" +# 43182 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 43276 "parsing/parser.ml" +# 43188 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43328,38 +43240,38 @@ module Tables = struct let attrs2 = let _1 = _1_inlined2 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 43334 "parsing/parser.ml" +# 43246 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined2_ in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 43343 "parsing/parser.ml" +# 43255 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 1434 "parsing/parser.mly" +# 1439 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Incl.mk thing ~attrs ~loc ~docs, ext ) -# 43357 "parsing/parser.ml" +# 43269 "parsing/parser.ml" in -# 1351 "parsing/parser.mly" +# 1355 "parsing/parser.mly" ( pstr_include _1 ) -# 43363 "parsing/parser.ml" +# 43275 "parsing/parser.ml" in let _endpos__1_ = _endpos__1_inlined2_ in @@ -43367,15 +43279,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 869 "parsing/parser.mly" +# 873 "parsing/parser.mly" ( wrap_mkstr_ext ~loc:_sloc _1 ) -# 43373 "parsing/parser.ml" +# 43285 "parsing/parser.ml" in -# 1353 "parsing/parser.mly" +# 1357 "parsing/parser.mly" ( _1 ) -# 43379 "parsing/parser.ml" +# 43291 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43398,9 +43310,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3637 "parsing/parser.mly" +# 3653 "parsing/parser.mly" ( "-" ) -# 43404 "parsing/parser.ml" +# 43316 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43423,9 +43335,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (string) = -# 3638 "parsing/parser.mly" +# 3654 "parsing/parser.mly" ( "-." ) -# 43429 "parsing/parser.ml" +# 43341 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43478,9 +43390,9 @@ module Tables = struct let _v : (Parsetree.row_field) = let _5 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 43484 "parsing/parser.ml" +# 43396 "parsing/parser.ml" in let _endpos__5_ = _endpos__1_inlined1_ in @@ -43489,18 +43401,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 43493 "parsing/parser.ml" +# 43405 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 43498 "parsing/parser.ml" +# 43410 "parsing/parser.ml" in -# 3349 "parsing/parser.mly" +# 3365 "parsing/parser.mly" ( _1 ) -# 43504 "parsing/parser.ml" +# 43416 "parsing/parser.ml" in let _1 = @@ -43508,20 +43420,20 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 43514 "parsing/parser.ml" +# 43426 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3335 "parsing/parser.mly" +# 3351 "parsing/parser.mly" ( let info = symbol_info _endpos in let attrs = add_info_attrs info _5 in Rf.tag ~loc:(make_loc _sloc) ~attrs _1 _3 _4 ) -# 43525 "parsing/parser.ml" +# 43437 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43553,9 +43465,9 @@ module Tables = struct let _v : (Parsetree.row_field) = let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 43559 "parsing/parser.ml" +# 43471 "parsing/parser.ml" in let _endpos__2_ = _endpos__1_inlined1_ in @@ -43564,20 +43476,20 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 43570 "parsing/parser.ml" +# 43482 "parsing/parser.ml" in let _endpos = _endpos__2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3339 "parsing/parser.mly" +# 3355 "parsing/parser.mly" ( let info = symbol_info _endpos in let attrs = add_info_attrs info _2 in Rf.tag ~loc:(make_loc _sloc) ~attrs _1 true [] ) -# 43581 "parsing/parser.ml" +# 43493 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43609,7 +43521,7 @@ module Tables = struct let _v : (Parsetree.toplevel_phrase) = let arg = # 124 "" ( None ) -# 43613 "parsing/parser.ml" +# 43525 "parsing/parser.ml" in let _endpos_arg_ = _endpos__1_inlined1_ in let dir = @@ -43618,18 +43530,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 43624 "parsing/parser.ml" +# 43536 "parsing/parser.ml" in let _endpos = _endpos_arg_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3537 "parsing/parser.mly" +# 3553 "parsing/parser.mly" ( mk_directive ~loc:_sloc dir arg ) -# 43633 "parsing/parser.ml" +# 43545 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43660,9 +43572,9 @@ module Tables = struct }; } = _menhir_stack in let _1_inlined2 : ( -# 685 "parsing/parser.mly" +# 689 "parsing/parser.mly" (string * Location.t * string option) -# 43666 "parsing/parser.ml" +# 43578 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let _1_inlined1 : (Asttypes.label) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in @@ -43673,23 +43585,23 @@ module Tables = struct let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let x = let _1 = -# 3541 "parsing/parser.mly" +# 3557 "parsing/parser.mly" ( let (s, _, _) = _1 in Pdir_string s ) -# 43679 "parsing/parser.ml" +# 43591 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 874 "parsing/parser.mly" +# 878 "parsing/parser.mly" ( mk_directive_arg ~loc:_sloc _1 ) -# 43687 "parsing/parser.ml" +# 43599 "parsing/parser.ml" in # 126 "" ( Some x ) -# 43693 "parsing/parser.ml" +# 43605 "parsing/parser.ml" in let _endpos_arg_ = _endpos__1_inlined2_ in @@ -43699,18 +43611,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 43705 "parsing/parser.ml" +# 43617 "parsing/parser.ml" in let _endpos = _endpos_arg_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3537 "parsing/parser.mly" +# 3553 "parsing/parser.mly" ( mk_directive ~loc:_sloc dir arg ) -# 43714 "parsing/parser.ml" +# 43626 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43741,9 +43653,9 @@ module Tables = struct }; } = _menhir_stack in let _1_inlined2 : ( -# 633 "parsing/parser.mly" +# 637 "parsing/parser.mly" (string * char option) -# 43747 "parsing/parser.ml" +# 43659 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let _1_inlined1 : (Asttypes.label) = Obj.magic _1_inlined1 in let _1 : unit = Obj.magic _1 in @@ -43754,23 +43666,23 @@ module Tables = struct let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let x = let _1 = -# 3542 "parsing/parser.mly" +# 3558 "parsing/parser.mly" ( let (n, m) = _1 in Pdir_int (n ,m) ) -# 43760 "parsing/parser.ml" +# 43672 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 874 "parsing/parser.mly" +# 878 "parsing/parser.mly" ( mk_directive_arg ~loc:_sloc _1 ) -# 43768 "parsing/parser.ml" +# 43680 "parsing/parser.ml" in # 126 "" ( Some x ) -# 43774 "parsing/parser.ml" +# 43686 "parsing/parser.ml" in let _endpos_arg_ = _endpos__1_inlined2_ in @@ -43780,18 +43692,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 43786 "parsing/parser.ml" +# 43698 "parsing/parser.ml" in let _endpos = _endpos_arg_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3537 "parsing/parser.mly" +# 3553 "parsing/parser.mly" ( mk_directive ~loc:_sloc dir arg ) -# 43795 "parsing/parser.ml" +# 43707 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43831,23 +43743,23 @@ module Tables = struct let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let x = let _1 = -# 3543 "parsing/parser.mly" +# 3559 "parsing/parser.mly" ( Pdir_ident _1 ) -# 43837 "parsing/parser.ml" +# 43749 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 874 "parsing/parser.mly" +# 878 "parsing/parser.mly" ( mk_directive_arg ~loc:_sloc _1 ) -# 43845 "parsing/parser.ml" +# 43757 "parsing/parser.ml" in # 126 "" ( Some x ) -# 43851 "parsing/parser.ml" +# 43763 "parsing/parser.ml" in let _endpos_arg_ = _endpos__1_inlined2_ in @@ -43857,18 +43769,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 43863 "parsing/parser.ml" +# 43775 "parsing/parser.ml" in let _endpos = _endpos_arg_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3537 "parsing/parser.mly" +# 3553 "parsing/parser.mly" ( mk_directive ~loc:_sloc dir arg ) -# 43872 "parsing/parser.ml" +# 43784 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43908,23 +43820,23 @@ module Tables = struct let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let x = let _1 = -# 3544 "parsing/parser.mly" +# 3560 "parsing/parser.mly" ( Pdir_ident _1 ) -# 43914 "parsing/parser.ml" +# 43826 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 874 "parsing/parser.mly" +# 878 "parsing/parser.mly" ( mk_directive_arg ~loc:_sloc _1 ) -# 43922 "parsing/parser.ml" +# 43834 "parsing/parser.ml" in # 126 "" ( Some x ) -# 43928 "parsing/parser.ml" +# 43840 "parsing/parser.ml" in let _endpos_arg_ = _endpos__1_inlined2_ in @@ -43934,18 +43846,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 43940 "parsing/parser.ml" +# 43852 "parsing/parser.ml" in let _endpos = _endpos_arg_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3537 "parsing/parser.mly" +# 3553 "parsing/parser.mly" ( mk_directive ~loc:_sloc dir arg ) -# 43949 "parsing/parser.ml" +# 43861 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -43985,23 +43897,23 @@ module Tables = struct let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let x = let _1 = -# 3545 "parsing/parser.mly" +# 3561 "parsing/parser.mly" ( Pdir_bool false ) -# 43991 "parsing/parser.ml" +# 43903 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 874 "parsing/parser.mly" +# 878 "parsing/parser.mly" ( mk_directive_arg ~loc:_sloc _1 ) -# 43999 "parsing/parser.ml" +# 43911 "parsing/parser.ml" in # 126 "" ( Some x ) -# 44005 "parsing/parser.ml" +# 43917 "parsing/parser.ml" in let _endpos_arg_ = _endpos__1_inlined2_ in @@ -44011,18 +43923,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 44017 "parsing/parser.ml" +# 43929 "parsing/parser.ml" in let _endpos = _endpos_arg_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3537 "parsing/parser.mly" +# 3553 "parsing/parser.mly" ( mk_directive ~loc:_sloc dir arg ) -# 44026 "parsing/parser.ml" +# 43938 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44062,23 +43974,23 @@ module Tables = struct let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let x = let _1 = -# 3546 "parsing/parser.mly" +# 3562 "parsing/parser.mly" ( Pdir_bool true ) -# 44068 "parsing/parser.ml" +# 43980 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 874 "parsing/parser.mly" +# 878 "parsing/parser.mly" ( mk_directive_arg ~loc:_sloc _1 ) -# 44076 "parsing/parser.ml" +# 43988 "parsing/parser.ml" in # 126 "" ( Some x ) -# 44082 "parsing/parser.ml" +# 43994 "parsing/parser.ml" in let _endpos_arg_ = _endpos__1_inlined2_ in @@ -44088,18 +44000,18 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 44094 "parsing/parser.ml" +# 44006 "parsing/parser.ml" in let _endpos = _endpos_arg_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3537 "parsing/parser.mly" +# 3553 "parsing/parser.mly" ( mk_directive ~loc:_sloc dir arg ) -# 44103 "parsing/parser.ml" +# 44015 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44136,44 +44048,44 @@ module Tables = struct let _startpos = _startpos_e_ in let _endpos = _endpos__2_ in let _v : ( -# 781 "parsing/parser.mly" +# 785 "parsing/parser.mly" (Parsetree.toplevel_phrase) -# 44142 "parsing/parser.ml" +# 44054 "parsing/parser.ml" ) = let _1 = let _1 = let _1 = let attrs = -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 44149 "parsing/parser.ml" +# 44061 "parsing/parser.ml" in -# 1304 "parsing/parser.mly" +# 1308 "parsing/parser.mly" ( mkstrexp e attrs ) -# 44154 "parsing/parser.ml" +# 44066 "parsing/parser.ml" in let _startpos__1_ = _startpos_e_ in let _startpos = _startpos__1_ in -# 817 "parsing/parser.mly" +# 821 "parsing/parser.mly" ( text_str _startpos @ [_1] ) -# 44162 "parsing/parser.ml" +# 44074 "parsing/parser.ml" in let _startpos__1_ = _startpos_e_ in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 805 "parsing/parser.mly" +# 809 "parsing/parser.mly" ( extra_str _startpos _endpos _1 ) -# 44171 "parsing/parser.ml" +# 44083 "parsing/parser.ml" in -# 1082 "parsing/parser.mly" +# 1086 "parsing/parser.mly" ( Ptop_def _1 ) -# 44177 "parsing/parser.ml" +# 44089 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44203,28 +44115,28 @@ module Tables = struct let _startpos = _startpos_xss_ in let _endpos = _endpos__2_ in let _v : ( -# 781 "parsing/parser.mly" +# 785 "parsing/parser.mly" (Parsetree.toplevel_phrase) -# 44209 "parsing/parser.ml" +# 44121 "parsing/parser.ml" ) = let _1 = let _1 = # 260 "" ( List.flatten xss ) -# 44214 "parsing/parser.ml" +# 44126 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_xss_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 805 "parsing/parser.mly" +# 809 "parsing/parser.mly" ( extra_str _startpos _endpos _1 ) -# 44222 "parsing/parser.ml" +# 44134 "parsing/parser.ml" in -# 1086 "parsing/parser.mly" +# 1090 "parsing/parser.mly" ( Ptop_def _1 ) -# 44228 "parsing/parser.ml" +# 44140 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44254,13 +44166,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : ( -# 781 "parsing/parser.mly" +# 785 "parsing/parser.mly" (Parsetree.toplevel_phrase) -# 44260 "parsing/parser.ml" +# 44172 "parsing/parser.ml" ) = -# 1090 "parsing/parser.mly" +# 1094 "parsing/parser.mly" ( _1 ) -# 44264 "parsing/parser.ml" +# 44176 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44283,13 +44195,13 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : ( -# 781 "parsing/parser.mly" +# 785 "parsing/parser.mly" (Parsetree.toplevel_phrase) -# 44289 "parsing/parser.ml" +# 44201 "parsing/parser.ml" ) = -# 1093 "parsing/parser.mly" +# 1097 "parsing/parser.mly" ( raise End_of_file ) -# 44293 "parsing/parser.ml" +# 44205 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44312,9 +44224,9 @@ module Tables = struct let _startpos = _startpos_ty_ in let _endpos = _endpos_ty_ in let _v : (Parsetree.core_type) = -# 3241 "parsing/parser.mly" +# 3257 "parsing/parser.mly" ( ty ) -# 44318 "parsing/parser.ml" +# 44230 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44342,18 +44254,18 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 44346 "parsing/parser.ml" +# 44258 "parsing/parser.ml" in -# 975 "parsing/parser.mly" +# 979 "parsing/parser.mly" ( xs ) -# 44351 "parsing/parser.ml" +# 44263 "parsing/parser.ml" in -# 3244 "parsing/parser.mly" +# 3260 "parsing/parser.mly" ( Ptyp_tuple tys ) -# 44357 "parsing/parser.ml" +# 44269 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xs_, _startpos_xs_) in @@ -44361,15 +44273,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 44367 "parsing/parser.ml" +# 44279 "parsing/parser.ml" in -# 3246 "parsing/parser.mly" +# 3262 "parsing/parser.mly" ( _1 ) -# 44373 "parsing/parser.ml" +# 44285 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44399,9 +44311,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.core_type option * Parsetree.core_type option) = -# 2589 "parsing/parser.mly" +# 2591 "parsing/parser.mly" ( (Some _2, None) ) -# 44405 "parsing/parser.ml" +# 44317 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44445,9 +44357,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : (Parsetree.core_type option * Parsetree.core_type option) = -# 2590 "parsing/parser.mly" +# 2592 "parsing/parser.mly" ( (Some _2, Some _4) ) -# 44451 "parsing/parser.ml" +# 44363 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44477,9 +44389,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.core_type option * Parsetree.core_type option) = -# 2591 "parsing/parser.mly" +# 2593 "parsing/parser.mly" ( (None, Some _2) ) -# 44483 "parsing/parser.ml" +# 44395 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44509,9 +44421,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.core_type option * Parsetree.core_type option) = -# 2592 "parsing/parser.mly" +# 2594 "parsing/parser.mly" ( syntax_error() ) -# 44515 "parsing/parser.ml" +# 44427 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44541,9 +44453,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.core_type option * Parsetree.core_type option) = -# 2593 "parsing/parser.mly" +# 2595 "parsing/parser.mly" ( syntax_error() ) -# 44547 "parsing/parser.ml" +# 44459 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44559,9 +44471,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = -# 2916 "parsing/parser.mly" +# 2921 "parsing/parser.mly" ( (Ptype_abstract, Public, None) ) -# 44565 "parsing/parser.ml" +# 44477 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44591,9 +44503,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Parsetree.type_kind * Asttypes.private_flag * Parsetree.core_type option) = -# 2918 "parsing/parser.mly" +# 2923 "parsing/parser.mly" ( _2 ) -# 44597 "parsing/parser.ml" +# 44509 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44616,9 +44528,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3500 "parsing/parser.mly" +# 3516 "parsing/parser.mly" ( _1 ) -# 44622 "parsing/parser.ml" +# 44534 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44643,14 +44555,14 @@ module Tables = struct }; } = _menhir_stack in let _2 : (Parsetree.core_type) = Obj.magic _2 in - let _1 : (Asttypes.variance) = Obj.magic _1 in + let _1 : (Asttypes.variance * Asttypes.injectivity) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in - let _v : (Parsetree.core_type * Asttypes.variance) = -# 2933 "parsing/parser.mly" + let _v : (Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) = +# 2938 "parsing/parser.mly" ( _2, _1 ) -# 44654 "parsing/parser.ml" +# 44566 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44665,10 +44577,10 @@ module Tables = struct let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in - let _v : ((Parsetree.core_type * Asttypes.variance) list) = -# 2926 "parsing/parser.mly" + let _v : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = +# 2931 "parsing/parser.mly" ( [] ) -# 44672 "parsing/parser.ml" +# 44584 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44686,14 +44598,14 @@ module Tables = struct MenhirLib.EngineTypes.endp = _endpos_p_; MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in - let p : (Parsetree.core_type * Asttypes.variance) = Obj.magic p in + let p : (Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) = Obj.magic p in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos_p_ in let _endpos = _endpos_p_ in - let _v : ((Parsetree.core_type * Asttypes.variance) list) = -# 2928 "parsing/parser.mly" + let _v : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = +# 2933 "parsing/parser.mly" ( [p] ) -# 44697 "parsing/parser.ml" +# 44609 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44724,27 +44636,27 @@ module Tables = struct }; } = _menhir_stack in let _3 : unit = Obj.magic _3 in - let xs : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic xs in + let xs : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic xs in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in - let _v : ((Parsetree.core_type * Asttypes.variance) list) = let ps = + let _v : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = let ps = let xs = # 253 "" ( List.rev xs ) -# 44737 "parsing/parser.ml" +# 44649 "parsing/parser.ml" in -# 947 "parsing/parser.mly" +# 951 "parsing/parser.mly" ( xs ) -# 44742 "parsing/parser.ml" +# 44654 "parsing/parser.ml" in -# 2930 "parsing/parser.mly" +# 2935 "parsing/parser.mly" ( ps ) -# 44748 "parsing/parser.ml" +# 44660 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44775,24 +44687,132 @@ module Tables = struct let _endpos = _endpos_tyvar_ in let _v : (Parsetree.core_type) = let _1 = let _1 = -# 2938 "parsing/parser.mly" +# 2943 "parsing/parser.mly" ( Ptyp_var tyvar ) -# 44781 "parsing/parser.ml" +# 44693 "parsing/parser.ml" in let _endpos__1_ = _endpos_tyvar_ in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 850 "parsing/parser.mly" +# 854 "parsing/parser.mly" ( mktyp ~loc:_sloc _1 ) -# 44790 "parsing/parser.ml" +# 44702 "parsing/parser.ml" in -# 2941 "parsing/parser.mly" +# 2946 "parsing/parser.mly" ( _1 ) -# 44796 "parsing/parser.ml" +# 44708 "parsing/parser.ml" + in + { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = Obj.repr _v; + MenhirLib.EngineTypes.startp = _startpos; + MenhirLib.EngineTypes.endp = _endpos; + MenhirLib.EngineTypes.next = _menhir_stack; + }); + (fun _menhir_env -> + let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in + let { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = _1; + MenhirLib.EngineTypes.startp = _startpos__1_; + MenhirLib.EngineTypes.endp = _endpos__1_; + MenhirLib.EngineTypes.next = _menhir_stack; + } = _menhir_stack in + let _1 : unit = Obj.magic _1 in + let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in + let _startpos = _startpos__1_ in + let _endpos = _endpos__1_ in + let _v : (Parsetree.core_type) = let _1 = + let _1 = +# 2945 "parsing/parser.mly" + ( Ptyp_any ) +# 44734 "parsing/parser.ml" + in + let _endpos = _endpos__1_ in + let _symbolstartpos = _startpos__1_ in + let _sloc = (_symbolstartpos, _endpos) in + +# 854 "parsing/parser.mly" + ( mktyp ~loc:_sloc _1 ) +# 44742 "parsing/parser.ml" + + in + +# 2946 "parsing/parser.mly" + ( _1 ) +# 44748 "parsing/parser.ml" + in + { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = Obj.repr _v; + MenhirLib.EngineTypes.startp = _startpos; + MenhirLib.EngineTypes.endp = _endpos; + MenhirLib.EngineTypes.next = _menhir_stack; + }); + (fun _menhir_env -> + let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in + let _menhir_s = _menhir_env.MenhirLib.EngineTypes.current in + let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in + let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in + let _endpos = _startpos in + let _v : (Asttypes.variance * Asttypes.injectivity) = +# 2950 "parsing/parser.mly" + ( NoVariance, NoInjectivity ) +# 44766 "parsing/parser.ml" + in + { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = Obj.repr _v; + MenhirLib.EngineTypes.startp = _startpos; + MenhirLib.EngineTypes.endp = _endpos; + MenhirLib.EngineTypes.next = _menhir_stack; + }); + (fun _menhir_env -> + let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in + let { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = _1; + MenhirLib.EngineTypes.startp = _startpos__1_; + MenhirLib.EngineTypes.endp = _endpos__1_; + MenhirLib.EngineTypes.next = _menhir_stack; + } = _menhir_stack in + let _1 : unit = Obj.magic _1 in + let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in + let _startpos = _startpos__1_ in + let _endpos = _endpos__1_ in + let _v : (Asttypes.variance * Asttypes.injectivity) = +# 2951 "parsing/parser.mly" + ( Covariant, NoInjectivity ) +# 44791 "parsing/parser.ml" + in + { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = Obj.repr _v; + MenhirLib.EngineTypes.startp = _startpos; + MenhirLib.EngineTypes.endp = _endpos; + MenhirLib.EngineTypes.next = _menhir_stack; + }); + (fun _menhir_env -> + let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in + let { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = _1; + MenhirLib.EngineTypes.startp = _startpos__1_; + MenhirLib.EngineTypes.endp = _endpos__1_; + MenhirLib.EngineTypes.next = _menhir_stack; + } = _menhir_stack in + let _1 : unit = Obj.magic _1 in + let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in + let _startpos = _startpos__1_ in + let _endpos = _endpos__1_ in + let _v : (Asttypes.variance * Asttypes.injectivity) = +# 2952 "parsing/parser.mly" + ( Contravariant, NoInjectivity ) +# 44816 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44814,25 +44834,10 @@ module Tables = struct let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in - let _v : (Parsetree.core_type) = let _1 = - let _1 = -# 2940 "parsing/parser.mly" - ( Ptyp_any ) -# 44822 "parsing/parser.ml" - in - let _endpos = _endpos__1_ in - let _symbolstartpos = _startpos__1_ in - let _sloc = (_symbolstartpos, _endpos) in - -# 850 "parsing/parser.mly" - ( mktyp ~loc:_sloc _1 ) -# 44830 "parsing/parser.ml" - - in - -# 2941 "parsing/parser.mly" - ( _1 ) -# 44836 "parsing/parser.ml" + let _v : (Asttypes.variance * Asttypes.injectivity) = +# 2953 "parsing/parser.mly" + ( NoVariance, Injective ) +# 44841 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44843,14 +44848,124 @@ module Tables = struct }); (fun _menhir_env -> let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in - let _menhir_s = _menhir_env.MenhirLib.EngineTypes.current in + let { + MenhirLib.EngineTypes.state = _; + MenhirLib.EngineTypes.semv = _2; + MenhirLib.EngineTypes.startp = _startpos__2_; + MenhirLib.EngineTypes.endp = _endpos__2_; + MenhirLib.EngineTypes.next = { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = _1; + MenhirLib.EngineTypes.startp = _startpos__1_; + MenhirLib.EngineTypes.endp = _endpos__1_; + MenhirLib.EngineTypes.next = _menhir_stack; + }; + } = _menhir_stack in + let _2 : unit = Obj.magic _2 in + let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in - let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in - let _endpos = _startpos in - let _v : (Asttypes.variance) = -# 2945 "parsing/parser.mly" - ( Invariant ) -# 44854 "parsing/parser.ml" + let _startpos = _startpos__1_ in + let _endpos = _endpos__2_ in + let _v : (Asttypes.variance * Asttypes.injectivity) = +# 2954 "parsing/parser.mly" + ( Covariant, Injective ) +# 44873 "parsing/parser.ml" + in + { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = Obj.repr _v; + MenhirLib.EngineTypes.startp = _startpos; + MenhirLib.EngineTypes.endp = _endpos; + MenhirLib.EngineTypes.next = _menhir_stack; + }); + (fun _menhir_env -> + let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in + let { + MenhirLib.EngineTypes.state = _; + MenhirLib.EngineTypes.semv = _2; + MenhirLib.EngineTypes.startp = _startpos__2_; + MenhirLib.EngineTypes.endp = _endpos__2_; + MenhirLib.EngineTypes.next = { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = _1; + MenhirLib.EngineTypes.startp = _startpos__1_; + MenhirLib.EngineTypes.endp = _endpos__1_; + MenhirLib.EngineTypes.next = _menhir_stack; + }; + } = _menhir_stack in + let _2 : unit = Obj.magic _2 in + let _1 : unit = Obj.magic _1 in + let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in + let _startpos = _startpos__1_ in + let _endpos = _endpos__2_ in + let _v : (Asttypes.variance * Asttypes.injectivity) = +# 2954 "parsing/parser.mly" + ( Covariant, Injective ) +# 44905 "parsing/parser.ml" + in + { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = Obj.repr _v; + MenhirLib.EngineTypes.startp = _startpos; + MenhirLib.EngineTypes.endp = _endpos; + MenhirLib.EngineTypes.next = _menhir_stack; + }); + (fun _menhir_env -> + let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in + let { + MenhirLib.EngineTypes.state = _; + MenhirLib.EngineTypes.semv = _2; + MenhirLib.EngineTypes.startp = _startpos__2_; + MenhirLib.EngineTypes.endp = _endpos__2_; + MenhirLib.EngineTypes.next = { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = _1; + MenhirLib.EngineTypes.startp = _startpos__1_; + MenhirLib.EngineTypes.endp = _endpos__1_; + MenhirLib.EngineTypes.next = _menhir_stack; + }; + } = _menhir_stack in + let _2 : unit = Obj.magic _2 in + let _1 : unit = Obj.magic _1 in + let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in + let _startpos = _startpos__1_ in + let _endpos = _endpos__2_ in + let _v : (Asttypes.variance * Asttypes.injectivity) = +# 2955 "parsing/parser.mly" + ( Contravariant, Injective ) +# 44937 "parsing/parser.ml" + in + { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = Obj.repr _v; + MenhirLib.EngineTypes.startp = _startpos; + MenhirLib.EngineTypes.endp = _endpos; + MenhirLib.EngineTypes.next = _menhir_stack; + }); + (fun _menhir_env -> + let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in + let { + MenhirLib.EngineTypes.state = _; + MenhirLib.EngineTypes.semv = _2; + MenhirLib.EngineTypes.startp = _startpos__2_; + MenhirLib.EngineTypes.endp = _endpos__2_; + MenhirLib.EngineTypes.next = { + MenhirLib.EngineTypes.state = _menhir_s; + MenhirLib.EngineTypes.semv = _1; + MenhirLib.EngineTypes.startp = _startpos__1_; + MenhirLib.EngineTypes.endp = _endpos__1_; + MenhirLib.EngineTypes.next = _menhir_stack; + }; + } = _menhir_stack in + let _2 : unit = Obj.magic _2 in + let _1 : unit = Obj.magic _1 in + let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in + let _startpos = _startpos__1_ in + let _endpos = _endpos__2_ in + let _v : (Asttypes.variance * Asttypes.injectivity) = +# 2955 "parsing/parser.mly" + ( Contravariant, Injective ) +# 44969 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44868,14 +44983,21 @@ module Tables = struct MenhirLib.EngineTypes.endp = _endpos__1_; MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in - let _1 : unit = Obj.magic _1 in + let _1 : ( +# 629 "parsing/parser.mly" + (string) +# 44990 "parsing/parser.ml" + ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in - let _v : (Asttypes.variance) = -# 2946 "parsing/parser.mly" - ( Covariant ) -# 44879 "parsing/parser.ml" + let _v : (Asttypes.variance * Asttypes.injectivity) = let _loc__1_ = (_startpos__1_, _endpos__1_) in + +# 2957 "parsing/parser.mly" + ( if _1 = "+!" then Covariant, Injective else + if _1 = "-!" then Contravariant, Injective else + expecting _loc__1_ "type_variance" ) +# 45001 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44893,14 +45015,21 @@ module Tables = struct MenhirLib.EngineTypes.endp = _endpos__1_; MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in - let _1 : unit = Obj.magic _1 in + let _1 : ( +# 675 "parsing/parser.mly" + (string) +# 45022 "parsing/parser.ml" + ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in - let _v : (Asttypes.variance) = -# 2947 "parsing/parser.mly" - ( Contravariant ) -# 44904 "parsing/parser.ml" + let _v : (Asttypes.variance * Asttypes.injectivity) = let _loc__1_ = (_startpos__1_, _endpos__1_) in + +# 2961 "parsing/parser.mly" + ( if _1 = "!+" then Covariant, Injective else + if _1 = "!-" then Contravariant, Injective else + expecting _loc__1_ "type_variance" ) +# 45033 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -44930,47 +45059,47 @@ module Tables = struct let _startpos = _startpos_xss_ in let _endpos = _endpos__2_ in let _v : ( -# 783 "parsing/parser.mly" +# 787 "parsing/parser.mly" (Parsetree.toplevel_phrase list) -# 44936 "parsing/parser.ml" +# 45065 "parsing/parser.ml" ) = let _1 = let _1 = let ys = # 260 "" ( List.flatten xss ) -# 44942 "parsing/parser.ml" +# 45071 "parsing/parser.ml" in let xs = let _1 = -# 883 "parsing/parser.mly" +# 887 "parsing/parser.mly" ( [] ) -# 44948 "parsing/parser.ml" +# 45077 "parsing/parser.ml" in -# 1113 "parsing/parser.mly" +# 1117 "parsing/parser.mly" ( _1 ) -# 44953 "parsing/parser.ml" +# 45082 "parsing/parser.ml" in # 267 "" ( xs @ ys ) -# 44959 "parsing/parser.ml" +# 45088 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_xss_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 809 "parsing/parser.mly" +# 813 "parsing/parser.mly" ( extra_def _startpos _endpos _1 ) -# 44968 "parsing/parser.ml" +# 45097 "parsing/parser.ml" in -# 1106 "parsing/parser.mly" +# 1110 "parsing/parser.mly" ( _1 ) -# 44974 "parsing/parser.ml" +# 45103 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45014,15 +45143,15 @@ module Tables = struct let _startpos = _startpos_e_ in let _endpos = _endpos__2_ in let _v : ( -# 783 "parsing/parser.mly" +# 787 "parsing/parser.mly" (Parsetree.toplevel_phrase list) -# 45020 "parsing/parser.ml" +# 45149 "parsing/parser.ml" ) = let _1 = let _1 = let ys = # 260 "" ( List.flatten xss ) -# 45026 "parsing/parser.ml" +# 45155 "parsing/parser.ml" in let xs = let _1 = @@ -45030,61 +45159,61 @@ module Tables = struct let _1 = let _1 = let attrs = -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 45036 "parsing/parser.ml" +# 45165 "parsing/parser.ml" in -# 1304 "parsing/parser.mly" +# 1308 "parsing/parser.mly" ( mkstrexp e attrs ) -# 45041 "parsing/parser.ml" +# 45170 "parsing/parser.ml" in -# 827 "parsing/parser.mly" +# 831 "parsing/parser.mly" ( Ptop_def [_1] ) -# 45047 "parsing/parser.ml" +# 45176 "parsing/parser.ml" in let _startpos__1_ = _startpos_e_ in let _startpos = _startpos__1_ in -# 825 "parsing/parser.mly" +# 829 "parsing/parser.mly" ( text_def _startpos @ [_1] ) -# 45055 "parsing/parser.ml" +# 45184 "parsing/parser.ml" in -# 885 "parsing/parser.mly" +# 889 "parsing/parser.mly" ( x ) -# 45061 "parsing/parser.ml" +# 45190 "parsing/parser.ml" in -# 1113 "parsing/parser.mly" +# 1117 "parsing/parser.mly" ( _1 ) -# 45067 "parsing/parser.ml" +# 45196 "parsing/parser.ml" in # 267 "" ( xs @ ys ) -# 45073 "parsing/parser.ml" +# 45202 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos_xss_, _startpos_e_) in let _endpos = _endpos__1_ in let _startpos = _startpos__1_ in -# 809 "parsing/parser.mly" +# 813 "parsing/parser.mly" ( extra_def _startpos _endpos _1 ) -# 45082 "parsing/parser.ml" +# 45211 "parsing/parser.ml" in -# 1106 "parsing/parser.mly" +# 1110 "parsing/parser.mly" ( _1 ) -# 45088 "parsing/parser.ml" +# 45217 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45121,9 +45250,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : (Asttypes.label) = -# 3419 "parsing/parser.mly" +# 3435 "parsing/parser.mly" ( _2 ) -# 45127 "parsing/parser.ml" +# 45256 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45162,9 +45291,9 @@ module Tables = struct let _v : (Asttypes.label) = let _loc__3_ = (_startpos__3_, _endpos__3_) in let _loc__1_ = (_startpos__1_, _endpos__1_) in -# 3420 "parsing/parser.mly" +# 3436 "parsing/parser.mly" ( unclosed "(" _loc__1_ ")" _loc__3_ ) -# 45168 "parsing/parser.ml" +# 45297 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45195,9 +45324,9 @@ module Tables = struct let _endpos = _endpos__2_ in let _v : (Asttypes.label) = let _loc__2_ = (_startpos__2_, _endpos__2_) in -# 3421 "parsing/parser.mly" +# 3437 "parsing/parser.mly" ( expecting _loc__2_ "operator" ) -# 45201 "parsing/parser.ml" +# 45330 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45235,9 +45364,9 @@ module Tables = struct let _endpos = _endpos__3_ in let _v : (Asttypes.label) = let _loc__3_ = (_startpos__3_, _endpos__3_) in -# 3422 "parsing/parser.mly" +# 3438 "parsing/parser.mly" ( expecting _loc__3_ "module-expr" ) -# 45241 "parsing/parser.ml" +# 45370 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45256,17 +45385,17 @@ module Tables = struct MenhirLib.EngineTypes.next = _menhir_stack; } = _menhir_stack in let _1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 45262 "parsing/parser.ml" +# 45391 "parsing/parser.ml" ) = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3425 "parsing/parser.mly" +# 3441 "parsing/parser.mly" ( _1 ) -# 45270 "parsing/parser.ml" +# 45399 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45289,9 +45418,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.label) = -# 3426 "parsing/parser.mly" +# 3442 "parsing/parser.mly" ( _1 ) -# 45295 "parsing/parser.ml" +# 45424 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45314,9 +45443,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Longident.t) = -# 3494 "parsing/parser.mly" +# 3510 "parsing/parser.mly" ( _1 ) -# 45320 "parsing/parser.ml" +# 45449 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45361,9 +45490,9 @@ module Tables = struct let ty : (Parsetree.core_type) = Obj.magic ty in let _5 : unit = Obj.magic _5 in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 45367 "parsing/parser.ml" +# 45496 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let mutable_ : (Asttypes.mutable_flag) = Obj.magic mutable_ in let _1 : (Parsetree.attributes) = Obj.magic _1 in @@ -45375,33 +45504,33 @@ module Tables = struct Parsetree.attributes) = let label = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 45381 "parsing/parser.ml" +# 45510 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 45389 "parsing/parser.ml" +# 45518 "parsing/parser.ml" in let attrs = -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 45395 "parsing/parser.ml" +# 45524 "parsing/parser.ml" in let _1 = -# 3630 "parsing/parser.mly" +# 3646 "parsing/parser.mly" ( Fresh ) -# 45400 "parsing/parser.ml" +# 45529 "parsing/parser.ml" in -# 1855 "parsing/parser.mly" +# 1861 "parsing/parser.mly" ( (label, mutable_, Cfk_virtual ty), attrs ) -# 45405 "parsing/parser.ml" +# 45534 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45446,9 +45575,9 @@ module Tables = struct let _6 : (Parsetree.expression) = Obj.magic _6 in let _5 : unit = Obj.magic _5 in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 45452 "parsing/parser.ml" +# 45581 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _3 : (Asttypes.mutable_flag) = Obj.magic _3 in let _1 : (Parsetree.attributes) = Obj.magic _1 in @@ -45460,33 +45589,33 @@ module Tables = struct Parsetree.attributes) = let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 45466 "parsing/parser.ml" +# 45595 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 45474 "parsing/parser.ml" +# 45603 "parsing/parser.ml" in let _2 = -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 45480 "parsing/parser.ml" +# 45609 "parsing/parser.ml" in let _1 = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 45485 "parsing/parser.ml" +# 45614 "parsing/parser.ml" in -# 1857 "parsing/parser.mly" +# 1863 "parsing/parser.mly" ( (_4, _3, Cfk_concrete (_1, _6)), _2 ) -# 45490 "parsing/parser.ml" +# 45619 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45537,9 +45666,9 @@ module Tables = struct let _6 : (Parsetree.expression) = Obj.magic _6 in let _5 : unit = Obj.magic _5 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 45543 "parsing/parser.ml" +# 45672 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let _3 : (Asttypes.mutable_flag) = Obj.magic _3 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in @@ -45552,36 +45681,36 @@ module Tables = struct Parsetree.attributes) = let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 45558 "parsing/parser.ml" +# 45687 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 45566 "parsing/parser.ml" +# 45695 "parsing/parser.ml" in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 45574 "parsing/parser.ml" +# 45703 "parsing/parser.ml" in let _1 = -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 45580 "parsing/parser.ml" +# 45709 "parsing/parser.ml" in -# 1857 "parsing/parser.mly" +# 1863 "parsing/parser.mly" ( (_4, _3, Cfk_concrete (_1, _6)), _2 ) -# 45585 "parsing/parser.ml" +# 45714 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45633,9 +45762,9 @@ module Tables = struct let _6 : unit = Obj.magic _6 in let _5 : (Parsetree.core_type option * Parsetree.core_type option) = Obj.magic _5 in let _1_inlined1 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 45639 "parsing/parser.ml" +# 45768 "parsing/parser.ml" ) = Obj.magic _1_inlined1 in let _3 : (Asttypes.mutable_flag) = Obj.magic _3 in let _1 : (Parsetree.attributes) = Obj.magic _1 in @@ -45647,30 +45776,30 @@ module Tables = struct Parsetree.attributes) = let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined1_, _startpos__1_inlined1_, _1_inlined1) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 45653 "parsing/parser.ml" +# 45782 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 45661 "parsing/parser.ml" +# 45790 "parsing/parser.ml" in let _startpos__4_ = _startpos__1_inlined1_ in let _2 = -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 45668 "parsing/parser.ml" +# 45797 "parsing/parser.ml" in let (_endpos__2_, _startpos__2_) = (_endpos__1_, _startpos__1_) in let _1 = -# 3633 "parsing/parser.mly" +# 3649 "parsing/parser.mly" ( Fresh ) -# 45674 "parsing/parser.ml" +# 45803 "parsing/parser.ml" in let (_endpos__1_, _startpos__1_) = (_endpos__0_, _endpos__0_) in let _endpos = _endpos__7_ in @@ -45686,11 +45815,11 @@ module Tables = struct _startpos__4_ in let _sloc = (_symbolstartpos, _endpos) in -# 1860 "parsing/parser.mly" +# 1866 "parsing/parser.mly" ( let e = mkexp_constraint ~loc:_sloc _7 _5 in (_4, _3, Cfk_concrete (_1, e)), _2 ) -# 45694 "parsing/parser.ml" +# 45823 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45748,9 +45877,9 @@ module Tables = struct let _6 : unit = Obj.magic _6 in let _5 : (Parsetree.core_type option * Parsetree.core_type option) = Obj.magic _5 in let _1_inlined2 : ( -# 647 "parsing/parser.mly" +# 651 "parsing/parser.mly" (string) -# 45754 "parsing/parser.ml" +# 45883 "parsing/parser.ml" ) = Obj.magic _1_inlined2 in let _3 : (Asttypes.mutable_flag) = Obj.magic _3 in let _1_inlined1 : (Parsetree.attributes) = Obj.magic _1_inlined1 in @@ -45763,33 +45892,33 @@ module Tables = struct Parsetree.attributes) = let _4 = let (_endpos__1_, _startpos__1_, _1) = (_endpos__1_inlined2_, _startpos__1_inlined2_, _1_inlined2) in let _1 = -# 3393 "parsing/parser.mly" +# 3409 "parsing/parser.mly" ( _1 ) -# 45769 "parsing/parser.ml" +# 45898 "parsing/parser.ml" in let _endpos = _endpos__1_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 45777 "parsing/parser.ml" +# 45906 "parsing/parser.ml" in let _startpos__4_ = _startpos__1_inlined2_ in let _2 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 45786 "parsing/parser.ml" +# 45915 "parsing/parser.ml" in let (_endpos__2_, _startpos__2_) = (_endpos__1_inlined1_, _startpos__1_inlined1_) in let _1 = -# 3634 "parsing/parser.mly" +# 3650 "parsing/parser.mly" ( Override ) -# 45793 "parsing/parser.ml" +# 45922 "parsing/parser.ml" in let _endpos = _endpos__7_ in let _symbolstartpos = if _startpos__1_ != _endpos__1_ then @@ -45804,11 +45933,11 @@ module Tables = struct _startpos__4_ in let _sloc = (_symbolstartpos, _endpos) in -# 1860 "parsing/parser.mly" +# 1866 "parsing/parser.mly" ( let e = mkexp_constraint ~loc:_sloc _7 _5 in (_4, _3, Cfk_concrete (_1, e)), _2 ) -# 45812 "parsing/parser.ml" +# 45941 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45875,9 +46004,9 @@ module Tables = struct let _v : (Parsetree.value_description * string Asttypes.loc option) = let attrs2 = let _1 = _1_inlined3 in -# 3727 "parsing/parser.mly" +# 3743 "parsing/parser.mly" ( _1 ) -# 45881 "parsing/parser.ml" +# 46010 "parsing/parser.ml" in let _endpos_attrs2_ = _endpos__1_inlined3_ in @@ -45887,30 +46016,30 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 45893 "parsing/parser.ml" +# 46022 "parsing/parser.ml" in let attrs1 = let _1 = _1_inlined1 in -# 3731 "parsing/parser.mly" +# 3747 "parsing/parser.mly" ( _1 ) -# 45901 "parsing/parser.ml" +# 46030 "parsing/parser.ml" in let _endpos = _endpos_attrs2_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 2787 "parsing/parser.mly" +# 2792 "parsing/parser.mly" ( let attrs = attrs1 @ attrs2 in let loc = make_loc _sloc in let docs = symbol_docs _sloc in Val.mk id ty ~attrs ~loc ~docs, ext ) -# 45914 "parsing/parser.ml" +# 46043 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45926,9 +46055,9 @@ module Tables = struct let _startpos = _menhir_stack.MenhirLib.EngineTypes.endp in let _endpos = _startpos in let _v : (Asttypes.virtual_flag) = -# 3594 "parsing/parser.mly" +# 3610 "parsing/parser.mly" ( Concrete ) -# 45932 "parsing/parser.ml" +# 46061 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45951,9 +46080,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.virtual_flag) = -# 3595 "parsing/parser.mly" +# 3611 "parsing/parser.mly" ( Virtual ) -# 45957 "parsing/parser.ml" +# 46086 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -45976,9 +46105,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.mutable_flag) = -# 3618 "parsing/parser.mly" +# 3634 "parsing/parser.mly" ( Immutable ) -# 45982 "parsing/parser.ml" +# 46111 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46008,9 +46137,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.mutable_flag) = -# 3619 "parsing/parser.mly" +# 3635 "parsing/parser.mly" ( Mutable ) -# 46014 "parsing/parser.ml" +# 46143 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46040,9 +46169,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.mutable_flag) = -# 3620 "parsing/parser.mly" +# 3636 "parsing/parser.mly" ( Mutable ) -# 46046 "parsing/parser.ml" +# 46175 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46065,9 +46194,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.private_flag) = -# 3625 "parsing/parser.mly" +# 3641 "parsing/parser.mly" ( Public ) -# 46071 "parsing/parser.ml" +# 46200 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46097,9 +46226,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.private_flag) = -# 3626 "parsing/parser.mly" +# 3642 "parsing/parser.mly" ( Private ) -# 46103 "parsing/parser.ml" +# 46232 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46129,9 +46258,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.private_flag) = -# 3627 "parsing/parser.mly" +# 3643 "parsing/parser.mly" ( Private ) -# 46135 "parsing/parser.ml" +# 46264 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46183,7 +46312,7 @@ module Tables = struct let _1_inlined2 : (Parsetree.core_type) = Obj.magic _1_inlined2 in let _4 : (Asttypes.private_flag) = Obj.magic _4 in let _1_inlined1 : (Longident.t) = Obj.magic _1_inlined1 in - let _2 : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic _2 in + let _2 : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic _2 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -46193,27 +46322,27 @@ module Tables = struct let xs = # 253 "" ( List.rev xs ) -# 46197 "parsing/parser.ml" +# 46326 "parsing/parser.ml" in -# 897 "parsing/parser.mly" +# 901 "parsing/parser.mly" ( xs ) -# 46202 "parsing/parser.ml" +# 46331 "parsing/parser.ml" in -# 2887 "parsing/parser.mly" +# 2892 "parsing/parser.mly" ( _1 ) -# 46208 "parsing/parser.ml" +# 46337 "parsing/parser.ml" in let _endpos__6_ = _endpos_xs_ in let _5 = let _1 = _1_inlined2 in -# 3189 "parsing/parser.mly" +# 3205 "parsing/parser.mly" ( _1 ) -# 46217 "parsing/parser.ml" +# 46346 "parsing/parser.ml" in let _3 = @@ -46222,16 +46351,16 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 46228 "parsing/parser.ml" +# 46357 "parsing/parser.ml" in let _endpos = _endpos__6_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3112 "parsing/parser.mly" +# 3128 "parsing/parser.mly" ( let lident = loc_last _3 in Pwith_type (_3, @@ -46241,7 +46370,7 @@ module Tables = struct ~manifest:_5 ~priv:_4 ~loc:(make_loc _sloc))) ) -# 46245 "parsing/parser.ml" +# 46374 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46286,7 +46415,7 @@ module Tables = struct let _1_inlined2 : (Parsetree.core_type) = Obj.magic _1_inlined2 in let _4 : unit = Obj.magic _4 in let _1_inlined1 : (Longident.t) = Obj.magic _1_inlined1 in - let _2 : ((Parsetree.core_type * Asttypes.variance) list) = Obj.magic _2 in + let _2 : ((Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list) = Obj.magic _2 in let _1 : unit = Obj.magic _1 in let _endpos__0_ = _menhir_stack.MenhirLib.EngineTypes.endp in let _startpos = _startpos__1_ in @@ -46294,9 +46423,9 @@ module Tables = struct let _v : (Parsetree.with_constraint) = let _5 = let _1 = _1_inlined2 in -# 3189 "parsing/parser.mly" +# 3205 "parsing/parser.mly" ( _1 ) -# 46300 "parsing/parser.ml" +# 46429 "parsing/parser.ml" in let _endpos__5_ = _endpos__1_inlined2_ in @@ -46306,16 +46435,16 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 46312 "parsing/parser.ml" +# 46441 "parsing/parser.ml" in let _endpos = _endpos__5_ in let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 3125 "parsing/parser.mly" +# 3141 "parsing/parser.mly" ( let lident = loc_last _3 in Pwith_typesubst (_3, @@ -46323,7 +46452,7 @@ module Tables = struct ~params:_2 ~manifest:_5 ~loc:(make_loc _sloc))) ) -# 46327 "parsing/parser.ml" +# 46456 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46372,9 +46501,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 46378 "parsing/parser.ml" +# 46507 "parsing/parser.ml" in let _2 = @@ -46383,15 +46512,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 46389 "parsing/parser.ml" +# 46518 "parsing/parser.ml" in -# 3133 "parsing/parser.mly" +# 3149 "parsing/parser.mly" ( Pwith_module (_2, _4) ) -# 46395 "parsing/parser.ml" +# 46524 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46440,9 +46569,9 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 46446 "parsing/parser.ml" +# 46575 "parsing/parser.ml" in let _2 = @@ -46451,15 +46580,15 @@ module Tables = struct let _symbolstartpos = _startpos__1_ in let _sloc = (_symbolstartpos, _endpos) in -# 813 "parsing/parser.mly" +# 817 "parsing/parser.mly" ( mkrhs _1 _sloc ) -# 46457 "parsing/parser.ml" +# 46586 "parsing/parser.ml" in -# 3135 "parsing/parser.mly" +# 3151 "parsing/parser.mly" ( Pwith_modsubst (_2, _4) ) -# 46463 "parsing/parser.ml" +# 46592 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46482,9 +46611,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : (Asttypes.private_flag) = -# 3138 "parsing/parser.mly" +# 3154 "parsing/parser.mly" ( Public ) -# 46488 "parsing/parser.ml" +# 46617 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46514,9 +46643,9 @@ module Tables = struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : (Asttypes.private_flag) = -# 3139 "parsing/parser.mly" +# 3155 "parsing/parser.mly" ( Private ) -# 46520 "parsing/parser.ml" +# 46649 "parsing/parser.ml" in { MenhirLib.EngineTypes.state = _menhir_s; @@ -46544,222 +46673,222 @@ end let use_file = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1802 lexer lexbuf) : ( -# 783 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1809 lexer lexbuf) : ( +# 787 "parsing/parser.mly" (Parsetree.toplevel_phrase list) -# 46551 "parsing/parser.ml" +# 46680 "parsing/parser.ml" )) and toplevel_phrase = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1782 lexer lexbuf) : ( -# 781 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1789 lexer lexbuf) : ( +# 785 "parsing/parser.mly" (Parsetree.toplevel_phrase) -# 46559 "parsing/parser.ml" +# 46688 "parsing/parser.ml" )) and parse_val_longident = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1776 lexer lexbuf) : ( -# 793 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1783 lexer lexbuf) : ( +# 797 "parsing/parser.mly" (Longident.t) -# 46567 "parsing/parser.ml" +# 46696 "parsing/parser.ml" )) and parse_pattern = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1772 lexer lexbuf) : ( -# 789 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1779 lexer lexbuf) : ( +# 793 "parsing/parser.mly" (Parsetree.pattern) -# 46575 "parsing/parser.ml" +# 46704 "parsing/parser.ml" )) and parse_mty_longident = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1768 lexer lexbuf) : ( -# 795 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1775 lexer lexbuf) : ( +# 799 "parsing/parser.mly" (Longident.t) -# 46583 "parsing/parser.ml" +# 46712 "parsing/parser.ml" )) and parse_mod_longident = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1764 lexer lexbuf) : ( -# 799 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1771 lexer lexbuf) : ( +# 803 "parsing/parser.mly" (Longident.t) -# 46591 "parsing/parser.ml" +# 46720 "parsing/parser.ml" )) and parse_mod_ext_longident = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1760 lexer lexbuf) : ( -# 797 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1767 lexer lexbuf) : ( +# 801 "parsing/parser.mly" (Longident.t) -# 46599 "parsing/parser.ml" +# 46728 "parsing/parser.ml" )) and parse_expression = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1756 lexer lexbuf) : ( -# 787 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1763 lexer lexbuf) : ( +# 791 "parsing/parser.mly" (Parsetree.expression) -# 46607 "parsing/parser.ml" +# 46736 "parsing/parser.ml" )) and parse_core_type = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1752 lexer lexbuf) : ( -# 785 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1759 lexer lexbuf) : ( +# 789 "parsing/parser.mly" (Parsetree.core_type) -# 46615 "parsing/parser.ml" +# 46744 "parsing/parser.ml" )) and parse_constr_longident = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1748 lexer lexbuf) : ( -# 791 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1755 lexer lexbuf) : ( +# 795 "parsing/parser.mly" (Longident.t) -# 46623 "parsing/parser.ml" +# 46752 "parsing/parser.ml" )) and parse_any_longident = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1730 lexer lexbuf) : ( -# 801 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1737 lexer lexbuf) : ( +# 805 "parsing/parser.mly" (Longident.t) -# 46631 "parsing/parser.ml" +# 46760 "parsing/parser.ml" )) and interface = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1726 lexer lexbuf) : ( -# 779 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.entry 1733 lexer lexbuf) : ( +# 783 "parsing/parser.mly" (Parsetree.signature) -# 46639 "parsing/parser.ml" +# 46768 "parsing/parser.ml" )) and implementation = fun lexer lexbuf -> (Obj.magic (MenhirInterpreter.entry 0 lexer lexbuf) : ( -# 777 "parsing/parser.mly" +# 781 "parsing/parser.mly" (Parsetree.structure) -# 46647 "parsing/parser.ml" +# 46776 "parsing/parser.ml" )) module Incremental = struct let use_file = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1802 initial_position) : ( -# 783 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1809 initial_position) : ( +# 787 "parsing/parser.mly" (Parsetree.toplevel_phrase list) -# 46657 "parsing/parser.ml" +# 46786 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and toplevel_phrase = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1782 initial_position) : ( -# 781 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1789 initial_position) : ( +# 785 "parsing/parser.mly" (Parsetree.toplevel_phrase) -# 46665 "parsing/parser.ml" +# 46794 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and parse_val_longident = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1776 initial_position) : ( -# 793 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1783 initial_position) : ( +# 797 "parsing/parser.mly" (Longident.t) -# 46673 "parsing/parser.ml" +# 46802 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and parse_pattern = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1772 initial_position) : ( -# 789 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1779 initial_position) : ( +# 793 "parsing/parser.mly" (Parsetree.pattern) -# 46681 "parsing/parser.ml" +# 46810 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and parse_mty_longident = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1768 initial_position) : ( -# 795 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1775 initial_position) : ( +# 799 "parsing/parser.mly" (Longident.t) -# 46689 "parsing/parser.ml" +# 46818 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and parse_mod_longident = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1764 initial_position) : ( -# 799 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1771 initial_position) : ( +# 803 "parsing/parser.mly" (Longident.t) -# 46697 "parsing/parser.ml" +# 46826 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and parse_mod_ext_longident = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1760 initial_position) : ( -# 797 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1767 initial_position) : ( +# 801 "parsing/parser.mly" (Longident.t) -# 46705 "parsing/parser.ml" +# 46834 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and parse_expression = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1756 initial_position) : ( -# 787 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1763 initial_position) : ( +# 791 "parsing/parser.mly" (Parsetree.expression) -# 46713 "parsing/parser.ml" +# 46842 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and parse_core_type = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1752 initial_position) : ( -# 785 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1759 initial_position) : ( +# 789 "parsing/parser.mly" (Parsetree.core_type) -# 46721 "parsing/parser.ml" +# 46850 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and parse_constr_longident = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1748 initial_position) : ( -# 791 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1755 initial_position) : ( +# 795 "parsing/parser.mly" (Longident.t) -# 46729 "parsing/parser.ml" +# 46858 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and parse_any_longident = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1730 initial_position) : ( -# 801 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1737 initial_position) : ( +# 805 "parsing/parser.mly" (Longident.t) -# 46737 "parsing/parser.ml" +# 46866 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and interface = fun initial_position -> - (Obj.magic (MenhirInterpreter.start 1726 initial_position) : ( -# 779 "parsing/parser.mly" + (Obj.magic (MenhirInterpreter.start 1733 initial_position) : ( +# 783 "parsing/parser.mly" (Parsetree.signature) -# 46745 "parsing/parser.ml" +# 46874 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) and implementation = fun initial_position -> (Obj.magic (MenhirInterpreter.start 0 initial_position) : ( -# 777 "parsing/parser.mly" +# 781 "parsing/parser.mly" (Parsetree.structure) -# 46753 "parsing/parser.ml" +# 46882 "parsing/parser.ml" ) MenhirInterpreter.checkpoint) end -# 3761 "parsing/parser.mly" +# 3777 "parsing/parser.mly" -# 46761 "parsing/parser.ml" +# 46890 "parsing/parser.ml" # 269 "" -# 46766 "parsing/parser.ml" +# 46895 "parsing/parser.ml" diff --git a/boot/ocamlc b/boot/ocamlc index 9ddff6a38d58d6d61fa904c2b4868707b0630e35..aa2ce083227cf4acd3d66cd3c63367c0742a2e12 100755 GIT binary patch literal 2803430 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 ={C+*% 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

4Uv~3k_d6FpkyV?>BtyLF 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

dUe&h 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

@z`py~fY@NWft=Hk5q}8!~0{xDj z-t(rV-#LN))T~zw+|e!1X%l!(Z+N~tJowz>o(1*%ygcK2@A{b}LVVScd*;zS|J#mU zeD30RFSWIIYLk1umyO?(@unam55J50Ea~i$FNY`gW6#TR&!Jp{BYk_*Ul`D9&GW_@ z87BnfdAD}{+WpqfPyWBf_b@h`74QYW_h&X+S0C2JD6WrwHbFMs&Z+k*diaC}U%g{_ zH*pV;?Y-`_Kn&05W9Xgqrp!zJkeAFM?_*ZM8}^aStuNjyr);G0kLC1;izbHkoZ%lI zihf_lY7>pV;-BHDMrz%j+|lKp)x?f0GS>&au(w zr*w81YxEon#Lc_bIqA_{9gtgVXf_6U6&TSD^=-{MzDc&&>jF*9h@W09yN8UA38n)+ zi)kCbI$y0l=;(9i#892pyw2b_d(}9pJ~}GHd?Dk-Qj=y68z#Tj_gv$I|D8MG|%XB zs(V8G#etn?FChz!M(3CGbZ?7r^2M01+k+i}wbI+h#dutN`AEhwK`Uc@=4_YSF3_U- zaQxSdRu(044(2Vi#3}V7j z`CoB-MtrTalB{!nVfI$HM*S@x!auj}h)cyF@xV1SR` zbS?xp1aj-{6ra}CNwKI{q6Mx8DU?)jc1`7ZafOoWNPo_{ra^0?#x0>-=Xpif?OE*(>%t z1F`?n=A3&@%?4~Q8hO64p{cu8j>=c(*t3Bzmj&di6}rVhea#2-8*9eSdOa)E%&+F% zoc$LCrN_Jz)iFZr8yP>T(utEKhtM-bQUr)*g zf8G{@*km95wxDW79O~}i*YNHr`Qz5n)2$|Ie=cJ+O#b#@M=%wv57;OcY;v~bi%pf= z>5Tc$rgecPuC4s7nX^|--CKENmc1p9jpD-gvO6Y@>ZWqcSGEqnV-$x&!G?fM>?dbF zQ2!O*@;ggMb^b_`mMollIv(X`iq1K~8&yrusGYj+YOY1kN9u zeYSo@3Wq;(Wli15S$%%A{@kEq#~=DCw{%p!xr^k|+SS2Az$WjkWE)>~++wYY>2$zu zGWlI~UOZxKo$chY?VP~6){XvL`Zu{xs)pH0 zo_N$6xpiMwy!pI2K)W;0{xWjHKDwXrvRORZn5@g(J-FIfkb!TxSX7)2gq98a1F_r} zuvt7R=2ZjYf|gBN0-E8W!0tWa6_-i8Xr8ODc$=cb6g(iglvy$(>Yrg>u7E3x-Q}@m?J#579%o$%Cu(@K$ zW^|Ruxr}E6HlrE0N1phj6AO2BD|=h!_Q`H*dnlWKL%pr+de*a74pt)5-8xC8`@yq< zef+C4D&DXV;Qir1zWK-g-NAtrpS`z*a4NmMijC)Jtz~&c=NZ92IjeUw^NNROpSZC} zU$)58d_Wf(^FzT|!MOWQ+>4eCXg$lH8Hg9y|Aq~VKC&mKjcCqJ@7XLC=+vm3%bOmZ ze5m!3!Pe=3UDmvxkWqGc4w6MrTX$sb479g5=QU=H?rO0Fdf6kso@J$1KFHLpi4A}0 z?E+1lt$8nT{@77D;(sgS?(9`w>OF>Ua>Q<9`l<#m$e2CzLES_4>0{5N+;rK~wguvd zUJcSwXS&N+E1K2h8Xx_q2j>NBs{C%xn7#5^G-^X^`Dd+t2b9x=e%%>3IzY?bisP`> zJsasPdF;5XU*kucr(wM1qvW=HSsulh+@TCH5<`BqdB}A1oZg(CT#bLj&u~5;Idf!a zp4-RAQGVYTxNF>L({P1rk&}vN{%P;#e=kR@Dtce9a_1f}TL(`tW|K6X!aW#7|wCs|1w(+gx(ajFA zTOaHV_)&hVg|ail!{@)&ipN=U4{8;EyyV>+u=l#)_TU+TbEDOLQu1o;K^fHAhK$Qz zapS*M@i8u)bjcCjhk}Z&7_wy{sP7EqT*A z;z^#kwf)hU!@pK?Q_9_o- zsqwCiw*+JjY1+L>_K?-uBadZIhGXp!H|OiJpz`_rjGaI0(}DG}QNC-xY~=4GKeBa% z-l2|?p`Rqi zwUy9S-LM1p1#B17;{wm*UkvDW#>IFh;0GIqpNF3sr4?hbEBkh5{IpEOXlT3op^x63 z0sHe$qaOZ#bvkoCl7&wEitZ=J(9y3R&Ivp(9~9uT_K09zzz%bM%?D(5fhJFn8jX&m zVPDs;S8a{sB};4N4|&-%a34QCi9t8j&!3SwJBNAhvZj&K=7fCqiBTIf_j4C$3j9xzLOV^IwJpupnSk1pIx9in{`LsopGJLI0*cZ^ZH&_Vpvyn~q@yfM^W_R$+5b%Xh7so*~{MOhcu3F{CeZ$Tz0Uyz_adUvy zbK&%Ud}(@(4V5QjykuyT_QZ~jYLyP-k};PtpZK~nkQcuPY+oLn)!MfdLu17>FfbTOZ3eXQcJ*iJ6PFbvDZTO)(U&J9ksCTzu5iFh0*- zMSNz$|0O}yGQDb`;#E1T^TK}5f=MwrkUe&z7e`Gj$<*XPyEV8hP-7YzII-ON4X zp40myzT`Lq+%wuY{? zgFg2i9nRl$uftsX!pzY)v+f3Ya;Mu@OTV6q8w}G=gArK&zaSmv%|CHg`ua< zx^u7J*!P?IeskZ;rTy&z{$qpv|FjtUbs5`pf0mEyve(9}{G01(#O4E^Sd0x`&ywPO zSJqp5YWA`9f8XCN#;$73TE+FN`#p1dZ_k`;bM57W`SW}F)|Ll{uI$yj z)Aif?UY^a*?0e4>bN9La?7n|O-#@AE-RJiA^!?tx-{1G1MfMN%{nPvYiRsy|?w*tU zie34)E_3$Q{5|>Q0sd-y>I~Avo*cGaoOA7&yeEf!L;6fd@2?B#<;?dmZ|~PGOfO$* z2@iU$-qD=z+2HD6IbLU1D_*^`f}efzRWXPG)Nl-M`iA*qd?5??On<)?l1` zHRTR)FOhj5aBuAk#A1KoPA5}-{5u-xrUSh-I>eyWDR;9y(Cml;YsTu3JkOPbLCFz| zCuBa?uko2}8-i?&c-V=DFJ$?doSf2S{<=)~YfR6R)AM7Tp6RTY?sp!$7~|sGlfC8a zV}lyeuk@^K3#~Y4RU>uQN;e{ig?FAs(I^~=m zy)!+jmtQ`n*GP2mM z{eA4_U(Nmff_DA~gSqeS+I`={wR3+jyq!OBF!%R>#Z~<{i}dpUo3q~XJ#{dDWW(3y zh8**frJg>K&y!@SO|UOs`pRwTR}e{~MUN-iA`TWHEs`P0;du{%R z>*umVL(>_g;ZbjRUJxGdV;@WLZBH+^_B8jM`qlOYeApZC703+x=#DeLIZ*q2+!bsM z_(k5fK%7g5G0<^cKPH?17X@FOr$(3lfdn5*-!q$Wtz9-|t@iGZzMi@AO-U-EW8!QA}pm|q&f1G45d-%}>TIp!( zrPXKMv(&fcJ`a9;mGGWDiHGbqzL#fyP0+^0em&3226hawVa(c)X575Z{ZB-O*6Q4u zf014+KVRV;u553|wf1kJm%}x|`GNahT{*w%#=R$>TANoDbZ={BTpd|shr5>@+k&AT z?iQ`J&0T=+m;j%Tj?O6>?>1~cK3Eqx=XFN-g^mvU#|3pSc}Jt4|76oa_EbOD&j)D4 ztv&CV9&z`vfjoDHcdprf?oRRV1Y6r0uw^B3(02j5$z4tkIx%oBpnq8)4qc$}fj?Ts zwY{(81y1Vwn%|qgjoB5EH!gncZS_AR0fy7F{*+)Q1UCe=KJ3r!>D%=K{aVFBuDxr? zuiVN_#nF8`8$36t*w~|Aj>PVUK>e%@$|qy(?x6ILUojE~*K zO$P%pw*Hd9XMiq{D|XS>>bW5EpAF*b=sPgF+c=KP*M`uHTVHO?nV|dp;O&97Hz=K- z?|1$}d}(p*VBYS1zK-Qkt;nH!Pd%wQy&6}y?hASKd3AqKpB3vKa|YC>T2O0iQk`l_ z{i+3Hy!3c)(r*i#Ki_q|FoJfcN81J3r2#tcW8~t~imzm~YkYD4+bbW~dLVGl*v=Q{ z%sQL+JloHm!@7$%^?O^=uM5~92KdE9Y}mgu(B75rr10~9V?d_3SUW3lzR~0F0+BNCx?pQqEi|g)nG4l@VuHa{D=W81~#fzQd!5_5z;p+<;x|1^( z5Bkv6^O0R>t&54CfA&kx6UWFQqm{$HiZ7Y``Fy=Qu8r;E?t)iMSRc}U`wHoXe4mTC z`jIzx#}&bvKpl*$*Y^Cb4UOhJRleOBp1ID28Zs{VC6f#~wgu?i9WR=2cd)DYoCovP z2K+6}a4*}3?Q@RZb=sZ5RKP}k=@_2Rp{>i&M$}=y=KHZYwKmq-awnDjdovcp;advxeuSzV~w*ynMc`UvuAT6+g9bY(Ovh*2$<`R*&xZ zpzImS#8bQ_(^|>Q@Ccdoq0{rd^sreR)sq}OOQ6!q7taRketzWcoC$olWS?)I5k)I5 zXn%_EG|!lI0Uq^X-#I)daKCA4l}(y`bAGfrF{gu_^-k$dtk|%f+1Cg3$Uj;lcc`Ebur)D?a9*!}!K zJo!BpXzaWU$?*eUia76;qnWXU>y;izBXW7e6I_#H@n(NtA>s6Czm(qP@qnrG5 z1Fh}((OFDmA0M^WJ~2@r>{L_iX=71yJw0V-otNe8eDNynT!@Y?(Ad-ZW6gZ%m-y9v z)t-yx^1RYmU$sgf#9Cam2Qt&(qjJLN&&BUn=xgWqX6%{#k_ZxK zdb&WnG+=Yjzove)%7bym+gi~r6?^Zm_a@#gPixl|k=N>; zWMkP}wIfH)zjZ#SUB64Gmc)rK@?if^K<7dad1>qF&dmQ)FqeS7F8ID+Uj)1~fqq#6 z`Ig{=!H*{?GYRzLg7bpAgEOM|CBelJ`qDf!*G3L|(?2XVI}oUfmPp^wWu-PO<9(ZK#u+NjlHS zUaM0L?hn-eIGyrPI{DuP+E6DslXQ|j)$hBH#CIleuCK`?vNhweJ}8Xm8*?DbbzmF$vxEt+O|Nf?5iET2Lm+d4+QMk7nE%Ep>ELQHJ=VP1#)bTR*Z^AJ+9H@LQYh+tz zQ>*{W#^^8Fww~osjKx;ZFR_&)cNLjx$9v7XfL&Jy?5{h7TPKn&ISjp41BpvOx#oBfm!RzV(ebg%e{E3 zt8WO{YHqLYh|k6Ew0F^ee?e`&e3kOsdU{59#Yqgw@~jXqz4~A7z16d7ZQwpWH#jNi z0!=>fS6*tqD{IpMK6>zN2)aN+S72L>@y!MJ=+W3(&t17jU+*~8mke_dw8lXYT9>`u8)p7|RzWp4}?Y=ERxP?u*(Tp0}0M?tOLEhi7)BXMJdMorOB5=539m zzrW9%?=reTqklDL?iD$RZGNxMe0b*GG?IMeIYiT*-4}+h&KDc%yuLJJ{+s_>f0lh| zeC$?%Htw6kCr<8M_nlt6^e}wRw6XUbTaLG_+m=_(T06YURlct6$6b0&4&|0T&S8yr zWjq(81V*3#T6ups^_lf_P3Sa!R-L$$w6;b(Av`0TRsDSdw#B5;`|7(5(vH-*cH}=_ z3V4jq559XW&#|MJh}}5gcV6&+L->hkeXp~W*TNCan?q1%NpANBV(yu}BbW)iCweE4 zE9c!aU5!i!U7*QN?bW!=m3Xp^47R;2dd=7L^K1J#TkJ1nKD-;8Z>{y`ip8ZtT<_mp z?ul*M-at)VWRk4$P3{V9E+0FVXXUw^3qKL9@55X^G6dstDQ?4j%2At7G@orwKb2&* zIsM0eUOD}E=4{>{s5QQ*rM&@r#FCv`18bhq=F`EZz&?8G!|!mqtdXhL$WzB?YkX$L zbAkMzy)SGLGqv3XTIpI&Z=1)NMb@#oO~^*);X5;^+`11dW_4EGTjZFt$#-jApp{Md zYP>7sHWuA~*c$-z?t&!Wo%{`h=o@7jDx z+NIa%yd-G%Upm--_F(_I!TzCUU%bfb0*$`w2lP+MTC4A6gZ;-f`{U$&*??Yswens* z*q7JZA1Ch>1A3n~ik|&nKG;_~wLebYR}AQr!ozuzue$4u)os;+8j|b%!M(Zf)rWka z8qj%XFcmmY8oP(j0k!L0r3cRE{2?~d?7gblyDx1a-x;g;%aNFVIMC|u*q5=`EWXQ}F#1`5p9c&f_QSQ6%;m2= z>z}WGe?e|O8#rH|4gUkl+uqymFlSGlR1G=XX!Pz~wX-fzN6x(SguZ zHkc3aqr2iP&ZeQIr|i+QWuadurwcTD?kP66Hd=3O6x+&yxV)y<+5WBz z+r+>1}b*b}(z~qF1f5 zQzO$Fnc|3dHkc18K4L7^?Ha#<4`LzTI|FoU@^6gRvxiLbivB>xd~NAJ^zqN6r;Cm3 zE1&V57nE-`zd37u50?+>kUcjB7X<42vS4FyLck9Gk}Ec7yFfFSA2u74MHf42Z&$|C zfmogrID70H=F?pM<>~oB)hM3IF`0Zg6o~ayaCAU#`NU>1wf>rbPw$Vf;)BPYamgCy zo_uR1Z(NL=F)^Zpo#nF})wpup`m&szADLh$S>jK&+GTsKEoG;;m7RFxvg{M<8s8gR zKRmG2_fc#l3%Vdz))BQL{_LpwFy9r-1?q#ndNt2Jc@W=yL7iXxYNdKH-5AIl8_6B$1M-V^SH^Sw8h!TYGUf|9F*_xw8YI&k-%P+3c3Q_B%kqY#|drd-&@+8NI{TF$a)8_#@5-1@ z?5Jl5-S#V*7ELo=w57U^*b* z`lLIq?n!d#5*PBSPRIiGRy^6)1sYm0ZSAi$y}XqVb;iiq6-)=M|Go#|KU<~(weq|G z&4qz=<9)%T+OjV9dwUu@VpKhu^8L8r#uWSR^mw{JyEIS(l^?RM4u<}Ta~uDvOY7x# zyH6(>>=4h^|AoxEKwBzTy+avm+X6E2wdYJ-;kPHA_~e}o@!l8k0}cP}qqV=1_>)a#8Zf<-#8M z8u@JZ{aP1j@*^h8<%e#5vAr8;>qdVr z^0Bw%>djj|wbR};{2s~?BWun|7iil8>vY#=0QvAv!ZznlJ&9B4A9t>Xu_D90>TF*X z0m+qdVr%D2|~T6MLtp=0YUjjgR8?U;?w+Nfq~eOJcQfm{yx_`*iC#%SjPw4P`B zeSy6?>z8DVW?dkk*6q8a{2dwjo(-x_$U!Tv{G^M{>jQD1qYE^9760OsC73j3P19F#o&sU$f1!{!MsertT0%vF@s54>@ zeeGvB+OPa9WDa6MrY1)C#H9-~es>0G>dLz~o6)jED?Tx?#s+a=6WdViAN{#_R~Ub` zAY0D)xTs_N&zt3lJ(~mVNS@_?-dz4ThZ_E>4Z6EP6BBhb+mFSBjheCNmiSm>j~ZJp z*51#Ti?uqCLw7-aPP#DTl-j69YHvg4>Z6_!&dPOx{Vq_mdd+j8Ge~168f!H^Gvm2H zy;jce=;wSbo9Ge~zITDPTG=Iwe{#SFao-n+jeOJ@cbBn=oz{lBt&`UUnmK!&3Aw2K zTIc66%0JJ=Y=N5z;-xz<~&`L2wo1Abl| zEClFg1HJ+~$lDS)ANNK!x#Zs;vdLYE?2wIWiVbylsgZF|Z{yaNTe~8B=Lg~@rfNV= z#n71_)`PmRua?w<+^7Zg?U}D!R-NeUxoRwra{--lt6qja4tNt@zh>V z`M580z6_sB=Vndg-&`xN_fNwkJ`g?AQ-3T=B%S_^%ZZ$S*&WGJasN!&Uahu z*6Fah|=&SRJsNZ(?Up9ouu}tREL_4Co`T zVywS8KwGi1CMMIt+JOIEpz)Cm{bPgtFZAvyJK3O4$U&nY(vZ#fZ2{Tkmoc!nFpP`! ziVHntwfubG`{uxSU%)2uDgW8Te{*%B=fBTMHRoH6D-QIj0k}SpbM|(DMlN0DbAHrv zI4a4nSk&7BfIsF4Ro>Jo*r%aBOm!+ zv)wbD9vvEb-H~0Oxi93%*}o+~C!h4M4`u^0+2;ADwKj~avDOapAKF14+u7p2>;jD~ zYXY`h8i<1!uhy1|MfFR?q_t&3bajE&+Oj)yIb(-@r8yBBv8bLs!&s2HT%N^1UeszA zXymF-y?wn}8p^Mn4}GJPk7}@bu^_X~WXYP#8vSI=2i}bj^^|8ateW z?ZJ+qY!auH*i=4;{BWJLHu9Sd;#)rG*9Fr78_VX>$Htl9u0T5>Acud}<)iYO;o;gK z=eVF~oHJ*+3pBpcry28GL#N@rB*1fipnfk4@azrbqin=W51VEK@#psy!39Bn1T*?M zsn4@y*)QG|tCRi7H&We<7ubb&_K{=mA{js9Hpv&LdAF4`pe zqS+oAH82&-2X$9$%$UvOu(_a4rvtXjoByYmnBdzRsEt~m%~K(UUw-ZmZVyA3 zUPDvz7d$Mm_eJR+5uDP` zx1~QdI3qYK=z@bm`KNzo=FbkU3|C&ER)~KMXz?{8{j!;3L6D1Al+P-)Zpo99$5O zkBy#XcRcdb`8U6_nZG#ms*S5Me(+%akip#fZ0ViNcCMz|xwGERzi2Rb#@qc92lMsK zob7itwwr&|VE%@|{EdV8n+Eg$IGDeAFn`Nn{?&u|e;Um1Zsy|YelGvm`!&tJ`PVjc z^v+??n;+ZE(SKb-Z~pbo9Q{cRz4?Y_j{X}Odh>5==9!M}Ebj^D29@iS(WvdspS4$c zAGcRIAGcTex5qyBX8D`p5&BQ;_t3KSnN(;09_e{=L3ryG68Cs!JpipzAyr8~nT_GX&BEBi56nt8TYB=bKv zJY>FoF#pbGUNS3Z-<7>dIV+m~vIGr(FABs2oUffhuJ+OU%W(hLtgA(JF1Ox2Umaq0 ze|K-Enm7NRX1<&}^zUfsTlp{O<$rIpzY=->wV@~f`^R5-p{O}5B-n{~v|F!~}A6Ws-kFJ2`$0pFY7pp$qRbcM!c1L@* z`tC;Ve>^hk-ZFpBVEz+>`A-h!KQ);DbTf~*!)N8@jFpo!;yv_Df%o~Dz#aQD;j?~v zkm2YvV3)qV(=$Cno^v)y-p{U3p4z^82{}Kv0y*OL-$Pf=7W4NG=Ko_b|M|iE7Y6fR z9L(Q0nE%hg{C^GRzciS?e=z^$!TeVS^Isjzf32Cvy~FpnJ91qQ_kw4vcRTMN^%-d{ zV=?*l$Z#+Ed4lNnafB!+3w-JmcpR8uR+zpuXR+=MJ;a|5~s2GVidO^QboG$BgCWl7Re@ z<$bZ@ds@co!uL(&u)ktl`76CAWlt_Ym|RsZ-junV@~!x?J(8&g|0I*)y7{nEkm~r{E zkTI|UP5u8ltX&*`}mAm)7E7PR)u3$PiC`JkTE z_`kJ(FRY7CtAVrBoA$`4=nquQ+KHBWGIt z+T7VgFSee&XvDvzF?WXLSw8Ju5!BslePiHWBCFP&cQsftug=(7)!uZ*YlGra)-Q|!^65LnZU%SLN#+!bggPfWB6f|+2o^1LHy z~qMr}50e(8&Rp!PA0&!9Ua{*ehYU7{jsQ%QA92^Xc$t$=! zj?S$lcWjh94c)fDn!M}{@C@m#Rc*+F=ihK%{AEYIPpJLcyR9GdL*3BLAF`?rt41c- za#BxECR9gL8gUz!3ojU-A zZ+eW;Xsu53me#yz$JzI%%h)IPTHPV)gzsf1d(@nDexWmN&y@Sin*2Gp`0M=cZ`Sr@ zyb!eSKw@8h^5YqSCeQr-Tt45}+cg-@+dbpjuYS1y+05HoTpL|-Eq2a_CRXaO{hb-l zn=a5=+NvMlk7#!Wawfmp9l?$Ozq2I2np~i(`cNa#uGRR8tkcQPI@8A61G0@l&cXO| zo%8!6Z(aPlw`g<%T?v3%UEl3QaUPk zzDw#5r4_%ieKtU=yS+~@&7MZ)=kh*XF1KCmyEk~oz2s|i>seL#5GQdR=FGX$+T3)b zl_PUfxtPgb$*KA%`l0Np(AK@UCS&m2RAb`inM^L-r{xN_2>HQDo7l+7i`QM)XcK#EY z(^G4FS@S2Kmhr>AjM91MU_PC>SUe=)FS@DVJ^6n{$Y;gl!})(m6rD9Wzr9~mkKSKv z{k*KJtIAtD9?Cc)v=8oi*?v?nvuvT~NAt_cWQ^Vy(xaORb_ai!i)5UhHZQk^pWgE2 zG5>gE-cA|JkI#IhD~HZ|BUzdlbp~nm%tH6dIL}Tt@kQLcgVZ~vo_;+Udj9E)&KOSU zd*{G>L*H-g``Nyq>-#Nz@4TSj(f8`X{Pey*qwmk`d!GgDpVjwY()TB)$IEYL>AU{? zo_h}Dm!K~Q-Wa?!cwgYo#$UPP|JVJ)k#Rn)pQH0`CjRI?@b`;!;$&|agOmF8NB8|> z`kw7%tP9>88FW`1$$=s7uB_qV&*kAk!xp{I#Co~ZSFCqsjE9d;2#@^J>6t|*yUFmm zpzc{R#Q5ys&qL@v^cQlFwx^d9H47I8SN3D~oVxJ5_nqjo(m#;s9$ag{S??&%@+yL--oJc(oR8{?BFIm7$^P2g1*=;s4xh>T&*O2&sWAakf+ z4UnVJ^%tST)6#9t9NkbhA9n_7<753Z?F||8c}svtBlrKVLT=Sm7rv(iVt;Y)f?y$d zS@7!Mmf)`7tAlS0-WGgM@I%3m1wR|SFZi|K_kuqO{v!BT@QHxoes}NT!G>Tu*ct2& z_5@E4E(%^0yfk=iaA$CL@EyTV2mdqpz2HNEe*^SENy5W}M+RF0{|4$4gM-0y0>7WP z5WFJrJ9=LmyghhV@K?bnf~l$84S{>^!-<OB|NCY3|6!T^e_Uq&6U*%X(=z*?TxS1M%k2O2GW-8; znf-rRX8)dL_I;VURQ(>k%>J5X_NSKFU%SlygO=FOaUR{}?pSx&F`*saq3%Za=aBZ; zRnV?m1?_RGp#2Z4pndQvXdki+?Y_jrGhlBZ_aJ^>5I*l7?OisPx#z^XU>L)PE~AJ1 z%FV-;p`B#Y!&hKa%gc{19HVPC>zex58SrIKJ|pqf^X%aP8tY^n9~s{N+E}QiV}oHF zzG#fTadk(Q&y?ax#|dL}%w^sFP|uL}#8vVx^q(W>UB3d}Hl}TjoD|;G)X0X=uk=iw zyb9V!tb+EDtDybjRnR_a6||?Uf_CF7Xs1^}JF^UJn{%H_oD=Pue2#Ztr~|nKbu=4! zKHIn(+H<0Y-MQ$8XJykeHq@O#p6~CsrJo7tn_GsrwZE;|&EZ>V&AJQN4$lAjz|SDJ z1U~P2r`r;F;?eqS-)9B;TbJ42w#@$aW%hS0v%hnR{b4>%4ed(L=V_~;J$;3=`x7sD zI}pg3xf(DR8y!}rI(k={kQkGV=+I}8-WcL0wTgxQeSHVb@k>!jBd-C_JRNnyDOfTWUT#bh-Vi&CV|b9 z_U@1MHlChGRfp~qv8rdm%^Bxwkb8Wm>#pbm&G$K*192t`f5jf}9RYg#_T2lIZCIRN zmvKH~jh<2RiRP@pK3i%JpXZ3HVM zWqZl>>@KJy4e2N;&;Z#XmjiPQDI_poryPOtUb_i z>!S040)MYqr9N?68@MO`s2^9&>8l3SD!Q4#9dmq8cl;YOuDV{6G1_ASw3@m5-CSO( z&b?03Z;$?;3g}p^{x^l^zR>@zk;9&;fIZ(7uyEl0JDmJ%eta%2PPfyIa z^_Q&LV}I>sc!a-YOZEI~dF8Hn*`wa*oe8wMC)@V{{09R4>jOUhYM{0LsUQ0Mdmi%G z#^7f%*UD%0^tt*wL*E_U(5(RI_J0r_kD`L+F={r1UdeQ~~C7-;`q1BjyGMdvvo_ zv~oqCxZthWY{TZ}@_S27M_;-_^lC_fqc_PofitarL0@?JN|4a^x zd$8to@rNJuZRy8+syg70_~93y^3T2;&{uV7pB((HJ$T3ILM#6487CvlN356b>$5Ir za6%9_M$MS5?f`49Ou-*=YFba|AythwGDwYx^~^L|3whwa+JeWP7&h)%!X9Jl#kxIqL#?<^wi7FE*Un zua&)R9@VGXWHUXbV|T`nNr9FwchGczhMcM~veX~nwRT-ysVOzLJ*YeI=!`utFAa?O z#xH(FG$eX*mSVd_`>)vI+m5-UBpTjkjAyiTQ;gL8vTK^JJ-0{IeWJmdDs z*V_2Y-P42T1Q!RF2Ui3y30@YwGI(w9mBC%Xn}e?nzBzbX@Lz)O3*Hs{Sn$)q{|Nq9 z@N2>E1Rn_gH290)qrtH;a&z#Q;7P%uU_S6Wi(eCbd+^TSH-f(l1jfH9cuVk;!EXc~ z4%Q?Xe*f?h!IofGa8B^l;KJbM;Elm|1@5I^3qBD1MevE>tcdpW31`C{y?Ig9;dQk< zZvDIo>(837{_F|s;y6yeT#Q@)(h2MGHje(e6V@-Au>R5s>(@sE7fjZV6AE;}s%^kj~dGu_U2{iKEALHcTnRUnTVS#pgur_edXr<4y zkG`7&KVK{#TfN>FR-(6Lx+7OZf5Iy1JrjrW#b#U_#Ce?GVz`{&)1eva8OD2GXvDP5 zD}5FBiV53>`q&^xZ65JfzUML?r+*S($VYaR&TSL;hjA+U9V?)3{Vl$o4PWaIJ2n1Q ze)y-2lXGg;TYt&F2yq%&6{n&9=IaAFkPAS2Y+$eCJUrtqfitO9&Th?kB|jS`_r-zU zy;%OAp0V7ry<%HAJfmM{hgLomoi%optjA^C#sIzhViNt?W9Zp8q$guBmW$s}AISX5 z9_bFpVv%O?JL<<|T?~h4-+?^$w2CEr<(R)02Hs6I_mSp(Q@cHw3WoRJeAe1nJ}C2w zQb!OUNVo)`266cz_@(9En`i5%0}NiR2|^2 z^(XY}yodKjiO=4erj?kBb_++#jAH4++i-UKyY_Rws3K)bjd( z9Q$C;d9)`+ZwSbl4cu8v(QL{7F@e_Fc1h+diCNwKQ=tcS?kv|?@mZgoIvcfq_k{JY z8LVe|#GS;K+k*!M^f=d57k(Bq?#{^aC`Mw!j`ogvQRd}mdq;?+Cblh~HF4s%y@v+n zTZTu((0gymwpTfvM1RXF>Hp&ddbZC8lk}DCo|mmH>QOBKpN|hV1mw&GmAhLr_Uy&0 zzH0rp3G25{Sif_^`W+M2?;5OUI(qL|iOn|*c+2M3Ojy5h!usnbtiN```b~p%c@aDJ zv*+=y6v(ydo&C#$j|OVSe&tZTnzMP__o;icE=S_f@;#`ZZ%ePXwfzBlPzTOV`+YGv z^x1dT?63Cw;19rNHuQ# zq<~N6U7%H*#b;`?viLoju|2l1v#s?^N8hEX`{iij+Ojm{O_EbK)6aHivJ13s^yeZk z|JocEJ-J%~{%j9+1Z>(6kmuP#=1qaTs2BU7X@wru^>ky_ay-u zYu5*_4%o6eAXh_22D-Ah%UJ71e=f$Ees^r;7~k^)=Vd-<5#_Ut~nsxrkw|BSvQyHWGN0!_@Ho>cS%JWA9vNs0ms@1)a`NINzYx5g2 z$1@#N{o1F0Tfj%}OY-8J$d?*Z6Ls(T?iFptpG}@g&fU6zt&a<1dgC+oVGE( zHgmb+yBwR7rN+$bY|UlN4z_y{~5I(TblwInst}@_%VCA1w437q{)%+Yyjc_Y8N* zwtz9dlBtt|9pwe>0o>>O98Wy8Vjqni$f^;+L!R6fS} zPO6@J|Mmr9i$;%Me7)~H zI{j==_l+8%V?HqEL*<;TlIN_IJmcLE!E};c|JKD^#^kLFO3qZq&Y${mF8r*yYDt~& z$vtpZ17?0mDq zyV|V*e;*(Fy7Zq2=-U~f{l)(8z?f_A%-lX**7)-^S!0_VoRNMeaBm5g^{U~$8QUw{ z7Md}cVqY>J(d#KYz94h-t<7gou=#`eyY9|c+5F3ymwe9$>*DpUtjlrf_|~2djXSC6 zZtCUvuC8ovW3)f}@@P%p`f*e*(;B(<%Lci9U;p=wt$A0rUpCplEBht4_{99itPkUd zx9mo9Wy4$cTE8&s4^EF>&rjC5{yXRp?}US`F8UH0&m?6RZw?ZF9s zPriA|Y}9Y;`%Qh%H@euo=@UoR+>hnoKBI?@l3%{bFS+h*{UiFm^mtxcpYHp)^rr^= zd~k4b{)ffsM!80(*7f%Eh1q_L-`ci-z2flw`8UPTSA3V^#pBMoGCUQtisd+6=;dj5 z=p30+xpP< zb0beZwer|b9$(4aAK)dM?utX%AxC0SF{n9vyU17L>SCxvY{*?IK6_RXpP_G0UIFhg zUSh`Xz2SA%hBmLwnwlTRTCDhjci%F+>q8@kWP2Czj51cU#%eChhu@#vhv=P2F{`r~ zHKTVUXV-gH(OsCiJ?EBPEpL~(Mut6S6PR~=`Zo5FcG^lg!{OpfX zGRWeO@6_=!$~E4w58 zQnp`^eSTG}*(9!H-w+IaVp|tza3`LG{VZ)A&;=Nen& z<4_3Ys`mC|EQXpj&jaTYz5G6P8G7=c*3;8lXR&0cZMIe~&h%XzEEU^|8=Kp>@m*`< z;p}Y*^kO#^Y!7w>M+X|;yu+NBo^SM{74Md|^gb%<^x{*C8wT^bPu=S+_{2y4I~QWY z2J7OkIY0bB!@s8`#$9?14|!t$^sIaSqIpI`!=|?W)gf660UcEv=q?J_u&G~1$1i7a zXQ2H^|CzMj@eXFqd6Xx4Bd6V?PYmtx%UmPZ+P;7t=6Wa@56u{F7pRrtGh;q$e@u@pTPUyw^tnk!31i$$yuj;I5p54oT z&II}B)FgfNzQzY@dim9(E8pnZ8Sw2_^0}Vf=;hyf%s=YgS+DzxPwvh9H~PFnme`c9 z=IVx=iUFV1ws`S*I^gq{#*g-%Z{IcKWPML}e((1MeShHu|M_=9z-G;uo$Az@Sn`|h ziz1`mecO1m-}f=ENMW;eU7+z_eTi2WXqN`_0llT0K8~H;$Cqi zPaMr#`}k0GSbXFB5c|p*pDL$nOw6t6<+-g1vfG+?R{wnn{+&U>a@3xzmF!_Xu!T?V zCVuY@E>5iZb9wN>KCbBG;gZ3gyyN4i_|dm5kiV+}v8Xs*pRv1XHjt|!J^9a#{GzWo zZs}>ar{59K0b<79OT$xfe^Ta~0`}M1c^S|2Yqjo7$T?fIqP;9*wB*;?(=y&1sHfJ3 zs*zi=zBdpHH2kC|P_gqYQOy`OH*TCKAmzk1RVp2N=yb9dL@2hMa{9{GD+Ge4AZ@vEyBMF3hc zEFbq|EDrYPm)Ng7dKcBi(i)p;T=#_gru69fzcZK$ekJcU>cE^|zmPc^XWP2F!kj!Fuvr~zn*u&vIoKEfJpozlul(_geSEn*I45%0Ay#_tXceay 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 G)4u>`SXh|= literal 2754885 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ℑ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%0DgSA&DD2it*f($@)9v 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 diff --git a/boot/ocamllex b/boot/ocamllex index 2c11b336a79d5c8e86d63c1ea34331fed06c992a..01856b69b36995ff11d0df64c883bd7bc2484697 100755 GIT binary patch delta 80311 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/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi @@ -138,7 +142,7 @@ Linux|GNU|GNU/*) # We could probably try harder. LIBC=gnu - eval "$set_cc_for_build" + set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) @@ -199,7 +203,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval "$set_cc_for_build" + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -237,7 +241,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "$machine-${os}${release}${abi}" + echo "$machine-${os}${release}${abi-}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` @@ -260,6 +264,9 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" + exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; @@ -269,12 +276,15 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; + *:Twizzler:*:*) + echo "$UNAME_MACHINE"-unknown-twizzler + exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) - echo mips-dec-osf1 - exit ;; + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -389,7 +399,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval "$set_cc_for_build" + set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. @@ -482,7 +492,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ @@ -579,7 +589,7 @@ EOF exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include @@ -660,7 +670,7 @@ EOF esac fi if [ "$HP_ARCH" = "" ]; then - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE @@ -700,7 +710,7 @@ EOF esac if [ "$HP_ARCH" = hppa2.0w ] then - eval "$set_cc_for_build" + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -726,7 +736,7 @@ EOF echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int @@ -840,6 +850,17 @@ EOF *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + fi + exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case "$UNAME_PROCESSOR" in @@ -881,7 +902,7 @@ EOF echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin + echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" @@ -894,8 +915,8 @@ EOF # other systems with GNU libc and userland echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; - i*86:Minix:*:*) - echo "$UNAME_MACHINE"-pc-minix + *:Minix:*:*) + echo "$UNAME_MACHINE"-unknown-minix exit ;; aarch64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -905,7 +926,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -922,7 +943,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then @@ -971,23 +992,51 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" - test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -1046,11 +1095,17 @@ EOF echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - if objdump -f /bin/sh | grep -q elf32-x86-64; then - echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 - else - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + set_cc_for_build + LIBCABI=$LIBC + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI="$LIBC"x32 + fi fi + echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -1104,7 +1159,7 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then @@ -1287,39 +1342,43 @@ EOF *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; + arm64:Darwin:*:*) + echo aarch64-apple-darwin"$UNAME_RELEASE" + exit ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval "$set_cc_for_build" - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build fi - if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc - if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_PPC >/dev/null - then - UNAME_PROCESSOR=powerpc - fi + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; @@ -1362,6 +1421,7 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. + # shellcheck disable=SC2154 if test "$cputype" = 386; then UNAME_MACHINE=i386 else @@ -1418,8 +1478,148 @@ EOF amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; esac +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in @@ -1442,6 +1642,12 @@ copies of config.guess and config.sub with the latest versions from: https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess and https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +EOF + +year=`echo $timestamp | sed 's,-.*,,'` +# shellcheck disable=SC2003 +if test "`expr "\`date +%Y\`" - "$year"`" -lt 3 ; then + cat >&2 <." version="\ GNU config.sub ($timestamp) -Copyright 1992-2018 Free Software Foundation, Inc. +Copyright 1992-2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -89,7 +89,7 @@ while test $# -gt 0 ; do - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) @@ -110,1223 +110,1167 @@ case $# in exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | cloudabi*-eabi* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo "$1" | sed 's/-[^-]*$//'` - if [ "$basic_machine" != "$1" ] - then os=`echo "$1" | sed 's/.*-/-/'` - else os=; fi - ;; -esac +# Split fields of configuration type +# shellcheck disable=SC2162 +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 ;; - -lynx*) - os=-lynxos + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 ;; - -ptx*) - basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac ;; - -psos*) - os=-psos + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac ;; esac -# Decode aliases for certain CPU-COMPANY combinations. +# Decode 1-component or ad-hoc basic machines case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | ba \ - | be32 | be64 \ - | bfin \ - | c4x | c8051 | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | e2k | epiphany \ - | fido | fr30 | frv | ft32 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia16 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | pdp10 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pru \ - | pyramid \ - | riscv32 | riscv64 \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | visium \ - | wasm32 \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - leon|leon[3-9]) - basic_machine=sparc-$basic_machine - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) + op50n) + cpu=hppa1.1 + vendor=oki ;; - ms1) - basic_machine=mt-unknown + op60c) + cpu=hppa1.1 + vendor=oki ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown + ibm*) + cpu=i370 + vendor=ibm ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none + orion105) + cpu=clipper + vendor=highlevel ;; - xscaleeb) - basic_machine=armeb-unknown + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple ;; - - xscaleel) - basic_machine=armel-unknown + pmac | pmac-mpw) + cpu=powerpc + vendor=apple ;; - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | ba-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | e2k-* | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | or1k*-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pru-* \ - | pyramid-* \ - | riscv32-* | riscv64-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | visium-* \ - | wasm32-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-pc - os=-bsd - ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att + cpu=m68000 + vendor=att ;; 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - asmjs) - basic_machine=asmjs-unknown - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux + cpu=we32k + vendor=att ;; bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec + cpu=powerpc + vendor=ibm + basic_os=cnk ;; decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 + cpu=pdp10 + vendor=dec + basic_os=tops10 ;; decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 + cpu=pdp10 + vendor=dec + basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx + cpu=m68k + vendor=motorola ;; dpx2*) - basic_machine=m68k-bull - os=-sysv3 - ;; - e500v[12]) - basic_machine=powerpc-unknown - os=$os"spe" - ;; - e500v[12]-*) - basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=$os"spe" - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd + cpu=m68k + vendor=bull + basic_os=sysv3 ;; encore | umax | mmax) - basic_machine=ns32k-encore + cpu=ns32k + vendor=encore ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} ;; fx2800) - basic_machine=i860-alliant + cpu=i860 + vendor=alliant ;; genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 + cpu=ns32k + vendor=ns ;; h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp + cpu=m68000 + vendor=hp ;; hp9k3[2-9][0-9]) - basic_machine=m68k-hp + cpu=m68k + vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm + cpu=hppa1.0 + vendor=hp ;; i*86v32) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv32 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 ;; i*86v4*) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv4 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 ;; i*86v) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv ;; i*86sol2) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 ;; - vsta) - basic_machine=i386-unknown - os=-vsta + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} ;; iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) + cpu=mips + vendor=sgi + case $basic_os in + irix*) ;; *) - os=-irix4 + basic_os=irix4 ;; esac ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - leon-*|leon[3-9]-*) - basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox + cpu=m68000 + vendor=convergent ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint ;; news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv + cpu=mips + vendor=sony + basic_os=newsos ;; next | m*-next) - basic_machine=m68k-next - case $os in - -nextstep* ) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) ;; - -ns2*) - os=-nextstep2 + ns2*) + basic_os=nextstep2 ;; *) - os=-nextstep3 + basic_os=nextstep3 ;; esac ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - nsv-tandem) - basic_machine=nsv-tandem - ;; - nsx-tandem) - basic_machine=nsx-tandem + cpu=np1 + vendor=gould ;; op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k + cpu=hppa1.1 + vendor=oki + basic_os=proelf ;; pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; pbd) - basic_machine=sparc-tti + cpu=sparc + vendor=tti ;; pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc + cpu=m68k + vendor=tti ;; - pc98-*) - basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` + pc532) + cpu=ns32k + vendor=pc532 ;; pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown + cpu=pn + vendor=gould ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` + power) + cpu=power + vendor=ibm ;; - ppc64) basic_machine=powerpc64-unknown + ps2) + cpu=i386 + vendor=ibm ;; - ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + rm[46]00) + cpu=mips + vendor=siemens ;; - ppc64le | powerpc64little) - basic_machine=powerpc64le-unknown + rtpc | rtpc-*) + cpu=romp + vendor=ibm ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} ;; - ps2) - basic_machine=i386-ibm + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks ;; - pw32) - basic_machine=i586-unknown - os=-pw32 + tower | tower-32) + cpu=m68k + vendor=ncr ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu ;; - rdos32) - basic_machine=i386-pc - os=-rdos + w65) + cpu=w65 + vendor=wdc ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf ;; - rm[46]00) - basic_machine=mips-siemens + none) + cpu=none + vendor=none ;; - rtpc | rtpc-*) - basic_machine=romp-ibm + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine ;; - s390 | s390-*) - basic_machine=s390-ibm + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; - s390x | s390x-*) - basic_machine=s390x-ibm + + *-*) + # shellcheck disable=SC2162 + IFS="-" read cpu vendor <&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv64 \ + | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1334,203 +1278,215 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x"$os" != x"" ] +if [ x$basic_os != x ] then + +# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo $basic_os | sed -e 's|gnu/linux|gnu|'` + ;; + nto-qnx*) + kernel=nto + os=`echo $basic_os | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + IFS="-" read kernel os <&2 - exit 1 + # No normalization, but not necessarily accepted, that comes below. ;; esac + else # Here we handle the default operating systems that come with various machines. @@ -1543,258 +1499,352 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +kernel= +case $cpu-$vendor in score-*) - os=-elf + os=elf ;; spu-*) - os=-elf + os=elf ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + kernel=linux + os=gnu ;; arm*-semi) - os=-aout + os=aout ;; c4x-* | tic4x-*) - os=-coff + os=coff ;; c8051-*) - os=-elf + os=elf + ;; + clipper-intergraph) + os=clix ;; hexagon-*) - os=-elf + os=elf ;; tic54x-*) - os=-coff + os=coff ;; tic55x-*) - os=-coff + os=coff ;; tic6x-*) - os=-coff + os=coff ;; # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; pdp11-*) - os=-none + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout ;; mep-*) - os=-elf + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf + os=elf ;; or32-*) - os=-coff + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 ;; pru-*) - os=-elf + os=elf ;; *-be) - os=-beos + os=beos ;; *-ibm) - os=-aix + os=aix ;; *-knuth) - os=-mmixware + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna + os=luna ;; *-next) - os=-nextstep + os=nextstep ;; *-sequent) - os=-ptx + os=ptx ;; *-crds) - os=-unos + os=unos ;; *-ns) - os=-genix + os=genix ;; i370-*) - os=-mvs + os=mvs ;; *-gould) - os=-sysv + os=sysv ;; *-highlevel) - os=-bsd + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; *-sgi) - os=-irix + os=irix ;; *-siemens) - os=-sysv4 + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f30[01]-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + os=none ;; esac + fi +# Now, validate our (potentially fixed-up) OS. +case $os in + # Sometimes we do "kernel-abi", so those need to count as OSes. + musl* | newlib* | uclibc*) + ;; + # Likewise for "kernel-libc" + eabi | eabihf | gnueabi | gnueabihf) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + none) + ;; + *) + echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + nto-qnx*) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - -sunos*) + *-sunos*) vendor=sun ;; - -cnk*|-aix*) + *-cnk* | *-aix*) vendor=ibm ;; - -beos*) + *-beos*) vendor=be ;; - -hpux*) + *-hpux*) vendor=hp ;; - -mpeix*) + *-mpeix*) vendor=hp ;; - -hiux*) + *-hiux*) vendor=hitachi ;; - -unos*) + *-unos*) vendor=crds ;; - -dgux*) + *-dgux*) vendor=dg ;; - -luna*) + *-luna*) vendor=omron ;; - -genix*) + *-genix*) vendor=ns ;; - -mvs* | -opened*) + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) vendor=ibm ;; - -os400*) + s390-* | s390x-*) vendor=ibm ;; - -ptx*) + *-ptx*) vendor=sequent ;; - -tpf*) + *-tpf*) vendor=ibm ;; - -vxsim* | -vxworks* | -windiss*) + *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; - -aux*) + *-aux*) vendor=apple ;; - -hms*) + *-hms*) vendor=hitachi ;; - -mpw* | -macos*) + *-mpw* | *-macos*) vendor=apple ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; - -vos*) + *-vos*) vendor=stratus ;; esac - basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo "$basic_machine$os" +echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: -# eval: (add-hook 'write-file-functions 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/bytecomp/bytegen.ml b/bytecomp/bytegen.ml index ca34b034..49314565 100644 --- a/bytecomp/bytegen.ml +++ b/bytecomp/bytegen.ml @@ -176,7 +176,7 @@ let rec size_of_lambda env = function | Lvar id -> begin try Ident.find_same id env with Not_found -> RHS_nonrec end | Lfunction{params} as funct -> - RHS_function (1 + Ident.Set.cardinal(free_variables funct), + RHS_function (2 + Ident.Set.cardinal(free_variables funct), List.length params) | Llet (Strict, _k, id, Lprim (Pduprecord (kind, size), _, _), body) when check_recordwith_updates id body -> @@ -195,8 +195,8 @@ let rec size_of_lambda env = function let fv = Ident.Set.elements (free_variables (Lletrec(bindings, lambda_unit))) in (* See Instruct(CLOSUREREC) in interp.c *) - let blocksize = List.length bindings * 2 - 1 + List.length fv in - let offsets = List.mapi (fun i (id, _e) -> (id, i * 2)) bindings in + let blocksize = List.length bindings * 3 - 1 + List.length fv in + let offsets = List.mapi (fun i (id, _e) -> (id, i * 3)) bindings in let env = List.fold_right (fun (id, offset) env -> Ident.add id (RHS_infix { blocksize; offset }) env) offsets env in size_of_lambda env body @@ -676,12 +676,14 @@ let rec comp_expr env exp sz cont = comp_expr env arg sz (add_const_unit cont) | Lprim(Pdirapply, [func;arg], loc) | Lprim(Prevapply, [arg;func], loc) -> - let exp = Lapply{ap_should_be_tailcall=false; - ap_loc=loc; - ap_func=func; - ap_args=[arg]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise} in + let exp = Lapply{ + ap_loc=loc; + ap_func=func; + ap_args=[arg]; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + } in comp_expr env exp sz cont | Lprim(Pnot, [arg], _) -> let newcont = @@ -1057,8 +1059,8 @@ let comp_function tc cont = | id :: rem -> Ident.add id pos (positions (pos + delta) delta rem) in let env = { ce_stack = positions arity (-1) tc.params; - ce_heap = positions (2 * (tc.num_defs - tc.rec_pos) - 1) 1 tc.free_vars; - ce_rec = positions (-2 * tc.rec_pos) 2 tc.rec_vars } in + ce_heap = positions (3 * (tc.num_defs - tc.rec_pos) - 1) 1 tc.free_vars; + ce_rec = positions (-3 * tc.rec_pos) 3 tc.rec_vars } in let cont = comp_block env tc.body arity (Kreturn arity :: cont) in if arity > 1 then diff --git a/bytecomp/bytelink.ml b/bytecomp/bytelink.ml index 9a7a46ab..fd5bd490 100644 --- a/bytecomp/bytelink.ml +++ b/bytecomp/bytelink.ml @@ -28,7 +28,7 @@ type error = | Custom_runtime | File_exists of filepath | Cannot_open_dll of filepath - | Required_module_unavailable of modname + | Required_module_unavailable of modname * modname | Camlheader of string * filepath exception Error of error @@ -86,17 +86,17 @@ let add_ccobjs origin l = (* First pass: determine which units are needed *) -let missing_globals = ref Ident.Set.empty +let missing_globals = ref Ident.Map.empty let is_required (rel, _pos) = match rel with Reloc_setglobal id -> - Ident.Set.mem id !missing_globals + Ident.Map.mem id !missing_globals | _ -> false let add_required compunit = let add id = - missing_globals := Ident.Set.add id !missing_globals + missing_globals := Ident.Map.add id compunit.cu_name !missing_globals in List.iter add (Symtable.required_globals compunit.cu_reloc); List.iter add compunit.cu_required_globals @@ -104,7 +104,7 @@ let add_required compunit = let remove_required (rel, _pos) = match rel with Reloc_setglobal id -> - missing_globals := Ident.Set.remove id !missing_globals + missing_globals := Ident.Map.remove id !missing_globals | _ -> () let scan_file obj_name tolink = @@ -188,7 +188,7 @@ let check_consistency file_name cu = begin try let source = List.assoc cu.cu_name !implementations_defined in Location.prerr_warning (Location.in_file file_name) - (Warnings.Multiple_definition(cu.cu_name, + (Warnings.Module_linked_twice(cu.cu_name, Location.show_filename file_name, Location.show_filename source)) with Not_found -> () @@ -466,7 +466,8 @@ let link_bytecode_as_c tolink outfile with_main = (fun () -> (* The bytecode *) output_string outchan "\ -#define CAML_INTERNALS\ +#define CAML_INTERNALS\n\ +#define CAMLDLLIMPORT\ \n\ \n#ifdef __cplusplus\ \nextern \"C\" {\ @@ -573,7 +574,13 @@ let build_custom_runtime prim_name exec_name = else "-lcamlrun" ^ !Clflags.runtime_variant in let debug_prefix_map = if Config.c_has_debug_prefix_map && not !Clflags.keep_camlprimc_file then - [Printf.sprintf "-fdebug-prefix-map=%s=camlprim.c" prim_name] + let flag = + [Printf.sprintf "-fdebug-prefix-map=%s=camlprim.c" prim_name] + in + if Ccomp.linker_is_flexlink then + "-link" :: flag + else + flag else [] in let exitcode = @@ -614,12 +621,13 @@ let link objfiles output_name = in let tolink = List.fold_right scan_file objfiles [] in let missing_modules = - Ident.Set.filter (fun id -> not (Ident.is_predef id)) !missing_globals + Ident.Map.filter (fun id _ -> not (Ident.is_predef id)) !missing_globals in begin - match Ident.Set.elements missing_modules with + match Ident.Map.bindings missing_modules with | [] -> () - | id :: _ -> raise (Error (Required_module_unavailable (Ident.name id))) + | (id, cu_name) :: _ -> + raise (Error (Required_module_unavailable (Ident.name id, cu_name))) end; Clflags.ccobjs := !Clflags.ccobjs @ !lib_ccobjs; (* put user's libs last *) Clflags.all_ccopts := !lib_ccopts @ !Clflags.all_ccopts; @@ -751,8 +759,8 @@ let report_error ppf = function | Cannot_open_dll file -> fprintf ppf "Error on dynamically loaded library: %a" Location.print_filename file - | Required_module_unavailable s -> - fprintf ppf "Required module `%s' is unavailable" s + | Required_module_unavailable (s, m) -> + fprintf ppf "Module `%s' is unavailable (required by `%s')" s m | Camlheader (msg, header) -> fprintf ppf "System error while copying file %s: %s" header msg @@ -767,7 +775,7 @@ let reset () = lib_ccobjs := []; lib_ccopts := []; lib_dllibs := []; - missing_globals := Ident.Set.empty; + missing_globals := Ident.Map.empty; Consistbl.clear crc_interfaces; implementations_defined := []; debug_info := []; diff --git a/bytecomp/bytelink.mli b/bytecomp/bytelink.mli index 4792e7c8..82f851e6 100644 --- a/bytecomp/bytelink.mli +++ b/bytecomp/bytelink.mli @@ -33,7 +33,7 @@ type error = | Custom_runtime | File_exists of filepath | Cannot_open_dll of filepath - | Required_module_unavailable of modname + | Required_module_unavailable of modname * modname | Camlheader of string * filepath exception Error of error diff --git a/bytecomp/dll.ml b/bytecomp/dll.ml index a902a9fc..0f45d15b 100644 --- a/bytecomp/dll.ml +++ b/bytecomp/dll.ml @@ -31,8 +31,16 @@ external get_current_dlls: unit -> dll_handle array (* Current search path for DLLs *) let search_path = ref ([] : string list) +type opened_dll = + | Checking of Binutils.t + | Execution of dll_handle + +let dll_close = function + | Checking _ -> () + | Execution dll -> dll_close dll + (* DLLs currently opened *) -let opened_dlls = ref ([] : dll_handle list) +let opened_dlls = ref ([] : opened_dll list) (* File names for those DLLs *) let names_of_opened_dlls = ref ([] : string list) @@ -67,12 +75,24 @@ let open_dll mode name = else fullname with Not_found -> name in if not (List.mem fullname !names_of_opened_dlls) then begin - try - let dll = dll_open mode fullname in - names_of_opened_dlls := fullname :: !names_of_opened_dlls; - opened_dlls := dll :: !opened_dlls - with Failure msg -> - failwith (fullname ^ ": " ^ msg) + let dll = + match mode with + | For_checking -> + begin match Binutils.read fullname with + | Ok t -> Checking t + | Error err -> + failwith (fullname ^ ": " ^ Binutils.error_to_string err) + end + | For_execution -> + begin match dll_open mode fullname with + | dll -> + Execution dll + | exception Failure msg -> + failwith (fullname ^ ": " ^ msg) + end + in + names_of_opened_dlls := fullname :: !names_of_opened_dlls; + opened_dlls := dll :: !opened_dlls end let open_dlls mode names = @@ -85,19 +105,28 @@ let close_all_dlls () = opened_dlls := []; names_of_opened_dlls := [] -(* Find a primitive in the currently opened DLLs. - Raise [Not_found] if not found. *) +(* Find a primitive in the currently opened DLLs. *) + +type primitive_address = + | Prim_loaded of dll_address + | Prim_exists let find_primitive prim_name = let rec find seen = function [] -> - raise Not_found - | dll :: rem -> + None + | Execution dll as curr :: rem -> let addr = dll_sym dll prim_name in - if addr == Obj.magic () then find (dll :: seen) rem else begin - if seen <> [] then opened_dlls := dll :: List.rev_append seen rem; - addr - end in + if addr == Obj.magic () then find (curr :: seen) rem else begin + if seen <> [] then opened_dlls := curr :: List.rev_append seen rem; + Some (Prim_loaded addr) + end + | Checking t as curr :: rem -> + if Binutils.defines_symbol t prim_name then + Some Prim_exists + else + find (curr :: seen) rem + in find [] !opened_dlls (* If linking in core (dynlink or toplevel), synchronize the VM @@ -156,7 +185,9 @@ let init_toplevel dllpath = ld_library_path_contents() @ split_dll_path dllpath @ ld_conf_contents(); - opened_dlls := Array.to_list (get_current_dlls()); + opened_dlls := + List.map (fun dll -> Execution dll) + (Array.to_list (get_current_dlls())); names_of_opened_dlls := []; linking_in_core := true diff --git a/bytecomp/dll.mli b/bytecomp/dll.mli index 485035ea..5d80e1d4 100644 --- a/bytecomp/dll.mli +++ b/bytecomp/dll.mli @@ -34,9 +34,14 @@ val close_all_dlls: unit -> unit (* The abstract type representing C function pointers *) type dll_address +type primitive_address = + | Prim_loaded of dll_address (* Primitive found in a DLL opened + "for execution" *) + | Prim_exists (* Primitive found in a DLL opened "for checking" *) + (* Find a primitive in the currently opened DLLs and return its address. - Raise [Not_found] if not found. *) -val find_primitive: string -> dll_address + Return [None] if the primitive is not found. *) +val find_primitive: string -> primitive_address option (* If linking in core (dynlink or toplevel), synchronize the VM table of primitive with the linker's table of primitive diff --git a/bytecomp/emitcode.ml b/bytecomp/emitcode.ml index 03251eb0..8eefde57 100644 --- a/bytecomp/emitcode.ml +++ b/bytecomp/emitcode.ml @@ -77,7 +77,6 @@ exception AsInt let const_as_int = function | Const_base(Const_int i) -> i | Const_base(Const_char c) -> Char.code c - | Const_pointer i -> i | _ -> raise AsInt let is_immed i = immed_min <= i && i <= immed_max @@ -227,8 +226,8 @@ let emit_instr = function let org = !out_position in List.iter (out_label_with_orig org) lbls | Koffsetclosure ofs -> - if ofs = -2 || ofs = 0 || ofs = 2 - then out (opOFFSETCLOSURE0 + ofs / 2) + if ofs = -3 || ofs = 0 || ofs = 3 + then out (opOFFSETCLOSURE0 + ofs / 3) else (out opOFFSETCLOSURE; out_int ofs) | Kgetglobal q -> out opGETGLOBAL; slot_for_getglobal q | Ksetglobal q -> out opSETGLOBAL; slot_for_setglobal q @@ -240,10 +239,6 @@ let emit_instr = function else (out opCONSTINT; out_int i) | Const_base(Const_char c) -> out opCONSTINT; out_int (Char.code c) - | Const_pointer i -> - if i >= 0 && i <= 3 - then out (opCONST0 + i) - else (out opCONSTINT; out_int i) | Const_block(t, []) -> if t = 0 then out opATOM0 else (out opATOM; out_int t) | _ -> @@ -356,8 +351,8 @@ let rec emit = function else (out opPUSHENVACC; out_int n); emit c | Kpush :: Koffsetclosure ofs :: c -> - if ofs = -2 || ofs = 0 || ofs = 2 - then out(opPUSHOFFSETCLOSURE0 + ofs / 2) + if ofs = -3 || ofs = 0 || ofs = 3 + then out(opPUSHOFFSETCLOSURE0 + ofs / 3) else (out opPUSHOFFSETCLOSURE; out_int ofs); emit c | Kpush :: Kgetglobal id :: Kgetfield n :: c -> @@ -372,10 +367,6 @@ let rec emit = function else (out opPUSHCONSTINT; out_int i) | Const_base(Const_char c) -> out opPUSHCONSTINT; out_int(Char.code c) - | Const_pointer i -> - if i >= 0 && i <= 3 - then out (opPUSHCONST0 + i) - else (out opPUSHCONSTINT; out_int i) | Const_block(t, []) -> if t = 0 then out opPUSHATOM0 else (out opPUSHATOM; out_int t) | _ -> diff --git a/bytecomp/meta.ml b/bytecomp/meta.ml index d92ea0d4..db2ba155 100644 --- a/bytecomp/meta.ml +++ b/bytecomp/meta.ml @@ -23,7 +23,7 @@ external reify_bytecode : = "caml_reify_bytecode" external release_bytecode : bytecode -> unit = "caml_static_release_bytecode" -external invoke_traced_function : Obj.t -> Obj.t -> Obj.t -> Obj.t +external invoke_traced_function : Obj.raw_data -> Obj.t -> Obj.t -> Obj.t = "caml_invoke_traced_function" external get_section_table : unit -> (string * Obj.t) list = "caml_get_section_table" diff --git a/bytecomp/meta.mli b/bytecomp/meta.mli index 0cf9862a..6ce6ea03 100644 --- a/bytecomp/meta.mli +++ b/bytecomp/meta.mli @@ -25,7 +25,7 @@ external reify_bytecode : = "caml_reify_bytecode" external release_bytecode : bytecode -> unit = "caml_static_release_bytecode" -external invoke_traced_function : Obj.t -> Obj.t -> Obj.t -> Obj.t +external invoke_traced_function : Obj.raw_data -> Obj.t -> Obj.t -> Obj.t = "caml_invoke_traced_function" external get_section_table : unit -> (string * Obj.t) list = "caml_get_section_table" diff --git a/bytecomp/symtable.ml b/bytecomp/symtable.ml index dad4cafe..18960437 100644 --- a/bytecomp/symtable.ml +++ b/bytecomp/symtable.ml @@ -98,12 +98,14 @@ let of_prim name = then PrimMap.enter c_prim_table name else begin - let symb = - try Dll.find_primitive name - with Not_found -> raise(Error(Unavailable_primitive name)) in - let num = PrimMap.enter c_prim_table name in - Dll.synchronize_primitive num symb; - num + match Dll.find_primitive name with + | None -> raise(Error(Unavailable_primitive name)) + | Some Prim_exists -> + PrimMap.enter c_prim_table name + | Some (Prim_loaded symb) -> + let num = PrimMap.enter c_prim_table name in + Dll.synchronize_primitive num symb; + num end let require_primitive name = @@ -222,7 +224,6 @@ let rec transl_const = function | Const_base(Const_int32 i) -> Obj.repr i | Const_base(Const_int64 i) -> Obj.repr i | Const_base(Const_nativeint i) -> Obj.repr i - | Const_pointer i -> Obj.repr i | Const_immstring s -> Obj.repr s | Const_block(tag, fields) -> let block = Obj.new_block tag (List.length fields) in diff --git a/compilerlibs/Makefile.compilerlibs b/compilerlibs/Makefile.compilerlibs index 3acfaf8b..315add7e 100644 --- a/compilerlibs/Makefile.compilerlibs +++ b/compilerlibs/Makefile.compilerlibs @@ -26,11 +26,12 @@ UTILS=utils/config.cmo utils/build_path_prefix_map.cmo utils/misc.cmo \ utils/identifiable.cmo utils/numbers.cmo utils/arg_helper.cmo \ - utils/clflags.cmo utils/profile.cmo utils/load_path.cmo \ + utils/clflags.cmo utils/profile.cmo utils/local_store.cmo \ + utils/load_path.cmo \ utils/terminfo.cmo utils/ccomp.cmo utils/warnings.cmo \ utils/consistbl.cmo utils/strongly_connected_components.cmo \ utils/targetint.cmo utils/int_replace_polymorphic_compare.cmo \ - utils/domainstate.cmo + utils/domainstate.cmo utils/binutils.cmo UTILS_CMI= PARSING=parsing/location.cmo parsing/longident.cmo \ @@ -57,7 +58,7 @@ TYPING=typing/ident.cmo typing/path.cmo \ typing/tast_iterator.cmo typing/tast_mapper.cmo typing/stypes.cmo \ file_formats/cmt_format.cmo typing/cmt2annot.cmo typing/untypeast.cmo \ typing/includemod.cmo typing/typetexp.cmo typing/printpat.cmo \ - typing/parmatch.cmo \ + typing/patterns.cmo typing/parmatch.cmo \ typing/typedecl_properties.cmo typing/typedecl_variance.cmo \ typing/typedecl_unboxed.cmo typing/typedecl_immediacy.cmo \ typing/typedecl_separability.cmo \ @@ -99,14 +100,9 @@ COMMON=$(UTILS) $(PARSING) $(TYPING) $(LAMBDA) $(COMP) BYTECOMP=bytecomp/instruct.cmo bytecomp/bytegen.cmo \ bytecomp/printinstr.cmo bytecomp/emitcode.cmo \ bytecomp/bytelink.cmo bytecomp/bytelibrarian.cmo bytecomp/bytepackager.cmo \ - driver/errors.cmo driver/compile.cmo + driver/errors.cmo driver/compile.cmo driver/maindriver.cmo BYTECOMP_CMI= -ARCH_SPECIFIC =\ - asmcomp/arch.ml asmcomp/proc.ml asmcomp/CSE.ml asmcomp/selection.ml \ - asmcomp/scheduling.ml asmcomp/reload.ml -ARCH_SPECIFIC_CMI= - INTEL_ASM=\ asmcomp/x86_proc.cmo \ asmcomp/x86_dsl.cmo \ @@ -116,6 +112,7 @@ INTEL_ASM_CMI=\ asmcomp/x86_ast.cmi ARCH_SPECIFIC_ASMCOMP= +ARCH_SPECIFIC_ASMCOMP_CMI= ifeq ($(ARCH),i386) ARCH_SPECIFIC_ASMCOMP=$(INTEL_ASM) ARCH_SPECIFIC_ASMCOMP_CMI=$(INTEL_ASM_CMI) @@ -139,7 +136,7 @@ ASMCOMP=\ asmcomp/cmmgen.cmo \ asmcomp/interval.cmo \ asmcomp/printmach.cmo asmcomp/selectgen.cmo \ - asmcomp/spacetime_profiling.cmo asmcomp/selection.cmo \ + asmcomp/selection.cmo \ asmcomp/comballoc.cmo \ asmcomp/CSEgen.cmo asmcomp/CSE.cmo \ asmcomp/liveness.cmo \ @@ -149,6 +146,7 @@ ASMCOMP=\ asmcomp/reloadgen.cmo asmcomp/reload.cmo \ asmcomp/deadcode.cmo \ asmcomp/linear.cmo asmcomp/printlinear.cmo asmcomp/linearize.cmo \ + file_formats/linear_format.cmo \ asmcomp/debug/available_regs.cmo \ asmcomp/debug/compute_ranges_intf.cmo \ asmcomp/debug/compute_ranges.cmo \ @@ -157,7 +155,7 @@ ASMCOMP=\ asmcomp/branch_relaxation.cmo \ asmcomp/emitaux.cmo asmcomp/emit.cmo asmcomp/asmgen.cmo \ asmcomp/asmlink.cmo asmcomp/asmlibrarian.cmo asmcomp/asmpackager.cmo \ - driver/opterrors.cmo driver/optcompile.cmo + driver/opterrors.cmo driver/optcompile.cmo driver/optmaindriver.cmo ASMCOMP_CMI=$(ARCH_SPECIFIC_ASMCOMP_CMI) # Files under middle_end/ are not to reference files under asmcomp/. @@ -272,8 +270,8 @@ OPTTOPLEVEL=toplevel/genprintval.cmo toplevel/opttoploop.cmo \ OPTTOPLEVEL_CMI= -$(COMMON:.cmo=.cmx) $(BYTECOMP:.cmo=.cmx) $(OPTCOMP:.cmo=.cmx): ocamlopt -$(OPTTOPLEVEL:.cmo=.cmx): ocamlopt +$(COMMON:.cmo=.cmx) $(BYTECOMP:.cmo=.cmx) $(OPTCOMP:.cmo=.cmx): ocamlopt$(EXE) +$(OPTTOPLEVEL:.cmo=.cmx): ocamlopt$(EXE) compilerlibs/ocamlcommon.cma: $(COMMON_CMI) $(COMMON) diff --git a/configure b/configure index 50a7bb22..34330eab 100755 --- a/configure +++ b/configure @@ -56,7 +56,7 @@ if test -e '.git' ; then : fi fi # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for OCaml 4.11.2. +# Generated by GNU Autoconf 2.69 for OCaml 4.12.0. # # Report bugs to . # @@ -646,8 +646,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='OCaml' PACKAGE_TARNAME='ocaml' -PACKAGE_VERSION='4.11.2' -PACKAGE_STRING='OCaml 4.11.2' +PACKAGE_VERSION='4.12.0' +PACKAGE_STRING='OCaml 4.12.0' PACKAGE_BUGREPORT='caml-list@inria.fr' PACKAGE_URL='http://www.ocaml.org' @@ -694,10 +694,14 @@ PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC ax_pthread_config +rlwrap +SYSTEM_AS DIRECT_LD INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM +ac_ct_DEP_CC +DEP_CC CPP LT_SYS_LIBRARY_PATH OTOOL64 @@ -729,10 +733,6 @@ ac_ct_LD LD DEFAULT_STRING WINDOWS_UNICODE_MODE -BFD_LIB_DIR -BFD_INCLUDE_DIR -LIBUNWIND_LIB_DIR -LIBUNWIND_INCLUDE_DIR DLLIBS PARTIALLD target_os @@ -747,6 +747,9 @@ build_os build_vendor build_cpu build +naked_pointers_checker +naked_pointers +compute_deps stdlib_manpages PACKLD flexlink_flags @@ -757,14 +760,8 @@ afl function_sections flat_float_array windows_unicode -max_testsuite_dir_retries flambda_invariants flambda -libunwind_link_flags -libunwind_include_flags -libunwind_available -call_counts -spacetime frame_pointers profinfo_width profinfo @@ -779,9 +776,6 @@ asm_cfi_supported AS endianness ASPP -bfd_ldlibs -bfd_ldflags -bfd_cppflags x_libraries x_includes pthread_link @@ -810,6 +804,7 @@ ocamlc_cppflags ocamlc_cflags nativecclibs bytecclibs +oc_dll_ldflags oc_ldflags oc_cppflags oc_cflags @@ -885,11 +880,10 @@ ac_user_opts=' enable_option_checking enable_debug_runtime enable_debugger +enable_dependency_generation enable_instrumented_runtime enable_vmthreads enable_systhreads -with_libunwind -with_bfd enable_graph_lib enable_str_lib enable_unix_lib @@ -898,8 +892,7 @@ enable_ocamldoc enable_ocamltest enable_frame_pointers enable_naked_pointers -enable_spacetime -enable_call_counts +enable_naked_pointers_checker enable_cfi enable_installing_source_artifacts enable_installing_bytecode_programs @@ -909,6 +902,7 @@ enable_flambda_invariants with_target_bindir enable_reserved_header_bits enable_stdlib_manpages +enable_warn_error enable_force_safe_string enable_flat_float_array enable_function_sections @@ -929,10 +923,6 @@ AS ASPP PARTIALLD DLLIBS -LIBUNWIND_INCLUDE_DIR -LIBUNWIND_LIB_DIR -BFD_INCLUDE_DIR -BFD_LIB_DIR WINDOWS_UNICODE_MODE DEFAULT_STRING CC @@ -1482,7 +1472,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures OCaml 4.11.2 to adapt to many kinds of systems. +\`configure' configures OCaml 4.12.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1548,7 +1538,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of OCaml 4.11.2:";; + short | recursive ) echo "Configuration of OCaml 4.12.0:";; esac cat <<\_ACEOF @@ -1558,6 +1548,8 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-debug-runtime do not build runtime with debugging support --enable-debugger build the debugger [default=auto] + --disable-dependency-generation + do not compute dependency information for C sources --enable-instrumented-runtime build the instrumented runtime [default=auto] @@ -1570,8 +1562,8 @@ Optional Features: --enable-frame-pointers use frame pointers in runtime and generated code --disable-naked-pointers do not allow naked pointers - --enable-spacetime build the spacetime profiler - --disable-call-counts disable the call counts in spacetime + --enable-naked-pointers-checker + enable the naked pointers checker --disable-cfi disable the CFI directives in assembly files --enable-installing-source-artifacts install *.cmt* and *.mli files @@ -1587,6 +1579,7 @@ Optional Features: headers for profiling info --disable-stdlib-manpages do not build or install the library man pages + --enable-warn-error treat C compiler warnings as errors --disable-force-safe-string do not force strings to be safe --disable-flat-float-array @@ -1602,9 +1595,6 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --without-libunwind disable libunwind support for Spacetime profiling - --without-bfd disable BFD (Binary File Description) library - support --with-target-bindir location of binary programs on target system --with-afl use the AFL fuzzer --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use @@ -1622,13 +1612,6 @@ Some influential environment variables: PARTIALLD how to build partial (relocatable) object files DLLIBS which libraries to use (in addition to -ldl) to load dynamic libs - LIBUNWIND_INCLUDE_DIR - location of header files for libunwind - LIBUNWIND_LIB_DIR - location of library files for libunwind - BFD_INCLUDE_DIR - location of header files for the BFD library - BFD_LIB_DIR location of library files for the BFD library WINDOWS_UNICODE_MODE how to handle Unicode under Windows: ansi, compatible DEFAULT_STRING @@ -1711,7 +1694,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -OCaml configure 4.11.2 +OCaml configure 4.12.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2314,6 +2297,52 @@ rm -f conftest.val } # ac_fn_c_compute_int +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including @@ -2374,7 +2403,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by OCaml $as_me 4.11.2, which was +It was created by OCaml $as_me 4.12.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2723,8 +2752,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring OCaml version 4.11.2" >&5 -$as_echo "$as_me: Configuring OCaml version 4.11.2" >&6;} +{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring OCaml version 4.12.0" >&5 +$as_echo "$as_me: Configuring OCaml version 4.12.0" >&6;} # Configuration variables @@ -2738,7 +2767,11 @@ programs_man_section=1 libraries_man_section=3 # Command to build executalbes -mkexe="\$(CC) \$(OC_CFLAGS) \$(OC_CPPFLAGS) \$(OC_LDFLAGS)" +# In general this command is supposed to use the CFLAGs-related variables +# ($OC_CFLAGS and $CFLAGS), but at the moment they are not taken into +# account on Windows, because flexlink, which is used to build +# executables on this platform, can not handle them. +mkexe="\$(CC) \$(OC_CFLAGS) \$(CFLAGS) \$(OC_LDFLAGS)" # Flags for building executable files with debugging symbols mkexedebugflag="-g" @@ -2749,6 +2782,7 @@ internal_cppflags="" ocamlc_cflags="" ocamlc_cppflags="" oc_ldflags="" +oc_dll_ldflags="" with_sharedlibs=true ostype="Unix" iflexdir="" @@ -2765,7 +2799,7 @@ instrumented_runtime_ldlibs="" ## Source directory -## Directory containing auxiliary scripts used dugring build +## Directory containing auxiliary scripts used during build ac_aux_dir= for ac_dir in build-aux "$srcdir"/build-aux; do if test -f "$ac_dir/install-sh"; then @@ -2800,7 +2834,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -VERSION=4.11.2 +VERSION=4.12.0 # Note: This is present for the flexdll bootstrap where it exposed as the old @@ -2855,13 +2889,8 @@ VERSION=4.11.2 - # TODO: rename this variable - - - - - + # TODO: rename this variable @@ -2900,7 +2929,7 @@ VERSION=4.11.2 ## Generated files -ac_config_files="$ac_config_files Makefile.common" +ac_config_files="$ac_config_files Makefile.build_config" ac_config_files="$ac_config_files Makefile.config" @@ -3032,6 +3061,10 @@ case $host in #( SO=dll outputexe=-Fe syslib='$(1).lib' ;; #( + i386-*-solaris*) : + as_fn_error $? "Building for 32 bits target is not supported. \ +If your host is 64 bits, you can try with './configure CC=\"gcc -m64\"' \ +(or \"cc -m64\" if you don't have GCC)." "$LINENO" 5 ;; #( *) : ccomptype=cc S=s @@ -3062,6 +3095,14 @@ else fi +# Check whether --enable-dependency-generation was given. +if test "${enable_dependency_generation+set}" = set; then : + enableval=$enable_dependency_generation; +else + enable_dependency_generation=auto +fi + + # Check whether --enable-instrumented-runtime was given. @@ -3085,30 +3126,6 @@ if test "${enable_systhreads+set}" = set; then : fi - -# Check whether --with-libunwind was given. -if test "${with_libunwind+set}" = set; then : - withval=$with_libunwind; -fi - - - - - - - -# Check whether --with-bfd was given. -if test "${with_bfd+set}" = set; then : - withval=$with_bfd; -else - with_bfd=auto -fi - - - - - - # Check whether --enable-graph-lib was given. if test "${enable_graph_lib+set}" = set; then : enableval=$enable_graph_lib; as_fn_error $? "The graphics library is no longer distributed with OCaml \ @@ -3161,15 +3178,9 @@ if test "${enable_naked_pointers+set}" = set; then : fi -# Check whether --enable-spacetime was given. -if test "${enable_spacetime+set}" = set; then : - enableval=$enable_spacetime; -fi - - -# Check whether --enable-call-counts was given. -if test "${enable_call_counts+set}" = set; then : - enableval=$enable_call_counts; +# Check whether --enable-naked-pointers-checker was given. +if test "${enable_naked_pointers_checker+set}" = set; then : + enableval=$enable_naked_pointers_checker; fi @@ -3221,7 +3232,7 @@ if test "${enable_reserved_header_bits+set}" = set; then : 0) : with_profinfo=false profinfo_width=0 ;; #( - [1-9]|1[0-9]|2[0-1]) : + [1-9]|[1-2][0-9]|3[0-1]) : with_profinfo=true profinfo_width="$enable_reserved_header_bits" ;; #( *) : @@ -3236,6 +3247,12 @@ if test "${enable_stdlib_manpages+set}" = set; then : fi +# Check whether --enable-warn-error was given. +if test "${enable_warn_error+set}" = set; then : + enableval=$enable_warn_error; +fi + + # There are two configure-time string safety options, @@ -3418,10 +3435,14 @@ esac fi # libtool expects host_os=mingw for native Windows +# Also, it has been observed that, on some platforms (e.g. msvc) LT_INIT +# alters the CFLAGS variable, so we save its value before calling the macro +# and restore it after the call old_host_os=$host_os if test x"$host_os" = "xwindows"; then : host_os=mingw fi +saved_CFLAGS="$CFLAGS" case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 @@ -12267,8 +12288,138 @@ CC=$lt_save_CC # Only expand once: +CFLAGS="$saved_CFLAGS" host_os=$old_host_os +case $host in #( + sparc-sun-solaris*) : + DEP_CC="false" ;; #( + *-pc-windows) : + if test -n "$ac_tool_prefix"; then + for ac_prog in $DEP_CC gcc cc x86_64-w64-mingw32-gcc i686-w64-mingw32-gcc + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DEP_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DEP_CC"; then + ac_cv_prog_DEP_CC="$DEP_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DEP_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DEP_CC=$ac_cv_prog_DEP_CC +if test -n "$DEP_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DEP_CC" >&5 +$as_echo "$DEP_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DEP_CC" && break + done +fi +if test -z "$DEP_CC"; then + ac_ct_DEP_CC=$DEP_CC + for ac_prog in $DEP_CC gcc cc x86_64-w64-mingw32-gcc i686-w64-mingw32-gcc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DEP_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DEP_CC"; then + ac_cv_prog_ac_ct_DEP_CC="$ac_ct_DEP_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DEP_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DEP_CC=$ac_cv_prog_ac_ct_DEP_CC +if test -n "$ac_ct_DEP_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DEP_CC" >&5 +$as_echo "$ac_ct_DEP_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DEP_CC" && break +done + + if test "x$ac_ct_DEP_CC" = x; then + DEP_CC="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DEP_CC=$ac_ct_DEP_CC + fi +fi + ;; #( + *) : + DEP_CC="$CC" ;; +esac + +case $enable_dependency_generation in #( + yes) : + if test "$DEP_CC" = "false"; then : + as_fn_error $? "The MSVC ports cannot generate dependency information. Install gcc (or another CC-like compiler)" "$LINENO" 5 +else + compute_deps=true +fi ;; #( + no) : + compute_deps=false ;; #( + *) : + if test -e .git; then : + if test "$DEP_CC" = "false"; then : + compute_deps=false +else + compute_deps=true +fi +else + compute_deps=false +fi ;; +esac + # Extracting information from libtool's configuration if test -n "$RANLIB" ; then : RANLIBCMD="$RANLIB" @@ -12322,6 +12473,8 @@ clang __clang_major__ __clang_minor__ gcc __GNUC__ __GNUC_MINOR__ #elif defined(__xlc__) && defined(__xlC__) xlc __xlC__ __xlC_ver__ +#elif defined(__SUNPRO_C) +sunc __SUNPRO_C __SUNPRO_C #else unknown #endif @@ -12360,6 +12513,9 @@ case $ocaml_cv_cc_vendor in #( xlc-*) : CPP="$CC -E -qnoppline" ;; #( # suppress incompatible XLC line directives + sunc-*) : + CPP="$CC -E -Qn" ;; #( + # suppress generation of Sun PRO ident string msvc-*) : CPP="$CC -nologo -EP" ;; #( *) : @@ -12468,21 +12624,28 @@ fi case $ocaml_cv_cc_vendor in #( xlc-*) : - outputobj='-o $(EMPTY)'; gcc_warnings="-qflag=i:i" ;; #( + outputobj='-o $(EMPTY)' + warn_error_flag='' + cc_warnings='-qflag=i:i' ;; #( # all warnings enabled + sunc-*) : + outputobj='-o $(EMPTY)'; cc_warnings="" ;; #( msvc-*) : - outputobj=-Fo; gcc_warnings="" ;; #( + outputobj='-Fo' + warn_error_flag='-WX' + cc_warnings='' ;; #( *) : outputobj='-o $(EMPTY)' - gcc_warnings='-Wall -Wdeclaration-after-statement' - case 4.11.2 in #( - *+dev*) : - gcc_warnings="$gcc_warnings -Werror" ;; #( + warn_error_flag='-Werror' + cc_warnings='-Wall -Wdeclaration-after-statement' ;; +esac + +case $enable_warn_error,4.12.0 in #( + yes,*|,*+dev*) : + cc_warnings="$cc_warnings $warn_error_flag" ;; #( *) : ;; esac - ;; -esac # We select high optimization levels, provided we can turn off: # - strict type-based aliasing analysis (too risky for the OCaml runtime) @@ -12505,7 +12668,7 @@ case $host in #( gcc-[01234]-*) : as_fn_error $? "This version of Mingw GCC is too old. Please use GCC version 5 or above." "$LINENO" 5 ;; #( gcc-*) : - internal_cflags="-Wno-unused $gcc_warnings \ + internal_cflags="-Wno-unused $cc_warnings \ -fexcess-precision=standard" # TODO: see whether the code can be fixed to avoid -Wno-unused common_cflags="-O2 -fno-strict-aliasing -fwrapv -mms-bitfields" @@ -12519,7 +12682,7 @@ esac ;; #( case $ocaml_cv_cc_vendor in #( clang-*) : common_cflags="-O2 -fno-strict-aliasing -fwrapv"; - internal_cflags="$gcc_warnings -fno-common" ;; #( + internal_cflags="$cc_warnings -fno-common" ;; #( gcc-[012]-*) : # Some versions known to miscompile OCaml, e,g, 2.7.2.1, some 2.96. # Plus: C99 support unknown. @@ -12532,29 +12695,34 @@ $as_echo "$as_me: WARNING: This version of GCC is rather old. Reducing optimizat { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Consider using GCC version 4.2 or above." >&5 $as_echo "$as_me: WARNING: Consider using GCC version 4.2 or above." >&2;}; common_cflags="-std=gnu99 -O"; - internal_cflags="$gcc_warnings" ;; #( + internal_cflags="$cc_warnings" ;; #( gcc-4-[234]) : # No -fexcess-precision option before GCC 4.5 common_cflags="-std=gnu99 -O2 -fno-strict-aliasing -fwrapv \ -fno-builtin-memcmp"; - internal_cflags="$gcc_warnings" ;; #( + internal_cflags="$cc_warnings" ;; #( gcc-4-*) : common_cflags="-std=gnu99 -O2 -fno-strict-aliasing -fwrapv \ -fno-builtin-memcmp"; - internal_cflags="$gcc_warnings -fexcess-precision=standard" ;; #( + internal_cflags="$cc_warnings -fexcess-precision=standard" ;; #( gcc-*) : common_cflags="-O2 -fno-strict-aliasing -fwrapv"; - internal_cflags="$gcc_warnings -fno-common \ + internal_cflags="$cc_warnings -fno-common \ -fexcess-precision=standard" ;; #( msvc-*) : - common_cflags="-nologo -O2 -Gy- -MD" + common_cflags="-nologo -O2 -Gy- -MD $cc_warnings" common_cppflags="-D_CRT_SECURE_NO_DEPRECATE" internal_cppflags='-DUNICODE -D_UNICODE' internal_cppflags="$internal_cppflags -DWINDOWS_UNICODE=" internal_cppflags="${internal_cppflags}\$(WINDOWS_UNICODE)" ;; #( xlc-*) : - common_cflags="-O5 -qtune=balanced -qnoipa -qinline $CFLAGS"; - internal_cflags="$gcc_warnings" ;; #( + common_cflags="-O5 -qtune=balanced -qnoipa -qinline"; + internal_cflags="$cc_warnings" ;; #( + sunc-*) : + # Optimization should be >= O4 to inline functions + # and prevent unresolved externals + common_cflags="-O4 -xc99=all -D_XPG6 $CFLAGS"; + internal_cflags="$cc_warnings" ;; #( *) : common_cflags="-O" ;; esac ;; @@ -12636,7 +12804,7 @@ fi if $with_sharedlibs; then : case $host in #( i686-*-*) : - flexdll_chain="mingw" ;; #( + flexdll_chain="mingw"; oc_dll_ldflags="-static-libgcc" ;; #( x86_64-*-*) : flexdll_chain="mingw64" ;; #( *) : @@ -12652,13 +12820,13 @@ fi fi ostype="Win32" toolchain="mingw" - mkexe='$(MKEXE_ANSI) $(if $(OC_LDFLAGS),-link "$(OC_LDFLAGS)")' + mkexe='$(FLEXLINK) -exe $(if $(OC_LDFLAGS),-link "$(OC_LDFLAGS)")' oc_ldflags='-municode' SO="dll" ;; #( *,*-pc-windows) : toolchain=msvc ostype="Win32" - mkexe='$(MKEXE_ANSI) $(if $(OC_LDFLAGS),-link "$(OC_LDFLAGS)")' + mkexe='$(FLEXLINK) -exe $(if $(OC_LDFLAGS),-link "$(OC_LDFLAGS)")' oc_ldflags='/ENTRY:wmainCRTStartup' case $host in #( i686-pc-windows) : @@ -12685,6 +12853,8 @@ fi ;; #( oc_ldflags="-brtl -bexpfull" $as_echo "#define HAS_ARCH_CODE32 1" >>confdefs.h ;; #( + gcc*,powerpc-*-linux*) : + oc_ldflags="-mbss-plt" ;; #( *) : ;; esac @@ -12868,13 +13038,6 @@ if test "x$ac_cv_header_stdint_h" = xyes; then : fi -ac_fn_c_check_header_mongrel "$LINENO" "sys/shm.h" "ac_cv_header_sys_shm_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_shm_h" = xyes; then : - $as_echo "#define HAS_SYS_SHM_H 1" >>confdefs.h - -fi - - ac_fn_c_check_header_compile "$LINENO" "dirent.h" "ac_cv_header_dirent_h" "#include " if test "x$ac_cv_header_dirent_h" = xyes; then : @@ -13325,7 +13488,7 @@ $as_echo "$ac_cv_c_bigendian" >&6; } yes) $as_echo "#define ARCH_BIG_ENDIAN 1" >>confdefs.h -, + endianness="be" ;; #( no) @@ -13487,6 +13650,11 @@ if test x"$enable_shared" != "xno"; then : *-*-mingw32) : mksharedlib='$(FLEXLINK)' mkmaindll='$(FLEXLINK) -maindll' + if test -n "$oc_dll_ldflags"; then : + + mksharedlib="$mksharedlib -link \"$oc_dll_ldflags\"" + mkmaindll="$mkmaindll -link \"$oc_dll_ldflags\"" +fi shared_libraries_supported=$with_sharedlibs ;; #( *-pc-windows) : mksharedlib='$(FLEXLINK)' @@ -13497,17 +13665,28 @@ if test x"$enable_shared" != "xno"; then : mkmaindll="$flexlink -maindll" shared_libraries_supported=true ;; #( powerpc-ibm-aix*) : - case $CC in #( + case $ocaml_cv_cc_vendor in #( xlc*) : mksharedlib="$CC -qmkshrobj -G" shared_libraries_supported=true ;; #( *) : ;; esac ;; #( + *-*-solaris*) : + sharedlib_cflags="-fPIC" + mksharedlib="$CC -shared" + rpath="-Wl,-rpath," + mksharedlibrpath="-Wl,-rpath," + shared_libraries_supported=true ;; #( *-*-linux*|*-*-freebsd[3-9]*|*-*-freebsd[1-9][0-9]*\ |*-*-openbsd*|*-*-netbsd*|*-*-dragonfly*|*-*-gnu*|*-*-haiku*) : sharedlib_cflags="-fPIC" - mksharedlib="$CC -shared" + case $CC,$host in #( + gcc*,powerpc-*-linux*) : + mksharedlib="$CC -shared -mbss-plt" ;; #( + *) : + mksharedlib="$CC -shared" ;; +esac oc_ldflags="$oc_ldflags -Wl,-E" rpath="-Wl,-rpath," mksharedlibrpath="-Wl,-rpath," @@ -13540,12 +13719,18 @@ if test x"$enable_shared" != "xno"; then : natdynlink=true ;; #( x86_64-*-linux*) : natdynlink=true ;; #( + arm64-*-darwin*) : + natdynlink=true ;; #( + aarch64-*-darwin*) : + natdynlink=true ;; #( x86_64-*-darwin*) : natdynlink=true ;; #( s390x*-*-linux*) : natdynlink=true ;; #( powerpc*-*-linux*) : natdynlink=true ;; #( + x86_64-*-solaris*) : + natdynlink=true ;; #( i686-*-kfreebsd*) : natdynlink=true ;; #( x86_64-*-kfreebsd*) : @@ -13634,6 +13819,32 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +## Check whether __attribute__((optimize("tree-vectorize")))) is supported + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler supports __attribute__((optimize(\"tree-vectorize\")))" >&5 +$as_echo_n "checking whether the C compiler supports __attribute__((optimize(\"tree-vectorize\")))... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="-Werror $CFLAGS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + __attribute__((optimize("tree-vectorize"))) void f(void){} + int main() { f(); return 0; } + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + $as_echo "#define SUPPORTS_TREE_VECTORIZE 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$saved_CFLAGS" + + # Configure the native-code compiler arch=none @@ -13705,12 +13916,18 @@ fi; system=elf ;; #( arch=amd64; system=gnu ;; #( x86_64-*-dragonfly*) : arch=amd64; system=dragonfly ;; #( + x86_64-*-solaris*) : + arch=amd64; system=solaris ;; #( x86_64-*-freebsd*) : arch=amd64; system=freebsd ;; #( x86_64-*-netbsd*) : arch=amd64; system=netbsd ;; #( x86_64-*-openbsd*) : arch=amd64; system=openbsd ;; #( + arm64-*-darwin*) : + arch=arm64; system=macosx ;; #( + aarch64-*-darwin*) : + arch=arm64; system=macosx ;; #( x86_64-*-darwin*) : arch=amd64; system=macosx ;; #( x86_64-*-mingw32) : @@ -13729,7 +13946,7 @@ fi; system=elf ;; #( esac if test x"$enable_native_compiler" = "xno"; then : - arch=none; model=default; system=unknown; native_compiler=false + native_compiler=false { $as_echo "$as_me:${as_lineno-$LINENO}: the native compiler is disabled" >&5 $as_echo "$as_me: the native compiler is disabled" >&6;} else @@ -13844,34 +14061,31 @@ else fi if test -z "$PARTIALLD"; then : - # The string for PACKLD must be capable of being concatenated with the - # output filename. Don't assume that all C compilers understand GNU -ofoo - # form, so ensure that the definition includes a space at the end (which is - # achieved using the $(EMPTY) expansion trick). case "$arch,$CC,$system,$model" in #( amd64,gcc*,macosx,*) : - PACKLD='ld -r -arch x86_64 -o $(EMPTY)' ;; #( - amd64,gcc*,solaris,*) : - PACKLD='ld -r -m elf_x86_64 -o $(EMPTY)' ;; #( + PACKLD_FLAGS=' -arch x86_64' ;; #( power,gcc*,elf,ppc) : - PACKLD='ld -r -m elf32ppclinux -o $(EMPTY)' ;; #( + PACKLD_FLAGS=' -m elf32ppclinux' ;; #( power,gcc*,elf,ppc64) : - PACKLD='ld -r -m elf64ppc -o $(EMPTY)' ;; #( + PACKLD_FLAGS=' -m elf64ppc' ;; #( power,gcc*,elf,ppc64le) : - PACKLD='ld -r -m elf64lppc -o $(EMPTY)' ;; #( - # For the Microsoft C compiler there must be no space at the end of the - # string. - *,cl,*,*) : - PACKLD="link -lib -nologo $machine -out:" ;; #( + PACKLD_FLAGS=' -m elf64lppc' ;; #( *) : - PACKLD="$DIRECT_LD -r -o \$(EMPTY)" ;; + PACKLD_FLAGS='' ;; esac + # The string for PACKLD must be capable of being concatenated with the + # output filename. Don't assume that all C compilers understand GNU -ofoo + # form, so ensure that the definition includes a space at the end (which is + # achieved using the $(EMPTY) expansion trick). + if test x"$CC" = "xcl"; then : + # For the Microsoft C compiler there must be no space at the end of the + # string. + PACKLD="link -lib -nologo $machine -out:" else - PACKLD="$PARTIALLD -o \$(EMPTY)" + PACKLD="$DIRECT_LD -r$PACKLD_FLAGS -o \$(EMPTY)" fi - -if test $arch != "none" && $arch64 ; then : - otherlibraries="$otherlibraries raw_spacetime_lib" +else + PACKLD="$PARTIALLD -o \$(EMPTY)" fi # Disable PIE at link time when ocamlopt does not produce position-independent @@ -13913,45 +14127,152 @@ fi # One may want to check whether the user provided values first # and only compute values if none has been provided -case "$arch,$system" in #( - i386,win32) : - default_as="ml -nologo -coff -Cp -c -Fo" ;; #( - amd64,win64) : - default_as="ml64 -nologo -Cp -c -Fo" ;; #( - amd64,macosx) : - case $ocaml_cv_cc_vendor in #( - clang-*) : - default_as='clang -arch x86_64 -Wno-trigraphs -c' - default_aspp='clang -arch x86_64 -Wno-trigraphs -c' ;; #( - *) : - default_as="${toolpref}as -arch x86_64" - default_aspp="${toolpref}gcc -arch x86_64 -c" ;; -esac ;; #( - amd64,solaris) : - default_as="${toolpref}as --64" - default_aspp="${toolpref}gcc -m64 -c" ;; #( - i386,solaris) : - default_as="${toolpref}as" - default_aspp="${toolpref}gcc -c" ;; #( - power,elf) : - case $model in #( - ppc64le) : - default_as="${toolpref}as -a64 -mpower8" - default_aspp="${toolpref}gcc -m64 -mcpu=powerpc64le -c" ;; #( - ppc64) : - default_as="${toolpref}as -a64 -mppc64" - default_aspp="${toolpref}gcc -m64 -c" ;; #( - ppc) : - default_as="${toolpref}as -mppc" - default_aspp="${toolpref}gcc -m32 -c" ;; #( - *) : - ;; -esac ;; #( - s390x,elf) : - default_as="${toolpref}as -m 64 -march=$model" - default_aspp="${toolpref}gcc -c -Wa,-march=$model" ;; #( - *,freebsd) : - default_as="${toolpref}cc -c -Wno-trigraphs" +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_SYSTEM_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$SYSTEM_AS"; then + ac_cv_prog_SYSTEM_AS="$SYSTEM_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_SYSTEM_AS="${ac_tool_prefix}as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +SYSTEM_AS=$ac_cv_prog_SYSTEM_AS +if test -n "$SYSTEM_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SYSTEM_AS" >&5 +$as_echo "$SYSTEM_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_SYSTEM_AS"; then + ac_ct_SYSTEM_AS=$SYSTEM_AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_SYSTEM_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_SYSTEM_AS"; then + ac_cv_prog_ac_ct_SYSTEM_AS="$ac_ct_SYSTEM_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_SYSTEM_AS="as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_SYSTEM_AS=$ac_cv_prog_ac_ct_SYSTEM_AS +if test -n "$ac_ct_SYSTEM_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_SYSTEM_AS" >&5 +$as_echo "$ac_ct_SYSTEM_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_SYSTEM_AS" = x; then + SYSTEM_AS="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + SYSTEM_AS=$ac_ct_SYSTEM_AS + fi +else + SYSTEM_AS="$ac_cv_prog_SYSTEM_AS" +fi + + +case "$arch,$system" in #( + i386,win32) : + default_as="ml -nologo -coff -Cp -c -Fo" ;; #( + amd64,win64) : + default_as="ml64 -nologo -Cp -c -Fo" ;; #( + amd64,macosx) : + case $ocaml_cv_cc_vendor in #( + clang-*) : + default_as='clang -arch x86_64 -Wno-trigraphs -c' + default_aspp='clang -arch x86_64 -Wno-trigraphs -c' ;; #( + *) : + default_as="${toolpref}as -arch x86_64" + default_aspp="${toolpref}gcc -arch x86_64 -c" ;; +esac ;; #( + amd64,solaris) : + case $ocaml_cv_cc_vendor in #( + sunc-*) : + if test x"$SYSTEM_AS" = "x"; then : + as_fn_error $? "GNU as assembler is required." "$LINENO" 5 +else + default_as="${toolpref}as --64" + default_aspp="${toolpref}cc -m64 -c" +fi ;; #( + gcc-*) : + if test x"$SYSTEM_AS" = "x"; then : + default_as="${toolpref}gcc -m64 -c" + default_aspp="${toolpref}gcc -m64 -c" +else + default_as="${toolpref}as --64" + default_aspp="${toolpref}gcc -m64 -c" +fi ;; #( + *) : + ;; +esac ;; #( + power,elf) : + case $model in #( + ppc64le) : + default_as="${toolpref}as -a64 -mpower8" + default_aspp="${toolpref}gcc -m64 -mcpu=powerpc64le -c" ;; #( + ppc64) : + default_as="${toolpref}as -a64 -mppc64" + default_aspp="${toolpref}gcc -m64 -c" ;; #( + ppc) : + default_as="${toolpref}as -mppc" + default_aspp="${toolpref}gcc -m32 -c" ;; #( + *) : + ;; +esac ;; #( + s390x,elf) : + default_as="${toolpref}as -m 64 -march=$model" + default_aspp="${toolpref}gcc -c -Wa,-march=$model" ;; #( + *,freebsd) : + default_as="${toolpref}cc -c -Wno-trigraphs" default_aspp="${toolpref}cc -c -Wno-trigraphs" ;; #( *,dragonfly) : default_as="${toolpref}as" @@ -13987,6 +14308,53 @@ if test -z "$ASPP"; then : ASPP="$default_aspp" fi +# Utilities +# Extract the first word of "rlwrap", so it can be a program name with args. +set dummy rlwrap; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_rlwrap+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$rlwrap"; then + ac_cv_prog_rlwrap="$rlwrap" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_rlwrap="rlwrap" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +rlwrap=$ac_cv_prog_rlwrap +if test -n "$rlwrap"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rlwrap" >&5 +$as_echo "$rlwrap" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +case $rlwrap,$system in #( + rlwrap,win*|rlwrap,mingw*) : + { $as_echo "$as_me:${as_lineno-$LINENO}: rlwrap doesn't work with native win32 - disabling" >&5 +$as_echo "$as_me: rlwrap doesn't work with native win32 - disabling" >&6;} + rlwrap='' ;; #( + *) : + ;; +esac + # Checks for library functions ## Check the semantics of signal handlers @@ -14196,6 +14564,8 @@ esac if test "x$enable_instrumented_runtime" != "xno" ; then : case $host in #( + sparc-sun-solaris*) : + instrumented_runtime=false ;; #( *-*-windows) : instrumented_runtime=true ;; #( *-apple-darwin*) : @@ -14320,6 +14690,9 @@ case $host in #( *-*-haiku) : cclibs="$cclibs -lnetwork" sockets=true ;; #( + *-*-solaris*) : + cclibs="$cclibs -lsocket -lnsl" + sockets=true ;; #( *) : ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" @@ -14464,6 +14837,14 @@ if test "x$ac_cv_func_getcwd" = xyes; then : fi +ac_fn_c_check_decl "$LINENO" "system" "ac_cv_have_decl_system" "#include +" +if test "x$ac_cv_have_decl_system" = xyes; then : + $as_echo "#define HAS_SYSTEM 1" >>confdefs.h + +fi + + ## utime ## Note: this was defined in config/s-nt.h but the autoconf macros do not # seem to detect it properly on Windows so we hardcode the definition @@ -14903,13 +15284,15 @@ fi ## -fdebug-prefix-map support by the C compiler -case $CC,$host in #( +case $ocaml_cv_cc_vendor,$host in #( *,*-*-mingw32) : cc_has_debug_prefix_map=false ;; #( *,*-pc-windows) : cc_has_debug_prefix_map=false ;; #( xlc*,powerpc-ibm-aix*) : cc_has_debug_prefix_map=false ;; #( + sunc*,sparc-sun-*) : + cc_has_debug_prefix_map=false ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler supports -fdebug-prefix-map" >&5 @@ -15440,6 +15823,23 @@ if test "x$ac_cv_func_getauxval" = xyes; then : fi +## shmat +ac_fn_c_check_header_mongrel "$LINENO" "sys/shm.h" "ac_cv_header_sys_shm_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_shm_h" = xyes; then : + + $as_echo "#define HAS_SYS_SHM_H 1" >>confdefs.h + + ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" +if test "x$ac_cv_func_shmat" = xyes; then : + $as_echo "#define HAS_SHMAT 1" >>confdefs.h + +fi + + +fi + + + ## execvpe ac_fn_c_check_func "$LINENO" "execvpe" "ac_cv_func_execvpe" @@ -15449,6 +15849,24 @@ if test "x$ac_cv_func_execvpe" = xyes; then : fi +## posix_spawn + +ac_fn_c_check_header_mongrel "$LINENO" "spawn.h" "ac_cv_header_spawn_h" "$ac_includes_default" +if test "x$ac_cv_header_spawn_h" = xyes; then : + ac_fn_c_check_func "$LINENO" "posix_spawn" "ac_cv_func_posix_spawn" +if test "x$ac_cv_func_posix_spawn" = xyes; then : + ac_fn_c_check_func "$LINENO" "posix_spawnp" "ac_cv_func_posix_spawnp" +if test "x$ac_cv_func_posix_spawnp" = xyes; then : + $as_echo "#define HAS_POSIX_SPAWN 1" >>confdefs.h + +fi + +fi + +fi + + + ## ffs or _BitScanForward ac_fn_c_check_func "$LINENO" "ffs" "ac_cv_func_ffs" @@ -16152,10 +16570,10 @@ if test "x$ax_pthread_ok" = "xyes"; then systhread_support=true otherlibraries="$otherlibraries systhreads" case $host in #( - *-*-solaris*) : - pthread_link="-lpthread -lposix4" ;; #( *-*-haiku*) : pthread_link="" ;; #( + *-*-android*) : + pthread_link="" ;; #( *) : pthread_link="-lpthread" ;; esac @@ -16195,282 +16613,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu esac fi -## BFD (Binary File Description) library - -bfd_cppflags="" -bfd_ldflags="" -bfd_ldlibs="" - -if test x"$with_bfd" != "xno"; then : - bfd_available=false - case $host in #( - x86_64-*-darwin*) : - if test -z "$BFD_INCLUDE_DIR"; then : - BFD_INCLUDE_DIR="/opt/local/include" -fi - if test -z "$BFD_LIB_DIR"; then : - BFD_LIB_DIR="/opt/local/lib" -fi ;; #( - *-*-openbsd*|*-*-freebsd*) : - if test -z "$BFD_INCLUDE_DIR"; then : - BFD_INCLUDE_DIR="/usr/local/include" -fi - if test -z "$BFD_LIB_DIR"; then : - BFD_LIB_DIR="/usr/local/lib" -fi ;; #( - *) : - ;; -esac - if test -n "$BFD_INCLUDE_DIR"; then : - bfd_cppflags="-I$BFD_INCLUDE_DIR" -fi - if test -n "$BFD_LIB_DIR"; then : - bfd_ldflags="-L$BFD_LIB_DIR" -fi - SAVED_CPPFLAGS="$CPPFLAGS" - SAVED_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $bfd_cppflags" - LDFLAGS="$LDFLAGS $bfd_ldflags" - ac_fn_c_check_header_mongrel "$LINENO" "bfd.h" "ac_cv_header_bfd_h" "$ac_includes_default" -if test "x$ac_cv_header_bfd_h" = xyes; then : - bfd_ldlibs="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bfd_openr in -lbfd" >&5 -$as_echo_n "checking for bfd_openr in -lbfd... " >&6; } -if ${ac_cv_lib_bfd_bfd_openr+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbfd $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char bfd_openr (); -int -main () -{ -return bfd_openr (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bfd_bfd_openr=yes -else - ac_cv_lib_bfd_bfd_openr=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bfd_bfd_openr" >&5 -$as_echo "$ac_cv_lib_bfd_bfd_openr" >&6; } -if test "x$ac_cv_lib_bfd_bfd_openr" = xyes; then : - bfd_ldlibs="-lbfd" -fi - - if test -z "$bfd_ldlibs"; then : - unset ac_cv_lib_bfd_bfd_openr - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bfd_openr in -lbfd" >&5 -$as_echo_n "checking for bfd_openr in -lbfd... " >&6; } -if ${ac_cv_lib_bfd_bfd_openr+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbfd $DLLIBS $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char bfd_openr (); -int -main () -{ -return bfd_openr (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bfd_bfd_openr=yes -else - ac_cv_lib_bfd_bfd_openr=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bfd_bfd_openr" >&5 -$as_echo "$ac_cv_lib_bfd_bfd_openr" >&6; } -if test "x$ac_cv_lib_bfd_bfd_openr" = xyes; then : - bfd_ldlibs="-lbfd $DLLIBS" -fi - -fi - if test -z "$bfd_ldlibs"; then : - unset ac_cv_lib_bfd_bfd_openr - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bfd_openr in -lbfd" >&5 -$as_echo_n "checking for bfd_openr in -lbfd... " >&6; } -if ${ac_cv_lib_bfd_bfd_openr+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbfd $DLLIBS -liberty $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char bfd_openr (); -int -main () -{ -return bfd_openr (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bfd_bfd_openr=yes -else - ac_cv_lib_bfd_bfd_openr=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bfd_bfd_openr" >&5 -$as_echo "$ac_cv_lib_bfd_bfd_openr" >&6; } -if test "x$ac_cv_lib_bfd_bfd_openr" = xyes; then : - bfd_ldlibs="-lbfd $DLLIBS -liberty" -fi - -fi - if test -z "$bfd_ldlibs"; then : - unset ac_cv_lib_bfd_bfd_openr - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bfd_openr in -lbfd" >&5 -$as_echo_n "checking for bfd_openr in -lbfd... " >&6; } -if ${ac_cv_lib_bfd_bfd_openr+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbfd $DLLIBS -liberty -lz $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char bfd_openr (); -int -main () -{ -return bfd_openr (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bfd_bfd_openr=yes -else - ac_cv_lib_bfd_bfd_openr=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bfd_bfd_openr" >&5 -$as_echo "$ac_cv_lib_bfd_bfd_openr" >&6; } -if test "x$ac_cv_lib_bfd_bfd_openr" = xyes; then : - bfd_ldlibs="-lbfd $DLLIBS -liberty -lz" -fi - -fi - if test -z "$bfd_ldlibs"; then : - unset ac_cv_lib_bfd_bfd_openr - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bfd_openr in -lbfd" >&5 -$as_echo_n "checking for bfd_openr in -lbfd... " >&6; } -if ${ac_cv_lib_bfd_bfd_openr+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbfd $DLLIBS -liberty -lz -lintl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char bfd_openr (); -int -main () -{ -return bfd_openr (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bfd_bfd_openr=yes -else - ac_cv_lib_bfd_bfd_openr=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bfd_bfd_openr" >&5 -$as_echo "$ac_cv_lib_bfd_bfd_openr" >&6; } -if test "x$ac_cv_lib_bfd_bfd_openr" = xyes; then : - bfd_ldlibs="-lbfd $DLLIBS -liberty -lz -lintl" -fi - -fi - if test -n "$bfd_ldlibs"; then : - bfd_available=true - $as_echo "#define HAS_LIBBFD 1" >>confdefs.h - -fi -fi - - - if ! $bfd_available; then : - if test x"$with_bfd" = "xyes"; then : - as_fn_error $? "BFD library support requested but not available" "$LINENO" 5 -else - bfd_cppflags="" - bfd_ldflags="" - { $as_echo "$as_me:${as_lineno-$LINENO}: BFD library not found, 'ocamlobjinfo' will be unable to display info on .cmxs files." >&5 -$as_echo "$as_me: BFD library not found, 'ocamlobjinfo' will be unable to display info on .cmxs files." >&6;} -fi -fi - LDFLAGS="$SAVED_LDFLAGS" - CPP_FLAGS="$SAVED_CPPFLAGS" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: Support for the BFD (Binary File Description) library disabled, 'ocamlobjinfo' will be unable to display info on .cmxs files." >&5 -$as_echo "$as_me: Support for the BFD (Binary File Description) library disabled, 'ocamlobjinfo' will be unable to display info on .cmxs files." >&6;} -fi - ## Does the assembler support debug prefix map and CFI directives as_has_debug_prefix_map=false asm_cfi_supported=false @@ -16657,8 +16799,32 @@ fi ## No naked pointers if test x"$enable_naked_pointers" = "xno" ; then : - $as_echo "#define NO_NAKED_POINTERS 1" >>confdefs.h + naked_pointers=false + $as_echo "#define NO_NAKED_POINTERS 1" >>confdefs.h +else + naked_pointers=true +fi + +if test x"$enable_naked_pointers_checker" = "xyes" ; then : + if test x"$enable_naked_pointers" = "xno" ; then : + as_fn_error $? "--enable-naked-pointers-checker and --disable-naked-pointers are incompatible" "$LINENO" 5 +fi + case "$arch","$system" in #( + amd64,linux|amd64,macosx \ + |amd64,openbsd|amd64,win64 \ + |amd64,freebsd|amd64,solaris) : + naked_pointers_checker=true + $as_echo "#define NAKED_POINTERS_CHECKER 1" >>confdefs.h + ;; #( + *) : + as_fn_error $? "naked pointers checker not supported on this platform" "$LINENO" 5 + ;; #( + *) : + ;; +esac +else + naked_pointers_checker=false fi ## Check for mmap support for huge pages and contiguous heap @@ -16729,143 +16895,6 @@ fi -# Spacetime profiling, including libunwind detection - -# The number of bits used for profiling information is configurable here. -# The more bits used for profiling, the smaller will be Max_wosize. -# Note that PROFINFO_WIDTH must still be defined even if not configuring -# for Spacetime (see comment in runtime/caml/mlvalues.h on [Profinfo_hd]). -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build spacetime" >&5 -$as_echo_n "checking whether to build spacetime... " >&6; } -if test x"$enable_spacetime" != "xyes" ; then : - spacetime=false - call_counts=true # as in original script but should probably be false - libunwind_available=false - libunwind_include_flags= - libunwind_link_flags= - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -else - case $arch in #( - amd64) : - spacetime_supported=true ;; #( - *) : - spacetime_supported=false ;; -esac - if $spacetime_supported; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - spacetime=true - profinfo=true - profinfo_width=26 - $as_echo "#define WITH_SPACETIME 1" >>confdefs.h - - if test x"$enable_call_counts" != "xno"; then : - call_counts=true - $as_echo "#define ENABLE_CALL_COUNTS 1" >>confdefs.h - -else - call_counts=false -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use libunwind" >&5 -$as_echo_n "checking whether to use libunwind... " >&6; } - if test x"$with_libunwind" = "xno"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 -$as_echo "disabled" >&6; } -else - if test x"$with_libunwind" = "x"; then : - libunwind_requested=false - { $as_echo "$as_me:${as_lineno-$LINENO}: result: if available" >&5 -$as_echo "if available" >&6; } -else - libunwind_requested=true - { $as_echo "$as_me:${as_lineno-$LINENO}: result: requested" >&5 -$as_echo "requested" >&6; } - if test x"$with_libunwind" != "xyes"; then : - if test x"$LIBUNWIND_INCLUDE_DIR" = "x"; then : - LIBUNWIND_INCLUDE_DIR="$with_libunwind/include" -fi - if test x"$LIBUNWIND_LIB_DIR" = "x"; then : - LIBUNWIND_LIB_DIR="$with_libunwind/lib" -fi - -fi - -fi - if test "$system" = "macosx"; then : - if test x"$LIBUNWIND_INCLUDE_DIR" != x -o \ - x"$LIBUNWIND_LIB_DIR" != x; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: On MacOSX, specifying paths for libunwind headers or libraries is strongly discouraged. It is recommended to rely on the defaults provided by the configure script" >&5 -$as_echo "$as_me: WARNING: On MacOSX, specifying paths for libunwind headers or libraries is strongly discouraged. It is recommended to rely on the defaults provided by the configure script" >&2;} -fi -fi - - if test x"$LIBUNWIND_INCLUDE_DIR" != x; then : - libunwind_include_flags="-I$LIBUNWIND_INCLUDE_DIR" -else - libunwind_include_flags="" -fi - - case "$system" in #( - "macosx") : - libunwind_link_flags="-framework System" ;; #( - *) : - libunwind_link_flags="-lunwind -lunwind-x86_64" ;; -esac - - if test x"$LIBUNWIND_LIB_DIR" != x; then : - libunwind_link_flags="-L$LIBUNWIND_LIB_DIR $libunwind_link_flags" -fi - - - SAVED_CFLAGS="$CFLAGS" - SAVED_LDFLAGS="$LDFLAGS" - CFLAGS="$CFLAGS $libunwind_include_flags" - LDFLAGS="$LDFLAGS $libunwind_link_flags" - ac_fn_c_check_header_mongrel "$LINENO" "libunwind.h" "ac_cv_header_libunwind_h" "$ac_includes_default" -if test "x$ac_cv_header_libunwind_h" = xyes; then : - $as_echo "#define HAS_LIBUNWIND 1" >>confdefs.h - - libunwind_available=true -else - libunwind_available=false -fi - - - LDFLAGS="$SAVED_LDFLAGS" - CFLAGS="$SAVED_CFLAGS" - - - if $libunwind_requested && ! $libunwind_available; then : - as_fn_error $? "libunwind was requested but can not be found" "$LINENO" 5 -fi - - # We need unwinding information at runtime, but since we use - # -no_compact_unwind, we also need -keep_dwarf_unwind otherwise - # the OS X linker will chuck away the DWARF-like (.eh_frame) - # information. (Older versions of OS X don't provide this.) - - if $libunwind_available && test x"$system" = "xmacosx"; then : - extra_flags="-Wl,-keep_dwarf_unwind" - mkexe="$mkexe $extra_flags" - mksharedlib="$mksharedlib $extra_flags" -fi -fi - -else - if test x"$enable_spacetime" = "xyes"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: requested but not supported" >&5 -$as_echo "requested but not supported" >&6; } - as_fn_error $? "exiting" "$LINENO" 5 -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -fi - -fi - cat >>confdefs.h <<_ACEOF #define PROFINFO_WIDTH $profinfo_width _ACEOF @@ -16893,7 +16922,7 @@ else ocamldoc=ocamldoc fi -case $enable_ocamltest,4.11.2 in #( +case $enable_ocamltest,4.12.0 in #( yes,*|,*+dev*) : ocamltest='ocamltest' ;; #( *) : @@ -16997,8 +17026,8 @@ fi oc_cflags="$common_cflags $internal_cflags" oc_cppflags="$common_cppflags $internal_cppflags" -ocamlc_cflags="$common_cflags $sharedlib_cflags" -ocamlc_cppflags="$common_cppflags" +ocamlc_cflags="$common_cflags $sharedlib_cflags \$(CFLAGS)" +ocamlc_cppflags="$common_cppflags \$(CPPFLAGS)" cclibs="$cclibs $mathlib" case $host in #( @@ -17023,7 +17052,6 @@ fi case $host in #( *-*-mingw32|*-pc-windows) : - max_testsuite_dir_retries=1 case $WINDOWS_UNICODE_MODE in #( ansi) : windows_unicode=0 ;; #( @@ -17033,8 +17061,7 @@ case $host in #( as_fn_error $? "unexpected windows unicode mode" "$LINENO" 5 ;; esac ;; #( *) : - max_testsuite_dir_retries=0 - windows_unicode=0 ;; + windows_unicode=0 ;; esac # Define flexlink chain and flags correctly for the different Windows ports @@ -17093,6 +17120,11 @@ case $host in #( $as_echo "#define HAS_IPV6 1" >>confdefs.h $as_echo "#define HAS_NICE 1" >>confdefs.h + ;; #( + *-*-solaris*) : + # This is required as otherwise floats are printed + # as "Infinity" and "Inf" instead of the expected "inf" + $as_echo "#define HAS_BROKEN_PRINTF 1" >>confdefs.h ;; #( *) : ;; @@ -17610,7 +17642,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by OCaml $as_me 4.11.2, which was +This file was extended by OCaml $as_me 4.12.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17677,7 +17709,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -OCaml config.status 4.11.2 +OCaml config.status 4.12.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -18087,7 +18119,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in - "Makefile.common") CONFIG_FILES="$CONFIG_FILES Makefile.common" ;; + "Makefile.build_config") CONFIG_FILES="$CONFIG_FILES Makefile.build_config" ;; "Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;; "tools/eventlog_metadata") CONFIG_FILES="$CONFIG_FILES tools/eventlog_metadata" ;; "runtime/caml/m.h") CONFIG_HEADERS="$CONFIG_HEADERS runtime/caml/m.h" ;; diff --git a/configure.ac b/configure.ac index d7dee697..83455a3b 100644 --- a/configure.ac +++ b/configure.ac @@ -37,7 +37,11 @@ programs_man_section=1 libraries_man_section=3 # Command to build executalbes -mkexe="\$(CC) \$(OC_CFLAGS) \$(OC_CPPFLAGS) \$(OC_LDFLAGS)" +# In general this command is supposed to use the CFLAGs-related variables +# ($OC_CFLAGS and $CFLAGS), but at the moment they are not taken into +# account on Windows, because flexlink, which is used to build +# executables on this platform, can not handle them. +mkexe="\$(CC) \$(OC_CFLAGS) \$(CFLAGS) \$(OC_LDFLAGS)" # Flags for building executable files with debugging symbols mkexedebugflag="-g" @@ -48,6 +52,7 @@ internal_cppflags="" ocamlc_cflags="" ocamlc_cppflags="" oc_ldflags="" +oc_dll_ldflags="" with_sharedlibs=true ostype="Unix" iflexdir="" @@ -64,7 +69,7 @@ instrumented_runtime_ldlibs="" ## Source directory AC_CONFIG_SRCDIR([runtime/interp.c]) -## Directory containing auxiliary scripts used dugring build +## Directory containing auxiliary scripts used during build AC_CONFIG_AUX_DIR([build-aux]) ## Output variables @@ -104,6 +109,7 @@ AC_SUBST([toolchain]) AC_SUBST([oc_cflags]) AC_SUBST([oc_cppflags]) AC_SUBST([oc_ldflags]) +AC_SUBST([oc_dll_ldflags]) AC_SUBST([bytecclibs]) AC_SUBST([nativecclibs]) AC_SUBST([ocamlc_cflags]) @@ -132,9 +138,6 @@ AC_SUBST([ocamltest]) AC_SUBST([pthread_link]) AC_SUBST([x_includes]) AC_SUBST([x_libraries]) -AC_SUBST([bfd_cppflags]) -AC_SUBST([bfd_ldflags]) -AC_SUBST([bfd_ldlibs]) AC_SUBST([ASPP]) AC_SUBST([endianness]) AC_SUBST([AS]) @@ -149,14 +152,8 @@ AC_SUBST([install_source_artifacts]) AC_SUBST([profinfo]) AC_SUBST([profinfo_width]) AC_SUBST([frame_pointers]) -AC_SUBST([spacetime]) -AC_SUBST([call_counts]) -AC_SUBST([libunwind_available]) -AC_SUBST([libunwind_include_flags]) -AC_SUBST([libunwind_link_flags]) AC_SUBST([flambda]) AC_SUBST([flambda_invariants]) -AC_SUBST([max_testsuite_dir_retries]) AC_SUBST([windows_unicode]) AC_SUBST([flat_float_array]) AC_SUBST([function_sections]) @@ -167,10 +164,13 @@ AC_SUBST([flexdll_chain]) AC_SUBST([flexlink_flags]) AC_SUBST([PACKLD]) AC_SUBST([stdlib_manpages]) +AC_SUBST([compute_deps]) +AC_SUBST([naked_pointers]) +AC_SUBST([naked_pointers_checker]) ## Generated files -AC_CONFIG_FILES([Makefile.common]) +AC_CONFIG_FILES([Makefile.build_config]) AC_CONFIG_FILES([Makefile.config]) AC_CONFIG_FILES([tools/eventlog_metadata]) AC_CONFIG_HEADERS([runtime/caml/m.h]) @@ -190,6 +190,10 @@ AS_CASE([$host], SO=dll outputexe=-Fe syslib='$(1).lib'], + [i386-*-solaris*], + [AC_MSG_ERROR([Building for 32 bits target is not supported. \ +If your host is 64 bits, you can try with './configure CC="gcc -m64"' \ +(or "cc -m64" if you don't have GCC).])], [ccomptype=cc S=s SO=so @@ -214,6 +218,12 @@ AC_ARG_ENABLE([debugger], [], [enable_debugger=auto]) +AC_ARG_ENABLE([dependency-generation], + [AS_HELP_STRING([--disable-dependency-generation], + [do not compute dependency information for C sources])], + [], + [enable_dependency_generation=auto]) + AC_ARG_VAR([DLLIBS], [which libraries to use (in addition to -ldl) to load dynamic libs]) @@ -232,28 +242,6 @@ AC_ARG_ENABLE([systhreads], [AS_HELP_STRING([--disable-systhreads], [disable the Win32/POSIX threads library])]) -AC_ARG_WITH([libunwind], - [AS_HELP_STRING([--without-libunwind], - [disable libunwind support for Spacetime profiling])]) - -AC_ARG_VAR([LIBUNWIND_INCLUDE_DIR], - [location of header files for libunwind]) - -AC_ARG_VAR([LIBUNWIND_LIB_DIR], - [location of library files for libunwind]) - -AC_ARG_WITH([bfd], - [AS_HELP_STRING([--without-bfd], - [disable BFD (Binary File Description) library support])], - [], - [with_bfd=auto]) - -AC_ARG_VAR([BFD_INCLUDE_DIR], - [location of header files for the BFD library]) - -AC_ARG_VAR([BFD_LIB_DIR], - [location of library files for the BFD library]) - AC_ARG_ENABLE([graph-lib], [], [AC_MSG_ERROR([The graphics library is no longer distributed with OCaml \ since version 4.09. It is now distributed as a separate "graphics" package: \ @@ -290,13 +278,9 @@ AC_ARG_ENABLE([naked-pointers], [AS_HELP_STRING([--disable-naked-pointers], [do not allow naked pointers])]) -AC_ARG_ENABLE([spacetime], - [AS_HELP_STRING([--enable-spacetime], - [build the spacetime profiler])]) - -AC_ARG_ENABLE([call-counts], - [AS_HELP_STRING([--disable-call-counts], - [disable the call counts in spacetime])]) +AC_ARG_ENABLE([naked-pointers-checker], + [AS_HELP_STRING([--enable-naked-pointers-checker], + [enable the naked pointers checker])]) AC_ARG_ENABLE([cfi], [AS_HELP_STRING([--disable-cfi], @@ -332,7 +316,7 @@ AC_ARG_ENABLE([reserved-header-bits], [0], [with_profinfo=false profinfo_width=0], - [[[1-9]]|1[[0-9]]|2[[0-1]]], + [[[1-9]]|[[1-2]][[0-9]]|3[[0-1]]], [with_profinfo=true profinfo_width="$enable_reserved_header_bits"], [AC_MSG_ERROR([invalid argument to --enable-reserved-header-bits])])]) @@ -341,6 +325,10 @@ AC_ARG_ENABLE([stdlib-manpages], [AS_HELP_STRING([--disable-stdlib-manpages], [do not build or install the library man pages])]) +AC_ARG_ENABLE([warn-error], + [AS_HELP_STRING([--enable-warn-error], + [treat C compiler warnings as errors])]) + AC_ARG_VAR([WINDOWS_UNICODE_MODE], [how to handle Unicode under Windows: ansi, compatible]) @@ -409,11 +397,39 @@ AS_IF([test x"$enable_unix_lib" = "xno" -o x"$enable_str_lib" = "xno"], # User-specified LD still takes precedence. AC_CHECK_TOOLS([LD],[ld link]) # libtool expects host_os=mingw for native Windows +# Also, it has been observed that, on some platforms (e.g. msvc) LT_INIT +# alters the CFLAGS variable, so we save its value before calling the macro +# and restore it after the call old_host_os=$host_os AS_IF([test x"$host_os" = "xwindows"],[host_os=mingw]) +saved_CFLAGS="$CFLAGS" LT_INIT +CFLAGS="$saved_CFLAGS" host_os=$old_host_os +AS_CASE([$host], + [sparc-sun-solaris*], + [DEP_CC="false"], + [*-pc-windows], + [AC_CHECK_TOOLS( + [DEP_CC], + [$DEP_CC gcc cc x86_64-w64-mingw32-gcc i686-w64-mingw32-gcc], + [false])], + [DEP_CC="$CC"]) + +AS_CASE([$enable_dependency_generation], + [yes], + [AS_IF([test "$DEP_CC" = "false"], + [AC_MSG_ERROR(m4_normalize([The MSVC ports cannot generate dependency + information. Install gcc (or another CC-like compiler)]))], + [compute_deps=true])], + [no], [compute_deps=false], + [AS_IF([test -e .git], + [AS_IF([test "$DEP_CC" = "false"], + [compute_deps=false], + [compute_deps=true])], + [compute_deps=false])]) + # Extracting information from libtool's configuration AS_IF([test -n "$RANLIB" ], [RANLIBCMD="$RANLIB"], @@ -459,6 +475,8 @@ OCAML_CC_VENDOR AS_CASE([$ocaml_cv_cc_vendor], [xlc-*], [CPP="$CC -E -qnoppline"], # suppress incompatible XLC line directives + [sunc-*], + [CPP="$CC -E -Qn"], # suppress generation of Sun PRO ident string [msvc-*], [CPP="$CC -nologo -EP"]) @@ -528,15 +546,22 @@ AS_IF( AS_CASE([$ocaml_cv_cc_vendor], [xlc-*], - [outputobj='-o $(EMPTY)'; gcc_warnings="-qflag=i:i"], # all warnings enabled + [outputobj='-o $(EMPTY)' + warn_error_flag='' + cc_warnings='-qflag=i:i'], # all warnings enabled + [sunc-*], + [outputobj='-o $(EMPTY)'; cc_warnings=""], [msvc-*], - [outputobj=-Fo; gcc_warnings=""], + [outputobj='-Fo' + warn_error_flag='-WX' + cc_warnings=''], [outputobj='-o $(EMPTY)' - gcc_warnings='-Wall -Wdeclaration-after-statement' - AS_CASE([AC_PACKAGE_VERSION], - [*+dev*], - [gcc_warnings="$gcc_warnings -Werror"]) - ]) + warn_error_flag='-Werror' + cc_warnings='-Wall -Wdeclaration-after-statement']) + +AS_CASE([$enable_warn_error,AC_PACKAGE_VERSION], + [yes,*|,*+dev*], + [cc_warnings="$cc_warnings $warn_error_flag"]) # We select high optimization levels, provided we can turn off: # - strict type-based aliasing analysis (too risky for the OCaml runtime) @@ -560,7 +585,7 @@ AS_CASE([$host], [AC_MSG_ERROR(m4_normalize([This version of Mingw GCC is too old. Please use GCC version 5 or above.]))], [gcc-*], - [internal_cflags="-Wno-unused $gcc_warnings \ + [internal_cflags="-Wno-unused $cc_warnings \ -fexcess-precision=standard" # TODO: see whether the code can be fixed to avoid -Wno-unused common_cflags="-O2 -fno-strict-aliasing -fwrapv -mms-bitfields" @@ -571,7 +596,7 @@ AS_CASE([$host], [AS_CASE([$ocaml_cv_cc_vendor], [clang-*], [common_cflags="-O2 -fno-strict-aliasing -fwrapv"; - internal_cflags="$gcc_warnings -fno-common"], + internal_cflags="$cc_warnings -fno-common"], [gcc-[[012]]-*], # Some versions known to miscompile OCaml, e,g, 2.7.2.1, some 2.96. # Plus: C99 support unknown. @@ -584,29 +609,33 @@ AS_CASE([$host], Reducing optimization level."])); AC_MSG_WARN([Consider using GCC version 4.2 or above.]); common_cflags="-std=gnu99 -O"; - internal_cflags="$gcc_warnings"], + internal_cflags="$cc_warnings"], [gcc-4-[[234]]], # No -fexcess-precision option before GCC 4.5 [common_cflags="-std=gnu99 -O2 -fno-strict-aliasing -fwrapv \ -fno-builtin-memcmp"; - internal_cflags="$gcc_warnings"], + internal_cflags="$cc_warnings"], [gcc-4-*], [common_cflags="-std=gnu99 -O2 -fno-strict-aliasing -fwrapv \ -fno-builtin-memcmp"; - internal_cflags="$gcc_warnings -fexcess-precision=standard"], + internal_cflags="$cc_warnings -fexcess-precision=standard"], [gcc-*], [common_cflags="-O2 -fno-strict-aliasing -fwrapv"; - internal_cflags="$gcc_warnings -fno-common \ + internal_cflags="$cc_warnings -fno-common \ -fexcess-precision=standard"], [msvc-*], - [common_cflags="-nologo -O2 -Gy- -MD" + [common_cflags="-nologo -O2 -Gy- -MD $cc_warnings" common_cppflags="-D_CRT_SECURE_NO_DEPRECATE" internal_cppflags='-DUNICODE -D_UNICODE' internal_cppflags="$internal_cppflags -DWINDOWS_UNICODE=" internal_cppflags="${internal_cppflags}\$(WINDOWS_UNICODE)"], [xlc-*], - [common_cflags="-O5 -qtune=balanced -qnoipa -qinline $CFLAGS"; - internal_cflags="$gcc_warnings"], + [common_cflags="-O5 -qtune=balanced -qnoipa -qinline"; + internal_cflags="$cc_warnings"], + [sunc-*], # Optimization should be >= O4 to inline functions + # and prevent unresolved externals + [common_cflags="-O4 -xc99=all -D_XPG6 $CFLAGS"; + internal_cflags="$cc_warnings"], [common_cflags="-O"])]) internal_cppflags="-DCAML_NAME_SPACE $internal_cppflags" @@ -665,7 +694,7 @@ AS_CASE([$CC,$host], [*,*-*-mingw32], [AS_IF([$with_sharedlibs], [AS_CASE([$host], - [i686-*-*], [flexdll_chain="mingw"], + [i686-*-*], [flexdll_chain="mingw"; oc_dll_ldflags="-static-libgcc"], [x86_64-*-*], [flexdll_chain="mingw64"]) flexlink="flexlink -chain $flexdll_chain -merge-manifest -stack 16777216" flexdir=`$flexlink -where | tr -d '\015'` @@ -674,13 +703,13 @@ AS_CASE([$CC,$host], mkexedebugflag="-link -g"]) ostype="Win32" toolchain="mingw" - mkexe='$(MKEXE_ANSI) $(if $(OC_LDFLAGS),-link "$(OC_LDFLAGS)")' + mkexe='$(FLEXLINK) -exe $(if $(OC_LDFLAGS),-link "$(OC_LDFLAGS)")' oc_ldflags='-municode' SO="dll"], [*,*-pc-windows], [toolchain=msvc ostype="Win32" - mkexe='$(MKEXE_ANSI) $(if $(OC_LDFLAGS),-link "$(OC_LDFLAGS)")' + mkexe='$(FLEXLINK) -exe $(if $(OC_LDFLAGS),-link "$(OC_LDFLAGS)")' oc_ldflags='/ENTRY:wmainCRTStartup' AS_CASE([$host], [i686-pc-windows], [flexdll_chain=msvc], @@ -697,6 +726,8 @@ AS_CASE([$CC,$host], [mkexe="$mkexe " oc_ldflags="-brtl -bexpfull" AC_DEFINE([HAS_ARCH_CODE32], [1])], + [gcc*,powerpc-*-linux*], + [oc_ldflags="-mbss-plt"], ) @@ -715,7 +746,6 @@ AS_IF([test "x$ac_cv_lib_m_cos" = xyes ], [mathlib="-lm"], [mathlib=""]) AC_CHECK_HEADER([math.h]) AC_CHECK_HEADERS([unistd.h],[AC_DEFINE([HAS_UNISTD])]) AC_CHECK_HEADER([stdint.h],[AC_DEFINE([HAS_STDINT_H])]) -AC_CHECK_HEADER([sys/shm.h],[AC_DEFINE([HAS_SYS_SHM_H])]) AC_CHECK_HEADER([dirent.h], [AC_DEFINE([HAS_DIRENT])], [], [#include ]) @@ -764,7 +794,7 @@ AC_MSG_NOTICE([Target is a $bits bits architecture]) AC_C_BIGENDIAN( [ - AC_DEFINE([ARCH_BIG_ENDIAN], [1]), + AC_DEFINE([ARCH_BIG_ENDIAN], [1]) [endianness="be"] ], [endianness="le"], @@ -807,6 +837,9 @@ AS_IF([test x"$enable_shared" != "xno"], [*-*-mingw32], [mksharedlib='$(FLEXLINK)' mkmaindll='$(FLEXLINK) -maindll' + AS_IF([test -n "$oc_dll_ldflags"],[ + mksharedlib="$mksharedlib -link \"$oc_dll_ldflags\"" + mkmaindll="$mkmaindll -link \"$oc_dll_ldflags\""]) shared_libraries_supported=$with_sharedlibs], [*-pc-windows], [mksharedlib='$(FLEXLINK)' @@ -817,14 +850,22 @@ AS_IF([test x"$enable_shared" != "xno"], mkmaindll="$flexlink -maindll" shared_libraries_supported=true], [powerpc-ibm-aix*], - [AS_CASE([$CC], + [AS_CASE([$ocaml_cv_cc_vendor], [xlc*], [mksharedlib="$CC -qmkshrobj -G" shared_libraries_supported=true])], + [*-*-solaris*], + [sharedlib_cflags="-fPIC" + mksharedlib="$CC -shared" + rpath="-Wl,-rpath," + mksharedlibrpath="-Wl,-rpath," + shared_libraries_supported=true], [[*-*-linux*|*-*-freebsd[3-9]*|*-*-freebsd[1-9][0-9]*\ |*-*-openbsd*|*-*-netbsd*|*-*-dragonfly*|*-*-gnu*|*-*-haiku*]], [sharedlib_cflags="-fPIC" - mksharedlib="$CC -shared" + AS_CASE([$CC,$host], + [gcc*,powerpc-*-linux*], [mksharedlib="$CC -shared -mbss-plt"], + [mksharedlib="$CC -shared"]) oc_ldflags="$oc_ldflags -Wl,-E" rpath="-Wl,-rpath," mksharedlibrpath="-Wl,-rpath," @@ -845,9 +886,12 @@ AS_IF([test x"$enable_shared" != "xno"], [[i[3456]86-*-linux*]], [natdynlink=true], [[i[3456]86-*-gnu*]], [natdynlink=true], [[x86_64-*-linux*]], [natdynlink=true], + [arm64-*-darwin*], [natdynlink=true], + [aarch64-*-darwin*], [natdynlink=true], [x86_64-*-darwin*], [natdynlink=true], [s390x*-*-linux*], [natdynlink=true], [powerpc*-*-linux*], [natdynlink=true], + [x86_64-*-solaris*], [natdynlink=true], [i686-*-kfreebsd*], [natdynlink=true], [x86_64-*-kfreebsd*], [natdynlink=true], [x86_64-*-dragonfly*], [natdynlink=true], @@ -875,6 +919,9 @@ AS_CASE(["$CC,$host"], OCAML_CC_SUPPORTS_ALIGNED +## Check whether __attribute__((optimize("tree-vectorize")))) is supported +OCAML_CC_SUPPORTS_TREE_VECTORIZE + # Configure the native-code compiler arch=none @@ -942,12 +989,18 @@ AS_CASE([$host], [arch=amd64; system=gnu], [x86_64-*-dragonfly*], [arch=amd64; system=dragonfly], + [x86_64-*-solaris*], + [arch=amd64; system=solaris], [x86_64-*-freebsd*], [arch=amd64; system=freebsd], [x86_64-*-netbsd*], [arch=amd64; system=netbsd], [x86_64-*-openbsd*], [arch=amd64; system=openbsd], + [arm64-*-darwin*], + [arch=arm64; system=macosx], + [aarch64-*-darwin*], + [arch=arm64; system=macosx], [x86_64-*-darwin*], [arch=amd64; system=macosx], [x86_64-*-mingw32], @@ -963,7 +1016,7 @@ AS_CASE([$host], ) AS_IF([test x"$enable_native_compiler" = "xno"], - [arch=none; model=default; system=unknown; native_compiler=false + [native_compiler=false AC_MSG_NOTICE([the native compiler is disabled])], [native_compiler=true]) @@ -975,25 +1028,23 @@ AC_DEFINE_UNQUOTED([OCAML_OS_TYPE], ["$ostype"]) AC_CHECK_TOOL([DIRECT_LD],[ld]) AS_IF([test -z "$PARTIALLD"], + [AS_CASE(["$arch,$CC,$system,$model"], + [amd64,gcc*,macosx,*], [PACKLD_FLAGS=' -arch x86_64'], + [power,gcc*,elf,ppc], [PACKLD_FLAGS=' -m elf32ppclinux'], + [power,gcc*,elf,ppc64], [PACKLD_FLAGS=' -m elf64ppc'], + [power,gcc*,elf,ppc64le], [PACKLD_FLAGS=' -m elf64lppc'], + [PACKLD_FLAGS='']) # The string for PACKLD must be capable of being concatenated with the # output filename. Don't assume that all C compilers understand GNU -ofoo # form, so ensure that the definition includes a space at the end (which is # achieved using the $(EMPTY) expansion trick). - [AS_CASE(["$arch,$CC,$system,$model"], - [amd64,gcc*,macosx,*], [PACKLD='ld -r -arch x86_64 -o $(EMPTY)'], - [amd64,gcc*,solaris,*], [PACKLD='ld -r -m elf_x86_64 -o $(EMPTY)'], - [power,gcc*,elf,ppc], [PACKLD='ld -r -m elf32ppclinux -o $(EMPTY)'], - [power,gcc*,elf,ppc64], [PACKLD='ld -r -m elf64ppc -o $(EMPTY)'], - [power,gcc*,elf,ppc64le], [PACKLD='ld -r -m elf64lppc -o $(EMPTY)'], + AS_IF([test x"$CC" = "xcl"], # For the Microsoft C compiler there must be no space at the end of the # string. - [*,cl,*,*], [PACKLD="link -lib -nologo $machine -out:"], - [PACKLD="$DIRECT_LD -r -o \$(EMPTY)"])], + [PACKLD="link -lib -nologo $machine -out:"], + [PACKLD="$DIRECT_LD -r$PACKLD_FLAGS -o \$(EMPTY)"])], [PACKLD="$PARTIALLD -o \$(EMPTY)"]) -AS_IF([test $arch != "none" && $arch64 ], - [otherlibraries="$otherlibraries raw_spacetime_lib"]) - # Disable PIE at link time when ocamlopt does not produce position-independent # code and the system produces PIE executables by default and demands PIC # object files to do so. @@ -1025,6 +1076,8 @@ AS_IF([test -n "$host_alias"], [toolpref="${host_alias}-"], [toolpref=""]) # One may want to check whether the user provided values first # and only compute values if none has been provided +AC_CHECK_TOOL([SYSTEM_AS],[as]) + AS_CASE(["$arch,$system"], [i386,win32], [default_as="ml -nologo -coff -Cp -c -Fo"], @@ -1038,11 +1091,18 @@ AS_CASE(["$arch,$system"], [default_as="${toolpref}as -arch x86_64" default_aspp="${toolpref}gcc -arch x86_64 -c"])], [amd64,solaris], - [default_as="${toolpref}as --64" - default_aspp="${toolpref}gcc -m64 -c"], - [i386,solaris], - [default_as="${toolpref}as" - default_aspp="${toolpref}gcc -c"], + [AS_CASE([$ocaml_cv_cc_vendor], + [sunc-*], + [AS_IF([test x"$SYSTEM_AS" = "x"], + [AC_MSG_ERROR([GNU as assembler is required.])], + [default_as="${toolpref}as --64" + default_aspp="${toolpref}cc -m64 -c"])], + [gcc-*], + [AS_IF([test x"$SYSTEM_AS" = "x"], + [default_as="${toolpref}gcc -m64 -c" + default_aspp="${toolpref}gcc -m64 -c"], + [default_as="${toolpref}as --64" + default_aspp="${toolpref}gcc -m64 -c"])])], [power,elf], [AS_CASE([$model], [ppc64le], @@ -1081,6 +1141,13 @@ AS_IF([test -z "$AS"], [AS="$default_as"]) AS_IF([test -z "$ASPP"], [ASPP="$default_aspp"]) +# Utilities +AC_CHECK_PROG([rlwrap],[rlwrap],[rlwrap]) +AS_CASE([$rlwrap,$system], + [rlwrap,win*|rlwrap,mingw*], + [AC_MSG_NOTICE([rlwrap doesn't work with native win32 - disabling]) + rlwrap='']) + # Checks for library functions ## Check the semantics of signal handlers @@ -1173,6 +1240,8 @@ AS_CASE([$host], AS_IF([test "x$enable_instrumented_runtime" != "xno" ], [ AS_CASE([$host], + [sparc-sun-solaris*], + [instrumented_runtime=false], [*-*-windows], [instrumented_runtime=true], [*-apple-darwin*], [ @@ -1228,6 +1297,9 @@ AS_CASE([$host], [*-*-haiku], [cclibs="$cclibs -lnetwork" sockets=true], + [*-*-solaris*], + [cclibs="$cclibs -lsocket -lnsl" + sockets=true], [ AC_CHECK_FUNC([socket]) AC_CHECK_FUNC([socketpair]) @@ -1283,6 +1355,8 @@ AC_CHECK_FUNC([mkfifo], [AC_DEFINE([HAS_MKFIFO])]) AC_CHECK_FUNC([getcwd], [AC_DEFINE([HAS_GETCWD])]) +AC_CHECK_DECL([system], [AC_DEFINE([HAS_SYSTEM])], [], [[#include ]]) + ## utime ## Note: this was defined in config/s-nt.h but the autoconf macros do not # seem to detect it properly on Windows so we hardcode the definition @@ -1449,10 +1523,11 @@ AC_CHECK_HEADER([sys/mman.h], AC_CHECK_FUNC([pwrite], [AC_DEFINE([HAS_PWRITE])]) ## -fdebug-prefix-map support by the C compiler -AS_CASE([$CC,$host], +AS_CASE([$ocaml_cv_cc_vendor,$host], [*,*-*-mingw32], [cc_has_debug_prefix_map=false], [*,*-pc-windows], [cc_has_debug_prefix_map=false], [xlc*,powerpc-ibm-aix*], [cc_has_debug_prefix_map=false], + [sunc*,sparc-sun-*], [cc_has_debug_prefix_map=false], [OCAML_CC_HAS_DEBUG_PREFIX_MAP]) ## Does stat support nanosecond precision @@ -1532,10 +1607,23 @@ AC_CHECK_FUNC([accept4], [AC_DEFINE([HAS_ACCEPT4])]) AC_CHECK_FUNC([getauxval], [AC_DEFINE([HAS_GETAUXVAL])]) +## shmat +AC_CHECK_HEADER([sys/shm.h], + [ + AC_DEFINE([HAS_SYS_SHM_H]) + AC_CHECK_FUNC([shmat], [AC_DEFINE([HAS_SHMAT])]) + ]) + ## execvpe AC_CHECK_FUNC([execvpe], [AC_DEFINE([HAS_EXECVPE])]) +## posix_spawn + +AC_CHECK_HEADER([spawn.h], + [AC_CHECK_FUNC([posix_spawn], + [AC_CHECK_FUNC([posix_spawnp], [AC_DEFINE([HAS_POSIX_SPAWN])])])]) + ## ffs or _BitScanForward AC_CHECK_FUNC([ffs], [AC_DEFINE([HAS_FFS])]) @@ -1584,8 +1672,8 @@ AS_IF([test x"$enable_systhreads" = "xno"], [systhread_support=true otherlibraries="$otherlibraries systhreads" AS_CASE([$host], - [*-*-solaris*], [pthread_link="-lpthread -lposix4"], [*-*-haiku*], [pthread_link=""], + [*-*-android*], [pthread_link=""], [pthread_link="-lpthread"]) common_cppflags="$common_cppflags -D_REENTRANT" AC_MSG_NOTICE([the POSIX threads library is supported]) @@ -1601,72 +1689,6 @@ AS_IF([test x"$enable_systhreads" = "xno"], [systhread_support=false AC_MSG_NOTICE([the POSIX threads library is not supported])])])])]) -## BFD (Binary File Description) library - -bfd_cppflags="" -bfd_ldflags="" -bfd_ldlibs="" - -AS_IF([test x"$with_bfd" != "xno"], - [bfd_available=false - AS_CASE([$host], - [x86_64-*-darwin*], - [AS_IF([test -z "$BFD_INCLUDE_DIR"], - [BFD_INCLUDE_DIR="/opt/local/include"]) - AS_IF([test -z "$BFD_LIB_DIR"], - [BFD_LIB_DIR="/opt/local/lib"])], - [*-*-openbsd*|*-*-freebsd*], - [AS_IF([test -z "$BFD_INCLUDE_DIR"], - [BFD_INCLUDE_DIR="/usr/local/include"]) - AS_IF([test -z "$BFD_LIB_DIR"], - [BFD_LIB_DIR="/usr/local/lib"])]) - AS_IF([test -n "$BFD_INCLUDE_DIR"], - [bfd_cppflags="-I$BFD_INCLUDE_DIR"]) - AS_IF([test -n "$BFD_LIB_DIR"], - [bfd_ldflags="-L$BFD_LIB_DIR"]) - SAVED_CPPFLAGS="$CPPFLAGS" - SAVED_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $bfd_cppflags" - LDFLAGS="$LDFLAGS $bfd_ldflags" - AC_CHECK_HEADER([bfd.h], - [bfd_ldlibs="" - AC_CHECK_LIB([bfd], [bfd_openr], [bfd_ldlibs="-lbfd"]) - AS_IF([test -z "$bfd_ldlibs"], - [unset ac_cv_lib_bfd_bfd_openr - AC_CHECK_LIB([bfd], [bfd_openr], - [bfd_ldlibs="-lbfd $DLLIBS"], [], [$DLLIBS])]) - AS_IF([test -z "$bfd_ldlibs"], - [unset ac_cv_lib_bfd_bfd_openr - AC_CHECK_LIB([bfd], [bfd_openr], - [bfd_ldlibs="-lbfd $DLLIBS -liberty"], [], [$DLLIBS -liberty])]) - AS_IF([test -z "$bfd_ldlibs"], - [unset ac_cv_lib_bfd_bfd_openr - AC_CHECK_LIB([bfd], [bfd_openr], - [bfd_ldlibs="-lbfd $DLLIBS -liberty -lz"], [], [$DLLIBS -liberty -lz])]) - AS_IF([test -z "$bfd_ldlibs"], - [unset ac_cv_lib_bfd_bfd_openr - AC_CHECK_LIB([bfd], [bfd_openr], - [bfd_ldlibs="-lbfd $DLLIBS -liberty -lz -lintl"], [], - [$DLLIBS -liberty -lz -lintl])]) - AS_IF([test -n "$bfd_ldlibs"], - [bfd_available=true - AC_DEFINE([HAS_LIBBFD])])]) - AS_IF([! $bfd_available], - [AS_IF([test x"$with_bfd" = "xyes"], - [AC_MSG_ERROR([BFD library support requested but not available])], - [bfd_cppflags="" - bfd_ldflags="" - AC_MSG_NOTICE(m4_normalize([ - BFD library not found, 'ocamlobjinfo' will be unable to display - info on .cmxs files. - ]))])]) - LDFLAGS="$SAVED_LDFLAGS" - CPP_FLAGS="$SAVED_CPPFLAGS"], - [AC_MSG_NOTICE(m4_normalize([ - Support for the BFD (Binary File Description) library disabled, - 'ocamlobjinfo' will be unable to display info on .cmxs files. - ]))]) - ## Does the assembler support debug prefix map and CFI directives as_has_debug_prefix_map=false asm_cfi_supported=false @@ -1693,95 +1715,29 @@ AS_IF([test x"$enable_frame_pointers" = "xyes"], ## No naked pointers AS_IF([test x"$enable_naked_pointers" = "xno" ], - [AC_DEFINE([NO_NAKED_POINTERS])]) + [naked_pointers=false + AC_DEFINE([NO_NAKED_POINTERS])], + [naked_pointers=true]) + +AS_IF([test x"$enable_naked_pointers_checker" = "xyes" ], + [AS_IF([test x"$enable_naked_pointers" = "xno" ], + [AC_MSG_ERROR(m4_normalize([ + --enable-naked-pointers-checker and --disable-naked-pointers + are incompatible]))]) + AS_CASE(["$arch","$system"], + [amd64,linux|amd64,macosx \ + |amd64,openbsd|amd64,win64 \ + |amd64,freebsd|amd64,solaris], + [naked_pointers_checker=true + AC_DEFINE([NAKED_POINTERS_CHECKER])], + [*], + [AC_MSG_ERROR([naked pointers checker not supported on this platform])] + )], + [naked_pointers_checker=false]) ## Check for mmap support for huge pages and contiguous heap OCAML_MMAP_SUPPORTS_HUGE_PAGES -# Spacetime profiling, including libunwind detection - -# The number of bits used for profiling information is configurable here. -# The more bits used for profiling, the smaller will be Max_wosize. -# Note that PROFINFO_WIDTH must still be defined even if not configuring -# for Spacetime (see comment in runtime/caml/mlvalues.h on [Profinfo_hd]). -AC_MSG_CHECKING([whether to build spacetime]) -AS_IF([test x"$enable_spacetime" != "xyes" ], - [spacetime=false - call_counts=true # as in original script but should probably be false - libunwind_available=false - libunwind_include_flags= - libunwind_link_flags= - AC_MSG_RESULT([no])], - [AS_CASE([$arch], - [amd64], [spacetime_supported=true], - [spacetime_supported=false]) - AS_IF([$spacetime_supported], - [AC_MSG_RESULT([yes]) - spacetime=true - profinfo=true - profinfo_width=26 - AC_DEFINE([WITH_SPACETIME]) - AS_IF([test x"$enable_call_counts" != "xno"], - [call_counts=true - AC_DEFINE([ENABLE_CALL_COUNTS])], - [call_counts=false]) - AC_MSG_CHECKING([whether to use libunwind]) - AS_IF([test x"$with_libunwind" = "xno"], - [AC_MSG_RESULT([disabled])], - [AS_IF([test x"$with_libunwind" = "x"], - [libunwind_requested=false - AC_MSG_RESULT([if available])], - [libunwind_requested=true - AC_MSG_RESULT([requested]) - AS_IF([test x"$with_libunwind" != "xyes"], - [AS_IF([test x"$LIBUNWIND_INCLUDE_DIR" = "x"], - [LIBUNWIND_INCLUDE_DIR="$with_libunwind/include"]) - AS_IF([test x"$LIBUNWIND_LIB_DIR" = "x"], - [LIBUNWIND_LIB_DIR="$with_libunwind/lib"]) - ]) - ]) - AS_IF([test "$system" = "macosx"], - [AS_IF([test x"$LIBUNWIND_INCLUDE_DIR" != x -o \ - x"$LIBUNWIND_LIB_DIR" != x], - [AC_MSG_WARN(m4_normalize([ - On MacOSX, specifying paths for libunwind headers or libraries - is strongly discouraged. It is recommended to rely on the - defaults provided by the configure script - ]))])]) - - AS_IF([test x"$LIBUNWIND_INCLUDE_DIR" != x], - [libunwind_include_flags="-I$LIBUNWIND_INCLUDE_DIR"], - [libunwind_include_flags=""]) - - AS_CASE(["$system"], - ["macosx"], [libunwind_link_flags="-framework System"], - [libunwind_link_flags="-lunwind -lunwind-x86_64"]) - - AS_IF([test x"$LIBUNWIND_LIB_DIR" != x], - [libunwind_link_flags="-L$LIBUNWIND_LIB_DIR $libunwind_link_flags"]) - - OCAML_CHECK_LIBUNWIND - - AS_IF([$libunwind_requested && ! $libunwind_available], - [AC_MSG_ERROR([libunwind was requested but can not be found])]) - - # We need unwinding information at runtime, but since we use - # -no_compact_unwind, we also need -keep_dwarf_unwind otherwise - # the OS X linker will chuck away the DWARF-like (.eh_frame) - # information. (Older versions of OS X don't provide this.) - - AS_IF([$libunwind_available && test x"$system" = "xmacosx"], - [extra_flags="-Wl,-keep_dwarf_unwind" - mkexe="$mkexe $extra_flags" - mksharedlib="$mksharedlib $extra_flags"])]) - ], - [AS_IF([test x"$enable_spacetime" = "xyes"], - [AC_MSG_RESULT([requested but not supported]) - AC_MSG_ERROR([exiting])], - [AC_MSG_RESULT([no])]) - ]) - ]) - AC_DEFINE_UNQUOTED([PROFINFO_WIDTH], [$profinfo_width]) AS_IF([$profinfo], [AC_DEFINE([WITH_PROFINFO])]) @@ -1862,8 +1818,8 @@ AS_IF([test x"$DEFAULT_STRING" = "xunsafe"], oc_cflags="$common_cflags $internal_cflags" oc_cppflags="$common_cppflags $internal_cppflags" -ocamlc_cflags="$common_cflags $sharedlib_cflags" -ocamlc_cppflags="$common_cppflags" +ocamlc_cflags="$common_cflags $sharedlib_cflags \$(CFLAGS)" +ocamlc_cppflags="$common_cppflags \$(CPPFLAGS)" cclibs="$cclibs $mathlib" AS_CASE([$host], @@ -1884,15 +1840,13 @@ AS_IF([test x"$mandir" = x'${datarootdir}/man'], AS_CASE([$host], [*-*-mingw32|*-pc-windows], - [max_testsuite_dir_retries=1 - AS_CASE([$WINDOWS_UNICODE_MODE], + [AS_CASE([$WINDOWS_UNICODE_MODE], [ansi], [windows_unicode=0], [compatible|""], [windows_unicode=1], [AC_MSG_ERROR([unexpected windows unicode mode])])], - [max_testsuite_dir_retries=0 - windows_unicode=0]) + [windows_unicode=0]) # Define flexlink chain and flags correctly for the different Windows ports AS_CASE([$host], @@ -1929,7 +1883,11 @@ AS_CASE([$host], [AC_DEFINE([HAS_BROKEN_PRINTF]) AC_DEFINE([HAS_STRERROR]) AC_DEFINE([HAS_IPV6]) - AC_DEFINE([HAS_NICE])]) + AC_DEFINE([HAS_NICE])], + [*-*-solaris*], + # This is required as otherwise floats are printed + # as "Infinity" and "Inf" instead of the expected "inf" + [AC_DEFINE([HAS_BROKEN_PRINTF])]) AS_IF([test x"$enable_stdlib_manpages" != "xno"], [stdlib_manpages=true],[stdlib_manpages=false]) diff --git a/debugger/Makefile b/debugger/Makefile index 9b8c11f0..3620fa88 100644 --- a/debugger/Makefile +++ b/debugger/Makefile @@ -15,8 +15,7 @@ ROOTDIR = .. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common +include $(ROOTDIR)/Makefile.common include $(ROOTDIR)/Makefile.best_binaries DYNLINKDIR=$(ROOTDIR)/otherlibs/dynlink @@ -28,7 +27,6 @@ CAMLC=$(BEST_OCAMLC) -g -nostdlib -I $(ROOTDIR)/stdlib COMPFLAGS=$(INCLUDES) -absname -w +a-4-9-41-42-44-45-48 -warn-error A \ -safe-string -strict-sequence -strict-formats LINKFLAGS=-linkall -I $(UNIXDIR) -I $(DYNLINKDIR) -YACCFLAGS= CAMLLEX=$(BEST_OCAMLLEX) CAMLDEP=$(BEST_OCAMLDEP) DEPFLAGS=-slash @@ -61,7 +59,7 @@ ocamldebug$(EXE): $(libraries) $(all_objects) $(CAMLC) $(LINKFLAGS) -o $@ -linkall $^ install: - $(INSTALL_PROG) ocamldebug$(EXE) "$(INSTALL_BINDIR)/ocamldebug$(EXE)" + $(INSTALL_PROG) ocamldebug$(EXE) "$(INSTALL_BINDIR)" clean:: rm -f ocamldebug ocamldebug.exe diff --git a/debugger/time_travel.ml b/debugger/time_travel.ml index 4d3252fb..83cf23f4 100644 --- a/debugger/time_travel.ml +++ b/debugger/time_travel.ml @@ -181,7 +181,7 @@ let new_checkpoint_list checkpoint_count accepted rejected = let (k, l) = list_truncate2 (checkpoint_count - List.length accepted) rejected in - (List.merge (fun {c_time = t1} {c_time = t2} -> compare t2 t1) accepted k, + (List.merge (fun t1 t2 -> compare t2.c_time t1.c_time) accepted k, l) (* Clean the checkpoint list. *) diff --git a/driver/compenv.ml b/driver/compenv.ml index 8c960915..8efe79e6 100644 --- a/driver/compenv.ml +++ b/driver/compenv.ml @@ -15,6 +15,8 @@ open Clflags +exception Exit_with_status of int + let output_prefix name = let oname = match !output_name with @@ -27,17 +29,19 @@ let print_version_and_library compiler = print_string Config.version; print_newline(); print_string "Standard library directory: "; print_string Config.standard_library; print_newline(); - exit 0 + raise (Exit_with_status 0) let print_version_string () = - print_string Config.version; print_newline(); exit 0 + print_string Config.version; print_newline(); + raise (Exit_with_status 0) let print_standard_library () = - print_string Config.standard_library; print_newline(); exit 0 + print_string Config.standard_library; print_newline(); + raise (Exit_with_status 0) let fatal err = prerr_endline err; - exit 2 + raise (Exit_with_status 2) let extract_output = function | Some s -> s @@ -189,6 +193,30 @@ let check_bool ppf name s = "bad value %s for %s" s name; false +let decode_compiler_pass ppf v ~name ~filter = + let module P = Clflags.Compiler_pass in + let passes = P.available_pass_names ~filter ~native:!native_code in + begin match List.find_opt (String.equal v) passes with + | None -> + Printf.ksprintf (print_error ppf) + "bad value %s for option \"%s\" (expected one of: %s)" + v name (String.concat ", " passes); + None + | Some v -> P.of_string v + end + +let set_compiler_pass ppf ~name v flag ~filter = + match decode_compiler_pass ppf v ~name ~filter with + | None -> () + | Some pass -> + match !flag with + | None -> flag := Some pass + | Some p -> + if not (p = pass) then begin + Printf.ksprintf (print_error ppf) + "Please specify at most one %s ." name + end + (* 'can-discard=' specifies which arguments can be discarded without warning because they are not understood by some versions of OCaml. *) let can_discard = ref [] @@ -432,17 +460,16 @@ let read_one_param ppf position name v = profile_columns := if check_bool ppf name v then if_on else [] | "stop-after" -> - let module P = Clflags.Compiler_pass in - let passes = P.available_pass_names ~native:!native_code in - begin match List.find_opt (String.equal v) passes with - | None -> - Printf.ksprintf (print_error ppf) - "bad value %s for option \"stop-after\" (expected one of: %s)" - v (String.concat ", " passes) - | Some v -> - let pass = Option.get (P.of_string v) in - Clflags.stop_after := Some pass + set_compiler_pass ppf v ~name Clflags.stop_after ~filter:(fun _ -> true) + + | "save-ir-after" -> + if !native_code then begin + let filter = Clflags.Compiler_pass.can_save_ir_after in + match decode_compiler_pass ppf v ~name ~filter with + | None -> () + | Some pass -> set_save_ir_after pass true end + | _ -> if not (List.mem name !can_discard) then begin can_discard := name :: !can_discard; @@ -451,20 +478,22 @@ let read_one_param ppf position name v = name end + let read_OCAMLPARAM ppf position = try let s = Sys.getenv "OCAMLPARAM" in - let (before, after) = - try - parse_args s - with SyntaxError s -> - print_error ppf s; - [],[] - in - List.iter (fun (name, v) -> read_one_param ppf position name v) - (match position with - Before_args -> before - | Before_compile _ | Before_link -> after) + if s <> "" then + let (before, after) = + try + parse_args s + with SyntaxError s -> + print_error ppf s; + [],[] + in + List.iter (fun (name, v) -> read_one_param ppf position name v) + (match position with + Before_args -> before + | Before_compile _ | Before_link -> after) with Not_found -> () (* OCAMLPARAM passed as file *) @@ -589,12 +618,15 @@ let c_object_of_filename name = let process_action (ppf, implementation, interface, ocaml_mod_ext, ocaml_lib_ext) action = + let impl ~start_from name = + readenv ppf (Before_compile name); + let opref = output_prefix name in + implementation ~start_from ~source_file:name ~output_prefix:opref; + objfiles := (opref ^ ocaml_mod_ext) :: !objfiles + in match action with | ProcessImplementation name -> - readenv ppf (Before_compile name); - let opref = output_prefix name in - implementation ~source_file:name ~output_prefix:opref; - objfiles := (opref ^ ocaml_mod_ext) :: !objfiles + impl ~start_from:Compiler_pass.Parsing name | ProcessInterface name -> readenv ppf (Before_compile name); let opref = output_prefix name in @@ -603,7 +635,7 @@ let process_action | ProcessCFile name -> readenv ppf (Before_compile name); Location.input_name := name; - if Ccomp.compile_file name <> 0 then exit 2; + if Ccomp.compile_file name <> 0 then raise (Exit_with_status 2); ccobjs := c_object_of_filename name :: !ccobjs | ProcessObjects names -> ccobjs := names @ !ccobjs @@ -621,7 +653,11 @@ let process_action else if not !native_code && Filename.check_suffix name Config.ext_dll then dllibs := name :: !dllibs else - raise(Arg.Bad("don't know what to do with " ^ name)) + match Compiler_pass.of_input_filename name with + | Some start_from -> + Location.input_name := name; + impl ~start_from name + | None -> raise(Arg.Bad("don't know what to do with " ^ name)) let action_of_file name = diff --git a/driver/compenv.mli b/driver/compenv.mli index 2afbdfae..93a585dc 100644 --- a/driver/compenv.mli +++ b/driver/compenv.mli @@ -13,6 +13,8 @@ (* *) (**************************************************************************) +exception Exit_with_status of int + val module_of_filename : string -> string -> string val output_prefix : string -> string @@ -69,7 +71,8 @@ val intf : string -> unit val process_deferred_actions : Format.formatter * - (source_file:string -> output_prefix:string -> unit) * + (start_from:Clflags.Compiler_pass.t -> + source_file:string -> output_prefix:string -> unit) * (* compile implementation *) (source_file:string -> output_prefix:string -> unit) * (* compile interface *) diff --git a/driver/compile.ml b/driver/compile.ml index c41a877f..ead46036 100644 --- a/driver/compile.ml +++ b/driver/compile.ml @@ -54,10 +54,13 @@ let emit_bytecode i (bytecode, required_globals) = (Emitcode.to_file oc i.module_name cmofile ~required_globals); ) -let implementation ~source_file ~output_prefix = +let implementation ~start_from ~source_file ~output_prefix = let backend info typed = let bytecode = to_bytecode info typed in emit_bytecode info bytecode in with_info ~source_file ~output_prefix ~dump_ext:"cmo" @@ fun info -> - Compile_common.implementation info ~backend + match (start_from : Clflags.Compiler_pass.t) with + | Parsing -> Compile_common.implementation info ~backend + | _ -> Misc.fatal_errorf "Cannot start from %s" + (Clflags.Compiler_pass.to_string start_from) diff --git a/driver/compile.mli b/driver/compile.mli index 7c564c3e..96895576 100644 --- a/driver/compile.mli +++ b/driver/compile.mli @@ -18,6 +18,7 @@ val interface: source_file:string -> output_prefix:string -> unit val implementation: + start_from:Clflags.Compiler_pass.t -> source_file:string -> output_prefix:string -> unit (** {2 Internal functions} **) diff --git a/driver/compile_common.ml b/driver/compile_common.ml index 82b5f006..95442afb 100644 --- a/driver/compile_common.ml +++ b/driver/compile_common.ml @@ -14,7 +14,6 @@ (**************************************************************************) open Misc -open Compenv type info = { source_file : string; @@ -33,7 +32,7 @@ let annot i = i.output_prefix ^ ".annot" let with_info ~native ~tool_name ~source_file ~output_prefix ~dump_ext k = Compmisc.init_path (); - let module_name = module_of_filename source_file output_prefix in + let module_name = Compenv.module_of_filename source_file output_prefix in Env.set_unit_name module_name; let env = Compmisc.initial_env() in let dump_file = String.concat "." [output_prefix; dump_ext] in diff --git a/driver/compmisc.ml b/driver/compmisc.ml index 601d1269..2a7e0d61 100644 --- a/driver/compmisc.ml +++ b/driver/compmisc.ml @@ -13,8 +13,6 @@ (* *) (**************************************************************************) -open Compenv - (* Initialize the search path. [dir] is always searched first (default: the current directory), then the directories specified with the -I option (in command-line order), @@ -28,7 +26,8 @@ let init_path ?(dir="") () = !Clflags.include_dirs in let dirs = - !last_include_dirs @ dirs @ Config.flexdll_dirs @ !first_include_dirs + !Compenv.last_include_dirs @ dirs @ Config.flexdll_dirs @ + !Compenv.first_include_dirs in let exp_dirs = List.map (Misc.expand_directory Config.standard_library) dirs in diff --git a/driver/main.ml b/driver/main.ml index 449d91c9..b8e4344c 100644 --- a/driver/main.ml +++ b/driver/main.ml @@ -1,116 +1,2 @@ -(**************************************************************************) -(* *) -(* OCaml *) -(* *) -(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -(* *) -(* Copyright 1996 Institut National de Recherche en Informatique et *) -(* en Automatique. *) -(* *) -(* All rights reserved. This file is distributed under the terms of *) -(* the GNU Lesser General Public License version 2.1, with the *) -(* special exception on linking described in the file LICENSE. *) -(* *) -(**************************************************************************) - -open Clflags -open Compenv - -let usage = "Usage: ocamlc \nOptions are:" - -(* Error messages to standard error formatter *) -let ppf = Format.err_formatter - -module Options = Main_args.Make_bytecomp_options (Main_args.Default.Main) - -let main () = - Clflags.add_arguments __LOC__ Options.list; - Clflags.add_arguments __LOC__ - ["-depend", Arg.Unit Makedepend.main_from_option, - " Compute dependencies (use 'ocamlc -depend -help' for details)"]; - try - readenv ppf Before_args; - Clflags.parse_arguments anonymous usage; - Compmisc.read_clflags_from_env (); - if !Clflags.plugin then - fatal "-plugin is only supported up to OCaml 4.08.0"; - begin try - Compenv.process_deferred_actions - (ppf, - Compile.implementation, - Compile.interface, - ".cmo", - ".cma"); - with Arg.Bad msg -> - begin - prerr_endline msg; - Clflags.print_arguments usage; - exit 2 - end - end; - readenv ppf Before_link; - if - List.length - (List.filter (fun x -> !x) - [make_archive;make_package;stop_early;output_c_object]) - > 1 - then begin - let module P = Clflags.Compiler_pass in - match !stop_after with - | None -> - fatal "Please specify at most one of -pack, -a, -c, -output-obj"; - | Some ((P.Parsing | P.Typing) as p) -> - assert (P.is_compilation_pass p); - Printf.ksprintf fatal - "Options -i and -stop-after (%s) \ - are incompatible with -pack, -a, -output-obj" - (String.concat "|" - (Clflags.Compiler_pass.available_pass_names ~native:false)) - | Some P.Scheduling -> assert false (* native only *) - end; - if !make_archive then begin - Compmisc.init_path (); - - Bytelibrarian.create_archive - (Compenv.get_objfiles ~with_ocamlparam:false) - (extract_output !output_name); - Warnings.check_fatal (); - end - else if !make_package then begin - Compmisc.init_path (); - let extracted_output = extract_output !output_name in - let revd = get_objfiles ~with_ocamlparam:false in - Compmisc.with_ppf_dump ~file_prefix:extracted_output (fun ppf_dump -> - Bytepackager.package_files ~ppf_dump (Compmisc.initial_env ()) - revd (extracted_output)); - Warnings.check_fatal (); - end - else if not !stop_early && !objfiles <> [] then begin - let target = - if !output_c_object && not !output_complete_executable then - let s = extract_output !output_name in - if (Filename.check_suffix s Config.ext_obj - || Filename.check_suffix s Config.ext_dll - || Filename.check_suffix s ".c") - then s - else - fatal - (Printf.sprintf - "The extension of the output file must be .c, %s or %s" - Config.ext_obj Config.ext_dll - ) - else - default_output !output_name - in - Compmisc.init_path (); - Bytelink.link (get_objfiles ~with_ocamlparam:true) target; - Warnings.check_fatal (); - end; - with x -> - Location.report_exception ppf x; - exit 2 - let () = - main (); - Profile.print Format.std_formatter !Clflags.profile_columns; - exit 0 + exit (Maindriver.main Sys.argv Format.err_formatter) diff --git a/driver/main_args.ml b/driver/main_args.ml index 5c28ded5..d5a4ca42 100644 --- a/driver/main_args.ml +++ b/driver/main_args.ml @@ -107,11 +107,24 @@ let mk_function_sections f = ;; let mk_stop_after ~native f = - "-stop-after", - Arg.Symbol (Clflags.Compiler_pass.available_pass_names ~native, f), + let pass_names = Clflags.Compiler_pass.available_pass_names + ~filter:(fun _ -> true) + ~native + in + "-stop-after", Arg.Symbol (pass_names, f), " Stop after the given compilation pass." ;; +let mk_save_ir_after ~native f = + let pass_names = + Clflags.Compiler_pass.(available_pass_names + ~filter:can_save_ir_after + ~native) + in + "-save-ir-after", Arg.Symbol (pass_names, f), + " Save intermediate representation after the given compilation pass\ + (may be specified more than once)." + let mk_dtypes f = "-dtypes", Arg.Unit f, " (deprecated) same as -annot" ;; @@ -1105,6 +1118,7 @@ module type Optcomp_options = sig val _afl_instrument : unit -> unit val _afl_inst_ratio : int -> unit val _function_sections : unit -> unit + val _save_ir_after : string -> unit end;; module type Opttop_options = sig @@ -1333,6 +1347,7 @@ struct mk_g_opt F._g; mk_function_sections F._function_sections; mk_stop_after ~native:true F._stop_after; + mk_save_ir_after ~native:true F._save_ir_after; mk_i F._i; mk_I F._I; mk_impl F._impl; @@ -1624,6 +1639,7 @@ let options_with_command_line_syntax_inner r after_rest = if not !after_rest then (after_rest := true; option ()); arg a in + let rest_all a = option (); List.iter arg a in match spec with | Unit f -> Unit (fun a -> f a; option ()) | Bool f -> Bool (fun a -> f a; option_with_arg (string_of_bool a)) @@ -1641,6 +1657,7 @@ let options_with_command_line_syntax_inner r after_rest = Tuple (loop ~name_opt hd :: List.map (loop ~name_opt:None) tl) | Symbol (l, f) -> Symbol (l, (fun a -> f a; option_with_arg a)) | Rest f -> Rest (fun a -> f a; rest a) + | Rest_all f -> Rest_all (fun a -> f a; rest_all a) | Expand f -> Expand f in loop @@ -1655,7 +1672,6 @@ let options_with_command_line_syntax options r = module Default = struct open Clflags - open Compenv let set r () = r := true let clear r () = r := false @@ -1686,7 +1702,7 @@ module Default = struct let _unsafe_string = set unsafe_string let _w s = Warnings.parse_options false s - let anonymous = anonymous + let anonymous = Compenv.anonymous end @@ -1706,7 +1722,7 @@ module Default = struct let _error_style = Misc.set_or_ignore error_style_reader.parse error_style let _nopervasives = set nopervasives - let _ppx s = first_ppx := (s :: (!first_ppx)) + let _ppx s = Compenv.first_ppx := (s :: (!Compenv.first_ppx)) let _unsafe = set unsafe let _warn_error s = Warnings.parse_options true s let _warn_help = Warnings.help_warnings @@ -1824,8 +1840,8 @@ module Default = struct let _binannot = set binary_annotations let _c = set compile_only let _cc s = c_compiler := (Some s) - let _cclib s = defer (ProcessObjects (Misc.rev_split_words s)) - let _ccopt s = first_ccopts := (s :: (!first_ccopts)) + let _cclib s = Compenv.defer (ProcessObjects (Misc.rev_split_words s)) + let _ccopt s = Compenv.first_ccopts := (s :: (!Compenv.first_ccopts)) let _config = Misc.show_config_and_exit let _config_var = Misc.show_config_variable_and_exit let _dprofile () = profile_columns := Profile.all_columns @@ -1834,8 +1850,8 @@ module Default = struct let _for_pack s = for_package := (Some s) let _g = set debug let _i = set print_types - let _impl = impl - let _intf = intf + let _impl = Compenv.impl + let _intf = Compenv.intf let _intf_suffix s = Config.interface_suffix := s let _keep_docs = set keep_docs let _keep_locs = set keep_locs @@ -1859,12 +1875,18 @@ module Default = struct | None -> stop_after := (Some pass) | Some p -> if not (p = pass) then - fatal "Please specify at most one -stop-after ." + Compenv.fatal "Please specify at most one -stop-after ." + let _save_ir_after pass = + let module P = Compiler_pass in + match P.of_string pass with + | None -> () (* this should not occur as we use Arg.Symbol *) + | Some pass -> + set_save_ir_after pass true let _thread = set use_threads let _verbose = set verbose - let _version () = print_version_string () - let _vnum () = print_version_string () - let _where () = print_standard_library () + let _version () = Compenv.print_version_string () + let _vnum () = Compenv.print_version_string () + let _where () = Compenv.print_standard_library () let _with_runtime = set with_runtime let _without_runtime = clear with_runtime end @@ -1873,12 +1895,12 @@ module Default = struct let print_version () = Printf.printf "The OCaml toplevel, version %s\n" Sys.ocaml_version; - exit 0; + raise (Compenv.Exit_with_status 0); ;; let print_version_num () = Printf.printf "%s\n" Sys.ocaml_version; - exit 0; + raise (Compenv.Exit_with_status 0); ;; let _args (_:string) = (* placeholder: wrap_expand Arg.read_arg *) [||] @@ -1913,18 +1935,18 @@ module Default = struct let _afl_instrument = set afl_instrument let _function_sections () = assert Config.function_sections; - first_ccopts := ("-ffunction-sections" :: (!first_ccopts)); + Compenv.first_ccopts := ("-ffunction-sections" ::(!Compenv.first_ccopts)); function_sections := true let _nodynlink = clear dlcode let _output_complete_obj () = set output_c_object (); set output_complete_object () let _output_obj = set output_c_object let _p () = - fatal + Compenv.fatal "Profiling with \"gprof\" (option `-p') is only supported up to \ OCaml 4.08.0" let _shared () = shared := true; dlcode := true - let _v () = print_version_and_library "native-code compiler" + let _v () = Compenv.print_version_and_library "native-code compiler" end module Odoc_args = struct @@ -1965,7 +1987,7 @@ third-party libraries such as Lwt, but with a different API." let _custom = set custom_runtime let _dcamlprimc = set keep_camlprimc_file let _dinstr = set dump_instr - let _dllib s = defer (ProcessDLLs (Misc.rev_split_words s)) + let _dllib s = Compenv.defer (ProcessDLLs (Misc.rev_split_words s)) let _dllpath s = dllpaths := ((!dllpaths) @ [s]) let _make_runtime () = custom_runtime := true; make_runtime := true; link_everything := true @@ -1979,8 +2001,8 @@ third-party libraries such as Lwt, but with a different API." let _output_obj () = output_c_object := true; custom_runtime := true let _use_prims s = use_prims := s let _use_runtime s = use_runtime := s - let _v () = print_version_and_library "compiler" - let _vmthread () = fatal vmthread_removed_message + let _v () = Compenv.print_version_and_library "compiler" + let _vmthread () = Compenv.fatal vmthread_removed_message end end diff --git a/driver/main_args.mli b/driver/main_args.mli index 083a1827..27fb475a 100644 --- a/driver/main_args.mli +++ b/driver/main_args.mli @@ -234,6 +234,7 @@ module type Optcomp_options = sig val _afl_instrument : unit -> unit val _afl_inst_ratio : int -> unit val _function_sections : unit -> unit + val _save_ir_after : string -> unit end;; module type Opttop_options = sig diff --git a/driver/maindriver.ml b/driver/maindriver.ml new file mode 100644 index 00000000..81d7edfd --- /dev/null +++ b/driver/maindriver.ml @@ -0,0 +1,114 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +open Clflags + +let usage = "Usage: ocamlc \nOptions are:" + +module Options = Main_args.Make_bytecomp_options (Main_args.Default.Main) + +let main argv ppf = + Clflags.add_arguments __LOC__ Options.list; + Clflags.add_arguments __LOC__ + ["-depend", Arg.Unit Makedepend.main_from_option, + " Compute dependencies (use 'ocamlc -depend -help' for details)"]; + match + Compenv.readenv ppf Before_args; + Clflags.parse_arguments argv Compenv.anonymous usage; + Compmisc.read_clflags_from_env (); + if !Clflags.plugin then + Compenv.fatal "-plugin is only supported up to OCaml 4.08.0"; + begin try + Compenv.process_deferred_actions + (ppf, + Compile.implementation, + Compile.interface, + ".cmo", + ".cma"); + with Arg.Bad msg -> + begin + prerr_endline msg; + Clflags.print_arguments usage; + exit 2 + end + end; + Compenv.readenv ppf Before_link; + if + List.length + (List.filter (fun x -> !x) + [make_archive;make_package;Compenv.stop_early;output_c_object]) + > 1 + then begin + let module P = Clflags.Compiler_pass in + match !stop_after with + | None -> + Compenv.fatal + "Please specify at most one of -pack, -a, -c, -output-obj"; + | Some ((P.Parsing | P.Typing) as p) -> + assert (P.is_compilation_pass p); + Printf.ksprintf Compenv.fatal + "Options -i and -stop-after (%s) \ + are incompatible with -pack, -a, -output-obj" + (String.concat "|" + (P.available_pass_names ~filter:(fun _ -> true) ~native:false)) + | Some (P.Scheduling | P.Emit) -> assert false (* native only *) + end; + if !make_archive then begin + Compmisc.init_path (); + + Bytelibrarian.create_archive + (Compenv.get_objfiles ~with_ocamlparam:false) + (Compenv.extract_output !output_name); + Warnings.check_fatal (); + end + else if !make_package then begin + Compmisc.init_path (); + let extracted_output = Compenv.extract_output !output_name in + let revd = Compenv.get_objfiles ~with_ocamlparam:false in + Compmisc.with_ppf_dump ~file_prefix:extracted_output (fun ppf_dump -> + Bytepackager.package_files ~ppf_dump (Compmisc.initial_env ()) + revd (extracted_output)); + Warnings.check_fatal (); + end + else if not !Compenv.stop_early && !objfiles <> [] then begin + let target = + if !output_c_object && not !output_complete_executable then + let s = Compenv.extract_output !output_name in + if (Filename.check_suffix s Config.ext_obj + || Filename.check_suffix s Config.ext_dll + || Filename.check_suffix s ".c") + then s + else + Compenv.fatal + (Printf.sprintf + "The extension of the output file must be .c, %s or %s" + Config.ext_obj Config.ext_dll + ) + else + Compenv.default_output !output_name + in + Compmisc.init_path (); + Bytelink.link (Compenv.get_objfiles ~with_ocamlparam:true) target; + Warnings.check_fatal (); + end; + with + | exception (Compenv.Exit_with_status n) -> + n + | exception x -> + Location.report_exception ppf x; + 2 + | () -> + Profile.print Format.std_formatter !Clflags.profile_columns; + 0 diff --git a/driver/optmain.mli b/driver/maindriver.mli similarity index 78% rename from driver/optmain.mli rename to driver/maindriver.mli index f0911cea..3397452d 100644 --- a/driver/optmain.mli +++ b/driver/maindriver.mli @@ -13,6 +13,9 @@ (* *) (**************************************************************************) -(* - this "empty" file is here to speed up garbage collection in ocamlopt.opt -*) +(* [main argv ppf] runs the compiler with arguments [argv], printing any + errors encountered to [ppf], and returns the exit code. + + NB: Due to internal state in the compiler, calling [main] twice during + the same process is unsupported. *) +val main : string array -> Format.formatter -> int diff --git a/driver/makedepend.ml b/driver/makedepend.ml index c4a7cabc..481b6507 100644 --- a/driver/makedepend.ml +++ b/driver/makedepend.ml @@ -13,7 +13,6 @@ (* *) (**************************************************************************) -open Compenv open Parsetree module String = Misc.Stdlib.String @@ -562,6 +561,18 @@ let parse_map fname = module_map := String.Map.add modname mm !module_map ;; +(* Dependency processing *) + +type dep_arg = + | Map of Misc.filepath (* -map option *) + | Src of Misc.filepath * file_kind option (* -impl, -intf or anon arg *) + +let process_dep_arg = function + | Map file -> parse_map file + | Src (file, None) -> file_dependencies file + | Src (file, (Some file_kind)) -> file_dependencies_as file_kind file + +let process_dep_args dep_args = List.iter process_dep_arg dep_args (* Entry point *) @@ -575,7 +586,10 @@ let print_version_num () = exit 0; ;; -let main () = + +let run_main argv = + let dep_args_rev : dep_arg list ref = ref [] in + let add_dep_arg f s = dep_args_rev := (f s) :: !dep_args_rev in Clflags.classic := false; Compenv.readenv ppf Before_args; Clflags.reset_arguments (); (* reset arguments from ocamlc/ocamlopt *) @@ -596,11 +610,11 @@ let main () = "-nocwd", Arg.Set nocwd, " Do not add current working directory to \ the list of include directories"; - "-impl", Arg.String (file_dependencies_as ML), + "-impl", Arg.String (add_dep_arg (fun f -> Src (f, Some ML))), " Process as a .ml file"; - "-intf", Arg.String (file_dependencies_as MLI), + "-intf", Arg.String (add_dep_arg (fun f -> Src (f, Some MLI))), " Process as a .mli file"; - "-map", Arg.String parse_map, + "-map", Arg.String (add_dep_arg (fun f -> Map f)), " Read and propagate delayed dependencies to following files"; "-ml-synonym", Arg.String(add_to_synonym_list ml_synonyms), " Consider as a synonym of the .ml extension"; @@ -620,7 +634,7 @@ let main () = " (no longer supported)"; "-pp", Arg.String(fun s -> Clflags.preprocessor := Some s), " Pipe sources through preprocessor "; - "-ppx", Arg.String (add_to_list first_ppx), + "-ppx", Arg.String (add_to_list Compenv.first_ppx), " Pipe abstract syntax trees through preprocessor "; "-shared", Arg.Set shared, " Generate dependencies for native plugin files (.cmxs targets)"; @@ -643,19 +657,24 @@ let main () = Printf.sprintf "Usage: %s [options] \nOptions are:" (Filename.basename Sys.argv.(0)) in - Clflags.parse_arguments file_dependencies usage; + Clflags.parse_arguments argv (add_dep_arg (fun f -> Src (f, None))) usage; + process_dep_args (List.rev !dep_args_rev); Compenv.readenv ppf Before_link; if !sort_files then sort_files_by_dependencies !files else List.iter print_file_dependencies (List.sort compare !files); exit (if Error_occurred.get () then 2 else 0) +let main () = + run_main Sys.argv + let main_from_option () = if Sys.argv.(1) <> "-depend" then begin Printf.eprintf "Fatal error: argument -depend must be used as first argument.\n%!"; exit 2; end; - incr Arg.current; - Sys.argv.(0) <- Sys.argv.(0) ^ " -depend"; - Sys.argv.(!Arg.current) <- Sys.argv.(0); - main () + let args = + Array.concat [ [| Sys.argv.(0) ^ " -depend" |]; + Array.sub Sys.argv 2 (Array.length Sys.argv - 2) ] in + Sys.argv.(0) <- args.(0); + run_main args diff --git a/driver/optcompile.ml b/driver/optcompile.ml index 9ca93c33..693a35f4 100644 --- a/driver/optcompile.ml +++ b/driver/optcompile.ml @@ -85,7 +85,12 @@ let clambda i backend typed = ~ppf_dump:i.ppf_dump; Compilenv.save_unit_info (cmx i)) -let implementation ~backend ~source_file ~output_prefix = +(* Emit assembly directly from Linear IR *) +let emit i = + Compilenv.reset ?packname:!Clflags.for_package i.module_name; + Asmgen.compile_implementation_linear i.output_prefix ~progname:i.source_file + +let implementation ~backend ~start_from ~source_file ~output_prefix = let backend info typed = Compilenv.reset ?packname:!Clflags.for_package info.module_name; if Config.flambda @@ -93,4 +98,8 @@ let implementation ~backend ~source_file ~output_prefix = else clambda info backend typed in with_info ~source_file ~output_prefix ~dump_ext:"cmx" @@ fun info -> - Compile_common.implementation info ~backend + match (start_from:Clflags.Compiler_pass.t) with + | Parsing -> Compile_common.implementation info ~backend + | Emit -> emit info + | _ -> Misc.fatal_errorf "Cannot start from %s" + (Clflags.Compiler_pass.to_string start_from) diff --git a/driver/optcompile.mli b/driver/optcompile.mli index 9a23b8b2..f04e75e6 100644 --- a/driver/optcompile.mli +++ b/driver/optcompile.mli @@ -19,6 +19,7 @@ val interface: source_file:string -> output_prefix:string -> unit val implementation: backend:(module Backend_intf.S) + -> start_from:Clflags.Compiler_pass.t -> source_file:string -> output_prefix:string -> unit (** {2 Internal functions} **) diff --git a/driver/optmain.ml b/driver/optmain.ml index d7ef1c48..7216f34e 100644 --- a/driver/optmain.ml +++ b/driver/optmain.ml @@ -1,139 +1,2 @@ -(**************************************************************************) -(* *) -(* OCaml *) -(* *) -(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -(* *) -(* Copyright 1996 Institut National de Recherche en Informatique et *) -(* en Automatique. *) -(* *) -(* All rights reserved. This file is distributed under the terms of *) -(* the GNU Lesser General Public License version 2.1, with the *) -(* special exception on linking described in the file LICENSE. *) -(* *) -(**************************************************************************) - -open Clflags -open Compenv - -module Backend = struct - (* See backend_intf.mli. *) - - let symbol_for_global' = Compilenv.symbol_for_global' - let closure_symbol = Compilenv.closure_symbol - - let really_import_approx = Import_approx.really_import_approx - let import_symbol = Import_approx.import_symbol - - let size_int = Arch.size_int - let big_endian = Arch.big_endian - - let max_sensible_number_of_arguments = - (* The "-1" is to allow for a potential closure environment parameter. *) - Proc.max_arguments_for_tailcalls - 1 -end -let backend = (module Backend : Backend_intf.S) - -let usage = "Usage: ocamlopt \nOptions are:" - -module Options = Main_args.Make_optcomp_options (Main_args.Default.Optmain) -let main () = - native_code := true; - let ppf = Format.err_formatter in - try - readenv ppf Before_args; - Clflags.add_arguments __LOC__ (Arch.command_line_options @ Options.list); - Clflags.add_arguments __LOC__ - ["-depend", Arg.Unit Makedepend.main_from_option, - " Compute dependencies \ - (use 'ocamlopt -depend -help' for details)"]; - Clflags.parse_arguments anonymous usage; - Compmisc.read_clflags_from_env (); - if !Clflags.plugin then - fatal "-plugin is only supported up to OCaml 4.08.0"; - begin try - Compenv.process_deferred_actions - (ppf, - Optcompile.implementation ~backend, - Optcompile.interface, - ".cmx", - ".cmxa"); - with Arg.Bad msg -> - begin - prerr_endline msg; - Clflags.print_arguments usage; - exit 2 - end - end; - readenv ppf Before_link; - if - List.length (List.filter (fun x -> !x) - [make_package; make_archive; shared; - stop_early; output_c_object]) > 1 - then - begin - let module P = Clflags.Compiler_pass in - match !stop_after with - | None -> - fatal "Please specify at most one of -pack, -a, -shared, -c, \ - -output-obj"; - | Some ((P.Parsing | P.Typing | P.Scheduling) as p) -> - assert (P.is_compilation_pass p); - Printf.ksprintf fatal - "Options -i and -stop-after (%s) \ - are incompatible with -pack, -a, -shared, -output-obj" - (String.concat "|" - (Clflags.Compiler_pass.available_pass_names ~native:true)) - end; - if !make_archive then begin - Compmisc.init_path (); - let target = extract_output !output_name in - Asmlibrarian.create_archive - (get_objfiles ~with_ocamlparam:false) target; - Warnings.check_fatal (); - end - else if !make_package then begin - Compmisc.init_path (); - let target = extract_output !output_name in - Compmisc.with_ppf_dump ~file_prefix:target (fun ppf_dump -> - Asmpackager.package_files ~ppf_dump (Compmisc.initial_env ()) - (get_objfiles ~with_ocamlparam:false) target ~backend); - Warnings.check_fatal (); - end - else if !shared then begin - Compmisc.init_path (); - let target = extract_output !output_name in - Compmisc.with_ppf_dump ~file_prefix:target (fun ppf_dump -> - Asmlink.link_shared ~ppf_dump - (get_objfiles ~with_ocamlparam:false) target); - Warnings.check_fatal (); - end - else if not !stop_early && !objfiles <> [] then begin - let target = - if !output_c_object then - let s = extract_output !output_name in - if (Filename.check_suffix s Config.ext_obj - || Filename.check_suffix s Config.ext_dll) - then s - else - fatal - (Printf.sprintf - "The extension of the output file must be %s or %s" - Config.ext_obj Config.ext_dll - ) - else - default_output !output_name - in - Compmisc.init_path (); - Compmisc.with_ppf_dump ~file_prefix:target (fun ppf_dump -> - Asmlink.link ~ppf_dump (get_objfiles ~with_ocamlparam:true) target); - Warnings.check_fatal (); - end; - with x -> - Location.report_exception ppf x; - exit 2 - let () = - main (); - Profile.print Format.std_formatter !Clflags.profile_columns; - exit 0 + exit (Optmaindriver.main Sys.argv Format.err_formatter) diff --git a/driver/optmaindriver.ml b/driver/optmaindriver.ml new file mode 100644 index 00000000..9986a5a5 --- /dev/null +++ b/driver/optmaindriver.ml @@ -0,0 +1,139 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +open Clflags + +module Backend = struct + (* See backend_intf.mli. *) + + let symbol_for_global' = Compilenv.symbol_for_global' + let closure_symbol = Compilenv.closure_symbol + + let really_import_approx = Import_approx.really_import_approx + let import_symbol = Import_approx.import_symbol + + let size_int = Arch.size_int + let big_endian = Arch.big_endian + + let max_sensible_number_of_arguments = + (* The "-1" is to allow for a potential closure environment parameter. *) + Proc.max_arguments_for_tailcalls - 1 +end +let backend = (module Backend : Backend_intf.S) + +let usage = "Usage: ocamlopt \nOptions are:" + +module Options = Main_args.Make_optcomp_options (Main_args.Default.Optmain) +let main argv ppf = + native_code := true; + match + Compenv.readenv ppf Before_args; + Clflags.add_arguments __LOC__ (Arch.command_line_options @ Options.list); + Clflags.add_arguments __LOC__ + ["-depend", Arg.Unit Makedepend.main_from_option, + " Compute dependencies \ + (use 'ocamlopt -depend -help' for details)"]; + Clflags.parse_arguments argv Compenv.anonymous usage; + Compmisc.read_clflags_from_env (); + if !Clflags.plugin then + Compenv.fatal "-plugin is only supported up to OCaml 4.08.0"; + begin try + Compenv.process_deferred_actions + (ppf, + Optcompile.implementation ~backend, + Optcompile.interface, + ".cmx", + ".cmxa"); + with Arg.Bad msg -> + begin + prerr_endline msg; + Clflags.print_arguments usage; + exit 2 + end + end; + Compenv.readenv ppf Before_link; + if + List.length (List.filter (fun x -> !x) + [make_package; make_archive; shared; + Compenv.stop_early; output_c_object]) > 1 + then + begin + let module P = Clflags.Compiler_pass in + match !stop_after with + | None -> + Compenv.fatal "Please specify at most one of -pack, -a, -shared, -c, \ + -output-obj"; + | Some ((P.Parsing | P.Typing | P.Scheduling | P.Emit) as p) -> + assert (P.is_compilation_pass p); + Printf.ksprintf Compenv.fatal + "Options -i and -stop-after (%s) \ + are incompatible with -pack, -a, -shared, -output-obj" + (String.concat "|" + (P.available_pass_names ~filter:(fun _ -> true) ~native:true)) + end; + if !make_archive then begin + Compmisc.init_path (); + let target = Compenv.extract_output !output_name in + Asmlibrarian.create_archive + (Compenv.get_objfiles ~with_ocamlparam:false) target; + Warnings.check_fatal (); + end + else if !make_package then begin + Compmisc.init_path (); + let target = Compenv.extract_output !output_name in + Compmisc.with_ppf_dump ~file_prefix:target (fun ppf_dump -> + Asmpackager.package_files ~ppf_dump (Compmisc.initial_env ()) + (Compenv.get_objfiles ~with_ocamlparam:false) target ~backend); + Warnings.check_fatal (); + end + else if !shared then begin + Compmisc.init_path (); + let target = Compenv.extract_output !output_name in + Compmisc.with_ppf_dump ~file_prefix:target (fun ppf_dump -> + Asmlink.link_shared ~ppf_dump + (Compenv.get_objfiles ~with_ocamlparam:false) target); + Warnings.check_fatal (); + end + else if not !Compenv.stop_early && !objfiles <> [] then begin + let target = + if !output_c_object then + let s = Compenv.extract_output !output_name in + if (Filename.check_suffix s Config.ext_obj + || Filename.check_suffix s Config.ext_dll) + then s + else + Compenv.fatal + (Printf.sprintf + "The extension of the output file must be %s or %s" + Config.ext_obj Config.ext_dll + ) + else + Compenv.default_output !output_name + in + Compmisc.init_path (); + Compmisc.with_ppf_dump ~file_prefix:target (fun ppf_dump -> + let objs = Compenv.get_objfiles ~with_ocamlparam:true in + Asmlink.link ~ppf_dump objs target); + Warnings.check_fatal (); + end; + with + | exception (Compenv.Exit_with_status n) -> + n + | exception x -> + Location.report_exception ppf x; + 2 + | () -> + Profile.print Format.std_formatter !Clflags.profile_columns; + 0 diff --git a/driver/optmaindriver.mli b/driver/optmaindriver.mli new file mode 100644 index 00000000..3397452d --- /dev/null +++ b/driver/optmaindriver.mli @@ -0,0 +1,21 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Damien Doligez, projet Moscova, INRIA Rocquencourt *) +(* *) +(* Copyright 2000 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* [main argv ppf] runs the compiler with arguments [argv], printing any + errors encountered to [ppf], and returns the exit code. + + NB: Due to internal state in the compiler, calling [main] twice during + the same process is unsupported. *) +val main : string array -> Format.formatter -> int diff --git a/driver/pparse.ml b/driver/pparse.ml index a5e98c0a..5991459d 100644 --- a/driver/pparse.ml +++ b/driver/pparse.ml @@ -175,7 +175,7 @@ let file_aux ~tool_name inputfile (type a) parse_fun invariant_fun Location.input_name := (input_value ic : string); if !Clflags.unsafe then Location.prerr_warning (Location.in_file !Location.input_name) - Warnings.Unsafe_without_parsing; + Warnings.Unsafe_array_syntax_without_parsing; let ast = (input_value ic : a) in if !Clflags.all_ppx = [] then invariant_fun ast; (* if all_ppx <> [], invariant_fun will be called by apply_rewriters *) diff --git a/dune b/dune index f80f6391..aa026eb5 100644 --- a/dune +++ b/dune @@ -45,7 +45,7 @@ ;; UTILS config build_path_prefix_map misc identifiable numbers arg_helper clflags profile terminfo ccomp warnings consistbl strongly_connected_components - targetint load_path int_replace_polymorphic_compare + targetint load_path int_replace_polymorphic_compare binutils local_store ;; PARSING location longident docstrings syntaxerr ast_helper camlinternalMenhirLib @@ -59,7 +59,8 @@ cmi_format persistent_env env type_immediacy typedtree printtyped ctype printtyp includeclass mtype envaux includecore tast_iterator tast_mapper cmt_format untypeast includemod - typetexp printpat parmatch stypes typedecl typeopt rec_check typecore + typetexp patterns printpat parmatch stypes typedecl typeopt rec_check + typecore typeclass typemod typedecl_variance typedecl_properties typedecl_immediacy typedecl_unboxed typedecl_separability cmt2annot ; manual update: mli only files @@ -151,7 +152,7 @@ CSE CSEgen deadcode domainstate emit emitaux interf interval linear linearize linscan liveness mach printcmm printlinear printmach proc reg reload reloadgen - schedgen scheduling selectgen selection spacetime_profiling spill split + schedgen scheduling selectgen selection spill split strmatch x86_ast x86_dsl x86_gas x86_masm x86_proc ;; asmcomp/debug/ diff --git a/file_formats/linear_format.ml b/file_formats/linear_format.ml new file mode 100644 index 00000000..5525a697 --- /dev/null +++ b/file_formats/linear_format.ml @@ -0,0 +1,101 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* Greta Yorsh, Jane Street Europe *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* Copyright 2019 Jane Street Group LLC *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* Marshal and unmarshal a compilation unit in linear format *) +type linear_item_info = + | Func of Linear.fundecl + | Data of Cmm.data_item list + +type linear_unit_info = + { + mutable unit_name : string; + mutable items : linear_item_info list; + mutable for_pack : string option + } + +type error = + | Wrong_format of string + | Wrong_version of string + | Corrupted of string + | Marshal_failed of string + +exception Error of error + +let save filename linear_unit_info = + let ch = open_out_bin filename in + Misc.try_finally (fun () -> + output_string ch Config.linear_magic_number; + output_value ch linear_unit_info; + (* Saved because Linearize and Emit depend on Cmm.label. *) + output_value ch (Cmm.cur_label ()); + (* Compute digest of the contents and append it to the file. *) + flush ch; + let crc = Digest.file filename in + output_value ch crc + ) + ~always:(fun () -> close_out ch) + ~exceptionally:(fun () -> raise (Error (Marshal_failed filename))) + +let restore filename = + let ic = open_in_bin filename in + Misc.try_finally + (fun () -> + let magic = Config.linear_magic_number in + let buffer = really_input_string ic (String.length magic) in + if String.equal buffer magic then begin + try + let linear_unit_info = (input_value ic : linear_unit_info) in + let last_label = (input_value ic : Cmm.label) in + Cmm.reset (); + Cmm.set_label last_label; + let crc = (input_value ic : Digest.t) in + linear_unit_info, crc + with End_of_file | Failure _ -> raise (Error (Corrupted filename)) + | Error e -> raise (Error e) + end + else if String.sub buffer 0 9 = String.sub magic 0 9 then + raise (Error (Wrong_version filename)) + else + raise (Error (Wrong_format filename)) + ) + ~always:(fun () -> close_in ic) + +(* Error report *) + +open Format + +let report_error ppf = function + | Wrong_format filename -> + fprintf ppf "Expected Linear format. Incompatible file %a" + Location.print_filename filename + | Wrong_version filename -> + fprintf ppf + "%a@ is not compatible with this version of OCaml" + Location.print_filename filename + | Corrupted filename -> + fprintf ppf "Corrupted format@ %a" + Location.print_filename filename + | Marshal_failed filename -> + fprintf ppf "Failed to marshal Linear to file@ %a" + Location.print_filename filename + +let () = + Location.register_error_of_exn + (function + | Error err -> Some (Location.error_of_printer_file report_error err) + | _ -> None + ) diff --git a/file_formats/linear_format.mli b/file_formats/linear_format.mli new file mode 100644 index 00000000..766db5db --- /dev/null +++ b/file_formats/linear_format.mli @@ -0,0 +1,38 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* Greta Yorsh, Jane Street Europe *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* Copyright 2019 Jane Street Group LLC *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* Format of .cmir-linear files *) + +(* Compiler can optionally save Linear representation of a compilation unit, + along with other information required to emit assembly. *) +type linear_item_info = + | Func of Linear.fundecl + | Data of Cmm.data_item list + +type linear_unit_info = + { + mutable unit_name : string; + mutable items : linear_item_info list; + mutable for_pack : string option + } + +(* Marshal and unmarshal a compilation unit in Linear format. + It includes saving and restoring global state required for Emit, + that currently consists of Cmm.label_counter. +*) +val save : string -> linear_unit_info -> unit +val restore : string -> linear_unit_info * Digest.t diff --git a/lambda/debuginfo.ml b/lambda/debuginfo.ml index c1195d72..5308a4be 100644 --- a/lambda/debuginfo.ml +++ b/lambda/debuginfo.ml @@ -20,12 +20,23 @@ open Location module Scoped_location = struct type scope_item = | Sc_anonymous_function - | Sc_value_definition of string - | Sc_module_definition of string - | Sc_class_definition of string - | Sc_method_definition of string + | Sc_value_definition + | Sc_module_definition + | Sc_class_definition + | Sc_method_definition - type scopes = scope_item list + type scopes = + | Empty + | Cons of {item: scope_item; str: string; str_fun: string} + + let str_fun = function + | Empty -> "(fun)" + | Cons r -> r.str_fun + + let cons item str = + Cons {item; str; str_fun = str ^ ".(fun)"} + + let empty_scopes = Empty let add_parens_if_symbolic = function | "" -> "" @@ -34,46 +45,36 @@ module Scoped_location = struct | 'a'..'z' | 'A'..'Z' | '_' | '0'..'9' -> s | _ -> "(" ^ s ^ ")" - let string_of_scope_item = function - | Sc_anonymous_function -> - "(fun)" - | Sc_value_definition name - | Sc_module_definition name - | Sc_class_definition name - | Sc_method_definition name -> - add_parens_if_symbolic name - - let string_of_scopes scopes = - let dot acc = - match acc with - | [] -> [] - | acc -> "." :: acc in - let rec to_strings acc = function - | [] -> acc - (* Collapse nested anonymous function scopes *) - | Sc_anonymous_function :: ((Sc_anonymous_function :: _) as rest) -> - to_strings acc rest - (* Use class#meth syntax for classes *) - | (Sc_method_definition _ as meth) :: - (Sc_class_definition _ as cls) :: rest -> - to_strings (string_of_scope_item cls :: "#" :: - string_of_scope_item meth :: dot acc) rest - | s :: rest -> - to_strings (string_of_scope_item s :: dot acc) rest in + let dot ?(sep = ".") scopes s = + let s = add_parens_if_symbolic s in match scopes with - | [] -> "" - | scopes -> String.concat "" (to_strings [] scopes) + | Empty -> s + | Cons {str; _} -> str ^ sep ^ s let enter_anonymous_function ~scopes = - Sc_anonymous_function :: scopes + let str = str_fun scopes in + Cons {item = Sc_anonymous_function; str; str_fun = str} + let enter_value_definition ~scopes id = - Sc_value_definition (Ident.name id) :: scopes + cons Sc_value_definition (dot scopes (Ident.name id)) + let enter_module_definition ~scopes id = - Sc_module_definition (Ident.name id) :: scopes + cons Sc_module_definition (dot scopes (Ident.name id)) + let enter_class_definition ~scopes id = - Sc_class_definition (Ident.name id) :: scopes - let enter_method_definition ~scopes (m : Asttypes.label) = - Sc_method_definition m :: scopes + cons Sc_class_definition (dot scopes (Ident.name id)) + + let enter_method_definition ~scopes (s : Asttypes.label) = + let str = + match scopes with + | Cons {item = Sc_class_definition; _} -> dot ~sep:"#" scopes s + | _ -> dot scopes s + in + cons Sc_method_definition str + + let string_of_scopes = function + | Empty -> "" + | Cons {str; _} -> str type t = | Loc_unknown diff --git a/lambda/debuginfo.mli b/lambda/debuginfo.mli index 4ce8d5f9..4d99ddf3 100644 --- a/lambda/debuginfo.mli +++ b/lambda/debuginfo.mli @@ -14,17 +14,10 @@ (**************************************************************************) module Scoped_location : sig - type scope_item = - | Sc_anonymous_function - | Sc_value_definition of string - | Sc_module_definition of string - | Sc_class_definition of string - | Sc_method_definition of string - - type scopes = scope_item list - val string_of_scope_item : scope_item -> string + type scopes val string_of_scopes : scopes -> string + val empty_scopes : scopes val enter_anonymous_function : scopes:scopes -> scopes val enter_value_definition : scopes:scopes -> Ident.t -> scopes val enter_module_definition : scopes:scopes -> Ident.t -> scopes diff --git a/lambda/lambda.ml b/lambda/lambda.ml index 3a776bee..71067851 100644 --- a/lambda/lambda.ml +++ b/lambda/lambda.ml @@ -207,11 +207,16 @@ let equal_value_kind x y = type structured_constant = Const_base of constant - | Const_pointer of int | Const_block of int * structured_constant list | Const_float_array of string list | Const_immstring of string +type tailcall_attribute = + | Tailcall_expectation of bool + (* [@tailcall] and [@tailcall true] have [true], + [@tailcall false] has [false] *) + | Default_tailcall (* no [@tailcall] attribute *) + type inline_attribute = | Always_inline (* [@inline] or [@inline always] *) | Never_inline (* [@inline never] *) @@ -312,7 +317,7 @@ and lambda_apply = { ap_func : lambda; ap_args : lambda list; ap_loc : scoped_location; - ap_should_be_tailcall : bool; + ap_tailcall : tailcall_attribute; ap_inlined : inline_attribute; ap_specialised : specialise_attribute; } @@ -342,7 +347,9 @@ type program = required_globals : Ident.Set.t; code : lambda } -let const_unit = Const_pointer 0 +let const_int n = Const_base (Const_int n) + +let const_unit = const_int 0 let lambda_unit = Lconst const_unit @@ -679,79 +686,120 @@ let rec make_sequence fn = function Assumes that the image of the substitution is out of reach of the bound variables of the lambda-term (no capture). *) -let subst update_env s lam = - let rec subst s lam = - let remove_list l s = - List.fold_left (fun s (id, _kind) -> Ident.Map.remove id s) s l - in +let subst update_env ?(freshen_bound_variables = false) s input_lam = + (* [s] contains a partial substitution for the free variables of the + input term [input_lam]. + + During our traversal of the term we maintain a second environment + [l] with all the bound variables of [input_lam] in the current + scope, mapped to either themselves or freshened versions of + themselves when [freshen_bound_variables] is set. *) + let bind id l = + let id' = if not freshen_bound_variables then id else Ident.rename id in + id', Ident.Map.add id id' l + in + let bind_many ids l = + List.fold_right (fun (id, rhs) (ids', l) -> + let id', l = bind id l in + ((id', rhs) :: ids' , l) + ) ids ([], l) + in + let rec subst s l lam = match lam with - | Lvar id as l -> - begin try Ident.Map.find id s with Not_found -> l end + | Lvar id as lam -> + begin match Ident.Map.find id l with + | id' -> Lvar id' + | exception Not_found -> + (* note: as this point we know [id] is not a bound + variable of the input term, otherwise it would belong + to [l]; it is a free variable of the input term. *) + begin try Ident.Map.find id s with Not_found -> lam end + end | Lconst _ as l -> l | Lapply ap -> - Lapply{ap with ap_func = subst s ap.ap_func; - ap_args = subst_list s ap.ap_args} + Lapply{ap with ap_func = subst s l ap.ap_func; + ap_args = subst_list s l ap.ap_args} | Lfunction lf -> - let s = - List.fold_right - (fun (id, _) s -> Ident.Map.remove id s) - lf.params s - in - Lfunction {lf with body = subst s lf.body} + let params, l' = bind_many lf.params l in + Lfunction {lf with params; body = subst s l' lf.body} | Llet(str, k, id, arg, body) -> - Llet(str, k, id, subst s arg, subst (Ident.Map.remove id s) body) + let id, l' = bind id l in + Llet(str, k, id, subst s l arg, subst s l' body) | Lletrec(decl, body) -> - let s = - List.fold_left (fun s (id, _) -> Ident.Map.remove id s) - s decl - in - Lletrec(List.map (subst_decl s) decl, subst s body) - | Lprim(p, args, loc) -> Lprim(p, subst_list s args, loc) + let decl, l' = bind_many decl l in + Lletrec(List.map (subst_decl s l') decl, subst s l' body) + | Lprim(p, args, loc) -> Lprim(p, subst_list s l args, loc) | Lswitch(arg, sw, loc) -> - Lswitch(subst s arg, - {sw with sw_consts = List.map (subst_case s) sw.sw_consts; - sw_blocks = List.map (subst_case s) sw.sw_blocks; - sw_failaction = subst_opt s sw.sw_failaction; }, + Lswitch(subst s l arg, + {sw with sw_consts = List.map (subst_case s l) sw.sw_consts; + sw_blocks = List.map (subst_case s l) sw.sw_blocks; + sw_failaction = subst_opt s l sw.sw_failaction; }, loc) | Lstringswitch (arg,cases,default,loc) -> Lstringswitch - (subst s arg,List.map (subst_strcase s) cases,subst_opt s default,loc) - | Lstaticraise (i,args) -> Lstaticraise (i, subst_list s args) + (subst s l arg, + List.map (subst_strcase s l) cases, + subst_opt s l default, + loc) + | Lstaticraise (i,args) -> Lstaticraise (i, subst_list s l args) | Lstaticcatch(body, (id, params), handler) -> - Lstaticcatch(subst s body, (id, params), - subst (remove_list params s) handler) + let params, l' = bind_many params l in + Lstaticcatch(subst s l body, (id, params), + subst s l' handler) | Ltrywith(body, exn, handler) -> - Ltrywith(subst s body, exn, subst (Ident.Map.remove exn s) handler) - | Lifthenelse(e1, e2, e3) -> Lifthenelse(subst s e1, subst s e2, subst s e3) - | Lsequence(e1, e2) -> Lsequence(subst s e1, subst s e2) - | Lwhile(e1, e2) -> Lwhile(subst s e1, subst s e2) + let exn, l' = bind exn l in + Ltrywith(subst s l body, exn, subst s l' handler) + | Lifthenelse(e1, e2, e3) -> + Lifthenelse(subst s l e1, subst s l e2, subst s l e3) + | Lsequence(e1, e2) -> Lsequence(subst s l e1, subst s l e2) + | Lwhile(e1, e2) -> Lwhile(subst s l e1, subst s l e2) | Lfor(v, lo, hi, dir, body) -> - Lfor(v, subst s lo, subst s hi, dir, - subst (Ident.Map.remove v s) body) + let v, l' = bind v l in + Lfor(v, subst s l lo, subst s l hi, dir, subst s l' body) | Lassign(id, e) -> - assert(not (Ident.Map.mem id s)); - Lassign(id, subst s e) + assert (not (Ident.Map.mem id s)); + let id = try Ident.Map.find id l with Not_found -> id in + Lassign(id, subst s l e) | Lsend (k, met, obj, args, loc) -> - Lsend (k, subst s met, subst s obj, subst_list s args, loc) + Lsend (k, subst s l met, subst s l obj, subst_list s l args, loc) | Levent (lam, evt) -> - let lev_env = - Ident.Map.fold (fun id _ env -> - match Env.find_value (Path.Pident id) evt.lev_env with - | exception Not_found -> env - | vd -> update_env id vd env - ) s evt.lev_env + let old_env = evt.lev_env in + let env_updates = + let find_in_old id = Env.find_value (Path.Pident id) old_env in + let rebind id id' new_env = + match find_in_old id with + | exception Not_found -> new_env + | vd -> Env.add_value id' vd new_env + in + let update_free id new_env = + match find_in_old id with + | exception Not_found -> new_env + | vd -> update_env id vd new_env + in + Ident.Map.merge (fun id bound free -> + match bound, free with + | Some id', _ -> + if Ident.equal id id' then None else Some (rebind id id') + | None, Some _ -> Some (update_free id) + | None, None -> None + ) l s + in + let new_env = + Ident.Map.fold (fun _id update env -> update env) env_updates old_env in - Levent (subst s lam, { evt with lev_env }) - | Lifused (v, e) -> Lifused (v, subst s e) - and subst_list s l = List.map (subst s) l - and subst_decl s (id, exp) = (id, subst s exp) - and subst_case s (key, case) = (key, subst s case) - and subst_strcase s (key, case) = (key, subst s case) - and subst_opt s = function + Levent (subst s l lam, { evt with lev_env = new_env }) + | Lifused (id, e) -> + let id = try Ident.Map.find id l with Not_found -> id in + Lifused (id, subst s l e) + and subst_list s l li = List.map (subst s l) li + and subst_decl s l (id, exp) = (id, subst s l exp) + and subst_case s l (key, case) = (key, subst s l case) + and subst_strcase s l (key, case) = (key, subst s l case) + and subst_opt s l = function | None -> None - | Some e -> Some (subst s e) + | Some e -> Some (subst s l e) in - subst s lam + subst s Ident.Map.empty input_lam let rename idmap lam = let update_env oldid vd env = @@ -761,16 +809,23 @@ let rename idmap lam = let s = Ident.Map.map (fun new_id -> Lvar new_id) idmap in subst update_env s lam +let duplicate lam = + subst + (fun _ _ env -> env) + ~freshen_bound_variables:true + Ident.Map.empty + lam + let shallow_map f = function | Lvar _ | Lconst _ as lam -> lam - | Lapply { ap_func; ap_args; ap_loc; ap_should_be_tailcall; + | Lapply { ap_func; ap_args; ap_loc; ap_tailcall; ap_inlined; ap_specialised } -> Lapply { ap_func = f ap_func; ap_args = List.map f ap_args; ap_loc; - ap_should_be_tailcall; + ap_tailcall; ap_inlined; ap_specialised; } @@ -892,5 +947,10 @@ let function_is_curried func = | Curried -> true | Tupled -> false +let max_arity () = + if !Clflags.native_code then 126 else max_int + (* 126 = 127 (the maximal number of parameters supported in C--) + - 1 (the hidden parameter containing the environment) *) + let reset () = raise_count := 0 diff --git a/lambda/lambda.mli b/lambda/lambda.mli index d1816981..fa29315d 100644 --- a/lambda/lambda.mli +++ b/lambda/lambda.mli @@ -198,11 +198,16 @@ val equal_boxed_integer : boxed_integer -> boxed_integer -> bool type structured_constant = Const_base of constant - | Const_pointer of int | Const_block of int * structured_constant list | Const_float_array of string list | Const_immstring of string +type tailcall_attribute = + | Tailcall_expectation of bool + (* [@tailcall] and [@tailcall true] have [true], + [@tailcall false] has [false] *) + | Default_tailcall (* no [@tailcall] attribute *) + type inline_attribute = | Always_inline (* [@inline] or [@inline always] *) | Never_inline (* [@inline never] *) @@ -296,7 +301,7 @@ and lambda_apply = { ap_func : lambda; ap_args : lambda list; ap_loc : scoped_location; - ap_should_be_tailcall : bool; (* true if [@tailcall] was specified *) + ap_tailcall : tailcall_attribute; ap_inlined : inline_attribute; (* specified with the [@inlined] attribute *) ap_specialised : specialise_attribute; } @@ -341,6 +346,7 @@ type program = val make_key: lambda -> lambda option val const_unit: structured_constant +val const_int : int -> structured_constant val lambda_unit: lambda val name_lambda: let_kind -> lambda -> (Ident.t -> lambda) -> lambda val name_lambda_list: lambda list -> (lambda list -> lambda) -> lambda @@ -375,21 +381,30 @@ val transl_class_path: scoped_location -> Env.t -> Path.t -> lambda val make_sequence: ('a -> lambda) -> 'a list -> lambda -val subst: (Ident.t -> Types.value_description -> Env.t -> Env.t) -> +val subst: + (Ident.t -> Types.value_description -> Env.t -> Env.t) -> + ?freshen_bound_variables:bool -> lambda Ident.Map.t -> lambda -> lambda -(** [subst env_update_fun s lt] applies a substitution [s] to the lambda-term - [lt]. +(** [subst update_env ?freshen_bound_variables s lt] + applies a substitution [s] to the lambda-term [lt]. Assumes that the image of the substitution is out of reach of the bound variables of the lambda-term (no capture). - [env_update_fun] is used to refresh the environment contained in debug - events. *) + [update_env] is used to refresh the environment contained in debug + events. + + [freshen_bound_variables], which defaults to [false], freshens + the bound variables within [lt]. + *) val rename : Ident.t Ident.Map.t -> lambda -> lambda (** A version of [subst] specialized for the case where we're just renaming idents. *) +val duplicate : lambda -> lambda +(** Duplicate a term, freshening all locally-bound identifiers. *) + val map : (lambda -> lambda) -> lambda -> lambda (** Bottom-up rewriting, applying the function on each node from the leaves to the root. *) @@ -412,6 +427,12 @@ val default_stub_attribute : function_attribute val function_is_curried : lfunction -> bool +val max_arity : unit -> int + (** Maximal number of parameters for a function, or in other words, + maximal length of the [params] list of a [lfunction] record. + This is unlimited ([max_int]) for bytecode, but limited + (currently to 126) for native code. *) + (***********************) (* For static failures *) (***********************) diff --git a/lambda/matching.ml b/lambda/matching.ml index 95f296f6..45803f6c 100644 --- a/lambda/matching.ml +++ b/lambda/matching.ml @@ -95,7 +95,8 @@ open Lambda open Parmatch open Printf open Printpat -open Debuginfo.Scoped_location + +module Scoped_location = Debuginfo.Scoped_location let dbg = false @@ -130,94 +131,44 @@ let string_of_lam lam = let all_record_args lbls = match lbls with + | [] -> fatal_error "Matching.all_record_args" | (_, { lbl_all }, _) :: _ -> let t = Array.map - (fun lbl -> (mknoloc (Longident.Lident "?temp?"), lbl, omega)) + (fun lbl -> + (mknoloc (Longident.Lident "?temp?"), lbl, Patterns.omega)) lbl_all in List.iter (fun ((_, lbl, _) as x) -> t.(lbl.lbl_pos) <- x) lbls; Array.to_list t - | _ -> fatal_error "Matching.all_record_args" - -type 'a clause = 'a * lambda - -module Non_empty_clause = struct - type 'a t = ('a * Typedtree.pattern list) clause - - let of_initial = function - | [], _ -> assert false - | pat :: patl, act -> ((pat, patl), act) - let map_head f ((p, patl), act) = ((f p, patl), act) -end +let expand_record_head h = + let open Patterns.Head in + match h.pat_desc with + | Record [] -> fatal_error "Matching.expand_record_head" + | Record ({ lbl_all } :: _) -> + { h with pat_desc = Record (Array.to_list lbl_all) } + | _ -> h -type simple_view = - [ `Any - | `Constant of constant - | `Tuple of pattern list - | `Construct of Longident.t loc * constructor_description * pattern list - | `Variant of label * pattern option * row_desc ref - | `Record of - (Longident.t loc * label_description * pattern) list * closed_flag - | `Array of pattern list - | `Lazy of pattern ] +let head_loc ~scopes head = + Scoped_location.of_location ~scopes head.pat_loc -type half_simple_view = - [ simple_view | `Or of pattern * pattern * row_desc option ] +type 'a clause = 'a * lambda -type general_view = - [ half_simple_view - | `Var of Ident.t * string loc - | `Alias of pattern * Ident.t * string loc ] +let map_on_row f (row, action) = (f row, action) -module General : sig - type pattern = general_view pattern_data +let map_on_rows f = List.map (map_on_row f) - type clause = pattern Non_empty_clause.t +module Non_empty_row = Patterns.Non_empty_row - val view : Typedtree.pattern -> pattern +module General = struct + include Patterns.General - val erase : [< general_view ] pattern_data -> Typedtree.pattern -end = struct - type pattern = general_view pattern_data - - type clause = pattern Non_empty_clause.t - - let view_desc = function - | Tpat_any -> `Any - | Tpat_var (id, str) -> `Var (id, str) - | Tpat_alias (p, id, str) -> `Alias (p, id, str) - | Tpat_constant cst -> `Constant cst - | Tpat_tuple ps -> `Tuple ps - | Tpat_construct (cstr, cstr_descr, args) -> - `Construct (cstr, cstr_descr, args) - | Tpat_variant (cstr, arg, row_desc) -> `Variant (cstr, arg, row_desc) - | Tpat_record (fields, closed) -> `Record (fields, closed) - | Tpat_array ps -> `Array ps - | Tpat_or (p, q, row_desc) -> `Or (p, q, row_desc) - | Tpat_lazy p -> `Lazy p - - let view p : pattern = { p with pat_desc = view_desc p.pat_desc } - - let erase_desc = function - | `Any -> Tpat_any - | `Var (id, str) -> Tpat_var (id, str) - | `Alias (p, id, str) -> Tpat_alias (p, id, str) - | `Constant cst -> Tpat_constant cst - | `Tuple ps -> Tpat_tuple ps - | `Construct (cstr, cst_descr, args) -> - Tpat_construct (cstr, cst_descr, args) - | `Variant (cstr, arg, row_desc) -> Tpat_variant (cstr, arg, row_desc) - | `Record (fields, closed) -> Tpat_record (fields, closed) - | `Array ps -> Tpat_array ps - | `Or (p, q, row_desc) -> Tpat_or (p, q, row_desc) - | `Lazy p -> Tpat_lazy p - - let erase p = { p with pat_desc = erase_desc p.pat_desc } + type nonrec clause = pattern Non_empty_row.t clause end module Half_simple : sig + include module type of Patterns.Half_simple (** Half-simplified patterns are patterns where: - records are expanded so that they possess all fields - aliases are removed and replaced by bindings in actions. @@ -239,15 +190,13 @@ module Half_simple : sig In particular, or-patterns may still occur in the leading column, so this is only a "half-simplification". *) - type pattern = half_simple_view pattern_data - - type clause = pattern Non_empty_clause.t + type nonrec clause = pattern Non_empty_row.t clause val of_clause : arg:lambda -> General.clause -> clause end = struct - type pattern = half_simple_view pattern_data + include Patterns.Half_simple - type clause = pattern Non_empty_clause.t + type nonrec clause = pattern Non_empty_row.t clause let rec simpl_under_orpat p = match p.pat_desc with @@ -270,15 +219,15 @@ end = struct (* Explode or-patterns and turn aliases into bindings in actions *) let of_clause ~arg cl = let rec aux (((p, patl), action) : General.clause) : clause = - let continue p (view : general_view) : clause = + let continue p (view : General.view) : clause = aux (({ p with pat_desc = view }, patl), action) in - let stop p (view : half_simple_view) : clause = + let stop p (view : view) : clause = (({ p with pat_desc = view }, patl), action) in match p.pat_desc with | `Any -> stop p `Any - | `Var (id, s) -> continue p (`Alias (omega, id, s)) + | `Var (id, s) -> continue p (`Alias (Patterns.omega, id, s)) | `Alias (p, id, _) -> let k = Typeopt.value_kind p.pat_env p.pat_type in aux @@ -304,26 +253,28 @@ end exception Cannot_flatten module Simple : sig - type pattern = simple_view pattern_data + include module type of Patterns.Simple - type clause = pattern Non_empty_clause.t + type nonrec clause = pattern Non_empty_row.t clause - val head : pattern -> Pattern_head.t + val head : pattern -> Patterns.Head.t val explode_or_pat : Half_simple.pattern * Typedtree.pattern list -> - arg:Ident.t option -> + arg_id:Ident.t option -> mk_action:(vars:Ident.t list -> lambda) -> vars:Ident.t list -> clause list -> clause list + (** If the toplevel pattern is given a name, but the scrutinee is not named + (i.e. [arg_id = None]), which happens (only) when matching a literal + tuple, then [Cannot_flatten] is raised. *) end = struct - type pattern = simple_view pattern_data + include Patterns.Simple - type clause = pattern Non_empty_clause.t + type nonrec clause = pattern Non_empty_row.t clause - let head p = - fst (Pattern_head.deconstruct (General.erase (p :> General.pattern))) + let head p = fst (Patterns.Head.deconstruct p) let alpha env (p : pattern) : pattern = let alpha_pat env p = Typedtree.alpha_pat env p in @@ -344,19 +295,19 @@ end = struct in { p with pat_desc } - let mk_alpha_env arg aliases ids = + let mk_alpha_env arg_id aliases ids = List.map (fun id -> ( id, if List.mem id aliases then - match arg with + match arg_id with | Some v -> v | _ -> raise Cannot_flatten else Ident.create_local (Ident.name id) )) ids - let explode_or_pat ((p : Half_simple.pattern), patl) ~arg ~mk_action ~vars + let explode_or_pat ((p : Half_simple.pattern), patl) ~arg_id ~mk_action ~vars (rem : clause list) : clause list = let rec explode p aliases rem = let split_explode p aliases rem = explode (General.view p) aliases rem in @@ -366,10 +317,10 @@ end = struct | `Alias (p, id, _) -> split_explode p (id :: aliases) rem | `Var (id, str) -> explode - { p with pat_desc = `Alias (Parmatch.omega, id, str) } + { p with pat_desc = `Alias (Patterns.omega, id, str) } aliases rem - | #simple_view as view -> - let env = mk_alpha_env arg aliases vars in + | #view as view -> + let env = mk_alpha_env arg_id aliases vars in ( (alpha env { p with pat_desc = view }, patl), mk_action ~vars:(List.map snd env) ) :: rem @@ -377,11 +328,17 @@ end = struct explode (p : Half_simple.pattern :> General.pattern) [] rem end +let expand_record_simple : Simple.pattern -> Simple.pattern = + fun p -> + match p.pat_desc with + | `Record (l, _) -> { p with pat_desc = `Record (all_record_args l, Closed) } + | _ -> p + type initial_clause = pattern list clause type matrix = pattern list list -let add_omega_column pss = List.map (fun ps -> omega :: ps) pss +let add_omega_column pss = List.map (fun ps -> Patterns.omega :: ps) pss let rec rev_split_at n ps = if n <= 0 then @@ -395,6 +352,62 @@ let rec rev_split_at n ps = exception NoMatch +let matcher discr (p : Simple.pattern) rem = + let discr = expand_record_head discr in + let p = expand_record_simple p in + let omegas = Patterns.(omegas (Head.arity discr)) in + let ph, args = Patterns.Head.deconstruct p in + let yes () = args @ rem in + let no () = raise NoMatch in + let yesif b = + if b then + yes () + else + no () + in + let open Patterns.Head in + match (discr.pat_desc, ph.pat_desc) with + | Any, _ -> rem + | ( ( Constant _ | Construct _ | Variant _ | Lazy | Array _ | Record _ + | Tuple _ ), + Any ) -> + omegas @ rem + | Constant cst, Constant cst' -> yesif (const_compare cst cst' = 0) + | Constant _, (Construct _ | Variant _ | Lazy | Array _ | Record _ | Tuple _) + -> + no () + | Construct cstr, Construct cstr' -> + (* NB: may_equal_constr considers (potential) constructor rebinding; + Types.may_equal_constr does check that the arities are the same, + preserving row-size coherence. *) + yesif (Types.may_equal_constr cstr cstr') + | Construct _, (Constant _ | Variant _ | Lazy | Array _ | Record _ | Tuple _) + -> + no () + | Variant { tag; has_arg }, Variant { tag = tag'; has_arg = has_arg' } -> + yesif (tag = tag' && has_arg = has_arg') + | Variant _, (Constant _ | Construct _ | Lazy | Array _ | Record _ | Tuple _) + -> + no () + | Array n1, Array n2 -> yesif (n1 = n2) + | Array _, (Constant _ | Construct _ | Variant _ | Lazy | Record _ | Tuple _) + -> + no () + | Tuple n1, Tuple n2 -> yesif (n1 = n2) + | Tuple _, (Constant _ | Construct _ | Variant _ | Lazy | Array _ | Record _) + -> + no () + | Record l, Record l' -> + (* we already expanded the record fully *) + yesif (List.length l = List.length l') + | Record _, (Constant _ | Construct _ | Variant _ | Lazy | Array _ | Tuple _) + -> + no () + | Lazy, Lazy -> yes () + | Lazy, (Constant _ | Construct _ | Variant _ | Array _ | Record _ | Tuple _) + -> + no () + let ncols = function | [] -> 0 | ps :: _ -> List.length ps @@ -410,7 +423,7 @@ module Context : sig val eprintf : t -> unit - val specialize : pattern -> t -> t + val specialize : Patterns.Head.t -> t -> t val lshift : t -> t @@ -443,7 +456,7 @@ end = struct let lforget { left; right } = match right with - | _ :: xs -> { left = omega :: left; right = xs } + | _ :: xs -> { left = Patterns.omega :: left; right = xs } | _ -> assert false let rshift { left; right } = @@ -468,7 +481,7 @@ end = struct let empty = [] - let start n : t = [ { left = []; right = omegas n } ] + let start n : t = [ { left = []; right = Patterns.omegas n } ] let is_empty = function | [] -> true @@ -489,76 +502,32 @@ end = struct let combine ctx = List.map Row.combine ctx - let ctx_matcher p q rem = - let rec expand_record p = - match p.pat_desc with - | Tpat_record (l, _) -> - { p with pat_desc = Tpat_record (all_record_args l, Closed) } - | Tpat_alias (p, _, _) -> expand_record p - | _ -> p - in - let ph, omegas = - let ph, p_args = Pattern_head.deconstruct (expand_record p) in - (ph, List.map (fun _ -> omega) p_args) - in - let qh, args = Pattern_head.deconstruct (expand_record q) in - let yes () = (p, args @ rem) in - let no () = raise NoMatch in - let yesif b = - if b then - yes () - else - no () + let specialize head ctx = + let non_empty = function + | { Row.left = _; right = [] } -> + fatal_error "Matching.Context.specialize" + | { Row.left; right = p :: ps } -> (left, p, ps) in - match (Pattern_head.desc ph, Pattern_head.desc qh) with - | Any, _ -> fatal_error "Matching.Context.matcher" - | _, Any -> (p, omegas @ rem) - | Construct cstr, Construct cstr' -> - (* NB: may_equal_constr considers (potential) constructor rebinding *) - yesif (Types.may_equal_constr cstr cstr') - | Construct _, _ -> no () - | Constant cst, Constant cst' -> yesif (const_compare cst cst' = 0) - | Constant _, _ -> no () - | Variant { tag; has_arg }, Variant { tag = tag'; has_arg = has_arg' } -> - yesif (tag = tag' && has_arg = has_arg') - | Variant _, _ -> no () - | Array n1, Array n2 -> yesif (n1 = n2) - | Array _, _ -> no () - | Tuple n1, Tuple n2 -> yesif (n1 = n2) - | Tuple _, _ -> no () - | Record l, Record l' -> - (* we called expand_record on both arguments so l, l' are full *) - yesif (List.length l = List.length l') - | Record _, _ -> no () - | Lazy, Lazy -> yes () - | Lazy, _ -> no () - - let specialize q ctx = - let matcher = ctx_matcher q in - let rec filter_rec : t -> t = function - | ({ right = p :: ps } as l) :: rem -> ( + let ctx = List.map non_empty ctx in + let rec filter_rec = function + | [] -> [] + | (left, p, right) :: rem -> ( + let p = General.view p in match p.pat_desc with - | Tpat_or (p1, p2, _) -> - filter_rec - ({ l with right = p1 :: ps } - :: { l with - Row.right (* disam not principal, OK *) = p2 :: ps - } - :: rem - ) - | Tpat_alias (p, _, _) -> - filter_rec ({ l with right = p :: ps } :: rem) - | Tpat_var _ -> filter_rec ({ l with right = omega :: ps } :: rem) - | _ -> ( - let rem = filter_rec rem in - try - let to_left, right = matcher p ps in - { left = to_left :: l.left; right } :: rem - with NoMatch -> rem + | `Or (p1, p2, _) -> + filter_rec ((left, p1, right) :: (left, p2, right) :: rem) + | `Alias (p, _, _) -> filter_rec ((left, p, right) :: rem) + | `Var _ -> filter_rec ((left, Patterns.omega, right) :: rem) + | #Simple.view as view -> ( + let p = { p with pat_desc = view } in + match matcher head p right with + | exception NoMatch -> filter_rec rem + | right -> + let left = Patterns.Head.to_omega_pattern head :: left in + { Row.left; right } + :: filter_rec rem ) ) - | [] -> [] - | _ -> fatal_error "Matching.Context.specialize" in filter_rec ctx @@ -591,11 +560,9 @@ end = struct let union pss qss = get_mins Row.le (pss @ qss) end -exception OrPat - let rec flatten_pat_line size p k = match p.pat_desc with - | Tpat_any -> omegas size :: k + | Tpat_any -> Patterns.omegas size :: k | Tpat_tuple args -> args :: k | Tpat_or (p1, p2, _) -> flatten_pat_line size p1 (flatten_pat_line size p2 k) @@ -642,7 +609,7 @@ module Default_environment : sig val cons : matrix -> int -> t -> t - val specialize : (pattern -> pattern list -> pattern list) -> t -> t + val specialize : Patterns.Head.t -> t -> t val pop_column : t -> t @@ -668,55 +635,123 @@ end = struct | [] -> default | _ -> (matrix, raise_num) :: default - let specialize_matrix matcher pss = + let specialize_matrix arity matcher pss = let rec filter_rec = function - | (p :: ps) :: rem -> ( + | [] -> [] + | (p, ps) :: rem -> ( + let p = General.view p in match p.pat_desc with - | Tpat_alias (p, _, _) -> filter_rec ((p :: ps) :: rem) - | Tpat_var _ -> filter_rec ((omega :: ps) :: rem) - | _ -> ( - let rem = filter_rec rem in - try matcher p ps :: rem with - | NoMatch -> rem - | OrPat -> ( - match p.pat_desc with - | Tpat_or (p1, p2, _) -> - filter_rec [ p1 :: ps; p2 :: ps ] @ rem - | _ -> assert false - ) + | `Alias (p, _, _) -> filter_rec ((p, ps) :: rem) + | `Var _ -> filter_rec ((Patterns.omega, ps) :: rem) + | `Or (p1, p2, _) -> filter_rec_or p1 p2 ps rem + | #Simple.view as view -> ( + let p = { p with pat_desc = view } in + match matcher p ps with + | exception NoMatch -> filter_rec rem + | specialized -> + assert (List.length specialized = List.length ps + arity); + specialized :: filter_rec rem ) ) - | [] -> [] + + (* Filter just one row, without a `rem` accumulator + of further rows to process. + The following equality holds: + filter_rec ((p :: ps) :: rem) + = filter_one p ps @ filter_rec rem + *) + and filter_one p ps = + filter_rec [ (p, ps) ] + + and filter_rec_or p1 p2 ps rem = + match arity with + | 0 -> ( + (* if K has arity 0, specializing ((K|K)::rem) returns just (rem): + if either sides works (filters into a non-empty list), + no need to keep the other. *) + match filter_one p1 ps with + | [] -> filter_rec ((p2, ps) :: rem) + | matches -> matches @ filter_rec rem + ) + | 1 -> ( + (* if K has arity 1, ((K p | K q) :: rem) can be expressed + as ((p | q) :: rem): even if both sides of an or-pattern + match, we can compress the output in a single row, + instead of duplicating the row. + + In particular, filtering a single row (the filter_one calls) + returns a result that respects the following properties: + - "row count": the result is either an empty list or a single row + - "row shape": if there is a row in the result, it contains one + pattern consed to the tail [ps] of our input row; in particular + the row is not empty. *) + match (filter_one p1 ps, filter_one p2 ps) with + | [], row + | row, [] -> + row @ filter_rec rem + | [ (arg1 :: _) ], [ (arg2 :: _) ] -> + (* By the row shape property, + the wildcard patterns can only be ps. *) + (* The output below is a single row, + respecting the row count property. *) + ({ arg1 with + pat_desc = Tpat_or (arg1, arg2, None); + pat_loc = Location.none + } + :: ps + ) + :: filter_rec rem + | (_ :: _ :: _), _ + | _, (_ :: _ :: _) -> + (* Cannot happen from the row count property. *) + assert false + | [ [] ], _ + | _, [ [] ] -> + (* Cannot happen from the row shape property. *) + assert false + ) | _ -> - pretty_matrix Format.err_formatter pss; - fatal_error "Matching.Default_environment.specialize_matrix" + (* we cannot preserve the or-pattern as in the arity-1 case, + because we cannot express + (K (p1, .., pn) | K (q1, .. qn)) + as (p1 .. pn | q1 .. qn) *) + filter_rec ((p1, ps) :: (p2, ps) :: rem) in filter_rec pss - let specialize matcher env = + let specialize_ arity matcher env = let rec make_rec = function | [] -> [] - | ([ [] ], i) :: _ -> [ ([ [] ], i) ] + | (([] :: _), i) :: _ -> [ ([ [] ], i) ] | (pss, i) :: rem -> ( - let rem = make_rec rem in - match specialize_matrix matcher pss with - | [] -> rem + (* we already handled the empty-row case + so we know that all rows in pss are non-empty *) + let non_empty = function + | [] -> assert false + | p :: ps -> (p, ps) + in + let pss = List.map non_empty pss in + match specialize_matrix arity matcher pss with + | [] -> make_rec rem | [] :: _ -> [ ([ [] ], i) ] - | pss -> (pss, i) :: rem + | pss -> (pss, i) :: make_rec rem ) in make_rec env - let pop_column def = specialize (fun _p rem -> rem) def + let specialize head def = + specialize_ (Patterns.Head.arity head) (matcher head) def + + let pop_column def = specialize_ 0 (fun _p rem -> rem) def let pop_compat p def = let compat_matcher q rem = - if may_compat p q then + if may_compat p (General.erase q) then rem else raise NoMatch in - specialize compat_matcher def + specialize_ 0 compat_matcher def let pop = function | [] -> None @@ -855,7 +890,7 @@ type handler = { } type 'head_pat pm_or_compiled = { - body : 'head_pat Non_empty_clause.t pattern_matching; + body : 'head_pat Non_empty_row.t clause pattern_matching; handlers : handler list; or_matrix : matrix } @@ -1012,23 +1047,27 @@ let safe_before ((p, ps), act_p) l = || not (may_compats (General.erase p :: ps) (General.erase q :: qs))) l -let half_simplify_nonempty ~arg (cls : Typedtree.pattern Non_empty_clause.t) : - Half_simple.clause = - cls |> Non_empty_clause.map_head General.view |> Half_simple.of_clause ~arg +let half_simplify_nonempty ~arg (cls : Typedtree.pattern Non_empty_row.t clause) + : Half_simple.clause = + cls + |> map_on_row (Non_empty_row.map_first General.view) + |> Half_simple.of_clause ~arg let half_simplify_clause ~arg (cls : Typedtree.pattern list clause) = - cls |> Non_empty_clause.of_initial |> half_simplify_nonempty ~arg + cls + |> map_on_row Non_empty_row.of_initial + |> half_simplify_nonempty ~arg (* Once matchings are *fully* simplified, one can easily find their nature. *) let rec what_is_cases ~skip_any cases = match cases with - | [] -> Pattern_head.omega + | [] -> Patterns.Head.omega | ((p, _), _) :: rem -> ( let head = Simple.head p in - match Pattern_head.desc head with - | Any when skip_any -> what_is_cases ~skip_any rem + match head.pat_desc with + | Patterns.Head.Any when skip_any -> what_is_cases ~skip_any rem | _ -> head ) @@ -1042,12 +1081,10 @@ let pm_free_variables { cases } = cases Ident.Set.empty (* Basic grouping predicates *) -let pat_as_constr = function - | { pat_desc = Tpat_construct (_, cstr, _) } -> cstr - | _ -> fatal_error "Matching.pat_as_constr" let can_group discr pat = - match (Pattern_head.desc discr, Pattern_head.desc (Simple.head pat)) with + let open Patterns.Head in + match (discr.pat_desc, (Simple.head pat).pat_desc) with | Any, Any | Constant (Const_int _), Constant (Const_int _) | Constant (Const_char _), Constant (Const_char _) @@ -1095,7 +1132,7 @@ let rec omega_like p = | _ -> false let simple_omega_like p = - match Pattern_head.desc (Simple.head p) with + match (Simple.head p).pat_desc with | Any -> true | _ -> false @@ -1235,7 +1272,7 @@ let as_matrix cases = *) -let rec split_or argo (cls : Half_simple.clause list) args def = +let rec split_or ~arg_id (cls : Half_simple.clause list) args def = let rec do_split (rev_before : Simple.clause list) rev_ors rev_no = function | [] -> cons_next (List.rev rev_before) (List.rev rev_ors) (List.rev rev_no) @@ -1243,7 +1280,7 @@ let rec split_or argo (cls : Half_simple.clause list) args def = do_split rev_before rev_ors (cl :: rev_no) rem | (((p, ps), act) as cl) :: rem -> ( match p.pat_desc with - | #simple_view as view when safe_before cl rev_ors -> + | #Simple.view as view when safe_before cl rev_ors -> do_split ((({ p with pat_desc = view }, ps), act) :: rev_before) rev_ors rev_no rem @@ -1266,7 +1303,7 @@ let rec split_or argo (cls : Half_simple.clause list) args def = in match yesor with | [] -> split_no_or yes args def nexts - | _ -> precompile_or argo yes yesor args def nexts + | _ -> precompile_or ~arg_id yes yesor args def nexts in do_split [] [] [] cls @@ -1315,8 +1352,8 @@ and split_no_or cls args def k = insert_split group_discr yes no def k and insert_split group_discr yes no def k = let precompile_group = - match Pattern_head.desc group_discr with - | Any -> precompile_var + match group_discr.pat_desc with + | Patterns.Head.Any -> precompile_var | _ -> do_not_precompile in match no with @@ -1328,8 +1365,8 @@ and split_no_or cls args def k = (Default_environment.cons matrix idef def) ((idef, next) :: nexts) and should_split group_discr = - match Pattern_head.desc group_discr with - | Construct { cstr_tag = Cstr_extension _ } -> + match group_discr.pat_desc with + | Patterns.Head.Construct { cstr_tag = Cstr_extension _ } -> (* it is unlikely that we will raise anything, so we split now *) true | _ -> false @@ -1365,7 +1402,7 @@ and precompile_var args cls def k = cls and var_def = Default_environment.pop_column def in let { me = first; matrix }, nexts = - split_or (Some v) var_cls var_args var_def + split_or ~arg_id:(Some v) var_cls var_args var_def in (* Compute top information *) match nexts with @@ -1416,12 +1453,12 @@ and do_not_precompile args cls def k = }, k ) -and precompile_or argo (cls : Simple.clause list) ors args def k = +and precompile_or ~arg_id (cls : Simple.clause list) ors args def k = let rec do_cases = function | [] -> ([], []) | ((p, patl), action) :: rem -> ( match p.pat_desc with - | #simple_view as view -> + | #Simple.view as view -> let new_ord, new_to_catch = do_cases rem in ( (({ p with pat_desc = view }, patl), action) :: new_ord, new_to_catch ) @@ -1450,13 +1487,13 @@ and precompile_or argo (cls : Simple.clause list) ors args def k = (id, Typeopt.value_kind orp.pat_env ty)) in let or_num = next_raise_count () in - let new_patl = Parmatch.omega_list patl in + let new_patl = Patterns.omega_list patl in let mk_new_action ~vars = Lstaticraise (or_num, List.map (fun v -> Lvar v) vars) in let rem_cases, rem_handlers = do_cases rem in let cases = - Simple.explode_or_pat (p, new_patl) ~arg:argo + Simple.explode_or_pat (p, new_patl) ~arg_id ~mk_action:mk_new_action ~vars:(List.map fst vars) rem_cases in let handler = @@ -1502,8 +1539,8 @@ let split_and_precompile_simplified pm = dbg_split_and_precompile pm next nexts; (next, nexts) -let split_and_precompile_half_simplified ~arg pm = - let { me = next }, nexts = split_or arg pm.cases pm.args pm.default in +let split_and_precompile_half_simplified ~arg_id pm = + let { me = next }, nexts = split_or ~arg_id pm.cases pm.args pm.default in dbg_split_and_precompile pm next nexts; (next, nexts) @@ -1511,18 +1548,34 @@ let split_and_precompile ~arg_id ~arg_lambda pm = let pm = { pm with cases = List.map (half_simplify_clause ~arg:arg_lambda) pm.cases } in - split_and_precompile_half_simplified ~arg:arg_id pm + split_and_precompile_half_simplified ~arg_id pm (* General divide functions *) type cell = { pm : initial_clause pattern_matching; ctx : Context.t; - discr : pattern + discr : Patterns.Head.t } (** a submatrix after specializing by discriminant pattern; [ctx] is the context shared by all rows. *) +let make_matching get_expr_args head def ctx = function + | [] -> fatal_error "Matching.make_matching" + | arg :: rem -> + let def = Default_environment.specialize head def + and args = get_expr_args head arg rem + and ctx = Context.specialize head ctx in + { pm = { cases = []; args; default = def }; ctx; discr = head } + +let make_line_matching get_expr_args head def = function + | [] -> fatal_error "Matching.make_line_matching" + | arg :: rem -> + { cases = []; + args = get_expr_args head arg rem; + default = Default_environment.specialize head def + } + type 'a division = { args : (lambda * let_kind) list; cells : ('a * cell) list @@ -1541,12 +1594,15 @@ let add_in_div make_matching_fun eq_key key patl_action division = in { division with cells } -let divide make eq_key get_key get_args ctx +let divide get_expr_args eq_key get_key get_pat_args ctx (pm : Simple.clause pattern_matching) = let add ((p, patl), action) division = + let ph = Simple.head p in let p = General.erase p in - add_in_div (make p pm.default ctx) eq_key (get_key p) - (get_args p patl, action) + add_in_div + (make_matching get_expr_args ph pm.default ctx) + eq_key (get_key p) + (get_pat_args p patl, action) division in List.fold_right add pm.cases { args = pm.args; cells = [] } @@ -1555,39 +1611,33 @@ let add_line patl_action pm = pm.cases <- patl_action :: pm.cases; pm -let divide_line make_ctx make get_args discr ctx +let divide_line make_ctx get_expr_args get_pat_args discr ctx (pm : Simple.clause pattern_matching) = let add ((p, patl), action) submatrix = let p = General.erase p in - add_line (get_args p patl, action) submatrix + add_line (get_pat_args p patl, action) submatrix + in + let pm = + List.fold_right add pm.cases + (make_line_matching get_expr_args discr pm.default pm.args) in - let pm = List.fold_right add pm.cases (make pm.default pm.args) in { pm; ctx = make_ctx ctx; discr } +let drop_pat_arg _p rem = rem +let drop_expr_arg _head _arg rem = rem + (* Then come various functions, There is one set of functions per matching style (constants, constructors etc.) - - matcher functions are arguments to Default_environment.specialize (for - default handlers) - They may raise NoMatch or OrPat and perform the full - matching (selection + arguments). - - - get_args and get_key are for the compiled matrices, note that - selection and getting arguments are separated. + - get_{expr,pat}_args and get_key are for the compiled matrices, + note that selection and getting arguments are separated. - make_*_matching combines the previous functions for producing new ``pattern_matching'' records. *) -let rec matcher_const cst p rem = - match p.pat_desc with - | Tpat_or (p1, p2, _) -> ( - try matcher_const cst p1 rem with NoMatch -> matcher_const cst p2 rem - ) - | Tpat_constant c1 when const_compare c1 cst = 0 -> rem - | Tpat_any -> rem - | _ -> raise NoMatch +(* Matching against a constant *) let get_key_constant caller = function | { pat_desc = Tpat_constant cst } -> cst @@ -1596,189 +1646,68 @@ let get_key_constant caller = function pretty_pat p; assert false -let get_args_constant _ rem = rem - -let make_constant_matching p def ctx = function - | [] -> fatal_error "Matching.make_constant_matching" - | _ :: argl -> - let def = - Default_environment.specialize - (matcher_const (get_key_constant "make" p)) - def - and ctx = Context.specialize p ctx in - { pm = { cases = []; args = argl; default = def }; - ctx; - discr = normalize_pat p - } +let get_pat_args_constant = drop_pat_arg +let get_expr_args_constant = drop_expr_arg let divide_constant ctx m = - divide make_constant_matching + divide + get_expr_args_constant (fun c d -> const_compare c d = 0) (get_key_constant "divide") - get_args_constant ctx m + get_pat_args_constant ctx m (* Matching against a constructor *) -let make_field_args loc binding_kind arg first_pos last_pos argl = - let rec make_args pos = - if pos > last_pos then - argl - else - (Lprim (Pfield pos, [ arg ], loc), binding_kind) :: make_args (pos + 1) - in - make_args first_pos - let get_key_constr = function - | { pat_desc = Tpat_construct (_, cstr, _) } -> cstr.cstr_tag + | { pat_desc = Tpat_construct (_, cstr, _) } -> cstr | _ -> assert false -let get_args_constr p rem = +let get_pat_args_constr p rem = match p with | { pat_desc = Tpat_construct (_, _, args) } -> args @ rem | _ -> assert false -(* NB: matcher_constr applies to default matrices. - - In that context, matching by constructors of extensible - types degrades to arity checking, due to potential rebinding. - This comparison is performed by Types.may_equal_constr. -*) - -let matcher_constr cstr = - match cstr.cstr_arity with - | 0 -> - let rec matcher_rec q rem = - match q.pat_desc with - | Tpat_or (p1, p2, _) -> ( - try matcher_rec p1 rem with NoMatch -> matcher_rec p2 rem - ) - | Tpat_construct (_, cstr', []) when Types.may_equal_constr cstr cstr' - -> - rem - | Tpat_any -> rem - | _ -> raise NoMatch - in - matcher_rec - | 1 -> - let rec matcher_rec q rem = - match q.pat_desc with - | Tpat_or (p1, p2, _) -> ( - (* if both sides of the or-pattern match the head constructor, - (K p1 | K p2) :: rem - return (p1 | p2) :: rem *) - let r1 = try Some (matcher_rec p1 rem) with NoMatch -> None - and r2 = try Some (matcher_rec p2 rem) with NoMatch -> None in - match (r1, r2) with - | None, None -> raise NoMatch - | Some r1, None -> r1 - | None, Some r2 -> r2 - | Some (a1 :: _), Some (a2 :: _) -> - { a1 with - pat_loc = Location.none; - pat_desc = Tpat_or (a1, a2, None) - } - :: rem - | _, _ -> assert false - ) - | Tpat_construct (_, cstr', [ arg ]) - when Types.may_equal_constr cstr cstr' -> - arg :: rem - | Tpat_any -> omega :: rem - | _ -> raise NoMatch - in - matcher_rec - | _ -> ( - fun q rem -> - match q.pat_desc with - | Tpat_or (_, _, _) -> - (* we cannot preserve the or-pattern as in the arity-1 case, - because we cannot express - (K (p1, .., pn) | K (q1, .. qn)) - as (p1 .. pn | q1 .. qn) *) - raise OrPat - | Tpat_construct (_, cstr', args) - when Types.may_equal_constr cstr cstr' -> - args @ rem - | Tpat_any -> Parmatch.omegas cstr.cstr_arity @ rem - | _ -> raise NoMatch - ) - -let make_constr_matching ~scopes p def ctx = function - | [] -> fatal_error "Matching.make_constr_matching" - | (arg, _mut) :: argl -> - let cstr = pat_as_constr p in - let newargs = - if cstr.cstr_inlined <> None then - (arg, Alias) :: argl - else - match cstr.cstr_tag with - | Cstr_constant _ - | Cstr_block _ -> - make_field_args (of_location ~scopes p.pat_loc) - Alias arg 0 (cstr.cstr_arity - 1) argl - | Cstr_unboxed -> (arg, Alias) :: argl - | Cstr_extension _ -> - make_field_args (of_location ~scopes p.pat_loc) - Alias arg 1 cstr.cstr_arity argl - in - { pm = - { cases = []; - args = newargs; - default = Default_environment.specialize (matcher_constr cstr) def - }; - ctx = Context.specialize p ctx; - discr = normalize_pat p - } +let get_expr_args_constr ~scopes head (arg, _mut) rem = + let cstr = + match head.pat_desc with + | Patterns.Head.Construct cstr -> cstr + | _ -> fatal_error "Matching.get_expr_args_constr" + in + let loc = head_loc ~scopes head in + let make_field_accesses binding_kind first_pos last_pos argl = + let rec make_args pos = + if pos > last_pos then + argl + else + (Lprim (Pfield pos, [ arg ], loc), binding_kind) :: make_args (pos + 1) + in + make_args first_pos + in + if cstr.cstr_inlined <> None then + (arg, Alias) :: rem + else + match cstr.cstr_tag with + | Cstr_constant _ + | Cstr_block _ -> + make_field_accesses Alias 0 (cstr.cstr_arity - 1) rem + | Cstr_unboxed -> (arg, Alias) :: rem + | Cstr_extension _ -> make_field_accesses Alias 1 cstr.cstr_arity rem let divide_constructor ~scopes ctx pm = - divide (make_constr_matching ~scopes) ( = ) - get_key_constr get_args_constr ctx pm + divide + (get_expr_args_constr ~scopes) + (fun cstr1 cstr2 -> Types.equal_tag cstr1.cstr_tag cstr2.cstr_tag) + get_key_constr + get_pat_args_constr + ctx pm (* Matching against a variant *) -let rec matcher_variant_const lab p rem = - match p.pat_desc with - | Tpat_or (p1, p2, _) -> ( - try matcher_variant_const lab p1 rem - with NoMatch -> matcher_variant_const lab p2 rem - ) - | Tpat_variant (lab1, _, _) when lab1 = lab -> rem - | Tpat_any -> rem - | _ -> raise NoMatch - -let make_variant_matching_constant p lab def ctx = function - | [] -> fatal_error "Matching.make_variant_matching_constant" - | _ :: argl -> - let def = Default_environment.specialize (matcher_variant_const lab) def - and ctx = Context.specialize p ctx in - { pm = { cases = []; args = argl; default = def }; - ctx; - discr = normalize_pat p - } +let get_expr_args_variant_constant = drop_expr_arg -let matcher_variant_nonconst lab p rem = - match p.pat_desc with - | Tpat_or (_, _, _) -> raise OrPat - | Tpat_variant (lab1, Some arg, _) when lab1 = lab -> arg :: rem - | Tpat_any -> omega :: rem - | _ -> raise NoMatch - -let make_variant_matching_nonconst ~scopes p lab def ctx = function - | [] -> fatal_error "Matching.make_variant_matching_nonconst" - | (arg, _mut) :: argl -> - let def = - Default_environment.specialize (matcher_variant_nonconst lab) def - and ctx = Context.specialize p ctx - and loc = of_location ~scopes p.pat_loc in - { pm = - { cases = []; - args = (Lprim (Pfield 1, [ arg ], loc), Alias) - :: argl; - default = def - }; - ctx; - discr = normalize_pat p - } +let get_expr_args_variant_nonconst ~scopes head (arg, _mut) rem = + let loc = head_loc ~scopes head in + (Lprim (Pfield 1, [ arg ], loc), Alias) :: rem let divide_variant ~scopes row ctx { cases = cl; args; default = def } = let row = Btype.row_repr row in @@ -1790,7 +1719,7 @@ let divide_variant ~scopes row ctx { cases = cl; args; default = def } = | `Variant (lab, pato, _) -> lab, pato | _ -> assert false in - let p = General.erase p in + let head = Simple.head p in let variants = divide rem in if try Btype.row_field_repr (List.assoc lab row.row_fields) = Rabsent @@ -1802,11 +1731,13 @@ let divide_variant ~scopes row ctx { cases = cl; args; default = def } = match pato with | None -> add_in_div - (make_variant_matching_constant p lab def ctx) + (make_matching get_expr_args_variant_constant head def ctx) ( = ) (Cstr_constant tag) (patl, action) variants | Some pat -> add_in_div - (make_variant_matching_nonconst ~scopes p lab def ctx) + (make_matching + (get_expr_args_variant_nonconst ~scopes) + head def ctx) ( = ) (Cstr_block tag) (pat :: patl, action) variants @@ -1819,36 +1750,24 @@ let divide_variant ~scopes row ctx { cases = cl; args; default = def } = *) (* Matching against a variable *) -let get_args_var _p rem = rem -let make_var_matching def = function - | [] -> fatal_error "Matching.make_var_matching" - | _ :: argl -> - { cases = []; - args = argl; - default = Default_environment.specialize get_args_var def - } +let get_pat_args_var = drop_pat_arg +let get_expr_args_var = drop_expr_arg let divide_var ctx pm = - divide_line Context.lshift make_var_matching get_args_var omega ctx pm + divide_line Context.lshift + get_expr_args_var + get_pat_args_var + Patterns.Head.omega ctx pm (* Matching and forcing a lazy value *) -let get_arg_lazy p rem = +let get_pat_args_lazy p rem = match p with - | { pat_desc = Tpat_any } -> omega :: rem + | { pat_desc = Tpat_any } -> Patterns.omega :: rem | { pat_desc = Tpat_lazy arg } -> arg :: rem | _ -> assert false -let matcher_lazy p rem = - match p.pat_desc with - | Tpat_or (_, _, _) -> raise OrPat - | Tpat_any - | Tpat_var _ -> - omega :: rem - | Tpat_lazy arg -> arg :: rem - | _ -> raise NoMatch - (* Inlining the tag tests before calling the primitive that works on lazy blocks. This is also used in translcore.ml. No other call than Obj.tag when the value has been forced before. @@ -1916,7 +1835,7 @@ let inline_lazy_force_cond arg loc = [ tag_var; Lconst (Const_base (Const_int Obj.lazy_tag)) ], loc ), Lapply - { ap_should_be_tailcall = false; + { ap_tailcall = Default_tailcall; ap_loc = loc; ap_func = force_fun; ap_args = [ varg ]; @@ -1948,7 +1867,7 @@ let inline_lazy_force_switch arg loc = [ (Obj.forward_tag, Lprim (Pfield 0, [ varg ], loc)); ( Obj.lazy_tag, Lapply - { ap_should_be_tailcall = false; + { ap_tailcall = Default_tailcall; ap_loc = loc; ap_func = force_fun; ap_args = [ varg ]; @@ -1967,7 +1886,7 @@ let inline_lazy_force arg loc = instrumentation output. (see https://github.com/stedolan/crowbar/issues/14) *) Lapply - { ap_should_be_tailcall = false; + { ap_tailcall = Default_tailcall; ap_loc = loc; ap_func = Lazy.force code_force_lazy; ap_args = [ arg ]; @@ -1982,113 +1901,100 @@ let inline_lazy_force arg loc = tables (~ 250 elts); conditionals are better *) inline_lazy_force_cond arg loc -let make_lazy_matching def = function - | [] -> fatal_error "Matching.make_lazy_matching" - | (arg, _mut) :: argl -> - { cases = []; - args = (inline_lazy_force arg Loc_unknown, Strict) :: argl; - default = Default_environment.specialize matcher_lazy def - } +let get_expr_args_lazy ~scopes head (arg, _mut) rem = + let loc = head_loc ~scopes head in + (inline_lazy_force arg loc, Strict) :: rem -let divide_lazy p ctx pm = - divide_line (Context.specialize p) make_lazy_matching get_arg_lazy p ctx pm +let divide_lazy ~scopes head ctx pm = + divide_line (Context.specialize head) + (get_expr_args_lazy ~scopes) + get_pat_args_lazy + head ctx pm (* Matching against a tuple pattern *) -let get_args_tuple arity p rem = +let get_pat_args_tuple arity p rem = match p with - | { pat_desc = Tpat_any } -> omegas arity @ rem + | { pat_desc = Tpat_any } -> Patterns.omegas arity @ rem | { pat_desc = Tpat_tuple args } -> args @ rem | _ -> assert false -let matcher_tuple arity p rem = - match p.pat_desc with - | Tpat_or (_, _, _) -> raise OrPat - | Tpat_any - | Tpat_var _ -> - omegas arity @ rem - | Tpat_tuple args when List.length args = arity -> args @ rem - | _ -> raise NoMatch - -let make_tuple_matching loc arity def = function - | [] -> fatal_error "Matching.make_tuple_matching" - | (arg, _mut) :: argl -> - let rec make_args pos = - if pos >= arity then - argl - else - (Lprim (Pfield pos, [ arg ], loc), Alias) :: make_args (pos + 1) - in - { cases = []; - args = make_args 0; - default = Default_environment.specialize (matcher_tuple arity) def - } +let get_expr_args_tuple ~scopes head (arg, _mut) rem = + let loc = head_loc ~scopes head in + let arity = Patterns.Head.arity head in + let rec make_args pos = + if pos >= arity then + rem + else + (Lprim (Pfield pos, [ arg ], loc), Alias) :: make_args (pos + 1) + in + make_args 0 -let divide_tuple ~scopes arity p ctx pm = - divide_line (Context.specialize p) - (make_tuple_matching (of_location ~scopes p.pat_loc) arity) - (get_args_tuple arity) p ctx pm +let divide_tuple ~scopes head ctx pm = + let arity = Patterns.Head.arity head in + divide_line (Context.specialize head) + (get_expr_args_tuple ~scopes) + (get_pat_args_tuple arity) + head ctx pm (* Matching against a record pattern *) let record_matching_line num_fields lbl_pat_list = - let patv = Array.make num_fields omega in + let patv = Array.make num_fields Patterns.omega in List.iter (fun (_, lbl, pat) -> patv.(lbl.lbl_pos) <- pat) lbl_pat_list; Array.to_list patv -let get_args_record num_fields p rem = +let get_pat_args_record num_fields p rem = match p with | { pat_desc = Tpat_any } -> record_matching_line num_fields [] @ rem | { pat_desc = Tpat_record (lbl_pat_list, _) } -> record_matching_line num_fields lbl_pat_list @ rem | _ -> assert false -let matcher_record num_fields p rem = - match p.pat_desc with - | Tpat_or (_, _, _) -> raise OrPat - | Tpat_any - | Tpat_var _ -> - record_matching_line num_fields [] @ rem - | Tpat_record ([], _) when num_fields = 0 -> rem - | Tpat_record (((_, lbl, _) :: _ as lbl_pat_list), _) - when Array.length lbl.lbl_all = num_fields -> - record_matching_line num_fields lbl_pat_list @ rem - | _ -> raise NoMatch - -let make_record_matching loc all_labels def = function - | [] -> fatal_error "Matching.make_record_matching" - | (arg, _mut) :: argl -> - let rec make_args pos = - if pos >= Array.length all_labels then - argl - else - let lbl = all_labels.(pos) in - let access = - match lbl.lbl_repres with - | Record_regular - | Record_inlined _ -> - Lprim (Pfield lbl.lbl_pos, [ arg ], loc) - | Record_unboxed _ -> arg - | Record_float -> Lprim (Pfloatfield lbl.lbl_pos, [ arg ], loc) - | Record_extension _ -> - Lprim (Pfield (lbl.lbl_pos + 1), [ arg ], loc) - in - let str = - match lbl.lbl_mut with - | Immutable -> Alias - | Mutable -> StrictOpt - in - (access, str) :: make_args (pos + 1) +let get_expr_args_record ~scopes head (arg, _mut) rem = + let loc = head_loc ~scopes head in + let all_labels = + let open Patterns.Head in + match head.pat_desc with + | Record (lbl :: _) -> lbl.lbl_all + | Record [] + | _ -> + assert false + in + let rec make_args pos = + if pos >= Array.length all_labels then + rem + else + let lbl = all_labels.(pos) in + let access = + match lbl.lbl_repres with + | Record_regular + | Record_inlined _ -> + Lprim (Pfield lbl.lbl_pos, [ arg ], loc) + | Record_unboxed _ -> arg + | Record_float -> Lprim (Pfloatfield lbl.lbl_pos, [ arg ], loc) + | Record_extension _ -> Lprim (Pfield (lbl.lbl_pos + 1), [ arg ], loc) in - let nfields = Array.length all_labels in - let def = Default_environment.specialize (matcher_record nfields) def in - { cases = []; args = make_args 0; default = def } - -let divide_record ~scopes all_labels p ctx pm = - let get_args = get_args_record (Array.length all_labels) in - divide_line (Context.specialize p) - (make_record_matching (of_location ~scopes p.pat_loc) all_labels) - get_args p ctx pm + let str = + match lbl.lbl_mut with + | Immutable -> Alias + | Mutable -> StrictOpt + in + (access, str) :: make_args (pos + 1) + in + make_args 0 + +let divide_record all_labels ~scopes head ctx pm = + (* There is some redundancy in the expansions here, [head] is + expanded here and again in the matcher. It would be + nicer to have a type-level distinction between expanded heads + and non-expanded heads, to be able to reason confidently on + when expansions must happen. *) + let head = expand_record_head head in + divide_line (Context.specialize head) + (get_expr_args_record ~scopes) + (get_pat_args_record (Array.length all_labels)) + head ctx pm (* Matching against an array pattern *) @@ -2096,43 +2002,36 @@ let get_key_array = function | { pat_desc = Tpat_array patl } -> List.length patl | _ -> assert false -let get_args_array p rem = +let get_pat_args_array p rem = match p with | { pat_desc = Tpat_array patl } -> patl @ rem | _ -> assert false -let matcher_array len p rem = - match p.pat_desc with - | Tpat_or (_, _, _) -> raise OrPat - | Tpat_array args when List.length args = len -> args @ rem - | Tpat_any -> Parmatch.omegas len @ rem - | _ -> raise NoMatch - -let make_array_matching ~scopes kind p def ctx = function - | [] -> fatal_error "Matching.make_array_matching" - | (arg, _mut) :: argl -> - let len = get_key_array p in - let rec make_args pos = - if pos >= len then - argl - else - ( Lprim - ( Parrayrefu kind, - [ arg; Lconst (Const_base (Const_int pos)) ], - (of_location ~scopes p.pat_loc) ), - StrictOpt ) - :: make_args (pos + 1) - in - let def = Default_environment.specialize (matcher_array len) def - and ctx = Context.specialize p ctx in - { pm = { cases = []; args = make_args 0; default = def }; - ctx; - discr = normalize_pat p - } +let get_expr_args_array ~scopes kind head (arg, _mut) rem = + let len = + let open Patterns.Head in + match head.pat_desc with + | Array len -> len + | _ -> assert false + in + let loc = head_loc ~scopes head in + let rec make_args pos = + if pos >= len then + rem + else + ( Lprim + (Parrayrefu kind, [ arg; Lconst (Const_base (Const_int pos)) ], loc), + StrictOpt ) + :: make_args (pos + 1) + in + make_args 0 let divide_array ~scopes kind ctx pm = - divide (make_array_matching ~scopes kind) ( = ) - get_key_array get_args_array ctx pm + divide + (get_expr_args_array ~scopes kind) + ( = ) + get_key_array get_pat_args_array + ctx pm (* Specific string test sequence @@ -2602,9 +2501,14 @@ let rec list_as_pat = function | pat :: rem -> { pat with pat_desc = Tpat_or (pat, list_as_pat rem, None) } let complete_pats_constrs = function - | p :: _ as pats -> - List.map (pat_of_constr p) - (complete_constrs p (List.map get_key_constr pats)) + | constr :: _ as constrs -> + let tag_of_constr constr = + constr.pat_desc.cstr_tag in + let pat_of_constr cstr = + let open Patterns.Head in + to_omega_pattern { constr with pat_desc = Construct cstr } in + List.map pat_of_constr + (complete_constrs constr (List.map tag_of_constr constrs)) | _ -> assert false (* @@ -2746,9 +2650,9 @@ let combine_constant loc arg cst partial ctx def let split_cases tag_lambda_list = let rec split_rec = function | [] -> ([], []) - | (cstr, act) :: rem -> ( + | (cstr_tag, act) :: rem -> ( let consts, nonconsts = split_rec rem in - match cstr with + match cstr_tag with | Cstr_constant n -> ((n, act) :: consts, nonconsts) | Cstr_block n -> (consts, (n, act) :: nonconsts) | Cstr_unboxed -> (consts, (0, act) :: nonconsts) @@ -2761,9 +2665,9 @@ let split_cases tag_lambda_list = let split_extension_cases tag_lambda_list = let rec split_rec = function | [] -> ([], []) - | (cstr, act) :: rem -> ( + | (cstr_tag, act) :: rem -> ( let consts, nonconsts = split_rec rem in - match cstr with + match cstr_tag with | Cstr_extension (path, true) -> ((path, act) :: consts, nonconsts) | Cstr_extension (path, false) -> (consts, (path, act) :: nonconsts) | _ -> assert false @@ -2772,13 +2676,15 @@ let split_extension_cases tag_lambda_list = split_rec tag_lambda_list let combine_constructor loc arg pat_env cstr partial ctx def - (tag_lambda_list, total1, pats) = + (descr_lambda_list, total1, pats) = + let tag_lambda (cstr, act) = (cstr.cstr_tag, act) in match cstr.cstr_tag with | Cstr_extension _ -> (* Special cases for extensions *) let fail, local_jumps = mk_failaction_neg partial ctx def in let lambda1 = - let consts, nonconsts = split_extension_cases tag_lambda_list in + let consts, nonconsts = + split_extension_cases (List.map tag_lambda descr_lambda_list) in let default, consts, nonconsts = match fail with | None -> ( @@ -2813,19 +2719,23 @@ let combine_constructor loc arg pat_env cstr partial ctx def (lambda1, Jumps.union local_jumps total1) | _ -> (* Regular concrete type *) - let ncases = List.length tag_lambda_list + let ncases = List.length descr_lambda_list and nconstrs = cstr.cstr_consts + cstr.cstr_nonconsts in let sig_complete = ncases = nconstrs in let fail_opt, fails, local_jumps = if sig_complete then (None, [], Jumps.empty) else - mk_failaction_pos partial pats ctx def + let constrs = + List.map2 (fun (constr, _act) p -> { p with pat_desc = constr }) + descr_lambda_list pats in + mk_failaction_pos partial constrs ctx def in - let tag_lambda_list = fails @ tag_lambda_list in - let consts, nonconsts = split_cases tag_lambda_list in + let descr_lambda_list = fails @ descr_lambda_list in + let consts, nonconsts = + split_cases (List.map tag_lambda descr_lambda_list) in let lambda1 = - match (fail_opt, same_actions tag_lambda_list) with + match (fail_opt, same_actions descr_lambda_list) with | None, Some act -> act (* Identical actions, no failure *) | _ -> ( match @@ -3006,14 +2916,17 @@ let compile_list compile_fun division = | (key, cell) :: rem -> ( if Context.is_empty cell.ctx then c_rec totals rem - else - try - let lambda1, total1 = compile_fun cell.ctx cell.pm in + else begin + match compile_fun cell.ctx cell.pm with + | exception Unused -> c_rec totals rem + | lambda1, total1 -> let c_rem, total, new_discrs = c_rec (Jumps.map Context.combine total1 :: totals) rem in - ((key, lambda1) :: c_rem, total, cell.discr :: new_discrs) - with Unused -> c_rec totals rem + ( (key, lambda1) :: c_rem, + total, + Patterns.Head.to_omega_pattern cell.discr :: new_discrs ) + end ) in c_rec [] division @@ -3022,10 +2935,12 @@ let compile_orhandlers compile_fun lambda1 total1 ctx to_catch = let rec do_rec r total_r = function | [] -> (r, total_r) | { provenance = mat; exit = i; vars; pm } :: rem -> ( - try - let ctx = Context.select_columns mat ctx in - let handler_i, total_i = compile_fun ctx pm in - match raw_action r with + let ctx = Context.select_columns mat ctx in + match compile_fun ctx pm with + | exception Unused -> + do_rec (Lstaticcatch (r, (i, vars), lambda_unit)) total_r rem + | handler_i, total_i -> + begin match raw_action r with | Lstaticraise (j, args) -> if i = j then ( List.fold_right2 @@ -3040,8 +2955,7 @@ let compile_orhandlers compile_fun lambda1 total1 ctx to_catch = (Jumps.union (Jumps.remove i total_r) (Jumps.map (Context.rshift_num (ncols mat)) total_i)) rem - with Unused -> - do_rec (Lstaticcatch (r, (i, vars), lambda_unit)) total_r rem + end ) in do_rec lambda1 total1 to_catch @@ -3117,28 +3031,28 @@ let rec comp_match_handlers comp_fun partial ctx first_match next_matchs = let ctx_i, total_rem = Jumps.extract i total_body in if Context.is_empty ctx_i then c_rec body total_body rem - else - try - let li, total_i = - comp_fun - ( match rem with - | [] -> partial - | _ -> Partial - ) - ctx_i pm - in + else begin + let partial = match rem with + | [] -> partial + | _ -> Partial + in + match comp_fun partial ctx_i pm with + | li, total_i -> c_rec (Lstaticcatch (body, (i, []), li)) (Jumps.union total_i total_rem) rem - with Unused -> - c_rec (Lstaticcatch (body, (i, []), lambda_unit)) total_rem rem + | exception Unused -> + c_rec + (Lstaticcatch (body, (i, []), lambda_unit)) + total_rem rem + end ) in - try - let first_lam, total = comp_fun Partial ctx first_match in + match comp_fun Partial ctx first_match with + | first_lam, total -> c_rec first_lam total rem - with Unused -> ( + | exception Unused -> ( match next_matchs with | [] -> raise Unused | (_, x) :: xs -> comp_match_handlers comp_fun partial ctx x xs @@ -3187,10 +3101,10 @@ let rec compile_match ~scopes repr partial ctx (event_branch repr action, Jumps.empty) | nonempty_cases -> compile_match_nonempty ~scopes repr partial ctx - { m with cases = List.map Non_empty_clause.of_initial nonempty_cases } + { m with cases = map_on_rows Non_empty_row.of_initial nonempty_cases } and compile_match_nonempty ~scopes repr partial ctx - (m : Typedtree.pattern Non_empty_clause.t pattern_matching) = + (m : Typedtree.pattern Non_empty_row.t clause pattern_matching) = match m with | { cases = []; args = [] } -> comp_exit ctx m | { args = (arg, str) :: argl } -> @@ -3199,7 +3113,7 @@ and compile_match_nonempty ~scopes repr partial ctx let cases = List.map (half_simplify_nonempty ~arg:newarg) m.cases in let m = { m with args; cases } in let first_match, rem = - split_and_precompile_half_simplified ~arg:(Some v) m in + split_and_precompile_half_simplified ~arg_id:(Some v) m in combine_handlers ~scopes repr partial ctx (v, str, arg) first_match rem | _ -> assert false @@ -3259,48 +3173,51 @@ and do_compile_matching ~scopes repr partial ctx pmh = assert false in let ph = what_is_cases pm.cases in - let pomega = Pattern_head.to_omega_pattern ph in - let ploc = Pattern_head.loc ph in - match Pattern_head.desc ph with + let pomega = Patterns.Head.to_omega_pattern ph in + let ploc = head_loc ~scopes ph in + let open Patterns.Head in + match ph.pat_desc with | Any -> - compile_no_test ~scopes divide_var Context.rshift repr partial ctx pm - | Tuple l -> - compile_no_test ~scopes (divide_tuple ~scopes l pomega) + compile_no_test ~scopes + divide_var + Context.rshift repr partial ctx pm + | Tuple _ -> + compile_no_test ~scopes + (divide_tuple ~scopes ph) Context.combine repr partial ctx pm | Record [] -> assert false | Record (lbl :: _) -> compile_no_test ~scopes - (divide_record ~scopes lbl.lbl_all pomega) + (divide_record ~scopes lbl.lbl_all ph) Context.combine repr partial ctx pm | Constant cst -> compile_test (compile_match ~scopes repr partial) partial divide_constant - (combine_constant (of_location ~scopes ploc) arg cst partial) + (combine_constant ploc arg cst partial) ctx pm | Construct cstr -> compile_test (compile_match ~scopes repr partial) partial (divide_constructor ~scopes) - (combine_constructor (of_location ~scopes ploc) arg - (Pattern_head.env ph) cstr partial) + (combine_constructor ploc arg ph.pat_env cstr partial) ctx pm | Array _ -> let kind = Typeopt.array_pattern_kind pomega in compile_test (compile_match ~scopes repr partial) partial (divide_array ~scopes kind) - (combine_array (of_location ~scopes ploc) arg kind partial) + (combine_array ploc arg kind partial) ctx pm | Lazy -> compile_no_test ~scopes - (divide_lazy pomega) + (divide_lazy ~scopes ph) Context.combine repr partial ctx pm | Variant { cstr_row = row } -> compile_test (compile_match ~scopes repr partial) partial (divide_variant ~scopes !row) - (combine_variant (of_location ~scopes ploc) !row arg partial) + (combine_variant ploc !row arg partial) ctx pm ) | PmVar { inside = pmh } -> @@ -3408,13 +3325,47 @@ let check_partial pat_act_list = (* have toplevel handler when appropriate *) -let check_total total lambda i handler_fun = +type failer_kind = + | Raise_match_failure + | Reraise_noloc of lambda + +let failure_handler ~scopes loc ~failer () = + match failer with + | Reraise_noloc exn_lam -> + Lprim (Praise Raise_reraise, [ exn_lam ], Scoped_location.Loc_unknown) + | Raise_match_failure -> + let sloc = Scoped_location.of_location ~scopes loc in + let slot = + transl_extension_path sloc + Env.initial_safe_string Predef.path_match_failure + in + let fname, line, char = + Location.get_pos_info loc.Location.loc_start in + Lprim + ( Praise Raise_regular, + [ Lprim + ( Pmakeblock (0, Immutable, None), + [ slot; + Lconst + (Const_block + ( 0, + [ Const_base (Const_string (fname, loc, None)); + Const_base (Const_int line); + Const_base (Const_int char) + ] )) + ], + sloc ) + ], + sloc ) + +let check_total ~scopes loc ~failer total lambda i = if Jumps.is_empty total then lambda else - Lstaticcatch (lambda, (i, []), handler_fun ()) + Lstaticcatch (lambda, (i, []), + failure_handler ~scopes loc ~failer ()) -let compile_matching ~scopes repr handler_fun arg pat_act_list partial = +let compile_matching ~scopes loc ~failer repr arg pat_act_list partial = let partial = check_partial pat_act_list partial in match partial with | Partial -> ( @@ -3422,13 +3373,14 @@ let compile_matching ~scopes repr handler_fun arg pat_act_list partial = let pm = { cases = List.map (fun (pat, act) -> ([ pat ], act)) pat_act_list; args = [ (arg, Strict) ]; - default = Default_environment.(cons [ [ omega ] ] raise_num empty) + default = + Default_environment.(cons [ [ Patterns.omega ] ] raise_num empty) } in try let lambda, total = compile_match ~scopes repr partial (Context.start 1) pm in - check_total total lambda raise_num handler_fun + check_total ~scopes loc ~failer total lambda raise_num with Unused -> assert false (* ; handler_fun() *) ) @@ -3444,43 +3396,25 @@ let compile_matching ~scopes repr handler_fun arg pat_act_list partial = assert (Jumps.is_empty total); lambda -let partial_function ~scopes loc () = - let sloc = of_location ~scopes loc in - let slot = - transl_extension_path sloc Env.initial_safe_string Predef.path_match_failure - in - let fname, line, char = - Location.get_pos_info loc.Location.loc_start in - Lprim - ( Praise Raise_regular, - [ Lprim - ( Pmakeblock (0, Immutable, None), - [ slot; - Lconst - (Const_block - ( 0, - [ Const_base (Const_string (fname, loc, None)); - Const_base (Const_int line); - Const_base (Const_int char) - ] )) - ], - sloc ) - ], - sloc ) - let for_function ~scopes loc repr param pat_act_list partial = - let f () = partial_function ~scopes loc () in - compile_matching ~scopes repr f param pat_act_list partial + compile_matching ~scopes loc ~failer:Raise_match_failure + repr param pat_act_list partial (* In the following two cases, exhaustiveness info is not available! *) -let for_trywith ~scopes param pat_act_list = - compile_matching ~scopes None - (fun () -> Lprim (Praise Raise_reraise, [ param ], Loc_unknown)) - param pat_act_list Partial +let for_trywith ~scopes loc param pat_act_list = + (* Note: the failure action of [for_trywith] corresponds + to an exception that is not matched by a try..with handler, + and is thus reraised for the next handler in the stack. + + It is important to *not* include location information in + the reraise (hence the [_noloc]) to avoid seeing this + silent reraise in exception backtraces. *) + compile_matching ~scopes loc ~failer:(Reraise_noloc param) + None param pat_act_list Partial let simple_for_let ~scopes loc param pat body = - compile_matching ~scopes None (partial_function ~scopes loc) - param [ (pat, body) ] Partial + compile_matching ~scopes loc ~failer:Raise_match_failure + None param [ (pat, body) ] Partial (* Optimize binding of immediate tuples @@ -3646,11 +3580,11 @@ let for_let ~scopes loc param pat body = let for_tupled_function ~scopes loc paraml pats_act_list partial = let partial = check_partial_list pats_act_list partial in let raise_num = next_raise_count () in - let omegas = [ List.map (fun _ -> omega) paraml ] in + let omega_params = [ Patterns.omega_list paraml ] in let pm = { cases = pats_act_list; args = List.map (fun id -> (Lvar id, Strict)) paraml; - default = Default_environment.(cons omegas raise_num empty) + default = Default_environment.(cons omega_params raise_num empty) } in try @@ -3658,20 +3592,43 @@ let for_tupled_function ~scopes loc paraml pats_act_list partial = compile_match ~scopes None partial (Context.start (List.length paraml)) pm in - check_total total lambda raise_num (partial_function ~scopes loc) - with Unused -> partial_function ~scopes loc () + check_total ~scopes loc ~failer:Raise_match_failure + total lambda raise_num + with Unused -> + failure_handler ~scopes loc ~failer:Raise_match_failure () let flatten_pattern size p = match p.pat_desc with | Tpat_tuple args -> args - | Tpat_any -> omegas size + | Tpat_any -> Patterns.omegas size | _ -> raise Cannot_flatten +let flatten_simple_pattern size (p : Simple.pattern) = + match p.pat_desc with + | `Tuple args -> args + | `Any -> Patterns.omegas size + | `Array _ + | `Variant _ + | `Record _ + | `Lazy _ + | `Construct _ + | `Constant _ -> + (* All calls to this function originate from [do_for_multiple_match], + where we know that the scrutinee is a tuple literal. + + Since the PM is well typed, none of these cases are possible. *) + let msg = + Format.fprintf Format.str_formatter + "Matching.flatten_pattern: got '%a'" top_pretty (General.erase p); + Format.flush_str_formatter () + in + fatal_error msg + let flatten_cases size cases = List.map (function | (p, []), action -> ( - match flatten_pattern size (General.erase p) with + match flatten_simple_pattern size p with | p :: ps -> ((p, ps), action) | [] -> assert false ) @@ -3689,7 +3646,7 @@ let flatten_handler size handler = type pm_flattened = | FPmOr of pattern pm_or_compiled - | FPm of pattern Non_empty_clause.t pattern_matching + | FPm of pattern Non_empty_row.t clause pattern_matching let flatten_precompiled size args pmh = match pmh with @@ -3722,10 +3679,12 @@ let do_for_multiple_match ~scopes loc paraml pat_act_list partial = match partial with | Partial -> let raise_num = next_raise_count () in - (raise_num, Default_environment.(cons [ [ omega ] ] raise_num empty)) + ( raise_num, + Default_environment.(cons [ [ Patterns.omega ] ] raise_num empty) + ) | Total -> (-1, Default_environment.empty) in - let loc = of_location ~scopes loc in + let loc = Scoped_location.of_location ~scopes loc in let arg = Lprim (Pmakeblock (0, Immutable, None), paraml, loc) in ( raise_num, arg, @@ -3735,40 +3694,41 @@ let do_for_multiple_match ~scopes loc paraml pat_act_list partial = } ) in try - try - (* Once for checking that compilation is possible *) - let next, nexts = - split_and_precompile ~arg_id:None ~arg_lambda:arg pm1 - in - let size = List.length paraml - and idl = List.map (fun _ -> Ident.create_local "*match*") paraml in - let args = List.map (fun id -> (Lvar id, Alias)) idl in - let flat_next = flatten_precompiled size args next - and flat_nexts = - List.map (fun (e, pm) -> (e, flatten_precompiled size args pm)) nexts - in - let lam, total = - comp_match_handlers (compile_flattened ~scopes repr) partial - (Context.start size) flat_next flat_nexts - in - List.fold_right2 (bind Strict) idl paraml - ( match partial with + match split_and_precompile ~arg_id:None ~arg_lambda:arg pm1 with + | exception Cannot_flatten -> + (* One pattern binds the whole tuple, flattening is not possible. + We need to allocate the scrutinee. *) + let lambda, total = + compile_match ~scopes None partial (Context.start 1) pm1 in + begin match partial with | Partial -> - check_total total lam raise_num (partial_function ~scopes loc) + check_total ~scopes loc ~failer:Raise_match_failure + total lambda raise_num | Total -> assert (Jumps.is_empty total); - lam - ) - with Cannot_flatten -> ( - let lambda, total = - compile_match ~scopes None partial (Context.start 1) pm1 in - match partial with - | Partial -> - check_total total lambda raise_num (partial_function ~scopes loc) - | Total -> - assert (Jumps.is_empty total); - lambda - ) + lambda + end + | next, nexts -> + let size = List.length paraml + and idl = List.map (fun _ -> Ident.create_local "*match*") paraml in + let args = List.map (fun id -> (Lvar id, Alias)) idl in + let flat_next = flatten_precompiled size args next + and flat_nexts = + List.map (fun (e, pm) -> (e, flatten_precompiled size args pm)) nexts + in + let lam, total = + comp_match_handlers (compile_flattened ~scopes repr) partial + (Context.start size) flat_next flat_nexts + in + List.fold_right2 (bind Strict) idl paraml + ( match partial with + | Partial -> + check_total ~scopes loc ~failer:Raise_match_failure + total lam raise_num + | Total -> + assert (Jumps.is_empty total); + lam + ) with Unused -> assert false (* ; partial_function loc () *) diff --git a/lambda/matching.mli b/lambda/matching.mli index 7b41a713..3178fe2f 100644 --- a/lambda/matching.mli +++ b/lambda/matching.mli @@ -25,7 +25,7 @@ val for_function: int ref option -> lambda -> (pattern * lambda) list -> partial -> lambda val for_trywith: - scopes:scopes -> + scopes:scopes -> Location.t -> lambda -> (pattern * lambda) list -> lambda val for_let: diff --git a/lambda/printlambda.ml b/lambda/printlambda.ml index 87340608..e73af87f 100644 --- a/lambda/printlambda.ml +++ b/lambda/printlambda.ml @@ -29,7 +29,6 @@ let rec struct_const ppf = function | Const_base(Const_int32 n) -> fprintf ppf "%lil" n | Const_base(Const_int64 n) -> fprintf ppf "%LiL" n | Const_base(Const_nativeint n) -> fprintf ppf "%nin" n - | Const_pointer n -> fprintf ppf "%ia" n | Const_block(tag, []) -> fprintf ppf "[%i]" tag | Const_block(tag, sc1::scl) -> @@ -474,9 +473,12 @@ let function_attribute ppf { inline; specialise; local; is_a_functor; stub } = | Never_local -> fprintf ppf "never_local@ " end -let apply_tailcall_attribute ppf tailcall = - if tailcall then - fprintf ppf " @@tailcall" +let apply_tailcall_attribute ppf = function + | Default_tailcall -> () + | Tailcall_expectation true -> + fprintf ppf " tailcall" + | Tailcall_expectation false -> + fprintf ppf " tailcall(false)" let apply_inlined_attribute ppf = function | Default_inline -> () @@ -499,7 +501,7 @@ let rec lam ppf = function let lams ppf largs = List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in fprintf ppf "@[<2>(apply@ %a%a%a%a%a)@]" lam ap.ap_func lams ap.ap_args - apply_tailcall_attribute ap.ap_should_be_tailcall + apply_tailcall_attribute ap.ap_tailcall apply_inlined_attribute ap.ap_inlined apply_specialised_attribute ap.ap_specialised | Lfunction{kind; params; return; body; attr} -> diff --git a/lambda/simplif.ml b/lambda/simplif.ml index b8a3415b..dfb556f3 100644 --- a/lambda/simplif.ml +++ b/lambda/simplif.ml @@ -219,23 +219,28 @@ let simplify_exits lam = | Prevapply, [x; Lapply ap] | Prevapply, [x; Levent (Lapply ap,_)] -> Lapply {ap with ap_args = ap.ap_args @ [x]; ap_loc = loc} - | Prevapply, [x; f] -> Lapply {ap_should_be_tailcall=false; - ap_loc=loc; - ap_func=f; - ap_args=[x]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise} - + | Prevapply, [x; f] -> + Lapply { + ap_loc=loc; + ap_func=f; + ap_args=[x]; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + } (* Simplify %apply, for n-ary functions with n > 1 *) | Pdirapply, [Lapply ap; x] | Pdirapply, [Levent (Lapply ap,_); x] -> Lapply {ap with ap_args = ap.ap_args @ [x]; ap_loc = loc} - | Pdirapply, [f; x] -> Lapply {ap_should_be_tailcall=false; - ap_loc=loc; - ap_func=f; - ap_args=[x]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise} + | Pdirapply, [f; x] -> + Lapply { + ap_loc=loc; + ap_func=f; + ap_args=[x]; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + } (* Simplify %identity *) | Pidentity, [e] -> e @@ -515,7 +520,8 @@ let simplify_lets lam = | Lfunction{kind; params; return=return1; body = l; attr; loc} -> begin match simplif l with Lfunction{kind=Curried; params=params'; return=return2; body; attr; loc} - when kind = Curried && optimize -> + when kind = Curried && optimize && + List.length params + List.length params' <= Lambda.max_arity() -> (* The return type is the type of the value returned after applying all the parameters to the function. The return type of the merged function taking [params @ params'] as @@ -597,19 +603,28 @@ let simplify_lets lam = (* Tail call info in annotation files *) -let is_tail_native_heuristic : (int -> bool) ref = - ref (fun _ -> true) - let rec emit_tail_infos is_tail lambda = match lambda with | Lvar _ -> () | Lconst _ -> () | Lapply ap -> - if ap.ap_should_be_tailcall - && not is_tail - && Warnings.is_active Warnings.Expect_tailcall - then Location.prerr_warning (to_location ap.ap_loc) - Warnings.Expect_tailcall; + begin + (* Note: is_tail does not take backend-specific logic into + account (maximum number of parameters, etc.) so it may + over-approximate tail-callness. + + Trying to do something more fine-grained would result in + different warnings depending on whether the native or + bytecode compiler is used. *) + let maybe_warn ~is_tail ~expect_tail = + if is_tail <> expect_tail then + Location.prerr_warning (to_location ap.ap_loc) + (Warnings.Wrong_tailcall_expectation expect_tail) in + match ap.ap_tailcall with + | Default_tailcall -> () + | Tailcall_expectation expect_tail -> + maybe_warn ~is_tail ~expect_tail + end; emit_tail_infos false ap.ap_func; list_emit_tail_infos false ap.ap_args | Lfunction {body = lam} -> @@ -709,7 +724,7 @@ let split_default_wrapper ~id:fun_id ~kind ~params ~return ~body ~attr ~loc = ap_func = Lvar inner_id; ap_args = args; ap_loc = Loc_unknown; - ap_should_be_tailcall = false; + ap_tailcall = Default_tailcall; ap_inlined = Default_inline; ap_specialised = Default_specialise; } @@ -874,6 +889,7 @@ let simplify_lambda lam = |> simplify_exits |> simplify_lets in - if !Clflags.annotations || Warnings.is_active Warnings.Expect_tailcall - then emit_tail_infos true lam; + if !Clflags.annotations + || Warnings.is_active (Warnings.Wrong_tailcall_expectation true) + then emit_tail_infos true lam; lam diff --git a/lambda/simplif.mli b/lambda/simplif.mli index a8011a20..2e5be0ac 100644 --- a/lambda/simplif.mli +++ b/lambda/simplif.mli @@ -38,7 +38,3 @@ val split_default_wrapper -> attr:function_attribute -> loc:Lambda.scoped_location -> (Ident.t * lambda) list - -(* To be filled by asmcomp/selectgen.ml *) -val is_tail_native_heuristic: (int -> bool) ref - (* # arguments -> can tailcall *) diff --git a/lambda/translattribute.ml b/lambda/translattribute.ml index d2d48c84..e88f4111 100644 --- a/lambda/translattribute.ml +++ b/lambda/translattribute.ml @@ -57,16 +57,48 @@ let is_unrolled = function | {txt="inline"|"ocaml.inline"|"inlined"|"ocaml.inlined"} -> false | _ -> assert false -let get_id_payload = +let get_payload get_from_exp = let open Parsetree in function - | PStr [] -> Some "" - | PStr [{pstr_desc = Pstr_eval ({pexp_desc},[])}] -> - begin match pexp_desc with - | Pexp_ident { txt = Longident.Lident id } -> Some id - | _ -> None - end - | _ -> None + | PStr [{pstr_desc = Pstr_eval (exp, [])}] -> get_from_exp exp + | _ -> Result.Error () + +let get_optional_payload get_from_exp = + let open Parsetree in + function + | PStr [] -> Result.Ok None + | other -> Result.map Option.some (get_payload get_from_exp other) + +let get_id_from_exp = + let open Parsetree in + function + | { pexp_desc = Pexp_ident { txt = Longident.Lident id } } -> Result.Ok id + | _ -> Result.Error () + +let get_int_from_exp = + let open Parsetree in + function + | { pexp_desc = Pexp_constant (Pconst_integer(s, None)) } -> + begin match Misc.Int_literal_converter.int s with + | n -> Result.Ok n + | exception (Failure _) -> Result.Error () + end + | _ -> Result.Error () + +let get_construct_from_exp = + let open Parsetree in + function + | { pexp_desc = + Pexp_construct ({ txt = Longident.Lident constr }, None) } -> + Result.Ok constr + | _ -> Result.Error () + +let get_bool_from_exp exp = + Result.bind (get_construct_from_exp exp) + (function + | "true" -> Result.Ok true + | "false" -> Result.Ok false + | _ -> Result.Error ()) let parse_id_payload txt loc ~default ~empty cases payload = let[@local] warn () = @@ -80,10 +112,10 @@ let parse_id_payload txt loc ~default ~empty cases payload = Location.prerr_warning loc (Warnings.Attribute_payload (txt, msg)); default in - match get_id_payload payload with - | Some "" -> empty - | None -> warn () - | Some id -> + match get_optional_payload get_id_from_exp payload with + | Error () -> warn () + | Ok None -> empty + | Ok (Some id) -> match List.assoc_opt id cases with | Some r -> r | None -> warn () @@ -92,27 +124,14 @@ let parse_inline_attribute attr = match attr with | None -> Default_inline | Some {Parsetree.attr_name = {txt;loc} as id; attr_payload = payload} -> - let open Parsetree in if is_unrolled id then begin (* the 'unrolled' attributes must be used as [@unrolled n]. *) let warning txt = Warnings.Attribute_payload (txt, "It must be an integer literal") in - match payload with - | PStr [{pstr_desc = Pstr_eval ({pexp_desc},[])}] -> begin - match pexp_desc with - | Pexp_constant (Pconst_integer(s, None)) -> begin - try - Unroll (Misc.Int_literal_converter.int s) - with Failure _ -> - Location.prerr_warning loc (warning txt); - Default_inline - end - | _ -> - Location.prerr_warning loc (warning txt); - Default_inline - end - | _ -> + match get_payload get_int_from_exp payload with + | Ok n -> Unroll n + | Error () -> Location.prerr_warning loc (warning txt); Default_inline end else @@ -274,18 +293,26 @@ let get_tailcall_attribute e = | {Parsetree.attr_name = {txt=("tailcall"|"ocaml.tailcall")}; _} -> true | _ -> false in - let tailcalls, exp_attributes = + let tailcalls, other_attributes = List.partition is_tailcall_attribute e.exp_attributes in - match tailcalls with - | [] -> false, e - | _ :: r -> - begin match r with - | [] -> () - | {Parsetree.attr_name = {txt;loc}; _} :: _ -> - Location.prerr_warning loc (Warnings.Duplicated_attribute txt) - end; - true, { e with exp_attributes } + let tailcall_attribute = match tailcalls with + | [] -> Default_tailcall + | {Parsetree.attr_name = {txt; loc}; attr_payload = payload} :: r -> + begin match r with + | [] -> () + | {Parsetree.attr_name = {txt;loc}; _} :: _ -> + Location.prerr_warning loc (Warnings.Duplicated_attribute txt) + end; + match get_optional_payload get_bool_from_exp payload with + | Ok (None | Some true) -> Tailcall_expectation true + | Ok (Some false) -> Tailcall_expectation false + | Error () -> + let msg = "Only an optional boolean literal is supported." in + Location.prerr_warning loc (Warnings.Attribute_payload (txt, msg)); + Default_tailcall + in + tailcall_attribute, { e with exp_attributes = other_attributes } let check_attribute e {Parsetree.attr_name = { txt; loc }; _} = match txt with diff --git a/lambda/translattribute.mli b/lambda/translattribute.mli index bf22fd1c..6047ab52 100644 --- a/lambda/translattribute.mli +++ b/lambda/translattribute.mli @@ -67,7 +67,7 @@ val get_and_remove_specialised_attribute val get_tailcall_attribute : Typedtree.expression - -> bool * Typedtree.expression + -> Lambda.tailcall_attribute * Typedtree.expression val add_function_attributes : Lambda.lambda diff --git a/lambda/translclass.ml b/lambda/translclass.ml index 1f39ea10..a4655798 100644 --- a/lambda/translclass.ml +++ b/lambda/translclass.ml @@ -30,7 +30,8 @@ exception Error of Location.t * error let lfunction params body = if params = [] then body else match body with - | Lfunction {kind = Curried; params = params'; body = body'; attr; loc} -> + | Lfunction {kind = Curried; params = params'; body = body'; attr; loc} + when List.length params + List.length params' <= Lambda.max_arity() -> Lfunction {kind = Curried; params = params @ params'; return = Pgenval; body = body'; attr; @@ -49,12 +50,14 @@ let lapply ap = Lapply ap let mkappl (func, args) = - Lapply {ap_should_be_tailcall=false; - ap_loc=Loc_unknown; - ap_func=func; - ap_args=args; - ap_inlined=Default_inline; - ap_specialised=Default_specialise};; + Lapply { + ap_loc=Loc_unknown; + ap_func=func; + ap_args=args; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + };; let lsequence l1 l2 = if l2 = lambda_unit then l1 else Lsequence(l1, l2) @@ -64,7 +67,7 @@ let lfield v i = Lprim(Pfield i, [Lvar v], Loc_unknown) let transl_label l = share (Const_immstring l) let transl_meth_list lst = - if lst = [] then Lconst (Const_pointer 0) else + if lst = [] then Lconst (const_int 0) else share (Const_block (0, List.map (fun lab -> Const_immstring lab) lst)) @@ -379,7 +382,7 @@ let rec build_class_init ~scopes cla cstr super inh_init cl_init msubst top cl = Llet (Strict, Pgenval, inh, mkappl(oo_prim "inherits", narrow_args @ [path_lam; - Lconst(Const_pointer(if top then 1 else 0))]), + Lconst(const_int (if top then 1 else 0))]), Llet(StrictOpt, Pgenval, obj_init, lfield inh 0, cl_init))) | _ -> let core cl_init = @@ -487,12 +490,14 @@ let transl_class_rebind ~scopes cl vf = let obj_init = Ident.create_local "obj_init" and self = Ident.create_local "self" in let obj_init0 = - lapply {ap_should_be_tailcall=false; - ap_loc=Loc_unknown; - ap_func=Lvar obj_init; - ap_args=[Lvar self]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise} + lapply { + ap_loc=Loc_unknown; + ap_func=Lvar obj_init; + ap_args=[Lvar self]; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + } in let _, path_lam, obj_init' = transl_class_rebind_0 ~scopes self obj_init0 cl vf in @@ -547,7 +552,7 @@ let rec builtin_meths self env env2 body = | Lprim(Parrayrefu _, [Lvar s; Lvar n], _) when List.mem s self -> "var", [Lvar n] | Lprim(Pfield n, [Lvar e], _) when Ident.same e env -> - "env", [Lvar env2; Lconst(Const_pointer n)] + "env", [Lvar env2; Lconst(const_int n)] | Lsend(Self, met, Lvar s, [], _) when List.mem s self -> "meth", [met] | _ -> raise Not_found @@ -618,7 +623,7 @@ module M = struct | "send_env" -> SendEnv | "send_meth" -> SendMeth | _ -> assert false - in Lconst(Const_pointer(Obj.magic tag)) :: args + in Lconst(const_int (Obj.magic tag)) :: args end open M diff --git a/lambda/translcore.ml b/lambda/translcore.ml index a1697666..653f12ce 100644 --- a/lambda/translcore.ml +++ b/lambda/translcore.ml @@ -64,7 +64,7 @@ let transl_extension_constructor ~scopes env path ext = Text_decl _ -> Lprim (Pmakeblock (Obj.object_tag, Immutable, None), [Lconst (Const_base (Const_string (name, ext.ext_loc, None))); - Lprim (prim_fresh_oo_id, [Lconst (Const_base (Const_int 0))], loc)], + Lprim (prim_fresh_oo_id, [Lconst (const_int 0)], loc)], loc) | Text_rebind(path, _lid) -> transl_extension_path loc env path @@ -270,7 +270,7 @@ and transl_exp0 ~in_new_scope ~scopes e = in if extra_args = [] then lam else begin - let should_be_tailcall, funct = + let tailcall, funct = Translattribute.get_tailcall_attribute funct in let inlined, funct = @@ -281,11 +281,11 @@ and transl_exp0 ~in_new_scope ~scopes e = in let e = { e with exp_desc = Texp_apply(funct, oargs) } in event_after ~scopes e - (transl_apply ~scopes ~should_be_tailcall ~inlined ~specialised + (transl_apply ~scopes ~tailcall ~inlined ~specialised lam extra_args (of_location ~scopes e.exp_loc)) end | Texp_apply(funct, oargs) -> - let should_be_tailcall, funct = + let tailcall, funct = Translattribute.get_tailcall_attribute funct in let inlined, funct = @@ -296,14 +296,14 @@ and transl_exp0 ~in_new_scope ~scopes e = in let e = { e with exp_desc = Texp_apply(funct, oargs) } in event_after ~scopes e - (transl_apply ~scopes ~should_be_tailcall ~inlined ~specialised + (transl_apply ~scopes ~tailcall ~inlined ~specialised (transl_exp ~scopes funct) oargs (of_location ~scopes e.exp_loc)) | Texp_match(arg, pat_expr_list, partial) -> transl_match ~scopes e arg pat_expr_list partial | Texp_try(body, pat_expr_list) -> let id = Typecore.name_cases "exn" pat_expr_list in Ltrywith(transl_exp ~scopes body, id, - Matching.for_trywith ~scopes (Lvar id) + Matching.for_trywith ~scopes e.exp_loc (Lvar id) (transl_cases_try ~scopes pat_expr_list)) | Texp_tuple el -> let ll, shape = transl_list_with_shape ~scopes el in @@ -320,7 +320,7 @@ and transl_exp0 ~in_new_scope ~scopes e = | _ -> assert false end else begin match cstr.cstr_tag with Cstr_constant n -> - Lconst(Const_pointer n) + Lconst(const_int n) | Cstr_unboxed -> (match ll with [v] -> v | _ -> assert false) | Cstr_block n -> @@ -343,15 +343,15 @@ and transl_exp0 ~in_new_scope ~scopes e = | Texp_variant(l, arg) -> let tag = Btype.hash_variant l in begin match arg with - None -> Lconst(Const_pointer tag) + None -> Lconst(const_int tag) | Some arg -> let lam = transl_exp ~scopes arg in try - Lconst(Const_block(0, [Const_base(Const_int tag); + Lconst(Const_block(0, [const_int tag; extract_constant lam])) with Not_constant -> Lprim(Pmakeblock(0, Immutable, None), - [Lconst(Const_base(Const_int tag)); lam], + [Lconst(const_int tag); lam], of_location ~scopes e.exp_loc) end | Texp_record {fields; representation; extended_expression} -> @@ -465,13 +465,15 @@ and transl_exp0 ~in_new_scope ~scopes e = event_after ~scopes e lam | Texp_new (cl, {Location.loc=loc}, _) -> let loc = of_location ~scopes loc in - Lapply{ap_should_be_tailcall=false; - ap_loc=loc; - ap_func= - Lprim(Pfield 0, [transl_class_path loc e.exp_env cl], loc); - ap_args=[lambda_unit]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise} + Lapply{ + ap_loc=loc; + ap_func= + Lprim(Pfield 0, [transl_class_path loc e.exp_env cl], loc); + ap_args=[lambda_unit]; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + } | Texp_instvar(path_self, path, _) -> let loc = of_location ~scopes e.exp_loc in let self = transl_value_path loc e.exp_env path_self in @@ -487,12 +489,14 @@ and transl_exp0 ~in_new_scope ~scopes e = let self = transl_value_path loc e.exp_env path_self in let cpy = Ident.create_local "copy" in Llet(Strict, Pgenval, cpy, - Lapply{ap_should_be_tailcall=false; - ap_loc=Loc_unknown; - ap_func=Translobj.oo_prim "copy"; - ap_args=[self]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise}, + Lapply{ + ap_loc=Loc_unknown; + ap_func=Translobj.oo_prim "copy"; + ap_args=[self]; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + }, List.fold_right (fun (path, _, expr) rem -> let var = transl_value_path loc e.exp_env path in @@ -659,8 +663,12 @@ and transl_tupled_cases ~scopes patl_expr_list = List.map (fun (patl, guard, expr) -> (patl, transl_guard ~scopes guard expr)) patl_expr_list -and transl_apply ~scopes ?(should_be_tailcall=false) ?(inlined = Default_inline) - ?(specialised = Default_specialise) lam sargs loc = +and transl_apply ~scopes + ?(tailcall=Default_tailcall) + ?(inlined = Default_inline) + ?(specialised = Default_specialise) + lam sargs loc + = let lapply funct args = match funct with Lsend(k, lmet, lobj, largs, _) -> @@ -670,12 +678,14 @@ and transl_apply ~scopes ?(should_be_tailcall=false) ?(inlined = Default_inline) | Lapply ap -> Lapply {ap with ap_args = ap.ap_args @ args; ap_loc = loc} | lexp -> - Lapply {ap_should_be_tailcall=should_be_tailcall; - ap_loc=loc; - ap_func=lexp; - ap_args=args; - ap_inlined=inlined; - ap_specialised=specialised;} + Lapply { + ap_loc=loc; + ap_func=lexp; + ap_args=args; + ap_tailcall=tailcall; + ap_inlined=inlined; + ap_specialised=specialised; + } in let rec build_apply lam args = function (None, optional) :: l -> @@ -734,23 +744,53 @@ and transl_apply ~scopes ?(should_be_tailcall=false) ?(inlined = Default_inline) sargs) : Lambda.lambda) -and transl_function0 - ~scopes loc return untuplify_fn repr partial (param:Ident.t) cases = +and transl_curried_function + ~scopes loc return + repr partial (param:Ident.t) cases = + let max_arity = Lambda.max_arity () in + let rec loop ~scopes loc return ~arity partial (param:Ident.t) cases = + match cases with + [{c_lhs=pat; c_guard=None; + c_rhs={exp_desc = + Texp_function + { arg_label = _; param = param'; cases = cases'; + partial = partial'; }; exp_env; exp_type;exp_loc}}] + when arity < max_arity -> + if Parmatch.inactive ~partial pat + then + let kind = value_kind pat.pat_env pat.pat_type in + let return_kind = function_return_value_kind exp_env exp_type in + let ((_, params, return), body) = + loop ~scopes exp_loc return_kind ~arity:(arity + 1) + partial' param' cases' + in + ((Curried, (param, kind) :: params, return), + Matching.for_function ~scopes loc None (Lvar param) + [pat, body] partial) + else begin + begin match partial with + | Total -> + Location.prerr_warning pat.pat_loc + Match_on_mutable_state_prevent_uncurry + | Partial -> () + end; + transl_tupled_function ~scopes ~arity + loc return repr partial param cases + end + | cases -> + transl_tupled_function ~scopes ~arity + loc return repr partial param cases + in + loop ~scopes loc return ~arity:1 partial param cases + +and transl_tupled_function + ~scopes ~arity loc return + repr partial (param:Ident.t) cases = match cases with - [{c_lhs=pat; c_guard=None; - c_rhs={exp_desc = Texp_function { arg_label = _; param = param'; cases; - partial = partial'; }; exp_env; exp_type} as exp}] - when Parmatch.inactive ~partial pat -> - let kind = value_kind pat.pat_env pat.pat_type in - let return_kind = function_return_value_kind exp_env exp_type in - let ((_, params, return), body) = - transl_function0 ~scopes exp.exp_loc return_kind false - repr partial' param' cases - in - ((Curried, (param, kind) :: params, return), - Matching.for_function ~scopes loc None (Lvar param) - [pat, body] partial) - | {c_lhs={pat_desc = Tpat_tuple pl}} :: _ when untuplify_fn -> + | {c_lhs={pat_desc = Tpat_tuple pl}} :: _ + when !Clflags.native_code + && arity = 1 + && List.length pl <= (Lambda.max_arity ()) -> begin try let size = List.length pl in let pats_expr_list = @@ -782,28 +822,30 @@ and transl_function0 ((Tupled, tparams, return), Matching.for_tupled_function ~scopes loc params (transl_tupled_cases ~scopes pats_expr_list) partial) - with Matching.Cannot_flatten -> - ((Curried, [param, Pgenval], return), - Matching.for_function ~scopes loc repr (Lvar param) - (transl_cases ~scopes cases) partial) + with Matching.Cannot_flatten -> + transl_function0 ~scopes loc return repr partial param cases end - | {c_lhs=pat} :: other_cases -> - let kind = + | _ -> transl_function0 ~scopes loc return repr partial param cases + +and transl_function0 + ~scopes loc return + repr partial (param:Ident.t) cases = + let kind = + match cases with + | [] -> + (* With Camlp4, a pattern matching might be empty *) + Pgenval + | {c_lhs=pat} :: other_cases -> (* All the patterns might not share the same types. We must take the union of the patterns types *) List.fold_left (fun k {c_lhs=pat} -> - Typeopt.value_kind_union k - (value_kind pat.pat_env pat.pat_type)) + Typeopt.value_kind_union k + (value_kind pat.pat_env pat.pat_type)) (value_kind pat.pat_env pat.pat_type) other_cases - in - ((Curried, [param, kind], return), - Matching.for_function ~scopes loc repr (Lvar param) - (transl_cases ~scopes cases) partial) - | [] -> - (* With Camlp4, a pattern matching might be empty *) - ((Curried, [param, Pgenval], return), - Matching.for_function ~scopes loc repr (Lvar param) - (transl_cases ~scopes cases) partial) + in + ((Curried, [param, kind], return), + Matching.for_function ~scopes loc repr (Lvar param) + (transl_cases ~scopes cases) partial) and transl_function ~scopes e param cases partial = let ((kind, params, return), body) = @@ -811,7 +853,7 @@ and transl_function ~scopes e param cases partial = (function repr -> let pl = push_defaults e.exp_loc [] cases partial in let return_kind = function_return_value_kind e.exp_env e.exp_type in - transl_function0 ~scopes e.exp_loc return_kind !Clflags.native_code + transl_curried_function ~scopes e.exp_loc return_kind repr partial param pl) in let attr = default_function_attribute in @@ -1026,7 +1068,7 @@ and transl_match ~scopes e arg pat_expr_list partial = let static_exception_id = next_raise_count () in Lstaticcatch (Ltrywith (Lstaticraise (static_exception_id, body), id, - Matching.for_trywith ~scopes (Lvar id) exn_cases), + Matching.for_trywith ~scopes e.exp_loc (Lvar id) exn_cases), (static_exception_id, val_ids), handler) in @@ -1077,12 +1119,14 @@ and transl_letop ~scopes loc env let_ ands param case partial = let exp = transl_exp ~scopes and_.bop_exp in let lam = bind Strict right_id exp - (Lapply{ap_should_be_tailcall = false; - ap_loc = of_location ~scopes and_.bop_loc; - ap_func = op; - ap_args=[Lvar left_id; Lvar right_id]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise}) + (Lapply{ + ap_loc = of_location ~scopes and_.bop_loc; + ap_func = op; + ap_args=[Lvar left_id; Lvar right_id]; + ap_tailcall = Default_tailcall; + ap_inlined = Default_inline; + ap_specialised = Default_specialise; + }) in bind Strict left_id prev_lam (loop lam rest) in @@ -1096,19 +1140,21 @@ and transl_letop ~scopes loc env let_ ands param case partial = let (kind, params, return), body = event_function ~scopes case.c_rhs (function repr -> - transl_function0 ~scopes case.c_rhs.exp_loc return_kind - !Clflags.native_code repr partial param [case]) + transl_curried_function ~scopes case.c_rhs.exp_loc return_kind + repr partial param [case]) in let attr = default_function_attribute in let loc = of_location ~scopes case.c_rhs.exp_loc in Lfunction{kind; params; return; body; attr; loc} in - Lapply{ap_should_be_tailcall = false; - ap_loc = of_location ~scopes loc; - ap_func = op; - ap_args=[exp; func]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise} + Lapply{ + ap_loc = of_location ~scopes loc; + ap_func = op; + ap_args=[exp; func]; + ap_tailcall = Default_tailcall; + ap_inlined = Default_inline; + ap_specialised = Default_specialise; + } (* Wrapper for class compilation *) diff --git a/lambda/translcore.mli b/lambda/translcore.mli index 61b1a1d2..dce2d275 100644 --- a/lambda/translcore.mli +++ b/lambda/translcore.mli @@ -25,7 +25,7 @@ val pure_module : module_expr -> let_kind val transl_exp: scopes:scopes -> expression -> lambda val transl_apply: scopes:scopes - -> ?should_be_tailcall:bool + -> ?tailcall:tailcall_attribute -> ?inlined:inline_attribute -> ?specialised:specialise_attribute -> lambda -> (arg_label * expression option) list diff --git a/lambda/translmod.ml b/lambda/translmod.ml index e578ee7e..e1521aa3 100644 --- a/lambda/translmod.ml +++ b/lambda/translmod.ml @@ -126,12 +126,14 @@ and apply_coercion_result loc strict funct params args cc_res = loc = loc; body = apply_coercion loc Strict cc_res - (Lapply{ap_should_be_tailcall=false; - ap_loc=loc; - ap_func=Lvar id; - ap_args=List.rev args; - ap_inlined=Default_inline; - ap_specialised=Default_specialise})}) + (Lapply{ + ap_loc=loc; + ap_func=Lvar id; + ap_args=List.rev args; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + })}) and wrap_id_pos_list loc id_pos_list get_field lam = let fv = free_variables lam in @@ -217,8 +219,8 @@ let undefined_location loc = let (fname, line, char) = Location.get_pos_info loc.Location.loc_start in Lconst(Const_block(0, [Const_base(Const_string (fname, loc, None)); - Const_base(Const_int line); - Const_base(Const_int char)])) + const_int line; + const_int char])) exception Initialization_failure of unsafe_info @@ -242,9 +244,9 @@ let init_shape id modl = let init_v = match Ctype.expand_head env ty with {desc = Tarrow(_,_,_,_)} -> - Const_pointer 0 (* camlinternalMod.Function *) + const_int 0 (* camlinternalMod.Function *) | {desc = Tconstr(p, _, _)} when Path.same p Predef.path_lazy_t -> - Const_pointer 1 (* camlinternalMod.Lazy *) + const_int 1 (* camlinternalMod.Lazy *) | _ -> let not_a_function = Unsafe {reason=Unsafe_non_function; loc; subid } @@ -270,7 +272,7 @@ let init_shape id modl = | Sig_modtype(id, minfo, _) :: rem -> init_shape_struct (Env.add_modtype id minfo env) rem | Sig_class _ :: rem -> - Const_pointer 2 (* camlinternalMod.Class *) + const_int 2 (* camlinternalMod.Class *) :: init_shape_struct env rem | Sig_class_type _ :: rem -> init_shape_struct env rem @@ -358,12 +360,14 @@ let eval_rec_bindings bindings cont = bind_inits rem | (Id id, Some(loc, shape), _rhs) :: rem -> Llet(Strict, Pgenval, id, - Lapply{ap_should_be_tailcall=false; - ap_loc=Loc_unknown; - ap_func=mod_prim "init_mod"; - ap_args=[loc; shape]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise}, + Lapply{ + ap_loc=Loc_unknown; + ap_func=mod_prim "init_mod"; + ap_args=[loc; shape]; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + }, bind_inits rem) and bind_strict = function [] -> @@ -381,13 +385,16 @@ let eval_rec_bindings bindings cont = | (_, None, _rhs) :: rem -> patch_forwards rem | (Id id, Some(_loc, shape), rhs) :: rem -> - Lsequence(Lapply{ap_should_be_tailcall=false; - ap_loc=Loc_unknown; - ap_func=mod_prim "update_mod"; - ap_args=[shape; Lvar id; rhs]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise}, - patch_forwards rem) + Lsequence( + Lapply { + ap_loc=Loc_unknown; + ap_func=mod_prim "update_mod"; + ap_args=[shape; Lvar id; rhs]; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + }, + patch_forwards rem) in bind_inits bindings @@ -512,12 +519,13 @@ and transl_module ~scopes cc rootpath mexp = in oo_wrap mexp.mod_env true (apply_coercion loc Strict cc) - (Lapply{ap_should_be_tailcall=false; - ap_loc=loc; - ap_func=transl_module ~scopes Tcoerce_none None funct; - ap_args=[transl_module ~scopes ccarg None arg]; - ap_inlined=inlined_attribute; - ap_specialised=Default_specialise}) + (Lapply{ + ap_loc=loc; + ap_func=transl_module ~scopes Tcoerce_none None funct; + ap_args=[transl_module ~scopes ccarg None arg]; + ap_tailcall=Default_tailcall; + ap_inlined=inlined_attribute; + ap_specialised=Default_specialise}) | Tmod_constraint(arg, _, _, ccarg) -> transl_module ~scopes (compose_coercions cc ccarg) rootpath arg | Tmod_unpack(arg, _) -> @@ -658,7 +666,11 @@ and transl_structure ~scopes loc fields cc rootpath final_env = function in Llet(pure_module mb.mb_expr, Pgenval, id, module_body, body), size end - | Tstr_module {mb_presence=Mp_absent} -> + | Tstr_module ({mb_presence=Mp_absent} as mb) -> + List.iter (Translattribute.check_attribute_on_module mb.mb_expr) + mb.mb_attributes; + List.iter (Translattribute.check_attribute_on_module mb.mb_expr) + mb.mb_expr.mod_attributes; transl_structure ~scopes loc fields cc rootpath final_env rem | Tstr_recmodule bindings -> let ext_fields = @@ -794,7 +806,7 @@ let transl_implementation_flambda module_name (str, cc) = primitive_declarations := []; Translprim.clear_used_primitives (); let module_id = Ident.create_persistent module_name in - let scopes = [Sc_module_definition module_name] in + let scopes = enter_module_definition ~scopes:empty_scopes module_id in let body, size = Translobj.transl_label_init (fun () -> transl_struct ~scopes Loc_unknown [] cc @@ -1112,7 +1124,11 @@ let transl_store_structure ~scopes glob map prims aliases str = transl_store ~scopes rootpath (add_ident true id subst) cont rem)) - | Tstr_module {mb_presence=Mp_absent} -> + | Tstr_module ({mb_presence=Mp_absent} as mb) -> + List.iter (Translattribute.check_attribute_on_module mb.mb_expr) + mb.mb_attributes; + List.iter (Translattribute.check_attribute_on_module mb.mb_expr) + mb.mb_expr.mod_attributes; transl_store ~scopes rootpath subst cont rem | Tstr_recmodule bindings -> let ids = List.filter_map (fun mb -> mb.mb_id) bindings in @@ -1367,14 +1383,17 @@ let transl_store_gen ~scopes module_name ({ str_items = str }, restr) topl = (*size, transl_label_init (transl_store_structure module_id map prims str)*) let transl_store_phrases module_name str = - let scopes = [Sc_module_definition module_name] in + let scopes = + enter_module_definition ~scopes:empty_scopes + (Ident.create_persistent module_name) + in transl_store_gen ~scopes module_name (str,Tcoerce_none) true let transl_store_implementation module_name (str, restr) = let s = !transl_store_subst in transl_store_subst := Ident.Map.empty; let module_ident = Ident.create_persistent module_name in - let scopes = [Sc_module_definition module_name] in + let scopes = enter_module_definition ~scopes:empty_scopes module_ident in let (i, code) = transl_store_gen ~scopes module_name (str, restr) false in transl_store_subst := s; { Lambda.main_module_block_size = i; @@ -1401,27 +1420,32 @@ let toplevel_name id = with Not_found -> Ident.name id let toploop_getvalue id = - Lapply{ap_should_be_tailcall=false; - ap_loc=Loc_unknown; - ap_func=Lprim(Pfield toploop_getvalue_pos, - [Lprim(Pgetglobal toploop_ident, [], Loc_unknown)], - Loc_unknown); - ap_args=[Lconst(Const_base( - Const_string (toplevel_name id, Location.none,None)))]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise} + Lapply{ + ap_loc=Loc_unknown; + ap_func=Lprim(Pfield toploop_getvalue_pos, + [Lprim(Pgetglobal toploop_ident, [], Loc_unknown)], + Loc_unknown); + ap_args=[Lconst(Const_base( + Const_string (toplevel_name id, Location.none, None)))]; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + } let toploop_setvalue id lam = - Lapply{ap_should_be_tailcall=false; - ap_loc=Loc_unknown; - ap_func=Lprim(Pfield toploop_setvalue_pos, - [Lprim(Pgetglobal toploop_ident, [], Loc_unknown)], - Loc_unknown); - ap_args=[Lconst(Const_base( - Const_string (toplevel_name id, Location.none, None))); - lam]; - ap_inlined=Default_inline; - ap_specialised=Default_specialise} + Lapply{ + ap_loc=Loc_unknown; + ap_func=Lprim(Pfield toploop_setvalue_pos, + [Lprim(Pgetglobal toploop_ident, [], Loc_unknown)], + Loc_unknown); + ap_args= + [Lconst(Const_base( + Const_string(toplevel_name id, Location.none, None))); + lam]; + ap_tailcall=Default_tailcall; + ap_inlined=Default_inline; + ap_specialised=Default_specialise; + } let toploop_setvalue_id id = toploop_setvalue id (Lvar id) @@ -1526,8 +1550,13 @@ let transl_toplevel_item ~scopes item = transl_module ~scopes Tcoerce_none None od.open_expr, set_idents 0 ids) end + | Tstr_module ({mb_presence=Mp_absent} as mb) -> + List.iter (Translattribute.check_attribute_on_module mb.mb_expr) + mb.mb_attributes; + List.iter (Translattribute.check_attribute_on_module mb.mb_expr) + mb.mb_expr.mod_attributes; + lambda_unit | Tstr_modtype _ - | Tstr_module {mb_presence=Mp_absent} | Tstr_type _ | Tstr_class_type _ | Tstr_attribute _ -> @@ -1540,7 +1569,9 @@ let transl_toplevel_item_and_close ~scopes itm = let transl_toplevel_definition str = reset_labels (); Translprim.clear_used_primitives (); - make_sequence (transl_toplevel_item_and_close ~scopes:[]) str.str_items + make_sequence + (transl_toplevel_item_and_close ~scopes:empty_scopes) + str.str_items (* Compile the initialization code for a packed library *) diff --git a/lambda/translprim.ml b/lambda/translprim.ml index f4cb200e..6c9bf92b 100644 --- a/lambda/translprim.ml +++ b/lambda/translprim.ml @@ -75,6 +75,7 @@ type loc_kind = | Loc_MODULE | Loc_LOC | Loc_POS + | Loc_FUNCTION type prim = | Primitive of Lambda.primitive * int @@ -121,6 +122,7 @@ let primitives_table = "%loc_LINE", Loc Loc_LINE; "%loc_POS", Loc Loc_POS; "%loc_MODULE", Loc Loc_MODULE; + "%loc_FUNCTION", Loc Loc_FUNCTION; "%field0", Primitive ((Pfield 0), 1); "%field1", Primitive ((Pfield 1), 1); "%setfield0", Primitive ((Psetfield(0, Pointer, Assignment)), 2); @@ -592,8 +594,8 @@ let comparison_primitive comparison comparison_kind = | Compare, Compare_int32s -> Pcompare_bints Pint32 | Compare, Compare_int64s -> Pcompare_bints Pint64 -let lambda_of_loc kind loc = - let loc = to_location loc in +let lambda_of_loc kind sloc = + let loc = to_location sloc in let loc_start = loc.Location.loc_start in let (file, lnum, cnum) = Location.get_pos_info loc_start in let file = @@ -622,6 +624,9 @@ let lambda_of_loc kind loc = file lnum cnum enum in Lconst (Const_immstring loc) | Loc_LINE -> Lconst (Const_base (Const_int lnum)) + | Loc_FUNCTION -> + let scope_name = Debuginfo.Scoped_location.string_of_scoped_location sloc in + Lconst (Const_immstring scope_name) let caml_restore_raw_backtrace = Primitive.simple ~name:"caml_restore_raw_backtrace" ~arity:2 ~alloc:false @@ -639,7 +644,7 @@ let lambda_of_prim prim_name prim loc args arg_exps = | Primitive (prim, arity), args when arity = List.length args -> Lprim(prim, args, loc) | External prim, args when prim = prim_sys_argv -> - Lprim(Pccall prim, Lconst (Const_pointer 0) :: args, loc) + Lprim(Pccall prim, Lconst (const_int 0) :: args, loc) | External prim, args -> Lprim(Pccall prim, args, loc) | Comparison(comp, knd), ([_;_] as args) -> @@ -674,7 +679,7 @@ let lambda_of_prim prim_name prim loc args arg_exps = loc), Lprim(Praise Raise_reraise, [raise_arg], loc))) | Lazy_force, [arg] -> - Matching.inline_lazy_force arg Loc_unknown + Matching.inline_lazy_force arg loc | Loc kind, [] -> lambda_of_loc kind loc | Loc kind, [arg] -> diff --git a/lex/Makefile b/lex/Makefile index 5ee94e66..5f6b1655 100644 --- a/lex/Makefile +++ b/lex/Makefile @@ -17,18 +17,16 @@ ROOTDIR = .. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common +include $(ROOTDIR)/Makefile.common -CAMLYACC ?= $(ROOTDIR)/yacc/ocamlyacc +CAMLYACC ?= $(ROOTDIR)/yacc/ocamlyacc$(EXE) CAMLC = $(BOOT_OCAMLC) -strict-sequence -nostdlib \ -I $(ROOTDIR)/boot -use-prims $(ROOTDIR)/runtime/primitives -CAMLOPT = $(CAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib +CAMLOPT = $(CAMLRUN) $(ROOTDIR)/ocamlopt$(EXE) -nostdlib -I $(ROOTDIR)/stdlib COMPFLAGS = -absname -w +a-4-9-41-42-44-45-48 -warn-error A \ -safe-string -strict-sequence -strict-formats -bin-annot LINKFLAGS = -YACCFLAGS = -v CAMLLEX = $(CAMLRUN) $(ROOTDIR)/boot/ocamllex CAMLDEP = $(BOOT_OCAMLC) -depend DEPFLAGS = -slash @@ -37,23 +35,27 @@ DEPINCLUDES = OBJS=cset.cmo syntax.cmo parser.cmo lexer.cmo table.cmo lexgen.cmo \ compact.cmo common.cmo output.cmo outputbis.cmo main.cmo +programs := ocamllex ocamllex.opt + +$(foreach program, $(programs), $(eval $(call PROGRAM_SYNONYM,$(program)))) + .PHONY: all allopt opt.opt # allopt and opt.opt are synonyms all: ocamllex allopt: ocamllex.opt opt.opt: allopt -ocamllex: $(OBJS) - $(CAMLC) $(LINKFLAGS) -compat-32 -o ocamllex $(OBJS) +ocamllex$(EXE): $(OBJS) + $(CAMLC) $(LINKFLAGS) -compat-32 -o $@ $^ -ocamllex.opt: $(OBJS:.cmo=.cmx) - $(CAMLOPT_CMD) -o ocamllex.opt $(OBJS:.cmo=.cmx) +ocamllex.opt$(EXE): $(OBJS:.cmo=.cmx) + $(CAMLOPT_CMD) -o $@ $^ clean:: - rm -f ocamllex ocamllex.opt + rm -f $(programs) $(programs:=.exe) rm -f *.cmo *.cmi *.cmx *.cmt *.cmti *.o *.obj parser.ml parser.mli: parser.mly - $(CAMLYACC) $(YACCFLAGS) parser.mly + $(CAMLYACC) -v parser.mly clean:: rm -f parser.ml parser.mli parser.output diff --git a/man/ocamlc.m b/man/ocamlc.m index 3f2b387d..b0608d44 100644 --- a/man/ocamlc.m +++ b/man/ocamlc.m @@ -960,6 +960,10 @@ mutually recursive types. 67 \ \ Unused functor parameter. +68 +\ \ Pattern-matching depending on mutable state prevents the remaining +arguments from being uncurried. + The letters stand for the following sets of warnings. Any letter not mentioned here corresponds to the empty set. @@ -1013,7 +1017,7 @@ mentioned here corresponds to the empty set. .IP The default setting is -.BR \-w\ +a\-4\-6\-7\-9\-27\-29\-30\-32..42\-44\-45\-48\-50\-60\-66 . +.BR \-w\ +a\-4\-6\-7\-9\-27\-29\-30\-32..42\-44\-45\-48\-50\-60\-66\-67\-68 . Note that warnings .BR 5 \ and \ 10 are not always triggered, depending on the internals of the type checker. diff --git a/man/ocamlopt.m b/man/ocamlopt.m index b7f6bb81..15400bd9 100644 --- a/man/ocamlopt.m +++ b/man/ocamlopt.m @@ -556,7 +556,14 @@ is saved in the file Stop compilation after the given compilation pass. The currently supported passes are: .BR parsing , -.BR typing . +.BR typing , +.BR scheduling , +.BR emit . +.TP +.BI \-save\-ir\-after \ pass +Save intermediate representation after the given compilation pass. The currently +supported passes are: +.BR scheduling . .TP .B \-safe\-string Enforce the separation between types diff --git a/man/ocamlrun.m b/man/ocamlrun.m index fea7ef8d..ba59d20b 100644 --- a/man/ocamlrun.m +++ b/man/ocamlrun.m @@ -211,7 +211,7 @@ What GC messages to print to stderr. This is a sum of values selected from the following: .B 0x001 -Start of major GC cycle. +Start and end of major GC cycle. .B 0x002 Minor collection and major GC slice. diff --git a/manual/Makefile b/manual/Makefile index 0ccbf188..afd7ea44 100644 --- a/manual/Makefile +++ b/manual/Makefile @@ -18,6 +18,9 @@ manual: tools html: tools $(MAKE) -C manual html +web: tools + $(MAKE) -C manual web + release: $(MAKE) -C manual release @@ -40,3 +43,7 @@ clean: $(MAKE) -C manual clean $(MAKE) -C tools clean $(MAKE) -C tests clean + +.PHONY: distclean +distclean: + $(MAKE) -C manual distclean diff --git a/manual/README.md b/manual/README.md index f6640338..4df8b109 100644 --- a/manual/README.md +++ b/manual/README.md @@ -78,14 +78,11 @@ chapters (or sometimes sections) are mapped to a distinct `.etex` file: - Native-code compilation (ocamlopt): `native.etex` - Lexer and parser generators (ocamllex, ocamlyacc): `lexyacc.etex` - Dependency generator (ocamldep): `ocamldep.etex` - - The browser/editor (ocamlbrowser): `browser.etex` - The documentation generator (ocamldoc): `ocamldoc.etex` - The debugger (ocamldebug): `debugger.etex` - Profiling (ocamlprof): `profil.etex` - - The ocamlbuild compilation manager: `ocamlbuild.etex` - Interfacing C with OCaml: `intf-c.etex` - Optimisation with Flambda: `flambda.etex` - - Memory profiling with Spacetime: `spacetime-chapter.etex` - Fuzzing with afl-fuzz: `afl-fuzz.etex` - Runtime tracing with the instrumented runtime: `instrumented-runtime.etex` @@ -102,14 +99,10 @@ of `unified-options.etex` contains the relevant information. - The standard library: `stdlib-blurb.etex` - The compiler front-end: `compilerlibs.etex` - The unix library: Unix system calls: `libunix.etex` - - The legacy num library: this library has been removed from the core - distribution, see `libnum.etex` - The str library: regular expressions and string processing: `libstr.etex` - The threads library: `libthreads.etex` - - The graphics library: `libgraph.etex` - The dynlink library: dynamic loading and linking of object files: `libdynlink.etex` - - The bigarray library: `libbigarray.etex` Latex extensions ---------------- diff --git a/manual/manual/.gitignore b/manual/manual/.gitignore index 71605a70..04dd6ffc 100644 --- a/manual/manual/.gitignore +++ b/manual/manual/.gitignore @@ -6,3 +6,4 @@ warnings.etex warnings.tex foreword.htex manual.html +webman diff --git a/manual/manual/Makefile b/manual/manual/Makefile index fbee1e02..05622334 100644 --- a/manual/manual/Makefile +++ b/manual/manual/Makefile @@ -54,6 +54,7 @@ html: htmlman/libref/style.css htmlman/compilerlibref/style.css etex-files htmlman/libref/style.css: style.css $(STDLIB_MLIS) $(DOC_STDLIB_TEXT) mkdir -p htmlman/libref $(OCAMLDOC) -colorize-code -sort -html \ + -charset "UTF-8" \ -d htmlman/libref \ $(DOC_STDLIB_INCLUDES) \ $(DOC_STDLIB_TEXT:%=-text %) \ @@ -71,6 +72,7 @@ htmlman/compilerlibref/style.css: library/compiler_libs.txt style.css \ $(COMPILERLIBS_MLIS) mkdir -p htmlman/compilerlibref $(OCAMLDOC) -colorize-code -sort -html \ + -charset "UTF-8" \ -d htmlman/compilerlibref \ -I $(SRC)/stdlib \ $(DOC_COMPILERLIBS_INCLUDES) \ @@ -118,6 +120,8 @@ release: all cp textman/manual.txt $(RELEASE)refman.txt tar cf - infoman/ocaml.info* | gzip > $(RELEASE)refman.info.tar.gz +web: html + $(MAKE) -C html_processing all files: $(FILES) $(MAKE) -C cmds all @@ -147,12 +151,13 @@ warnings-help.etex: $(SRC)/utils/warnings.ml $(SRC)/ocamlc echo "% when a new warning is documented.";\ echo "%";\ $(SET_LD_PATH) $(SRC)/boot/ocamlrun $(SRC)/ocamlc -warn-help \ - | sed -e 's/^ *\([0-9A-Z][0-9]*\)\(.*\)/\\item[\1] \2/'\ + | sed -e 's/^ *\([0-9][0-9]*\) *\[\([a-z][a-z-]*\)\]\(.*\)/\\item[\1 "\2"] \3/' \ + -e 's/^ *\([0-9A-Z][0-9]*\) *\([^]].*\)/\\item[\1] \2/'\ ) >$@ # sed --inplace is not portable, emulate for i in 52 57; do\ sed\ - s'/\\item\['$$i'\]/\\item\['$$i' (see \\ref{ss:warn'$$i'})\]/'\ + s'/\\item\[\('$$i'[^]]*\)\]/\\item\[\1 (see \\ref{ss:warn'$$i'})\]/'\ $@ > $@.tmp;\ mv $@.tmp $@;\ done @@ -165,6 +170,7 @@ clean: $(MAKE) -C library clean $(MAKE) -C refman clean $(MAKE) -C tutorials clean + $(MAKE) -C html_processing clean -rm -f texstuff/* cd htmlman; rm -rf libref compilerlibref index.html \ manual*.html *.haux *.hind *.svg diff --git a/manual/manual/allfiles.etex b/manual/manual/allfiles.etex index 5c8aea8b..990be732 100644 --- a/manual/manual/allfiles.etex +++ b/manual/manual/allfiles.etex @@ -26,7 +26,7 @@ \begin{quote} \rule{}{} This manual is also available in -\ahref{https://ocaml.org/releases/\ocamlversion/ocaml-\ocamlversion-refman.pdf}{PDF}. +\ahref{https://ocaml.org/releases/\ocamlversion/ocaml-\ocamlversion-refman.pdf}{PDF}, \ahref{https://ocaml.org/releases/\ocamlversion/ocaml-\ocamlversion-refman.txt}{plain text}, as a \ahref{https://ocaml.org/releases/\ocamlversion/ocaml-\ocamlversion-refman-html.tar.gz}{bundle of HTML files}, @@ -63,15 +63,11 @@ and as a \input{native.tex} \input{lexyacc.tex} \input{ocamldep.tex} -\input{browser.tex} \input{ocamldoc.tex} \input{debugger.tex} \input{profil.tex} -\input{ocamlbuild.tex} -% \input emacs.tex \input{intf-c.tex} \input{flambda.tex} -\input{spacetime-chapter.tex} \input{afl-fuzz.tex} \input{instrumented-runtime.tex} @@ -81,15 +77,13 @@ and as a \input{stdlib-blurb.tex} \input{compilerlibs.tex} \input{libunix.tex} -\input{libnum.tex} \input{libstr.tex} \input{libthreads.tex} -\input{libgraph.tex} \input{libdynlink.tex} -\input{libbigarray.tex} +\input{old.tex} -\part{Appendix} -\label{p:appendix} +\part{Indexes} +\label{p:indexes} \ifouthtml \begin{links} diff --git a/manual/manual/cmds/Makefile b/manual/manual/cmds/Makefile index b6522128..273835b1 100644 --- a/manual/manual/cmds/Makefile +++ b/manual/manual/cmds/Makefile @@ -11,11 +11,11 @@ TEXQUOTE = $(OCAMLRUN) $(TOOLS)/texquote2 TRANSF = $(SET_LD_PATH) $(OCAMLRUN) $(TOOLS)/transf FILES = comp.tex top.tex runtime.tex native.tex lexyacc.tex intf-c.tex \ - ocamldep.tex profil.tex debugger.tex browser.tex ocamldoc.tex \ - warnings-help.tex ocamlbuild.tex flambda.tex spacetime-chapter.tex \ + ocamldep.tex profil.tex debugger.tex ocamldoc.tex \ + warnings-help.tex flambda.tex \ afl-fuzz.tex instrumented-runtime.tex unified-options.tex -WITH_TRANSF = top.tex intf-c.tex flambda.tex spacetime-chapter.tex \ +WITH_TRANSF = top.tex intf-c.tex flambda.tex \ afl-fuzz.tex lexyacc.tex debugger.tex WITH_CAMLEXAMPLE = instrumented-runtime.tex ocamldoc.tex diff --git a/manual/manual/cmds/browser.etex b/manual/manual/cmds/browser.etex deleted file mode 100644 index 0731e8a4..00000000 --- a/manual/manual/cmds/browser.etex +++ /dev/null @@ -1,6 +0,0 @@ -\chapter{The browser/editor (ocamlbrowser)} \label{c:browser} -%HEVEA\cutname{browser.html} - -Since OCaml version 4.02, the OCamlBrowser tool and the Labltk library -are distributed separately from the OCaml compiler. The project is now -hosted at \url{https://forge.ocamlcore.org/projects/labltk/}. diff --git a/manual/manual/cmds/debugger.etex b/manual/manual/cmds/debugger.etex index d964a250..e43d7f79 100644 --- a/manual/manual/cmds/debugger.etex +++ b/manual/manual/cmds/debugger.etex @@ -650,9 +650,9 @@ Read debugger commands from the script \var{filename}. \section{s:inf-debugger}{Running the debugger under Emacs} -The most user-friendly way to use the debugger is to run it under Emacs. -See the file "emacs/README" in the distribution for information on how -to load the Emacs Lisp files for OCaml support. +The most user-friendly way to use the debugger is to run it under Emacs with +the OCaml mode available through MELPA and also at +\url{https://github.com/ocaml/caml-mode}. The OCaml debugger is started under Emacs by the command "M-x camldebug", with argument the name of the executable file diff --git a/manual/manual/cmds/intf-c.etex b/manual/manual/cmds/intf-c.etex index d7174caa..5c00cfb0 100644 --- a/manual/manual/cmds/intf-c.etex +++ b/manual/manual/cmds/intf-c.etex @@ -23,10 +23,10 @@ User primitives are declared in an implementation file or \end{alltt} This defines the value name \var{name} as a function with type \var{type} that executes by calling the given C function. -For instance, here is how the "int_of_string" primitive is declared in the +For instance, here is how the "seek_in" primitive is declared in the standard library module "Stdlib": \begin{verbatim} - external int_of_string : string -> int = "caml_int_of_string" + external seek_in : in_channel -> int -> unit = "caml_ml_seek_in" \end{verbatim} Primitives with several arguments are always curried. The C function does not necessarily have the same name as the ML function. @@ -51,13 +51,13 @@ modules from libraries at link-time. The arity (number of arguments) of a primitive is automatically determined from its OCaml type in the "external" declaration, by counting the number of function arrows in the type. For instance, -"input" above has arity 4, and the "input" C function is called with -four arguments. Similarly, +"seek_in" above has arity 2, and the "caml_ml_seek_in" C function +is called with two arguments. Similarly, \begin{verbatim} - external input2 : in_channel * bytes * int * int -> int = "input2" + external seek_in_pair: in_channel * int -> unit = "caml_ml_seek_in_pair" \end{verbatim} -has arity 1, and the "input2" C function receives one argument (which -is a quadruple of OCaml values). +has arity 1, and the "caml_ml_seek_in_pair" C function receives one argument +(which is a pair of OCaml values). Type abbreviations are not expanded when determining the arity of a primitive. For instance, @@ -185,7 +185,7 @@ serialization and deserialization functions for custom blocks \entree{"caml/threads.h"}{operations for interfacing in the presence of multiple threads (see section~\ref{s:C-multithreading}).} \end{tableau} -Before including any of these files, you should define the "OCAML_NAME_SPACE" +Before including any of these files, you should define the "CAML_NAME_SPACE" macro. For instance, \begin{verbatim} #define CAML_NAME_SPACE @@ -699,6 +699,9 @@ containing \var{v} and \var{w} in fields 1 and 2. false otherwise \item "Is_block("\var{v}")" is true if value \var{v} is a pointer to a block, and false if it is an immediate integer. +\item "Is_none("\var{v}")" is true if value \var{v} is "None". +\item "Is_some("\var{v}")" is true if value \var{v} (assumed to be of option +type) corresponds to the "Some" constructor. \end{itemize} \subsection{ss:c-int-ops}{Operations on integers} @@ -713,6 +716,7 @@ truth value of the C integer \var{x}. \item "Bool_val("\var{v}")" returns 0 if \var{v} is the OCaml boolean "false", 1 if \var{v} is "true". \item "Val_true", "Val_false" represent the OCaml booleans "true" and "false". +\item "Val_none" represents the OCaml value "None". \end{itemize} \subsection{ss:c-block-access}{Accessing blocks} @@ -768,6 +772,8 @@ of a value \var{v} of any boxed type (record or concrete data type). \item "caml_field_unboxable("\var{v}")" calls either "caml_field_unboxed" or "caml_field_boxed" according to the default representation of unboxable types in the current version of OCaml. +\item "Some_val("\var{v}")" returns the argument "\var{x}" of a value \var{v} of +the form "Some("\var{x}")". \end{itemize} The expressions "Field("\var{v}", "\var{n}")", "Byte("\var{v}", "\var{n}")" and @@ -836,6 +842,8 @@ any boxed type) whose field is the value \var{v}. \item "caml_alloc_unboxable("\var{v}")" calls either "caml_alloc_unboxed" or "caml_alloc_boxed" according to the default representation of unboxable types in the current version of OCaml. +\item "caml_alloc_some("\var{v}")" allocates a block representing +"Some("\var{v}")". \end{itemize} \subsubsection{sss:c-low-level-alloc}{Low-level interface} @@ -975,7 +983,7 @@ variables. Example: \begin{verbatim} -value bar (value v1, value v2, value v3) +CAMLprim value bar (value v1, value v2, value v3) { CAMLparam3 (v1, v2, v3); CAMLlocal1 (result); @@ -998,7 +1006,7 @@ block (i.e. "Is_block("\var{b}")" must be true). Example: \begin{verbatim} -value bar (value v1, value v2, value v3) +CAMLprim value bar (value v1, value v2, value v3) { CAMLparam3 (v1, v2, v3); CAMLlocal1 (result); @@ -1320,62 +1328,62 @@ static value alloc_window(WINDOW * w) return v; } -value caml_curses_initscr(value unit) +CAMLprim value caml_curses_initscr(value unit) { CAMLparam1 (unit); CAMLreturn (alloc_window(initscr())); } -value caml_curses_endwin(value unit) +CAMLprim value caml_curses_endwin(value unit) { CAMLparam1 (unit); endwin(); CAMLreturn (Val_unit); } -value caml_curses_refresh(value unit) +CAMLprim value caml_curses_refresh(value unit) { CAMLparam1 (unit); refresh(); CAMLreturn (Val_unit); } -value caml_curses_wrefresh(value win) +CAMLprim value caml_curses_wrefresh(value win) { CAMLparam1 (win); wrefresh(Window_val(win)); CAMLreturn (Val_unit); } -value caml_curses_newwin(value nlines, value ncols, value x0, value y0) +CAMLprim value caml_curses_newwin(value nlines, value ncols, value x0, value y0) { CAMLparam4 (nlines, ncols, x0, y0); CAMLreturn (alloc_window(newwin(Int_val(nlines), Int_val(ncols), Int_val(x0), Int_val(y0)))); } -value caml_curses_addch(value c) +CAMLprim value caml_curses_addch(value c) { CAMLparam1 (c); addch(Int_val(c)); /* Characters are encoded like integers */ CAMLreturn (Val_unit); } -value caml_curses_mvwaddch(value win, value x, value y, value c) +CAMLprim value caml_curses_mvwaddch(value win, value x, value y, value c) { CAMLparam4 (win, x, y, c); mvwaddch(Window_val(win), Int_val(x), Int_val(y), Int_val(c)); CAMLreturn (Val_unit); } -value caml_curses_addstr(value s) +CAMLprim value caml_curses_addstr(value s) { CAMLparam1 (s); addstr(String_val(s)); CAMLreturn (Val_unit); } -value caml_curses_mvwaddstr(value win, value x, value y, value s) +CAMLprim value caml_curses_mvwaddstr(value win, value x, value y, value s) { CAMLparam4 (win, x, y, s); mvwaddstr(Window_val(win), Int_val(x), Int_val(y), String_val(s)); @@ -1470,7 +1478,7 @@ can crash since \var{v} does not contain a valid value. Example: \begin{verbatim} - value call_caml_f_ex(value closure, value arg) + CAMLprim value call_caml_f_ex(value closure, value arg) { CAMLparam2(closure, arg); CAMLlocal2(res, tmp); @@ -2155,13 +2163,20 @@ The kind of array elements is one of the following constants: \entree{"CAML_BA_NATIVE_INT"}{32- or 64-bit (platform-native) integers} \end{tableau} % +\paragraph{Warning:} +"Caml_ba_array_val("\var{v}")" must always be dereferenced immediately and not stored +anywhere, including local variables. +It resolves to a derived pointer: it is not a valid OCaml value but points to +a memory region managed by the GC. For this reason this value must not be +stored in any memory location that could be live cross a GC. + The following example shows the passing of a two-dimensional Bigarray to a C function and a Fortran function. \begin{verbatim} extern void my_c_function(double * data, int dimx, int dimy); extern void my_fortran_function_(double * data, int * dimx, int * dimy); - value caml_stub(value bigarray) + CAMLprim value caml_stub(value bigarray) { int dimx = Caml_ba_array_val(bigarray)->dim[0]; int dimy = Caml_ba_array_val(bigarray)->dim[1]; @@ -2205,7 +2220,7 @@ Fortran arrays can be made available to OCaml. extern long my_c_array[100][200]; extern float my_fortran_array_[300][400]; - value caml_get_c_array(value unit) + CAMLprim value caml_get_c_array(value unit) { long dims[2]; dims[0] = 100; dims[1] = 200; @@ -2213,7 +2228,7 @@ Fortran arrays can be made available to OCaml. 2, my_c_array, dims); } - value caml_get_fortran_array(value unit) + CAMLprim value caml_get_fortran_array(value unit) { return caml_ba_alloc_dims(CAML_BA_FLOAT32 | CAML_BA_FORTRAN_LAYOUT, 2, my_fortran_array_, 300L, 400L); @@ -2285,7 +2300,7 @@ CAMLprim value foo_byte(value a, value b) } \end{verbatim} -For convenicence, when all arguments and the result are annotated with +For convenience, when all arguments and the result are annotated with "[\@unboxed]", it is possible to put the attribute only once on the declaration itself. So we can also write instead: diff --git a/manual/manual/cmds/native.etex b/manual/manual/cmds/native.etex index a923b81c..ee156218 100644 --- a/manual/manual/cmds/native.etex +++ b/manual/manual/cmds/native.etex @@ -86,10 +86,12 @@ libraries. They are linked with the program. The output of the linking phase is a regular Unix or Windows executable file. It does not need "ocamlrun" to run. -% The following two paragraphs are a duplicate from the description of the batch compiler. +The compiler is able to emit some information on its internal stages: -The compiler is able to emit some information on its internal stages. -It can output ".cmt" files for the implementation of the compilation unit +\begin{itemize} +\item +% The following two paragraphs are a duplicate from the description of the batch compiler. +".cmt" files for the implementation of the compilation unit and ".cmti" for signatures if the option "-bin-annot" is passed to it (see the description of "-bin-annot" below). Each such file contains a typed abstract syntax tree (AST), that is produced @@ -99,6 +101,18 @@ The AST is partial if type checking was unsuccessful. These ".cmt" and ".cmti" files are typically useful for code inspection tools. +\item +".cmir-linear" files for the implementation of the compilation unit +if the option "-save-ir-after scheduling" is passed to it. +Each such file contains a low-level intermediate representation, +produced by the instruction scheduling pass. + +An external tool can perform low-level optimisations, +such as code layout, by transforming a ".cmir-linear" file. +To continue compilation, the compiler can be invoked with (a possibly modified) +".cmir-linear" file as an argument, instead of the corresponding source file. +\end{itemize} + \section{s:native-options}{Options} The following command-line options are recognized by "ocamlopt". @@ -113,12 +127,13 @@ exclusive. % compilers and toplevel \input{unified-options.tex} -\paragraph{Options for the IA32 architecture} -The IA32 code generator (Intel Pentium, AMD Athlon) supports the +\paragraph{Options for the 32-bit x86 architecture} +The 32-bit code generator for Intel/AMD x86 processors ("i386" +architecture) supports the following additional option: \begin{options} -\item["-ffast-math"] Use the IA32 instructions to compute +\item["-ffast-math"] Use the processor instructions to compute trigonometric and exponential functions, instead of calling the corresponding library routines. The functions affected are: "atan", "atan2", "cos", "log", "log10", "sin", "sqrt" and "tan". @@ -128,9 +143,9 @@ trigonometric operations "cos", "sin", "tan" have their range reduced to $[-2^{64}, 2^{64}]$. \end{options} -\paragraph{Options for the AMD64 architecture} -The AMD64 code generator (64-bit versions of Intel Pentium and AMD -Athlon) supports the following additional options: +\paragraph{Options for the 64-bit x86 architecture} +The 64-bit code generator for Intel/AMD x86 processors ("amd64" +architecture) supports the following additional options: \begin{options} \item["-fPIC"] Generate position-independent machine code. This is @@ -219,8 +234,8 @@ until the next heap allocation. beneficial, but produces floating-point results that differ slightly from those produced by the bytecode interpreter. -\item On IA32 processors only (Intel and AMD x86 processors in 32-bit -mode), some intermediate results in floating-point computations are +\item On Intel/AMD x86 processors in 32-bit mode, +some intermediate results in floating-point computations are kept in extended precision rather than being rounded to double precision like the bytecode compiler always does. Floating-point results can therefore differ slightly between bytecode and native code. diff --git a/manual/manual/cmds/ocamlbuild.etex b/manual/manual/cmds/ocamlbuild.etex deleted file mode 100644 index 66c7101a..00000000 --- a/manual/manual/cmds/ocamlbuild.etex +++ /dev/null @@ -1,5 +0,0 @@ -\chapter{The ocamlbuild compilation manager} \label{c:ocamlbuild} - -Since OCaml version 4.03, the ocamlbuild compilation manager is -distributed separately from the OCaml compiler. The project is now -hosted at \url{https://github.com/ocaml/ocamlbuild/}. diff --git a/manual/manual/cmds/ocamldep.etex b/manual/manual/cmds/ocamldep.etex index 93892b74..2b761e16 100644 --- a/manual/manual/cmds/ocamldep.etex +++ b/manual/manual/cmds/ocamldep.etex @@ -75,7 +75,7 @@ Process \var{file} as a ".ml" file. Process \var{file} as a ".mli" file. \item["-map" \var{file}] -Read an propagate the delayed dependencies for module aliases in +Read and propagate the delayed dependencies for module aliases in \var{file}, so that the following files will depend on the exported aliased modules if they use them. See the example below. diff --git a/manual/manual/cmds/runtime.etex b/manual/manual/cmds/runtime.etex index ebaf6a68..0e9189dd 100644 --- a/manual/manual/cmds/runtime.etex +++ b/manual/manual/cmds/runtime.etex @@ -98,6 +98,8 @@ The following environment variables are also consulted: (If "OCAMLRUNPARAM" is not set, "CAMLRUNPARAM" will be used instead.) This variable must be a sequence of parameter specifications separated by commas. + For convenience, commas at the beginning of the variable are ignored, + and multiple runs of commas are interpreted as a single one. A parameter specification is an option letter followed by an "=" sign, a decimal number (or an hexadecimal number prefixed by "0x"), and an optional multiplier. The options are documented below; @@ -110,8 +112,13 @@ The following environment variables are also consulted: \fi \begin{options} \item[b] (backtrace) Trigger the printing of a stack backtrace - when an uncaught exception aborts the program. - This option takes no argument. + when an uncaught exception aborts the program. An optional argument can + be provided: "b=0" turns backtrace printing off; "b=1" is equivalent to + "b" and turns backtrace printing on; "b=2" turns backtrace printing on + and forces the runtime system to load debugging information at program + startup time instead of at backtrace printing time. "b=2" can be used if + the runtime is unable to load debugging information at backtrace + printing time, for example if there are no file descriptors available. \item[p] (parser trace) Turn on debugging support for "ocamlyacc"-generated parsers. When this option is on, the pushdown automaton that executes the parsers prints a @@ -143,7 +150,7 @@ The following environment variables are also consulted: \item[v] ("verbose") What GC messages to print to stderr. This is a sum of values selected from the following: \begin{options} - \item[1 (= 0x001)] Start of major GC cycle. + \item[1 (= 0x001)] Start and end of major GC cycle. \item[2 (= 0x002)] Minor collection and major GC slice. \item[4 (= 0x004)] Growing and shrinking of the heap. \item[8 (= 0x008)] Resizing of stacks and memory manager tables. diff --git a/manual/manual/cmds/spacetime-chapter.etex b/manual/manual/cmds/spacetime-chapter.etex deleted file mode 100644 index 5b75eb86..00000000 --- a/manual/manual/cmds/spacetime-chapter.etex +++ /dev/null @@ -1,125 +0,0 @@ -\chapter{Memory profiling with Spacetime} -%HEVEA\cutname{spacetime.html} - -\section{s:spacetime-overview}{Overview} - -Spacetime is the name given to functionality within the OCaml compiler that -provides for accurate profiling of the memory behaviour of a program. -Using Spacetime it is possible to determine the source of memory leaks -and excess memory allocation quickly and easily. Excess allocation slows -programs down both by imposing a higher load on the garbage collector and -reducing the cache locality of the program's code. Spacetime provides -full backtraces for every allocation that occurred on the OCaml heap -during the lifetime of the program including those in C stubs. - -Spacetime only analyses the memory behaviour of a program with respect to -the OCaml heap allocators and garbage collector. It does not analyse -allocation on the C heap. Spacetime does not affect the memory behaviour -of a program being profiled with the exception of any change caused by the -overhead of profiling (see section\ \ref{s:spacetime-runtimeoverhead})---for example -the program running slower might cause it to allocate less memory in total. - -Spacetime is currently only available for x86-64 targets and has only been -tested on Linux systems (although it is expected to work on most modern -Unix-like systems and provision has been made for running under -Windows). It is expected that the set of supported platforms will -be extended in the future. - -\section{s:spacetime-howto}{How to use it} - -\subsection{ss:spacetime-building}{Building} - -To use Spacetime it is necessary to use an OCaml compiler that was -configured with the {\tt -spacetime} option. It is not possible to select -Spacetime on a per-source-file basis or for a subset of files in a project; -all files involved in the executable being profiled must be built with the -Spacetime compiler. Only native code compilation is supported (not -bytecode). - -If the {\tt libunwind} library is not available on the system then it will -not be possible for Spacetime to profile allocations occurring within -C stubs. If the {\tt libunwind} library is available but in an unusual -location then that location may be specified to the {\tt configure} script -using the {\tt -libunwinddir} option (or alternatively, using separate -{\tt -libunwindinclude} and {\tt -libunwindlib} options). - -OPAM switches will be provided for Spacetime-configured compilers. - -Once the appropriate compiler has been selected the program should be -built as normal (ensuring that all files are built with the Spacetime -compiler---there is currently no protection to ensure this is the case, but -it is essential). For many uses it will not be necessary to change the -code of the program to use the profiler. - -Spacetime-configured compilers run slower and occupy more memory than their -counterparts. It is hoped this will be fixed in the future as part of -improved cross compilation support. - -\subsection{ss:spacetime-running}{Running} - -Programs built with Spacetime instrumentation have a dependency on -the {\tt libunwind} library unless that was unavailable at configure time or -the {\tt -disable-libunwind} option was specified -(see section\ \ref{s:spacetime-runtimeoverhead}). - -Setting the {\tt OCAML\_SPACETIME\_INTERVAL} environment variable to an -integer representing a number of milliseconds before running a program built -with Spacetime will cause memory profiling to be in operation when the -program is started. The contents of the OCaml heap will be sampled each -time the number of milliseconds that the program has spent executing since the -last sample exceeds the given number. (Note that the time base is combined -user plus system time---{\em not} wall clock time. This peculiarity may be -changed in future.) - -The program being profiled must exit normally or be caused to exit using -the {\tt SIGINT} signal (e.g. by pressing Ctrl+C). When the program exits -files will be written in the directory that was the working directory when -the program was started. One Spacetime file will be written for each -process that was involved, indexed by process ID; there will normally only -be one such. The Spacetime files may be substantial. The directory to which -they are written may be overridden by setting -the {\tt OCAML\_SPACETIME\_SNAPSHOT\_DIR} environment variable before the -program is started. - -Instead of using the automatic snapshot facility described above it is also -possible to manually control Spacetime profiling. (The environment variables -{\tt OCAML\_SPACETIME\_INTERVAL} and {\tt OCAML\_SPACETIME\_SNAPSHOT\_DIR} -are then not relevant.) Full documentation as regards this method of profiling -is provided in the standard library documentation (section\ \ref{c:stdlib}) -for the {\tt Spacetime} module. - -\subsection{ss:spacetime-analysis}{Analysis} - -The compiler distribution does not itself provide the facility for analysing -Spacetime output files; this is left to external tools. The first such tool -will appear in OPAM as a package called {\tt prof_spacetime}. That tool will -provide interactive graphical and terminal-based visualisation of -the results of profiling. - -\section{s:spacetime-runtimeoverhead}{Runtime overhead} - -The runtime overhead imposed by Spacetime varies considerably depending on -the particular program being profiled. The overhead may be as low as -ten percent---but more usually programs should be expected to run at perhaps -a third or quarter of their normal speed. It is expected that this overhead -will be reduced in future versions of the compiler. - -Execution speed of instrumented programs may be increased by using a compiler -configured with the {\tt -disable-libunwind} option. This prevents collection -of profiling information from C stubs. - -Programs running with Spacetime instrumentation consume significantly more -memory than their non-instrumented counterparts. It is expected that this -memory overhead will also be reduced in the future. - -\section{s:spacetime-dev}{For developers} - -The compiler distribution provides an ``{\tt otherlibs}'' library called -{\tt raw\_spacetime\_lib} for decoding Spacetime files. This library -provides facilities to read not only memory profiling information but also -the full dynamic call graph of the profiled program which is written into -Spacetime output files. - -A library package {\tt spacetime\_lib} will be provided in OPAM -to provide an interface for decoding profiling information at a higher -level than that provided by {\tt raw\_spacetime\_lib}. diff --git a/manual/manual/cmds/unified-options.etex b/manual/manual/cmds/unified-options.etex index fe636112..b17aed6a 100644 --- a/manual/manual/cmds/unified-options.etex +++ b/manual/manual/cmds/unified-options.etex @@ -393,8 +393,13 @@ libraries and options on the command line. \nat{% \item["-nodynlink"] -Allow the compiler to use some optimizations that are valid only for code -that is never dynlinked. +Allow the compiler to use some optimizations that are valid only for +code that is statically linked to produce a non-relocatable +executable. The generated code cannot be linked to produce a shared +library nor a position-independent executable (PIE). Many operating +systems produce PIEs by default, causing errors when linking code +compiled with "-nodynlink". Either do not use "-nodynlink" or pass +the option "-ccopt -no-pie" at link-time. }%nat \item["-nolabels"] @@ -604,8 +609,25 @@ code such as C stubs. \notop{ \item["-stop-after" \var{pass}] Stop compilation after the given compilation pass. The currently -supported passes are: "parsing", "typing". -}%notop +supported passes are: +"parsing", "typing"\nat{, "scheduling", "emit"}. +}%notop + +\nat{ +\item["-save-ir-after" \var{pass}] +Save intermediate representation after the given compilation pass +to a file. +The currently supported passes and the corresponding file extensions are: +"scheduling" (".cmir-linear"). + +This experimental feature enables external tools to inspect and manipulate +compiler's intermediate representation of the program +using "compiler-libs" library (see +\ifouthtml chapter~\ref{c:parsinglib} and +\ahref{compilerlibref/Compiler\_libs.html}{ \texttt{Compiler_libs} } +\else section~\ref{Compiler-underscorelibs}\fi +). +}%nat \nat{% \item["-S"] @@ -753,8 +775,18 @@ to \var{uppercase-letter}. to \var{lowercase-letter}. \end{options} -Warning numbers and letters which are out of the range of warnings -that are currently defined are ignored. The warnings are as follows. +Alternatively, \var{warning-list} can specify a single warning using its +mnemonic name (see below), as follows: + +\begin{options} +\item["+"\var{name}] Enable warning \var{name}. +\item["-"\var{name}] Disable warning \var{name}. +\item["@"\var{name}] Enable and mark as fatal warning \var{name}. +\end{options} + +Warning numbers, letters and names which are not currently defined are +ignored. The warnings are as follows (the name following each number specifies +the mnemonic for that warning). \begin{options} \input{warnings-help.tex} \end{options} diff --git a/manual/manual/foreword.etex b/manual/manual/foreword.etex index c595abe6..614e6b52 100644 --- a/manual/manual/foreword.etex +++ b/manual/manual/foreword.etex @@ -14,7 +14,7 @@ the compilers, toplevel system, and programming utilities. \item Part~\ref{p:library}, ``The OCaml library'', describes the modules provided in the standard library. \begin{latexonly} -\item Part~\ref{p:appendix}, ``Appendix'', contains an +\item Part~\ref{p:indexes}, ``Indexes'', contains an index of all identifiers defined in the standard library, and an index of keywords. \end{latexonly} @@ -31,7 +31,7 @@ systems, including Linux and macOS. \end{unix} \begin{windows} This is material specific to Microsoft Windows - (XP, Vista, 7, 8, 10). + (Vista, 7, 8, 10). \end{windows} \section*{license}{License} diff --git a/manual/manual/html_processing/.gitignore b/manual/manual/html_processing/.gitignore new file mode 100644 index 00000000..fcd498c1 --- /dev/null +++ b/manual/manual/html_processing/.gitignore @@ -0,0 +1,7 @@ +dune +markup.ml +uchar +uutf +lambdasoup +ocaml-re +.sass-cache diff --git a/manual/manual/html_processing/Makefile b/manual/manual/html_processing/Makefile new file mode 100644 index 00000000..f4d5b147 --- /dev/null +++ b/manual/manual/html_processing/Makefile @@ -0,0 +1,137 @@ +DUNE_CMD := $(if $(wildcard dune/dune.exe),dune/dune.exe,dune) +DUNE ?= $(DUNE_CMD) + +DEBUG ?= 0 +ifeq ($(DEBUG), 1) + DBG= +else + DBG=quiet +endif + +WEBDIR = ../webman +WEBDIRMAN = $(WEBDIR)/manual +WEBDIRAPI = $(WEBDIR)/api +WEBDIRCOMP = $(WEBDIRAPI)/compilerlibref + +# The "all" target generates the Web Manual in the directories +# ../webman/manual, ../webman/api, and ../webman/api/compilerlibref +all: css js img + $(DUNE) exec --root=. src/process_manual.exe $(DBG) + $(DUNE) exec --root=. src/process_api.exe overwrite $(DBG) + $(DUNE) exec --root=. src/process_api.exe compiler overwrite $(DBG) + +$(WEBDIR): + mkdir -p $(WEBDIRMAN) + mkdir -p $(WEBDIRCOMP) + +$(WEBDIRMAN)/manual.css: scss/_common.scss scss/manual.scss $(WEBDIR) + sass scss/manual.scss > $(WEBDIRMAN)/manual.css + +$(WEBDIRAPI)/style.css: scss/_common.scss scss/style.scss $(WEBDIR) + sass scss/style.scss > $(WEBDIRAPI)/style.css + cp $(WEBDIRAPI)/style.css $(WEBDIRCOMP)/style.css + +css: $(WEBDIRMAN)/manual.css $(WEBDIRAPI)/style.css + +# Just copy the JS files +JS_FILES0 := scroll.js navigation.js +JS_FILES1 := $(JS_FILES0) search.js +JS_FILES := $(addprefix $(WEBDIRAPI)/, $(JS_FILES1)) $(addprefix $(WEBDIRCOMP)/, $(JS_FILES1)) $(addprefix $(WEBDIRMAN)/, $(JS_FILES0)) + +# There must be a more clever way +$(WEBDIRAPI)/%.js: js/%.js + cp $< $@ + +$(WEBDIRMAN)/%.js: js/%.js + cp $< $@ + +$(WEBDIRCOMP)/%.js: js/%.js + cp $< $@ + +js: $(WEBDIR) $(JS_FILES) + +# download images for local use +SEARCH := search_icon.svg +$(WEBDIRAPI)/search_icon.svg: $(WEBDIR) + curl "https://ocaml.org/img/search.svg" > $(WEBDIRAPI)/$(SEARCH) + cp $(WEBDIRAPI)/$(SEARCH) $(WEBDIRCOMP)/$(SEARCH) + +LOGO := colour-logo.svg +$(WEBDIRAPI)/colour-logo.svg: $(WEBDIR) + curl "https://raw.githubusercontent.com/ocaml/ocaml-logo/master/Colour/SVG/colour-logo.svg" > $(WEBDIRAPI)/$(LOGO) + cp $(WEBDIRAPI)/$(LOGO) $(WEBDIRMAN)/$(LOGO) + cp $(WEBDIRAPI)/$(LOGO) $(WEBDIRCOMP)/$(LOGO) + +ICON := favicon.ico +$(WEBDIRAPI)/favicon.ico: $(WEBDIR) + curl "https://raw.githubusercontent.com/ocaml/ocaml-logo/master/Colour/Favicon/32x32.ico" > $(WEBDIRAPI)/$(ICON) + cp $(WEBDIRAPI)/$(ICON) $(WEBDIRMAN)/$(ICON) + cp $(WEBDIRAPI)/$(ICON) $(WEBDIRCOMP)/$(ICON) + +IMG_FILES0 := colour-logo.svg +IMG_FILES := $(addprefix $(WEBDIRAPI)/, $(IMG_FILES0)) $(addprefix $(WEBDIRCOMP)/, $(IMG_FILES0)) $(addprefix $(WEBDIRMAN)/, $(IMG_FILES0)) + +img: $(WEBDIR) $(WEBDIRAPI)/search_icon.svg $(WEBDIRAPI)/favicon.ico $(WEBDIRCOMP)/search_icon.svg $(WEBDIRCOMP)/favicon.ico $(IMG_FILES) + +clean: + rm -rf $(WEBDIR) src/.merlin _build + +distclean:: + rm -rf .sass-cache + +# We need Dune and Lambda Soup; Markup.ml and Uutf are dependencies +DUNE_TAG = 2.6.2 +LAMBDASOUP_TAG = 0.7.1 +MARKUP_TAG = 0.8.2 +UUTF_TAG = v1.0.2 +RE_TAG = 1.9.0 + +# Duniverse rules - set-up dune and the dependencies in-tree for CI +duniverse: dune/dune.exe re markup.ml uutf lambdasoup + +dune/dune.exe: dune + cd dune; ocaml bootstrap.ml + +GIT_CHECKOUT = git -c advice.detachedHead=false checkout + +dune: + git clone https://github.com/ocaml/dune.git -n -o upstream + cd dune; $(GIT_CHECKOUT) $(DUNE_TAG) + +distclean:: + rm -rf dune + +re: + git clone https://github.com/ocaml/ocaml-re.git -n -o upstream + cd ocaml-re; $(GIT_CHECKOUT) $(RE_TAG) + +distclean:: + rm -rf ocaml-re + +lambdasoup: + git clone https://github.com/aantron/lambdasoup.git -n -o upstream + cd lambdasoup; $(GIT_CHECKOUT) $(LAMBDASOUP_TAG) + +distclean:: + rm -rf lambdasoup + +markup.ml: + git clone https://github.com/aantron/markup.ml.git -n -o upstream + cd markup.ml; $(GIT_CHECKOUT) $(MARKUP_TAG) + +distclean:: + rm -rf markup.ml + +uutf: + git clone https://github.com/dbuenzli/uutf.git -n -o upstream + cd uutf; $(GIT_CHECKOUT) $(UUTF_TAG) + cd uutf; \ + mv opam uutf.opam; \ + echo '(lang dune 1.0)' > dune-project; \ + echo '(name uutf)' >> dune-project; \ + echo '(library (name uutf)(public_name uutf)(flags (:standard -w -3-27))(wrapped false))' > src/dune + +distclean:: + rm -rf uutf + +.PHONY: css js img duniverse diff --git a/manual/manual/html_processing/README.md b/manual/manual/html_processing/README.md new file mode 100644 index 00000000..9741b275 --- /dev/null +++ b/manual/manual/html_processing/README.md @@ -0,0 +1,71 @@ +# HTML post-processing + +This directory contains material for enhancing the html of the manual +and the API (from the `../htmlman` directory), including a quick +search widget for the API. + +The process will create the `../webman` dir, and output the new html +files (and assets) in `../webman/manual` (the manual) and `../webman/api` (the +API). + +## manual and api + +There are two different scripts, `process_manual.ml` and +`process_api.ml`. The first one deals with all the chapters of the +manual, while the latter deals with the api generated with `ocamldoc`. +They both use a common module `common.ml`. + +## How to build + +With dependencies to build the whole manual: +``` +cd .. +make web +``` + +Or, much faster if you know that `htmlman` is already up-to-date, from +within the `html_processing` dir: + +``` +make +``` + +You need a working +[`sass`](https://sass-lang.com/) CSS processor (tested with version +"3.4.23"). + +## How to browse + +From the `html_processing` directory: + +`firefox ../webman/api/index.html` + +`firefox ../webman/manual/index.html` + +## Debug + +``` +make DEBUG=1 +``` + +By default all html files are re-created by `make`, but the javascript +index `webman/api/index.js` and `webman/api/compilerlibref/index.js` +are kept if they already exist. You can use `make clean` to delete all +generated files. + +The javascript files in the `html_processing/js` dir add functionality +but the web-manual is still browsable without them: + +- `scroll.js`: adds smooth scrolling in the html page, but only for + near targets. The reason is that when you jump to another place in a + text, if the jump is immediate (no scrolling), you easily get lost; + for instance you usually don't even realize that the target of the + link is just half a page below! Thus smooth scrolling helps + _understanding the structure_ of the document. However, when the + target is very far, the browser will scroll a huge amount of text + very quickly, and this becomes useless, and even painful for the + eye. Hence we disable smooth scrolling for far targets. + +- `search.js`: adds an 'as-you-type quick search widget', which + recognize values, modules, and type signatures. It is very useful, + but of course not strictly necessary. diff --git a/manual/manual/html_processing/dune-project b/manual/manual/html_processing/dune-project new file mode 100644 index 00000000..0636ab6a --- /dev/null +++ b/manual/manual/html_processing/dune-project @@ -0,0 +1 @@ +(lang dune 1.11) diff --git a/manual/manual/html_processing/js/navigation.js b/manual/manual/html_processing/js/navigation.js new file mode 100644 index 00000000..7e21ffeb --- /dev/null +++ b/manual/manual/html_processing/js/navigation.js @@ -0,0 +1,102 @@ +// NaVigation helpers for the manual, especially in mobile mode. + +// copyright 2020 San Vu Ngoc +// + +// Permission to use, copy, modify, and/or distribute this software +// for any purpose with or without fee is hereby granted, provided +// that the above copyright notice and this permission notice appear +// in all copies. + +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// In mobile mode, both left navigation bar and top part menu are +// closed by default. + +var MENU_HEIGHT = 0; + +function closeSidebarExceptSearch (event) { + if ( event && event.target && event.target.classList.contains("api_search") ) { + false; + } else { + closeSidebar (); + true; + } +} + +// This closes the sidebar in mobile mode. This should have no effect +// in desktop mode. +function closeSidebar () { + let bar = document.getElementById("sidebar"); + let w = getComputedStyle(bar).width; + bar.style.left = "-" + w; + document.body.removeEventListener("click", closeSidebarExceptSearch); +} + +function toggleSidebar () { + let bar = document.getElementById("sidebar"); + let l = getComputedStyle(bar).left; + if (l == "0px") { + closeSidebar (); + } else { + bar.style.left = "0px"; + setTimeout(function(){ + // Any click anywhere but in search widget will close the sidebar + document.body.addEventListener("click", closeSidebarExceptSearch); + }, 1000); + } +} + +function togglePartMenu () { + let pm = document.getElementById("part-menu"); + let h = pm.offsetHeight; + if ( h == 0 ) { + pm.style.height = MENU_HEIGHT.toString() + "px"; + } else { + pm.style.height = "0px"; + } +} + +function partMenu () { + let pm = document.getElementById("part-menu"); + if ( pm != null ) { + MENU_HEIGHT = pm.scrollHeight; // This should give the true + // height of the menu, even if + // it was initialized to 0 in + // the CSS (mobile view). + // In desktop mode, the height is initially on "auto"; we + // have to detect it in + // order for the css animmations to work. + // TODO update this when window is resized + let currentHeight = pm.offsetHeight; + pm.style.height = currentHeight.toString() + "px"; + let p = document.getElementById("part-title"); + if ( p != null ) { + p.onclick = togglePartMenu; + } + } +} + +function sideBar () { + closeSidebar(); + let btn = document.getElementById("sidebar-button"); + btn.onclick = toggleSidebar; +} + +// We add it to the chain of window.onload +window.onload=(function(previousLoad){ + return function (){ + previousLoad && previousLoad (); + partMenu (); + sideBar (); + } +})(window.onload); + + diff --git a/manual/manual/html_processing/js/scroll.js b/manual/manual/html_processing/js/scroll.js new file mode 100644 index 00000000..3d6f731f --- /dev/null +++ b/manual/manual/html_processing/js/scroll.js @@ -0,0 +1,104 @@ +// Smooth scrolling only for near targets +// copyright 2019-2020 San Vu Ngoc +// + +// Permission to use, copy, modify, and/or distribute this software +// for any purpose with or without fee is hereby granted, provided +// that the above copyright notice and this permission notice appear +// in all copies. + +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +// Goal: if a link is located at distance larger than MAX_DISTANCE, we +// don't use a smooth scrolling. +// +// usage: to activate this, run setSmooth within window.onload: +// window.onload = setSmooth +// Here instead we create a loading chain because we have other things +// to add window.onload later. + +const MAX_DISTANCE = 1000; +const SCROLL_DURATION = 600; + +const url = window.location.pathname; +var filename = url.substring(url.lastIndexOf('/')+1); +if (filename == "") { filename = "index.html"; } + +function localLink (link) { + return (link.length > 0 && + (link.charAt(0) == '#' + || link.substring(0,filename.length) == filename)); +} + +//aaa.html#s%3Adatatypes --> s:datatypes +function getId (link) { + let uri = link.substring(link.lastIndexOf('#')+1); + return decodeURIComponent(uri) + // for instance decodeURIComponent("s%3Adatatypes") == 's:datatypes' +} + +// Get absolute y position of element. +// modified from: +// https://www.kirupa.com/html5/get_element_position_using_javascript.htm +// assuming effective licence CC0, see +// https://forum.kirupa.com/t/get-an-elements-position-using-javascript/352186/3 +function getPosition(el) { + let yPos = 0; + while (el) { + yPos += (el.offsetTop + el.clientTop); + el = el.offsetParent; + } + return yPos; +} + +// This function scans all "a" tags with a valid "href", and for those +// that are local links (links within the same file) it adds a special +// onclick function for smooth scrolling. +function setSmooth () { + let a = document.getElementsByTagName("a"); + let container = document.body.parentNode; + let i; + for (i = 0; i < a.length; i++) { + let href = a[i].getAttribute("href"); + if (href != null && localLink(href)) { + a[i].onclick = function () { + let id = getId(href); + let target = ""; + if ( id == "" ) { + target = container; + } else { + target = document.getElementById(id); } + if (! target) { + console.log ("Error, no target for id=" + id); + target = container; } + let top = container.scrollTop; + let dist = top - getPosition(target) + if (Math.abs(dist) < MAX_DISTANCE) { + target.scrollIntoView({ block: "start", inline: "nearest", behavior: 'smooth' }); + setTimeout(function () { + location.href = href; + // this will set the "target" property. + }, SCROLL_DURATION); + return false; + // so we don't follow the link immediately + } + } + } + } +} + +// We add it to the chain of window.onload +window.onload=(function(previousLoad){ + return function (){ + previousLoad && previousLoad (); + setSmooth (); + } +})(window.onload); diff --git a/manual/manual/html_processing/js/search.js b/manual/manual/html_processing/js/search.js new file mode 100644 index 00000000..bb0a2c36 --- /dev/null +++ b/manual/manual/html_processing/js/search.js @@ -0,0 +1,248 @@ +// Searching the OCAML API. +// Copyright 2019-2020 San VU NGOC + +// Permission to use, copy, modify, and/or distribute this software +// for any purpose with or without fee is hereby granted, provided +// that the above copyright notice and this permission notice appear +// in all copies. + +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// Thanks @steinuil for help on deferred loading. +// Thanks @osener, @UnixJunkie, @Armael for very helpful suggestions +// Thanks to all testers! + +const MAX_RESULTS = 20; +const MAX_ERROR = 10; +const DESCR_INDEX = 4; // index of HTML description in index.js +const SIG_INDEX = 6; // index of HTML signature in index.js +const ERR_INDEX = 8; // length of each line in index.js. This is used + // for storing the computed error, except if we + // don't want description and type signature, + // then ERR_INDEX becomes DESCR_INDEX. + +let indexState = 'NOT_LOADED'; + +// return true if we are loading the index file +function loadingIndex (includeDescr) { + switch (indexState) { + case 'NOT_LOADED': + indexState = 'LOADING'; + + const script = document.createElement('script'); + script.src = 'index.js'; + script.addEventListener('load', () => { + indexState = 'HAS_LOADED'; + mySearch(includeDescr); + }); + document.head.appendChild(script); + return true; + + case 'LOADING': + return true; + + case 'HAS_LOADED': + return false; + } +} + +// line is a string array. We check if sub is a substring of one of +// the elements of the array. The start/end of the string s are marked +// by "^" and "$", and hence these chars can be used in sub to refine +// the search. Case sensitive is better for OCaml modules. Searching +// within line.join() is slightly more efficient that iterating 'line' +// with .findIndex (my benchmarks show about 15% faster; except if we +// search for the value at the beginning of line). However it might +// use more memory. +function hasSubString (sub, line) { + let lineAll = "^" + line.join("$^") + "$"; + return (lineAll.includes(sub)); +} + +// Check if one of the strings in subs is a substring of one of the +// strings in line. +function hasSubStrings (subs, line) { + let lineAll = "^" + line.join("$^") + "$"; + return (subs.findIndex(function (sub) { + return (lineAll.includes(sub))}) !== -1); +} +// Error of sub being a substring of s. Best if starts at 0. Except +// for strings containing "->", which is then best if the substring is +// at the most right-hand position (representing the "return type"). +// markers "^" and "$" for start/end of string can be used: if they +// are not satisfied, the MAX_ERROR is returned. +function subError (sub, s) { + let StartOnly = false; + let EndOnly = false; + if (sub.length>1) { + if (sub[0] == "^") { + StartOnly = true; + sub = sub.substring(1); + } + if (sub[sub.length - 1] == "$") { + EndOnly = true; + sub = sub.substring(0, sub.length - 1); + } + } + let err = s.indexOf(sub); + if (err == -1 || + (StartOnly && err != 0) || + (EndOnly && err != s.length - sub.length)) { + err = MAX_ERROR; + } else { + if ( sub.includes("->") ) { + err = Math.min(s.length - sub.length - err,1); // 0 or 1 + // err = 0 if the substring is right-aligned + } else { + err = Math.min(err,1); // 0 or 1 + // err = 0 if the substring + } + err += Math.abs((s.length - sub.length) / s.length);} + return (err) + // between 0 and 2, except if MAX_ERROR +} + +// Minimal substring error. In particular, it returns 0 if the string +// 'sub' has an exact match with one of the strings in 'line'. +function subMinError (sub, line) { + let errs = line.map(function (s) { return subError (sub, s); }); + return Math.min(...errs); // destructuring assignment +} + + +function add (acc, a) { + return acc + a; +} + +// for each sub we compute the minimal error within 'line', and then +// take the average over all 'subs'. Thus it returns 0 if each sub has +// an exact match with one of the strings in 'line'. +function subsAvgMinError (subs, line) { + let errs = subs.map(function (sub) { return subMinError (sub, line); }); + return errs.reduce(add,0) / subs.length; +} + +function formatLine (line) { + let li = '

  • '; + let html = `${line[0]}.${line[2]}`; + if (line.length > 5) { + if ( line[ERR_INDEX] == 0 ) { + li = '
  • '; + } + html = `
    ${html} : ${line[SIG_INDEX]}
    ${line[DESCR_INDEX]}`; } + return (li + html + "
  • \n"); +} + +// Split a string into an array of non-empty words, or phrases +// delimited by quotes ("") +function splitWords (s) { + let phrases = s.split('"'); + let words = []; + phrases.forEach(function (phrase,i) { + if ( i%2 == 0 ) { + words.push(...phrase.split(" ")); + } else { + words.push(phrase); + } + }); + return (words.filter(function (s) { + return (s !== "")})); +} + +// The initial format of an entry of the GENERAL_INDEX array is +// [ module, module_link, +// value, value_link, +// html_description, bare_description, +// html_signature, bare_signature ] + +// If includeDescr is false, the line is truncated to its first 4 +// elements. When searching, the search error is added at the end of +// each line. + +// In order to reduce the size of the index.js file, one could create +// the bare_description on-the-fly using .textContent, see +// https://stackoverflow.com/questions/28899298/extract-the-text-out-of-html-string-using-javascript, +// but it would probably make searching slower (haven't tested). +function mySearch (includeDescr) { + if (loadingIndex (includeDescr)) { + return; + } + let text = document.getElementById('api_search').value; + let results = []; + let html = ""; + let count = 0; + let err_index = DESCR_INDEX; + + if (text !== "") { + if ( includeDescr ) { + err_index = ERR_INDEX; + } + + let t0 = performance.now(); + let exactMatches = 0; + results = GENERAL_INDEX.filter(function (line) { + // We remove the html hrefs and add the Module.value complete name: + let cleanLine = [line[0], line[2], line[0] + '.' + line[2]]; + line.length = err_index; // This truncates the line: + // this removes the description part if includeDescr = + // false (which modifies the lines of the GENERAL_INDEX.) + if ( includeDescr ) { + cleanLine.push(line[DESCR_INDEX+1]); + cleanLine.push(line[SIG_INDEX+1]); + // add the description and signature (txt format) + } + let error = MAX_ERROR; + if ( exactMatches <= MAX_RESULTS ) { + // We may stop searching when exactMatches > + // MAX_RESULTS because the ranking between all exact + // matches is unspecified (depends on the construction + // of the GENERAL_INDEX array) + if ( hasSubString(text, cleanLine) ) { + error = subMinError(text, cleanLine); + // one could merge hasSubString and subMinError + // for efficiency + } + if ( error != 0 && includeDescr ) { + let words = splitWords(text); + if ( hasSubStrings(words, cleanLine) ) { + // if there is no exact match for text and + // includeDescr=true, we also search for all separated + // words + error = subsAvgMinError(words, cleanLine); + } + } + if ( error == 0 ) { exactMatches += 1; } + } + line[err_index] = error; + // we add the error as element #err_index + return ( error != MAX_ERROR ); + }); + // We sort the results by relevance: + results.sort(function(line1, line2) { + return (line1[err_index] - line2[err_index])}); + count = results.length; + console.log("Search results = " + (count.toString())); + results.length = Math.min(results.length, MAX_RESULTS); + html = "no results"; + } + // inject new html + if (results.length > 0) { + html = "
      "; + function myIter(line, index, array) { + html = html + formatLine(line); + } + results.forEach(myIter); + html += "
    "; + if (count > results.length) { + html += "(...)"; + } + } + document.getElementById("search_results").innerHTML = html; +} diff --git a/manual/manual/html_processing/scss/_common.scss b/manual/manual/html_processing/scss/_common.scss new file mode 100644 index 00000000..2484cbb2 --- /dev/null +++ b/manual/manual/html_processing/scss/_common.scss @@ -0,0 +1,246 @@ +// SCSS Module for manual.scss and style.scss + +// set this to true for integration into the ocaml.org wesite +$ocamlorg:false; +/* ocaml logo color */ +$logocolor:#ec6a0d; +$logo_height:67px; + +@if $ocamlorg { + .container { + margin-left:0; + margin-right:0; + } +} + + +/* Fonts */ +@import url(https://fonts.googleapis.com/css?family=Fira+Mono:400,500); +@import url(https://fonts.googleapis.com/css?family=Noticia+Text:400,400i,700); +@import url(https://fonts.googleapis.com/css?family=Fira+Sans:400,400i,500,500i,600,600i,700,700i); + +/* Reset */ +.pre,a,b,body,code,div,em,form,h1,h2,h3,h4,h5,h6,header,html,i,img,li,mark,menu,nav,object,output,p,pre,s,section,span,time,ul,td,var{ + margin:0; + padding:0; + border:0; + font-size:inherit; + font:inherit; + line-height:inherit; + vertical-align:baseline; + text-align:inherit; + color:inherit; + background:0 0 +} +*,:after,:before{ + box-sizing:border-box +} + +html.smooth-scroll { + scroll-behavior:smooth; +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior:auto; + } +} + +body{ + font-family:"Fira Sans",Helvetica,Arial,sans-serif; + text-align:left; + color:#333; + background:#fff +} + +html { + font-size: 16px; + .dt-thefootnotes{ + height:1ex; + } + .footnotetext{ + font-size: 13px; + } +} + +#sidebar-button{ + float:right; + cursor: context-menu; + span{ + font-size:28px; + } + display:none; + } + +.content, .api { + &>header { + margin-bottom: 30px; + nav { + font-family: "Fira Sans", Helvetica, Arial, sans-serif; + } + } +} + +@mixin content-frame { + max-width:90ex; + margin-left:calc(10vw + 20ex); + margin-right:4ex; + margin-top:20px; + margin-bottom:50px; + font-family:"Noticia Text",Georgia,serif; + line-height:1.5 +} + +/* Menu in the left bar */ +@mixin nav-toc { + display: block; + padding-top: 10px; + position:fixed; + @if $ocamlorg { + top:0; + } @else { + top:$logo_height; + } + bottom:0; + left:0; + max-width:30ex; + min-width:26ex; + width:20%; + background:linear-gradient(to left,#ccc,transparent); + overflow:auto; + color:#1F2D3D; + padding-left:2ex; + padding-right:2ex; + .toc_version { + font-size:smaller; + text-align:right; + a { + color:#888; + } + } + ul{ + list-style-type:none; + li{ + margin:0; + ul{ + margin:0 + } + li{ + border-left:1px solid #ccc; + margin-left:5px; + padding-left:12px; + } + a { + font-family:"Fira Sans",sans-serif; + font-size:.95em; + color:#333; + font-weight:400; + line-height:1.6em; + display:block; + &:hover { + box-shadow:none; + background-color: #edbf84;} + } + &.top a { + color: #848484; + &:hover { + background-color: unset; + text-decoration: underline; + } + } + } + } + &>ul>li { + margin-bottom:.3em; + &>a { /* First level titles */ + font-weight:500;} + } +} + +/* OCaml Logo */ +@mixin brand { + @if $ocamlorg { + display:none; + } + top:0; + height:$logo_height; + img{ + margin-top:14px; + height:36px + } +} + +@mixin mobile { + .api, .content{ + margin:auto; + padding:2em; + h1 { + margin-top:0; + } + } +} + +@mixin nav-toc-mobile { + position:static; + width:auto; + min-width:unset; + border:none; + padding:.2em 1em; + border-radius:5px 0; + &.brand {border-radius: 0 5px;} +} + +/* Header is used as a side-bar */ +@mixin header-mobile { + margin-bottom:0; + position:fixed; + left:-10000px; /* initially hidden */ + background-color:#ffefe7; + transition:left 0.4s; + top:0; + max-width:calc(100% - 2em); + max-height: 100%; + overflow-y: auto; + box-shadow:0.4rem 0rem 0.8rem #bbb; +} + +@mixin sidebar-button { + #sidebar-button{ + display:inline-block; + position:fixed; + top:1.5em; + right:1ex; + } +} + +/* Print adjustements. */ +/* This page can be nicely printed or saved to PDF (local version) */ + +@media print { + body { + color: black; + background: white; + } + body nav:first-child { + position: absolute; + background: transparent; + } + .content, .api { + nav.toc { + margin-right: 1em; + float: left; + position: initial; + background: #eee; + } + margin-left: 3em; + margin-right: 3em; + } +} + +@mixin caret { + content:"▶"; + color:$logocolor; + font-size:smaller; + margin-right:4px; + margin-left:-1em +} diff --git a/manual/manual/html_processing/scss/manual.scss b/manual/manual/html_processing/scss/manual.scss new file mode 100644 index 00000000..27d96a03 --- /dev/null +++ b/manual/manual/html_processing/scss/manual.scss @@ -0,0 +1,349 @@ +// SOURCE FILE + +/* If the above line does not say "SOURCE FILE", then do not edit. It */ +/* means this file is generated from [sass manual.scss] */ + +/* CSS file for the Ocaml manual */ + +/* San Vu Ngoc, 2019-2020 */ + +@import "common"; +@charset "UTF-8"; + +.content{ + @include content-frame; + #part-title{ + float:left; + color:#777; + cursor: context-menu; + font-family:"Fira Sans",Helvetica,Arial,sans-serif; + span{ /* menu icon */ + font-size:22px; + margin-right:1ex; + } + } + ul{list-style:none;} + ul.itemize li::before{@include caret;} + + /* When the TOC is repeated in the main content */ + ul.ul-content { + } + /* navigation links at the bottom of page */ + .bottom-navigation { + margin-bottom:1em; + a.next { + float: right; + } + } + .copyright{ + font-size:smaller; + display:inline-block; + } +} +.index{ /* index.html */ + ul{ + list-style: none; + li { + margin-left: 0.5ex; + span { + color:#c88b5f; + } + span.c003{ + color:#564233; + } + } + } + /* only for Contents/Foreword in index.html: */ + ul.ul-content li::before{@include caret;} + /* table of contents: (manual.001.html): */ + ul.toc ul.toc ul.toc{ + font-size:smaller; + } + section>ul>li>a{ /* for Parts title */ + font-family:"Fira Sans",Helvetica,Arial,sans-serif; + font-size:larger; + background:linear-gradient(to left,#fff 0,#ede8e5 100%); + } + section>ul>li>ul>li:hover{ /* Chapters */ + background:linear-gradient(to left,#fff 0,#ede8e5 100%); + } + section>ul>li>ul>li{ + transition: background 0.5s; + } +} +b{ + font-weight:500 +} +em,i{ + font-style:italic +} +.ocaml { + background:#f7f5f4; +} +.ocaml,pre{ + margin-top:.8em; + margin-bottom:1.2em +} +.ocaml .pre{ + white-space:pre +} +p,ul{ + margin-top:.5em; + margin-bottom:1em +} +ul{ + list-style-position:outside +} +ul>li{ + margin-left:22px +} +li>:first-child{ + margin-top:0 +} +.left{ + text-align:left +} +.right{ + text-align:right +} +a{ + text-decoration:none; + color:#92370a +} +a:hover{ + box-shadow:0 1px 0 0 #92370a +} +:target{ + background-color:rgba(255,215,181,.3)!important; + box-shadow:0 0 0 1px rgba(255,215,181,.8)!important; + border-radius:1px +} +:hover>a.section-anchor{ + visibility:visible +} +a.section-anchor:before{ + content:"#" +} +a.section-anchor:hover{ + box-shadow:none; + text-decoration:none; + color:#555 +} +a.section-anchor{ + visibility:hidden; + position:absolute; + margin-left:-1.3em; + font-weight:400; + font-style:normal; + padding-right:.4em; + padding-left:.4em; + color:#d5d5d5 +} +.h10,.h7,.h8,.h9,h1,h2,h3,h4,h5,h6{ + font-family:"Fira Sans",Helvetica,Arial,sans-serif; + font-weight:400; + margin:.5em 0 .5em 0; + padding-top:.1em; + line-height:1.2; + overflow-wrap:break-word +} +h1{ + font-weight:500; + font-size:2.441em; + margin-top:1.214em +} +h1{ + font-weight:500; + font-size:1.953em; + box-shadow:0 1px 0 0 #ddd +} +h2{ + font-size:1.563em +} +h3{ + font-size:1.25em +} +h1 code{ + font-size:inherit; + font-weight:inherit +} +h2 code{ + font-size:inherit; + font-weight:inherit +} +h3 code{ + font-size:inherit; + font-weight:inherit +} +h3 code{ + font-size:inherit; + font-weight:inherit +} +h4{ + font-size:1.12em +} +.ocaml,.pre,code,pre,tt{ + font-family:"Fira Mono",courier; + font-weight:400 +} +.pre,pre{ + border-left:4px solid #e69c7f; + overflow-x:auto; + padding-left:1ex +} +.ocaml .pre{ + overflow-x:initial; +} +.caml-example .ocaml{ + overflow-x:auto; +} +li code,p code{ + background-color:#f6f8fa; + color:#0d2b3e; + border-radius:3px; + padding:0 .3ex +} +.pre .code,.pre.code,pre code{ + background-color:inherit +} +p a>code{ + color:#92370a} +.pre code.ocaml,.pre.code.ocaml,pre code.ocaml{ + font-size:.893rem} +.keyword,.ocamlkeyword{ + font-weight:500} +section+section{ + margin-top:25px} + +/* Table of Contents in the Left-hand sidebar */ +nav.toc{ + @include nav-toc; + &.brand{ + @include brand; + } + .toc_title{ + display:block; + margin:.5em 0 1.414em} +/* .toc_title a{ */ +/* color:#777; */ +/* font-size:1em; */ +/* line-height:1.2; */ + /* font-weight:500} */ + +} +.tableau { + table { + border-collapse: collapse; + } + td { + background:#f8f7f6; + border:1px solid #ccc; + padding-left:3px; + padding-right:3px; + } +} + +pre{ + background:linear-gradient(to left,#fff 0,#ede8e5 100%) +} +code.caml-output.ok,div.caml-output.ok{ + color:#045804 +} +code.caml-output.error,div.caml-output.error{ + color:#ff4500; + white-space:normal +} +.chapter span,.tutorial span,.maintitle h1 span{ + color:$logocolor +} +h1 span{ + color: #d28853; +} +blockquote.quote{ + margin:0; + /*font-size: smaller;*/ + hr{ + display:none; + } +} +#part-menu{ + font-family:"Fira Sans"; + text-align:right; + list-style:none; + overflow-y:hidden; + transition:height 0.3s; +} +#part-menu li.active a{ + color:#000; + &::before{@include caret;} +} +span.c003{ + color:#564233; + font-family:"Fira Mono",courier; + background-color:#f3ece6; + border-radius:6px +} +div.caml-example.toplevel code.caml-input::before, +div.caml-example.toplevel div.caml-input::before{ + content:"#"; + color:#888 +} +span.c004{ + color:#888 +} +span.c006{ + font-weight:700; + color:#564233; + font-family:"Fira Mono",courier; +} +span.c009{ + font-style:italic; + background-color:#f3ece6; + border-radius:6px +} +span.authors.c009{ + background-color:inherit +} +span.c013{ + font-weight:700 +} +.caml-input{ + span.ocamlkeyword{ + font-weight:500; + color:#444 + } + span.ocamlhighlight{ + font-weight:500; + text-decoration:underline + } + span.id{ + color:#523b74 + } + span.ocamlstring,.caml-input span.string{ + color:#df5000 + } + span.comment, .caml-input span.ocamlcomment{ + color:#969896 + } +} +.ocaml span.ocamlerror{ + font-weight:500 +} + + +/* Mobile */ +@media only screen and (max-width:95ex){ + @include mobile; + @include sidebar-button; + .content #part-menu{ + display:inline-block; + height:0; + width:100%; + } + nav.toc{ + @include nav-toc-mobile; + } + header{ + @include header-mobile; + } +} diff --git a/manual/manual/html_processing/scss/style.scss b/manual/manual/html_processing/scss/style.scss new file mode 100644 index 00000000..ff89b375 --- /dev/null +++ b/manual/manual/html_processing/scss/style.scss @@ -0,0 +1,1075 @@ +// SOURCE FILE + +/* If the above line does not say "SOURCE FILE", then do not edit. It */ +/* means this file is generated from [sass style.scss] */ + +/* CSS file for the Ocaml API. San Vu Ngoc 2019 */ + +// TODO: the ocamldoc output of Functors like in +// compilerlibref/4.08/Arg_helper.Make.html +// is not easy to style... without breaking other tables. + +@import "common"; +@charset "UTF-8"; + +// tables are difficult to style, be careful. +// These settings should apply to the main index tables +// (like "index_values.html"), which do not have any particular class. +// These tables have two columns. +.api>table { + word-break: break-word; + // this is unfortunately due to some very long names in Internal modules + td.module, + td:first-child { + width: 33%; + } + td:nth-child(2) { + width: 65%; + } + td[align="left"] { + // for the "Parameter" column of module signatures like + // Arg_helper.Make.html, which unfortunately have no class + // either. + word-break: normal; + } + td[align="left"]:first-child { + width: 1%; + } +} + +.api { + // font-size: 16px; + // font-family: "Fira Sans", Helvetica, Arial, sans-serif; + // text-align: left; + // color: #333; + // background: #FFFFFF; + table { + // tables are difficult to style, be careful + border-collapse: collapse; + border-spacing: 0; + thead { + background: rgb(228, 217, 211); + } + /* must be same as
    : */
    +	background: linear-gradient(to left, white 0%, rgb(237, 232, 229) 100%);
    +	width: 100%;
    +	td {
    +	    padding-left: 1ex;
    +	    padding-right: 1ex;
    +	    /*float: left;*/
    +	}
    +	/* add some room at the end of the table */
    +	tr:last-child td {
    +	    padding-bottom: 7px;
    +	}
    +    }
    +    // Tables are used for describing types, in particular union types:
    +    table.typetable {
    +	width: 100%;
    +	word-break: normal;
    +	box-shadow: none;
    +	td {
    +	    float: left;
    +	}
    +	td:nth-child(2) {
    +	    width: 37%;
    +	    code {
    +		white-space: pre-line;
    +	    }
    +	}
    +	td:last-child {
    +	    width: calc(100% - 1.3em);
    +	    // cf: CamlinternalFormatBasics.html
    +	    // the 1.3em is related to the 1em below
    +	}
    +	td:first-child {
    +	    width: 1em;
    +	}
    +	td:nth-child(4).typefieldcomment {
    +	    /* this should be the column with the type */
    +	    width: 60%;
    +	    /* not optimal, see: Format.html#symbolic
    +	    but leaving it automatic is not always good either: see: Arg.html */
    +	}
    +    }
    +
    +    // for functor signature
    +    table.paramstable {
    +	word-break: normal;
    +	td {
    +	    code {
    +		white-space: pre-wrap;
    +	    }	    
    +	}
    +	td:first-child, td:nth-child(2) {
    +	    width: 1em; // second column should contain only
    +			// ":". First one will adapt to size.
    +	}	
    +    }
    +    
    +    .sig_block {
    +	border-left: 4px solid #e69c7f;
    +	padding-left: 1em;
    +	background: linear-gradient(to left, white 0%, rgb(237, 232, 229) 100%);
    +	// PROBLEM the sig_block ends too soon, it should actually
    +	// include the "end)" line ==> REPORT THIS
    +	// (eg: compilerlibref/Arg_helper.html)
    +	pre {
    +	    margin-top: 0;
    +	    background: none;
    +	    border-left: 0;
    +	}
    +    }
    +    pre .sig_block {
    +	margin-bottom: 0; // see above
    +	border-left: 0;
    +    }
    +	
    +    *, *:before, *:after { 
    +	box-sizing: border-box; 
    +    }
    +    
    +    @include content-frame;
    +
    +    /* Basic markup elements */
    +    
    +    b, strong {
    +	font-weight: 600;
    +    }
    +    i, em {
    +	font-style: italic;
    +    }
    +    sup {
    +	vertical-align: super;
    +    }
    +    sub {
    +	vertical-align: sub;
    +    }
    +    sup, sub {
    +	font-size: 12px;
    +	line-height: 0;
    +	margin-left: 0.2ex;
    +    }
    +    pre {
    +	margin-top: 0.8em;
    +	margin-bottom: 0;
    +    }
    +    p, ul, ol {
    +	margin-top: 0.5em;
    +	margin-bottom: 1em;
    +    }
    +    ul, ol {
    +	list-style-position: outside
    +    }
    +    ul>li {
    +	margin-left: 22px;
    +    }
    +    ol>li {
    +	margin-left: 27.2px;
    +    }
    +    li>*:first-child {
    +	margin-top: 0
    +    }
    +
    +    /* Text alignements, this should be forbidden. */
    +
    +    .left {
    +	text-align: left;
    +    }
    +    .right {
    +	text-align: right;
    +    }
    +    .center {
    +	text-align: center;
    +    }
    +    /* Links and anchors */
    +    a {
    +	text-decoration: none;
    +	color: #92370A;
    +	/* box-shadow: 0 1px 0 0 #d8b68b; */
    +    }
    +    a:hover {
    +	box-shadow: 0 1px 0 0 #92370A;
    +    }
    +    td a:hover {
    +	background: white;
    +    }
    +    /* Linked highlight */
    +    *:target {
    +	/*box-shadow: 0 0px 0 1px rgba(255, 215, 181, 0.8) !important;*/
    +	border-radius: 1px;
    +	/*border-bottom: 4px solid rgb(255, 215, 181);*/
    +	box-shadow: 0 4px 0 0px rgb(255, 215, 181);
    +	z-index: 0;
    +	@if $ocamlorg {
    +	    /* Because of fixed banner in the ocaml.org site, we have to offset the targets. See https://stackoverflow.com/questions/10732690/offsetting-an-html-anchor-to-adjust-for-fixed-header */
    +	    padding-top: 85px;
    +	    margin-top: -85px;
    +	}
    +    }
    +
    +    
    +    h2:target {
    +	/* background: linear-gradient(to bottom, rgb(253, 252, 252) 0%, rgba(255, 215, 181, 0.3) 100%) !important; */
    +	/*	transition: 300ms; this prevents margin-top:-80 to work... */
    +    }
    +
    +    *:hover>a.section-anchor {
    +	visibility: visible;
    +    }
    +
    +    a.section-anchor:before {
    +	content: "#"
    +    }
    +
    +    a.section-anchor:hover {
    +	box-shadow: none;
    +	text-decoration: none;
    +	color: #555;
    +    }
    +
    +    a.section-anchor {
    +	visibility: hidden;
    +	position: absolute;
    +	/* top: 0px; */
    +	/* margin-left: -3ex; */
    +	margin-left: -1.3em;
    +	font-weight: normal;
    +	font-style: normal;
    +	padding-right: 0.4em;
    +	padding-left: 0.4em;
    +	/* To remain selectable */
    +	color: #d5d5d5;
    +    }
    +
    +    .spec > a.section-anchor {
    +	margin-left: -2.3em;
    +	padding-right: 0.9em;
    +    }
    +
    +    .xref-unresolved {
    +	color: #92370A
    +    }
    +    .xref-unresolved:hover {
    +	box-shadow: 0 1px 0 0 #CC6666;
    +    }
    +
    +    /* Section and document divisions.
    +    Until at least 4.03 many of the modules of the stdlib start at .h7,
    +    we restart the sequence there like h2  */
    +
    +       h1, h2, h3, h4, h5, h6, .h7, .h8, .h9, .h10 {
    +	font-family: "Fira Sans", Helvetica, Arial, sans-serif;
    +	font-weight: 400;
    +	margin: 0.5em 0 0.5em 0;
    +	padding-top: 0.1em;
    +	line-height: 1.2;
    +	overflow-wrap: break-word;
    +    }
    +
    +    h1 {
    +	margin-top: 1.214em;
    +	margin-bottom: 19px;
    +	font-weight: 500;
    +	font-size: 1.953em;
    +	box-shadow: 0 1px 0 0 #ddd;
    +    }
    +
    +    h2 {
    +	font-size: 1.563em;
    +	margin: 1em 0 1em 0
    +    }
    +
    +    h3 {
    +	font-size: 1.25em;
    +    }
    +
    +    small, .font_small {
    +	font-size: 0.8em;
    +    }
    +
    +    h1 code, h1 tt {
    +	font-size: inherit;
    +	font-weight: inherit;
    +    }
    +
    +    h2 code, h2 tt {
    +	font-size: inherit;
    +	font-weight: inherit;
    +    }
    +
    +    h3 code, h3 tt {
    +	font-size: inherit;
    +	font-weight: inherit;
    +    }
    +
    +    h3 code, h3 tt {
    +	font-size: inherit;
    +	font-weight: inherit;
    +    }
    +
    +    h4 {
    +	font-size: 1.12em;
    +    }
    +
    +
    +    /* Preformatted and code */
    +
    +    tt, code, pre {
    +	font-family: "Fira Mono", courier;
    +	font-weight: 400;
    +    }
    +
    +    pre {
    +	border-left: 4px solid #e69c7f;
    +	white-space: pre-wrap;
    +	word-wrap: break-word;
    +	padding-left: 1ex;
    +    }
    +
    +    p code, li code { /* useful ? */
    +	background-color: #ebf2f9;  /*#f6f8fa;*/
    +	color: #0d2b3e;
    +	border-radius: 3px;
    +	padding: 0 0.3ex;
    +	white-space: pre-wrap; // utile seulement dans la table index_values? (attention à bootstrap.css)
    +    }
    +
    +    pre code {
    +	background-color: inherit;
    +    }
    +
    +    p a > code {
    +	color: #92370A;
    +    }
    +
    +    /* Code blocks (e.g. Examples) */
    +
    +    pre code.ocaml {
    +	font-size: 0.893rem;
    +    }
    +
    +    /* Code lexemes */
    +
    +    .keyword {
    +	font-weight: 500;
    +	color: inherit;
    +    }
    +
    +    /* Module member specification */
    +
    +    .spec:not(.include), .spec.include details summary {
    +	background: linear-gradient(to left, rgb(253, 252, 252) 0%, rgb(234, 246, 250) 100%);
    +	border-radius: 3px;
    +	border-left: 4px solid #5c9cf5;
    +	border-right: 5px solid transparent;
    +	padding: 0.35em 0.5em;
    +    }
    +
    +    .spec.include details summary:hover {
    +	background-color: #ebeff2;
    +    }
    +
    +    dl, div.spec, .doc, aside {
    +	margin-bottom: 20px;
    +    }
    +
    +    dl > dd {
    +	padding: 0.5em;
    +    }
    +
    +    dd> :first-child {
    +	margin-top: 0;
    +    }
    +
    +    dd > p:first-child > code:first-child {
    +	color: teal;
    +    }
    +
    +    dl:last-child, dd> :last-child, aside:last-child, article:last-child {
    +	margin-bottom: 0;
    +    }
    +
    +    dt+dt {
    +	margin-top: 15px;
    +    }
    +
    +    section+section, section > header + dl {
    +	margin-top: 25px;
    +    }
    +
    +    .spec.type .variant {
    +	margin-left: 2ch;
    +    }
    +    .spec.type .variant p {
    +	margin: 0;
    +	font-style: italic;
    +    }
    +    .spec.type .record {
    +	margin-left: 2ch;
    +    }
    +    .spec.type .record p {
    +	margin: 0;
    +	font-style: italic;
    +    }
    +
    +    div.def {
    +	margin-top: 0;
    +	text-indent: -2ex;
    +	padding-left: 2ex;
    +    }
    +
    +    div.def+div.doc {
    +	margin-left: 1ex;
    +	margin-top: 2.5px
    +    }
    +
    +    div.doc>*:first-child {
    +	margin-top: 0;
    +    }
    +
    +    /* The elements other than heading should be wrapped in 
    " ; - print_DEBUG "html#html_of_class : info" ; ( if complete then self#html_of_info ~cls: "class top" ~indent: true diff --git a/ocamldoc/odoc_latex.ml b/ocamldoc/odoc_latex.ml index 621ceec8..ca669d76 100644 --- a/ocamldoc/odoc_latex.ml +++ b/ocamldoc/odoc_latex.ml @@ -15,8 +15,6 @@ (** Generation of LaTeX documentation. *) -let print_DEBUG s = print_string s ; print_newline () - open Odoc_info open Value open Type diff --git a/ocamldoc/odoc_lexer.mll b/ocamldoc/odoc_lexer.mll index 8749d123..bb41cb92 100644 --- a/ocamldoc/odoc_lexer.mll +++ b/ocamldoc/odoc_lexer.mll @@ -44,11 +44,8 @@ let blank = "[ \013\009\012]" (** The nested comments level. *) let comments_level = ref 0 -let print_DEBUG2 s = print_string s; print_newline () - (** This function returns the given string without the leading and trailing blanks.*) let remove_blanks s = - print_DEBUG2 ("remove_blanks "^s); let l = Str.split_delim (Str.regexp "\n") s in let l2 = let rec iter liste = @@ -57,7 +54,6 @@ let remove_blanks s = let h2 = Str.global_replace (Str.regexp ("^"^blank^"+")) "" h in if h2 = "" then ( - print_DEBUG2 (h^" n'a que des blancs"); (* we remove this line and must remove leading blanks of the next one *) iter q ) @@ -75,7 +71,6 @@ let remove_blanks s = let h2 = Str.global_replace (Str.regexp (blank^"+$")) "" h in if h2 = "" then ( - print_DEBUG2 (h^" n'a que des blancs"); (* we remove this line and must remove trailing blanks of the next one *) iter q ) @@ -294,7 +289,6 @@ and elements = parse | [ '\010' ] { incr line_number; incr Odoc_comments_global.nb_chars; - print_DEBUG2 "newline"; elements lexbuf } | "@" { @@ -306,7 +300,6 @@ and elements = parse let s = Lexing.lexeme lexbuf in Odoc_comments_global.nb_chars := !Odoc_comments_global.nb_chars + (String.length s); let s2 = String.sub s 1 ((String.length s) - 1) in - print_DEBUG2 s2; match s2 with "param" -> T_PARAM @@ -339,7 +332,6 @@ and elements = parse let s = Lexing.lexeme lexbuf in let s = Str.global_replace (Str.regexp_string "\\@") "@" s in let s = remove_blanks s in - print_DEBUG2 ("Desc "^s); Desc s } | eof diff --git a/ocamldoc/odoc_module.ml b/ocamldoc/odoc_module.ml index 1b9cb180..c61c8f71 100644 --- a/ocamldoc/odoc_module.ml +++ b/ocamldoc/odoc_module.ml @@ -17,8 +17,6 @@ module String = Misc.Stdlib.String (** Representation and manipulation of modules and module types. *) -let print_DEBUG s = print_string s ; print_newline () - module Name = Odoc_name (** To keep the order of elements in a module. *) @@ -253,11 +251,8 @@ let module_elements ?(trans=true) m = *) let rec module_elements visited ?(trans=true) m = let rec iter_kind = function - Module_struct l -> - print_DEBUG "Odoc_module.module_elements: Module_struct"; - l + Module_struct l -> l | Module_alias ma -> - print_DEBUG "Odoc_module.module_elements: Module_alias"; if trans then match ma.ma_module with None -> [] @@ -270,18 +265,14 @@ let module_elements ?(trans=true) m = else [] | Module_functor (_, k) - | Module_apply (k, _) -> - print_DEBUG "Odoc_module.module_elements: Module_functor ou Module_apply"; - iter_kind k + | Module_apply (k, _) -> iter_kind k | Module_with (tk,_) -> - print_DEBUG "Odoc_module.module_elements: Module_with"; module_type_elements ~trans: trans { mt_name = "" ; mt_info = None ; mt_type = None ; mt_is_interface = false ; mt_file = "" ; mt_kind = Some tk ; mt_loc = Odoc_types.dummy_loc ; } | Module_constraint (k, _tk) -> - print_DEBUG "Odoc_module.module_elements: Module_constraint"; (* FIXME : use k or tk ? *) module_elements visited ~trans: trans { m_name = "" ; diff --git a/ocamldoc/odoc_parameter.ml b/ocamldoc/odoc_parameter.ml index 32aa0dec..48918358 100644 --- a/ocamldoc/odoc_parameter.ml +++ b/ocamldoc/odoc_parameter.ml @@ -15,8 +15,6 @@ (** Representation and manipulation of method / function / class parameters. *) -let print_DEBUG s = print_string s ; print_newline () - (** Types *) (** Representation of a simple parameter name *) @@ -109,7 +107,6 @@ let type_by_name pi name = (** access to the optional description of a parameter name from an optional info structure.*) let desc_from_info_opt info_opt s = - print_DEBUG "desc_from_info_opt"; match info_opt with None -> None | Some i -> @@ -119,7 +116,4 @@ let desc_from_info_opt info_opt s = try Some (List.assoc s i.Odoc_types.i_params) with - Not_found -> - print_DEBUG ("desc_from_info_opt "^s^" not found in\n"); - List.iter (fun (s, _) -> print_DEBUG s) i.Odoc_types.i_params; - None + Not_found -> None diff --git a/ocamldoc/odoc_parser.mly b/ocamldoc/odoc_parser.mly index f27a9982..da3280ba 100644 --- a/ocamldoc/odoc_parser.mly +++ b/ocamldoc/odoc_parser.mly @@ -20,8 +20,6 @@ let uppercase = "[A-Z\192-\214\216-\222]" let identchar = "[A-Za-z_\192-\214\216-\246\248-\255'0-9]" let blank = "[ \010\013\009\012]" - -let print_DEBUG s = print_string s; print_newline () %} %token Description @@ -101,12 +99,9 @@ param: | _ :: [] -> raise (Failure "usage: @param id description") | id :: _ -> - print_DEBUG ("Identificator "^id); let reg = identchar^"+" in - print_DEBUG ("reg="^reg); if Str.string_match (Str.regexp reg) id 0 then let remain = String.sub s (String.length id) ((String.length s) - (String.length id)) in - print_DEBUG ("T_PARAM Desc remain="^remain); let remain2 = Str.replace_first (Str.regexp ("^"^blank^"+")) "" remain in params := !params @ [(id, remain2)] else @@ -135,7 +130,6 @@ before: | _ :: [] -> raise (Failure "usage: @before version description") | id :: _ -> - print_DEBUG ("version "^id); let remain = String.sub s (String.length id) ((String.length s) - (String.length id)) in let remain2 = Str.replace_first (Str.regexp ("^"^blank^"+")) "" remain in before := !before @ [(id, remain2)] @@ -154,9 +148,7 @@ raise_exc: | _ :: [] -> raise (Failure "usage: @raise Exception description") | id :: _ -> - print_DEBUG ("exception "^id); let reg = uppercase^identchar^"*"^"\\(\\."^uppercase^identchar^"*\\)*" in - print_DEBUG ("reg="^reg); if Str.string_match (Str.regexp reg) id 0 then let remain = String.sub s (String.length id) ((String.length s) - (String.length id)) in let remain2 = Str.replace_first (Str.regexp ("^"^blank^"+")) "" remain in diff --git a/ocamldoc/odoc_see_lexer.mll b/ocamldoc/odoc_see_lexer.mll index 1962d50d..5b68a733 100644 --- a/ocamldoc/odoc_see_lexer.mll +++ b/ocamldoc/odoc_see_lexer.mll @@ -14,8 +14,6 @@ (* *) (**************************************************************************) -let print_DEBUG2 s = print_string s ; print_newline () - (** the lexer for special comments. *) open Odoc_parser @@ -27,38 +25,32 @@ let buf = Buffer.create 32 rule main = parse [' ' '\013' '\009' '\012'] + { - print_DEBUG2 "[' ' '\013' '\009' '\012'] +"; main lexbuf } | [ '\010' ] { - print_DEBUG2 " [ '\010' ] "; main lexbuf } | "<" { - print_DEBUG2 "call url lexbuf" ; url lexbuf } | "\"" { - print_DEBUG2 "call doc lexbuf" ; doc lexbuf } | '\'' { - print_DEBUG2 "call file lexbuf" ; file lexbuf } | eof { - print_DEBUG2 "EOF"; EOF } @@ -73,7 +65,6 @@ and url = parse | ([^'>'] | '\n')+">" { let s = Lexing.lexeme lexbuf in - print_DEBUG2 ("([^'>'] | '\n')+ \">\" with "^s) ; See_url (String.sub s 0 ((String.length s) -1)) } diff --git a/ocamldoc/odoc_sig.ml b/ocamldoc/odoc_sig.ml index e7cb90ab..d52dee89 100644 --- a/ocamldoc/odoc_sig.ml +++ b/ocamldoc/odoc_sig.ml @@ -17,9 +17,6 @@ open Asttypes open Types - -let print_DEBUG s = print_string s ; print_newline ();; - open Odoc_parameter open Odoc_value open Odoc_type @@ -391,8 +388,14 @@ module Analyser = | Cstr_record l -> Cstr_record (List.map (get_field env name_comment_list) l) in + let vc_name = match constructor_name with + | "::" -> + (* The only infix constructor is always printed (::) *) + "(::)" + | s -> s + in { - vc_name = constructor_name ; + vc_name; vc_args; vc_ret = Option.map (Odoc_env.subst_type env) ret_type; vc_text = comment_opt @@ -954,23 +957,6 @@ module Analyser = pos_limit2 type_decl in -(* DEBUG *) begin -(* DEBUG *) let comm = -(* DEBUG *) match assoc_com with -(* DEBUG *) | None -> "sans commentaire" -(* DEBUG *) | Some c -> Odoc_misc.string_of_info c -(* DEBUG *) in -(* DEBUG *) print_DEBUG ("Type "^name.txt^" : "^comm); -(* DEBUG *) let f_DEBUG (name, c_opt) = -(* DEBUG *) let comm = -(* DEBUG *) match c_opt with -(* DEBUG *) | None -> "sans commentaire" -(* DEBUG *) | Some c -> Odoc_misc.string_of_info c -(* DEBUG *) in -(* DEBUG *) print_DEBUG ("constructor/field "^name^": "^comm) -(* DEBUG *) in -(* DEBUG *) List.iter f_DEBUG name_comment_list; -(* DEBUG *) end; (* get the information for the type in the signature *) let sig_type_decl = try Signature_search.search_type table name.txt @@ -1062,23 +1048,6 @@ module Analyser = pos_limit2 type_decl in -(* DEBUG *) begin -(* DEBUG *) let comm = -(* DEBUG *) match assoc_com with -(* DEBUG *) | None -> "sans commentaire" -(* DEBUG *) | Some c -> Odoc_misc.string_of_info c -(* DEBUG *) in -(* DEBUG *) print_DEBUG ("Type "^name.txt^" : "^comm); -(* DEBUG *) let f_DEBUG (name, c_opt) = -(* DEBUG *) let comm = -(* DEBUG *) match c_opt with -(* DEBUG *) | None -> "sans commentaire" -(* DEBUG *) | Some c -> Odoc_misc.string_of_info c -(* DEBUG *) in -(* DEBUG *) print_DEBUG ("constructor/field "^name^": "^comm) -(* DEBUG *) in -(* DEBUG *) List.iter f_DEBUG name_comment_list; -(* DEBUG *) end; (* get the information for the type in the signature *) let sig_type_decl = try Signature_search.search_type table name.txt @@ -1218,9 +1187,7 @@ module Analyser = (* FIXME : can this be a Tmty_ident? in this case, we wouldn't have the signature *) Types.Mty_signature s -> Odoc_env.add_signature e complete_name ~rel: name s - | _ -> - print_DEBUG "not a Tmty_signature"; - e + | _ -> e ) env decls @@ -1589,7 +1556,6 @@ module Analyser = let loc_start = Loc.start loc in let loc_end = Loc.end_ loc in let mp_type_code = get_string_of_file loc_start loc_end in - print_DEBUG (Printf.sprintf "mp_type_code=%s" mp_type_code); match sig_module_type with Types.Mty_functor (param, body_module_type) -> let mp_name, mp_kind = @@ -1689,7 +1655,6 @@ module Analyser = let loc_start = Loc.start loc in let loc_end = Loc.end_ loc in let mp_type_code = get_string_of_file loc_start loc_end in - print_DEBUG (Printf.sprintf "mp_type_code=%s" mp_type_code); let mp_name, mp_kind = match param2, param with Parsetree.Named (_, pmty), Types.Named (Some ident, mty) -> @@ -1744,7 +1709,6 @@ module Analyser = match parse_class_type.Parsetree.pcty_desc, sig_class_type with (Parsetree.Pcty_constr (_, _) (*of Longident.t * core_type list *), Types.Cty_constr (p, typ_list, _) (*of Path.t * type_expr list * class_type*)) -> - print_DEBUG "Cty_constr _"; let path_name = Name.from_path p in let name = Odoc_env.full_class_or_class_type_name env path_name in let k = @@ -1795,7 +1759,6 @@ module Analyser = match parse_class_type.Parsetree.pcty_desc, sig_class_type with (Parsetree.Pcty_constr (_, _) (*of Longident.t * core_type list *), Types.Cty_constr (p, typ_list, _) (*of Path.t * type_expr list * class_type*)) -> - print_DEBUG "Cty_constr _"; Class_type { cta_name = Odoc_env.full_class_or_class_type_name env (Name.from_path p) ; diff --git a/ocamldoc/odoc_text_lexer.mll b/ocamldoc/odoc_text_lexer.mll index f503b527..b13d72cb 100644 --- a/ocamldoc/odoc_text_lexer.mll +++ b/ocamldoc/odoc_text_lexer.mll @@ -43,9 +43,6 @@ let description = ref "" let blank = "[ \013\009\012]" - -let print_DEBUG s = print_string s; print_newline () - (** this flag indicates whether we're in a string between begin_code and end_code tokens, to remember the number of open '[' and handle ']' correctly. *) let open_brackets = ref 0 @@ -189,7 +186,6 @@ rule main = parse | end { - print_DEBUG "end"; incr_cpts lexbuf ; if !verb_mode || !target_mode || !code_pre_mode || (!open_brackets >= 1) then @@ -202,7 +198,6 @@ rule main = parse } | begin_title { - print_DEBUG "begin_title"; incr_cpts lexbuf ; if !verb_mode || !target_mode || !code_pre_mode || (!open_brackets >= 1) || !ele_ref_mode then @@ -313,7 +308,6 @@ rule main = parse } | begin_list { - print_DEBUG "LIST"; incr_cpts lexbuf ; if !verb_mode || !target_mode || !code_pre_mode || (!open_brackets >= 1) || !ele_ref_mode then @@ -332,7 +326,6 @@ rule main = parse } | begin_item { - print_DEBUG "ITEM"; incr_cpts lexbuf ; if !verb_mode || !target_mode || !code_pre_mode || (!open_brackets >= 1) || !ele_ref_mode then @@ -828,7 +821,6 @@ rule main = parse | begin_custom { - print_DEBUG "begin_custom"; incr_cpts lexbuf ; if !verb_mode || !target_mode || !code_pre_mode || (!open_brackets >= 1) || !ele_ref_mode then diff --git a/ocamldoc/odoc_text_parser.mly b/ocamldoc/odoc_text_parser.mly index 3d590d45..2b7b2a6b 100644 --- a/ocamldoc/odoc_text_parser.mly +++ b/ocamldoc/odoc_text_parser.mly @@ -23,8 +23,6 @@ let remove_beginning_blanks s = let remove_trailing_blanks s = Str.global_replace (Str.regexp (blank^"+$")) "" s - -let print_DEBUG s = print_string s; print_newline () %} %token END diff --git a/ocamltest/.depend b/ocamltest/.depend index 01a6139e..83262d55 100644 --- a/ocamltest/.depend +++ b/ocamltest/.depend @@ -1,25 +1,3 @@ -run_unix.$(O): run_unix.c run.h ../runtime/caml/misc.h \ - ../runtime/caml/config.h ../runtime/caml/m.h ../runtime/caml/s.h \ - run_common.h -run_stubs.$(O): run_stubs.c run.h ../runtime/caml/misc.h \ - ../runtime/caml/config.h ../runtime/caml/m.h ../runtime/caml/s.h \ - ../runtime/caml/mlvalues.h ../runtime/caml/misc.h \ - ../runtime/caml/domain_state.h ../runtime/caml/mlvalues.h \ - ../runtime/caml/domain_state.tbl ../runtime/caml/memory.h \ - ../runtime/caml/gc.h ../runtime/caml/major_gc.h \ - ../runtime/caml/freelist.h ../runtime/caml/minor_gc.h \ - ../runtime/caml/address_class.h ../runtime/caml/domain.h \ - ../runtime/caml/io.h ../runtime/caml/osdeps.h ../runtime/caml/memory.h -ocamltest_stdlib_stubs.$(O): ocamltest_stdlib_stubs.c \ - ../runtime/caml/config.h ../runtime/caml/m.h ../runtime/caml/s.h \ - ../runtime/caml/mlvalues.h ../runtime/caml/config.h \ - ../runtime/caml/misc.h ../runtime/caml/domain_state.h \ - ../runtime/caml/mlvalues.h ../runtime/caml/domain_state.tbl \ - ../runtime/caml/memory.h ../runtime/caml/gc.h ../runtime/caml/major_gc.h \ - ../runtime/caml/freelist.h ../runtime/caml/minor_gc.h \ - ../runtime/caml/address_class.h ../runtime/caml/domain.h \ - ../runtime/caml/alloc.h ../runtime/caml/signals.h \ - ../runtime/caml/osdeps.h ../runtime/caml/memory.h actions.cmo : \ variables.cmi \ result.cmi \ @@ -243,10 +221,12 @@ ocaml_directories.cmi : ocaml_files.cmo : \ ocamltest_stdlib.cmi \ ocamltest_config.cmi \ + ocaml_directories.cmi \ ocaml_files.cmi ocaml_files.cmx : \ ocamltest_stdlib.cmx \ ocamltest_config.cmx \ + ocaml_directories.cmx \ ocaml_files.cmi ocaml_files.cmi : ocaml_filetypes.cmo : \ @@ -366,10 +346,20 @@ ocamltest_config.cmx : \ ocamltest_config.cmi ocamltest_config.cmi : ocamltest_stdlib.cmo : \ + ocamltest_unix.cmi \ + ocamltest_config.cmi \ ocamltest_stdlib.cmi ocamltest_stdlib.cmx : \ + ocamltest_unix.cmx \ + ocamltest_config.cmx \ ocamltest_stdlib.cmi -ocamltest_stdlib.cmi : +ocamltest_stdlib.cmi : \ + ocamltest_unix.cmi +ocamltest_unix.cmo : \ + ocamltest_unix.cmi +ocamltest_unix.cmx : \ + ocamltest_unix.cmi +ocamltest_unix.cmi : options.cmo : \ variables.cmi \ tests.cmi \ diff --git a/ocamltest/Makefile b/ocamltest/Makefile index eb7e7587..ea28f4ab 100644 --- a/ocamltest/Makefile +++ b/ocamltest/Makefile @@ -17,8 +17,7 @@ ROOTDIR = .. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common +include $(ROOTDIR)/Makefile.common include $(ROOTDIR)/Makefile.best_binaries ifeq "$(filter str,$(OTHERLIBRARIES))" "" @@ -34,8 +33,16 @@ else endif ifeq "$(filter $(UNIXLIB),$(OTHERLIBRARIES))" "" + ocamltest_unix := dummy + unix_name := + unix_path := unix := None + unix_include := else + ocamltest_unix := real + unix_name := unix + unix_path := $(ROOTDIR)/otherlibs/$(UNIXLIB) + unix_include := -I $(unix_path) $(EMPTY) ifeq "$(UNIX_OR_WIN32)" "win32" unix := Some false else @@ -44,13 +51,11 @@ else endif ifeq "$(UNIX_OR_WIN32)" "win32" - ocamlsrcdir := $(shell echo "$(abspath $(shell pwd)/..)"|cygpath -w -f - \ - | sed 's/\\/\\\\\\\\/g') - mkexe := $(MKEXE_ANSI) -link $(OC_LDFLAGS) + ocamlsrcdir := $(shell echo "$(abspath $(shell pwd)/..)" | cygpath -w -f -) else ocamlsrcdir := $(abspath $(shell pwd)/..) - mkexe := $(MKEXE) endif +mkexe := $(MKEXE) ifeq "$(TOOLCHAIN)" "msvc" CPP := $(CPP) 2> nul @@ -80,7 +85,17 @@ endif OC_CPPFLAGS += -I$(ROOTDIR)/runtime -DCAML_INTERNALS -run := run_$(UNIX_OR_WIN32) +ifdef UNIX_OR_WIN32 +run_source := run_$(UNIX_OR_WIN32).c +else +ifneq "$(filter-out $(CLEAN_TARGET_NAMES), $(MAKECMDGOALS))" "" +$(warning The variable UNIX_OR_WIN32 is not defined. \ + It must be set (usually by $(ROOTDIR)/configure), \ + or only clean rules are supported.) +endif +# If we are in a 'clean' rule, we ask for both versions to be cleaned. +run_source := run_unix.c run_win32.c +endif # List of source files from which ocamltest is compiled # (all the different sorts of files are derived from this) @@ -89,10 +104,9 @@ run := run_$(UNIX_OR_WIN32) # which is actually built into the tool but clearly separated from its core core := \ - $(run).c \ - run_stubs.c \ - ocamltest_stdlib_stubs.c \ + $(run_source) run_stubs.c \ ocamltest_config.mli ocamltest_config.ml.in \ + ocamltest_unix.mli ocamltest_unix.ml \ ocamltest_stdlib.mli ocamltest_stdlib.ml \ run_command.mli run_command.ml \ filecompare.mli filecompare.ml \ @@ -160,6 +174,7 @@ parsers := $(filter %.mly,$(sources)) config_files := $(filter %.ml.in,$(sources)) dependencies_generated_prereqs := \ + ocamltest_unix.ml \ $(config_files:.ml.in=.ml) \ $(lexers:.mll=.ml) \ $(parsers:.mly=.mli) $(parsers:.mly=.ml) @@ -179,9 +194,9 @@ flags := -g -nostdlib $(include_directories) \ -strict-sequence -safe-string -strict-formats \ -w +a-4-9-41-42-44-45-48 -warn-error A -ocamlc := $(BEST_OCAMLC) $(flags) +ocamlc = $(BEST_OCAMLC) $(flags) -ocamlopt := $(BEST_OCAMLOPT) $(flags) +ocamlopt = $(BEST_OCAMLOPT) $(flags) ocamldep := $(BEST_OCAMLDEP) depflags := -slash @@ -189,7 +204,7 @@ depincludes := ocamllex := $(BEST_OCAMLLEX) -ocamlyacc := $(ROOTDIR)/yacc/ocamlyacc +ocamlyacc := $(ROOTDIR)/yacc/ocamlyacc$(EXE) ocamlcdefaultflags := @@ -204,22 +219,29 @@ opt.opt: allopt compdeps_names=ocamlcommon ocamlbytecomp compdeps_paths=$(addprefix $(ROOTDIR)/compilerlibs/,$(compdeps_names)) -compdeps_byte=$(addsuffix .cma,$(compdeps_paths)) -compdeps_opt=$(addsuffix .cmxa,$(compdeps_paths)) +deps_paths=$(compdeps_paths) $(addprefix $(unix_path)/,$(unix_name)) +deps_byte=$(addsuffix .cma,$(deps_paths)) +deps_opt=$(addsuffix .cmxa,$(deps_paths)) -ocamltest$(EXE): $(compdeps_byte) $(bytecode_modules) - $(ocamlc_cmd) -custom -o $@ $^ +$(eval $(call PROGRAM_SYNONYM,ocamltest)) -%.cmo: %.ml $(compdeps_byte) +ocamltest_unix.%: flags+=$(unix_include) -opaque + +ocamltest$(EXE): $(deps_byte) $(bytecode_modules) + $(ocamlc_cmd) $(unix_include)-custom -o $@ $^ + +%.cmo: %.ml $(deps_byte) $(ocamlc) -c $< -ocamltest.opt$(EXE): $(compdeps_opt) $(native_modules) - $(ocamlopt_cmd) -o $@ $^ +$(eval $(call PROGRAM_SYNONYM,ocamltest.opt)) + +ocamltest.opt$(EXE): $(deps_opt) $(native_modules) + $(ocamlopt_cmd) $(unix_include)-o $@ $^ -%.cmx: %.ml $(compdeps_opt) +%.cmx: %.ml $(deps_opt) $(ocamlopt) -c $< -%.cmi: %.mli $(compdeps_byte) +%.cmi: %.mli $(deps_byte) $(ocamlc) -c $< %.ml %.mli: %.mly @@ -228,44 +250,49 @@ ocamltest.opt$(EXE): $(compdeps_opt) $(native_modules) %.ml: %.mll $(ocamllex) $(OCAMLLEX_FLAGS) $< +ocamltest_unix.ml: ocamltest_unix_$(ocamltest_unix).ml + echo '# 1 "$^"' > $@ + cat $^ >> $@ + ocamltest_config.ml: ocamltest_config.ml.in Makefile ../Makefile.config - sed \ - -e 's|@@AFL_INSTRUMENT@@|$(AFL_INSTRUMENT)|' \ - -e 's|@@RUNTIMEI@@|$(RUNTIMEI)|' \ - -e 's|@@ARCH@@|$(ARCH)|' \ - -e 's|@@SHARED_LIBRARIES@@|$(SUPPORTS_SHARED_LIBRARIES)|' \ - -e 's|@@UNIX@@|$(unix)|' \ - -e 's|@@SYSTHREADS@@|$(systhreads)|' \ - -e 's|@@STR@@|$(str)|' \ - -e 's|@@SYSTEM@@|$(SYSTEM)|' \ - -e 's|@@CPP@@|$(CPP)|' \ - -e 's|@@OCAMLCDEFAULTFLAGS@@|$(ocamlcdefaultflags)|' \ - -e 's|@@OCAMLOPTDEFAULTFLAGS@@|$(ocamloptdefaultflags)|' \ - -e 's|@@OCAMLSRCDIR@@|$(ocamlsrcdir)|' \ - -e 's|@@FLAMBDA@@|$(FLAMBDA)|' \ - -e 's|@@SPACETIME@@|$(WITH_SPACETIME)|' \ - -e 's|@@FORCE_SAFE_STRING@@|$(FORCE_SAFE_STRING)|' \ - -e 's|@@FLAT_FLOAT_ARRAY@@|$(FLAT_FLOAT_ARRAY)|' \ - -e 's|@@OCAMLDOC@@|$(WITH_OCAMLDOC)|' \ - -e 's|@@OCAMLDEBUG@@|$(WITH_OCAMLDEBUG)|' \ - -e 's|@@OBJEXT@@|$(O)|' \ - -e 's|@@ASMEXT@@|$(S)|' \ - -e 's|@@NATIVE_DYNLINK@@|$(NATDYNLINK)|' \ - -e 's|@@SHARED_LIBRARY_CFLAGS@@|$(SHAREDLIB_CFLAGS)|' \ - -e 's|@@SHAREDOBJEXT@@|$(SO)|' \ - -e 's|@@CSC@@|$(CSC)|' \ - -e 's|@@CSCFLAGS@@|$(CSCFLAGS)|' \ - -e 's|@@MKDLL@@|$(MKDLL)|' \ - -e 's|@@MKEXE@@|$(mkexe)|' \ - -e 's|@@BYTECCLIBS@@|$(BYTECCLIBS)|' \ - -e 's|@@NATIVECCLIBS@@|$(NATIVECCLIBS)|' \ - -e 's|@@ASM@@|$(ASM)|' \ - -e 's|@@CC@@|$(CC)|' \ - -e 's|@@CFLAGS@@|$(OC_CFLAGS)|' \ - -e 's|@@CCOMPTYPE@@|$(CCOMPTYPE)|' \ - -e 's|@@WINDOWS_UNICODE@@|$(WINDOWS_UNICODE)|' \ - -e 's|@@FUNCTION_SECTIONS@@|$(FUNCTION_SECTIONS)|' \ - $< > $@ + sed $(call SUBST,AFL_INSTRUMENT) \ + $(call SUBST,RUNTIMEI) \ + $(call SUBST,ARCH) \ + $(call SUBST,SUPPORTS_SHARED_LIBRARIES) \ + $(call SUBST,unix) \ + $(call SUBST,systhreads) \ + $(call SUBST,str) \ + $(call SUBST,SYSTEM) \ + $(call SUBST_STRING,CPP) \ + $(call SUBST_STRING,ocamlcdefaultflags) \ + $(call SUBST_STRING,ocamloptdefaultflags) \ + $(call SUBST_STRING,ocamlsrcdir) \ + $(call SUBST,FLAMBDA) \ + $(call SUBST,FORCE_SAFE_STRING) \ + $(call SUBST,FLAT_FLOAT_ARRAY) \ + $(call SUBST,WITH_OCAMLDOC) \ + $(call SUBST,WITH_OCAMLDEBUG) \ + $(call SUBST,O) \ + $(call SUBST,S) \ + $(call SUBST,NATIVE_COMPILER) \ + $(call SUBST,NATDYNLINK) \ + $(call SUBST_STRING,SHAREDLIB_CFLAGS) \ + $(call SUBST,SO) \ + $(call SUBST_STRING,CSC) \ + $(call SUBST_STRING,CSCFLAGS) \ + $(call SUBST_STRING,EXE) \ + $(call SUBST_STRING,MKDLL) \ + $(call SUBST_STRING,mkexe) \ + $(call SUBST_STRING,BYTECCLIBS) \ + $(call SUBST_STRING,NATIVECCLIBS) \ + $(call SUBST_STRING,ASM) \ + $(call SUBST_STRING,CC) \ + $(call SUBST_STRING,OC_CFLAGS) \ + $(call SUBST,CCOMPTYPE) \ + $(call SUBST,WINDOWS_UNICODE) \ + $(call SUBST,FUNCTION_SECTIONS) \ + $(call SUBST,NAKED_POINTERS) \ + $< > $@ # Manual @@ -280,21 +307,24 @@ ocamltest.html: ocamltest.org clean: rm -rf ocamltest ocamltest.exe ocamltest.opt ocamltest.opt.exe rm -rf $(c_files:.c=.o) $(c_files:.c=.obj) - rm -rf run_unix.o run_win32.o run_win32.obj rm -rf $(ml_files:.ml=.o) $(ml_files:.ml=.obj) rm -rf $(cmi_files) rm -rf $(cmo_files) rm -rf $(cmx_files) rm -rf $(generated) rm -f ocamltest.html + rm -rf $(DEPDIR) + +ifeq "$(COMPUTE_DEPS)" "true" +include $(addprefix $(DEPDIR)/, $(c_files:.c=.$(D))) +endif + +$(DEPDIR)/%.$(D): %.c | $(DEPDIR) + $(DEP_CC) $(OC_CPPFLAGS) $(CPPFLAGS) $< -MT '$*.$(O)' -MF $@ -ifneq "$(TOOLCHAIN)" "msvc" .PHONY: depend depend: $(dependencies_generated_prereqs) - $(CC) -MM $(OC_CPPFLAGS) $(c_files) \ - | sed -e 's/\.o/.$$(O)/' > .depend $(ocamldep) $(depflags) $(depincludes) $(mli_files) $(ml_files) \ - >> .depend -endif + > .depend -include .depend diff --git a/ocamltest/actions_helpers.ml b/ocamltest/actions_helpers.ml index 6dae89fd..eee65752 100644 --- a/ocamltest/actions_helpers.ml +++ b/ocamltest/actions_helpers.ml @@ -62,14 +62,25 @@ let files env = words_of_variable env Builtin_variables.files let setup_symlinks test_source_directory build_directory files = let symlink filename = + (* Emulate ln -sfT *) let src = Filename.concat test_source_directory filename in - let cmd = "ln -sf " ^ src ^" " ^ build_directory in - Sys.run_system_command cmd in + let dst = Filename.concat build_directory filename in + let () = + if Sys.file_exists dst then + if Sys.win32 && Sys.is_directory dst then + (* Native symbolic links to directories don't disappear with unlink; + doing rmdir here is technically slightly more than ln -sfT would + do *) + Sys.rmdir dst + else + Sys.remove dst + in + Unix.symlink src dst in let copy filename = let src = Filename.concat test_source_directory filename in let dst = Filename.concat build_directory filename in Sys.copy_file src dst in - let f = if Sys.os_type="Win32" then copy else symlink in + let f = if Unix.has_symlink () then symlink else copy in Sys.make_directory build_directory; List.iter f files @@ -122,7 +133,7 @@ let run_cmd in let lst = List.concat (List.map String.words cmd) in let quoted_lst = - if Sys.os_type="Win32" + if Sys.win32 then List.map Filename.maybe_quote lst else lst in let cmd' = String.concat " " quoted_lst in @@ -140,17 +151,29 @@ let run_cmd environment (Environments.to_system_env env) in - Run_command.run { - Run_command.progname = progname; - Run_command.argv = arguments; - Run_command.envp = systemenv; - Run_command.stdin_filename = stdin_filename; - Run_command.stdout_filename = stdout_filename; - Run_command.stderr_filename = stderr_filename; - Run_command.append = append; - Run_command.timeout = timeout; - Run_command.log = log - } + let n = + Run_command.run { + Run_command.progname = progname; + Run_command.argv = arguments; + Run_command.envp = systemenv; + Run_command.stdin_filename = stdin_filename; + Run_command.stdout_filename = stdout_filename; + Run_command.stderr_filename = stderr_filename; + Run_command.append = append; + Run_command.timeout = timeout; + Run_command.log = log + } + in + let dump_file s fn = + if not (Sys.file_is_empty fn) then begin + Printf.fprintf log "### begin %s ###\n" s; + Sys.dump_file log fn; + Printf.fprintf log "### end %s ###\n" s + end + in + dump_file "stdout" stdout_filename; + if stdout_filename <> stderr_filename then dump_file "stderr" stderr_filename; + n let run (log_message : string) diff --git a/ocamltest/builtin_actions.ml b/ocamltest/builtin_actions.ml index 99059c1c..4baf788b 100644 --- a/ocamltest/builtin_actions.ml +++ b/ocamltest/builtin_actions.ml @@ -187,9 +187,15 @@ let function_sections = make "Target supports function sections" "Target does not support function sections") +let naked_pointers = make + "naked_pointers" + (Actions_helpers.pass_or_skip (Ocamltest_config.naked_pointers) + "Runtime system supports naked pointers" + "Runtime system does not support naked pointers") + let has_symlink = make "has_symlink" - (Actions_helpers.pass_or_skip (Sys.has_symlink () ) + (Actions_helpers.pass_or_skip (Unix.has_symlink () ) "symlinks available" "symlinks not available") @@ -224,7 +230,7 @@ let initialize_test_exit_status_variables _log env = ] env let _ = - Environments.register_initializer + Environments.register_initializer Environments.Post "test_exit_status_variables" initialize_test_exit_status_variables; List.iter register [ @@ -257,4 +263,5 @@ let _ = arch_i386; arch_power; function_sections; + naked_pointers ] diff --git a/ocamltest/dune b/ocamltest/dune index ff6cb830..f10cab79 100644 --- a/ocamltest/dune +++ b/ocamltest/dune @@ -22,9 +22,16 @@ (rule (targets ocamltest_config.ml) - (deps ../Makefile.config ../Makefile.common ../Makefile.best_binaries Makefile - ./ocamltest_config.ml.in ./getocamloptdefaultflags) - (action (run make %{targets}))) + (deps + ../Makefile.config + ../Makefile.build_config + ../Makefile.config_if_required + ../Makefile.common + ../Makefile.best_binaries + Makefile + ./ocamltest_config.ml.in + ./getocamloptdefaultflags) + (action (run make %{targets} COMPUTE_DEPS=false))) ;; FIXME: handle UNIX_OR_WIN32 or something similar (library @@ -32,10 +39,13 @@ (modes byte) (wrapped false) (flags (:standard -nostdlib)) - (libraries ocamlcommon stdlib) + (libraries ocamlcommon stdlib + (select ocamltest_unix.ml from + (unix -> ocamltest_unix_real.ml) + (-> ocamltest_unix_dummy.ml))) (modules (:standard \ options main)) (c_flags (-DCAML_INTERNALS -I%{project_root}/runtime)) ; fixme - (c_names run_unix run_stubs ocamltest_stdlib_stubs)) + (c_names run_unix run_stubs)) (rule (targets empty.ml) diff --git a/ocamltest/environments.ml b/ocamltest/environments.ml index 43dd1173..09f668c2 100644 --- a/ocamltest/environments.ml +++ b/ocamltest/environments.ml @@ -95,18 +95,31 @@ let dump log environment = (* Initializers *) +type kind = Pre | Post + type env_initializer = out_channel -> t -> t -let (initializers : (string, env_initializer) Hashtbl.t) = Hashtbl.create 10 +type initializers = + { + pre: (string, env_initializer) Hashtbl.t; + post: (string, env_initializer) Hashtbl.t; + } + +let initializers = {pre = Hashtbl.create 10; post = Hashtbl.create 10} + +let get_initializers = function + | Pre -> initializers.pre + | Post -> initializers.post -let register_initializer name code = Hashtbl.add initializers name code +let register_initializer kind name code = + Hashtbl.add (get_initializers kind) name code let apply_initializer _log _name code env = code _log env -let initialize log env = +let initialize kind log env = let f = apply_initializer log in - Hashtbl.fold f initializers env + Hashtbl.fold f (get_initializers kind) env (* Modifiers *) diff --git a/ocamltest/environments.mli b/ocamltest/environments.mli index f288a6f1..62152e83 100644 --- a/ocamltest/environments.mli +++ b/ocamltest/environments.mli @@ -43,11 +43,13 @@ val dump : out_channel -> t -> unit (* Initializers *) +type kind = Pre | Post + type env_initializer = out_channel -> t -> t -val register_initializer : string -> env_initializer -> unit +val register_initializer : kind -> string -> env_initializer -> unit -val initialize : env_initializer +val initialize : kind -> env_initializer (* Modifiers *) diff --git a/ocamltest/filecompare.ml b/ocamltest/filecompare.ml index 2e87d0ce..97d00ff3 100644 --- a/ocamltest/filecompare.ml +++ b/ocamltest/filecompare.ml @@ -59,34 +59,103 @@ type files = { output_filename : string; } -let read_text_file lines_to_drop fn = - let ic = open_in_bin fn in - let drop_cr s = - let l = String.length s in - if l > 0 && s.[l - 1] = '\r' then String.sub s 0 (l - 1) - else raise Exit - in - let rec drop k = - if k = 0 then - loop [] +let last_is_cr s = + let l = String.length s in + l > 0 && s.[l - 1] = '\r' + +(* Returns last character of an input file. Fails for an empty file. *) +let last_char ic = + seek_in ic (in_channel_length ic - 1); + input_char ic + +(* [line_seq_of_in_channel ~normalise ic first_line] constructs a sequence of + the lines of [ic] where [first_line] is the already read first line of [ic]. + Strings include the line terminator and CRLF is normalised to LF if + [normalise] is [true]. The sequence raises [Exit] if normalise is [true] and + a terminated line is encountered which does not end CRLF. The final line of + the sequence only includes a terminator if it is present in the file (and a + terminating CR is never normalised if not strictly followed by LF). *) +let line_seq_of_in_channel ~normalise ic = + let normalise = + if normalise then + fun s -> + if last_is_cr s then + String.sub s 0 (String.length s - 1) + else + raise Exit else - let stop = try ignore (input_line ic); false with End_of_file -> true in - if stop then [] else drop (k-1) - and loop acc = - match input_line ic with - | s -> loop (s :: acc) - | exception End_of_file -> - close_in ic; - try List.rev_map drop_cr acc - with Exit -> List.rev acc + Fun.id in - drop lines_to_drop + let rec read_line last () = + (* Read the next line to determine if the last line ended with LF *) + match input_line ic with + | line -> + Seq.Cons (normalise last ^ "\n", read_line line) + | exception End_of_file -> + (* EOF reached - seek the last character to determine if the final + line ends in LF *) + let last = + if last_char ic = '\n' then + normalise last ^ "\n" + else + last + in + Seq.Cons (last, Seq.empty) + in + read_line -let compare_text_files dropped_lines file1 file2 = - if read_text_file 0 file1 = read_text_file dropped_lines file2 then - Same - else - Different +let compare_text_files ignored_lines file1 file2 = + Sys.with_input_file ~bin:true file2 @@ fun ic2 -> + (* Get the first non-dropped line of file2 and determine if could be + CRLF-normalised (it can't be in any of the dropped lines didn't end + CRLF. *) + let (crlf_endings2, line2, reached_end_file2) = + let rec loop crlf_endings2 k = + match input_line ic2 with + | line -> + let crlf_endings2 = crlf_endings2 && last_is_cr line in + if k = 0 then + (crlf_endings2, line, false) + else + loop crlf_endings2 (pred k) + | exception End_of_file -> + (false, "", true) + in + loop true ignored_lines + in + Sys.with_input_file ~bin:true file1 @@ fun ic1 -> + if reached_end_file2 then + (* We reached the end of file2 while ignoring lines, so only an empty + file can be identical, as in the binary comparison case. *) + if in_channel_length ic1 = 0 then + Same + else + Different + else + (* file2 has at least one non-ignored line *) + match input_line ic1 with + | exception End_of_file -> Different + | line1 -> + let crlf_endings1 = last_is_cr line1 in + (* If both files appear to have CRLF endings, then there's no need + to attempt to normalise either. *) + let seq1 = + let normalise = crlf_endings1 && not crlf_endings2 in + line_seq_of_in_channel ~normalise ic1 line1 in + let seq2 = + let normalise = crlf_endings2 && not crlf_endings1 in + line_seq_of_in_channel ~normalise ic2 line2 in + try + if Seq.equal seq1 seq2 then + Same + else + raise Exit + with Exit -> + (* Either the lines weren't equal, or the file which was being + normalised suddenly had a line which didn't end CRLF. In this + case, the files must differ since only one file is ever being + normalised, so the earlier lines differed too. *) + Different (* Version of Stdlib.really_input which stops at EOF, rather than raising an exception. *) @@ -108,8 +177,8 @@ let really_input_up_to ic = Bytes.sub buf 0 bytes_read let compare_binary_files bytes_to_ignore file1 file2 = - let ic1 = open_in_bin file1 in - let ic2 = open_in_bin file2 in + Sys.with_input_file ~bin:true file1 @@ fun ic1 -> + Sys.with_input_file ~bin:true file2 @@ fun ic2 -> seek_in ic1 bytes_to_ignore; seek_in ic2 bytes_to_ignore; let rec compare () = @@ -123,10 +192,7 @@ let compare_binary_files bytes_to_ignore file1 file2 = else Different in - let result = compare () in - close_in ic1; - close_in ic2; - result + compare () let compare_files ?(tool = default_comparison_tool) files = match tool with @@ -138,11 +204,8 @@ let compare_files ?(tool = default_comparison_tool) files = files.reference_filename; files.output_filename ] in - let dev_null = match Sys.os_type with - | "Win32" -> "NUL" - | _ -> "/dev/null" in let settings = Run_command.settings_of_commandline - ~stdout_fname:dev_null ~stderr_fname:dev_null commandline in + ~stdout_fname:Filename.null ~stderr_fname:Filename.null commandline in let status = Run_command.run settings in result_of_exitcode commandline status | Internal ignore -> @@ -168,32 +231,30 @@ let diff files = let temporary_file = Filename.temp_file "ocamltest" "diff" in let diff_commandline = Filename.quote_command "diff" ~stdout:temporary_file - [ "-u"; + [ "--strip-trailing-cr"; "-u"; files.reference_filename; files.output_filename ] in let result = - if (Sys.command diff_commandline) = 2 then Stdlib.Error "diff" - else Ok (Sys.string_of_file temporary_file) + match Sys.command diff_commandline with + | 0 -> Ok "Inconsistent LF/CRLF line-endings" + | 2 -> Stdlib.Error "diff" + | _ -> Ok (Sys.string_of_file temporary_file) in Sys.force_remove temporary_file; result -let promote files ignore_conf = - match files.filetype, ignore_conf with - | Text, {lines = skip_lines; _} -> - let reference = open_out files.reference_filename in - let output = open_in files.output_filename in - for _ = 1 to skip_lines do - try ignore (input_line output) with End_of_file -> () - done; - Sys.copy_chan output reference; - close_out reference; - close_in output - | Binary, {bytes = skip_bytes; _} -> - let reference = open_out_bin files.reference_filename in - let output = open_in_bin files.output_filename in - seek_in output skip_bytes; - Sys.copy_chan output reference; - close_out reference; - close_in output +let promote {filetype; reference_filename; output_filename} ignore_conf = + match filetype, ignore_conf with + | Text, {lines = skip_lines; _} -> + Sys.with_output_file reference_filename @@ fun reference -> + Sys.with_input_file output_filename @@ fun output -> + for _ = 1 to skip_lines do + try ignore (input_line output) with End_of_file -> () + done; + Sys.copy_chan output reference + | Binary, {bytes = skip_bytes; _} -> + Sys.with_output_file ~bin:true reference_filename @@ fun reference -> + Sys.with_input_file ~bin:true output_filename @@ fun output -> + seek_in output skip_bytes; + Sys.copy_chan output reference diff --git a/ocamltest/main.ml b/ocamltest/main.ml index 9d952965..9197ce32 100644 --- a/ocamltest/main.ml +++ b/ocamltest/main.ml @@ -127,9 +127,6 @@ let init_tests_to_skip () = tests_to_skip := String.words (Sys.safe_getenv "OCAMLTEST_SKIP_TESTS") let test_file test_filename = - (* Printf.printf "# reading test file %s\n%!" test_filename; *) - (* Save current working directory *) - let cwd = Sys.getcwd() in let skip_test = List.mem test_filename !tests_to_skip in let tsl_block = tsl_block_of_file_safe test_filename in let (rootenv_statements, test_trees) = test_trees_of_tsl_block tsl_block in @@ -155,20 +152,21 @@ let test_file test_filename = let test_build_directory_prefix = get_test_build_directory_prefix test_directory in let clean_test_build_directory () = - ignore - (Sys.command - (Filename.quote_command "rm" ["-rf"; test_build_directory_prefix])) + try + Sys.rm_rf test_build_directory_prefix + with Sys_error _ -> () in clean_test_build_directory (); Sys.make_directory test_build_directory_prefix; + let log_filename = + Filename.concat test_build_directory_prefix (test_prefix ^ ".log") in + let log = + if Options.log_to_stderr then stderr else begin + open_out log_filename + end in let summary = Sys.with_chdir test_build_directory_prefix (fun () -> - let log = - if !Options.log_to_stderr then stderr else begin - let log_filename = test_prefix ^ ".log" in - open_out log_filename - end in - let promote = string_of_bool !Options.promote in + let promote = string_of_bool Options.promote in let install_hook name = let hook_name = Filename.make_filename hookname_prefix name in if Sys.file_exists hook_name then begin @@ -190,10 +188,12 @@ let test_file test_filename = test_build_directory_prefix; Builtin_variables.promote, promote; ] in - let root_environment = + let rootenv = + Environments.initialize Environments.Pre log initial_environment in + let rootenv = interprete_environment_statements - initial_environment rootenv_statements in - let rootenv = Environments.initialize log root_environment in + rootenv rootenv_statements in + let rootenv = Environments.initialize Environments.Post log rootenv in let common_prefix = " ... testing '" ^ test_basename ^ "' with" in let initial_status = if skip_test then Skip_all_tests else Run rootenv @@ -201,15 +201,15 @@ let test_file test_filename = let summary = run_test_trees log common_prefix "" initial_status test_trees in Actions.clear_all_hooks(); - if not !Options.log_to_stderr then close_out log; summary ) in - (* Restore current working directory *) - Sys.chdir cwd; + if not Options.log_to_stderr then close_out log; begin match summary with - | Some_failure -> () + | Some_failure -> + if not Options.log_to_stderr then + Sys.dump_file stderr ~prefix:"> " log_filename | No_failure -> - if not !Options.keep_test_dir_on_success then + if not Options.keep_test_dir_on_success then clean_test_build_directory () end @@ -221,6 +221,8 @@ let is_test s = let ignored s = s = "" || s.[0] = '_' || s.[0] = '.' +let sort_strings = List.sort String.compare + let find_test_dirs dir = let res = ref [] in let rec loop dir = @@ -236,7 +238,7 @@ let find_test_dirs dir = if !contains_tests then res := dir :: !res in loop dir; - List.rev !res + sort_strings !res let list_tests dir = let res = ref [] in @@ -250,12 +252,12 @@ let list_tests dir = end ) (Sys.readdir dir) end; - List.rev !res + sort_strings !res let () = init_tests_to_skip() -let main () = +let () = let failed = ref false in let work_done = ref false in let list_tests dir = @@ -265,10 +267,8 @@ let main () = in let find_test_dirs dir = List.iter print_endline (find_test_dirs dir) in let doit f x = work_done := true; f x in - List.iter (doit find_test_dirs) !Options.find_test_dirs; - List.iter (doit list_tests) !Options.list_tests; - List.iter (doit test_file) !Options.files_to_test; + List.iter (doit find_test_dirs) Options.find_test_dirs; + List.iter (doit list_tests) Options.list_tests; + List.iter (doit test_file) Options.files_to_test; if not !work_done then print_usage(); if !failed || not !work_done then exit 1 - -let _ = main() diff --git a/ocamltest/ocaml_actions.ml b/ocamltest/ocaml_actions.ml index 8334c43a..b3741e0c 100644 --- a/ocamltest/ocaml_actions.ml +++ b/ocamltest/ocaml_actions.ml @@ -20,13 +20,12 @@ open Actions (* Extracting information from environment *) -let native_support = Ocamltest_config.arch <> "none" - let no_native_compilers _log env = (Result.skip_with_reason "native compilers disabled", env) let native_action a = - if native_support then a else (Actions.update a no_native_compilers) + if Ocamltest_config.native_compiler then a + else (Actions.update a no_native_compilers) let get_backend_value_from_env env bytecode_var native_var = Ocaml_backends.make_backend_function @@ -94,7 +93,7 @@ let default_ocaml_env = [| type module_generator = { description : string; - command : string -> string; + command : string; flags : Environments.t -> string; generated_compilation_units : string -> (string * Ocaml_filetypes.t) list @@ -122,7 +121,7 @@ let ocamlyacc = ] } -let generate_module generator ocamlsrcdir output_variable input log env = +let generate_module generator output_variable input log env = let basename = fst input in let input_file = Ocaml_filetypes.make_filename input in let what = @@ -132,7 +131,7 @@ let generate_module generator ocamlsrcdir output_variable input log env = Printf.fprintf log "%s\n%!" what; let commandline = [ - generator.command ocamlsrcdir; + generator.command; generator.flags env; input_file ] in @@ -159,7 +158,7 @@ let generate_lexer = generate_module ocamllex let generate_parser = generate_module ocamlyacc -let prepare_module ocamlsrcdir output_variable log env input = +let prepare_module output_variable log env input = let input_type = snd input in let open Ocaml_filetypes in match input_type with @@ -168,9 +167,9 @@ let prepare_module ocamlsrcdir output_variable log env input = | Backend_specific _ -> [input] | C_minus_minus -> assert false | Lexer -> - generate_lexer ocamlsrcdir output_variable input log env + generate_lexer output_variable input log env | Grammar -> - generate_parser ocamlsrcdir output_variable input log env + generate_parser output_variable input log env | Text -> assert false let get_program_file backend env = @@ -206,20 +205,20 @@ let cmas_need_dynamic_loading directories libraries = begin try close_in ic with Sys_error _ -> () end; Some (Error ("Corrupt or non-CMA file: " ^ library)) in - Misc.Stdlib.List.find_map loads_c_code (String.words libraries) + List.find_map loads_c_code (String.words libraries) -let compile_program ocamlsrcdir (compiler : Ocaml_compilers.compiler) log env = +let compile_program (compiler : Ocaml_compilers.compiler) log env = let program_variable = compiler#program_variable in let program_file = Environments.safe_lookup program_variable env in let all_modules = Actions_helpers.words_of_variable env Ocaml_variables.all_modules in let output_variable = compiler#output_variable in - let prepare = prepare_module ocamlsrcdir output_variable log env in + let prepare = prepare_module output_variable log env in let modules = List.concatmap prepare (List.map Ocaml_filetypes.filetype all_modules) in let has_c_file = List.exists is_c_file modules in let c_headers_flags = - if has_c_file then Ocaml_flags.c_includes ocamlsrcdir else "" in + if has_c_file then Ocaml_flags.c_includes else "" in let expected_exit_status = Ocaml_tools.expected_exit_status env (compiler :> Ocaml_tools.tool) in let module_names = @@ -250,11 +249,11 @@ let compile_program ocamlsrcdir (compiler : Ocaml_compilers.compiler) log env = let bytecode_links_c_code = (cmas_need_dynamic_loading = Some (Ok ())) in let commandline = [ - compiler#name ocamlsrcdir; - Ocaml_flags.runtime_flags ocamlsrcdir env compiler#target + compiler#name; + Ocaml_flags.runtime_flags env compiler#target (has_c_file || bytecode_links_c_code); c_headers_flags; - Ocaml_flags.stdlib ocamlsrcdir; + Ocaml_flags.stdlib; directory_flags env; flags env; libraries; @@ -283,7 +282,7 @@ let compile_program ocamlsrcdir (compiler : Ocaml_compilers.compiler) log env = (Result.fail_with_reason reason, env) end -let compile_module ocamlsrcdir compiler module_ log env = +let compile_module compiler module_ log env = let expected_exit_status = Ocaml_tools.expected_exit_status env (compiler :> Ocaml_tools.tool) in let what = Printf.sprintf "Compiling module %s" module_ in @@ -291,11 +290,11 @@ let compile_module ocamlsrcdir compiler module_ log env = let module_with_filetype = Ocaml_filetypes.filetype module_ in let is_c = is_c_file module_with_filetype in let c_headers_flags = - if is_c then Ocaml_flags.c_includes ocamlsrcdir else "" in + if is_c then Ocaml_flags.c_includes else "" in let commandline = [ - compiler#name ocamlsrcdir; - Ocaml_flags.stdlib ocamlsrcdir; + compiler#name; + Ocaml_flags.stdlib; c_headers_flags; directory_flags env; flags env; @@ -459,20 +458,19 @@ let setup_ocamlnat_build_env = Ocaml_toplevels.ocamlnat) let compile (compiler : Ocaml_compilers.compiler) log env = - let ocamlsrcdir = Ocaml_directories.srcdir () in match Environments.lookup_nonempty Builtin_variables.commandline env with | None -> begin match Environments.lookup_nonempty Ocaml_variables.module_ env with - | None -> compile_program ocamlsrcdir compiler log env - | Some module_ -> compile_module ocamlsrcdir compiler module_ log env + | None -> compile_program compiler log env + | Some module_ -> compile_module compiler module_ log env end | Some cmdline -> let expected_exit_status = Ocaml_tools.expected_exit_status env (compiler :> Ocaml_tools.tool) in let what = Printf.sprintf "Compiling using commandline %s" cmdline in Printf.fprintf log "%s\n%!" what; - let commandline = [compiler#name ocamlsrcdir; cmdline] in + let commandline = [compiler#name; cmdline] in let exit_status = Actions_helpers.run_cmd ~environment:default_ocaml_env @@ -515,8 +513,8 @@ let ocamlopt_opt = "ocamlopt.opt" (compile Ocaml_compilers.ocamlopt_opt)) -let env_with_lib_unix ocamlsrcdir env = - let libunixdir = Ocaml_directories.libunix ocamlsrcdir in +let env_with_lib_unix env = + let libunixdir = Ocaml_directories.libunix in let newlibs = match Environments.lookup Ocaml_variables.caml_ld_library_path env with | None -> libunixdir @@ -525,20 +523,19 @@ let env_with_lib_unix ocamlsrcdir env = Environments.add Ocaml_variables.caml_ld_library_path newlibs env let debug log env = - let ocamlsrcdir = Ocaml_directories.srcdir () in let program = Environments.safe_lookup Builtin_variables.program env in let what = Printf.sprintf "Debugging program %s" program in Printf.fprintf log "%s\n%!" what; let commandline = [ - Ocaml_commands.ocamlrun_ocamldebug ocamlsrcdir; - Ocaml_flags.ocamldebug_default_flags ocamlsrcdir; + Ocaml_commands.ocamlrun_ocamldebug; + Ocaml_flags.ocamldebug_default_flags; program ] in let systemenv = Array.append default_ocaml_env - (Environments.to_system_env (env_with_lib_unix ocamlsrcdir env)) + (Environments.to_system_env (env_with_lib_unix env)) in let expected_exit_status = 0 in let exit_status = @@ -548,7 +545,7 @@ let debug log env = ~stdout_variable:Builtin_variables.output ~stderr_variable:Builtin_variables.output ~append:true - log (env_with_lib_unix ocamlsrcdir env) commandline in + log (env_with_lib_unix env) commandline in if exit_status=expected_exit_status then (Result.pass, env) else begin @@ -561,14 +558,13 @@ let debug log env = let ocamldebug = Actions.make "ocamldebug" debug let objinfo log env = - let ocamlsrcdir = Ocaml_directories.srcdir () in - let tools_directory = Ocaml_directories.tools ocamlsrcdir in + let tools_directory = Ocaml_directories.tools in let program = Environments.safe_lookup Builtin_variables.program env in let what = Printf.sprintf "Running ocamlobjinfo on %s" program in Printf.fprintf log "%s\n%!" what; let commandline = [ - Ocaml_commands.ocamlrun_ocamlobjinfo ocamlsrcdir; + Ocaml_commands.ocamlrun_ocamlobjinfo; Ocaml_flags.ocamlobjinfo_default_flags; program ] in @@ -578,7 +574,7 @@ let objinfo log env = [ default_ocaml_env; ocamllib; - (Environments.to_system_env (env_with_lib_unix ocamlsrcdir env)) + (Environments.to_system_env (env_with_lib_unix env)) ] in let expected_exit_status = 0 in @@ -588,7 +584,7 @@ let objinfo log env = ~stdout_variable:Builtin_variables.output ~stderr_variable:Builtin_variables.output ~append:true - log (env_with_lib_unix ocamlsrcdir env) commandline in + log (env_with_lib_unix env) commandline in if exit_status=expected_exit_status then (Result.pass, env) else begin @@ -601,20 +597,19 @@ let objinfo log env = let ocamlobjinfo = Actions.make "ocamlobjinfo" objinfo let mklib log env = - let ocamlsrcdir = Ocaml_directories.srcdir () in let program = Environments.safe_lookup Builtin_variables.program env in let what = Printf.sprintf "Running ocamlmklib to produce %s" program in Printf.fprintf log "%s\n%!" what; let ocamlc_command = String.concat " " [ - Ocaml_commands.ocamlrun_ocamlc ocamlsrcdir; - Ocaml_flags.stdlib ocamlsrcdir; + Ocaml_commands.ocamlrun_ocamlc; + Ocaml_flags.stdlib; ] in let commandline = [ - Ocaml_commands.ocamlrun_ocamlmklib ocamlsrcdir; + Ocaml_commands.ocamlrun_ocamlmklib; "-ocamlc '" ^ ocamlc_command ^ "'"; "-o " ^ program ] @ modules env in @@ -637,11 +632,11 @@ let mklib log env = let ocamlmklib = Actions.make "ocamlmklib" mklib -let finalise_codegen_cc ocamlsrcdir test_basename _log env = +let finalise_codegen_cc test_basename _log env = let test_module = Filename.make_filename test_basename "s" in - let archmod = Ocaml_files.asmgen_archmod ocamlsrcdir in + let archmod = Ocaml_files.asmgen_archmod in let modules = test_module ^ " " ^ archmod in let program = Filename.make_filename test_basename "out" in let env = Environments.add_bindings @@ -651,7 +646,7 @@ let finalise_codegen_cc ocamlsrcdir test_basename _log env = ] env in (Result.pass, env) -let finalise_codegen_msvc ocamlsrcdir test_basename log env = +let finalise_codegen_msvc test_basename log env = let obj = Filename.make_filename test_basename Ocamltest_config.objext in let src = Filename.make_filename test_basename "s" in let what = "Running Microsoft assembler" in @@ -667,7 +662,7 @@ let finalise_codegen_msvc ocamlsrcdir test_basename log env = log env commandline in if exit_status=expected_exit_status then begin - let archmod = Ocaml_files.asmgen_archmod ocamlsrcdir in + let archmod = Ocaml_files.asmgen_archmod in let modules = obj ^ " " ^ archmod in let program = Filename.make_filename test_basename "out" in let env = Environments.add_bindings @@ -684,7 +679,6 @@ let finalise_codegen_msvc ocamlsrcdir test_basename log env = end let run_codegen log env = - let ocamlsrcdir = Ocaml_directories.srcdir () in let testfile = Actions_helpers.testfile env in let testfile_basename = Filename.chop_extension testfile in let what = Printf.sprintf "Running codegen on %s" testfile in @@ -705,7 +699,7 @@ let run_codegen log env = let env = Environments.add Builtin_variables.output output env in let commandline = [ - Ocaml_commands.ocamlrun_codegen ocamlsrcdir; + Ocaml_commands.ocamlrun_codegen; flags env; "-S " ^ testfile ] in @@ -724,7 +718,7 @@ let run_codegen log env = then finalise_codegen_msvc else finalise_codegen_cc in - finalise ocamlsrcdir testfile_basename log env + finalise testfile_basename log env end else begin let reason = (Actions_helpers.mkreason @@ -735,7 +729,6 @@ let run_codegen log env = let codegen = Actions.make "codegen" run_codegen let run_cc log env = - let ocamlsrcdir = Ocaml_directories.srcdir () in let program = Environments.safe_lookup Builtin_variables.program env in let what = Printf.sprintf "Running C compiler to build %s" program in Printf.fprintf log "%s\n%!" what; @@ -746,7 +739,7 @@ let run_cc log env = [ Ocamltest_config.cc; Ocamltest_config.cflags; - "-I" ^ Ocaml_directories.runtime ocamlsrcdir; + "-I" ^ Ocaml_directories.runtime; output_exe ^ program; Environments.safe_lookup Builtin_variables.arguments env; ] @ modules env in @@ -769,13 +762,13 @@ let run_cc log env = let cc = Actions.make "cc" run_cc -let run_expect_once ocamlsrcdir input_file principal log env = +let run_expect_once input_file principal log env = let expect_flags = Sys.safe_getenv "EXPECT_FLAGS" in - let repo_root = "-repo-root " ^ ocamlsrcdir in + let repo_root = "-repo-root " ^ Ocaml_directories.srcdir in let principal_flag = if principal then "-principal" else "" in let commandline = [ - Ocaml_commands.ocamlrun_expect_test ocamlsrcdir; + Ocaml_commands.ocamlrun_expect_test; expect_flags; flags env; repo_root; @@ -792,13 +785,13 @@ let run_expect_once ocamlsrcdir input_file principal log env = (Result.fail_with_reason reason, env) end -let run_expect_twice ocamlsrcdir input_file log env = +let run_expect_twice input_file log env = let corrected filename = Filename.make_filename filename "corrected" in - let (result1, env1) = run_expect_once ocamlsrcdir input_file false log env in + let (result1, env1) = run_expect_once input_file false log env in if Result.is_pass result1 then begin let intermediate_file = corrected input_file in let (result2, env2) = - run_expect_once ocamlsrcdir intermediate_file true log env1 in + run_expect_once intermediate_file true log env1 in if Result.is_pass result2 then begin let output_file = corrected intermediate_file in let output_env = Environments.add_bindings @@ -811,9 +804,8 @@ let run_expect_twice ocamlsrcdir input_file log env = end else (result1, env1) let run_expect log env = - let ocamlsrcdir = Ocaml_directories.srcdir () in let input_file = Actions_helpers.testfile env in - run_expect_twice ocamlsrcdir input_file log env + run_expect_twice input_file log env let run_expect = Actions.make "run-expect" run_expect @@ -853,37 +845,16 @@ let really_compare_programs backend comparison_tool log env = Filecompare.reference_filename = program; Filecompare.output_filename = program2 } in - if Ocamltest_config.flambda && backend = Ocaml_backends.Native - then begin - let reason = - "flambda temporarily disables comparison of native programs" in - (Result.pass_with_reason reason, env) - end else - if backend = Ocaml_backends.Native && - (Sys.os_type="Win32" || Sys.os_type="Cygwin") - then begin - let reason = - "comparison of native programs temporarily disabled under Windows" in - (Result.pass_with_reason reason, env) - end else begin - let comparison_tool = - if backend=Ocaml_backends.Native && - (Sys.os_type="Win32" || Sys.os_type="Cygwin") - then - let bytes_to_ignore = 512 (* comparison_start_address program *) in - Filecompare.(make_cmp_tool ~ignore:{bytes=bytes_to_ignore; lines=0}) - else comparison_tool in - match Filecompare.compare_files ~tool:comparison_tool files with - | Filecompare.Same -> (Result.pass, env) - | Filecompare.Different -> - let reason = Printf.sprintf "Files %s and %s are different" - program program2 in - (Result.fail_with_reason reason, env) - | Filecompare.Unexpected_output -> assert false - | Filecompare.Error (commandline, exitcode) -> - let reason = Actions_helpers.mkreason what commandline exitcode in - (Result.fail_with_reason reason, env) - end + match Filecompare.compare_files ~tool:comparison_tool files with + | Filecompare.Same -> (Result.pass, env) + | Filecompare.Different -> + let reason = Printf.sprintf "Files %s and %s are different" + program program2 in + (Result.fail_with_reason reason, env) + | Filecompare.Unexpected_output -> assert false + | Filecompare.Error (commandline, exitcode) -> + let reason = Actions_helpers.mkreason what commandline exitcode in + (Result.fail_with_reason reason, env) let compare_programs backend comparison_tool log env = let compare_programs = @@ -893,18 +864,17 @@ let compare_programs backend comparison_tool log env = (Result.pass_with_reason reason, env) end else really_compare_programs backend comparison_tool log env -let make_bytecode_programs_comparison_tool ocamlsrcdir = - let ocamlrun = Ocaml_files.ocamlrun ocamlsrcdir in - let cmpbyt = Ocaml_files.cmpbyt ocamlsrcdir in +let make_bytecode_programs_comparison_tool = + let ocamlrun = Ocaml_files.ocamlrun in + let cmpbyt = Ocaml_files.cmpbyt in let tool_name = ocamlrun ^ " " ^ cmpbyt in Filecompare.make_comparison_tool tool_name "" let native_programs_comparison_tool = Filecompare.default_comparison_tool let compare_bytecode_programs_code log env = - let ocamlsrcdir = Ocaml_directories.srcdir () in let bytecode_programs_comparison_tool = - make_bytecode_programs_comparison_tool ocamlsrcdir in + make_bytecode_programs_comparison_tool in compare_programs Ocaml_backends.Bytecode bytecode_programs_comparison_tool log env @@ -914,14 +884,13 @@ let compare_bytecode_programs = "compare-bytecode-programs" compare_bytecode_programs_code) -let compare_native_programs = +let compare_binary_files = native_action (Actions.make - "compare-native-programs" + "compare-binary-files" (compare_programs Ocaml_backends.Native native_programs_comparison_tool)) -let compile_module - ocamlsrcdir compiler compilername compileroutput log env +let compile_module compiler compilername compileroutput log env (module_basename, module_filetype) = let backend = compiler#target in let filename = @@ -938,7 +907,7 @@ let compile_module | Some file -> "-o " ^ file in [ compilername; - Ocaml_flags.stdlib ocamlsrcdir; + Ocaml_flags.stdlib; flags env; backend_flags env backend; optional_flags; @@ -980,19 +949,18 @@ let compile_module let _object_filename = module_basename ^ object_extension in let commandline = compile_commandline filename None - (Ocaml_flags.c_includes ocamlsrcdir) in + Ocaml_flags.c_includes in exec commandline | _ -> let reason = Printf.sprintf "File %s of type %s not supported yet" filename (Ocaml_filetypes.string_of_filetype module_filetype) in (Result.fail_with_reason reason, env) -let compile_modules - ocamlsrcdir compiler compilername compileroutput +let compile_modules compiler compilername compileroutput modules_with_filetypes log initial_env = let compile_mod env mod_ = - compile_module ocamlsrcdir compiler compilername compileroutput + compile_module compiler compilername compileroutput log env mod_ in let rec compile_mods env = function | [] -> (Result.pass, env) @@ -1008,84 +976,80 @@ let run_test_program_in_toplevel (toplevel : Ocaml_toplevels.toplevel) log env = (* This is a sub-optimal check - skip the test if any libraries requiring C stubs are loaded. It would be better at this point to build a custom toplevel. *) - let toplevel_can_run = + let toplevel_supports_dynamic_loading = Config.supports_shared_libraries || backend <> Ocaml_backends.Bytecode in - if not toplevel_can_run then - (Result.skip, env) - else - match cmas_need_dynamic_loading (directories env) libraries with - | Some (Error reason) -> - (Result.fail_with_reason reason, env) - | Some (Ok ()) -> - (Result.skip, env) - | None -> - let testfile = Actions_helpers.testfile env in - let expected_exit_status = - Ocaml_tools.expected_exit_status env (toplevel :> Ocaml_tools.tool) in - let compiler_output_variable = toplevel#output_variable in - let ocamlsrcdir = Ocaml_directories.srcdir () in - let compiler = toplevel#compiler in - let compiler_name = compiler#name ocamlsrcdir in - let modules_with_filetypes = - List.map Ocaml_filetypes.filetype (modules env) in - let (result, env) = compile_modules - ocamlsrcdir compiler compiler_name compiler_output_variable - modules_with_filetypes log env in - if Result.is_pass result then begin - let what = - Printf.sprintf "Running %s in %s toplevel \ - (expected exit status: %d)" - testfile - (Ocaml_backends.string_of_backend backend) - expected_exit_status in - Printf.fprintf log "%s\n%!" what; - let toplevel_name = toplevel#name ocamlsrcdir in - let ocaml_script_as_argument = - match - Environments.lookup_as_bool - Ocaml_variables.ocaml_script_as_argument env - with - | None -> false - | Some b -> b - in - let commandline = - [ - toplevel_name; - Ocaml_flags.toplevel_default_flags; - toplevel#flags; - Ocaml_flags.stdlib ocamlsrcdir; - directory_flags env; - Ocaml_flags.include_toplevel_directory ocamlsrcdir; - flags env; - libraries; - binary_modules backend env; - if ocaml_script_as_argument then testfile else ""; - Environments.safe_lookup Builtin_variables.arguments env - ] in - let exit_status = - if ocaml_script_as_argument - then Actions_helpers.run_cmd - ~environment:default_ocaml_env - ~stdout_variable:compiler_output_variable - ~stderr_variable:compiler_output_variable - log env commandline - else Actions_helpers.run_cmd - ~environment:default_ocaml_env - ~stdin_variable:Builtin_variables.test_file - ~stdout_variable:compiler_output_variable - ~stderr_variable:compiler_output_variable - log env commandline - in - if exit_status=expected_exit_status - then (Result.pass, env) - else begin - let reason = - (Actions_helpers.mkreason - what (String.concat " " commandline) exit_status) in - (Result.fail_with_reason reason, env) - end - end else (result, env) + match cmas_need_dynamic_loading (directories env) libraries with + | Some (Error reason) -> + (Result.fail_with_reason reason, env) + | Some (Ok ()) when not toplevel_supports_dynamic_loading -> + (Result.skip, env) + | _ -> + let testfile = Actions_helpers.testfile env in + let expected_exit_status = + Ocaml_tools.expected_exit_status env (toplevel :> Ocaml_tools.tool) in + let compiler_output_variable = toplevel#output_variable in + let compiler = toplevel#compiler in + let compiler_name = compiler#name in + let modules_with_filetypes = + List.map Ocaml_filetypes.filetype (modules env) in + let (result, env) = compile_modules + compiler compiler_name compiler_output_variable + modules_with_filetypes log env in + if Result.is_pass result then begin + let what = + Printf.sprintf "Running %s in %s toplevel \ + (expected exit status: %d)" + testfile + (Ocaml_backends.string_of_backend backend) + expected_exit_status in + Printf.fprintf log "%s\n%!" what; + let toplevel_name = toplevel#name in + let ocaml_script_as_argument = + match + Environments.lookup_as_bool + Ocaml_variables.ocaml_script_as_argument env + with + | None -> false + | Some b -> b + in + let commandline = + [ + toplevel_name; + Ocaml_flags.toplevel_default_flags; + toplevel#flags; + Ocaml_flags.stdlib; + directory_flags env; + Ocaml_flags.include_toplevel_directory; + flags env; + libraries; + binary_modules backend env; + if ocaml_script_as_argument then testfile else ""; + Environments.safe_lookup Builtin_variables.arguments env + ] in + let exit_status = + if ocaml_script_as_argument + then Actions_helpers.run_cmd + ~environment:default_ocaml_env + ~stdout_variable:compiler_output_variable + ~stderr_variable:compiler_output_variable + log env commandline + else Actions_helpers.run_cmd + ~environment:default_ocaml_env + ~stdin_variable:Builtin_variables.test_file + ~stdout_variable:compiler_output_variable + ~stderr_variable:compiler_output_variable + log env commandline + in + if exit_status=expected_exit_status + then (Result.pass, env) + else begin + let reason = + (Actions_helpers.mkreason + what (String.concat " " commandline) exit_status) in + (Result.fail_with_reason reason, env) + end + end else (result, env) let ocaml = Actions.make "ocaml" @@ -1106,19 +1070,19 @@ let check_ocamlnat_output = "check-ocamlnat-output" Ocaml_toplevels.ocamlnat) let config_variables _log env = - let ocamlsrcdir = Ocaml_directories.srcdir () in Environments.add_bindings [ Ocaml_variables.arch, Ocamltest_config.arch; - Ocaml_variables.ocamlrun, Ocaml_files.ocamlrun ocamlsrcdir; - Ocaml_variables.ocamlc_byte, Ocaml_files.ocamlc ocamlsrcdir; - Ocaml_variables.ocamlopt_byte, Ocaml_files.ocamlopt ocamlsrcdir; + Ocaml_variables.ocamlrun, Ocaml_files.ocamlrun; + Ocaml_variables.ocamlc_byte, Ocaml_files.ocamlc; + Ocaml_variables.ocamlopt_byte, Ocaml_files.ocamlopt; Ocaml_variables.bytecc_libs, Ocamltest_config.bytecc_libs; Ocaml_variables.nativecc_libs, Ocamltest_config.nativecc_libs; Ocaml_variables.mkdll, Sys.getenv_with_default_value "MKDLL" Ocamltest_config.mkdll; Ocaml_variables.mkexe, Ocamltest_config.mkexe; Ocaml_variables.c_preprocessor, Ocamltest_config.c_preprocessor; + Ocaml_variables.cc, Ocamltest_config.cc; Ocaml_variables.csc, Ocamltest_config.csc; Ocaml_variables.csc_flags, Ocamltest_config.csc_flags; Ocaml_variables.shared_library_cflags, @@ -1131,7 +1095,7 @@ let config_variables _log env = Ocaml_variables.ocamlopt_default_flags, Ocamltest_config.ocamlopt_default_flags; Ocaml_variables.ocamlrunparam, Sys.safe_getenv "OCAMLRUNPARAM"; - Ocaml_variables.ocamlsrcdir, Ocaml_directories.srcdir(); + Ocaml_variables.ocamlsrcdir, Ocaml_directories.srcdir; Ocaml_variables.os_type, Sys.os_type; ] env @@ -1159,18 +1123,6 @@ let no_flambda = make "support for flambda disabled" "support for flambda enabled") -let spacetime = Actions.make - "spacetime" - (Actions_helpers.pass_or_skip Ocamltest_config.spacetime - "support for spacetime enabled" - "support for spacetime disabled") - -let no_spacetime = make - "no-spacetime" - (Actions_helpers.pass_or_skip (not Ocamltest_config.spacetime) - "support for spacetime disabled" - "support for spacetime enabled") - let shared_libraries = Actions.make "shared-libraries" (Actions_helpers.pass_or_skip Ocamltest_config.shared_libraries @@ -1185,7 +1137,7 @@ let no_shared_libraries = Actions.make let native_compiler = Actions.make "native-compiler" - (Actions_helpers.pass_or_skip (Ocamltest_config.arch <> "none") + (Actions_helpers.pass_or_skip Ocamltest_config.native_compiler "native compiler available" "native compiler not available") @@ -1247,9 +1199,9 @@ let compiled_doc_name input = input ^ ".odoc" (* The compiler used for compiling both cmi file and plugins *) -let compiler_for_ocamldoc ocamlsrcdir = +let compiler_for_ocamldoc = let compiler = Ocaml_compilers.ocamlc_byte in - compile_modules ocamlsrcdir compiler (compiler#name ocamlsrcdir) + compile_modules compiler compiler#name compiler#output_variable (* Within ocamldoc tests, @@ -1257,21 +1209,21 @@ let compiler_for_ocamldoc ocamlsrcdir = secondaries documentation modules that need to be compiled into cmi files and odoc file (serialized ocamldoc information) before the main documentation is generated *) -let compile_ocamldoc ocamlsrcdir (basename,filetype as module_) log env = +let compile_ocamldoc (basename,filetype as module_) log env = let expected_exit_status = Ocaml_tools.expected_exit_status env (ocamldoc :> Ocaml_tools.tool) in let what = Printf.sprintf "Compiling documentation for module %s" basename in Printf.fprintf log "%s\n%!" what; let filename = Ocaml_filetypes.make_filename (basename, filetype) in - let (r,env) = compiler_for_ocamldoc ocamlsrcdir [module_] log env in + let (r,env) = compiler_for_ocamldoc [module_] log env in if not (Result.is_pass r) then (r,env) else let commandline = (* currently, we are ignoring the global ocamldoc_flags, since we don't have per-module flags *) [ - Ocaml_commands.ocamlrun_ocamldoc ocamlsrcdir; - Ocaml_flags.stdlib ocamlsrcdir; + Ocaml_commands.ocamlrun_ocamldoc; + Ocaml_flags.stdlib; "-dump " ^ compiled_doc_name basename; filename; ] in @@ -1292,12 +1244,12 @@ let compile_ocamldoc ocamlsrcdir (basename,filetype as module_) log env = (Result.fail_with_reason reason, env) end -let rec ocamldoc_compile_all ocamlsrcdir log env = function +let rec ocamldoc_compile_all log env = function | [] -> (Result.pass, env) | a :: q -> - let (r,env) = compile_ocamldoc ocamlsrcdir a log env in + let (r,env) = compile_ocamldoc a log env in if Result.is_pass r then - ocamldoc_compile_all ocamlsrcdir log env q + ocamldoc_compile_all log env q else (r,env) @@ -1341,10 +1293,9 @@ let run_ocamldoc = let modules = List.map Ocaml_filetypes.filetype @@ modules env in (* plugins are used for custom documentation generators *) let plugins = List.map Ocaml_filetypes.filetype @@ plugins env in - let ocamlsrcdir = Ocaml_directories.srcdir () in - let (r,env) = compiler_for_ocamldoc ocamlsrcdir plugins log env in + let (r,env) = compiler_for_ocamldoc plugins log env in if not (Result.is_pass r) then r, env else - let (r,env) = ocamldoc_compile_all ocamlsrcdir log env modules in + let (r,env) = ocamldoc_compile_all log env modules in if not (Result.is_pass r) then r, env else let input_file = Actions_helpers.testfile env in Printf.fprintf log "Generating documentation for %s\n%!" input_file; @@ -1356,9 +1307,9 @@ let run_ocamldoc = List.map (fun name -> "-g " ^ ocamldoc_plugin (fst name)) plugins in let commandline = [ - Ocaml_commands.ocamlrun_ocamldoc ocamlsrcdir; + Ocaml_commands.ocamlrun_ocamldoc; ocamldoc_backend_flag env; - Ocaml_flags.stdlib ocamlsrcdir; + Ocaml_flags.stdlib; ocamldoc_flags env] @ load_all @ with_plugins @ [ input_file; @@ -1380,8 +1331,10 @@ let run_ocamldoc = end let _ = - Environments.register_initializer "find_source_modules" find_source_modules; - Environments.register_initializer "config_variables" config_variables; + Environments.register_initializer Environments.Post + "find_source_modules" find_source_modules; + Environments.register_initializer Environments.Pre + "config_variables" config_variables; List.iter register [ setup_ocamlc_byte_build_env; @@ -1398,7 +1351,7 @@ let _ = check_ocamlopt_opt_output; run_expect; compare_bytecode_programs; - compare_native_programs; + compare_binary_files; setup_ocaml_build_env; ocaml; check_ocaml_output; @@ -1409,8 +1362,6 @@ let _ = no_flat_float_array; flambda; no_flambda; - spacetime; - no_spacetime; shared_libraries; no_shared_libraries; native_compiler; diff --git a/ocamltest/ocaml_actions.mli b/ocamltest/ocaml_actions.mli index efa05a10..f392fe00 100644 --- a/ocamltest/ocaml_actions.mli +++ b/ocamltest/ocaml_actions.mli @@ -29,7 +29,7 @@ val ocamlopt_opt : Actions.t val check_ocamlopt_opt_output : Actions.t val run_expect : Actions.t val compare_bytecode_programs : Actions.t -val compare_native_programs : Actions.t +val compare_binary_files : Actions.t val setup_ocaml_build_env : Actions.t val ocaml : Actions.t val check_ocaml_output : Actions.t diff --git a/ocamltest/ocaml_commands.ml b/ocamltest/ocaml_commands.ml index 59bbb6c9..3d6834a0 100644 --- a/ocamltest/ocaml_commands.ml +++ b/ocamltest/ocaml_commands.ml @@ -15,31 +15,31 @@ (* Helper functions to build OCaml-related commands *) -let ocamlrun ocamlsrcdir program = - (Ocaml_files.ocamlrun ocamlsrcdir) ^ " " ^ (program ocamlsrcdir) +let ocamlrun program = + Ocaml_files.ocamlrun ^ " " ^ program -let ocamlrun_ocamlc ocamlsrcdir = ocamlrun ocamlsrcdir Ocaml_files.ocamlc +let ocamlrun_ocamlc = ocamlrun Ocaml_files.ocamlc -let ocamlrun_ocamlopt ocamlsrcdir = ocamlrun ocamlsrcdir Ocaml_files.ocamlopt +let ocamlrun_ocamlopt = ocamlrun Ocaml_files.ocamlopt -let ocamlrun_ocaml ocamlsrcdir = ocamlrun ocamlsrcdir Ocaml_files.ocaml +let ocamlrun_ocaml = ocamlrun Ocaml_files.ocaml -let ocamlrun_expect_test ocamlsrcdir = - ocamlrun ocamlsrcdir Ocaml_files.expect_test +let ocamlrun_expect_test = + ocamlrun Ocaml_files.expect_test -let ocamlrun_ocamllex ocamlsrcdir = ocamlrun ocamlsrcdir Ocaml_files.ocamllex +let ocamlrun_ocamllex = ocamlrun Ocaml_files.ocamllex -let ocamlrun_ocamldoc ocamlsrcdir = - ocamlrun ocamlsrcdir Ocaml_files.ocamldoc +let ocamlrun_ocamldoc = + ocamlrun Ocaml_files.ocamldoc -let ocamlrun_ocamldebug ocamlsrcdir = - ocamlrun ocamlsrcdir Ocaml_files.ocamldebug +let ocamlrun_ocamldebug = + ocamlrun Ocaml_files.ocamldebug -let ocamlrun_ocamlobjinfo ocamlsrcdir = - ocamlrun ocamlsrcdir Ocaml_files.ocamlobjinfo +let ocamlrun_ocamlobjinfo = + ocamlrun Ocaml_files.ocamlobjinfo -let ocamlrun_ocamlmklib ocamlsrcdir = - ocamlrun ocamlsrcdir Ocaml_files.ocamlmklib +let ocamlrun_ocamlmklib = + ocamlrun Ocaml_files.ocamlmklib -let ocamlrun_codegen ocamlsrcdir = - ocamlrun ocamlsrcdir Ocaml_files.codegen +let ocamlrun_codegen = + ocamlrun Ocaml_files.codegen diff --git a/ocamltest/ocaml_commands.mli b/ocamltest/ocaml_commands.mli index 9a1474e2..3cacfaef 100644 --- a/ocamltest/ocaml_commands.mli +++ b/ocamltest/ocaml_commands.mli @@ -15,21 +15,21 @@ (* Helper functions to build OCaml-related commands *) -val ocamlrun_ocamlc : string -> string +val ocamlrun_ocamlc : string -val ocamlrun_ocamlopt : string -> string +val ocamlrun_ocamlopt : string -val ocamlrun_ocaml : string -> string +val ocamlrun_ocaml : string -val ocamlrun_expect_test : string -> string +val ocamlrun_expect_test : string -val ocamlrun_ocamllex : string -> string +val ocamlrun_ocamllex : string -val ocamlrun_ocamldoc : string -> string +val ocamlrun_ocamldoc : string -val ocamlrun_ocamldebug : string -> string +val ocamlrun_ocamldebug : string -val ocamlrun_ocamlobjinfo : string -> string +val ocamlrun_ocamlobjinfo : string -val ocamlrun_ocamlmklib : string -> string -val ocamlrun_codegen : string -> string +val ocamlrun_ocamlmklib : string +val ocamlrun_codegen : string diff --git a/ocamltest/ocaml_compilers.ml b/ocamltest/ocaml_compilers.ml index bb3ed6ae..a47c2ae6 100644 --- a/ocamltest/ocaml_compilers.ml +++ b/ocamltest/ocaml_compilers.ml @@ -18,7 +18,7 @@ open Ocamltest_stdlib class compiler - ~(name : string -> string) + ~(name : string) ~(flags : string) ~(directory : string) ~(exit_status_variable : Variables.t) diff --git a/ocamltest/ocaml_compilers.mli b/ocamltest/ocaml_compilers.mli index e4eb638e..1b907b90 100644 --- a/ocamltest/ocaml_compilers.mli +++ b/ocamltest/ocaml_compilers.mli @@ -16,7 +16,7 @@ (* Descriptions of the OCaml compilers *) class compiler : - name : (string -> string) -> + name : string -> flags : string -> directory : string -> exit_status_variable : Variables.t -> diff --git a/ocamltest/ocaml_directories.ml b/ocamltest/ocaml_directories.ml index b85ff07c..9f1c8465 100644 --- a/ocamltest/ocaml_directories.ml +++ b/ocamltest/ocaml_directories.ml @@ -17,21 +17,21 @@ open Ocamltest_stdlib -let srcdir () = +let srcdir = Sys.getenv_with_default_value "OCAMLSRCDIR" Ocamltest_config.ocamlsrcdir -let stdlib ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "stdlib"] +let stdlib = + Filename.make_path [srcdir; "stdlib"] -let libunix ocamlsrcdir = - let subdir = if Sys.os_type="Win32" then "win32unix" else "unix" in - Filename.make_path [ocamlsrcdir; "otherlibs"; subdir] +let libunix = + let subdir = if Sys.win32 then "win32unix" else "unix" in + Filename.make_path [srcdir; "otherlibs"; subdir] -let toplevel ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "toplevel"] +let toplevel = + Filename.make_path [srcdir; "toplevel"] -let runtime ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "runtime"] +let runtime = + Filename.make_path [srcdir; "runtime"] -let tools ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "tools"] +let tools = + Filename.make_path [srcdir; "tools"] diff --git a/ocamltest/ocaml_directories.mli b/ocamltest/ocaml_directories.mli index d689f34e..20c4d0f2 100644 --- a/ocamltest/ocaml_directories.mli +++ b/ocamltest/ocaml_directories.mli @@ -15,14 +15,14 @@ (* Locations of directories in the OCaml source tree *) -val srcdir : unit -> string +val srcdir : string -val stdlib : string -> string +val stdlib : string -val libunix : string -> string +val libunix : string -val toplevel : string -> string +val toplevel : string -val runtime : string -> string +val runtime : string -val tools : string -> string +val tools : string diff --git a/ocamltest/ocaml_files.ml b/ocamltest/ocaml_files.ml index 70e24d7d..1e3c7dfa 100644 --- a/ocamltest/ocaml_files.ml +++ b/ocamltest/ocaml_files.ml @@ -28,62 +28,71 @@ let runtime_variant() = else if use_runtime="i" then Instrumented else Normal -let ocamlrun ocamlsrcdir = +let ocamlrun = let runtime = match runtime_variant () with | Normal -> "ocamlrun" | Debug -> "ocamlrund" | Instrumented -> "ocamlruni" in let ocamlrunfile = Filename.mkexe runtime in - Filename.make_path [ocamlsrcdir; "runtime"; ocamlrunfile] + Filename.make_path [Ocaml_directories.srcdir; "runtime"; ocamlrunfile] -let ocamlc ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "ocamlc"] +let ocamlc = + Filename.make_path [Ocaml_directories.srcdir; Filename.mkexe "ocamlc"] -let ocaml ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "ocaml"] +let ocaml = + Filename.make_path [Ocaml_directories.srcdir; Filename.mkexe "ocaml"] -let ocamlc_dot_opt ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "ocamlc.opt"] +let ocamlc_dot_opt = + Filename.make_path [Ocaml_directories.srcdir; Filename.mkexe "ocamlc.opt"] -let ocamlopt ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "ocamlopt"] +let ocamlopt = + Filename.make_path [Ocaml_directories.srcdir; Filename.mkexe "ocamlopt"] -let ocamlopt_dot_opt ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "ocamlopt.opt"] +let ocamlopt_dot_opt = + Filename.make_path [Ocaml_directories.srcdir; Filename.mkexe "ocamlopt.opt"] -let ocamlnat ocamlsrcdir = - Filename.make_path [ocamlsrcdir; Filename.mkexe "ocamlnat"] +let ocamlnat = + Filename.make_path [Ocaml_directories.srcdir; Filename.mkexe "ocamlnat"] -let cmpbyt ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "tools"; "cmpbyt"] +let cmpbyt = + Filename.make_path + [Ocaml_directories.srcdir; "tools"; Filename.mkexe "cmpbyt"] -let expect_test ocamlsrcdir = +let expect_test = Filename.make_path - [ocamlsrcdir; "testsuite"; "tools"; Filename.mkexe "expect_test"] + [Ocaml_directories.srcdir; "testsuite"; "tools"; + Filename.mkexe "expect_test"] -let ocamllex ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "lex"; "ocamllex"] +let ocamllex = + Filename.make_path + [Ocaml_directories.srcdir; "lex"; Filename.mkexe "ocamllex"] -let ocamlyacc ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "yacc"; Filename.mkexe "ocamlyacc"] +let ocamlyacc = + Filename.make_path + [Ocaml_directories.srcdir; "yacc"; Filename.mkexe "ocamlyacc"] -let ocamldoc ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "ocamldoc"; "ocamldoc"] +let ocamldoc = + Filename.make_path + [Ocaml_directories.srcdir; "ocamldoc"; Filename.mkexe "ocamldoc"] -let ocamldebug ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "debugger"; Filename.mkexe "ocamldebug"] +let ocamldebug = + Filename.make_path + [Ocaml_directories.srcdir; "debugger"; Filename.mkexe "ocamldebug"] -let ocamlobjinfo ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "tools"; "ocamlobjinfo"] +let ocamlobjinfo = + Filename.make_path + [Ocaml_directories.srcdir; "tools"; Filename.mkexe "ocamlobjinfo"] -let ocamlmklib ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "tools"; "ocamlmklib"] +let ocamlmklib = + Filename.make_path + [Ocaml_directories.srcdir; "tools"; Filename.mkexe "ocamlmklib"] -let codegen ocamlsrcdir = - Filename.make_path [ocamlsrcdir; "testsuite"; "tools"; "codegen"] +let codegen = + Filename.make_path + [Ocaml_directories.srcdir; "testsuite"; "tools"; Filename.mkexe "codegen"] -let asmgen_archmod ocamlsrcdir = +let asmgen_archmod = let objname = "asmgen_" ^ Ocamltest_config.arch ^ "." ^ Ocamltest_config.objext in - Filename.make_path [ocamlsrcdir; "testsuite"; "tools"; objname] + Filename.make_path [Ocaml_directories.srcdir; "testsuite"; "tools"; objname] diff --git a/ocamltest/ocaml_files.mli b/ocamltest/ocaml_files.mli index 95c93179..56566454 100644 --- a/ocamltest/ocaml_files.mli +++ b/ocamltest/ocaml_files.mli @@ -22,32 +22,32 @@ type runtime_variant = val runtime_variant : unit -> runtime_variant -val ocamlrun : string -> string +val ocamlrun : string -val ocamlc : string -> string +val ocamlc : string -val ocaml : string -> string +val ocaml : string -val ocamlc_dot_opt : string -> string +val ocamlc_dot_opt : string -val ocamlopt : string -> string +val ocamlopt : string -val ocamlopt_dot_opt : string -> string +val ocamlopt_dot_opt : string -val ocamlnat : string -> string +val ocamlnat : string -val cmpbyt : string -> string +val cmpbyt : string -val expect_test : string -> string +val expect_test : string -val ocamllex : string -> string +val ocamllex : string -val ocamlyacc : string -> string +val ocamlyacc : string -val ocamldoc : string -> string -val ocamldebug : string -> string -val ocamlobjinfo : string -> string -val ocamlmklib : string -> string -val codegen : string -> string +val ocamldoc : string +val ocamldebug : string +val ocamlobjinfo : string +val ocamlmklib : string +val codegen : string -val asmgen_archmod : string -> string +val asmgen_archmod : string diff --git a/ocamltest/ocaml_flags.ml b/ocamltest/ocaml_flags.ml index bfb31cc7..a3511739 100644 --- a/ocamltest/ocaml_flags.ml +++ b/ocamltest/ocaml_flags.ml @@ -15,15 +15,15 @@ (* Flags used in OCaml commands *) -let stdlib ocamlsrcdir = - let stdlib_path = Ocaml_directories.stdlib ocamlsrcdir in +let stdlib = + let stdlib_path = Ocaml_directories.stdlib in "-nostdlib -I " ^ stdlib_path -let include_toplevel_directory ocamlsrcdir = - "-I " ^ (Ocaml_directories.toplevel ocamlsrcdir) +let include_toplevel_directory = + "-I " ^ Ocaml_directories.toplevel -let c_includes ocamlsrcdir = - let dir = Ocaml_directories.runtime ocamlsrcdir in +let c_includes = + let dir = Ocaml_directories.runtime in "-ccopt -I" ^ dir let runtime_variant_flags () = match Ocaml_files.runtime_variant() with @@ -31,9 +31,9 @@ let runtime_variant_flags () = match Ocaml_files.runtime_variant() with | Ocaml_files.Debug -> " -runtime-variant d" | Ocaml_files.Instrumented -> " -runtime-variant i" -let runtime_flags ocamlsrcdir env backend c_files = +let runtime_flags env backend c_files = let runtime_library_flags = "-I " ^ - (Ocaml_directories.runtime ocamlsrcdir) in + Ocaml_directories.runtime in let rt_flags = match backend with | Ocaml_backends.Native -> runtime_variant_flags () | Ocaml_backends.Bytecode -> @@ -46,16 +46,16 @@ let runtime_flags ocamlsrcdir env backend c_files = in if use_runtime = Some false then "" - else "-use-runtime " ^ (Ocaml_files.ocamlrun ocamlsrcdir) + else "-use-runtime " ^ Ocaml_files.ocamlrun end end in rt_flags ^ " " ^ runtime_library_flags let toplevel_default_flags = "-noinit -no-version -noprompt" -let ocamldebug_default_flags ocamlsrcdir = +let ocamldebug_default_flags = "-no-version -no-prompt -no-time -no-breakpoint-message " ^ - ("-I " ^ (Ocaml_directories.stdlib ocamlsrcdir) ^ " ") ^ - ("-topdirs-path " ^ (Ocaml_directories.toplevel ocamlsrcdir)) + ("-I " ^ Ocaml_directories.stdlib ^ " ") ^ + ("-topdirs-path " ^ Ocaml_directories.toplevel) let ocamlobjinfo_default_flags = "-null-crc" diff --git a/ocamltest/ocaml_flags.mli b/ocamltest/ocaml_flags.mli index 7bfb3a32..3d4e4cfc 100644 --- a/ocamltest/ocaml_flags.mli +++ b/ocamltest/ocaml_flags.mli @@ -15,17 +15,17 @@ (* Flags used in OCaml commands *) -val stdlib : string -> string +val stdlib : string -val include_toplevel_directory : string -> string +val include_toplevel_directory : string -val c_includes : string -> string +val c_includes : string val runtime_flags : - string -> Environments.t -> Ocaml_backends.t -> bool -> string + Environments.t -> Ocaml_backends.t -> bool -> string val toplevel_default_flags : string -val ocamldebug_default_flags : string -> string +val ocamldebug_default_flags : string val ocamlobjinfo_default_flags : string diff --git a/ocamltest/ocaml_modifiers.ml b/ocamltest/ocaml_modifiers.ml index c310cf36..c65dafde 100644 --- a/ocamltest/ocaml_modifiers.ml +++ b/ocamltest/ocaml_modifiers.ml @@ -18,51 +18,53 @@ open Ocamltest_stdlib open Environments +let wrap sl = " " ^ String.concat " " sl ^ " " +let append var sl = Append (var, wrap sl) +let add var s = Add (var, s) + let principal = [ - Append (Ocaml_variables.flags, " -principal "); - Add (Ocaml_variables.compiler_directory_suffix, ".principal"); - Add (Ocaml_variables.compiler_reference_suffix, ".principal"); + append Ocaml_variables.flags ["-principal"]; + add Ocaml_variables.compiler_directory_suffix ".principal"; + add Ocaml_variables.compiler_reference_suffix ".principal"; ] let latex = [ - Add (Ocaml_variables.ocamldoc_backend, "latex"); - Append (Ocaml_variables.ocamldoc_flags, "-latex-type-prefix=TYP "); - Append (Ocaml_variables.ocamldoc_flags, "-latex-module-prefix= "); - Append (Ocaml_variables.ocamldoc_flags, "-latex-value-prefix= "); - Append (Ocaml_variables.ocamldoc_flags, "-latex-module-type-prefix= "); - Append (Ocaml_variables.ocamldoc_flags, "-latextitle=1,subsection* "); - Append (Ocaml_variables.ocamldoc_flags, "-latextitle=2,subsubsection* "); - Append (Ocaml_variables.ocamldoc_flags, "-latextitle=6,subsection* "); - Append (Ocaml_variables.ocamldoc_flags, "-latextitle=7,subsubsection* "); + add Ocaml_variables.ocamldoc_backend "latex"; + append Ocaml_variables.ocamldoc_flags ["-latex-type-prefix=TYP"]; + append Ocaml_variables.ocamldoc_flags ["-latex-module-prefix="]; + append Ocaml_variables.ocamldoc_flags ["-latex-value-prefix="]; + append Ocaml_variables.ocamldoc_flags ["-latex-module-type-prefix="]; + append Ocaml_variables.ocamldoc_flags ["-latextitle=1,subsection*"]; + append Ocaml_variables.ocamldoc_flags ["-latextitle=2,subsubsection*"]; + append Ocaml_variables.ocamldoc_flags ["-latextitle=6,subsection*"]; + append Ocaml_variables.ocamldoc_flags ["-latextitle=7,subsubsection*"]; ] let html = [ - Add (Ocaml_variables.ocamldoc_backend, "html"); - Append (Ocaml_variables.ocamldoc_flags, "-colorize-code "); + add Ocaml_variables.ocamldoc_backend "html"; + append Ocaml_variables.ocamldoc_flags ["-colorize-code"]; ] let man = [ - Add (Ocaml_variables.ocamldoc_backend, "man"); + add Ocaml_variables.ocamldoc_backend "man"; ] -let wrap str = (" " ^ str ^ " ") - -let make_library_modifier library directory = +let make_library_modifier library directories = [ - Append (Ocaml_variables.directories, (wrap directory)); - Append (Ocaml_variables.libraries, (wrap library)); - Append (Ocaml_variables.caml_ld_library_path, (wrap directory)); + append Ocaml_variables.directories directories; + append Ocaml_variables.libraries [library]; + append Ocaml_variables.caml_ld_library_path directories; ] let make_module_modifier unit_name directory = [ - Append (Ocaml_variables.directories, (wrap directory)); - Append (Ocaml_variables.binary_modules, (wrap unit_name)); + append Ocaml_variables.directories [directory]; + append Ocaml_variables.binary_modules [unit_name]; ] let compiler_subdir subdir = @@ -70,30 +72,32 @@ let compiler_subdir subdir = let config = [ - Append (Ocaml_variables.directories, (wrap (compiler_subdir ["utils"]))); + append Ocaml_variables.directories [compiler_subdir ["utils"]]; ] let testing = make_library_modifier - "testing" (compiler_subdir ["testsuite"; "lib"]) + "testing" [compiler_subdir ["testsuite"; "lib"]] let tool_ocaml_lib = make_module_modifier "lib" (compiler_subdir ["testsuite"; "lib"]) -let unixlibdir = if Sys.os_type="Win32" then "win32unix" else "unix" +let unixlibdir = if Sys.win32 then "win32unix" else "unix" let unix = make_library_modifier - "unix" (compiler_subdir ["otherlibs"; unixlibdir]) + "unix" [compiler_subdir ["otherlibs"; unixlibdir]] let dynlink = - make_library_modifier "dynlink" (compiler_subdir ["otherlibs"; "dynlink"]) + make_library_modifier "dynlink" + [compiler_subdir ["otherlibs"; "dynlink"]; + compiler_subdir ["otherlibs"; "dynlink"; "native"]] let str = make_library_modifier - "str" (compiler_subdir ["otherlibs"; "str"]) + "str" [compiler_subdir ["otherlibs"; "str"]] let systhreads = unix @ (make_library_modifier - "threads" (compiler_subdir ["otherlibs"; "systhreads"])) + "threads" [compiler_subdir ["otherlibs"; "systhreads"]]) let compilerlibs_subdirs = [ @@ -111,11 +115,11 @@ let compilerlibs_subdirs = ] let add_compiler_subdir subdir = - Append (Ocaml_variables.directories, (wrap (compiler_subdir [subdir]))) + append Ocaml_variables.directories [compiler_subdir [subdir]] let compilerlibs_archive archive = - (Append (Ocaml_variables.libraries, wrap archive)) :: - (List.map add_compiler_subdir compilerlibs_subdirs) + append Ocaml_variables.libraries [archive] :: + List.map add_compiler_subdir compilerlibs_subdirs let debugger = [add_compiler_subdir "debugger"] diff --git a/ocamltest/ocaml_tests.ml b/ocamltest/ocaml_tests.ml index 964eaa2f..b42172d3 100644 --- a/ocamltest/ocaml_tests.ml +++ b/ocamltest/ocaml_tests.ml @@ -51,13 +51,12 @@ let native = setup_ocamlopt_opt_build_env; ocamlopt_opt; check_ocamlopt_opt_output; - compare_native_programs; ] in { test_name = "native"; test_run_by_default = true; test_actions = - (if Ocamltest_config.arch<>"none" then opt_actions else [skip]) + (if Ocamltest_config.native_compiler then opt_actions else [skip]) } let toplevel = { @@ -108,9 +107,6 @@ let ocamldoc = let asmgen_skip_on_bytecode_only = Actions_helpers.skip_with_reason "native compiler disabled" -let asmgen_skip_on_spacetime = - Actions_helpers.skip_with_reason "not ported to Spacetime yet" - let msvc64 = Ocamltest_config.ccomptype = "msvc" && Ocamltest_config.arch="amd64" @@ -118,8 +114,7 @@ let asmgen_skip_on_msvc64 = Actions_helpers.skip_with_reason "not ported to MSVC64 yet" let asmgen_actions = - if Ocamltest_config.arch="none" then [asmgen_skip_on_bytecode_only] - else if Ocamltest_config.spacetime then [asmgen_skip_on_spacetime] + if not Ocamltest_config.native_compiler then [asmgen_skip_on_bytecode_only] else if msvc64 then [asmgen_skip_on_msvc64] else [ setup_simple_build_env; diff --git a/ocamltest/ocaml_tools.ml b/ocamltest/ocaml_tools.ml index 4b98bc2d..e3368de0 100644 --- a/ocamltest/ocaml_tools.ml +++ b/ocamltest/ocaml_tools.ml @@ -18,7 +18,7 @@ open Ocamltest_stdlib class tool - ~(name : string -> string) + ~(name : string) ~(family : string) ~(flags : string) ~(directory : string) diff --git a/ocamltest/ocaml_tools.mli b/ocamltest/ocaml_tools.mli index c8acbee3..cc589eb1 100644 --- a/ocamltest/ocaml_tools.mli +++ b/ocamltest/ocaml_tools.mli @@ -16,7 +16,7 @@ (* Descriptions of the OCaml tools *) class tool : - name : (string -> string) -> + name : string -> family : string -> flags : string -> directory : string -> @@ -24,7 +24,7 @@ class tool : reference_variable : Variables.t -> output_variable : Variables.t -> object - method name : string -> string + method name : string method family : string method flags : string method directory : string diff --git a/ocamltest/ocaml_toplevels.ml b/ocamltest/ocaml_toplevels.ml index 9121cc0c..7ba72f72 100644 --- a/ocamltest/ocaml_toplevels.ml +++ b/ocamltest/ocaml_toplevels.ml @@ -18,7 +18,7 @@ open Ocamltest_stdlib class toplevel - ~(name : string -> string) + ~(name : string) ~(flags : string) ~(directory : string) ~(exit_status_variable : Variables.t) diff --git a/ocamltest/ocaml_toplevels.mli b/ocamltest/ocaml_toplevels.mli index f29fbac7..f68e2474 100644 --- a/ocamltest/ocaml_toplevels.mli +++ b/ocamltest/ocaml_toplevels.mli @@ -16,7 +16,7 @@ (* Descriptions of the OCaml toplevels *) class toplevel : - name : (string -> string) -> + name : string -> flags : string -> directory : string -> exit_status_variable : Variables.t -> diff --git a/ocamltest/ocaml_variables.ml b/ocamltest/ocaml_variables.ml index b9515629..78c138ef 100644 --- a/ocamltest/ocaml_variables.ml +++ b/ocamltest/ocaml_variables.ml @@ -41,6 +41,9 @@ let bytecc_libs = make ("bytecc_libs", let c_preprocessor = make ("c_preprocessor", "Command to use to invoke the C preprocessor") +let cc = make ("cc", + "Command to use to invoke the C compiler") + let caml_ld_library_path_name = "CAML_LD_LIBRARY_PATH" let export_caml_ld_library_path value = diff --git a/ocamltest/ocaml_variables.mli b/ocamltest/ocaml_variables.mli index 89686de1..5487ea2f 100644 --- a/ocamltest/ocaml_variables.mli +++ b/ocamltest/ocaml_variables.mli @@ -28,6 +28,8 @@ val bytecc_libs : Variables.t val c_preprocessor : Variables.t +val cc : Variables.t + val caml_ld_library_path : Variables.t val compare_programs : Variables.t diff --git a/ocamltest/ocamltest_config.ml.in b/ocamltest/ocamltest_config.ml.in index b42f9230..01013957 100644 --- a/ocamltest/ocamltest_config.ml.in +++ b/ocamltest/ocamltest_config.ml.in @@ -15,70 +15,74 @@ (* The configuration module for ocamltest *) -let arch = "@@ARCH@@" +let arch = "%%ARCH%%" -let afl_instrument = @@AFL_INSTRUMENT@@ +let afl_instrument = %%AFL_INSTRUMENT%% -let asm = "@@ASM@@" +let asm = "%%ASM%%" -let cc = "@@CC@@" +let cc = "%%CC%%" -let cflags = "@@CFLAGS@@" +let cflags = "%%OC_CFLAGS%%" -let ccomptype = "@@CCOMPTYPE@@" +let ccomptype = "%%CCOMPTYPE%%" -let shared_libraries = @@SHARED_LIBRARIES@@ +let shared_libraries = %%SUPPORTS_SHARED_LIBRARIES%% -let libunix = @@UNIX@@ +let libunix = %%unix%% -let systhreads = @@SYSTHREADS@@ +let systhreads = %%systhreads%% -let str = @@STR@@ +let str = %%str%% -let objext = "@@OBJEXT@@" +let objext = "%%O%%" -let asmext = "@@ASMEXT@@" +let asmext = "%%S%%" -let system = "@@SYSTEM@@" +let system = "%%SYSTEM%%" -let c_preprocessor = "@@CPP@@" +let c_preprocessor = "%%CPP%%" -let ocamlsrcdir = "@@OCAMLSRCDIR@@" +let ocamlsrcdir = "%%ocamlsrcdir%%" -let flambda = @@FLAMBDA@@ +let flambda = %%FLAMBDA%% -let spacetime = @@SPACETIME@@ +let ocamlc_default_flags = "%%ocamlcdefaultflags%%" +let ocamlopt_default_flags = "%%ocamloptdefaultflags%%" -let ocamlc_default_flags = "@@OCAMLCDEFAULTFLAGS@@" -let ocamlopt_default_flags = "@@OCAMLOPTDEFAULTFLAGS@@" +let safe_string = %%FORCE_SAFE_STRING%% -let safe_string = @@FORCE_SAFE_STRING@@ +let flat_float_array = %%FLAT_FLOAT_ARRAY%% -let flat_float_array = @@FLAT_FLOAT_ARRAY@@ +let ocamldoc = %%WITH_OCAMLDOC%% -let ocamldoc = @@OCAMLDOC@@ +let ocamldebug = %%WITH_OCAMLDEBUG%% -let ocamldebug = @@OCAMLDEBUG@@ +let native_compiler = %%NATIVE_COMPILER%% -let native_dynlink = @@NATIVE_DYNLINK@@ +let native_dynlink = %%NATDYNLINK%% -let shared_library_cflags = "@@SHARED_LIBRARY_CFLAGS@@" +let shared_library_cflags = "%%SHAREDLIB_CFLAGS%%" -let sharedobjext = "@@SHAREDOBJEXT@@" +let sharedobjext = "%%SO%%" -let csc = "@@CSC@@" +let csc = "%%CSC%%" -let csc_flags = "@@CSCFLAGS@@" +let csc_flags = "%%CSCFLAGS%%" -let mkdll = "@@MKDLL@@" -let mkexe = "@@MKEXE@@" +let exe = "%%EXE%%" -let bytecc_libs = "@@BYTECCLIBS@@" +let mkdll = "%%MKDLL%%" +let mkexe = "%%mkexe%%" -let nativecc_libs = "@@NATIVECCLIBS@@" +let bytecc_libs = "%%BYTECCLIBS%%" -let windows_unicode = @@WINDOWS_UNICODE@@ != 0 +let nativecc_libs = "%%NATIVECCLIBS%%" -let function_sections = @@FUNCTION_SECTIONS@@ +let windows_unicode = %%WINDOWS_UNICODE%% != 0 -let has_instrumented_runtime = @@RUNTIMEI@@ +let function_sections = %%FUNCTION_SECTIONS%% + +let has_instrumented_runtime = %%RUNTIMEI%% + +let naked_pointers = %%NAKED_POINTERS%% diff --git a/ocamltest/ocamltest_config.mli b/ocamltest/ocamltest_config.mli index a03c6b68..5bf1a47c 100644 --- a/ocamltest/ocamltest_config.mli +++ b/ocamltest/ocamltest_config.mli @@ -16,7 +16,7 @@ (* Interface for ocamltest's configuration module *) val arch : string -(** Architecture for the native compiler, "none" if it is disabled *) +(** Architecture for the native compiler *) val afl_instrument : bool (** Whether AFL support has been enabled in the compiler *) @@ -70,9 +70,6 @@ val ocamlsrcdir : string val flambda : bool (** Whether flambda has been enabled at configure time *) -val spacetime : bool -(** Whether Spacetime profiling has been enabled at configure time *) - val safe_string : bool (** Whether the compiler was configured with -safe-string *) @@ -85,6 +82,9 @@ val ocamldoc : bool val ocamldebug : bool (** Whether ocamldebug has been enabled at configure time *) +val native_compiler : bool +(** Whether the native compiler has been enabled at configure time *) + val native_dynlink : bool (** Whether support for native dynlink is available or not *) @@ -100,6 +100,9 @@ val csc : string val csc_flags : string (** Flags for the CSharp compiler *) +val exe : string +(** Extension of executable files *) + val mkdll : string val mkexe : string @@ -115,3 +118,6 @@ val function_sections : bool val has_instrumented_runtime : bool (** Whether the instrumented runtime is available *) + +val naked_pointers : bool +(** Whether the runtime system supports naked pointers outside the heap *) diff --git a/ocamltest/ocamltest_stdlib.ml b/ocamltest/ocamltest_stdlib.ml index 3b550101..a6ee5319 100644 --- a/ocamltest/ocamltest_stdlib.ml +++ b/ocamltest/ocamltest_stdlib.ml @@ -15,7 +15,7 @@ (* A few extensions to OCaml's standard library *) -(* Pervaisive *) +module Unix = Ocamltest_unix let input_line_opt ic = try Some (input_line ic) with End_of_file -> None @@ -28,7 +28,7 @@ end module Filename = struct include Filename - let path_sep = if Sys.os_type="Win32" then ";" else ":" + let path_sep = if Sys.win32 then ";" else ":" (* This function comes from otherlibs/win32unix/unix.ml *) let maybe_quote f = if String.contains f ' ' || @@ -42,10 +42,7 @@ module Filename = struct let make_path components = List.fold_left Filename.concat "" components - let mkexe = - if Sys.os_type="Win32" - then fun name -> make_filename name "exe" - else fun name -> name + let mkexe filename = filename ^ Ocamltest_config.exe end module List = struct @@ -87,52 +84,76 @@ end module Sys = struct include Sys - let file_is_empty filename = - let ic = open_in filename in - let filesize = in_channel_length ic in - close_in ic; - filesize = 0 - - let run_system_command command = match Sys.command command with - | 0 -> () - | _ as exitcode -> - Printf.eprintf "Sysem command %s failed with status %d\n%!" - command exitcode; - exit 3 - - let mkdir dir = - if not (Sys.file_exists dir) then - run_system_command (Filename.quote_command "mkdir" [dir]) + let erase_file path = + try Sys.remove path + with Sys_error _ when Sys.win32 && Ocamltest_config.libunix <> None -> + (* Deal with read-only attribute on Windows. Ignore any error from chmod + so that the message always come from Sys.remove *) + let () = try Unix.chmod path 0o666 with Sys_error _ -> () in + Sys.remove path + + let rm_rf path = + let rec erase path = + if Sys.is_directory path then begin + Array.iter (fun entry -> erase (Filename.concat path entry)) + (Sys.readdir path); + Sys.rmdir path + end else erase_file path + in + try if Sys.file_exists path then erase path + with Sys_error err -> + raise (Sys_error (Printf.sprintf "Failed to remove %S (%s)" path err)) let rec make_directory dir = if Sys.file_exists dir then () - else (make_directory (Filename.dirname dir); mkdir dir) + else let () = make_directory (Filename.dirname dir) in + if not (Sys.file_exists dir) then + Sys.mkdir dir 0o777 + else () + + let make_directory dir = + try make_directory dir + with Sys_error err -> + raise (Sys_error (Printf.sprintf "Failed to create %S (%s)" dir err)) + + let with_input_file ?(bin=false) x f = + let ic = (if bin then open_in_bin else open_in) x in + Fun.protect ~finally:(fun () -> close_in_noerr ic) + (fun () -> f ic) + + let file_is_empty filename = + not (Sys.file_exists filename) || + with_input_file filename in_channel_length = 0 let string_of_file filename = - let chan = open_in_bin filename in + with_input_file ~bin:true filename @@ fun chan -> let filesize = in_channel_length chan in if filesize > Sys.max_string_length then - begin - close_in chan; failwith ("The file " ^ filename ^ " is too large to be loaded into a string") - end else begin - let result = - try really_input_string chan filesize - with End_of_file -> - close_in chan; - failwith ("Got unexpected end of file while reading " ^ filename) in - close_in chan; - result + else begin + try really_input_string chan filesize + with End_of_file -> + failwith ("Got unexpected end of file while reading " ^ filename) end - let with_input_file ?(bin=false) x f = - let ic = (if bin then open_in_bin else open_in) x in - try let res = f ic in close_in ic; res with e -> (close_in ic; raise e) + let iter_lines_of_file f filename = + let rec go ic = + match input_line ic with + | exception End_of_file -> () + | l -> f l; go ic + in + with_input_file filename go + + let dump_file oc ?(prefix = "") filename = + let f s = + output_string oc prefix; output_string oc s; output_char oc '\n' in + iter_lines_of_file f filename let with_output_file ?(bin=false) x f = let oc = (if bin then open_out_bin else open_out) x in - try let res = f oc in close_out oc; res with e -> (close_out oc; raise e) + Fun.protect ~finally:(fun () -> close_out_noerr oc) + (fun () -> f oc) let copy_chan ic oc = let m = in_channel_length ic in @@ -148,29 +169,29 @@ module Sys = struct in loop () let copy_file src dest = - with_input_file ~bin:true src begin fun ic -> - with_output_file ~bin:true dest begin fun oc -> - copy_chan ic oc - end - end + with_input_file ~bin:true src @@ fun ic -> + with_output_file ~bin:true dest @@ fun oc -> + copy_chan ic oc let force_remove file = if file_exists file then remove file - external has_symlink : unit -> bool = "caml_has_symlink" - let with_chdir path f = let oldcwd = Sys.getcwd () in Sys.chdir path; - match f () with - | r -> - Sys.chdir oldcwd; - r - | exception e -> - Sys.chdir oldcwd; - raise e + Fun.protect ~finally:(fun () -> Sys.chdir oldcwd) f let getenv_with_default_value variable default_value = try Sys.getenv variable with Not_found -> default_value let safe_getenv variable = getenv_with_default_value variable "" end + +module Seq = struct + include Seq + + let rec equal s1 s2 = + match s1 (), s2 () with + | Nil, Nil -> true + | Cons(e1, s1), Cons(e2, s2) -> e1 = e2 && equal s1 s2 + | _, _ -> false +end diff --git a/ocamltest/ocamltest_stdlib.mli b/ocamltest/ocamltest_stdlib.mli index d74fc2c2..f28bf05a 100644 --- a/ocamltest/ocamltest_stdlib.mli +++ b/ocamltest/ocamltest_stdlib.mli @@ -46,14 +46,27 @@ end module Sys : sig include module type of Sys val file_is_empty : string -> bool - val run_system_command : string -> unit val make_directory : string -> unit + val rm_rf : string -> unit val string_of_file : string -> string + val iter_lines_of_file : (string -> unit) -> string -> unit + val dump_file : out_channel -> ?prefix:string -> string -> unit val copy_chan : in_channel -> out_channel -> unit val copy_file : string -> string -> unit val force_remove : string -> unit - val has_symlink : unit -> bool val with_chdir : string -> (unit -> 'a) -> 'a val getenv_with_default_value : string -> string -> string val safe_getenv : string -> string + val with_input_file : ?bin:bool -> string -> (in_channel -> 'a) -> 'a + val with_output_file : ?bin:bool -> string -> (out_channel -> 'a) -> 'a +end + +module Seq : sig + include module type of struct include Seq end + + val equal : 'a t -> 'a t -> bool +end + +module Unix : sig + include module type of Ocamltest_unix end diff --git a/ocamltest/ocamltest_stdlib_stubs.c b/ocamltest/ocamltest_stdlib_stubs.c deleted file mode 100644 index 18f4f519..00000000 --- a/ocamltest/ocamltest_stdlib_stubs.c +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************/ -/* */ -/* OCaml */ -/* */ -/* Sebastien Hinderer, projet Gallium, INRIA Paris */ -/* */ -/* Copyright 2018 Institut National de Recherche en Informatique et */ -/* en Automatique. */ -/* */ -/* All rights reserved. This file is distributed under the terms of */ -/* the GNU Lesser General Public License version 2.1, with the */ -/* special exception on linking described in the file LICENSE. */ -/* */ -/**************************************************************************/ - -/* Stubs for ocamltest's standard library */ - -#include -#include - -#include -#include -#include -#include -/* -#include -*/ -#include -#include - - -#ifdef _WIN32 - -/* - * Windows Vista functions enabled - */ -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 - -#include -#include -#include -#include - -#define luid_eq(l, r) (l.LowPart == r.LowPart && l.HighPart == r.HighPart) - -CAMLprim value caml_has_symlink(value unit) -{ - CAMLparam1(unit); - HANDLE hProcess = GetCurrentProcess(); - BOOL result = FALSE; - - if (OpenProcessToken(hProcess, TOKEN_READ, &hProcess)) { - LUID seCreateSymbolicLinkPrivilege; - - if (LookupPrivilegeValue(NULL, - SE_CREATE_SYMBOLIC_LINK_NAME, - &seCreateSymbolicLinkPrivilege)) { - DWORD length; - - if (!GetTokenInformation(hProcess, TokenPrivileges, NULL, 0, &length)) { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - TOKEN_PRIVILEGES* privileges = - (TOKEN_PRIVILEGES*)caml_stat_alloc(length); - if (GetTokenInformation(hProcess, - TokenPrivileges, - privileges, - length, - &length)) { - DWORD count = privileges->PrivilegeCount; - - if (count) { - LUID_AND_ATTRIBUTES* privs = privileges->Privileges; - while (count-- && - !(result = luid_eq(privs->Luid, - seCreateSymbolicLinkPrivilege))) - privs++; - } - } - - caml_stat_free(privileges); - } - } - } - - CloseHandle(hProcess); - } - - CAMLreturn(Val_bool(result)); -} - - -#else /* _WIN32 */ - -#ifdef HAS_SYMLINK - -CAMLprim value caml_has_symlink(value unit) -{ - CAMLparam0(); - CAMLreturn(Val_true); -} - -#else /* HAS_SYMLINK */ - -CAMLprim value unix_symlink(value to_dir, value path1, value path2) -{ caml_invalid_argument("symlink not implemented"); } - -CAMLprim value caml_has_symlink(value unit) -{ - CAMLparam0(); - CAMLreturn(Val_false); -} - -#endif - -#endif /* _WIN32 */ diff --git a/ocamltest/ocamltest_unix.mli b/ocamltest/ocamltest_unix.mli new file mode 100644 index 00000000..1a111fd9 --- /dev/null +++ b/ocamltest/ocamltest_unix.mli @@ -0,0 +1,20 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* David Allsopp, OCaml Labs, Cambridge. *) +(* *) +(* Copyright 2020 David Allsopp Ltd. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(** Functions imported from Unix. They are explicitly here to remove the + temptation to use the Unix module directly in ocamltest. *) + +val has_symlink : unit -> bool +val symlink : ?to_dir:bool -> string -> string -> unit +val chmod : string -> int -> unit diff --git a/asmcomp/spacetime_profiling.mli b/ocamltest/ocamltest_unix_dummy.ml similarity index 72% rename from asmcomp/spacetime_profiling.mli rename to ocamltest/ocamltest_unix_dummy.ml index 16c69148..32b80599 100644 --- a/asmcomp/spacetime_profiling.mli +++ b/ocamltest/ocamltest_unix_dummy.ml @@ -2,9 +2,9 @@ (* *) (* OCaml *) (* *) -(* Mark Shinwell and Leo White, Jane Street Europe *) +(* David Allsopp, OCaml Labs, Cambridge. *) (* *) -(* Copyright 2015--2016 Jane Street Group LLC *) +(* Copyright 2020 David Allsopp Ltd. *) (* *) (* All rights reserved. This file is distributed under the terms of *) (* the GNU Lesser General Public License version 2.1, with the *) @@ -12,6 +12,7 @@ (* *) (**************************************************************************) -(** Insertion of instrumentation code for Spacetime profiling. *) - -class virtual instruction_selection : Selectgen.selector_generic +(* Dummy implementations for when the Unix library isn't built *) +let has_symlink () = false +let symlink ?to_dir:_ _ _ = invalid_arg "symlink not available" +let chmod _ _ = invalid_arg "chmod not available" diff --git a/ocamltest/ocamltest_unix_real.ml b/ocamltest/ocamltest_unix_real.ml new file mode 100644 index 00000000..322b911f --- /dev/null +++ b/ocamltest/ocamltest_unix_real.ml @@ -0,0 +1,29 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* David Allsopp, OCaml Labs, Cambridge. *) +(* *) +(* Copyright 2020 David Allsopp Ltd. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* Unix.has_symlink never raises *) +let has_symlink = Unix.has_symlink + +(* Convert Unix_error to Sys_error *) +let wrap f x = + try f x + with Unix.Unix_error(err, fn_name, arg) -> + let msg = + Printf.sprintf "%s failed on %S with %s" + fn_name arg (Unix.error_message err) + in + raise (Sys_error msg) + +let symlink ?to_dir source = wrap (Unix.symlink ?to_dir source) +let chmod file = wrap (Unix.chmod file) diff --git a/ocamltest/options.ml b/ocamltest/options.ml index 60bcdeb7..8c152bd6 100644 --- a/ocamltest/options.ml +++ b/ocamltest/options.ml @@ -78,5 +78,12 @@ let files_to_test = ref [] let usage = "Usage: " ^ Sys.argv.(0) ^ " options files to test" -let _ = +let () = Arg.parse (Arg.align commandline_options) (add_to_list files_to_test) usage + +let log_to_stderr = !log_to_stderr +let files_to_test = !files_to_test +let promote = !promote +let find_test_dirs = !find_test_dirs +let list_tests = !list_tests +let keep_test_dir_on_success = !keep_test_dir_on_success diff --git a/ocamltest/options.mli b/ocamltest/options.mli index 2047f60a..36e09cf3 100644 --- a/ocamltest/options.mli +++ b/ocamltest/options.mli @@ -15,16 +15,16 @@ (* Description of ocamltest's command-line options *) -val log_to_stderr : bool ref +val log_to_stderr : bool -val files_to_test : string list ref +val files_to_test : string list -val promote : bool ref +val promote : bool val usage : string -val find_test_dirs : string list ref +val find_test_dirs : string list -val list_tests : string list ref +val list_tests : string list -val keep_test_dir_on_success : bool ref +val keep_test_dir_on_success : bool diff --git a/ocamltest/run_command.ml b/ocamltest/run_command.ml index 1a1df614..5819fa66 100644 --- a/ocamltest/run_command.ml +++ b/ocamltest/run_command.ml @@ -32,7 +32,7 @@ type settings = { let settings_of_commandline ?(stdout_fname="") ?(stderr_fname="") commandline = let words = String.words commandline in let quoted_words = - if Sys.os_type="Win32" + if Sys.win32 then List.map Filename.maybe_quote words else words in { diff --git a/ocamltest/run_stubs.c b/ocamltest/run_stubs.c index 2f89e83d..10f82c33 100644 --- a/ocamltest/run_stubs.c +++ b/ocamltest/run_stubs.c @@ -71,8 +71,10 @@ static void logToChannel(void *voidchannel, const char *fmt, va_list ap) if (text == NULL) return; if (vsnprintf(text, length, fmt, ap) != length) goto end; } + Lock(channel); caml_putblock(channel, text, length); caml_flush(channel); + Unlock(channel); end: free(text); } diff --git a/ocamltest/run_unix.c b/ocamltest/run_unix.c index 2cfd6868..ecdff90b 100644 --- a/ocamltest/run_unix.c +++ b/ocamltest/run_unix.c @@ -147,6 +147,8 @@ static void update_environment(array local_env) memcpy(value, pos_eq + 1, value_length); value[value_length] = '\0'; setenv(name, value, 1); /* 1 means overwrite */ + free(name); + free(value); } } } diff --git a/ocamltest/tests.ml b/ocamltest/tests.ml index 7e86bbf7..78b50576 100644 --- a/ocamltest/tests.ml +++ b/ocamltest/tests.ml @@ -54,7 +54,7 @@ let run_actions log testenv actions = | [] -> (Result.pass, env) | action::remaining_actions -> begin - Printf.fprintf log "Running action %d/%d (%s)\n%!" + Printf.fprintf log "\nRunning action %d/%d (%s)\n%!" action_number total (Actions.name action); let (result, env') = Actions.run log env action in Printf.fprintf log "Action %d/%d (%s) %s\n%!" diff --git a/ocamltest/tsl_lexer.mll b/ocamltest/tsl_lexer.mll index 19ef10ee..21a2038d 100644 --- a/ocamltest/tsl_lexer.mll +++ b/ocamltest/tsl_lexer.mll @@ -36,7 +36,7 @@ rule token = parse | "*/" { TSL_END_C_STYLE } | "(*" blank* "TEST" { TSL_BEGIN_OCAML_STYLE } | "*)" { TSL_END_OCAML_STYLE } - | "," { COMA } + | "," { COMMA } | '*'+ { TEST_DEPTH (String.length (Lexing.lexeme lexbuf)) } | "+=" { PLUSEQUAL } | "=" { EQUAL } diff --git a/ocamltest/tsl_parser.mly b/ocamltest/tsl_parser.mly index eb891f6a..c2c0708e 100644 --- a/ocamltest/tsl_parser.mly +++ b/ocamltest/tsl_parser.mly @@ -33,7 +33,7 @@ let mkenvstmt envstmt = %token TSL_BEGIN_C_STYLE TSL_END_C_STYLE %token TSL_BEGIN_OCAML_STYLE TSL_END_OCAML_STYLE -%token COMA +%token COMMA %token TEST_DEPTH %token EQUAL PLUSEQUAL /* %token COLON */ @@ -67,7 +67,7 @@ with_environment_modifiers: opt_environment_modifiers: | { [] } -| opt_environment_modifiers COMA identifier { $3::$1 } +| opt_environment_modifiers COMMA identifier { $3::$1 } env_item: | identifier EQUAL string diff --git a/otherlibs/Makefile b/otherlibs/Makefile index 8342b402..0da6669b 100644 --- a/otherlibs/Makefile +++ b/otherlibs/Makefile @@ -14,10 +14,9 @@ #************************************************************************** ROOTDIR=.. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common +include $(ROOTDIR)/Makefile.common -OTHERLIBRARIES ?= bigarray dynlink raw_spacetime_lib str systhreads \ +OTHERLIBRARIES ?= bigarray dynlink str systhreads \ unix win32unix # $1: target name to dispatch to all otherlibs/*/Makefile diff --git a/otherlibs/Makefile.otherlibs.common b/otherlibs/Makefile.otherlibs.common index 2e0802de..4e9a726c 100644 --- a/otherlibs/Makefile.otherlibs.common +++ b/otherlibs/Makefile.otherlibs.common @@ -16,8 +16,7 @@ # Common Makefile for otherlibs ROOTDIR=../.. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common +include $(ROOTDIR)/Makefile.common include $(ROOTDIR)/Makefile.best_binaries CAMLRUN ?= $(ROOTDIR)/boot/ocamlrun @@ -25,8 +24,12 @@ CAMLRUN ?= $(ROOTDIR)/boot/ocamlrun CAMLC := $(BEST_OCAMLC) -nostdlib -I $(ROOTDIR)/stdlib CAMLOPT := $(BEST_OCAMLOPT) -nostdlib -I $(ROOTDIR)/stdlib +ifneq "$(CCOMPTYPE)" "msvc" +OC_CFLAGS += -g +endif + OC_CFLAGS += $(SHAREDLIB_CFLAGS) $(EXTRACFLAGS) -OC_CPPFLAGS += -I$(ROOTDIR)/runtime +OC_CPPFLAGS += -I$(ROOTDIR)/runtime $(EXTRACPPFLAGS) # Compilation options COMPFLAGS=-absname -w +a-4-9-41-42-44-45-48 -warn-error A -bin-annot -g \ @@ -44,6 +47,7 @@ MKLIB=$(CAMLRUN) $(ROOTDIR)/tools/ocamlmklib # but have sensible default values: COBJS ?= EXTRACFLAGS ?= +EXTRACPPFLAGS ?= EXTRACAMLFLAGS ?= LINKOPTS ?= LDOPTS ?= @@ -89,8 +93,7 @@ lib$(CLIBNAME).$(A): $(COBJS) install:: if test -f dll$(CLIBNAME)$(EXT_DLL); then \ $(INSTALL_PROG) \ - dll$(CLIBNAME)$(EXT_DLL) \ - "$(INSTALL_STUBLIBDIR)/"; \ + dll$(CLIBNAME)$(EXT_DLL) "$(INSTALL_STUBLIBDIR)"; \ fi ifneq "$(STUBSLIB)" "" $(INSTALL_DATA) $(STUBSLIB) "$(INSTALL_LIBDIR)/" @@ -116,7 +119,7 @@ installopt: "$(INSTALL_LIBDIR)/" cd "$(INSTALL_LIBDIR)"; $(RANLIB) $(LIBNAME).a if test -f $(LIBNAME).cmxs; then \ - $(INSTALL_PROG) $(LIBNAME).cmxs "$(INSTALL_LIBDIR)/"; \ + $(INSTALL_PROG) $(LIBNAME).cmxs "$(INSTALL_LIBDIR)"; \ fi partialclean: @@ -124,8 +127,9 @@ partialclean: clean:: partialclean rm -f *.dll *.so *.a *.lib *.o *.obj + rm -rf $(DEPDIR) -.SUFFIXES: .ml .mli .cmi .cmo .cmx .$(O) +.SUFFIXES: .ml .mli .cmi .cmo .cmx .mli.cmi: $(CAMLC) -c $(COMPFLAGS) $< @@ -136,5 +140,11 @@ clean:: partialclean .ml.cmx: $(CAMLOPT) -c $(COMPFLAGS) $(OPTCOMPFLAGS) $< -.c.$(O): - $(CC) -c $(OC_CFLAGS) $(OC_CPPFLAGS) $(OUTPUTOBJ)$@ $< +ifeq "$(COMPUTE_DEPS)" "true" +ifneq "$(COBJS)" "" +include $(addprefix $(DEPDIR)/, $(COBJS:.$(O)=.$(D))) +endif +endif + +$(DEPDIR)/%.$(D): %.c | $(DEPDIR) + $(DEP_CC) $(OC_CPPFLAGS) $(CPPFLAGS) $< -MT '$*.$(O)' -MF $@ diff --git a/otherlibs/dynlink/Makefile b/otherlibs/dynlink/Makefile index fc41cd5f..5c88164a 100644 --- a/otherlibs/dynlink/Makefile +++ b/otherlibs/dynlink/Makefile @@ -21,11 +21,10 @@ ROOTDIR = ../.. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common +include $(ROOTDIR)/Makefile.common include $(ROOTDIR)/Makefile.best_binaries -CAMLRUN ?= $(ROOTDIR)/boot/ocamlrun +CAMLRUN ?= $(ROOTDIR)/boot/ocamlrun$(EXE) OCAMLC=$(BEST_OCAMLC) -g -nostdlib -I $(ROOTDIR)/stdlib OCAMLOPT=$(BEST_OCAMLOPT) -g -nostdlib -I $(ROOTDIR)/stdlib @@ -74,6 +73,7 @@ COMPILERLIBS_INTFS=\ # .ml files from compilerlibs that have corresponding .mli files. COMPILERLIBS_SOURCES=\ + utils/binutils.ml \ utils/config.ml \ utils/build_path_prefix_map.ml \ utils/misc.ml \ @@ -85,6 +85,7 @@ COMPILERLIBS_SOURCES=\ utils/consistbl.ml \ utils/terminfo.ml \ utils/warnings.ml \ + utils/local_store.ml \ utils/load_path.ml \ utils/int_replace_polymorphic_compare.ml \ parsing/location.ml \ @@ -205,7 +206,9 @@ native/dynlink_compilerlibs.cmx: $(COMPILERLIBS_CMX) # The main dynlink rules start here. -all: dynlink.cma extract_crc +extract_crc := extract_crc$(EXE) + +all: dynlink.cma $(extract_crc) allopt: dynlink.cmxa @@ -229,7 +232,9 @@ dynlink.cmxa: $(NATOBJS) dynlink_platform_intf.mli: dynlink_platform_intf.ml cp $< $@ -extract_crc: dynlink.cma byte/dynlink_compilerlibs.cmo extract_crc.cmo +$(eval $(call PROGRAM_SYNONYM,extract_crc)) + +$(extract_crc): dynlink.cma byte/dynlink_compilerlibs.cmo extract_crc.cmo $(OCAMLC) -o $@ $^ install: @@ -241,8 +246,7 @@ ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true" dynlink.cmti dynlink.mli \ "$(INSTALL_LIBDIR)" endif - $(INSTALL_PROG) \ - extract_crc "$(INSTALL_LIBDIR)/extract_crc$(EXE)" + $(INSTALL_PROG) $(extract_crc) "$(INSTALL_LIBDIR)" installopt: if $(NATDYNLINK); then \ @@ -253,13 +257,14 @@ installopt: fi partialclean: - rm -f extract_crc *.cm[ioaxt] *.cmti *.cmxa \ + rm -f $(extract_crc) *.cm[ioaxt] *.cmti *.cmxa \ byte/*.cm[iot] byte/*.cmti \ native/*.cm[ixt] native/*.cmti native/*.o native/*.obj \ $(LOCAL_SRC)/*.cm[ioaxt] $(LOCAL_SRC)/*.cmti \ $(LOCAL_SRC)/*.o $(LOCAL_SRC)/*.obj clean: partialclean + rm -f extract_crc extract_crc.exe rm -f *.a *.lib *.o *.obj *.so *.dll dynlink_platform_intf.mli \ $(LOCAL_SRC)/*.ml $(LOCAL_SRC)/*.mli $(LOCAL_SRC)/Makefile \ $(LOCAL_SRC)/.depend byte/dynlink.mli native/dynlink.mli @@ -268,10 +273,6 @@ clean: partialclean beforedepend: dynlink_platform_intf.mli .PHONY: depend -ifeq "$(TOOLCHAIN)" "msvc" -depend: - $(error Dependencies cannot be regenerated using the MSVC ports) -else DEPEND_DUMMY_FILES=\ native/dynlink_compilerlibs.ml \ byte/dynlink_compilerlibs.mli \ @@ -285,11 +286,10 @@ depend: beforedepend $(CAMLRUN) $(ROOTDIR)/boot/ocamlc -depend -slash \ -I native -native *.ml native/dynlink.ml >> .depend rm -f $(DEPEND_DUMMY_FILES) -endif include .depend -.SUFFIXES: .ml .mli .cmi .cmo .cmx .$(O) +.SUFFIXES: .ml .mli .cmi .cmo .cmx .mli.cmi: $(OCAMLC) -c $(COMPFLAGS) $< diff --git a/otherlibs/dynlink/dynlink_common.ml b/otherlibs/dynlink/dynlink_common.ml index 3a362fd1..3264ac4b 100644 --- a/otherlibs/dynlink/dynlink_common.ml +++ b/otherlibs/dynlink/dynlink_common.ml @@ -316,12 +316,15 @@ module Make (P : Dynlink_platform_intf.S) = struct global_state := state let main_program_units () = + init (); String.Set.elements (!global_state).main_program_units let public_dynamically_loaded_units () = + init (); String.Set.elements (!global_state).public_dynamically_loaded_units let all_units () = + init (); String.Set.elements (String.Set.union (!global_state).main_program_units (!global_state).public_dynamically_loaded_units) diff --git a/otherlibs/raw_spacetime_lib/.depend b/otherlibs/raw_spacetime_lib/.depend deleted file mode 100644 index 7f6e6e7a..00000000 --- a/otherlibs/raw_spacetime_lib/.depend +++ /dev/null @@ -1,22 +0,0 @@ -spacetime_offline.$(O): spacetime_offline.c ../../runtime/caml/alloc.h \ - ../../runtime/caml/misc.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/domain_state.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/config.h \ - ../../runtime/caml/fail.h ../../runtime/caml/gc.h \ - ../../runtime/caml/intext.h ../../runtime/caml/io.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/misc.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/roots.h \ - ../../runtime/caml/memory.h ../../runtime/caml/signals.h \ - ../../runtime/caml/stack.h ../../runtime/caml/sys.h \ - ../../runtime/caml/spacetime.h ../../runtime/caml/stack.h \ - ../../runtime/caml/s.h -raw_spacetime_lib.cmo : \ - raw_spacetime_lib.cmi -raw_spacetime_lib.cmx : \ - raw_spacetime_lib.cmi -raw_spacetime_lib.cmi : diff --git a/otherlibs/raw_spacetime_lib/raw_spacetime_lib.ml b/otherlibs/raw_spacetime_lib/raw_spacetime_lib.ml deleted file mode 100644 index 5ee81fc2..00000000 --- a/otherlibs/raw_spacetime_lib/raw_spacetime_lib.ml +++ /dev/null @@ -1,668 +0,0 @@ -(**************************************************************************) -(* *) -(* OCaml *) -(* *) -(* Mark Shinwell and Leo White, Jane Street Europe *) -(* *) -(* Copyright 2015--2017 Jane Street Group LLC *) -(* *) -(* All rights reserved. This file is distributed under the terms of *) -(* the GNU Lesser General Public License version 2.1, with the *) -(* special exception on linking described in the file LICENSE. *) -(* *) -(**************************************************************************) - -module Gc_stats : sig - type t - - val minor_words : t -> int - val promoted_words : t -> int - val major_words : t -> int - val minor_collections : t -> int - val major_collections : t -> int - val heap_words : t -> int - val heap_chunks : t -> int - val compactions : t -> int - val top_heap_words : t -> int -end = struct - type t = { - minor_words : int; - promoted_words : int; - major_words : int; - minor_collections : int; - major_collections : int; - heap_words : int; - heap_chunks : int; - compactions : int; - top_heap_words : int; - } - - let minor_words t = t.minor_words - let promoted_words t = t.promoted_words - let major_words t = t.major_words - let minor_collections t = t.minor_collections - let major_collections t = t.major_collections - let heap_words t = t.heap_words - let heap_chunks t = t.heap_chunks - let compactions t = t.compactions - let top_heap_words t = t.top_heap_words -end - -module Program_counter = struct - module OCaml = struct - type t = Int64.t - - let to_int64 t = t - end - - module Foreign = struct - type t = Int64.t - - let to_int64 t = t - end -end - -module Function_identifier = struct - type t = Int64.t - - let to_int64 t = t -end - -module Function_entry_point = struct - type t = Int64.t - - let to_int64 t = t -end - -module Int64_map = Map.Make (Int64) - -module Frame_table = struct - type raw = (Int64.t * (Printexc.Slot.t list)) list - - type t = Printexc.Slot.t list Int64_map.t - - let demarshal chn : t = - let raw : raw = Marshal.from_channel chn in - List.fold_left (fun map (pc, rev_location_list) -> - Int64_map.add pc (List.rev rev_location_list) map) - Int64_map.empty - raw - - let find_exn = Int64_map.find -end - -module Shape_table = struct - type part_of_shape = - | Direct_call of { call_site : Int64.t; callee : Int64.t; } - | Indirect_call of Int64.t - | Allocation_point of Int64.t - - let _ = Direct_call { call_site = 0L; callee = 0L; } - let _ = Indirect_call 0L - let _ = Allocation_point 0L - - type raw = (Int64.t * (part_of_shape list)) list - - type t = { - shapes : part_of_shape list Int64_map.t; - call_counts : bool; - } - - let part_of_shape_size t = function - | Direct_call _ -> if t.call_counts then 2 else 1 - | Indirect_call _ -> 1 - | Allocation_point _ -> 3 - - let demarshal chn ~call_counts : t = - let raw : raw = Marshal.from_channel chn in - let shapes = - List.fold_left (fun map (key, data) -> Int64_map.add key data map) - Int64_map.empty - raw - in - { shapes; - call_counts; - } - - let find_exn func_id t = Int64_map.find func_id t.shapes - let call_counts t = t.call_counts -end - -module Annotation = struct - type t = int - - let to_int t = t -end - -module Trace = struct - type node - type ocaml_node - type foreign_node - type uninstrumented_node - - type t = node option - type trace = t - - (* This function unmarshals into malloc blocks, which mean that we - obtain a straightforward means of writing [compare] on [node]s. *) - external unmarshal : in_channel -> 'a - = "caml_spacetime_unmarshal_trie" - - let unmarshal in_channel = - let trace = unmarshal in_channel in - if trace = () then - None - else - Some ((Obj.magic trace) : node) - - let foreign_node_is_null (node : foreign_node) = - ((Obj.magic node) : unit) == () - - external node_num_header_words : unit -> int - = "caml_spacetime_node_num_header_words" [@@noalloc] - - let num_header_words = lazy (node_num_header_words ()) - - module OCaml = struct - type field_iterator = { - node : ocaml_node; - offset : int; - part_of_shape : Shape_table.part_of_shape; - remaining_layout : Shape_table.part_of_shape list; - shape_table : Shape_table.t; - } - - module Allocation_point = struct - type t = field_iterator - - let program_counter t = - match t.part_of_shape with - | Shape_table.Allocation_point call_site -> call_site - | _ -> assert false - - external annotation : ocaml_node -> int -> Annotation.t - = "caml_spacetime_ocaml_allocation_point_annotation" - [@@noalloc] - - let annotation t = annotation t.node t.offset - - external count : ocaml_node -> int -> int - = "caml_spacetime_ocaml_allocation_point_count" - [@@noalloc] - - let num_words_including_headers t = count t.node t.offset - end - - module Direct_call_point = struct - type _ t = field_iterator - - let call_site t = - match t.part_of_shape with - | Shape_table.Direct_call { call_site; _ } -> call_site - | _ -> assert false - - let callee t = - match t.part_of_shape with - | Shape_table.Direct_call { callee; _ } -> callee - | _ -> assert false - - external callee_node : ocaml_node -> int -> 'target - = "caml_spacetime_ocaml_direct_call_point_callee_node" - - let callee_node (type target) (t : target t) : target = - callee_node t.node t.offset - - external call_count : ocaml_node -> int -> int - = "caml_spacetime_ocaml_direct_call_point_call_count" - - let call_count t = - if Shape_table.call_counts t.shape_table then - Some (call_count t.node t.offset) - else - None - end - - module Indirect_call_point = struct - type t = field_iterator - - let call_site t = - match t.part_of_shape with - | Shape_table.Indirect_call call_site -> call_site - | _ -> assert false - - module Callee = struct - (* CR-soon mshinwell: we should think about the names again. This is - a "c_node" but it isn't foreign. *) - type t = { - node : foreign_node; - call_counts : bool; - } - - let is_null t = foreign_node_is_null t.node - - (* CR-soon mshinwell: maybe rename ...c_node_call_site -> c_node_pc, - since it isn't a call site in this case. *) - external callee : foreign_node -> Function_entry_point.t - = "caml_spacetime_c_node_call_site" - - let callee t = callee t.node - - (* This can return a node satisfying "is_null" in the case of an - uninitialised tail call point. See the comment in the C code. *) - external callee_node : foreign_node -> node - = "caml_spacetime_c_node_callee_node" [@@noalloc] - - let callee_node t = callee_node t.node - - external call_count : foreign_node -> int - = "caml_spacetime_c_node_call_count" - - let call_count t = - if t.call_counts then Some (call_count t.node) - else None - - external next : foreign_node -> foreign_node - = "caml_spacetime_c_node_next" [@@noalloc] - - let next t = - let next = { t with node = next t.node; } in - if foreign_node_is_null next.node then None - else Some next - end - - external callees : ocaml_node -> int -> foreign_node - = "caml_spacetime_ocaml_indirect_call_point_callees" - [@@noalloc] - - let callees t = - let callees = - { Callee. - node = callees t.node t.offset; - call_counts = Shape_table.call_counts t.shape_table; - } - in - if Callee.is_null callees then None - else Some callees - end - - module Field = struct - type t = field_iterator - - type direct_call_point = - | To_ocaml of ocaml_node Direct_call_point.t - | To_foreign of foreign_node Direct_call_point.t - | To_uninstrumented of - uninstrumented_node Direct_call_point.t - - type classification = - | Allocation of Allocation_point.t - | Direct_call of direct_call_point - | Indirect_call of Indirect_call_point.t - - external classify_direct_call_point : ocaml_node -> int -> int - = "caml_spacetime_classify_direct_call_point" - [@@noalloc] - - let classify t = - match t.part_of_shape with - | Shape_table.Direct_call _callee -> - let direct_call_point = - match classify_direct_call_point t.node t.offset with - | 0 -> - (* We should never classify uninitialised call points here. *) - assert false - | 1 -> To_ocaml t - | 2 -> To_foreign t - | _ -> assert false - in - Direct_call direct_call_point - | Shape_table.Indirect_call _ -> Indirect_call t - | Shape_table.Allocation_point _ -> Allocation t - - (* CR-soon mshinwell: change to "is_unused"? *) - let is_uninitialised t = - let offset_to_node_hole = - match t.part_of_shape with - | Shape_table.Direct_call _ -> Some 0 - | Shape_table.Indirect_call _ -> Some 0 - | Shape_table.Allocation_point _ -> None - in - match offset_to_node_hole with - | None -> false - | Some offset_to_node_hole -> - (* There are actually two cases: - 1. A normal unused node hole, which says Val_unit; - 2. An unused tail call point. This will contain a pointer to the - start of the current node, but it also has the bottom bit - set. *) - let offset = t.offset + offset_to_node_hole in - Obj.is_int (Obj.field (Obj.repr t.node) offset) - - let rec next t = - match t.remaining_layout with - | [] -> None - | part_of_shape::remaining_layout -> - let size = - Shape_table.part_of_shape_size t.shape_table t.part_of_shape - in - let offset = t.offset + size in - assert (offset < Obj.size (Obj.repr t.node)); - let t = - { node = t.node; - offset; - part_of_shape; - remaining_layout; - shape_table = t.shape_table; - } - in - skip_uninitialised t - - and skip_uninitialised t = - if not (is_uninitialised t) then Some t - else next t - end - - module Node = struct - type t = ocaml_node - - external function_identifier : t -> Function_identifier.t - = "caml_spacetime_ocaml_function_identifier" - - external next_in_tail_call_chain : t -> t - = "caml_spacetime_ocaml_tail_chain" [@@noalloc] - - external compare : t -> t -> int - = "caml_spacetime_compare_node" [@@noalloc] - - let fields t ~shape_table = - let id = function_identifier t in - match Shape_table.find_exn id shape_table with - | exception Not_found -> None - | [] -> None - | part_of_shape::remaining_layout -> - let t = - { node = t; - offset = Lazy.force num_header_words; - part_of_shape; - remaining_layout; - shape_table; - } - in - Field.skip_uninitialised t - end - end - - module Foreign = struct - module Node = struct - type t = foreign_node - - external compare : t -> t -> int - = "caml_spacetime_compare_node" [@@noalloc] - - let fields t = - if foreign_node_is_null t then None - else Some t - end - - module Allocation_point = struct - type t = foreign_node - - external program_counter : t -> Program_counter.Foreign.t - (* This is not a mistake; the same C function works. *) - = "caml_spacetime_c_node_call_site" - - external annotation : t -> Annotation.t - = "caml_spacetime_c_node_profinfo" [@@noalloc] - - external num_words_including_headers : t -> int - = "caml_spacetime_c_node_allocation_count" [@@noalloc] - end - - module Call_point = struct - type t = foreign_node - - external call_site : t -> Program_counter.Foreign.t - = "caml_spacetime_c_node_call_site" - - (* May return a null node. See comment above and the C code. *) - external callee_node : t -> node - = "caml_spacetime_c_node_callee_node" [@@noalloc] - end - - module Field = struct - type t = foreign_node - - type classification = - | Allocation of Allocation_point.t - | Call of Call_point.t - - external is_call : t -> bool - = "caml_spacetime_c_node_is_call" [@@noalloc] - - let classify t = - if is_call t then Call t - else Allocation t - - external next : t -> t - = "caml_spacetime_c_node_next" [@@noalloc] - - let next t = - let next = next t in - if foreign_node_is_null next then None - else Some next - end - end - - module Node = struct - module T = struct - type t = node - - external compare : t -> t -> int - = "caml_spacetime_compare_node" [@@noalloc] - end - - include T - - type classification = - | OCaml of OCaml.Node.t - | Foreign of Foreign.Node.t - - external is_ocaml_node : t -> bool - = "caml_spacetime_is_ocaml_node" [@@noalloc] - - let classify t = - if is_ocaml_node t then OCaml ((Obj.magic t) : ocaml_node) - else Foreign ((Obj.magic t) : foreign_node) - - let of_ocaml_node (node : ocaml_node) : t = Obj.magic node - let of_foreign_node (node : foreign_node) : t = Obj.magic node - - module Map = Map.Make (T) - module Set = Set.Make (T) - end - - let root t = t -end - -module Heap_snapshot = struct - - module Entries = struct - type t = int array (* == "struct snapshot_entries" *) - - let length t = - let length = Array.length t in - assert (length mod 3 = 0); - length / 3 - - let annotation t idx = t.(idx*3) - let num_blocks t idx = t.(idx*3 + 1) - let num_words_including_headers t idx = t.(idx*3 + 2) - end - - type total_allocations = - | End - | Total of { - annotation : Annotation.t; - count : int; - next : total_allocations; - } - - let (_ : total_allocations) = (* suppress compiler warning *) - Total { annotation = 0; count = 0; next = End; } - - type t = { - timestamp : float; - gc_stats : Gc_stats.t; - entries : Entries.t; - words_scanned : int; - words_scanned_with_profinfo : int; - total_allocations : total_allocations; - } - - type heap_snapshot = t - - let timestamp t = t.timestamp - let gc_stats t = t.gc_stats - let entries t = t.entries - let words_scanned t = t.words_scanned - let words_scanned_with_profinfo t = t.words_scanned_with_profinfo - - module Total_allocation = struct - type t = total_allocations (* [End] is forbidden *) - - let annotation = function - | End -> assert false - | Total { annotation; _ } -> annotation - - let num_words_including_headers = function - | End -> assert false - | Total { count; _ } -> count - - let next = function - | End -> assert false - | Total { next = End; _ } -> None - | Total { next; _ } -> Some next - end - - let total_allocations t = - match t.total_allocations with - | End -> None - | (Total _) as totals -> Some totals - - module Event = struct - type t = { - event_name : string; - time : float; - } - - let event_name t = t.event_name - let timestamp t = t.time - end - - module Series = struct - type t = { - num_snapshots : int; - time_of_writer_close : float; - frame_table : Frame_table.t; - shape_table : Shape_table.t; - traces_by_thread : Trace.t array; - finaliser_traces_by_thread : Trace.t array; - snapshots : heap_snapshot array; - events : Event.t list; - call_counts : bool; - } - - (* The order of these constructors must match the C code. *) - type what_comes_next = - | Snapshot - | Traces - | Event - - (* Suppress compiler warning 37. *) - let _ : what_comes_next list = [Snapshot; Traces; Event;] - - let rec read_snapshots_and_events chn snapshots events = - let next : what_comes_next = Marshal.from_channel chn in - match next with - | Snapshot -> - let snapshot : heap_snapshot = Marshal.from_channel chn in - read_snapshots_and_events chn (snapshot :: snapshots) events - | Event -> - let event_name : string = Marshal.from_channel chn in - let time : float = Marshal.from_channel chn in - let event = { Event. event_name; time; } in - read_snapshots_and_events chn snapshots (event :: events) - | Traces -> - (Array.of_list (List.rev snapshots)), List.rev events - - let read ~path = - let chn = open_in_bin path in - let magic_number : int = Marshal.from_channel chn in - let magic_number_base = magic_number land 0xffff_ffff in - let version_number = (magic_number lsr 32) land 0xffff in - let features = (magic_number lsr 48) land 0xffff in - if magic_number_base <> 0xace00ace then begin - failwith "Raw_spacetime_lib: not a Spacetime profiling file" - end else begin - match version_number with - | 0 -> - let call_counts = - match features with - | 0 -> false - | 1 -> true - | _ -> - failwith "Raw_spacetime_lib: unknown Spacetime profiling file \ - feature set" - in - let snapshots, events = read_snapshots_and_events chn [] [] in - let num_snapshots = Array.length snapshots in - let time_of_writer_close : float = Marshal.from_channel chn in - let frame_table = Frame_table.demarshal chn in - let shape_table = Shape_table.demarshal chn ~call_counts in - let num_threads : int = Marshal.from_channel chn in - let traces_by_thread = Array.init num_threads (fun _ -> None) in - let finaliser_traces_by_thread = - Array.init num_threads (fun _ -> None) - in - for thread = 0 to num_threads - 1 do - let trace : Trace.t = Trace.unmarshal chn in - let finaliser_trace : Trace.t = Trace.unmarshal chn in - traces_by_thread.(thread) <- trace; - finaliser_traces_by_thread.(thread) <- finaliser_trace - done; - close_in chn; - { num_snapshots; - time_of_writer_close; - frame_table; - shape_table; - traces_by_thread; - finaliser_traces_by_thread; - snapshots; - events; - call_counts; - } - | _ -> - failwith "Raw_spacetime_lib: unknown Spacetime profiling file \ - version number" - end - - type trace_kind = Normal | Finaliser - - let num_threads t = Array.length t.traces_by_thread - - let trace t ~kind ~thread_index = - if thread_index < 0 || thread_index >= num_threads t then None - else - match kind with - | Normal -> Some t.traces_by_thread.(thread_index) - | Finaliser -> Some t.finaliser_traces_by_thread.(thread_index) - - let num_snapshots t = t.num_snapshots - let snapshot t ~index = t.snapshots.(index) - let frame_table t = t.frame_table - let shape_table t = t.shape_table - let time_of_writer_close t = t.time_of_writer_close - let events t = t.events - let has_call_counts t = t.call_counts - end -end diff --git a/otherlibs/raw_spacetime_lib/raw_spacetime_lib.mli b/otherlibs/raw_spacetime_lib/raw_spacetime_lib.mli deleted file mode 100644 index 6bdffffe..00000000 --- a/otherlibs/raw_spacetime_lib/raw_spacetime_lib.mli +++ /dev/null @@ -1,364 +0,0 @@ -(**************************************************************************) -(* *) -(* OCaml *) -(* *) -(* Mark Shinwell and Leo White, Jane Street Europe *) -(* *) -(* Copyright 2015--2017 Jane Street Group LLC *) -(* *) -(* All rights reserved. This file is distributed under the terms of *) -(* the GNU Lesser General Public License version 2.1, with the *) -(* special exception on linking described in the file LICENSE. *) -(* *) -(**************************************************************************) - -(** Access to the information recorded by the [Spacetime] - module. (It is intended that this module will be used by - post-processors rather than users wishing to understand their - programs.) - For 64-bit targets only. - This module may be used from any program, not just one compiled - with a compiler configured for Spacetime. *) - -module Gc_stats : sig - type t - - val minor_words : t -> int - val promoted_words : t -> int - val major_words : t -> int - val minor_collections : t -> int - val major_collections : t -> int - val heap_words : t -> int - val heap_chunks : t -> int - val compactions : t -> int - val top_heap_words : t -> int -end - -module Annotation : sig - (** An annotation written into a value's header. These may be looked up - in a [Trace.t] (see below). *) - type t - - (* CR-someday mshinwell: consider using tag and size to increase the - available space of annotations. Need to be careful of [Obj.truncate]. - Could also randomise the tags on records. - *) - - val to_int : t -> int -end - -module Program_counter : sig - module OCaml : sig - type t - - val to_int64 : t -> Int64.t - end - - module Foreign : sig - type t - - val to_int64 : t -> Int64.t - end - -end - -module Frame_table : sig - (* CR-someday mshinwell: move to [Gc] if dependencies permit? *) - (** A value of type [t] corresponds to the frame table of a running - OCaml program. The table is indexed by program counter address - (typically, but not always when using Spacetime, return addresses). *) - type t - - (** Find the location, including any inlined frames, corresponding to the - given program counter address. Raises [Not_found] if the location - could not be resolved. *) - val find_exn : Program_counter.OCaml.t -> t -> Printexc.Slot.t list -end - -module Function_entry_point : sig - type t - - val to_int64 : t -> Int64.t -end - -module Function_identifier : sig - type t - (* CR-soon mshinwell: same as [Function_entry_point] now *) - val to_int64 : t -> Int64.t -end - -module Shape_table : sig - type t -end - -module Trace : sig - (** A value of type [t] holds the dynamic call structure of the program - (i.e. which functions have called which other functions) together with - information required to decode profiling annotations written into - values' headers. *) - type t - type trace = t - - type node - type ocaml_node - type foreign_node - type uninstrumented_node - - module OCaml : sig - module Allocation_point : sig - (** A value of type [t] corresponds to an allocation point in OCaml - code. *) - type t - - (** The program counter at (or close to) the allocation site. *) - val program_counter : t -> Program_counter.OCaml.t - - (** The annotation written into the headers of boxed values allocated - at the given allocation site. *) - val annotation : t -> Annotation.t - - (** The total number of words allocated at this point. *) - val num_words_including_headers : t -> int - end - - module Direct_call_point : sig - (** A value of type ['target t] corresponds to a direct (i.e. known - at compile time) call point in OCaml code. ['target] is the type - of the node corresponding to the callee. *) - type 'target t - - (** The program counter at (or close to) the call site. *) - val call_site : _ t -> Program_counter.OCaml.t - - (** The address of the first instruction of the callee. *) - val callee : _ t -> Function_entry_point.t - - (** The node corresponding to the callee. *) - val callee_node : 'target t -> 'target - - (** The number of times the callee was called. Only available if the - compiler that recorded the Spacetime profile was configured with - "-with-spacetime-call-counts". [None] will be returned otherwise. *) - val call_count : _ t -> int option - end - - module Indirect_call_point : sig - (** A value of type [t] corresponds to an indirect call point in OCaml - code. Each such value contains a list of callees to which the - call point has branched. *) - type t - - (** The program counter at (or close to) the call site. *) - val call_site : t -> Program_counter.OCaml.t - - module Callee : sig - type t - - (** The address of the first instruction of the callee. *) - val callee : t -> Function_entry_point.t - - (** The node corresponding to the callee. *) - val callee_node : t -> node - - (** The number of times the callee was called. This returns [None] in - the same circumstances as [Direct_call_point.call_count], above. *) - val call_count : t -> int option - - (** Move to the next callee to which this call point has branched. - [None] is returned when the end of the list is reached. *) - val next : t -> t option - end - - (** The list of callees to which this indirect call point has - branched. *) - val callees : t -> Callee.t option - end - - module Field : sig - (** A value of type [t] enables iteration through the contents - ("fields") of an OCaml node. *) - type t - - type direct_call_point = - | To_ocaml of ocaml_node Direct_call_point.t - | To_foreign of foreign_node Direct_call_point.t - (* CR-soon mshinwell: once everything's finished, "uninstrumented" - should be able to go away. Let's try to do this after the - first release. *) - | To_uninstrumented of - uninstrumented_node Direct_call_point.t - - type classification = - | Allocation of Allocation_point.t - | Direct_call of direct_call_point - | Indirect_call of Indirect_call_point.t - - val classify : t -> classification - val next : t -> t option - end - - module Node : sig - (** A node corresponding to an invocation of a function written in - OCaml. *) - type t = ocaml_node - - val compare : t -> t -> int - - (** A unique identifier for the function corresponding to this node. *) - val function_identifier : t -> Function_identifier.t - - (** This function traverses a circular list. *) - val next_in_tail_call_chain : t -> t - - val fields : t -> shape_table:Shape_table.t -> Field.t option - end - end - - module Foreign : sig - module Allocation_point : sig - (** A value of type [t] corresponds to an allocation point in non-OCaml - code. *) - type t - - val program_counter : t -> Program_counter.Foreign.t - val annotation : t -> Annotation.t - val num_words_including_headers : t -> int - end - - module Call_point : sig - (** A value of type [t] corresponds to a call point from non-OCaml - code (to either non-OCaml code, or OCaml code via the usual - assembly veneer). Call counts are not available for such nodes. *) - type t - - (** N.B. The address of the callee (of type [Function_entry_point.t]) is - not available. It must be recovered during post-processing. *) - val call_site : t -> Program_counter.Foreign.t - val callee_node : t -> node - end - - module Field : sig - (** A value of type [t] enables iteration through the contents ("fields") - of a C node. *) - type t - - type classification = private - | Allocation of Allocation_point.t - | Call of Call_point.t - - val classify : t -> classification - val next : t -> t option - end - - module Node : sig - (** A node corresponding to an invocation of a function written in C - (or any other language that is not OCaml). *) - type t = foreign_node - - val compare : t -> t -> int - - val fields : t -> Field.t option - - end - - end - - module Node : sig - (** Either an OCaml or a foreign node; or an indication that this - is a branch of the graph corresponding to uninstrumented - code. *) - type t = node - - val compare : t -> t -> int - - type classification = private - | OCaml of OCaml.Node.t - | Foreign of Foreign.Node.t - - val classify : t -> classification - - val of_ocaml_node : OCaml.Node.t -> t - val of_foreign_node : Foreign.Node.t -> t - - module Set : Set.S with type elt = t - module Map : Map.S with type key = t - end - - (** Obtains the root of the graph for traversal. [None] is returned if - the graph is empty. *) - val root : t -> Node.t option -end - -module Heap_snapshot : sig - type t - type heap_snapshot = t - - module Entries : sig - (** An immutable array of the total number of blocks (= boxed - values) and the total number of words occupied by such blocks - (including their headers) for each profiling annotation in - the heap. *) - type t - - val length : t -> int - val annotation : t -> int -> Annotation.t - val num_blocks : t -> int -> int - val num_words_including_headers : t -> int -> int - - end - - (** The timestamp of a snapshot. The units are as for [Sys.time] - (unless custom timestamps are being provided, cf. the [Spacetime] module - in the standard library). *) - val timestamp : t -> float - - val gc_stats : t -> Gc_stats.t - val entries : t -> Entries.t - val words_scanned : t -> int - val words_scanned_with_profinfo : t -> int - - module Total_allocation : sig - type t - - val annotation : t -> Annotation.t - val num_words_including_headers : t -> int - val next : t -> t option - end - - (** Total allocations across *all threads*. *) - (* CR-someday mshinwell: change the relevant variables to be thread-local *) - val total_allocations : t -> Total_allocation.t option - - module Event : sig - type t - - val event_name : t -> string - val timestamp : t -> float - end - - module Series : sig - type t - - (** At present, the [Trace.t] associated with a [Series.t] cannot be - garbage collected or freed. This should not be a problem, since - the intention is that a post-processor reads the trace and outputs - another format. *) - val read : path:string -> t - - val time_of_writer_close : t -> float - val num_threads : t -> int - - type trace_kind = Normal | Finaliser - val trace : t -> kind:trace_kind -> thread_index:int -> Trace.t option - - val frame_table : t -> Frame_table.t - val shape_table : t -> Shape_table.t - val num_snapshots : t -> int - val snapshot : t -> index:int -> heap_snapshot - val events : t -> Event.t list - - (** Returns [true] iff call count information was recorded in the - series. *) - val has_call_counts : t -> bool - end -end diff --git a/otherlibs/raw_spacetime_lib/spacetime_offline.c b/otherlibs/raw_spacetime_lib/spacetime_offline.c deleted file mode 100644 index d022c5de..00000000 --- a/otherlibs/raw_spacetime_lib/spacetime_offline.c +++ /dev/null @@ -1,250 +0,0 @@ -/**************************************************************************/ -/* */ -/* OCaml */ -/* */ -/* Mark Shinwell and Leo White, Jane Street Europe */ -/* */ -/* Copyright 2013--2016, Jane Street Group, LLC */ -/* */ -/* All rights reserved. This file is distributed under the terms of */ -/* the GNU Lesser General Public License version 2.1, with the */ -/* special exception on linking described in the file LICENSE. */ -/* */ -/**************************************************************************/ - -#define CAML_INTERNALS - -#include -#include -#include -#include -#include - -#include "caml/alloc.h" -#include "caml/config.h" -#include "caml/fail.h" -#include "caml/gc.h" -#include "caml/intext.h" -#include "caml/major_gc.h" -#include "caml/memory.h" -#include "caml/minor_gc.h" -#include "caml/misc.h" -#include "caml/mlvalues.h" -#include "caml/roots.h" -#include "caml/signals.h" -#include "caml/stack.h" -#include "caml/sys.h" -#include "caml/spacetime.h" - -#include "caml/s.h" - -#define SPACETIME_PROFINFO_WIDTH 26 -#define Spacetime_profinfo_hd(hd) \ - (Gen_profinfo_hd(SPACETIME_PROFINFO_WIDTH, hd)) - -#ifdef ARCH_SIXTYFOUR - -/* CR-someday lwhite: The following two definitions are copied from spacetime.c - because they are needed here, but must be inlined in spacetime.c - for performance. Perhaps a macro or "static inline" would be - more appropriate. */ - -c_node* caml_spacetime_offline_c_node_of_stored_pointer_not_null - (value node_stored) -{ - CAMLassert(Is_c_node(node_stored)); - return (c_node*) Hp_val(node_stored); -} - -c_node_type caml_spacetime_offline_classify_c_node(c_node* node) -{ - return (node->pc & 2) ? CALL : ALLOCATION; -} - -CAMLprim value caml_spacetime_compare_node( - value node1, value node2) -{ - CAMLassert(!Is_in_value_area(node1)); - CAMLassert(!Is_in_value_area(node2)); - - if (node1 == node2) { - return Val_long(0); - } - if (node1 < node2) { - return Val_long(-1); - } - return Val_long(1); -} - -CAMLprim value caml_spacetime_unmarshal_trie (value v_channel) -{ - return caml_input_value_to_outside_heap(v_channel); -} - -CAMLprim value caml_spacetime_node_num_header_words(value unit) -{ - return Val_long(Node_num_header_words); -} - -CAMLprim value caml_spacetime_is_ocaml_node(value node) -{ - CAMLassert(Is_ocaml_node(node) || Is_c_node(node)); - return Val_bool(Is_ocaml_node(node)); -} - -CAMLprim value caml_spacetime_ocaml_function_identifier(value node) -{ - CAMLassert(Is_ocaml_node(node)); - return caml_copy_int64((uint64_t) Decode_node_pc(Node_pc(node))); -} - -CAMLprim value caml_spacetime_ocaml_tail_chain(value node) -{ - CAMLassert(Is_ocaml_node(node)); - return Tail_link(node); -} - -CAMLprim value caml_spacetime_classify_direct_call_point - (value node, value offset) -{ - uintnat field; - value callee_node; - - CAMLassert(Is_ocaml_node(node)); - - field = Long_val(offset); - - callee_node = Direct_callee_node(node, field); - if (!Is_block(callee_node)) { - /* An unused call point (may be a tail call point). */ - return Val_long(0); - } else if (Is_ocaml_node(callee_node)) { - return Val_long(1); /* direct call point to OCaml code */ - } else { - return Val_long(2); /* direct call point to non-OCaml code */ - } -} - -CAMLprim value caml_spacetime_ocaml_allocation_point_annotation - (value node, value offset) -{ - uintnat profinfo_shifted; - profinfo_shifted = (uintnat) Alloc_point_profinfo(node, Long_val(offset)); - return Val_long(Spacetime_profinfo_hd(profinfo_shifted)); -} - -CAMLprim value caml_spacetime_ocaml_allocation_point_count - (value node, value offset) -{ - value count = Alloc_point_count(node, Long_val(offset)); - CAMLassert(!Is_block(count)); - return count; -} - -CAMLprim value caml_spacetime_ocaml_direct_call_point_callee_node - (value node, value offset) -{ - return Direct_callee_node(node, Long_val(offset)); -} - -CAMLprim value caml_spacetime_ocaml_direct_call_point_call_count -(value node, value offset) -{ - return Direct_call_count(node, Long_val(offset)); -} - -CAMLprim value caml_spacetime_ocaml_indirect_call_point_callees - (value node, value offset) -{ - value callees = Indirect_pc_linked_list(node, Long_val(offset)); - CAMLassert(Is_block(callees)); - CAMLassert(Is_c_node(callees)); - return callees; -} - -CAMLprim value caml_spacetime_c_node_is_call(value node) -{ - c_node* c_node; - CAMLassert(node != (value) NULL); - CAMLassert(Is_c_node(node)); - c_node = caml_spacetime_offline_c_node_of_stored_pointer_not_null(node); - switch (caml_spacetime_offline_classify_c_node(c_node)) { - case CALL: return Val_true; - case ALLOCATION: return Val_false; - } - CAMLassert(0); - return Val_unit; /* silence compiler warning */ -} - -CAMLprim value caml_spacetime_c_node_next(value node) -{ - c_node* c_node; - - CAMLassert(node != (value) NULL); - CAMLassert(Is_c_node(node)); - c_node = caml_spacetime_offline_c_node_of_stored_pointer_not_null(node); - CAMLassert(c_node->next == Val_unit || Is_c_node(c_node->next)); - return c_node->next; -} - -CAMLprim value caml_spacetime_c_node_call_site(value node) -{ - c_node* c_node; - CAMLassert(node != (value) NULL); - CAMLassert(Is_c_node(node)); - c_node = caml_spacetime_offline_c_node_of_stored_pointer_not_null(node); - return caml_copy_int64((uint64_t) Decode_c_node_pc(c_node->pc)); -} - -CAMLprim value caml_spacetime_c_node_callee_node(value node) -{ - c_node* c_node; - CAMLassert(node != (value) NULL); - CAMLassert(Is_c_node(node)); - c_node = caml_spacetime_offline_c_node_of_stored_pointer_not_null(node); - CAMLassert(caml_spacetime_offline_classify_c_node(c_node) == CALL); - /* This might be an uninitialised tail call point: for example if an OCaml - callee was indirectly called but the callee wasn't instrumented (e.g. a - leaf function that doesn't allocate). */ - if (Is_tail_caller_node_encoded(c_node->data.call.callee_node)) { - return Val_unit; - } - return c_node->data.call.callee_node; -} - -CAMLprim value caml_spacetime_c_node_call_count(value node) -{ - c_node* c_node; - CAMLassert(node != (value) NULL); - CAMLassert(Is_c_node(node)); - c_node = caml_spacetime_offline_c_node_of_stored_pointer_not_null(node); - CAMLassert(caml_spacetime_offline_classify_c_node(c_node) == CALL); - if (Is_tail_caller_node_encoded(c_node->data.call.callee_node)) { - return Val_long(0); - } - return c_node->data.call.call_count; -} - -CAMLprim value caml_spacetime_c_node_profinfo(value node) -{ - c_node* c_node; - CAMLassert(node != (value) NULL); - CAMLassert(Is_c_node(node)); - c_node = caml_spacetime_offline_c_node_of_stored_pointer_not_null(node); - CAMLassert(caml_spacetime_offline_classify_c_node(c_node) == ALLOCATION); - CAMLassert(!Is_block(c_node->data.allocation.profinfo)); - return Val_long(Spacetime_profinfo_hd(c_node->data.allocation.profinfo)); -} - -CAMLprim value caml_spacetime_c_node_allocation_count(value node) -{ - c_node* c_node; - CAMLassert(node != (value) NULL); - CAMLassert(Is_c_node(node)); - c_node = caml_spacetime_offline_c_node_of_stored_pointer_not_null(node); - CAMLassert(caml_spacetime_offline_classify_c_node(c_node) == ALLOCATION); - CAMLassert(!Is_block(c_node->data.allocation.count)); - return c_node->data.allocation.count; -} - -#endif diff --git a/otherlibs/str/.depend b/otherlibs/str/.depend index e9bdc28a..0021a7d1 100644 --- a/otherlibs/str/.depend +++ b/otherlibs/str/.depend @@ -1,10 +1,3 @@ -strstubs.$(O): strstubs.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h \ - ../../runtime/caml/fail.h str.cmo : \ str.cmi str.cmx : \ diff --git a/otherlibs/str/Makefile b/otherlibs/str/Makefile index 6b0f025e..ef8aca10 100644 --- a/otherlibs/str/Makefile +++ b/otherlibs/str/Makefile @@ -26,11 +26,6 @@ str.cmx: str.cmi .PHONY: depend depend: -ifeq "$(TOOLCHAIN)" "msvc" - $(error Dependencies cannot be regenerated using the MSVC ports) -else - $(CC) -MM $(OC_CPPFLAGS) *.c | sed -e 's/\.o/.$$(O)/g' > .depend - $(CAMLRUN) $(ROOTDIR)/boot/ocamlc -depend -slash *.mli *.ml >> .depend -endif + $(CAMLRUN) $(ROOTDIR)/boot/ocamlc -depend -slash *.mli *.ml > .depend include .depend diff --git a/otherlibs/systhreads/.depend b/otherlibs/systhreads/.depend index 8647bddf..3bd0a007 100644 --- a/otherlibs/systhreads/.depend +++ b/otherlibs/systhreads/.depend @@ -1,37 +1,3 @@ -st_stubs_b.$(O): st_stubs.c ../../runtime/caml/alloc.h \ - ../../runtime/caml/misc.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/domain_state.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/backtrace.h \ - ../../runtime/caml/exec.h ../../runtime/caml/callback.h \ - ../../runtime/caml/custom.h ../../runtime/caml/domain.h \ - ../../runtime/caml/fail.h ../../runtime/caml/io.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h ../../runtime/caml/misc.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/printexc.h \ - ../../runtime/caml/roots.h ../../runtime/caml/memory.h \ - ../../runtime/caml/signals.h ../../runtime/caml/stacks.h \ - ../../runtime/caml/sys.h ../../runtime/caml/memprof.h \ - ../../runtime/caml/roots.h threads.h -st_stubs_n.$(O): st_stubs.c ../../runtime/caml/alloc.h \ - ../../runtime/caml/misc.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/domain_state.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/backtrace.h \ - ../../runtime/caml/exec.h ../../runtime/caml/callback.h \ - ../../runtime/caml/custom.h ../../runtime/caml/domain.h \ - ../../runtime/caml/fail.h ../../runtime/caml/io.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h ../../runtime/caml/misc.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/printexc.h \ - ../../runtime/caml/roots.h ../../runtime/caml/memory.h \ - ../../runtime/caml/signals.h ../../runtime/caml/stack.h \ - ../../runtime/caml/sys.h ../../runtime/caml/memprof.h \ - ../../runtime/caml/roots.h threads.h condition.cmo : \ mutex.cmi \ condition.cmi @@ -54,6 +20,15 @@ mutex.cmo : \ mutex.cmx : \ mutex.cmi mutex.cmi : +semaphore.cmo : \ + mutex.cmi \ + condition.cmi \ + semaphore.cmi +semaphore.cmx : \ + mutex.cmx \ + condition.cmx \ + semaphore.cmi +semaphore.cmi : thread.cmo : \ thread.cmi thread.cmx : \ diff --git a/otherlibs/systhreads/Makefile b/otherlibs/systhreads/Makefile index 173183ba..be42d0b8 100644 --- a/otherlibs/systhreads/Makefile +++ b/otherlibs/systhreads/Makefile @@ -15,11 +15,14 @@ ROOTDIR=../.. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common +include $(ROOTDIR)/Makefile.common include $(ROOTDIR)/Makefile.best_binaries -OC_CFLAGS += $(SHAREDLIB_CFLAGS) +ifneq "$(CCOMPTYPE)" "msvc" +OC_CFLAGS += -g +endif + +OC_CFLAGS += $(SHAREDLIB_CFLAGS) $(PTHREAD_CFLAGS) OC_CPPFLAGS += -I$(ROOTDIR)/runtime @@ -33,7 +36,7 @@ LIBS = -nostdlib -I $(ROOTDIR)/stdlib -I $(ROOTDIR)/otherlibs/$(UNIXLIB) CAMLC=$(BEST_OCAMLC) $(LIBS) CAMLOPT=$(BEST_OCAMLOPT) $(LIBS) -MKLIB=$(CAMLRUN) $(ROOTDIR)/tools/ocamlmklib +MKLIB=$(CAMLRUN) $(ROOTDIR)/tools/ocamlmklib$(EXE) COMPFLAGS=-w +33..39 -warn-error A -g -bin-annot -safe-string ifeq "$(FLAMBDA)" "true" OPTCOMPFLAGS += -O3 @@ -41,26 +44,23 @@ endif LIBNAME=threads -ifeq "$(UNIX_OR_WIN32)" "unix" -HEADER = st_posix.h -else # Windows -HEADER = st_win32.h -endif - # Note: the header on which object files produced from st_stubs.c # should actually depend is known for sure only at compile-time. # That's why this dependency is handled in the Makefile directly # and removed from the output of the C compiler during make depend -BYTECODE_C_OBJS=st_stubs_b.$(O) -NATIVECODE_C_OBJS=st_stubs_n.$(O) +BYTECODE_C_OBJS=st_stubs.b.$(O) +NATIVECODE_C_OBJS=st_stubs.n.$(O) -THREADS_SOURCES = thread.ml mutex.ml condition.ml event.ml threadUnix.ml +THREADS_SOURCES = thread.ml mutex.ml condition.ml event.ml threadUnix.ml \ + semaphore.ml THREADS_BCOBJS = $(THREADS_SOURCES:.ml=.cmo) THREADS_NCOBJS = $(THREADS_SOURCES:.ml=.cmx) -MLIFILES=thread.mli mutex.mli condition.mli event.mli threadUnix.mli +MLIFILES=thread.mli mutex.mli condition.mli event.mli threadUnix.mli \ + semaphore.mli + CMIFILES=$(MLIFILES:.mli=.cmi) all: lib$(LIBNAME).$(A) $(LIBNAME).cma $(CMIFILES) @@ -95,30 +95,32 @@ $(LIBNAME).cmxa: $(THREADS_NCOBJS) # which itself will pass -lunix to the C linker. It seems more # modular to me this way. -- Alain -# The following lines produce two object files st_stubs_b.$(O) and -# st_stubs_n.$(O) from the same source file st_stubs.c (it is compiled +# The following lines produce two object files st_stubs.b.$(O) and +# st_stubs.n.$(O) from the same source file st_stubs.c (it is compiled # twice, each time with different options). -st_stubs_n.$(O): OC_CPPFLAGS += $(NATIVE_CPPFLAGS) - -st_stubs_b.$(O): st_stubs.c $(HEADER) - $(CC) -c $(OC_CFLAGS) $(OC_CPPFLAGS) $(OUTPUTOBJ)$@ $< +st_stubs.n.$(O): OC_CPPFLAGS += $(NATIVE_CPPFLAGS) -st_stubs_n.$(O): st_stubs.c $(HEADER) - $(CC) -c $(OC_CFLAGS) $(OC_CPPFLAGS) $(OUTPUTOBJ)$@ $< +ifneq "$(COMPUTE_DEPS)" "false" +st_stubs.%.$(O): st_stubs.c +else +st_stubs.%.$(O): st_stubs.c $(RUNTIME_HEADERS) $(wildcard *.h) +endif + $(CC) -c $(OC_CFLAGS) $(CFLAGS) $(OC_CPPFLAGS) $(CPPFLAGS) \ + $(OUTPUTOBJ)$@ $< partialclean: rm -f *.cm* clean: partialclean rm -f dllthreads*.so dllthreads*.dll *.a *.lib *.o *.obj + rm -rf $(DEPDIR) INSTALL_THREADSLIBDIR=$(INSTALL_LIBDIR)/$(LIBNAME) install: if test -f dllthreads$(EXT_DLL); then \ - $(INSTALL_PROG) \ - dllthreads$(EXT_DLL) "$(INSTALL_STUBLIBDIR)/dllthreads$(EXT_DLL)"; \ + $(INSTALL_PROG) dllthreads$(EXT_DLL) "$(INSTALL_STUBLIBDIR)"; \ fi $(INSTALL_DATA) libthreads.$(A) "$(INSTALL_LIBDIR)" cd "$(INSTALL_LIBDIR)"; $(RANLIB) libthreads.$(A) @@ -153,19 +155,27 @@ installopt: .ml.cmx: $(CAMLOPT) -c $(COMPFLAGS) $(OPTCOMPFLAGS) $< +DEP_FILES := st_stubs.b.$(D) +ifneq "$(NATIVE_COMPILER)" "false" +DEP_FILES += st_stubs.n.$(D) +endif + +ifeq "$(COMPUTE_DEPS)" "true" +include $(addprefix $(DEPDIR)/, $(DEP_FILES)) +endif + +%.n.$(O): OC_CPPFLAGS += $(NATIVE_CPPFLAGS) +%.n.$(D): OC_CPPFLAGS += $(NATIVE_CPPFLAGS) + +define GEN_RULE +$(DEPDIR)/%.$(1).$(D): %.c | $(DEPDIR) + $$(DEP_CC) $$(OC_CPPFLAGS) $$(CPPFLAGS) $$< -MT '$$*.$(1).$(O)' -MF $$@ +endef + +$(foreach object_type, b n, $(eval $(call GEN_RULE,$(object_type)))) + .PHONY: depend -ifeq "$(TOOLCHAIN)" "msvc" depend: - $(error Dependencies cannot be regenerated using the MSVC ports) -else -depend: - $(CC) -MM $(OC_CPPFLAGS) st_stubs.c \ - | sed -e 's/st_stubs\.o/st_stubs_b.$$(O)/' \ - -e 's/ st_\(posix\|win32\)\.h//g' > .depend - $(CC) -MM $(OC_CPPFLAGS) $(NATIVE_CPPFLAGS) \ - st_stubs.c | sed -e 's/st_stubs\.o/st_stubs_n.$$(O)/' \ - -e 's/ st_\(posix\|win32\)\.h//g' >> .depend - $(CAMLRUN) $(ROOTDIR)/boot/ocamlc -depend -slash *.mli *.ml >> .depend -endif + $(CAMLRUN) $(ROOTDIR)/boot/ocamlc -depend -slash *.mli *.ml > .depend include .depend diff --git a/otherlibs/systhreads/mutex.mli b/otherlibs/systhreads/mutex.mli index 8953a159..70a67ce4 100644 --- a/otherlibs/systhreads/mutex.mli +++ b/otherlibs/systhreads/mutex.mli @@ -36,7 +36,13 @@ val lock : t -> unit (** Lock the given mutex. Only one thread can have the mutex locked at any time. A thread that attempts to lock a mutex already locked by another thread will suspend until the other thread unlocks - the mutex. *) + the mutex. + + @raise Sys_error if the mutex is already locked by the thread calling + {!Mutex.lock}. + + @before 4.12 {!Sys_error} was not raised for recursive locking + (platform-dependent behaviour) *) val try_lock : t -> bool (** Same as {!Mutex.lock}, but does not suspend the calling thread if @@ -46,4 +52,9 @@ val try_lock : t -> bool val unlock : t -> unit (** Unlock the given mutex. Other threads suspended trying to lock - the mutex will restart. *) + the mutex will restart. The mutex must have been previously locked + by the thread that calls {!Mutex.unlock}. + @raise Sys_error if the mutex is unlocked or was locked by another thread. + + @before 4.12 {!Sys_error} was not raised when unlocking an unlocked mutex + or when unlocking a mutex from a different thread. *) diff --git a/otherlibs/systhreads/semaphore.ml b/otherlibs/systhreads/semaphore.ml new file mode 100644 index 00000000..e4fa4181 --- /dev/null +++ b/otherlibs/systhreads/semaphore.ml @@ -0,0 +1,86 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, Collège de France and INRIA Paris *) +(* *) +(* Copyright 2020 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(** Semaphores *) + +type sem = { + mut: Mutex.t; (* protects [v] *) + mutable v: int; (* the current value *) + nonzero: Condition.t (* signaled when [v > 0] *) +} + +module Counting = struct + +type t = sem + +let make v = + if v < 0 then invalid_arg "Semaphore.Counting.init: wrong initial value"; + { mut = Mutex.create(); v; nonzero = Condition.create() } + +let release s = + Mutex.lock s.mut; + if s.v < max_int then begin + s.v <- s.v + 1; + Condition.signal s.nonzero; + Mutex.unlock s.mut + end else begin + Mutex.unlock s.mut; + raise (Sys_error "Semaphore.Counting.release: overflow") + end + +let acquire s = + Mutex.lock s.mut; + while s.v = 0 do Condition.wait s.nonzero s.mut done; + s.v <- s.v - 1; + Mutex.unlock s.mut + +let try_acquire s = + Mutex.lock s.mut; + let ret = if s.v = 0 then false else (s.v <- s.v - 1; true) in + Mutex.unlock s.mut; + ret + +let get_value s = s.v + +end + +module Binary = struct + +type t = sem + +let make b = + { mut = Mutex.create(); + v = if b then 1 else 0; + nonzero = Condition.create() } + +let release s = + Mutex.lock s.mut; + s.v <- 1; + Condition.signal s.nonzero; + Mutex.unlock s.mut + +let acquire s = + Mutex.lock s.mut; + while s.v = 0 do Condition.wait s.nonzero s.mut done; + s.v <- 0; + Mutex.unlock s.mut + +let try_acquire s = + Mutex.lock s.mut; + let ret = if s.v = 0 then false else (s.v <- 0; true) in + Mutex.unlock s.mut; + ret + +end diff --git a/otherlibs/systhreads/semaphore.mli b/otherlibs/systhreads/semaphore.mli new file mode 100644 index 00000000..3a627478 --- /dev/null +++ b/otherlibs/systhreads/semaphore.mli @@ -0,0 +1,140 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, Collège de France and INRIA Paris *) +(* *) +(* Copyright 2020 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(** Semaphores + + A semaphore is a thread synchronization device that can be used to + control access to a shared resource. + + Two flavors of semaphores are provided: counting semaphores and + binary semaphores. + + @since 4.12 *) + +(** {2 Counting semaphores} *) + +(** + A counting semaphore is a counter that can be accessed concurrently + by several threads. The typical use is to synchronize producers and + consumers of a resource by counting how many units of the resource + are available. + + The two basic operations on semaphores are: +- "release" (also called "V", "post", "up", and "signal"), which + increments the value of the counter. This corresponds to producing + one more unit of the shared resource and making it available to others. +- "acquire" (also called "P", "wait", "down", and "pend"), which + waits until the counter is greater than zero and decrements it. + This corresponds to consuming one unit of the shared resource. + + @since 4.12 *) + +module Counting : sig + +type t +(** The type of counting semaphores. *) + +val make : int -> t +(** [make n] returns a new counting semaphore, with initial value [n]. + The initial value [n] must be nonnegative. + + @raise Invalid_argument if [n < 0] +*) + +val release : t -> unit +(** [release s] increments the value of semaphore [s]. + If other threads are waiting on [s], one of them is restarted. + If the current value of [s] is equal to [max_int], the value of + the semaphore is unchanged and a [Sys_error] exception is raised + to signal overflow. + + @raise Sys_error if the value of the semaphore would overflow [max_int] +*) + +val acquire : t -> unit +(** [acquire s] blocks the calling thread until the value of semaphore [s] + is not zero, then atomically decrements the value of [s] and returns. +*) + +val try_acquire : t -> bool +(** [try_acquire s] immediately returns [false] if the value of semaphore [s] + is zero. Otherwise, the value of [s] is atomically decremented + and [try_acquire s] returns [true]. +*) + +val get_value : t -> int +(** [get_value s] returns the current value of semaphore [s]. + The current value can be modified at any time by concurrent + {!release} and {!acquire} operations. Hence, the [get_value] + operation is racy, and its result should only be used for debugging + or informational messages. +*) + +end + +(** {2 Binary semaphores} *) + +(** Binary semaphores are a variant of counting semaphores + where semaphores can only take two values, 0 and 1. + + A binary semaphore can be used to control access to a single + shared resource, with value 1 meaning "resource is available" and + value 0 meaning "resource is unavailable". + + The "release" operation of a binary semaphore sets its value to 1, + and "acquire" waits until the value is 1 and sets it to 0. + + A binary semaphore can be used instead of a mutex (see module + {!Mutex}) when the mutex discipline (of unlocking the mutex from the + thread that locked it) is too restrictive. The "acquire" operation + corresponds to locking the mutex, and the "release" operation to + unlocking it, but "release" can be performed in a thread different + than the one that performed the "acquire". Likewise, it is safe + to release a binary semaphore that is already available. + + @since 4.12 +*) + +module Binary : sig + +type t +(** The type of binary semaphores. *) + +val make : bool -> t +(** [make b] returns a new binary semaphore. + If [b] is [true], the initial value of the semaphore is 1, meaning + "available". If [b] is [false], the initial value of the + semaphore is 0, meaning "unavailable". +*) + +val release : t -> unit +(** [release s] sets the value of semaphore [s] to 1, putting it in the + "available" state. If other threads are waiting on [s], one of them is + restarted. +*) + +val acquire : t -> unit +(** [acquire s] blocks the calling thread until the semaphore [s] + has value 1 (is available), then atomically sets it to 0 + and returns. +*) + +val try_acquire : t -> bool +(** [try_acquire s] immediately returns [false] if the semaphore [s] + has value 0. If [s] has value 1, its value is atomically set to 0 + and [try_acquire s] returns [true]. +*) + +end diff --git a/otherlibs/systhreads/st_posix.h b/otherlibs/systhreads/st_posix.h index 17ed1514..957f4717 100644 --- a/otherlibs/systhreads/st_posix.h +++ b/otherlibs/systhreads/st_posix.h @@ -21,9 +21,6 @@ #include #include #include -#ifdef __sun -#define _POSIX_PTHREAD_SEMANTICS -#endif #include #include #include @@ -106,6 +103,12 @@ Caml_inline void st_tls_set(st_tlskey k, void * v) pthread_setspecific(k, v); } +/* Windows-specific hook. */ +Caml_inline void st_thread_set_id(intnat id) +{ + return; +} + /* The master lock. This is a mutex that is held most of the time, so we implement it in a slightly convoluted way to avoid all risks of busy-waiting. Also, we count the number of waiting @@ -197,12 +200,26 @@ typedef pthread_mutex_t * st_mutex; static int st_mutex_create(st_mutex * res) { int rc; - st_mutex m = caml_stat_alloc_noexc(sizeof(pthread_mutex_t)); - if (m == NULL) return ENOMEM; - rc = pthread_mutex_init(m, NULL); - if (rc != 0) { caml_stat_free(m); return rc; } + pthread_mutexattr_t attr; + st_mutex m; + + rc = pthread_mutexattr_init(&attr); + if (rc != 0) goto error1; + rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); + if (rc != 0) goto error2; + m = caml_stat_alloc_noexc(sizeof(pthread_mutex_t)); + if (m == NULL) { rc = ENOMEM; goto error2; } + rc = pthread_mutex_init(m, &attr); + if (rc != 0) goto error3; + pthread_mutexattr_destroy(&attr); *res = m; return 0; +error3: + caml_stat_free(m); +error2: + pthread_mutexattr_destroy(&attr); +error1: + return rc; } static int st_mutex_destroy(st_mutex m) @@ -213,19 +230,23 @@ static int st_mutex_destroy(st_mutex m) return rc; } +#define MUTEX_DEADLOCK EDEADLK + Caml_inline int st_mutex_lock(st_mutex m) { return pthread_mutex_lock(m); } -#define PREVIOUSLY_UNLOCKED 0 -#define ALREADY_LOCKED EBUSY +#define MUTEX_PREVIOUSLY_UNLOCKED 0 +#define MUTEX_ALREADY_LOCKED EBUSY Caml_inline int st_mutex_trylock(st_mutex m) { return pthread_mutex_trylock(m); } +#define MUTEX_NOT_OWNED EPERM + Caml_inline int st_mutex_unlock(st_mutex m) { return pthread_mutex_unlock(m); @@ -437,6 +458,8 @@ value caml_thread_sigmask(value cmd, value sigs) /* ML */ retcode = pthread_sigmask(how, &set, &oldset); caml_leave_blocking_section(); st_check_error(retcode, "Thread.sigmask"); + /* Run any handlers for just-unmasked pending signals */ + caml_process_pending_actions(); return st_encode_sigset(&oldset); } diff --git a/otherlibs/systhreads/st_stubs.c b/otherlibs/systhreads/st_stubs.c index 285466ed..2f3f1d10 100644 --- a/otherlibs/systhreads/st_stubs.c +++ b/otherlibs/systhreads/st_stubs.c @@ -35,11 +35,9 @@ #endif #include "caml/sys.h" #include "caml/memprof.h" -#include "threads.h" -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) -#include "caml/spacetime.h" -#endif +/* threads.h is *not* included since it contains the _external_ declarations for + the caml_c_thread_register and caml_c_thread_unregister functions. */ #ifndef NATIVE_CODE /* Initial size of bytecode stack when a thread is created (4 Ko) */ @@ -82,12 +80,6 @@ struct caml_thread_struct { char * exception_pointer; /* Saved value of Caml_state->exception_pointer */ struct caml__roots_block * local_roots; /* Saved value of local_roots */ struct longjmp_buffer * exit_buf; /* For thread exit */ -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - value internal_spacetime_trie_root; - value internal_spacetime_finaliser_trie_root; - value* spacetime_trie_node_ptr; - value* spacetime_finaliser_trie_root; -#endif #else value * stack_low; /* The execution stack for this thread */ value * stack_high; @@ -101,7 +93,7 @@ struct caml_thread_struct { int backtrace_pos; /* Saved Caml_state->backtrace_pos */ backtrace_slot * backtrace_buffer; /* Saved Caml_state->backtrace_buffer */ value backtrace_last_exn; /* Saved Caml_state->backtrace_last_exn (root) */ - struct caml_memprof_th_ctx memprof_ctx; + struct caml_memprof_th_ctx *memprof_ctx; }; typedef struct caml_thread_struct * caml_thread_t; @@ -148,9 +140,7 @@ static void (*prev_scan_roots_hook) (scanning_action); static void caml_thread_scan_roots(scanning_action action) { - caml_thread_t th; - - th = curr_thread; + caml_thread_t th = curr_thread; do { (*action)(th->descr, &th->descr); (*action)(th->backtrace_last_exn, &th->backtrace_last_exn); @@ -170,6 +160,17 @@ static void caml_thread_scan_roots(scanning_action action) if (prev_scan_roots_hook != NULL) (*prev_scan_roots_hook)(action); } +/* Hook for iterating over Memprof's entries arrays */ + +static void memprof_ctx_iter(th_ctx_action f, void* data) +{ + caml_thread_t th = curr_thread; + do { + f(th->memprof_ctx, data); + th = th->next; + } while (th != curr_thread); +} + /* Saving and restoring runtime state in curr_thread */ Caml_inline void caml_thread_save_runtime_state(void) @@ -180,12 +181,6 @@ Caml_inline void caml_thread_save_runtime_state(void) curr_thread->last_retaddr = Caml_state->last_return_address; curr_thread->gc_regs = Caml_state->gc_regs; curr_thread->exception_pointer = Caml_state->exception_pointer; -#ifdef WITH_SPACETIME - curr_thread->spacetime_trie_node_ptr - = caml_spacetime_trie_node_ptr; - curr_thread->spacetime_finaliser_trie_root - = caml_spacetime_finaliser_trie_root; -#endif #else curr_thread->stack_low = Caml_state->stack_low; curr_thread->stack_high = Caml_state->stack_high; @@ -198,7 +193,7 @@ Caml_inline void caml_thread_save_runtime_state(void) curr_thread->backtrace_pos = Caml_state->backtrace_pos; curr_thread->backtrace_buffer = Caml_state->backtrace_buffer; curr_thread->backtrace_last_exn = Caml_state->backtrace_last_exn; - caml_memprof_save_th_ctx(&curr_thread->memprof_ctx); + caml_memprof_leave_thread(); } Caml_inline void caml_thread_restore_runtime_state(void) @@ -209,12 +204,6 @@ Caml_inline void caml_thread_restore_runtime_state(void) Caml_state->last_return_address = curr_thread->last_retaddr; Caml_state->gc_regs = curr_thread->gc_regs; Caml_state->exception_pointer = curr_thread->exception_pointer; -#ifdef WITH_SPACETIME - caml_spacetime_trie_node_ptr - = curr_thread->spacetime_trie_node_ptr; - caml_spacetime_finaliser_trie_root - = curr_thread->spacetime_finaliser_trie_root; -#endif #else Caml_state->stack_low = curr_thread->stack_low; Caml_state->stack_high = curr_thread->stack_high; @@ -227,7 +216,7 @@ Caml_inline void caml_thread_restore_runtime_state(void) Caml_state->backtrace_pos = curr_thread->backtrace_pos; Caml_state->backtrace_buffer = curr_thread->backtrace_buffer; Caml_state->backtrace_last_exn = curr_thread->backtrace_last_exn; - caml_memprof_restore_th_ctx(&curr_thread->memprof_ctx); + caml_memprof_enter_thread(curr_thread->memprof_ctx); } /* Hooks for caml_enter_blocking_section and caml_leave_blocking_section */ @@ -253,15 +242,6 @@ static void caml_thread_leave_blocking_section(void) caml_thread_restore_runtime_state(); } -static int caml_thread_try_leave_blocking_section(void) -{ - /* Disable immediate processing of signals (PR#3659). - try_leave_blocking_section always fails, forcing the signal to be - recorded and processed at the next leave_blocking_section or - polling. */ - return 0; -} - /* Hooks for I/O locking */ static void caml_io_mutex_free(struct channel *chan) @@ -282,7 +262,7 @@ static void caml_io_mutex_lock(struct channel *chan) chan->mutex = mutex; } /* PR#4351: first try to acquire mutex without releasing the master lock */ - if (st_mutex_trylock(mutex) == PREVIOUSLY_UNLOCKED) { + if (st_mutex_trylock(mutex) == MUTEX_PREVIOUSLY_UNLOCKED) { st_tls_set(last_channel_locked_key, (void *) chan); return; } @@ -353,20 +333,6 @@ static caml_thread_t caml_thread_new_info(void) th->exception_pointer = NULL; th->local_roots = NULL; th->exit_buf = NULL; -#ifdef WITH_SPACETIME - /* CR-someday mshinwell: The commented-out changes here are for multicore, - where we think we should have one trie per domain. */ - th->internal_spacetime_trie_root = Val_unit; - th->spacetime_trie_node_ptr = - &caml_spacetime_trie_root; /* &th->internal_spacetime_trie_root; */ - th->internal_spacetime_finaliser_trie_root = Val_unit; - th->spacetime_finaliser_trie_root - = caml_spacetime_finaliser_trie_root; - /* &th->internal_spacetime_finaliser_trie_root; */ - caml_spacetime_register_thread( - th->spacetime_trie_node_ptr, - th->spacetime_finaliser_trie_root); -#endif #else /* Allocate the stacks */ th->stack_low = (value *) caml_stat_alloc(Thread_stack_size); @@ -380,7 +346,7 @@ static caml_thread_t caml_thread_new_info(void) th->backtrace_pos = 0; th->backtrace_buffer = NULL; th->backtrace_last_exn = Val_unit; - caml_memprof_init_th_ctx(&th->memprof_ctx); + th->memprof_ctx = caml_memprof_new_th_ctx(); return th; } @@ -418,33 +384,22 @@ static void caml_thread_remove_info(caml_thread_t th) caml_stat_free(th->stack_low); #endif if (th->backtrace_buffer != NULL) caml_stat_free(th->backtrace_buffer); -#ifndef WITH_SPACETIME caml_stat_free(th); - /* CR-soon mshinwell: consider what to do about the Spacetime trace. Could - perhaps have a hook to save a snapshot on thread termination. - For the moment we can't even free [th], since it contains the trie - roots. */ -#endif } /* Reinitialize the thread machinery after a fork() (PR#4577) */ static void caml_thread_reinitialize(void) { - caml_thread_t thr, next; struct channel * chan; /* Remove all other threads (now nonexistent) from the doubly-linked list of threads */ - thr = curr_thread->next; - while (thr != curr_thread) { - next = thr->next; - caml_stat_free(thr); - thr = next; + while (curr_thread->next != curr_thread) { + caml_memprof_delete_th_ctx(curr_thread->next->memprof_ctx); + caml_thread_remove_info(curr_thread->next); } - curr_thread->next = curr_thread; - curr_thread->prev = curr_thread; - all_threads = curr_thread; + /* Reinitialize the master lock machinery, just in case the fork happened while other threads were doing caml_leave_blocking_section */ @@ -487,16 +442,17 @@ CAMLprim value caml_thread_initialize(value unit) /* ML */ #ifdef NATIVE_CODE curr_thread->exit_buf = &caml_termination_jmpbuf; #endif + curr_thread->memprof_ctx = &caml_memprof_main_ctx; /* The stack-related fields will be filled in at the next caml_enter_blocking_section */ /* Associate the thread descriptor with the thread */ st_tls_set(thread_descriptor_key, (void *) curr_thread); + st_thread_set_id(Ident(curr_thread->descr)); /* Set up the hooks */ prev_scan_roots_hook = caml_scan_roots_hook; caml_scan_roots_hook = caml_thread_scan_roots; caml_enter_blocking_section_hook = caml_thread_enter_blocking_section; caml_leave_blocking_section_hook = caml_thread_leave_blocking_section; - caml_try_leave_blocking_section_hook = caml_thread_try_leave_blocking_section; #ifdef NATIVE_CODE caml_termination_hook = st_thread_exit; #endif @@ -506,6 +462,7 @@ CAMLprim value caml_thread_initialize(value unit) /* ML */ caml_channel_mutex_unlock_exn = caml_io_mutex_unlock_exn; prev_stack_usage_hook = caml_stack_usage_hook; caml_stack_usage_hook = caml_thread_stack_usage; + caml_memprof_th_ctx_iter_hook = memprof_ctx_iter; /* Set up fork() to reinitialize the thread machinery in the child (PR#4577) */ st_atfork(caml_thread_reinitialize); @@ -537,11 +494,14 @@ static void caml_thread_stop(void) below uses accurate information. */ caml_thread_save_runtime_state(); /* Tell memprof that this thread is terminating. */ - caml_memprof_stop_th_ctx(&curr_thread->memprof_ctx); + caml_memprof_delete_th_ctx(curr_thread->memprof_ctx); /* Signal that the thread has terminated */ caml_threadstatus_terminate(Terminated(curr_thread->descr)); /* Remove th from the doubly-linked list of threads and free its info block */ caml_thread_remove_info(curr_thread); + /* If no other OCaml thread remains, ask the tick thread to stop + so that it does not prevent the whole process from exiting (#9971) */ + if (all_threads == NULL) caml_thread_cleanup(Val_unit); /* OS-specific cleanups */ st_thread_cleanup(); /* Release the runtime system */ @@ -563,6 +523,7 @@ static ST_THREAD_FUNCTION caml_thread_start(void * arg) /* Associate the thread descriptor with the thread */ st_tls_set(thread_descriptor_key, (void *) th); + st_thread_set_id(Ident(th->descr)); /* Acquire the global mutex */ caml_leave_blocking_section(); caml_setup_stack_overflow_detection(); @@ -651,6 +612,7 @@ CAMLexport int caml_c_thread_register(void) /* Now we can re-enter the run-time system and heap-allocate the descriptor */ caml_leave_blocking_section(); th->descr = caml_thread_new_descriptor(Val_unit); /* no closure */ + st_thread_set_id(Ident(th->descr)); /* Create the tick thread if not already done. */ if (! caml_tick_thread_running) { err = st_thread_create(&caml_tick_thread_id, caml_thread_tick, NULL); @@ -675,6 +637,9 @@ CAMLexport int caml_c_thread_unregister(void) st_tls_set(thread_descriptor_key, NULL); /* Remove thread info block from list of threads, and free it */ caml_thread_remove_info(th); + /* If no other OCaml thread remains, ask the tick thread to stop + so that it does not prevent the whole process from exiting (#9971) */ + if (all_threads == NULL) caml_thread_cleanup(Val_unit); /* Release the runtime */ st_masterlock_release(&caml_master_lock); return 1; @@ -819,7 +784,7 @@ CAMLprim value caml_mutex_lock(value wrapper) /* ML */ st_retcode retcode; /* PR#4351: first try to acquire mutex without releasing the master lock */ - if (st_mutex_trylock(mut) == PREVIOUSLY_UNLOCKED) return Val_unit; + if (st_mutex_trylock(mut) == MUTEX_PREVIOUSLY_UNLOCKED) return Val_unit; /* If unsuccessful, block on mutex */ Begin_root(wrapper) /* prevent the deallocation of mutex */ caml_enter_blocking_section(); @@ -845,7 +810,7 @@ CAMLprim value caml_mutex_try_lock(value wrapper) /* ML */ st_mutex mut = Mutex_val(wrapper); st_retcode retcode; retcode = st_mutex_trylock(mut); - if (retcode == ALREADY_LOCKED) return Val_false; + if (retcode == MUTEX_ALREADY_LOCKED) return Val_false; st_check_error(retcode, "Mutex.try_lock"); return Val_true; } diff --git a/otherlibs/systhreads/st_win32.h b/otherlibs/systhreads/st_win32.h index ab4e2b59..3f598a71 100644 --- a/otherlibs/systhreads/st_win32.h +++ b/otherlibs/systhreads/st_win32.h @@ -38,18 +38,37 @@ typedef DWORD st_retcode; #define SIGPREEMPTION SIGTERM +/* Unique thread identifiers and atomic operations over them */ +#ifdef ARCH_SIXTYFOUR +typedef LONG64 st_tid; +#define Tid_Atomic_Exchange InterlockedExchange64 +#define Tid_Atomic_Compare_Exchange InterlockedCompareExchange64 +#else +typedef LONG st_tid; +#define Tid_Atomic_Exchange InterlockedExchange +#define Tid_Atomic_Compare_Exchange InterlockedCompareExchange +#endif + /* Thread-local storage associating a Win32 event to every thread. */ static DWORD st_thread_sem_key; +/* Thread-local storage for the OCaml thread ID. */ +static DWORD st_thread_id_key; + /* OS-specific initialization */ static DWORD st_initialize(void) { + DWORD result = 0; st_thread_sem_key = TlsAlloc(); if (st_thread_sem_key == TLS_OUT_OF_INDEXES) return GetLastError(); - else - return 0; + st_thread_id_key = TlsAlloc(); + if (st_thread_id_key == TLS_OUT_OF_INDEXES) { + result = GetLastError(); + TlsFree(st_thread_sem_key); + } + return result; } /* Thread creation. Created in detached mode if [res] is NULL. */ @@ -120,6 +139,22 @@ Caml_inline void st_tls_set(st_tlskey k, void * v) TlsSetValue(k, v); } +/* OS-specific handling of the OCaml thread ID (must be called with the runtime + lock). */ +Caml_inline void st_thread_set_id(intnat id) +{ + CAMLassert(id != 0); + st_tls_set(st_thread_id_key, (void *)id); +} + +/* Return the identifier for the current thread. The 0 value is reserved. */ +Caml_inline intnat st_current_thread_id(void) +{ + intnat id = (intnat)st_tls_get(st_thread_id_key); + CAMLassert(id != 0); + return id; +} + /* The master lock. */ typedef CRITICAL_SECTION st_masterlock; @@ -160,53 +195,100 @@ Caml_inline void st_thread_yield(st_masterlock * m) /* Mutexes */ -typedef CRITICAL_SECTION * st_mutex; +struct st_mutex_ { + CRITICAL_SECTION crit; + volatile st_tid owner; /* 0 if unlocked */ + /* The "owner" field is not always protected by "crit"; it is also + accessed without holding "crit", using the Interlocked API for + atomic accesses */ +}; + +typedef struct st_mutex_ * st_mutex; static DWORD st_mutex_create(st_mutex * res) { - st_mutex m = caml_stat_alloc_noexc(sizeof(CRITICAL_SECTION)); + st_mutex m = caml_stat_alloc_noexc(sizeof(struct st_mutex_)); if (m == NULL) return ERROR_NOT_ENOUGH_MEMORY; - InitializeCriticalSection(m); + InitializeCriticalSection(&m->crit); + m->owner = 0; *res = m; return 0; } static DWORD st_mutex_destroy(st_mutex m) { - DeleteCriticalSection(m); + DeleteCriticalSection(&m->crit); caml_stat_free(m); return 0; } +/* Error codes with the 29th bit set are reserved for the application */ + +#define MUTEX_DEADLOCK (1<<29 | 1) +#define MUTEX_PREVIOUSLY_UNLOCKED 0 +#define MUTEX_ALREADY_LOCKED (1 << 29) +#define MUTEX_NOT_OWNED (1<<29 | 2) + Caml_inline DWORD st_mutex_lock(st_mutex m) { + st_tid self, prev; TRACE1("st_mutex_lock", m); - EnterCriticalSection(m); + self = st_current_thread_id(); + /* Critical sections are recursive locks, so this will succeed + if we already own the lock */ + EnterCriticalSection(&m->crit); + /* Record that we are the owner of the lock */ + prev = Tid_Atomic_Exchange(&m->owner, self); + if (prev != 0) { + /* The mutex was already locked by ourselves. + Cancel the EnterCriticalSection above and return an error. */ + TRACE1("st_mutex_lock (deadlock)", m); + LeaveCriticalSection(&m->crit); + return MUTEX_DEADLOCK; + } TRACE1("st_mutex_lock (done)", m); return 0; } -/* Error codes with the 29th bit set are reserved for the application */ - -#define PREVIOUSLY_UNLOCKED 0 -#define ALREADY_LOCKED (1<<29) - Caml_inline DWORD st_mutex_trylock(st_mutex m) { + st_tid self, prev; TRACE1("st_mutex_trylock", m); - if (TryEnterCriticalSection(m)) { - TRACE1("st_mutex_trylock (success)", m); - return PREVIOUSLY_UNLOCKED; - } else { + self = st_current_thread_id(); + if (! TryEnterCriticalSection(&m->crit)) { TRACE1("st_mutex_trylock (failure)", m); - return ALREADY_LOCKED; + return MUTEX_ALREADY_LOCKED; } + /* Record that we are the owner of the lock */ + prev = Tid_Atomic_Exchange(&m->owner, self); + if (prev != 0) { + /* The mutex was already locked by ourselves. + Cancel the EnterCriticalSection above and return "already locked". */ + TRACE1("st_mutex_trylock (already locked by self)", m); + LeaveCriticalSection(&m->crit); + return MUTEX_ALREADY_LOCKED; + } + TRACE1("st_mutex_trylock (done)", m); + return MUTEX_PREVIOUSLY_UNLOCKED; } Caml_inline DWORD st_mutex_unlock(st_mutex m) { + st_tid self, prev; + /* If the calling thread holds the lock, m->owner is stable and equal + to st_current_thread_id(). + Otherwise, the value of m->owner can be 0 (if the mutex is unlocked) + or some other thread ID (if the mutex is held by another thread), + but is never equal to st_current_thread_id(). */ + self = st_current_thread_id(); + prev = Tid_Atomic_Compare_Exchange(&m->owner, 0, self); + if (prev != self) { + /* The value of m->owner is unchanged */ + TRACE1("st_mutex_unlock (error)", m); + return MUTEX_NOT_OWNED; + } TRACE1("st_mutex_unlock", m); - LeaveCriticalSection(m); + LeaveCriticalSection(&m->crit); return 0; } @@ -289,6 +371,8 @@ static DWORD st_condvar_wait(st_condvar c, st_mutex m) { HANDLE ev; struct st_wait_list wait; + DWORD rc; + st_tid self, prev; TRACE1("st_condvar_wait", c); /* Recover (or create) the event associated with the calling thread */ @@ -301,14 +385,23 @@ static DWORD st_condvar_wait(st_condvar c, st_mutex m) if (ev == NULL) return GetLastError(); TlsSetValue(st_thread_sem_key, (void *) ev); } - EnterCriticalSection(&c->lock); + /* Get ready to release the mutex */ + self = st_current_thread_id(); + prev = Tid_Atomic_Compare_Exchange(&m->owner, 0, self); + if (prev != self) { + /* The value of m->owner is unchanged */ + TRACE1("st_condvar_wait: error: mutex not held", m); + return MUTEX_NOT_OWNED; + } /* Insert the current thread in the waiting list (atomically) */ + EnterCriticalSection(&c->lock); wait.event = ev; wait.next = c->waiters; c->waiters = &wait; LeaveCriticalSection(&c->lock); - /* Release the mutex m */ - LeaveCriticalSection(m); + /* Finish releasing the mutex m (like st_mutex_unlock does, minus + the error checking, which we've already done above). */ + LeaveCriticalSection(&m->crit); /* Wait for our event to be signaled. There is no risk of lost wakeup, since we inserted ourselves on the waiting list of c before releasing m */ @@ -316,9 +409,10 @@ static DWORD st_condvar_wait(st_condvar c, st_mutex m) if (WaitForSingleObject(ev, INFINITE) == WAIT_FAILED) return GetLastError(); /* Reacquire the mutex m */ - TRACE1("st_condvar_wait: restarted, acquiring mutex", m); - EnterCriticalSection(m); - TRACE1("st_condvar_wait: acquired mutex", m); + TRACE1("st_condvar_wait: restarted, acquiring mutex", c); + rc = st_mutex_lock(m); + if (rc != 0) return rc; + TRACE1("st_condvar_wait: acquired mutex", c); return 0; } @@ -373,16 +467,28 @@ static void st_check_error(DWORD retcode, char * msg) if (retcode == 0) return; if (retcode == ERROR_NOT_ENOUGH_MEMORY) caml_raise_out_of_memory(); - ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - retcode, - 0, - err, - sizeof(err)/sizeof(wchar_t), - NULL); - if (! ret) { - ret = - swprintf(err, sizeof(err)/sizeof(wchar_t), L"error code %lx", retcode); + switch (retcode) { + case MUTEX_DEADLOCK: + ret = swprintf(err, sizeof(err)/sizeof(wchar_t), + L"Mutex is already locked by calling thread"); + break; + case MUTEX_NOT_OWNED: + ret = swprintf(err, sizeof(err)/sizeof(wchar_t), + L"Mutex is not locked by calling thread"); + break; + default: + ret = FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + retcode, + 0, + err, + sizeof(err)/sizeof(wchar_t), + NULL); + if (! ret) { + ret = + swprintf(err, sizeof(err)/sizeof(wchar_t), L"error code %lx", retcode); + } } msglen = strlen(msg); errlen = win_wide_char_to_multi_byte(err, ret, NULL, 0); diff --git a/otherlibs/systhreads/thread.ml b/otherlibs/systhreads/thread.ml index bf47d75b..8a756920 100644 --- a/otherlibs/systhreads/thread.ml +++ b/otherlibs/systhreads/thread.ml @@ -27,20 +27,27 @@ external yield : unit -> unit = "caml_thread_yield" external self : unit -> t = "caml_thread_self" [@@noalloc] external id : t -> int = "caml_thread_id" [@@noalloc] external join : t -> unit = "caml_thread_join" -external exit : unit -> unit = "caml_thread_exit" +external exit_stub : unit -> unit = "caml_thread_exit" (* For new, make sure the function passed to thread_new never raises an exception. *) +let[@inline never] check_memprof_cb () = ref () + let create fn arg = thread_new (fun () -> try - fn arg; () + fn arg; + ignore (Sys.opaque_identity (check_memprof_cb ())) with exn -> flush stdout; flush stderr; thread_uncaught_exception exn) +let exit () = + ignore (Sys.opaque_identity (check_memprof_cb ())); + exit_stub () + (* Thread.kill is currently not implemented due to problems with cleanup handlers on several platforms *) diff --git a/otherlibs/systhreads/thread.mli b/otherlibs/systhreads/thread.mli index 2373e58d..2ae325ff 100644 --- a/otherlibs/systhreads/thread.mli +++ b/otherlibs/systhreads/thread.mli @@ -34,7 +34,7 @@ val create : ('a -> 'b) -> 'a -> t directly accessible to the parent thread. *) val self : unit -> t -(** Return the thread currently executing. *) +(** Return the handle for the thread currently executing. *) val id : t -> int (** Return the identifier of the given thread. A thread identifier @@ -45,7 +45,11 @@ val exit : unit -> unit (** Terminate prematurely the currently executing thread. *) val kill : t -> unit -(** Terminate prematurely the thread whose handle is given. *) + [@@ocaml.deprecated "Not implemented, do not use"] +(** This function was supposed to terminate prematurely the thread + whose handle is given. It is not currently implemented due to + problems with cleanup handlers on many POSIX 1003.1c implementations. + It always raises the [Invalid_argument] exception. *) (** {1 Suspending threads} *) @@ -58,49 +62,59 @@ val join : t -> unit (** [join th] suspends the execution of the calling thread until the thread [th] has terminated. *) +val yield : unit -> unit +(** Re-schedule the calling thread without suspending it. + This function can be used to give scheduling hints, + telling the scheduler that now is a good time to + switch to other threads. *) + +(** {1 Waiting for file descriptors or processes} *) + +(** The functions below are leftovers from an earlier, VM-based threading + system. The {!Unix} module provides equivalent functionality, in + a more general and more standard-conformant manner. It is recommended + to use {!Unix} functions directly. *) + val wait_read : Unix.file_descr -> unit -(** See {!Thread.wait_write}.*) + [@@ocaml.deprecated "This function no longer does anything"] +(** This function does nothing in the current implementation of the threading + library and can be removed from all user programs. *) val wait_write : Unix.file_descr -> unit -(** This function does nothing in this implementation. *) + [@@ocaml.deprecated "This function no longer does anything"] +(** This function does nothing in the current implementation of the threading + library and can be removed from all user programs. *) val wait_timed_read : Unix.file_descr -> float -> bool (** See {!Thread.wait_timed_write}.*) val wait_timed_write : Unix.file_descr -> float -> bool (** Suspend the execution of the calling thread until at least - one character or EOF is available for reading ([wait_read]) or - one character can be written without blocking ([wait_write]) + one character or EOF is available for reading ([wait_timed_read]) or + one character can be written without blocking ([wait_timed_write]) on the given Unix file descriptor. Wait for at most the amount of time given as second argument (in seconds). Return [true] if the file descriptor is ready for input/output and [false] if the timeout expired. - - These functions return immediately [true] in the Win32 - implementation. *) + The same functionality can be achieved with {!Unix.select}. +*) val select : Unix.file_descr list -> Unix.file_descr list -> Unix.file_descr list -> float -> Unix.file_descr list * Unix.file_descr list * Unix.file_descr list -(** Suspend the execution of the calling thread until input/output +(** Same function as {!Unix.select}. + Suspend the execution of the calling thread until input/output becomes possible on the given Unix file descriptors. The arguments and results have the same meaning as for - [Unix.select]. - This function is not implemented yet under Win32. *) + {!Unix.select}. *) val wait_pid : int -> int * Unix.process_status -(** [wait_pid p] suspends the execution of the calling thread +(** Same function as {!Unix.waitpid}. + [wait_pid p] suspends the execution of the calling thread until the process specified by the process identifier [p] terminates. Returns the pid of the child caught and - its termination status, as per [Unix.wait]. - This function is not implemented under MacOS. *) - -val yield : unit -> unit -(** Re-schedule the calling thread without suspending it. - This function can be used to give scheduling hints, - telling the scheduler that now is a good time to - switch to other threads. *) + its termination status, as per {!Unix.wait}. *) (** {1 Management of signals} *) diff --git a/otherlibs/systhreads/threadUnix.mli b/otherlibs/systhreads/threadUnix.mli index 1fe1bcc8..5d904e72 100644 --- a/otherlibs/systhreads/threadUnix.mli +++ b/otherlibs/systhreads/threadUnix.mli @@ -21,6 +21,8 @@ (block the calling thread, if required, but do not block all threads in the process). *) +[@@@ocaml.deprecated "Use the Unix module instead of ThreadUnix"] + (** {1 Process handling} *) val execv : string -> string array -> unit diff --git a/otherlibs/unix/.depend b/otherlibs/unix/.depend index 5c9eb799..70c377d2 100644 --- a/otherlibs/unix/.depend +++ b/otherlibs/unix/.depend @@ -1,647 +1,3 @@ -accept.o: accept.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -access.o: access.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -addrofstr.o: addrofstr.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/fail.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -alarm.o: alarm.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -bind.o: bind.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -channels.o: channels.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/io.h \ - ../../runtime/caml/signals.h unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -chdir.o: chdir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -chmod.o: chmod.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -chown.o: chown.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -chroot.o: chroot.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -close.o: close.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/signals.h \ - unixsupport.h -closedir.o: closedir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -connect.o: connect.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/signals.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -cst2constr.o: cst2constr.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/fail.h \ - cst2constr.h -cstringv.o: cstringv.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h -dup.o: dup.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -dup2.o: dup2.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -envir.o: envir.c ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h -errmsg.o: errmsg.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h -execv.o: execv.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h -execve.o: execve.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h -execvp.o: execvp.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -exit.o: exit.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -fchmod.o: fchmod.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/signals.h unixsupport.h -fchown.o: fchown.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/signals.h unixsupport.h -fcntl.o: fcntl.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h unixsupport.h -fork.o: fork.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/debugger.h \ - ../../runtime/caml/eventlog.h unixsupport.h -fsync.o: fsync.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/signals.h \ - unixsupport.h -ftruncate.o: ftruncate.c ../../runtime/caml/fail.h \ - ../../runtime/caml/misc.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/domain_state.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/io.h ../../runtime/caml/signals.h unixsupport.h -getaddrinfo.o: getaddrinfo.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/misc.h \ - ../../runtime/caml/signals.h unixsupport.h cst2constr.h socketaddr.h -getcwd.o: getcwd.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h unixsupport.h -getegid.o: getegid.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -geteuid.o: geteuid.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -getgid.o: getgid.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -getgr.o: getgr.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/fail.h \ - ../../runtime/caml/alloc.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h unixsupport.h -getgroups.o: getgroups.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h -gethost.o: gethost.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -gethostname.o: gethostname.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h -getlogin.o: getlogin.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - unixsupport.h -getnameinfo.o: getnameinfo.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -getpeername.o: getpeername.c ../../runtime/caml/fail.h \ - ../../runtime/caml/misc.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/domain_state.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/mlvalues.h \ - unixsupport.h socketaddr.h ../../runtime/caml/misc.h -getpid.o: getpid.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -getppid.o: getppid.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -getproto.o: getproto.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h unixsupport.h -getpw.o: getpw.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h \ - ../../runtime/caml/fail.h unixsupport.h -getserv.o: getserv.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h unixsupport.h -getsockname.o: getsockname.c ../../runtime/caml/fail.h \ - ../../runtime/caml/misc.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/domain_state.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/mlvalues.h \ - unixsupport.h socketaddr.h ../../runtime/caml/misc.h -gettimeofday.o: gettimeofday.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h -getuid.o: getuid.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -gmtime.o: gmtime.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h unixsupport.h -initgroups.o: initgroups.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h -isatty.o: isatty.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -itimer.o: itimer.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h unixsupport.h -kill.o: kill.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/fail.h \ - unixsupport.h ../../runtime/caml/signals.h -link.o: link.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -listen.o: listen.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h unixsupport.h -lockf.o: lockf.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/signals.h unixsupport.h -lseek.o: lseek.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/io.h ../../runtime/caml/signals.h unixsupport.h -mkdir.o: mkdir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -mkfifo.o: mkfifo.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -mmap.o: mmap.c ../../runtime/caml/bigarray.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/fail.h ../../runtime/caml/io.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/signals.h \ - ../../runtime/caml/sys.h unixsupport.h -mmap_ba.o: mmap_ba.c ../../runtime/caml/alloc.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/bigarray.h ../../runtime/caml/custom.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h ../../runtime/caml/misc.h -nice.o: nice.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -open.o: open.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h \ - ../../runtime/caml/misc.h ../../runtime/caml/signals.h unixsupport.h -opendir.o: opendir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/alloc.h \ - ../../runtime/caml/signals.h unixsupport.h -pipe.o: pipe.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - unixsupport.h -putenv.o: putenv.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h -read.o: read.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -readdir.o: readdir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/fail.h \ - ../../runtime/caml/alloc.h ../../runtime/caml/signals.h unixsupport.h -readlink.o: readlink.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/signals.h unixsupport.h -rename.o: rename.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -rewinddir.o: rewinddir.c ../../runtime/caml/fail.h \ - ../../runtime/caml/misc.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/domain_state.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/mlvalues.h \ - unixsupport.h -rmdir.o: rmdir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -select.o: select.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -sendrecv.o: sendrecv.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -setgid.o: setgid.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -setgroups.o: setgroups.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h unixsupport.h -setsid.o: setsid.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h unixsupport.h -setuid.o: setuid.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -shutdown.o: shutdown.c ../../runtime/caml/fail.h \ - ../../runtime/caml/misc.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/domain_state.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/mlvalues.h \ - unixsupport.h -signals.o: signals.c ../../runtime/caml/alloc.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/signals.h unixsupport.h -sleep.o: sleep.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/signals.h \ - unixsupport.h -socket.o: socket.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h unixsupport.h -socketaddr.o: socketaddr.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -socketpair.o: socketpair.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h -sockopt.o: sockopt.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -stat.o: stat.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/alloc.h ../../runtime/caml/signals.h \ - ../../runtime/caml/io.h unixsupport.h cst2constr.h nanosecond_stat.h -strofaddr.o: strofaddr.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -symlink.o: symlink.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -termios.o: termios.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h -time.o: time.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - unixsupport.h -times.o: times.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h unixsupport.h -truncate.o: truncate.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/fail.h ../../runtime/caml/signals.h \ - ../../runtime/caml/io.h unixsupport.h -umask.o: umask.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -unixsupport.o: unixsupport.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/callback.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/fail.h unixsupport.h \ - cst2constr.h -unlink.o: unlink.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -utimes.o: utimes.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -wait.o: wait.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h unixsupport.h -write.o: write.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h unix.cmo : \ unix.cmi unix.cmx : \ diff --git a/otherlibs/unix/Makefile b/otherlibs/unix/Makefile index 2eaa5097..02272abc 100644 --- a/otherlibs/unix/Makefile +++ b/otherlibs/unix/Makefile @@ -19,6 +19,9 @@ LIBNAME=unix EXTRACAMLFLAGS=-nolabels +unixLabels.cmi: \ + EXTRACAMLFLAGS += -pp "$(AWK) -f $(ROOTDIR)/stdlib/expand_module_aliases.awk" + # dllunix.so particularly requires libm for modf symbols LDOPTS=$(NATIVECCLIBS) @@ -36,7 +39,7 @@ COBJS=accept.o access.o addrofstr.o alarm.o bind.o channels.o chdir.o \ readdir.o readlink.o rename.o rewinddir.o rmdir.o select.o sendrecv.o \ setgid.o setgroups.o setsid.o setuid.o shutdown.o signals.o \ sleep.o socket.o socketaddr.o \ - socketpair.o sockopt.o stat.o strofaddr.o symlink.o termios.o \ + socketpair.o sockopt.o spawn.o stat.o strofaddr.o symlink.o termios.o \ time.o times.o truncate.o umask.o unixsupport.o unlink.o \ utimes.o wait.o write.o @@ -48,11 +51,6 @@ include ../Makefile.otherlibs.common .PHONY: depend depend: -ifeq "$(TOOLCHAIN)" "msvc" - $(error Dependencies cannot be regenerated using the MSVC ports) -else - $(CC) -MM $(OC_CPPFLAGS) *.c > .depend - $(CAMLRUN) $(ROOTDIR)/boot/ocamlc -depend -slash *.mli *.ml >> .depend -endif + $(CAMLRUN) $(ROOTDIR)/boot/ocamlc -depend -slash *.mli *.ml > .depend include .depend diff --git a/otherlibs/unix/channels.c b/otherlibs/unix/channels.c index ecf0cc2f..753bf9f5 100644 --- a/otherlibs/unix/channels.c +++ b/otherlibs/unix/channels.c @@ -64,10 +64,6 @@ static int unix_check_stream_semantics(int fd) } } -/* From runtime/io.c. To be declared in ? */ -extern value caml_ml_open_descriptor_in(value fd); -extern value caml_ml_open_descriptor_out(value fd); - CAMLprim value unix_inchannel_of_filedescr(value fd) { int err; diff --git a/otherlibs/unix/execvp.c b/otherlibs/unix/execvp.c index 90ea1d01..68bb1637 100644 --- a/otherlibs/unix/execvp.c +++ b/otherlibs/unix/execvp.c @@ -14,6 +14,7 @@ /**************************************************************************/ #define _GNU_SOURCE /* helps to find execvpe() */ +#include #include #include #define CAML_INTERNALS @@ -36,32 +37,126 @@ CAMLprim value unix_execvp(value path, value args) /* from smart compilers */ } -#ifdef HAS_EXECVPE +#ifndef HAS_EXECVPE +int unix_execvpe_emulation(const char * name, + char * const argv[], + char * const envp[]); +#endif CAMLprim value unix_execvpe(value path, value args, value env) { char_os ** argv; char_os ** envp; char_os * wpath; + int err; caml_unix_check_path(path, "execvpe"); argv = cstringvect(args, "execvpe"); envp = cstringvect(env, "execvpe"); wpath = caml_stat_strdup_to_os(String_val(path)); +#ifdef HAS_EXECVPE (void) execvpe_os((const char_os *)wpath, EXECV_CAST argv, EXECV_CAST envp); + err = errno; +#else + err = unix_execvpe_emulation(wpath, argv, envp); +#endif caml_stat_free(wpath); cstringvect_free(argv); cstringvect_free(envp); - uerror("execvpe", path); + unix_error(err, "execvpe", path); return Val_unit; /* never reached, but suppress warnings */ /* from smart compilers */ } -#else +#ifndef HAS_EXECVPE -CAMLprim value unix_execvpe(value path, value args, value env) +static int unix_execve_script(const char * path, + char * const argv[], + char * const envp[]) +{ + size_t argc, i; + char ** new_argv; + + /* Try executing directly. Will not return if it succeeds. */ + execve(path, argv, envp); + if (errno != ENOEXEC) return errno; + /* Try executing as a shell script. */ + for (argc = 0; argv[argc] != NULL; argc++) /*skip*/; + /* The new argument vector is + {"/bin/sh", path, argv[1], ..., argv[argc-1], NULL} */ + new_argv = calloc(argc + 3, sizeof (char *)); + if (new_argv == NULL) return ENOMEM; + new_argv[0] = "/bin/sh"; + new_argv[1] = (char *) path; + for (i = 1; i < argc; i++) new_argv[i + 1] = argv[i]; + new_argv[argc + 1] = NULL; + /* Execute the shell with the new argument vector. + Will not return if it succeeds. */ + execve(new_argv[0], new_argv, envp); + /* Shell execution failed. */ + free(new_argv); + return errno; +} + +int unix_execvpe_emulation(const char * name, + char * const argv[], + char * const envp[]) { - unix_error(ENOSYS, "execvpe", path); - return Val_unit; + char * searchpath, * p, * q, * fullname; + size_t namelen, dirlen; + int r, got_eacces; + + /* If name contains a '/', do not search in path */ + if (strchr(name, '/') != NULL) return unix_execve_script(name, argv, envp); + /* Determine search path */ + searchpath = getenv("PATH"); + if (searchpath == NULL) searchpath = "/bin:/usr/bin"; + if (searchpath[0] == 0) return ENOENT; + namelen = strlen(name); + got_eacces = 0; + p = searchpath; + while (1) { + /* End of path component is next ':' or end of string */ + for (q = p; *q != 0 && *q != ':'; q++) /*skip*/; + /* Path component is between p (included) and q (excluded) */ + dirlen = q - p; + if (dirlen == 0) { + /* An empty path component means "current working directory" */ + r = unix_execve_script(name, argv, envp); + } else { + /* Construct the string "directory/name" */ + fullname = malloc(dirlen + 1 + namelen + 1); + if (fullname == NULL) return ENOMEM; + memcpy(fullname, p, dirlen); /* copy directory from path */ + fullname[dirlen] = '/'; /* add separator */ + memcpy(fullname + dirlen + 1, name, namelen + 1); + /* add name, including final 0 */ + r = unix_execve_script(fullname, argv, envp); + free(fullname); + } + switch (r) { + case EACCES: + /* Record that we got a "Permission denied" error and continue. */ + got_eacces = 1; break; + case ENOENT: case ENOTDIR: + /* The file was not found. Continue the search. */ + break; + case EISDIR: case ELOOP: + case ENODEV: case ETIMEDOUT: + /* Strange, unexpected error. Continue the search. */ + break; + default: + /* Serious error. We found an executable file but could not + execute it. Stop the search and return the error. */ + return r; + } + /* Continue with next path component, if any */ + if (*q == 0) break; + p = q + 1; /* skip ':' */ + } + /* If we found a file but had insufficient permissions, return + EACCES to our caller. Otherwise, say we did not find a file + (ENOENT). */ + return got_eacces ? EACCES : ENOENT; } #endif diff --git a/otherlibs/unix/gettimeofday.c b/otherlibs/unix/gettimeofday.c index 609a9a82..3e4879cb 100644 --- a/otherlibs/unix/gettimeofday.c +++ b/otherlibs/unix/gettimeofday.c @@ -17,22 +17,17 @@ #include #include #include "unixsupport.h" - -#ifdef HAS_GETTIMEOFDAY - #include #include -CAMLprim value unix_gettimeofday(value unit) +double unix_gettimeofday_unboxed(value unit) { struct timeval tp; - if (gettimeofday(&tp, NULL) == -1) uerror("gettimeofday", Nothing); - return caml_copy_double((double) tp.tv_sec + (double) tp.tv_usec / 1e6); + gettimeofday(&tp, NULL); + return ((double) tp.tv_sec + (double) tp.tv_usec / 1e6); } -#else - CAMLprim value unix_gettimeofday(value unit) -{ caml_invalid_argument("gettimeofday not implemented"); } - -#endif +{ + return caml_copy_double(unix_gettimeofday_unboxed(unit)); +} diff --git a/otherlibs/unix/kill.c b/otherlibs/unix/kill.c index d229d3e9..7154e1d1 100644 --- a/otherlibs/unix/kill.c +++ b/otherlibs/unix/kill.c @@ -27,5 +27,6 @@ CAMLprim value unix_kill(value pid, value signal) sig = caml_convert_signal_number(Int_val(signal)); if (kill(Int_val(pid), sig) == -1) uerror("kill", Nothing); + caml_process_pending_actions(); return Val_unit; } diff --git a/otherlibs/unix/mkdir.c b/otherlibs/unix/mkdir.c index 0c177781..ff1c6ed4 100644 --- a/otherlibs/unix/mkdir.c +++ b/otherlibs/unix/mkdir.c @@ -13,9 +13,15 @@ /* */ /**************************************************************************/ +#ifndef _WIN32 #include #include +#endif + +#define CAML_INTERNALS #include +#include +#include #include #include #include "unixsupport.h" @@ -23,12 +29,12 @@ CAMLprim value unix_mkdir(value path, value perm) { CAMLparam2(path, perm); - char * p; + char_os * p; int ret; caml_unix_check_path(path, "mkdir"); - p = caml_stat_strdup(String_val(path)); + p = caml_stat_strdup_to_os(String_val(path)); caml_enter_blocking_section(); - ret = mkdir(p, Int_val(perm)); + ret = mkdir_os(p, Int_val(perm)); caml_leave_blocking_section(); caml_stat_free(p); if (ret == -1) uerror("mkdir", path); diff --git a/otherlibs/unix/mmap.c b/otherlibs/unix/mmap.c index 15465ddc..7afab62f 100644 --- a/otherlibs/unix/mmap.c +++ b/otherlibs/unix/mmap.c @@ -39,8 +39,7 @@ #endif /* Defined in [mmap_ba.c] */ -CAMLextern value -caml_unix_mapped_alloc(int flags, int num_dims, void * data, intnat * dim); +extern value caml_unix_mapped_alloc(int, int, void *, intnat *); #if defined(HAS_MMAP) diff --git a/otherlibs/unix/mmap_ba.c b/otherlibs/unix/mmap_ba.c index bdb5c60f..3e34fc72 100644 --- a/otherlibs/unix/mmap_ba.c +++ b/otherlibs/unix/mmap_ba.c @@ -24,7 +24,7 @@ /* Allocation of bigarrays for memory-mapped files. This is the OS-independent part of [mmap.c]. */ -CAMLextern void caml_ba_unmap_file(void * addr, uintnat len); +extern void caml_ba_unmap_file(void *, uintnat); static void caml_ba_mapped_finalize(value v) { diff --git a/otherlibs/unix/setsid.c b/otherlibs/unix/setsid.c index b4449e67..cf600b86 100644 --- a/otherlibs/unix/setsid.c +++ b/otherlibs/unix/setsid.c @@ -23,7 +23,9 @@ CAMLprim value unix_setsid(value unit) { #ifdef HAS_SETSID - return Val_int(setsid()); + pid_t pid = setsid(); + if (pid == (pid_t)(-1)) uerror("setsid", Nothing); + return Val_long(pid); #else caml_invalid_argument("setsid not implemented"); return Val_unit; diff --git a/otherlibs/unix/signals.c b/otherlibs/unix/signals.c index ff59a726..6e54032d 100644 --- a/otherlibs/unix/signals.c +++ b/otherlibs/unix/signals.c @@ -71,6 +71,8 @@ CAMLprim value unix_sigprocmask(value vaction, value vset) caml_enter_blocking_section(); retcode = caml_sigmask_hook(how, &set, &oldset); caml_leave_blocking_section(); + /* Run any handlers for just-unmasked pending signals */ + caml_process_pending_actions(); if (retcode != 0) unix_error(retcode, "sigprocmask", Nothing); return encode_sigset(&oldset); } diff --git a/otherlibs/unix/socketaddr.h b/otherlibs/unix/socketaddr.h index 4c80d25d..0f52f3aa 100644 --- a/otherlibs/unix/socketaddr.h +++ b/otherlibs/unix/socketaddr.h @@ -17,15 +17,19 @@ #define CAML_SOCKETADDR_H #include "caml/misc.h" +#ifndef _WIN32 #include #include #include #include #include +#endif union sock_addr_union { struct sockaddr s_gen; +#ifndef _WIN32 struct sockaddr_un s_unix; +#endif struct sockaddr_in s_inet; #ifdef HAS_IPV6 struct sockaddr_in6 s_inet6; @@ -45,13 +49,13 @@ extern "C" { extern void get_sockaddr (value mladdr, union sock_addr_union * addr /*out*/, socklen_param_type * addr_len /*out*/); -CAMLexport value alloc_sockaddr (union sock_addr_union * addr /*in*/, +extern value alloc_sockaddr (union sock_addr_union * addr /*in*/, socklen_param_type addr_len, int close_on_error); -CAMLexport value alloc_inet_addr (struct in_addr * inaddr); +extern value alloc_inet_addr (struct in_addr * inaddr); #define GET_INET_ADDR(v) (*((struct in_addr *) (v))) #ifdef HAS_IPV6 -CAMLexport value alloc_inet6_addr (struct in6_addr * inaddr); +extern value alloc_inet6_addr (struct in6_addr * inaddr); #define GET_INET6_ADDR(v) (*((struct in6_addr *) (v))) #endif diff --git a/otherlibs/unix/sockopt.c b/otherlibs/unix/sockopt.c index d2961d09..383ecc8c 100644 --- a/otherlibs/unix/sockopt.c +++ b/otherlibs/unix/sockopt.c @@ -38,6 +38,9 @@ #ifndef SO_REUSEADDR #define SO_REUSEADDR (-1) #endif +#ifndef SO_REUSEPORT +#define SO_REUSEPORT (-1) +#endif #ifndef SO_KEEPALIVE #define SO_KEEPALIVE (-1) #endif @@ -114,7 +117,8 @@ static struct socket_option sockopt_bool[] = { { SOL_SOCKET, SO_OOBINLINE }, { SOL_SOCKET, SO_ACCEPTCONN }, { IPPROTO_TCP, TCP_NODELAY }, - { IPPROTO_IPV6, IPV6_V6ONLY} + { IPPROTO_IPV6, IPV6_V6ONLY}, + { SOL_SOCKET, SO_REUSEPORT } }; static struct socket_option sockopt_int[] = { diff --git a/otherlibs/unix/spawn.c b/otherlibs/unix/spawn.c new file mode 100644 index 00000000..159bba6a --- /dev/null +++ b/otherlibs/unix/spawn.c @@ -0,0 +1,165 @@ +/**************************************************************************/ +/* */ +/* OCaml */ +/* */ +/* Xavier Leroy, projet Cambium, Collège de France and INRIA Paris */ +/* */ +/* Copyright 2020 Institut National de Recherche en Informatique et */ +/* en Automatique. */ +/* */ +/* All rights reserved. This file is distributed under the terms of */ +/* the GNU Lesser General Public License version 2.1, with the */ +/* special exception on linking described in the file LICENSE. */ +/* */ +/**************************************************************************/ + +#define _GNU_SOURCE /* helps to find execvpe() */ +#include +#include +#include +#include +#include "unixsupport.h" + +#ifdef HAS_POSIX_SPAWN + +#include + +extern char ** environ; + +/* Implementation based on posix_spawn() */ + +CAMLprim value unix_spawn(value executable, /* string */ + value args, /* string array */ + value optenv, /* string array option */ + value usepath, /* bool */ + value redirect) /* int array (size 3) */ +{ + char ** argv; + char ** envp; + const char * path; + pid_t pid; + int src, dst, r, i; + posix_spawn_file_actions_t act; + + caml_unix_check_path(executable, "create_process"); + path = String_val(executable); + argv = cstringvect(args, "create_process"); + if (Is_block(optenv)) { + envp = cstringvect(Field(optenv, 0), "create_process"); + } else { + envp = environ; + } + /* Prepare the redirections for stdin, stdout, stderr */ + posix_spawn_file_actions_init(&act); + for (dst = 0; dst <= 2; dst++) { + /* File descriptor [redirect.(dst)] becomes file descriptor [dst] */ + src = Int_val(Field(redirect, dst)); + if (src != dst) { + r = posix_spawn_file_actions_adddup2(&act, src, dst); + if (r != 0) goto error; + /* Close [src] if this is its last use */ + for (i = dst + 1; i <= 2; i++) { + if (src == Int_val(Field(redirect, i))) goto dontclose; + } + r = posix_spawn_file_actions_addclose(&act, src); + if (r != 0) goto error; + dontclose: + /*skip*/; + } + } + /* Spawn the new process */ + if (Bool_val(usepath)) { + r = posix_spawnp(&pid, path, &act, NULL, argv, envp); + } else { + r = posix_spawn(&pid, path, &act, NULL, argv, envp); + } + error: + posix_spawn_file_actions_destroy(&act); + cstringvect_free(argv); + if (Is_block(optenv)) cstringvect_free(envp); + if (r != 0) unix_error(r, "create_process", executable); + return Val_long(pid); +} + +#else + +/* Fallback implementation based on fork() and exec() */ + +#ifndef HAS_EXECVPE +extern int unix_execvpe_emulation(const char * name, + char * const argv[], + char * const envp[]); +#endif + +/* Exit code used for the child process to report failure to exec */ +/* This is consistent with system() and allowed by posix_spawn() specs */ + +#define ERROR_EXIT_STATUS 127 + +CAMLprim value unix_spawn(value executable, /* string */ + value args, /* string array */ + value optenv, /* string array option */ + value usepath, /* bool */ + value redirect) /* int array (size 3) */ +{ + char ** argv; + char ** envp; + const char * path; + pid_t pid; + int src, dst, i; + + caml_unix_check_path(executable, "create_process"); + path = String_val(executable); + argv = cstringvect(args, "create_process"); + if (Is_block(optenv)) { + envp = cstringvect(Field(optenv, 0), "create_process"); + } else { + envp = NULL; + } + pid = fork(); + if (pid != 0) { + /* This is the parent process */ + cstringvect_free(argv); + if (envp != NULL) cstringvect_free(envp); + if (pid == -1) uerror("create_process", executable); + return Val_long(pid); + } + /* This is the child process */ + /* Perform the redirections for stdin, stdout, stderr */ + for (dst = 0; dst <= 2; dst++) { + /* File descriptor [redirect.(dst)] becomes file descriptor [dst] */ + src = Int_val(Field(redirect, dst)); + if (src != dst) { + if (dup2(src, dst) == -1) _exit(ERROR_EXIT_STATUS); + /* Close [src] if this is its last use */ + for (i = dst + 1; i <= 2; i++) { + if (src == Int_val(Field(redirect, i))) goto dontclose; + } + if (close(src) == -1) _exit(ERROR_EXIT_STATUS); + dontclose: + /*skip*/; + } + } + /* Transfer control to the executable */ + if (Bool_val(usepath)) { + if (envp == NULL) { + execvp(path, argv); + } else { +#ifdef HAS_EXECVPE + execvpe(path, argv, envp); +#else + unix_execvpe_emulation(path, argv, envp); +#endif + } + } else { + if (envp == NULL) { + execv(path, argv); + } else { + execve(path, argv, envp); + } + } + /* If we get here, the exec*() call failed. */ + _exit(ERROR_EXIT_STATUS); +} + +#endif diff --git a/otherlibs/unix/time.c b/otherlibs/unix/time.c index f7916c99..0c2d94ff 100644 --- a/otherlibs/unix/time.c +++ b/otherlibs/unix/time.c @@ -18,7 +18,12 @@ #include #include "unixsupport.h" +double unix_time_unboxed(value unit) +{ + return ((double) time((time_t *) NULL)); +} + CAMLprim value unix_time(value unit) { - return caml_copy_double((double) time((time_t *) NULL)); + return caml_copy_double(unix_time_unboxed(unit)); } diff --git a/otherlibs/unix/unix.ml b/otherlibs/unix/unix.ml index ae9b1fc8..8c795683 100644 --- a/otherlibs/unix/unix.ml +++ b/otherlibs/unix/unix.ml @@ -205,72 +205,13 @@ type wait_flag = external execv : string -> string array -> 'a = "unix_execv" external execve : string -> string array -> string array -> 'a = "unix_execve" external execvp : string -> string array -> 'a = "unix_execvp" -external execvpe_c : - string -> string array -> string array -> 'a = "unix_execvpe" - -let execvpe_ml name args env = - (* Try to execute the given file *) - let exec file = - try - execve file args env - with Unix_error(ENOEXEC, _, _) -> - (* Assume this is a script and try to execute through the shell *) - let argc = Array.length args in - (* Drop the original args.(0) if it is there *) - let new_args = Array.append - [| shell; file |] - (if argc = 0 then args else Array.sub args 1 (argc - 1)) in - execve new_args.(0) new_args env in - (* Try each path element in turn *) - let rec scan_dir eacces = function - | [] -> - (* No matching file was found (if [eacces = false]) or - a matching file was found but we got a "permission denied" - error while trying to execute it (if [eacces = true]). - Raise the error appropriate to each case. *) - raise (Unix_error((if eacces then EACCES else ENOENT), - "execvpe", name)) - | dir :: rem -> - let dir = (* an empty path element means the current directory *) - if dir = "" then Filename.current_dir_name else dir in - try - exec (Filename.concat dir name) - with Unix_error(err, _, _) as exn -> - match err with - (* The following errors are treated as nonfatal, meaning that - we will ignore them and continue searching in the path. - Among those errors, EACCES is recorded specially so as - to produce the correct exception in the end. - To determine which errors are nonfatal, we looked at the - execvpe() sources in Glibc and in OpenBSD. *) - | EACCES -> - scan_dir true rem - | EISDIR|ELOOP|ENAMETOOLONG|ENODEV|ENOENT|ENOTDIR|ETIMEDOUT -> - scan_dir eacces rem - (* Other errors, e.g. E2BIG, are fatal and abort the search. *) - | _ -> - raise exn in - if String.contains name '/' then - (* If the command name contains "/" characters, don't search in path *) - exec name - else - (* Split path into elements and search in these elements *) - (try unsafe_getenv "PATH" with Not_found -> "/bin:/usr/bin") - |> String.split_on_char ':' - |> scan_dir false - (* [unsafe_getenv] and not [getenv] to be consistent with [execvp], - which looks up the PATH environment variable whether SUID or not. *) - -let execvpe name args env = - try - execvpe_c name args env - with Unix_error(ENOSYS, _, _) -> - execvpe_ml name args env +external execvpe : string -> string array -> string array -> 'a = "unix_execvpe" external fork : unit -> int = "unix_fork" external wait : unit -> int * process_status = "unix_wait" external waitpid : wait_flag list -> int -> int * process_status = "unix_waitpid" +external _exit : int -> 'a = "unix_exit" external getpid : unit -> int = "unix_getpid" external getppid : unit -> int = "unix_getppid" external nice : int -> int = "unix_nice" @@ -497,8 +438,10 @@ type tm = tm_yday : int; tm_isdst : bool } -external time : unit -> float = "unix_time" -external gettimeofday : unit -> float = "unix_gettimeofday" +external time : unit -> (float [@unboxed]) = + "unix_time" "unix_time_unboxed" [@@noalloc] +external gettimeofday : unit -> (float [@unboxed]) = + "unix_gettimeofday" "unix_gettimeofday_unboxed" [@@noalloc] external gmtime : float -> tm = "unix_gmtime" external localtime : float -> tm = "unix_localtime" external mktime : tm -> float * tm = "unix_mktime" @@ -661,6 +604,7 @@ type socket_bool_option = | SO_ACCEPTCONN | TCP_NODELAY | IPV6_ONLY + | SO_REUSEPORT type socket_int_option = SO_SNDBUF @@ -938,67 +882,48 @@ let rec waitpid_non_intr pid = try waitpid [] pid with Unix_error (EINTR, _, _) -> waitpid_non_intr pid -external sys_exit : int -> 'a = "caml_sys_exit" +external spawn : string -> string array -> string array option -> + bool -> int array -> int + = "unix_spawn" let system cmd = - match fork() with - 0 -> begin try - execv shell [| shell; "-c"; cmd |] - with _ -> - sys_exit 127 - end - | id -> snd(waitpid_non_intr id) - -(* Duplicate [fd] if needed to make sure it isn't one of the - standard descriptors (stdin, stdout, stderr). - Note that this function always leaves the standard descriptors open, - the caller must take care of closing them if needed. - The "cloexec" mode doesn't matter, because - the descriptor returned by [dup] will be closed before the [exec], - and because no other thread is running concurrently - (we are in the child process of a fork). - *) -let rec file_descr_not_standard fd = - if fd >= 3 then fd else file_descr_not_standard (dup fd) - -let safe_close fd = - try close fd with Unix_error(_,_,_) -> () - -let perform_redirections new_stdin new_stdout new_stderr = - let new_stdin = file_descr_not_standard new_stdin in - let new_stdout = file_descr_not_standard new_stdout in - let new_stderr = file_descr_not_standard new_stderr in - (* The three dup2 close the original stdin, stdout, stderr, - which are the descriptors possibly left open - by file_descr_not_standard *) - dup2 ~cloexec:false new_stdin stdin; - dup2 ~cloexec:false new_stdout stdout; - dup2 ~cloexec:false new_stderr stderr; - safe_close new_stdin; - safe_close new_stdout; - safe_close new_stderr + let pid = spawn shell [| shell; "-c"; cmd |] None false [| 0; 1; 2 |] in + snd(waitpid_non_intr pid) + +let create_process_gen usepath cmd args optenv + new_stdin new_stdout new_stderr = + let toclose = ref [] in + let close_after () = + List.iter + (fun fd -> try close fd with Unix_error(_,_,_) -> ()) + !toclose in + (* Duplicate [fd] if needed to make sure it isn't one of the + standard descriptors (stdin, stdout, stderr). + The temporary file descriptors created here will be closed + after the spawn, both in the parent (call to [close_after] below) + and in the child (they are close-on-exec). *) + let rec file_descr_not_standard fd = + if fd >= 3 then fd else begin + let fd' = dup ~cloexec:true fd in + toclose := fd' :: !toclose; + file_descr_not_standard fd' + end in + (* As an optimization, if a standard descriptor is not redirected, + i.e. "redirected to itself", don't duplicate it: the [unix_spawn] + C stub will perform no redirection either. *) + let redirections = [| + (if new_stdin = 0 then 0 else file_descr_not_standard new_stdin); + (if new_stdout = 1 then 1 else file_descr_not_standard new_stdout); + (if new_stderr = 2 then 2 else file_descr_not_standard new_stderr) + |] in + Fun.protect ~finally:close_after + (fun () -> spawn cmd args optenv usepath redirections) let create_process cmd args new_stdin new_stdout new_stderr = - match fork() with - 0 -> - begin try - perform_redirections new_stdin new_stdout new_stderr; - execvp cmd args - with _ -> - sys_exit 127 - end - | id -> id + create_process_gen true cmd args None new_stdin new_stdout new_stderr let create_process_env cmd args env new_stdin new_stdout new_stderr = - match fork() with - 0 -> - begin try - perform_redirections new_stdin new_stdout new_stderr; - execvpe cmd args env - with _ -> - sys_exit 127 - end - | id -> id + create_process_gen true cmd args (Some env) new_stdin new_stdout new_stderr type popen_process = Process of in_channel * out_channel @@ -1009,16 +934,9 @@ type popen_process = let popen_processes = (Hashtbl.create 7 : (popen_process, int) Hashtbl.t) let open_proc prog args envopt proc input output error = - match fork() with - 0 -> perform_redirections input output error; - begin try - match envopt with - | Some env -> execve prog args env - | None -> execv prog args - with _ -> - sys_exit 127 - end - | id -> Hashtbl.add popen_processes proc id + let pid = + create_process_gen false prog args envopt input output error in + Hashtbl.add popen_processes proc pid let open_process_args_in prog args = let (in_read, in_write) = pipe ~cloexec:true () in @@ -1187,8 +1105,8 @@ let establish_server server_fun sockaddr = (* The "double fork" trick, the process which calls server_fun will not leave a zombie process *) match fork() with - 0 -> if fork() <> 0 then sys_exit 0; - (* The son exits, the grandson works *) + 0 -> if fork() <> 0 then _exit 0; + (* The child exits, the grandchild works *) close sock; let inchan = in_channel_of_descr s in let outchan = out_channel_of_descr s in @@ -1197,5 +1115,5 @@ let establish_server server_fun sockaddr = have done it already, and we are about to exit anyway (PR#3794) *) exit 0 - | id -> close s; ignore(waitpid_non_intr id) (* Reclaim the son *) + | id -> close s; ignore(waitpid_non_intr id) (* Reclaim the child *) done diff --git a/otherlibs/unix/unix.mli b/otherlibs/unix/unix.mli index ab23cf27..e0656971 100644 --- a/otherlibs/unix/unix.mli +++ b/otherlibs/unix/unix.mli @@ -13,12 +13,30 @@ (* *) (**************************************************************************) +(* NOTE: + If this file is unixLabels.mli, run tools/sync_stdlib_docs after editing it + to generate unix.mli. + + If this file is unix.mli, do not edit it directly -- edit unixLabels.mli + instead. +*) + +(* NOTE: + When a new function is added which is not implemented on Windows (or + partially implemented), or the Windows-status of an existing function is + changed, remember to update the summary table in + manual/manual/library/libunix.etex +*) + (** Interface to the Unix system. - Note: all the functions of this module (except {!error_message} and - {!handle_unix_error}) are liable to raise the {!Unix_error} - exception whenever the underlying system call signals an error. *) + To use the labeled version of this module, add [module Unix][ = ][UnixLabels] + in your implementation. + Note: all the functions of this module (except {!error_message} and + {!handle_unix_error}) are liable to raise the {!Unix_error} + exception whenever the underlying system call signals an error. +*) (** {1 Error report} *) @@ -105,7 +123,10 @@ exception Unix_error of error * string * string (** Raised by the system calls below when an error is encountered. The first component is the error code; the second component is the function name; the third component is the string parameter - to the function, if it has one, or the empty string otherwise. *) + to the function, if it has one, or the empty string otherwise. + + {!UnixLabels.Unix_error} and {!Unix.Unix_error} are the same, and + catching one will catch the other. *) val error_message : error -> string (** Return a string describing the given error code. *) @@ -131,7 +152,7 @@ val unsafe_environment : unit -> string array privileges. See the documentation for {!unsafe_getenv} for more details. - @since 4.06.0 *) + @since 4.06.0 (4.12.0 in UnixLabels) *) val getenv : string -> string (** Return the value associated to a variable in the process @@ -139,7 +160,7 @@ val getenv : string -> string @raise Not_found if the variable is unbound or the process has special privileges. - (This function is identical to {!Sys.getenv}. *) + This function is identical to {!Sys.getenv}. *) val unsafe_getenv : string -> string (** Return the value associated to a variable in the process @@ -156,7 +177,7 @@ val unsafe_getenv : string -> string @since 4.06.0 *) val putenv : string -> string -> unit -(** [Unix.putenv name value] sets the value associated to a +(** [putenv name value] sets the value associated to a variable in the process environment. [name] is the name of the environment variable, and [value] its new associated value. *) @@ -182,27 +203,27 @@ type process_status = type wait_flag = WNOHANG (** Do not block if no child has - died yet, but immediately return with a pid equal to 0.*) + died yet, but immediately return with a pid equal to 0. *) | WUNTRACED (** Report also the children that receive stop signals. *) -(** Flags for {!Unix.waitpid}. *) +(** Flags for {!waitpid}. *) val execv : string -> string array -> 'a (** [execv prog args] execute the program in file [prog], with the arguments [args], and the current process environment. These [execv*] functions never return: on success, the current program is replaced by the new one. - @raise Unix.Unix_error on failure. *) + @raise Unix_error on failure *) val execve : string -> string array -> string array -> 'a -(** Same as {!Unix.execv}, except that the third argument provides the +(** Same as {!execv}, except that the third argument provides the environment to the program executed. *) val execvp : string -> string array -> 'a -(** Same as {!Unix.execv}, except that +(** Same as {!execv}, except that the program is searched in the path. *) val execvpe : string -> string array -> string array -> 'a -(** Same as {!Unix.execve}, except that +(** Same as {!execve}, except that the program is searched in the path. *) val fork : unit -> int @@ -215,10 +236,10 @@ val wait : unit -> int * process_status (** Wait until one of the children processes die, and return its pid and termination status. - On Windows: Not implemented, use {!waitpid}. *) + On Windows: not implemented, use {!waitpid}. *) val waitpid : wait_flag list -> int -> int * process_status -(** Same as {!Unix.wait}, but waits for the child process whose pid is given. +(** Same as {!wait}, but waits for the child process whose pid is given. A pid of [-1] means wait for any child. A pid of [0] means wait for any child in the same process group as the current process. @@ -227,8 +248,7 @@ val waitpid : wait_flag list -> int -> int * process_status immediately without waiting, and whether it should report stopped children. - On Windows, this function can only wait for a given PID, not any - child process. *) + On Windows: can only wait for a given PID, not any child process. *) val system : string -> process_status (** Execute the given command, wait until it terminates, and return @@ -241,12 +261,33 @@ val system : string -> process_status The result [WEXITED 127] indicates that the shell couldn't be executed. *) +val _exit : int -> 'a +(** Terminate the calling process immediately, returning the given + status code to the operating system: usually 0 to indicate no + errors, and a small positive integer to indicate failure. + Unlike {!Stdlib.exit}, {!Unix._exit} performs no finalization + whatsoever: functions registered with {!Stdlib.at_exit} are not called, + input/output channels are not flushed, and the C run-time system + is not finalized either. + + The typical use of {!Unix._exit} is after a {!Unix.fork} operation, + when the child process runs into a fatal error and must exit. In + this case, it is preferable to not perform any finalization action + in the child process, as these actions could interfere with similar + actions performed by the parent process. For example, output + channels should not be flushed by the child process, as the parent + process may flush them again later, resulting in duplicate + output. + + @since 4.12.0 *) + val getpid : unit -> int (** Return the pid of the process. *) val getppid : unit -> int (** Return the pid of the parent process. - On Windows: not implemented (because it is meaningless). *) + + On Windows: not implemented (because it is meaningless). *) val nice : int -> int (** Change the process priority. The integer argument is added to the @@ -255,7 +296,6 @@ val nice : int -> int On Windows: not implemented. *) - (** {1 Basic file input/output} *) @@ -282,20 +322,20 @@ type open_flag = | O_EXCL (** Fail if existing *) | O_NOCTTY (** Don't make this dev a controlling tty *) | O_DSYNC (** Writes complete as `Synchronised I/O data - integrity completion' *) + integrity completion' *) | O_SYNC (** Writes complete as `Synchronised I/O file - integrity completion' *) - | O_RSYNC (** Reads complete as writes (depending on - O_SYNC/O_DSYNC) *) + integrity completion' *) + | O_RSYNC (** Reads complete as writes (depending + on O_SYNC/O_DSYNC) *) | O_SHARE_DELETE (** Windows only: allow the file to be deleted - while still open *) + while still open *) | O_CLOEXEC (** Set the close-on-exec flag on the descriptor returned by {!openfile}. See {!set_close_on_exec} for more information. *) | O_KEEPEXEC (** Clear the close-on-exec flag. This is currently the default. *) -(** The flags to {!Unix.openfile}. *) +(** The flags to {!openfile}. *) type file_perm = int @@ -311,32 +351,35 @@ val close : file_descr -> unit (** Close a file descriptor. *) val fsync : file_descr -> unit -(** Flush file buffers to disk. *) +(** Flush file buffers to disk. + + @since 4.08.0 (4.12.0 in UnixLabels) *) val read : file_descr -> bytes -> int -> int -> int -(** [read fd buff ofs len] reads [len] bytes from descriptor [fd], - storing them in byte sequence [buff], starting at position [ofs] in - [buff]. Return the number of bytes actually read. *) +(** [read fd buf pos len] reads [len] bytes from descriptor [fd], + storing them in byte sequence [buf], starting at position [pos] in + [buf]. Return the number of bytes actually read. *) val write : file_descr -> bytes -> int -> int -> int -(** [write fd buff ofs len] writes [len] bytes to descriptor [fd], - taking them from byte sequence [buff], starting at position [ofs] +(** [write fd buf pos len] writes [len] bytes to descriptor [fd], + taking them from byte sequence [buf], starting at position [pos] in [buff]. Return the number of bytes actually written. [write] repeats the writing operation until all bytes have been written or an error occurs. *) val single_write : file_descr -> bytes -> int -> int -> int -(** Same as [write], but attempts to write only once. +(** Same as {!write}, but attempts to write only once. Thus, if an error occurs, [single_write] guarantees that no data has been written. *) val write_substring : file_descr -> string -> int -> int -> int -(** Same as [write], but take the data from a string instead of a byte +(** Same as {!write}, but take the data from a string instead of a byte sequence. @since 4.02.0 *) -val single_write_substring : file_descr -> string -> int -> int -> int -(** Same as [single_write], but take the data from a string instead of +val single_write_substring : + file_descr -> string -> int -> int -> int +(** Same as {!single_write}, but take the data from a string instead of a byte sequence. @since 4.02.0 *) @@ -350,7 +393,8 @@ val in_channel_of_descr : file_descr -> in_channel [set_binary_mode_in ic false] if text mode is desired. Text mode is supported only if the descriptor refers to a file or pipe, but is not supported if it refers to a socket. - On Windows, [set_binary_mode_in] always fails on channels created + + On Windows: [set_binary_mode_in] always fails on channels created with this function. Beware that channels are buffered so more characters may have been @@ -367,7 +411,8 @@ val out_channel_of_descr : file_descr -> out_channel [set_binary_mode_out oc false] if text mode is desired. Text mode is supported only if the descriptor refers to a file or pipe, but is not supported if it refers to a socket. - On Windows, [set_binary_mode_out] always fails on channels created + + On Windows: [set_binary_mode_out] always fails on channels created with this function. Beware that channels are buffered so you may have to [flush] them @@ -393,7 +438,7 @@ type seek_command = SEEK_SET (** indicates positions relative to the beginning of the file *) | SEEK_CUR (** indicates positions relative to the current position *) | SEEK_END (** indicates positions relative to the end of the file *) -(** Positioning modes for {!Unix.lseek}. *) +(** Positioning modes for {!lseek}. *) val lseek : file_descr -> int -> seek_command -> int @@ -434,13 +479,13 @@ type stats = st_mtime : float; (** Last modification time *) st_ctime : float; (** Last status change time *) } -(** The information returned by the {!Unix.stat} calls. *) +(** The information returned by the {!stat} calls. *) val stat : string -> stats (** Return the information for the named file. *) val lstat : string -> stats -(** Same as {!Unix.stat}, but in case the file is a symbolic link, +(** Same as {!stat}, but in case the file is a symbolic link, return the information for the link itself. *) val fstat : file_descr -> stats @@ -456,13 +501,13 @@ val isatty : file_descr -> bool module LargeFile : sig val lseek : file_descr -> int64 -> seek_command -> int64 - (** See {!Unix.lseek}. *) + (** See [lseek]. *) val truncate : string -> int64 -> unit - (** See {!Unix.truncate}. *) + (** See [truncate]. *) val ftruncate : file_descr -> int64 -> unit - (** See {!Unix.ftruncate}. *) + (** See [ftruncate]. *) type stats = { st_dev : int; (** Device number *) @@ -484,10 +529,11 @@ module LargeFile : end (** File operations on large files. This sub-module provides 64-bit variants of the functions - {!Unix.lseek} (for positioning a file descriptor), - {!Unix.truncate} and {!Unix.ftruncate} (for changing the size of a file), - and {!Unix.stat}, {!Unix.lstat} and {!Unix.fstat} (for obtaining - information on files). These alternate functions represent + {!lseek} (for positioning a file descriptor), + {!truncate} and {!ftruncate} + (for changing the size of a file), + and {!stat}, {!lstat} and {!fstat} + (for obtaining information on files). These alternate functions represent positions and sizes by 64-bit integers (type [int64]) instead of regular integers (type [int]), thus allowing operating on files whose sizes are greater than [max_int]. *) @@ -495,7 +541,9 @@ module LargeFile : (** {1 Mapping files into memory} *) val map_file : - file_descr -> ?pos:int64 -> ('a, 'b) Stdlib.Bigarray.kind -> + file_descr -> + ?pos (* thwart tools/sync_stdlib_docs *):int64 -> + ('a, 'b) Stdlib.Bigarray.kind -> 'c Stdlib.Bigarray.layout -> bool -> int array -> ('a, 'b, 'c) Stdlib.Bigarray.Genarray.t (** Memory mapping of a file as a Bigarray. @@ -504,7 +552,7 @@ val map_file : and dimensions as specified in [dims]. The data contained in this Bigarray are the contents of the file referred to by the file descriptor [fd] (as opened previously with - [Unix.openfile], for example). The optional [pos] parameter + {!openfile}, for example). The optional [pos] parameter is the byte offset in the file of the data being mapped; it defaults to 0 (map from the beginning of the file). @@ -559,19 +607,20 @@ val unlink : string -> unit *) val rename : string -> string -> unit -(** [rename old new] changes the name of a file from [old] to [new], - moving it between directories if needed. If [new] already - exists, its contents will be replaced with those of [old]. +(** [rename src dst] changes the name of a file from [src] to [dst], + moving it between directories if needed. If [dst] already + exists, its contents will be replaced with those of [src]. Depending on the operating system, the metadata (permissions, - owner, etc) of [new] can either be preserved or be replaced by - those of [old]. *) + owner, etc) of [dst] can either be preserved or be replaced by + those of [src]. *) -val link : ?follow:bool -> string -> string -> unit -(** [link ?follow source dest] creates a hard link named [dest] to the file - named [source]. +val link : ?follow (* thwart tools/sync_stdlib_docs *) :bool -> + string -> string -> unit +(** [link ?follow src dst] creates a hard link named [dst] to the file + named [src]. - @param follow indicates whether a [source] symlink is followed or a - hardlink to [source] itself will be created. On {e Unix} systems this is + @param follow indicates whether a [src] symlink is followed or a + hardlink to [src] itself will be created. On {e Unix} systems this is done using the [linkat(2)] function. If [?follow] is not provided, then the [link(2)] function is used whose behaviour is OS-dependent, but more widely available. @@ -589,7 +638,7 @@ type access_permission = | W_OK (** Write permission *) | X_OK (** Execution permission *) | F_OK (** File exists *) -(** Flags for the {!Unix.access} call. *) +(** Flags for the {!access} call. *) val chmod : string -> file_perm -> unit @@ -597,40 +646,48 @@ val chmod : string -> file_perm -> unit val fchmod : file_descr -> file_perm -> unit (** Change the permissions of an opened file. + On Windows: not implemented. *) val chown : string -> int -> int -> unit (** Change the owner uid and owner gid of the named file. - On Windows: not implemented (make no sense on a DOS file system). *) + + On Windows: not implemented. *) val fchown : file_descr -> int -> int -> unit (** Change the owner uid and owner gid of an opened file. - On Windows: not implemented (make no sense on a DOS file system). *) + + On Windows: not implemented. *) val umask : int -> int (** Set the process's file mode creation mask, and return the previous mask. + On Windows: not implemented. *) val access : string -> access_permission list -> unit (** Check that the process has the given permissions over the named file. - @raise Unix_error otherwise. - On Windows, execute permission [X_OK], cannot be tested, it just - tests for read permission instead. *) + On Windows: execute permission [X_OK] cannot be tested, just + tests for read permission instead. + + @raise Unix_error otherwise. + *) (** {1 Operations on file descriptors} *) -val dup : ?cloexec:bool -> file_descr -> file_descr +val dup : ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + file_descr -> file_descr (** Return a new file descriptor referencing the same file as the given descriptor. See {!set_close_on_exec} for documentation on the [cloexec] optional argument. *) -val dup2 : ?cloexec:bool -> file_descr -> file_descr -> unit -(** [dup2 fd1 fd2] duplicates [fd1] to [fd2], closing [fd2] if already +val dup2 : ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + file_descr -> file_descr -> unit +(** [dup2 src dst] duplicates [src] to [dst], closing [dst] if already opened. See {!set_close_on_exec} for documentation on the [cloexec] optional argument. *) @@ -645,7 +702,7 @@ val set_nonblock : file_descr -> unit val clear_nonblock : file_descr -> unit (** Clear the ``non-blocking'' flag on the given descriptor. - See {!Unix.set_nonblock}.*) + See {!set_nonblock}.*) val set_close_on_exec : file_descr -> unit (** Set the ``close-on-exec'' flag on the given descriptor. @@ -696,7 +753,7 @@ val set_close_on_exec : file_descr -> unit val clear_close_on_exec : file_descr -> unit (** Clear the ``close-on-exec'' flag on the given descriptor. - See {!Unix.set_close_on_exec}.*) + See {!set_close_on_exec}.*) (** {1 Directories} *) @@ -716,6 +773,7 @@ val getcwd : unit -> string val chroot : string -> unit (** Change the process root directory. + On Windows: not implemented. *) type dir_handle @@ -739,7 +797,8 @@ val closedir : dir_handle -> unit (** {1 Pipes and redirections} *) -val pipe : ?cloexec:bool -> unit -> file_descr * file_descr +val pipe : ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + unit -> file_descr * file_descr (** Create a pipe. The first component of the result is opened for reading, that's the exit to the pipe. The second component is opened for writing, that's the entrance to the pipe. @@ -748,6 +807,7 @@ val pipe : ?cloexec:bool -> unit -> file_descr * file_descr val mkfifo : string -> file_perm -> unit (** Create a named pipe with the given permissions (see {!umask}). + On Windows: not implemented. *) @@ -755,25 +815,26 @@ val mkfifo : string -> file_perm -> unit val create_process : - string -> string array -> file_descr -> file_descr -> file_descr -> int -(** [create_process prog args new_stdin new_stdout new_stderr] + string -> string array -> file_descr -> file_descr -> + file_descr -> int +(** [create_process prog args stdin stdout stderr] forks a new process that executes the program in file [prog], with arguments [args]. The pid of the new process is returned immediately; the new process executes concurrently with the current process. The standard input and outputs of the new process are connected - to the descriptors [new_stdin], [new_stdout] and [new_stderr]. - Passing e.g. [stdout] for [new_stdout] prevents the redirection + to the descriptors [stdin], [stdout] and [stderr]. + Passing e.g. [Stdlib.stdout] for [stdout] prevents the redirection and causes the new process to have the same standard output as the current process. The executable file [prog] is searched in the path. The new process has the same environment as the current process. *) val create_process_env : - string -> string array -> string array -> file_descr -> file_descr -> - file_descr -> int -(** [create_process_env prog args env new_stdin new_stdout new_stderr] - works as {!Unix.create_process}, except that the extra argument + string -> string array -> string array -> file_descr -> + file_descr -> file_descr -> int +(** [create_process_env prog args env stdin stdout stderr] + works as {!create_process}, except that the extra argument [env] specifies the environment passed to the program. *) @@ -783,42 +844,42 @@ val open_process_in : string -> in_channel The standard output of the command is redirected to a pipe, which can be read via the returned input channel. The command is interpreted by the shell [/bin/sh] - (or [cmd.exe] on Windows), cf. {!Unix.system}. + (or [cmd.exe] on Windows), cf. {!system}. The {!Filename.quote_command} function can be used to quote the command and its arguments as appropriate for the shell being used. If the command does not need to be run through the shell, - {!Unix.open_process_args_in} can be used as a more robust and - more efficient alternative to {!Unix.open_process_in}. *) + {!open_process_args_in} can be used as a more robust and + more efficient alternative to {!open_process_in}. *) val open_process_out : string -> out_channel -(** Same as {!Unix.open_process_in}, but redirect the standard input of +(** Same as {!open_process_in}, but redirect the standard input of the command to a pipe. Data written to the returned output channel is sent to the standard input of the command. Warning: writes on output channels are buffered, hence be careful to call {!Stdlib.flush} at the right times to ensure correct synchronization. If the command does not need to be run through the shell, - {!Unix.open_process_args_out} can be used instead of - {!Unix.open_process_out}. *) + {!open_process_args_out} can be used instead of + {!open_process_out}. *) val open_process : string -> in_channel * out_channel -(** Same as {!Unix.open_process_out}, but redirects both the standard input +(** Same as {!open_process_out}, but redirects both the standard input and standard output of the command to pipes connected to the two returned channels. The input channel is connected to the output of the command, and the output channel to the input of the command. If the command does not need to be run through the shell, - {!Unix.open_process_args} can be used instead of - {!Unix.open_process}. *) + {!open_process_args} can be used instead of + {!open_process}. *) val open_process_full : string -> string array -> in_channel * out_channel * in_channel -(** Similar to {!Unix.open_process}, but the second argument specifies +(** Similar to {!open_process}, but the second argument specifies the environment passed to the command. The result is a triple of channels connected respectively to the standard output, standard input, and standard error of the command. If the command does not need to be run through the shell, - {!Unix.open_process_args_full} can be used instead of - {!Unix.open_process_full}. *) + {!open_process_args_full} can be used instead of + {!open_process_full}. *) val open_process_args_in : string -> string array -> in_channel (** High-level pipe and process management. The first argument specifies the @@ -830,7 +891,7 @@ val open_process_args_in : string -> string array -> in_channel @since 4.08.0 *) val open_process_args_out : string -> string array -> out_channel -(** Same as {!Unix.open_process_args_in}, but redirect the standard input of the +(** Same as {!open_process_args_in}, but redirect the standard input of the command to a pipe. Data written to the returned output channel is sent to the standard input of the command. Warning: writes on output channels are buffered, hence be careful to call {!Stdlib.flush} at the right times to @@ -839,7 +900,7 @@ val open_process_args_out : string -> string array -> out_channel @since 4.08.0 *) val open_process_args : string -> string array -> in_channel * out_channel -(** Same as {!Unix.open_process_args_out}, but redirects both the standard input +(** Same as {!open_process_args_out}, but redirects both the standard input and standard output of the command to pipes connected to the two returned channels. The input channel is connected to the output of the command, and the output channel to the input of the command. @@ -849,7 +910,7 @@ val open_process_args : string -> string array -> in_channel * out_channel val open_process_args_full : string -> string array -> string array -> in_channel * out_channel * in_channel -(** Similar to {!Unix.open_process_args}, but the third argument specifies the +(** Similar to {!open_process_args}, but the third argument specifies the environment passed to the command. The result is a triple of channels connected respectively to the standard output, standard input, and standard error of the command. @@ -857,47 +918,47 @@ val open_process_args_full : @since 4.08.0 *) val process_in_pid : in_channel -> int -(** Return the pid of a process opened via {!Unix.open_process_in} or - {!Unix.open_process_args_in}. +(** Return the pid of a process opened via {!open_process_in} or + {!open_process_args_in}. - @since 4.08.0 *) + @since 4.08.0 (4.12.0 in UnixLabels) *) val process_out_pid : out_channel -> int -(** Return the pid of a process opened via {!Unix.open_process_out} or - {!Unix.open_process_args_out}. +(** Return the pid of a process opened via {!open_process_out} or + {!open_process_args_out}. - @since 4.08.0 *) + @since 4.08.0 (4.12.0 in UnixLabels) *) val process_pid : in_channel * out_channel -> int -(** Return the pid of a process opened via {!Unix.open_process} or - {!Unix.open_process_args}. +(** Return the pid of a process opened via {!open_process} or + {!open_process_args}. - @since 4.08.0 *) + @since 4.08.0 (4.12.0 in UnixLabels) *) val process_full_pid : in_channel * out_channel * in_channel -> int -(** Return the pid of a process opened via {!Unix.open_process_full} or - {!Unix.open_process_args_full}. +(** Return the pid of a process opened via {!open_process_full} or + {!open_process_args_full}. - @since 4.08.0 *) + @since 4.08.0 (4.12.0 in UnixLabels) *) val close_process_in : in_channel -> process_status -(** Close channels opened by {!Unix.open_process_in}, +(** Close channels opened by {!open_process_in}, wait for the associated command to terminate, and return its termination status. *) val close_process_out : out_channel -> process_status -(** Close channels opened by {!Unix.open_process_out}, +(** Close channels opened by {!open_process_out}, wait for the associated command to terminate, and return its termination status. *) val close_process : in_channel * out_channel -> process_status -(** Close channels opened by {!Unix.open_process}, +(** Close channels opened by {!open_process}, wait for the associated command to terminate, and return its termination status. *) val close_process_full : in_channel * out_channel * in_channel -> process_status -(** Close channels opened by {!Unix.open_process_full}, +(** Close channels opened by {!open_process_full}, wait for the associated command to terminate, and return its termination status. *) @@ -905,13 +966,14 @@ val close_process_full : (** {1 Symbolic links} *) -val symlink : ?to_dir:bool -> string -> string -> unit -(** [symlink ?to_dir source dest] creates the file [dest] as a symbolic link - to the file [source]. On Windows, [~to_dir] indicates if the symbolic link - points to a directory or a file; if omitted, [symlink] examines [source] - using [stat] and picks appropriately, if [source] does not exist then [false] - is assumed (for this reason, it is recommended that the [~to_dir] parameter - be specified in new code). On Unix, [~to_dir] is ignored. +val symlink : ?to_dir: (* thwart tools/sync_stdlib_docs *) bool -> + string -> string -> unit +(** [symlink ?to_dir src dst] creates the file [dst] as a symbolic link + to the file [src]. On Windows, [to_dir] indicates if the symbolic link + points to a directory or a file; if omitted, [symlink] examines [src] + using [stat] and picks appropriately, if [src] does not exist then [false] + is assumed (for this reason, it is recommended that the [to_dir] parameter + be specified in new code). On Unix, [to_dir] is ignored. Windows symbolic links are available in Windows Vista onwards. There are some important differences between Windows symlinks and their POSIX counterparts. @@ -934,8 +996,8 @@ val symlink : ?to_dir:bool -> string -> string -> unit SeCreateSymbolicLinkPrivilege via Local Security Policy (secpol.msc) or via Active Directory. - {!has_symlink} can be used to check that a process is able to create symbolic - links. *) + {!has_symlink} can be used to check that a process is able to create + symbolic links. *) val has_symlink : unit -> bool (** Returns [true] if the user is able to create symbolic links. On Windows, @@ -952,8 +1014,8 @@ val readlink : string -> string val select : - file_descr list -> file_descr list -> file_descr list -> float -> - file_descr list * file_descr list * file_descr list + file_descr list -> file_descr list -> file_descr list -> + float -> file_descr list * file_descr list * file_descr list (** Wait until some input/output operations become possible on some channels. The three list arguments are, respectively, a set of descriptors to check for reading (first argument), for writing @@ -965,7 +1027,6 @@ val select : and over which an exceptional condition is pending (third component). *) - (** {1 Locking} *) type lock_command = @@ -975,14 +1036,14 @@ type lock_command = | F_TEST (** Test a region for other process locks *) | F_RLOCK (** Lock a region for reading, and block if already locked *) | F_TRLOCK (** Lock a region for reading, or fail if already locked *) -(** Commands for {!Unix.lockf}. *) +(** Commands for {!lockf}. *) val lockf : file_descr -> lock_command -> int -> unit -(** [lockf fd cmd size] puts a lock on a region of the file opened +(** [lockf fd mode len] puts a lock on a region of the file opened as [fd]. The region starts at the current read/write position for - [fd] (as set by {!Unix.lseek}), and extends [size] bytes forward if - [size] is positive, [size] bytes backwards if [size] is negative, - or to the end of the file if [size] is zero. + [fd] (as set by {!lseek}), and extends [len] bytes forward if + [len] is positive, [len] bytes backwards if [len] is negative, + or to the end of the file if [len] is zero. A write lock prevents any other process from acquiring a read or write lock on the region. A read lock prevents any other @@ -1007,8 +1068,7 @@ val lockf : file_descr -> lock_command -> int -> unit already locked by the same process depends on the OS. On POSIX-compliant systems, the second lock operation succeeds and may "promote" the older lock from read lock to write lock. On Windows, the second lock - operation will block or fail. -*) + operation will block or fail. *) (** {1 Signals} @@ -1017,9 +1077,10 @@ val lockf : file_descr -> lock_command -> int -> unit *) val kill : int -> int -> unit -(** [kill pid sig] sends signal number [sig] to the process - with id [pid]. On Windows, only the {!Sys.sigkill} signal - is emulated. *) +(** [kill pid signal] sends signal number [signal] to the process + with id [pid]. + + On Windows: only the {!Sys.sigkill} signal is emulated. *) type sigprocmask_command = SIG_SETMASK @@ -1027,12 +1088,12 @@ type sigprocmask_command = | SIG_UNBLOCK val sigprocmask : sigprocmask_command -> int list -> int list -(** [sigprocmask cmd sigs] changes the set of blocked signals. - If [cmd] is [SIG_SETMASK], blocked signals are set to those in +(** [sigprocmask mode sigs] changes the set of blocked signals. + If [mode] is [SIG_SETMASK], blocked signals are set to those in the list [sigs]. - If [cmd] is [SIG_BLOCK], the signals in [sigs] are added to + If [mode] is [SIG_BLOCK], the signals in [sigs] are added to the set of blocked signals. - If [cmd] is [SIG_UNBLOCK], the signals in [sigs] are removed + If [mode] is [SIG_UNBLOCK], the signals in [sigs] are removed from the set of blocked signals. [sigprocmask] returns the set of previously blocked signals. @@ -1090,22 +1151,22 @@ val time : unit -> float in seconds. *) val gettimeofday : unit -> float -(** Same as {!Unix.time}, but with resolution better than 1 second. *) +(** Same as {!time}, but with resolution better than 1 second. *) val gmtime : float -> tm -(** Convert a time in seconds, as returned by {!Unix.time}, into a date and +(** Convert a time in seconds, as returned by {!time}, into a date and a time. Assumes UTC (Coordinated Universal Time), also known as GMT. To perform the inverse conversion, set the TZ environment variable to "UTC", use {!mktime}, and then restore the original value of TZ. *) val localtime : float -> tm -(** Convert a time in seconds, as returned by {!Unix.time}, into a date and +(** Convert a time in seconds, as returned by {!time}, into a date and a time. Assumes the local time zone. The function performing the inverse conversion is {!mktime}. *) val mktime : tm -> float * tm (** Convert a date and time, specified by the [tm] argument, into - a time in seconds, as returned by {!Unix.time}. The [tm_isdst], + a time in seconds, as returned by {!time}. The [tm_isdst], [tm_wday] and [tm_yday] fields of [tm] are ignored. Also return a normalized copy of the given [tm] record, with the [tm_wday], [tm_yday], and [tm_isdst] fields recomputed from the other fields, @@ -1125,11 +1186,12 @@ val sleepf : float -> unit (** Stop execution for the given number of seconds. Like [sleep], but fractions of seconds are supported. - @since 4.03.0 *) + @since 4.03.0 (4.12.0 in UnixLabels) *) val times : unit -> process_times (** Return the execution times of the process. - On Windows, it is partially implemented, will not report timings + + On Windows: partially implemented, will not report timings for child processes. *) val utimes : string -> float -> float -> unit @@ -1141,10 +1203,10 @@ val utimes : string -> float -> float -> unit type interval_timer = ITIMER_REAL (** decrements in real time, and sends the signal [SIGALRM] when - expired.*) + expired.*) | ITIMER_VIRTUAL - (** decrements in process virtual time, and sends [SIGVTALRM] - when expired. *) + (** decrements in process virtual time, and sends [SIGVTALRM] when + expired. *) | ITIMER_PROF (** (for profiling) decrements both when the process is running and when the system is running on behalf of the @@ -1178,39 +1240,46 @@ val setitimer : (** {1 User id, group id} *) - val getuid : unit -> int (** Return the user id of the user executing the process. - On Windows, always return [1]. *) + + On Windows: always returns [1]. *) val geteuid : unit -> int (** Return the effective user id under which the process runs. - On Windows, always return [1]. *) + + On Windows: always returns [1]. *) val setuid : int -> unit (** Set the real user id and effective user id for the process. + On Windows: not implemented. *) val getgid : unit -> int (** Return the group id of the user executing the process. - On Windows, always return [1]. *) + + On Windows: always returns [1]. *) val getegid : unit -> int (** Return the effective group id under which the process runs. - On Windows, always return [1]. *) + + On Windows: always returns [1]. *) val setgid : int -> unit (** Set the real group id and effective group id for the process. + On Windows: not implemented. *) val getgroups : unit -> int array (** Return the list of groups to which the user executing the process belongs. - On Windows, always return [[|1|]]. *) + + On Windows: always returns [[|1|]]. *) val setgroups : int array -> unit (** [setgroups groups] sets the supplementary group IDs for the calling process. Appropriate privileges are required. + On Windows: not implemented. *) val initgroups : string -> int -> unit @@ -1218,6 +1287,7 @@ val initgroups : string -> int -> unit reading the group database /etc/group and using all groups of which [user] is a member. The additional group [group] is also added to the list. + On Windows: not implemented. *) type passwd_entry = @@ -1244,27 +1314,22 @@ val getlogin : unit -> string val getpwnam : string -> passwd_entry (** Find an entry in [passwd] with the given name. - @raise Not_found if no such entry exist. - - On Windows, always raise [Not_found]. *) + @raise Not_found if no such entry exists, or always on Windows. *) val getgrnam : string -> group_entry (** Find an entry in [group] with the given name. - @raise Not_found if no such entry exist. - On Windows, always raise [Not_found]. *) + @raise Not_found if no such entry exists, or always on Windows. *) val getpwuid : int -> passwd_entry (** Find an entry in [passwd] with the given user id. - @raise Not_found if no such entry exist. - On Windows, always raise [Not_found]. *) + @raise Not_found if no such entry exists, or always on Windows. *) val getgrgid : int -> group_entry (** Find an entry in [group] with the given group id. - @raise Not_found if no such entry exist. - On Windows, always raise [Not_found]. *) + @raise Not_found if no such entry exists, or always on Windows. *) (** {1 Internet addresses} *) @@ -1283,7 +1348,7 @@ val inet_addr_of_string : string -> inet_addr val string_of_inet_addr : inet_addr -> string (** Return the printable representation of the given Internet address. - See {!Unix.inet_addr_of_string} for a description of the + See {!inet_addr_of_string} for a description of the printable representation. *) val inet_addr_any : inet_addr @@ -1300,6 +1365,9 @@ val inet6_addr_any : inet_addr val inet6_addr_loopback : inet_addr (** A special IPv6 address representing the host machine ([::1]). *) +val is_inet6_addr : inet_addr -> bool +(** Whether the given [inet_addr] is an IPv6 address. + @since 4.12.0 *) (** {1 Sockets} *) @@ -1309,8 +1377,9 @@ type socket_domain = | PF_INET (** Internet domain (IPv4) *) | PF_INET6 (** Internet domain (IPv6) *) (** The type of socket domains. Not all platforms support - IPv6 sockets (type [PF_INET6]). Windows does not support - [PF_UNIX]. *) + IPv6 sockets (type [PF_INET6]). + + On Windows: [PF_UNIX] not implemented. *) type socket_type = SOCK_STREAM (** Stream socket *) @@ -1332,7 +1401,8 @@ type sockaddr = [port] is the port number. *) val socket : - ?cloexec:bool -> socket_domain -> socket_type -> int -> file_descr + ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + socket_domain -> socket_type -> int -> file_descr (** Create a new socket in the given domain, and with the given kind. The third argument is the protocol type; 0 selects the default protocol for that kind of sockets. @@ -1343,13 +1413,15 @@ val domain_of_sockaddr: sockaddr -> socket_domain (** Return the socket domain adequate for the given socket address. *) val socketpair : - ?cloexec:bool -> socket_domain -> socket_type -> int -> - file_descr * file_descr + ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + socket_domain -> socket_type -> int -> + file_descr * file_descr (** Create a pair of unnamed sockets, connected together. See {!set_close_on_exec} for documentation on the [cloexec] optional argument. *) -val accept : ?cloexec:bool -> file_descr -> file_descr * sockaddr +val accept : ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + file_descr -> file_descr * sockaddr (** Accept connections on the given socket. The returned descriptor is a socket connected to the client; the returned address is the address of the connecting client. @@ -1390,35 +1462,41 @@ type msg_flag = MSG_OOB | MSG_DONTROUTE | MSG_PEEK (**) -(** The flags for {!Unix.recv}, {!Unix.recvfrom}, - {!Unix.send} and {!Unix.sendto}. *) +(** The flags for {!recv}, {!recvfrom}, {!send} and {!sendto}. *) -val recv : file_descr -> bytes -> int -> int -> msg_flag list -> int +val recv : + file_descr -> bytes -> int -> int -> msg_flag list -> int (** Receive data from a connected socket. *) val recvfrom : - file_descr -> bytes -> int -> int -> msg_flag list -> int * sockaddr + file_descr -> bytes -> int -> int -> msg_flag list -> + int * sockaddr (** Receive data from an unconnected socket. *) -val send : file_descr -> bytes -> int -> int -> msg_flag list -> int +val send : + file_descr -> bytes -> int -> int -> msg_flag list -> int (** Send data over a connected socket. *) -val send_substring : file_descr -> string -> int -> int -> msg_flag list -> int +val send_substring : + file_descr -> string -> int -> int -> msg_flag list -> int (** Same as [send], but take the data from a string instead of a byte sequence. @since 4.02.0 *) val sendto : - file_descr -> bytes -> int -> int -> msg_flag list -> sockaddr -> int + file_descr -> bytes -> int -> int -> msg_flag list -> + sockaddr -> int (** Send data over an unconnected socket. *) val sendto_substring : - file_descr -> string -> int -> int -> msg_flag list -> sockaddr -> int + file_descr -> string -> int -> int -> msg_flag list + -> sockaddr -> int (** Same as [sendto], but take the data from a string instead of a byte sequence. @since 4.02.0 *) + (** {1 Socket options} *) @@ -1432,35 +1510,35 @@ type socket_bool_option = | SO_ACCEPTCONN (** Report whether socket listening is enabled *) | TCP_NODELAY (** Control the Nagle algorithm for TCP sockets *) | IPV6_ONLY (** Forbid binding an IPv6 socket to an IPv4 address *) -(** The socket options that can be consulted with {!Unix.getsockopt} - and modified with {!Unix.setsockopt}. These options have a boolean + | SO_REUSEPORT (** Allow reuse of address and port bindings *) +(** The socket options that can be consulted with {!getsockopt} + and modified with {!setsockopt}. These options have a boolean ([true]/[false]) value. *) type socket_int_option = - SO_SNDBUF (** Size of send buffer *) - | SO_RCVBUF (** Size of received buffer *) - | SO_ERROR (** Deprecated. Use {!Unix.getsockopt_error} instead. *) - | SO_TYPE (** Report the socket type *) - | SO_RCVLOWAT (** Minimum number of bytes to process for input operations*) - | SO_SNDLOWAT (** Minimum number of bytes to process for output - operations *) -(** The socket options that can be consulted with {!Unix.getsockopt_int} - and modified with {!Unix.setsockopt_int}. These options have an + SO_SNDBUF (** Size of send buffer *) + | SO_RCVBUF (** Size of received buffer *) + | SO_ERROR (** Deprecated. Use {!getsockopt_error} instead. *) + | SO_TYPE (** Report the socket type *) + | SO_RCVLOWAT (** Minimum number of bytes to process for input operations *) + | SO_SNDLOWAT (** Minimum number of bytes to process for output operations *) +(** The socket options that can be consulted with {!getsockopt_int} + and modified with {!setsockopt_int}. These options have an integer value. *) type socket_optint_option = SO_LINGER (** Whether to linger on closed connections that have data present, and for how long (in seconds) *) -(** The socket options that can be consulted with {!Unix.getsockopt_optint} - and modified with {!Unix.setsockopt_optint}. These options have a +(** The socket options that can be consulted with {!getsockopt_optint} + and modified with {!setsockopt_optint}. These options have a value of type [int option], with [None] meaning ``disabled''. *) type socket_float_option = SO_RCVTIMEO (** Timeout for input operations *) | SO_SNDTIMEO (** Timeout for output operations *) -(** The socket options that can be consulted with {!Unix.getsockopt_float} - and modified with {!Unix.setsockopt_float}. These options have a +(** The socket options that can be consulted with {!getsockopt_float} + and modified with {!setsockopt_float}. These options have a floating-point value representing a time in seconds. The value 0 means infinite timeout. *) @@ -1472,33 +1550,32 @@ val setsockopt : file_descr -> socket_bool_option -> bool -> unit (** Set or clear a boolean-valued option in the given socket. *) val getsockopt_int : file_descr -> socket_int_option -> int -(** Same as {!Unix.getsockopt} for an integer-valued socket option. *) +(** Same as {!getsockopt} for an integer-valued socket option. *) val setsockopt_int : file_descr -> socket_int_option -> int -> unit -(** Same as {!Unix.setsockopt} for an integer-valued socket option. *) +(** Same as {!setsockopt} for an integer-valued socket option. *) val getsockopt_optint : file_descr -> socket_optint_option -> int option -(** Same as {!Unix.getsockopt} for a socket option whose value is an - [int option]. *) +(** Same as {!getsockopt} for a socket option whose value is + an [int option]. *) val setsockopt_optint : file_descr -> socket_optint_option -> int option -> unit -(** Same as {!Unix.setsockopt} for a socket option whose value is an - [int option]. *) +(** Same as {!setsockopt} for a socket option whose value is + an [int option]. *) val getsockopt_float : file_descr -> socket_float_option -> float -(** Same as {!Unix.getsockopt} for a socket option whose value is a - floating-point number. *) +(** Same as {!getsockopt} for a socket option whose value is a + floating-point number. *) val setsockopt_float : file_descr -> socket_float_option -> float -> unit -(** Same as {!Unix.setsockopt} for a socket option whose value is a - floating-point number. *) +(** Same as {!setsockopt} for a socket option whose value is a + floating-point number. *) val getsockopt_error : file_descr -> error option (** Return the error condition associated with the given socket, and clear it. *) - (** {1 High-level network connection functions} *) @@ -1509,25 +1586,25 @@ val open_connection : sockaddr -> in_channel * out_channel times to ensure correct synchronization. *) val shutdown_connection : in_channel -> unit -(** ``Shut down'' a connection established with {!Unix.open_connection}; +(** ``Shut down'' a connection established with {!open_connection}; that is, transmit an end-of-file condition to the server reading on the other side of the connection. This does not fully close the file descriptor associated with the channel, which you must remember to free via {!Stdlib.close_in}. *) -val establish_server : (in_channel -> out_channel -> unit) -> sockaddr -> unit +val establish_server : + (in_channel -> out_channel -> unit) -> sockaddr -> unit (** Establish a server on the given address. The function given as first argument is called for each connection with two buffered channels connected to the client. A new process - is created for each connection. The function {!Unix.establish_server} + is created for each connection. The function {!establish_server} never returns normally. - On Windows, it is not implemented. Use threads. *) + On Windows: not implemented (use threads). *) (** {1 Host and protocol databases} *) - type host_entry = { h_name : string; h_aliases : string array; @@ -1556,27 +1633,27 @@ val gethostname : unit -> string val gethostbyname : string -> host_entry (** Find an entry in [hosts] with the given name. - @raise Not_found if no such entry exist. *) + @raise Not_found if no such entry exists. *) val gethostbyaddr : inet_addr -> host_entry (** Find an entry in [hosts] with the given address. - @raise Not_found if no such entry exist. *) + @raise Not_found if no such entry exists. *) val getprotobyname : string -> protocol_entry (** Find an entry in [protocols] with the given name. - @raise Not_found if no such entry exist. *) + @raise Not_found if no such entry exists. *) val getprotobynumber : int -> protocol_entry (** Find an entry in [protocols] with the given protocol number. - @raise Not_found if no such entry exist. *) + @raise Not_found if no such entry exists. *) val getservbyname : string -> string -> service_entry (** Find an entry in [services] with the given name. - @raise Not_found if no such entry exist. *) + @raise Not_found if no such entry exists. *) val getservbyport : int -> string -> service_entry (** Find an entry in [services] with the given service number. - @raise Not_found if no such entry exist. *) + @raise Not_found if no such entry exists. *) type addr_info = { ai_family : socket_domain; (** Socket domain *) @@ -1585,7 +1662,7 @@ type addr_info = ai_addr : sockaddr; (** Address *) ai_canonname : string (** Canonical host name *) } -(** Address information returned by {!Unix.getaddrinfo}. *) +(** Address information returned by {!getaddrinfo}. *) type getaddrinfo_option = AI_FAMILY of socket_domain (** Impose the given socket domain *) @@ -1596,12 +1673,12 @@ type getaddrinfo_option = | AI_CANONNAME (** Fill the [ai_canonname] field of the result *) | AI_PASSIVE (** Set address to ``any'' address - for use with {!Unix.bind} *) -(** Options to {!Unix.getaddrinfo}. *) + for use with {!bind} *) +(** Options to {!getaddrinfo}. *) val getaddrinfo: string -> string -> getaddrinfo_option list -> addr_info list -(** [getaddrinfo host service opts] returns a list of {!Unix.addr_info} +(** [getaddrinfo host service opts] returns a list of {!addr_info} records describing socket parameters and addresses suitable for communicating with the given host and service. The empty list is returned if the host or service names are unknown, or the constraints @@ -1622,7 +1699,7 @@ type name_info = { ni_hostname : string; (** Name or IP address of host *) ni_service : string; (** Name of service or port number *) } -(** Host and service information returned by {!Unix.getnameinfo}. *) +(** Host and service information returned by {!getnameinfo}. *) type getnameinfo_option = NI_NOFQDN (** Do not qualify local host names *) @@ -1631,7 +1708,7 @@ type getnameinfo_option = | NI_NUMERICSERV (** Always return service as port number *) | NI_DGRAM (** Consider the service as UDP-based instead of the default TCP *) -(** Options to {!Unix.getnameinfo}. *) +(** Options to {!getnameinfo}. *) val getnameinfo : sockaddr -> getnameinfo_option list -> name_info (** [getnameinfo addr opts] returns the host name and service name @@ -1700,7 +1777,8 @@ type terminal_io = val tcgetattr : file_descr -> terminal_io (** Return the status of the terminal referred to by the given file descriptor. - On Windows, not implemented. *) + + On Windows: not implemented. *) type setattr_when = TCSANOW @@ -1717,20 +1795,20 @@ val tcsetattr : file_descr -> setattr_when -> terminal_io -> unit the output parameters; [TCSAFLUSH], when changing the input parameters. - On Windows, not implemented. *) + On Windows: not implemented. *) val tcsendbreak : file_descr -> int -> unit (** Send a break condition on the given file descriptor. The second argument is the duration of the break, in 0.1s units; 0 means standard duration (0.25s). - On Windows, not implemented. *) + On Windows: not implemented. *) val tcdrain : file_descr -> unit (** Waits until all output written on the given file descriptor has been transmitted. - On Windows, not implemented. *) + On Windows: not implemented. *) type flush_queue = TCIFLUSH @@ -1744,7 +1822,7 @@ val tcflush : file_descr -> flush_queue -> unit [TCOFLUSH] flushes data written but not transmitted, and [TCIOFLUSH] flushes both. - On Windows, not implemented. *) + On Windows: not implemented. *) type flow_action = TCOOFF @@ -1759,10 +1837,10 @@ val tcflow : file_descr -> flow_action -> unit [TCIOFF] transmits a STOP character to suspend input, and [TCION] transmits a START character to restart input. - On Windows, not implemented. *) + On Windows: not implemented. *) val setsid : unit -> int (** Put the calling process in a new session and detach it from its controlling terminal. - On Windows, not implemented. *) + On Windows: not implemented. *) diff --git a/otherlibs/unix/unixLabels.mli b/otherlibs/unix/unixLabels.mli index 6b4c9374..7a556809 100644 --- a/otherlibs/unix/unixLabels.mli +++ b/otherlibs/unix/unixLabels.mli @@ -13,9 +13,29 @@ (* *) (**************************************************************************) +(* NOTE: + If this file is unixLabels.mli, run tools/sync_stdlib_docs after editing it + to generate unix.mli. + + If this file is unix.mli, do not edit it directly -- edit unixLabels.mli + instead. +*) + +(* NOTE: + When a new function is added which is not implemented on Windows (or + partially implemented), or the Windows-status of an existing function is + changed, remember to update the summary table in + manual/manual/library/libunix.etex +*) + (** Interface to the Unix system. - To use as replacement to default {!Unix} module, - add [module Unix = UnixLabels] in your implementation. + + To use the labeled version of this module, add [module Unix][ = ][UnixLabels] + in your implementation. + + Note: all the functions of this module (except {!error_message} and + {!handle_unix_error}) are liable to raise the {!Unix_error} + exception whenever the underlying system call signals an error. *) (** {1 Error report} *) @@ -103,14 +123,17 @@ exception Unix_error of error * string * string (** Raised by the system calls below when an error is encountered. The first component is the error code; the second component is the function name; the third component is the string parameter - to the function, if it has one, or the empty string otherwise. *) + to the function, if it has one, or the empty string otherwise. + + {!UnixLabels.Unix_error} and {!Unix.Unix_error} are the same, and + catching one will catch the other. *) val error_message : error -> string (** Return a string describing the given error code. *) val handle_unix_error : ('a -> 'b) -> 'a -> 'b (** [handle_unix_error f x] applies [f] to [x] and returns the result. - If the exception [Unix_error] is raised, it prints a message + If the exception {!Unix_error} is raised, it prints a message describing the error and exits with code 2. *) @@ -119,12 +142,25 @@ val handle_unix_error : ('a -> 'b) -> 'a -> 'b val environment : unit -> string array (** Return the process environment, as an array of strings - with the format ``variable=value''. *) + with the format ``variable=value''. The returned array + is empty if the process has special privileges. *) + +val unsafe_environment : unit -> string array +(** Return the process environment, as an array of strings with the + format ``variable=value''. Unlike {!environment}, this function + returns a populated array even if the process has special + privileges. See the documentation for {!unsafe_getenv} for more + details. + + @since 4.06.0 (4.12.0 in UnixLabels) *) val getenv : string -> string (** Return the value associated to a variable in the process - environment. Raise [Not_found] if the variable is unbound. - (This function is identical to [Sys.getenv].) *) + environment, unless the process has special privileges. + @raise Not_found if the variable is unbound or the process has + special privileges. + + This function is identical to {!Sys.getenv}. *) val unsafe_getenv : string -> string (** Return the value associated to a variable in the process @@ -141,7 +177,7 @@ val unsafe_getenv : string -> string @since 4.06.0 *) val putenv : string -> string -> unit -(** [Unix.putenv name value] sets the value associated to a +(** [putenv name value] sets the value associated to a variable in the process environment. [name] is the name of the environment variable, and [value] its new associated value. *) @@ -166,66 +202,99 @@ type process_status = Unix.process_status = type wait_flag = Unix.wait_flag = - WNOHANG (** do not block if no child has - died yet, but immediately return with a pid equal to 0.*) - | WUNTRACED (** report also the children that receive stop signals. *) -(** Flags for {!UnixLabels.waitpid}. *) + WNOHANG (** Do not block if no child has + died yet, but immediately return with a pid equal to 0. *) + | WUNTRACED (** Report also the children that receive stop signals. *) +(** Flags for {!waitpid}. *) val execv : prog:string -> args:string array -> 'a -(** [execv prog args] execute the program in file [prog], with +(** [execv ~prog ~args] execute the program in file [prog], with the arguments [args], and the current process environment. These [execv*] functions never return: on success, the current - program is replaced by the new one; - on failure, a {!UnixLabels.Unix_error} exception is raised. *) + program is replaced by the new one. + @raise Unix_error on failure *) val execve : prog:string -> args:string array -> env:string array -> 'a -(** Same as {!UnixLabels.execv}, except that the third argument provides the +(** Same as {!execv}, except that the third argument provides the environment to the program executed. *) val execvp : prog:string -> args:string array -> 'a -(** Same as {!UnixLabels.execv}, except that +(** Same as {!execv}, except that the program is searched in the path. *) val execvpe : prog:string -> args:string array -> env:string array -> 'a -(** Same as {!UnixLabels.execve}, except that +(** Same as {!execve}, except that the program is searched in the path. *) val fork : unit -> int (** Fork a new process. The returned integer is 0 for the child - process, the pid of the child process for the parent process. *) + process, the pid of the child process for the parent process. + + On Windows: not implemented, use {!create_process} or threads. *) val wait : unit -> int * process_status (** Wait until one of the children processes die, and return its pid - and termination status. *) + and termination status. + + On Windows: not implemented, use {!waitpid}. *) val waitpid : mode:wait_flag list -> int -> int * process_status -(** Same as {!UnixLabels.wait}, but waits for the child process whose pid - is given. +(** Same as {!wait}, but waits for the child process whose pid is given. A pid of [-1] means wait for any child. A pid of [0] means wait for any child in the same process group as the current process. Negative pid arguments represent process groups. The list of options indicates whether [waitpid] should return - immediately without waiting, or also report stopped children. *) + immediately without waiting, and whether it should report stopped + children. + + On Windows: can only wait for a given PID, not any child process. *) val system : string -> process_status (** Execute the given command, wait until it terminates, and return its termination status. The string is interpreted by the shell - [/bin/sh] and therefore can contain redirections, quotes, variables, - etc. The result [WEXITED 127] indicates that the shell couldn't - be executed. *) + [/bin/sh] (or the command interpreter [cmd.exe] on Windows) and + therefore can contain redirections, quotes, variables, etc. + To properly quote whitespace and shell special characters occurring + in file names or command arguments, the use of + {!Filename.quote_command} is recommended. + The result [WEXITED 127] indicates that the shell couldn't be + executed. *) + +val _exit : int -> 'a +(** Terminate the calling process immediately, returning the given + status code to the operating system: usually 0 to indicate no + errors, and a small positive integer to indicate failure. + Unlike {!Stdlib.exit}, {!Unix._exit} performs no finalization + whatsoever: functions registered with {!Stdlib.at_exit} are not called, + input/output channels are not flushed, and the C run-time system + is not finalized either. + + The typical use of {!Unix._exit} is after a {!Unix.fork} operation, + when the child process runs into a fatal error and must exit. In + this case, it is preferable to not perform any finalization action + in the child process, as these actions could interfere with similar + actions performed by the parent process. For example, output + channels should not be flushed by the child process, as the parent + process may flush them again later, resulting in duplicate + output. + + @since 4.12.0 *) val getpid : unit -> int (** Return the pid of the process. *) val getppid : unit -> int -(** Return the pid of the parent process. *) +(** Return the pid of the parent process. + + On Windows: not implemented (because it is meaningless). *) val nice : int -> int (** Change the process priority. The integer argument is added to the ``nice'' value. (Higher values of the ``nice'' value mean - lower priorities.) Return the new nice value. *) + lower priorities.) Return the new nice value. + On Windows: not implemented. *) (** {1 Basic file input/output} *) @@ -261,10 +330,12 @@ type open_flag = Unix.open_flag = | O_SHARE_DELETE (** Windows only: allow the file to be deleted while still open *) | O_CLOEXEC (** Set the close-on-exec flag on the - descriptor returned by {!openfile} *) + descriptor returned by {!openfile}. + See {!set_close_on_exec} for more + information. *) | O_KEEPEXEC (** Clear the close-on-exec flag. This is currently the default. *) -(** The flags to {!UnixLabels.openfile}. *) +(** The flags to {!openfile}. *) type file_perm = int @@ -272,38 +343,43 @@ type file_perm = int read for group, none for others *) val openfile : string -> mode:open_flag list -> perm:file_perm -> file_descr -(** Open the named file with the given flags. Third argument is - the permissions to give to the file if it is created. Return - a file descriptor on the named file. *) +(** Open the named file with the given flags. Third argument is the + permissions to give to the file if it is created (see + {!umask}). Return a file descriptor on the named file. *) val close : file_descr -> unit (** Close a file descriptor. *) +val fsync : file_descr -> unit +(** Flush file buffers to disk. + + @since 4.08.0 (4.12.0 in UnixLabels) *) + val read : file_descr -> buf:bytes -> pos:int -> len:int -> int -(** [read fd buff ofs len] reads [len] bytes from descriptor [fd], - storing them in byte sequence [buff], starting at position [ofs] in - [buff]. Return the number of bytes actually read. *) +(** [read fd ~buf ~pos ~len] reads [len] bytes from descriptor [fd], + storing them in byte sequence [buf], starting at position [pos] in + [buf]. Return the number of bytes actually read. *) val write : file_descr -> buf:bytes -> pos:int -> len:int -> int -(** [write fd buff ofs len] writes [len] bytes to descriptor [fd], - taking them from byte sequence [buff], starting at position [ofs] +(** [write fd ~buf ~pos ~len] writes [len] bytes to descriptor [fd], + taking them from byte sequence [buf], starting at position [pos] in [buff]. Return the number of bytes actually written. [write] repeats the writing operation until all bytes have been written or an error occurs. *) val single_write : file_descr -> buf:bytes -> pos:int -> len:int -> int -(** Same as [write], but attempts to write only once. +(** Same as {!write}, but attempts to write only once. Thus, if an error occurs, [single_write] guarantees that no data has been written. *) val write_substring : file_descr -> buf:string -> pos:int -> len:int -> int -(** Same as [write], but take the data from a string instead of a byte +(** Same as {!write}, but take the data from a string instead of a byte sequence. @since 4.02.0 *) val single_write_substring : file_descr -> buf:string -> pos:int -> len:int -> int -(** Same as [single_write], but take the data from a string instead of +(** Same as {!single_write}, but take the data from a string instead of a byte sequence. @since 4.02.0 *) @@ -314,12 +390,39 @@ val single_write_substring : val in_channel_of_descr : file_descr -> in_channel (** Create an input channel reading from the given descriptor. The channel is initially in binary mode; use - [set_binary_mode_in ic false] if text mode is desired. *) + [set_binary_mode_in ic false] if text mode is desired. + Text mode is supported only if the descriptor refers to a file + or pipe, but is not supported if it refers to a socket. + + On Windows: [set_binary_mode_in] always fails on channels created + with this function. + + Beware that channels are buffered so more characters may have been + read from the file descriptor than those accessed using channel functions. + Channels also keep a copy of the current position in the file. + + You need to explicitly close all channels created with this function. + Closing the channel also closes the underlying file descriptor (unless + it was already closed). *) val out_channel_of_descr : file_descr -> out_channel (** Create an output channel writing on the given descriptor. The channel is initially in binary mode; use - [set_binary_mode_out oc false] if text mode is desired. *) + [set_binary_mode_out oc false] if text mode is desired. + Text mode is supported only if the descriptor refers to a file + or pipe, but is not supported if it refers to a socket. + + On Windows: [set_binary_mode_out] always fails on channels created + with this function. + + Beware that channels are buffered so you may have to [flush] them + to ensure that all data has been sent to the file descriptor. + Channels also keep a copy of the current position in the file. + + You need to explicitly close all channels created with this function. + Closing the channel flushes the data and closes the underlying file + descriptor (unless it has already been closed, in which case the + buffered data is lost).*) val descr_of_in_channel : in_channel -> file_descr (** Return the descriptor corresponding to an input channel. *) @@ -335,7 +438,7 @@ type seek_command = Unix.seek_command = SEEK_SET (** indicates positions relative to the beginning of the file *) | SEEK_CUR (** indicates positions relative to the current position *) | SEEK_END (** indicates positions relative to the end of the file *) -(** Positioning modes for {!UnixLabels.lseek}. *) +(** Positioning modes for {!lseek}. *) val lseek : file_descr -> int -> mode:seek_command -> int @@ -376,13 +479,13 @@ type stats = Unix.stats = st_mtime : float; (** Last modification time *) st_ctime : float; (** Last status change time *) } -(** The information returned by the {!UnixLabels.stat} calls. *) +(** The information returned by the {!stat} calls. *) val stat : string -> stats (** Return the information for the named file. *) val lstat : string -> stats -(** Same as {!UnixLabels.stat}, but in case the file is a symbolic link, +(** Same as {!stat}, but in case the file is a symbolic link, return the information for the link itself. *) val fstat : file_descr -> stats @@ -398,8 +501,14 @@ val isatty : file_descr -> bool module LargeFile : sig val lseek : file_descr -> int64 -> mode:seek_command -> int64 + (** See [lseek]. *) + val truncate : string -> len:int64 -> unit + (** See [truncate]. *) + val ftruncate : file_descr -> len:int64 -> unit + (** See [ftruncate]. *) + type stats = Unix.LargeFile.stats = { st_dev : int; (** Device number *) st_ino : int; (** Inode number *) @@ -420,29 +529,30 @@ module LargeFile : end (** File operations on large files. This sub-module provides 64-bit variants of the functions - {!UnixLabels.lseek} (for positioning a file descriptor), - {!UnixLabels.truncate} and {!UnixLabels.ftruncate} + {!lseek} (for positioning a file descriptor), + {!truncate} and {!ftruncate} (for changing the size of a file), - and {!UnixLabels.stat}, {!UnixLabels.lstat} and {!UnixLabels.fstat} + and {!stat}, {!lstat} and {!fstat} (for obtaining information on files). These alternate functions represent positions and sizes by 64-bit integers (type [int64]) instead of regular integers (type [int]), thus allowing operating on files whose sizes are greater than [max_int]. *) - (** {1 Mapping files into memory} *) val map_file : - file_descr -> ?pos:int64 -> kind:('a, 'b) Stdlib.Bigarray.kind -> + file_descr -> + ?pos (* thwart tools/sync_stdlib_docs *):int64 -> + kind:('a, 'b) Stdlib.Bigarray.kind -> layout:'c Stdlib.Bigarray.layout -> shared:bool -> dims:int array -> ('a, 'b, 'c) Stdlib.Bigarray.Genarray.t (** Memory mapping of a file as a Bigarray. - [map_file fd kind layout shared dims] + [map_file fd ~kind ~layout ~shared ~dims] returns a Bigarray of kind [kind], layout [layout], and dimensions as specified in [dims]. The data contained in this Bigarray are the contents of the file referred to by the file descriptor [fd] (as opened previously with - [Unix.openfile], for example). The optional [pos] parameter + {!openfile}, for example). The optional [pos] parameter is the byte offset in the file of the data being mapped; it defaults to 0 (map from the beginning of the file). @@ -487,17 +597,30 @@ val map_file : val unlink : string -> unit -(** Removes the named file *) - -val rename : src:string -> dst:string -> unit -(** [rename old new] changes the name of a file from [old] to [new]. *) +(** Removes the named file. -val link : ?follow:bool -> src:string -> dst:string -> unit -(** [link ?follow source dest] creates a hard link named [dest] to the file - named [source]. + If the named file is a directory, raises: + {ul + {- [EPERM] on POSIX compliant system} + {- [EISDIR] on Linux >= 2.1.132} + {- [EACCESS] on Windows}} +*) - @param follow indicates whether a [source] symlink is followed or a - hardlink to [source] itself will be created. On {e Unix} systems this is +val rename : src:string -> dst:string -> unit +(** [rename ~src ~dst] changes the name of a file from [src] to [dst], + moving it between directories if needed. If [dst] already + exists, its contents will be replaced with those of [src]. + Depending on the operating system, the metadata (permissions, + owner, etc) of [dst] can either be preserved or be replaced by + those of [src]. *) + +val link : ?follow (* thwart tools/sync_stdlib_docs *) :bool -> + src:string -> dst:string -> unit +(** [link ?follow ~src ~dst] creates a hard link named [dst] to the file + named [src]. + + @param follow indicates whether a [src] symlink is followed or a + hardlink to [src] itself will be created. On {e Unix} systems this is done using the [linkat(2)] function. If [?follow] is not provided, then the [link(2)] function is used whose behaviour is OS-dependent, but more widely available. @@ -515,40 +638,59 @@ type access_permission = Unix.access_permission = | W_OK (** Write permission *) | X_OK (** Execution permission *) | F_OK (** File exists *) -(** Flags for the {!UnixLabels.access} call. *) +(** Flags for the {!access} call. *) val chmod : string -> perm:file_perm -> unit (** Change the permissions of the named file. *) val fchmod : file_descr -> perm:file_perm -> unit -(** Change the permissions of an opened file. *) +(** Change the permissions of an opened file. + + On Windows: not implemented. *) val chown : string -> uid:int -> gid:int -> unit -(** Change the owner uid and owner gid of the named file. *) +(** Change the owner uid and owner gid of the named file. + + On Windows: not implemented. *) val fchown : file_descr -> uid:int -> gid:int -> unit -(** Change the owner uid and owner gid of an opened file. *) +(** Change the owner uid and owner gid of an opened file. + + On Windows: not implemented. *) val umask : int -> int (** Set the process's file mode creation mask, and return the previous - mask. *) + mask. + + On Windows: not implemented. *) val access : string -> perm:access_permission list -> unit -(** Check that the process has the given permissions over the named - file. Raise [Unix_error] otherwise. *) +(** Check that the process has the given permissions over the named file. + + On Windows: execute permission [X_OK] cannot be tested, just + tests for read permission instead. + + @raise Unix_error otherwise. + *) (** {1 Operations on file descriptors} *) -val dup : ?cloexec:bool -> file_descr -> file_descr +val dup : ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + file_descr -> file_descr (** Return a new file descriptor referencing the same file as - the given descriptor. *) + the given descriptor. + See {!set_close_on_exec} for documentation on the [cloexec] + optional argument. *) -val dup2 : ?cloexec:bool -> src:file_descr -> dst:file_descr -> unit -(** [dup2 fd1 fd2] duplicates [fd1] to [fd2], closing [fd2] if already - opened. *) +val dup2 : ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + src:file_descr -> dst:file_descr -> unit +(** [dup2 ~src ~dst] duplicates [src] to [dst], closing [dst] if already + opened. + See {!set_close_on_exec} for documentation on the [cloexec] + optional argument. *) val set_nonblock : file_descr -> unit (** Set the ``non-blocking'' flag on the given descriptor. @@ -560,24 +702,65 @@ val set_nonblock : file_descr -> unit val clear_nonblock : file_descr -> unit (** Clear the ``non-blocking'' flag on the given descriptor. - See {!UnixLabels.set_nonblock}.*) + See {!set_nonblock}.*) val set_close_on_exec : file_descr -> unit (** Set the ``close-on-exec'' flag on the given descriptor. A descriptor with the close-on-exec flag is automatically closed when the current process starts another program with - one of the [exec] functions. *) + one of the [exec], [create_process] and [open_process] functions. + + It is often a security hole to leak file descriptors opened on, say, + a private file to an external program: the program, then, gets access + to the private file and can do bad things with it. Hence, it is + highly recommended to set all file descriptors ``close-on-exec'', + except in the very few cases where a file descriptor actually needs + to be transmitted to another program. + + The best way to set a file descriptor ``close-on-exec'' is to create + it in this state. To this end, the [openfile] function has + [O_CLOEXEC] and [O_KEEPEXEC] flags to enforce ``close-on-exec'' mode + or ``keep-on-exec'' mode, respectively. All other operations in + the Unix module that create file descriptors have an optional + argument [?cloexec:bool] to indicate whether the file descriptor + should be created in ``close-on-exec'' mode (by writing + [~cloexec:true]) or in ``keep-on-exec'' mode (by writing + [~cloexec:false]). For historical reasons, the default file + descriptor creation mode is ``keep-on-exec'', if no [cloexec] optional + argument is given. This is not a safe default, hence it is highly + recommended to pass explicit [cloexec] arguments to operations that + create file descriptors. + + The [cloexec] optional arguments and the [O_KEEPEXEC] flag were introduced + in OCaml 4.05. Earlier, the common practice was to create file descriptors + in the default, ``keep-on-exec'' mode, then call [set_close_on_exec] + on those freshly-created file descriptors. This is not as safe as + creating the file descriptor in ``close-on-exec'' mode because, in + multithreaded programs, a window of vulnerability exists between the time + when the file descriptor is created and the time [set_close_on_exec] + completes. If another thread spawns another program during this window, + the descriptor will leak, as it is still in the ``keep-on-exec'' mode. + + Regarding the atomicity guarantees given by [~cloexec:true] or by + the use of the [O_CLOEXEC] flag: on all platforms it is guaranteed + that a concurrently-executing Caml thread cannot leak the descriptor + by starting a new process. On Linux, this guarantee extends to + concurrently-executing C threads. As of Feb 2017, other operating + systems lack the necessary system calls and still expose a window + of vulnerability during which a C thread can see the newly-created + file descriptor in ``keep-on-exec'' mode. + *) val clear_close_on_exec : file_descr -> unit (** Clear the ``close-on-exec'' flag on the given descriptor. - See {!UnixLabels.set_close_on_exec}.*) + See {!set_close_on_exec}.*) (** {1 Directories} *) val mkdir : string -> perm:file_perm -> unit -(** Create a directory with the given permissions. *) +(** Create a directory with the given permissions (see {!umask}). *) val rmdir : string -> unit (** Remove an empty directory. *) @@ -589,7 +772,9 @@ val getcwd : unit -> string (** Return the name of the current working directory. *) val chroot : string -> unit -(** Change the process root directory. *) +(** Change the process root directory. + + On Windows: not implemented. *) type dir_handle = Unix.dir_handle (** The type of descriptors over opened directories. *) @@ -612,13 +797,18 @@ val closedir : dir_handle -> unit (** {1 Pipes and redirections} *) -val pipe : ?cloexec:bool -> unit -> file_descr * file_descr +val pipe : ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + unit -> file_descr * file_descr (** Create a pipe. The first component of the result is opened for reading, that's the exit to the pipe. The second component is - opened for writing, that's the entrance to the pipe. *) + opened for writing, that's the entrance to the pipe. + See {!set_close_on_exec} for documentation on the [cloexec] + optional argument. *) val mkfifo : string -> perm:file_perm -> unit -(** Create a named pipe with the given permissions. *) +(** Create a named pipe with the given permissions (see {!umask}). + + On Windows: not implemented. *) (** {1 High-level process and redirection management} *) @@ -627,14 +817,14 @@ val mkfifo : string -> perm:file_perm -> unit val create_process : prog:string -> args:string array -> stdin:file_descr -> stdout:file_descr -> stderr:file_descr -> int -(** [create_process prog args new_stdin new_stdout new_stderr] +(** [create_process ~prog ~args ~stdin ~stdout ~stderr] forks a new process that executes the program in file [prog], with arguments [args]. The pid of the new process is returned immediately; the new process executes concurrently with the current process. The standard input and outputs of the new process are connected - to the descriptors [new_stdin], [new_stdout] and [new_stderr]. - Passing e.g. [stdout] for [new_stdout] prevents the redirection + to the descriptors [stdin], [stdout] and [stderr]. + Passing e.g. [Stdlib.stdout] for [stdout] prevents the redirection and causes the new process to have the same standard output as the current process. The executable file [prog] is searched in the path. @@ -643,8 +833,8 @@ val create_process : val create_process_env : prog:string -> args:string array -> env:string array -> stdin:file_descr -> stdout:file_descr -> stderr:file_descr -> int -(** [create_process_env prog args env new_stdin new_stdout new_stderr] - works as {!UnixLabels.create_process}, except that the extra argument +(** [create_process_env ~prog ~args ~env ~stdin ~stdout ~stderr] + works as {!create_process}, except that the extra argument [env] specifies the environment passed to the program. *) @@ -653,28 +843,43 @@ val open_process_in : string -> in_channel runs the given command in parallel with the program. The standard output of the command is redirected to a pipe, which can be read via the returned input channel. - The command is interpreted by the shell [/bin/sh] (cf. [system]). *) + The command is interpreted by the shell [/bin/sh] + (or [cmd.exe] on Windows), cf. {!system}. + The {!Filename.quote_command} function can be used to + quote the command and its arguments as appropriate for the shell being + used. If the command does not need to be run through the shell, + {!open_process_args_in} can be used as a more robust and + more efficient alternative to {!open_process_in}. *) val open_process_out : string -> out_channel -(** Same as {!UnixLabels.open_process_in}, but redirect the standard input of +(** Same as {!open_process_in}, but redirect the standard input of the command to a pipe. Data written to the returned output channel is sent to the standard input of the command. Warning: writes on output channels are buffered, hence be careful to call {!Stdlib.flush} at the right times to ensure - correct synchronization. *) + correct synchronization. + If the command does not need to be run through the shell, + {!open_process_args_out} can be used instead of + {!open_process_out}. *) val open_process : string -> in_channel * out_channel -(** Same as {!UnixLabels.open_process_out}, but redirects both the standard - input and standard output of the command to pipes connected to the two +(** Same as {!open_process_out}, but redirects both the standard input + and standard output of the command to pipes connected to the two returned channels. The input channel is connected to the output - of the command, and the output channel to the input of the command. *) + of the command, and the output channel to the input of the command. + If the command does not need to be run through the shell, + {!open_process_args} can be used instead of + {!open_process}. *) val open_process_full : string -> env:string array -> in_channel * out_channel * in_channel -(** Similar to {!UnixLabels.open_process}, but the second argument specifies +(** Similar to {!open_process}, but the second argument specifies the environment passed to the command. The result is a triple of channels connected respectively to the standard output, standard input, - and standard error of the command. *) + and standard error of the command. + If the command does not need to be run through the shell, + {!open_process_args_full} can be used instead of + {!open_process_full}. *) val open_process_args_in : string -> string array -> in_channel (** High-level pipe and process management. The first argument specifies the @@ -686,7 +891,7 @@ val open_process_args_in : string -> string array -> in_channel @since 4.08.0 *) val open_process_args_out : string -> string array -> out_channel -(** Same as {!Unix.open_process_args_in}, but redirect the standard input of the +(** Same as {!open_process_args_in}, but redirect the standard input of the command to a pipe. Data written to the returned output channel is sent to the standard input of the command. Warning: writes on output channels are buffered, hence be careful to call {!Stdlib.flush} at the right times to @@ -695,7 +900,7 @@ val open_process_args_out : string -> string array -> out_channel @since 4.08.0 *) val open_process_args : string -> string array -> in_channel * out_channel -(** Same as {!Unix.open_process_args_out}, but redirects both the standard input +(** Same as {!open_process_args_out}, but redirects both the standard input and standard output of the command to pipes connected to the two returned channels. The input channel is connected to the output of the command, and the output channel to the input of the command. @@ -705,31 +910,55 @@ val open_process_args : string -> string array -> in_channel * out_channel val open_process_args_full : string -> string array -> string array -> in_channel * out_channel * in_channel -(** Similar to {!Unix.open_process_args}, but the third argument specifies the +(** Similar to {!open_process_args}, but the third argument specifies the environment passed to the command. The result is a triple of channels connected respectively to the standard output, standard input, and standard error of the command. @since 4.08.0 *) +val process_in_pid : in_channel -> int +(** Return the pid of a process opened via {!open_process_in} or + {!open_process_args_in}. + + @since 4.08.0 (4.12.0 in UnixLabels) *) + +val process_out_pid : out_channel -> int +(** Return the pid of a process opened via {!open_process_out} or + {!open_process_args_out}. + + @since 4.08.0 (4.12.0 in UnixLabels) *) + +val process_pid : in_channel * out_channel -> int +(** Return the pid of a process opened via {!open_process} or + {!open_process_args}. + + @since 4.08.0 (4.12.0 in UnixLabels) *) + +val process_full_pid : in_channel * out_channel * in_channel -> int +(** Return the pid of a process opened via {!open_process_full} or + {!open_process_args_full}. + + @since 4.08.0 (4.12.0 in UnixLabels) *) + val close_process_in : in_channel -> process_status -(** Close channels opened by {!UnixLabels.open_process_in}, +(** Close channels opened by {!open_process_in}, wait for the associated command to terminate, and return its termination status. *) val close_process_out : out_channel -> process_status -(** Close channels opened by {!UnixLabels.open_process_out}, +(** Close channels opened by {!open_process_out}, wait for the associated command to terminate, and return its termination status. *) val close_process : in_channel * out_channel -> process_status -(** Close channels opened by {!UnixLabels.open_process}, +(** Close channels opened by {!open_process}, wait for the associated command to terminate, and return its termination status. *) val close_process_full : in_channel * out_channel * in_channel -> process_status -(** Close channels opened by {!UnixLabels.open_process_full}, +(** Close channels opened by {!open_process_full}, wait for the associated command to terminate, and return its termination status. *) @@ -737,9 +966,38 @@ val close_process_full : (** {1 Symbolic links} *) -val symlink : ?to_dir:bool -> src:string -> dst:string -> unit -(** [symlink source dest] creates the file [dest] as a symbolic link - to the file [source]. See {!Unix.symlink} for details of [~to_dir] *) +val symlink : ?to_dir: (* thwart tools/sync_stdlib_docs *) bool -> + src:string -> dst:string -> unit +(** [symlink ?to_dir ~src ~dst] creates the file [dst] as a symbolic link + to the file [src]. On Windows, [~to_dir] indicates if the symbolic link + points to a directory or a file; if omitted, [symlink] examines [src] + using [stat] and picks appropriately, if [src] does not exist then [false] + is assumed (for this reason, it is recommended that the [~to_dir] parameter + be specified in new code). On Unix, [~to_dir] is ignored. + + Windows symbolic links are available in Windows Vista onwards. There are some + important differences between Windows symlinks and their POSIX counterparts. + + Windows symbolic links come in two flavours: directory and regular, which + designate whether the symbolic link points to a directory or a file. The type + must be correct - a directory symlink which actually points to a file cannot + be selected with chdir and a file symlink which actually points to a + directory cannot be read or written (note that Cygwin's emulation layer + ignores this distinction). + + When symbolic links are created to existing targets, this distinction doesn't + matter and [symlink] will automatically create the correct kind of symbolic + link. The distinction matters when a symbolic link is created to a + non-existent target. + + The other caveat is that by default symbolic links are a privileged + operation. Administrators will always need to be running elevated (or with + UAC disabled) and by default normal user accounts need to be granted the + SeCreateSymbolicLinkPrivilege via Local Security Policy (secpol.msc) or via + Active Directory. + + {!has_symlink} can be used to check that a process is able to create + symbolic links. *) val has_symlink : unit -> bool (** Returns [true] if the user is able to create symbolic links. On Windows, @@ -749,7 +1007,7 @@ val has_symlink : unit -> bool @since 4.03.0 *) val readlink : string -> string -(** Read the contents of a link. *) +(** Read the contents of a symbolic link. *) (** {1 Polling} *) @@ -771,7 +1029,6 @@ val select : (** {1 Locking} *) - type lock_command = Unix.lock_command = F_ULOCK (** Unlock a region *) | F_LOCK (** Lock a region for writing, and block if already locked *) @@ -779,14 +1036,14 @@ type lock_command = Unix.lock_command = | F_TEST (** Test a region for other process locks *) | F_RLOCK (** Lock a region for reading, and block if already locked *) | F_TRLOCK (** Lock a region for reading, or fail if already locked *) -(** Commands for {!UnixLabels.lockf}. *) +(** Commands for {!lockf}. *) val lockf : file_descr -> mode:lock_command -> len:int -> unit -(** [lockf fd cmd size] puts a lock on a region of the file opened +(** [lockf fd ~mode ~len] puts a lock on a region of the file opened as [fd]. The region starts at the current read/write position for - [fd] (as set by {!UnixLabels.lseek}), and extends [size] bytes forward if - [size] is positive, [size] bytes backwards if [size] is negative, - or to the end of the file if [size] is zero. + [fd] (as set by {!lseek}), and extends [len] bytes forward if + [len] is positive, [len] bytes backwards if [len] is negative, + or to the end of the file if [len] is zero. A write lock prevents any other process from acquiring a read or write lock on the region. A read lock prevents any other @@ -805,7 +1062,13 @@ val lockf : file_descr -> mode:lock_command -> len:int -> unit the specified region. Finally, the [F_TEST] command tests whether a write lock can be acquired on the specified region, without actually putting a lock. - It returns immediately if successful, or fails otherwise. *) + It returns immediately if successful, or fails otherwise. + + What happens when a process tries to lock a region of a file that is + already locked by the same process depends on the OS. On POSIX-compliant + systems, the second lock operation succeeds and may "promote" the older + lock from read lock to write lock. On Windows, the second lock + operation will block or fail. *) (** {1 Signals} @@ -814,8 +1077,10 @@ val lockf : file_descr -> mode:lock_command -> len:int -> unit *) val kill : pid:int -> signal:int -> unit -(** [kill pid sig] sends signal number [sig] to the process - with id [pid]. *) +(** [kill ~pid ~signal] sends signal number [signal] to the process + with id [pid]. + + On Windows: only the {!Sys.sigkill} signal is emulated. *) type sigprocmask_command = Unix.sigprocmask_command = SIG_SETMASK @@ -823,25 +1088,37 @@ type sigprocmask_command = Unix.sigprocmask_command = | SIG_UNBLOCK val sigprocmask : mode:sigprocmask_command -> int list -> int list -(** [sigprocmask cmd sigs] changes the set of blocked signals. - If [cmd] is [SIG_SETMASK], blocked signals are set to those in +(** [sigprocmask ~mode sigs] changes the set of blocked signals. + If [mode] is [SIG_SETMASK], blocked signals are set to those in the list [sigs]. - If [cmd] is [SIG_BLOCK], the signals in [sigs] are added to + If [mode] is [SIG_BLOCK], the signals in [sigs] are added to the set of blocked signals. - If [cmd] is [SIG_UNBLOCK], the signals in [sigs] are removed + If [mode] is [SIG_UNBLOCK], the signals in [sigs] are removed from the set of blocked signals. - [sigprocmask] returns the set of previously blocked signals. *) + [sigprocmask] returns the set of previously blocked signals. + + When the systhreads version of the [Thread] module is loaded, this + function redirects to [Thread.sigmask]. I.e., [sigprocmask] only + changes the mask of the current thread. + + On Windows: not implemented (no inter-process signals on Windows). *) val sigpending : unit -> int list -(** Return the set of blocked signals that are currently pending. *) +(** Return the set of blocked signals that are currently pending. + + On Windows: not implemented (no inter-process signals on Windows). *) val sigsuspend : int list -> unit (** [sigsuspend sigs] atomically sets the blocked signals to [sigs] and waits for a non-ignored, non-blocked signal to be delivered. - On return, the blocked signals are reset to their initial value. *) + On return, the blocked signals are reset to their initial value. + + On Windows: not implemented (no inter-process signals on Windows). *) val pause : unit -> unit -(** Wait until a non-ignored, non-blocked signal is delivered. *) +(** Wait until a non-ignored, non-blocked signal is delivered. + + On Windows: not implemented (no inter-process signals on Windows). *) (** {1 Time functions} *) @@ -874,19 +1151,22 @@ val time : unit -> float in seconds. *) val gettimeofday : unit -> float -(** Same as {!UnixLabels.time}, but with resolution better than 1 second. *) +(** Same as {!time}, but with resolution better than 1 second. *) val gmtime : float -> tm -(** Convert a time in seconds, as returned by {!UnixLabels.time}, into a date - and a time. Assumes UTC (Coordinated Universal Time), also known as GMT. *) +(** Convert a time in seconds, as returned by {!time}, into a date and + a time. Assumes UTC (Coordinated Universal Time), also known as GMT. + To perform the inverse conversion, set the TZ environment variable + to "UTC", use {!mktime}, and then restore the original value of TZ. *) val localtime : float -> tm -(** Convert a time in seconds, as returned by {!UnixLabels.time}, into a date - and a time. Assumes the local time zone. *) +(** Convert a time in seconds, as returned by {!time}, into a date and + a time. Assumes the local time zone. + The function performing the inverse conversion is {!mktime}. *) val mktime : tm -> float * tm (** Convert a date and time, specified by the [tm] argument, into - a time in seconds, as returned by {!UnixLabels.time}. The [tm_isdst], + a time in seconds, as returned by {!time}. The [tm_isdst], [tm_wday] and [tm_yday] fields of [tm] are ignored. Also return a normalized copy of the given [tm] record, with the [tm_wday], [tm_yday], and [tm_isdst] fields recomputed from the other fields, @@ -895,19 +1175,30 @@ val mktime : tm -> float * tm local time zone. *) val alarm : int -> int -(** Schedule a [SIGALRM] signal after the given number of seconds. *) +(** Schedule a [SIGALRM] signal after the given number of seconds. + + On Windows: not implemented. *) val sleep : int -> unit (** Stop execution for the given number of seconds. *) +val sleepf : float -> unit +(** Stop execution for the given number of seconds. Like [sleep], + but fractions of seconds are supported. + + @since 4.03.0 (4.12.0 in UnixLabels) *) + val times : unit -> process_times -(** Return the execution times of the process. *) +(** Return the execution times of the process. + + On Windows: partially implemented, will not report timings + for child processes. *) val utimes : string -> access:float -> modif:float -> unit (** Set the last access time (second arg) and last modification time (third arg) for a file. Times are expressed in seconds from - 00:00:00 GMT, Jan. 1, 1970. A time of [0.0] is interpreted as the - current time. *) + 00:00:00 GMT, Jan. 1, 1970. If both times are [0.0], the access + and last modification times are both set to the current time. *) type interval_timer = Unix.interval_timer = ITIMER_REAL @@ -929,7 +1220,9 @@ type interval_timer_status = Unix.interval_timer_status = (** The type describing the status of an interval timer *) val getitimer : interval_timer -> interval_timer_status -(** Return the current status of the given interval timer. *) +(** Return the current status of the given interval timer. + + On Windows: not implemented. *) val setitimer : interval_timer -> interval_timer_status -> interval_timer_status @@ -937,46 +1230,65 @@ val setitimer : its previous status. The [s] argument is interpreted as follows: [s.it_value], if nonzero, is the time to the next timer expiration; [s.it_interval], if nonzero, specifies a value to - be used in reloading it_value when the timer expires. - Setting [s.it_value] to zero disable the timer. + be used in reloading [it_value] when the timer expires. + Setting [s.it_value] to zero disables the timer. Setting [s.it_interval] to zero causes the timer to be disabled - after its next expiration. *) + after its next expiration. + On Windows: not implemented. *) -(** {1 User id, group id} *) +(** {1 User id, group id} *) val getuid : unit -> int -(** Return the user id of the user executing the process. *) +(** Return the user id of the user executing the process. + + On Windows: always returns [1]. *) val geteuid : unit -> int -(** Return the effective user id under which the process runs. *) +(** Return the effective user id under which the process runs. + + On Windows: always returns [1]. *) val setuid : int -> unit -(** Set the real user id and effective user id for the process. *) +(** Set the real user id and effective user id for the process. + + On Windows: not implemented. *) val getgid : unit -> int -(** Return the group id of the user executing the process. *) +(** Return the group id of the user executing the process. + + On Windows: always returns [1]. *) val getegid : unit -> int -(** Return the effective group id under which the process runs. *) +(** Return the effective group id under which the process runs. + + On Windows: always returns [1]. *) val setgid : int -> unit -(** Set the real group id and effective group id for the process. *) +(** Set the real group id and effective group id for the process. + + On Windows: not implemented. *) val getgroups : unit -> int array (** Return the list of groups to which the user executing the process - belongs. *) + belongs. + + On Windows: always returns [[|1|]]. *) val setgroups : int array -> unit - (** [setgroups groups] sets the supplementary group IDs for the - calling process. Appropriate privileges are required. *) +(** [setgroups groups] sets the supplementary group IDs for the + calling process. Appropriate privileges are required. + + On Windows: not implemented. *) val initgroups : string -> int -> unit - (** [initgroups user group] initializes the group access list by - reading the group database /etc/group and using all groups of - which [user] is a member. The additional group [group] is also - added to the list. *) +(** [initgroups user group] initializes the group access list by + reading the group database /etc/group and using all groups of + which [user] is a member. The additional group [group] is also + added to the list. + + On Windows: not implemented. *) type passwd_entry = Unix.passwd_entry = { pw_name : string; @@ -1001,20 +1313,23 @@ val getlogin : unit -> string (** Return the login name of the user executing the process. *) val getpwnam : string -> passwd_entry -(** Find an entry in [passwd] with the given name, or raise - [Not_found] if the matching entry is not found. *) +(** Find an entry in [passwd] with the given name. + @raise Not_found if no such entry exists, or always on Windows. *) val getgrnam : string -> group_entry -(** Find an entry in [group] with the given name, or raise - [Not_found] if the matching entry is not found. *) +(** Find an entry in [group] with the given name. + + @raise Not_found if no such entry exists, or always on Windows. *) val getpwuid : int -> passwd_entry -(** Find an entry in [passwd] with the given user id, or raise - [Not_found] if the matching entry is not found. *) +(** Find an entry in [passwd] with the given user id. + + @raise Not_found if no such entry exists, or always on Windows. *) val getgrgid : int -> group_entry -(** Find an entry in [group] with the given group id, or raise - [Not_found] if the matching entry is not found. *) +(** Find an entry in [group] with the given group id. + + @raise Not_found if no such entry exists, or always on Windows. *) (** {1 Internet addresses} *) @@ -1028,12 +1343,12 @@ val inet_addr_of_string : string -> inet_addr address to its internal representation. The argument string consists of 4 numbers separated by periods ([XXX.YYY.ZZZ.TTT]) for IPv4 addresses, and up to 8 numbers separated by colons - for IPv6 addresses. Raise [Failure] when given a string that - does not match these formats. *) + for IPv6 addresses. + @raise Failure when given a string that does not match these formats. *) val string_of_inet_addr : inet_addr -> string (** Return the printable representation of the given Internet address. - See {!Unix.inet_addr_of_string} for a description of the + See {!inet_addr_of_string} for a description of the printable representation. *) val inet_addr_any : inet_addr @@ -1050,6 +1365,9 @@ val inet6_addr_any : inet_addr val inet6_addr_loopback : inet_addr (** A special IPv6 address representing the host machine ([::1]). *) +val is_inet6_addr : inet_addr -> bool +(** Whether the given [inet_addr] is an IPv6 address. + @since 4.12.0 *) (** {1 Sockets} *) @@ -1059,7 +1377,9 @@ type socket_domain = Unix.socket_domain = | PF_INET (** Internet domain (IPv4) *) | PF_INET6 (** Internet domain (IPv6) *) (** The type of socket domains. Not all platforms support - IPv6 sockets (type [PF_INET6]). *) + IPv6 sockets (type [PF_INET6]). + + On Windows: [PF_UNIX] not implemented. *) type socket_type = Unix.socket_type = SOCK_STREAM (** Stream socket *) @@ -1067,7 +1387,9 @@ type socket_type = Unix.socket_type = | SOCK_RAW (** Raw socket *) | SOCK_SEQPACKET (** Sequenced packets socket *) (** The type of socket kinds, specifying the semantics of - communications. *) + communications. [SOCK_SEQPACKET] is included for completeness, + but is rarely supported by the OS, and needs system calls that + are not available in this library. *) type sockaddr = Unix.sockaddr = ADDR_UNIX of string @@ -1079,24 +1401,32 @@ type sockaddr = Unix.sockaddr = [port] is the port number. *) val socket : - ?cloexec:bool -> domain:socket_domain -> kind:socket_type -> protocol:int -> - file_descr + ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + domain:socket_domain -> kind:socket_type -> protocol:int -> file_descr (** Create a new socket in the given domain, and with the given kind. The third argument is the protocol type; 0 selects - the default protocol for that kind of sockets. *) + the default protocol for that kind of sockets. + See {!set_close_on_exec} for documentation on the [cloexec] + optional argument. *) val domain_of_sockaddr: sockaddr -> socket_domain (** Return the socket domain adequate for the given socket address. *) val socketpair : - ?cloexec:bool -> domain:socket_domain -> kind:socket_type -> protocol:int -> + ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + domain:socket_domain -> kind:socket_type -> protocol:int -> file_descr * file_descr -(** Create a pair of unnamed sockets, connected together. *) +(** Create a pair of unnamed sockets, connected together. + See {!set_close_on_exec} for documentation on the [cloexec] + optional argument. *) -val accept : ?cloexec:bool -> file_descr -> file_descr * sockaddr +val accept : ?cloexec: (* thwart tools/sync_stdlib_docs *) bool -> + file_descr -> file_descr * sockaddr (** Accept connections on the given socket. The returned descriptor is a socket connected to the client; the returned address is - the address of the connecting client. *) + the address of the connecting client. + See {!set_close_on_exec} for documentation on the [cloexec] + optional argument. *) val bind : file_descr -> addr:sockaddr -> unit (** Bind a socket to an address. *) @@ -1132,8 +1462,7 @@ type msg_flag = Unix.msg_flag = MSG_OOB | MSG_DONTROUTE | MSG_PEEK (**) -(** The flags for {!UnixLabels.recv}, {!UnixLabels.recvfrom}, - {!UnixLabels.send} and {!UnixLabels.sendto}. *) +(** The flags for {!recv}, {!recvfrom}, {!send} and {!sendto}. *) val recv : file_descr -> buf:bytes -> pos:int -> len:int -> mode:msg_flag list -> int @@ -1171,7 +1500,7 @@ val sendto_substring : (** {1 Socket options} *) -type socket_bool_option = +type socket_bool_option = Unix.socket_bool_option = SO_DEBUG (** Record debugging information *) | SO_BROADCAST (** Permit sending of broadcast messages *) | SO_REUSEADDR (** Allow reuse of local addresses for bind *) @@ -1181,34 +1510,35 @@ type socket_bool_option = | SO_ACCEPTCONN (** Report whether socket listening is enabled *) | TCP_NODELAY (** Control the Nagle algorithm for TCP sockets *) | IPV6_ONLY (** Forbid binding an IPv6 socket to an IPv4 address *) -(** The socket options that can be consulted with {!UnixLabels.getsockopt} - and modified with {!UnixLabels.setsockopt}. These options have a boolean + | SO_REUSEPORT (** Allow reuse of address and port bindings *) +(** The socket options that can be consulted with {!getsockopt} + and modified with {!setsockopt}. These options have a boolean ([true]/[false]) value. *) -type socket_int_option = +type socket_int_option = Unix.socket_int_option = SO_SNDBUF (** Size of send buffer *) | SO_RCVBUF (** Size of received buffer *) - | SO_ERROR (** Deprecated. Use {!Unix.getsockopt_error} instead. *) + | SO_ERROR (** Deprecated. Use {!getsockopt_error} instead. *) | SO_TYPE (** Report the socket type *) | SO_RCVLOWAT (** Minimum number of bytes to process for input operations *) | SO_SNDLOWAT (** Minimum number of bytes to process for output operations *) -(** The socket options that can be consulted with {!UnixLabels.getsockopt_int} - and modified with {!UnixLabels.setsockopt_int}. These options have an +(** The socket options that can be consulted with {!getsockopt_int} + and modified with {!setsockopt_int}. These options have an integer value. *) -type socket_optint_option = +type socket_optint_option = Unix.socket_optint_option = SO_LINGER (** Whether to linger on closed connections that have data present, and for how long (in seconds) *) -(** The socket options that can be consulted with {!Unix.getsockopt_optint} - and modified with {!Unix.setsockopt_optint}. These options have a +(** The socket options that can be consulted with {!getsockopt_optint} + and modified with {!setsockopt_optint}. These options have a value of type [int option], with [None] meaning ``disabled''. *) -type socket_float_option = +type socket_float_option = Unix.socket_float_option = SO_RCVTIMEO (** Timeout for input operations *) | SO_SNDTIMEO (** Timeout for output operations *) -(** The socket options that can be consulted with {!UnixLabels.getsockopt_float} - and modified with {!UnixLabels.setsockopt_float}. These options have a +(** The socket options that can be consulted with {!getsockopt_float} + and modified with {!setsockopt_float}. These options have a floating-point value representing a time in seconds. The value 0 means infinite timeout. *) @@ -1220,26 +1550,26 @@ val setsockopt : file_descr -> socket_bool_option -> bool -> unit (** Set or clear a boolean-valued option in the given socket. *) val getsockopt_int : file_descr -> socket_int_option -> int -(** Same as {!Unix.getsockopt} for an integer-valued socket option. *) +(** Same as {!getsockopt} for an integer-valued socket option. *) val setsockopt_int : file_descr -> socket_int_option -> int -> unit -(** Same as {!Unix.setsockopt} for an integer-valued socket option. *) +(** Same as {!setsockopt} for an integer-valued socket option. *) val getsockopt_optint : file_descr -> socket_optint_option -> int option -(** Same as {!Unix.getsockopt} for a socket option whose value is +(** Same as {!getsockopt} for a socket option whose value is an [int option]. *) val setsockopt_optint : file_descr -> socket_optint_option -> int option -> unit -(** Same as {!Unix.setsockopt} for a socket option whose value is +(** Same as {!setsockopt} for a socket option whose value is an [int option]. *) val getsockopt_float : file_descr -> socket_float_option -> float -(** Same as {!Unix.getsockopt} for a socket option whose value is a +(** Same as {!getsockopt} for a socket option whose value is a floating-point number. *) val setsockopt_float : file_descr -> socket_float_option -> float -> unit -(** Same as {!Unix.setsockopt} for a socket option whose value is a +(** Same as {!setsockopt} for a socket option whose value is a floating-point number. *) val getsockopt_error : file_descr -> error option @@ -1256,21 +1586,24 @@ val open_connection : sockaddr -> in_channel * out_channel times to ensure correct synchronization. *) val shutdown_connection : in_channel -> unit -(** ``Shut down'' a connection established with {!UnixLabels.open_connection}; +(** ``Shut down'' a connection established with {!open_connection}; that is, transmit an end-of-file condition to the server reading - on the other side of the connection. *) + on the other side of the connection. This does not fully close the + file descriptor associated with the channel, which you must remember + to free via {!Stdlib.close_in}. *) val establish_server : (in_channel -> out_channel -> unit) -> addr:sockaddr -> unit (** Establish a server on the given address. The function given as first argument is called for each connection with two buffered channels connected to the client. A new process - is created for each connection. The function {!UnixLabels.establish_server} - never returns normally. *) + is created for each connection. The function {!establish_server} + never returns normally. + On Windows: not implemented (use threads). *) -(** {1 Host and protocol databases} *) +(** {1 Host and protocol databases} *) type host_entry = Unix.host_entry = { h_name : string; @@ -1299,39 +1632,39 @@ val gethostname : unit -> string (** Return the name of the local host. *) val gethostbyname : string -> host_entry -(** Find an entry in [hosts] with the given name, or raise - [Not_found]. *) +(** Find an entry in [hosts] with the given name. + @raise Not_found if no such entry exists. *) val gethostbyaddr : inet_addr -> host_entry -(** Find an entry in [hosts] with the given address, or raise - [Not_found]. *) +(** Find an entry in [hosts] with the given address. + @raise Not_found if no such entry exists. *) val getprotobyname : string -> protocol_entry -(** Find an entry in [protocols] with the given name, or raise - [Not_found]. *) +(** Find an entry in [protocols] with the given name. + @raise Not_found if no such entry exists. *) val getprotobynumber : int -> protocol_entry -(** Find an entry in [protocols] with the given protocol number, - or raise [Not_found]. *) +(** Find an entry in [protocols] with the given protocol number. + @raise Not_found if no such entry exists. *) val getservbyname : string -> protocol:string -> service_entry -(** Find an entry in [services] with the given name, or raise - [Not_found]. *) +(** Find an entry in [services] with the given name. + @raise Not_found if no such entry exists. *) val getservbyport : int -> protocol:string -> service_entry -(** Find an entry in [services] with the given service number, - or raise [Not_found]. *) +(** Find an entry in [services] with the given service number. + @raise Not_found if no such entry exists. *) -type addr_info = +type addr_info = Unix.addr_info = { ai_family : socket_domain; (** Socket domain *) ai_socktype : socket_type; (** Socket type *) ai_protocol : int; (** Socket protocol number *) ai_addr : sockaddr; (** Address *) ai_canonname : string (** Canonical host name *) } -(** Address information returned by {!Unix.getaddrinfo}. *) +(** Address information returned by {!getaddrinfo}. *) -type getaddrinfo_option = +type getaddrinfo_option = Unix.getaddrinfo_option = AI_FAMILY of socket_domain (** Impose the given socket domain *) | AI_SOCKTYPE of socket_type (** Impose the given socket type *) | AI_PROTOCOL of int (** Impose the given protocol *) @@ -1340,12 +1673,12 @@ type getaddrinfo_option = | AI_CANONNAME (** Fill the [ai_canonname] field of the result *) | AI_PASSIVE (** Set address to ``any'' address - for use with {!Unix.bind} *) -(** Options to {!Unix.getaddrinfo}. *) + for use with {!bind} *) +(** Options to {!getaddrinfo}. *) val getaddrinfo: string -> string -> getaddrinfo_option list -> addr_info list -(** [getaddrinfo host service opts] returns a list of {!Unix.addr_info} +(** [getaddrinfo host service opts] returns a list of {!addr_info} records describing socket parameters and addresses suitable for communicating with the given host and service. The empty list is returned if the host or service names are unknown, or the constraints @@ -1362,26 +1695,26 @@ val getaddrinfo: to force a particular socket domain (e.g. IPv6 only or IPv4 only) or a particular socket type (e.g. TCP only or UDP only). *) -type name_info = +type name_info = Unix.name_info = { ni_hostname : string; (** Name or IP address of host *) ni_service : string; (** Name of service or port number *) } -(** Host and service information returned by {!Unix.getnameinfo}. *) +(** Host and service information returned by {!getnameinfo}. *) -type getnameinfo_option = +type getnameinfo_option = Unix.getnameinfo_option = NI_NOFQDN (** Do not qualify local host names *) | NI_NUMERICHOST (** Always return host as IP address *) | NI_NAMEREQD (** Fail if host name cannot be determined *) | NI_NUMERICSERV (** Always return service as port number *) | NI_DGRAM (** Consider the service as UDP-based instead of the default TCP *) -(** Options to {!Unix.getnameinfo}. *) +(** Options to {!getnameinfo}. *) val getnameinfo : sockaddr -> getnameinfo_option list -> name_info (** [getnameinfo addr opts] returns the host name and service name corresponding to the socket address [addr]. [opts] is a possibly empty list of options that governs how these names are obtained. - Raise [Not_found] if an error occurs. *) + @raise Not_found if an error occurs. *) (** {1 Terminal interface} *) @@ -1443,7 +1776,9 @@ type terminal_io = Unix.terminal_io = val tcgetattr : file_descr -> terminal_io (** Return the status of the terminal referred to by the given - file descriptor. *) + file descriptor. + + On Windows: not implemented. *) type setattr_when = Unix.setattr_when = TCSANOW @@ -1458,16 +1793,22 @@ val tcsetattr : file_descr -> mode:setattr_when -> terminal_io -> unit or after flushing all input that has been received but not read ([TCSAFLUSH]). [TCSADRAIN] is recommended when changing the output parameters; [TCSAFLUSH], when changing the input - parameters. *) + parameters. + + On Windows: not implemented. *) val tcsendbreak : file_descr -> duration:int -> unit (** Send a break condition on the given file descriptor. The second argument is the duration of the break, in 0.1s units; - 0 means standard duration (0.25s). *) + 0 means standard duration (0.25s). + + On Windows: not implemented. *) val tcdrain : file_descr -> unit (** Waits until all output written on the given file descriptor - has been transmitted. *) + has been transmitted. + + On Windows: not implemented. *) type flush_queue = Unix.flush_queue = TCIFLUSH @@ -1479,7 +1820,9 @@ val tcflush : file_descr -> mode:flush_queue -> unit transmitted, or data received but not yet read, depending on the second argument: [TCIFLUSH] flushes data received but not read, [TCOFLUSH] flushes data written but not transmitted, and - [TCIOFLUSH] flushes both. *) + [TCIOFLUSH] flushes both. + + On Windows: not implemented. *) type flow_action = Unix.flow_action = TCOOFF @@ -1492,8 +1835,12 @@ val tcflow : file_descr -> mode:flow_action -> unit the given file descriptor, depending on the second argument: [TCOOFF] suspends output, [TCOON] restarts output, [TCIOFF] transmits a STOP character to suspend input, - and [TCION] transmits a START character to restart input. *) + and [TCION] transmits a START character to restart input. + + On Windows: not implemented. *) val setsid : unit -> int (** Put the calling process in a new session and detach it from - its controlling terminal. *) + its controlling terminal. + + On Windows: not implemented. *) diff --git a/otherlibs/win32unix/.depend b/otherlibs/win32unix/.depend index 68b0f1b2..70c377d2 100644 --- a/otherlibs/win32unix/.depend +++ b/otherlibs/win32unix/.depend @@ -1,553 +1,3 @@ -accept.$(O): accept.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -bind.$(O): bind.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -channels.$(O): channels.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/io.h ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - unixsupport.h -close.$(O): close.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h \ - ../../runtime/caml/io.h -close_on.$(O): close_on.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -connect.$(O): connect.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/signals.h \ - unixsupport.h socketaddr.h ../../runtime/caml/misc.h -createprocess.$(O): createprocess.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - unixsupport.h ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h -dup.$(O): dup.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -dup2.$(O): dup2.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -errmsg.$(O): errmsg.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - unixsupport.h -envir.$(O): envir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h -getpeername.$(O): getpeername.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -getpid.$(O): getpid.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -getsockname.$(O): getsockname.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -gettimeofday.$(O): gettimeofday.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - unixsupport.h -isatty.$(O): isatty.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h unixsupport.h -link.$(O): link.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/fail.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -listen.$(O): listen.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -lockf.$(O): lockf.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/fail.h unixsupport.h \ - ../../runtime/caml/signals.h -lseek.$(O): lseek.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - unixsupport.h -nonblock.$(O): nonblock.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/signals.h \ - unixsupport.h -mkdir.$(O): mkdir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h ../../runtime/caml/memory.h unixsupport.h -mmap.$(O): mmap.c ../../runtime/caml/alloc.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/bigarray.h ../../runtime/caml/fail.h \ - ../../runtime/caml/io.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/signals.h ../../runtime/caml/sys.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - unixsupport.h -open.$(O): open.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/memory.h unixsupport.h -pipe.$(O): pipe.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/alloc.h unixsupport.h -read.$(O): read.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -readlink.$(O): readlink.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/alloc.h ../../runtime/caml/fail.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -rename.$(O): rename.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h ../../runtime/caml/memory.h unixsupport.h -select.$(O): select.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h \ - ../../runtime/caml/fail.h ../../runtime/caml/signals.h winworker.h \ - unixsupport.h windbug.h winlist.h -sendrecv.$(O): sendrecv.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -shutdown.$(O): shutdown.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -sleep.$(O): sleep.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/signals.h \ - unixsupport.h -socket.$(O): socket.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -sockopt.$(O): sockopt.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -startup.$(O): startup.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl winworker.h unixsupport.h windbug.h -stat.$(O): stat.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/alloc.h ../../runtime/caml/signals.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h \ - ../unix/cst2constr.h -symlink.$(O): symlink.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/alloc.h ../../runtime/caml/fail.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -system.$(O): system.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/alloc.h ../../runtime/caml/signals.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h -times.$(O): times.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - unixsupport.h -truncate.$(O): truncate.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/fail.h ../../runtime/caml/signals.h \ - ../../runtime/caml/io.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -unixsupport.$(O): unixsupport.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/callback.h \ - ../../runtime/caml/alloc.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/fail.h \ - ../../runtime/caml/custom.h unixsupport.h ../unix/cst2constr.h -windir.$(O): windir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/alloc.h ../../runtime/caml/fail.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h -winwait.$(O): winwait.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h unixsupport.h -write.$(O): write.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h -winlist.$(O): winlist.c winlist.h -winworker.$(O): winworker.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h winworker.h unixsupport.h winlist.h \ - windbug.h -windbug.$(O): windbug.c windbug.h -utimes.$(O): utimes.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/mlvalues.h ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -access.$(O): access.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -addrofstr.$(O): addrofstr.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/fail.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -chdir.$(O): chdir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -chmod.$(O): chmod.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -cst2constr.$(O): cst2constr.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/fail.h \ - ../unix/cst2constr.h -cstringv.$(O): cstringv.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h -execv.$(O): execv.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h -execve.$(O): execve.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h -execvp.$(O): execvp.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -exit.$(O): exit.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl unixsupport.h -getaddrinfo.$(O): getaddrinfo.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/misc.h \ - ../../runtime/caml/signals.h unixsupport.h ../unix/cst2constr.h \ - socketaddr.h -getcwd.$(O): getcwd.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h unixsupport.h -gethost.$(O): gethost.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -gethostname.$(O): gethostname.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h -getnameinfo.$(O): getnameinfo.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h ../../runtime/caml/signals.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -getproto.$(O): getproto.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h unixsupport.h -getserv.$(O): getserv.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h unixsupport.h -gmtime.$(O): gmtime.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h ../../runtime/caml/memory.h \ - ../../runtime/caml/domain.h unixsupport.h -mmap_ba.$(O): mmap_ba.c ../../runtime/caml/alloc.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/bigarray.h ../../runtime/caml/custom.h \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h ../../runtime/caml/misc.h -putenv.$(O): putenv.c ../../runtime/caml/fail.h ../../runtime/caml/misc.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/domain_state.tbl \ - ../../runtime/caml/memory.h ../../runtime/caml/gc.h \ - ../../runtime/caml/major_gc.h ../../runtime/caml/freelist.h \ - ../../runtime/caml/minor_gc.h ../../runtime/caml/address_class.h \ - ../../runtime/caml/domain.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/osdeps.h ../../runtime/caml/memory.h unixsupport.h -rmdir.$(O): rmdir.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -socketaddr.$(O): socketaddr.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/memory.h ../../runtime/caml/domain.h unixsupport.h \ - socketaddr.h ../../runtime/caml/misc.h -strofaddr.$(O): strofaddr.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - ../../runtime/caml/fail.h unixsupport.h socketaddr.h \ - ../../runtime/caml/misc.h -time.$(O): time.c ../../runtime/caml/mlvalues.h ../../runtime/caml/config.h \ - ../../runtime/caml/m.h ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/alloc.h \ - unixsupport.h -unlink.$(O): unlink.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/memory.h \ - ../../runtime/caml/gc.h ../../runtime/caml/major_gc.h \ - ../../runtime/caml/freelist.h ../../runtime/caml/minor_gc.h \ - ../../runtime/caml/address_class.h ../../runtime/caml/domain.h \ - ../../runtime/caml/signals.h ../../runtime/caml/osdeps.h \ - ../../runtime/caml/memory.h unixsupport.h -fsync.$(O): fsync.c ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/config.h ../../runtime/caml/m.h \ - ../../runtime/caml/s.h ../../runtime/caml/misc.h \ - ../../runtime/caml/domain_state.h ../../runtime/caml/mlvalues.h \ - ../../runtime/caml/domain_state.tbl ../../runtime/caml/signals.h \ - unixsupport.h unix.cmo : \ unix.cmi unix.cmx : \ diff --git a/otherlibs/win32unix/Makefile b/otherlibs/win32unix/Makefile index 7d5ec984..149b8e93 100644 --- a/otherlibs/win32unix/Makefile +++ b/otherlibs/win32unix/Makefile @@ -22,7 +22,7 @@ WIN_FILES = accept.c bind.c channels.c close.c \ close_on.c connect.c createprocess.c dup.c dup2.c errmsg.c envir.c \ getpeername.c getpid.c getsockname.c gettimeofday.c isatty.c \ link.c listen.c lockf.c lseek.c nonblock.c \ - mkdir.c mmap.c open.c pipe.c read.c readlink.c rename.c \ + mmap.c open.c pipe.c read.c readlink.c rename.c \ select.c sendrecv.c \ shutdown.c sleep.c socket.c sockopt.c startup.c stat.c \ symlink.c system.c times.c truncate.c unixsupport.c windir.c winwait.c \ @@ -30,7 +30,7 @@ WIN_FILES = accept.c bind.c channels.c close.c \ # Files from the ../unix directory UNIX_FILES = access.c addrofstr.c chdir.c chmod.c cst2constr.c \ - cstringv.c execv.c execve.c execvp.c \ + cstringv.c execv.c execve.c execvp.c mkdir.c \ exit.c getaddrinfo.c getcwd.c gethost.c gethostname.c \ getnameinfo.c getproto.c \ getserv.c gmtime.c mmap_ba.c putenv.c rmdir.c \ @@ -46,17 +46,15 @@ CAMLOBJS=unix.cmo unixLabels.cmo WIN32_LIBS=$(call SYSLIB,ws2_32) $(call SYSLIB,advapi32) LINKOPTS=$(addprefix -cclib ,$(WIN32_LIBS)) EXTRACAMLFLAGS=-nolabels -EXTRACFLAGS=-I../unix -HEADERS=unixsupport.h socketaddr.h +EXTRACPPFLAGS=-I../unix +HEADERS=unixsupport.h ../unix/socketaddr.h +unixLabels.cmi: \ + EXTRACAMLFLAGS += -pp "$(AWK) -f $(ROOTDIR)/stdlib/expand_module_aliases.awk" include ../Makefile.otherlibs.common -ifeq "$(SYSTEM)" "mingw" -LDOPTS=-ldopt "-link -static-libgcc" $(addprefix -ldopt ,$(WIN32_LIBS)) -else LDOPTS=$(addprefix -ldopt ,$(WIN32_LIBS)) -endif clean:: rm -f $(UNIX_FILES) $(UNIX_CAML_FILES) @@ -65,15 +63,8 @@ $(UNIX_FILES) $(UNIX_CAML_FILES): %: ../unix/% cp ../unix/$* $* .PHONY: depend -ifeq "$(TOOLCHAIN)" "msvc" -depend: - $(error Dependencies cannot be regenerated using the MSVC ports) -else depend: $(ALL_FILES) $(UNIX_CAML_FILES) unix.ml - $(CC) -MM $(OC_CPPFLAGS) -I../unix $(ALL_FILES) \ - | sed -e 's/\.o/.$$(O)/g' > .depend $(CAMLRUN) $(ROOTDIR)/boot/ocamlc -depend -slash $(UNIX_CAML_FILES) \ - unix.ml >> .depend -endif + unix.ml > .depend include .depend diff --git a/otherlibs/win32unix/accept.c b/otherlibs/win32unix/accept.c index 0a15673e..7ee5c23e 100644 --- a/otherlibs/win32unix/accept.c +++ b/otherlibs/win32unix/accept.c @@ -29,7 +29,7 @@ CAMLprim value unix_accept(value cloexec, value sock) socklen_param_type addr_len; DWORD err = 0; - addr_len = sizeof(sock_addr); + addr_len = sizeof(addr); caml_enter_blocking_section(); snew = accept(sconn, &addr.s_gen, &addr_len); if (snew == INVALID_SOCKET) err = WSAGetLastError (); diff --git a/otherlibs/win32unix/getpeername.c b/otherlibs/win32unix/getpeername.c index d022a847..019c5101 100644 --- a/otherlibs/win32unix/getpeername.c +++ b/otherlibs/win32unix/getpeername.c @@ -17,16 +17,14 @@ #include "unixsupport.h" #include "socketaddr.h" -CAMLprim value unix_getpeername(sock) - value sock; +CAMLprim value unix_getpeername(value sock) { int retcode; union sock_addr_union addr; socklen_param_type addr_len; - addr_len = sizeof(sock_addr); - retcode = getpeername(Socket_val(sock), - &addr.s_gen, &addr_len); + addr_len = sizeof(addr); + retcode = getpeername(Socket_val(sock), &addr.s_gen, &addr_len); if (retcode == -1) { win32_maperr(WSAGetLastError()); uerror("getpeername", Nothing); diff --git a/otherlibs/win32unix/getsockname.c b/otherlibs/win32unix/getsockname.c index 6df6adfb..a5828457 100644 --- a/otherlibs/win32unix/getsockname.c +++ b/otherlibs/win32unix/getsockname.c @@ -17,16 +17,14 @@ #include "unixsupport.h" #include "socketaddr.h" -CAMLprim value unix_getsockname(sock) - value sock; +CAMLprim value unix_getsockname(value sock) { int retcode; union sock_addr_union addr; socklen_param_type addr_len; - addr_len = sizeof(sock_addr); - retcode = getsockname(Socket_val(sock), - &addr.s_gen, &addr_len); + addr_len = sizeof(addr); + retcode = getsockname(Socket_val(sock), &addr.s_gen, &addr_len); if (retcode == -1) uerror("getsockname", Nothing); return alloc_sockaddr(&addr, addr_len, -1); } diff --git a/otherlibs/win32unix/gettimeofday.c b/otherlibs/win32unix/gettimeofday.c index 20f62a1f..6e2b56e8 100644 --- a/otherlibs/win32unix/gettimeofday.c +++ b/otherlibs/win32unix/gettimeofday.c @@ -22,7 +22,7 @@ /* Unix epoch as a Windows timestamp in hundreds of ns */ #define epoch_ft 116444736000000000.0; -CAMLprim value unix_gettimeofday(value unit) +double unix_gettimeofday_unboxed(value unit) { FILETIME ft; double tm; @@ -36,5 +36,10 @@ CAMLprim value unix_gettimeofday(value unit) #else tm = *(uint64_t *)&ft - epoch_ft; /* shift to Epoch-relative time */ #endif - return caml_copy_double(tm * 1e-7); /* tm is in 100ns */ + return (tm * 1e-7); /* tm is in 100ns */ +} + +CAMLprim value unix_gettimeofday(value unit) +{ + return caml_copy_double(unix_gettimeofday_unboxed(unit)); } diff --git a/otherlibs/win32unix/mmap.c b/otherlibs/win32unix/mmap.c index da08a19f..1259d8d0 100644 --- a/otherlibs/win32unix/mmap.c +++ b/otherlibs/win32unix/mmap.c @@ -30,8 +30,7 @@ do { win32_maperr(GetLastError()); uerror(func, arg); } while(0) /* Defined in [mmap_ba.c] */ -CAMLextern value -caml_unix_mapped_alloc(int flags, int num_dims, void * data, intnat * dim); +extern value caml_unix_mapped_alloc(int, int, void *, intnat *); #ifndef INVALID_SET_FILE_POINTER #define INVALID_SET_FILE_POINTER (-1) diff --git a/otherlibs/win32unix/sendrecv.c b/otherlibs/win32unix/sendrecv.c index 1daa8e99..c5d04233 100644 --- a/otherlibs/win32unix/sendrecv.c +++ b/otherlibs/win32unix/sendrecv.c @@ -67,7 +67,7 @@ CAMLprim value unix_recvfrom(value sock, value buff, value ofs, value len, Begin_roots2 (buff, adr); numbytes = Long_val(len); if (numbytes > UNIX_BUFFER_SIZE) numbytes = UNIX_BUFFER_SIZE; - addr_len = sizeof(sock_addr); + addr_len = sizeof(addr); caml_enter_blocking_section(); ret = recvfrom(s, iobuf, (int) numbytes, flg, &addr.s_gen, &addr_len); if (ret == -1) err = WSAGetLastError(); diff --git a/otherlibs/win32unix/socketaddr.h b/otherlibs/win32unix/socketaddr.h deleted file mode 100644 index e951bece..00000000 --- a/otherlibs/win32unix/socketaddr.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************/ -/* */ -/* OCaml */ -/* */ -/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ -/* */ -/* Copyright 1996 Institut National de Recherche en Informatique et */ -/* en Automatique. */ -/* */ -/* All rights reserved. This file is distributed under the terms of */ -/* the GNU Lesser General Public License version 2.1, with the */ -/* special exception on linking described in the file LICENSE. */ -/* */ -/**************************************************************************/ - -#ifndef CAML_SOCKETADDR_H -#define CAML_SOCKETADDR_H - -#include "caml/misc.h" - -union sock_addr_union { - struct sockaddr s_gen; - struct sockaddr_in s_inet; -#ifdef HAS_IPV6 - struct sockaddr_in6 s_inet6; -#endif -}; - -extern union sock_addr_union sock_addr; - -#ifdef HAS_SOCKLEN_T -typedef socklen_t socklen_param_type; -#else -typedef int socklen_param_type; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern void get_sockaddr (value mladdr, - union sock_addr_union * addr /*out*/, - socklen_param_type * addr_len /*out*/); -CAMLprim value alloc_sockaddr (union sock_addr_union * addr /*in*/, - socklen_param_type addr_len, int close_on_error); -CAMLprim value alloc_inet_addr (struct in_addr * inaddr); -#define GET_INET_ADDR(v) (*((struct in_addr *) (v))) - -#ifdef HAS_IPV6 -CAMLexport value alloc_inet6_addr (struct in6_addr * inaddr); -#define GET_INET6_ADDR(v) (*((struct in6_addr *) (v))) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* CAML_SOCKETADDR_H */ diff --git a/otherlibs/win32unix/sockopt.c b/otherlibs/win32unix/sockopt.c index 6035556f..63639e00 100644 --- a/otherlibs/win32unix/sockopt.c +++ b/otherlibs/win32unix/sockopt.c @@ -21,6 +21,9 @@ #include "unixsupport.h" #include "socketaddr.h" +#ifndef SO_REUSEPORT +#define SO_REUSEPORT (-1) +#endif #ifndef IPPROTO_IPV6 #define IPPROTO_IPV6 (-1) #endif @@ -52,7 +55,8 @@ static struct socket_option sockopt_bool[] = { { SOL_SOCKET, SO_OOBINLINE }, { SOL_SOCKET, SO_ACCEPTCONN }, { IPPROTO_TCP, TCP_NODELAY }, - { IPPROTO_IPV6, IPV6_V6ONLY} + { IPPROTO_IPV6, IPV6_V6ONLY}, + { SOL_SOCKET, SO_REUSEPORT } }; static struct socket_option sockopt_int[] = { diff --git a/otherlibs/win32unix/stat.c b/otherlibs/win32unix/stat.c index cafa8e3d..3748c9bc 100644 --- a/otherlibs/win32unix/stat.c +++ b/otherlibs/win32unix/stat.c @@ -30,7 +30,6 @@ #include #include "unixsupport.h" #include "cst2constr.h" -#define _INTEGRAL_MAX_BITS 64 #include #include #include diff --git a/otherlibs/win32unix/symlink.c b/otherlibs/win32unix/symlink.c index 1336ba6c..ce02eb8d 100644 --- a/otherlibs/win32unix/symlink.c +++ b/otherlibs/win32unix/symlink.c @@ -28,15 +28,54 @@ #include #include "unixsupport.h" +#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE +#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x2) +#endif + typedef BOOLEAN (WINAPI *LPFN_CREATESYMBOLICLINK) (LPWSTR, LPWSTR, DWORD); static LPFN_CREATESYMBOLICLINK pCreateSymbolicLink = NULL; static int no_symlink = 0; +static DWORD additional_symlink_flags = 0; + +// Developer Mode allows the creation of symlinks without elevation - see +// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createsymboliclinkw +static BOOL IsDeveloperModeEnabled() +{ + HKEY hKey; + LSTATUS status; + DWORD developerModeRegistryValue, dwordSize = sizeof(DWORD); + + status = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock", + 0, + KEY_READ | KEY_WOW64_64KEY, + &hKey + ); + if (status != ERROR_SUCCESS) { + return FALSE; + } + + status = RegQueryValueExW( + hKey, + L"AllowDevelopmentWithoutDevLicense", + NULL, + NULL, + (LPBYTE)&developerModeRegistryValue, + &dwordSize + ); + RegCloseKey(hKey); + if (status != ERROR_SUCCESS) { + return FALSE; + } + return developerModeRegistryValue != 0; +} CAMLprim value unix_symlink(value to_dir, value osource, value odest) { CAMLparam3(to_dir, osource, odest); - DWORD flags = (Bool_val(to_dir) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0); + DWORD flags; BOOLEAN result; LPWSTR source; LPWSTR dest; @@ -49,11 +88,17 @@ again: } if (!pCreateSymbolicLink) { - pCreateSymbolicLink = (LPFN_CREATESYMBOLICLINK)GetProcAddress(GetModuleHandle(L"kernel32"), "CreateSymbolicLinkW"); - no_symlink = !pCreateSymbolicLink; + if (!(pCreateSymbolicLink = (LPFN_CREATESYMBOLICLINK)GetProcAddress(GetModuleHandle(L"kernel32"), "CreateSymbolicLinkW"))) { + no_symlink = 1; + } else if (IsDeveloperModeEnabled()) { + additional_symlink_flags = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; + } + goto again; } + flags = (Bool_val(to_dir) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) | additional_symlink_flags; + /* Copy source and dest outside the OCaml heap */ source = caml_stat_strdup_to_utf16(String_val(osource)); dest = caml_stat_strdup_to_utf16(String_val(odest)); @@ -81,6 +126,10 @@ CAMLprim value unix_has_symlink(value unit) HANDLE hProcess = GetCurrentProcess(); BOOL result = FALSE; + if (IsDeveloperModeEnabled()) { + CAMLreturn(Val_true); + } + if (OpenProcessToken(hProcess, TOKEN_READ, &hProcess)) { LUID seCreateSymbolicLinkPrivilege; diff --git a/otherlibs/win32unix/unix.ml b/otherlibs/win32unix/unix.ml index 8d986544..bfa396bb 100644 --- a/otherlibs/win32unix/unix.ml +++ b/otherlibs/win32unix/unix.ml @@ -241,6 +241,7 @@ let execvpe prog args env = external waitpid : wait_flag list -> int -> int * process_status = "win_waitpid" +external _exit : int -> 'a = "unix_exit" external getpid : unit -> int = "unix_getpid" let fork () = invalid_arg "Unix.fork not implemented" @@ -566,8 +567,10 @@ type tm = tm_yday : int; tm_isdst : bool } -external time : unit -> float = "unix_time" -external gettimeofday : unit -> float = "unix_gettimeofday" +external time : unit -> (float [@unboxed]) = + "unix_time" "unix_time_unboxed" [@@noalloc] +external gettimeofday : unit -> (float [@unboxed]) = + "unix_gettimeofday" "unix_gettimeofday_unboxed" [@@noalloc] external gmtime : float -> tm = "unix_gmtime" external localtime : float -> tm = "unix_localtime" external mktime : tm -> float * tm = "unix_mktime" @@ -733,6 +736,7 @@ type socket_bool_option = | SO_ACCEPTCONN | TCP_NODELAY | IPV6_ONLY + | SO_REUSEPORT type socket_int_option = SO_SNDBUF diff --git a/otherlibs/win32unix/unixsupport.c b/otherlibs/win32unix/unixsupport.c index c6005bfc..50d27ab3 100644 --- a/otherlibs/win32unix/unixsupport.c +++ b/otherlibs/win32unix/unixsupport.c @@ -141,6 +141,7 @@ static struct error_entry win_error_table[] = { { ERROR_WRITE_PROTECT, ERROR_SHARING_BUFFER_EXCEEDED - ERROR_WRITE_PROTECT, EACCES }, + { ERROR_PRIVILEGE_NOT_HELD, 0, EPERM}, { WSAEINVAL, 0, EINVAL }, { WSAEACCES, 0, EACCES }, { WSAEBADF, 0, EBADF }, diff --git a/otherlibs/win32unix/utimes.c b/otherlibs/win32unix/utimes.c index cf448c2a..548a07c3 100644 --- a/otherlibs/win32unix/utimes.c +++ b/otherlibs/win32unix/utimes.c @@ -56,7 +56,7 @@ CAMLprim value unix_utimes(value path, value atime, value mtime) FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - 0, + FILE_FLAG_BACKUP_SEMANTICS, NULL); caml_leave_blocking_section(); caml_stat_free(wpath); diff --git a/parsing/ast_helper.mli b/parsing/ast_helper.mli index 330f68ee..8182e5dd 100644 --- a/parsing/ast_helper.mli +++ b/parsing/ast_helper.mli @@ -204,7 +204,7 @@ module Val: module Type: sig val mk: ?loc:loc -> ?attrs:attrs -> ?docs:docs -> ?text:text -> - ?params:(core_type * variance) list -> + ?params:(core_type * (variance * injectivity)) list -> ?cstrs:(core_type * core_type * loc) list -> ?kind:type_kind -> ?priv:private_flag -> ?manifest:core_type -> str -> type_declaration @@ -220,8 +220,8 @@ module Type: module Te: sig val mk: ?loc:loc -> ?attrs:attrs -> ?docs:docs -> - ?params:(core_type * variance) list -> ?priv:private_flag -> - lid -> extension_constructor list -> type_extension + ?params:(core_type * (variance * injectivity)) list -> + ?priv:private_flag -> lid -> extension_constructor list -> type_extension val mk_exception: ?loc:loc -> ?attrs:attrs -> ?docs:docs -> extension_constructor -> type_exception @@ -454,7 +454,8 @@ module Cf: module Ci: sig val mk: ?loc:loc -> ?attrs:attrs -> ?docs:docs -> ?text:text -> - ?virt:virtual_flag -> ?params:(core_type * variance) list -> + ?virt:virtual_flag -> + ?params:(core_type * (variance * injectivity)) list -> str -> 'a -> 'a class_infos end diff --git a/parsing/asttypes.mli b/parsing/asttypes.mli index 353d7776..f4745fb7 100644 --- a/parsing/asttypes.mli +++ b/parsing/asttypes.mli @@ -60,4 +60,8 @@ type 'a loc = 'a Location.loc = { type variance = | Covariant | Contravariant - | Invariant + | NoVariance + +type injectivity = + | Injective + | NoInjectivity diff --git a/parsing/docstrings.ml b/parsing/docstrings.ml index 987365aa..a39f75d2 100644 --- a/parsing/docstrings.ml +++ b/parsing/docstrings.ml @@ -44,18 +44,18 @@ let docstrings : docstring list ref = ref [] (* Warn for unused and ambiguous docstrings *) let warn_bad_docstrings () = - if Warnings.is_active (Warnings.Bad_docstring true) then begin + if Warnings.is_active (Warnings.Unexpected_docstring true) then begin List.iter (fun ds -> match ds.ds_attached with | Info -> () | Unattached -> - prerr_warning ds.ds_loc (Warnings.Bad_docstring true) + prerr_warning ds.ds_loc (Warnings.Unexpected_docstring true) | Docs -> match ds.ds_associated with | Zero | One -> () | Many -> - prerr_warning ds.ds_loc (Warnings.Bad_docstring false)) + prerr_warning ds.ds_loc (Warnings.Unexpected_docstring false)) (List.rev !docstrings) end diff --git a/parsing/lexer.mll b/parsing/lexer.mll index 6d68b59e..95339044 100644 --- a/parsing/lexer.mll +++ b/parsing/lexer.mll @@ -331,10 +331,14 @@ let lowercase_latin1 = ['a'-'z' '\223'-'\246' '\248'-'\255' '_'] let uppercase_latin1 = ['A'-'Z' '\192'-'\214' '\216'-'\222'] let identchar_latin1 = ['A'-'Z' 'a'-'z' '_' '\192'-'\214' '\216'-'\246' '\248'-'\255' '\'' '0'-'9'] +(* This should be kept in sync with the [is_identchar] function in [env.ml] *) + let symbolchar = ['!' '$' '%' '&' '*' '+' '-' '.' '/' ':' '<' '=' '>' '?' '@' '^' '|' '~'] let dotsymbolchar = ['!' '$' '%' '&' '*' '+' '-' '/' ':' '=' '>' '?' '@' '^' '|'] +let symbolchar_or_hash = + symbolchar | '#' let kwdopchar = ['$' '&' '*' '+' '-' '/' '<' '=' '>' '@' '^' '|'] @@ -547,9 +551,9 @@ rule token = parse | "-" { MINUS } | "-." { MINUSDOT } - | "!" symbolchar + as op + | "!" symbolchar_or_hash + as op { PREFIXOP op } - | ['~' '?'] symbolchar + as op + | ['~' '?'] symbolchar_or_hash + as op { PREFIXOP op } | ['=' '<' '>' '|' '&' '$'] symbolchar * as op { INFIXOP0 op } @@ -562,7 +566,7 @@ rule token = parse | '%' { PERCENT } | ['*' '/' '%'] symbolchar * as op { INFIXOP3 op } - | '#' (symbolchar | '#') + as op + | '#' symbolchar_or_hash + as op { HASHOP op } | "let" kwdopchar dotsymbolchar * as op { LETOP op } diff --git a/parsing/location.ml b/parsing/location.ml index aa596c85..fa31feaf 100644 --- a/parsing/location.ml +++ b/parsing/location.ml @@ -294,19 +294,19 @@ struct List.exists (fun ((_, s), (_, e)) -> s <= pos && pos <= e) iset let find_bound_in iset ~range:(start, end_) = - Misc.Stdlib.List.find_map (fun ((a, x), (b, y)) -> + List.find_map (fun ((a, x), (b, y)) -> if start <= x && x <= end_ then Some (a, x) else if start <= y && y <= end_ then Some (b, y) else None ) iset let is_start iset ~pos = - Misc.Stdlib.List.find_map (fun ((a, x), _) -> + List.find_map (fun ((a, x), _) -> if pos = x then Some a else None ) iset let is_end iset ~pos = - Misc.Stdlib.List.find_map (fun (_, (b, y)) -> + List.find_map (fun (_, (b, y)) -> if pos = y then Some b else None ) iset diff --git a/parsing/parse.mli b/parsing/parse.mli index 699e6bad..8669a4b6 100644 --- a/parsing/parse.mli +++ b/parsing/parse.mli @@ -32,7 +32,7 @@ val pattern : Lexing.lexbuf -> Parsetree.pattern val longident: Lexing.lexbuf -> Longident.t (** - The function [longident] is guaranted to parse all subclasses + The function [longident] is guaranteed to parse all subclasses of {!Longident.t} used in OCaml: values, constructors, simple or extended module paths, and types or module types. diff --git a/parsing/parser.mly b/parsing/parser.mly index 12e18186..1fe25c8d 100644 --- a/parsing/parser.mly +++ b/parsing/parser.mly @@ -39,7 +39,7 @@ let ghost_loc (startpos, endpos) = { Location.loc_ghost = true; } -let mktyp ~loc d = Typ.mk ~loc:(make_loc loc) d +let mktyp ~loc ?attrs d = Typ.mk ~loc:(make_loc loc) ?attrs d let mkpat ~loc d = Pat.mk ~loc:(make_loc loc) d let mkexp ~loc d = Exp.mk ~loc:(make_loc loc) d let mkmty ~loc ?attrs d = Mty.mk ~loc:(make_loc loc) ?attrs d @@ -211,7 +211,7 @@ let mkexp_opt_constraint ~loc e = function let mkpat_opt_constraint ~loc p = function | None -> p - | Some typ -> mkpat ~loc (Ppat_constraint(p, typ)) + | Some typ -> ghpat ~loc (Ppat_constraint(p, typ)) let syntax_error () = raise Syntaxerr.Escape_error @@ -236,9 +236,7 @@ let bracket = "[", "]" let lident x = Lident x let ldot x y = Ldot(x,y) let dotop_fun ~loc dotop = - (* We could use ghexp here, but sticking to mkexp for parser.mly - compatibility. TODO improve parser.mly *) - mkexp ~loc (Pexp_ident (ghloc ~loc dotop)) + ghexp ~loc (Pexp_ident (ghloc ~loc dotop)) let array_function ~loc str name = ghloc ~loc (Ldot(Lident str, @@ -336,24 +334,27 @@ let lapply ~loc p1 p2 = else raise (Syntaxerr.Error( Syntaxerr.Applicative_path (make_loc loc))) -let exp_of_longident ~loc lid = - mkexp ~loc (Pexp_ident {lid with txt = Lident(Longident.last lid.txt)}) - (* [loc_map] could be [Location.map]. *) let loc_map (f : 'a -> 'b) (x : 'a Location.loc) : 'b Location.loc = { x with txt = f x.txt } +let make_ghost x = { x with loc = { x.loc with loc_ghost = true }} + let loc_last (id : Longident.t Location.loc) : string Location.loc = loc_map Longident.last id let loc_lident (id : string Location.loc) : Longident.t Location.loc = loc_map (fun x -> Lident x) id +let exp_of_longident ~loc lid = + let lid = make_ghost (loc_map (fun id -> Lident (Longident.last id)) lid) in + ghexp ~loc (Pexp_ident lid) + let exp_of_label ~loc lbl = mkexp ~loc (Pexp_ident (loc_lident lbl)) -let pat_of_label ~loc lbl = - mkpat ~loc (Ppat_var (loc_last lbl)) +let pat_of_label lbl = + Pat.mk ~loc:lbl.loc (Ppat_var (loc_last lbl)) let mk_newtypes ~loc newtypes exp = let mkexp = mkexp ~loc in @@ -427,7 +428,8 @@ let text_str pos = Str.text (rhs_text pos) let text_sig pos = Sig.text (rhs_text pos) let text_cstr pos = Cf.text (rhs_text pos) let text_csig pos = Ctf.text (rhs_text pos) -let text_def pos = [Ptop_def (Str.text (rhs_text pos))] +let text_def pos = + List.map (fun def -> Ptop_def [def]) (Str.text (rhs_text pos)) let extra_text startpos endpos text items = match items with @@ -445,7 +447,9 @@ let extra_sig p1 p2 items = extra_text p1 p2 Sig.text items let extra_cstr p1 p2 items = extra_text p1 p2 Cf.text items let extra_csig p1 p2 items = extra_text p1 p2 Ctf.text items let extra_def p1 p2 items = - extra_text p1 p2 (fun txt -> [Ptop_def (Str.text txt)]) items + extra_text p1 p2 + (fun txt -> List.map (fun def -> Ptop_def [def]) (Str.text txt)) + items let extra_rhs_core_type ct ~pos = let docs = rhs_info pos in @@ -555,9 +559,9 @@ let package_type_of_module_type pmty = err pmty.pmty_loc "only 'with type t =' constraints are supported" in match pmty with - | {pmty_desc = Pmty_ident lid} -> (lid, []) + | {pmty_desc = Pmty_ident lid} -> (lid, [], pmty.pmty_attributes) | {pmty_desc = Pmty_with({pmty_desc = Pmty_ident lid}, cstrs)} -> - (lid, List.map map_cstr cstrs) + (lid, List.map map_cstr cstrs, pmty.pmty_attributes) | _ -> err pmty.pmty_loc "only module type identifier and 'with type' constraints are supported" @@ -1183,10 +1187,10 @@ parse_any_longident: functor_arg: (* An anonymous and untyped argument. *) LPAREN RPAREN - { Unit } + { $startpos, Unit } | (* An argument accompanied with an explicit type. *) LPAREN x = mkrhs(module_name) COLON mty = module_type RPAREN - { Named (x, mty) } + { $startpos, Named (x, mty) } ; module_name: @@ -1214,8 +1218,8 @@ module_expr: { unclosed "struct" $loc($1) "end" $loc($4) } | FUNCTOR attrs = attributes args = functor_args MINUSGREATER me = module_expr { wrap_mod_attrs ~loc:$sloc attrs ( - List.fold_left (fun acc arg -> - mkmod ~loc:$sloc (Pmod_functor (arg, acc)) + List.fold_left (fun acc (startpos, arg) -> + mkmod ~loc:(startpos, $endpos) (Pmod_functor (arg, acc)) ) me args ) } | me = paren_module_expr @@ -1374,8 +1378,9 @@ module_binding_body: | mkmod( COLON mty = module_type EQUAL me = module_expr { Pmod_constraint(me, mty) } - | arg = functor_arg body = module_binding_body - { Pmod_functor(arg, body) } + | arg_and_pos = functor_arg body = module_binding_body + { let (_, arg) = arg_and_pos in + Pmod_functor(arg, body) } ) { $1 } ; @@ -1508,8 +1513,8 @@ module_type: MINUSGREATER mty = module_type %prec below_WITH { wrap_mty_attrs ~loc:$sloc attrs ( - List.fold_left (fun acc arg -> - mkmty ~loc:$sloc (Pmty_functor (arg, acc)) + List.fold_left (fun acc (startpos, arg) -> + mkmty ~loc:(startpos, $endpos) (Pmty_functor (arg, acc)) ) mty args ) } | MODULE TYPE OF attributes module_expr %prec below_LBRACKETAT @@ -1615,8 +1620,9 @@ module_declaration_body: COLON mty = module_type { mty } | mkmty( - arg = functor_arg body = module_declaration_body - { Pmty_functor(arg, body) } + arg_and_pos = functor_arg body = module_declaration_body + { let (_, arg) = arg_and_pos in + Pmty_functor(arg, body) } ) { $1 } ; @@ -1765,7 +1771,7 @@ class_expr: | let_bindings(no_ext) IN class_expr { class_of_let_bindings ~loc:$sloc $1 $3 } | LET OPEN override_flag attributes mkrhs(mod_longident) IN class_expr - { let loc = ($startpos($2), $endpos($4)) in + { let loc = ($startpos($2), $endpos($5)) in let od = Opn.mk ~override:$3 ~loc:(make_loc loc) $5 in mkclass ~loc:$sloc ~attrs:$4 (Pcl_open(od, $7)) } | class_expr attribute @@ -1919,7 +1925,7 @@ class_signature: | class_signature attribute { Cty.attr $1 $2 } | LET OPEN override_flag attributes mkrhs(mod_longident) IN class_signature - { let loc = ($startpos($2), $endpos($4)) in + { let loc = ($startpos($2), $endpos($5)) in let od = Opn.mk ~override:$3 ~loc:(make_loc loc) $5 in mkcty ~loc:$sloc ~attrs:$4 (Pcty_open(od, $7)) } ; @@ -2338,8 +2344,7 @@ simple_expr: | extension { Pexp_extension $1 } | od=open_dot_declaration DOT mkrhs(LPAREN RPAREN {Lident "()"}) - { (* TODO: review the location of Pexp_construct *) - Pexp_open(od, mkexp ~loc:$sloc (Pexp_construct($3, None))) } + { Pexp_open(od, mkexp ~loc:($loc($3)) (Pexp_construct($3, None))) } | mod_longident DOT LPAREN seq_expr error { unclosed "(" $loc($3) ")" $loc($5) } | LBRACE record_expr_content RBRACE @@ -2349,8 +2354,8 @@ simple_expr: { unclosed "{" $loc($1) "}" $loc($3) } | od=open_dot_declaration DOT LBRACE record_expr_content RBRACE { let (exten, fields) = $4 in - (* TODO: review the location of Pexp_construct *) - Pexp_open(od, mkexp ~loc:$sloc (Pexp_record(fields, exten))) } + Pexp_open(od, mkexp ~loc:($startpos($3), $endpos) + (Pexp_record(fields, exten))) } | mod_longident DOT LBRACE record_expr_content error { unclosed "{" $loc($3) "}" $loc($5) } | LBRACKETBAR expr_semi_list BARRBRACKET @@ -2360,11 +2365,10 @@ simple_expr: | LBRACKETBAR BARRBRACKET { Pexp_array [] } | od=open_dot_declaration DOT LBRACKETBAR expr_semi_list BARRBRACKET - { (* TODO: review the location of Pexp_array *) - Pexp_open(od, mkexp ~loc:$sloc (Pexp_array($4))) } + { Pexp_open(od, mkexp ~loc:($startpos($3), $endpos) (Pexp_array($4))) } | od=open_dot_declaration DOT LBRACKETBAR BARRBRACKET { (* TODO: review the location of Pexp_array *) - Pexp_open(od, mkexp ~loc:$sloc (Pexp_array [])) } + Pexp_open(od, mkexp ~loc:($startpos($3), $endpos) (Pexp_array [])) } | mod_longident DOT LBRACKETBAR expr_semi_list error { unclosed "[|" $loc($3) "|]" $loc($5) } @@ -2376,19 +2380,17 @@ simple_expr: { let list_exp = (* TODO: review the location of list_exp *) let tail_exp, _tail_loc = mktailexp $loc($5) $4 in - mkexp ~loc:$sloc tail_exp in + mkexp ~loc:($startpos($3), $endpos) tail_exp in Pexp_open(od, list_exp) } | od=open_dot_declaration DOT mkrhs(LBRACKET RBRACKET {Lident "[]"}) - { (* TODO: review the location of Pexp_construct *) - Pexp_open(od, mkexp ~loc:$sloc (Pexp_construct($3, None))) } + { Pexp_open(od, mkexp ~loc:$loc($3) (Pexp_construct($3, None))) } | mod_longident DOT LBRACKET expr_semi_list error { unclosed "[" $loc($3) "]" $loc($5) } | od=open_dot_declaration DOT LPAREN MODULE ext_attributes module_expr COLON package_type RPAREN - { (* TODO: review the location of Pexp_constraint *) - let modexp = - mkexp_attrs ~loc:$sloc + { let modexp = + mkexp_attrs ~loc:($startpos($3), $endpos) (Pexp_constraint (ghexp ~loc:$sloc (Pexp_pack $6), $8)) $5 in Pexp_open(od, modexp) } | mod_longident DOT @@ -2677,7 +2679,7 @@ simple_pattern_not_ident: { mkpat_attrs ~loc:$sloc (Ppat_unpack $4) $3 } | LPAREN MODULE ext_attributes mkrhs(module_name) COLON package_type RPAREN { mkpat_attrs ~loc:$sloc - (Ppat_constraint(mkpat ~loc:$sloc (Ppat_unpack $4), $6)) + (Ppat_constraint(mkpat ~loc:$loc($4) (Ppat_unpack $4), $6)) $3 } | mkpat(simple_pattern_not_ident_) { $1 } @@ -2762,13 +2764,16 @@ pattern_comma_list(self): label = mkrhs(label_longident) octy = preceded(COLON, core_type)? opat = preceded(EQUAL, pattern)? - { let pat = + { let label, pat = match opat with | None -> - (* No pattern; this is a pun. Desugar it. *) - pat_of_label ~loc:$sloc label + (* No pattern; this is a pun. Desugar it. + But that the pattern was there and the label reconstructed (which + piece of AST is marked as ghost is important for warning + emission). *) + make_ghost label, pat_of_label label | Some pat -> - pat + label, pat in label, mkpat_opt_constraint ~loc:$sloc pat octy } @@ -2942,9 +2947,20 @@ type_variable: ; type_variance: - /* empty */ { Invariant } - | PLUS { Covariant } - | MINUS { Contravariant } + /* empty */ { NoVariance, NoInjectivity } + | PLUS { Covariant, NoInjectivity } + | MINUS { Contravariant, NoInjectivity } + | BANG { NoVariance, Injective } + | PLUS BANG | BANG PLUS { Covariant, Injective } + | MINUS BANG | BANG MINUS { Contravariant, Injective } + | INFIXOP2 + { if $1 = "+!" then Covariant, Injective else + if $1 = "-!" then Contravariant, Injective else + expecting $loc($1) "type_variance" } + | PREFIXOP + { if $1 = "!+" then Covariant, Injective else + if $1 = "!-" then Contravariant, Injective else + expecting $loc($1) "type_variance" } ; (* A sequence of constructor declarations is either a single BAR, which @@ -3008,7 +3024,7 @@ sig_exception_declaration: attrs2 = attributes attrs = post_item_attributes { let args, res = args_res in - let loc = make_loc $sloc in + let loc = make_loc ($startpos, $endpos(attrs2)) in let docs = symbol_docs $sloc in Te.mk_exception ~attrs (Te.decl id ~args ?res ~attrs:(attrs1 @ attrs2) ~loc ~docs) @@ -3315,10 +3331,10 @@ atomic_type: { tys } ; -%inline package_type: - mktyp(module_type - { Ptyp_package (package_type_of_module_type $1) }) - { $1 } +%inline package_type: module_type + { let (lid, cstrs, attrs) = package_type_of_module_type $1 in + let descr = Ptyp_package (lid, cstrs) in + mktyp ~loc:$sloc ~attrs descr } ; %inline row_field_list: separated_nonempty_llist(BAR, row_field) diff --git a/parsing/parsetree.mli b/parsing/parsetree.mli index 0712f87c..58239c87 100644 --- a/parsing/parsetree.mli +++ b/parsing/parsetree.mli @@ -174,7 +174,7 @@ and row_field_desc = (see 4.2 in the manual) *) | Rinherit of core_type - (* [ T ] *) + (* [ | t ] *) and object_field = { pof_desc : object_field_desc; @@ -429,7 +429,7 @@ and value_description = and type_declaration = { ptype_name: string loc; - ptype_params: (core_type * variance) list; + ptype_params: (core_type * (variance * injectivity)) list; (* ('a1,...'an) t; None represents _*) ptype_cstrs: (core_type * core_type * Location.t) list; (* ... constraint T1=T1' ... constraint Tn=Tn' *) @@ -497,7 +497,7 @@ and constructor_arguments = and type_extension = { ptyext_path: Longident.t loc; - ptyext_params: (core_type * variance) list; + ptyext_params: (core_type * (variance * injectivity)) list; ptyext_constructors: extension_constructor list; ptyext_private: private_flag; ptyext_loc: Location.t; @@ -598,7 +598,7 @@ and class_type_field_desc = and 'a class_infos = { pci_virt: virtual_flag; - pci_params: (core_type * variance) list; + pci_params: (core_type * (variance * injectivity)) list; pci_name: string loc; pci_expr: 'a; pci_loc: Location.t; diff --git a/parsing/pprintast.ml b/parsing/pprintast.ml index d731bdff..f2b49de7 100644 --- a/parsing/pprintast.ml +++ b/parsing/pprintast.ml @@ -118,10 +118,14 @@ let override = function (* variance encoding: need to sync up with the [parser.mly] *) let type_variance = function - | Invariant -> "" + | NoVariance -> "" | Covariant -> "+" | Contravariant -> "-" +let type_injectivity = function + | NoInjectivity -> "" + | Injective -> "!" + type construct = [ `cons of expression list | `list of expression list @@ -326,6 +330,9 @@ and core_type1 ctxt f x = | _ -> list ~first:"(" ~last:")@;" (core_type ctxt) ~sep:",@;" f l) l longident_loc li | Ptyp_variant (l, closed, low) -> + let first_is_inherit = match l with + | {Parsetree.prf_desc = Rinherit _}::_ -> true + | _ -> false in let type_variant_helper f x = match x.prf_desc with | Rtag (l, _, ctl) -> @@ -344,7 +351,7 @@ and core_type1 ctxt f x = | _ -> pp f "%s@;%a" (match (closed,low) with - | (Closed,None) -> "" + | (Closed,None) -> if first_is_inherit then " |" else "" | (Closed,Some _) -> "<" (* FIXME desugar the syntax sugar*) | (Open,_) -> ">") (list type_variant_helper ~sep:"@;<1 -2>| ") l) l @@ -390,22 +397,26 @@ and core_type1 ctxt f x = (********************pattern********************) (* be cautious when use [pattern], [pattern1] is preferred *) and pattern ctxt f x = - let rec list_of_pattern acc = function (* only consider ((A|B)|C)*) - | {ppat_desc= Ppat_or (p1,p2); ppat_attributes = []} -> - list_of_pattern (p2::acc) p1 - | x -> x::acc - in if x.ppat_attributes <> [] then begin pp f "((%a)%a)" (pattern ctxt) {x with ppat_attributes=[]} (attributes ctxt) x.ppat_attributes end else match x.ppat_desc with | Ppat_alias (p, s) -> - pp f "@[<2>%a@;as@;%a@]" (pattern ctxt) p protect_ident s.txt (* RA*) - | Ppat_or _ -> (* *) - pp f "@[%a@]" (list ~sep:"@,|" (pattern ctxt)) - (list_of_pattern [] x) - | _ -> pattern1 ctxt f x + pp f "@[<2>%a@;as@;%a@]" (pattern ctxt) p protect_ident s.txt + | _ -> pattern_or ctxt f x + +and pattern_or ctxt f x = + let rec left_associative x acc = match x with + | {ppat_desc=Ppat_or (p1,p2); ppat_attributes = []} -> + left_associative p1 (p2 :: acc) + | x -> x :: acc + in + match left_associative x [] with + | [] -> assert false + | [x] -> pattern1 ctxt f x + | orpats -> + pp f "@[%a@]" (list ~sep:"@ | " (pattern1 ctxt)) orpats and pattern1 ctxt (f:Format.formatter) (x:pattern) : unit = let rec pattern_list_helper f = function @@ -1203,11 +1214,11 @@ and payload ctxt f = function (expression ctxt) e (item_attributes ctxt) attrs | PStr x -> structure ctxt f x - | PTyp x -> pp f ":"; core_type ctxt f x - | PSig x -> pp f ":"; signature ctxt f x - | PPat (x, None) -> pp f "?"; pattern ctxt f x + | PTyp x -> pp f ":@ "; core_type ctxt f x + | PSig x -> pp f ":@ "; signature ctxt f x + | PPat (x, None) -> pp f "?@ "; pattern ctxt f x | PPat (x, Some e) -> - pp f "?"; pattern ctxt f x; + pp f "?@ "; pattern ctxt f x; pp f " when "; expression ctxt f e (* transform [f = fun g h -> ..] to [f g h = ... ] could be improved *) @@ -1251,7 +1262,16 @@ and binding ctxt f {pvb_pat=p; pvb_expr=x; _} = Some (p, pt_tyvars, e_ct, e) else None | _ -> None in if x.pexp_attributes <> [] - then pp f "%a@;=@;%a" (pattern ctxt) p (expression ctxt) x else + then + match p with + | {ppat_desc=Ppat_constraint({ppat_desc=Ppat_var _; _} as pat, + ({ptyp_desc=Ptyp_poly _; _} as typ)); + ppat_attributes=[]; _} -> + pp f "%a@;: %a@;=@;%a" + (simple_pattern ctxt) pat (core_type ctxt) typ (expression ctxt) x + | _ -> + pp f "%a@;=@;%a" (pattern ctxt) p (expression ctxt) x + else match is_desugared_gadt p x with | Some (p, [], ct, e) -> pp f "%a@;: %a@;=@;%a" @@ -1434,8 +1454,8 @@ and structure_item ctxt f x = item_extension ctxt f e; item_attributes ctxt f a -and type_param ctxt f (ct, a) = - pp f "%s%a" (type_variance a) (core_type ctxt) ct +and type_param ctxt f (ct, (a,b)) = + pp f "%s%s%a" (type_variance a) (type_injectivity b) (core_type ctxt) ct and type_params ctxt f = function | [] -> () @@ -1571,9 +1591,9 @@ and extension_constructor ctxt f x = | Pext_decl(l, r) -> constructor_declaration ctxt f (x.pext_name.txt, l, r, x.pext_attributes) | Pext_rebind li -> - pp f "%s%a@;=@;%a" x.pext_name.txt - (attributes ctxt) x.pext_attributes + pp f "%s@;=@;%a%a" x.pext_name.txt longident_loc li + (attributes ctxt) x.pext_attributes and case_list ctxt f l : unit = let aux f {pc_lhs; pc_guard; pc_rhs} = diff --git a/News b/release-info/News similarity index 80% rename from News rename to release-info/News index 79f3f72f..339ad9de 100644 --- a/News +++ b/release-info/News @@ -1,3 +1,68 @@ +OCaml 4.10.0 (21 February 2020) +------------------------------- + +- New best-fit allocator for the major heap +- Preliminary runtime work for OCaml multicore +- Immutable strings are now enforced at configuration time +- User-defined indexing operators for multidimensional arrays +- Coming soon: statmemprof, a new statistical memory profiler. +- The external API will be released next version. +- Various improvements to the manual +- More precise exhaustiveness check for GADTs +- Many bug fixes + + +OCaml 4.09.1 (18 March 2020) +---------------------------- + +Bug fixes. + +OCaml 4.09.0 (18 September 2019) +-------------------------------- + +- New optimisations, in particular for affine functions in matches, + for instance: + + type t = A | B | C + let affine = function + | A -> 4 + | B -> 3 + | C -> 2 + +- The `graphics` library was moved out of the compiler distribution. +- The `vmthread` library was removed. +- Support for compiler plugins was removed. +- Many bug fixes. + +OCaml 4.08.1 (5 August 2019) +---------------------------- + +Bug fixes. + +OCaml 4.08.0 (14 June 2019) +--------------------------- + +- Binding operators (let*, let+, and*, etc). They can be used to + streamline monadic code. + +- `open` now applies to arbitrary module expression in structures and + to applicative paths in signatures. + +- A new notion of (user-defined) "alerts" generalizes the deprecated + warning. + +- New modules in the standard library: Fun, Bool, Int, Option, Result. + +- A significant number of new functions in Float, including FMA + support, and a new Float.Array submodule. + +- Source highlighting for errors and warnings in batch mode. + +- Many error messages were improved. + +- Improved AFL instrumentation for objects and lazy values. + + OCaml 4.07.1 (4 October 2018) ----------------------------- diff --git a/tools/release-checklist b/release-info/howto.md similarity index 82% rename from tools/release-checklist rename to release-info/howto.md index aab3d95d..cbd9da1a 100644 --- a/tools/release-checklist +++ b/release-info/howto.md @@ -23,19 +23,25 @@ OCamlLabs folks (for OPAM testing). ``` rm -f /tmp/env-$USER.sh cat >/tmp/env-$USER.sh < 4.07.0+rc2 # Update ocaml-variants.opam with new version. # Update \year in manual/manual/macros.hva -rm -r autom4te.cache make -B configure +# For a production release make coreboot -j5 make coreboot -j5 # must say "Fixpoint reached, bootstrap succeeded." git commit -m "release $VERSION" -a @@ -126,7 +144,6 @@ git tag -m "release $VERSION" $VERSION # for testing candidates, use N+dev(D+2) instead; for example, # 4.07.0+rc2 => 4.07.0+dev10-2018-06-26 # Revert ocaml-variants.opam to its "trunk" version. -rm -r autom4te.cache make -B configure git commit -m "increment version number after tagging $VERSION" VERSION configure ocaml-variants.opam git push @@ -156,12 +173,12 @@ git commit -m "first commit after branching $VERSION" -a git push # Switch to the new branch -git checkout $VERSION +git checkout $BRANCH # increment VERSION, for instance # 4.07.0+dev1-2018-06-26 => 4.07.0+dev2-2018-06-30 make -B configure -git commit -m "first commit on branch $VERSION" -a -git push $VERSION +git commit -m "first commit on branch $BRANCH" -a +git push --set-upstream origin $BRANCH ``` Adjust github branch settings: @@ -191,6 +208,16 @@ Remove any badge that tracks a version older than Debian stable. ## 6: create OPAM packages +Clone the opam-repository +``` +git clone https://github.com/ocaml/opam-repository +``` + +Create a branch for the new release +``` +git checkout -b OCaml_$VERSION +``` + Create ocaml-variants packages for the new version, copying the particular switch configuration choices from the previous version. @@ -198,6 +225,18 @@ Do not forget to add/update the checksum field for the tarballs in the "url" section of the opam files. Use opam-lint before sending the pull request. +You can test the new opam package before sending a PR to the +main opam-repository by using the local repository: + +``` +opam repo add local /path/to/your/opam-repository +opam switch create --repo=local,beta=git+https://github.com/ocaml/ocaml-beta-repository.git ocaml-variants.$VERSION +``` +The switch should build. + +For a production release, you also need to create new opam files for the ocaml-manual and +ocaml-src packages. + ## 6.1 Update OPAM dev packages after branching Create a new ocaml/ocaml.$NEXT/opam file. @@ -210,6 +249,7 @@ The "src" field should point to src: "https://github.com/ocaml/ocaml/archive/$VERSION.tar.gz" The synopsis should be "latest $VERSION development(,...)". + ## 7: build the release archives ``` @@ -218,12 +258,11 @@ TMPDIR=/tmp/ocaml-release git checkout $VERSION git checkout-index -a -f --prefix=$TMPDIR/ocaml-$VERSION/ cd $TMPDIR -gtar -c --owner 0 --group 0 -f ocaml-$VERSION.tar ocaml-$VERSION +$TAR -c --owner 0 --group 0 -f ocaml-$VERSION.tar ocaml-$VERSION gzip -9 ocaml-$VERSION.tar.gz xz ocaml-$VERSION.tar.xz ``` - ## 8: upload the archives and compute checksums For the first beta of a major version, create the distribution directory on @@ -341,119 +380,29 @@ organize the webpage for the new release. See -## 13: announce the release on caml-list and caml-announce +## 13: announce the release on caml-list, caml-announce, and discuss.ocaml.org -See the email announce templates at the end of this file. +See the email announce templates in the `templates/` directory. # Appendix -## Announcing a production release: +## Announce templates -``` -Dear OCaml users, +See -We have the pleasure of celebrating by announcing the release of -OCaml version $VERSION. -This is mainly a bug-fix release, see the list of changes below. +- templates/beta.md for alpha and beta releases +- templates/rc.md for release candidate +- templates/production.md for the production release -It is (or soon will be) available as a set of OPAM switches, -and as a source download here: - https://caml.inria.fr/pub/distrib/ocaml-$BRANCH/ - -Happy hacking, - --- Damien Doligez for the OCaml team. - -<< insert the relevant Changes section >> -``` - -## Announcing a release candidate: - -``` -Dear OCaml users, - -The release of OCaml version $MAJOR.$MINOR.$BUGFIX is imminent. We have -created a release candidate that you can test. - -The source code is available at these addresses: - - https://github.com/ocaml/ocaml/archive/$VERSION.tar.gz - https://caml.inria.fr/pub/distrib/ocaml-$BRANCH/ocaml-$VERSION.tar.gz - -The compiler can also be installed as an OPAM switch with one of the -following commands. - -opam switch create ocaml-variants.$VERSION --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git - -or - -opam switch create ocaml-variants.$VERSION+ --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git - - where you replace with one of these: - afl - default-unsafe-string - force-safe-string - flambda - fp - fp+flambda - -We want to know about all bugs. Please report them here: - https://github.com/ocaml/ocaml/issues - -Happy hacking, - --- Damien Doligez for the OCaml team. - -<< insert the relevant Changes section >> -``` - -## Announcing a beta version: - -``` -Dear OCaml users, - -The release of OCaml $MAJOR.$MINOR.$BUGFIX is approaching. We have created -a beta version to help you adapt your software to the new features -ahead of the release. - -The source code is available at these addresses: - - https://github.com/ocaml/ocaml/archive/$VERSION.tar.gz - https://caml.inria.fr/pub/distrib/ocaml-$BRANCH/$VERSION.tar.gz - -The compiler can also be installed as an OPAM switch with one of the -following commands. - -opam switch create ocaml-variants.$VERSION --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git - -or - -opam switch create ocaml-variants.$VERSION+ --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git - - where you replace with one of these: - afl - default-unsafe-string - force-safe-string - flambda - fp - fp+flambda - -We want to know about all bugs. Please report them here: - https://github.com/ocaml/ocaml/issues - -Happy hacking, - --- Damien Doligez for the OCaml team. -``` ## Changelog template for a new version A list of common subsection for the "Changes" file: ``` -### Language features +### Language features: ### Runtime system: @@ -508,7 +457,7 @@ Here are typical forms of divergence and their usual solutions: Fix: ensure that the entry is in the same section on all branches, by putting it in the "smallest" version -- assuming that all bigger - versions also contain this cange. + versions also contain this change. - A change entry is present in a given section, but the change is not present in the corresponding release branch. @@ -592,3 +541,8 @@ release don't. Usually "Language features" is among the first, and If some entries feel very anecdotal, consider moving them to the Bug Fixes section. + +### Extract release highlights to News + +From time to time, synchronize the `News` file with the release highlights +of each version. diff --git a/tools/markdown-add-pr-links.sh b/release-info/markdown-add-pr-links.sh similarity index 72% rename from tools/markdown-add-pr-links.sh rename to release-info/markdown-add-pr-links.sh index 3b388006..4b3a37a8 100644 --- a/tools/markdown-add-pr-links.sh +++ b/release-info/markdown-add-pr-links.sh @@ -15,20 +15,16 @@ #* * #************************************************************************** -# This script performs a series of transformation on standard input to +# This script performs a series of transformation on its argument to # turn ASCII references into Markdown-format links: -# - GPR#NNNN links to Github -# - MPR#NNNN and PR#NNNN link to Mantis +# - #NNNN links to Github # - (Changes#VERSION) link to the Changes file +# Breaking change list bullet are converted into annotations # It was only tested with GNU sed. Sorry! GITHUB=https://github.com/ocaml/ocaml -MANTIS=https://caml.inria.fr/mantis -cat \ -| sed "s,GPR#\\([0-9]*\\),[GPR~#~\\1]($GITHUB/pull/\\1),g"\ -| sed "s,MPR#\\([0-9]*\\),[PR~#~\\1]($MANTIS/view.php?id=\\1),g"\ -| sed "s,PR#\\([0-9]*\\),[PR~#~\\1]($MANTIS/view.php?id=\\1),g"\ -| sed "s,(Changes#\\(.*\\)),[Changes file for \\1]($GITHUB/blob/\\1/Changes),g"\ -| sed "s,PR~#~,PR#,g" \ +sed "s,(Changes#\(.*\)),[Changes file for \\1]($GITHUB/blob/\\1/Changes),g" $1 \ +| sed "s,#\([0-9]\+\),[#\\1]($GITHUB/issues/\\1),g" \ +| sed "s/^*/* [*breaking change*]/g" diff --git a/release-info/templates/beta.md b/release-info/templates/beta.md new file mode 100644 index 00000000..03a0c6fc --- /dev/null +++ b/release-info/templates/beta.md @@ -0,0 +1,39 @@ +## Announcing a beta version: + + +``` +Dear OCaml users, + +The release of OCaml $MAJOR.$MINOR.$BUGFIX is approaching. We have created +a beta version to help you adapt your software to the new features +ahead of the release. + +The source code is available at these addresses: + + https://github.com/ocaml/ocaml/archive/$VERSION.tar.gz + https://caml.inria.fr/pub/distrib/ocaml-$BRANCH/ocaml-$VERSION.tar.gz + +The compiler can also be installed as an OPAM switch with one of the +following commands: + +opam update +opam switch create ocaml-variants.$VERSION --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git + +or + +opam update +opam switch create ocaml-variants.$VERSION+ --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git + + where you replace with one of these: + afl + flambda + fp + fp+flambda + +We want to know about all bugs. Please report them here: + https://github.com/ocaml/ocaml/issues + +Happy hacking, + +-- $HUMAN for the OCaml team. +``` diff --git a/release-info/templates/production.md b/release-info/templates/production.md new file mode 100644 index 00000000..b8cf3023 --- /dev/null +++ b/release-info/templates/production.md @@ -0,0 +1,19 @@ +## Announcing a production release: + +``` +Dear OCaml users, + +We have the pleasure of celebrating by announcing the release of +OCaml version $VERSION. +This is mainly a bug-fix release, see the list of changes below. + +It is (or soon will be) available as a set of OPAM switches, +and as a source download here: + https://caml.inria.fr/pub/distrib/ocaml-$BRANCH/ + +Happy hacking, + +-- $HUMAN for the OCaml team. + +<< insert the relevant Changes section >> +``` diff --git a/release-info/templates/rc.md b/release-info/templates/rc.md new file mode 100644 index 00000000..65723998 --- /dev/null +++ b/release-info/templates/rc.md @@ -0,0 +1,40 @@ + +## Announcing a release candidate: + +``` +Dear OCaml users, + +The release of OCaml version $MAJOR.$MINOR.$BUGFIX is imminent. We have +created a release candidate that you can test. + +The source code is available at these addresses: + + https://github.com/ocaml/ocaml/archive/$VERSION.tar.gz + https://caml.inria.fr/pub/distrib/ocaml-$BRANCH/ocaml-$VERSION.tar.gz + +The compiler can also be installed as an OPAM switch with one of the +following commands: + +opam update +opam switch create ocaml-variants.$VERSION --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git + +or + +opam update +opam switch create ocaml-variants.$VERSION+ --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git + + where you replace with one of these: + afl + flambda + fp + fp+flambda + +We want to know about all bugs. Please report them here: + https://github.com/ocaml/ocaml/issues + +Happy hacking, + +-- $HUMAN for the OCaml team. + +<< insert the relevant Changes section >> +``` diff --git a/runtime/.depend b/runtime/.depend deleted file mode 100644 index b56ad7ab..00000000 --- a/runtime/.depend +++ /dev/null @@ -1,2509 +0,0 @@ -interp_b.$(O): interp.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/callback.h caml/debugger.h caml/fail.h \ - caml/fix_code.h caml/instrtrace.h caml/instruct.h caml/interp.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/prims.h caml/signals.h caml/stacks.h caml/memory.h \ - caml/startup_aux.h caml/jumptbl.h -misc_b.$(O): misc.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/memory.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/osdeps.h caml/memory.h \ - caml/version.h -stacks_b.$(O): stacks.c caml/config.h caml/m.h caml/s.h caml/fail.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/misc.h caml/mlvalues.h caml/stacks.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -fix_code_b.$(O): fix_code.c caml/config.h caml/m.h caml/s.h caml/codefrag.h \ - caml/debugger.h caml/misc.h caml/config.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/fix_code.h \ - caml/instruct.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -startup_aux_b.$(O): startup_aux.c caml/backtrace.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/exec.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/callback.h caml/major_gc.h caml/dynlink.h \ - caml/osdeps.h caml/memory.h caml/startup_aux.h caml/memprof.h \ - caml/roots.h -startup_byt_b.$(O): startup_byt.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/callback.h \ - caml/custom.h caml/debugger.h caml/domain.h caml/dynlink.h \ - caml/eventlog.h caml/exec.h caml/fail.h caml/fix_code.h caml/freelist.h \ - caml/gc_ctrl.h caml/instrtrace.h caml/interp.h caml/intext.h caml/io.h \ - caml/io.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h caml/prims.h \ - caml/printexc.h caml/reverse.h caml/signals.h caml/stacks.h caml/sys.h \ - caml/startup.h caml/startup_aux.h caml/version.h -freelist_b.$(O): freelist.c caml/config.h caml/m.h caml/s.h caml/custom.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/major_gc.h caml/misc.h \ - caml/mlvalues.h caml/eventlog.h -major_gc_b.$(O): major_gc.c caml/compact.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/config.h caml/fail.h caml/finalise.h caml/roots.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/freelist.h caml/gc.h \ - caml/gc_ctrl.h caml/major_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/signals.h caml/weak.h caml/memprof.h caml/eventlog.h -minor_gc_b.$(O): minor_gc.c caml/custom.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/memory.h caml/minor_gc.h caml/misc.h \ - caml/mlvalues.h caml/roots.h caml/signals.h caml/weak.h caml/memprof.h \ - caml/eventlog.h -memory_b.$(O): memory.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/signals.h caml/memprof.h caml/roots.h \ - caml/memory.h caml/eventlog.h -alloc_b.$(O): alloc.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/stacks.h caml/memory.h caml/signals.h -roots_byt_b.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/globroots.h caml/major_gc.h caml/memory.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/roots.h caml/stacks.h caml/memprof.h \ - caml/eventlog.h -globroots_b.$(O): globroots.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/globroots.h \ - caml/roots.h caml/skiplist.h -fail_byt_b.$(O): fail_byt.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/fail.h caml/gc.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/printexc.h caml/signals.h \ - caml/stacks.h caml/memory.h -signals_b.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/config.h caml/fail.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/roots.h caml/memory.h \ - caml/signals.h caml/signals_machdep.h caml/sys.h caml/memprof.h \ - caml/roots.h caml/finalise.h -signals_byt_b.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ - caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/fail.h caml/finalise.h caml/roots.h caml/memory.h caml/osdeps.h \ - caml/signals.h caml/signals_machdep.h -printexc_b.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/exec.h caml/callback.h caml/debugger.h caml/fail.h caml/misc.h \ - caml/mlvalues.h caml/printexc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/memprof.h caml/roots.h caml/memory.h -backtrace_byt_b.$(O): backtrace_byt.c caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/mlvalues.h caml/domain_state.tbl caml/alloc.h caml/custom.h \ - caml/io.h caml/instruct.h caml/intext.h caml/io.h caml/exec.h \ - caml/fix_code.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/startup.h \ - caml/exec.h caml/stacks.h caml/memory.h caml/sys.h caml/backtrace.h \ - caml/fail.h caml/backtrace_prim.h caml/backtrace.h caml/debugger.h -backtrace_b.$(O): backtrace.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/backtrace.h caml/exec.h \ - caml/backtrace_prim.h caml/backtrace.h caml/fail.h caml/debugger.h -compare_b.$(O): compare.c caml/custom.h caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h -ints_b.$(O): ints.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/fail.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h -eventlog_b.$(O): eventlog.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/eventlog.h caml/misc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h -floats_b.$(O): floats.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/stacks.h caml/memory.h -str_b.$(O): str.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/mlvalues.h caml/misc.h -array_b.$(O): array.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/mlvalues.h \ - caml/signals.h caml/eventlog.h caml/spacetime.h caml/io.h caml/stack.h -io_b.$(O): io.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/signals.h caml/sys.h -extern_b.$(O): extern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/custom.h caml/fail.h caml/gc.h \ - caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -intern_b.$(O): intern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/codefrag.h caml/config.h caml/custom.h caml/fail.h \ - caml/gc.h caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/memprof.h caml/roots.h caml/memory.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/signals.h -hash_b.$(O): hash.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/custom.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/hash.h -sys_b.$(O): sys.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/debugger.h caml/fail.h caml/gc_ctrl.h caml/io.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/signals.h caml/stacks.h caml/sys.h caml/version.h caml/callback.h \ - caml/startup_aux.h -meta_b.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/codefrag.h \ - caml/config.h caml/debugger.h caml/fail.h caml/fix_code.h caml/interp.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/stacks.h caml/memory.h -parsing_b.$(O): parsing.c caml/config.h caml/m.h caml/s.h caml/mlvalues.h \ - caml/config.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/alloc.h -gc_ctrl_b.$(O): gc_ctrl.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/compact.h caml/custom.h caml/fail.h \ - caml/finalise.h caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h caml/memory.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/signals.h \ - caml/eventlog.h caml/stacks.h caml/startup_aux.h -md5_b.$(O): md5.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/md5.h caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/io.h caml/reverse.h -obj_b.$(O): obj.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/gc.h caml/interp.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/spacetime.h caml/io.h caml/stack.h -lexing_b.$(O): lexing.c caml/fail.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/mlvalues.h caml/stacks.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h -callback_b.$(O): callback.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/interp.h caml/instruct.h caml/fix_code.h \ - caml/stacks.h caml/memory.h -debugger_b.$(O): debugger.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/debugger.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/skiplist.h caml/fail.h \ - caml/fix_code.h caml/instruct.h caml/intext.h caml/io.h caml/io.h \ - caml/mlvalues.h caml/stacks.h caml/sys.h -weak_b.$(O): weak.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/weak.h caml/memory.h caml/minor_gc.h caml/signals.h caml/eventlog.h -compact_b.$(O): compact.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/finalise.h caml/roots.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h \ - caml/memory.h caml/mlvalues.h caml/roots.h caml/weak.h caml/compact.h \ - caml/memprof.h caml/eventlog.h -finalise_b.$(O): finalise.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/compact.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/minor_gc.h caml/mlvalues.h \ - caml/roots.h caml/signals.h -custom_b.$(O): custom.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/gc_ctrl.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/signals.h -dynlink_b.$(O): dynlink.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/dynlink.h caml/fail.h caml/mlvalues.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/prims.h caml/signals.h -spacetime_byt_b.$(O): spacetime_byt.c caml/fail.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/mlvalues.h -afl_b.$(O): afl.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -unix_b.$(O): unix.c caml/config.h caml/m.h caml/s.h caml/fail.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/signals.h caml/sys.h caml/io.h caml/alloc.h -bigarray_b.$(O): bigarray.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/bigarray.h caml/custom.h caml/fail.h caml/intext.h caml/io.h \ - caml/hash.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/signals.h -main_b.$(O): main.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/sys.h caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -memprof_b.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/fail.h \ - caml/alloc.h caml/callback.h caml/signals.h caml/memory.h \ - caml/minor_gc.h caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/weak.h caml/stack.h caml/misc.h caml/compact.h caml/printexc.h \ - caml/eventlog.h -domain_b.$(O): domain.c caml/domain_state.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -skiplist_b.$(O): skiplist.c caml/config.h caml/m.h caml/s.h caml/memory.h \ - caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/skiplist.h -codefrag_b.$(O): codefrag.c caml/codefrag.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/md5.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/skiplist.h -win32_b.$(O): win32.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/address_class.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/sys.h caml/config.h -instrtrace_b.$(O): instrtrace.c -interp_bd.$(O): interp.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/callback.h caml/debugger.h caml/fail.h \ - caml/fix_code.h caml/instrtrace.h caml/instruct.h caml/interp.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/prims.h caml/signals.h caml/stacks.h caml/memory.h \ - caml/startup_aux.h -misc_bd.$(O): misc.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/memory.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/osdeps.h caml/memory.h \ - caml/version.h -stacks_bd.$(O): stacks.c caml/config.h caml/m.h caml/s.h caml/fail.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/misc.h caml/mlvalues.h caml/stacks.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -fix_code_bd.$(O): fix_code.c caml/config.h caml/m.h caml/s.h caml/codefrag.h \ - caml/debugger.h caml/misc.h caml/config.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/fix_code.h \ - caml/instruct.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -startup_aux_bd.$(O): startup_aux.c caml/backtrace.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/exec.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/callback.h caml/major_gc.h caml/dynlink.h \ - caml/osdeps.h caml/memory.h caml/startup_aux.h caml/memprof.h \ - caml/roots.h -startup_byt_bd.$(O): startup_byt.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/callback.h \ - caml/custom.h caml/debugger.h caml/domain.h caml/dynlink.h \ - caml/eventlog.h caml/exec.h caml/fail.h caml/fix_code.h caml/freelist.h \ - caml/gc_ctrl.h caml/instrtrace.h caml/interp.h caml/intext.h caml/io.h \ - caml/io.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h caml/prims.h \ - caml/printexc.h caml/reverse.h caml/signals.h caml/stacks.h caml/sys.h \ - caml/startup.h caml/startup_aux.h caml/version.h -freelist_bd.$(O): freelist.c caml/config.h caml/m.h caml/s.h caml/custom.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/major_gc.h caml/misc.h \ - caml/mlvalues.h caml/eventlog.h -major_gc_bd.$(O): major_gc.c caml/compact.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/config.h caml/fail.h caml/finalise.h caml/roots.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/freelist.h caml/gc.h \ - caml/gc_ctrl.h caml/major_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/signals.h caml/weak.h caml/memprof.h caml/eventlog.h -minor_gc_bd.$(O): minor_gc.c caml/custom.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/memory.h caml/minor_gc.h caml/misc.h \ - caml/mlvalues.h caml/roots.h caml/signals.h caml/weak.h caml/memprof.h \ - caml/eventlog.h -memory_bd.$(O): memory.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/signals.h caml/memprof.h caml/roots.h \ - caml/memory.h caml/eventlog.h -alloc_bd.$(O): alloc.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/stacks.h caml/memory.h caml/signals.h -roots_byt_bd.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/globroots.h caml/major_gc.h caml/memory.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/roots.h caml/stacks.h caml/memprof.h \ - caml/eventlog.h -globroots_bd.$(O): globroots.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/globroots.h \ - caml/roots.h caml/skiplist.h -fail_byt_bd.$(O): fail_byt.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/fail.h caml/gc.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/printexc.h caml/signals.h \ - caml/stacks.h caml/memory.h -signals_bd.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/config.h caml/fail.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/roots.h caml/memory.h \ - caml/signals.h caml/signals_machdep.h caml/sys.h caml/memprof.h \ - caml/roots.h caml/finalise.h -signals_byt_bd.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ - caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/fail.h caml/finalise.h caml/roots.h caml/memory.h caml/osdeps.h \ - caml/signals.h caml/signals_machdep.h -printexc_bd.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/exec.h caml/callback.h caml/debugger.h caml/fail.h caml/misc.h \ - caml/mlvalues.h caml/printexc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/memprof.h caml/roots.h caml/memory.h -backtrace_byt_bd.$(O): backtrace_byt.c caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/mlvalues.h caml/domain_state.tbl caml/alloc.h caml/custom.h \ - caml/io.h caml/instruct.h caml/intext.h caml/io.h caml/exec.h \ - caml/fix_code.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/startup.h \ - caml/exec.h caml/stacks.h caml/memory.h caml/sys.h caml/backtrace.h \ - caml/fail.h caml/backtrace_prim.h caml/backtrace.h caml/debugger.h -backtrace_bd.$(O): backtrace.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/backtrace.h caml/exec.h \ - caml/backtrace_prim.h caml/backtrace.h caml/fail.h caml/debugger.h -compare_bd.$(O): compare.c caml/custom.h caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h -ints_bd.$(O): ints.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/fail.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h -eventlog_bd.$(O): eventlog.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/eventlog.h caml/misc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h -floats_bd.$(O): floats.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/stacks.h caml/memory.h -str_bd.$(O): str.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/mlvalues.h caml/misc.h -array_bd.$(O): array.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/mlvalues.h \ - caml/signals.h caml/eventlog.h caml/spacetime.h caml/io.h caml/stack.h -io_bd.$(O): io.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/signals.h caml/sys.h -extern_bd.$(O): extern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/custom.h caml/fail.h caml/gc.h \ - caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -intern_bd.$(O): intern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/codefrag.h caml/config.h caml/custom.h caml/fail.h \ - caml/gc.h caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/memprof.h caml/roots.h caml/memory.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/signals.h -hash_bd.$(O): hash.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/custom.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/hash.h -sys_bd.$(O): sys.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/debugger.h caml/fail.h caml/gc_ctrl.h caml/io.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/signals.h caml/stacks.h caml/sys.h caml/version.h caml/callback.h \ - caml/startup_aux.h -meta_bd.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/codefrag.h \ - caml/config.h caml/debugger.h caml/fail.h caml/fix_code.h caml/interp.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/stacks.h caml/memory.h -parsing_bd.$(O): parsing.c caml/config.h caml/m.h caml/s.h caml/mlvalues.h \ - caml/config.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/alloc.h -gc_ctrl_bd.$(O): gc_ctrl.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/compact.h caml/custom.h caml/fail.h \ - caml/finalise.h caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h caml/memory.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/signals.h \ - caml/eventlog.h caml/stacks.h caml/startup_aux.h -md5_bd.$(O): md5.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/md5.h caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/io.h caml/reverse.h -obj_bd.$(O): obj.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/gc.h caml/interp.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/spacetime.h caml/io.h caml/stack.h -lexing_bd.$(O): lexing.c caml/fail.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/mlvalues.h caml/stacks.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h -callback_bd.$(O): callback.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/interp.h caml/instruct.h caml/fix_code.h \ - caml/stacks.h caml/memory.h -debugger_bd.$(O): debugger.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/debugger.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/skiplist.h caml/fail.h \ - caml/fix_code.h caml/instruct.h caml/intext.h caml/io.h caml/io.h \ - caml/mlvalues.h caml/stacks.h caml/sys.h -weak_bd.$(O): weak.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/weak.h caml/memory.h caml/minor_gc.h caml/signals.h caml/eventlog.h -compact_bd.$(O): compact.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/finalise.h caml/roots.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h \ - caml/memory.h caml/mlvalues.h caml/roots.h caml/weak.h caml/compact.h \ - caml/memprof.h caml/eventlog.h -finalise_bd.$(O): finalise.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/compact.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/minor_gc.h caml/mlvalues.h \ - caml/roots.h caml/signals.h -custom_bd.$(O): custom.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/gc_ctrl.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/signals.h -dynlink_bd.$(O): dynlink.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/dynlink.h caml/fail.h caml/mlvalues.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/prims.h caml/signals.h -spacetime_byt_bd.$(O): spacetime_byt.c caml/fail.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/mlvalues.h -afl_bd.$(O): afl.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -unix_bd.$(O): unix.c caml/config.h caml/m.h caml/s.h caml/fail.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/signals.h caml/sys.h caml/io.h caml/alloc.h -bigarray_bd.$(O): bigarray.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/bigarray.h caml/custom.h caml/fail.h caml/intext.h caml/io.h \ - caml/hash.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/signals.h -main_bd.$(O): main.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/sys.h caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -memprof_bd.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/fail.h \ - caml/alloc.h caml/callback.h caml/signals.h caml/memory.h \ - caml/minor_gc.h caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/weak.h caml/stack.h caml/misc.h caml/compact.h caml/printexc.h \ - caml/eventlog.h -domain_bd.$(O): domain.c caml/domain_state.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -skiplist_bd.$(O): skiplist.c caml/config.h caml/m.h caml/s.h caml/memory.h \ - caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/skiplist.h -codefrag_bd.$(O): codefrag.c caml/codefrag.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/md5.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/skiplist.h -win32_bd.$(O): win32.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/address_class.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/sys.h caml/config.h -instrtrace_bd.$(O): instrtrace.c caml/instrtrace.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/instruct.h caml/misc.h caml/mlvalues.h \ - caml/opnames.h caml/prims.h caml/stacks.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/startup_aux.h -interp_bi.$(O): interp.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/callback.h caml/debugger.h caml/fail.h \ - caml/fix_code.h caml/instrtrace.h caml/instruct.h caml/interp.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/prims.h caml/signals.h caml/stacks.h caml/memory.h \ - caml/startup_aux.h caml/jumptbl.h -misc_bi.$(O): misc.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/memory.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/osdeps.h caml/memory.h \ - caml/version.h -stacks_bi.$(O): stacks.c caml/config.h caml/m.h caml/s.h caml/fail.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/misc.h caml/mlvalues.h caml/stacks.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -fix_code_bi.$(O): fix_code.c caml/config.h caml/m.h caml/s.h caml/codefrag.h \ - caml/debugger.h caml/misc.h caml/config.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/fix_code.h \ - caml/instruct.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -startup_aux_bi.$(O): startup_aux.c caml/backtrace.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/exec.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/callback.h caml/major_gc.h caml/dynlink.h \ - caml/osdeps.h caml/memory.h caml/startup_aux.h caml/memprof.h \ - caml/roots.h -startup_byt_bi.$(O): startup_byt.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/callback.h \ - caml/custom.h caml/debugger.h caml/domain.h caml/dynlink.h \ - caml/eventlog.h caml/exec.h caml/fail.h caml/fix_code.h caml/freelist.h \ - caml/gc_ctrl.h caml/instrtrace.h caml/interp.h caml/intext.h caml/io.h \ - caml/io.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h caml/prims.h \ - caml/printexc.h caml/reverse.h caml/signals.h caml/stacks.h caml/sys.h \ - caml/startup.h caml/startup_aux.h caml/version.h -freelist_bi.$(O): freelist.c caml/config.h caml/m.h caml/s.h caml/custom.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/major_gc.h caml/misc.h \ - caml/mlvalues.h caml/eventlog.h -major_gc_bi.$(O): major_gc.c caml/compact.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/config.h caml/fail.h caml/finalise.h caml/roots.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/freelist.h caml/gc.h \ - caml/gc_ctrl.h caml/major_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/signals.h caml/weak.h caml/memprof.h caml/eventlog.h -minor_gc_bi.$(O): minor_gc.c caml/custom.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/memory.h caml/minor_gc.h caml/misc.h \ - caml/mlvalues.h caml/roots.h caml/signals.h caml/weak.h caml/memprof.h \ - caml/eventlog.h -memory_bi.$(O): memory.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/signals.h caml/memprof.h caml/roots.h \ - caml/memory.h caml/eventlog.h -alloc_bi.$(O): alloc.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/stacks.h caml/memory.h caml/signals.h -roots_byt_bi.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/globroots.h caml/major_gc.h caml/memory.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/roots.h caml/stacks.h caml/memprof.h \ - caml/eventlog.h -globroots_bi.$(O): globroots.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/globroots.h \ - caml/roots.h caml/skiplist.h -fail_byt_bi.$(O): fail_byt.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/fail.h caml/gc.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/printexc.h caml/signals.h \ - caml/stacks.h caml/memory.h -signals_bi.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/config.h caml/fail.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/roots.h caml/memory.h \ - caml/signals.h caml/signals_machdep.h caml/sys.h caml/memprof.h \ - caml/roots.h caml/finalise.h -signals_byt_bi.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ - caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/fail.h caml/finalise.h caml/roots.h caml/memory.h caml/osdeps.h \ - caml/signals.h caml/signals_machdep.h -printexc_bi.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/exec.h caml/callback.h caml/debugger.h caml/fail.h caml/misc.h \ - caml/mlvalues.h caml/printexc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/memprof.h caml/roots.h caml/memory.h -backtrace_byt_bi.$(O): backtrace_byt.c caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/mlvalues.h caml/domain_state.tbl caml/alloc.h caml/custom.h \ - caml/io.h caml/instruct.h caml/intext.h caml/io.h caml/exec.h \ - caml/fix_code.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/startup.h \ - caml/exec.h caml/stacks.h caml/memory.h caml/sys.h caml/backtrace.h \ - caml/fail.h caml/backtrace_prim.h caml/backtrace.h caml/debugger.h -backtrace_bi.$(O): backtrace.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/backtrace.h caml/exec.h \ - caml/backtrace_prim.h caml/backtrace.h caml/fail.h caml/debugger.h -compare_bi.$(O): compare.c caml/custom.h caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h -ints_bi.$(O): ints.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/fail.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h -eventlog_bi.$(O): eventlog.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/eventlog.h caml/misc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h -floats_bi.$(O): floats.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/stacks.h caml/memory.h -str_bi.$(O): str.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/mlvalues.h caml/misc.h -array_bi.$(O): array.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/mlvalues.h \ - caml/signals.h caml/eventlog.h caml/spacetime.h caml/io.h caml/stack.h -io_bi.$(O): io.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/signals.h caml/sys.h -extern_bi.$(O): extern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/custom.h caml/fail.h caml/gc.h \ - caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -intern_bi.$(O): intern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/codefrag.h caml/config.h caml/custom.h caml/fail.h \ - caml/gc.h caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/memprof.h caml/roots.h caml/memory.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/signals.h -hash_bi.$(O): hash.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/custom.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/hash.h -sys_bi.$(O): sys.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/debugger.h caml/fail.h caml/gc_ctrl.h caml/io.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/signals.h caml/stacks.h caml/sys.h caml/version.h caml/callback.h \ - caml/startup_aux.h -meta_bi.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/codefrag.h \ - caml/config.h caml/debugger.h caml/fail.h caml/fix_code.h caml/interp.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/stacks.h caml/memory.h -parsing_bi.$(O): parsing.c caml/config.h caml/m.h caml/s.h caml/mlvalues.h \ - caml/config.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/alloc.h -gc_ctrl_bi.$(O): gc_ctrl.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/compact.h caml/custom.h caml/fail.h \ - caml/finalise.h caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h caml/memory.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/signals.h \ - caml/eventlog.h caml/stacks.h caml/startup_aux.h -md5_bi.$(O): md5.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/md5.h caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/io.h caml/reverse.h -obj_bi.$(O): obj.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/gc.h caml/interp.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/spacetime.h caml/io.h caml/stack.h -lexing_bi.$(O): lexing.c caml/fail.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/mlvalues.h caml/stacks.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h -callback_bi.$(O): callback.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/interp.h caml/instruct.h caml/fix_code.h \ - caml/stacks.h caml/memory.h -debugger_bi.$(O): debugger.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/debugger.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/skiplist.h caml/fail.h \ - caml/fix_code.h caml/instruct.h caml/intext.h caml/io.h caml/io.h \ - caml/mlvalues.h caml/stacks.h caml/sys.h -weak_bi.$(O): weak.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/weak.h caml/memory.h caml/minor_gc.h caml/signals.h caml/eventlog.h -compact_bi.$(O): compact.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/finalise.h caml/roots.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h \ - caml/memory.h caml/mlvalues.h caml/roots.h caml/weak.h caml/compact.h \ - caml/memprof.h caml/eventlog.h -finalise_bi.$(O): finalise.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/compact.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/minor_gc.h caml/mlvalues.h \ - caml/roots.h caml/signals.h -custom_bi.$(O): custom.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/gc_ctrl.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/signals.h -dynlink_bi.$(O): dynlink.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/dynlink.h caml/fail.h caml/mlvalues.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/prims.h caml/signals.h -spacetime_byt_bi.$(O): spacetime_byt.c caml/fail.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/mlvalues.h -afl_bi.$(O): afl.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -unix_bi.$(O): unix.c caml/config.h caml/m.h caml/s.h caml/fail.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/signals.h caml/sys.h caml/io.h caml/alloc.h -bigarray_bi.$(O): bigarray.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/bigarray.h caml/custom.h caml/fail.h caml/intext.h caml/io.h \ - caml/hash.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/signals.h -main_bi.$(O): main.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/sys.h caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -memprof_bi.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/fail.h \ - caml/alloc.h caml/callback.h caml/signals.h caml/memory.h \ - caml/minor_gc.h caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/weak.h caml/stack.h caml/misc.h caml/compact.h caml/printexc.h \ - caml/eventlog.h -domain_bi.$(O): domain.c caml/domain_state.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -skiplist_bi.$(O): skiplist.c caml/config.h caml/m.h caml/s.h caml/memory.h \ - caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/skiplist.h -codefrag_bi.$(O): codefrag.c caml/codefrag.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/md5.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/skiplist.h -win32_bi.$(O): win32.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/address_class.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/sys.h caml/config.h -instrtrace_bi.$(O): instrtrace.c -interp_bpic.$(O): interp.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/callback.h caml/debugger.h caml/fail.h \ - caml/fix_code.h caml/instrtrace.h caml/instruct.h caml/interp.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/prims.h caml/signals.h caml/stacks.h caml/memory.h \ - caml/startup_aux.h caml/jumptbl.h -misc_bpic.$(O): misc.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/memory.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/osdeps.h caml/memory.h \ - caml/version.h -stacks_bpic.$(O): stacks.c caml/config.h caml/m.h caml/s.h caml/fail.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/misc.h caml/mlvalues.h caml/stacks.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -fix_code_bpic.$(O): fix_code.c caml/config.h caml/m.h caml/s.h caml/codefrag.h \ - caml/debugger.h caml/misc.h caml/config.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/fix_code.h \ - caml/instruct.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -startup_aux_bpic.$(O): startup_aux.c caml/backtrace.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/exec.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/callback.h caml/major_gc.h caml/dynlink.h \ - caml/osdeps.h caml/memory.h caml/startup_aux.h caml/memprof.h \ - caml/roots.h -startup_byt_bpic.$(O): startup_byt.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/callback.h \ - caml/custom.h caml/debugger.h caml/domain.h caml/dynlink.h \ - caml/eventlog.h caml/exec.h caml/fail.h caml/fix_code.h caml/freelist.h \ - caml/gc_ctrl.h caml/instrtrace.h caml/interp.h caml/intext.h caml/io.h \ - caml/io.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h caml/prims.h \ - caml/printexc.h caml/reverse.h caml/signals.h caml/stacks.h caml/sys.h \ - caml/startup.h caml/startup_aux.h caml/version.h -freelist_bpic.$(O): freelist.c caml/config.h caml/m.h caml/s.h caml/custom.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/major_gc.h caml/misc.h \ - caml/mlvalues.h caml/eventlog.h -major_gc_bpic.$(O): major_gc.c caml/compact.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/config.h caml/fail.h caml/finalise.h caml/roots.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/freelist.h caml/gc.h \ - caml/gc_ctrl.h caml/major_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/signals.h caml/weak.h caml/memprof.h caml/eventlog.h -minor_gc_bpic.$(O): minor_gc.c caml/custom.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/memory.h caml/minor_gc.h caml/misc.h \ - caml/mlvalues.h caml/roots.h caml/signals.h caml/weak.h caml/memprof.h \ - caml/eventlog.h -memory_bpic.$(O): memory.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/signals.h caml/memprof.h caml/roots.h \ - caml/memory.h caml/eventlog.h -alloc_bpic.$(O): alloc.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/stacks.h caml/memory.h caml/signals.h -roots_byt_bpic.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/globroots.h caml/major_gc.h caml/memory.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/roots.h caml/stacks.h caml/memprof.h \ - caml/eventlog.h -globroots_bpic.$(O): globroots.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/globroots.h \ - caml/roots.h caml/skiplist.h -fail_byt_bpic.$(O): fail_byt.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/fail.h caml/gc.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/printexc.h caml/signals.h \ - caml/stacks.h caml/memory.h -signals_bpic.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/config.h caml/fail.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/roots.h caml/memory.h \ - caml/signals.h caml/signals_machdep.h caml/sys.h caml/memprof.h \ - caml/roots.h caml/finalise.h -signals_byt_bpic.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \ - caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/fail.h caml/finalise.h caml/roots.h caml/memory.h caml/osdeps.h \ - caml/signals.h caml/signals_machdep.h -printexc_bpic.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/exec.h caml/callback.h caml/debugger.h caml/fail.h caml/misc.h \ - caml/mlvalues.h caml/printexc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/memprof.h caml/roots.h caml/memory.h -backtrace_byt_bpic.$(O): backtrace_byt.c caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/mlvalues.h caml/domain_state.tbl caml/alloc.h caml/custom.h \ - caml/io.h caml/instruct.h caml/intext.h caml/io.h caml/exec.h \ - caml/fix_code.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/startup.h \ - caml/exec.h caml/stacks.h caml/memory.h caml/sys.h caml/backtrace.h \ - caml/fail.h caml/backtrace_prim.h caml/backtrace.h caml/debugger.h -backtrace_bpic.$(O): backtrace.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/backtrace.h caml/exec.h \ - caml/backtrace_prim.h caml/backtrace.h caml/fail.h caml/debugger.h -compare_bpic.$(O): compare.c caml/custom.h caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h -ints_bpic.$(O): ints.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/fail.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h -eventlog_bpic.$(O): eventlog.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/eventlog.h caml/misc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h -floats_bpic.$(O): floats.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/stacks.h caml/memory.h -str_bpic.$(O): str.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/mlvalues.h caml/misc.h -array_bpic.$(O): array.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/mlvalues.h \ - caml/signals.h caml/eventlog.h caml/spacetime.h caml/io.h caml/stack.h -io_bpic.$(O): io.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/signals.h caml/sys.h -extern_bpic.$(O): extern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/custom.h caml/fail.h caml/gc.h \ - caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -intern_bpic.$(O): intern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/codefrag.h caml/config.h caml/custom.h caml/fail.h \ - caml/gc.h caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/memprof.h caml/roots.h caml/memory.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/signals.h -hash_bpic.$(O): hash.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/custom.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/hash.h -sys_bpic.$(O): sys.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/debugger.h caml/fail.h caml/gc_ctrl.h caml/io.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/signals.h caml/stacks.h caml/sys.h caml/version.h caml/callback.h \ - caml/startup_aux.h -meta_bpic.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/codefrag.h \ - caml/config.h caml/debugger.h caml/fail.h caml/fix_code.h caml/interp.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/stacks.h caml/memory.h -parsing_bpic.$(O): parsing.c caml/config.h caml/m.h caml/s.h caml/mlvalues.h \ - caml/config.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/alloc.h -gc_ctrl_bpic.$(O): gc_ctrl.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/compact.h caml/custom.h caml/fail.h \ - caml/finalise.h caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h caml/memory.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/signals.h \ - caml/eventlog.h caml/stacks.h caml/startup_aux.h -md5_bpic.$(O): md5.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/md5.h caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/io.h caml/reverse.h -obj_bpic.$(O): obj.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/gc.h caml/interp.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/spacetime.h caml/io.h caml/stack.h -lexing_bpic.$(O): lexing.c caml/fail.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/mlvalues.h caml/stacks.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h -callback_bpic.$(O): callback.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/interp.h caml/instruct.h caml/fix_code.h \ - caml/stacks.h caml/memory.h -debugger_bpic.$(O): debugger.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/debugger.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/skiplist.h caml/fail.h \ - caml/fix_code.h caml/instruct.h caml/intext.h caml/io.h caml/io.h \ - caml/mlvalues.h caml/stacks.h caml/sys.h -weak_bpic.$(O): weak.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/weak.h caml/memory.h caml/minor_gc.h caml/signals.h caml/eventlog.h -compact_bpic.$(O): compact.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/finalise.h caml/roots.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h \ - caml/memory.h caml/mlvalues.h caml/roots.h caml/weak.h caml/compact.h \ - caml/memprof.h caml/eventlog.h -finalise_bpic.$(O): finalise.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/compact.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/minor_gc.h caml/mlvalues.h \ - caml/roots.h caml/signals.h -custom_bpic.$(O): custom.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/gc_ctrl.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/signals.h -dynlink_bpic.$(O): dynlink.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/dynlink.h caml/fail.h caml/mlvalues.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/prims.h caml/signals.h -spacetime_byt_bpic.$(O): spacetime_byt.c caml/fail.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/mlvalues.h -afl_bpic.$(O): afl.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -unix_bpic.$(O): unix.c caml/config.h caml/m.h caml/s.h caml/fail.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/signals.h caml/sys.h caml/io.h caml/alloc.h -bigarray_bpic.$(O): bigarray.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/bigarray.h caml/custom.h caml/fail.h caml/intext.h caml/io.h \ - caml/hash.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/signals.h -main_bpic.$(O): main.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/sys.h caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -memprof_bpic.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/fail.h \ - caml/alloc.h caml/callback.h caml/signals.h caml/memory.h \ - caml/minor_gc.h caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/weak.h caml/stack.h caml/misc.h caml/compact.h caml/printexc.h \ - caml/eventlog.h -domain_bpic.$(O): domain.c caml/domain_state.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -skiplist_bpic.$(O): skiplist.c caml/config.h caml/m.h caml/s.h caml/memory.h \ - caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/skiplist.h -codefrag_bpic.$(O): codefrag.c caml/codefrag.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/md5.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/skiplist.h -win32_bpic.$(O): win32.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/address_class.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/sys.h caml/config.h -instrtrace_bpic.$(O): instrtrace.c -startup_aux_n.$(O): startup_aux.c caml/backtrace.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/exec.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/callback.h caml/major_gc.h caml/osdeps.h \ - caml/memory.h caml/startup_aux.h caml/memprof.h caml/roots.h -startup_nat_n.$(O): startup_nat.c caml/callback.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/custom.h \ - caml/codefrag.h caml/debugger.h caml/domain.h caml/eventlog.h \ - caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/intext.h \ - caml/io.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/printexc.h caml/stack.h \ - caml/startup_aux.h caml/sys.h -main_n.$(O): main.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/sys.h caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -fail_nat_n.$(O): fail_nat.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/io.h caml/gc.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/printexc.h caml/signals.h \ - caml/stack.h caml/roots.h caml/memory.h caml/callback.h -roots_nat_n.$(O): roots_nat.c caml/finalise.h caml/roots.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/globroots.h caml/memory.h caml/major_gc.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/stack.h caml/roots.h caml/memprof.h \ - caml/eventlog.h -signals_n.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/config.h caml/fail.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/roots.h caml/memory.h \ - caml/signals.h caml/signals_machdep.h caml/sys.h caml/memprof.h \ - caml/roots.h caml/finalise.h -signals_nat_n.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - signals_osdep.h caml/stack.h caml/spacetime.h caml/io.h caml/stack.h \ - caml/memprof.h caml/roots.h caml/finalise.h -misc_n.$(O): misc.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/memory.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/osdeps.h caml/memory.h \ - caml/version.h -freelist_n.$(O): freelist.c caml/config.h caml/m.h caml/s.h caml/custom.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/major_gc.h caml/misc.h \ - caml/mlvalues.h caml/eventlog.h -major_gc_n.$(O): major_gc.c caml/compact.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/config.h caml/fail.h caml/finalise.h caml/roots.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/freelist.h caml/gc.h \ - caml/gc_ctrl.h caml/major_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/signals.h caml/weak.h caml/memprof.h caml/eventlog.h -minor_gc_n.$(O): minor_gc.c caml/custom.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/memory.h caml/minor_gc.h caml/misc.h \ - caml/mlvalues.h caml/roots.h caml/signals.h caml/weak.h caml/memprof.h \ - caml/eventlog.h -memory_n.$(O): memory.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/signals.h caml/memprof.h caml/roots.h \ - caml/memory.h caml/eventlog.h -alloc_n.$(O): alloc.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/stacks.h caml/memory.h caml/signals.h -compare_n.$(O): compare.c caml/custom.h caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h -ints_n.$(O): ints.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/fail.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h -floats_n.$(O): floats.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/stacks.h caml/memory.h -str_n.$(O): str.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/mlvalues.h caml/misc.h -array_n.$(O): array.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/mlvalues.h \ - caml/signals.h caml/eventlog.h caml/spacetime.h caml/io.h caml/stack.h -io_n.$(O): io.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/signals.h caml/sys.h -extern_n.$(O): extern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/custom.h caml/fail.h caml/gc.h \ - caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -intern_n.$(O): intern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/codefrag.h caml/config.h caml/custom.h caml/fail.h \ - caml/gc.h caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/memprof.h caml/roots.h caml/memory.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/signals.h -hash_n.$(O): hash.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/custom.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/hash.h -sys_n.$(O): sys.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/debugger.h caml/fail.h caml/gc_ctrl.h caml/io.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/signals.h caml/stacks.h caml/sys.h caml/version.h caml/callback.h \ - caml/startup_aux.h -parsing_n.$(O): parsing.c caml/config.h caml/m.h caml/s.h caml/mlvalues.h \ - caml/config.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/alloc.h -gc_ctrl_n.$(O): gc_ctrl.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/compact.h caml/custom.h caml/fail.h \ - caml/finalise.h caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h caml/memory.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/signals.h \ - caml/eventlog.h caml/stack.h caml/startup_aux.h -eventlog_n.$(O): eventlog.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/eventlog.h caml/misc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h -md5_n.$(O): md5.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/md5.h caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/io.h caml/reverse.h -obj_n.$(O): obj.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/gc.h caml/interp.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/spacetime.h caml/io.h caml/stack.h -lexing_n.$(O): lexing.c caml/fail.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/mlvalues.h caml/stacks.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h -unix_n.$(O): unix.c caml/config.h caml/m.h caml/s.h caml/fail.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/signals.h caml/sys.h caml/io.h caml/alloc.h -printexc_n.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/exec.h caml/callback.h caml/debugger.h caml/fail.h caml/misc.h \ - caml/mlvalues.h caml/printexc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/memprof.h caml/roots.h caml/memory.h -callback_n.$(O): callback.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h -weak_n.$(O): weak.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/weak.h caml/memory.h caml/minor_gc.h caml/signals.h caml/eventlog.h -compact_n.$(O): compact.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/finalise.h caml/roots.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h \ - caml/memory.h caml/mlvalues.h caml/roots.h caml/weak.h caml/compact.h \ - caml/memprof.h caml/eventlog.h -finalise_n.$(O): finalise.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/compact.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/minor_gc.h caml/mlvalues.h \ - caml/roots.h caml/signals.h -custom_n.$(O): custom.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/gc_ctrl.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/signals.h -globroots_n.$(O): globroots.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/globroots.h \ - caml/roots.h caml/skiplist.h -backtrace_nat_n.$(O): backtrace_nat.c caml/alloc.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/backtrace_prim.h \ - caml/backtrace.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/stack.h -backtrace_n.$(O): backtrace.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/backtrace.h caml/exec.h \ - caml/backtrace_prim.h caml/backtrace.h caml/fail.h caml/debugger.h -dynlink_nat_n.$(O): dynlink_nat.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/stack.h caml/callback.h caml/codefrag.h caml/alloc.h caml/intext.h \ - caml/io.h caml/osdeps.h caml/memory.h caml/fail.h caml/signals.h \ - caml/hooks.h -debugger_n.$(O): debugger.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/debugger.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/skiplist.h -meta_n.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/codefrag.h \ - caml/config.h caml/debugger.h caml/fail.h caml/fix_code.h caml/interp.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/stacks.h caml/memory.h -dynlink_n.$(O): dynlink.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/dynlink.h caml/fail.h caml/mlvalues.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/prims.h caml/signals.h -clambda_checks_n.$(O): clambda_checks.c caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl -spacetime_nat_n.$(O): spacetime_nat.c caml/config.h caml/m.h caml/s.h \ - caml/alloc.h caml/misc.h caml/config.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/backtrace_prim.h \ - caml/backtrace.h caml/exec.h caml/fail.h caml/gc.h caml/intext.h \ - caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/roots.h caml/signals.h caml/stack.h caml/sys.h caml/spacetime.h \ - caml/stack.h -spacetime_snapshot_n.$(O): spacetime_snapshot.c caml/alloc.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/config.h caml/custom.h caml/fail.h caml/gc.h caml/gc_ctrl.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/memory.h caml/signals.h caml/stack.h caml/sys.h caml/spacetime.h \ - caml/stack.h -afl_n.$(O): afl.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -bigarray_n.$(O): bigarray.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/bigarray.h caml/custom.h caml/fail.h caml/intext.h caml/io.h \ - caml/hash.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/signals.h -memprof_n.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/fail.h \ - caml/alloc.h caml/callback.h caml/signals.h caml/memory.h \ - caml/minor_gc.h caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/weak.h caml/stack.h caml/misc.h caml/compact.h caml/printexc.h \ - caml/eventlog.h -domain_n.$(O): domain.c caml/domain_state.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -skiplist_n.$(O): skiplist.c caml/config.h caml/m.h caml/s.h caml/memory.h \ - caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/skiplist.h -codefrag_n.$(O): codefrag.c caml/codefrag.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/md5.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/skiplist.h -win32_n.$(O): win32.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/address_class.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/sys.h caml/config.h -startup_aux_nd.$(O): startup_aux.c caml/backtrace.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/exec.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/callback.h caml/major_gc.h caml/osdeps.h \ - caml/memory.h caml/startup_aux.h caml/memprof.h caml/roots.h -startup_nat_nd.$(O): startup_nat.c caml/callback.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/custom.h \ - caml/codefrag.h caml/debugger.h caml/domain.h caml/eventlog.h \ - caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/intext.h \ - caml/io.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/printexc.h caml/stack.h \ - caml/startup_aux.h caml/sys.h -main_nd.$(O): main.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/sys.h caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -fail_nat_nd.$(O): fail_nat.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/io.h caml/gc.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/printexc.h caml/signals.h \ - caml/stack.h caml/roots.h caml/memory.h caml/callback.h -roots_nat_nd.$(O): roots_nat.c caml/finalise.h caml/roots.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/globroots.h caml/memory.h caml/major_gc.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/stack.h caml/roots.h caml/memprof.h \ - caml/eventlog.h -signals_nd.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/config.h caml/fail.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/roots.h caml/memory.h \ - caml/signals.h caml/signals_machdep.h caml/sys.h caml/memprof.h \ - caml/roots.h caml/finalise.h -signals_nat_nd.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - signals_osdep.h caml/stack.h caml/spacetime.h caml/io.h caml/stack.h \ - caml/memprof.h caml/roots.h caml/finalise.h -misc_nd.$(O): misc.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/memory.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/osdeps.h caml/memory.h \ - caml/version.h -freelist_nd.$(O): freelist.c caml/config.h caml/m.h caml/s.h caml/custom.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/major_gc.h caml/misc.h \ - caml/mlvalues.h caml/eventlog.h -major_gc_nd.$(O): major_gc.c caml/compact.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/config.h caml/fail.h caml/finalise.h caml/roots.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/freelist.h caml/gc.h \ - caml/gc_ctrl.h caml/major_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/signals.h caml/weak.h caml/memprof.h caml/eventlog.h -minor_gc_nd.$(O): minor_gc.c caml/custom.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/memory.h caml/minor_gc.h caml/misc.h \ - caml/mlvalues.h caml/roots.h caml/signals.h caml/weak.h caml/memprof.h \ - caml/eventlog.h -memory_nd.$(O): memory.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/signals.h caml/memprof.h caml/roots.h \ - caml/memory.h caml/eventlog.h -alloc_nd.$(O): alloc.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/stacks.h caml/memory.h caml/signals.h -compare_nd.$(O): compare.c caml/custom.h caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h -ints_nd.$(O): ints.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/fail.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h -floats_nd.$(O): floats.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/stacks.h caml/memory.h -str_nd.$(O): str.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/mlvalues.h caml/misc.h -array_nd.$(O): array.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/mlvalues.h \ - caml/signals.h caml/eventlog.h caml/spacetime.h caml/io.h caml/stack.h -io_nd.$(O): io.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/signals.h caml/sys.h -extern_nd.$(O): extern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/custom.h caml/fail.h caml/gc.h \ - caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -intern_nd.$(O): intern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/codefrag.h caml/config.h caml/custom.h caml/fail.h \ - caml/gc.h caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/memprof.h caml/roots.h caml/memory.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/signals.h -hash_nd.$(O): hash.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/custom.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/hash.h -sys_nd.$(O): sys.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/debugger.h caml/fail.h caml/gc_ctrl.h caml/io.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/signals.h caml/stacks.h caml/sys.h caml/version.h caml/callback.h \ - caml/startup_aux.h -parsing_nd.$(O): parsing.c caml/config.h caml/m.h caml/s.h caml/mlvalues.h \ - caml/config.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/alloc.h -gc_ctrl_nd.$(O): gc_ctrl.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/compact.h caml/custom.h caml/fail.h \ - caml/finalise.h caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h caml/memory.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/signals.h \ - caml/eventlog.h caml/stack.h caml/startup_aux.h -eventlog_nd.$(O): eventlog.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/eventlog.h caml/misc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h -md5_nd.$(O): md5.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/md5.h caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/io.h caml/reverse.h -obj_nd.$(O): obj.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/gc.h caml/interp.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/spacetime.h caml/io.h caml/stack.h -lexing_nd.$(O): lexing.c caml/fail.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/mlvalues.h caml/stacks.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h -unix_nd.$(O): unix.c caml/config.h caml/m.h caml/s.h caml/fail.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/signals.h caml/sys.h caml/io.h caml/alloc.h -printexc_nd.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/exec.h caml/callback.h caml/debugger.h caml/fail.h caml/misc.h \ - caml/mlvalues.h caml/printexc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/memprof.h caml/roots.h caml/memory.h -callback_nd.$(O): callback.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h -weak_nd.$(O): weak.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/weak.h caml/memory.h caml/minor_gc.h caml/signals.h caml/eventlog.h -compact_nd.$(O): compact.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/finalise.h caml/roots.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h \ - caml/memory.h caml/mlvalues.h caml/roots.h caml/weak.h caml/compact.h \ - caml/memprof.h caml/eventlog.h -finalise_nd.$(O): finalise.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/compact.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/minor_gc.h caml/mlvalues.h \ - caml/roots.h caml/signals.h -custom_nd.$(O): custom.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/gc_ctrl.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/signals.h -globroots_nd.$(O): globroots.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/globroots.h \ - caml/roots.h caml/skiplist.h -backtrace_nat_nd.$(O): backtrace_nat.c caml/alloc.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/backtrace_prim.h \ - caml/backtrace.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/stack.h -backtrace_nd.$(O): backtrace.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/backtrace.h caml/exec.h \ - caml/backtrace_prim.h caml/backtrace.h caml/fail.h caml/debugger.h -dynlink_nat_nd.$(O): dynlink_nat.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/stack.h caml/callback.h caml/codefrag.h caml/alloc.h caml/intext.h \ - caml/io.h caml/osdeps.h caml/memory.h caml/fail.h caml/signals.h \ - caml/hooks.h -debugger_nd.$(O): debugger.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/debugger.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/skiplist.h -meta_nd.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/codefrag.h \ - caml/config.h caml/debugger.h caml/fail.h caml/fix_code.h caml/interp.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/stacks.h caml/memory.h -dynlink_nd.$(O): dynlink.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/dynlink.h caml/fail.h caml/mlvalues.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/prims.h caml/signals.h -clambda_checks_nd.$(O): clambda_checks.c caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl -spacetime_nat_nd.$(O): spacetime_nat.c caml/config.h caml/m.h caml/s.h \ - caml/alloc.h caml/misc.h caml/config.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/backtrace_prim.h \ - caml/backtrace.h caml/exec.h caml/fail.h caml/gc.h caml/intext.h \ - caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/roots.h caml/signals.h caml/stack.h caml/sys.h caml/spacetime.h \ - caml/stack.h -spacetime_snapshot_nd.$(O): spacetime_snapshot.c caml/alloc.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/config.h caml/custom.h caml/fail.h caml/gc.h caml/gc_ctrl.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/memory.h caml/signals.h caml/stack.h caml/sys.h caml/spacetime.h \ - caml/stack.h -afl_nd.$(O): afl.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -bigarray_nd.$(O): bigarray.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/bigarray.h caml/custom.h caml/fail.h caml/intext.h caml/io.h \ - caml/hash.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/signals.h -memprof_nd.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/fail.h \ - caml/alloc.h caml/callback.h caml/signals.h caml/memory.h \ - caml/minor_gc.h caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/weak.h caml/stack.h caml/misc.h caml/compact.h caml/printexc.h \ - caml/eventlog.h -domain_nd.$(O): domain.c caml/domain_state.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -skiplist_nd.$(O): skiplist.c caml/config.h caml/m.h caml/s.h caml/memory.h \ - caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/skiplist.h -codefrag_nd.$(O): codefrag.c caml/codefrag.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/md5.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/skiplist.h -win32_nd.$(O): win32.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/address_class.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/sys.h caml/config.h -startup_aux_ni.$(O): startup_aux.c caml/backtrace.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/exec.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/callback.h caml/major_gc.h caml/osdeps.h \ - caml/memory.h caml/startup_aux.h caml/memprof.h caml/roots.h -startup_nat_ni.$(O): startup_nat.c caml/callback.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/custom.h \ - caml/codefrag.h caml/debugger.h caml/domain.h caml/eventlog.h \ - caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/intext.h \ - caml/io.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/printexc.h caml/stack.h \ - caml/startup_aux.h caml/sys.h -main_ni.$(O): main.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/sys.h caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -fail_nat_ni.$(O): fail_nat.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/io.h caml/gc.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/printexc.h caml/signals.h \ - caml/stack.h caml/roots.h caml/memory.h caml/callback.h -roots_nat_ni.$(O): roots_nat.c caml/finalise.h caml/roots.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/globroots.h caml/memory.h caml/major_gc.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/stack.h caml/roots.h caml/memprof.h \ - caml/eventlog.h -signals_ni.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/config.h caml/fail.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/roots.h caml/memory.h \ - caml/signals.h caml/signals_machdep.h caml/sys.h caml/memprof.h \ - caml/roots.h caml/finalise.h -signals_nat_ni.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - signals_osdep.h caml/stack.h caml/spacetime.h caml/io.h caml/stack.h \ - caml/memprof.h caml/roots.h caml/finalise.h -misc_ni.$(O): misc.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/memory.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/osdeps.h caml/memory.h \ - caml/version.h -freelist_ni.$(O): freelist.c caml/config.h caml/m.h caml/s.h caml/custom.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/major_gc.h caml/misc.h \ - caml/mlvalues.h caml/eventlog.h -major_gc_ni.$(O): major_gc.c caml/compact.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/config.h caml/fail.h caml/finalise.h caml/roots.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/freelist.h caml/gc.h \ - caml/gc_ctrl.h caml/major_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/signals.h caml/weak.h caml/memprof.h caml/eventlog.h -minor_gc_ni.$(O): minor_gc.c caml/custom.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/memory.h caml/minor_gc.h caml/misc.h \ - caml/mlvalues.h caml/roots.h caml/signals.h caml/weak.h caml/memprof.h \ - caml/eventlog.h -memory_ni.$(O): memory.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/signals.h caml/memprof.h caml/roots.h \ - caml/memory.h caml/eventlog.h -alloc_ni.$(O): alloc.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/stacks.h caml/memory.h caml/signals.h -compare_ni.$(O): compare.c caml/custom.h caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h -ints_ni.$(O): ints.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/fail.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h -floats_ni.$(O): floats.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/stacks.h caml/memory.h -str_ni.$(O): str.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/mlvalues.h caml/misc.h -array_ni.$(O): array.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/mlvalues.h \ - caml/signals.h caml/eventlog.h caml/spacetime.h caml/io.h caml/stack.h -io_ni.$(O): io.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/signals.h caml/sys.h -extern_ni.$(O): extern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/custom.h caml/fail.h caml/gc.h \ - caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -intern_ni.$(O): intern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/codefrag.h caml/config.h caml/custom.h caml/fail.h \ - caml/gc.h caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/memprof.h caml/roots.h caml/memory.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/signals.h -hash_ni.$(O): hash.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/custom.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/hash.h -sys_ni.$(O): sys.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/debugger.h caml/fail.h caml/gc_ctrl.h caml/io.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/signals.h caml/stacks.h caml/sys.h caml/version.h caml/callback.h \ - caml/startup_aux.h -parsing_ni.$(O): parsing.c caml/config.h caml/m.h caml/s.h caml/mlvalues.h \ - caml/config.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/alloc.h -gc_ctrl_ni.$(O): gc_ctrl.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/compact.h caml/custom.h caml/fail.h \ - caml/finalise.h caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h caml/memory.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/signals.h \ - caml/eventlog.h caml/stack.h caml/startup_aux.h -eventlog_ni.$(O): eventlog.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/eventlog.h caml/misc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h -md5_ni.$(O): md5.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/md5.h caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/io.h caml/reverse.h -obj_ni.$(O): obj.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/gc.h caml/interp.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/spacetime.h caml/io.h caml/stack.h -lexing_ni.$(O): lexing.c caml/fail.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/mlvalues.h caml/stacks.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h -unix_ni.$(O): unix.c caml/config.h caml/m.h caml/s.h caml/fail.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/signals.h caml/sys.h caml/io.h caml/alloc.h -printexc_ni.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/exec.h caml/callback.h caml/debugger.h caml/fail.h caml/misc.h \ - caml/mlvalues.h caml/printexc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/memprof.h caml/roots.h caml/memory.h -callback_ni.$(O): callback.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h -weak_ni.$(O): weak.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/weak.h caml/memory.h caml/minor_gc.h caml/signals.h caml/eventlog.h -compact_ni.$(O): compact.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/finalise.h caml/roots.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h \ - caml/memory.h caml/mlvalues.h caml/roots.h caml/weak.h caml/compact.h \ - caml/memprof.h caml/eventlog.h -finalise_ni.$(O): finalise.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/compact.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/minor_gc.h caml/mlvalues.h \ - caml/roots.h caml/signals.h -custom_ni.$(O): custom.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/gc_ctrl.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/signals.h -globroots_ni.$(O): globroots.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/globroots.h \ - caml/roots.h caml/skiplist.h -backtrace_nat_ni.$(O): backtrace_nat.c caml/alloc.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/backtrace_prim.h \ - caml/backtrace.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/stack.h -backtrace_ni.$(O): backtrace.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/backtrace.h caml/exec.h \ - caml/backtrace_prim.h caml/backtrace.h caml/fail.h caml/debugger.h -dynlink_nat_ni.$(O): dynlink_nat.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/stack.h caml/callback.h caml/codefrag.h caml/alloc.h caml/intext.h \ - caml/io.h caml/osdeps.h caml/memory.h caml/fail.h caml/signals.h \ - caml/hooks.h -debugger_ni.$(O): debugger.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/debugger.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/skiplist.h -meta_ni.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/codefrag.h \ - caml/config.h caml/debugger.h caml/fail.h caml/fix_code.h caml/interp.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/stacks.h caml/memory.h -dynlink_ni.$(O): dynlink.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/dynlink.h caml/fail.h caml/mlvalues.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/prims.h caml/signals.h -clambda_checks_ni.$(O): clambda_checks.c caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl -spacetime_nat_ni.$(O): spacetime_nat.c caml/config.h caml/m.h caml/s.h \ - caml/alloc.h caml/misc.h caml/config.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/backtrace_prim.h \ - caml/backtrace.h caml/exec.h caml/fail.h caml/gc.h caml/intext.h \ - caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/roots.h caml/signals.h caml/stack.h caml/sys.h caml/spacetime.h \ - caml/stack.h -spacetime_snapshot_ni.$(O): spacetime_snapshot.c caml/alloc.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/config.h caml/custom.h caml/fail.h caml/gc.h caml/gc_ctrl.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/memory.h caml/signals.h caml/stack.h caml/sys.h caml/spacetime.h \ - caml/stack.h -afl_ni.$(O): afl.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -bigarray_ni.$(O): bigarray.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/bigarray.h caml/custom.h caml/fail.h caml/intext.h caml/io.h \ - caml/hash.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/signals.h -memprof_ni.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/fail.h \ - caml/alloc.h caml/callback.h caml/signals.h caml/memory.h \ - caml/minor_gc.h caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/weak.h caml/stack.h caml/misc.h caml/compact.h caml/printexc.h \ - caml/eventlog.h -domain_ni.$(O): domain.c caml/domain_state.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -skiplist_ni.$(O): skiplist.c caml/config.h caml/m.h caml/s.h caml/memory.h \ - caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/skiplist.h -codefrag_ni.$(O): codefrag.c caml/codefrag.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/md5.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/skiplist.h -win32_ni.$(O): win32.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/address_class.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/sys.h caml/config.h -startup_aux_npic.$(O): startup_aux.c caml/backtrace.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/exec.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/callback.h caml/major_gc.h caml/osdeps.h \ - caml/memory.h caml/startup_aux.h caml/memprof.h caml/roots.h -startup_nat_npic.$(O): startup_nat.c caml/callback.h caml/mlvalues.h \ - caml/config.h caml/m.h caml/s.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/custom.h \ - caml/codefrag.h caml/debugger.h caml/domain.h caml/eventlog.h \ - caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/intext.h \ - caml/io.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/printexc.h caml/stack.h \ - caml/startup_aux.h caml/sys.h -main_npic.$(O): main.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/sys.h caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -fail_nat_npic.$(O): fail_nat.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/io.h caml/gc.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/printexc.h caml/signals.h \ - caml/stack.h caml/roots.h caml/memory.h caml/callback.h -roots_nat_npic.$(O): roots_nat.c caml/finalise.h caml/roots.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/globroots.h caml/memory.h caml/major_gc.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/stack.h caml/roots.h caml/memprof.h \ - caml/eventlog.h -signals_npic.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/config.h caml/fail.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/roots.h caml/memory.h \ - caml/signals.h caml/signals_machdep.h caml/sys.h caml/memprof.h \ - caml/roots.h caml/finalise.h -signals_nat_npic.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h caml/signals.h caml/signals_machdep.h \ - signals_osdep.h caml/stack.h caml/spacetime.h caml/io.h caml/stack.h \ - caml/memprof.h caml/roots.h caml/finalise.h -misc_npic.$(O): misc.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/memory.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/osdeps.h caml/memory.h \ - caml/version.h -freelist_npic.$(O): freelist.c caml/config.h caml/m.h caml/s.h caml/custom.h \ - caml/mlvalues.h caml/config.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/major_gc.h caml/misc.h \ - caml/mlvalues.h caml/eventlog.h -major_gc_npic.$(O): major_gc.c caml/compact.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/config.h caml/fail.h caml/finalise.h caml/roots.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/freelist.h caml/gc.h \ - caml/gc_ctrl.h caml/major_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/signals.h caml/weak.h caml/memprof.h caml/eventlog.h -minor_gc_npic.$(O): minor_gc.c caml/custom.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/memory.h caml/minor_gc.h caml/misc.h \ - caml/mlvalues.h caml/roots.h caml/signals.h caml/weak.h caml/memprof.h \ - caml/eventlog.h -memory_npic.$(O): memory.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/fail.h caml/freelist.h caml/gc.h caml/gc_ctrl.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/minor_gc.h \ - caml/misc.h caml/mlvalues.h caml/signals.h caml/memprof.h caml/roots.h \ - caml/memory.h caml/eventlog.h -alloc_npic.$(O): alloc.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/stacks.h caml/memory.h caml/signals.h -compare_npic.$(O): compare.c caml/custom.h caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h -ints_npic.$(O): ints.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/custom.h \ - caml/fail.h caml/intext.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h -floats_npic.$(O): floats.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/stacks.h caml/memory.h -str_npic.$(O): str.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/mlvalues.h caml/misc.h -array_npic.$(O): array.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/mlvalues.h \ - caml/signals.h caml/eventlog.h caml/spacetime.h caml/io.h caml/stack.h -io_npic.$(O): io.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/signals.h caml/sys.h -extern_npic.$(O): extern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/custom.h caml/fail.h caml/gc.h \ - caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/mlvalues.h caml/reverse.h -intern_npic.$(O): intern.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/callback.h caml/codefrag.h caml/config.h caml/custom.h caml/fail.h \ - caml/gc.h caml/intext.h caml/io.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/memprof.h caml/roots.h caml/memory.h caml/mlvalues.h \ - caml/misc.h caml/reverse.h caml/signals.h -hash_npic.$(O): hash.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/custom.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/hash.h -sys_npic.$(O): sys.c caml/config.h caml/m.h caml/s.h caml/alloc.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/debugger.h caml/fail.h caml/gc_ctrl.h caml/io.h caml/misc.h \ - caml/mlvalues.h caml/osdeps.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/signals.h caml/stacks.h caml/sys.h caml/version.h caml/callback.h \ - caml/startup_aux.h -parsing_npic.$(O): parsing.c caml/config.h caml/m.h caml/s.h caml/mlvalues.h \ - caml/config.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/alloc.h -gc_ctrl_npic.$(O): gc_ctrl.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace.h caml/exec.h caml/compact.h caml/custom.h caml/fail.h \ - caml/finalise.h caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h caml/memory.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/signals.h \ - caml/eventlog.h caml/stack.h caml/startup_aux.h -eventlog_npic.$(O): eventlog.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/eventlog.h caml/misc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/osdeps.h caml/memory.h -md5_npic.$(O): md5.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/md5.h caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h caml/io.h caml/reverse.h -obj_npic.$(O): obj.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/gc.h caml/interp.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/spacetime.h caml/io.h caml/stack.h -lexing_npic.$(O): lexing.c caml/fail.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/mlvalues.h caml/stacks.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h -unix_npic.$(O): unix.c caml/config.h caml/m.h caml/s.h caml/fail.h caml/misc.h \ - caml/config.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/signals.h caml/sys.h caml/io.h caml/alloc.h -printexc_npic.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/exec.h caml/callback.h caml/debugger.h caml/fail.h caml/misc.h \ - caml/mlvalues.h caml/printexc.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/memprof.h caml/roots.h caml/memory.h -callback_npic.$(O): callback.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/domain.h caml/fail.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/mlvalues.h -weak_npic.$(O): weak.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl caml/fail.h \ - caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/weak.h caml/memory.h caml/minor_gc.h caml/signals.h caml/eventlog.h -compact_npic.$(O): compact.c caml/address_class.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/config.h caml/finalise.h caml/roots.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/freelist.h caml/gc.h caml/gc_ctrl.h caml/major_gc.h \ - caml/memory.h caml/mlvalues.h caml/roots.h caml/weak.h caml/compact.h \ - caml/memprof.h caml/eventlog.h -finalise_npic.$(O): finalise.c caml/callback.h caml/mlvalues.h caml/config.h \ - caml/m.h caml/s.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/compact.h caml/fail.h caml/finalise.h caml/roots.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/minor_gc.h caml/mlvalues.h \ - caml/roots.h caml/signals.h -custom_npic.$(O): custom.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/custom.h caml/fail.h caml/gc_ctrl.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/mlvalues.h caml/signals.h -globroots_npic.$(O): globroots.c caml/mlvalues.h caml/config.h caml/m.h caml/s.h \ - caml/misc.h caml/domain_state.h caml/mlvalues.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/globroots.h \ - caml/roots.h caml/skiplist.h -backtrace_nat_npic.$(O): backtrace_nat.c caml/alloc.h caml/misc.h caml/config.h \ - caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace.h caml/exec.h caml/backtrace_prim.h \ - caml/backtrace.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/misc.h \ - caml/mlvalues.h caml/stack.h -backtrace_npic.$(O): backtrace.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/backtrace.h caml/exec.h \ - caml/backtrace_prim.h caml/backtrace.h caml/fail.h caml/debugger.h -dynlink_nat_npic.$(O): dynlink_nat.c caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/stack.h caml/callback.h caml/codefrag.h caml/alloc.h caml/intext.h \ - caml/io.h caml/osdeps.h caml/memory.h caml/fail.h caml/signals.h \ - caml/hooks.h -debugger_npic.$(O): debugger.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/codefrag.h caml/config.h caml/debugger.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/skiplist.h -meta_npic.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/codefrag.h \ - caml/config.h caml/debugger.h caml/fail.h caml/fix_code.h caml/interp.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/prims.h \ - caml/signals.h caml/stacks.h caml/memory.h -dynlink_npic.$(O): dynlink.c caml/config.h caml/m.h caml/s.h caml/alloc.h \ - caml/misc.h caml/config.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/dynlink.h caml/fail.h caml/mlvalues.h \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/osdeps.h \ - caml/memory.h caml/prims.h caml/signals.h -clambda_checks_npic.$(O): clambda_checks.c caml/mlvalues.h caml/config.h caml/m.h \ - caml/s.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl -spacetime_nat_npic.$(O): spacetime_nat.c caml/config.h caml/m.h caml/s.h \ - caml/alloc.h caml/misc.h caml/config.h caml/mlvalues.h \ - caml/domain_state.h caml/domain_state.tbl caml/backtrace_prim.h \ - caml/backtrace.h caml/exec.h caml/fail.h caml/gc.h caml/intext.h \ - caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/osdeps.h caml/memory.h \ - caml/roots.h caml/signals.h caml/stack.h caml/sys.h caml/spacetime.h \ - caml/stack.h -spacetime_snapshot_npic.$(O): spacetime_snapshot.c caml/alloc.h caml/misc.h \ - caml/config.h caml/m.h caml/s.h caml/mlvalues.h caml/domain_state.h \ - caml/domain_state.tbl caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/config.h caml/custom.h caml/fail.h caml/gc.h caml/gc_ctrl.h \ - caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \ - caml/gc.h caml/major_gc.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/minor_gc.h caml/misc.h caml/mlvalues.h caml/roots.h \ - caml/memory.h caml/signals.h caml/stack.h caml/sys.h caml/spacetime.h \ - caml/stack.h -afl_npic.$(O): afl.c caml/config.h caml/m.h caml/s.h caml/misc.h caml/config.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/mlvalues.h \ - caml/domain_state.tbl caml/osdeps.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h -bigarray_npic.$(O): bigarray.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/bigarray.h caml/custom.h caml/fail.h caml/intext.h caml/io.h \ - caml/hash.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/mlvalues.h \ - caml/signals.h -memprof_npic.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/misc.h caml/domain_state.h caml/domain_state.tbl \ - caml/roots.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \ - caml/minor_gc.h caml/address_class.h caml/domain.h caml/fail.h \ - caml/alloc.h caml/callback.h caml/signals.h caml/memory.h \ - caml/minor_gc.h caml/backtrace_prim.h caml/backtrace.h caml/exec.h \ - caml/weak.h caml/stack.h caml/misc.h caml/compact.h caml/printexc.h \ - caml/eventlog.h -domain_npic.$(O): domain.c caml/domain_state.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h -skiplist_npic.$(O): skiplist.c caml/config.h caml/m.h caml/s.h caml/memory.h \ - caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/major_gc.h caml/freelist.h caml/minor_gc.h \ - caml/address_class.h caml/domain.h caml/misc.h caml/skiplist.h -codefrag_npic.$(O): codefrag.c caml/codefrag.h caml/misc.h caml/config.h caml/m.h \ - caml/s.h caml/md5.h caml/mlvalues.h caml/misc.h caml/domain_state.h \ - caml/domain_state.tbl caml/io.h caml/memory.h caml/gc.h caml/major_gc.h \ - caml/freelist.h caml/minor_gc.h caml/address_class.h caml/domain.h \ - caml/skiplist.h -win32_npic.$(O): win32.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \ - caml/mlvalues.h caml/domain_state.h caml/domain_state.tbl \ - caml/address_class.h caml/fail.h caml/io.h caml/memory.h caml/gc.h \ - caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \ - caml/domain.h caml/misc.h caml/osdeps.h caml/memory.h caml/signals.h \ - caml/sys.h caml/config.h diff --git a/runtime/Makefile b/runtime/Makefile index bab27854..1abf2c8c 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -15,8 +15,7 @@ ROOTDIR = .. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common +include $(ROOTDIR)/Makefile.common # Lists of source files @@ -26,7 +25,7 @@ BYTECODE_C_SOURCES := $(addsuffix .c, \ signals_byt printexc backtrace_byt backtrace compare ints eventlog \ floats str array io extern intern hash sys meta parsing gc_ctrl md5 obj \ lexing callback debugger weak compact finalise custom dynlink \ - spacetime_byt afl $(UNIX_OR_WIN32) bigarray main memprof domain \ + afl $(UNIX_OR_WIN32) bigarray main memprof domain \ skiplist codefrag) NATIVE_C_SOURCES := $(addsuffix .c, \ @@ -35,17 +34,11 @@ NATIVE_C_SOURCES := $(addsuffix .c, \ floats str array io extern intern hash sys parsing gc_ctrl eventlog md5 obj \ lexing $(UNIX_OR_WIN32) printexc callback weak compact finalise custom \ globroots backtrace_nat backtrace dynlink_nat debugger meta \ - dynlink clambda_checks spacetime_nat spacetime_snapshot afl bigarray \ + dynlink clambda_checks afl bigarray \ memprof domain skiplist codefrag) -# The other_files variable stores the list of files whose dependencies -# should be computed by `make depend` although they do not need to be -# compiled on the current build system -ifeq "$(UNIX_OR_WIN32)" "win32" -other_files := unix.c -else -other_files := win32.c -endif +GENERATED_HEADERS := caml/opnames.h caml/version.h caml/jumptbl.h +CONFIG_HEADERS := caml/m.h caml/s.h ifeq "$(TOOLCHAIN)" "msvc" ASM_EXT := asm @@ -88,22 +81,22 @@ endif ASM_OBJECTS := $(ASM_SOURCES:.$(ASM_EXT)=.$(O)) -libcamlrun_OBJECTS := $(BYTECODE_C_SOURCES:.c=_b.$(O)) +libcamlrun_OBJECTS := $(BYTECODE_C_SOURCES:.c=.b.$(O)) -libcamlrund_OBJECTS := $(BYTECODE_C_SOURCES:.c=_bd.$(O)) \ - instrtrace_bd.$(O) +libcamlrund_OBJECTS := $(BYTECODE_C_SOURCES:.c=.bd.$(O)) \ + instrtrace.bd.$(O) -libcamlruni_OBJECTS := $(BYTECODE_C_SOURCES:.c=_bi.$(O)) +libcamlruni_OBJECTS := $(BYTECODE_C_SOURCES:.c=.bi.$(O)) -libcamlrunpic_OBJECTS := $(BYTECODE_C_SOURCES:.c=_bpic.$(O)) +libcamlrunpic_OBJECTS := $(BYTECODE_C_SOURCES:.c=.bpic.$(O)) -libasmrun_OBJECTS := $(NATIVE_C_SOURCES:.c=_n.$(O)) $(ASM_OBJECTS) +libasmrun_OBJECTS := $(NATIVE_C_SOURCES:.c=.n.$(O)) $(ASM_OBJECTS) -libasmrund_OBJECTS := $(NATIVE_C_SOURCES:.c=_nd.$(O)) $(ASM_OBJECTS) +libasmrund_OBJECTS := $(NATIVE_C_SOURCES:.c=.nd.$(O)) $(ASM_OBJECTS) -libasmruni_OBJECTS := $(NATIVE_C_SOURCES:.c=_ni.$(O)) $(ASM_OBJECTS) +libasmruni_OBJECTS := $(NATIVE_C_SOURCES:.c=.ni.$(O)) $(ASM_OBJECTS) -libasmrunpic_OBJECTS := $(NATIVE_C_SOURCES:.c=_npic.$(O)) \ +libasmrunpic_OBJECTS := $(NATIVE_C_SOURCES:.c=.npic.$(O)) \ $(ASM_OBJECTS:.$(O)=_libasmrunpic.$(O)) # General (non target-specific) assembler and compiler flags @@ -137,22 +130,21 @@ ifneq "$(CCOMPTYPE)" "msvc" OC_CFLAGS += -g endif +OC_CPPFLAGS += -DCAMLDLLIMPORT= + OC_NATIVE_CPPFLAGS = -DNATIVE_CODE -DTARGET_$(ARCH) ifeq "$(UNIX_OR_WIN32)" "unix" OC_NATIVE_CPPFLAGS += -DMODEL_$(MODEL) endif -OC_NATIVE_CPPFLAGS += -DSYS_$(SYSTEM) $(IFLEXDIR) $(LIBUNWIND_INCLUDE_FLAGS) +OC_NATIVE_CPPFLAGS += -DSYS_$(SYSTEM) $(IFLEXDIR) OC_DEBUG_CPPFLAGS=-DDEBUG OC_INSTR_CPPFLAGS=-DCAML_INSTR ifeq "$(TOOLCHAIN)" "msvc" ASMFLAGS= -ifeq ($(WITH_SPACETIME),true) -ASMFLAGS=/DWITH_SPACETIME -endif endif ASPPFLAGS = -DSYS_$(SYSTEM) -I$(ROOTDIR)/runtime @@ -180,7 +172,12 @@ endif all: $(BYTECODE_STATIC_LIBRARIES) $(BYTECODE_SHARED_LIBRARIES) $(PROGRAMS) .PHONY: allopt +ifneq "$(NATIVE_COMPILER)" "false" allopt: $(NATIVE_STATIC_LIBRARIES) $(NATIVE_SHARED_LIBRARIES) +else +allopt: + $(error The build has been configured with --disable-native-compiler) +endif INSTALL_INCDIR=$(INSTALL_LIBDIR)/caml .PHONY: install @@ -205,8 +202,9 @@ clean: rm -f *.o *.obj *.a *.lib *.so *.dll ld.conf rm -f ocamlrun ocamlrund ocamlruni rm -f ocamlrun.exe ocamlrund.exe ocamlruni.exe - rm -f primitives primitives.new prims.c caml/opnames.h caml/jumptbl.h - rm -f caml/version.h domain_state*.inc + rm -f primitives primitives.new prims.c $(GENERATED_HEADERS) + rm -f domain_state*.inc + rm -rf $(DEPDIR) .PHONY: distclean distclean: clean @@ -314,20 +312,26 @@ libasmrun_shared.$(SO): $(libasmrunpic_OBJECTS) # Target-specific preprocessor and compiler flags -%_bd.$(O): OC_CPPFLAGS += $(OC_DEBUG_CPPFLAGS) +%.bd.$(O): OC_CPPFLAGS += $(OC_DEBUG_CPPFLAGS) +%.bd.$(D): OC_CPPFLAGS += $(OC_DEBUG_CPPFLAGS) -%_bi.$(O): OC_CPPFLAGS += $(OC_INSTR_CPPFLAGS) +%.bi.$(O): OC_CPPFLAGS += $(OC_INSTR_CPPFLAGS) +%.bi.$(D): OC_CPPFLAGS += $(OC_INSTR_CPPFLAGS) -%_bpic.$(O): OC_CFLAGS += $(SHAREDLIB_CFLAGS) +%.bpic.$(O): OC_CFLAGS += $(SHAREDLIB_CFLAGS) -%_n.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) +%.n.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) +%.n.$(D): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) -%_nd.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) $(OC_DEBUG_CPPFLAGS) +%.nd.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) $(OC_DEBUG_CPPFLAGS) +%.nd.$(D): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) $(OC_DEBUG_CPPFLAGS) -%_ni.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) $(OC_INSTR_CPPFLAGS) +%.ni.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) $(OC_INSTR_CPPFLAGS) +%.ni.$(D): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) $(OC_INSTR_CPPFLAGS) -%_npic.$(O): OC_CFLAGS += $(SHAREDLIB_CFLAGS) -%_npic.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) +%.npic.$(O): OC_CFLAGS += $(SHAREDLIB_CFLAGS) +%.npic.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) +%.npic.$(D): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) # Compilation of C files @@ -335,16 +339,35 @@ libasmrun_shared.$(SO): $(libasmrunpic_OBJECTS) # that corresponds to the name of the generated object file # (without the extension, which is added by the macro) define COMPILE_C_FILE +ifneq "$(COMPUTE_DEPS)" "false" +ifneq "$(1)" "%" +# -MG would ensure that the dependencies are generated even if the files listed +# in $$(GENERATED_HEADERS) haven't been assembled yet. However, this goes subtly +# wrong if the user has the headers installed, as gcc will pick up a dependency +# on those instead and the local ones will not be generated. For this reason, we +# don't use -MG and instead include $(GENERATED_HEADERS) in the order only +# dependencies to ensure that they exist before dependencies are computed. +$(DEPDIR)/$(1).$(D): %.c | $(DEPDIR) $(GENERATED_HEADERS) + $$(DEP_CC) $$(OC_CPPFLAGS) $$(CPPFLAGS) $$< -MT \ + '$$*$(subst %,,$(1)).$(O)' -MF $$@ +endif $(1).$(O): %.c - $$(CC) -c $$(OC_CFLAGS) $$(OC_CPPFLAGS) $$(OUTPUTOBJ)$$@ $$< +else +$(1).$(O): %.c $(CONFIG_HEADERS) $(GENERATED_HEADERS) $(RUNTIME_HEADERS) +endif + $$(CC) -c $$(OC_CFLAGS) $$(CFLAGS) $$(OC_CPPFLAGS) $$(CPPFLAGS) \ + $$(OUTPUTOBJ)$$@ $$< endef -object_types := % %_b %_bd %_bi %_bpic %_n %_nd %_ni %_np %_npic +object_types := % %.b %.bd %.bi %.bpic +ifneq "$(NATIVE_COMPILER)" "false" +object_types += %.n %.nd %.ni %.np %.npic +endif $(foreach object_type, $(object_types), \ $(eval $(call COMPILE_C_FILE,$(object_type)))) -dynlink_%.$(O): OC_CPPFLAGS += $(STDLIB_CPP_FLAG) +dynlink.%.$(O): OC_CPPFLAGS += $(STDLIB_CPP_FLAG) $(foreach object_type,$(subst %,,$(object_types)), \ $(eval dynlink$(object_type).$(O): $(ROOTDIR)/Makefile.config)) @@ -378,37 +401,15 @@ i386nt.obj: i386nt.asm domain_state32.inc # Dependencies -.PHONY: depend -ifeq "$(TOOLCHAIN)" "msvc" -depend: - $(error Dependencies cannot be regenerated using the MSVC ports) -else - -NATIVE_DEP_CPPFLAGS := $(OC_CPPFLAGS) $(OC_NATIVE_CPPFLAGS) -BYTECODE_DEP_FILES := $(BYTECODE_C_SOURCES) $(other_files) instrtrace.c -NATIVE_DEP_FILES := $(NATIVE_C_SOURCES) $(other_files) - -depend: *.c caml/opnames.h caml/jumptbl.h caml/version.h - $(CC) -MM $(OC_CPPFLAGS) $(BYTECODE_DEP_FILES) | \ - sed -e 's/\([^.]*\)\.o/\1_b.$$(O)/' > .depend - $(CC) -MM $(OC_CPPFLAGS) $(OC_DEBUG_CPPFLAGS) \ - $(BYTECODE_DEP_FILES) | \ - sed -e 's/\([^.]*\)\.o/\1_bd.$$(O)/' >> .depend - $(CC) -MM $(OC_CPPFLAGS) $(OC_INSTR_CPPFLAGS) \ - $(BYTECODE_DEP_FILES) | \ - sed -e 's/\([^.]*\)\.o/\1_bi.$$(O)/' >> .depend - $(CC) -MM $(OC_CPPFLAGS) $(BYTECODE_DEP_FILES) | \ - sed -e 's/\([^.]*\)\.o/\1_bpic.$$(O)/' >> .depend - $(CC) -MM $(NATIVE_DEP_CPPFLAGS) $(NATIVE_DEP_FILES) | \ - sed -e 's/\([^.]*\)\.o/\1_n.$$(O)/' >> .depend - $(CC) -MM $(NATIVE_DEP_CPPFLAGS) $(OC_DEBUG_CPPFLAGS) \ - $(NATIVE_DEP_FILES) | \ - sed -e 's/\([^.]*\)\.o/\1_nd.$$(O)/' >> .depend - $(CC) -MM $(NATIVE_DEP_CPPFLAGS) $(OC_INSTR_CPPFLAGS) \ - $(NATIVE_DEP_FILES) | \ - sed -e 's/\([^.]*\)\.o/\1_ni.$$(O)/' >> .depend - $(CC) -MM $(NATIVE_DEP_CPPFLAGS) $(NATIVE_DEP_FILES) | \ - sed -e 's/\([^.]*\)\.o/\1_npic.$$(O)/' >> .depend +DEP_FILES := $(addsuffix .b, $(basename $(BYTECODE_C_SOURCES) instrtrace)) +ifneq "$(NATIVE_COMPILER)" "false" +DEP_FILES += $(addsuffix .n, $(basename $(NATIVE_C_SOURCES))) endif +DEP_FILES += $(addsuffix d, $(DEP_FILES)) \ + $(addsuffix i, $(DEP_FILES)) \ + $(addsuffix pic, $(DEP_FILES)) +DEP_FILES := $(addsuffix .$(D), $(DEP_FILES)) -include .depend +ifeq "$(COMPUTE_DEPS)" "true" +include $(addprefix $(DEPDIR)/, $(DEP_FILES)) +endif diff --git a/runtime/afl.c b/runtime/afl.c index 582449ef..bc6c9826 100644 --- a/runtime/afl.c +++ b/runtime/afl.c @@ -15,7 +15,7 @@ /* Runtime support for afl-fuzz */ #include "caml/config.h" -#if !defined(HAS_SYS_SHM_H) +#if !defined(HAS_SYS_SHM_H) || !defined(HAS_SHMAT) #include "caml/mlvalues.h" diff --git a/runtime/alloc.c b/runtime/alloc.c index 7ae6b62c..189d309d 100644 --- a/runtime/alloc.c +++ b/runtime/alloc.c @@ -69,23 +69,6 @@ CAMLexport value caml_alloc_small (mlsize_t wosize, tag_t tag) return result; } -CAMLexport value caml_alloc_small_with_my_or_given_profinfo (mlsize_t wosize, - tag_t tag, uintnat profinfo) -{ - if (profinfo == 0) { - return caml_alloc_small(wosize, tag); - } - else { - value result; - - CAMLassert (wosize > 0); - CAMLassert (wosize <= Max_young_wosize); - CAMLassert (tag < 256); - Alloc_small_with_profinfo (result, wosize, tag, profinfo); - return result; - } -} - /* [n] is a number of words (fields) */ CAMLexport value caml_alloc_tuple(mlsize_t n) { @@ -227,6 +210,12 @@ CAMLprim value caml_alloc_dummy_infix(value vsize, value voffset) { mlsize_t wosize = Long_val(vsize), offset = Long_val(voffset); value v = caml_alloc(wosize, Closure_tag); + /* The following choice of closure info causes the GC to skip + the whole block contents. This is correct since the dummy + block contains no pointers into the heap. However, the block + cannot be marshaled or hashed, because not all closinfo fields + and infix header fields are correctly initialized. */ + Closinfo_val(v) = Make_closinfo(0, wosize); if (offset > 0) { v += Bsize_wsize(offset); Hd_val(v) = Make_header(offset, Infix_tag, Caml_white); @@ -257,6 +246,10 @@ CAMLprim value caml_update_dummy(value dummy, value newval) dummy = dummy - Infix_offset_val(dummy); size = Wosize_val(clos); CAMLassert (size == Wosize_val(dummy)); + /* It is safe to use [caml_modify] to copy code pointers + from [clos] to [dummy], because the value being overwritten is + an integer, and the new "value" is a pointer outside the minor + heap. */ for (i = 0; i < size; i++) { caml_modify (&Field(dummy, i), Field(clos, i)); } @@ -266,9 +259,19 @@ CAMLprim value caml_update_dummy(value dummy, value newval) Tag_val(dummy) = tag; size = Wosize_val(newval); CAMLassert (size == Wosize_val(dummy)); + /* See comment above why this is safe even if [tag == Closure_tag] + and some of the "values" being copied are actually code pointers. */ for (i = 0; i < size; i++){ caml_modify (&Field(dummy, i), Field(newval, i)); } } return Val_unit; } + +CAMLexport value caml_alloc_some(value v) +{ + CAMLparam1(v); + value some = caml_alloc_small(1, 0); + Field(some, 0) = v; + CAMLreturn(some); +} diff --git a/runtime/amd64.S b/runtime/amd64.S index 2950f1ae..756d4a5a 100644 --- a/runtime/amd64.S +++ b/runtime/amd64.S @@ -58,7 +58,7 @@ #define GREL(r) r@GOTPCREL #define GCALL(r) r@PLT #if defined(FUNCTION_SECTIONS) -#define TEXT_SECTION(name) .section .text.##name,"ax",%progbits +#define TEXT_SECTION(name) .section .text.caml.##name,"ax",%progbits #else #define TEXT_SECTION(name) #endif @@ -66,7 +66,7 @@ #define EIGHT_ALIGN 8 #define SIXTEEN_ALIGN 16 #define FUNCTION(name) \ - TEXT_SECTION(caml.##name); \ + TEXT_SECTION(name); \ .globl name; \ .type name,@function; \ .align FUNCTION_ALIGN; \ @@ -292,6 +292,8 @@ #define C_ARG_4 %rcx #endif + .text + #if defined(FUNCTION_SECTIONS) TEXT_SECTION(caml_hot__code_begin) .globl G(caml_hot__code_begin) @@ -302,8 +304,7 @@ G(caml_hot__code_begin): G(caml_hot__code_end): #endif - .text - + TEXT_SECTION(caml_system__code_begin) .globl G(caml_system__code_begin) G(caml_system__code_begin): ret /* just one instruction, so that debuggers don't display @@ -345,9 +346,6 @@ LBL(caml_call_gc): movq %rsp, Caml_state(gc_regs) /* Save young_ptr */ movq %r15, Caml_state(young_ptr) -#ifdef WITH_SPACETIME - STORE_VAR(%r13, caml_spacetime_trie_node_ptr) -#endif /* Save floating-point registers */ subq $(16*8), %rsp; CFI_ADJUST (16*8); movsd %xmm0, 0*8(%rsp) @@ -457,11 +455,6 @@ LBL(caml_c_call): movq %rsp, Caml_state(bottom_of_stack) /* equivalent to pushing last return address */ subq $8, %rsp; CFI_ADJUST(8) -#ifdef WITH_SPACETIME - /* Record the trie node hole pointer that corresponds to - [Caml_state->last_return_address] */ - STORE_VAR(%r13, caml_spacetime_trie_node_ptr) -#endif /* Touch the stack to trigger a recoverable segfault if insufficient space remains */ subq $(STACK_PROBE_SIZE), %rsp; CFI_ADJUST(STACK_PROBE_SIZE); @@ -489,29 +482,10 @@ FUNCTION(G(caml_start_program)) /* Common code for caml_start_program and caml_callback* */ LBL(caml_start_program): /* Build a callback link */ -#ifdef WITH_SPACETIME - PUSH_VAR(caml_spacetime_trie_node_ptr) -#else subq $8, %rsp; CFI_ADJUST (8) /* stack 16-aligned */ -#endif pushq Caml_state(gc_regs); CFI_ADJUST(8) pushq Caml_state(last_return_address); CFI_ADJUST(8) pushq Caml_state(bottom_of_stack); CFI_ADJUST(8) -#ifdef WITH_SPACETIME - /* Save arguments to caml_callback* */ - pushq %rax; CFI_ADJUST (8) - pushq %rbx; CFI_ADJUST (8) - pushq %rdi; CFI_ADJUST (8) - pushq %rsi; CFI_ADJUST (8) - /* No need to push %r12: it's callee-save. */ - movq %r12, C_ARG_1 - LEA_VAR(caml_start_program, C_ARG_2) - call GCALL(caml_spacetime_c_to_ocaml) - popq %rsi; CFI_ADJUST (-8) - popq %rdi; CFI_ADJUST (-8) - popq %rbx; CFI_ADJUST (-8) - popq %rax; CFI_ADJUST (-8) -#endif /* Setup alloc ptr */ movq Caml_state(young_ptr), %r15 /* Build an exception handler */ @@ -519,9 +493,6 @@ LBL(caml_start_program): pushq %r13; CFI_ADJUST(8) pushq Caml_state(exception_pointer); CFI_ADJUST(8) movq %rsp, Caml_state(exception_pointer) -#ifdef WITH_SPACETIME - LOAD_VAR(caml_spacetime_trie_node_ptr, %r13) -#endif /* Call the OCaml code */ call *%r12 LBL(107): @@ -535,11 +506,7 @@ LBL(109): popq Caml_state(bottom_of_stack); CFI_ADJUST(-8) popq Caml_state(last_return_address); CFI_ADJUST(-8) popq Caml_state(gc_regs); CFI_ADJUST(-8) -#ifdef WITH_SPACETIME - POP_VAR(caml_spacetime_trie_node_ptr) -#else addq $8, %rsp; CFI_ADJUST (-8); -#endif /* Restore callee-save registers. */ POP_CALLEE_SAVE_REGS /* Return to caller. */ @@ -692,6 +659,7 @@ CFI_STARTPROC CFI_ENDPROC ENDFUNCTION(G(caml_ml_array_bound_error)) + TEXT_SECTION(caml_system__code_end) .globl G(caml_system__code_end) G(caml_system__code_end): @@ -708,19 +676,6 @@ G(caml_system__frametable): .quad 0 .string "amd64.S" -#ifdef WITH_SPACETIME - .data - .globl G(caml_system__spacetime_shapes) - .align EIGHT_ALIGN -G(caml_system__spacetime_shapes): - .quad G(caml_start_program) - .quad 2 /* indirect call point to OCaml code */ - .quad LBL(107) /* in caml_start_program / caml_callback* */ - .quad 0 /* end of shapes for caml_start_program */ - .quad 0 /* end of shape table */ - .align EIGHT_ALIGN -#endif - #if defined(SYS_macosx) .literal16 #elif defined(SYS_mingw64) || defined(SYS_cygwin) diff --git a/runtime/amd64nt.asm b/runtime/amd64nt.asm index d34631ab..a625e2a3 100644 --- a/runtime/amd64nt.asm +++ b/runtime/amd64nt.asm @@ -26,10 +26,6 @@ EXTRN caml_program: NEAR EXTRN caml_array_bound_error: NEAR EXTRN caml_stash_backtrace: NEAR -IFDEF WITH_SPACETIME - EXTRN caml_spacetime_trie_node_ptr: QWORD - EXTRN caml_spacetime_c_to_ocaml: NEAR -ENDIF INCLUDE domain_state64.inc @@ -57,9 +53,6 @@ caml_call_gc: add rsp, 01000h ; Save young_ptr Store_young_ptr r15 -IFDEF WITH_SPACETIME - mov caml_spacetime_trie_node_ptr, r13 -ENDIF ; Build array of registers, save it into Caml_state(gc_regs) push rbp push r11 @@ -173,11 +166,6 @@ caml_c_call: pop r12 Store_last_return_address r12 Store_bottom_of_stack rsp -IFDEF WITH_SPACETIME - ; Record the trie node hole pointer that corresponds to - ; [Caml_state(last_return_address)] - mov caml_spacetime_trie_node_ptr, r13 -ENDIF ; Touch the stack to trigger a recoverable segfault ; if insufficient space remains sub rsp, 01000h @@ -225,29 +213,10 @@ caml_start_program: ; Common code for caml_start_program and caml_callback* L106: ; Build a callback link -IFDEF WITH_SPACETIME - push caml_spacetime_trie_node_ptr -ELSE sub rsp, 8 ; stack 16-aligned -ENDIF Push_gc_regs Push_last_return_address Push_bottom_of_stack -IFDEF WITH_SPACETIME - ; Save arguments to caml_callback - push rax - push rbx - push rdi - push rsi - ; No need to push r12: it is callee-save. - mov rcx, r12 - lea rdx, caml_start_program - call caml_spacetime_c_to_ocaml - pop rsi - pop rdi - pop rbx - pop rax -ENDIF ; Setup alloc ptr Load_young_ptr r15 ; Build an exception handler @@ -255,9 +224,6 @@ ENDIF push r13 Push_exception_pointer Store_exception_pointer rsp -IFDEF WITH_SPACETIME - mov r13, caml_spacetime_trie_node_ptr -ENDIF ; Call the OCaml code call r12 L107: @@ -271,11 +237,7 @@ L109: Pop_bottom_of_stack Pop_last_return_address Pop_gc_regs -IFDEF WITH_SPACETIME - pop caml_spacetime_trie_node_ptr -ELSE add rsp, 8 -ENDIF ; Restore callee-save registers. movapd xmm6, OWORD PTR [rsp + 0*16] movapd xmm7, OWORD PTR [rsp + 1*16] @@ -473,19 +435,6 @@ caml_system__frametable LABEL QWORD WORD 0 ; no roots here ALIGN 8 -IFDEF WITH_SPACETIME - .DATA - PUBLIC caml_system__spacetime_shapes - ALIGN 8 -caml_system__spacetime_shapes LABEL QWORD - QWORD caml_start_program - QWORD 2 ; indirect call point to OCaml code - QWORD L107 ; in caml_start_program / caml_callback* - QWORD 0 ; end of shapes in caml_start_program - QWORD 0 ; end of shape table - ALIGN 8 -ENDIF - PUBLIC caml_negf_mask ALIGN 16 caml_negf_mask LABEL QWORD diff --git a/runtime/arm.S b/runtime/arm.S index 85ebb84e..612757a1 100644 --- a/runtime/arm.S +++ b/runtime/arm.S @@ -100,13 +100,13 @@ domain_state_ptr .req r11 #endif #if defined(FUNCTION_SECTIONS) -#define TEXT_SECTION(name) .section .text.##name,"ax",%progbits +#define TEXT_SECTION(name) .section .text.caml.##name,"ax",%progbits #else #define TEXT_SECTION(name) #endif #define FUNCTION(name) \ - TEXT_SECTION(caml.##name); \ + TEXT_SECTION(name); \ .align 2; \ .globl name; \ .type name, %function; \ @@ -132,6 +132,7 @@ caml_hot__code_end: #define Caml_state(var) [domain_state_ptr, 8*domain_field_caml_##var] /* Allocation functions and GC interface */ + TEXT_SECTION(caml_system__code_begin) .globl caml_system__code_begin caml_system__code_begin: @@ -424,6 +425,7 @@ FUNCTION(caml_ml_array_bound_error) CFI_ENDPROC .size caml_ml_array_bound_error, .-caml_ml_array_bound_error + TEXT_SECTION(caml_system__code_end) .globl caml_system__code_end caml_system__code_end: diff --git a/runtime/arm64.S b/runtime/arm64.S index 6bad4ce8..30092c8d 100644 --- a/runtime/arm64.S +++ b/runtime/arm64.S @@ -24,10 +24,9 @@ #define TRAP_PTR x26 #define ALLOC_PTR x27 #define ALLOC_LIMIT x28 -#define ARG x15 +#define ADDITIONAL_ARG x8 #define TMP x16 #define TMP2 x17 -#define ARG_DOMAIN_STATE_PTR x18 #define C_ARG_1 x0 #define C_ARG_2 x1 @@ -51,57 +50,115 @@ #endif .set domain_curr_field, 0 +#if defined(SYS_macosx) +#define DOMAIN_STATE(c_type, name) DOMAIN_STATE c_type, name + .macro DOMAIN_STATE c_type, name + .equ domain_field_caml_\name, domain_curr_field + .set domain_curr_field, domain_curr_field + 1 + .endm +#else #define DOMAIN_STATE(c_type, name) \ .equ domain_field_caml_##name, domain_curr_field ; \ .set domain_curr_field, domain_curr_field + 1 +#endif #include "../runtime/caml/domain_state.tbl" #undef DOMAIN_STATE #define Caml_state(var) [x25, 8*domain_field_caml_##var] -#if defined(__PIC__) +/* Globals and labels */ +#if defined(SYS_macosx) +#define G(sym) _##sym +#define L(lbl) L##lbl +#else +#define G(sym) sym +#define L(lbl) .L##lbl +#endif + +#if defined(SYS_macosx) +#define ADDRGLOBAL(reg,symb) ADDRGLOBAL reg, symb + .macro ADDRGLOBAL reg, symb + adrp TMP2, G(\symb)@GOTPAGE + ldr \reg, [TMP2, G(\symb)@GOTPAGEOFF] + .endm +#elif defined(__PIC__) #define ADDRGLOBAL(reg,symb) \ - adrp TMP2, :got:symb; \ - ldr reg, [TMP2, #:got_lo12:symb] + adrp TMP2, :got:G(symb); \ + ldr reg, [TMP2, #:got_lo12:G(symb)] #else #define ADDRGLOBAL(reg,symb) \ - adrp reg, symb; \ - add reg, reg, #:lo12:symb + adrp reg, G(symb); \ + add reg, reg, #:lo12:G(symb) #endif #if defined(FUNCTION_SECTIONS) -#define TEXT_SECTION(name) .section .text.##name,"ax",%progbits +#define TEXT_SECTION(name) .section .text.caml.##name,"ax",%progbits #else #define TEXT_SECTION(name) #endif #if defined(FUNCTION_SECTIONS) TEXT_SECTION(caml_hot__code_begin) - .globl caml_hot__code_begin -caml_hot__code_begin: + .globl G(caml_hot__code_begin) +G(caml_hot__code_begin): TEXT_SECTION(caml_hot__code_end) - .globl caml_hot__code_end -caml_hot__code_end: + .globl G(caml_hot__code_end) +G(caml_hot__code_end): #endif +#if defined(SYS_macosx) + +#define FUNCTION(name) FUNCTION name + .macro FUNCTION name + TEXT_SECTION(G(\name)) + .align 2 + .globl G(\name) +G(\name): + .endm +#define END_FUNCTION(name) + +#define OBJECT(name) OBJECT name + .macro OBJECT name + .data + .align 3 + .globl G(\name) +G(\name): + .endm +#define END_OBJECT(name) + +#else + #define FUNCTION(name) \ - TEXT_SECTION(caml.##name); \ - .align 2; \ - .globl name; \ - .type name, %function; \ -name: + TEXT_SECTION(name); \ + .align 2; \ + .globl G(name); \ + .type G(name), %function; \ +G(name): +#define END_FUNCTION(name) \ + .size G(name), .-G(name) + +#define OBJECT(name) \ + .data; \ + .align 3; \ + .globl G(name); \ + .type G(name), %object; \ +G(name): +#define END_OBJECT(name) \ + .size G(name), .-G(name) +#endif /* Allocation functions and GC interface */ - .globl caml_system__code_begin -caml_system__code_begin: + TEXT_SECTION(caml_system__code_begin) + .globl G(caml_system__code_begin) +G(caml_system__code_begin): FUNCTION(caml_call_gc) CFI_STARTPROC -.Lcaml_call_gc: +L(caml_call_gc): /* Record return address */ str x30, Caml_state(last_return_address) /* Record lowest stack address */ @@ -150,7 +207,7 @@ FUNCTION(caml_call_gc) /* Save trap pointer in case an exception is raised during GC */ str TRAP_PTR, Caml_state(exception_pointer) /* Call the garbage collector */ - bl caml_garbage_collection + bl G(caml_garbage_collection) /* Restore registers */ ldp x0, x1, [sp, 16] ldp x2, x3, [sp, 32] @@ -183,46 +240,46 @@ FUNCTION(caml_call_gc) ldp x29, x30, [sp], 400 ret CFI_ENDPROC - .size caml_call_gc, .-caml_call_gc + END_FUNCTION(caml_call_gc) FUNCTION(caml_alloc1) CFI_STARTPROC sub ALLOC_PTR, ALLOC_PTR, #16 cmp ALLOC_PTR, ALLOC_LIMIT - b.lo .Lcaml_call_gc + b.lo L(caml_call_gc) ret CFI_ENDPROC - .size caml_alloc1, .-caml_alloc1 + END_FUNCTION(caml_alloc1) FUNCTION(caml_alloc2) CFI_STARTPROC sub ALLOC_PTR, ALLOC_PTR, #24 cmp ALLOC_PTR, ALLOC_LIMIT - b.lo .Lcaml_call_gc + b.lo L(caml_call_gc) ret CFI_ENDPROC - .size caml_alloc2, .-caml_alloc2 + END_FUNCTION(caml_alloc2) FUNCTION(caml_alloc3) CFI_STARTPROC sub ALLOC_PTR, ALLOC_PTR, #32 cmp ALLOC_PTR, ALLOC_LIMIT - b.lo .Lcaml_call_gc + b.lo L(caml_call_gc) ret CFI_ENDPROC - .size caml_alloc3, .-caml_alloc3 + END_FUNCTION(caml_alloc3) FUNCTION(caml_allocN) CFI_STARTPROC - sub ALLOC_PTR, ALLOC_PTR, ARG + sub ALLOC_PTR, ALLOC_PTR, ADDITIONAL_ARG cmp ALLOC_PTR, ALLOC_LIMIT - b.lo .Lcaml_call_gc + b.lo L(caml_call_gc) ret CFI_ENDPROC - .size caml_allocN, .-caml_allocN + END_FUNCTION(caml_allocN) /* Call a C function from OCaml */ -/* Function to call is in ARG */ +/* Function to call is in ADDITIONAL_ARG */ FUNCTION(caml_c_call) CFI_STARTPROC @@ -237,27 +294,28 @@ FUNCTION(caml_c_call) str ALLOC_PTR, Caml_state(young_ptr) str TRAP_PTR, Caml_state(exception_pointer) /* Call the function */ - blr ARG + blr ADDITIONAL_ARG /* Reload alloc ptr and alloc limit */ ldr ALLOC_PTR, Caml_state(young_ptr) ldr ALLOC_LIMIT, Caml_state(young_limit) /* Return */ ret x19 CFI_ENDPROC - .size caml_c_call, .-caml_c_call + END_FUNCTION(caml_c_call) /* Start the OCaml program */ FUNCTION(caml_start_program) CFI_STARTPROC - mov ARG_DOMAIN_STATE_PTR, C_ARG_1 - ADDRGLOBAL(ARG, caml_program) + mov TMP, C_ARG_1 + ADDRGLOBAL(TMP2, caml_program) /* Code shared with caml_callback* */ -/* Address of OCaml code to call is in ARG */ +/* Address of domain state is in TMP */ +/* Address of OCaml code to call is in TMP2 */ /* Arguments to the OCaml code are in x0...x7 */ -.Ljump_to_caml: +L(jump_to_caml): /* Set up stack frame and save callee-save registers */ CFI_OFFSET(29, -160) CFI_OFFSET(30, -152) @@ -274,7 +332,7 @@ FUNCTION(caml_start_program) stp d12, d13, [sp, 128] stp d14, d15, [sp, 144] /* Load domain state pointer from argument */ - mov DOMAIN_STATE_PTR, ARG_DOMAIN_STATE_PTR + mov DOMAIN_STATE_PTR, TMP /* Setup a callback link on the stack */ ldr x8, Caml_state(bottom_of_stack) ldr x9, Caml_state(last_return_address) @@ -284,7 +342,7 @@ FUNCTION(caml_start_program) str x10, [sp, 16] /* Setup a trap frame to catch exceptions escaping the OCaml code */ ldr x8, Caml_state(exception_pointer) - adr x9, .Ltrap_handler + adr x9, L(trap_handler) stp x8, x9, [sp, -16]! CFI_ADJUST(16) add TRAP_PTR, sp, #0 @@ -292,14 +350,14 @@ FUNCTION(caml_start_program) ldr ALLOC_PTR, Caml_state(young_ptr) ldr ALLOC_LIMIT, Caml_state(young_limit) /* Call the OCaml code */ - blr ARG -.Lcaml_retaddr: + blr TMP2 +L(caml_retaddr): /* Pop the trap frame, restoring caml_exception_pointer */ ldr x8, [sp], 16 CFI_ADJUST(-16) str x8, Caml_state(exception_pointer) /* Pop the callback link, restoring the global variables */ -.Lreturn_result: +L(return_result): ldr x10, [sp, 16] ldp x8, x9, [sp], 32 CFI_ADJUST(-32) @@ -323,24 +381,20 @@ FUNCTION(caml_start_program) /* Return to C caller */ ret CFI_ENDPROC - .type .Lcaml_retaddr, %function - .size .Lcaml_retaddr, .-.Lcaml_retaddr - .size caml_start_program, .-caml_start_program + END_FUNCTION(caml_start_program) /* The trap handler */ .align 2 -.Ltrap_handler: +L(trap_handler): CFI_STARTPROC /* Save exception pointer */ str TRAP_PTR, Caml_state(exception_pointer) /* Encode exception bucket as an exception result */ orr x0, x0, #2 /* Return it */ - b .Lreturn_result + b L(return_result) CFI_ENDPROC - .type .Ltrap_handler, %function - .size .Ltrap_handler, .-.Ltrap_handler /* Raise an exception from OCaml */ @@ -362,12 +416,12 @@ FUNCTION(caml_raise_exn) mov x1, x30 /* arg2: pc of raise */ add x2, sp, #0 /* arg3: sp of raise */ mov x3, TRAP_PTR /* arg4: sp of handler */ - bl caml_stash_backtrace + bl G(caml_stash_backtrace) /* Restore exception bucket and raise */ mov x0, x19 b 1b CFI_ENDPROC - .size caml_raise_exn, .-caml_raise_exn + END_FUNCTION(caml_raise_exn) /* Raise an exception from C */ @@ -397,12 +451,12 @@ FUNCTION(caml_raise_exception) ldr x1, Caml_state(last_return_address) /* arg2: pc of raise */ ldr x2, Caml_state(bottom_of_stack) /* arg3: sp of raise */ mov x3, TRAP_PTR /* arg4: sp of handler */ - bl caml_stash_backtrace + bl G(caml_stash_backtrace) /* Restore exception bucket and raise */ mov x0, x19 b 1b CFI_ENDPROC - .size caml_raise_exception, .-caml_raise_exception + END_FUNCTION(caml_raise_exception) /* Callback from C to OCaml */ @@ -410,74 +464,65 @@ FUNCTION(caml_callback_asm) CFI_STARTPROC /* Initial shuffling of arguments */ /* (x0 = Caml_state, x1 = closure, [x2] = first arg) */ - mov ARG_DOMAIN_STATE_PTR, x0 + mov TMP, x0 ldr x0, [x2] /* x0 = first arg */ /* x1 = closure environment */ - ldr ARG, [x1] /* code pointer */ - b .Ljump_to_caml + ldr TMP2, [x1] /* code pointer */ + b L(jump_to_caml) CFI_ENDPROC - .type caml_callback_asm, %function - .size caml_callback_asm, .-caml_callback_asm + END_FUNCTION(caml_callback_asm) - TEXT_SECTION(caml_callback2_asm) - .align 2 - .globl caml_callback2_asm -caml_callback2_asm: +FUNCTION(caml_callback2_asm) CFI_STARTPROC /* Initial shuffling of arguments */ /* (x0 = Caml_state, x1 = closure, [x2] = arg1, [x2,8] = arg2) */ - mov ARG_DOMAIN_STATE_PTR, x0 - mov TMP, x1 + mov TMP, x0 + mov TMP2, x1 ldp x0, x1, [x2, 0] /* x0 = first arg, x1 = second arg */ - mov x2, TMP /* x2 = closure environment */ - ADDRGLOBAL(ARG, caml_apply2) - b .Ljump_to_caml + mov x2, TMP2 /* x2 = closure environment */ + ADDRGLOBAL(TMP2, caml_apply2) + b L(jump_to_caml) CFI_ENDPROC - .type caml_callback2_asm, %function - .size caml_callback2_asm, .-caml_callback2_asm + END_FUNCTION(caml_callback2_asm) - TEXT_SECTION(caml_callback3_asm) - .align 2 - .globl caml_callback3_asm -caml_callback3_asm: +FUNCTION(caml_callback3_asm) CFI_STARTPROC /* Initial shuffling of arguments */ /* (x0 = Caml_state, x1 = closure, [x2] = arg1, [x2,8] = arg2, [x2,16] = arg3) */ - mov ARG_DOMAIN_STATE_PTR, x0 + mov TMP, x0 mov x3, x1 /* x3 = closure environment */ ldp x0, x1, [x2, 0] /* x0 = first arg, x1 = second arg */ ldr x2, [x2, 16] /* x2 = third arg */ - ADDRGLOBAL(ARG, caml_apply3) - b .Ljump_to_caml + ADDRGLOBAL(TMP2, caml_apply3) + b L(jump_to_caml) CFI_ENDPROC - .size caml_callback3_asm, .-caml_callback3_asm + END_FUNCTION(caml_callback3_asm) FUNCTION(caml_ml_array_bound_error) CFI_STARTPROC - /* Load address of [caml_array_bound_error] in ARG */ - ADDRGLOBAL(ARG, caml_array_bound_error) + /* Load address of [caml_array_bound_error] in ADDITIONAL_ARG */ + ADDRGLOBAL(ADDITIONAL_ARG, caml_array_bound_error) /* Call that function */ - b caml_c_call + b G(caml_c_call) CFI_ENDPROC - .size caml_ml_array_bound_error, .-caml_ml_array_bound_error + END_FUNCTION(caml_ml_array_bound_error) - .globl caml_system__code_end -caml_system__code_end: + TEXT_SECTION(caml_system__code_end) + .globl G(caml_system__code_end) +G(caml_system__code_end): /* GC roots for callback */ - .data - .align 3 - .globl caml_system__frametable -caml_system__frametable: +OBJECT(caml_system__frametable) .quad 1 /* one descriptor */ - .quad .Lcaml_retaddr /* return address into callback */ + .quad L(caml_retaddr) /* return address into callback */ .short -1 /* negative frame size => use callback link */ .short 0 /* no roots */ .align 3 - .type caml_system__frametable, %object - .size caml_system__frametable, .-caml_system__frametable + END_OBJECT(caml_system__frametable) +#if !defined(SYS_macosx) /* Mark stack as non-executable */ .section .note.GNU-stack,"",%progbits +#endif diff --git a/runtime/array.c b/runtime/array.c index 37af6b7f..9c93e0bf 100644 --- a/runtime/array.c +++ b/runtime/array.c @@ -24,8 +24,6 @@ #include "caml/mlvalues.h" #include "caml/signals.h" #include "caml/eventlog.h" -/* Why is caml/spacetime.h included conditionnally sometimes and not here ? */ -#include "caml/spacetime.h" static const mlsize_t mlsize_t_max = -1; @@ -285,7 +283,6 @@ CAMLprim value caml_floatarray_create(value len) } /* [len] is a [value] representing number of words or floats */ -/* Spacetime profiling assumes that this function is only called from OCaml. */ CAMLprim value caml_make_vect(value len, value init) { CAMLparam2 (len, init); @@ -311,9 +308,7 @@ CAMLprim value caml_make_vect(value len, value init) #endif } else { if (size <= Max_young_wosize) { - uintnat profinfo; - Get_my_profinfo_with_cached_backtrace(profinfo, size); - res = caml_alloc_small_with_my_or_given_profinfo(size, 0, profinfo); + res = caml_alloc_small(size, 0); for (i = 0; i < size; i++) Field(res, i) = init; } else if (size > Max_wosize) caml_invalid_argument("Array.make"); @@ -397,6 +392,15 @@ CAMLprim value caml_make_array(value init) /* Blitting */ +CAMLprim value caml_floatarray_blit(value a1, value ofs1, value a2, value ofs2, + value n) +{ + memmove((double *)a2 + Long_val(ofs2), + (double *)a1 + Long_val(ofs1), + Long_val(n) * sizeof(double)); + return Val_unit; +} + CAMLprim value caml_array_blit(value a1, value ofs1, value a2, value ofs2, value n) { diff --git a/runtime/backtrace.c b/runtime/backtrace.c index 3e68a356..cfce56de 100644 --- a/runtime/backtrace.c +++ b/runtime/backtrace.c @@ -27,6 +27,7 @@ #include "caml/backtrace_prim.h" #include "caml/fail.h" #include "caml/debugger.h" +#include "caml/startup.h" void caml_init_backtrace(void) { @@ -121,6 +122,38 @@ CAMLexport void caml_print_exception_backtrace(void) print_location(&li, i); } } + + /* See also printexc.ml */ + switch (caml_debug_info_status()) { + case FILE_NOT_FOUND: + fprintf(stderr, + "(Cannot print locations:\n " + "bytecode executable program file not found)\n"); + break; + case BAD_BYTECODE: + fprintf(stderr, + "(Cannot print locations:\n " + "bytecode executable program file appears to be corrupt)\n"); + break; + case WRONG_MAGIC: + fprintf(stderr, + "(Cannot print locations:\n " + "bytecode executable program file has wrong magic number)\n"); + break; + case NO_FDS: + fprintf(stderr, + "(Cannot print locations:\n " + "bytecode executable program file cannot be opened;\n " + "-- too many open files. Try running with OCAMLRUNPARAM=b=2)\n"); + break; + } +} + +/* Return the status of loading backtrace information (error reporting in + bytecode) */ +CAMLprim value caml_ml_debug_info_status(value unit) +{ + return Val_int(caml_debug_info_status()); } /* Get a copy of the latest backtrace */ diff --git a/runtime/backtrace_byt.c b/runtime/backtrace_byt.c index 28fe44c7..9eb99335 100644 --- a/runtime/backtrace_byt.c +++ b/runtime/backtrace_byt.c @@ -304,7 +304,7 @@ code_t caml_next_frame_pointer(value ** sp, value ** trsp) if (Is_long(*spv)) continue; p = (code_t*) spv; if(&Trap_pc(*trsp) == p) { - *trsp = Trap_link(*trsp); + *trsp = *trsp + Long_val(Trap_link_offset(*trsp)); continue; } @@ -377,8 +377,9 @@ static void read_main_debug_info(struct debug_info *di) } fd = caml_attempt_open(&exec_name, &trail, 1); - if (fd < 0){ - caml_fatal_error ("executable program file not found"); + if (fd < 0) { + /* Record the failure of caml_attempt_open in di->already-read */ + di->already_read = fd; CAMLreturn0; } @@ -386,6 +387,7 @@ static void read_main_debug_info(struct debug_info *di) if (caml_seek_optional_section(fd, &trail, "DBUG") != -1) { chan = caml_open_descriptor_in(fd); + Lock(chan); num_events = caml_getword(chan); events = caml_alloc(num_events, 0); @@ -401,10 +403,13 @@ static void read_main_debug_info(struct debug_info *di) /* Record event list */ Store_field(events, i, evl); } + Unlock(chan); caml_close_channel(chan); di->events = process_debug_events(caml_start_code, events, &di->num_events); + } else { + close(fd); } CAMLreturn0; @@ -416,11 +421,27 @@ CAMLexport void caml_init_debug_info(void) caml_add_debug_info(caml_start_code, Val_long(caml_code_size), Val_unit); } +CAMLexport void caml_load_main_debug_info(void) +{ + if (Caml_state->backtrace_active > 1) { + read_main_debug_info(caml_debug_info.contents[0]); + } +} + int caml_debug_info_available(void) { return (caml_debug_info.size != 0); } +int caml_debug_info_status(void) +{ + if (!caml_debug_info_available()) { + return 0; + } else { + return ((struct debug_info *)caml_debug_info.contents[0])->already_read; + } +} + /* Search the event index for the given PC. Return -1 if not found. */ static struct ev_info *event_for_location(code_t pc) diff --git a/runtime/backtrace_nat.c b/runtime/backtrace_nat.c index 893ba15d..5da300fb 100644 --- a/runtime/backtrace_nat.c +++ b/runtime/backtrace_nat.c @@ -295,3 +295,8 @@ int caml_debug_info_available(void) { return 1; } + +int caml_debug_info_status(void) +{ + return 1; +} diff --git a/runtime/callback.c b/runtime/callback.c index 71936374..347e3a9d 100644 --- a/runtime/callback.c +++ b/runtime/callback.c @@ -28,6 +28,7 @@ /* Bytecode callbacks */ +#include "caml/codefrag.h" #include "caml/interp.h" #include "caml/instruct.h" #include "caml/fix_code.h" @@ -35,73 +36,38 @@ CAMLexport int caml_callback_depth = 0; -#ifndef LOCAL_CALLBACK_BYTECODE static opcode_t callback_code[] = { ACC, 0, APPLY, 0, POP, 1, STOP }; -#endif - -#ifdef THREADED_CODE +static int callback_code_inited = 0; -static int callback_code_threaded = 0; - -static void thread_callback(void) +static void init_callback_code(void) { + caml_register_code_fragment((char *) callback_code, + (char *) callback_code + sizeof(callback_code), + DIGEST_IGNORE, NULL); +#ifdef THREADED_CODE caml_thread_code(callback_code, sizeof(callback_code)); - callback_code_threaded = 1; -} - -#define Init_callback() if (!callback_code_threaded) thread_callback() - -#else - -#define Init_callback() - #endif + callback_code_inited = 1; +} CAMLexport value caml_callbackN_exn(value closure, int narg, value args[]) { int i; value res; - /* some alternate bytecode implementations (e.g. a JIT translator) - might require that the bytecode is kept in a local variable on - the C stack */ -#ifdef LOCAL_CALLBACK_BYTECODE - opcode_t local_callback_code[7]; -#endif - CAMLassert(narg + 4 <= 256); Caml_state->extern_sp -= narg + 4; for (i = 0; i < narg; i++) Caml_state->extern_sp[i] = args[i]; /* arguments */ -#ifndef LOCAL_CALLBACK_BYTECODE Caml_state->extern_sp[narg] = (value)(callback_code + 4); /* return address */ Caml_state->extern_sp[narg + 1] = Val_unit; /* environment */ Caml_state->extern_sp[narg + 2] = Val_long(0); /* extra args */ Caml_state->extern_sp[narg + 3] = closure; - Init_callback(); + if (!callback_code_inited) init_callback_code(); callback_code[1] = narg + 3; callback_code[3] = narg; res = caml_interprete(callback_code, sizeof(callback_code)); -#else /*have LOCAL_CALLBACK_BYTECODE*/ - /* return address */ - Caml_state->extern_sp[narg] = (value) (local_callback_code + 4); - Caml_state->extern_sp[narg + 1] = Val_unit; /* environment */ - Caml_state->extern_sp[narg + 2] = Val_long(0); /* extra args */ - Caml_state->extern_sp[narg + 3] = closure; - local_callback_code[0] = ACC; - local_callback_code[1] = narg + 3; - local_callback_code[2] = APPLY; - local_callback_code[3] = narg; - local_callback_code[4] = POP; - local_callback_code[5] = 1; - local_callback_code[6] = STOP; -#ifdef THREADED_CODE - caml_thread_code(local_callback_code, sizeof(local_callback_code)); -#endif /*THREADED_CODE*/ - res = caml_interprete(local_callback_code, sizeof(local_callback_code)); - caml_release_bytecode(local_callback_code, sizeof(local_callback_code)); -#endif /*LOCAL_CALLBACK_BYTECODE*/ if (Is_exception_result(res)) Caml_state->extern_sp += narg + 4; /* PR#3419 */ return res; } diff --git a/runtime/caml/address_class.h b/runtime/caml/address_class.h index 45e5410e..82e5cf71 100644 --- a/runtime/caml/address_class.h +++ b/runtime/caml/address_class.h @@ -15,6 +15,46 @@ /* Classification of addresses for GC and runtime purposes. */ +/* The current runtime supports two different configurations that + correspond to two different value models, depending on whether + "naked pointers", that do not point to a well-formed OCaml block, + are allowed (considered valid values). + + In "classic mode", naked pointers are allowed, and the + implementation uses a page table. A valid value is then either: + - a tagged integer (Is_long or !Is_block from mlvalues.h) + - a pointer to the minor heap (Is_young) + - a pointer to the major heap (Is_in_heap) + - a pointer to a constant block statically-allocated by OCaml code + or the OCaml runtime (Is_in_static_data) + - a "foreign" pointer, which is none of the above; the destination + of those pointers may be a well-formed OCaml blocks, but it may + also be a naked pointer. + + The macros and functions below give access to a global page table + to classify addresses to be able to implement Is_in_heap, + In_static_data (or their disjunction Is_in_value_area) and thus + detect values which may be naked pointers. The runtime + conservatively assumes that all foreign pointers may be naked + pointers, and uses the page table to not dereference/follow them. + + In "no naked pointers" mode (when NO_NAKED_POINTERS is defined), + naked pointers are illegal, so pointers that are values can always + be assumed to point to well-formed blocks. + + To support an implementation without a global page table, runtime + code should not rely on Is_in_heap and Is_in_static_data. This + corresponds to a simpler model where a valid value is either: + - a tagged integer (Is_long) + - a pointer to the minor heap (Is_young) + - a pointer to a well-formed block outside the minor heap + (it may be in the major heap, or static, or a foreign pointer, + without a check to distinguish the various cases). + + (To create a well-formed block outside the heap that the GC will + not scan, one can use the Caml_out_of_heap_header from mlvalues.h.) +*/ + #ifndef CAML_ADDRESS_CLASS_H #define CAML_ADDRESS_CLASS_H @@ -32,28 +72,29 @@ #define Is_in_heap(a) (Classify_addr(a) & In_heap) +#ifdef NO_NAKED_POINTERS + +#define Is_in_heap_or_young(a) 1 +#define Is_in_value_area(a) 1 + +#else + #define Is_in_heap_or_young(a) (Classify_addr(a) & (In_heap | In_young)) #define Is_in_value_area(a) \ (Classify_addr(a) & (In_heap | In_young | In_static_data)) -#define Is_in_code_area(pc) \ - ( ((char *)(pc) >= caml_code_area_start && \ - (char *)(pc) <= caml_code_area_end) \ - || (Classify_addr(pc) & In_code_area) ) - #define Is_in_static_data(a) (Classify_addr(a) & In_static_data) +#endif + /***********************************************************************/ /* The rest of this file is private and may change without notice. */ -extern char * caml_code_area_start, * caml_code_area_end; - #define Not_in_heap 0 #define In_heap 1 #define In_young 2 #define In_static_data 4 -#define In_code_area 8 #ifdef ARCH_SIXTYFOUR diff --git a/runtime/caml/alloc.h b/runtime/caml/alloc.h index 7e2be4b0..13f0fac2 100644 --- a/runtime/caml/alloc.h +++ b/runtime/caml/alloc.h @@ -49,11 +49,7 @@ CAMLextern value caml_alloc_sprintf(const char * format, ...) __attribute__ ((format (printf, 1, 2))) #endif ; - -CAMLextern value caml_alloc_with_profinfo (mlsize_t, tag_t, intnat); -CAMLextern value caml_alloc_small_with_my_or_given_profinfo ( - mlsize_t, tag_t, uintnat); -CAMLextern value caml_alloc_small_with_profinfo (mlsize_t, tag_t, intnat); +CAMLextern value caml_alloc_some(value); typedef void (*final_fun)(value); CAMLextern value caml_alloc_final (mlsize_t wosize, diff --git a/runtime/caml/backtrace.h b/runtime/caml/backtrace.h index 5cf24b85..37a804c6 100644 --- a/runtime/caml/backtrace.h +++ b/runtime/caml/backtrace.h @@ -96,7 +96,7 @@ * It might be called before GC initialization, so it shouldn't do OCaml * allocation. */ -CAMLprim value caml_record_backtrace(value vflag); +CAMLextern value caml_record_backtrace(value vflag); #ifndef NATIVE_CODE @@ -109,6 +109,7 @@ CAMLextern char_os * caml_cds_file; * different prototype. */ extern void caml_stash_backtrace(value exn, value * sp, int reraise); +CAMLextern void caml_load_main_debug_info(void); #endif @@ -122,7 +123,7 @@ extern void caml_stash_backtrace(value exn, value * sp, int reraise); CAMLextern void caml_print_exception_backtrace(void); void caml_init_backtrace(void); -CAMLexport void caml_init_debug_info(void); +CAMLextern void caml_init_debug_info(void); #endif /* CAML_INTERNALS */ diff --git a/runtime/caml/backtrace_prim.h b/runtime/caml/backtrace_prim.h index cf9596d3..cd084da0 100644 --- a/runtime/caml/backtrace_prim.h +++ b/runtime/caml/backtrace_prim.h @@ -52,6 +52,12 @@ typedef void * debuginfo; * Relevant for bytecode, always true for native code. */ int caml_debug_info_available(void); +/* Check load status of debug information for the main program. This is always 1 + * for native code. For bytecode, it is 1 if the debug information has been + * loaded, 0 if it has not been loaded or one of the error constants in + * startup.h if something went wrong loading the debug information. */ +int caml_debug_info_status(void); + /* Return debuginfo associated to a slot or NULL. */ debuginfo caml_debuginfo_extract(backtrace_slot slot); diff --git a/runtime/caml/compatibility.h b/runtime/caml/compatibility.h index 1ec4df3f..1c0150e6 100644 --- a/runtime/caml/compatibility.h +++ b/runtime/caml/compatibility.h @@ -264,7 +264,6 @@ #define something_to_do caml_something_to_do #define enter_blocking_section_hook caml_enter_blocking_section_hook #define leave_blocking_section_hook caml_leave_blocking_section_hook -#define try_leave_blocking_section_hook caml_try_leave_blocking_section_hook #define enter_blocking_section caml_enter_blocking_section #define leave_blocking_section caml_leave_blocking_section #define convert_signal_number caml_convert_signal_number diff --git a/runtime/caml/config.h b/runtime/caml/config.h index d42a9205..5e06f022 100644 --- a/runtime/caml/config.h +++ b/runtime/caml/config.h @@ -101,7 +101,7 @@ #endif #endif -#ifdef __MINGW32__ +#if defined(__MINGW32__) && !__USE_MINGW_ANSI_STDIO #define ARCH_INT64_TYPE long long #define ARCH_UINT64_TYPE unsigned long long #define ARCH_INT64_PRINTF_FORMAT "I64" @@ -179,7 +179,7 @@ typedef uint64_t uintnat; as first-class values (GCC 2.x). */ #if defined(__GNUC__) && __GNUC__ >= 2 && !defined(DEBUG) \ - && !defined (SHRINKED_GNUC) && !defined(CAML_JIT) + && !defined (SHRINKED_GNUC) #define THREADED_CODE #endif diff --git a/runtime/caml/custom.h b/runtime/caml/custom.h index 2713867b..420121f4 100644 --- a/runtime/caml/custom.h +++ b/runtime/caml/custom.h @@ -75,6 +75,11 @@ extern struct custom_operations * caml_final_custom_operations(void (*fn)(value)); extern void caml_init_custom_operations(void); + +extern struct custom_operations caml_nativeint_ops; +extern struct custom_operations caml_int32_ops; +extern struct custom_operations caml_int64_ops; +extern struct custom_operations caml_ba_ops; #endif /* CAML_INTERNALS */ #ifdef __cplusplus diff --git a/runtime/caml/debugger.h b/runtime/caml/debugger.h index f5b27f61..a5f90226 100644 --- a/runtime/caml/debugger.h +++ b/runtime/caml/debugger.h @@ -35,7 +35,7 @@ enum event_kind { void caml_debugger_init (void); void caml_debugger (enum event_kind event, value param); -void caml_debugger_cleanup_fork (void); +CAMLextern void caml_debugger_cleanup_fork (void); opcode_t caml_debugger_saved_instruction(code_t pc); diff --git a/runtime/caml/domain_state.tbl b/runtime/caml/domain_state.tbl index ef838433..f094d37f 100644 --- a/runtime/caml/domain_state.tbl +++ b/runtime/caml/domain_state.tbl @@ -36,6 +36,9 @@ DOMAIN_STATE(struct caml_ephe_ref_table*, ephe_ref_table) DOMAIN_STATE(struct caml_custom_table*, custom_table) /* See minor_gc.c */ +DOMAIN_STATE(struct mark_stack*, mark_stack) +/* See major_gc.c */ + DOMAIN_STATE(value*, stack_low) DOMAIN_STATE(value*, stack_high) DOMAIN_STATE(value*, stack_threshold) @@ -71,12 +74,18 @@ DOMAIN_STATE(intnat, stat_major_collections) DOMAIN_STATE(intnat, stat_heap_wsz) DOMAIN_STATE(intnat, stat_top_heap_wsz) DOMAIN_STATE(intnat, stat_compactions) +DOMAIN_STATE(intnat, stat_forced_major_collections) DOMAIN_STATE(intnat, stat_heap_chunks) /* See gc_ctrl.c */ DOMAIN_STATE(uintnat, eventlog_startup_timestamp) -DOMAIN_STATE(uint32_t, eventlog_startup_pid) +DOMAIN_STATE(long, eventlog_startup_pid) DOMAIN_STATE(uintnat, eventlog_paused) DOMAIN_STATE(uintnat, eventlog_enabled) DOMAIN_STATE(FILE*, eventlog_out) /* See eventlog.c */ + +#if defined(NAKED_POINTERS_CHECKER) && !defined(_WIN32) +DOMAIN_STATE(void*, checking_pointer_pc) +/* See major_gc.c */ +#endif diff --git a/runtime/caml/exec.h b/runtime/caml/exec.h index c8b4ab37..a2cf546a 100644 --- a/runtime/caml/exec.h +++ b/runtime/caml/exec.h @@ -60,7 +60,7 @@ struct exec_trailer { /* Magic number for this release */ -#define EXEC_MAGIC "Caml1999X028" +#define EXEC_MAGIC "Caml1999X029" #endif /* CAML_INTERNALS */ diff --git a/runtime/caml/fail.h b/runtime/caml/fail.h index ca4d8fd4..677b1f72 100644 --- a/runtime/caml/fail.h +++ b/runtime/caml/fail.h @@ -65,7 +65,7 @@ struct longjmp_buffer { int caml_is_special_exception(value exn); -value caml_raise_if_exception(value res); +CAMLextern value caml_raise_if_exception(value res); #endif /* CAML_INTERNALS */ diff --git a/runtime/caml/gc.h b/runtime/caml/gc.h index 5276087e..854f9dba 100644 --- a/runtime/caml/gc.h +++ b/runtime/caml/gc.h @@ -56,19 +56,7 @@ Make_header(wosize, tag, color) #endif -#ifdef WITH_SPACETIME -struct ext_table; -extern uintnat caml_spacetime_my_profinfo(struct ext_table**, uintnat); -#define Make_header_allocated_here(wosize, tag, color) \ - (Make_header_with_profinfo(wosize, tag, color, \ - caml_spacetime_my_profinfo(NULL, wosize)) \ - ) -#else -#define Make_header_allocated_here Make_header -#endif - #define Is_white_val(val) (Color_val(val) == Caml_white) -#define Is_gray_val(val) (Color_val(val) == Caml_gray) #define Is_blue_val(val) (Color_val(val) == Caml_blue) #define Is_black_val(val) (Color_val(val) == Caml_black) diff --git a/runtime/caml/instruct.h b/runtime/caml/instruct.h index 5c10df4f..d29a7b7b 100644 --- a/runtime/caml/instruct.h +++ b/runtime/caml/instruct.h @@ -32,9 +32,9 @@ enum instructions { APPTERM, APPTERM1, APPTERM2, APPTERM3, RETURN, RESTART, GRAB, CLOSURE, CLOSUREREC, - OFFSETCLOSUREM2, OFFSETCLOSURE0, OFFSETCLOSURE2, OFFSETCLOSURE, - PUSHOFFSETCLOSUREM2, PUSHOFFSETCLOSURE0, - PUSHOFFSETCLOSURE2, PUSHOFFSETCLOSURE, + OFFSETCLOSUREM3, OFFSETCLOSURE0, OFFSETCLOSURE3, OFFSETCLOSURE, + PUSHOFFSETCLOSUREM3, PUSHOFFSETCLOSURE0, + PUSHOFFSETCLOSURE3, PUSHOFFSETCLOSURE, GETGLOBAL, PUSHGETGLOBAL, GETGLOBALFIELD, PUSHGETGLOBALFIELD, SETGLOBAL, ATOM0, ATOM, PUSHATOM0, PUSHATOM, MAKEBLOCK, MAKEBLOCK1, MAKEBLOCK2, MAKEBLOCK3, MAKEFLOATBLOCK, diff --git a/runtime/caml/interp.h b/runtime/caml/interp.h index d1ebdc01..00d2de87 100644 --- a/runtime/caml/interp.h +++ b/runtime/caml/interp.h @@ -26,12 +26,6 @@ /* interpret a bytecode */ value caml_interprete (code_t prog, asize_t prog_size); -/* tell the runtime that a bytecode program might be needed */ -void caml_prepare_bytecode(code_t prog, asize_t prog_size); - -/* tell the runtime that a bytecode program is no more needed */ -void caml_release_bytecode(code_t prog, asize_t prog_size); - #endif /* CAML_INTERNALS */ #endif /* CAML_INTERP_H */ diff --git a/runtime/caml/intext.h b/runtime/caml/intext.h index be4b9467..a2a3fb82 100644 --- a/runtime/caml/intext.h +++ b/runtime/caml/intext.h @@ -127,17 +127,6 @@ CAMLextern intnat caml_output_value_to_block(value v, value flags, #ifdef CAML_INTERNALS value caml_input_val (struct channel * chan); /* Read a structured value from the channel [chan]. */ - -extern value caml_input_value_to_outside_heap (value channel); - /* As for [caml_input_value], but the value is unmarshalled into - malloc blocks that are not added to the heap. Not for the - casual user. */ - -extern int caml_extern_allow_out_of_heap; - /* Permit the marshaller to traverse structures that look like OCaml - values but do not live in the OCaml heap. */ - -extern value caml_output_value(value vchan, value v, value flags); #endif /* CAML_INTERNALS */ CAMLextern value caml_input_val_from_string (value str, intnat ofs); diff --git a/runtime/caml/io.h b/runtime/caml/io.h index 2d961f95..29868e70 100644 --- a/runtime/caml/io.h +++ b/runtime/caml/io.h @@ -52,10 +52,8 @@ struct channel { enum { CHANNEL_FLAG_FROM_SOCKET = 1, /* For Windows */ -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - CHANNEL_FLAG_BLOCKING_WRITE = 2, /* Don't release master lock when writing */ -#endif CHANNEL_FLAG_MANAGED_BY_GC = 4, /* Free and close using GC finalization */ + CHANNEL_TEXT_MODE = 8, /* "Text mode" for Windows and Cygwin */ }; /* For an output channel: @@ -64,8 +62,19 @@ enum { [offset] is the absolute position of the logical end of the buffer, [max]. */ -/* Functions and macros that can be called from C. Take arguments of - type struct channel *. No locking is performed. */ +/* Creating and closing channels from C */ + +CAMLextern struct channel * caml_open_descriptor_in (int); +CAMLextern struct channel * caml_open_descriptor_out (int); +CAMLextern void caml_close_channel (struct channel *); +CAMLextern file_offset caml_channel_size (struct channel *); +CAMLextern void caml_seek_in (struct channel *, file_offset); +CAMLextern void caml_seek_out (struct channel *, file_offset); +CAMLextern file_offset caml_pos_in (struct channel *); +CAMLextern file_offset caml_pos_out (struct channel *); + +/* I/O on channels from C. The channel must be locked (see below) before + calling any of the functions and macros below */ #define caml_putch(channel, ch) do{ \ if ((channel)->curr >= (channel)->end) caml_flush_partial(channel); \ @@ -77,11 +86,8 @@ enum { ? caml_refill(channel) \ : (unsigned char) *((channel)->curr)++) -CAMLextern struct channel * caml_open_descriptor_in (int); -CAMLextern struct channel * caml_open_descriptor_out (int); -CAMLextern void caml_close_channel (struct channel *); -CAMLextern int caml_channel_binary_mode (struct channel *); CAMLextern value caml_alloc_channel(struct channel *chan); +CAMLextern int caml_channel_binary_mode (struct channel *); CAMLextern int caml_flush_partial (struct channel *); CAMLextern void caml_flush (struct channel *); @@ -119,6 +125,10 @@ CAMLextern struct channel * caml_all_opened_channels; #define Val_file_offset(fofs) caml_copy_int64(fofs) #define File_offset_val(v) ((file_offset) Int64_val(v)) +/* Primitives required by the Unix library */ +CAMLextern value caml_ml_open_descriptor_in(value fd); +CAMLextern value caml_ml_open_descriptor_out(value fd); + #endif /* CAML_INTERNALS */ #endif /* CAML_IO_H */ diff --git a/runtime/caml/m.h.in b/runtime/caml/m.h.in index b5a7205b..1c3dee17 100644 --- a/runtime/caml/m.h.in +++ b/runtime/caml/m.h.in @@ -78,15 +78,14 @@ #undef PROFINFO_WIDTH -#undef WITH_SPACETIME -#undef ENABLE_CALL_COUNTS - #undef ASM_CFI_SUPPORTED #undef WITH_FRAME_POINTERS #undef NO_NAKED_POINTERS +#undef NAKED_POINTERS_CHECKER + #undef WITH_PROFINFO #undef CAML_WITH_FPIC @@ -98,3 +97,5 @@ #undef FUNCTION_SECTIONS #undef SUPPORTS_ALIGNED_ATTRIBUTE + +#undef SUPPORTS_TREE_VECTORIZE diff --git a/runtime/caml/major_gc.h b/runtime/caml/major_gc.h index 87339757..4ac0282c 100644 --- a/runtime/caml/major_gc.h +++ b/runtime/caml/major_gc.h @@ -26,12 +26,16 @@ typedef struct { asize_t alloc; /* in bytes, used for compaction */ asize_t size; /* in bytes */ char *next; + value* redarken_start; /* first block in chunk to redarken */ + value* redarken_end; /* last block in chunk that needs redarkening */ } heap_chunk_head; #define Chunk_size(c) (((heap_chunk_head *) (c)) [-1]).size #define Chunk_alloc(c) (((heap_chunk_head *) (c)) [-1]).alloc #define Chunk_next(c) (((heap_chunk_head *) (c)) [-1]).next #define Chunk_block(c) (((heap_chunk_head *) (c)) [-1]).block +#define Chunk_redarken_start(c) (((heap_chunk_head *) (c)) [-1]).redarken_start +#define Chunk_redarken_end(c) (((heap_chunk_head *) (c)) [-1]).redarken_end extern int caml_gc_phase; extern int caml_gc_subphase; @@ -80,6 +84,7 @@ void caml_init_major_heap (asize_t); /* size in bytes */ asize_t caml_clip_heap_chunk_wsz (asize_t wsz); void caml_darken (value, value *); void caml_major_collection_slice (intnat); +void caml_shrink_mark_stack (); void major_collection (void); void caml_finish_major_cycle (void); void caml_set_major_window (int); diff --git a/runtime/caml/memory.h b/runtime/caml/memory.h index 2669cfdf..07370904 100644 --- a/runtime/caml/memory.h +++ b/runtime/caml/memory.h @@ -57,11 +57,12 @@ CAMLextern void caml_free_dependent_memory (mlsize_t bsz); CAMLextern void caml_modify (value *, value); CAMLextern void caml_initialize (value *, value); CAMLextern value caml_check_urgent_gc (value); +CAMLextern color_t caml_allocation_color (void *hp); +#ifdef CAML_INTERNALS CAMLextern char *caml_alloc_for_heap (asize_t request); /* Size in bytes. */ CAMLextern void caml_free_for_heap (char *mem); -CAMLextern void caml_disown_for_heap (char *mem); CAMLextern int caml_add_to_heap (char *mem); -CAMLextern color_t caml_allocation_color (void *hp); +#endif /* CAML_INTERNALS */ CAMLextern int caml_huge_fallback_count; @@ -238,26 +239,11 @@ extern void caml_alloc_small_dispatch (intnat wosize, int flags, #define Alloc_small_with_profinfo(result, wosize, tag, profinfo) \ Alloc_small_aux(result, wosize, tag, profinfo, CAML_DO_TRACK) -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - -extern uintnat caml_spacetime_my_profinfo(struct ext_table**, uintnat); - -#define Alloc_small(result, wosize, tag) \ - Alloc_small_with_profinfo(result, wosize, tag, \ - caml_spacetime_my_profinfo(NULL, wosize)) -#define Alloc_small_no_track(result, wosize, tag) \ - Alloc_small_aux(result, wosize, tag, \ - caml_spacetime_my_profinfo(NULL, wosize), CAML_DONT_TRACK) - -#else - #define Alloc_small(result, wosize, tag) \ Alloc_small_with_profinfo(result, wosize, tag, (uintnat) 0) #define Alloc_small_no_track(result, wosize, tag) \ Alloc_small_aux(result, wosize, tag, (uintnat) 0, CAML_DONT_TRACK) -#endif - /* Deprecated alias for [caml_modify] */ #define Modify(fp,val) caml_modify((fp), (val)) diff --git a/runtime/caml/memprof.h b/runtime/caml/memprof.h index af311050..a25e565c 100644 --- a/runtime/caml/memprof.h +++ b/runtime/caml/memprof.h @@ -22,11 +22,12 @@ #include "mlvalues.h" #include "roots.h" -extern int caml_memprof_suspended; +extern void caml_memprof_set_suspended(int); extern value caml_memprof_handle_postponed_exn(void); extern void caml_memprof_track_alloc_shr(value block); +extern void caml_memprof_track_custom(value block, mlsize_t bytes); extern void caml_memprof_track_young(uintnat wosize, int from_caml, int nallocs, unsigned char* alloc_lens); extern void caml_memprof_track_interned(header_t* block, header_t* blockend); @@ -40,15 +41,15 @@ extern void caml_memprof_do_roots(scanning_action f); extern void caml_memprof_update_clean_phase(void); extern void caml_memprof_invert_tracked(void); -extern void caml_memprof_shutdown(void); +CAMLextern struct caml_memprof_th_ctx caml_memprof_main_ctx; -struct caml_memprof_th_ctx { - int suspended, callback_running; -}; -extern void caml_memprof_init_th_ctx(struct caml_memprof_th_ctx* ctx); -extern void caml_memprof_stop_th_ctx(struct caml_memprof_th_ctx* ctx); -extern void caml_memprof_save_th_ctx(struct caml_memprof_th_ctx* ctx); -extern void caml_memprof_restore_th_ctx(const struct caml_memprof_th_ctx* ctx); +CAMLextern struct caml_memprof_th_ctx* caml_memprof_new_th_ctx(void); +CAMLextern void caml_memprof_leave_thread(void); +CAMLextern void caml_memprof_enter_thread(struct caml_memprof_th_ctx*); +CAMLextern void caml_memprof_delete_th_ctx(struct caml_memprof_th_ctx*); + +typedef void (*th_ctx_action)(struct caml_memprof_th_ctx*, void*); +extern void (*caml_memprof_th_ctx_iter_hook)(th_ctx_action, void*); #endif diff --git a/runtime/caml/minor_gc.h b/runtime/caml/minor_gc.h index 20baa8d5..eefd3850 100644 --- a/runtime/caml/minor_gc.h +++ b/runtime/caml/minor_gc.h @@ -63,11 +63,13 @@ struct caml_custom_table CAML_TABLE_STRUCT(struct caml_custom_elt); /* Table of custom blocks in the minor heap that contain finalizers or GC speed parameters. */ +CAMLextern void caml_minor_collection (void); + +#ifdef CAML_INTERNALS extern void caml_set_minor_heap_size (asize_t); /* size in bytes */ extern void caml_empty_minor_heap (void); -CAMLextern void caml_gc_dispatch (void); -CAMLextern void caml_minor_collection (void); -CAMLextern void garbage_collection (void); /* runtime/signals_nat.c */ +extern void caml_gc_dispatch (void); +extern void caml_garbage_collection (void); /* runtime/signals_nat.c */ extern void caml_oldify_one (value, value *); extern void caml_oldify_mopup (void); @@ -131,4 +133,6 @@ Caml_inline void add_to_custom_table (struct caml_custom_table *tbl, value v, elt->max = max; } +#endif /* CAML_INTERNALS */ + #endif /* CAML_MINOR_GC_H */ diff --git a/runtime/caml/misc.h b/runtime/caml/misc.h index 4d9ac010..5c363103 100644 --- a/runtime/caml/misc.h +++ b/runtime/caml/misc.h @@ -74,13 +74,20 @@ CAMLdeprecated_typedef(addr, char *); #define Noreturn #endif - - /* Export control (to mark primitives and to handle Windows DLL) */ +#ifndef CAMLDLLIMPORT + #if defined(SUPPORT_DYNAMIC_LINKING) && defined(ARCH_SIXTYFOUR) \ + && defined(__CYGWIN__) + #define CAMLDLLIMPORT __declspec(dllimport) + #else + #define CAMLDLLIMPORT + #endif +#endif + #define CAMLexport #define CAMLprim -#define CAMLextern extern +#define CAMLextern CAMLDLLIMPORT extern /* Weak function definitions that can be overridden by external libs */ /* Conservatively restricted to ELF and MacOSX platforms */ @@ -259,6 +266,7 @@ extern double caml_log1p(double); #define unlink_os _wunlink #define rename_os caml_win32_rename #define chdir_os _wchdir +#define mkdir_os(path, perm) _wmkdir(path) #define getcwd_os _wgetcwd #define system_os _wsystem #define rmdir_os _wrmdir @@ -294,6 +302,7 @@ extern double caml_log1p(double); #define unlink_os unlink #define rename_os rename #define chdir_os chdir +#define mkdir_os mkdir #define getcwd_os getcwd #define system_os system #define rmdir_os rmdir @@ -334,6 +343,9 @@ extern void caml_ext_table_remove(struct ext_table * tbl, void * data); extern void caml_ext_table_free(struct ext_table * tbl, int free_entries); extern void caml_ext_table_clear(struct ext_table * tbl, int free_entries); +/* Add to [contents] the (short) names of the files contained in + the directory named [dirname]. No entries are added for [.] and [..]. + Return 0 on success, -1 on error; set errno in the case of error. */ CAMLextern int caml_read_directory(char_os * dirname, struct ext_table * contents); diff --git a/runtime/caml/mlvalues.h b/runtime/caml/mlvalues.h index 487dd080..0cd6fc2d 100644 --- a/runtime/caml/mlvalues.h +++ b/runtime/caml/mlvalues.h @@ -214,7 +214,7 @@ typedef opcode_t * code_t; /* If tag == Infix_tag : an infix header inside a closure */ /* Infix_tag must be odd so that the infix header is scanned as an integer */ -/* Infix_tag must be 1 modulo 4 and infix headers can only occur in blocks +/* Infix_tag must be 1 modulo 2 and infix headers can only occur in blocks with tag Closure_tag (see compact.c). */ #define Infix_tag 249 @@ -235,6 +235,23 @@ CAMLextern value caml_get_public_method (value obj, value tag); /* Special case of tuples of fields: closures */ #define Closure_tag 247 #define Code_val(val) (((code_t *) (val)) [0]) /* Also an l-value. */ +#define Closinfo_val(val) Field((val), 1) /* Arity and start env */ +/* In the closure info field, the top 8 bits are the arity (signed). + The low bit is set to one, to look like an integer. + The remaining bits are the field number for the first word of the + environment, or, in other words, the offset (in words) from the closure + to the environment part. */ +#ifdef ARCH_SIXTYFOUR +#define Arity_closinfo(info) ((intnat)(info) >> 56) +#define Start_env_closinfo(info) (((uintnat)(info) << 8) >> 9) +#define Make_closinfo(arity,delta) \ + (((uintnat)(arity) << 56) + ((uintnat)(delta) << 1) + 1) +#else +#define Arity_closinfo(info) ((intnat)(info) >> 24) +#define Start_env_closinfo(info) (((uintnat)(info) << 8) >> 9) +#define Make_closinfo(arity,delta) \ + (((uintnat)(arity) << 24) + ((uintnat)(delta) << 1) + 1) +#endif /* This tag is used (with Forward_tag) to implement lazy values. See major_gc.c and stdlib/lazy.ml. */ @@ -373,12 +390,29 @@ CAMLextern header_t *caml_atom_table; #define Val_emptylist Val_int(0) #define Tag_cons 0 +/* Option constructors */ + +#define Val_none Val_int(0) +#define Some_val(v) Field(v, 0) +#define Tag_some 0 +#define Is_none(v) ((v) == Val_none) +#define Is_some(v) Is_block(v) + /* The table of global identifiers */ extern value caml_global_data; CAMLextern value caml_set_oo_id(value obj); +/* Header for out-of-heap blocks. */ + +#define Caml_out_of_heap_header(wosize, tag) \ + (/*CAMLassert ((wosize) <= Max_wosize),*/ \ + ((header_t) (((header_t) (wosize) << 10) \ + + (3 << 8) /* matches [Caml_black]. See [gc.h] */ \ + + (tag_t) (tag))) \ + ) + #ifdef __cplusplus } #endif diff --git a/runtime/caml/osdeps.h b/runtime/caml/osdeps.h index d41779d3..441c19cc 100644 --- a/runtime/caml/osdeps.h +++ b/runtime/caml/osdeps.h @@ -30,12 +30,16 @@ extern unsigned short caml_win32_revision; #include "misc.h" #include "memory.h" +#define Io_interrupted (-1) + /* Read at most [n] bytes from file descriptor [fd] into buffer [buf]. [flags] indicates whether [fd] is a socket (bit [CHANNEL_FLAG_FROM_SOCKET] is set in this case, see [io.h]). (This distinction matters for Win32, but not for Unix.) Return number of bytes read. - In case of error, raises [Sys_error] or [Sys_blocked_io]. */ + In case of error, raises [Sys_error] or [Sys_blocked_io]. + If interrupted by a signal and no bytes where read, returns + Io_interrupted without raising. */ extern int caml_read_fd(int fd, int flags, void * buf, int n); /* Write at most [n] bytes from buffer [buf] onto file descriptor [fd]. @@ -43,7 +47,9 @@ extern int caml_read_fd(int fd, int flags, void * buf, int n); (bit [CHANNEL_FLAG_FROM_SOCKET] is set in this case, see [io.h]). (This distinction matters for Win32, but not for Unix.) Return number of bytes written. - In case of error, raises [Sys_error] or [Sys_blocked_io]. */ + In case of error, raises [Sys_error] or [Sys_blocked_io]. + If interrupted by a signal and no bytes were written, returns + Io_interrupted without raising. */ extern int caml_write_fd(int fd, int flags, void * buf, int n); /* Decompose the given path into a list of directories, and add them @@ -85,11 +91,6 @@ extern void * caml_globalsym(const char * name); /* Return an error message describing the most recent dynlink failure. */ extern char * caml_dlerror(void); -/* Add to [contents] the (short) names of the files contained in - the directory named [dirname]. No entries are added for [.] and [..]. - Return 0 on success, -1 on error; set errno in the case of error. */ -extern int caml_read_directory(char_os * dirname, struct ext_table * contents); - /* Recover executable name if possible (/proc/sef/exe under Linux, GetModuleFileName under Windows). Return NULL on error, string allocated with [caml_stat_alloc] on success. */ @@ -117,11 +118,11 @@ extern wchar_t *caml_win32_getenv(wchar_t const *); /* Windows Unicode support */ -extern int win_multi_byte_to_wide_char(const char* s, +CAMLextern int win_multi_byte_to_wide_char(const char* s, int slen, wchar_t *out, int outlen); -extern int win_wide_char_to_multi_byte(const wchar_t* s, +CAMLextern int win_wide_char_to_multi_byte(const wchar_t* s, int slen, char *out, int outlen); @@ -134,7 +135,7 @@ extern int win_wide_char_to_multi_byte(const wchar_t* s, The returned string is allocated with [caml_stat_alloc], so it should be free using [caml_stat_free]. */ -extern wchar_t* caml_stat_strdup_to_utf16(const char *s); +CAMLextern wchar_t* caml_stat_strdup_to_utf16(const char *s); /* [caml_stat_strdup_of_utf16(s)] returns a NULL-terminated copy of [s], re-encoded in UTF-8 if [caml_windows_unicode_runtime_enabled] is non-zero or @@ -143,15 +144,17 @@ extern wchar_t* caml_stat_strdup_to_utf16(const char *s); The returned string is allocated with [caml_stat_alloc], so it should be free using [caml_stat_free]. */ -extern char* caml_stat_strdup_of_utf16(const wchar_t *s); +CAMLextern char* caml_stat_strdup_of_utf16(const wchar_t *s); /* [caml_copy_string_of_utf16(s)] returns an OCaml string containing a copy of [s] re-encoded in UTF-8 if [caml_windows_unicode_runtime_enabled] is non-zero or in the current code page otherwise. */ -extern value caml_copy_string_of_utf16(const wchar_t *s); +CAMLextern value caml_copy_string_of_utf16(const wchar_t *s); + +CAMLextern int caml_win32_isatty(int fd); -extern int caml_win32_isatty(int fd); +CAMLextern void caml_expand_command_line (int *, wchar_t ***); #endif /* _WIN32 */ diff --git a/runtime/caml/printexc.h b/runtime/caml/printexc.h index 92c5af53..8ae788b1 100644 --- a/runtime/caml/printexc.h +++ b/runtime/caml/printexc.h @@ -26,7 +26,9 @@ extern "C" { CAMLextern char * caml_format_exception (value); +#ifdef CAML_INTERNALS CAMLnoreturn_start void caml_fatal_uncaught_exception (value) CAMLnoreturn_end; +#endif /* CAML_INTERNALS */ #ifdef __cplusplus } diff --git a/runtime/caml/roots.h b/runtime/caml/roots.h index 755aa8a7..8ac9d8d2 100644 --- a/runtime/caml/roots.h +++ b/runtime/caml/roots.h @@ -29,12 +29,15 @@ intnat caml_darken_all_roots_slice (intnat); void caml_do_roots (scanning_action, int); extern uintnat caml_incremental_roots_count; #ifndef NATIVE_CODE -CAMLextern void caml_do_local_roots (scanning_action, value *, value *, - struct caml__roots_block *); +CAMLextern void caml_do_local_roots_byt (scanning_action, value *, value *, + struct caml__roots_block *); +#define caml_do_local_roots caml_do_local_roots_byt #else -CAMLextern void caml_do_local_roots(scanning_action f, char * c_bottom_of_stack, - uintnat last_retaddr, value * v_gc_regs, - struct caml__roots_block * gc_local_roots); +CAMLextern void caml_do_local_roots_nat ( + scanning_action f, char * c_bottom_of_stack, + uintnat last_retaddr, value * v_gc_regs, + struct caml__roots_block * gc_local_roots); +#define caml_do_local_roots caml_do_local_roots_nat #endif CAMLextern void (*caml_scan_roots_hook) (scanning_action); diff --git a/runtime/caml/s.h.in b/runtime/caml/s.h.in index 30d2d768..2460577d 100644 --- a/runtime/caml/s.h.in +++ b/runtime/caml/s.h.in @@ -106,6 +106,10 @@ /* Define HAS_GETCWD if the library provides the getcwd() function. */ +#undef HAS_SYSTEM + +/* Define HAS_SYSTEM if the library provides the system() function. */ + #undef HAS_UTIME #undef HAS_UTIMES @@ -245,8 +249,12 @@ #undef HAS_SYS_SHM_H +#undef HAS_SHMAT + #undef HAS_EXECVPE +#undef HAS_POSIX_SPAWN + #undef HAS_FFS #undef HAS_BITSCANFORWARD @@ -254,14 +262,10 @@ #undef HAS_SIGWAIT -#undef HAS_LIBBFD - #undef HAS_HUGE_PAGES #undef HUGE_PAGE_SIZE -#undef HAS_LIBUNWIND - #undef HAS_BROKEN_PRINTF #undef HAS_STRERROR diff --git a/runtime/caml/signals.h b/runtime/caml/signals.h index 7ec1ad3b..3ff152c2 100644 --- a/runtime/caml/signals.h +++ b/runtime/caml/signals.h @@ -31,6 +31,7 @@ extern "C" { #endif CAMLextern void caml_enter_blocking_section (void); +CAMLextern void caml_enter_blocking_section_no_pending (void); CAMLextern void caml_leave_blocking_section (void); CAMLextern void caml_process_pending_actions (void); @@ -39,6 +40,9 @@ CAMLextern void caml_process_pending_actions (void); Memprof callbacks. Assumes that the runtime lock is held. Can raise exceptions asynchronously into OCaml code. */ +CAMLextern int caml_check_pending_actions (void); +/* Returns 1 if there are pending actions, 0 otherwise. */ + CAMLextern value caml_process_pending_actions_exn (void); /* Same as [caml_process_pending_actions], but returns the exception if any (otherwise returns [Val_unit]). */ @@ -76,17 +80,17 @@ void caml_request_minor_gc (void); CAMLextern int caml_convert_signal_number (int); CAMLextern int caml_rev_convert_signal_number (int); value caml_execute_signal_exn(int signal_number, int in_signal_handler); -void caml_record_signal(int signal_number); -value caml_process_pending_signals_exn(void); +CAMLextern void caml_record_signal(int signal_number); +CAMLextern value caml_process_pending_signals_exn(void); void caml_set_action_pending (void); value caml_do_pending_actions_exn (void); value caml_process_pending_actions_with_root (value extra_root); // raises +value caml_process_pending_actions_with_root_exn (value extra_root); int caml_set_signal_action(int signo, int action); -void caml_setup_stack_overflow_detection(void); +CAMLextern void caml_setup_stack_overflow_detection(void); CAMLextern void (*caml_enter_blocking_section_hook)(void); CAMLextern void (*caml_leave_blocking_section_hook)(void); -CAMLextern int (*caml_try_leave_blocking_section_hook)(void); #ifdef POSIX_SIGNALS CAMLextern int (*caml_sigmask_hook)(int, const sigset_t *, sigset_t *); #endif diff --git a/runtime/caml/spacetime.h b/runtime/caml/spacetime.h deleted file mode 100644 index 5bcc9232..00000000 --- a/runtime/caml/spacetime.h +++ /dev/null @@ -1,203 +0,0 @@ -/**************************************************************************/ -/* */ -/* OCaml */ -/* */ -/* Mark Shinwell and Leo White, Jane Street Europe */ -/* */ -/* Copyright 2013--2016, Jane Street Group, LLC */ -/* */ -/* All rights reserved. This file is distributed under the terms of */ -/* the GNU Lesser General Public License version 2.1, with the */ -/* special exception on linking described in the file LICENSE. */ -/* */ -/**************************************************************************/ - -#ifndef CAML_SPACETIME_H -#define CAML_SPACETIME_H - -#include "io.h" -#include "misc.h" -#include "stack.h" - -/* Runtime support for Spacetime profiling. - * This header file is not intended for the casual user. - * - * The implementation is split into three files: - * 1. spacetime.c: core management of the instrumentation; - * 2. spacetime_snapshot.c: the taking of heap snapshots; - * 3. spacetime_offline.c: functions that are also used when examining - * saved profiling data. - */ - -typedef enum { - CALL, - ALLOCATION -} c_node_type; - -/* All pointers between nodes point at the word immediately after the - GC headers, and everything is traversable using the normal OCaml rules. - - On entry to an OCaml function: - If the node hole pointer register has the bottom bit set, then the function - is being tail called or called from a self-recursive call site: - - If the node hole is empty, the callee must create a new node and link - it into the tail chain. The node hole pointer will point at the tail - chain. - - Otherwise the node should be used as normal. - Otherwise (not a tail call): - - If the node hole is empty, the callee must create a new node, but the - tail chain is untouched. - - Otherwise the node should be used as normal. -*/ - -/* Classification of nodes (OCaml or C) with corresponding GC tags. */ -#define OCaml_node_tag 0 -#define C_node_tag 1 -#define Is_ocaml_node(node) (Is_block(node) && Tag_val(node) == OCaml_node_tag) -#define Is_c_node(node) (Is_block(node) && Tag_val(node) == C_node_tag) - -/* The header words are: - 1. The node program counter. - 2. The tail link. */ -#define Node_num_header_words 2 - -/* The "node program counter" at the start of an OCaml node. */ -#define Node_pc(node) (Field(node, 0)) -#define Encode_node_pc(pc) (((value) pc) | 1) -#define Decode_node_pc(encoded_pc) ((void*) (encoded_pc & ~1)) - -/* The circular linked list of tail-called functions within OCaml nodes. */ -#define Tail_link(node) (Field(node, 1)) - -/* The convention for pointers from OCaml nodes to other nodes. There are - two special cases: - 1. [Val_unit] means "uninitialized", and further, that this is not a - tail call point. (Tail call points are pre-initialized, as in case 2.) - 2. If the bottom bit is set, and the value is not [Val_unit], this is a - tail call point. */ -#define Encode_tail_caller_node(node) ((node) | 1) -#define Decode_tail_caller_node(node) ((node) & ~1) -#define Is_tail_caller_node_encoded(node) (((node) & 1) == 1) - -/* Allocation points within OCaml nodes. - The "profinfo" value looks exactly like a black Infix_tag header. - This enables us to point just after it and return such pointer as a valid - OCaml value. (Used for the list of all allocation points. We could do - without this and instead just encode the list pointers as integers, but - this would mean that the structure was destroyed on marshalling. This - might not be a great problem since it is intended that the total counts - be obtained via snapshots, but it seems neater and easier to use - Infix_tag. - The "count" is just an OCaml integer giving the total number of words - (including headers) allocated at the point. - The "pointer to next allocation point" points to the "count" word of the - next allocation point in the linked list of all allocation points. - There is no special encoding needed by virtue of the [Infix_tag] trick. */ -#define Alloc_point_profinfo(node, offset) (Field(node, offset)) -#define Alloc_point_count(node, offset) (Field(node, offset + 1)) -#define Alloc_point_next_ptr(node, offset) (Field(node, offset + 2)) - -/* Direct call points (tail or non-tail) within OCaml nodes. - They hold a pointer to the child node and (if the compiler was so - configured) a call count. - The call site and callee are both recorded in the shape. */ -#define Direct_callee_node(node,offset) (Field(node, offset)) -#define Direct_call_count(node,offset) (Field(node, offset + 1)) -#define Encode_call_point_pc(pc) (((value) pc) | 1) -#define Decode_call_point_pc(pc) ((void*) (((value) pc) & ~((uintnat) 1))) - -/* Indirect call points (tail or non-tail) within OCaml nodes. - They hold a linked list of (PC upon entry to the callee, pointer to - child node) pairs. The linked list is encoded using C nodes and should - be thought of as part of the OCaml node itself. */ -#define Indirect_num_fields 1 -#define Indirect_pc_linked_list(node,offset) (Field(node, offset)) - -/* Encodings of the program counter value within a C node. */ -#define Encode_c_node_pc_for_call(pc) ((((value) pc) << 2) | 3) -#define Encode_c_node_pc_for_alloc_point(pc) ((((value) pc) << 2) | 1) -#define Decode_c_node_pc(pc) ((void*) (((uintnat) (pc)) >> 2)) - -typedef struct { - /* The layout and encoding of this structure must match that of the - allocation points within OCaml nodes, so that the linked list - traversal across all allocation points works correctly. */ - value profinfo; /* encoded using [Infix_tag] (see above) */ - value count; - /* [next] is [Val_unit] for the end of the list. - Otherwise it points at the second word of this [allocation_point] - structure. */ - value next; -} allocation_point; - -typedef struct { - value callee_node; - value call_count; -} call_point; - -typedef struct { - /* CR-soon mshinwell: delete [gc_header], all the offset arithmetic will - then go away */ - uintnat gc_header; - uintnat pc; /* see above for encodings */ - union { - call_point call; /* for CALL */ - allocation_point allocation; /* for ALLOCATION */ - } data; - value next; /* [Val_unit] for the end of the list */ -} c_node; /* CR-soon mshinwell: rename to dynamic_node */ - -typedef struct shape_table { - uint64_t* table; - struct shape_table* next; -} shape_table; - -extern uint64_t** caml_spacetime_static_shape_tables; -extern shape_table* caml_spacetime_dynamic_shape_tables; - -typedef struct ext_table* spacetime_unwind_info_cache; - -extern value caml_spacetime_trie_root; -extern value* caml_spacetime_trie_node_ptr; -extern value* caml_spacetime_finaliser_trie_root; - -extern allocation_point* caml_all_allocation_points; - -extern void caml_spacetime_initialize(void); -extern uintnat caml_spacetime_my_profinfo( - spacetime_unwind_info_cache*, uintnat); -extern c_node_type caml_spacetime_classify_c_node(c_node* node); -extern c_node* caml_spacetime_c_node_of_stored_pointer(value); -extern c_node* caml_spacetime_c_node_of_stored_pointer_not_null(value); -extern value caml_spacetime_stored_pointer_of_c_node(c_node* node); -extern void caml_spacetime_register_thread(value*, value*); -extern void caml_spacetime_register_shapes(void*); -extern value caml_spacetime_frame_table(void); -extern value caml_spacetime_shape_table(void); -extern void caml_spacetime_save_snapshot (struct channel *chan, - double time_override, - int use_time_override); -extern value caml_spacetime_timestamp(double time_override, - int use_time_override); -extern void caml_spacetime_automatic_snapshot (void); - -/* For use in runtime functions that are executed from OCaml - code, to save the overhead of using libunwind every time. */ -#ifdef WITH_SPACETIME -#define Get_my_profinfo_with_cached_backtrace(profinfo, size) \ - do { \ - static spacetime_unwind_info_cache spacetime_unwind_info = NULL; \ - profinfo = caml_spacetime_my_profinfo(&spacetime_unwind_info, size); \ - } \ - while (0); -#else -#define Get_my_profinfo_with_cached_backtrace(profinfo, size) \ - profinfo = (uintnat) 0; -#endif - -#else - -#define Get_my_profinfo_with_cached_backtrace(profinfo, size) \ - profinfo = (uintnat) 0; - -#endif diff --git a/runtime/caml/stack.h b/runtime/caml/stack.h index 6b7df0e6..9c182ee6 100644 --- a/runtime/caml/stack.h +++ b/runtime/caml/stack.h @@ -81,9 +81,6 @@ struct caml_context { char * bottom_of_stack; /* beginning of OCaml stack chunk */ uintnat last_retaddr; /* last return address in OCaml code */ value * gc_regs; /* pointer to register block */ -#ifdef WITH_SPACETIME - void* trie_node; -#endif }; /* Structure of frame descriptors */ diff --git a/runtime/caml/stacks.h b/runtime/caml/stacks.h index 8cbb02a8..d309141f 100644 --- a/runtime/caml/stacks.h +++ b/runtime/caml/stacks.h @@ -33,7 +33,7 @@ #define caml_trap_barrier (Caml_state_field(trap_barrier)) #define Trap_pc(tp) (((code_t *)(tp))[0]) -#define Trap_link(tp) (((value **)(tp))[1]) +#define Trap_link_offset(tp) (((value *)(tp))[1]) void caml_init_stack (uintnat init_max_size); void caml_realloc_stack (asize_t required_size); diff --git a/runtime/caml/startup.h b/runtime/caml/startup.h index abbcd596..f3e1fe6d 100644 --- a/runtime/caml/startup.h +++ b/runtime/caml/startup.h @@ -21,8 +21,6 @@ #include "mlvalues.h" #include "exec.h" -CAMLextern void caml_main(char_os **argv); - CAMLextern void caml_startup_code( code_t code, asize_t code_size, char *data, asize_t data_size, @@ -37,7 +35,8 @@ CAMLextern value caml_startup_code_exn( int pooling, char_os **argv); -enum { FILE_NOT_FOUND = -1, BAD_BYTECODE = -2, WRONG_MAGIC = -3 }; +/* These enum members should all be negative */ +enum { FILE_NOT_FOUND = -1, BAD_BYTECODE = -2, WRONG_MAGIC = -3, NO_FDS = -4 }; extern int caml_attempt_open(char_os **name, struct exec_trailer *trail, int do_open_script); diff --git a/runtime/caml/sys.h b/runtime/caml/sys.h index 39e24c57..8f5683e0 100644 --- a/runtime/caml/sys.h +++ b/runtime/caml/sys.h @@ -41,7 +41,6 @@ CAMLnoreturn_start CAMLextern value caml_sys_exit (value) CAMLnoreturn_end; -extern double caml_sys_time_unboxed(value); CAMLextern value caml_sys_get_argv(value unit); extern char_os * caml_exe_name; diff --git a/runtime/caml/weak.h b/runtime/caml/weak.h index a8f36ab1..8192496f 100644 --- a/runtime/caml/weak.h +++ b/runtime/caml/weak.h @@ -176,7 +176,7 @@ Caml_inline void caml_ephe_clean_partial (value v, child = Field (v, i); ephemeron_again: if (child != caml_ephe_none - && Is_block (child) && Is_in_heap_or_young (child)){ + && Is_block (child) && Is_in_value_area (child)){ if (Tag_val (child) == Forward_tag){ value f = Forward_val (child); if (Is_block (f)) { @@ -191,6 +191,7 @@ Caml_inline void caml_ephe_clean_partial (value v, } } } + if (Tag_val (child) == Infix_tag) child -= Infix_offset_val (child); if (Is_white_val (child) && !Is_young (child)){ release_data = 1; Field (v, i) = caml_ephe_none; @@ -200,15 +201,16 @@ Caml_inline void caml_ephe_clean_partial (value v, child = Field (v, 1); if(child != caml_ephe_none){ - if (release_data){ - Field (v, 1) = caml_ephe_none; - } else { - /* If we scanned all the keys and the data field remains filled, - then the mark phase must have marked it */ - CAMLassert( !(offset_start == 2 && offset_end == Wosize_hd (Hd_val(v)) - && Is_block (child) && Is_in_heap (child) - && Is_white_val (child))); - } + if (release_data) Field (v, 1) = caml_ephe_none; +#ifdef DEBUG + else if (offset_start == 2 && offset_end == Wosize_hd (Hd_val(v)) && + Is_block (child) && Is_in_heap (child)) { + if (Tag_val (child) == Infix_tag) child -= Infix_offset_val (child); + /* If we scanned all the keys and the data field remains filled, + then the mark phase must have marked it */ + CAMLassert( !Is_white_val (child) ); + } +#endif } } diff --git a/runtime/compact.c b/runtime/compact.c index 02aec46b..8397ab58 100644 --- a/runtime/compact.c +++ b/runtime/compact.c @@ -35,88 +35,59 @@ extern uintnat caml_percent_free; /* major_gc.c */ extern void caml_shrink_heap (char *); /* memory.c */ -/* Encoded headers: the color is stored in the 2 least significant bits. - (For pointer inversion, we need to distinguish headers from pointers.) - s is a Wosize, t is a tag, and c is a color (a two-bit number) - - For the purpose of compaction, "colors" are: - 0: pointers (direct or inverted) - 1: integer or (unencoded) infix header - 2: inverted pointer for infix header - 3: integer or encoded (noninfix) header - - XXX Should be fixed: - XXX The above assumes that all roots are aligned on a 4-byte boundary, - XXX which is not always guaranteed by C. - XXX (see [caml_register_global_roots]) - XXX Should be able to fix it to only assume 2-byte alignment. +/* Colors + + We use the GC's color bits in the following way: + + - White words are headers of live blocks. + - Blue words are headers of free blocks. + - Black words are headers of out-of-heap "blocks". + - Gray words are the encoding of pointers in inverted lists. + + Encoded pointers: + Pointers always have their two low-order bits clear. We make use of + this to encode pointers by shifting bits 2-9 to 0-7: + ...XXXyyyyyyyy00 becomes ...XXX01yyyyyyyy + Note that 01 corresponds to the "gray" color of the GC, so we can now + mix pointers and headers because there are no gray headers anywhere in + the heap (or outside) when we start a compaction (which must be done at + the end of a sweep phase). */ -#ifdef WITH_PROFINFO -#define Make_ehd(s,t,c,p) \ - (((s) << 10) | (t) << 2 | (c) | ((p) << PROFINFO_SHIFT)) -#else -#define Make_ehd(s,t,c,p) (((s) << 10) | (t) << 2 | (c)) -#endif -#define Whsize_ehd(h) Whsize_hd (h) -#define Wosize_ehd(h) Wosize_hd (h) -#define Tag_ehd(h) (((h) >> 2) & 0xFF) -#ifdef WITH_PROFINFO -#define Profinfo_ehd(hd) Profinfo_hd(hd) -#endif -#define Ecolor(w) ((w) & 3) typedef uintnat word; +#define eptr(p) \ + (((word) (p) & ~0x3FF) | ((((word) p) & 0x3FF) >> 2) | Caml_gray) +#define dptr(p) ((word *) (((word) (p) & ~0x3FF) | ((((word) p) & 0xFF) << 2))) + static void invert_pointer_at (word *p) { word q = *p; - CAMLassert (Ecolor ((intnat) p) == 0); - - /* Use Ecolor (q) == 0 instead of Is_block (q) because q could be an - inverted pointer for an infix header (with Ecolor == 2). */ - if (Ecolor (q) == 0 && Is_in_heap (q)){ - switch (Ecolor (Hd_val (q))){ - case 0: - case 3: /* Pointer or header: insert in inverted list. */ - *p = Hd_val (q); - Hd_val (q) = (header_t) p; - break; - case 1: /* Infix header: make inverted infix list. */ - /* Double inversion: the last of the inverted infix list points to - the next infix header in this block. The last of the last list - contains the original block header. */ - { - /* This block as a value. */ - value val = (value) q - Infix_offset_val (q); - /* Get the block header. */ - word *hp = (word *) Hp_val (val); - - while (Ecolor (*hp) == 0) hp = (word *) *hp; - CAMLassert (Ecolor (*hp) == 3); - if (Tag_ehd (*hp) == Closure_tag){ - /* This is the first infix found in this block. */ - /* Save original header. */ - *p = *hp; - /* Link inverted infix list. */ - Hd_val (q) = (header_t) ((word) p | 2); - /* Change block header's tag to Infix_tag, and change its size - to point to the infix list. */ - *hp = Make_ehd (Wosize_bhsize (q - val), Infix_tag, 3, (uintnat) 0); - }else{ - CAMLassert (Tag_ehd (*hp) == Infix_tag); - /* Point the last of this infix list to the current first infix - list of the block. */ - *p = (word) &Field (val, Wosize_ehd (*hp)) | 1; - /* Point the head of this infix list to the above. */ - Hd_val (q) = (header_t) ((word) p | 2); - /* Change block header's size to point to this infix list. */ - *hp = Make_ehd (Wosize_bhsize (q - val), Infix_tag, 3, (uintnat) 0); - } + header_t h; + + CAMLassert (((uintnat) p & 3) == 0); + + if (Is_block (q) && Is_in_value_area (q)){ + h = Hd_val (q); + switch (Color_hd (h)){ + case Caml_white: + if (Tag_hd (h) == Infix_tag){ + value realvalue = (value) q - Infix_offset_val (q); + if (Is_black_val (realvalue)) break; } + /* FALL THROUGH */ + case Caml_gray: + CAMLassert (Is_in_heap (q)); + /* [q] points to some inverted list, insert it. */ + *p = h; + Hd_val (q) = eptr (p); break; - case 2: /* Inverted infix list: insert. */ - *p = Hd_val (q); - Hd_val (q) = (header_t) ((word) p | 2); + case Caml_black: + /* [q] points to an out-of-heap value. Leave it alone. */ + break; + default: /* Caml_blue */ + /* We found a pointer to a free block. This cannot happen. */ + CAMLassert (0); break; } } @@ -124,6 +95,13 @@ static void invert_pointer_at (word *p) void caml_invert_root (value v, value *p) { +#ifdef NO_NAKED_POINTERS + /* Note: this assertion will become tautological and should be removed when + we finally get rid of the page table in NNP mode. + */ + CAMLassert (Is_long (*p) || Is_in_heap (*p) || Is_black_val (*p) + || Tag_val (*p) == Infix_tag); +#endif invert_pointer_at ((word *) p); } @@ -176,40 +154,13 @@ static void do_compaction (intnat new_allocation_policy) */ caml_fl_reset_and_switch_policy (new_allocation_policy); - - /* First pass: encode all noninfix headers. */ - { - ch = caml_heap_start; - while (ch != NULL){ - header_t *p = (header_t *) ch; - - chend = ch + Chunk_size (ch); - while ((char *) p < chend){ - header_t hd = Hd_hp (p); - mlsize_t sz = Wosize_hd (hd); - - if (Is_blue_hd (hd)){ - /* Free object. Give it a string tag. */ - Hd_hp (p) = Make_ehd (sz, String_tag, 3, (uintnat) 0); - }else{ - CAMLassert (Is_white_hd (hd)); - /* Live object. Keep its tag. */ - Hd_hp (p) = Make_ehd (sz, Tag_hd (hd), 3, Profinfo_hd (hd)); - } - p += Whsize_wosize (sz); - } - ch = Chunk_next (ch); - } - } + /* First pass: removed in 4.12 thanks to the new closure representation. */ /* Second pass: invert pointers. - Link infix headers in each block in an inverted list of inverted lists. - Don't forget roots and weak pointers. */ + Don't forget roots and weak pointers. + This is a mark-like pass. */ { - /* Invert roots first because the threads library needs some heap - data structures to find its roots. Fortunately, it doesn't need - the headers (see above). */ caml_do_roots (caml_invert_root, 1); /* The values to be finalised are not roots but should still be inverted */ caml_final_invert_finalisable_values (); @@ -223,27 +174,27 @@ static void do_compaction (intnat new_allocation_policy) while ((char *) p < chend){ word q = *p; - size_t sz, i; + mlsize_t wosz, i, first_field; tag_t t; - word *infixes; - - while (Ecolor (q) == 0) q = * (word *) q; - sz = Whsize_ehd (q); - t = Tag_ehd (q); - - if (t == Infix_tag){ - /* Get the original header of this block. */ - infixes = p + sz; - q = *infixes; - while (Ecolor (q) != 3) q = * (word *) (q & ~(uintnat)3); - sz = Whsize_ehd (q); - t = Tag_ehd (q); - } - if (t < No_scan_tag){ - for (i = 1; i < sz; i++) invert_pointer_at (&(p[i])); + while (Is_gray_hd (q)) q = * dptr (q); + wosz = Wosize_hd (q); + if (Is_white_hd (q)){ + t = Tag_hd (q); + CAMLassert (t != Infix_tag); + if (t < No_scan_tag){ + value v = Val_hp (p); + if (t == Closure_tag){ + first_field = Start_env_closinfo (Closinfo_val (v)); + }else{ + first_field = 0; + } + for (i = first_field; i < wosz; i++){ + invert_pointer_at ((word *) &Field (v,i)); + } + } } - p += sz; + p += Whsize_wosize (wosz); } ch = Chunk_next (ch); } @@ -258,8 +209,9 @@ static void do_compaction (intnat new_allocation_policy) p = *pp; if (p == (value) NULL) break; q = Hd_val (p); - while (Ecolor (q) == 0) q = * (word *) q; - sz = Wosize_ehd (q); + while (Is_gray_hd (q)) q = * dptr (q); + CAMLassert (Is_white_hd (q)); + sz = Wosize_hd (q); for (i = 1; i < sz; i++){ if (Field (p,i) != caml_ephe_none){ invert_pointer_at ((word *) &(Field (p,i))); @@ -272,8 +224,8 @@ static void do_compaction (intnat new_allocation_policy) } - /* Third pass: reallocate virtually; revert pointers; decode headers. - Rebuild infix headers. */ + /* Third pass: reallocate virtually; revert pointers. + This is a sweep-like pass. */ { init_compact_allocate (); ch = caml_heap_start; @@ -282,75 +234,59 @@ static void do_compaction (intnat new_allocation_policy) chend = ch + Chunk_size (ch); while ((char *) p < chend){ - word q = *p; + header_t h = Hd_hp (p); + size_t sz; + + while (Is_gray_hd (h)) h = * dptr (h); + sz = Whsize_hd (h); - if (Ecolor (q) == 0 || Tag_ehd (q) == Infix_tag){ - /* There were (normal or infix) pointers to this block. */ - size_t sz; + CAMLassert (!Is_black_hd (h)); + CAMLassert (!Is_gray_hd (h)); + if (Is_white_hd (h)){ + word q; tag_t t; char *newadr; -#ifdef WITH_PROFINFO - uintnat profinfo; -#endif - word *infixes = NULL; - while (Ecolor (q) == 0) q = * (word *) q; - sz = Whsize_ehd (q); - t = Tag_ehd (q); -#ifdef WITH_PROFINFO - profinfo = Profinfo_ehd (q); -#endif - if (t == Infix_tag){ - /* Get the original header of this block. */ - infixes = p + sz; - q = *infixes; - CAMLassert (Ecolor (q) == 2); - while (Ecolor (q) != 3) q = * (word *) (q & ~(uintnat)3); - sz = Whsize_ehd (q); - t = Tag_ehd (q); - } + t = Tag_hd (h); + CAMLassert (t != Infix_tag); newadr = compact_allocate (Bsize_wsize (sz)); q = *p; - while (Ecolor (q) == 0){ - word next = * (word *) q; - * (word *) q = (word) Val_hp (newadr); - q = next; + while (Is_gray_hd (q)){ + word *pp = dptr (q); + q = *pp; + *pp = (word) Val_hp (newadr); } - *p = Make_header_with_profinfo (Wosize_whsize (sz), t, Caml_white, - profinfo); - - if (infixes != NULL){ - /* Rebuild the infix headers and revert the infix pointers. */ - while (Ecolor ((word) infixes) != 3){ - infixes = (word *) ((word) infixes & ~(uintnat) 3); - q = *infixes; - while (Ecolor (q) == 2){ - word next; - q = (word) q & ~(uintnat) 3; - next = * (word *) q; - * (word *) q = (word) Val_hp ((word *) newadr + (infixes - p)); - q = next; + CAMLassert (q == h); + *p = q; + + if (t == Closure_tag){ + /* Revert the infix pointers to this block. */ + mlsize_t i, startenv; + value v; + + v = Val_hp (p); + startenv = Start_env_closinfo (Closinfo_val (v)); + i = 0; + while (1){ + int arity = Arity_closinfo (Field (v, i+1)); + i += 2 + (arity != 0 && arity != 1); + if (i >= startenv) break; + + /* Revert the inverted list for infix header at offset [i]. */ + q = Field (v, i); + while (Is_gray_hd (q)){ + word *pp = dptr (q); + q = *pp; + *pp = (word) Val_hp ((header_t *) &Field (Val_hp (newadr), i)); } - CAMLassert (Ecolor (q) == 1 || Ecolor (q) == 3); - /* No need to preserve any profinfo value on the [Infix_tag] - headers; the Spacetime profiling heap snapshot code doesn't - look at them. */ - *infixes = Make_header (infixes - p, Infix_tag, Caml_white); - infixes = (word *) q; + CAMLassert (Tag_hd (q) == Infix_tag); + Field (v, i) = q; + ++i; } } - p += sz; - }else{ - CAMLassert (Ecolor (q) == 3); - /* This is guaranteed only if caml_compact_heap was called after a - nonincremental major GC: CAMLassert (Tag_ehd (q) == String_tag); - */ - /* No pointers to the header and no infix header: - the object was free. */ - *p = Make_header (Wosize_ehd (q), Tag_ehd (q), Caml_blue); - p += Whsize_ehd (q); } + p += sz; } ch = Chunk_next (ch); } @@ -432,6 +368,9 @@ static void do_compaction (intnat new_allocation_policy) } } ++ Caml_state->stat_compactions; + + caml_shrink_mark_stack(); + caml_gc_message (0x10, "done.\n"); } @@ -565,7 +504,10 @@ void caml_compact_heap_maybe (void) if (fp >= caml_percent_max){ caml_gc_message (0x200, "Automatic compaction triggered.\n"); caml_empty_minor_heap (); /* minor heap must be empty for compaction */ + caml_gc_message + (0x1, "Finishing major GC cycle (triggered by compaction)\n"); caml_finish_major_cycle (); + ++ Caml_state->stat_forced_major_collections; fw = caml_fl_cur_wsz; fp = 100.0 * fw / (Caml_state->stat_heap_wsz - fw); diff --git a/runtime/compare.c b/runtime/compare.c index 974e0c01..4a0eb6ea 100644 --- a/runtime/compare.c +++ b/runtime/compare.c @@ -127,11 +127,9 @@ static intnat do_compare_val(struct compare_stack* stk, if (Is_long(v2)) return Long_val(v1) - Long_val(v2); /* Subtraction above cannot overflow and cannot result in UNORDERED */ -#ifndef NO_NAKED_POINTERS if (!Is_in_value_area(v2)) return LESS; -#endif - switch (Tag_val(v2)) { + switch (Tag_val(v2)) { case Forward_tag: v2 = Forward_val(v2); continue; @@ -150,11 +148,9 @@ static intnat do_compare_val(struct compare_stack* stk, return LESS; /* v1 long < v2 block */ } if (Is_long(v2)) { -#ifndef NO_NAKED_POINTERS if (!Is_in_value_area(v1)) return GREATER; -#endif - switch (Tag_val(v1)) { + switch (Tag_val(v1)) { case Forward_tag: v1 = Forward_val(v1); continue; @@ -172,7 +168,6 @@ static intnat do_compare_val(struct compare_stack* stk, } return GREATER; /* v1 block > v2 long */ } -#ifndef NO_NAKED_POINTERS /* If one of the objects is outside the heap (but is not an atom), use address comparison. Since both addresses are 2-aligned, shift lsb off to avoid overflow in subtraction. */ @@ -181,13 +176,30 @@ static intnat do_compare_val(struct compare_stack* stk, return (v1 >> 1) - (v2 >> 1); /* Subtraction above cannot result in UNORDERED */ } -#endif t1 = Tag_val(v1); t2 = Tag_val(v2); - if (t1 == Forward_tag) { v1 = Forward_val (v1); continue; } - if (t2 == Forward_tag) { v2 = Forward_val (v2); continue; } - if (t1 != t2) return (intnat)t1 - (intnat)t2; + if (t1 != t2) { + /* Besides long/block comparisons, the only forms of + heterogeneous comparisons we support are: + - Forward_tag pointers, which may point to values of any type, and + - comparing Infix_tag and Closure_tag functions (#9521). + + Other heterogeneous cases may still happen due to + existential types, and we just compare the tags. + */ + if (t1 == Forward_tag) { v1 = Forward_val (v1); continue; } + if (t2 == Forward_tag) { v2 = Forward_val (v2); continue; } + if (t1 == Infix_tag) t1 = Closure_tag; + if (t2 == Infix_tag) t2 = Closure_tag; + if (t1 != t2) + return (intnat)t1 - (intnat)t2; + } switch(t1) { + case Forward_tag: { + v1 = Forward_val (v1); + v2 = Forward_val (v2); + continue; + } case String_tag: { mlsize_t len1, len2; int res; diff --git a/runtime/custom.c b/runtime/custom.c index 8568b587..3ff5462c 100644 --- a/runtime/custom.c +++ b/runtime/custom.c @@ -24,6 +24,7 @@ #include "caml/memory.h" #include "caml/mlvalues.h" #include "caml/signals.h" +#include "caml/memprof.h" uintnat caml_custom_major_ratio = Custom_major_ratio_def; uintnat caml_custom_minor_ratio = Custom_minor_ratio_def; @@ -102,7 +103,9 @@ CAMLexport value caml_alloc_custom_mem(struct custom_operations * ops, Bsize_wsize (Caml_state->stat_heap_wsz) / 150 * caml_custom_major_ratio; mlsize_t max_minor = Bsize_wsize (Caml_state->minor_heap_wsz) / 100 * caml_custom_minor_ratio; - return alloc_custom_gen (ops, bsz, mem, max_major, mem_minor, max_minor); + value v = alloc_custom_gen (ops, bsz, mem, max_major, mem_minor, max_minor); + caml_memprof_track_custom(v, mem); + return v; } struct custom_operations_list { @@ -155,11 +158,6 @@ struct custom_operations * caml_final_custom_operations(final_fun fn) return ops; } -extern struct custom_operations caml_int32_ops, - caml_nativeint_ops, - caml_int64_ops, - caml_ba_ops; - void caml_init_custom_operations(void) { caml_register_custom_operations(&caml_int32_ops); diff --git a/runtime/debugger.c b/runtime/debugger.c index 050389e2..53d85c94 100644 --- a/runtime/debugger.c +++ b/runtime/debugger.c @@ -45,7 +45,7 @@ void caml_debugger(enum event_kind event, value param) { } -void caml_debugger_cleanup_fork(void) +CAMLexport void caml_debugger_cleanup_fork(void) { } @@ -141,6 +141,12 @@ static void open_connection(void) #endif dbg_in = caml_open_descriptor_in(dbg_socket); dbg_out = caml_open_descriptor_out(dbg_socket); + /* The code in this file does not bracket channel I/O operations with + Lock and Unlock, so fail if those are not no-ops. */ + if (caml_channel_mutex_lock != NULL || + caml_channel_mutex_unlock != NULL || + caml_channel_mutex_unlock_exn != NULL) + caml_fatal_error("debugger does not support channel locks"); if (!caml_debugger_in_use) caml_putword(dbg_out, -1); /* first connection */ #ifdef _WIN32 caml_putword(dbg_out, _getpid()); @@ -556,7 +562,7 @@ void caml_debugger(enum event_kind event, value param) } } -void caml_debugger_cleanup_fork(void) +CAMLexport void caml_debugger_cleanup_fork(void) { /* We could remove all of the event points, but closing the connection * means that they'll just be skipped anyway. */ diff --git a/runtime/domain.c b/runtime/domain.c index 0850021f..d4d8de53 100644 --- a/runtime/domain.c +++ b/runtime/domain.c @@ -69,6 +69,7 @@ void caml_init_domain () Caml_state->stat_heap_wsz = 0; Caml_state->stat_top_heap_wsz = 0; Caml_state->stat_compactions = 0; + Caml_state->stat_forced_major_collections = 0; Caml_state->stat_heap_chunks = 0; Caml_state->backtrace_active = 0; @@ -86,4 +87,8 @@ void caml_init_domain () Caml_state->eventlog_startup_pid = 0; Caml_state->eventlog_startup_timestamp = 0; Caml_state->eventlog_out = NULL; + +#if defined(NAKED_POINTERS_CHECKER) && !defined(_WIN32) + Caml_state->checking_pointer_pc = NULL; + #endif } diff --git a/runtime/dune b/runtime/dune index 4b9c50af..3b4e2cc1 100644 --- a/runtime/dune +++ b/runtime/dune @@ -15,29 +15,42 @@ (rule (targets primitives) (mode fallback) - (deps alloc.c array.c compare.c extern.c floats.c gc_ctrl.c hash.c intern.c - interp.c ints.c io.c lexing.c md5.c meta.c obj.c parsing.c signals.c - str.c sys.c callback.c weak.c finalise.c stacks.c dynlink.c - backtrace_byt.c backtrace.c spacetime_byt.c afl.c bigarray.c) + (deps + ; matches the line structure of files in gen_primitives.sh + alloc.c array.c compare.c extern.c floats.c gc_ctrl.c hash.c intern.c + interp.c ints.c io.c + lexing.c md5.c meta.c memprof.c obj.c parsing.c signals.c str.c sys.c + callback.c weak.c + finalise.c stacks.c dynlink.c backtrace_byt.c backtrace.c + afl.c + bigarray.c eventlog.c) (action (with-stdout-to %{targets} (run %{dep:gen_primitives.sh})))) (rule (targets libcamlrun.a) (mode fallback) - (deps ../Makefile.config ../Makefile.common Makefile - (glob_files caml/*.h) - interp.c misc.c stacks.c fix_code.c startup_aux.c startup_byt.c - freelist.c major_gc.c minor_gc.c memory.c alloc.c roots_byt.c - globroots.c fail_byt.c signals.c signals_byt.c printexc.c - backtrace_byt.c backtrace.c compare.c ints.c floats.c str.c array.c - io.c extern.c intern.c hash.c sys.c meta.c parsing.c gc_ctrl.c md5.c - obj.c lexing.c callback.c debugger.c weak.c compact.c finalise.c - custom.c dynlink.c spacetime_byt.c afl.c unix.c win32.c bigarray.c - main.c memprof.c domain.c) + (deps + ../Makefile.config + ../Makefile.build_config + ../Makefile.config_if_required + ../Makefile.common Makefile + (glob_files caml/*.h) + ; matches the line structure of files in Makefile/BYTECODE_C_SOURCES + interp.c misc.c stacks.c fix_code.c startup_aux.c startup_byt.c freelist.c + major_gc.c + minor_gc.c memory.c alloc.c roots_byt.c globroots.c fail_byt.c signals.c + signals_byt.c printexc.c backtrace_byt.c backtrace.c compare.c ints.c + eventlog.c + floats.c str.c array.c io.c extern.c intern.c hash.c sys.c meta.c parsing.c + gc_ctrl.c md5.c obj.c + lexing.c callback.c debugger.c weak.c compact.c finalise.c custom.c dynlink.c + afl.c unix.c win32.c bigarray.c main.c memprof.c domain.c + skiplist.c codefrag.c + ) (action (progn (bash "touch .depend") ; hack. - (run make %{targets}) + (run make %{targets} COMPUTE_DEPS=false) (bash "rm .depend")))) ;; HACK diff --git a/runtime/dynlink_nat.c b/runtime/dynlink_nat.c index 0bd2319b..dba30c38 100644 --- a/runtime/dynlink_nat.c +++ b/runtime/dynlink_nat.c @@ -26,9 +26,6 @@ #include "caml/osdeps.h" #include "caml/fail.h" #include "caml/signals.h" -#ifdef WITH_SPACETIME -#include "caml/spacetime.h" -#endif #include "caml/hooks.h" @@ -111,11 +108,6 @@ CAMLprim value caml_natdynlink_run(value handle_v, value symbol) { sym = optsym("__frametable"); if (NULL != sym) caml_register_frametable(sym); -#ifdef WITH_SPACETIME - sym = optsym("__spacetime_shapes"); - if (NULL != sym) caml_spacetime_register_shapes(sym); -#endif - sym = optsym("__gc_roots"); if (NULL != sym) caml_register_dyn_global(sym); @@ -126,11 +118,9 @@ CAMLprim value caml_natdynlink_run(value handle_v, value symbol) { sym = optsym("__code_begin"); sym2 = optsym("__code_end"); - if (NULL != sym && NULL != sym2) { - caml_page_table_add(In_code_area, sym, sym2); + if (NULL != sym && NULL != sym2) caml_register_code_fragment((char *) sym, (char *) sym2, DIGEST_LATER, NULL); - } if( caml_natdynlink_hook != NULL ) caml_natdynlink_hook(handle,unit); diff --git a/runtime/eventlog.c b/runtime/eventlog.c index 6d3bd7ca..2ed452da 100644 --- a/runtime/eventlog.c +++ b/runtime/eventlog.c @@ -139,12 +139,12 @@ static void setup_eventlog_file() eventlog_filename = caml_secure_getenv(T("OCAML_EVENTLOG_PREFIX")); if (eventlog_filename) { - int ret = snprintf_os(output_file, OUTPUT_FILE_LEN, T("%s.%d.eventlog"), + int ret = snprintf_os(output_file, OUTPUT_FILE_LEN, T("%s.%ld.eventlog"), eventlog_filename, Caml_state->eventlog_startup_pid); if (ret > OUTPUT_FILE_LEN) caml_fatal_error("eventlog: specified OCAML_EVENTLOG_PREFIX is too long"); } else { - snprintf_os(output_file, OUTPUT_FILE_LEN, T("caml-%d.eventlog"), + snprintf_os(output_file, OUTPUT_FILE_LEN, T("caml-%ld.eventlog"), Caml_state->eventlog_startup_pid); } diff --git a/runtime/extern.c b/runtime/extern.c index 440753a2..d87177ea 100644 --- a/runtime/extern.c +++ b/runtime/extern.c @@ -480,13 +480,211 @@ static void writecode64(int code, intnat val) } #endif -/* Marshal the given value in the output buffer */ +/* Marshaling integers */ + +Caml_inline void extern_int(intnat n) +{ + if (n >= 0 && n < 0x40) { + write(PREFIX_SMALL_INT + n); + } else if (n >= -(1 << 7) && n < (1 << 7)) { + writecode8(CODE_INT8, n); + } else if (n >= -(1 << 15) && n < (1 << 15)) { + writecode16(CODE_INT16, n); +#ifdef ARCH_SIXTYFOUR + } else if (n < -((intnat)1 << 30) || n >= ((intnat)1 << 30)) { + if (extern_flags & COMPAT_32) + extern_failwith("output_value: integer cannot be read back on " + "32-bit platform"); + writecode64(CODE_INT64, n); +#endif + } else { + writecode32(CODE_INT32, n); + } +} -int caml_extern_allow_out_of_heap = 0; +/* Marshaling references to previously-marshaled blocks */ -static void extern_rec(value v) +Caml_inline void extern_shared_reference(uintnat d) +{ + if (d < 0x100) { + writecode8(CODE_SHARED8, d); + } else if (d < 0x10000) { + writecode16(CODE_SHARED16, d); +#ifdef ARCH_SIXTYFOUR + } else if (d >= (uintnat)1 << 32) { + writecode64(CODE_SHARED64, d); +#endif + } else { + writecode32(CODE_SHARED32, d); + } +} + +/* Marshaling block headers */ + +Caml_inline void extern_header(mlsize_t sz, tag_t tag) +{ + if (tag < 16 && sz < 8) { + write(PREFIX_SMALL_BLOCK + tag + (sz << 4)); + } else { + header_t hd = Make_header(sz, tag, Caml_white); +#ifdef ARCH_SIXTYFOUR + if (sz > 0x3FFFFF && (extern_flags & COMPAT_32)) + extern_failwith("output_value: array cannot be read back on " + "32-bit platform"); + if (hd < (uintnat)1 << 32) + writecode32(CODE_BLOCK32, hd); + else + writecode64(CODE_BLOCK64, hd); +#else + writecode32(CODE_BLOCK32, hd); +#endif + } +} + +/* Marshaling strings */ + +Caml_inline void extern_string(value v, mlsize_t len) +{ + if (len < 0x20) { + write(PREFIX_SMALL_STRING + len); + } else if (len < 0x100) { + writecode8(CODE_STRING8, len); + } else { +#ifdef ARCH_SIXTYFOUR + if (len > 0xFFFFFB && (extern_flags & COMPAT_32)) + extern_failwith("output_value: string cannot be read back on " + "32-bit platform"); + if (len < (uintnat)1 << 32) + writecode32(CODE_STRING32, len); + else + writecode64(CODE_STRING64, len); +#else + writecode32(CODE_STRING32, len); +#endif + } + writeblock(String_val(v), len); +} + +/* Marshaling FP numbers */ + +Caml_inline void extern_double(value v) +{ + write(CODE_DOUBLE_NATIVE); + writeblock_float8((double *) v, 1); +} + +/* Marshaling FP arrays */ + +Caml_inline void extern_double_array(value v, mlsize_t nfloats) +{ + if (nfloats < 0x100) { + writecode8(CODE_DOUBLE_ARRAY8_NATIVE, nfloats); + } else { +#ifdef ARCH_SIXTYFOUR + if (nfloats > 0x1FFFFF && (extern_flags & COMPAT_32)) + extern_failwith("output_value: float array cannot be read back on " + "32-bit platform"); + if (nfloats < (uintnat) 1 << 32) + writecode32(CODE_DOUBLE_ARRAY32_NATIVE, nfloats); + else + writecode64(CODE_DOUBLE_ARRAY64_NATIVE, nfloats); +#else + writecode32(CODE_DOUBLE_ARRAY32_NATIVE, nfloats); +#endif + } + writeblock_float8((double *) v, nfloats); +} + +/* Marshaling custom blocks */ + +Caml_inline void extern_custom(value v, + /*out*/ uintnat * sz_32, + /*out*/ uintnat * sz_64) +{ + char * size_header; + char const * ident = Custom_ops_val(v)->identifier; + void (*serialize)(value v, uintnat * bsize_32, uintnat * bsize_64) + = Custom_ops_val(v)->serialize; + const struct custom_fixed_length* fixed_length + = Custom_ops_val(v)->fixed_length; + if (serialize == NULL) + extern_invalid_argument("output_value: abstract value (Custom)"); + if (fixed_length == NULL) { + write(CODE_CUSTOM_LEN); + writeblock(ident, strlen(ident) + 1); + /* Reserve 12 bytes for the lengths (sz_32 and sz_64). */ + if (extern_ptr + 12 >= extern_limit) grow_extern_output(12); + size_header = extern_ptr; + extern_ptr += 12; + serialize(v, sz_32, sz_64); + /* Store length before serialized block */ + store32(size_header, *sz_32); + store64(size_header + 4, *sz_64); + } else { + write(CODE_CUSTOM_FIXED); + writeblock(ident, strlen(ident) + 1); + serialize(v, sz_32, sz_64); + if (*sz_32 != fixed_length->bsize_32 || + *sz_64 != fixed_length->bsize_64) + caml_fatal_error( + "output_value: incorrect fixed sizes specified by %s", + ident); + } +} + +/* Marshaling code pointers */ + +static void extern_code_pointer(char * codeptr) { struct code_fragment * cf; + const char * digest; + + cf = caml_find_code_fragment_by_pc(codeptr); + if (cf != NULL) { + if ((extern_flags & CLOSURES) == 0) + extern_invalid_argument("output_value: functional value"); + digest = (const char *) caml_digest_of_code_fragment(cf); + if (digest == NULL) + extern_invalid_argument("output_value: private function"); + writecode32(CODE_CODEPOINTER, codeptr - cf->code_start); + writeblock(digest, 16); + } else { + extern_invalid_argument("output_value: abstract value (outside heap)"); + } +} + +/* Marshaling the non-environment part of closures */ + +#ifdef NO_NAKED_POINTERS +Caml_inline mlsize_t extern_closure_up_to_env(value v) +{ + mlsize_t startenv, i; + value info; + + startenv = Start_env_closinfo(Closinfo_val(v)); + i = 0; + do { + /* The infix header */ + if (i > 0) extern_int(Long_val(Field(v, i++))); + /* The default entry point */ + extern_code_pointer((char *) Field(v, i++)); + /* The closure info. */ + info = Field(v, i++); + extern_int(Long_val(info)); + /* The direct entry point if arity is neither 0 nor 1 */ + if (Arity_closinfo(info) != 0 && Arity_closinfo(info) != 1) { + extern_code_pointer((char *) Field(v, i++)); + } + } while (i < startenv); + CAMLassert(i == startenv); + return startenv; +} +#endif + +/* Marshal the given value in the output buffer */ + +static void extern_rec(value v) +{ struct extern_item * sp; uintnat h = 0; uintnat pos = 0; @@ -496,25 +694,14 @@ static void extern_rec(value v) while(1) { if (Is_long(v)) { - intnat n = Long_val(v); - if (n >= 0 && n < 0x40) { - write(PREFIX_SMALL_INT + n); - } else if (n >= -(1 << 7) && n < (1 << 7)) { - writecode8(CODE_INT8, n); - } else if (n >= -(1 << 15) && n < (1 << 15)) { - writecode16(CODE_INT16, n); -#ifdef ARCH_SIXTYFOUR - } else if (n < -((intnat)1 << 30) || n >= ((intnat)1 << 30)) { - if (extern_flags & COMPAT_32) - extern_failwith("output_value: integer cannot be read back on " - "32-bit platform"); - writecode64(CODE_INT64, n); -#endif - } else - writecode32(CODE_INT32, n); - goto next_item; + extern_int(Long_val(v)); + } + else if (! (Is_in_value_area(v))) { + /* Naked pointer outside the heap: try to marshal it as a code pointer, + otherwise fail. */ + extern_code_pointer((char *) v); } - if (Is_in_value_area(v) || caml_extern_allow_out_of_heap) { + else { header_t hd = Hd_val(v); tag_t tag = Tag_hd(hd); mlsize_t sz = Wosize_hd(hd); @@ -537,68 +724,29 @@ static void extern_rec(value v) /* Atoms are treated specially for two reasons: they are not allocated in the externed block, and they are automatically shared. */ if (sz == 0) { - if (tag < 16) { - write(PREFIX_SMALL_BLOCK + tag); - } else { -#ifdef WITH_PROFINFO - writecode32(CODE_BLOCK32, Hd_no_profinfo(hd)); -#else - writecode32(CODE_BLOCK32, hd); -#endif - } + extern_header(0, tag); goto next_item; } /* Check if object already seen */ if (! (extern_flags & NO_SHARING)) { if (extern_lookup_position(v, &pos, &h)) { - uintnat d = obj_counter - pos; - if (d < 0x100) { - writecode8(CODE_SHARED8, d); - } else if (d < 0x10000) { - writecode16(CODE_SHARED16, d); -#ifdef ARCH_SIXTYFOUR - } else if (d >= (uintnat)1 << 32) { - writecode64(CODE_SHARED64, d); -#endif - } else { - writecode32(CODE_SHARED32, d); - } + extern_shared_reference(obj_counter - pos); goto next_item; } } - /* Output the contents of the object */ switch(tag) { case String_tag: { mlsize_t len = caml_string_length(v); - if (len < 0x20) { - write(PREFIX_SMALL_STRING + len); - } else if (len < 0x100) { - writecode8(CODE_STRING8, len); - } else { -#ifdef ARCH_SIXTYFOUR - if (len > 0xFFFFFB && (extern_flags & COMPAT_32)) - extern_failwith("output_value: string cannot be read back on " - "32-bit platform"); - if (len < (uintnat)1 << 32) - writecode32(CODE_STRING32, len); - else - writecode64(CODE_STRING64, len); -#else - writecode32(CODE_STRING32, len); -#endif - } - writeblock(String_val(v), len); + extern_string(v, len); size_32 += 1 + (len + 4) / 4; size_64 += 1 + (len + 8) / 8; extern_record_location(v, h); break; } case Double_tag: { - if (sizeof(double) != 8) - extern_invalid_argument("output_value: non-standard floats"); - write(CODE_DOUBLE_NATIVE); - writeblock_float8((double *) v, 1); + CAMLassert(sizeof(double) == 8); + extern_double(v); size_32 += 1 + 2; size_64 += 1 + 1; extern_record_location(v, h); @@ -606,25 +754,9 @@ static void extern_rec(value v) } case Double_array_tag: { mlsize_t nfloats; - if (sizeof(double) != 8) - extern_invalid_argument("output_value: non-standard floats"); + CAMLassert(sizeof(double) == 8); nfloats = Wosize_val(v) / Double_wosize; - if (nfloats < 0x100) { - writecode8(CODE_DOUBLE_ARRAY8_NATIVE, nfloats); - } else { -#ifdef ARCH_SIXTYFOUR - if (nfloats > 0x1FFFFF && (extern_flags & COMPAT_32)) - extern_failwith("output_value: float array cannot be read back on " - "32-bit platform"); - if (nfloats < (uintnat) 1 << 32) - writecode32(CODE_DOUBLE_ARRAY32_NATIVE, nfloats); - else - writecode64(CODE_DOUBLE_ARRAY64_NATIVE, nfloats); -#else - writecode32(CODE_DOUBLE_ARRAY32_NATIVE, nfloats); -#endif - } - writeblock_float8((double *) v, nfloats); + extern_double_array(v, nfloats); size_32 += 1 + nfloats * 2; size_64 += 1 + nfloats; extern_record_location(v, h); @@ -639,92 +771,51 @@ static void extern_rec(value v) continue; case Custom_tag: { uintnat sz_32, sz_64; - char * size_header; - char const * ident = Custom_ops_val(v)->identifier; - void (*serialize)(value v, uintnat * bsize_32, - uintnat * bsize_64) - = Custom_ops_val(v)->serialize; - const struct custom_fixed_length* fixed_length - = Custom_ops_val(v)->fixed_length; - if (serialize == NULL) - extern_invalid_argument("output_value: abstract value (Custom)"); - if (fixed_length == NULL) { - write(CODE_CUSTOM_LEN); - writeblock(ident, strlen(ident) + 1); - /* Reserve 12 bytes for the lengths (sz_32 and sz_64). */ - if (extern_ptr + 12 >= extern_limit) grow_extern_output(12); - size_header = extern_ptr; - extern_ptr += 12; - serialize(v, &sz_32, &sz_64); - /* Store length before serialized block */ - store32(size_header, sz_32); - store64(size_header + 4, sz_64); - } else { - write(CODE_CUSTOM_FIXED); - writeblock(ident, strlen(ident) + 1); - serialize(v, &sz_32, &sz_64); - if (sz_32 != fixed_length->bsize_32 || - sz_64 != fixed_length->bsize_64) - caml_fatal_error( - "output_value: incorrect fixed sizes specified by %s", - ident); - } + extern_custom(v, &sz_32, &sz_64); size_32 += 2 + ((sz_32 + 3) >> 2); /* header + ops + data */ size_64 += 2 + ((sz_64 + 7) >> 3); extern_record_location(v, h); break; } - default: { - value field0; - if (tag < 16 && sz < 8) { - write(PREFIX_SMALL_BLOCK + tag + (sz << 4)); - } else { -#ifdef ARCH_SIXTYFOUR -#ifdef WITH_PROFINFO - header_t hd_erased = Hd_no_profinfo(hd); -#else - header_t hd_erased = hd; -#endif - if (sz > 0x3FFFFF && (extern_flags & COMPAT_32)) - extern_failwith("output_value: array cannot be read back on " - "32-bit platform"); - if (hd_erased < (uintnat)1 << 32) - writecode32(CODE_BLOCK32, Whitehd_hd (hd_erased)); - else - writecode64(CODE_BLOCK64, Whitehd_hd (hd_erased)); -#else - writecode32(CODE_BLOCK32, Whitehd_hd (hd)); -#endif +#ifdef NO_NAKED_POINTERS + case Closure_tag: { + mlsize_t i; + extern_header(sz, tag); + size_32 += 1 + sz; + size_64 += 1 + sz; + extern_record_location(v, h); + i = extern_closure_up_to_env(v); + if (i >= sz) goto next_item; + /* Remember that we still have to serialize fields i + 1 ... sz - 1 */ + if (i < sz - 1) { + sp++; + if (sp >= extern_stack_limit) sp = extern_resize_stack(sp); + sp->v = &Field(v, i + 1); + sp->count = sz - i - 1; } + /* Continue serialization with the first environment field */ + v = Field(v, i); + continue; + } +#endif + default: { + extern_header(sz, tag); size_32 += 1 + sz; size_64 += 1 + sz; - field0 = Field(v, 0); extern_record_location(v, h); /* Remember that we still have to serialize fields 1 ... sz - 1 */ if (sz > 1) { sp++; if (sp >= extern_stack_limit) sp = extern_resize_stack(sp); - sp->v = &Field(v,1); - sp->count = sz-1; + sp->v = &Field(v, 1); + sp->count = sz - 1; } /* Continue serialization with the first field */ - v = field0; + v = Field(v, 0); continue; } } } - else if ((cf = caml_find_code_fragment_by_pc((char*) v)) != NULL) { - const char * digest; - if ((extern_flags & CLOSURES) == 0) - extern_invalid_argument("output_value: functional value"); - digest = (const char *) caml_digest_of_code_fragment(cf); - if (digest == NULL) - extern_invalid_argument("output_value: private function"); - writecode32(CODE_CODEPOINTER, (char *) v - cf->code_start); - writeblock(digest, 16); - } else { - extern_invalid_argument("output_value: abstract value (outside heap)"); - } next_item: /* Pop one more item to marshal, if any */ if (sp == extern_stack) { @@ -1035,3 +1126,65 @@ CAMLexport void caml_serialize_block_float_8(void * data, intnat len) } #endif } + +CAMLprim value caml_obj_reachable_words(value v) +{ + intnat size; + struct extern_item * sp; + uintnat h = 0; + uintnat pos; + + extern_init_position_table(); + sp = extern_stack; + size = 0; + while (1) { + if (Is_long(v)) { + /* Tagged integers contribute 0 to the size, nothing to do */ + } else if (! Is_in_heap_or_young(v)) { + /* Out-of-heap blocks contribute 0 to the size, nothing to do */ + /* However, in no-naked-pointers mode, we don't distinguish + between major heap blocks and out-of-heap blocks, + and the test above is always false, + so we end up counting out-of-heap blocks too. */ + } else if (extern_lookup_position(v, &pos, &h)) { + /* Already seen and counted, nothing to do */ + } else { + header_t hd = Hd_val(v); + tag_t tag = Tag_hd(hd); + mlsize_t sz = Wosize_hd(hd); + /* Infix pointer: go back to containing closure */ + if (tag == Infix_tag) { + v = v - Infix_offset_hd(hd); + continue; + } + /* Remember that we've visited this block */ + extern_record_location(v, h); + /* The block contributes to the total size */ + size += 1 + sz; /* header word included */ + if (tag < No_scan_tag) { + /* i is the position of the first field to traverse recursively */ + uintnat i = + tag == Closure_tag ? Start_env_closinfo(Closinfo_val(v)) : 0; + if (i < sz) { + if (i < sz - 1) { + /* Remember that we need to count fields i + 1 ... sz - 1 */ + sp++; + if (sp >= extern_stack_limit) sp = extern_resize_stack(sp); + sp->v = &Field(v, i + 1); + sp->count = sz - i - 1; + } + /* Continue with field i */ + v = Field(v, i); + continue; + } + } + } + /* Pop one more item to traverse, if any */ + if (sp == extern_stack) break; + v = *((sp->v)++); + if (--(sp->count) == 0) sp--; + } + extern_free_stack(); + extern_free_position_table(); + return Val_long(size); +} diff --git a/runtime/fail_byt.c b/runtime/fail_byt.c index b2e8d8b7..0d0d2b05 100644 --- a/runtime/fail_byt.c +++ b/runtime/fail_byt.c @@ -34,6 +34,13 @@ CAMLexport void caml_raise(value v) { Unlock_exn(); + CAMLassert(!Is_exception_result(v)); + + // avoid calling caml_raise recursively + v = caml_process_pending_actions_with_root_exn(v); + if (Is_exception_result(v)) + v = Extract_exception(v); + Caml_state->exn_bucket = v; if (Caml_state->external_raise == NULL) caml_fatal_uncaught_exception(v); siglongjmp(Caml_state->external_raise->buf, 1); @@ -190,7 +197,7 @@ CAMLexport void caml_raise_sys_blocked_io(void) caml_raise_constant(Field(caml_global_data, SYS_BLOCKED_IO)); } -value caml_raise_if_exception(value res) +CAMLexport value caml_raise_if_exception(value res) { if (Is_exception_result(res)) caml_raise(Extract_exception(res)); return res; diff --git a/runtime/fail_nat.c b/runtime/fail_nat.c index 380578ac..352206f9 100644 --- a/runtime/fail_nat.c +++ b/runtime/fail_nat.c @@ -62,6 +62,14 @@ CAMLno_asan void caml_raise(value v) { Unlock_exn(); + + CAMLassert(!Is_exception_result(v)); + + // avoid calling caml_raise recursively + v = caml_process_pending_actions_with_root_exn(v); + if (Is_exception_result(v)) + v = Extract_exception(v); + if (Caml_state->exception_pointer == NULL) caml_fatal_uncaught_exception(v); while (Caml_state->local_roots != NULL && @@ -173,7 +181,7 @@ void caml_raise_sys_blocked_io(void) caml_raise_constant((value) caml_exn_Sys_blocked_io); } -value caml_raise_if_exception(value res) +CAMLexport value caml_raise_if_exception(value res) { if (Is_exception_result(res)) caml_raise(Extract_exception(res)); return res; diff --git a/runtime/finalise.c b/runtime/finalise.c index 455f91ae..46e1b7dd 100644 --- a/runtime/finalise.c +++ b/runtime/finalise.c @@ -25,9 +25,6 @@ #include "caml/mlvalues.h" #include "caml/roots.h" #include "caml/signals.h" -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) -#include "caml/spacetime.h" -#endif struct final { value fun; @@ -170,9 +167,6 @@ value caml_final_do_calls_exn (void) { struct final f; value res; -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - void* saved_spacetime_trie_node_ptr; -#endif if (!running_finalisation_function && to_do_hd != NULL){ if (caml_finalise_begin_hook != NULL) (*caml_finalise_begin_hook) (); @@ -189,17 +183,7 @@ value caml_final_do_calls_exn (void) -- to_do_hd->size; f = to_do_hd->item[to_do_hd->size]; running_finalisation_function = 1; -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - /* We record the finaliser's execution separately. - (The code of [caml_callback_exn] will do the hard work of finding - the correct place in the trie.) */ - saved_spacetime_trie_node_ptr = caml_spacetime_trie_node_ptr; - caml_spacetime_trie_node_ptr = caml_spacetime_finaliser_trie_root; -#endif res = caml_callback_exn (f.fun, f.val + f.offset); -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - caml_spacetime_trie_node_ptr = saved_spacetime_trie_node_ptr; -#endif running_finalisation_function = 0; if (Is_exception_result (res)) return res; } diff --git a/runtime/floats.c b/runtime/floats.c index c8176502..7b8d04a1 100644 --- a/runtime/floats.c +++ b/runtime/floats.c @@ -1047,23 +1047,3 @@ CAMLprim value caml_classify_float(value vd) { return caml_classify_float_unboxed(Double_val(vd)); } - -/* The [caml_init_ieee_float] function should initialize floating-point hardware - so that it behaves as much as possible like the IEEE standard. - In particular, return special numbers like Infinity and NaN instead - of signalling exceptions. Currently, everyone is in IEEE mode - at program startup, except FreeBSD prior to 4.0R. */ - -#ifdef __FreeBSD__ -#include -#if (__FreeBSD_version < 400017) -#include -#endif -#endif - -void caml_init_ieee_floats(void) -{ -#if defined(__FreeBSD__) && (__FreeBSD_version < 400017) - fpsetmask(0); -#endif -} diff --git a/runtime/freelist.c b/runtime/freelist.c index 363adaaf..66bcca3b 100644 --- a/runtime/freelist.c +++ b/runtime/freelist.c @@ -1523,7 +1523,7 @@ static header_t *bf_allocate (mlsize_t wosz) return Hp_val (block); }else{ /* allocate from the next available size */ - mlsize_t s = ffs (bf_small_map & ((-1) << wosz)); + mlsize_t s = ffs (bf_small_map & ((~0U) << wosz)); FREELIST_DEBUG_bf_check (); if (s != 0){ block = bf_small_fl[s].free; @@ -1670,7 +1670,6 @@ static header_t *bf_merge_block (value bp, char *limit) switch (Color_val (cur)){ case Caml_white: goto white; case Caml_blue: bf_remove (cur); goto next; - case Caml_gray: case Caml_black: goto end_of_run; } diff --git a/runtime/gc_ctrl.c b/runtime/gc_ctrl.c index 539d6176..4d51cb42 100644 --- a/runtime/gc_ctrl.c +++ b/runtime/gc_ctrl.c @@ -173,7 +173,7 @@ static value heap_stats (int returnstats) } } break; - case Caml_gray: case Caml_black: + case Caml_black: CAMLassert (Wosize_hd (cur_hd) > 0); ++ live_blocks; live_words += Whsize_hd (cur_hd); @@ -233,9 +233,10 @@ static value heap_stats (int returnstats) intnat majcoll = Caml_state->stat_major_collections; intnat heap_words = Caml_state->stat_heap_wsz; intnat cpct = Caml_state->stat_compactions; + intnat forcmajcoll = Caml_state->stat_forced_major_collections; intnat top_heap_words = Caml_state->stat_top_heap_wsz; - res = caml_alloc_tuple (16); + res = caml_alloc_tuple (17); Store_field (res, 0, caml_copy_double (minwords)); Store_field (res, 1, caml_copy_double (prowords)); Store_field (res, 2, caml_copy_double (majwords)); @@ -252,6 +253,7 @@ static value heap_stats (int returnstats) Store_field (res, 13, Val_long (cpct)); Store_field (res, 14, Val_long (top_heap_words)); Store_field (res, 15, Val_long (caml_stack_usage())); + Store_field (res, 16, Val_long (forcmajcoll)); CAMLreturn (res); }else{ CAMLreturn (Val_unit); @@ -292,9 +294,10 @@ CAMLprim value caml_gc_quick_stat(value v) intnat heap_words = Caml_state->stat_heap_wsz; intnat top_heap_words = Caml_state->stat_top_heap_wsz; intnat cpct = Caml_state->stat_compactions; + intnat forcmajcoll = Caml_state->stat_forced_major_collections; intnat heap_chunks = Caml_state->stat_heap_chunks; - res = caml_alloc_tuple (16); + res = caml_alloc_tuple (17); Store_field (res, 0, caml_copy_double (minwords)); Store_field (res, 1, caml_copy_double (prowords)); Store_field (res, 2, caml_copy_double (majwords)); @@ -311,6 +314,7 @@ CAMLprim value caml_gc_quick_stat(value v) Store_field (res, 13, Val_long (cpct)); Store_field (res, 14, Val_long (top_heap_words)); Store_field (res, 15, Val_long (caml_stack_usage())); + Store_field (res, 16, Val_long (forcmajcoll)); CAMLreturn (res); } @@ -502,8 +506,10 @@ CAMLprim value caml_gc_set(value v) newpolicy = Long_val (Field (v, 6)); if (newpolicy != caml_allocation_policy){ caml_empty_minor_heap (); + caml_gc_message (0x1, "Full major GC cycle (changing allocation policy)\n"); caml_finish_major_cycle (); caml_finish_major_cycle (); + ++ Caml_state->stat_forced_major_collections; caml_compact_heap (newpolicy); caml_gc_message (0x20, "New allocation policy: %" ARCH_INTNAT_PRINTF_FORMAT "u\n", newpolicy); @@ -558,7 +564,7 @@ CAMLprim value caml_gc_major(value v) CAML_EV_BEGIN(EV_EXPLICIT_GC_MAJOR); CAMLassert (v == Val_unit); - caml_gc_message (0x1, "Major GC cycle requested\n"); + caml_gc_message (0x1, "Finishing major GC cycle (requested by user)\n"); caml_empty_minor_heap (); caml_finish_major_cycle (); test_and_compact (); @@ -575,7 +581,7 @@ CAMLprim value caml_gc_full_major(value v) CAML_EV_BEGIN(EV_EXPLICIT_GC_FULL_MAJOR); CAMLassert (v == Val_unit); - caml_gc_message (0x1, "Full major GC cycle requested\n"); + caml_gc_message (0x1, "Full major GC cycle (requested by user)\n"); caml_empty_minor_heap (); caml_finish_major_cycle (); // call finalisers @@ -583,6 +589,7 @@ CAMLprim value caml_gc_full_major(value v) if (Is_exception_result(exn)) goto cleanup; caml_empty_minor_heap (); caml_finish_major_cycle (); + ++ Caml_state->stat_forced_major_collections; test_and_compact (); // call finalisers exn = caml_process_pending_actions_exn(); @@ -596,10 +603,21 @@ cleanup: CAMLprim value caml_gc_major_slice (value v) { + value exn = Val_unit; CAML_EV_BEGIN(EV_EXPLICIT_GC_MAJOR_SLICE); CAMLassert (Is_long (v)); - caml_major_collection_slice (Long_val (v)); + if (caml_gc_phase == Phase_idle){ + /* We need to start a new major GC cycle. Go through the pending_action + machinery. */ + caml_request_major_slice (); + exn = caml_process_pending_actions_exn (); + /* Calls the major GC without passing [v] but the initial slice + ignores this parameter anyway. */ + }else{ + caml_major_collection_slice (Long_val (v)); + } CAML_EV_END(EV_EXPLICIT_GC_MAJOR_SLICE); + caml_raise_if_exception (exn); return Val_long (0); } @@ -611,12 +629,14 @@ CAMLprim value caml_gc_compaction(value v) CAMLassert (v == Val_unit); caml_gc_message (0x10, "Heap compaction requested\n"); caml_empty_minor_heap (); + caml_gc_message (0x1, "Full major GC cycle (compaction)\n"); caml_finish_major_cycle (); // call finalisers exn = caml_process_pending_actions_exn(); if (Is_exception_result(exn)) goto cleanup; caml_empty_minor_heap (); caml_finish_major_cycle (); + ++ Caml_state->stat_forced_major_collections; caml_compact_heap (-1); // call finalisers exn = caml_process_pending_actions_exn(); diff --git a/runtime/gen_primitives.sh b/runtime/gen_primitives.sh index 8816ccb4..a727d5c2 100755 --- a/runtime/gen_primitives.sh +++ b/runtime/gen_primitives.sh @@ -24,7 +24,7 @@ export LC_ALL=C for prim in \ alloc array compare extern floats gc_ctrl hash intern interp ints io \ lexing md5 meta memprof obj parsing signals str sys callback weak \ - finalise stacks dynlink backtrace_byt backtrace spacetime_byt afl \ + finalise stacks dynlink backtrace_byt backtrace afl \ bigarray eventlog do sed -n -e 's/^CAMLprim value \([a-z0-9_][a-z0-9_]*\).*/\1/p' "$prim.c" diff --git a/runtime/globroots.c b/runtime/globroots.c index a55b069b..3025d095 100644 --- a/runtime/globroots.c +++ b/runtime/globroots.c @@ -91,8 +91,10 @@ static enum gc_root_class classify_gc_root(value v) { if(!Is_block(v)) return UNTRACKED; if(Is_young(v)) return YOUNG; - if(Is_in_heap(v)) return OLD; - return UNTRACKED; +#ifndef NO_NAKED_POINTERS + if(!Is_in_heap(v)) return UNTRACKED; +#endif + return OLD; } /* Register a global C root of the generational kind */ diff --git a/runtime/hash.c b/runtime/hash.c index f7d0d222..f33634c2 100644 --- a/runtime/hash.c +++ b/runtime/hash.c @@ -25,8 +25,8 @@ #include "caml/memory.h" #include "caml/hash.h" -/* The new implementation, based on MurmurHash 3, - http://code.google.com/p/smhasher/ */ +/* The implementation based on MurmurHash 3, + https://github.com/aappleby/smhasher/ */ #define ROTL32(x,n) ((x) << n | (x) >> (32-n)) @@ -205,7 +205,13 @@ CAMLprim value caml_hash(value count, value limit, value seed, value obj) h = caml_hash_mix_intnat(h, v); num--; } - else if (Is_in_value_area(v)) { + else if (!Is_in_value_area(v)) { + /* v is a pointer outside the heap, probably a code pointer. + Shall we count it? Let's say yes by compatibility with old code. */ + h = caml_hash_mix_intnat(h, v); + num--; + } + else { switch (Tag_val(v)) { case String_tag: h = caml_hash_mix_string(h, v); @@ -254,6 +260,28 @@ CAMLprim value caml_hash(value count, value limit, value seed, value obj) num--; } break; +#ifdef NO_NAKED_POINTERS + case Closure_tag: { + mlsize_t startenv; + len = Wosize_val(v); + startenv = Start_env_closinfo(Closinfo_val(v)); + CAMLassert (startenv <= len); + /* Mix in the tag and size, but do not count this towards [num] */ + h = caml_hash_mix_uint32(h, Whitehd_hd(Hd_val(v))); + /* Mix the code pointers, closure info fields, and infix headers */ + for (i = 0; i < startenv; i++) { + h = caml_hash_mix_intnat(h, Field(v, i)); + num--; + } + /* Copy environment fields into queue, + not exceeding the total size [sz] */ + for (/*nothing*/; i < len; i++) { + if (wr >= sz) break; + queue[wr++] = Field(v, i); + } + break; + } +#endif default: /* Mix in the tag and size, but do not count this towards [num] */ h = caml_hash_mix_uint32(h, Whitehd_hd(Hd_val(v))); @@ -264,11 +292,6 @@ CAMLprim value caml_hash(value count, value limit, value seed, value obj) } break; } - } else { - /* v is a pointer outside the heap, probably a code pointer. - Shall we count it? Let's say yes by compatibility with old code. */ - h = caml_hash_mix_intnat(h, v); - num--; } } /* Final mixing of bits */ @@ -278,130 +301,6 @@ CAMLprim value caml_hash(value count, value limit, value seed, value obj) return Val_int(h & 0x3FFFFFFFU); } -/* The old implementation */ - -struct hash_state { - uintnat accu; - intnat univ_limit, univ_count; -}; - -static void hash_aux(struct hash_state*, value obj); - -CAMLprim value caml_hash_univ_param(value count, value limit, value obj) -{ - struct hash_state h; - h.univ_limit = Long_val(limit); - h.univ_count = Long_val(count); - h.accu = 0; - hash_aux(&h, obj); - return Val_long(h.accu & 0x3FFFFFFF); - /* The & has two purposes: ensure that the return value is positive - and give the same result on 32 bit and 64 bit architectures. */ -} - -#define Alpha 65599 -#define Beta 19 -#define Combine(new) (h->accu = h->accu * Alpha + (new)) -#define Combine_small(new) (h->accu = h->accu * Beta + (new)) - -static void hash_aux(struct hash_state* h, value obj) -{ - unsigned char * p; - mlsize_t i, j; - tag_t tag; - - h->univ_limit--; - if (h->univ_count < 0 || h->univ_limit < 0) return; - - again: - if (Is_long(obj)) { - h->univ_count--; - Combine(Long_val(obj)); - return; - } - - /* Pointers into the heap are well-structured blocks. So are atoms. - We can inspect the block contents. */ - - CAMLassert (Is_block (obj)); - if (Is_in_value_area(obj)) { - tag = Tag_val(obj); - switch (tag) { - case String_tag: - h->univ_count--; - i = caml_string_length(obj); - for (p = &Byte_u(obj, 0); i > 0; i--, p++) - Combine_small(*p); - break; - case Double_tag: - /* For doubles, we inspect their binary representation, LSB first. - The results are consistent among all platforms with IEEE floats. */ - h->univ_count--; -#ifdef ARCH_BIG_ENDIAN - for (p = &Byte_u(obj, sizeof(double) - 1), i = sizeof(double); - i > 0; - p--, i--) -#else - for (p = &Byte_u(obj, 0), i = sizeof(double); - i > 0; - p++, i--) -#endif - Combine_small(*p); - break; - case Double_array_tag: - h->univ_count--; - for (j = 0; j < Bosize_val(obj); j += sizeof(double)) { -#ifdef ARCH_BIG_ENDIAN - for (p = &Byte_u(obj, j + sizeof(double) - 1), i = sizeof(double); - i > 0; - p--, i--) -#else - for (p = &Byte_u(obj, j), i = sizeof(double); - i > 0; - p++, i--) -#endif - Combine_small(*p); - } - break; - case Abstract_tag: - /* We don't know anything about the contents of the block. - Better do nothing. */ - break; - case Infix_tag: - hash_aux(h, obj - Infix_offset_val(obj)); - break; - case Forward_tag: - obj = Forward_val (obj); - goto again; - case Object_tag: - h->univ_count--; - Combine(Oid_val(obj)); - break; - case Custom_tag: - /* If no hashing function provided, do nothing */ - if (Custom_ops_val(obj)->hash != NULL) { - h->univ_count--; - Combine(Custom_ops_val(obj)->hash(obj)); - } - break; - default: - h->univ_count--; - Combine_small(tag); - i = Wosize_val(obj); - while (i != 0) { - i--; - hash_aux(h, Field(obj, i)); - } - break; - } - return; - } - - /* Otherwise, obj is a pointer outside the heap, to an object with - a priori unknown structure. Use its physical address as hash key. */ - Combine((intnat) obj); -} - /* Hashing variant tags */ CAMLexport value caml_hash_variant(char const * tag) diff --git a/runtime/i386.S b/runtime/i386.S index e3b8cc2e..e1cc5778 100644 --- a/runtime/i386.S +++ b/runtime/i386.S @@ -48,14 +48,14 @@ #if defined(SYS_macosx) || defined(SYS_mingw) || defined(SYS_cygwin) #define TEXT_SECTION(name) #else -#define TEXT_SECTION(name) .section .text.##name,"ax",%progbits +#define TEXT_SECTION(name) .section .text.caml.##name,"ax",%progbits #endif #else #define TEXT_SECTION(name) #endif #define FUNCTION(name) \ - TEXT_SECTION(caml.##name); \ + TEXT_SECTION(name); \ .globl G(name); \ .align FUNCTION_ALIGN; \ G(name): @@ -96,6 +96,7 @@ #define ALIGN_STACK(amount) subl $ amount, %esp ; CFI_ADJUST(amount) #define UNDO_ALIGN_STACK(amount) addl $ amount, %esp ; CFI_ADJUST(-amount) + .text #if defined(FUNCTION_SECTIONS) TEXT_SECTION(caml_hot__code_begin) .globl G(caml_hot__code_begin) @@ -107,7 +108,7 @@ G(caml_hot__code_end): #endif /* Allocation */ - .text + TEXT_SECTION(caml_system__code_begin) .globl G(caml_system__code_begin) G(caml_system__code_begin): @@ -416,6 +417,7 @@ FUNCTION(caml_ml_array_bound_error) CFI_ENDPROC ENDFUNCTION(caml_ml_array_bound_error) + TEXT_SECTION(caml_system__code_end) .globl G(caml_system__code_end) G(caml_system__code_end): diff --git a/runtime/i386nt.asm b/runtime/i386nt.asm index 548aa9dc..52cd2109 100644 --- a/runtime/i386nt.asm +++ b/runtime/i386nt.asm @@ -26,9 +26,14 @@ EXTERN _caml_stash_backtrace: PROC EXTERN _Caml_state: DWORD + .CODE + + PUBLIC _caml_system__code_begin +_caml_system__code_begin: + ret ; just one instruction, so that debuggers don't display + ; caml_system__code_begin instead of caml_call_gc ; Allocation - .CODE PUBLIC _caml_call_gc PUBLIC _caml_alloc1 PUBLIC _caml_alloc2 @@ -292,6 +297,9 @@ _caml_ml_array_bound_error: mov eax, offset _caml_array_bound_error jmp _caml_c_call + PUBLIC _caml_system__code_end +_caml_system__code_end: + .DATA PUBLIC _caml_system__frametable _caml_system__frametable LABEL DWORD diff --git a/runtime/instrtrace.c b/runtime/instrtrace.c index 3e5cbb56..2760475e 100644 --- a/runtime/instrtrace.c +++ b/runtime/instrtrace.c @@ -149,7 +149,7 @@ char * caml_instr_string (code_t pc) snprintf(buf, sizeof(buf), "%s %d, %d", nam, pc[0], pc[1]); break; case SWITCH: - snprintf(buf, sizeof(buf), "SWITCH sz%#lx=%ld::ntag%ld nint%ld", + snprintf(buf, sizeof(buf), "SWITCH sz%#lx=%ld::ntag%lu nint%lu", (long) pc[0], (long) pc[0], (unsigned long) pc[0] >> 16, (unsigned long) pc[0] & 0xffff); break; diff --git a/runtime/intern.c b/runtime/intern.c index 5f189bac..0ca5b14f 100644 --- a/runtime/intern.c +++ b/runtime/intern.c @@ -372,7 +372,7 @@ static void intern_rec(value *dest) } else { v = Val_hp(intern_dest); if (intern_obj_table != NULL) intern_obj_table[obj_counter++] = v; - *intern_dest = Make_header_allocated_here(size, tag, intern_color); + *intern_dest = Make_header(size, tag, intern_color); intern_dest += 1 + size; /* For objects, we need to freshen the oid */ if (tag == Object_tag) { @@ -402,7 +402,7 @@ static void intern_rec(value *dest) size = (len + sizeof(value)) / sizeof(value); v = Val_hp(intern_dest); if (intern_obj_table != NULL) intern_obj_table[obj_counter++] = v; - *intern_dest = Make_header_allocated_here(size, String_tag, intern_color); + *intern_dest = Make_header(size, String_tag, intern_color); intern_dest += 1 + size; Field(v, size - 1) = 0; ofs_ind = Bsize_wsize(size) - 1; @@ -474,8 +474,8 @@ static void intern_rec(value *dest) case CODE_DOUBLE_BIG: v = Val_hp(intern_dest); if (intern_obj_table != NULL) intern_obj_table[obj_counter++] = v; - *intern_dest = Make_header_allocated_here(Double_wosize, Double_tag, - intern_color); + *intern_dest = Make_header(Double_wosize, Double_tag, + intern_color); intern_dest += 1 + Double_wosize; readfloat((double *) v, code); break; @@ -486,8 +486,8 @@ static void intern_rec(value *dest) size = len * Double_wosize; v = Val_hp(intern_dest); if (intern_obj_table != NULL) intern_obj_table[obj_counter++] = v; - *intern_dest = Make_header_allocated_here(size, Double_array_tag, - intern_color); + *intern_dest = Make_header(size, Double_array_tag, + intern_color); intern_dest += 1 + size; readfloats((double *) v, len, code); break; @@ -570,8 +570,8 @@ static void intern_rec(value *dest) size = 1 + (size + sizeof(value) - 1) / sizeof(value); v = Val_hp(intern_dest); if (intern_obj_table != NULL) intern_obj_table[obj_counter++] = v; - *intern_dest = Make_header_allocated_here(size, Custom_tag, - intern_color); + *intern_dest = Make_header(size, Custom_tag, + intern_color); Custom_ops_val(v) = ops; if (ops->finalize != NULL && Is_young(v)) { @@ -599,8 +599,7 @@ static void intern_rec(value *dest) intern_free_stack(); } -static void intern_alloc(mlsize_t whsize, mlsize_t num_objects, - int outside_heap) +static void intern_alloc(mlsize_t whsize, mlsize_t num_objects) { mlsize_t wosize; @@ -610,7 +609,7 @@ static void intern_alloc(mlsize_t whsize, mlsize_t num_objects, return; } wosize = Wosize_whsize(whsize); - if (outside_heap || wosize > Max_wosize) { + if (wosize > Max_wosize) { /* Round desired size up to next page */ asize_t request = ((Bsize_wsize(whsize) + Page_size - 1) >> Page_log) << Page_log; @@ -619,8 +618,7 @@ static void intern_alloc(mlsize_t whsize, mlsize_t num_objects, intern_cleanup(); caml_raise_out_of_memory(); } - intern_color = - outside_heap ? Caml_black : caml_allocation_color(intern_extra_block); + intern_color = caml_allocation_color(intern_extra_block); intern_dest = (header_t *) intern_extra_block; CAMLassert (intern_block == 0); } else { @@ -767,7 +765,7 @@ static void caml_parse_header(char * fun_name, /* Reading from a channel */ -static value caml_input_val_core(struct channel *chan, int outside_heap) +value caml_input_val(struct channel *chan) { intnat r; char header[32]; @@ -803,24 +801,10 @@ static value caml_input_val_core(struct channel *chan, int outside_heap) } /* Initialize global state */ intern_init(block, block); - intern_alloc(h.whsize, h.num_objects, outside_heap); + intern_alloc(h.whsize, h.num_objects); /* Fill it in */ intern_rec(&res); - if (!outside_heap) - return intern_end(res, h.whsize); - else { - caml_disown_for_heap(intern_extra_block); - intern_extra_block = NULL; - intern_block = 0; - /* Free everything */ - intern_cleanup(); - return caml_check_urgent_gc(res); - } -} - -value caml_input_val(struct channel* chan) -{ - return caml_input_val_core(chan, 0); + return intern_end(res, h.whsize); } CAMLprim value caml_input_value(value vchan) @@ -837,18 +821,6 @@ CAMLprim value caml_input_value(value vchan) /* Reading from memory-resident blocks */ -CAMLprim value caml_input_value_to_outside_heap(value vchan) -{ - CAMLparam1 (vchan); - struct channel * chan = Channel(vchan); - CAMLlocal1 (res); - - Lock(chan); - res = caml_input_val_core(chan, 1); - Unlock(chan); - CAMLreturn (res); -} - CAMLexport value caml_input_val_from_bytes(value str, intnat ofs) { CAMLparam1 (str); @@ -861,18 +833,13 @@ CAMLexport value caml_input_val_from_bytes(value str, intnat ofs) if (ofs + h.header_len + h.data_len > caml_string_length(str)) caml_failwith("input_val_from_string: bad length"); /* Allocate result */ - intern_alloc(h.whsize, h.num_objects, 0); + intern_alloc(h.whsize, h.num_objects); intern_src = &Byte_u(str, ofs + h.header_len); /* If a GC occurred */ /* Fill it in */ intern_rec(&obj); CAMLreturn (intern_end(obj, h.whsize)); } -CAMLprim value caml_input_value_from_string(value str, value ofs) -{ - return caml_input_val_from_bytes(str, Long_val(ofs)); -} - CAMLprim value caml_input_value_from_bytes(value str, value ofs) { return caml_input_val_from_bytes(str, Long_val(ofs)); @@ -882,7 +849,7 @@ static value input_val_from_block(struct marshal_header * h) { value obj; /* Allocate result */ - intern_alloc(h->whsize, h->num_objects, 0); + intern_alloc(h->whsize, h->num_objects); /* Fill it in */ intern_rec(&obj); return (intern_end(obj, h->whsize)); diff --git a/runtime/interp.c b/runtime/interp.c index 443dc2e7..a59811c8 100644 --- a/runtime/interp.c +++ b/runtime/interp.c @@ -519,11 +519,11 @@ value caml_interprete(code_t prog, asize_t prog_size) } Instruct(RESTART): { - int num_args = Wosize_val(env) - 2; + int num_args = Wosize_val(env) - 3; int i; sp -= num_args; - for (i = 0; i < num_args; i++) sp[i] = Field(env, i + 2); - env = Field(env, 1); + for (i = 0; i < num_args; i++) sp[i] = Field(env, i + 3); + env = Field(env, 2); extra_args += num_args; Next; } @@ -535,11 +535,11 @@ value caml_interprete(code_t prog, asize_t prog_size) } else { mlsize_t num_args, i; num_args = 1 + extra_args; /* arg1 + extra args */ - Alloc_small(accu, num_args + 2, Closure_tag); - Field(accu, 1) = env; - for (i = 0; i < num_args; i++) Field(accu, i + 2) = sp[i]; - CAMLassert(!Is_in_value_area(pc-3)); + Alloc_small(accu, num_args + 3, Closure_tag); + Field(accu, 2) = env; + for (i = 0; i < num_args; i++) Field(accu, i + 3) = sp[i]; Code_val(accu) = pc - 3; /* Point to the preceding RESTART instr. */ + Closinfo_val(accu) = Make_closinfo(0, 2); sp += num_args; pc = (code_t)(sp[0]); env = sp[1]; @@ -553,21 +553,21 @@ value caml_interprete(code_t prog, asize_t prog_size) int nvars = *pc++; int i; if (nvars > 0) *--sp = accu; - if (nvars < Max_young_wosize) { - /* nvars + 1 <= Max_young_wosize, can allocate in minor heap */ - Alloc_small(accu, 1 + nvars, Closure_tag); - for (i = 0; i < nvars; i++) Field(accu, i + 1) = sp[i]; + if (nvars <= Max_young_wosize - 2) { + /* nvars + 2 <= Max_young_wosize, can allocate in minor heap */ + Alloc_small(accu, 2 + nvars, Closure_tag); + for (i = 0; i < nvars; i++) Field(accu, i + 2) = sp[i]; } else { /* PR#6385: must allocate in major heap */ /* caml_alloc_shr and caml_initialize never trigger a GC, so no need to Setup_for_gc */ - accu = caml_alloc_shr(1 + nvars, Closure_tag); - for (i = 0; i < nvars; i++) caml_initialize(&Field(accu, i + 1), sp[i]); + accu = caml_alloc_shr(2 + nvars, Closure_tag); + for (i = 0; i < nvars; i++) caml_initialize(&Field(accu, i + 2), sp[i]); } /* The code pointer is not in the heap, so no need to go through caml_initialize. */ - CAMLassert(!Is_in_value_area(pc + *pc)); Code_val(accu) = pc + *pc; + Closinfo_val(accu) = Make_closinfo(0, 2); pc++; sp += nvars; Next; @@ -576,35 +576,36 @@ value caml_interprete(code_t prog, asize_t prog_size) Instruct(CLOSUREREC): { int nfuncs = *pc++; int nvars = *pc++; - mlsize_t blksize = nfuncs * 2 - 1 + nvars; + mlsize_t envofs = nfuncs * 3 - 1; + mlsize_t blksize = envofs + nvars; int i; value * p; if (nvars > 0) *--sp = accu; if (blksize <= Max_young_wosize) { Alloc_small(accu, blksize, Closure_tag); - p = &Field(accu, nfuncs * 2 - 1); + p = &Field(accu, envofs); for (i = 0; i < nvars; i++, p++) *p = sp[i]; } else { /* PR#6385: must allocate in major heap */ /* caml_alloc_shr and caml_initialize never trigger a GC, so no need to Setup_for_gc */ accu = caml_alloc_shr(blksize, Closure_tag); - p = &Field(accu, nfuncs * 2 - 1); + p = &Field(accu, envofs); for (i = 0; i < nvars; i++, p++) caml_initialize(p, sp[i]); } sp += nvars; /* The code pointers and infix headers are not in the heap, so no need to go through caml_initialize. */ - p = &Field(accu, 0); - *p = (value) (pc + pc[0]); *--sp = accu; - p++; + p = &Field(accu, 0); + *p++ = (value) (pc + pc[0]); + *p++ = Make_closinfo(0, envofs); for (i = 1; i < nfuncs; i++) { - *p = Make_header(i * 2, Infix_tag, Caml_white); /* color irrelevant. */ - p++; - *p = (value) (pc + pc[i]); + *p++ = Make_header(i * 3, Infix_tag, Caml_white); /* color irrelevant */ *--sp = (value) p; - p++; + *p++ = (value) (pc + pc[i]); + envofs -= 3; + *p++ = Make_closinfo(0, envofs); } pc += nfuncs; Next; @@ -615,18 +616,18 @@ value caml_interprete(code_t prog, asize_t prog_size) Instruct(OFFSETCLOSURE): accu = env + *pc++ * sizeof(value); Next; - Instruct(PUSHOFFSETCLOSUREM2): + Instruct(PUSHOFFSETCLOSUREM3): *--sp = accu; /* fallthrough */ - Instruct(OFFSETCLOSUREM2): - accu = env - 2 * sizeof(value); Next; + Instruct(OFFSETCLOSUREM3): + accu = env - 3 * sizeof(value); Next; Instruct(PUSHOFFSETCLOSURE0): *--sp = accu; /* fallthrough */ Instruct(OFFSETCLOSURE0): accu = env; Next; - Instruct(PUSHOFFSETCLOSURE2): + Instruct(PUSHOFFSETCLOSURE3): *--sp = accu; /* fallthrough */ - Instruct(OFFSETCLOSURE2): - accu = env + 2 * sizeof(value); Next; + Instruct(OFFSETCLOSURE3): + accu = env + 3 * sizeof(value); Next; /* Access to global variables */ @@ -847,7 +848,7 @@ value caml_interprete(code_t prog, asize_t prog_size) Instruct(PUSHTRAP): sp -= 4; Trap_pc(sp) = pc + *pc; - Trap_link(sp) = Caml_state->trapsp; + Trap_link_offset(sp) = Val_long(Caml_state->trapsp - sp); sp[2] = env; sp[3] = Val_long(extra_args); Caml_state->trapsp = sp; @@ -862,7 +863,7 @@ value caml_interprete(code_t prog, asize_t prog_size) pc--; /* restart the POPTRAP after processing the signal */ goto process_actions; } - Caml_state->trapsp = Trap_link(sp); + Caml_state->trapsp = sp + Long_val(Trap_link_offset(sp)); sp += 4; Next; @@ -895,7 +896,7 @@ value caml_interprete(code_t prog, asize_t prog_size) } sp = Caml_state->trapsp; pc = Trap_pc(sp); - Caml_state->trapsp = Trap_link(sp); + Caml_state->trapsp = sp + Long_val(Trap_link_offset(sp)); env = sp[2]; extra_args = Long_val(sp[3]); sp += 4; @@ -1081,10 +1082,6 @@ value caml_interprete(code_t prog, asize_t prog_size) #define Lookup(obj, lab) Field (Field (obj, 0), Int_val(lab)) - /* please don't forget to keep below code in sync with the - functions caml_cache_public_method and - caml_cache_public_method2 in obj.c */ - Instruct(GETMETHOD): accu = Lookup(sp[0], accu); Next; @@ -1181,20 +1178,3 @@ value caml_interprete(code_t prog, asize_t prog_size) } #endif } - -void caml_prepare_bytecode(code_t prog, asize_t prog_size) { - /* other implementations of the interpreter (such as an hypothetical - JIT translator) might want to do something with a bytecode before - running it */ - CAMLassert(prog); - CAMLassert(prog_size>0); - /* actually, the threading of the bytecode might be done here */ -} - -void caml_release_bytecode(code_t prog, asize_t prog_size) { - /* other implementations of the interpreter (such as an hypothetical - JIT translator) might want to know when a bytecode is removed */ - /* check that we have a program */ - CAMLassert(prog); - CAMLassert(prog_size>0); -} diff --git a/runtime/io.c b/runtime/io.c index 90a1aa64..b5dbb606 100644 --- a/runtime/io.c +++ b/runtime/io.c @@ -69,13 +69,35 @@ CAMLexport struct channel * caml_all_opened_channels = NULL; /* Functions shared between input and output */ +static void check_pending(struct channel *channel) +{ + if (caml_check_pending_actions()) { + /* Temporarily unlock the channel, to ensure locks are not held + while any signal handlers (or finalisers, etc) are running */ + Unlock(channel); + caml_process_pending_actions(); + Lock(channel); + } +} + +Caml_inline int descriptor_is_in_binary_mode(int fd) +{ +#if defined(_WIN32) || defined(__CYGWIN__) + int oldmode = setmode(fd, O_TEXT); + if (oldmode != -1 && oldmode != O_TEXT) setmode(fd, oldmode); + return oldmode == O_BINARY; +#else + return 1; +#endif +} + CAMLexport struct channel * caml_open_descriptor_in(int fd) { struct channel * channel; channel = (struct channel *) caml_stat_alloc(sizeof(struct channel)); channel->fd = fd; - caml_enter_blocking_section(); + caml_enter_blocking_section_no_pending(); channel->offset = lseek(fd, 0, SEEK_CUR); caml_leave_blocking_section(); channel->curr = channel->max = channel->buff; @@ -84,7 +106,7 @@ CAMLexport struct channel * caml_open_descriptor_in(int fd) channel->revealed = 0; channel->old_revealed = 0; channel->refcount = 0; - channel->flags = 0; + channel->flags = descriptor_is_in_binary_mode(fd) ? 0 : CHANNEL_TEXT_MODE; channel->next = caml_all_opened_channels; channel->prev = NULL; channel->name = NULL; @@ -128,33 +150,32 @@ CAMLexport void caml_close_channel(struct channel *channel) CAMLexport file_offset caml_channel_size(struct channel *channel) { - file_offset offset; - file_offset end; + file_offset here, end; int fd; + check_pending(channel); /* We extract data from [channel] before dropping the OCaml lock, in case someone else touches the block. */ fd = channel->fd; - offset = channel->offset; - caml_enter_blocking_section(); - end = lseek(fd, 0, SEEK_END); - if (end == -1 || lseek(fd, offset, SEEK_SET) != offset) { - caml_leave_blocking_section(); - caml_sys_error(NO_ARG); + here = channel->flags & CHANNEL_TEXT_MODE ? -1 : channel->offset; + caml_enter_blocking_section_no_pending(); + if (here == -1) { + here = lseek(fd, 0, SEEK_CUR); + if (here == -1) goto error; } + end = lseek(fd, 0, SEEK_END); + if (end == -1) goto error; + if (lseek(fd, here, SEEK_SET) != here) goto error; caml_leave_blocking_section(); return end; + error: + caml_leave_blocking_section(); + caml_sys_error(NO_ARG); } CAMLexport int caml_channel_binary_mode(struct channel *channel) { -#if defined(_WIN32) || defined(__CYGWIN__) - int oldmode = setmode(channel->fd, O_BINARY); - if (oldmode == O_TEXT) setmode(channel->fd, O_TEXT); - return oldmode == O_BINARY; -#else - return 1; -#endif + return channel->flags & CHANNEL_TEXT_MODE ? 0 : 1; } /* Output */ @@ -167,12 +188,15 @@ CAMLexport int caml_channel_binary_mode(struct channel *channel) CAMLexport int caml_flush_partial(struct channel *channel) { int towrite, written; + again: + check_pending(channel); towrite = channel->curr - channel->buff; CAMLassert (towrite >= 0); if (towrite > 0) { written = caml_write_fd(channel->fd, channel->flags, channel->buff, towrite); + if (written == Io_interrupted) goto again; channel->offset += written; if (written < towrite) memmove(channel->buff, channel->buff + written, towrite - written); @@ -202,7 +226,7 @@ CAMLexport void caml_putword(struct channel *channel, uint32_t w) CAMLexport int caml_putblock(struct channel *channel, char *p, intnat len) { - int n, free, towrite, written; + int n, free; n = len >= INT_MAX ? INT_MAX : (int) len; free = channel->end - channel->curr; @@ -215,13 +239,8 @@ CAMLexport int caml_putblock(struct channel *channel, char *p, intnat len) /* Write request overflows buffer (or just fills it up): transfer whatever fits to buffer and write the buffer */ memmove(channel->curr, p, free); - towrite = channel->end - channel->buff; - written = caml_write_fd(channel->fd, channel->flags, - channel->buff, towrite); - if (written < towrite) - memmove(channel->buff, channel->buff + written, towrite - written); - channel->offset += written; - channel->curr = channel->end - written; + channel->curr = channel->end; + caml_flush_partial(channel); return free; } } @@ -240,7 +259,7 @@ CAMLexport void caml_really_putblock(struct channel *channel, CAMLexport void caml_seek_out(struct channel *channel, file_offset dest) { caml_flush(channel); - caml_enter_blocking_section(); + caml_enter_blocking_section_no_pending(); if (lseek(channel->fd, dest, SEEK_SET) != dest) { caml_leave_blocking_section(); caml_sys_error(NO_ARG); @@ -256,19 +275,24 @@ CAMLexport file_offset caml_pos_out(struct channel *channel) /* Input */ -/* caml_do_read is exported for Cash */ -CAMLexport int caml_do_read(int fd, char *p, unsigned int n) +int caml_do_read(int fd, char *p, unsigned int n) { - return caml_read_fd(fd, 0, p, n); + int r; + do { + r = caml_read_fd(fd, 0, p, n); + } while (r == Io_interrupted); + return r; } CAMLexport unsigned char caml_refill(struct channel *channel) { int n; - + again: + check_pending(channel); n = caml_read_fd(channel->fd, channel->flags, channel->buff, channel->end - channel->buff); - if (n == 0) caml_raise_end_of_file(); + if (n == Io_interrupted) goto again; + else if (n == 0) caml_raise_end_of_file(); channel->offset += n; channel->max = channel->buff + n; channel->curr = channel->buff + 1; @@ -292,7 +316,8 @@ CAMLexport uint32_t caml_getword(struct channel *channel) CAMLexport int caml_getblock(struct channel *channel, char *p, intnat len) { int n, avail, nread; - + again: + check_pending(channel); n = len >= INT_MAX ? INT_MAX : (int) len; avail = channel->max - channel->curr; if (n <= avail) { @@ -306,6 +331,7 @@ CAMLexport int caml_getblock(struct channel *channel, char *p, intnat len) } else { nread = caml_read_fd(channel->fd, channel->flags, channel->buff, channel->end - channel->buff); + if (nread == Io_interrupted) goto again; channel->offset += nread; channel->max = channel->buff + nread; if (n > nread) n = nread; @@ -331,11 +357,12 @@ CAMLexport intnat caml_really_getblock(struct channel *chan, char *p, intnat n) CAMLexport void caml_seek_in(struct channel *channel, file_offset dest) { - if (dest >= channel->offset - (channel->max - channel->buff) && - dest <= channel->offset) { + if (dest >= channel->offset - (channel->max - channel->buff) + && dest <= channel->offset + && (channel->flags & CHANNEL_TEXT_MODE) == 0) { channel->curr = channel->max - (channel->offset - dest); } else { - caml_enter_blocking_section(); + caml_enter_blocking_section_no_pending(); if (lseek(channel->fd, dest, SEEK_SET) != dest) { caml_leave_blocking_section(); caml_sys_error(NO_ARG); @@ -351,11 +378,12 @@ CAMLexport file_offset caml_pos_in(struct channel *channel) return channel->offset - (file_offset)(channel->max - channel->curr); } -CAMLexport intnat caml_input_scan_line(struct channel *channel) +intnat caml_input_scan_line(struct channel *channel) { char * p; int n; - + again: + check_pending(channel); p = channel->curr; do { if (p >= channel->max) { @@ -378,7 +406,8 @@ CAMLexport intnat caml_input_scan_line(struct channel *channel) /* Fill the buffer as much as possible */ n = caml_read_fd(channel->fd, channel->flags, channel->max, channel->end - channel->max); - if (n == 0) { + if (n == Io_interrupted) goto again; + else if (n == 0) { /* End-of-file encountered. Return the number of characters in the buffer, with negative sign since we haven't encountered a newline. */ @@ -396,8 +425,7 @@ CAMLexport intnat caml_input_scan_line(struct channel *channel) objects into a heap-allocated object. Perform locking and unlocking around the I/O operations. */ -/* FIXME CAMLexport, but not in io.h exported for Cash ? */ -CAMLexport void caml_finalize_channel(value vchan) +void caml_finalize_channel(value vchan) { struct channel * chan = Channel(vchan); if ((chan->flags & CHANNEL_FLAG_MANAGED_BY_GC) == 0) return; @@ -545,7 +573,7 @@ CAMLprim value caml_ml_close_channel(value vchannel) channel->curr = channel->max = channel->end; if (do_syscall) { - caml_enter_blocking_section(); + caml_enter_blocking_section_no_pending(); result = close(fd); caml_leave_blocking_section(); } @@ -563,16 +591,28 @@ CAMLprim value caml_ml_close_channel(value vchannel) #define EOVERFLOW ERANGE #endif +static file_offset ml_channel_size(value vchannel) +{ + CAMLparam1 (vchannel); + struct channel * channel = Channel(vchannel); + file_offset size; + + Lock(channel); + size = caml_channel_size(Channel(vchannel)); + Unlock(channel); + CAMLreturnT(file_offset, size); +} + CAMLprim value caml_ml_channel_size(value vchannel) { - file_offset size = caml_channel_size(Channel(vchannel)); + file_offset size = ml_channel_size(vchannel); if (size > Max_long) { errno = EOVERFLOW; caml_sys_error(NO_ARG); } return Val_long(size); } CAMLprim value caml_ml_channel_size_64(value vchannel) { - return Val_file_offset(caml_channel_size(Channel(vchannel))); + return Val_file_offset(ml_channel_size(vchannel)); } CAMLprim value caml_ml_set_binary_mode(value vchannel, value mode) @@ -590,6 +630,10 @@ CAMLprim value caml_ml_set_binary_mode(value vchannel, value mode) #endif if (setmode(channel->fd, Bool_val(mode) ? O_BINARY : O_TEXT) == -1) caml_sys_error(NO_ARG); + if (Bool_val(mode)) + channel->flags &= ~CHANNEL_TEXT_MODE; + else + channel->flags |= CHANNEL_TEXT_MODE; #endif return Val_unit; } @@ -601,19 +645,6 @@ CAMLprim value caml_ml_set_binary_mode(value vchannel, value mode) file descriptors that may be closed. */ -CAMLprim value caml_ml_flush_partial(value vchannel) -{ - CAMLparam1 (vchannel); - struct channel * channel = Channel(vchannel); - int res; - - if (channel->fd == -1) CAMLreturn(Val_true); - Lock(channel); - res = caml_flush_partial(channel); - Unlock(channel); - CAMLreturn (Val_bool(res)); -} - CAMLprim value caml_ml_flush(value vchannel) { CAMLparam1 (vchannel); @@ -648,19 +679,6 @@ CAMLprim value caml_ml_output_int(value vchannel, value w) CAMLreturn (Val_unit); } -CAMLprim value caml_ml_output_partial(value vchannel, value buff, value start, - value length) -{ - CAMLparam4 (vchannel, buff, start, length); - struct channel * channel = Channel(vchannel); - int res; - - Lock(channel); - res = caml_putblock(channel, &Byte(buff, Long_val(start)), Long_val(length)); - Unlock(channel); - CAMLreturn (Val_int(res)); -} - CAMLprim value caml_ml_output_bytes(value vchannel, value buff, value start, value length) { @@ -757,6 +775,8 @@ CAMLprim value caml_ml_input(value vchannel, value buff, value vstart, int n, avail, nread; Lock(channel); + again: + check_pending(channel); /* We cannot call caml_getblock here because buff may move during caml_read_fd */ start = Long_val(vstart); @@ -773,6 +793,7 @@ CAMLprim value caml_ml_input(value vchannel, value buff, value vstart, } else { nread = caml_read_fd(channel->fd, channel->flags, channel->buff, channel->end - channel->buff); + if (nread == Io_interrupted) goto again; channel->offset += nread; channel->max = channel->buff + nread; if (n > nread) n = nread; diff --git a/runtime/main.c b/runtime/main.c index 5e5839ff..ec97abc3 100644 --- a/runtime/main.c +++ b/runtime/main.c @@ -22,15 +22,12 @@ #include "caml/mlvalues.h" #include "caml/sys.h" #include "caml/osdeps.h" +#include "caml/callback.h" #ifdef _WIN32 #include #endif -CAMLextern void caml_main (char_os **); - #ifdef _WIN32 -CAMLextern void caml_expand_command_line (int *, wchar_t ***); - int wmain(int argc, wchar_t **argv) #else int main(int argc, char **argv) diff --git a/runtime/major_gc.c b/runtime/major_gc.c index 5e4f06bc..75a5f186 100644 --- a/runtime/major_gc.c +++ b/runtime/major_gc.c @@ -30,42 +30,49 @@ #include "caml/misc.h" #include "caml/mlvalues.h" #include "caml/roots.h" +#include "caml/skiplist.h" #include "caml/signals.h" #include "caml/weak.h" #include "caml/memprof.h" #include "caml/eventlog.h" -#if defined (NATIVE_CODE) && defined (NO_NAKED_POINTERS) -#define NATIVE_CODE_AND_NO_NAKED_POINTERS -#else -#undef NATIVE_CODE_AND_NO_NAKED_POINTERS -#endif - #ifdef _MSC_VER Caml_inline double fmin(double a, double b) { return (a < b) ? a : b; } #endif +#define MARK_STACK_INIT_SIZE 2048 + +typedef struct { + value block; + uintnat offset; +} mark_entry; + +struct mark_stack { + mark_entry* stack; + uintnat count; + uintnat size; +}; + uintnat caml_percent_free; uintnat caml_major_heap_increment; CAMLexport char *caml_heap_start; char *caml_gc_sweep_hp; int caml_gc_phase; /* always Phase_mark, Pase_clean, Phase_sweep, or Phase_idle */ -static value *gray_vals; -static value *gray_vals_cur, *gray_vals_end; -static asize_t gray_vals_size; -static int heap_is_pure; /* The heap is pure if the only gray objects - below [markhp] are also in [gray_vals]. */ uintnat caml_allocated_words; uintnat caml_dependent_size, caml_dependent_allocated; double caml_extra_heap_resources; uintnat caml_fl_wsz_at_phase_change = 0; -extern char *caml_fl_merge; /* Defined in freelist.c. */ +extern value caml_fl_merge; /* Defined in freelist.c. */ -static char *markhp, *chunk, *limit; +/* redarken_first_chunk is the first chunk needing redarkening, if NULL no + redarkening required */ +static char *redarken_first_chunk = NULL; + +static char *sweep_chunk, *sweep_limit; static double p_backlog = 0.0; /* backlog for the gc speedup parameter */ int caml_gc_subphase; /* Subphase_{mark_roots,mark_main,mark_final} */ @@ -106,7 +113,7 @@ int caml_gc_subphase; /* Subphase_{mark_roots,mark_main,mark_final} */ */ static int ephe_list_pure; /** The ephemerons is pure if since the start of its iteration - no value have been darken. */ + no value have been darkened. */ static value *ephes_checked_if_pure; static value *ephes_to_check; @@ -122,40 +129,159 @@ static unsigned long major_gc_counter = 0; void (*caml_major_gc_hook)(void) = NULL; -static void realloc_gray_vals (void) +/* This function prunes the mark stack if it's about to overflow. It does so + by building a skiplist of major heap chunks and then iterating through the + mark stack and setting redarken_start/redarken_end on each chunk to indicate + the range that requires redarkening. */ +static void mark_stack_prune (struct mark_stack* stk) +{ + int entry; + uintnat mark_stack_count = stk->count; + mark_entry* mark_stack = stk->stack; + + char* heap_chunk = caml_heap_start; + struct skiplist chunk_sklist = SKIPLIST_STATIC_INITIALIZER; + + do { + caml_skiplist_insert(&chunk_sklist, (uintnat)heap_chunk, + (uintnat)(heap_chunk+Chunk_size(heap_chunk))); + heap_chunk = Chunk_next(heap_chunk); + } while( heap_chunk != NULL ); + + for( entry = 0; entry < mark_stack_count ; entry++ ) { + mark_entry me = mark_stack[entry]; + value* block_op = Op_val(me.block); + uintnat chunk_addr = 0, chunk_addr_below = 0; + + if( caml_skiplist_find_below(&chunk_sklist, (uintnat)me.block, + &chunk_addr, &chunk_addr_below) + && me.block < chunk_addr_below ) { + + if( Chunk_redarken_start(chunk_addr) > block_op ) { + Chunk_redarken_start(chunk_addr) = block_op; + } + + if( Chunk_redarken_end(chunk_addr) < block_op ) { + Chunk_redarken_end(chunk_addr) = block_op; + } + + if( redarken_first_chunk == NULL + || redarken_first_chunk > (char*)chunk_addr ) { + redarken_first_chunk = (char*)chunk_addr; + } + } + } + + caml_skiplist_empty(&chunk_sklist); + + caml_gc_message(0x08, "Mark stack overflow.\n"); + + stk->count = 0; +} + +static void realloc_mark_stack (struct mark_stack* stk) { - value *new; + mark_entry* new; + uintnat mark_stack_bsize = stk->size * sizeof(mark_entry); - CAMLassert (gray_vals_cur == gray_vals_end); - if (gray_vals_size < Caml_state->stat_heap_wsz / 32){ - caml_gc_message (0x08, "Growing gray_vals to %" + if ( Wsize_bsize(mark_stack_bsize) < Caml_state->stat_heap_wsz / 64 ) { + caml_gc_message (0x08, "Growing mark stack to %" ARCH_INTNAT_PRINTF_FORMAT "uk bytes\n", - (intnat) gray_vals_size * sizeof (value) / 512); - new = (value *) caml_stat_resize_noexc ((char *) gray_vals, - 2 * gray_vals_size * - sizeof (value)); - if (new == NULL){ - caml_gc_message (0x08, "No room for growing gray_vals\n"); - gray_vals_cur = gray_vals; - heap_is_pure = 0; - }else{ - gray_vals = new; - gray_vals_cur = gray_vals + gray_vals_size; - gray_vals_size *= 2; - gray_vals_end = gray_vals + gray_vals_size; + (intnat) mark_stack_bsize * 2 / 1024); + + new = (mark_entry*) caml_stat_resize_noexc ((char*) stk->stack, + 2 * mark_stack_bsize); + if (new != NULL) { + stk->stack = new; + stk->size *= 2; + return; } - }else{ - gray_vals_cur = gray_vals + gray_vals_size / 2; - heap_is_pure = 0; } + + caml_gc_message (0x08, "No room for growing mark stack. Pruning..\n"); + mark_stack_prune(stk); } -void caml_darken (value v, value *p /* not used */) +/* This function pushes the provided mark_entry [me] onto the current mark + stack [stk]. It first checks, if the block is small enough, whether there + are any fields we would actually do mark work on. If so then it enqueues + the entry. */ +Caml_inline void mark_stack_push(struct mark_stack* stk, value block, + uintnat offset, intnat* work) { -#ifdef NATIVE_CODE_AND_NO_NAKED_POINTERS - if (Is_block (v) && !Is_young (v) && Wosize_val (v) > 0) { + value v; + int i, block_wsz = Wosize_val(block), end; + mark_entry* me; + + CAMLassert(Is_block(block) && Is_in_heap (block) + && Is_black_val(block)); + CAMLassert(Tag_val(block) != Infix_tag); + CAMLassert(Tag_val(block) < No_scan_tag); + +#if defined(NO_NAKED_POINTERS) || defined(NAKED_POINTERS_CHECKER) + if (Tag_val(block) == Closure_tag) { + /* Skip the code pointers and integers at beginning of closure; + start scanning at the first word of the environment part. */ + /* It might be the case that [mark_stack_push] has been called + while we are traversing a closure block but have not enough + budget to finish the block. In that specific case, we should not + update [m.offset] */ + if (offset == 0) + offset = Start_env_closinfo(Closinfo_val(block)); + + CAMLassert(offset <= Wosize_val(block) + && offset >= Start_env_closinfo(Closinfo_val(block))); + } +#endif + + end = (block_wsz < 8 ? block_wsz : 8); + + /* Optimisation to avoid pushing small, unmarkable objects such as [Some 42] + * into the mark stack. */ + for (i = offset; i < end; i++) { + v = Field(block, i); + + if (Is_block(v) && !Is_young(v)) + /* found something to mark */ + break; + } + + if (i == block_wsz) { + /* nothing left to mark */ + if( work != NULL ) { + /* we should take credit for it though */ + *work -= Whsize_wosize(block_wsz - offset); + } + return; + } + + if( work != NULL ) { + /* take credit for the work we skipped due to the optimisation. + we will take credit for the header later as part of marking. */ + *work -= (i - offset); + } + + offset = i; + + if (stk->count == stk->size) + realloc_mark_stack(stk); + + me = &stk->stack[stk->count++]; + + me->block = block; + me->offset = offset; +} + +#if defined(NAKED_POINTERS_CHECKER) && defined(NATIVE_CODE) +static void is_naked_pointer_safe (value v, value *p); +#endif + +void caml_darken (value v, value *p) +{ +#ifdef NO_NAKED_POINTERS + if (Is_block(v) && !Is_young (v)) { #else - if (Is_block (v) && Is_in_heap (v)) { + if (Is_block(v) && Is_in_heap (v)) { #endif header_t h = Hd_val (v); tag_t t = Tag_hd (h); @@ -164,38 +290,95 @@ void caml_darken (value v, value *p /* not used */) h = Hd_val (v); t = Tag_hd (h); } -#ifdef NATIVE_CODE_AND_NO_NAKED_POINTERS +#ifdef NO_NAKED_POINTERS /* We insist that naked pointers to outside the heap point to things that - look like values with headers coloured black. This isn't always - strictly necessary but is essential in certain cases---in particular - when the value is allocated in a read-only section. (For the values - where it would be safe it is a performance improvement since we avoid - putting them on the grey list.) */ + look like values with headers coloured black. This is always + strictly necessary because the compactor relies on it. */ CAMLassert (Is_in_heap (v) || Is_black_hd (h)); #endif CAMLassert (!Is_blue_hd (h)); if (Is_white_hd (h)){ ephe_list_pure = 0; + Hd_val (v) = Blackhd_hd (h); if (t < No_scan_tag){ - Hd_val (v) = Grayhd_hd (h); - *gray_vals_cur++ = v; - if (gray_vals_cur >= gray_vals_end) realloc_gray_vals (); - }else{ - Hd_val (v) = Blackhd_hd (h); + mark_stack_push(Caml_state->mark_stack, v, 0, NULL); } } } +#if defined(NAKED_POINTERS_CHECKER) && defined(NATIVE_CODE) + else if (Is_block(v) && !Is_young(v)) { + is_naked_pointer_safe(v, p); + } +#endif +} + +/* This function shrinks the mark stack back to the MARK_STACK_INIT_SIZE size + and is called at the end of a GC compaction to avoid a mark stack greater + than 1/32th of the heap. */ +void caml_shrink_mark_stack () { + struct mark_stack* stk = Caml_state->mark_stack; + intnat init_stack_bsize = MARK_STACK_INIT_SIZE * sizeof(mark_entry); + mark_entry* shrunk_stack; + + caml_gc_message (0x08, "Shrinking mark stack to %" + ARCH_INTNAT_PRINTF_FORMAT "uk bytes\n", + init_stack_bsize); + + shrunk_stack = (mark_entry*) caml_stat_resize_noexc ((char*) stk->stack, + init_stack_bsize); + if (shrunk_stack != NULL) { + stk->stack = shrunk_stack; + stk->size = MARK_STACK_INIT_SIZE; + }else{ + caml_gc_message (0x08, "Mark stack shrinking failed"); + } +} + +/* This function adds blocks in the passed heap chunk [heap_chunk] to + the mark stack. It returns 1 when the supplied chunk has no more + range to redarken. It returns 0 if there are still blocks in the + chunk that need redarkening because pushing them onto the stack + would make it grow more than a quarter full. This is to lower the + chance of triggering another overflow, which would be + wasteful. Subsequent calls will continue progress. + */ +static int redarken_chunk(char* heap_chunk, struct mark_stack* stk) { + value* p = Chunk_redarken_start(heap_chunk); + value* end = Chunk_redarken_end(heap_chunk); + + while (p <= end) { + header_t hd = Hd_op(p); + + if( Is_black_hd(hd) && Tag_hd(hd) < No_scan_tag ) { + if( stk->count < stk->size/4 ) { + mark_stack_push(stk, Val_op(p), 0, NULL); + } else { + /* Only fill up a quarter of the mark stack, we can resume later + for more if we need to */ + Chunk_redarken_start(heap_chunk) = p; + return 0; + } + } + + p += Whsize_hp(Hp_op(p)); + } + + Chunk_redarken_start(heap_chunk) = + (value*)(heap_chunk + Chunk_size(heap_chunk)); + + Chunk_redarken_end(heap_chunk) = 0; + return 1; } static void start_cycle (void) { CAMLassert (caml_gc_phase == Phase_idle); - CAMLassert (gray_vals_cur == gray_vals); + CAMLassert (Caml_state->mark_stack->count == 0); + CAMLassert (redarken_first_chunk == NULL); caml_gc_message (0x01, "Starting new major GC cycle\n"); caml_darken_all_roots_start (); caml_gc_phase = Phase_mark; caml_gc_subphase = Subphase_mark_roots; - markhp = NULL; ephe_list_pure = 1; ephes_checked_if_pure = &caml_ephe_list_head; ephes_to_check = &caml_ephe_list_head; @@ -205,13 +388,6 @@ static void start_cycle (void) #endif } -/* We may stop the slice inside values, in order to avoid large latencies - on large arrays. In this case, [current_value] is the partially-marked - value and [current_index] is the index of the next field to be marked. -*/ -static value current_value = 0; -static mlsize_t current_index = 0; - static void init_sweep_phase(void) { /* Phase_clean is done. */ @@ -219,32 +395,25 @@ static void init_sweep_phase(void) caml_gc_sweep_hp = caml_heap_start; caml_fl_init_merge (); caml_gc_phase = Phase_sweep; - chunk = caml_heap_start; - caml_gc_sweep_hp = chunk; - limit = chunk + Chunk_size (chunk); + sweep_chunk = caml_heap_start; + caml_gc_sweep_hp = sweep_chunk; + sweep_limit = sweep_chunk + Chunk_size (sweep_chunk); caml_fl_wsz_at_phase_change = caml_fl_cur_wsz; if (caml_major_gc_hook) (*caml_major_gc_hook)(); } /* auxiliary function of mark_slice */ -Caml_inline value* mark_slice_darken(value *gray_vals_ptr, - value v, mlsize_t i, - int in_ephemeron, int *slice_pointers) +Caml_inline void mark_slice_darken(struct mark_stack* stk, value v, mlsize_t i, + int in_ephemeron, int *slice_pointers, + intnat *work) { value child; header_t chd; child = Field (v, i); -#ifdef NATIVE_CODE_AND_NO_NAKED_POINTERS - if (Is_block (child) - && ! Is_young (child) - && Wosize_val (child) > 0 /* Atoms never need to be marked. */ - /* Closure blocks contain code pointers at offsets that cannot - be reliably determined, so we always use the page table when - marking such values. */ - && (!(Tag_val (v) == Closure_tag || Tag_val (v) == Infix_tag) || - Is_in_heap (child))) { +#ifdef NO_NAKED_POINTERS + if (Is_block (child) && ! Is_young (child)) { #else if (Is_block (child) && Is_in_heap (child)) { #endif @@ -277,26 +446,28 @@ Caml_inline value* mark_slice_darken(value *gray_vals_ptr, child -= Infix_offset_val(child); chd = Hd_val(child); } -#ifdef NATIVE_CODE_AND_NO_NAKED_POINTERS +#ifdef NO_NAKED_POINTERS /* See [caml_darken] for a description of this assertion. */ CAMLassert (Is_in_heap (child) || Is_black_hd (chd)); #endif if (Is_white_hd (chd)){ ephe_list_pure = 0; - Hd_val (child) = Grayhd_hd (chd); - *gray_vals_ptr++ = child; - if (gray_vals_ptr >= gray_vals_end) { - gray_vals_cur = gray_vals_ptr; - realloc_gray_vals (); - gray_vals_ptr = gray_vals_cur; + Hd_val (child) = Blackhd_hd (chd); + if( Tag_hd(chd) < No_scan_tag ) { + mark_stack_push(stk, child, 0, work); + } else { + *work -= 1; /* Account for header */ } } } - - return gray_vals_ptr; +#if defined(NAKED_POINTERS_CHECKER) && defined(NATIVE_CODE) + else if (Is_block(child) && ! Is_young(child)) { + is_naked_pointer_safe(child, &Field (v, i)); + } +#endif } -static value* mark_ephe_aux (value *gray_vals_ptr, intnat *work, +static void mark_ephe_aux (struct mark_stack *stk, intnat *work, int *slice_pointers) { value v, data, key; @@ -308,7 +479,13 @@ static value* mark_ephe_aux (value *gray_vals_ptr, intnat *work, CAMLassert(Tag_val (v) == Abstract_tag); data = Field(v,CAML_EPHE_DATA_OFFSET); if ( data != caml_ephe_none && - Is_block (data) && Is_in_heap (data) && Is_white_val (data)){ + Is_block (data) && +#ifdef NO_NAKED_POINTERS + !Is_young(data) && +#else + Is_in_heap (data) && +#endif + Is_white_val (data)){ int alive_data = 1; @@ -321,7 +498,13 @@ static value* mark_ephe_aux (value *gray_vals_ptr, intnat *work, key = Field (v, i); ephemeron_again: if (key != caml_ephe_none && - Is_block (key) && Is_in_heap (key)){ + Is_block (key) && +#ifdef NO_NAKED_POINTERS + !Is_young(key) +#else + Is_in_heap(key) +#endif + ){ if (Tag_val (key) == Forward_tag){ value f = Forward_val (key); if (Is_long (f) || @@ -346,13 +529,11 @@ static value* mark_ephe_aux (value *gray_vals_ptr, intnat *work, *work -= Whsize_wosize(i); if (alive_data){ - gray_vals_ptr = mark_slice_darken(gray_vals_ptr,v, - CAML_EPHE_DATA_OFFSET, - /*in_ephemeron=*/1, - slice_pointers); + mark_slice_darken(stk, v, CAML_EPHE_DATA_OFFSET, /*in_ephemeron=*/1, + slice_pointers, work); } else { /* not triggered move to the next one */ ephes_to_check = &Field(v,CAML_EPHE_LINK_OFFSET); - return gray_vals_ptr; + return; } } else { /* a simily weak pointer or an already alive data */ *work -= 1; @@ -372,105 +553,78 @@ static value* mark_ephe_aux (value *gray_vals_ptr, intnat *work, *ephes_checked_if_pure = v; ephes_checked_if_pure = &Field(v,CAML_EPHE_LINK_OFFSET); } - return gray_vals_ptr; } - - static void mark_slice (intnat work) { - value *gray_vals_ptr; /* Local copy of [gray_vals_cur] */ - value v; - header_t hd; - mlsize_t size, i, start, end; /* [start] is a local copy of [current_index] */ + mark_entry me = {0, 0}; + mlsize_t me_end = 0; #ifdef CAML_INSTR int slice_fields = 0; /** eventlog counters */ #endif /*CAML_INSTR*/ int slice_pointers = 0; + struct mark_stack* stk = Caml_state->mark_stack; caml_gc_message (0x40, "Marking %"ARCH_INTNAT_PRINTF_FORMAT"d words\n", work); caml_gc_message (0x40, "Subphase = %d\n", caml_gc_subphase); - gray_vals_ptr = gray_vals_cur; - v = current_value; - start = current_index; - while (work > 0){ - if (v == 0 && gray_vals_ptr > gray_vals){ - CAMLassert (start == 0); - v = *--gray_vals_ptr; - CAMLassert (Is_gray_val (v)); + + while (1){ + int can_mark = 0; + + if (me.offset == me_end) { + if (stk->count > 0) + { + me = stk->stack[--stk->count]; + me_end = Wosize_val(me.block); + can_mark = 1; + } + } else { + can_mark = 1; } - if (v != 0){ - hd = Hd_val(v); - CAMLassert (Is_gray_hd (hd)); - size = Wosize_hd (hd); - end = start + work; - if (Tag_hd (hd) < No_scan_tag){ - start = size < start ? size : start; - end = size < end ? size : end; - CAMLassert (end >= start); + + if (work <= 0) { + if( can_mark ) { + mark_stack_push(stk, me.block, me.offset, NULL); CAML_EVENTLOG_DO({ - slice_fields += end - start; - if (size > end) - CAML_EV_COUNTER (EV_C_MAJOR_MARK_SLICE_REMAIN, size - end); + CAML_EV_COUNTER(EV_C_MAJOR_MARK_SLICE_REMAIN, me_end - me.offset); }); - for (i = start; i < end; i++){ - gray_vals_ptr = mark_slice_darken(gray_vals_ptr,v,i, - /*in_ephemeron=*/ 0, - &slice_pointers); - } - if (end < size){ - work = 0; - start = end; - /* [v] doesn't change. */ - CAMLassert (Is_gray_val (v)); - }else{ - CAMLassert (end == size); - Hd_val (v) = Blackhd_hd (hd); - work -= Whsize_wosize(end - start); - start = 0; - v = 0; - } - }else{ - /* The block doesn't contain any pointers. */ - CAMLassert (start == 0); - Hd_val (v) = Blackhd_hd (hd); - work -= Whsize_wosize(size); - v = 0; } - }else if (markhp != NULL){ - if (markhp == limit){ - chunk = Chunk_next (chunk); - if (chunk == NULL){ - markhp = NULL; - }else{ - markhp = chunk; - limit = chunk + Chunk_size (chunk); - } - }else{ - if (Is_gray_val (Val_hp (markhp))){ - CAMLassert (gray_vals_ptr == gray_vals); - CAMLassert (v == 0 && start == 0); - v = Val_hp (markhp); - } - markhp += Bhsize_hp (markhp); + break; + } + + if( can_mark ) { + CAMLassert(Is_block(me.block) && + Is_black_val (me.block) && + Tag_val(me.block) < No_scan_tag); + + mark_slice_darken(stk, me.block, me.offset++, /*in_ephemeron=*/ 0, + &slice_pointers, &work); + + work--; + + CAML_EVENTLOG_DO({ + slice_fields++; + }); + + if( me.offset == me_end ) { + work--; /* Include header word */ + } + } else if( redarken_first_chunk != NULL ) { + /* There are chunks that need to be redarkened because we + overflowed our mark stack */ + if( redarken_chunk(redarken_first_chunk, stk) ) { + redarken_first_chunk = Chunk_next(redarken_first_chunk); } - }else if (!heap_is_pure){ - heap_is_pure = 1; - chunk = caml_heap_start; - markhp = chunk; - limit = chunk + Chunk_size (chunk); } else if (caml_gc_subphase == Subphase_mark_roots) { CAML_EV_BEGIN(EV_MAJOR_MARK_ROOTS); - gray_vals_cur = gray_vals_ptr; work = caml_darken_all_roots_slice (work); - gray_vals_ptr = gray_vals_cur; CAML_EV_END(EV_MAJOR_MARK_ROOTS); if (work > 0){ caml_gc_subphase = Subphase_mark_main; } } else if (*ephes_to_check != (value) NULL) { /* Continue to scan the list of ephe */ - gray_vals_ptr = mark_ephe_aux(gray_vals_ptr,&work,&slice_pointers); + mark_ephe_aux(stk,&work,&slice_pointers); } else if (!ephe_list_pure){ /* We must scan again the list because some value have been darken */ ephe_list_pure = 1; @@ -481,13 +635,7 @@ static void mark_slice (intnat work) /* Subphase_mark_main is done. Mark finalised values. */ CAML_EV_BEGIN(EV_MAJOR_MARK_MAIN); - gray_vals_cur = gray_vals_ptr; caml_final_update_mark_phase (); - gray_vals_ptr = gray_vals_cur; - if (gray_vals_ptr > gray_vals){ - v = *--gray_vals_ptr; - CAMLassert (start == 0); - } /* Complete the marking */ ephes_to_check = ephes_checked_if_pure; CAML_EV_END(EV_MAJOR_MARK_MAIN); @@ -516,9 +664,6 @@ static void mark_slice (intnat work) } } } - gray_vals_cur = gray_vals_ptr; - current_value = v; - current_index = start; CAML_EV_COUNTER(EV_C_MAJOR_MARK_SLICE_FIELDS, slice_fields); CAML_EV_COUNTER(EV_C_MAJOR_MARK_SLICE_POINTERS, slice_pointers); } @@ -559,36 +704,37 @@ static void sweep_slice (intnat work) caml_gc_message (0x40, "Sweeping %" ARCH_INTNAT_PRINTF_FORMAT "d words\n", work); while (work > 0){ - if (caml_gc_sweep_hp < limit){ + if (caml_gc_sweep_hp < sweep_limit){ hp = caml_gc_sweep_hp; hd = Hd_hp (hp); work -= Whsize_hd (hd); caml_gc_sweep_hp += Bhsize_hd (hd); switch (Color_hd (hd)){ case Caml_white: - caml_gc_sweep_hp = (char *) caml_fl_merge_block (Val_hp (hp), limit); + caml_gc_sweep_hp = + (char *)caml_fl_merge_block(Val_hp (hp), sweep_limit); break; case Caml_blue: /* Only the blocks of the free-list are blue. See [freelist.c]. */ - caml_fl_merge = Bp_hp (hp); + caml_fl_merge = (value) Bp_hp (hp); break; default: /* gray or black */ CAMLassert (Color_hd (hd) == Caml_black); Hd_hp (hp) = Whitehd_hd (hd); break; } - CAMLassert (caml_gc_sweep_hp <= limit); + CAMLassert (caml_gc_sweep_hp <= sweep_limit); }else{ - chunk = Chunk_next (chunk); - if (chunk == NULL){ + sweep_chunk = Chunk_next (sweep_chunk); + if (sweep_chunk == NULL){ /* Sweeping is done. */ ++ Caml_state->stat_major_collections; work = 0; caml_gc_phase = Phase_idle; caml_request_minor_gc (); }else{ - caml_gc_sweep_hp = chunk; - limit = chunk + Chunk_size (chunk); + caml_gc_sweep_hp = sweep_chunk; + sweep_limit = sweep_chunk + Chunk_size (sweep_chunk); } } } @@ -832,6 +978,7 @@ void caml_finish_major_cycle (void) while (caml_gc_phase == Phase_mark) mark_slice (LONG_MAX); while (caml_gc_phase == Phase_clean) clean_slice (LONG_MAX); CAMLassert (caml_gc_phase == Phase_sweep); + CAMLassert (redarken_first_chunk == NULL); while (caml_gc_phase == Phase_sweep) sweep_slice (LONG_MAX); CAMLassert (caml_gc_phase == Phase_idle); Caml_state->stat_major_words += caml_allocated_words; @@ -890,13 +1037,20 @@ void caml_init_major_heap (asize_t heap_size) caml_make_free_blocks ((value *) caml_heap_start, Caml_state->stat_heap_wsz, 1, Caml_white); caml_gc_phase = Phase_idle; - gray_vals_size = 2048; - gray_vals = (value *) caml_stat_alloc_noexc (gray_vals_size * sizeof (value)); - if (gray_vals == NULL) - caml_fatal_error ("not enough memory for the gray cache"); - gray_vals_cur = gray_vals; - gray_vals_end = gray_vals + gray_vals_size; - heap_is_pure = 1; + + Caml_state->mark_stack = caml_stat_alloc_noexc(sizeof(struct mark_stack)); + if (Caml_state->mark_stack == NULL) + caml_fatal_error ("not enough memory for the mark stack"); + + Caml_state->mark_stack->stack = + caml_stat_alloc_noexc(MARK_STACK_INIT_SIZE * sizeof(mark_entry)); + + if(Caml_state->mark_stack->stack == NULL) + caml_fatal_error("not enough memory for the mark stack"); + + Caml_state->mark_stack->count = 0; + Caml_state->mark_stack->size = MARK_STACK_INIT_SIZE; + caml_allocated_words = 0; caml_extra_heap_resources = 0.0; for (i = 0; i < Max_major_window; i++) caml_major_ring[i] = 0.0; @@ -922,15 +1076,104 @@ void caml_finalise_heap (void) { /* Finishing major cycle (all values become white) */ caml_empty_minor_heap (); + caml_gc_message (0x1, "Finishing major GC cycle (finalising heap)\n"); caml_finish_major_cycle (); CAMLassert (caml_gc_phase == Phase_idle); /* Finalising all values (by means of forced sweeping) */ caml_fl_init_merge (); caml_gc_phase = Phase_sweep; - chunk = caml_heap_start; - caml_gc_sweep_hp = chunk; - limit = chunk + Chunk_size (chunk); + sweep_chunk = caml_heap_start; + caml_gc_sweep_hp = sweep_chunk; + sweep_limit = sweep_chunk + Chunk_size (sweep_chunk); while (caml_gc_phase == Phase_sweep) sweep_slice (LONG_MAX); } + +#if defined(NAKED_POINTERS_CHECKER) && defined(NATIVE_CODE) + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include + +Caml_inline int safe_load(volatile header_t * p, header_t * result) +{ + header_t v; + __try { + v = *p; + } + __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? + EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { + *result = 0xdeadbeef; + return 0; + } + *result = v; + return 1; +} + +#else + +Caml_inline int safe_load (header_t * addr, /*out*/ header_t * contents) +{ + int ok; + header_t h; + intnat tmp; + + asm volatile( + "leaq 1f(%%rip), %[tmp] \n\t" + "movq %[tmp], 0(%[handler]) \n\t" + "xorl %[ok], %[ok] \n\t" + "movq 0(%[addr]), %[h] \n\t" + "movl $1, %[ok] \n\t" + "1: \n\t" + "xorq %[tmp], %[tmp] \n\t" + "movq %[tmp], 0(%[handler])" + : [tmp] "=&r" (tmp), [ok] "=&r" (ok), [h] "=&r" (h) + : [addr] "r" (addr), + [handler] "r" (&(Caml_state->checking_pointer_pc))); + *contents = h; + return ok; +} + +#endif + +static void is_naked_pointer_safe (value v, value *p) +{ + header_t h; + tag_t t; + + /* The following conditions were checked by the caller */ + CAMLassert(Is_block(v) && !Is_young(v) && !Is_in_heap(v)); + + if (! safe_load(&Hd_val(v), &h)) goto on_segfault; + + t = Tag_hd(h); + if (t == Infix_tag) { + v -= Infix_offset_hd(h); + if (! safe_load(&Hd_val(v), &h)) goto on_segfault; + t = Tag_hd(h); + } + + /* For the out-of-heap pointer to be considered safe, + * it should have a black header and its size should be < 2 ** 40 + * words (128 GB). If not, we report a warning. */ + if (Is_black_hd(h) && Wosize_hd(h) < (INT64_LITERAL(1) << 40)) + return; + + if (!Is_black_hd(h)) { + fprintf (stderr, "Out-of-heap pointer at %p of value %p has " + "non-black head (tag=%d)\n", p, (void*)v, t); + } else { + fprintf (stderr, + "Out-of-heap pointer at %p of value %p has " + "suspiciously large size: %" ARCH_INT64_PRINTF_FORMAT "u words\n", + p, (void*)v, Wosize_hd(h)); + } + return; + + on_segfault: + fprintf (stderr, "Out-of-heap pointer at %p of value %p. " + "Cannot read head.\n", p, (void*)v); +} + +#endif diff --git a/runtime/memory.c b/runtime/memory.c index 6eb454b7..8c9cb0a2 100644 --- a/runtime/memory.c +++ b/runtime/memory.c @@ -52,7 +52,7 @@ extern uintnat caml_percent_free; /* major_gc.c */ /* Page table management */ #define Page(p) ((uintnat) (p) >> Page_log) -#define Page_mask ((uintnat) -1 << Page_log) +#define Page_mask ((~(uintnat)0) << Page_log) #ifdef ARCH_SIXTYFOUR @@ -262,6 +262,8 @@ char *caml_alloc_for_heap (asize_t request) mem = (char *) block + sizeof (heap_chunk_head); Chunk_size (mem) = size - sizeof (heap_chunk_head); Chunk_block (mem) = block; + Chunk_redarken_start(mem) = (value*)(mem + Chunk_size(mem)); + Chunk_redarken_end(mem) = (value*)mem; return mem; #else return NULL; @@ -277,19 +279,12 @@ char *caml_alloc_for_heap (asize_t request) mem += sizeof (heap_chunk_head); Chunk_size (mem) = request; Chunk_block (mem) = block; + Chunk_redarken_start(mem) = (value*)(mem + Chunk_size(mem)); + Chunk_redarken_end(mem) = (value*)mem; return mem; } } -/* Use this function if a block allocated with [caml_alloc_for_heap] is - not actually going to be added to the heap. The caller is responsible - for freeing it. */ -void caml_disown_for_heap (char* mem) -{ - /* Currently a no-op. */ - (void)mem; /* can CAMLunused_{start,end} be used here? */ -} - /* Use this function to free a block allocated with [caml_alloc_for_heap] if you don't add it with [caml_add_to_heap]. */ @@ -400,7 +395,7 @@ static value *expand_heap (mlsize_t request) }else{ Field (Val_hp (prev), 0) = (value) NULL; if (remain == 1) { - Hd_hp (hp) = Make_header_allocated_here (0, 0, Caml_white); + Hd_hp (hp) = Make_header (0, 0, Caml_white); } } CAMLassert (Wosize_hp (mem) >= request); @@ -429,7 +424,7 @@ void caml_shrink_heap (char *chunk) Caml_state->stat_heap_wsz -= Wsize_bsize (Chunk_size (chunk)); caml_gc_message (0x04, "Shrinking heap to %" - ARCH_INTNAT_PRINTF_FORMAT "uk words\n", + ARCH_INTNAT_PRINTF_FORMAT "dk words\n", Caml_state->stat_heap_wsz / 1024); #ifdef DEBUG @@ -455,7 +450,7 @@ void caml_shrink_heap (char *chunk) caml_free_for_heap (chunk); } -color_t caml_allocation_color (void *hp) +CAMLexport color_t caml_allocation_color (void *hp) { if (caml_gc_phase == Phase_mark || caml_gc_phase == Phase_clean || (caml_gc_phase == Phase_sweep && (char *)hp >= (char *)caml_gc_sweep_hp)){ @@ -556,21 +551,6 @@ CAMLexport value caml_alloc_shr_for_minor_gc (mlsize_t wosize, } #endif /* WITH_PROFINFO */ -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) -#include "caml/spacetime.h" - -CAMLexport value caml_alloc_shr (mlsize_t wosize, tag_t tag) -{ - return caml_alloc_shr_with_profinfo (wosize, tag, - caml_spacetime_my_profinfo (NULL, wosize)); -} - -CAMLexport value caml_alloc_shr_no_track_noexc (mlsize_t wosize, tag_t tag) -{ - return caml_alloc_shr_aux (wosize, tag, 0, 0, - caml_spacetime_my_profinfo (NULL, wosize)); -} -#else CAMLexport value caml_alloc_shr (mlsize_t wosize, tag_t tag) { return caml_alloc_shr_aux (wosize, tag, 1, 1, NO_PROFINFO); @@ -580,7 +560,6 @@ CAMLexport value caml_alloc_shr_no_track_noexc (mlsize_t wosize, tag_t tag) { return caml_alloc_shr_aux (wosize, tag, 0, 0, NO_PROFINFO); } -#endif /* Dependent memory is all memory blocks allocated out of the heap that depend on the GC (and finalizers) for deallocation. diff --git a/runtime/memprof.c b/runtime/memprof.c index 63ac685f..c14da084 100644 --- a/runtime/memprof.c +++ b/runtime/memprof.c @@ -15,7 +15,6 @@ #define CAML_INTERNALS -#include #include #include "caml/memprof.h" #include "caml/fail.h" @@ -32,27 +31,19 @@ #include "caml/printexc.h" #include "caml/eventlog.h" -#define MT_STATE_SIZE 624 +#define RAND_BLOCK_SIZE 64 -static uint32_t mt_state[MT_STATE_SIZE]; -static uint32_t mt_index; +static uint32_t xoshiro_state[4][RAND_BLOCK_SIZE]; +static uintnat rand_geom_buff[RAND_BLOCK_SIZE]; +static uint32_t rand_pos; /* [lambda] is the mean number of samples for each allocated word (including block headers). */ static double lambda = 0; - /* Precomputed value of [1/log(1-lambda)], for fast sampling of - geometric distribution. - Dummy if [lambda = 0]. */ -static double one_log1m_lambda; - -/* [caml_memprof_suspended] is used for masking memprof callbacks when - a callback is running or when an uncaught exception handler is - called. */ -int caml_memprof_suspended = 0; - -/* [callback_running] is used to trigger a fatal error whenever - [Thread.exit] is called from a callback. */ -static int callback_running = 0; +/* Precomputed value of [1/log(1-lambda)], for fast sampling of + geometric distribution. + Dummy if [lambda = 0]. */ +static float one_log1m_lambda; static intnat callstack_size; @@ -66,6 +57,114 @@ static intnat callstack_size; static value tracker; +/* Gc.Memprof.allocation_source */ +enum { SRC_NORMAL = 0, SRC_MARSHAL = 1, SRC_CUSTOM = 2 }; + +struct tracked { + /* Memory block being sampled. This is a weak GC root. */ + value block; + + /* Number of samples in this block. */ + uintnat n_samples; + + /* The size of this block. */ + uintnat wosize; + + /* The value returned by the previous callback for this block, or + the callstack if the alloc callback has not been called yet. + This is a strong GC root. */ + value user_data; + + /* The thread currently running a callback for this entry, + or NULL if there is none */ + struct caml_memprof_th_ctx* running; + + /* Whether this block has been initially allocated in the minor heap. */ + unsigned int alloc_young : 1; + + /* The source of the allocation: normal allocations, marshal or custom_mem. */ + unsigned int source : 2; + + /* Whether this block has been promoted. Implies [alloc_young]. */ + unsigned int promoted : 1; + + /* Whether this block has been deallocated. */ + unsigned int deallocated : 1; + + /* Whether the allocation callback has been called depends on + whether the entry is in a thread local entry array or in + [entries_global]. */ + + /* Whether the promotion callback has been called. */ + unsigned int cb_promote_called : 1; + + /* Whether the deallocation callback has been called. */ + unsigned int cb_dealloc_called : 1; + + /* Whether this entry is deleted. */ + unsigned int deleted : 1; +}; + +/* During the alloc callback for a minor allocation, the block being + sampled is not yet allocated. Instead, we place in the block field + a value computed with the following macro: */ +#define Placeholder_magic 0x04200000 +#define Placeholder_offs(offset) (Val_long(offset + Placeholder_magic)) +#define Offs_placeholder(block) (Long_val(block) & 0xFFFF) +#define Is_placeholder(block) \ + (Is_long(block) && (Long_val(block) & ~(uintnat)0xFFFF) == Placeholder_magic) + +/* A resizable array of entries */ +struct entry_array { + struct tracked* t; + uintnat min_alloc_len, alloc_len, len; + /* Before this position, the [block] and [user_data] fields point to + the major heap ([young <= len]). */ + uintnat young_idx; + /* There are no blocks to be deleted before this position + ([delete_idx <= len]). */ + uintnat delete_idx; +}; + +#define MIN_ENTRIES_LOCAL_ALLOC_LEN 16 +#define MIN_ENTRIES_GLOBAL_ALLOC_LEN 128 + +/* Entries for other blocks. This variable is shared accross threads. */ +static struct entry_array entries_global = + { NULL, MIN_ENTRIES_GLOBAL_ALLOC_LEN, 0, 0, 0, 0 }; + +/* There are no pending callbacks in [entries_global] before this + position ([callback_idx <= entries_global.len]). */ +static uintnat callback_idx; + +#define CB_IDLE -1 +#define CB_LOCAL -2 +#define CB_STOPPED -3 + +/* Structure for thread-local variables. */ +struct caml_memprof_th_ctx { + /* [suspended] is used for masking memprof callbacks when + a callback is running or when an uncaught exception handler is + called. */ + int suspended; + + /* [callback_status] contains: + - CB_STOPPED if the current thread is running a callback, but + sampling has been stopped using [caml_memprof_stop]; + - The index of the corresponding entry in the [entries_global] + array if the current thread is currently running a promotion or + a deallocation callback; + - CB_LOCAL if the current thread is currently running an + allocation callback; + - CB_IDLE if the current thread is not running any callback. + */ + intnat callback_status; + + /* Entries for blocks whose alloc callback has not yet been called. */ + struct entry_array entries; +} caml_memprof_main_ctx = + { 0, CB_IDLE, { NULL, MIN_ENTRIES_LOCAL_ALLOC_LEN, 0, 0, 0, 0 } }; +static struct caml_memprof_th_ctx* local = &caml_memprof_main_ctx; /* Pointer to the word following the next sample in the minor heap. Equals [Caml_state->young_alloc_start] if no sampling is planned in @@ -86,55 +185,131 @@ static intnat callstack_buffer_len = 0; /**** Statistical sampling ****/ -static double mt_generate_uniform(void) +Caml_inline uint64_t splitmix64_next(uint64_t* x) { - int i; - uint32_t y; + uint64_t z = (*x += 0x9E3779B97F4A7C15ull); + z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ull; + z = (z ^ (z >> 27)) * 0x94D049BB133111EBull; + return z ^ (z >> 31); +} - /* Mersenne twister PRNG */ - if (mt_index == MT_STATE_SIZE) { - for (i = 0; i < 227; i++) { - y = (mt_state[i] & 0x80000000) + (mt_state[i+1] & 0x7fffffff); - mt_state[i] = mt_state[i+397] ^ (y >> 1) ^ ((-(y&1)) & 0x9908b0df); - } - for (i = 227; i < MT_STATE_SIZE - 1; i++) { - y = (mt_state[i] & 0x80000000) + (mt_state[i+1] & 0x7fffffff); - mt_state[i] = mt_state[i-227] ^ (y >> 1) ^ ((-(y&1)) & 0x9908b0df); - } - y = (mt_state[MT_STATE_SIZE - 1] & 0x80000000) + (mt_state[0] & 0x7fffffff); - mt_state[MT_STATE_SIZE - 1] = - mt_state[396] ^ (y >> 1) ^ ((-(y&1)) & 0x9908b0df); - mt_index = 0; +static void xoshiro_init(void) +{ + int i; + uint64_t splitmix64_state = 42; + rand_pos = RAND_BLOCK_SIZE; + for (i = 0; i < RAND_BLOCK_SIZE; i++) { + uint64_t t = splitmix64_next(&splitmix64_state); + xoshiro_state[0][i] = t & 0xFFFFFFFF; + xoshiro_state[1][i] = t >> 32; + t = splitmix64_next(&splitmix64_state); + xoshiro_state[2][i] = t & 0xFFFFFFFF; + xoshiro_state[3][i] = t >> 32; } +} + +Caml_inline uint32_t xoshiro_next(int i) +{ + uint32_t res = xoshiro_state[0][i] + xoshiro_state[3][i]; + uint32_t t = xoshiro_state[1][i] << 9; + xoshiro_state[2][i] ^= xoshiro_state[0][i]; + xoshiro_state[3][i] ^= xoshiro_state[1][i]; + xoshiro_state[1][i] ^= xoshiro_state[2][i]; + xoshiro_state[0][i] ^= xoshiro_state[3][i]; + xoshiro_state[2][i] ^= t; + t = xoshiro_state[3][i]; + xoshiro_state[3][i] = (t << 11) | (t >> 21); + return res; +} + +/* Computes [log((y+0.5)/2^32)], up to a relatively good precision, + and guarantee that the result is negative. + The average absolute error is very close to 0. */ +Caml_inline float log_approx(uint32_t y) +{ + union { float f; int32_t i; } u; + float exp, x; + u.f = y + 0.5f; /* We convert y to a float ... */ + exp = u.i >> 23; /* ... of which we extract the exponent ... */ + u.i = (u.i & 0x7FFFFF) | 0x3F800000; + x = u.f; /* ... and the mantissa. */ + + return + /* This polynomial computes the logarithm of the mantissa (which + is in [1, 2]), up to an additive constant. It is chosen such that : + - Its degree is 4. + - Its average value is that of log in [1, 2] + (the sampling has the right mean when lambda is small). + - f(1) = f(2) - log(2) = -159*log(2) - 1e-5 + (this guarantee that log_approx(y) is always <= -1e-5 < 0). + - The maximum of abs(f(x)-log(x)+159*log(2)) is minimized. + */ + x * (2.104659476859f + x * (-0.720478916626f + x * 0.107132064797f)) + + /* Then, we add the term corresponding to the exponent, and + additive constants. */ + + (-111.701724334061f + 0.6931471805f*exp); +} + +/* This function regenerates [MT_STATE_SIZE] geometric random + variables at once. Doing this by batches help us gain performances: + many compilers (e.g., GCC, CLang, ICC) will be able to use SIMD + instructions to get a performance boost. +*/ +#ifdef SUPPORTS_TREE_VECTORIZE +__attribute__((optimize("tree-vectorize"))) +#endif +static void rand_batch(void) +{ + int i; - y = mt_state[mt_index]; - y = y ^ (y >> 11); - y = y ^ ((y << 7) & 0x9d2c5680); - y = y ^ ((y << 15) & 0xefc60000); - y = y ^ (y >> 18); + /* Instead of using temporary buffers, we could use one big loop, + but it turns out SIMD optimizations of compilers are more fragile + when using larger loops. */ + static uint32_t A[RAND_BLOCK_SIZE]; + static float B[RAND_BLOCK_SIZE]; + + CAMLassert(lambda > 0.); + + /* Shuffle the xoshiro samplers, and generate uniform variables in A. */ + for (i = 0; i < RAND_BLOCK_SIZE; i++) + A[i] = xoshiro_next(i); + + /* Generate exponential random variables by computing logarithms. We + do not use math.h library functions, which are slow and prevent + compiler from using SIMD instructions. */ + for (i = 0; i < RAND_BLOCK_SIZE; i++) + B[i] = 1 + log_approx(A[i]) * one_log1m_lambda; + + /* We do the final flooring for generating geometric + variables. Compilers are unlikely to use SIMD instructions for + this loop, because it involves a conditional and variables of + different sizes (32 and 64 bits). */ + for (i = 0; i < RAND_BLOCK_SIZE; i++) { + double f = B[i]; + CAMLassert (f >= 1); + /* [Max_long+1] is a power of two => no rounding in the test. */ + if (f >= Max_long+1) + rand_geom_buff[i] = Max_long; + else rand_geom_buff[i] = (uintnat)f; + } - mt_index++; - return y*2.3283064365386962890625e-10 + /* 2^-32 */ - 1.16415321826934814453125e-10; /* 2^-33 */ + rand_pos = 0; } /* Simulate a geometric variable of parameter [lambda]. The result is clipped in [1..Max_long] */ -static uintnat mt_generate_geom(void) +static uintnat rand_geom(void) { - double res; + uintnat res; CAMLassert(lambda > 0.); - /* We use the float versions of exp/log, since these functions are - significantly faster, and we really don't need much precision - here. The entropy contained in [next_mt_generate_geom] is anyway - bounded by the entropy provided by [mt_generate_uniform], which - is 32bits. */ - res = 1 + logf(mt_generate_uniform()) * one_log1m_lambda; - if (res > Max_long) return Max_long; - return (uintnat)res; + if (rand_pos == RAND_BLOCK_SIZE) rand_batch(); + res = rand_geom_buff[rand_pos++]; + CAMLassert(1 <= res && res <= Max_long); + return res; } -static uintnat next_mt_generate_geom; +static uintnat next_rand_geom; /* Simulate a binomial variable of parameters [len] and [lambda]. This sampling algorithm has running time linear with [len * lambda]. We could use more a involved algorithm, but this should @@ -146,13 +321,13 @@ static uintnat next_mt_generate_geom; Hormann, Wolfgang. "The generation of binomial random variates." Journal of statistical computation and simulation 46.1-2 (1993), pp101-110. */ -static uintnat mt_generate_binom(uintnat len) +static uintnat rand_binom(uintnat len) { uintnat res; CAMLassert(lambda > 0. && len < Max_long); - for (res = 0; next_mt_generate_geom < len; res++) - next_mt_generate_geom += mt_generate_geom(); - next_mt_generate_geom -= len; + for (res = 0; next_rand_geom < len; res++) + next_rand_geom += rand_geom(); + next_rand_geom -= len; return res; } @@ -188,14 +363,14 @@ static value capture_callstack_postponed() /* In this version, we are allowed to call the GC, so we use [caml_alloc], which is more efficient since it uses the minor heap. - Should be called with [caml_memprof_suspended == 1] */ + Should be called with [local->suspended == 1] */ static value capture_callstack(int alloc_idx) { value res; intnat callstack_len = caml_collect_current_callstack(&callstack_buffer, &callstack_buffer_len, callstack_size, alloc_idx); - CAMLassert(caml_memprof_suspended); + CAMLassert(local->suspended); res = caml_alloc(callstack_len, 0); memcpy(Op_val(res), callstack_buffer, sizeof(value) * callstack_len); if (callstack_buffer_len > 256 && callstack_buffer_len > callstack_len * 8) { @@ -206,318 +381,293 @@ static value capture_callstack(int alloc_idx) return res; } -/**** Data structures for tracked blocks. ****/ - -struct tracked { - /* Memory block being sampled. This is a weak GC root. */ - value block; - - /* Number of samples in this block. */ - uintnat n_samples; - - /* The size of this block. */ - uintnat wosize; - - /* The value returned by the previous callback for this block, or - the callstack if the alloc callback has not been called yet. - This is a strong GC root. */ - value user_data; - - /* Whether this block has been initially allocated in the minor heap. */ - unsigned int alloc_young : 1; - - /* Whether this block comes from unmarshalling. */ - unsigned int unmarshalled : 1; - - /* Whether this block has been promoted. Implies [alloc_young]. */ - unsigned int promoted : 1; - - /* Whether this block has been deallocated. */ - unsigned int deallocated : 1; - - /* Whether the allocation callback has been called. */ - unsigned int cb_alloc_called : 1; - - /* Whether the promotion callback has been called. */ - unsigned int cb_promote_called : 1; - - /* Whether the deallocation callback has been called. */ - unsigned int cb_dealloc_called : 1; - - /* Whether this entry is deleted. */ - unsigned int deleted : 1; - - /* Whether a callback is currently running for this entry. */ - unsigned int callback_running : 1; - - /* Pointer to the [t_idx] variable in the [run_callback] frame which - is currently running the callback for this entry. This is needed - to make [run_callback] reetrant, in the case it is called - simultaneously by several threads. */ - uintnat* idx_ptr; -}; - -/* During the alloc callback for a minor allocation, the block being - sampled is not yet allocated. Instead, we place in the block field - a value computed with the following macro: */ -#define Placeholder_magic 0x04200000 -#define Placeholder_offs(offset) (Val_long(offset + Placeholder_magic)) -#define Offs_placeholder(block) (Long_val(block) & 0xFFFF) -#define Is_placeholder(block) \ - (Is_long(block) && (Long_val(block) & ~(uintnat)0xFFFF) == Placeholder_magic) - -/* When an entry is deleted, its index is replaced by that integer. */ -#define Invalid_index (~(uintnat)0) - - -static struct tracking_state { - struct tracked* entries; - /* The allocated capacity of the entries array */ - uintnat alloc_len; - /* The number of active entries. (len <= alloc_len) */ - uintnat len; - /* Before this position, the [block] and [user_data] fields point to - the major heap (young <= len). */ - uintnat young; - /* There are no pending callbacks before this position (callback <= len). */ - uintnat callback; - /* There are no blocks to be deleted before this position */ - uintnat delete; -} trackst; - -#define MIN_TRACKST_ALLOC_LEN 128 - +/**** Managing data structures for tracked blocks. ****/ -/* Reallocate the [trackst] array if it is either too small or too +/* Reallocate the [ea] array if it is either too small or too large. - Returns 1 if reallocation succeeded --[trackst.alloc_len] is at - least [trackst.len]--, and 0 otherwise. */ -static int realloc_trackst(void) { - uintnat new_alloc_len; - struct tracked* new_entries; - if (trackst.len <= trackst.alloc_len && - (4*trackst.len >= trackst.alloc_len || - trackst.alloc_len == MIN_TRACKST_ALLOC_LEN)) + [grow] is the number of free cells needed. + Returns 1 if reallocation succeeded --[ea->alloc_len] is at + least [ea->len+grow]--, and 0 otherwise. */ +static int realloc_entries(struct entry_array* ea, uintnat grow) +{ + uintnat new_alloc_len, new_len = ea->len + grow; + struct tracked* new_t; + if (new_len <= ea->alloc_len && + (4*new_len >= ea->alloc_len || ea->alloc_len == ea->min_alloc_len)) return 1; - new_alloc_len = trackst.len * 2; - if (new_alloc_len < MIN_TRACKST_ALLOC_LEN) - new_alloc_len = MIN_TRACKST_ALLOC_LEN; - new_entries = caml_stat_resize_noexc(trackst.entries, - new_alloc_len * sizeof(struct tracked)); - if (new_entries == NULL) return 0; - trackst.entries = new_entries; - trackst.alloc_len = new_alloc_len; + new_alloc_len = new_len * 2; + if (new_alloc_len < ea->min_alloc_len) + new_alloc_len = ea->min_alloc_len; + new_t = caml_stat_resize_noexc(ea->t, new_alloc_len * sizeof(struct tracked)); + if (new_t == NULL) return 0; + ea->t = new_t; + ea->alloc_len = new_alloc_len; return 1; } +#define Invalid_index (~(uintnat)0) + Caml_inline uintnat new_tracked(uintnat n_samples, uintnat wosize, - int is_unmarshalled, int is_young, + int source, int is_young, value block, value user_data) { struct tracked *t; - trackst.len++; - if (!realloc_trackst()) { - trackst.len--; + if (!realloc_entries(&local->entries, 1)) return Invalid_index; - } - t = &trackst.entries[trackst.len - 1]; + local->entries.len++; + t = &local->entries.t[local->entries.len - 1]; t->block = block; t->n_samples = n_samples; t->wosize = wosize; t->user_data = user_data; - t->idx_ptr = NULL; + t->running = NULL; t->alloc_young = is_young; - t->unmarshalled = is_unmarshalled; + t->source = source; t->promoted = 0; t->deallocated = 0; - t->cb_alloc_called = t->cb_promote_called = t->cb_dealloc_called = 0; + t->cb_promote_called = t->cb_dealloc_called = 0; t->deleted = 0; - t->callback_running = 0; - return trackst.len - 1; + return local->entries.len - 1; } -static void mark_deleted(uintnat t_idx) +static void mark_deleted(struct entry_array* ea, uintnat t_idx) { - struct tracked* t = &trackst.entries[t_idx]; + struct tracked* t = &ea->t[t_idx]; t->deleted = 1; t->user_data = Val_unit; t->block = Val_unit; - if (t_idx < trackst.delete) trackst.delete = t_idx; - CAMLassert(t->idx_ptr == NULL); + if (t_idx < ea->delete_idx) ea->delete_idx = t_idx; } -/* The return value is an exception or [Val_unit] iff [*t_idx] is set to - [Invalid_index]. In this case, the entry is deleted. - Otherwise, the return value is a [Some(...)] block. */ -Caml_inline value run_callback_exn(uintnat *t_idx, value cb, value param) { - struct tracked* t = &trackst.entries[*t_idx]; +Caml_inline value run_callback_exn( + struct entry_array* ea, uintnat t_idx, value cb, value param) +{ + struct tracked* t = &ea->t[t_idx]; value res; - CAMLassert(!t->callback_running && t->idx_ptr == NULL); + CAMLassert(t->running == NULL); CAMLassert(lambda > 0.); - callback_running = t->callback_running = 1; - t->idx_ptr = t_idx; + local->callback_status = ea == &entries_global ? t_idx : CB_LOCAL; + t->running = local; + t->user_data = Val_unit; /* Release root. */ res = caml_callback_exn(cb, param); - callback_running = 0; - /* The call above can modify [*t_idx] and thus invalidate [t]. */ - if (*t_idx == Invalid_index) { - /* Make sure this entry has not been removed by [caml_memprof_set] */ - return Val_unit; + if (local->callback_status == CB_STOPPED) { + /* Make sure this entry has not been removed by [caml_memprof_stop] */ + local->callback_status = CB_IDLE; + return Is_exception_result(res) ? res : Val_unit; + } + /* The call above can move the tracked entry and thus invalidate + [t_idx] and [t]. */ + if (ea == &entries_global) { + CAMLassert(local->callback_status >= 0 && local->callback_status < ea->len); + t_idx = local->callback_status; + t = &ea->t[t_idx]; } - t = &trackst.entries[*t_idx]; - t->idx_ptr = NULL; - t->callback_running = 0; + local->callback_status = CB_IDLE; + CAMLassert(t->running == local); + t->running = NULL; if (Is_exception_result(res) || res == Val_unit) { /* Callback raised an exception or returned None or (), discard this entry. */ - mark_deleted(*t_idx); - *t_idx = Invalid_index; - } - return res; -} - -/* Run all the needed callbacks for a given entry. - In case of a thread context switch during a callback, this can be - called in a reetrant way. - If [*t_idx] equals [trackst.callback], then this function - increments [trackst.callback]. - The index of the entry may change. It is set to [Invalid_index] if - the entry is discarded. - Returns: - - An exception result if the callback raised an exception - - Val_long(0) == Val_unit == None otherwise - */ -static value handle_entry_callbacks_exn(uintnat* t_idx) -{ - value sample_info, res, user_data; /* No need to make these roots */ - struct tracked* t = &trackst.entries[*t_idx]; - if (*t_idx == trackst.callback) trackst.callback++; - - if (t->deleted || t->callback_running) return Val_unit; - - if (!t->cb_alloc_called) { - t->cb_alloc_called = 1; - CAMLassert(Is_block(t->block) - || Is_placeholder(t->block) - || t->deallocated); - sample_info = caml_alloc_small(4, 0); - Field(sample_info, 0) = Val_long(t->n_samples); - Field(sample_info, 1) = Val_long(t->wosize); - Field(sample_info, 2) = Val_long(t->unmarshalled); - Field(sample_info, 3) = t->user_data; - t->user_data = Val_unit; - res = run_callback_exn(t_idx, - t->alloc_young ? Alloc_minor(tracker) : Alloc_major(tracker), - sample_info); - if (*t_idx == Invalid_index) - return res; - CAMLassert(!Is_exception_result(res) && Is_block(res) && Tag_val(res) == 0 - && Wosize_val(res) == 1); - t = &trackst.entries[*t_idx]; - t->user_data = Field(res, 0); - if (Is_block(t->user_data) && Is_young(t->user_data) && - *t_idx < trackst.young) - trackst.young = *t_idx; - } - - if (t->promoted && !t->cb_promote_called) { - t->cb_promote_called = 1; - user_data = t->user_data; - t->user_data = Val_unit; - res = run_callback_exn(t_idx, Promote(tracker), user_data); - if (*t_idx == Invalid_index) - return res; + mark_deleted(ea, t_idx); + return res; + } else { + /* Callback returned [Some _]. Store the value in [user_data]. */ CAMLassert(!Is_exception_result(res) && Is_block(res) && Tag_val(res) == 0 && Wosize_val(res) == 1); - t = &trackst.entries[*t_idx]; t->user_data = Field(res, 0); if (Is_block(t->user_data) && Is_young(t->user_data) && - *t_idx < trackst.young) - trackst.young = *t_idx; - } + t_idx < ea->young_idx) + ea->young_idx = t_idx; + + // If the following condition are met: + // - we are running a promotion callback, + // - the corresponding block is deallocated, + // - another thread is running callbacks in + // [caml_memprof_handle_postponed_exn], + // then [callback_idx] may have moved forward during this callback, + // which means that we may forget to run the deallocation callback. + // Hence, we reset [callback_idx] if appropriate. + if (ea == &entries_global && t->deallocated && !t->cb_dealloc_called && + callback_idx > t_idx) + callback_idx = t_idx; - if (t->deallocated && !t->cb_dealloc_called) { - value cb = (t->promoted || !t->alloc_young) ? - Dealloc_major(tracker) : Dealloc_minor(tracker); - t->cb_dealloc_called = 1; - user_data = t->user_data; - t->user_data = Val_unit; - res = run_callback_exn(t_idx, cb, user_data); - /* [t] is invalid, but we do no longer use it. */ - CAMLassert(*t_idx == Invalid_index); - CAMLassert(Is_exception_result(res) || res == Val_unit); - return res; + return Val_unit; } +} - return Val_unit; +/* Run the allocation callback for a given entry of the local entries array. + This assumes that the corresponding [deleted] and + [running] fields of the entry are both set to 0. + Reentrancy is not a problem for this function, since other threads + will use a different array for entries. + The index of the entry will not change, except if [caml_memprof_stop] is + called . + Returns: + - An exception result if the callback raised an exception + - Val_long(0) == Val_unit == None otherwise + */ +static value run_alloc_callback_exn(uintnat t_idx) +{ + struct tracked* t = &local->entries.t[t_idx]; + value sample_info; + + CAMLassert(Is_block(t->block) || Is_placeholder(t->block) || t->deallocated); + sample_info = caml_alloc_small(4, 0); + Field(sample_info, 0) = Val_long(t->n_samples); + Field(sample_info, 1) = Val_long(t->wosize); + Field(sample_info, 2) = Val_long(t->source); + Field(sample_info, 3) = t->user_data; + return run_callback_exn(&local->entries, t_idx, + t->alloc_young ? Alloc_minor(tracker) : Alloc_major(tracker), sample_info); } -/* Remove any deleted entries, updating callback and young */ -static void flush_deleted(void) +/* Remove any deleted entries from [ea], updating [ea->young_idx] and + [callback_idx] if [ea == &entries_global]. */ +static void flush_deleted(struct entry_array* ea) { - uintnat i = trackst.delete, j = i; - while (i < trackst.len) { - if (!trackst.entries[i].deleted) { - if (trackst.entries[i].idx_ptr != NULL) - *trackst.entries[i].idx_ptr = j; - trackst.entries[j] = trackst.entries[i]; + uintnat i, j; + + if (ea == NULL) return; + + j = i = ea->delete_idx; + while (i < ea->len) { + if (!ea->t[i].deleted) { + struct caml_memprof_th_ctx* runner = ea->t[i].running; + if (runner != NULL && runner->callback_status == i) + runner->callback_status = j; + ea->t[j] = ea->t[i]; j++; } i++; - if (trackst.young == i) trackst.young = j; - if (trackst.callback == i) trackst.callback = j; + if (ea->young_idx == i) ea->young_idx = j; + if (ea == &entries_global && callback_idx == i) callback_idx = j; } - trackst.delete = trackst.len = j; - CAMLassert(trackst.callback <= trackst.len); - CAMLassert(trackst.young <= trackst.len); - realloc_trackst(); + ea->delete_idx = ea->len = j; + CAMLassert(ea != &entries_global || callback_idx <= ea->len); + CAMLassert(ea->young_idx <= ea->len); + realloc_entries(ea, 0); } -static void check_action_pending(void) { - if (!caml_memprof_suspended && trackst.callback < trackst.len) +static void check_action_pending(void) +{ + if (local->suspended) return; + if (callback_idx < entries_global.len || local->entries.len > 0) caml_set_action_pending(); } +void caml_memprof_set_suspended(int s) +{ + local->suspended = s; + caml_memprof_renew_minor_sample(); + if (!s) check_action_pending(); +} + /* In case of a thread context switch during a callback, this can be called in a reetrant way. */ value caml_memprof_handle_postponed_exn(void) { value res = Val_unit; - if (caml_memprof_suspended) return res; - caml_memprof_suspended = 1; - while (trackst.callback < trackst.len) { - uintnat i = trackst.callback; - res = handle_entry_callbacks_exn(&i); - if (Is_exception_result(res)) break; + uintnat i; + if (local->suspended) return Val_unit; + if (callback_idx >= entries_global.len && local->entries.len == 0) + return Val_unit; + + caml_memprof_set_suspended(1); + + for (i = 0; i < local->entries.len; i++) { + /* We are the only thread allowed to modify [local->entries], so + the indices cannot shift, but it is still possible that + [caml_memprof_stop] got called during the callback, + invalidating all the entries. */ + res = run_alloc_callback_exn(i); + if (Is_exception_result(res)) goto end; + if (local->entries.len == 0) + goto end; /* [caml_memprof_stop] has been called. */ + if (local->entries.t[i].deleted) continue; + if (realloc_entries(&entries_global, 1)) + /* Transfer the entry to the global array. */ + entries_global.t[entries_global.len++] = local->entries.t[i]; + mark_deleted(&local->entries, i); + } + + while (callback_idx < entries_global.len) { + struct tracked* t = &entries_global.t[callback_idx]; + + if (t->deleted || t->running != NULL) { + /* This entry is not ready. Ignore it. */ + callback_idx++; + } else if (t->promoted && !t->cb_promote_called) { + t->cb_promote_called = 1; + res = run_callback_exn(&entries_global, callback_idx, Promote(tracker), + t->user_data); + if (Is_exception_result(res)) goto end; + } else if (t->deallocated && !t->cb_dealloc_called) { + value cb = (t->promoted || !t->alloc_young) ? + Dealloc_major(tracker) : Dealloc_minor(tracker); + t->cb_dealloc_called = 1; + res = run_callback_exn(&entries_global, callback_idx, cb, t->user_data); + if (Is_exception_result(res)) goto end; + } else { + /* There is nothing more to do with this entry. */ + callback_idx++; + } } - caml_memprof_suspended = 0; - check_action_pending(); /* Needed in case of an exception */ - flush_deleted(); + + end: + flush_deleted(&local->entries); + flush_deleted(&entries_global); + /* We need to reset the suspended flag *after* flushing + [local->entries] to make sure the floag is not set back to 1. */ + caml_memprof_set_suspended(0); return res; } -void caml_memprof_oldify_young_roots(void) +/**** Handling weak and strong roots when the GC runs. ****/ + +typedef void (*ea_action)(struct entry_array*, void*); +struct call_on_entry_array_data { ea_action f; void *data; }; +static void call_on_entry_array(struct caml_memprof_th_ctx* ctx, void *data) +{ + struct call_on_entry_array_data* closure = data; + closure->f(&ctx->entries, closure->data); +} + +static void entry_arrays_iter(ea_action f, void *data) +{ + struct call_on_entry_array_data closure = { f, data }; + f(&entries_global, data); + caml_memprof_th_ctx_iter_hook(call_on_entry_array, &closure); +} + +static void entry_array_oldify_young_roots(struct entry_array *ea, void *data) { uintnat i; - /* This loop should always have a small number of iteration (when - compared to the size of the minor heap), because the young + (void)data; + /* This loop should always have a small number of iterations (when + compared to the size of the minor heap), because the young_idx pointer should always be close to the end of the array. Indeed, it is only moved back when returning from a callback triggered by allocation or promotion, which can only happen for blocks - allocated recently, which are close to the end of the trackst - array. */ - for (i = trackst.young; i < trackst.len; i++) - caml_oldify_one(trackst.entries[i].user_data, - &trackst.entries[i].user_data); + allocated recently, which are close to the end of the + [entries_global] array. */ + for (i = ea->young_idx; i < ea->len; i++) + caml_oldify_one(ea->t[i].user_data, &ea->t[i].user_data); } -void caml_memprof_minor_update(void) +void caml_memprof_oldify_young_roots(void) +{ + entry_arrays_iter(entry_array_oldify_young_roots, NULL); +} + +static void entry_array_minor_update(struct entry_array *ea, void *data) { uintnat i; - /* See comment in [caml_memprof_oldify_young_roots] for the number + (void)data; + /* See comment in [entry_array_oldify_young_roots] for the number of iterations of this loop. */ - for (i = trackst.young; i < trackst.len; i++) { - struct tracked *t = &trackst.entries[i]; + for (i = ea->young_idx; i < ea->len; i++) { + struct tracked *t = &ea->t[i]; CAMLassert(Is_block(t->block) || t->deleted || t->deallocated || Is_placeholder(t->block)); if (Is_block(t->block) && Is_young(t->block)) { @@ -533,25 +683,40 @@ void caml_memprof_minor_update(void) } } } - if (trackst.callback > trackst.young) { - trackst.callback = trackst.young; + ea->young_idx = ea->len; +} + +void caml_memprof_minor_update(void) +{ + if (callback_idx > entries_global.young_idx) { + /* The entries after [entries_global.young_idx] will possibly get + promoted. Hence, there might be pending promotion callbacks. */ + callback_idx = entries_global.young_idx; check_action_pending(); } - trackst.young = trackst.len; + + entry_arrays_iter(entry_array_minor_update, NULL); } -void caml_memprof_do_roots(scanning_action f) +static void entry_array_do_roots(struct entry_array *ea, void* data) { + scanning_action f = data; uintnat i; - for (i = 0; i < trackst.len; i++) - f(trackst.entries[i].user_data, &trackst.entries[i].user_data); + for (i = 0; i < ea->len; i++) + f(ea->t[i].user_data, &ea->t[i].user_data); } -void caml_memprof_update_clean_phase(void) +void caml_memprof_do_roots(scanning_action f) +{ + entry_arrays_iter(entry_array_do_roots, f); +} + +static void entry_array_clean_phase(struct entry_array *ea, void* data) { uintnat i; - for (i = 0; i < trackst.len; i++) { - struct tracked *t = &trackst.entries[i]; + (void)data; + for (i = 0; i < ea->len; i++) { + struct tracked *t = &ea->t[i]; if (Is_block(t->block) && !Is_young(t->block)) { CAMLassert(Is_in_heap(t->block)); CAMLassert(!t->alloc_young || t->promoted); @@ -561,38 +726,61 @@ void caml_memprof_update_clean_phase(void) } } } - trackst.callback = 0; +} + +void caml_memprof_update_clean_phase(void) +{ + entry_arrays_iter(entry_array_clean_phase, NULL); + callback_idx = 0; check_action_pending(); } -void caml_memprof_invert_tracked(void) +static void entry_array_invert(struct entry_array *ea, void *data) { uintnat i; - for (i = 0; i < trackst.len; i++) - caml_invert_root(trackst.entries[i].block, &trackst.entries[i].block); + (void)data; + for (i = 0; i < ea->len; i++) + caml_invert_root(ea->t[i].block, &ea->t[i].block); } -/**** Sampling procedures ****/ - -void caml_memprof_track_alloc_shr(value block) +void caml_memprof_invert_tracked(void) { - uintnat n_samples; - value callstack = 0; - CAMLassert(Is_in_heap(block)); + entry_arrays_iter(entry_array_invert, NULL); +} - /* This test also makes sure memprof is initialized. */ - if (lambda == 0 || caml_memprof_suspended) return; +/**** Sampling procedures ****/ - n_samples = mt_generate_binom(Whsize_val(block)); +static void maybe_track_block(value block, uintnat n_samples, + uintnat wosize, int src) +{ + value callstack; if (n_samples == 0) return; callstack = capture_callstack_postponed(); if (callstack == 0) return; - new_tracked(n_samples, Wosize_val(block), 0, 0, block, callstack); + new_tracked(n_samples, wosize, src, Is_young(block), block, callstack); check_action_pending(); } +void caml_memprof_track_alloc_shr(value block) +{ + CAMLassert(Is_in_heap(block)); + if (lambda == 0 || local->suspended) return; + + maybe_track_block(block, rand_binom(Whsize_val(block)), + Wosize_val(block), SRC_NORMAL); +} + +void caml_memprof_track_custom(value block, mlsize_t bytes) +{ + CAMLassert(Is_young(block) || Is_in_heap(block)); + if (lambda == 0 || local->suspended) return; + + maybe_track_block(block, rand_binom(Wsize_bsize(bytes)), + Wsize_bsize(bytes), SRC_CUSTOM); +} + /* Shifts the next sample in the minor heap by [n] words. Essentially, this tells the sampler to ignore the next [n] words of the minor heap. */ @@ -613,11 +801,11 @@ static void shift_sample(uintnat n) geometric distribution. */ void caml_memprof_renew_minor_sample(void) { - - if (lambda == 0) /* No trigger in the current minor heap. */ + if (lambda == 0 || local->suspended) + /* No trigger in the current minor heap. */ caml_memprof_young_trigger = Caml_state->young_alloc_start; else { - uintnat geom = mt_generate_geom(); + uintnat geom = rand_geom(); if (Caml_state->young_ptr - Caml_state->young_alloc_start < geom) /* No trigger in the current minor heap. */ caml_memprof_young_trigger = Caml_state->young_alloc_start; @@ -636,37 +824,23 @@ void caml_memprof_track_young(uintnat wosize, int from_caml, { uintnat whsize = Whsize_wosize(wosize); value callstack, res = Val_unit; - int alloc_idx = 0, i, allocs_sampled = 0, has_delete = 0; + int alloc_idx = 0, i, allocs_sampled = 0; intnat alloc_ofs, trigger_ofs; - /* usually, only one allocation is sampled, even when the block contains - multiple combined allocations. So, we delay allocating the full - sampled_allocs array until we discover we actually need two entries */ - uintnat first_idx, *idx_tab = &first_idx; double saved_lambda = lambda; - if (caml_memprof_suspended) { - caml_memprof_renew_minor_sample(); - return; - } - - /* If [lambda == 0], then [caml_memprof_young_trigger] should be + /* If this condition is false, then [caml_memprof_young_trigger] should be equal to [Caml_state->young_alloc_start]. But this function is only called with [Caml_state->young_alloc_start <= Caml_state->young_ptr < caml_memprof_young_trigger], which is contradictory. */ - CAMLassert(lambda > 0); + CAMLassert(!local->suspended && lambda > 0); if (!from_caml) { unsigned n_samples = 1 + - mt_generate_binom(caml_memprof_young_trigger - 1 - Caml_state->young_ptr); + rand_binom(caml_memprof_young_trigger - 1 - Caml_state->young_ptr); CAMLassert(encoded_alloc_lens == NULL); /* No Comballoc in C! */ caml_memprof_renew_minor_sample(); - - callstack = capture_callstack_postponed(); - if (callstack == 0) return; - - new_tracked(n_samples, wosize, - 0, 1, Val_hp(Caml_state->young_ptr), callstack); - check_action_pending(); + maybe_track_block(Val_hp(Caml_state->young_ptr), n_samples, + wosize, SRC_NORMAL); return; } @@ -685,8 +859,7 @@ void caml_memprof_track_young(uintnat wosize, int from_caml, /* Restore the minor heap in a valid state for calling the callbacks. We should not call the GC before these two instructions. */ Caml_state->young_ptr += whsize; - caml_memprof_renew_minor_sample(); - caml_memprof_suspended = 1; + caml_memprof_set_suspended(1); // This also updates the memprof trigger /* Perform the sampling of the block in the set of Comballoc'd blocks, insert them in the entries array, and run the @@ -698,126 +871,100 @@ void caml_memprof_track_young(uintnat wosize, int from_caml, alloc_ofs -= Whsize_wosize(alloc_wosz); while (alloc_ofs < trigger_ofs) { n_samples++; - trigger_ofs -= mt_generate_geom(); + trigger_ofs -= rand_geom(); } if (n_samples > 0) { - uintnat *idx_ptr, t_idx; + uintnat t_idx; + int stopped; callstack = capture_callstack(alloc_idx); - t_idx = new_tracked(n_samples, alloc_wosz, - 0, 1, Placeholder_offs(alloc_ofs), callstack); + t_idx = new_tracked(n_samples, alloc_wosz, SRC_NORMAL, 1, + Placeholder_offs(alloc_ofs), callstack); if (t_idx == Invalid_index) continue; - res = handle_entry_callbacks_exn(&t_idx); - if (t_idx == Invalid_index) { - has_delete = 1; + res = run_alloc_callback_exn(t_idx); + /* Has [caml_memprof_stop] been called during the callback? */ + stopped = local->entries.len == 0; + if (stopped) { + allocs_sampled = 0; if (saved_lambda != lambda) { /* [lambda] changed during the callback. We need to refresh [trigger_ofs]. */ saved_lambda = lambda; - trigger_ofs = lambda == 0. ? 0 : alloc_ofs - (mt_generate_geom() - 1); + trigger_ofs = lambda == 0. ? 0 : alloc_ofs - (rand_geom() - 1); } } if (Is_exception_result(res)) break; - if (t_idx == Invalid_index) continue; - - if (allocs_sampled == 1) { - /* Found a second sampled allocation! Allocate a buffer for them */ - idx_tab = caml_stat_alloc_noexc(sizeof(uintnat) * nallocs); - if (idx_tab == NULL) { - alloc_ofs = 0; - idx_tab = &first_idx; - break; - } - idx_tab[0] = first_idx; - if (idx_tab[0] != Invalid_index) - trackst.entries[idx_tab[0]].idx_ptr = &idx_tab[0]; - } - - /* Usually, trackst.entries[...].idx_ptr is owned by the thread - running a callback for the entry, if any. Here, we take ownership - of idx_ptr until the end of the function. - - This does not conflict with the usual use of idx_ptr because no - callbacks can run on this entry until the end of the function: - the allocation callback has already run and the other callbacks - do not run on Placeholder values */ - idx_ptr = &idx_tab[allocs_sampled]; - *idx_ptr = t_idx; - trackst.entries[*idx_ptr].idx_ptr = idx_ptr; - allocs_sampled++; + if (!stopped) allocs_sampled++; } } CAMLassert(alloc_ofs == 0 || Is_exception_result(res)); CAMLassert(allocs_sampled <= nallocs); - caml_memprof_suspended = 0; - check_action_pending(); - /* We need to call [check_action_pending] since we - reset [caml_memprof_suspended] to 0 (a GC collection may have - triggered some new callback). - - We need to make sure that the action pending flag is not set - systematically, which is to be expected, since [new_tracked] - created a new block without updating - [trackst.callback]. Fortunately, [handle_entry_callback_exn] - increments [trackst.callback] if it is equal to [t_idx]. */ - - /* This condition happens either in the case of an exception or if - one of the callbacks returned [None]. If these cases happen - frequently, then we need to call [flush_deleted] somewhere to - prevent a leak. */ - if (has_delete) - flush_deleted(); - - if (Is_exception_result(res)) { - for (i = 0; i < allocs_sampled; i++) - if (idx_tab[i] != Invalid_index) { - struct tracked* t = &trackst.entries[idx_tab[i]]; + + if (!Is_exception_result(res)) { + /* The callbacks did not raise. The allocation will take place. + We now restore the minor heap in the state needed by + [Alloc_small_aux]. */ + if (Caml_state->young_ptr - whsize < Caml_state->young_trigger) { + CAML_EV_COUNTER(EV_C_FORCE_MINOR_MEMPROF, 1); + caml_gc_dispatch(); + } + + /* Re-allocate the blocks in the minor heap. We should not call the + GC after this. */ + Caml_state->young_ptr -= whsize; + + /* Make sure this block is not going to be sampled again. */ + shift_sample(whsize); + } + + /* Since [local->entries] is local to the current thread, we know for + sure that the allocated entries are the [alloc_sampled] last entries of + [local->entries]. */ + + for (i = 0; i < allocs_sampled; i++) { + uintnat idx = local->entries.len-allocs_sampled+i; + if (local->entries.t[idx].deleted) continue; + if (realloc_entries(&entries_global, 1)) { + /* Transfer the entry to the global array. */ + struct tracked* t = &entries_global.t[entries_global.len]; + entries_global.len++; + *t = local->entries.t[idx]; + + if (Is_exception_result(res)) { /* The allocations are cancelled because of the exception, but this callback has already been called. We simulate a deallocation. */ t->block = Val_unit; t->deallocated = 1; - if (trackst.callback > idx_tab[i]) { - trackst.callback = idx_tab[i]; - check_action_pending(); - } + } else { + /* If the execution of the callback has succeeded, then we start the + tracking of this block.. + + Subtlety: we are actually writing [t->block] with an invalid + (uninitialized) block. This is correct because the allocation + and initialization happens right after returning from + [caml_memprof_track_young]. */ + t->block = Val_hp(Caml_state->young_ptr + Offs_placeholder(t->block)); + + /* We make sure that the action pending flag is not set + systematically, which is to be expected, since we created + a new block in the global entry array, but this new block + does not need promotion or deallocationc callback. */ + if (callback_idx == entries_global.len - 1) + callback_idx = entries_global.len; } - if (idx_tab != &first_idx) caml_stat_free(idx_tab); - caml_raise(Extract_exception(res)); - } - - /* We can now restore the minor heap in the state needed by - [Alloc_small_aux]. */ - if (Caml_state->young_ptr - whsize < Caml_state->young_trigger) { - CAML_EV_COUNTER(EV_C_FORCE_MINOR_MEMPROF, 1); - caml_gc_dispatch(); + } + mark_deleted(&local->entries, idx); } - /* Re-allocate the blocks in the minor heap. We should not call the - GC after this. */ - Caml_state->young_ptr -= whsize; + flush_deleted(&local->entries); + /* We need to reset the suspended flag *after* flushing + [local->entries] to make sure the floag is not set back to 1. */ + caml_memprof_set_suspended(0); - /* Make sure this block is not going to be sampled again. */ - shift_sample(whsize); - - for (i = 0; i < allocs_sampled; i++) { - if (idx_tab[i] != Invalid_index) { - /* If the execution of the callback has succeeded, then we start the - tracking of this block.. - - Subtlety: we are actually writing [t->block] with an invalid - (uninitialized) block. This is correct because the allocation - and initialization happens right after returning from - [caml_memprof_track_young]. */ - struct tracked *t = &trackst.entries[idx_tab[i]]; - t->block = Val_hp(Caml_state->young_ptr + Offs_placeholder(t->block)); - t->idx_ptr = NULL; - CAMLassert(t->cb_alloc_called); - if (idx_tab[i] < trackst.young) trackst.young = idx_tab[i]; - } - } - if (idx_tab != &first_idx) caml_stat_free(idx_tab); + if (Is_exception_result(res)) + caml_raise(Extract_exception(res)); /* /!\ Since the heap is in an invalid state before initialization, very little heap operations are allowed until then. */ @@ -825,17 +972,17 @@ void caml_memprof_track_young(uintnat wosize, int from_caml, return; } -void caml_memprof_track_interned(header_t* block, header_t* blockend) { +void caml_memprof_track_interned(header_t* block, header_t* blockend) +{ header_t *p; value callstack = 0; int is_young = Is_young(Val_hp(block)); - if (lambda == 0 || caml_memprof_suspended) - return; + if (lambda == 0 || local->suspended) return; p = block; while (1) { - uintnat next_sample = mt_generate_geom(); + uintnat next_sample = rand_geom(); header_t *next_sample_p, *next_p; if (next_sample > blockend - p) break; @@ -851,8 +998,8 @@ void caml_memprof_track_interned(header_t* block, header_t* blockend) { if (callstack == 0) callstack = capture_callstack_postponed(); if (callstack == 0) break; /* OOM */ - new_tracked(mt_generate_binom(next_p - next_sample_p) + 1, - Wosize_hp(p), 1, is_young, Val_hp(p), callstack); + new_tracked(rand_binom(next_p - next_sample_p) + 1, + Wosize_hp(p), SRC_MARSHAL, is_young, Val_hp(p), callstack); p = next_p; } check_action_pending(); @@ -860,30 +1007,10 @@ void caml_memprof_track_interned(header_t* block, header_t* blockend) { /**** Interface with the OCaml code. ****/ -static void caml_memprof_init(void) { - uintnat i; - +static void caml_memprof_init(void) +{ init = 1; - - mt_index = MT_STATE_SIZE; - mt_state[0] = 42; - for (i = 1; i < MT_STATE_SIZE; i++) - mt_state[i] = 0x6c078965 * (mt_state[i-1] ^ (mt_state[i-1] >> 30)) + i; -} - -void caml_memprof_shutdown(void) { - init = 0; - started = 0; - lambda = 0.; - caml_memprof_suspended = 0; - trackst.len = 0; - trackst.callback = trackst.young = trackst.delete = 0; - caml_stat_free(trackst.entries); - trackst.entries = NULL; - trackst.alloc_len = 0; - caml_stat_free(callstack_buffer); - callstack_buffer = NULL; - callstack_buffer_len = 0; + xoshiro_init(); } CAMLprim value caml_memprof_start(value lv, value szv, value tracker_param) @@ -903,7 +1030,10 @@ CAMLprim value caml_memprof_start(value lv, value szv, value tracker_param) lambda = l; if (l > 0) { one_log1m_lambda = l == 1 ? 0 : 1/caml_log1p(-l); - next_mt_generate_geom = mt_generate_geom(); + rand_pos = RAND_BLOCK_SIZE; + /* next_rand_geom can be zero if the next word is to be sampled, + but rand_geom always returns a value >= 1. Subtract 1 to correct. */ + next_rand_geom = rand_geom() - 1; } caml_memprof_renew_minor_sample(); @@ -917,28 +1047,37 @@ CAMLprim value caml_memprof_start(value lv, value szv, value tracker_param) CAMLreturn(Val_unit); } -CAMLprim value caml_memprof_stop(value unit) +static void empty_entry_array(struct entry_array *ea) { + if (ea != NULL) { + ea->alloc_len = ea->len = ea->young_idx = ea->delete_idx = 0; + caml_stat_free(ea->t); + ea->t = NULL; + } +} + +static void th_ctx_memprof_stop(struct caml_memprof_th_ctx* ctx, void* data) { - uintnat i; + (void)data; + if (ctx->callback_status != CB_IDLE) ctx->callback_status = CB_STOPPED; + empty_entry_array(&ctx->entries); +} +CAMLprim value caml_memprof_stop(value unit) +{ if (!started) caml_failwith("Gc.Memprof.stop: not started."); - /* This call to [caml_memprof_stop] will discard all the previously - tracked blocks. We try one last time to call the postponed - callbacks. */ - caml_raise_if_exception(caml_memprof_handle_postponed_exn()); - - /* Discard the tracked blocks. */ - for (i = 0; i < trackst.len; i++) - if (trackst.entries[i].idx_ptr != NULL) - *trackst.entries[i].idx_ptr = Invalid_index; - trackst.len = 0; - trackst.callback = trackst.young = trackst.delete = 0; - caml_stat_free(trackst.entries); - trackst.entries = NULL; - trackst.alloc_len = 0; + /* Discard the tracked blocks in the global entries array. */ + empty_entry_array(&entries_global); + + /* Discard the tracked blocks in the local entries array, + and set [callback_status] to [CB_STOPPED]. */ + caml_memprof_th_ctx_iter_hook(th_ctx_memprof_stop, NULL); + + callback_idx = 0; lambda = 0; + // Reset the memprof trigger in order to make sure we won't enter + // [caml_memprof_track_young]. caml_memprof_renew_minor_sample(); started = 0; @@ -953,26 +1092,45 @@ CAMLprim value caml_memprof_stop(value unit) /**** Interface with systhread. ****/ -void caml_memprof_init_th_ctx(struct caml_memprof_th_ctx* ctx) { +static void th_ctx_iter_default(th_ctx_action f, void* data) { + f(local, data); +} + +CAMLexport void (*caml_memprof_th_ctx_iter_hook)(th_ctx_action, void*) + = th_ctx_iter_default; + +CAMLexport struct caml_memprof_th_ctx* caml_memprof_new_th_ctx() +{ + struct caml_memprof_th_ctx* ctx = + caml_stat_alloc(sizeof(struct caml_memprof_th_ctx)); ctx->suspended = 0; - ctx->callback_running = 0; + ctx->callback_status = CB_IDLE; + ctx->entries.t = NULL; + ctx->entries.min_alloc_len = MIN_ENTRIES_LOCAL_ALLOC_LEN; + ctx->entries.alloc_len = ctx->entries.len = 0; + ctx->entries.young_idx = ctx->entries.delete_idx = 0; + return ctx; } -void caml_memprof_stop_th_ctx(struct caml_memprof_th_ctx* ctx) { - /* Make sure that no memprof callback is being executed in this - thread. If so, memprof data structures may have pointers to the - thread's stack. */ - if(ctx->callback_running) - caml_fatal_error("Thread.exit called from a memprof callback."); +CAMLexport void caml_memprof_delete_th_ctx(struct caml_memprof_th_ctx* ctx) +{ + if (ctx->callback_status >= 0) + /* A callback is running in this thread from the global entries + array. We delete the corresponding entry. */ + mark_deleted(&entries_global, ctx->callback_status); + if (ctx == local) local = NULL; + caml_stat_free(ctx->entries.t); + if (ctx != &caml_memprof_main_ctx) caml_stat_free(ctx); } -void caml_memprof_save_th_ctx(struct caml_memprof_th_ctx* ctx) { - ctx->suspended = caml_memprof_suspended; - ctx->callback_running = callback_running; +CAMLexport void caml_memprof_leave_thread(void) +{ + local = NULL; } -void caml_memprof_restore_th_ctx(const struct caml_memprof_th_ctx* ctx) { - caml_memprof_suspended = ctx->suspended; - callback_running = ctx->callback_running; - check_action_pending(); +CAMLexport void caml_memprof_enter_thread(struct caml_memprof_th_ctx* ctx) +{ + CAMLassert(local == NULL); + local = ctx; + caml_memprof_set_suspended(ctx->suspended); } diff --git a/runtime/meta.c b/runtime/meta.c index 3cf1222b..cbacc9a0 100644 --- a/runtime/meta.c +++ b/runtime/meta.c @@ -120,13 +120,13 @@ CAMLprim value caml_reify_bytecode(value ls_prog, #ifdef THREADED_CODE caml_thread_code((code_t) prog, len); #endif - caml_prepare_bytecode((code_t) prog, len); /* Notify debugger after fragment gets added and reified. */ caml_debugger(CODE_LOADED, Val_long(fragnum)); - clos = caml_alloc_small (1, Closure_tag); + clos = caml_alloc_small (2, Closure_tag); Code_val(clos) = (code_t) prog; + Closinfo_val(clos) = Make_closinfo(0, 2); bytecode = caml_alloc_small (2, Abstract_tag); Bytecode_val(bytecode)->prog = prog; Bytecode_val(bytecode)->len = len; @@ -137,17 +137,14 @@ CAMLprim value caml_reify_bytecode(value ls_prog, } /* signal to the interpreter machinery that a bytecode is no more - needed (before freeing it) - this might be useful for a JIT - implementation */ + needed (before freeing it) */ CAMLprim value caml_static_release_bytecode(value bc) { code_t prog; - asize_t len; struct code_fragment *cf; prog = Bytecode_val(bc)->prog; - len = Bytecode_val(bc)->len; caml_remove_debug_info(prog); cf = caml_find_code_fragment_by_pc((char *) prog); @@ -158,11 +155,6 @@ CAMLprim value caml_static_release_bytecode(value bc) caml_remove_code_fragment(cf); -#ifndef NATIVE_CODE - caml_release_bytecode(prog, len); -#else - caml_failwith("Meta.static_release_bytecode impossible with native code"); -#endif caml_stat_free(prog); return Val_unit; } @@ -231,7 +223,7 @@ CAMLprim value caml_invoke_traced_function(value codeptr, value env, value arg) Caml_state->extern_sp -= 4; nsp = Caml_state->extern_sp; for (i = 0; i < 7; i++) nsp[i] = osp[i]; - nsp[7] = codeptr; + nsp[7] = (value) Nativeint_val(codeptr); nsp[8] = env; nsp[9] = Val_int(0); nsp[10] = arg; diff --git a/runtime/minor_gc.c b/runtime/minor_gc.c index a3aeec4a..9155a6fd 100644 --- a/runtime/minor_gc.c +++ b/runtime/minor_gc.c @@ -31,9 +31,6 @@ #include "caml/signals.h" #include "caml/weak.h" #include "caml/memprof.h" -#ifdef WITH_SPACETIME -#include "caml/spacetime.h" -#endif #include "caml/eventlog.h" /* Pointers into the minor heap. @@ -284,9 +281,9 @@ Caml_inline int ephe_check_alive_data(struct caml_ephe_ref_elt *re){ for (i = CAML_EPHE_FIRST_KEY; i < Wosize_val(re->ephe); i++){ child = Field (re->ephe, i); if(child != caml_ephe_none - && Is_block (child) && Is_young (child) - && Hd_val (child) != 0){ /* Value not copied to major heap */ - return 0; + && Is_block (child) && Is_young (child)) { + if(Tag_val(child) == Infix_tag) child -= Infix_offset_val(child); + if(Hd_val (child) != 0) return 0; /* Value not copied to major heap */ } } return 1; @@ -301,7 +298,10 @@ void caml_oldify_mopup (void) value v, new_v, f; mlsize_t i; struct caml_ephe_ref_elt *re; - int redo = 0; + int redo; + + again: + redo = 0; while (oldify_todo_list != 0){ v = oldify_todo_list; /* Get the head. */ @@ -329,10 +329,12 @@ void caml_oldify_mopup (void) re < Caml_state->ephe_ref_table->ptr; re++){ /* look only at ephemeron with data in the minor heap */ if (re->offset == 1){ - value *data = &Field(re->ephe,1); - if (*data != caml_ephe_none && Is_block (*data) && Is_young (*data)){ - if (Hd_val (*data) == 0){ /* Value copied to major heap */ - *data = Field (*data, 0); + value *data = &Field(re->ephe,1), v = *data; + if (v != caml_ephe_none && Is_block (v) && Is_young (v)){ + mlsize_t offs = Tag_val(v) == Infix_tag ? Infix_offset_val(v) : 0; + v -= offs; + if (Hd_val (v) == 0){ /* Value copied to major heap */ + *data = Field (v, 0) + offs; } else { if (ephe_check_alive_data(re)){ caml_oldify_one(*data,data); @@ -343,7 +345,7 @@ void caml_oldify_mopup (void) } } - if (redo) caml_oldify_mopup (); + if (redo) goto again; } /* Make sure the minor heap is empty by performing a minor collection @@ -379,10 +381,12 @@ void caml_empty_minor_heap (void) re < Caml_state->ephe_ref_table->ptr; re++){ if(re->offset < Wosize_val(re->ephe)){ /* If it is not the case, the ephemeron has been truncated */ - value *key = &Field(re->ephe,re->offset); - if (*key != caml_ephe_none && Is_block (*key) && Is_young (*key)){ - if (Hd_val (*key) == 0){ /* Value copied to major heap */ - *key = Field (*key, 0); + value *key = &Field(re->ephe,re->offset), v = *key; + if (v != caml_ephe_none && Is_block (v) && Is_young (v)){ + mlsize_t offs = Tag_val (v) == Infix_tag ? Infix_offset_val (v) : 0; + v -= offs; + if (Hd_val (v) == 0){ /* Value copied to major heap */ + *key = Field (v, 0) + offs; }else{ /* Value not copied so it's dead */ CAMLassert(!ephe_check_alive_data(re)); *key = caml_ephe_none; @@ -450,41 +454,45 @@ void caml_empty_minor_heap (void) extern uintnat caml_instr_alloc_jump; #endif /*CAML_INSTR*/ -/* Do a minor collection or a slice of major collection, call finalisation - functions, etc. +/* Do a minor collection or a slice of major collection, etc. Leave enough room in the minor heap to allocate at least one object. Guaranteed not to call any OCaml callback. */ -CAMLexport void caml_gc_dispatch (void) +void caml_gc_dispatch (void) { - value *trigger = Caml_state->young_trigger; /* save old value of trigger */ - CAML_EVENTLOG_DO({ CAML_EV_COUNTER(EV_C_ALLOC_JUMP, caml_instr_alloc_jump); caml_instr_alloc_jump = 0; }); - if (trigger == Caml_state->young_alloc_start - || Caml_state->requested_minor_gc) { + if (Caml_state->young_trigger == Caml_state->young_alloc_start){ /* The minor heap is full, we must do a minor collection. */ + Caml_state->requested_minor_gc = 1; + }else{ + /* The minor heap is half-full, do a major GC slice. */ + Caml_state->requested_major_slice = 1; + } + if (caml_gc_phase == Phase_idle){ + /* The major GC needs an empty minor heap in order to start a new cycle. + If a major slice was requested, we need to do a minor collection + before we can do the major slice that starts a new major GC cycle. + If a minor collection was requested, we take the opportunity to start + a new major GC cycle. + In either case, we have to do a minor cycle followed by a major slice. + */ + Caml_state->requested_minor_gc = 1; + Caml_state->requested_major_slice = 1; + } + if (Caml_state->requested_minor_gc) { /* reset the pointers first because the end hooks might allocate */ CAML_EV_BEGIN(EV_MINOR); Caml_state->requested_minor_gc = 0; Caml_state->young_trigger = Caml_state->young_alloc_mid; caml_update_young_limit(); caml_empty_minor_heap (); - /* The minor heap is empty, we can start a major collection. */ CAML_EV_END(EV_MINOR); - if (caml_gc_phase == Phase_idle) - { - CAML_EV_BEGIN(EV_MAJOR); - caml_major_collection_slice (-1); - CAML_EV_END(EV_MAJOR); - } } - if (trigger != Caml_state->young_alloc_start - || Caml_state->requested_major_slice) { - /* The minor heap is half-full, do a major GC slice. */ + if (Caml_state->requested_major_slice) { Caml_state->requested_major_slice = 0; Caml_state->young_trigger = Caml_state->young_alloc_start; caml_update_young_limit(); @@ -529,11 +537,6 @@ void caml_alloc_small_dispatch (intnat wosize, int flags, callbacks. */ CAML_EV_COUNTER (EV_C_FORCE_MINOR_ALLOC_SMALL, 1); caml_gc_dispatch (); -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - if (caml_young_ptr == caml_young_alloc_end) { - caml_spacetime_automatic_snapshot(); - } -#endif } /* Re-do the allocation: we now have enough space in the minor heap. */ diff --git a/runtime/misc.c b/runtime/misc.c index 397bd7cf..e817a6cc 100644 --- a/runtime/misc.c +++ b/runtime/misc.c @@ -93,9 +93,6 @@ CAMLexport void caml_fatal_error (char *msg, ...) abort(); } -/* If you change the caml_ext_table* functions, also update - runtime/spacetime_nat.c:find_trie_node_from_libunwind. */ - void caml_ext_table_init(struct ext_table * tbl, int init_capa) { tbl->size = 0; diff --git a/runtime/obj.c b/runtime/obj.c index 20fe1e8e..45304155 100644 --- a/runtime/obj.c +++ b/runtime/obj.c @@ -29,30 +29,6 @@ #include "caml/mlvalues.h" #include "caml/prims.h" #include "caml/signals.h" -#include "caml/spacetime.h" - -/* [size] is a value encoding a number of bytes */ -CAMLprim value caml_static_alloc(value size) -{ - return (value) caml_stat_alloc((asize_t) Long_val(size)); -} - -CAMLprim value caml_static_free(value blk) -{ - caml_stat_free((void *) blk); - return Val_unit; -} - -CAMLprim value caml_static_resize(value blk, value new_size) -{ - return (value) caml_stat_resize((char *) blk, (asize_t) Long_val(new_size)); -} - -/* unused since GPR#427 */ -CAMLprim value caml_obj_is_block(value arg) -{ - return Val_bool(Is_block(arg)); -} CAMLprim value caml_obj_tag(value arg) { @@ -73,6 +49,18 @@ CAMLprim value caml_obj_set_tag (value arg, value new_tag) return Val_unit; } +CAMLprim value caml_obj_raw_field(value arg, value pos) +{ + /* Represent field contents as a native integer */ + return caml_copy_nativeint((intnat) Field(arg, Long_val(pos))); +} + +CAMLprim value caml_obj_set_raw_field(value arg, value pos, value bits) +{ + Field(arg, Long_val(pos)) = (value) Nativeint_val(bits); + return Val_unit; +} + CAMLprim value caml_obj_make_forward (value blk, value fwd) { caml_modify(&Field(blk, 0), fwd); @@ -84,20 +72,66 @@ CAMLprim value caml_obj_make_forward (value blk, value fwd) CAMLprim value caml_obj_block(value tag, value size) { value res; - mlsize_t sz, i; + mlsize_t sz; tag_t tg; sz = Long_val(size); tg = Long_val(tag); - if (sz == 0) return Atom(tg); - res = caml_alloc(sz, tg); - for (i = 0; i < sz; i++) - Field(res, i) = Val_long(0); + + /* When [tg < No_scan_tag], [caml_alloc] returns an object whose fields are + * initialised to [Val_unit]. Otherwise, the fields are uninitialised. We aim + * to avoid inconsistent states in other cases, on a best-effort basis -- + * by default there is no initialization. */ + switch (tg) { + default: { + res = caml_alloc(sz, tg); + break; + } + case Abstract_tag: + case Double_tag: + case Double_array_tag: { + /* In these cases, the initial content is irrelevant, + no specific initialization needed. */ + res = caml_alloc(sz, tg); + break; + } + case Closure_tag: { + /* [Closure_tag] is below [no_scan_tag], but closures have more + structure with in particular a "closure information" that + indicates where the environment starts. We initialize this to + a sane value, as it may be accessed by runtime functions. */ + /* Closinfo_val is the second field, so we need size at least 2 */ + if (sz < 2) caml_invalid_argument ("Obj.new_block"); + res = caml_alloc(sz, tg); + Closinfo_val(res) = Make_closinfo(0, 2); /* does not allocate */ + break; + } + case String_tag: { + /* For [String_tag], the initial content does not matter. However, + the length of the string is encoded using the last byte of the + block. For this reason, the blocks with [String_tag] cannot be + of size [0]. We initialise the last byte to [0] such that the + length returned by [String.length] and [Bytes.length] is + a non-negative number. */ + if (sz == 0) caml_invalid_argument ("Obj.new_block"); + res = caml_alloc(sz, tg); + Field (res, sz - 1) = 0; + break; + } + case Custom_tag: { + /* It is difficult to correctly use custom objects allocated + through [Obj.new_block], so we disallow it completely. The + first field of a custom object must contain a valid pointer to + a block of custom operations. Without initialisation, hashing, + finalising or serialising this custom object will lead to + crashes. See #9513 for more details. */ + caml_invalid_argument ("Obj.new_block"); + } + } return res; } -/* Spacetime profiling assumes that this function is only called from OCaml. */ CAMLprim value caml_obj_with_tag(value new_tag_v, value arg) { CAMLparam2 (new_tag_v, arg); @@ -112,20 +146,20 @@ CAMLprim value caml_obj_with_tag(value new_tag_v, value arg) res = caml_alloc(sz, tg); memcpy(Bp_val(res), Bp_val(arg), sz * sizeof(value)); } else if (sz <= Max_young_wosize) { - uintnat profinfo; - Get_my_profinfo_with_cached_backtrace(profinfo, sz); - res = caml_alloc_small_with_my_or_given_profinfo(sz, tg, profinfo); + res = caml_alloc_small(sz, tg); for (i = 0; i < sz; i++) Field(res, i) = Field(arg, i); } else { res = caml_alloc_shr(sz, tg); + /* It is safe to use [caml_initialize] even if [tag == Closure_tag] + and some of the "values" being copied are actually code pointers. + That's because the new "value" does not point to the minor heap. */ for (i = 0; i < sz; i++) caml_initialize(&Field(res, i), Field(arg, i)); - // Give gc a chance to run, and run memprof callbacks + /* Give gc a chance to run, and run memprof callbacks */ caml_process_pending_actions(); } CAMLreturn (res); } -/* Spacetime profiling assumes that this function is only called from OCaml. */ CAMLprim value caml_obj_dup(value arg) { return caml_obj_with_tag(Val_long(Tag_val(arg)), arg); @@ -189,21 +223,11 @@ CAMLprim value caml_obj_add_offset (value v, value offset) return v + (unsigned long) Int32_val (offset); } -/* The following functions are used in stdlib/lazy.ml. - They are not written in OCaml because they must be atomic with respect +/* The following function is used in stdlib/lazy.ml. + It is not written in OCaml because it must be atomic with respect to the GC. */ -CAMLprim value caml_lazy_follow_forward (value v) -{ - if (Is_block (v) && Is_in_value_area(v) - && Tag_val (v) == Forward_tag){ - return Forward_val (v); - }else{ - return v; - } -} - CAMLprim value caml_lazy_make_forward (value v) { CAMLparam1 (v); @@ -231,44 +255,6 @@ CAMLprim value caml_get_public_method (value obj, value tag) return (tag == Field(meths,li) ? Field (meths, li-1) : 0); } -/* these two functions might be useful to an hypothetical JIT */ - -#ifdef CAML_JIT -#ifdef NATIVE_CODE -#define MARK 1 -#else -#define MARK 0 -#endif -value caml_cache_public_method (value meths, value tag, value *cache) -{ - int li = 3, hi = Field(meths,0), mi; - while (li < hi) { - mi = ((li+hi) >> 1) | 1; - if (tag < Field(meths,mi)) hi = mi-2; - else li = mi; - } - *cache = (li-3)*sizeof(value) + MARK; - return Field (meths, li-1); -} - -value caml_cache_public_method2 (value *meths, value tag, value *cache) -{ - value ofs = *cache & meths[1]; - if (*(value*)(((char*)(meths+3)) + ofs - MARK) == tag) - return *(value*)(((char*)(meths+2)) + ofs - MARK); - { - int li = 3, hi = meths[0], mi; - while (li < hi) { - mi = ((li+hi) >> 1) | 1; - if (tag < meths[mi]) hi = mi-2; - else li = mi; - } - *cache = (li-3)*sizeof(value) + MARK; - return meths[li-1]; - } -} -#endif /*CAML_JIT*/ - static value oo_last_id = Val_int(0); CAMLprim value caml_set_oo_id (value obj) { @@ -295,113 +281,3 @@ struct queue_chunk { struct queue_chunk *next; value entries[ENTRIES_PER_QUEUE_CHUNK]; }; - - -CAMLprim value caml_obj_reachable_words(value v) -{ - static struct queue_chunk first_chunk; - struct queue_chunk *read_chunk, *write_chunk; - int write_pos, read_pos, i; - - intnat size = 0; - header_t hd; - mlsize_t sz; - - if (Is_long(v) || !Is_in_heap_or_young(v)) return Val_int(0); - if (Tag_hd(Hd_val(v)) == Infix_tag) v -= Infix_offset_hd(Hd_val(v)); - hd = Hd_val(v); - sz = Wosize_hd(hd); - - read_chunk = write_chunk = &first_chunk; - read_pos = 0; - write_pos = 1; - write_chunk->entries[0] = v | Colornum_hd(hd); - Hd_val(v) = Bluehd_hd(hd); - - /* We maintain a queue of "interesting" blocks that have been seen. - An interesting block is a block in the heap which does not - represent an infix pointer. Infix pointers are normalized to the - beginning of their block. Blocks in the static data area are excluded. - - The function maintains a queue of block pointers. Concretely, - the queue is stored as a linked list of chunks, each chunk - holding a number of pointers to interesting blocks. Initially, - it contains only the "root" value. The first chunk of the queue - is allocated statically. More chunks can be allocated as needed - and released before this function exits. - - When a block is inserted in the queue, it is marked as blue. - This mark is used to avoid a second visit of the same block. - The real color is stored in the last 2 bits of the pointer in the - queue. (Same technique as in extern.c.) - - Note: we make the assumption that there is no pointer - from the static data area to the heap. - */ - - /* First pass: mark accessible blocks and compute their total size */ - while (read_pos != write_pos || read_chunk != write_chunk) { - /* Pop the next element from the queue */ - if (read_pos == ENTRIES_PER_QUEUE_CHUNK) { - read_pos = 0; - read_chunk = read_chunk->next; - } - v = read_chunk->entries[read_pos++] & ~3; - - hd = Hd_val(v); - sz = Wosize_hd(hd); - - size += Whsize_wosize(sz); - - if (Tag_hd(hd) < No_scan_tag) { - /* Push the interesting fields on the queue */ - for (i = 0; i < sz; i++) { - value v2 = Field(v, i); - if (Is_block(v2) && Is_in_heap_or_young(v2)) { - if (Tag_hd(Hd_val(v2)) == Infix_tag){ - v2 -= Infix_offset_hd(Hd_val(v2)); - } - hd = Hd_val(v2); - if (Color_hd(hd) != Caml_blue) { - if (write_pos == ENTRIES_PER_QUEUE_CHUNK) { - struct queue_chunk *new_chunk = - malloc(sizeof(struct queue_chunk)); - if (new_chunk == NULL) { - size = (-1); - goto release; - } - write_chunk->next = new_chunk; - write_pos = 0; - write_chunk = new_chunk; - } - write_chunk->entries[write_pos++] = v2 | Colornum_hd(hd); - Hd_val(v2) = Bluehd_hd(hd); - } - } - } - } - } - - /* Second pass: restore colors and free extra queue chunks */ - release: - read_pos = 0; - read_chunk = &first_chunk; - while (read_pos != write_pos || read_chunk != write_chunk) { - color_t colornum; - if (read_pos == ENTRIES_PER_QUEUE_CHUNK) { - struct queue_chunk *prev = read_chunk; - read_pos = 0; - read_chunk = read_chunk->next; - if (prev != &first_chunk) free(prev); - } - v = read_chunk->entries[read_pos++]; - colornum = v & 3; - v &= ~3; - Hd_val(v) = Coloredhd_hd(Hd_val(v), colornum); - } - if (read_chunk != &first_chunk) free(read_chunk); - - if (size < 0) - caml_raise_out_of_memory(); - return Val_int(size); -} diff --git a/runtime/printexc.c b/runtime/printexc.c index e18beda3..2828fdbc 100644 --- a/runtime/printexc.c +++ b/runtime/printexc.c @@ -146,7 +146,7 @@ void caml_fatal_uncaught_exception(value exn) memprof's callback could raise an exception while [handle_uncaught_exception] is running, so that the printing of the exception fails. */ - caml_memprof_suspended = 1; + caml_memprof_set_suspended(1); if (handle_uncaught_exception != NULL) /* [Printexc.handle_uncaught_exception] does not raise exception. */ diff --git a/runtime/riscv.S b/runtime/riscv.S index 48e690e4..d3a5a794 100644 --- a/runtime/riscv.S +++ b/runtime/riscv.S @@ -63,9 +63,8 @@ FUNCTION(caml_call_gc) /* Record lowest stack address */ STORE sp, Caml_state(bottom_of_stack) /* Set up stack space, saving return address */ - /* (1 reg for RA, 1 reg for FP, 21 allocatable int regs, + /* (1 reg for RA, 1 reg for FP, 22 allocatable int regs, 20 caller-save float regs) * 8 */ - /* + 1 for alignment */ addi sp, sp, -0x160 STORE ra, 0x8(sp) STORE s0, 0x0(sp) @@ -92,26 +91,26 @@ FUNCTION(caml_call_gc) STORE t4, 0xa0(sp) STORE t5, 0xa8(sp) STORE t6, 0xb0(sp) + STORE t0, 0xb8(sp) /* Save caller-save floating-point registers on the stack (callee-saves are preserved by caml_garbage_collection) */ - fsd ft0, 0xb8(sp) - fsd ft1, 0xc0(sp) - fsd ft2, 0xc8(sp) - fsd ft3, 0xd0(sp) - fsd ft4, 0xd8(sp) - fsd ft5, 0xe0(sp) - fsd ft6, 0xe8(sp) - fsd ft7, 0xf0(sp) - fsd fa0, 0xf8(sp) - fsd fa1, 0x100(sp) - fsd fa2, 0x108(sp) - fsd fa3, 0x110(sp) - fsd fa4, 0x118(sp) - fsd fa5, 0x120(sp) - fsd fa6, 0x128(sp) - fsd fa7, 0x130(sp) - fsd ft8, 0x138(sp) - fsd ft9, 0x140(sp) + fsd ft0, 0xc0(sp) + fsd ft1, 0xc8(sp) + fsd ft2, 0xd0(sp) + fsd ft3, 0xd8(sp) + fsd ft4, 0xe0(sp) + fsd ft5, 0xe8(sp) + fsd ft6, 0xf0(sp) + fsd ft7, 0xf8(sp) + fsd fa0, 0x100(sp) + fsd fa1, 0x108(sp) + fsd fa2, 0x110(sp) + fsd fa3, 0x118(sp) + fsd fa4, 0x120(sp) + fsd fa5, 0x128(sp) + fsd fa6, 0x130(sp) + fsd fa7, 0x138(sp) + fsd ft8, 0x140(sp) fsd ft9, 0x148(sp) fsd ft10, 0x150(sp) fsd ft11, 0x158(sp) @@ -146,24 +145,24 @@ FUNCTION(caml_call_gc) LOAD t4, 0xa0(sp) LOAD t5, 0xa8(sp) LOAD t6, 0xb0(sp) - fld ft0, 0xb8(sp) - fld ft1, 0xc0(sp) - fld ft2, 0xc8(sp) - fld ft3, 0xd0(sp) - fld ft4, 0xd8(sp) - fld ft5, 0xe0(sp) - fld ft6, 0xe8(sp) - fld ft7, 0xf0(sp) - fld fa0, 0xf8(sp) - fld fa1, 0x100(sp) - fld fa2, 0x108(sp) - fld fa3, 0x110(sp) - fld fa4, 0x118(sp) - fld fa5, 0x120(sp) - fld fa6, 0x128(sp) - fld fa7, 0x130(sp) - fld ft8, 0x138(sp) - fld ft9, 0x140(sp) + LOAD t0, 0xb8(sp) + fld ft0, 0xc0(sp) + fld ft1, 0xc8(sp) + fld ft2, 0xd0(sp) + fld ft3, 0xd8(sp) + fld ft4, 0xe0(sp) + fld ft5, 0xe8(sp) + fld ft6, 0xf0(sp) + fld ft7, 0xf8(sp) + fld fa0, 0x100(sp) + fld fa1, 0x108(sp) + fld fa2, 0x110(sp) + fld fa3, 0x118(sp) + fld fa4, 0x120(sp) + fld fa5, 0x128(sp) + fld fa6, 0x130(sp) + fld fa7, 0x138(sp) + fld ft8, 0x140(sp) fld ft9, 0x148(sp) fld ft10, 0x150(sp) fld ft11, 0x158(sp) diff --git a/runtime/roots_byt.c b/runtime/roots_byt.c index bd549f14..9d65e080 100644 --- a/runtime/roots_byt.c +++ b/runtime/roots_byt.c @@ -17,6 +17,7 @@ /* To walk the memory roots for garbage collection */ +#include "caml/codefrag.h" #include "caml/finalise.h" #include "caml/globroots.h" #include "caml/major_gc.h" @@ -42,6 +43,9 @@ void caml_oldify_local_roots (void) intnat i, j; /* The stack */ + /* [caml_oldify_one] acts only on pointers into the minor heap. + So, it is safe to pass code pointers to [caml_oldify_one], + even in no-naked-pointers mode */ for (sp = Caml_state->extern_sp; sp < Caml_state->stack_high; sp++) { caml_oldify_one (*sp, sp); } @@ -88,8 +92,8 @@ void caml_do_roots (scanning_action f, int do_globals) CAML_EV_END(EV_MAJOR_ROOTS_GLOBAL); /* The stack and the local C roots */ CAML_EV_BEGIN(EV_MAJOR_ROOTS_LOCAL); - caml_do_local_roots(f, Caml_state->extern_sp, Caml_state->stack_high, - Caml_state->local_roots); + caml_do_local_roots_byt(f, Caml_state->extern_sp, Caml_state->stack_high, + Caml_state->local_roots); CAML_EV_END(EV_MAJOR_ROOTS_LOCAL); /* Global C roots */ CAML_EV_BEGIN(EV_MAJOR_ROOTS_C); @@ -109,16 +113,25 @@ void caml_do_roots (scanning_action f, int do_globals) CAML_EV_END(EV_MAJOR_ROOTS_HOOK); } -CAMLexport void caml_do_local_roots (scanning_action f, value *stack_low, - value *stack_high, - struct caml__roots_block *local_roots) +CAMLexport void caml_do_local_roots_byt (scanning_action f, value *stack_low, + value *stack_high, + struct caml__roots_block *local_roots) { register value * sp; struct caml__roots_block *lr; int i, j; for (sp = stack_low; sp < stack_high; sp++) { +#ifdef NO_NAKED_POINTERS + /* Code pointers inside the stack are naked pointers. + We must avoid passing them to function [f]. */ + value v = *sp; + if (Is_block(v) && caml_find_code_fragment_by_pc((char *) v) == NULL) { + f(v, sp); + } +#else f (*sp, sp); +#endif } for (lr = local_roots; lr != NULL; lr = lr->next) { for (i = 0; i < lr->ntables; i++){ diff --git a/runtime/roots_nat.c b/runtime/roots_nat.c index ec66e2db..aba07061 100644 --- a/runtime/roots_nat.c +++ b/runtime/roots_nat.c @@ -423,9 +423,9 @@ void caml_do_roots (scanning_action f, int do_globals) CAML_EV_END(EV_MAJOR_ROOTS_DYNAMIC_GLOBAL); /* The stack and local roots */ CAML_EV_BEGIN(EV_MAJOR_ROOTS_LOCAL); - caml_do_local_roots(f, Caml_state->bottom_of_stack, - Caml_state->last_return_address, Caml_state->gc_regs, - Caml_state->local_roots); + caml_do_local_roots_nat(f, Caml_state->bottom_of_stack, + Caml_state->last_return_address, Caml_state->gc_regs, + Caml_state->local_roots); CAML_EV_END(EV_MAJOR_ROOTS_LOCAL); /* Global C roots */ CAML_EV_BEGIN(EV_MAJOR_ROOTS_C); @@ -445,9 +445,9 @@ void caml_do_roots (scanning_action f, int do_globals) CAML_EV_END(EV_MAJOR_ROOTS_HOOK); } -void caml_do_local_roots(scanning_action f, char * bottom_of_stack, - uintnat last_retaddr, value * gc_regs, - struct caml__roots_block * local_roots) +void caml_do_local_roots_nat(scanning_action f, char * bottom_of_stack, + uintnat last_retaddr, value * gc_regs, + struct caml__roots_block * local_roots) { char * sp; uintnat retaddr; diff --git a/runtime/signals.c b/runtime/signals.c index 8f60e5a5..7cf746f2 100644 --- a/runtime/signals.c +++ b/runtime/signals.c @@ -33,10 +33,6 @@ #include "caml/memprof.h" #include "caml/finalise.h" -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) -#include "caml/spacetime.h" -#endif - #ifndef NSIG #define NSIG 64 #endif @@ -62,12 +58,20 @@ CAMLexport int (*caml_sigmask_hook)(int, const sigset_t *, sigset_t *) = sigprocmask_wrapper; #endif +static int check_for_pending_signals(void) +{ + int i; + for (i = 0; i < NSIG; i++) { + if (caml_pending_signals[i]) return 1; + } + return 0; +} + /* Execute all pending signals */ -value caml_process_pending_signals_exn(void) +CAMLexport value caml_process_pending_signals_exn(void) { int i; - int really_pending; #ifdef POSIX_SIGNALS sigset_t set; #endif @@ -78,13 +82,7 @@ value caml_process_pending_signals_exn(void) /* Check that there is indeed a pending signal before issuing the syscall in [caml_sigmask_hook]. */ - really_pending = 0; - for (i = 0; i < NSIG; i++) - if (caml_pending_signals[i]) { - really_pending = 1; - break; - } - if(!really_pending) + if (!check_for_pending_signals()) return Val_unit; #ifdef POSIX_SIGNALS @@ -127,7 +125,8 @@ void caml_set_action_pending(void) caml_garbage_collection and caml_alloc_small_dispatch. */ -CAMLno_tsan void caml_record_signal(int signal_number) +CAMLno_tsan +CAMLexport void caml_record_signal(int signal_number) { caml_pending_signals[signal_number] = 1; signals_are_pending = 1; @@ -136,33 +135,18 @@ CAMLno_tsan void caml_record_signal(int signal_number) /* Management of blocking sections. */ -static intnat volatile caml_async_signal_mode = 0; - static void caml_enter_blocking_section_default(void) { - CAMLassert (caml_async_signal_mode == 0); - caml_async_signal_mode = 1; } static void caml_leave_blocking_section_default(void) { - CAMLassert (caml_async_signal_mode == 1); - caml_async_signal_mode = 0; -} - -static int caml_try_leave_blocking_section_default(void) -{ - intnat res; - Read_and_clear(res, caml_async_signal_mode); - return res; } CAMLexport void (*caml_enter_blocking_section_hook)(void) = caml_enter_blocking_section_default; CAMLexport void (*caml_leave_blocking_section_hook)(void) = caml_leave_blocking_section_default; -CAMLexport int (*caml_try_leave_blocking_section_hook)(void) = - caml_try_leave_blocking_section_default; CAMLno_tsan /* The read of [caml_something_to_do] is not synchronized. */ CAMLexport void caml_enter_blocking_section(void) @@ -178,6 +162,11 @@ CAMLexport void caml_enter_blocking_section(void) } } +CAMLexport void caml_enter_blocking_section_no_pending(void) +{ + caml_enter_blocking_section_hook (); +} + CAMLexport void caml_leave_blocking_section(void) { int saved_errno; @@ -197,8 +186,10 @@ CAMLexport void caml_leave_blocking_section(void) examined by [caml_process_pending_signals_exn], then [signals_are_pending] is 0 but the signal needs to be handled at this point. */ - signals_are_pending = 1; - caml_raise_if_exception(caml_process_pending_signals_exn()); + if (check_for_pending_signals()) { + signals_are_pending = 1; + caml_set_action_pending(); + } errno = saved_errno; } @@ -211,9 +202,6 @@ value caml_execute_signal_exn(int signal_number, int in_signal_handler) { value res; value handler; -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - void* saved_spacetime_trie_node_ptr; -#endif #ifdef POSIX_SIGNALS sigset_t nsigs, sigs; /* Block the signal before executing the handler, and record in sigs @@ -222,36 +210,10 @@ value caml_execute_signal_exn(int signal_number, int in_signal_handler) sigaddset(&nsigs, signal_number); caml_sigmask_hook(SIG_BLOCK, &nsigs, &sigs); #endif -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - /* We record the signal handler's execution separately, in the same - trie used for finalisers. */ - saved_spacetime_trie_node_ptr - = caml_spacetime_trie_node_ptr; - caml_spacetime_trie_node_ptr - = caml_spacetime_finaliser_trie_root; -#endif -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - /* Handled action may have no associated handler, which we interpret - as meaning the signal should be handled by a call to exit. This is - used to allow spacetime profiles to be completed on interrupt */ - if (caml_signal_handlers == 0) { - res = caml_sys_exit(Val_int(2)); - } else { - handler = Field(caml_signal_handlers, signal_number); - if (!Is_block(handler)) { - res = caml_sys_exit(Val_int(2)); - } else { -#else handler = Field(caml_signal_handlers, signal_number); -#endif res = caml_callback_exn( handler, Val_int(caml_rev_convert_signal_number(signal_number))); -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - } - } - caml_spacetime_trie_node_ptr = saved_spacetime_trie_node_ptr; -#endif #ifdef POSIX_SIGNALS if (! in_signal_handler) { /* Restore the original signal mask */ @@ -342,6 +304,17 @@ Caml_inline value process_pending_actions_with_root_exn(value extra_root) return extra_root; } +CAMLno_tsan /* The access to [caml_something_to_do] is not synchronized. */ +int caml_check_pending_actions() +{ + return caml_something_to_do; +} + +value caml_process_pending_actions_with_root_exn(value extra_root) +{ + return process_pending_actions_with_root_exn(extra_root); +} + value caml_process_pending_actions_with_root(value extra_root) { value res = process_pending_actions_with_root_exn(extra_root); @@ -500,23 +473,8 @@ CAMLprim value caml_install_signal_handler(value signal_number, value action) res = Val_int(1); break; case 2: /* was Signal_handle */ - #if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - /* Handled action may have no associated handler - which we treat as Signal_default */ - if (caml_signal_handlers == 0) { - res = Val_int(0); - } else { - if (!Is_block(Field(caml_signal_handlers, sig))) { - res = Val_int(0); - } else { - res = caml_alloc_small (1, 0); - Field(res, 0) = Field(caml_signal_handlers, sig); - } - } - #else res = caml_alloc_small (1, 0); Field(res, 0) = Field(caml_signal_handlers, sig); - #endif break; default: /* error in caml_set_signal_action */ caml_sys_error(NO_ARG); diff --git a/runtime/signals_byt.c b/runtime/signals_byt.c index 040de03c..2183142d 100644 --- a/runtime/signals_byt.c +++ b/runtime/signals_byt.c @@ -46,12 +46,7 @@ static void handle_signal(int signal_number) signal(signal_number, handle_signal); #endif if (signal_number < 0 || signal_number >= NSIG) return; - if (caml_try_leave_blocking_section_hook()) { - caml_raise_if_exception(caml_execute_signal_exn(signal_number, 1)); - caml_enter_blocking_section_hook(); - }else{ - caml_record_signal(signal_number); - } + caml_record_signal(signal_number); errno = saved_errno; } @@ -86,4 +81,4 @@ int caml_set_signal_action(int signo, int action) return 0; } -void caml_setup_stack_overflow_detection(void) {} +CAMLexport void caml_setup_stack_overflow_detection(void) {} diff --git a/runtime/signals_nat.c b/runtime/signals_nat.c index fc5a77f8..8b64ab45 100644 --- a/runtime/signals_nat.c +++ b/runtime/signals_nat.c @@ -20,9 +20,13 @@ #if defined(TARGET_amd64) && defined (SYS_linux) #define _GNU_SOURCE #endif +#if defined(TARGET_i386) && defined (SYS_linux_elf) +#define _GNU_SOURCE +#endif #include #include #include +#include "caml/codefrag.h" #include "caml/fail.h" #include "caml/memory.h" #include "caml/osdeps.h" @@ -30,7 +34,6 @@ #include "caml/signals_machdep.h" #include "signals_osdep.h" #include "caml/stack.h" -#include "caml/spacetime.h" #include "caml/memprof.h" #include "caml/finalise.h" @@ -46,18 +49,6 @@ extern signal_handler caml_win32_signal(int sig, signal_handler action); extern void caml_win32_overflow_detection(); #endif -extern char * caml_code_area_start, * caml_code_area_end; -extern char caml_system__code_begin, caml_system__code_end; - -/* Do not use the macro from address_class.h here. */ -#undef Is_in_code_area -#define Is_in_code_area(pc) \ - ( ((char *)(pc) >= caml_code_area_start && \ - (char *)(pc) <= caml_code_area_end) \ -|| ((char *)(pc) >= &caml_system__code_begin && \ - (char *)(pc) <= &caml_system__code_end) \ -|| (Classify_addr(pc) & In_code_area) ) - /* This routine is the common entry point for garbage collection and signal handling. It can trigger a callback to OCaml code. With system threads, this callback can cause a context switch. @@ -107,19 +98,14 @@ DECLARE_SIGNAL_HANDLER(handle_signal) signal(sig, handle_signal); #endif if (sig < 0 || sig >= NSIG) return; - if (caml_try_leave_blocking_section_hook ()) { - caml_raise_if_exception(caml_execute_signal_exn(sig, 1)); - caml_enter_blocking_section_hook(); - } else { - caml_record_signal(sig); + caml_record_signal(sig); /* Some ports cache [Caml_state->young_limit] in a register. Use the signal context to modify that register too, but only if we are inside OCaml code (not inside C code). */ #if defined(CONTEXT_PC) && defined(CONTEXT_YOUNG_LIMIT) - if (Is_in_code_area(CONTEXT_PC)) - CONTEXT_YOUNG_LIMIT = (context_reg) Caml_state->young_limit; + if (caml_find_code_fragment_by_pc((char *) CONTEXT_PC) != NULL) + CONTEXT_YOUNG_LIMIT = (context_reg) Caml_state->young_limit; #endif - } errno = saved_errno; } @@ -223,7 +209,7 @@ DECLARE_SIGNAL_HANDLER(segv_handler) && fault_addr < Caml_state->top_of_stack && (uintnat)fault_addr >= CONTEXT_SP - EXTRA_STACK #ifdef CONTEXT_PC - && Is_in_code_area(CONTEXT_PC) + && caml_find_code_fragment_by_pc((char *) CONTEXT_PC) != NULL #endif ) { #ifdef RETURN_AFTER_STACK_OVERFLOW @@ -244,6 +230,14 @@ DECLARE_SIGNAL_HANDLER(segv_handler) #endif caml_raise_stack_overflow(); #endif +#ifdef NAKED_POINTERS_CHECKER + } else if (Caml_state->checking_pointer_pc) { +#ifdef CONTEXT_PC + CONTEXT_PC = (context_reg)Caml_state->checking_pointer_pc; +#else +#error "CONTEXT_PC must be defined if RETURN_AFTER_STACK_OVERFLOW is" +#endif /* CONTEXT_PC */ +#endif /* NAKED_POINTERS_CHECKER */ } else { /* Otherwise, deactivate our exception handler and return, causing fatal signal to be generated at point of error. */ @@ -296,7 +290,7 @@ void caml_init_signals(void) #endif } -void caml_setup_stack_overflow_detection(void) +CAMLexport void caml_setup_stack_overflow_detection(void) { #ifdef HAS_STACK_OVERFLOW_DETECTION stack_t stk; diff --git a/runtime/signals_osdep.h b/runtime/signals_osdep.h index d507d5a6..5b23bbf9 100644 --- a/runtime/signals_osdep.h +++ b/runtime/signals_osdep.h @@ -47,8 +47,9 @@ #include #include - #if !defined(MAC_OS_X_VERSION_10_5) \ - || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + #if (!defined(MAC_OS_X_VERSION_10_5) \ + || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) \ + && !defined(__IPHONE_OS_VERSION_MIN_REQUIRED) #define CONTEXT_REG(r) r #else #define CONTEXT_REG(r) __##r @@ -186,15 +187,16 @@ #elif defined(TARGET_i386) && defined(SYS_linux_elf) #define DECLARE_SIGNAL_HANDLER(name) \ - static void name(int sig, struct sigcontext context) + static void name(int sig, siginfo_t * info, ucontext_t * context) #define SET_SIGACT(sigact,name) \ - sigact.sa_handler = (void (*)(int)) (name); \ - sigact.sa_flags = 0 + sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \ + sigact.sa_flags = SA_SIGINFO - #define CONTEXT_FAULTING_ADDRESS ((char *) context.cr2) - #define CONTEXT_PC (context.eip) - #define CONTEXT_SP (context.esp) + typedef greg_t context_reg; + #define CONTEXT_PC (context->uc_mcontext.gregs[REG_EIP]) + #define CONTEXT_SP (context->uc_mcontext.gregs[REG_ESP]) + #define CONTEXT_FAULTING_ADDRESS ((char *)context->uc_mcontext.cr2) /****************** I386, BSD_ELF */ @@ -249,8 +251,9 @@ #include #include - #if !defined(MAC_OS_X_VERSION_10_5) \ - || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + #if (!defined(MAC_OS_X_VERSION_10_5) \ + || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) \ + && !defined(__IPHONE_OS_VERSION_MIN_REQUIRED) #define CONTEXT_REG(r) r #else #define CONTEXT_REG(r) __##r @@ -317,9 +320,9 @@ #define CONTEXT_SP (CONTEXT_STATE.CONTEXT_REG(r1)) #define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr) -/****************** PowerPC, ELF (Linux) */ +/****************** PowerPC 32 bits, ELF (Linux) */ -#elif defined(TARGET_power) && defined(SYS_elf) +#elif defined(TARGET_power) && defined(MODEL_ppc) && defined(SYS_elf) #define DECLARE_SIGNAL_HANDLER(name) \ static void name(int sig, struct sigcontext * context) @@ -335,6 +338,25 @@ #define CONTEXT_YOUNG_PTR (context->regs->gpr[31]) #define CONTEXT_SP (context->regs->gpr[1]) +/****************** PowerPC 64 bits, ELF (Linux) */ + +#elif defined(TARGET_power) && defined(SYS_elf) + + #define DECLARE_SIGNAL_HANDLER(name) \ + static void name(int sig, siginfo_t * info, ucontext_t * context) + + #define SET_SIGACT(sigact,name) \ + sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \ + sigact.sa_flags = SA_SIGINFO + + typedef unsigned long context_reg; + #define CONTEXT_PC (context->uc_mcontext.gp_regs[32]) + #define CONTEXT_EXCEPTION_POINTER (context->uc_mcontext.gp_regs[29]) + #define CONTEXT_YOUNG_LIMIT (context->uc_mcontext.gp_regs[30]) + #define CONTEXT_YOUNG_PTR (context->uc_mcontext.gp_regs[31]) + #define CONTEXT_SP (context->uc_mcontext.gp_regs[1]) + #define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr) + /****************** PowerPC, NetBSD */ #elif defined(TARGET_power) && defined (SYS_netbsd) @@ -379,18 +401,19 @@ #elif defined(TARGET_s390x) && defined(SYS_elf) #define DECLARE_SIGNAL_HANDLER(name) \ - static void name(int sig, struct sigcontext * context) + static void name(int sig, siginfo_t * info, ucontext_t * context) #define SET_SIGACT(sigact,name) \ - sigact.sa_handler = (void (*)(int)) (name); \ - sigact.sa_flags = 0 + sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \ + sigact.sa_flags = SA_SIGINFO typedef unsigned long context_reg; - #define CONTEXT_PC (context->sregs->regs.psw.addr) - #define CONTEXT_EXCEPTION_POINTER (context->sregs->regs.gprs[13]) - #define CONTEXT_YOUNG_LIMIT (context->sregs->regs.gprs[10]) - #define CONTEXT_YOUNG_PTR (context->sregs->regs.gprs[11]) - #define CONTEXT_SP (context->sregs->regs.gprs[15]) + #define CONTEXT_PC (context->uc_mcontext.psw.addr) + #define CONTEXT_EXCEPTION_POINTER (context->uc_mcontext.gregs[13]) + #define CONTEXT_YOUNG_LIMIT (context->uc_mcontext.gregs[10]) + #define CONTEXT_YOUNG_PTR (context->uc_mcontext.gregs[11]) + #define CONTEXT_SP (context->uc_mcontext.gregs[15]) + #define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr) /******************** Default */ diff --git a/runtime/spacetime_byt.c b/runtime/spacetime_byt.c deleted file mode 100644 index 2b0bf1dc..00000000 --- a/runtime/spacetime_byt.c +++ /dev/null @@ -1,38 +0,0 @@ -/**************************************************************************/ -/* */ -/* OCaml */ -/* */ -/* Mark Shinwell and Leo White, Jane Street Europe */ -/* */ -/* Copyright 2013--2016, Jane Street Group, LLC */ -/* */ -/* All rights reserved. This file is distributed under the terms of */ -/* the GNU Lesser General Public License version 2.1, with the */ -/* special exception on linking described in the file LICENSE. */ -/* */ -/**************************************************************************/ - -#include "caml/fail.h" -#include "caml/mlvalues.h" - -int caml_ensure_spacetime_dot_o_is_included = 42; - -CAMLprim value caml_spacetime_only_works_for_native_code(value foo, ...) -{ - caml_failwith("Spacetime profiling only works for native code"); -} - -uintnat caml_spacetime_my_profinfo (void) -{ - return 0; -} - -CAMLprim value caml_spacetime_enabled (value v_unit) -{ - return Val_false; /* running in bytecode */ -} - -CAMLprim value caml_register_channel_for_spacetime (value v_channel) -{ - return Val_unit; -} diff --git a/runtime/spacetime_nat.c b/runtime/spacetime_nat.c deleted file mode 100644 index 7e85e96e..00000000 --- a/runtime/spacetime_nat.c +++ /dev/null @@ -1,1160 +0,0 @@ -/**************************************************************************/ -/* */ -/* OCaml */ -/* */ -/* Mark Shinwell and Leo White, Jane Street Europe */ -/* */ -/* Copyright 2013--2016, Jane Street Group, LLC */ -/* */ -/* All rights reserved. This file is distributed under the terms of */ -/* the GNU Lesser General Public License version 2.1, with the */ -/* special exception on linking described in the file LICENSE. */ -/* */ -/**************************************************************************/ - -#define CAML_INTERNALS - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "caml/config.h" -#ifdef HAS_UNISTD -#include -#endif -#ifdef _WIN32 -#include /* for _getpid */ -#include /* for _wgetcwd */ -#endif - -#include "caml/alloc.h" -#include "caml/backtrace_prim.h" -#include "caml/fail.h" -#include "caml/gc.h" -#include "caml/intext.h" -#include "caml/major_gc.h" -#include "caml/memory.h" -#include "caml/minor_gc.h" -#include "caml/misc.h" -#include "caml/mlvalues.h" -#include "caml/osdeps.h" -#include "caml/roots.h" -#include "caml/signals.h" -#include "caml/stack.h" -#include "caml/sys.h" -#include "caml/spacetime.h" - -#ifdef WITH_SPACETIME - -/* We force "noinline" in certain places to be sure we know how many - frames there will be on the stack. */ -#ifdef _MSC_VER -#define NOINLINE __declspec(noinline) -#else -#define NOINLINE __attribute__((noinline)) -#endif - -#ifdef HAS_LIBUNWIND -#define UNW_LOCAL_ONLY -#include "libunwind.h" -#endif - -static int automatic_snapshots = 0; -static double snapshot_interval = 0.0; -static double next_snapshot_time = 0.0; -static struct channel *snapshot_channel; -static int pid_when_snapshot_channel_opened; - -extern value caml_spacetime_debug(value); - -static char* start_of_free_node_block; -static char* end_of_free_node_block; - -typedef struct per_thread { - value* trie_node_root; - value* finaliser_trie_node_root; - struct per_thread* next; -} per_thread; - -/* List of tries corresponding to threads that have been created. */ -/* CR-soon mshinwell: just include the main trie in this list. */ -static per_thread* per_threads = NULL; -static int num_per_threads = 0; - -/* [caml_spacetime_shapes] is defined in the startup file. */ -extern uint64_t* caml_spacetime_shapes; - -uint64_t** caml_spacetime_static_shape_tables = NULL; -shape_table* caml_spacetime_dynamic_shape_tables = NULL; - -static uintnat caml_spacetime_profinfo = (uintnat) 0; - -value caml_spacetime_trie_root = Val_unit; -value* caml_spacetime_trie_node_ptr = &caml_spacetime_trie_root; - -static value caml_spacetime_finaliser_trie_root_main_thread = Val_unit; -value* caml_spacetime_finaliser_trie_root - = &caml_spacetime_finaliser_trie_root_main_thread; - -/* CR-someday mshinwell: think about thread safety of the manipulation of - this list for multicore */ -allocation_point* caml_all_allocation_points = NULL; - -static const uintnat chunk_size = 1024 * 1024; - -#ifdef _WIN32 -#define strdup_os wcsdup -#else -#define strdup_os strdup -#endif - -static void reinitialise_free_node_block(void) -{ - size_t index; - - start_of_free_node_block = (char*) caml_stat_alloc_noexc(chunk_size); - end_of_free_node_block = start_of_free_node_block + chunk_size; - - for (index = 0; index < chunk_size / sizeof(value); index++) { - ((value*) start_of_free_node_block)[index] = Val_unit; - } -} - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -enum { - FEATURE_CALL_COUNTS = 1, -} features; - -static uint16_t version_number = 0; -static uint32_t magic_number_base = 0xace00ace; - -static void caml_spacetime_write_magic_number_internal(struct channel* chan) -{ - value magic_number; - uint16_t features = 0; - -#ifdef ENABLE_CALL_COUNTS - features |= FEATURE_CALL_COUNTS; -#endif - - magic_number = - Val_long(((uint64_t) magic_number_base) - | (((uint64_t) version_number) << 32) - | (((uint64_t) features) << 48)); - - Lock(chan); - caml_output_val(chan, magic_number, Val_long(0)); - Unlock(chan); -} - -CAMLprim value caml_spacetime_write_magic_number(value v_channel) -{ - caml_spacetime_write_magic_number_internal(Channel(v_channel)); - return Val_unit; -} - -static char_os* automatic_snapshot_dir; - -static void open_snapshot_channel(void) -{ - int fd; - char_os filename[8192]; - int pid; - int filename_len = sizeof(filename)/sizeof(char_os); -#ifdef _WIN32 - pid = _getpid(); -#else - pid = getpid(); -#endif - snprintf_os(filename, filename_len, T("%s/spacetime-%d"), - automatic_snapshot_dir, pid); - filename[filename_len-1] = '\0'; - fd = open_os(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); - if (fd == -1) { - automatic_snapshots = 0; - } - else { - snapshot_channel = caml_open_descriptor_out(fd); - snapshot_channel->flags |= CHANNEL_FLAG_BLOCKING_WRITE; - pid_when_snapshot_channel_opened = pid; - caml_spacetime_write_magic_number_internal(snapshot_channel); - } -} - -static void maybe_reopen_snapshot_channel(void) -{ - /* This function should be used before writing to the automatic snapshot - channel. It detects whether we have forked since the channel was opened. - If so, we close the old channel (ignoring any errors just in case the - old fd has been closed, e.g. in a double-fork situation where the middle - process has a loop to manually close all fds and no Spacetime snapshot - was written during that time) and then open a new one. */ - - int pid; -#ifdef _WIN32 - pid = _getpid(); -#else - pid = getpid(); -#endif - - if (pid != pid_when_snapshot_channel_opened) { - caml_close_channel(snapshot_channel); - open_snapshot_channel(); - } -} - -extern void caml_spacetime_automatic_save(void); - -void caml_spacetime_initialize(void) -{ - /* Note that this is called very early (even prior to GC initialisation). */ - - char_os *ap_interval; - - reinitialise_free_node_block(); - - caml_spacetime_static_shape_tables = &caml_spacetime_shapes; - - ap_interval = caml_secure_getenv (T("OCAML_SPACETIME_INTERVAL")); - if (ap_interval != NULL) { - unsigned int interval = 0; - sscanf_os(ap_interval, T("%u"), &interval); - if (interval != 0) { - double time; - char_os cwd[4096]; - char_os* user_specified_automatic_snapshot_dir; - int dir_ok = 1; - - user_specified_automatic_snapshot_dir = - caml_secure_getenv(T("OCAML_SPACETIME_SNAPSHOT_DIR")); - - if (user_specified_automatic_snapshot_dir == NULL) { -#if defined(HAS_GETCWD) - if (getcwd_os(cwd, sizeof(cwd)/sizeof(char_os)) == NULL) { - dir_ok = 0; - } -#else - dir_ok = 0; -#endif - if (dir_ok) { - automatic_snapshot_dir = strdup_os(cwd); - } - } - else { - automatic_snapshot_dir = - strdup_os(user_specified_automatic_snapshot_dir); - } - - if (dir_ok) { - automatic_snapshots = 1; - open_snapshot_channel(); - if (automatic_snapshots) { -#ifdef SIGINT - /* Catch interrupt so that the profile can be completed. - We do this by marking the signal as handled without - specifying an actual handler. This causes the signal - to be handled by a call to exit. */ - caml_set_signal_action(SIGINT, 2); -#endif - snapshot_interval = interval / 1e3; - time = caml_sys_time_unboxed(Val_unit); - next_snapshot_time = time + snapshot_interval; - atexit(&caml_spacetime_automatic_save); - } - } - } - } -} - -void caml_spacetime_register_shapes(void* dynlinked_table) -{ - shape_table* table; - table = (shape_table*) caml_stat_alloc_noexc(sizeof(shape_table)); - if (table == NULL) { - fprintf(stderr, "Out of memory whilst registering shape table"); - abort(); - } - table->table = (uint64_t*) dynlinked_table; - table->next = caml_spacetime_dynamic_shape_tables; - caml_spacetime_dynamic_shape_tables = table; -} - -CAMLprim value caml_spacetime_trie_is_initialized (value v_unit) -{ - return (caml_spacetime_trie_root == Val_unit) ? Val_false : Val_true; -} - -CAMLprim value caml_spacetime_get_trie_root (value v_unit) -{ - return caml_spacetime_trie_root; -} - -void caml_spacetime_register_thread( - value* trie_node_root, value* finaliser_trie_node_root) -{ - per_thread* thr; - - thr = (per_thread*) caml_stat_alloc_noexc(sizeof(per_thread)); - if (thr == NULL) { - fprintf(stderr, "Out of memory while registering thread for profiling\n"); - abort(); - } - thr->next = per_threads; - per_threads = thr; - - thr->trie_node_root = trie_node_root; - thr->finaliser_trie_node_root = finaliser_trie_node_root; - - /* CR-soon mshinwell: record thread ID (and for the main thread too) */ - - num_per_threads++; -} - -static void caml_spacetime_save_event_internal (value v_time_opt, - struct channel* chan, - value v_event_name) -{ - value v_time; - double time_override = 0.0; - int use_time_override = 0; - - if (Is_block(v_time_opt)) { - time_override = Double_field(Field(v_time_opt, 0), 0); - use_time_override = 1; - } - v_time = caml_spacetime_timestamp(time_override, use_time_override); - - Lock(chan); - caml_output_val(chan, Val_long(2), Val_long(0)); - caml_output_val(chan, v_event_name, Val_long(0)); - caml_extern_allow_out_of_heap = 1; - caml_output_val(chan, v_time, Val_long(0)); - caml_extern_allow_out_of_heap = 0; - Unlock(chan); - - caml_stat_free(Hp_val(v_time)); -} - -CAMLprim value caml_spacetime_save_event (value v_time_opt, - value v_channel, - value v_event_name) -{ - struct channel* chan = Channel(v_channel); - - caml_spacetime_save_event_internal(v_time_opt, chan, v_event_name); - - return Val_unit; -} - - -void save_trie (struct channel *chan, double time_override, - int use_time_override) -{ - value v_time, v_frames, v_shapes; - /* CR-someday mshinwell: The commented-out changes here are for multicore, - where we think we should have one trie per domain. */ - /* int num_marshalled = 0; - per_thread* thr = per_threads; */ - - Lock(chan); - - caml_output_val(chan, Val_long(1), Val_long(0)); - - v_time = caml_spacetime_timestamp(time_override, use_time_override); - v_frames = caml_spacetime_frame_table(); - v_shapes = caml_spacetime_shape_table(); - - caml_extern_allow_out_of_heap = 1; - caml_output_val(chan, v_time, Val_long(0)); - caml_output_val(chan, v_frames, Val_long(0)); - caml_output_val(chan, v_shapes, Val_long(0)); - caml_extern_allow_out_of_heap = 0; - - caml_output_val(chan, Val_long(1) /* Val_long(num_per_threads + 1) */, - Val_long(0)); - - /* Marshal both the main and finaliser tries, for all threads that have - been created, to an [out_channel]. This can be done by using the - extern.c code as usual, since the trie looks like standard OCaml values; - but we must allow it to traverse outside the heap. */ - - caml_extern_allow_out_of_heap = 1; - caml_output_val(chan, caml_spacetime_trie_root, Val_long(0)); - caml_output_val(chan, - caml_spacetime_finaliser_trie_root_main_thread, Val_long(0)); - /* while (thr != NULL) { - caml_output_val(chan, *(thr->trie_node_root), Val_long(0)); - caml_output_val(chan, *(thr->finaliser_trie_node_root), - Val_long(0)); - thr = thr->next; - num_marshalled++; - } - CAMLassert(num_marshalled == num_per_threads); */ - caml_extern_allow_out_of_heap = 0; - - Unlock(chan); -} - -CAMLprim value caml_spacetime_save_trie (value v_time_opt, value v_channel) -{ - struct channel* channel = Channel(v_channel); - double time_override = 0.0; - int use_time_override = 0; - - if (Is_block(v_time_opt)) { - time_override = Double_field(Field(v_time_opt, 0), 0); - use_time_override = 1; - } - - save_trie(channel, time_override, use_time_override); - - return Val_unit; -} - -c_node_type caml_spacetime_classify_c_node(c_node* node) -{ - return (node->pc & 2) ? CALL : ALLOCATION; -} - -c_node* caml_spacetime_c_node_of_stored_pointer(value node_stored) -{ - CAMLassert(node_stored == Val_unit || Is_c_node(node_stored)); - return (node_stored == Val_unit) ? NULL : (c_node*) Hp_val(node_stored); -} - -c_node* caml_spacetime_c_node_of_stored_pointer_not_null( - value node_stored) -{ - CAMLassert(Is_c_node(node_stored)); - return (c_node*) Hp_val(node_stored); -} - -value caml_spacetime_stored_pointer_of_c_node(c_node* c_node) -{ - value node; - CAMLassert(c_node != NULL); - node = Val_hp(c_node); - CAMLassert(Is_c_node(node)); - return node; -} - -#ifdef HAS_LIBUNWIND -static int pc_inside_c_node_matches(c_node* node, void* pc) -{ - return Decode_c_node_pc(node->pc) == pc; -} -#endif - -static value allocate_uninitialized_ocaml_node(int size_including_header) -{ - void* node; - uintnat size; - - CAMLassert(size_including_header >= 3); - node = caml_stat_alloc(sizeof(uintnat) * size_including_header); - - size = size_including_header * sizeof(value); - - node = (void*) start_of_free_node_block; - if (end_of_free_node_block - start_of_free_node_block < size) { - reinitialise_free_node_block(); - node = (void*) start_of_free_node_block; - CAMLassert(end_of_free_node_block - start_of_free_node_block >= size); - } - - start_of_free_node_block += size; - - /* We don't currently rely on [uintnat] alignment, but we do need some - alignment, so just be sure. */ - CAMLassert (((uintnat) node) % sizeof(uintnat) == 0); - return Val_hp(node); -} - -static value find_tail_node(value node, void* callee) -{ - /* Search the tail chain within [node] (which corresponds to an invocation - of a caller of [callee]) to determine whether it contains a tail node - corresponding to [callee]. Returns any such node, or [Val_unit] if no - such node exists. */ - - value starting_node; - value pc; - value found = Val_unit; - - starting_node = node; - pc = Encode_node_pc(callee); - - do { - CAMLassert(Is_ocaml_node(node)); - if (Node_pc(node) == pc) { - found = node; - } - else { - node = Tail_link(node); - } - } while (found == Val_unit && starting_node != node); - - return found; -} - -CAMLprim value caml_spacetime_allocate_node( - int size_including_header, void* pc, value* node_hole) -{ - value node; - value caller_node = Val_unit; - - node = *node_hole; - /* The node hole should either contain [Val_unit], indicating that this - function was not tail called and we have not been to this point in the - trie before; or it should contain a value encoded using - [Encoded_tail_caller_node] that points at the node of a caller - that tail called the current function. (Such a value is necessary to - be able to find the start of the caller's node, and hence its tail - chain, so we as a tail-called callee can link ourselves in.) */ - CAMLassert(Is_tail_caller_node_encoded(node)); - - if (node != Val_unit) { - value tail_node; - /* The callee was tail called. Find whether there already exists a node - for it in the tail call chain within the caller's node. The caller's - node must always be an OCaml node. */ - caller_node = Decode_tail_caller_node(node); - tail_node = find_tail_node(caller_node, pc); - if (tail_node != Val_unit) { - /* This tail calling sequence has happened before; just fill the hole - with the existing node and return. */ - *node_hole = tail_node; - return 0; /* indicates an existing node was returned */ - } - } - - node = allocate_uninitialized_ocaml_node(size_including_header); - Hd_val(node) = - Make_header(size_including_header - 1, OCaml_node_tag, Caml_black); - CAMLassert((((uintnat) pc) % 1) == 0); - Node_pc(node) = Encode_node_pc(pc); - /* If the callee was tail called, then the tail link field will link this - new node into an existing tail chain. Otherwise, it is initialized with - the empty tail chain, i.e. the one pointing directly at [node]. */ - if (caller_node == Val_unit) { - Tail_link(node) = node; - } - else { - Tail_link(node) = Tail_link(caller_node); - Tail_link(caller_node) = node; - } - - /* The callee node pointers for direct tail call points are - initialized from code emitted by the OCaml compiler. This is done to - avoid having to pass this function a description of which nodes are - direct tail call points. (We cannot just count them and put them at the - beginning of the node because we need the indexes of elements within the - node during instruction selection before we have found all call points.) - - All other fields have already been initialised by - [reinitialise_free_node_block]. - */ - - *node_hole = node; - - return 1; /* indicates a new node was created */ -} - -static c_node* allocate_c_node(void) -{ - c_node* node; - size_t index; - - node = (c_node*) start_of_free_node_block; - if (end_of_free_node_block - start_of_free_node_block < sizeof(c_node)) { - reinitialise_free_node_block(); - node = (c_node*) start_of_free_node_block; - CAMLassert(end_of_free_node_block - start_of_free_node_block - >= sizeof(c_node)); - } - start_of_free_node_block += sizeof(c_node); - - CAMLassert((sizeof(c_node) % sizeof(uintnat)) == 0); - - /* CR-soon mshinwell: remove this and pad the structure properly */ - for (index = 0; index < sizeof(c_node) / sizeof(value); index++) { - ((value*) node)[index] = Val_unit; - } - - node->gc_header = - Make_header(sizeof(c_node)/sizeof(uintnat) - 1, C_node_tag, Caml_black); - node->data.call.callee_node = Val_unit; - node->data.call.call_count = Val_long(0); - node->next = Val_unit; - - return node; -} - -/* Since a given indirect call site either always yields tail calls or - always yields non-tail calls, the output of - [caml_spacetime_indirect_node_hole_ptr] is uniquely determined by its - first two arguments (the callee and the node hole). We cache these - to increase performance of recursive functions containing an indirect - call (e.g. [List.map] when not inlined). */ -static void* last_indirect_node_hole_ptr_callee; -static value* last_indirect_node_hole_ptr_node_hole; -static call_point* last_indirect_node_hole_ptr_result; - -CAMLprim value* caml_spacetime_indirect_node_hole_ptr - (void* callee, value* node_hole, value caller_node) -{ - /* Find the address of the node hole for an indirect call to [callee]. - If [caller_node] is not [Val_unit], it is a pointer to the caller's - node, and indicates that this is a tail call site. */ - - c_node* c_node; - value encoded_callee; - - if (callee == last_indirect_node_hole_ptr_callee - && node_hole == last_indirect_node_hole_ptr_node_hole) { -#ifdef ENABLE_CALL_COUNTS - last_indirect_node_hole_ptr_result->call_count = - Val_long (Long_val (last_indirect_node_hole_ptr_result->call_count) + 1); -#endif - return &(last_indirect_node_hole_ptr_result->callee_node); - } - - last_indirect_node_hole_ptr_callee = callee; - last_indirect_node_hole_ptr_node_hole = node_hole; - - encoded_callee = Encode_c_node_pc_for_call(callee); - - while (*node_hole != Val_unit) { - CAMLassert(((uintnat) *node_hole) % sizeof(value) == 0); - - c_node = caml_spacetime_c_node_of_stored_pointer_not_null(*node_hole); - - CAMLassert(c_node != NULL); - CAMLassert(caml_spacetime_classify_c_node(c_node) == CALL); - - if (c_node->pc == encoded_callee) { -#ifdef ENABLE_CALL_COUNTS - c_node->data.call.call_count = - Val_long (Long_val(c_node->data.call.call_count) + 1); -#endif - last_indirect_node_hole_ptr_result = &(c_node->data.call); - return &(last_indirect_node_hole_ptr_result->callee_node); - } - else { - node_hole = &c_node->next; - } - } - - c_node = allocate_c_node(); - c_node->pc = encoded_callee; - - if (caller_node != Val_unit) { - /* This is a tail call site. - Perform the initialization equivalent to that emitted by - [Spacetime.code_for_function_prologue] for direct tail call - sites. */ - c_node->data.call.callee_node = Encode_tail_caller_node(caller_node); - } - - *node_hole = caml_spacetime_stored_pointer_of_c_node(c_node); - - CAMLassert(((uintnat) *node_hole) % sizeof(value) == 0); - CAMLassert(*node_hole != Val_unit); - -#ifdef ENABLE_CALL_COUNTS - c_node->data.call.call_count = - Val_long (Long_val(c_node->data.call.call_count) + 1); -#endif - last_indirect_node_hole_ptr_result = &(c_node->data.call); - - return &(last_indirect_node_hole_ptr_result->callee_node); -} - -/* Some notes on why caml_call_gc doesn't need a distinguished node. - (Remember that thread switches are irrelevant here because each thread - has its own trie.) - - caml_call_gc only invokes OCaml functions in the following circumstances: - 1. running an OCaml finaliser; - 2. executing an OCaml signal handler; - 3. executing memprof callbacks. - All of these are done on the finaliser trie. Furthermore, all of - these invocations start via caml_callback; the code in this file for - handling that (caml_spacetime_c_to_ocaml) correctly copes with that by - attaching a single "caml_start_program" node that can cope with any - number of indirect OCaml calls from that point. - - caml_call_gc may also invoke C functions that cause allocation. All of - these (assuming libunwind support is present) will cause a chain of - c_node structures to be attached to the trie, starting at the node hole - passed to caml_call_gc from OCaml code. These structures are extensible - and can thus accommodate any number of C backtraces leading from - caml_call_gc. -*/ -/* CR-soon mshinwell: it might in fact be the case now that nothing called - from caml_call_gc will do any allocation that ends up on the trie. We - can revisit this after the first release. */ - -static NOINLINE void* find_trie_node_from_libunwind(int for_allocation, - uintnat wosize, struct ext_table** cached_frames) -{ -#ifdef HAS_LIBUNWIND - /* Given that [Caml_state->last_return_address] is the most recent call site - in OCaml code, and that we are now in C (or other) code called from that - site, obtain a backtrace using libunwind and graft the most recent - portion (everything back to but not including [last_return_address]) - onto the trie. See the important comment below regarding the fact that - call site, and not callee, addresses are recorded during this process. - - If [for_allocation] is non-zero, the final node recorded will be for - an allocation, and the returned pointer is to the allocation node. - Otherwise, no node is recorded for the innermost frame, and the - returned pointer is a pointer to the *node hole* where a node for that - frame should be attached. - - If [for_allocation] is non-zero then [wosize] must give the size in - words, excluding the header, of the value being allocated. - - If [cached_frames != NULL] then: - 1. If [*cached_frames] is NULL then save the captured backtrace in a - newly-allocated table and store the pointer to that table in - [*cached_frames]; - 2. Otherwise use [*cached_frames] as the unwinding information. - The intention is that when the context is known (e.g. a function such - as [caml_make_vect] known to have been directly invoked from OCaml), - we can avoid expensive calls to libunwind. - */ - - unw_cursor_t cur; - unw_context_t ctx; - int ret; - int innermost_frame; - int frame; - static struct ext_table frames_local; - struct ext_table* frames; - static int ext_table_initialised = 0; - int have_frames_already = 0; - value* node_hole; - c_node* node = NULL; - int initial_table_size = 1000; - int must_initialise_node_for_allocation = 0; - - if (!cached_frames) { - if (!ext_table_initialised) { - caml_ext_table_init(&frames_local, initial_table_size); - ext_table_initialised = 1; - } - else { - caml_ext_table_clear(&frames_local, 0); - } - frames = &frames_local; - } else { - if (*cached_frames) { - frames = *cached_frames; - have_frames_already = 1; - } - else { - frames = - (struct ext_table*) caml_stat_alloc_noexc(sizeof(struct ext_table)); - if (!frames) { - caml_fatal_error("not enough memory for ext_table allocation"); - } - caml_ext_table_init(frames, initial_table_size); - *cached_frames = frames; - } - } - - if (!have_frames_already) { - /* Get the stack backtrace as far as [Caml_state->last_return_address]. */ - - ret = unw_getcontext(&ctx); - if (ret != UNW_ESUCCESS) { - return NULL; - } - - ret = unw_init_local(&cur, &ctx); - if (ret != UNW_ESUCCESS) { - return NULL; - } - - while ((ret = unw_step(&cur)) > 0) { - unw_word_t ip; - unw_get_reg(&cur, UNW_REG_IP, &ip); - if (Caml_state->last_return_address == (uintnat) ip) { - break; - } - else { - /* Inlined some of [caml_ext_table_add] for speed. */ - if (frames->size < frames->capacity) { - frames->contents[frames->size++] = (void*) ip; - } else { - caml_ext_table_add(frames, (void*) ip); - } - } - } - } - - /* We always need to ignore the frames for: - #0 find_trie_node_from_libunwind - #1 caml_spacetime_c_to_ocaml - Further, if this is not an allocation point, we should not create the - node for the current C function that triggered us (i.e. frame #2). */ - innermost_frame = for_allocation ? 1 : 2; - - if (frames->size - 1 < innermost_frame) { - /* Insufficiently many frames (maybe no frames) returned from - libunwind; just don't do anything. */ - return NULL; - } - - node_hole = caml_spacetime_trie_node_ptr; - /* Note that if [node_hole] is filled, then it must point to a C node, - since it is not possible for there to be a call point in an OCaml - function that sometimes calls C and sometimes calls OCaml. */ - - for (frame = frames->size - 1; frame >= innermost_frame; frame--) { - c_node_type expected_type; - void* pc = frames->contents[frame]; - CAMLassert (pc != (void*) Caml_state->last_return_address); - - if (!for_allocation) { - expected_type = CALL; - } - else { - expected_type = (frame > innermost_frame ? CALL : ALLOCATION); - } - - if (*node_hole == Val_unit) { - node = allocate_c_node(); - /* Note: for CALL nodes, the PC is the program counter at each call - site. We do not store program counter addresses of the start of - callees, unlike for OCaml nodes. This means that some trie nodes - will become conflated. These can be split during post-processing by - working out which function each call site was in. */ - node->pc = (expected_type == CALL ? Encode_c_node_pc_for_call(pc) - : Encode_c_node_pc_for_alloc_point(pc)); - *node_hole = caml_spacetime_stored_pointer_of_c_node(node); - if (expected_type == ALLOCATION) { - must_initialise_node_for_allocation = 1; - } - } - else { - c_node* prev; - int found = 0; - - node = caml_spacetime_c_node_of_stored_pointer_not_null(*node_hole); - CAMLassert(node != NULL); - CAMLassert(node->next == Val_unit - || (((uintnat) (node->next)) % sizeof(value) == 0)); - - prev = NULL; - - while (!found && node != NULL) { - if (caml_spacetime_classify_c_node(node) == expected_type - && pc_inside_c_node_matches(node, pc)) { - found = 1; - } - else { - prev = node; - node = caml_spacetime_c_node_of_stored_pointer(node->next); - } - } - if (!found) { - CAMLassert(prev != NULL); - node = allocate_c_node(); - node->pc = (expected_type == CALL ? Encode_c_node_pc_for_call(pc) - : Encode_c_node_pc_for_alloc_point(pc)); - if (expected_type == ALLOCATION) { - must_initialise_node_for_allocation = 1; - } - prev->next = caml_spacetime_stored_pointer_of_c_node(node); - } - } - - CAMLassert(node != NULL); - - CAMLassert(caml_spacetime_classify_c_node(node) == expected_type); - CAMLassert(pc_inside_c_node_matches(node, pc)); - node_hole = &node->data.call.callee_node; - } - - if (must_initialise_node_for_allocation) { - caml_spacetime_profinfo++; - if (caml_spacetime_profinfo > PROFINFO_MASK) { - /* Profiling counter overflow. */ - caml_spacetime_profinfo = PROFINFO_MASK; - } - node->data.allocation.profinfo = - Make_header_with_profinfo( - /* "-1" because [c_node] has the GC header as its first - element. */ - offsetof(c_node, data.allocation.count)/sizeof(value) - 1, - Infix_tag, - Caml_black, - caml_spacetime_profinfo); - node->data.allocation.count = Val_long(0); - - /* Add the new allocation point into the linked list of all allocation - points. */ - if (caml_all_allocation_points != NULL) { - node->data.allocation.next = - (value) &caml_all_allocation_points->count; - } else { - node->data.allocation.next = Val_unit; - } - caml_all_allocation_points = &node->data.allocation; - } - - if (for_allocation) { - CAMLassert(caml_spacetime_classify_c_node(node) == ALLOCATION); - CAMLassert(caml_spacetime_c_node_of_stored_pointer(node->next) != node); - CAMLassert(Profinfo_hd(node->data.allocation.profinfo) > 0); - node->data.allocation.count = - Val_long(Long_val(node->data.allocation.count) + (1 + wosize)); - } - - CAMLassert(node->next != (value) NULL); - - return for_allocation ? (void*) node : (void*) node_hole; -#else - return NULL; -#endif -} - -void caml_spacetime_c_to_ocaml(void* ocaml_entry_point, - void* identifying_pc_for_caml_start_program) -{ - /* Called in [caml_start_program] and [caml_callback*] when we are about - to cross from C into OCaml. [ocaml_entry_point] is the branch target. - This situation is handled by ensuring the presence of a new OCaml node - for the callback veneer; the node contains a single indirect call point - which accumulates the [ocaml_entry_point]s. - - The layout of the node is described in the "system shape table"; see - amd64.S. - */ - - value node; - - /* Update the trie with the current backtrace, as far back as - [Caml_state->last_return_address], and leave the node hole pointer at - the correct place for attachment of a [caml_start_program] node. */ - -#ifdef HAS_LIBUNWIND - value* node_temp; - node_temp = (value*) find_trie_node_from_libunwind(0, 0, NULL); - if (node_temp != NULL) { - caml_spacetime_trie_node_ptr = node_temp; - } -#endif - - if (*caml_spacetime_trie_node_ptr == Val_unit) { - uintnat size_including_header; - - size_including_header = - 1 /* GC header */ + Node_num_header_words + Indirect_num_fields; - - node = allocate_uninitialized_ocaml_node(size_including_header); - Hd_val(node) = - Make_header(size_including_header - 1, OCaml_node_tag, Caml_black); - CAMLassert((((uintnat) identifying_pc_for_caml_start_program) % 1) == 0); - Node_pc(node) = Encode_node_pc(identifying_pc_for_caml_start_program); - Tail_link(node) = node; - Indirect_pc_linked_list(node, Node_num_header_words) = Val_unit; - *caml_spacetime_trie_node_ptr = node; - } - else { - node = *caml_spacetime_trie_node_ptr; - /* If there is a node here already, it should never be an initialized - (but as yet unused) tail call point, since calls from OCaml into C - are never tail calls (and no C -> C call is marked as tail). */ - CAMLassert(!Is_tail_caller_node_encoded(node)); - } - - CAMLassert(Is_ocaml_node(node)); - CAMLassert(Decode_node_pc(Node_pc(node)) - == identifying_pc_for_caml_start_program); - CAMLassert(Tail_link(node) == node); - CAMLassert(Wosize_val(node) == Node_num_header_words + Indirect_num_fields); - - /* Search the node to find the node hole corresponding to the indirect - call to the OCaml function. */ - caml_spacetime_trie_node_ptr = - caml_spacetime_indirect_node_hole_ptr( - ocaml_entry_point, - &Indirect_pc_linked_list(node, Node_num_header_words), - Val_unit); - CAMLassert(*caml_spacetime_trie_node_ptr == Val_unit - || Is_ocaml_node(*caml_spacetime_trie_node_ptr)); -} - -extern void caml_garbage_collection(void); /* signals_nat.c */ -extern void caml_array_bound_error(void); /* fail.c */ - -CAMLprim uintnat caml_spacetime_generate_profinfo (void* profinfo_words, - uintnat index_within_node) -{ - /* Called from code that creates a value's header inside an OCaml - function. */ - - value node; - uintnat profinfo; - - caml_spacetime_profinfo++; - if (caml_spacetime_profinfo > PROFINFO_MASK) { - /* Profiling counter overflow. */ - caml_spacetime_profinfo = PROFINFO_MASK; - } - profinfo = caml_spacetime_profinfo; - - /* CR-someday mshinwell: we could always use the [struct allocation_point] - overlay instead of the macros now. */ - - /* [node] isn't really a node; it points into the middle of - one---specifically to the "profinfo" word of an allocation point. - It's done like this to avoid re-calculating the place in the node - (which already has to be done in the OCaml-generated code run before - this function). */ - node = (value) profinfo_words; - CAMLassert(Alloc_point_profinfo(node, 0) == Val_unit); - - /* The profinfo value is stored shifted to reduce the number of - instructions required on the OCaml side. It also enables us to use - [Infix_tag] to obtain valid value pointers into the middle of nodes, - which is used for the linked list of all allocation points. */ - profinfo = Make_header_with_profinfo( - index_within_node, Infix_tag, Caml_black, profinfo); - - CAMLassert(!Is_block(profinfo)); - Alloc_point_profinfo(node, 0) = profinfo; - /* The count is set to zero by the initialisation when the node was - created (see above). */ - CAMLassert(Alloc_point_count(node, 0) == Val_long(0)); - - /* Add the new allocation point into the linked list of all allocation - points. */ - if (caml_all_allocation_points != NULL) { - Alloc_point_next_ptr(node, 0) = (value) &caml_all_allocation_points->count; - } - else { - CAMLassert(Alloc_point_next_ptr(node, 0) == Val_unit); - } - caml_all_allocation_points = (allocation_point*) node; - - return profinfo; -} - -uintnat caml_spacetime_my_profinfo (struct ext_table** cached_frames, - uintnat wosize) -{ - /* Return the profinfo value that should be written into a value's header - during an allocation from C. This may necessitate extending the trie - with information obtained from libunwind. */ - - c_node* node; - uintnat profinfo = 0; - - node = find_trie_node_from_libunwind(1, wosize, cached_frames); - if (node != NULL) { - profinfo = ((uintnat) (node->data.allocation.profinfo)) >> PROFINFO_SHIFT; - } - - return profinfo; /* N.B. not shifted by PROFINFO_SHIFT */ -} - -void caml_spacetime_automatic_snapshot (void) -{ - if (automatic_snapshots) { - double start_time, end_time; - start_time = caml_sys_time_unboxed(Val_unit); - if (start_time >= next_snapshot_time) { - maybe_reopen_snapshot_channel(); - caml_spacetime_save_snapshot(snapshot_channel, 0.0, 0); - end_time = caml_sys_time_unboxed(Val_unit); - next_snapshot_time = end_time + snapshot_interval; - } - } -} - -CAMLprim value caml_spacetime_save_event_for_automatic_snapshots - (value v_event_name) -{ - if (automatic_snapshots) { - maybe_reopen_snapshot_channel(); - caml_spacetime_save_event_internal (Val_unit, snapshot_channel, - v_event_name); - } - return Val_unit; -} - -void caml_spacetime_automatic_save (void) -{ - /* Called from [atexit]. */ - - if (automatic_snapshots) { - automatic_snapshots = 0; - maybe_reopen_snapshot_channel(); - save_trie(snapshot_channel, 0.0, 0); - caml_flush(snapshot_channel); - caml_close_channel(snapshot_channel); - } -} - -CAMLprim value caml_spacetime_enabled (value v_unit) -{ - return Val_true; -} - -CAMLprim value caml_register_channel_for_spacetime (value v_channel) -{ - struct channel* channel = Channel(v_channel); - channel->flags |= CHANNEL_FLAG_BLOCKING_WRITE; - return Val_unit; -} - -#else - -/* Functions for when the compiler was not configured with "-spacetime". */ - -CAMLprim value caml_spacetime_write_magic_number(value v_channel) -{ - return Val_unit; -} - -CAMLprim value caml_spacetime_enabled (value v_unit) -{ - return Val_false; -} - -CAMLprim value caml_spacetime_save_event (value v_time_opt, - value v_channel, - value v_event_name) -{ - return Val_unit; -} - -CAMLprim value caml_spacetime_save_event_for_automatic_snapshots - (value v_event_name) -{ - return Val_unit; -} - -CAMLprim value caml_spacetime_save_trie (value ignored) -{ - return Val_unit; -} - -CAMLprim value caml_register_channel_for_spacetime (value v_channel) -{ - return Val_unit; -} - -#endif diff --git a/runtime/spacetime_snapshot.c b/runtime/spacetime_snapshot.c deleted file mode 100644 index 4ce31ceb..00000000 --- a/runtime/spacetime_snapshot.c +++ /dev/null @@ -1,600 +0,0 @@ -/**************************************************************************/ -/* */ -/* OCaml */ -/* */ -/* Mark Shinwell and Leo White, Jane Street Europe */ -/* */ -/* Copyright 2013--2016, Jane Street Group, LLC */ -/* */ -/* All rights reserved. This file is distributed under the terms of */ -/* the GNU Lesser General Public License version 2.1, with the */ -/* special exception on linking described in the file LICENSE. */ -/* */ -/**************************************************************************/ - -#define CAML_INTERNALS - -#include -#include -#include -#include -#include - -#include "caml/alloc.h" -#include "caml/backtrace_prim.h" -#include "caml/config.h" -#include "caml/custom.h" -#include "caml/fail.h" -#include "caml/gc.h" -#include "caml/gc_ctrl.h" -#include "caml/intext.h" -#include "caml/major_gc.h" -#include "caml/memory.h" -#include "caml/minor_gc.h" -#include "caml/misc.h" -#include "caml/mlvalues.h" -#include "caml/roots.h" -#include "caml/signals.h" -#include "caml/stack.h" -#include "caml/sys.h" -#include "caml/spacetime.h" - -#ifdef WITH_SPACETIME - -/* The following structures must match the type definitions in the - [Spacetime] module. */ - -typedef struct { - /* (GC header here.) */ - value minor_words; - value promoted_words; - value major_words; - value minor_collections; - value major_collections; - value heap_words; - value heap_chunks; - value compactions; - value top_heap_words; -} gc_stats; - -typedef struct { - value profinfo; - value num_blocks; - value num_words_including_headers; -} snapshot_entry; - -typedef struct { - /* (GC header here.) */ - snapshot_entry entries[0]; -} snapshot_entries; - -typedef struct { - /* (GC header here.) */ - value time; - value gc_stats; - value entries; - value words_scanned; - value words_scanned_with_profinfo; - value total_allocations; -} snapshot; - -typedef struct { - uintnat num_blocks; - uintnat num_words_including_headers; -} raw_snapshot_entry; - -static value allocate_outside_heap_with_tag(mlsize_t size_in_bytes, tag_t tag) -{ - /* CR-soon mshinwell: this function should live somewhere else */ - header_t* block; - - CAMLassert(size_in_bytes % sizeof(value) == 0); - block = caml_stat_alloc(sizeof(header_t) + size_in_bytes); - *block = Make_header(size_in_bytes / sizeof(value), tag, Caml_black); - return (value) &block[1]; -} - -static value allocate_outside_heap(mlsize_t size_in_bytes) -{ - CAMLassert(size_in_bytes > 0); - return allocate_outside_heap_with_tag(size_in_bytes, 0); -} - -static value take_gc_stats(void) -{ - value v_stats; - gc_stats* stats; - - v_stats = allocate_outside_heap(sizeof(gc_stats)); - stats = (gc_stats*) v_stats; - - stats->minor_words = Val_long(Caml_state->stat_minor_words); - stats->promoted_words = Val_long(Caml_state->stat_promoted_words); - stats->major_words = - Val_long(((uintnat) Caml_state->stat_major_words) - + ((uintnat) caml_allocated_words)); - stats->minor_collections = Val_long(Caml_state->stat_minor_collections); - stats->major_collections = Val_long(Caml_state->stat_major_collections); - stats->heap_words = Val_long(Caml_state->stat_heap_wsz / sizeof(value)); - stats->heap_chunks = Val_long(Caml_state->stat_heap_chunks); - stats->compactions = Val_long(Caml_state->stat_compactions); - stats->top_heap_words = - Val_long(Caml_state->stat_top_heap_wsz / sizeof(value)); - - return v_stats; -} - -static value get_total_allocations(void) -{ - value v_total_allocations = Val_unit; - allocation_point* total = caml_all_allocation_points; - - while (total != NULL) { - value v_total; - v_total = allocate_outside_heap_with_tag(3 * sizeof(value), 0); - - /* [v_total] is of type [Raw_spacetime_lib.total_allocations]. */ - Field(v_total, 0) = Val_long(Profinfo_hd(total->profinfo)); - Field(v_total, 1) = total->count; - Field(v_total, 2) = v_total_allocations; - v_total_allocations = v_total; - - CAMLassert (total->next == Val_unit - || (Is_block(total->next) && Tag_val(total->next) == Infix_tag)); - if (total->next == Val_unit) { - total = NULL; - } - else { - total = (allocation_point*) Hp_val(total->next); - } - } - - return v_total_allocations; -} - -static value take_snapshot(double time_override, int use_time_override) -{ - value v_snapshot; - snapshot* heap_snapshot; - value v_entries; - snapshot_entries* entries; - char* chunk; - value gc_stats; - uintnat index; - uintnat target_index; - value v_time; - double time; - uintnat profinfo; - uintnat num_distinct_profinfos; - /* Fixed size buffer to avoid needing a hash table: */ - static raw_snapshot_entry* raw_entries = NULL; - uintnat words_scanned = 0; - uintnat words_scanned_with_profinfo = 0; - value v_total_allocations; - - if (!use_time_override) { - time = caml_sys_time_unboxed(Val_unit); - } - else { - time = time_override; - } - - gc_stats = take_gc_stats(); - - if (raw_entries == NULL) { - size_t size = (PROFINFO_MASK + 1) * sizeof(raw_snapshot_entry); - raw_entries = caml_stat_alloc(size); - memset(raw_entries, '\0', size); - } else { - size_t size = (PROFINFO_MASK + 1) * sizeof(raw_snapshot_entry); - memset(raw_entries, '\0', size); - } - - num_distinct_profinfos = 0; - - /* CR-someday mshinwell: consider reintroducing minor heap scanning, - properly from roots, which would then give a snapshot function - that doesn't do a minor GC. Although this may not be that important - and potentially not worth the effort (it's quite tricky). */ - - /* Scan the major heap. */ - chunk = caml_heap_start; - while (chunk != NULL) { - char* hp; - char* limit; - - hp = chunk; - limit = chunk + Chunk_size (chunk); - - while (hp < limit) { - header_t hd = Hd_hp (hp); - switch (Color_hd(hd)) { - case Caml_blue: - break; - - default: - if (Wosize_hd(hd) > 0) { /* ignore atoms */ - profinfo = Profinfo_hd(hd); - words_scanned += Whsize_hd(hd); - if (profinfo > 0 && profinfo < PROFINFO_MASK) { - words_scanned_with_profinfo += Whsize_hd(hd); - CAMLassert (raw_entries[profinfo].num_blocks >= 0); - if (raw_entries[profinfo].num_blocks == 0) { - num_distinct_profinfos++; - } - raw_entries[profinfo].num_blocks++; - raw_entries[profinfo].num_words_including_headers += - Whsize_hd(hd); - } - } - break; - } - hp += Bhsize_hd (hd); - CAMLassert (hp <= limit); - } - - chunk = Chunk_next (chunk); - } - - if (num_distinct_profinfos > 0) { - v_entries = allocate_outside_heap( - num_distinct_profinfos*sizeof(snapshot_entry)); - entries = (snapshot_entries*) v_entries; - target_index = 0; - for (index = 0; index <= PROFINFO_MASK; index++) { - CAMLassert(raw_entries[index].num_blocks >= 0); - if (raw_entries[index].num_blocks > 0) { - CAMLassert(target_index < num_distinct_profinfos); - entries->entries[target_index].profinfo = Val_long(index); - entries->entries[target_index].num_blocks - = Val_long(raw_entries[index].num_blocks); - entries->entries[target_index].num_words_including_headers - = Val_long(raw_entries[index].num_words_including_headers); - target_index++; - } - } - } else { - v_entries = Atom(0); - } - - CAMLassert(sizeof(double) == sizeof(value)); - v_time = allocate_outside_heap_with_tag(sizeof(double), Double_tag); - Store_double_val(v_time, time); - - v_snapshot = allocate_outside_heap(sizeof(snapshot)); - heap_snapshot = (snapshot*) v_snapshot; - - v_total_allocations = get_total_allocations(); - - heap_snapshot->time = v_time; - heap_snapshot->gc_stats = gc_stats; - heap_snapshot->entries = v_entries; - heap_snapshot->words_scanned - = Val_long(words_scanned); - heap_snapshot->words_scanned_with_profinfo - = Val_long(words_scanned_with_profinfo); - heap_snapshot->total_allocations = v_total_allocations; - - return v_snapshot; -} - -void caml_spacetime_save_snapshot (struct channel *chan, double time_override, - int use_time_override) -{ - value v_snapshot; - value v_total_allocations; - snapshot* heap_snapshot; - - Lock(chan); - - v_snapshot = take_snapshot(time_override, use_time_override); - - caml_output_val(chan, Val_long(0), Val_long(0)); - - caml_extern_allow_out_of_heap = 1; - caml_output_val(chan, v_snapshot, Val_long(0)); - caml_extern_allow_out_of_heap = 0; - - Unlock(chan); - - heap_snapshot = (snapshot*) v_snapshot; - caml_stat_free(Hp_val(heap_snapshot->time)); - caml_stat_free(Hp_val(heap_snapshot->gc_stats)); - if (Wosize_val(heap_snapshot->entries) > 0) { - caml_stat_free(Hp_val(heap_snapshot->entries)); - } - v_total_allocations = heap_snapshot->total_allocations; - while (v_total_allocations != Val_unit) { - value next = Field(v_total_allocations, 2); - caml_stat_free(Hp_val(v_total_allocations)); - v_total_allocations = next; - } - - caml_stat_free(Hp_val(v_snapshot)); -} - -CAMLprim value caml_spacetime_take_snapshot(value v_time_opt, value v_channel) -{ - struct channel * channel = Channel(v_channel); - double time_override = 0.0; - int use_time_override = 0; - - if (Is_block(v_time_opt)) { - time_override = Double_field(Field(v_time_opt, 0), 0); - use_time_override = 1; - } - - caml_spacetime_save_snapshot(channel, time_override, use_time_override); - - return Val_unit; -} - -extern struct custom_operations caml_int64_ops; /* ints.c */ - -static value -allocate_int64_outside_heap(uint64_t i) -{ - value v; - - v = allocate_outside_heap_with_tag(2 * sizeof(value), Custom_tag); - Custom_ops_val(v) = &caml_int64_ops; - Int64_val(v) = i; - - return v; -} - -static value -copy_string_outside_heap(char const *s) -{ - int len; - mlsize_t wosize, offset_index; - value result; - - len = strlen(s); - wosize = (len + sizeof (value)) / sizeof (value); - result = allocate_outside_heap_with_tag(wosize * sizeof(value), String_tag); - - Field (result, wosize - 1) = 0; - offset_index = Bsize_wsize (wosize) - 1; - Byte (result, offset_index) = offset_index - len; - memmove(Bytes_val(result), s, len); - - return result; -} - -static value -allocate_loc_outside_heap(struct caml_loc_info li) -{ - value result; - - if (li.loc_valid) { - result = allocate_outside_heap_with_tag(5 * sizeof(value), 0); - Field(result, 0) = Val_bool(li.loc_is_raise); - Field(result, 1) = copy_string_outside_heap(li.loc_filename); - Field(result, 2) = Val_int(li.loc_lnum); - Field(result, 3) = Val_int(li.loc_startchr); - Field(result, 4) = Val_int(li.loc_endchr); - } else { - result = allocate_outside_heap_with_tag(sizeof(value), 1); - Field(result, 0) = Val_bool(li.loc_is_raise); - } - - return result; -} - -value caml_spacetime_timestamp(double time_override, int use_time_override) -{ - double time; - value v_time; - - if (!use_time_override) { - time = caml_sys_time_unboxed(Val_unit); - } - else { - time = time_override; - } - - v_time = allocate_outside_heap_with_tag(sizeof(double), Double_tag); - Store_double_val(v_time, time); - - return v_time; -} - -value caml_spacetime_frame_table(void) -{ - /* Flatten the frame table into a single associative list. */ - - value list = Val_long(0); /* the empty list */ - uintnat i; - - if (!caml_debug_info_available()) { - return list; - } - - if (caml_frame_descriptors == NULL) { - caml_init_frame_descriptors(); - } - - for (i = 0; i <= caml_frame_descriptors_mask; i++) { - frame_descr* descr = caml_frame_descriptors[i]; - if (descr != NULL) { - value location, return_address, pair, new_list_element, location_list; - struct caml_loc_info li; - debuginfo dbg; - if (descr->frame_size != 0xffff) { - dbg = caml_debuginfo_extract(descr); - if (dbg != NULL) { - location_list = Val_unit; - while (dbg != NULL) { - value list_element; - - caml_debuginfo_location(dbg, &li); - location = allocate_loc_outside_heap(li); - - list_element = - allocate_outside_heap_with_tag(2 * sizeof(value), 0 /* (::) */); - Field(list_element, 0) = location; - Field(list_element, 1) = location_list; - location_list = list_element; - - dbg = caml_debuginfo_next(dbg); - } - - return_address = allocate_int64_outside_heap(descr->retaddr); - pair = allocate_outside_heap_with_tag(2 * sizeof(value), 0); - Field(pair, 0) = return_address; - Field(pair, 1) = location_list; - - new_list_element = - allocate_outside_heap_with_tag(2 * sizeof(value), 0 /* (::) */); - Field(new_list_element, 0) = pair; - Field(new_list_element, 1) = list; - list = new_list_element; - } - } - } - } - - return list; -} - -static void add_unit_to_shape_table(uint64_t *unit_table, value *list) -{ - /* This function reverses the order of the lists giving the layout of each - node; however, spacetime_profiling.ml ensures they are emitted in - reverse order, so at the end of it all they're not reversed. */ - - uint64_t* ptr = unit_table; - - while (*ptr != (uint64_t) 0) { - value new_list_element, pair, function_address, layout; - - function_address = - allocate_int64_outside_heap(*ptr++); - - layout = Val_long(0); /* the empty list */ - while (*ptr != (uint64_t) 0) { - int tag; - int stored_tag; - value part_of_shape; - value new_part_list_element; - value location; - int has_extra_argument = 0; - - stored_tag = *ptr++; - /* CR-soon mshinwell: share with emit.mlp */ - switch (stored_tag) { - case 1: /* direct call to given location */ - tag = 0; - has_extra_argument = 1; /* the address of the callee */ - break; - - case 2: /* indirect call to given location */ - tag = 1; - break; - - case 3: /* allocation at given location */ - tag = 2; - break; - - default: - CAMLassert(0); - abort(); /* silence compiler warning */ - } - - location = allocate_int64_outside_heap(*ptr++); - - part_of_shape = allocate_outside_heap_with_tag( - sizeof(value) * (has_extra_argument ? 2 : 1), tag); - Field(part_of_shape, 0) = location; - if (has_extra_argument) { - Field(part_of_shape, 1) = - allocate_int64_outside_heap(*ptr++); - } - - new_part_list_element = - allocate_outside_heap_with_tag(2 * sizeof(value), 0 /* (::) */); - Field(new_part_list_element, 0) = part_of_shape; - Field(new_part_list_element, 1) = layout; - layout = new_part_list_element; - } - - pair = allocate_outside_heap_with_tag(2 * sizeof(value), 0); - Field(pair, 0) = function_address; - Field(pair, 1) = layout; - - new_list_element = - allocate_outside_heap_with_tag(2 * sizeof(value), 0 /* (::) */); - Field(new_list_element, 0) = pair; - Field(new_list_element, 1) = *list; - *list = new_list_element; - - ptr++; - } -} - -value caml_spacetime_shape_table(void) -{ - value list; - uint64_t* unit_table; - shape_table *dynamic_table; - uint64_t** static_table; - - /* Flatten the hierarchy of shape tables into a single associative list - mapping from function symbols to node layouts. The node layouts are - themselves lists. */ - - list = Val_long(0); /* the empty list */ - - /* Add static shape tables */ - static_table = caml_spacetime_static_shape_tables; - while (*static_table != (uint64_t) 0) { - unit_table = *static_table++; - add_unit_to_shape_table(unit_table, &list); - } - - /* Add dynamic shape tables */ - dynamic_table = caml_spacetime_dynamic_shape_tables; - - while (dynamic_table != NULL) { - unit_table = dynamic_table->table; - add_unit_to_shape_table(unit_table, &list); - dynamic_table = dynamic_table->next; - } - - return list; -} - -#else - -static value spacetime_disabled() -{ - caml_failwith("Spacetime profiling not enabled"); -} - -CAMLprim value caml_spacetime_take_snapshot(value ignored) -{ - return Val_unit; -} - -CAMLprim value caml_spacetime_marshal_frame_table () -{ - return spacetime_disabled(); -} - -CAMLprim value caml_spacetime_frame_table () -{ - return spacetime_disabled(); -} - -CAMLprim value caml_spacetime_marshal_shape_table () -{ - return spacetime_disabled(); -} - -CAMLprim value caml_spacetime_shape_table () -{ - return spacetime_disabled(); -} - -#endif diff --git a/runtime/stacks.c b/runtime/stacks.c index 2e3be6a0..a1409b2a 100644 --- a/runtime/stacks.c +++ b/runtime/stacks.c @@ -47,7 +47,6 @@ void caml_realloc_stack(asize_t required_space) { asize_t size; value * new_low, * new_high, * new_sp; - value * p; CAMLassert(Caml_state->extern_sp >= Caml_state->stack_low); size = Caml_state->stack_high - Caml_state->stack_low; @@ -72,8 +71,6 @@ void caml_realloc_stack(asize_t required_space) caml_stat_free(Caml_state->stack_low); Caml_state->trapsp = (value *) shift(Caml_state->trapsp); Caml_state->trap_barrier = (value *) shift(Caml_state->trap_barrier); - for (p = Caml_state->trapsp; p < new_high; p = Trap_link(p)) - Trap_link(p) = (value *) shift(Trap_link(p)); Caml_state->stack_low = new_low; Caml_state->stack_high = new_high; Caml_state->stack_threshold = diff --git a/runtime/startup_aux.c b/runtime/startup_aux.c index 5db9f480..53df3e21 100644 --- a/runtime/startup_aux.c +++ b/runtime/startup_aux.c @@ -28,7 +28,6 @@ #endif #include "caml/osdeps.h" #include "caml/startup_aux.h" -#include "caml/memprof.h" #ifdef _WIN32 @@ -60,11 +59,7 @@ void caml_init_atom_table(void) caml_stat_alloc_aligned_noexc(request, 0, &b); for(i = 0; i < 256; i++) { -#ifdef NATIVE_CODE - caml_atom_table[i] = Make_header_allocated_here(0, i, Caml_white); -#else - caml_atom_table[i] = Make_header(0, i, Caml_white); -#endif + caml_atom_table[i] = Make_header(0, i, Caml_black); } if (caml_page_table_add(In_static_data, caml_atom_table, caml_atom_table + 256 + 1) != 0) { @@ -116,7 +111,7 @@ void caml_parse_ocamlrunparam(void) switch (*opt++){ case 'a': scanmult (opt, &p); caml_set_allocation_policy ((intnat) p); break; - case 'b': scanmult (opt, &p); caml_record_backtrace(Val_bool (p)); + case 'b': scanmult (opt, &p); caml_record_backtrace(Val_int (p)); break; case 'c': scanmult (opt, &p); caml_cleanup_on_exit = (p != 0); break; case 'h': scanmult (opt, &caml_init_heap_wsz); break; @@ -135,6 +130,7 @@ void caml_parse_ocamlrunparam(void) case 'v': scanmult (opt, &caml_verb_gc); break; case 'w': scanmult (opt, &caml_init_major_window); break; case 'W': scanmult (opt, &caml_runtime_warnings); break; + case ',': continue; } while (*opt != '\0'){ if (*opt++ == ',') break; @@ -190,7 +186,6 @@ CAMLexport void caml_shutdown(void) call_registered_value("Pervasives.do_at_exit"); call_registered_value("Thread.at_shutdown"); caml_finalise_heap(); - caml_memprof_shutdown(); caml_free_locale(); #ifndef NATIVE_CODE caml_free_shared_libs(); diff --git a/runtime/startup_byt.c b/runtime/startup_byt.c index 60ffea77..a06617da 100644 --- a/runtime/startup_byt.c +++ b/runtime/startup_byt.c @@ -17,6 +17,7 @@ /* Start-up code */ +#include #include #include #include @@ -128,7 +129,10 @@ int caml_attempt_open(char_os **name, struct exec_trailer *trail, if (fd == -1) { caml_stat_free(truename); caml_gc_message(0x100, "Cannot open file\n"); - return FILE_NOT_FOUND; + if (errno == EMFILE) + return NO_FDS; + else + return FILE_NOT_FOUND; } if (!do_open_script) { err = read (fd, buf, 2); @@ -319,8 +323,6 @@ static int parse_command_line(char_os **argv) return i; } -extern void caml_init_ieee_floats (void); - #ifdef _WIN32 extern void caml_signal_thread(void * lpParam); #endif @@ -332,8 +334,6 @@ extern void caml_install_invalid_parameter_handler(); #endif -extern int caml_ensure_spacetime_dot_o_is_included; - /* Main entry point when loading code from a file */ CAMLexport void caml_main(char_os **argv) @@ -346,8 +346,6 @@ CAMLexport void caml_main(char_os **argv) char_os * shared_lib_path, * shared_libs; char_os * exe_name, * proc_self_exe; - caml_ensure_spacetime_dot_o_is_included++; - /* Initialize the domain */ caml_init_domain(); @@ -363,9 +361,6 @@ CAMLexport void caml_main(char_os **argv) if (!caml_startup_aux(/* pooling */ caml_cleanup_on_exit)) return; - /* Machine-dependent initialization of the floating-point hardware - so that it behaves as much as possible as specified in IEEE */ - caml_init_ieee_floats(); caml_init_locale(); #if defined(_MSC_VER) && __STDC_SECURE_LIB__ >= 200411L caml_install_invalid_parameter_handler(); @@ -449,7 +444,9 @@ CAMLexport void caml_main(char_os **argv) /* Load the globals */ caml_seek_section(fd, &trail, "DATA"); chan = caml_open_descriptor_in(fd); + Lock(chan); caml_global_data = caml_input_val(chan); + Unlock(chan); caml_close_channel(chan); /* this also closes fd */ caml_stat_free(trail.section); /* Ensure that the globals are in the major heap. */ @@ -457,6 +454,8 @@ CAMLexport void caml_main(char_os **argv) caml_oldify_mopup (); /* Initialize system libraries */ caml_sys_init(exe_name, argv + pos); + /* Load debugging info, if b>=2 */ + caml_load_main_debug_info(); #ifdef _WIN32 /* Start a thread to handle signals */ if (caml_secure_getenv(T("CAMLSIGPIPE"))) @@ -504,7 +503,6 @@ CAMLexport value caml_startup_code_exn( if (!caml_startup_aux(pooling)) return Val_unit; - caml_init_ieee_floats(); caml_init_locale(); #if defined(_MSC_VER) && __STDC_SECURE_LIB__ >= 200411L caml_install_invalid_parameter_handler(); @@ -549,6 +547,8 @@ CAMLexport value caml_startup_code_exn( caml_section_table_size = section_table_size; /* Initialize system libraries */ caml_sys_init(exe_name, argv); + /* Load debugging info, if b>=2 */ + caml_load_main_debug_info(); /* Execute the program */ caml_debugger(PROGRAM_START, Val_unit); return caml_interprete(caml_start_code, caml_code_size); diff --git a/runtime/startup_nat.c b/runtime/startup_nat.c index 444264bf..722f834b 100644 --- a/runtime/startup_nat.c +++ b/runtime/startup_nat.c @@ -39,15 +39,12 @@ #include "caml/stack.h" #include "caml/startup_aux.h" #include "caml/sys.h" -#ifdef WITH_SPACETIME -#include "caml/spacetime.h" -#endif #ifdef HAS_UI #include "caml/ui.h" #endif extern int caml_parser_trace; -char * caml_code_area_start, * caml_code_area_end; +extern char caml_system__code_begin, caml_system__code_end; /* Initialize the atom table and the static data and code area limits. */ @@ -56,6 +53,8 @@ struct segment { char * begin; char * end; }; static void init_static(void) { extern struct segment caml_data_segments[], caml_code_segments[]; + + char * caml_code_area_start, * caml_code_area_end; int i; caml_init_atom_table (); @@ -81,6 +80,10 @@ static void init_static(void) caml_register_code_fragment(caml_code_area_start, caml_code_area_end, DIGEST_LATER, NULL); + /* Also register the glue code written in assembly */ + caml_register_code_fragment(&caml_system__code_begin, + &caml_system__code_end, + DIGEST_IGNORE, NULL); } /* These are termination hooks used by the systhreads library */ @@ -88,7 +91,6 @@ struct longjmp_buffer caml_termination_jmpbuf; void (*caml_termination_hook)(void *) = NULL; extern value caml_start_program (caml_domain_state*); -extern void caml_init_ieee_floats (void); extern void caml_init_signals (void); #ifdef _WIN32 extern void caml_win32_overflow_detection (void); @@ -122,11 +124,7 @@ value caml_startup_common(char_os **argv, int pooling) if (!caml_startup_aux(pooling)) return Val_unit; -#ifdef WITH_SPACETIME - caml_spacetime_initialize(); -#endif caml_init_frame_descriptors(); - caml_init_ieee_floats(); caml_init_locale(); #if defined(_MSC_VER) && __STDC_SECURE_LIB__ >= 200411L caml_install_invalid_parameter_handler(); diff --git a/runtime/sys.c b/runtime/sys.c index 4da107a9..909a75f6 100644 --- a/runtime/sys.c +++ b/runtime/sys.c @@ -130,6 +130,7 @@ CAMLprim value caml_sys_exit(value retcode_v) intnat heap_chunks = Caml_state->stat_heap_chunks; intnat top_heap_words = Caml_state->stat_top_heap_wsz; intnat cpct = Caml_state->stat_compactions; + intnat forcmajcoll = Caml_state->stat_forced_major_collections; caml_gc_message(0x400, "allocated_words: %.0f\n", allocated_words); caml_gc_message(0x400, "minor_words: %.0f\n", minwords); caml_gc_message(0x400, "promoted_words: %.0f\n", prowords); @@ -146,6 +147,9 @@ CAMLprim value caml_sys_exit(value retcode_v) top_heap_words); caml_gc_message(0x400, "compactions: %"ARCH_INTNAT_PRINTF_FORMAT"d\n", cpct); + caml_gc_message(0x400, + "forced_major_collections: %"ARCH_INTNAT_PRINTF_FORMAT"d\n", + forcmajcoll); } #ifndef NATIVE_CODE @@ -315,6 +319,36 @@ CAMLprim value caml_sys_chdir(value dirname) CAMLreturn(Val_unit); } +CAMLprim value caml_sys_mkdir(value path, value perm) +{ + CAMLparam2(path, perm); + char_os * p; + int ret; + caml_sys_check_path(path); + p = caml_stat_strdup_to_os(String_val(path)); + caml_enter_blocking_section(); + ret = mkdir_os(p, Int_val(perm)); + caml_leave_blocking_section(); + caml_stat_free(p); + if (ret == -1) caml_sys_error(path); + CAMLreturn(Val_unit); +} + +CAMLprim value caml_sys_rmdir(value path) +{ + CAMLparam1(path); + char_os * p; + int ret; + caml_sys_check_path(path); + p = caml_stat_strdup_to_os(String_val(path)); + caml_enter_blocking_section(); + ret = rmdir_os(p); + caml_leave_blocking_section(); + caml_stat_free(p); + if (ret == -1) caml_sys_error(path); + CAMLreturn(Val_unit); +} + CAMLprim value caml_sys_getcwd(value unit) { char_os buff[4096]; @@ -427,6 +461,7 @@ void caml_sys_init(char_os * exe_name, char_os **argv) #endif #endif +#ifdef HAS_SYSTEM CAMLprim value caml_sys_system_command(value command) { CAMLparam1 (command); @@ -449,6 +484,12 @@ CAMLprim value caml_sys_system_command(value command) retcode = 255; CAMLreturn (Val_int(retcode)); } +#else +CAMLprim value caml_sys_system_command(value command) +{ + caml_invalid_argument("Sys.command not implemented"); +} +#endif double caml_sys_time_include_children_unboxed(value include_children) { @@ -657,3 +698,12 @@ CAMLprim value caml_sys_isatty(value chan) return ret; } + +CAMLprim value caml_sys_const_naked_pointers_checked(value unit) +{ +#ifdef NAKED_POINTERS_CHECKER + return Val_true; +#else + return Val_false; +#endif +} diff --git a/runtime/unix.c b/runtime/unix.c index c0ddbaaa..a3371773 100644 --- a/runtime/unix.c +++ b/runtime/unix.c @@ -74,12 +74,13 @@ int caml_read_fd(int fd, int flags, void * buf, int n) { int retcode; - do { - caml_enter_blocking_section(); - retcode = read(fd, buf, n); - caml_leave_blocking_section(); - } while (retcode == -1 && errno == EINTR); - if (retcode == -1) caml_sys_io_error(NO_ARG); + caml_enter_blocking_section_no_pending(); + retcode = read(fd, buf, n); + caml_leave_blocking_section(); + if (retcode == -1) { + if (errno == EINTR) return Io_interrupted; + else caml_sys_io_error(NO_ARG); + } return retcode; } @@ -87,19 +88,11 @@ int caml_write_fd(int fd, int flags, void * buf, int n) { int retcode; again: -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - if (flags & CHANNEL_FLAG_BLOCKING_WRITE) { - retcode = write(fd, buf, n); - } else { -#endif - caml_enter_blocking_section(); + caml_enter_blocking_section_no_pending(); retcode = write(fd, buf, n); caml_leave_blocking_section(); -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - } -#endif if (retcode == -1) { - if (errno == EINTR) goto again; + if (errno == EINTR) return Io_interrupted; if ((errno == EAGAIN || errno == EWOULDBLOCK) && n > 1) { /* We couldn't do a partial write here, probably because n <= PIPE_BUF and POSIX says that writes of less than diff --git a/runtime/weak.c b/runtime/weak.c index 85315263..29dc12c8 100644 --- a/runtime/weak.c +++ b/runtime/weak.c @@ -46,12 +46,19 @@ value caml_ephe_none = (value) &ephe_dummy; CAMLassert (offset < Wosize_val (eph) - CAML_EPHE_FIRST_KEY); \ }while(0) -#define CAMLassert_not_dead_value(v) do{ \ - CAMLassert ( caml_gc_phase != Phase_clean \ - || !Is_block(v) \ - || !Is_in_heap (v) \ - || !Is_white_val(v) ); \ +#ifdef DEBUG +#define CAMLassert_not_dead_value(v) do{ \ + value __v = v; \ + if (caml_gc_phase == Phase_clean \ + && Is_block(__v) \ + && Is_in_heap (__v)) { \ + if (Tag_val (__v) == Infix_tag) __v -= Infix_offset_val (__v); \ + CAMLassert ( !Is_white_val(__v) ); \ + } \ }while(0) +#else +#define CAMLassert_not_dead_value(v) +#endif CAMLexport mlsize_t caml_ephemeron_num_keys(value eph) { @@ -60,13 +67,19 @@ CAMLexport mlsize_t caml_ephemeron_num_keys(value eph) } /** The minor heap is considered alive. */ -#if defined (NATIVE_CODE) && defined (NO_NAKED_POINTERS) + /** Outside minor and major heap, x must be black. */ Caml_inline int Is_Dead_during_clean(value x) { CAMLassert (x != caml_ephe_none); CAMLassert (caml_gc_phase == Phase_clean); - return Is_block (x) && !Is_young (x) && Is_white_val(x); +#ifdef NO_NAKED_POINTERS + if (!Is_block(x) || Is_young (x)) return 0; +#else + if (!Is_block(x) || !Is_in_heap(x)) return 0; +#endif + if (Tag_val(x) == Infix_tag) x -= Infix_offset_val(x); + return Is_white_val(x); } /** The minor heap doesn't have to be marked, outside they should already be black @@ -75,22 +88,12 @@ Caml_inline int Must_be_Marked_during_mark(value x) { CAMLassert (x != caml_ephe_none); CAMLassert (caml_gc_phase == Phase_mark); +#ifdef NO_NAKED_POINTERS return Is_block (x) && !Is_young (x); -} #else -Caml_inline int Is_Dead_during_clean(value x) -{ - CAMLassert (x != caml_ephe_none); - CAMLassert (caml_gc_phase == Phase_clean); - return Is_block (x) && Is_in_heap (x) && Is_white_val(x); -} -Caml_inline int Must_be_Marked_during_mark(value x) -{ - CAMLassert (x != caml_ephe_none); - CAMLassert (caml_gc_phase == Phase_mark); return Is_block (x) && Is_in_heap (x); -} #endif +} /* [len] is a number of words (fields) */ CAMLexport value caml_ephemeron_create (mlsize_t len) @@ -355,27 +358,35 @@ CAMLprim value caml_ephe_get_data (value ar) return optionalize(caml_ephemeron_get_data(ar, &data), &data); } - -Caml_inline void copy_value(value src, value dst) +static void copy_value(value src, value dst) { - if (Tag_val (src) < No_scan_tag){ - mlsize_t i; - for (i = 0; i < Wosize_val (src); i++){ - value f = Field (src, i); - if (caml_gc_phase == Phase_mark && Must_be_Marked_during_mark(f)){ - caml_darken (f, NULL); - } - caml_modify (&Field (dst, i), f); + mlsize_t sz, i; + sz = Wosize_val(src); + if (Tag_val (src) >= No_scan_tag) { + /* Direct copy */ + memcpy (Bp_val (dst), Bp_val (src), Bsize_wsize (sz)); + return; + } + i = 0; + if (Tag_val (src) == Closure_tag) { + /* Direct copy of the code pointers and closure info fields */ + i = Start_env_closinfo(Closinfo_val(src)); + memcpy (Bp_val (dst), Bp_val (src), Bsize_wsize (i)); + } + /* Field-by-field copy and darkening of the remaining fields */ + for (/*nothing*/; i < sz; i++){ + value f = Field (src, i); + if (caml_gc_phase == Phase_mark && Must_be_Marked_during_mark(f)){ + caml_darken (f, NULL); } - }else{ - memmove (Bp_val (dst), Bp_val (src), Bosize_val (src)); + caml_modify (&Field (dst, i), f); } } CAMLexport int caml_ephemeron_get_key_copy(value ar, mlsize_t offset, value *key) { - mlsize_t loop = 0; + mlsize_t loop = 0, infix_offs; CAMLparam1(ar); value elt = Val_unit, v; /* Caution: they are NOT local roots. */ CAMLassert_valid_offset(ar, offset); @@ -386,13 +397,15 @@ CAMLexport int caml_ephemeron_get_key_copy(value ar, mlsize_t offset, if(is_ephe_key_none(ar, offset)) CAMLreturn(0); v = Field (ar, offset); /** Don't copy custom_block #7279 */ - if(!(Is_block (v) && Is_in_heap_or_young(v) && Tag_val(v) != Custom_tag)) { + if(!(Is_block (v) && Is_in_value_area(v) && Tag_val(v) != Custom_tag)) { if ( caml_gc_phase == Phase_mark && Must_be_Marked_during_mark(v) ){ caml_darken (v, NULL); }; *key = v; CAMLreturn(1); } + infix_offs = Tag_val(v) == Infix_tag ? Infix_offset_val(v) : 0; + v -= infix_offs; if (elt != Val_unit && Wosize_val(v) == Wosize_val(elt) && Tag_val(v) == Tag_val(elt)) { /* The allocation may trigger a finaliser that change the tag @@ -402,7 +415,7 @@ CAMLexport int caml_ephemeron_get_key_copy(value ar, mlsize_t offset, */ CAMLassert_not_dead_value(v); copy_value(v, elt); - *key = elt; + *key = elt + infix_offs; CAMLreturn(1); } @@ -435,7 +448,7 @@ CAMLprim value caml_weak_get_copy (value ar, value n) CAMLexport int caml_ephemeron_get_data_copy (value ar, value *data) { - mlsize_t loop = 0; + mlsize_t loop = 0, infix_offs; CAMLparam1 (ar); value elt = Val_unit, v; /* Caution: they are NOT local roots. */ CAMLassert_valid_ephemeron(ar); @@ -445,19 +458,21 @@ CAMLexport int caml_ephemeron_get_data_copy (value ar, value *data) v = Field (ar, CAML_EPHE_DATA_OFFSET); if (v == caml_ephe_none) CAMLreturn(0); /** Don't copy custom_block #7279 */ - if (!(Is_block (v) && Is_in_heap_or_young(v) && Tag_val(v) != Custom_tag)) { + if (!(Is_block (v) && Is_in_value_area(v) && Tag_val(v) != Custom_tag)) { if ( caml_gc_phase == Phase_mark && Must_be_Marked_during_mark(v) ){ caml_darken (v, NULL); }; *data = v; CAMLreturn(1); } + infix_offs = Tag_val(v) == Infix_tag ? Infix_offset_val(v) : 0; + v -= infix_offs; if (elt != Val_unit && Wosize_val(v) == Wosize_val(elt) && Tag_val(v) == Tag_val(elt)) { /** cf caml_ephemeron_get_key_copy */ CAMLassert_not_dead_value(v); copy_value(v, elt); - *data = elt; + *data = elt + infix_offs; CAMLreturn(1); } diff --git a/runtime/win32.c b/runtime/win32.c index 9c5f7fc2..d72c9540 100644 --- a/runtime/win32.c +++ b/runtime/win32.c @@ -38,7 +38,7 @@ #include #include #include "caml/alloc.h" -#include "caml/address_class.h" +#include "caml/codefrag.h" #include "caml/fail.h" #include "caml/io.h" #include "caml/memory.h" @@ -87,7 +87,7 @@ int caml_read_fd(int fd, int flags, void * buf, int n) { int retcode; if ((flags & CHANNEL_FLAG_FROM_SOCKET) == 0) { - caml_enter_blocking_section(); + caml_enter_blocking_section_no_pending(); retcode = read(fd, buf, n); /* Large reads from console can fail with ENOMEM. Reduce requested size and try again. */ @@ -97,7 +97,7 @@ int caml_read_fd(int fd, int flags, void * buf, int n) caml_leave_blocking_section(); if (retcode == -1) caml_sys_io_error(NO_ARG); } else { - caml_enter_blocking_section(); + caml_enter_blocking_section_no_pending(); retcode = recv((SOCKET) _get_osfhandle(fd), buf, n, 0); caml_leave_blocking_section(); if (retcode == -1) caml_win32_sys_error(WSAGetLastError()); @@ -109,20 +109,12 @@ int caml_write_fd(int fd, int flags, void * buf, int n) { int retcode; if ((flags & CHANNEL_FLAG_FROM_SOCKET) == 0) { -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - if (flags & CHANNEL_FLAG_BLOCKING_WRITE) { - retcode = write(fd, buf, n); - } else { -#endif - caml_enter_blocking_section(); + caml_enter_blocking_section_no_pending(); retcode = write(fd, buf, n); caml_leave_blocking_section(); -#if defined(NATIVE_CODE) && defined(WITH_SPACETIME) - } -#endif if (retcode == -1) caml_sys_io_error(NO_ARG); } else { - caml_enter_blocking_section(); + caml_enter_blocking_section_no_pending(); retcode = send((SOCKET) _get_osfhandle(fd), buf, n, 0); caml_leave_blocking_section(); if (retcode == -1) caml_win32_sys_error(WSAGetLastError()); @@ -249,7 +241,7 @@ void * caml_dlsym(void * handle, const char * name) void * caml_globalsym(const char * name) { - return flexdll_dlsym(flexdll_dlopen(NULL,0), name); + return flexdll_dlsym(flexdll_wdlopen(NULL,0), name); } char * caml_dlerror(void) @@ -410,7 +402,8 @@ CAMLexport void caml_expand_command_line(int * argcp, wchar_t *** argvp) the directory named [dirname]. No entries are added for [.] and [..]. Return 0 on success, -1 on error; set errno in the case of error. */ -int caml_read_directory(wchar_t * dirname, struct ext_table * contents) +CAMLexport int caml_read_directory(wchar_t * dirname, + struct ext_table * contents) { size_t dirnamelen; wchar_t * template; @@ -539,7 +532,8 @@ static LONG CALLBACK DWORD *ctx_ip = &(ctx->Eip); DWORD *ctx_sp = &(ctx->Esp); - if (code == EXCEPTION_STACK_OVERFLOW && Is_in_code_area (*ctx_ip)) + if (code == EXCEPTION_STACK_OVERFLOW && + caml_find_code_fragment_by_pc((char *) (*ctx_ip)) != NULL) { uintnat faulting_address; uintnat * alt_esp; @@ -561,24 +555,14 @@ static LONG CALLBACK #else -/* Do not use the macro from address_class.h here. */ -#undef Is_in_code_area -#define Is_in_code_area(pc) \ - ( ((char *)(pc) >= caml_code_area_start && \ - (char *)(pc) <= caml_code_area_end) \ -|| ((char *)(pc) >= &caml_system__code_begin && \ - (char *)(pc) <= &caml_system__code_end) \ -|| (Classify_addr(pc) & In_code_area) ) -extern char caml_system__code_begin, caml_system__code_end; - - static LONG CALLBACK caml_stack_overflow_VEH (EXCEPTION_POINTERS* exn_info) { DWORD code = exn_info->ExceptionRecord->ExceptionCode; CONTEXT *ctx = exn_info->ContextRecord; - if (code == EXCEPTION_STACK_OVERFLOW && Is_in_code_area (ctx->Rip)) + if (code == EXCEPTION_STACK_OVERFLOW && + caml_find_code_fragment_by_pc((char *) (ctx->Rip)) != NULL) { uintnat faulting_address; uintnat * alt_rsp; diff --git a/stdlib/.depend b/stdlib/.depend index 2c167666..30eeb857 100644 --- a/stdlib/.depend +++ b/stdlib/.depend @@ -31,6 +31,13 @@ stdlib__arrayLabels.cmx : \ stdlib__arrayLabels.cmi stdlib__arrayLabels.cmi : \ stdlib__seq.cmi +stdlib__atomic.cmo : \ + camlinternalAtomic.cmi \ + stdlib__atomic.cmi +stdlib__atomic.cmx : \ + camlinternalAtomic.cmx \ + stdlib__atomic.cmi +stdlib__atomic.cmi : stdlib__bigarray.cmo : \ stdlib__sys.cmi \ stdlib__complex.cmi \ @@ -98,6 +105,11 @@ stdlib__callback.cmx : \ stdlib__obj.cmx \ stdlib__callback.cmi stdlib__callback.cmi : +camlinternalAtomic.cmo : \ + camlinternalAtomic.cmi +camlinternalAtomic.cmx : \ + camlinternalAtomic.cmi +camlinternalAtomic.cmi : camlinternalFormat.cmo : \ stdlib__sys.cmi \ stdlib__string.cmi \ @@ -125,21 +137,25 @@ camlinternalFormatBasics.cmx : \ camlinternalFormatBasics.cmi camlinternalFormatBasics.cmi : camlinternalLazy.cmo : \ + stdlib__sys.cmi \ stdlib__obj.cmi \ camlinternalLazy.cmi camlinternalLazy.cmx : \ + stdlib__sys.cmx \ stdlib__obj.cmx \ camlinternalLazy.cmi camlinternalLazy.cmi : camlinternalMod.cmo : \ stdlib__sys.cmi \ stdlib__obj.cmi \ + stdlib__nativeint.cmi \ camlinternalOO.cmi \ stdlib__array.cmi \ camlinternalMod.cmi camlinternalMod.cmx : \ stdlib__sys.cmx \ stdlib__obj.cmx \ + stdlib__nativeint.cmx \ camlinternalOO.cmx \ stdlib__array.cmx \ camlinternalMod.cmi @@ -186,6 +202,11 @@ stdlib__digest.cmx : \ stdlib__bytes.cmx \ stdlib__digest.cmi stdlib__digest.cmi : +stdlib__either.cmo : \ + stdlib__either.cmi +stdlib__either.cmx : \ + stdlib__either.cmi +stdlib__either.cmi : stdlib__ephemeron.cmo : \ stdlib__sys.cmi \ stdlib__seq.cmi \ @@ -244,6 +265,7 @@ stdlib__format.cmo : \ stdlib__string.cmi \ stdlib.cmi \ stdlib__stack.cmi \ + stdlib__seq.cmi \ stdlib__queue.cmi \ stdlib__list.cmi \ stdlib__int.cmi \ @@ -255,6 +277,7 @@ stdlib__format.cmx : \ stdlib__string.cmx \ stdlib.cmx \ stdlib__stack.cmx \ + stdlib__seq.cmx \ stdlib__queue.cmx \ stdlib__list.cmx \ stdlib__int.cmx \ @@ -264,6 +287,7 @@ stdlib__format.cmx : \ stdlib__format.cmi stdlib__format.cmi : \ stdlib.cmi \ + stdlib__seq.cmi \ stdlib__buffer.cmi stdlib__fun.cmo : \ stdlib__printexc.cmi \ @@ -373,13 +397,16 @@ stdlib__lexing.cmi : stdlib__list.cmo : \ stdlib__sys.cmi \ stdlib__seq.cmi \ + stdlib__either.cmi \ stdlib__list.cmi stdlib__list.cmx : \ stdlib__sys.cmx \ stdlib__seq.cmx \ + stdlib__either.cmx \ stdlib__list.cmi stdlib__list.cmi : \ - stdlib__seq.cmi + stdlib__seq.cmi \ + stdlib__either.cmi stdlib__listLabels.cmo : \ stdlib__list.cmi \ stdlib__listLabels.cmi @@ -387,7 +414,8 @@ stdlib__listLabels.cmx : \ stdlib__list.cmx \ stdlib__listLabels.cmi stdlib__listLabels.cmi : \ - stdlib__seq.cmi + stdlib__seq.cmi \ + stdlib__either.cmi stdlib__map.cmo : \ stdlib__seq.cmi \ stdlib__map.cmi @@ -429,11 +457,13 @@ stdlib__nativeint.cmx : \ stdlib__nativeint.cmi : stdlib__obj.cmo : \ stdlib__sys.cmi \ + stdlib__nativeint.cmi \ stdlib__marshal.cmi \ stdlib__int32.cmi \ stdlib__obj.cmi stdlib__obj.cmx : \ stdlib__sys.cmx \ + stdlib__nativeint.cmx \ stdlib__marshal.cmx \ stdlib__int32.cmx \ stdlib__obj.cmi @@ -477,6 +507,7 @@ stdlib__printexc.cmo : \ stdlib__printf.cmi \ stdlib__obj.cmi \ stdlib__buffer.cmi \ + stdlib__atomic.cmi \ stdlib__array.cmi \ stdlib__printexc.cmi stdlib__printexc.cmx : \ @@ -484,6 +515,7 @@ stdlib__printexc.cmx : \ stdlib__printf.cmx \ stdlib__obj.cmx \ stdlib__buffer.cmx \ + stdlib__atomic.cmx \ stdlib__array.cmx \ stdlib__printexc.cmi stdlib__printexc.cmi : @@ -578,13 +610,6 @@ stdlib__set.cmx : \ stdlib__set.cmi stdlib__set.cmi : \ stdlib__seq.cmi -stdlib__spacetime.cmo : \ - stdlib__gc.cmi \ - stdlib__spacetime.cmi -stdlib__spacetime.cmx : \ - stdlib__gc.cmx \ - stdlib__spacetime.cmi -stdlib__spacetime.cmi : stdlib__stack.cmo : \ stdlib__seq.cmi \ stdlib__list.cmi \ @@ -680,9 +705,11 @@ stdlib__weak.cmi : \ stdlib__hashtbl.cmi stdlib.cmo : \ camlinternalFormatBasics.cmi \ + camlinternalAtomic.cmi \ stdlib.cmi stdlib.cmx : \ camlinternalFormatBasics.cmx \ + camlinternalAtomic.cmx \ stdlib.cmi stdlib.cmi : \ camlinternalFormatBasics.cmi diff --git a/stdlib/Compflags b/stdlib/Compflags index e2262d3c..066e1dc4 100755 --- a/stdlib/Compflags +++ b/stdlib/Compflags @@ -18,6 +18,10 @@ case $1 in stdlib.cm[iox]) echo ' -nopervasives -no-alias-deps -w -49' \ ' -pp "$AWK -f ./expand_module_aliases.awk"';; + # stdlib dependencies + camlinternalFormatBasics*.cm[iox]) echo ' -nopervasives';; + camlinternalAtomic.cm[iox]) echo ' -nopervasives';; + # end stdlib dependencies camlinternalOO.cmx) echo ' -inline 0 -afl-inst-ratio 0';; camlinternalLazy.cmx) echo ' -afl-inst-ratio 0';; # never instrument camlinternalOO or camlinternalLazy (PR#7725) @@ -25,11 +29,13 @@ case $1 in # make sure add_char is inlined (PR#5872) stdlib__buffer.cm[io]) echo ' -w A';; camlinternalFormat.cm[io]) echo ' -w Ae';; - camlinternalFormatBasics*.cm[iox]) echo ' -nopervasives';; stdlib__printf.cm[io]|stdlib__format.cm[io]|stdlib__scanf.cm[io]) echo ' -w Ae';; stdlib__scanf.cmx) echo ' -inline 9';; + *Labels.cmi) echo ' -pp "$AWK -f ./expand_module_aliases.awk"';; *Labels.cm[ox]) echo ' -nolabels -no-alias-deps';; stdlib__float.cm[ox]) echo ' -nolabels -no-alias-deps';; + stdlib__oo.cmi) echo ' -no-principal';; + # preserve structure sharing in Oo.copy (PR#9767) *) echo ' ';; esac diff --git a/stdlib/HACKING.adoc b/stdlib/HACKING.adoc index c29a513a..fbd40173 100644 --- a/stdlib/HACKING.adoc +++ b/stdlib/HACKING.adoc @@ -13,7 +13,7 @@ To add a new module, you must: * Create new `.mli` and `.ml` files for the modules, obviously. * Define the module in `stdlib/stdlib.mli` and `stdlib/stdlib.ml` in - the section of the code commented "MODULE ALIASES". Please maintain + the section of the code commented "MODULE_ALIASES". Please maintain the same style as the rest of the code, in particular the alphabetical ordering and whitespace alignment of module aliases. diff --git a/stdlib/Makefile b/stdlib/Makefile index 0b92fe1e..4a4c5347 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -15,20 +15,19 @@ ROOTDIR = .. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common +include $(ROOTDIR)/Makefile.common TARGET_BINDIR ?= $(BINDIR) -COMPILER=$(ROOTDIR)/ocamlc +COMPILER=$(ROOTDIR)/ocamlc$(EXE) CAMLC=$(CAMLRUN) $(COMPILER) COMPFLAGS=-strict-sequence -absname -w +a-4-9-41-42-44-45-48 \ - -g -warn-error A -bin-annot -nostdlib \ + -g -warn-error A -bin-annot -nostdlib -principal \ -safe-string -strict-formats ifeq "$(FLAMBDA)" "true" OPTCOMPFLAGS += -O3 endif -OPTCOMPILER=$(ROOTDIR)/ocamlopt +OPTCOMPILER=$(ROOTDIR)/ocamlopt$(EXE) CAMLOPT=$(CAMLRUN) $(OPTCOMPILER) CAMLDEP=$(BOOT_OCAMLC) -depend DEPFLAGS=-slash @@ -38,7 +37,8 @@ OC_CPPFLAGS += -I$(ROOTDIR)/runtime include StdlibModules OBJS=$(addsuffix .cmo,$(STDLIB_MODULES)) -OTHERS=$(filter-out camlinternalFormatBasics.cmo stdlib.cmo,$(OBJS)) +NOSTDLIB= camlinternalFormatBasics.cmo camlinternalAtomic.cmo stdlib.cmo +OTHERS=$(filter-out $(NOSTDLIB),$(OBJS)) PREFIXED_OBJS=$(filter stdlib__%.cmo,$(OBJS)) UNPREFIXED_OBJS=$(PREFIXED_OBJS:stdlib__%.cmo=%) @@ -58,17 +58,8 @@ endif allopt: stdlib.cmxa std_exit.cmx opt.opt: allopt -LEGACY_OBJS=$(patsubst stdlib__%,"$(INSTALL_LIBDIR)/%", \ - $(filter stdlib__%,$(OBJS))) .PHONY: install install:: -# Transitional: when upgrading from 4.06 -> 4.07, module M is in stdlib__m.cm*, -# while previously it was in m.cm*, which confuses the compiler. - rm -f $(LEGACY_OBJS) -# Remove "old" pervasives.* and bigarray.* to avoid getting confused with the -# Stdlib versions. - rm -f "$(INSTALL_LIBDIR)/pervasives.*" "$(INSTALL_LIBDIR)/bigarray.*" -# End transitional $(INSTALL_DATA) \ stdlib.cma std_exit.cmo *.cmi camlheader_ur \ "$(INSTALL_LIBDIR)" @@ -160,7 +151,8 @@ $(HEADERPROGRAM)%$(O): \ OC_CPPFLAGS += -DRUNTIME_NAME='"$(HEADER_PATH)ocamlrun$(subst .,,$*)"' $(HEADERPROGRAM)%$(O): $(HEADERPROGRAM).c - $(CC) -c $(OC_CFLAGS) $(OC_CPPFLAGS) $(OUTPUTOBJ)$@ $^ + $(CC) -c $(OC_CFLAGS) $(CFLAGS) $(OC_CPPFLAGS) $(CPPFLAGS) \ + $(OUTPUTOBJ)$@ $^ camlheader_ur: camlheader cp camlheader $@ @@ -171,7 +163,7 @@ tmptargetcamlheader%exe: $(TARGETHEADERPROGRAM)%$(O) strip $@ $(TARGETHEADERPROGRAM)%$(O): $(HEADERPROGRAM).c - $(CC) -c $(OC_CFLAGS) $(OC_CPPFLAGS) \ + $(CC) -c $(OC_CFLAGS) $(CFLAGS) $(OC_CPPFLAGS) $(CPPFLAGS) \ -DRUNTIME_NAME='"$(HEADER_TARGET_PATH)ocamlrun$(subst .,,$*)"' \ $(OUTPUTOBJ)$@ $^ @@ -239,7 +231,6 @@ $(OTHERS:.cmo=.cmx) std_exit.cmx: stdlib.cmx clean:: rm -f *.cm* *.o *.obj *.a *.lib *.odoc - rm -f camlheader* include .depend diff --git a/stdlib/StdlibModules b/stdlib/StdlibModules index cb21a671..4f475ba8 100644 --- a/stdlib/StdlibModules +++ b/stdlib/StdlibModules @@ -30,13 +30,15 @@ endef # Modules should be listed in dependency order. STDLIB_MODS=\ - camlinternalFormatBasics stdlib pervasives seq option result bool char uchar \ + camlinternalFormatBasics camlinternalAtomic \ + stdlib pervasives seq option either result bool char uchar \ sys list bytes string unit marshal obj array float int int32 int64 nativeint \ lexing parsing set map stack queue camlinternalLazy lazy stream buffer \ - camlinternalFormat printf arg printexc fun gc digest random hashtbl weak \ + camlinternalFormat printf arg atomic \ + printexc fun gc digest random hashtbl weak \ format scanf callback camlinternalOO oo camlinternalMod genlex ephemeron \ filename complex arrayLabels listLabels bytesLabels stringLabels moreLabels \ - stdLabels spacetime bigarray + stdLabels bigarray STDLIB_MODULES=\ $(foreach module, $(STDLIB_MODS), $(call add_stdlib_prefix,$(module))) diff --git a/stdlib/arg.ml b/stdlib/arg.ml index 64e63d77..909e88cc 100644 --- a/stdlib/arg.ml +++ b/stdlib/arg.ml @@ -36,6 +36,9 @@ type spec = call the function with the symbol. *) | Rest of (string -> unit) (* Stop interpreting keywords and call the function with each remaining argument *) + | Rest_all of (string list -> unit) + (* Stop interpreting keywords and call the + function with all remaining arguments. *) | Expand of (string -> string array) (* If the remaining arguments to process are of the form [["-foo"; "arg"] @ rest] where "foo" @@ -251,6 +254,14 @@ let parse_and_expand_argv_dynamic_aux allow_expand current argv speclist anonfun f !argv.(!current + 1); consume_arg (); done; + | Rest_all f -> + no_arg (); + let acc = ref [] in + while !current < Array.length !argv - 1 do + acc := !argv.(!current + 1) :: !acc; + consume_arg (); + done; + f (List.rev !acc) | Expand f -> if not allow_expand then raise (Invalid_argument "Arg.Expand is is only allowed with \ diff --git a/stdlib/arg.mli b/stdlib/arg.mli index 3f3116c5..2ea0ad50 100644 --- a/stdlib/arg.mli +++ b/stdlib/arg.mli @@ -16,16 +16,38 @@ (** Parsing of command line arguments. This module provides a general mechanism for extracting options and - arguments from the command line to the program. + arguments from the command line to the program. For example: + +{[ + let usage_msg = "append [-verbose] [] ... -o " + let verbose = ref false + let input_files = ref [] + let output_file = ref "" + + let anon_fun filename = + input_files := filename::!input_files + + let speclist = + [("-verbose", Arg.Set verbose, "Output debug information"); + ("-o", Arg.Set_string output_file, "Set output file name")] + + let () = + Arg.parse speclist anon_fun usage_msg; + (* Main functionality here *) +]} Syntax of command lines: A keyword is a character string starting with a [-]. An option is a keyword alone or followed by an argument. The types of keywords are: [Unit], [Bool], [Set], [Clear], [String], [Set_string], [Int], [Set_int], [Float], [Set_float], - [Tuple], [Symbol], and [Rest]. - [Unit], [Set] and [Clear] keywords take no argument. A [Rest] - keyword takes the remaining of the command line as arguments. + [Tuple], [Symbol], [Rest], [Rest_all] and [Expand]. + + [Unit], [Set] and [Clear] keywords take no argument. + + A [Rest] or [Rest_all] keyword takes the remainder of the command line + as arguments. (More explanations below.) + Every other keyword takes the following word on the command line as argument. For compatibility with GNU getopt_long, [keyword=arg] is also allowed. @@ -39,6 +61,14 @@ - [cmd a b c ](three anonymous arguments: ["a"], ["b"], and ["c"]) - [cmd a b -- c d ](two anonymous arguments and a rest option with two arguments) + + [Rest] takes a function that is called repeatedly for each + remaining command line argument. [Rest_all] takes a function that + is called once, with the list of all remaining arguments. + + Note that if no arguments follow a [Rest] keyword then the function + is not called at all whereas the function for a [Rest_all] keyword + is called with an empty list. *) type spec = @@ -59,6 +89,9 @@ type spec = call the function with the symbol *) | Rest of (string -> unit) (** Stop interpreting keywords and call the function with each remaining argument *) + | Rest_all of (string list -> unit) + (** Stop interpreting keywords and call the + function with all remaining arguments *) | Expand of (string -> string array) (** If the remaining arguments to process are of the form [["-foo"; "arg"] @ rest] where "foo" diff --git a/stdlib/array.mli b/stdlib/array.mli index 9a08d666..489cb234 100644 --- a/stdlib/array.mli +++ b/stdlib/array.mli @@ -13,157 +13,180 @@ (* *) (**************************************************************************) +(* NOTE: + If this file is arrayLabels.mli, run tools/sync_stdlib_docs after editing it + to generate array.mli. + + If this file is array.mli, do not edit it directly -- edit + arrayLabels.mli instead. + *) + +(** Array operations. + + The labeled version of this module can be used as described in the + {!StdLabels} module. +*) + type 'a t = 'a array (** An alias for the type of arrays. *) -(** Array operations. *) - external length : 'a array -> int = "%array_length" (** Return the length (number of elements) of the given array. *) external get : 'a array -> int -> 'a = "%array_safe_get" -(** [Array.get a n] returns the element number [n] of array [a]. +(** [get a n] returns the element number [n] of array [a]. The first element has number 0. - The last element has number [Array.length a - 1]. - You can also write [a.(n)] instead of [Array.get a n]. + The last element has number [length a - 1]. + You can also write [a.(n)] instead of [get a n]. + @raise Invalid_argument - if [n] is outside the range 0 to [(Array.length a - 1)]. *) + if [n] is outside the range 0 to [(length a - 1)]. *) external set : 'a array -> int -> 'a -> unit = "%array_safe_set" -(** [Array.set a n x] modifies array [a] in place, replacing +(** [set a n x] modifies array [a] in place, replacing element number [n] with [x]. - You can also write [a.(n) <- x] instead of [Array.set a n x]. + You can also write [a.(n) <- x] instead of [set a n x]. + @raise Invalid_argument - if [n] is outside the range 0 to [Array.length a - 1]. *) + if [n] is outside the range 0 to [length a - 1]. *) external make : int -> 'a -> 'a array = "caml_make_vect" -(** [Array.make n x] returns a fresh array of length [n], +(** [make n x] returns a fresh array of length [n], initialized with [x]. All the elements of this new array are initially physically equal to [x] (in the sense of the [==] predicate). Consequently, if [x] is mutable, it is shared among all elements of the array, and modifying [x] through one of the array entries will modify all other entries at the same time. + @raise Invalid_argument if [n < 0] or [n > Sys.max_array_length]. If the value of [x] is a floating-point number, then the maximum size is only [Sys.max_array_length / 2].*) external create : int -> 'a -> 'a array = "caml_make_vect" - [@@ocaml.deprecated "Use Array.make instead."] -(** @deprecated [Array.create] is an alias for {!Array.make}. *) + [@@ocaml.deprecated "Use Array.make/ArrayLabels.make instead."] +(** @deprecated [create] is an alias for {!make}. *) external create_float: int -> float array = "caml_make_float_vect" -(** [Array.create_float n] returns a fresh float array of length [n], +(** [create_float n] returns a fresh float array of length [n], with uninitialized data. @since 4.03 *) val make_float: int -> float array - [@@ocaml.deprecated "Use Array.create_float instead."] -(** @deprecated [Array.make_float] is an alias for {!Array.create_float}. *) + [@@ocaml.deprecated + "Use Array.create_float/ArrayLabels.create_float instead."] +(** @deprecated [make_float] is an alias for {!create_float}. *) val init : int -> (int -> 'a) -> 'a array -(** [Array.init n f] returns a fresh array of length [n], +(** [init n f] returns a fresh array of length [n], with element number [i] initialized to the result of [f i]. - In other terms, [Array.init n f] tabulates the results of [f] + In other terms, [init n f] tabulates the results of [f] applied to the integers [0] to [n-1]. + @raise Invalid_argument if [n < 0] or [n > Sys.max_array_length]. If the return type of [f] is [float], then the maximum size is only [Sys.max_array_length / 2].*) val make_matrix : int -> int -> 'a -> 'a array array -(** [Array.make_matrix dimx dimy e] returns a two-dimensional array +(** [make_matrix dimx dimy e] returns a two-dimensional array (an array of arrays) with first dimension [dimx] and second dimension [dimy]. All the elements of this new matrix are initially physically equal to [e]. The element ([x,y]) of a matrix [m] is accessed with the notation [m.(x).(y)]. + @raise Invalid_argument if [dimx] or [dimy] is negative or greater than {!Sys.max_array_length}. If the value of [e] is a floating-point number, then the maximum size is only [Sys.max_array_length / 2]. *) val create_matrix : int -> int -> 'a -> 'a array array - [@@ocaml.deprecated "Use Array.make_matrix instead."] -(** @deprecated [Array.create_matrix] is an alias for {!Array.make_matrix}. *) + [@@ocaml.deprecated + "Use Array.make_matrix/ArrayLabels.make_matrix instead."] +(** @deprecated [create_matrix] is an alias for {!make_matrix}. *) val append : 'a array -> 'a array -> 'a array -(** [Array.append v1 v2] returns a fresh array containing the +(** [append v1 v2] returns a fresh array containing the concatenation of the arrays [v1] and [v2]. @raise Invalid_argument if - [Array.length v1 + Array.length v2 > Sys.max_array_length]. *) + [length v1 + length v2 > Sys.max_array_length]. *) val concat : 'a array list -> 'a array -(** Same as {!Array.append}, but concatenates a list of arrays. *) +(** Same as {!append}, but concatenates a list of arrays. *) val sub : 'a array -> int -> int -> 'a array -(** [Array.sub a start len] returns a fresh array of length [len], - containing the elements number [start] to [start + len - 1] +(** [sub a pos len] returns a fresh array of length [len], + containing the elements number [pos] to [pos + len - 1] of array [a]. - @raise Invalid_argument if [start] and [len] do not + + @raise Invalid_argument if [pos] and [len] do not designate a valid subarray of [a]; that is, if - [start < 0], or [len < 0], or [start + len > Array.length a]. *) + [pos < 0], or [len < 0], or [pos + len > length a]. *) val copy : 'a array -> 'a array -(** [Array.copy a] returns a copy of [a], that is, a fresh array +(** [copy a] returns a copy of [a], that is, a fresh array containing the same elements as [a]. *) val fill : 'a array -> int -> int -> 'a -> unit -(** [Array.fill a ofs len x] modifies the array [a] in place, - storing [x] in elements number [ofs] to [ofs + len - 1]. - @raise Invalid_argument if [ofs] and [len] do not +(** [fill a pos len x] modifies the array [a] in place, + storing [x] in elements number [pos] to [pos + len - 1]. + + @raise Invalid_argument if [pos] and [len] do not designate a valid subarray of [a]. *) -val blit : 'a array -> int -> 'a array -> int -> int -> unit -(** [Array.blit v1 o1 v2 o2 len] copies [len] elements - from array [v1], starting at element number [o1], to array [v2], - starting at element number [o2]. It works correctly even if - [v1] and [v2] are the same array, and the source and +val blit : + 'a array -> int -> 'a array -> int -> int -> + unit +(** [blit src src_pos dst dst_pos len] copies [len] elements + from array [src], starting at element number [src_pos], to array [dst], + starting at element number [dst_pos]. It works correctly even if + [src] and [dst] are the same array, and the source and destination chunks overlap. - @raise Invalid_argument if [o1] and [len] do not - designate a valid subarray of [v1], or if [o2] and [len] do not - designate a valid subarray of [v2]. *) + + @raise Invalid_argument if [src_pos] and [len] do not + designate a valid subarray of [src], or if [dst_pos] and [len] do not + designate a valid subarray of [dst]. *) val to_list : 'a array -> 'a list -(** [Array.to_list a] returns the list of all the elements of [a]. *) +(** [to_list a] returns the list of all the elements of [a]. *) val of_list : 'a list -> 'a array -(** [Array.of_list l] returns a fresh array containing the elements +(** [of_list l] returns a fresh array containing the elements of [l]. - @raise Invalid_argument if the length of [l] is greater than - [Sys.max_array_length].*) + @raise Invalid_argument if the length of [l] is greater than + [Sys.max_array_length]. *) (** {1 Iterators} *) - val iter : ('a -> unit) -> 'a array -> unit -(** [Array.iter f a] applies function [f] in turn to all +(** [iter f a] applies function [f] in turn to all the elements of [a]. It is equivalent to - [f a.(0); f a.(1); ...; f a.(Array.length a - 1); ()]. *) + [f a.(0); f a.(1); ...; f a.(length a - 1); ()]. *) val iteri : (int -> 'a -> unit) -> 'a array -> unit -(** Same as {!Array.iter}, but the - function is applied with the index of the element as first argument, +(** Same as {!iter}, but the + function is applied to the index of the element as first argument, and the element itself as second argument. *) val map : ('a -> 'b) -> 'a array -> 'b array -(** [Array.map f a] applies function [f] to all the elements of [a], +(** [map f a] applies function [f] to all the elements of [a], and builds an array with the results returned by [f]: - [[| f a.(0); f a.(1); ...; f a.(Array.length a - 1) |]]. *) + [[| f a.(0); f a.(1); ...; f a.(length a - 1) |]]. *) val mapi : (int -> 'a -> 'b) -> 'a array -> 'b array -(** Same as {!Array.map}, but the +(** Same as {!map}, but the function is applied to the index of the element as first argument, and the element itself as second argument. *) val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b array -> 'a -(** [Array.fold_left f x a] computes - [f (... (f (f x a.(0)) a.(1)) ...) a.(n-1)], +(** [fold_left f init a] computes + [f (... (f (f init a.(0)) a.(1)) ...) a.(n-1)], where [n] is the length of the array [a]. *) val fold_right : ('b -> 'a -> 'a) -> 'b array -> 'a -> 'a -(** [Array.fold_right f a x] computes - [f a.(0) (f a.(1) ( ... (f a.(n-1) x) ...))], +(** [fold_right f a init] computes + [f a.(0) (f a.(1) ( ... (f a.(n-1) init) ...))], where [n] is the length of the array [a]. *) @@ -171,68 +194,67 @@ val fold_right : ('b -> 'a -> 'a) -> 'b array -> 'a -> 'a val iter2 : ('a -> 'b -> unit) -> 'a array -> 'b array -> unit -(** [Array.iter2 f a b] applies function [f] to all the elements of [a] +(** [iter2 f a b] applies function [f] to all the elements of [a] and [b]. @raise Invalid_argument if the arrays are not the same size. - @since 4.03.0 *) + @since 4.03.0 (4.05.0 in ArrayLabels) + *) val map2 : ('a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array -(** [Array.map2 f a b] applies function [f] to all the elements of [a] +(** [map2 f a b] applies function [f] to all the elements of [a] and [b], and builds an array with the results returned by [f]: - [[| f a.(0) b.(0); ...; f a.(Array.length a - 1) b.(Array.length b - 1)|]]. + [[| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|]]. @raise Invalid_argument if the arrays are not the same size. - @since 4.03.0 *) + @since 4.03.0 (4.05.0 in ArrayLabels) *) (** {1 Array scanning} *) - val for_all : ('a -> bool) -> 'a array -> bool -(** [Array.for_all p [|a1; ...; an|]] checks if all elements of the array - satisfy the predicate [p]. That is, it returns - [(p a1) && (p a2) && ... && (p an)]. +(** [for_all f [|a1; ...; an|]] checks if all elements + of the array satisfy the predicate [f]. That is, it returns + [(f a1) && (f a2) && ... && (f an)]. @since 4.03.0 *) val exists : ('a -> bool) -> 'a array -> bool -(** [Array.exists p [|a1; ...; an|]] checks if at least one element of - the array satisfies the predicate [p]. That is, it returns - [(p a1) || (p a2) || ... || (p an)]. +(** [exists f [|a1; ...; an|]] checks if at least one element of + the array satisfies the predicate [f]. That is, it returns + [(f a1) || (f a2) || ... || (f an)]. @since 4.03.0 *) val for_all2 : ('a -> 'b -> bool) -> 'a array -> 'b array -> bool -(** Same as {!Array.for_all}, but for a two-argument predicate. +(** Same as {!for_all}, but for a two-argument predicate. @raise Invalid_argument if the two arrays have different lengths. @since 4.11.0 *) val exists2 : ('a -> 'b -> bool) -> 'a array -> 'b array -> bool -(** Same as {!Array.exists}, but for a two-argument predicate. +(** Same as {!exists}, but for a two-argument predicate. @raise Invalid_argument if the two arrays have different lengths. @since 4.11.0 *) val mem : 'a -> 'a array -> bool -(** [mem a l] is true if and only if [a] is structurally equal +(** [mem a set] is true if and only if [a] is structurally equal to an element of [l] (i.e. there is an [x] in [l] such that [compare a x = 0]). @since 4.03.0 *) val memq : 'a -> 'a array -> bool -(** Same as {!Array.mem}, but uses physical equality instead of structural - equality to compare elements. +(** Same as {!mem}, but uses physical equality + instead of structural equality to compare list elements. @since 4.03.0 *) (** {1 Sorting} *) - val sort : ('a -> 'a -> int) -> 'a array -> unit (** Sort an array in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see below for a complete specification). For example, {!Stdlib.compare} is - a suitable comparison function. After calling [Array.sort], the + a suitable comparison function. After calling [sort], the array is sorted in place in increasing order. - [Array.sort] is guaranteed to run in constant heap space + [sort] is guaranteed to run in constant heap space and (at most) logarithmic stack space. The current implementation uses Heap Sort. It runs in constant @@ -244,25 +266,24 @@ val sort : ('a -> 'a -> int) -> 'a array -> unit - [cmp x y] > 0 if and only if [cmp y x] < 0 - if [cmp x y] >= 0 and [cmp y z] >= 0 then [cmp x z] >= 0 - When [Array.sort] returns, [a] contains the same elements as before, + When [sort] returns, [a] contains the same elements as before, reordered in such a way that for all i and j valid indices of [a] : - [cmp a.(i) a.(j)] >= 0 if and only if i >= j *) val stable_sort : ('a -> 'a -> int) -> 'a array -> unit -(** Same as {!Array.sort}, but the sorting algorithm is stable (i.e. +(** Same as {!sort}, but the sorting algorithm is stable (i.e. elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space. - The current implementation uses Merge Sort. It uses a temporary - array of length [n/2], where [n] is the length of the array. - It is usually faster than the current implementation of {!Array.sort}. + The current implementation uses Merge Sort. It uses a temporary array of + length [n/2], where [n] is the length of the array. It is usually faster + than the current implementation of {!sort}. *) val fast_sort : ('a -> 'a -> int) -> 'a array -> unit -(** Same as {!Array.sort} or {!Array.stable_sort}, whichever is faster - on typical input. -*) +(** Same as {!sort} or {!stable_sort}, whichever is + faster on typical input. *) (** {1 Iterators} *) @@ -283,6 +304,7 @@ val of_seq : 'a Seq.t -> 'a array @since 4.07 *) (**/**) + (** {1 Undocumented functions} *) (* The following is for system use only. Do not call directly. *) diff --git a/stdlib/arrayLabels.mli b/stdlib/arrayLabels.mli index a83a3ea4..9ac8d956 100644 --- a/stdlib/arrayLabels.mli +++ b/stdlib/arrayLabels.mli @@ -13,17 +13,19 @@ (* *) (**************************************************************************) -(** Array operations +(* NOTE: + If this file is arrayLabels.mli, run tools/sync_stdlib_docs after editing it + to generate array.mli. - This module is intended to be used via {!StdLabels} which replaces - {!Array}, {!Bytes}, {!List} and {!String} with their labeled counterparts + If this file is array.mli, do not edit it directly -- edit + arrayLabels.mli instead. + *) - For example: - {[ - open StdLabels +(** Array operations. - let everything = Array.create_matrix ~dimx:42 ~dimy:42 42 - ]} *) + The labeled version of this module can be used as described in the + {!StdLabels} module. +*) type 'a t = 'a array (** An alias for the type of arrays. *) @@ -62,9 +64,19 @@ external make : int -> 'a -> 'a array = "caml_make_vect" size is only [Sys.max_array_length / 2].*) external create : int -> 'a -> 'a array = "caml_make_vect" - [@@ocaml.deprecated "Use Array.make instead."] + [@@ocaml.deprecated "Use Array.make/ArrayLabels.make instead."] (** @deprecated [create] is an alias for {!make}. *) +external create_float: int -> float array = "caml_make_float_vect" +(** [create_float n] returns a fresh float array of length [n], + with uninitialized data. + @since 4.03 *) + +val make_float: int -> float array + [@@ocaml.deprecated + "Use Array.create_float/ArrayLabels.create_float instead."] +(** @deprecated [make_float] is an alias for {!create_float}. *) + val init : int -> f:(int -> 'a) -> 'a array (** [init n ~f] returns a fresh array of length [n], with element number [i] initialized to the result of [f i]. @@ -89,12 +101,15 @@ val make_matrix : dimx:int -> dimy:int -> 'a -> 'a array array size is only [Sys.max_array_length / 2]. *) val create_matrix : dimx:int -> dimy:int -> 'a -> 'a array array - [@@ocaml.deprecated "Use Array.make_matrix instead."] + [@@ocaml.deprecated + "Use Array.make_matrix/ArrayLabels.make_matrix instead."] (** @deprecated [create_matrix] is an alias for {!make_matrix}. *) val append : 'a array -> 'a array -> 'a array (** [append v1 v2] returns a fresh array containing the - concatenation of the arrays [v1] and [v2]. *) + concatenation of the arrays [v1] and [v2]. + @raise Invalid_argument if + [length v1 + length v2 > Sys.max_array_length]. *) val concat : 'a array list -> 'a array (** Same as {!append}, but concatenates a list of arrays. *) @@ -137,23 +152,28 @@ val to_list : 'a array -> 'a list val of_list : 'a list -> 'a array (** [of_list l] returns a fresh array containing the elements - of [l]. *) + of [l]. + + @raise Invalid_argument if the length of [l] is greater than + [Sys.max_array_length]. *) + +(** {1 Iterators} *) val iter : f:('a -> unit) -> 'a array -> unit (** [iter ~f a] applies function [f] in turn to all the elements of [a]. It is equivalent to [f a.(0); f a.(1); ...; f a.(length a - 1); ()]. *) -val map : f:('a -> 'b) -> 'a array -> 'b array -(** [map ~f a] applies function [f] to all the elements of [a], - and builds an array with the results returned by [f]: - [[| f a.(0); f a.(1); ...; f a.(length a - 1) |]]. *) - val iteri : f:(int -> 'a -> unit) -> 'a array -> unit (** Same as {!iter}, but the function is applied to the index of the element as first argument, and the element itself as second argument. *) +val map : f:('a -> 'b) -> 'a array -> 'b array +(** [map ~f a] applies function [f] to all the elements of [a], + and builds an array with the results returned by [f]: + [[| f a.(0); f a.(1); ...; f a.(length a - 1) |]]. *) + val mapi : f:(int -> 'a -> 'b) -> 'a array -> 'b array (** Same as {!map}, but the function is applied to the index of the element as first argument, @@ -177,18 +197,24 @@ val iter2 : f:('a -> 'b -> unit) -> 'a array -> 'b array -> unit (** [iter2 ~f a b] applies function [f] to all the elements of [a] and [b]. @raise Invalid_argument if the arrays are not the same size. - @since 4.05.0 *) + @since 4.03.0 (4.05.0 in ArrayLabels) + *) val map2 : f:('a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array (** [map2 ~f a b] applies function [f] to all the elements of [a] and [b], and builds an array with the results returned by [f]: [[| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|]]. @raise Invalid_argument if the arrays are not the same size. - @since 4.05.0 *) + @since 4.03.0 (4.05.0 in ArrayLabels) *) (** {1 Array scanning} *) +val for_all : f:('a -> bool) -> 'a array -> bool +(** [for_all ~f [|a1; ...; an|]] checks if all elements + of the array satisfy the predicate [f]. That is, it returns + [(f a1) && (f a2) && ... && (f an)]. + @since 4.03.0 *) val exists : f:('a -> bool) -> 'a array -> bool (** [exists ~f [|a1; ...; an|]] checks if at least one element of @@ -196,54 +222,37 @@ val exists : f:('a -> bool) -> 'a array -> bool [(f a1) || (f a2) || ... || (f an)]. @since 4.03.0 *) -val for_all : f:('a -> bool) -> 'a array -> bool -(** [for_all ~f [|a1; ...; an|]] checks if all elements - of the array satisfy the predicate [f]. That is, it returns - [(f a1) && (f a2) && ... && (f an)]. - @since 4.03.0 *) - val for_all2 : f:('a -> 'b -> bool) -> 'a array -> 'b array -> bool -(** Same as {!ArrayLabels.for_all}, but for a two-argument predicate. +(** Same as {!for_all}, but for a two-argument predicate. @raise Invalid_argument if the two arrays have different lengths. @since 4.11.0 *) val exists2 : f:('a -> 'b -> bool) -> 'a array -> 'b array -> bool -(** Same as {!ArrayLabels.exists}, but for a two-argument predicate. +(** Same as {!exists}, but for a two-argument predicate. @raise Invalid_argument if the two arrays have different lengths. @since 4.11.0 *) val mem : 'a -> set:'a array -> bool -(** [mem x ~set] is true if and only if [x] is equal - to an element of [set]. - @since 4.03.0 *) +(** [mem a ~set] is true if and only if [a] is structurally equal + to an element of [l] (i.e. there is an [x] in [l] such that + [compare a x = 0]). + @since 4.03.0 *) val memq : 'a -> set:'a array -> bool (** Same as {!mem}, but uses physical equality instead of structural equality to compare list elements. @since 4.03.0 *) -external create_float: int -> float array = "caml_make_float_vect" -(** [create_float n] returns a fresh float array of length [n], - with uninitialized data. - @since 4.03 *) - -val make_float: int -> float array - [@@ocaml.deprecated "Use Array.create_float instead."] -(** @deprecated {!make_float} is an alias for - {!create_float}. *) - (** {1 Sorting} *) - val sort : cmp:('a -> 'a -> int) -> 'a array -> unit (** Sort an array in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see below for a complete specification). For example, {!Stdlib.compare} is - a suitable comparison function, provided there are no floating-point - NaN values in the data. After calling [sort], the + a suitable comparison function. After calling [sort], the array is sorted in place in increasing order. [sort] is guaranteed to run in constant heap space and (at most) logarithmic stack space. @@ -253,7 +262,7 @@ val sort : cmp:('a -> 'a -> int) -> 'a array -> unit Specification of the comparison function: Let [a] be the array and [cmp] the comparison function. The following - must be true for all x, y, z in a : + must be true for all [x], [y], [z] in [a] : - [cmp x y] > 0 if and only if [cmp y x] < 0 - if [cmp x y] >= 0 and [cmp y z] >= 0 then [cmp x z] >= 0 @@ -267,23 +276,27 @@ val stable_sort : cmp:('a -> 'a -> int) -> 'a array -> unit elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space. - The current implementation uses Merge Sort. It uses [n/2] - words of heap space, where [n] is the length of the array. - It is usually faster than the current implementation of {!sort}. + The current implementation uses Merge Sort. It uses a temporary array of + length [n/2], where [n] is the length of the array. It is usually faster + than the current implementation of {!sort}. *) val fast_sort : cmp:('a -> 'a -> int) -> 'a array -> unit -(** Same as {!sort} or {!stable_sort}, whichever is faster on typical input. *) +(** Same as {!sort} or {!stable_sort}, whichever is + faster on typical input. *) (** {1 Iterators} *) val to_seq : 'a array -> 'a Seq.t -(** Iterate on the array, in increasing order +(** Iterate on the array, in increasing order. Modifications of the + array during iteration will be reflected in the iterator. @since 4.07 *) val to_seqi : 'a array -> (int * 'a) Seq.t -(** Iterate on the array, in increasing order, yielding indices along elements +(** Iterate on the array, in increasing order, yielding indices along elements. + Modifications of the array during iteration will be reflected in the + iterator. @since 4.07 *) val of_seq : 'a Seq.t -> 'a array diff --git a/driver/main.mli b/stdlib/atomic.ml similarity index 82% rename from driver/main.mli rename to stdlib/atomic.ml index ec43cbd7..a60a2451 100644 --- a/driver/main.mli +++ b/stdlib/atomic.ml @@ -2,9 +2,9 @@ (* *) (* OCaml *) (* *) -(* Damien Doligez, projet Moscova, INRIA Rocquencourt *) +(* Guillaume Munch-Maccagnoni, projet Gallinette, INRIA *) (* *) -(* Copyright 2000 Institut National de Recherche en Informatique et *) +(* Copyright 2020 Institut National de Recherche en Informatique et *) (* en Automatique. *) (* *) (* All rights reserved. This file is distributed under the terms of *) @@ -13,6 +13,4 @@ (* *) (**************************************************************************) -(* - this "empty" file is here to speed up garbage collection in ocamlc.opt -*) +include CamlinternalAtomic diff --git a/stdlib/atomic.mli b/stdlib/atomic.mli new file mode 100644 index 00000000..b66d576f --- /dev/null +++ b/stdlib/atomic.mli @@ -0,0 +1,59 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Stephen Dolan, University of Cambridge *) +(* Gabriel Scherer, projet Partout, INRIA Paris-Saclay *) +(* *) +(* Copyright 2020 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(** This module provides a purely sequential implementation of the + concurrent atomic references provided by the Multicore OCaml + standard library: + + https://github.com/ocaml-multicore/ocaml-multicore/blob/parallel_minor_gc/stdlib/atomic.mli + + This sequential implementation is provided in the interest of + compatibility: when people will start writing code to run on + Multicore, it would be nice if their use of Atomic was + backward-compatible with older versions of OCaml without having to + import additional compatibility layers. *) + +(** An atomic (mutable) reference to a value of type ['a]. *) +type !'a t + +(** Create an atomic reference. *) +val make : 'a -> 'a t + +(** Get the current value of the atomic reference. *) +val get : 'a t -> 'a + +(** Set a new value for the atomic reference. *) +val set : 'a t -> 'a -> unit + +(** Set a new value for the atomic reference, and return the current value. *) +val exchange : 'a t -> 'a -> 'a + +(** [compare_and_set r seen v] sets the new value of [r] to [v] only + if its current value is physically equal to [seen] -- the + comparison and the set occur atomically. Returns [true] if the + comparison succeeded (so the set happened) and [false] + otherwise. *) +val compare_and_set : 'a t -> 'a -> 'a -> bool + +(** [fetch_and_add r n] atomically increments the value of [r] by [n], + and returns the current value (before the increment). *) +val fetch_and_add : int t -> int -> int + +(** [incr r] atomically increments the value of [r] by [1]. *) +val incr : int t -> unit + +(** [decr r] atomically decrements the value of [r] by [1]. *) +val decr : int t -> unit diff --git a/stdlib/bigarray.ml b/stdlib/bigarray.ml index 86c737ae..ec3db6dd 100644 --- a/stdlib/bigarray.ml +++ b/stdlib/bigarray.ml @@ -92,13 +92,34 @@ let c_layout = C_layout let fortran_layout = Fortran_layout module Genarray = struct - type ('a, 'b, 'c) t + type (!'a, !'b, !'c) t external create: ('a, 'b) kind -> 'c layout -> int array -> ('a, 'b, 'c) t = "caml_ba_create" external get: ('a, 'b, 'c) t -> int array -> 'a = "caml_ba_get_generic" external set: ('a, 'b, 'c) t -> int array -> 'a -> unit = "caml_ba_set_generic" + + let rec cloop arr idx f col max = + if col = Array.length idx then set arr idx (f idx) + else for j = 0 to pred max.(col) do + idx.(col) <- j; + cloop arr idx f (succ col) max + done + let rec floop arr idx f col max = + if col < 0 then set arr idx (f idx) + else for j = 1 to max.(col) do + idx.(col) <- j; + floop arr idx f (pred col) max + done + let init (type t) kind (layout : t layout) dims f = + let arr = create kind layout dims in + match Array.length dims, layout with + | 0, _ -> arr + | dlen, C_layout -> cloop arr (Array.make dlen 0) f 0 dims; arr + | dlen, Fortran_layout -> floop arr (Array.make dlen 1) f (pred dlen) dims; + arr + external num_dims: ('a, 'b, 'c) t -> int = "caml_ba_num_dims" external nth_dim: ('a, 'b, 'c) t -> int -> int = "caml_ba_dim" let dims a = @@ -132,7 +153,7 @@ module Genarray = struct end module Array0 = struct - type ('a, 'b, 'c) t = ('a, 'b, 'c) Genarray.t + type (!'a, !'b, !'c) t = ('a, 'b, 'c) Genarray.t let create kind layout = Genarray.create kind layout [||] let get arr = Genarray.get arr [||] @@ -152,10 +173,11 @@ module Array0 = struct let a = create kind layout in set a v; a + let init = of_value end module Array1 = struct - type ('a, 'b, 'c) t = ('a, 'b, 'c) Genarray.t + type (!'a, !'b, !'c) t = ('a, 'b, 'c) Genarray.t let create kind layout dim = Genarray.create kind layout [|dim|] external get: ('a, 'b, 'c) t -> int -> 'a = "%caml_ba_ref_1" @@ -180,6 +202,15 @@ module Array1 = struct | Fortran_layout -> (Genarray.slice_right a [|n|]: (_, _, t) Genarray.t) external blit: ('a, 'b, 'c) t -> ('a, 'b, 'c) t -> unit = "caml_ba_blit" external fill: ('a, 'b, 'c) t -> 'a -> unit = "caml_ba_fill" + let c_init arr dim f = + for i = 0 to pred dim do unsafe_set arr i (f i) done + let fortran_init arr dim f = + for i = 1 to dim do unsafe_set arr i (f i) done + let init (type t) kind (layout : t layout) dim f = + let arr = create kind layout dim in + match layout with + | C_layout -> c_init arr dim f; arr + | Fortran_layout -> fortran_init arr dim f; arr let of_array (type t) kind (layout: t layout) data = let ba = create kind layout (Array.length data) in let ofs = @@ -192,7 +223,7 @@ module Array1 = struct end module Array2 = struct - type ('a, 'b, 'c) t = ('a, 'b, 'c) Genarray.t + type (!'a, !'b, !'c) t = ('a, 'b, 'c) Genarray.t let create kind layout dim1 dim2 = Genarray.create kind layout [|dim1; dim2|] external get: ('a, 'b, 'c) t -> int -> int -> 'a = "%caml_ba_ref_2" @@ -221,6 +252,23 @@ module Array2 = struct let slice_right a n = Genarray.slice_right a [|n|] external blit: ('a, 'b, 'c) t -> ('a, 'b, 'c) t -> unit = "caml_ba_blit" external fill: ('a, 'b, 'c) t -> 'a -> unit = "caml_ba_fill" + let c_init arr dim1 dim2 f = + for i = 0 to pred dim1 do + for j = 0 to pred dim2 do + unsafe_set arr i j (f i j) + done + done + let fortran_init arr dim1 dim2 f = + for j = 1 to dim2 do + for i = 1 to dim1 do + unsafe_set arr i j (f i j) + done + done + let init (type t) kind (layout : t layout) dim1 dim2 f = + let arr = create kind layout dim1 dim2 in + match layout with + | C_layout -> c_init arr dim1 dim2 f; arr + | Fortran_layout -> fortran_init arr dim1 dim2 f; arr let of_array (type t) kind (layout: t layout) data = let dim1 = Array.length data in let dim2 = if dim1 = 0 then 0 else Array.length data.(0) in @@ -242,7 +290,7 @@ module Array2 = struct end module Array3 = struct - type ('a, 'b, 'c) t = ('a, 'b, 'c) Genarray.t + type (!'a, !'b, !'c) t = ('a, 'b, 'c) Genarray.t let create kind layout dim1 dim2 dim3 = Genarray.create kind layout [|dim1; dim2; dim3|] external get: ('a, 'b, 'c) t -> int -> int -> int -> 'a = "%caml_ba_ref_3" @@ -275,6 +323,27 @@ module Array3 = struct let slice_right_2 a n = Genarray.slice_right a [|n|] external blit: ('a, 'b, 'c) t -> ('a, 'b, 'c) t -> unit = "caml_ba_blit" external fill: ('a, 'b, 'c) t -> 'a -> unit = "caml_ba_fill" + let c_init arr dim1 dim2 dim3 f = + for i = 0 to pred dim1 do + for j = 0 to pred dim2 do + for k = 0 to pred dim3 do + unsafe_set arr i j k (f i j k) + done + done + done + let fortran_init arr dim1 dim2 dim3 f = + for k = 1 to dim3 do + for j = 1 to dim2 do + for i = 1 to dim1 do + unsafe_set arr i j k (f i j k) + done + done + done + let init (type t) kind (layout : t layout) dim1 dim2 dim3 f = + let arr = create kind layout dim1 dim2 dim3 in + match layout with + | C_layout -> c_init arr dim1 dim2 dim3 f; arr + | Fortran_layout -> fortran_init arr dim1 dim2 dim3 f; arr let of_array (type t) kind (layout: t layout) data = let dim1 = Array.length data in let dim2 = if dim1 = 0 then 0 else Array.length data.(0) in diff --git a/stdlib/bigarray.mli b/stdlib/bigarray.mli index a474d559..97435606 100644 --- a/stdlib/bigarray.mli +++ b/stdlib/bigarray.mli @@ -255,7 +255,7 @@ val fortran_layout : fortran_layout layout module Genarray : sig - type ('a, 'b, 'c) t + type (!'a, !'b, !'c) t (** The type [Genarray.t] is the type of Bigarrays with variable numbers of dimensions. Any number of dimensions between 0 and 16 is supported. @@ -298,6 +298,34 @@ module Genarray : is not in the range 0 to 16 inclusive, or if one of the dimensions is negative. *) + val init: ('a, 'b) kind -> 'c layout -> int array -> (int array -> 'a) -> + ('a, 'b, 'c) t + (** [Genarray.init kind layout dimensions f] returns a new Bigarray [b] + whose element kind is determined by the parameter [kind] (one of + [float32], [float64], [int8_signed], etc) and whose layout is + determined by the parameter [layout] (one of [c_layout] or + [fortran_layout]). The [dimensions] parameter is an array of + integers that indicate the size of the Bigarray in each dimension. + The length of [dimensions] determines the number of dimensions + of the Bigarray. + + Each element [Genarray.get b i] is initialized to the result of [f i]. + In other words, [Genarray.init kind layout dimensions f] tabulates + the results of [f] applied to the indices of a new Bigarray whose + layout is described by [kind], [layout] and [dimensions]. The index + array [i] may be shared and mutated between calls to f. + + For instance, [Genarray.init int c_layout [|2; 1; 3|] + (Array.fold_left (+) 0)] returns a fresh Bigarray of integers, in C + layout, having three dimensions (2, 1, 3, respectively), with the + element values 0, 1, 2, 1, 2, 3. + + [Genarray.init] raises [Invalid_argument] if the number of dimensions + is not in the range 0 to 16 inclusive, or if one of the dimensions + is negative. + + @since 4.12.0 *) + external num_dims: ('a, 'b, 'c) t -> int = "caml_ba_num_dims" (** Return the number of dimensions of the given Bigarray. *) @@ -477,7 +505,7 @@ module Genarray : faster operations, and more precise static type-checking. @since 4.05.0 *) module Array0 : sig - type ('a, 'b, 'c) t + type (!'a, !'b, !'c) t (** The type of zero-dimensional Bigarrays whose elements have OCaml type ['a], representation kind ['b], and memory layout ['c]. *) @@ -486,6 +514,12 @@ module Array0 : sig [kind] and [layout] determine the array element kind and the array layout as described for {!Genarray.create}. *) + val init: ('a, 'b) kind -> 'c layout -> 'a -> ('a, 'b, 'c) t + (** [Array0.init kind layout v] behaves like [Array0.create kind layout] + except that the element is additionally initialized to the value [v]. + + @since 4.12.0 *) + external kind: ('a, 'b, 'c) t -> ('a, 'b) kind = "caml_ba_kind" (** Return the kind of the given Bigarray. *) @@ -535,7 +569,7 @@ end Statically knowing the number of dimensions of the array allows faster operations, and more precise static type-checking. *) module Array1 : sig - type ('a, 'b, 'c) t + type (!'a, !'b, !'c) t (** The type of one-dimensional Bigarrays whose elements have OCaml type ['a], representation kind ['b], and memory layout ['c]. *) @@ -545,6 +579,22 @@ module Array1 : sig determine the array element kind and the array layout as described for {!Genarray.create}. *) + val init: ('a, 'b) kind -> 'c layout -> int -> (int -> 'a) -> + ('a, 'b, 'c) t + (** [Array1.init kind layout dim f] returns a new Bigarray [b] + of one dimension, whose size is [dim]. [kind] and [layout] + determine the array element kind and the array layout + as described for {!Genarray.create}. + + Each element [Array1.get b i] of the array is initialized to the + result of [f i]. + + In other words, [Array1.init kind layout dimensions f] tabulates + the results of [f] applied to the indices of a new Bigarray whose + layout is described by [kind], [layout] and [dim]. + + @since 4.12.0 *) + external dim: ('a, 'b, 'c) t -> int = "%caml_ba_dim_1" (** Return the size (dimension) of the given one-dimensional Bigarray. *) @@ -632,17 +682,34 @@ end case of two-dimensional arrays. *) module Array2 : sig - type ('a, 'b, 'c) t + type (!'a, !'b, !'c) t (** The type of two-dimensional Bigarrays whose elements have OCaml type ['a], representation kind ['b], and memory layout ['c]. *) val create: ('a, 'b) kind -> 'c layout -> int -> int -> ('a, 'b, 'c) t (** [Array2.create kind layout dim1 dim2] returns a new Bigarray of - two dimension, whose size is [dim1] in the first dimension + two dimensions, whose size is [dim1] in the first dimension and [dim2] in the second dimension. [kind] and [layout] determine the array element kind and the array layout as described for {!Bigarray.Genarray.create}. *) + val init: ('a, 'b) kind -> 'c layout -> int -> int -> + (int -> int -> 'a) -> ('a, 'b, 'c) t + (** [Array2.init kind layout dim1 dim2 f] returns a new Bigarray [b] + of two dimensions, whose size is [dim2] in the first dimension + and [dim2] in the second dimension. [kind] and [layout] + determine the array element kind and the array layout + as described for {!Bigarray.Genarray.create}. + + Each element [Array2.get b i j] of the array is initialized to + the result of [f i j]. + + In other words, [Array2.init kind layout dim1 dim2 f] tabulates + the results of [f] applied to the indices of a new Bigarray whose + layout is described by [kind], [layout], [dim1] and [dim2]. + + @since 4.12.0 *) + external dim1: ('a, 'b, 'c) t -> int = "%caml_ba_dim_1" (** Return the first dimension of the given two-dimensional Bigarray. *) @@ -748,17 +815,34 @@ end of three-dimensional arrays. *) module Array3 : sig - type ('a, 'b, 'c) t + type (!'a, !'b, !'c) t (** The type of three-dimensional Bigarrays whose elements have OCaml type ['a], representation kind ['b], and memory layout ['c]. *) val create: ('a, 'b) kind -> 'c layout -> int -> int -> int -> ('a, 'b, 'c) t (** [Array3.create kind layout dim1 dim2 dim3] returns a new Bigarray of - three dimension, whose size is [dim1] in the first dimension, + three dimensions, whose size is [dim1] in the first dimension, [dim2] in the second dimension, and [dim3] in the third. [kind] and [layout] determine the array element kind and the array layout as described for {!Bigarray.Genarray.create}. *) + val init: ('a, 'b) kind -> 'c layout -> int -> int -> int -> + (int -> int -> int -> 'a) -> ('a, 'b, 'c) t + (** [Array3.init kind layout dim1 dim2 dim3 f] returns a new Bigarray [b] + of three dimensions, whose size is [dim1] in the first dimension, + [dim2] in the second dimension, and [dim3] in the third. + [kind] and [layout] determine the array element kind and the array + layout as described for {!Bigarray.Genarray.create}. + + Each element [Array3.get b i j k] of the array is initialized to + the result of [f i j k]. + + In other words, [Array3.init kind layout dim1 dim2 dim3 f] tabulates + the results of [f] applied to the indices of a new Bigarray whose + layout is described by [kind], [layout], [dim1], [dim2] and [dim3]. + + @since 4.12.0 *) + external dim1: ('a, 'b, 'c) t -> int = "%caml_ba_dim_1" (** Return the first dimension of the given three-dimensional Bigarray. *) diff --git a/stdlib/bool.mli b/stdlib/bool.mli index f45caacb..557b3daa 100644 --- a/stdlib/bool.mli +++ b/stdlib/bool.mli @@ -42,8 +42,8 @@ external ( || ) : bool -> bool -> bool = "%sequor" (** {1:preds Predicates and comparisons} *) val equal : bool -> bool -> bool -(** [equal b0 b1] is [true] iff [b0] and [b1] are both either [true] - or [false]. *) +(** [equal b0 b1] is [true] if and only if [b0] and [b1] are both [true] + or both [false]. *) val compare : bool -> bool -> int (** [compare b0 b1] is a total order on boolean values. [false] is smaller diff --git a/stdlib/buffer.mli b/stdlib/buffer.mli index c316a43e..2507a7aa 100644 --- a/stdlib/buffer.mli +++ b/stdlib/buffer.mli @@ -18,7 +18,16 @@ This module implements buffers that automatically expand as necessary. It provides accumulative concatenation of strings in quasi-linear time (instead of quadratic time when strings are - concatenated pairwise). + concatenated pairwise). For example: + +{[ + let concat_strings ss = + let b = Buffer.create 16 in + List.iter (Buffer.add_string b) ss; + Buffer.contents b + +]} + *) type t diff --git a/stdlib/bytes.mli b/stdlib/bytes.mli index abf3e90c..99f686aa 100644 --- a/stdlib/bytes.mli +++ b/stdlib/bytes.mli @@ -13,6 +13,14 @@ (* *) (**************************************************************************) +(* NOTE: + If this file is bytesLabels.mli, run tools/sync_stdlib_docs after editing it + to generate bytes.mli. + + If this file is bytes.mli, do not edit it directly -- edit + bytesLabels.mli instead. + *) + (** Byte sequence operations. A byte sequence is a mutable data structure that contains a @@ -39,8 +47,12 @@ Bytes are represented by the OCaml type [char]. + The labeled version of this module can be used as described in the + {!StdLabels} module. + @since 4.02.0 - *) + + *) external length : bytes -> int = "%bytes_length" (** Return the length (number of bytes) of the argument. *) @@ -49,6 +61,7 @@ external get : bytes -> int -> char = "%bytes_safe_get" (** [get s n] returns the byte at index [n] in argument [s]. @raise Invalid_argument if [n] is not a valid index in [s]. *) + external set : bytes -> int -> char -> unit = "%bytes_safe_set" (** [set s n c] modifies [s] in place, replacing the byte at index [n] with [c]. @@ -65,8 +78,8 @@ val make : int -> char -> bytes @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. *) val init : int -> (int -> char) -> bytes -(** [Bytes.init n f] returns a fresh byte sequence of length [n], with - character [i] initialized to the result of [f i] (in increasing +(** [init n f] returns a fresh byte sequence of length [n], + with character [i] initialized to the result of [f i] (in increasing index order). @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. *) @@ -86,14 +99,14 @@ val to_string : bytes -> string sequence. *) val sub : bytes -> int -> int -> bytes -(** [sub s start len] returns a new byte sequence of length [len], - containing the subsequence of [s] that starts at position [start] +(** [sub s pos len] returns a new byte sequence of length [len], + containing the subsequence of [s] that starts at position [pos] and has length [len]. - @raise Invalid_argument if [start] and [len] do not designate a + @raise Invalid_argument if [pos] and [len] do not designate a valid range of [s]. *) val sub_string : bytes -> int -> int -> string -(** Same as [sub] but return a string instead of a byte sequence. *) +(** Same as {!sub} but return a string instead of a byte sequence. *) val extend : bytes -> int -> int -> bytes (** [extend s left right] returns a new byte sequence that contains @@ -102,44 +115,52 @@ val extend : bytes -> int -> int -> bytes is negative, then bytes are removed (instead of appended) from the corresponding side of [s]. @raise Invalid_argument if the result length is negative or - longer than {!Sys.max_string_length} bytes. *) + longer than {!Sys.max_string_length} bytes. + @since 4.05.0 in BytesLabels *) val fill : bytes -> int -> int -> char -> unit -(** [fill s start len c] modifies [s] in place, replacing [len] - characters with [c], starting at [start]. - @raise Invalid_argument if [start] and [len] do not designate a +(** [fill s pos len c] modifies [s] in place, replacing [len] + characters with [c], starting at [pos]. + @raise Invalid_argument if [pos] and [len] do not designate a valid range of [s]. *) -val blit : bytes -> int -> bytes -> int -> int -> unit -(** [blit src srcoff dst dstoff len] copies [len] bytes from sequence - [src], starting at index [srcoff], to sequence [dst], starting at - index [dstoff]. It works correctly even if [src] and [dst] are the +val blit : + bytes -> int -> bytes -> int -> int + -> unit +(** [blit src src_pos dst dst_pos len] copies [len] bytes from sequence + [src], starting at index [src_pos], to sequence [dst], starting at + index [dst_pos]. It works correctly even if [src] and [dst] are the same byte sequence, and the source and destination intervals overlap. - @raise Invalid_argument if [srcoff] and [len] do not - designate a valid range of [src], or if [dstoff] and [len] + @raise Invalid_argument if [src_pos] and [len] do not + designate a valid range of [src], or if [dst_pos] and [len] do not designate a valid range of [dst]. *) -val blit_string : string -> int -> bytes -> int -> int -> unit -(** [blit_string src srcoff dst dstoff len] copies [len] bytes from - string [src], starting at index [srcoff], to byte sequence [dst], - starting at index [dstoff]. - @raise Invalid_argument if [srcoff] and [len] do not - designate a valid range of [src], or if [dstoff] and [len] - do not designate a valid range of [dst]. *) +val blit_string : + string -> int -> bytes -> int -> int + -> unit +(** [blit src src_pos dst dst_pos len] copies [len] bytes from string + [src], starting at index [src_pos], to byte sequence [dst], + starting at index [dst_pos]. + @raise Invalid_argument if [src_pos] and [len] do not + designate a valid range of [src], or if [dst_pos] and [len] + do not designate a valid range of [dst]. + @since 4.05.0 in BytesLabels *) val concat : bytes -> bytes list -> bytes (** [concat sep sl] concatenates the list of byte sequences [sl], inserting the separator byte sequence [sep] between each, and returns the result as a new byte sequence. @raise Invalid_argument if the result is longer than - {!Sys.max_string_length} bytes. *) + {!Sys.max_string_length} bytes. + *) val cat : bytes -> bytes -> bytes (** [cat s1 s2] concatenates [s1] and [s2] and returns the result as a new byte sequence. @raise Invalid_argument if the result is longer than - {!Sys.max_string_length} bytes. *) + {!Sys.max_string_length} bytes. + @since 4.05.0 in BytesLabels *) val iter : (char -> unit) -> bytes -> unit (** [iter f s] applies function [f] in turn to all the bytes of [s]. @@ -147,14 +168,14 @@ val iter : (char -> unit) -> bytes -> unit (length s - 1)); ()]. *) val iteri : (int -> char -> unit) -> bytes -> unit -(** Same as {!Bytes.iter}, but the function is applied to the index of +(** Same as {!iter}, but the function is applied to the index of the byte as first argument and the byte itself as second argument. *) val map : (char -> char) -> bytes -> bytes -(** [map f s] applies function [f] in turn to all the bytes of [s] - (in increasing index order) and stores the resulting bytes in - a new sequence that is returned as the result. *) +(** [map f s] applies function [f] in turn to all the bytes of [s] (in + increasing index order) and stores the resulting bytes in a new sequence + that is returned as the result. *) val mapi : (int -> char -> char) -> bytes -> bytes (** [mapi f s] calls [f] with each character of [s] and its @@ -196,8 +217,8 @@ val rindex_opt: bytes -> char -> int option val index_from : bytes -> int -> char -> int (** [index_from s i c] returns the index of the first occurrence of - byte [c] in [s] after position [i]. [Bytes.index s c] is - equivalent to [Bytes.index_from s 0 c]. + byte [c] in [s] after position [i]. [index s c] is + equivalent to [index_from s 0 c]. @raise Invalid_argument if [i] is not a valid position in [s]. @raise Not_found if [c] does not occur in [s] after position [i]. *) @@ -205,14 +226,14 @@ val index_from_opt: bytes -> int -> char -> int option (** [index_from_opt s i c] returns the index of the first occurrence of byte [c] in [s] after position [i] or [None] if [c] does not occur in [s] after position [i]. - [Bytes.index_opt s c] is equivalent to [Bytes.index_from_opt s 0 c]. + [index_opt s c] is equivalent to [index_from_opt s 0 c]. @raise Invalid_argument if [i] is not a valid position in [s]. @since 4.05 *) val rindex_from : bytes -> int -> char -> int (** [rindex_from s i c] returns the index of the last occurrence of byte [c] in [s] before position [i+1]. [rindex s c] is equivalent - to [rindex_from s (Bytes.length s - 1) c]. + to [rindex_from s (length s - 1) c]. @raise Invalid_argument if [i+1] is not a valid position in [s]. @raise Not_found if [c] does not occur in [s] before position [i+1]. *) @@ -220,7 +241,7 @@ val rindex_from_opt: bytes -> int -> char -> int option (** [rindex_from_opt s i c] returns the index of the last occurrence of byte [c] in [s] before position [i+1] or [None] if [c] does not occur in [s] before position [i+1]. [rindex_opt s c] is equivalent to - [rindex_from s (Bytes.length s - 1) c]. + [rindex_from s (length s - 1) c]. @raise Invalid_argument if [i+1] is not a valid position in [s]. @since 4.05 *) @@ -240,50 +261,54 @@ val rcontains_from : bytes -> int -> char -> bool position in [s]. *) val uppercase : bytes -> bytes - [@@ocaml.deprecated "Use Bytes.uppercase_ascii instead."] + [@@ocaml.deprecated + "Use Bytes.uppercase_ascii/BytesLabels.uppercase_ascii instead."] (** Return a copy of the argument, with all lowercase letters translated to uppercase, including accented letters of the ISO Latin-1 (8859-1) character set. @deprecated Functions operating on Latin-1 character set are deprecated. *) val lowercase : bytes -> bytes - [@@ocaml.deprecated "Use Bytes.lowercase_ascii instead."] + [@@ocaml.deprecated + "Use Bytes.lowercase_ascii/BytesLabels.lowercase_ascii instead."] (** Return a copy of the argument, with all uppercase letters translated to lowercase, including accented letters of the ISO Latin-1 (8859-1) character set. @deprecated Functions operating on Latin-1 character set are deprecated. *) val capitalize : bytes -> bytes - [@@ocaml.deprecated "Use Bytes.capitalize_ascii instead."] + [@@ocaml.deprecated + "Use Bytes.capitalize_ascii/BytesLabels.capitalize_ascii instead."] (** Return a copy of the argument, with the first character set to uppercase, - using the ISO Latin-1 (8859-1) character set.. + using the ISO Latin-1 (8859-1) character set. @deprecated Functions operating on Latin-1 character set are deprecated. *) val uncapitalize : bytes -> bytes - [@@ocaml.deprecated "Use Bytes.uncapitalize_ascii instead."] + [@@ocaml.deprecated + "Use Bytes.uncapitalize_ascii/BytesLabels.uncapitalize_ascii instead."] (** Return a copy of the argument, with the first character set to lowercase, - using the ISO Latin-1 (8859-1) character set.. + using the ISO Latin-1 (8859-1) character set. @deprecated Functions operating on Latin-1 character set are deprecated. *) val uppercase_ascii : bytes -> bytes (** Return a copy of the argument, with all lowercase letters translated to uppercase, using the US-ASCII character set. - @since 4.03.0 *) + @since 4.03.0 (4.05.0 in BytesLabels) *) val lowercase_ascii : bytes -> bytes (** Return a copy of the argument, with all uppercase letters translated to lowercase, using the US-ASCII character set. - @since 4.03.0 *) + @since 4.03.0 (4.05.0 in BytesLabels) *) val capitalize_ascii : bytes -> bytes (** Return a copy of the argument, with the first character set to uppercase, using the US-ASCII character set. - @since 4.03.0 *) + @since 4.03.0 (4.05.0 in BytesLabels) *) val uncapitalize_ascii : bytes -> bytes (** Return a copy of the argument, with the first character set to lowercase, using the US-ASCII character set. - @since 4.03.0 *) + @since 4.03.0 (4.05.0 in BytesLabels) *) type t = bytes (** An alias for the type of byte sequences. *) @@ -296,7 +321,7 @@ val compare: t -> t -> int val equal: t -> t -> bool (** The equality function for byte sequences. - @since 4.03.0 *) + @since 4.03.0 (4.05.0 in BytesLabels) *) (** {1:unsafe Unsafe conversions (for advanced users)} @@ -305,7 +330,7 @@ val equal: t -> t -> bool used improperly, they can break the immutability invariant on strings provided by the [-safe-string] option. They are available for expert library authors, but for most purposes you should use the - always-correct {!Bytes.to_string} and {!Bytes.of_string} instead. + always-correct {!to_string} and {!of_string} instead. *) val unsafe_to_string : bytes -> string @@ -427,6 +452,7 @@ let s = Bytes.of_string "hello" [string] type for this purpose. *) + (** {1 Iterators} *) val to_seq : t -> char Seq.t @@ -638,7 +664,6 @@ val set_int64_le : bytes -> int -> int64 -> unit *) - (**/**) (* The following is for system use only. Do not call directly. *) @@ -646,8 +671,8 @@ val set_int64_le : bytes -> int -> int64 -> unit external unsafe_get : bytes -> int -> char = "%bytes_unsafe_get" external unsafe_set : bytes -> int -> char -> unit = "%bytes_unsafe_set" external unsafe_blit : - bytes -> int -> bytes -> int -> int -> unit - = "caml_blit_bytes" [@@noalloc] + bytes -> int -> bytes -> int -> int -> + unit = "caml_blit_bytes" [@@noalloc] external unsafe_blit_string : string -> int -> bytes -> int -> int -> unit = "caml_blit_string" [@@noalloc] diff --git a/stdlib/bytesLabels.mli b/stdlib/bytesLabels.mli index e4f85d37..9582dd34 100644 --- a/stdlib/bytesLabels.mli +++ b/stdlib/bytesLabels.mli @@ -13,18 +13,46 @@ (* *) (**************************************************************************) +(* NOTE: + If this file is bytesLabels.mli, run tools/sync_stdlib_docs after editing it + to generate bytes.mli. + + If this file is bytes.mli, do not edit it directly -- edit + bytesLabels.mli instead. + *) + (** Byte sequence operations. - @since 4.02.0 - This module is intended to be used through {!StdLabels} which replaces - {!Array}, {!Bytes}, {!List} and {!String} with their labeled counterparts. + A byte sequence is a mutable data structure that contains a + fixed-length sequence of bytes. Each byte can be indexed in + constant time for reading or writing. - For example: - {[ - open StdLabels + Given a byte sequence [s] of length [l], we can access each of the + [l] bytes of [s] via its index in the sequence. Indexes start at + [0], and we will call an index valid in [s] if it falls within the + range [[0...l-1]] (inclusive). A position is the point between two + bytes or at the beginning or end of the sequence. We call a + position valid in [s] if it falls within the range [[0...l]] + (inclusive). Note that the byte at index [n] is between positions + [n] and [n+1]. + + Two parameters [start] and [len] are said to designate a valid + range of [s] if [len >= 0] and [start] and [start+len] are valid + positions in [s]. + + Byte sequences can be modified in place, for instance via the [set] + and [blit] functions described below. See also strings (module + {!String}), which are almost the same data structure, but cannot be + modified in place. + + Bytes are represented by the OCaml type [char]. + + The labeled version of this module can be used as described in the + {!StdLabels} module. - let first = Bytes.sub ~pos:0 ~len:1 - ]} *) + @since 4.02.0 + + *) external length : bytes -> int = "%bytes_length" (** Return the length (number of bytes) of the argument. *) @@ -51,7 +79,8 @@ val make : int -> char -> bytes val init : int -> f:(int -> char) -> bytes (** [init n f] returns a fresh byte sequence of length [n], - with character [i] initialized to the result of [f i]. + with character [i] initialized to the result of [f i] (in increasing + index order). @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. *) val empty : bytes @@ -70,83 +99,86 @@ val to_string : bytes -> string sequence. *) val sub : bytes -> pos:int -> len:int -> bytes -(** [sub s start len] returns a new byte sequence of length [len], - containing the subsequence of [s] that starts at position [start] +(** [sub s ~pos ~len] returns a new byte sequence of length [len], + containing the subsequence of [s] that starts at position [pos] and has length [len]. - @raise Invalid_argument if [start] and [len] do not designate a + @raise Invalid_argument if [pos] and [len] do not designate a valid range of [s]. *) val sub_string : bytes -> pos:int -> len:int -> string -(** Same as [sub] but return a string instead of a byte sequence. *) +(** Same as {!sub} but return a string instead of a byte sequence. *) val extend : bytes -> left:int -> right:int -> bytes -(** [extend s left right] returns a new byte sequence that contains +(** [extend s ~left ~right] returns a new byte sequence that contains the bytes of [s], with [left] uninitialized bytes prepended and [right] uninitialized bytes appended to it. If [left] or [right] is negative, then bytes are removed (instead of appended) from the corresponding side of [s]. @raise Invalid_argument if the result length is negative or longer than {!Sys.max_string_length} bytes. - @since 4.05.0 *) + @since 4.05.0 in BytesLabels *) val fill : bytes -> pos:int -> len:int -> char -> unit -(** [fill s start len c] modifies [s] in place, replacing [len] - characters with [c], starting at [start]. - @raise Invalid_argument if [start] and [len] do not designate a +(** [fill s ~pos ~len c] modifies [s] in place, replacing [len] + characters with [c], starting at [pos]. + @raise Invalid_argument if [pos] and [len] do not designate a valid range of [s]. *) val blit : src:bytes -> src_pos:int -> dst:bytes -> dst_pos:int -> len:int -> unit -(** [blit src srcoff dst dstoff len] copies [len] bytes from sequence - [src], starting at index [srcoff], to sequence [dst], starting at - index [dstoff]. It works correctly even if [src] and [dst] are the +(** [blit ~src ~src_pos ~dst ~dst_pos ~len] copies [len] bytes from sequence + [src], starting at index [src_pos], to sequence [dst], starting at + index [dst_pos]. It works correctly even if [src] and [dst] are the same byte sequence, and the source and destination intervals overlap. - @raise Invalid_argument if [srcoff] and [len] do not - designate a valid range of [src], or if [dstoff] and [len] + @raise Invalid_argument if [src_pos] and [len] do not + designate a valid range of [src], or if [dst_pos] and [len] do not designate a valid range of [dst]. *) val blit_string : src:string -> src_pos:int -> dst:bytes -> dst_pos:int -> len:int -> unit -(** [blit src srcoff dst dstoff len] copies [len] bytes from string - [src], starting at index [srcoff], to byte sequence [dst], - starting at index [dstoff]. - @raise Invalid_argument if [srcoff] and [len] do not - designate a valid range of [src], or if [dstoff] and [len] +(** [blit ~src ~src_pos ~dst ~dst_pos ~len] copies [len] bytes from string + [src], starting at index [src_pos], to byte sequence [dst], + starting at index [dst_pos]. + @raise Invalid_argument if [src_pos] and [len] do not + designate a valid range of [src], or if [dst_pos] and [len] do not designate a valid range of [dst]. - @since 4.05.0 *) + @since 4.05.0 in BytesLabels *) val concat : sep:bytes -> bytes list -> bytes -(** [concat sep sl] concatenates the list of byte sequences [sl], +(** [concat ~sep sl] concatenates the list of byte sequences [sl], inserting the separator byte sequence [sep] between each, and - returns the result as a new byte sequence. *) + returns the result as a new byte sequence. + @raise Invalid_argument if the result is longer than + {!Sys.max_string_length} bytes. + *) val cat : bytes -> bytes -> bytes (** [cat s1 s2] concatenates [s1] and [s2] and returns the result - as new byte sequence. + as a new byte sequence. @raise Invalid_argument if the result is longer than {!Sys.max_string_length} bytes. - @since 4.05.0 *) + @since 4.05.0 in BytesLabels *) val iter : f:(char -> unit) -> bytes -> unit -(** [iter f s] applies function [f] in turn to all the bytes of [s]. +(** [iter ~f s] applies function [f] in turn to all the bytes of [s]. It is equivalent to [f (get s 0); f (get s 1); ...; f (get s (length s - 1)); ()]. *) val iteri : f:(int -> char -> unit) -> bytes -> unit -(** Same as {!Bytes.iter}, but the function is applied to the index of +(** Same as {!iter}, but the function is applied to the index of the byte as first argument and the byte itself as second argument. *) val map : f:(char -> char) -> bytes -> bytes -(** [map f s] applies function [f] in turn to all the bytes of [s] and - stores the resulting bytes in a new sequence that is returned as - the result. *) +(** [map ~f s] applies function [f] in turn to all the bytes of [s] (in + increasing index order) and stores the resulting bytes in a new sequence + that is returned as the result. *) val mapi : f:(int -> char -> char) -> bytes -> bytes -(** [mapi f s] calls [f] with each character of [s] and its +(** [mapi ~f s] calls [f] with each character of [s] and its index (in increasing index order) and stores the resulting bytes in a new sequence that is returned as the result. *) @@ -157,7 +189,11 @@ val trim : bytes -> bytes val escaped : bytes -> bytes (** Return a copy of the argument, with special characters represented - by escape sequences, following the lexical conventions of OCaml. *) + by escape sequences, following the lexical conventions of OCaml. + All characters outside the ASCII printable range (32..126) are + escaped, as well as backslash and double-quote. + @raise Invalid_argument if the result is longer than + {!Sys.max_string_length} bytes. *) val index : bytes -> char -> int (** [index s c] returns the index of the first occurrence of byte [c] @@ -181,23 +217,23 @@ val rindex_opt: bytes -> char -> int option val index_from : bytes -> int -> char -> int (** [index_from s i c] returns the index of the first occurrence of - byte [c] in [s] after position [i]. [Bytes.index s c] is - equivalent to [Bytes.index_from s 0 c]. + byte [c] in [s] after position [i]. [index s c] is + equivalent to [index_from s 0 c]. @raise Invalid_argument if [i] is not a valid position in [s]. @raise Not_found if [c] does not occur in [s] after position [i]. *) val index_from_opt: bytes -> int -> char -> int option -(** [index_from _opts i c] returns the index of the first occurrence of +(** [index_from_opt s i c] returns the index of the first occurrence of byte [c] in [s] after position [i] or [None] if [c] does not occur in [s] after position [i]. - [Bytes.index_opt s c] is equivalent to [Bytes.index_from_opt s 0 c]. + [index_opt s c] is equivalent to [index_from_opt s 0 c]. @raise Invalid_argument if [i] is not a valid position in [s]. @since 4.05 *) val rindex_from : bytes -> int -> char -> int (** [rindex_from s i c] returns the index of the last occurrence of byte [c] in [s] before position [i+1]. [rindex s c] is equivalent - to [rindex_from s (Bytes.length s - 1) c]. + to [rindex_from s (length s - 1) c]. @raise Invalid_argument if [i+1] is not a valid position in [s]. @raise Not_found if [c] does not occur in [s] before position [i+1]. *) @@ -205,7 +241,7 @@ val rindex_from_opt: bytes -> int -> char -> int option (** [rindex_from_opt s i c] returns the index of the last occurrence of byte [c] in [s] before position [i+1] or [None] if [c] does not occur in [s] before position [i+1]. [rindex_opt s c] is equivalent to - [rindex_from s (Bytes.length s - 1) c]. + [rindex_from s (length s - 1) c]. @raise Invalid_argument if [i+1] is not a valid position in [s]. @since 4.05 *) @@ -225,50 +261,54 @@ val rcontains_from : bytes -> int -> char -> bool position in [s]. *) val uppercase : bytes -> bytes - [@@ocaml.deprecated "Use Bytes.uppercase_ascii instead."] + [@@ocaml.deprecated + "Use Bytes.uppercase_ascii/BytesLabels.uppercase_ascii instead."] (** Return a copy of the argument, with all lowercase letters translated to uppercase, including accented letters of the ISO Latin-1 (8859-1) character set. @deprecated Functions operating on Latin-1 character set are deprecated. *) val lowercase : bytes -> bytes - [@@ocaml.deprecated "Use Bytes.lowercase_ascii instead."] + [@@ocaml.deprecated + "Use Bytes.lowercase_ascii/BytesLabels.lowercase_ascii instead."] (** Return a copy of the argument, with all uppercase letters translated to lowercase, including accented letters of the ISO Latin-1 (8859-1) character set. @deprecated Functions operating on Latin-1 character set are deprecated. *) val capitalize : bytes -> bytes - [@@ocaml.deprecated "Use Bytes.capitalize_ascii instead."] + [@@ocaml.deprecated + "Use Bytes.capitalize_ascii/BytesLabels.capitalize_ascii instead."] (** Return a copy of the argument, with the first character set to uppercase, - using the ISO Latin-1 (8859-1) character set.. + using the ISO Latin-1 (8859-1) character set. @deprecated Functions operating on Latin-1 character set are deprecated. *) val uncapitalize : bytes -> bytes - [@@ocaml.deprecated "Use Bytes.uncapitalize_ascii instead."] + [@@ocaml.deprecated + "Use Bytes.uncapitalize_ascii/BytesLabels.uncapitalize_ascii instead."] (** Return a copy of the argument, with the first character set to lowercase, - using the ISO Latin-1 (8859-1) character set.. + using the ISO Latin-1 (8859-1) character set. @deprecated Functions operating on Latin-1 character set are deprecated. *) val uppercase_ascii : bytes -> bytes (** Return a copy of the argument, with all lowercase letters translated to uppercase, using the US-ASCII character set. - @since 4.05.0 *) + @since 4.03.0 (4.05.0 in BytesLabels) *) val lowercase_ascii : bytes -> bytes (** Return a copy of the argument, with all uppercase letters translated to lowercase, using the US-ASCII character set. - @since 4.05.0 *) + @since 4.03.0 (4.05.0 in BytesLabels) *) val capitalize_ascii : bytes -> bytes (** Return a copy of the argument, with the first character set to uppercase, using the US-ASCII character set. - @since 4.05.0 *) + @since 4.03.0 (4.05.0 in BytesLabels) *) val uncapitalize_ascii : bytes -> bytes (** Return a copy of the argument, with the first character set to lowercase, using the US-ASCII character set. - @since 4.05.0 *) + @since 4.03.0 (4.05.0 in BytesLabels) *) type t = bytes (** An alias for the type of byte sequences. *) @@ -281,7 +321,137 @@ val compare: t -> t -> int val equal: t -> t -> bool (** The equality function for byte sequences. - @since 4.05.0 *) + @since 4.03.0 (4.05.0 in BytesLabels) *) + +(** {1:unsafe Unsafe conversions (for advanced users)} + + This section describes unsafe, low-level conversion functions + between [bytes] and [string]. They do not copy the internal data; + used improperly, they can break the immutability invariant on + strings provided by the [-safe-string] option. They are available for + expert library authors, but for most purposes you should use the + always-correct {!to_string} and {!of_string} instead. +*) + +val unsafe_to_string : bytes -> string +(** Unsafely convert a byte sequence into a string. + + To reason about the use of [unsafe_to_string], it is convenient to + consider an "ownership" discipline. A piece of code that + manipulates some data "owns" it; there are several disjoint ownership + modes, including: + - Unique ownership: the data may be accessed and mutated + - Shared ownership: the data has several owners, that may only + access it, not mutate it. + + Unique ownership is linear: passing the data to another piece of + code means giving up ownership (we cannot write the + data again). A unique owner may decide to make the data shared + (giving up mutation rights on it), but shared data may not become + uniquely-owned again. + + [unsafe_to_string s] can only be used when the caller owns the byte + sequence [s] -- either uniquely or as shared immutable data. The + caller gives up ownership of [s], and gains ownership of the + returned string. + + There are two valid use-cases that respect this ownership + discipline: + + 1. Creating a string by initializing and mutating a byte sequence + that is never changed after initialization is performed. + + {[ +let string_init len f : string = + let s = Bytes.create len in + for i = 0 to len - 1 do Bytes.set s i (f i) done; + Bytes.unsafe_to_string s + ]} + + This function is safe because the byte sequence [s] will never be + accessed or mutated after [unsafe_to_string] is called. The + [string_init] code gives up ownership of [s], and returns the + ownership of the resulting string to its caller. + + Note that it would be unsafe if [s] was passed as an additional + parameter to the function [f] as it could escape this way and be + mutated in the future -- [string_init] would give up ownership of + [s] to pass it to [f], and could not call [unsafe_to_string] + safely. + + We have provided the {!String.init}, {!String.map} and + {!String.mapi} functions to cover most cases of building + new strings. You should prefer those over [to_string] or + [unsafe_to_string] whenever applicable. + + 2. Temporarily giving ownership of a byte sequence to a function + that expects a uniquely owned string and returns ownership back, so + that we can mutate the sequence again after the call ended. + + {[ +let bytes_length (s : bytes) = + String.length (Bytes.unsafe_to_string s) + ]} + + In this use-case, we do not promise that [s] will never be mutated + after the call to [bytes_length s]. The {!String.length} function + temporarily borrows unique ownership of the byte sequence + (and sees it as a [string]), but returns this ownership back to + the caller, which may assume that [s] is still a valid byte + sequence after the call. Note that this is only correct because we + know that {!String.length} does not capture its argument -- it could + escape by a side-channel such as a memoization combinator. + + The caller may not mutate [s] while the string is borrowed (it has + temporarily given up ownership). This affects concurrent programs, + but also higher-order functions: if {!String.length} returned + a closure to be called later, [s] should not be mutated until this + closure is fully applied and returns ownership. +*) + +val unsafe_of_string : string -> bytes +(** Unsafely convert a shared string to a byte sequence that should + not be mutated. + + The same ownership discipline that makes [unsafe_to_string] + correct applies to [unsafe_of_string]: you may use it if you were + the owner of the [string] value, and you will own the return + [bytes] in the same mode. + + In practice, unique ownership of string values is extremely + difficult to reason about correctly. You should always assume + strings are shared, never uniquely owned. + + For example, string literals are implicitly shared by the + compiler, so you never uniquely own them. + + {[ +let incorrect = Bytes.unsafe_of_string "hello" +let s = Bytes.of_string "hello" + ]} + + The first declaration is incorrect, because the string literal + ["hello"] could be shared by the compiler with other parts of the + program, and mutating [incorrect] is a bug. You must always use + the second version, which performs a copy and is thus correct. + + Assuming unique ownership of strings that are not string + literals, but are (partly) built from string literals, is also + incorrect. For example, mutating [unsafe_of_string ("foo" ^ s)] + could mutate the shared string ["foo"] -- assuming a rope-like + representation of strings. More generally, functions operating on + strings will assume shared ownership, they do not preserve unique + ownership. It is thus incorrect to assume unique ownership of the + result of [unsafe_of_string]. + + The only case we have reasonable confidence is safe is if the + produced [bytes] is shared -- used as an immutable byte + sequence. This is possibly useful for incremental migration of + low-level programs that manipulate immutable sequences of bytes + (for example {!Marshal.from_bytes}) and previously used the + [string] type for this purpose. +*) + (** {1 Iterators} *) @@ -508,5 +678,3 @@ external unsafe_blit_string : = "caml_blit_string" [@@noalloc] external unsafe_fill : bytes -> pos:int -> len:int -> char -> unit = "caml_fill_bytes" [@@noalloc] -val unsafe_to_string : bytes -> string -val unsafe_of_string : string -> bytes diff --git a/stdlib/camlinternalAtomic.ml b/stdlib/camlinternalAtomic.ml new file mode 100644 index 00000000..b7e74a53 --- /dev/null +++ b/stdlib/camlinternalAtomic.ml @@ -0,0 +1,60 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Gabriel Scherer, projet Partout, INRIA Paris-Saclay *) +(* *) +(* Copyright 2020 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* CamlinternalAtomic is a dependency of Stdlib, so it is compiled with + -nopervasives. *) +external ( == ) : 'a -> 'a -> bool = "%eq" +external ( + ) : int -> int -> int = "%addint" +external ignore : 'a -> unit = "%ignore" + +(* We are not reusing ('a ref) directly to make it easier to reason + about atomicity if we wish to: even in a sequential implementation, + signals and other asynchronous callbacks might break atomicity. *) +type 'a t = {mutable v: 'a} + +let make v = {v} +let get r = r.v +let set r v = r.v <- v + +(* The following functions are set to never be inlined: Flambda is + allowed to move surrounding code inside the critical section, + including allocations. *) + +let[@inline never] exchange r v = + (* BEGIN ATOMIC *) + let cur = r.v in + r.v <- v; + (* END ATOMIC *) + cur + +let[@inline never] compare_and_set r seen v = + (* BEGIN ATOMIC *) + let cur = r.v in + if cur == seen then ( + r.v <- v; + (* END ATOMIC *) + true + ) else + false + +let[@inline never] fetch_and_add r n = + (* BEGIN ATOMIC *) + let cur = r.v in + r.v <- (cur + n); + (* END ATOMIC *) + cur + +let incr r = ignore (fetch_and_add r 1) +let decr r = ignore (fetch_and_add r (-1)) diff --git a/stdlib/camlinternalAtomic.mli b/stdlib/camlinternalAtomic.mli new file mode 100644 index 00000000..3b9aab3c --- /dev/null +++ b/stdlib/camlinternalAtomic.mli @@ -0,0 +1,30 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Stephen Dolan, University of Cambridge *) +(* Guillaume Munch-Maccagnoni, projet Gallinette, INRIA *) +(* *) +(* Copyright 2020 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* The documentation is in atomic.mli. CamlinternalAtomic exists in + order to be a dependency of Stdlib. More precisely, the option + modules_before_stdlib used in stdlib/dune does not support the + Stdlib__ prefix trick. *) + +type !'a t +val make : 'a -> 'a t +val get : 'a t -> 'a +val set : 'a t -> 'a -> unit +val exchange : 'a t -> 'a -> 'a +val compare_and_set : 'a t -> 'a -> 'a -> bool +val fetch_and_add : int t -> int -> int +val incr : int t -> unit +val decr : int t -> unit diff --git a/stdlib/camlinternalFormat.ml b/stdlib/camlinternalFormat.ml index 5c2a2b3b..239d027c 100644 --- a/stdlib/camlinternalFormat.ml +++ b/stdlib/camlinternalFormat.ml @@ -2305,7 +2305,7 @@ let fmt_ebb_of_string ?legacy_behavior str = and get_prec () = prec_used := true; prec and get_padprec () = pad_used := true; padprec in - let get_int_pad () = + let get_int_pad () : (x,y) padding = (* %5.3d is accepted and meaningful: pad to length 5 with spaces, but first pad with zeros upto length 3 (0-padding is the interpretation of "precision" for integer formats). @@ -2330,7 +2330,7 @@ let fmt_ebb_of_string ?legacy_behavior str = | Arg_padding _ as pad, _ -> pad in (* Check that padty <> Zeros. *) - let check_no_0 symb (type a) (type b) (pad : (a, b) padding) = + let check_no_0 symb (type a b) (pad : (a, b) padding) : (a,b) padding = match pad with | No_padding -> pad | Lit_padding ((Left | Right), _) -> pad diff --git a/stdlib/camlinternalLazy.ml b/stdlib/camlinternalLazy.ml index 8226ffda..f03272e6 100644 --- a/stdlib/camlinternalLazy.ml +++ b/stdlib/camlinternalLazy.ml @@ -46,10 +46,18 @@ let force_val_lazy_block (blk : 'arg lazy_t) = (* [force] is not used, since [Lazy.force] is declared as a primitive - whose code inlines the tag tests of its argument. This function is - here for the sake of completeness, and for debugging purpose. *) + whose code inlines the tag tests of its argument, except when afl + instrumentation is turned on. *) let force (lzv : 'arg lazy_t) = + (* Using [Sys.opaque_identity] prevents two potential problems: + - If the value is known to have Forward_tag, then its tag could have + changed during GC, so that information must be forgotten (see GPR#713 + and issue #7301) + - If the value is known to be immutable, then if the compiler + cannot prove that the last branch is not taken it will issue a + warning 59 (modification of an immutable value) *) + let lzv = Sys.opaque_identity lzv in let x = Obj.repr lzv in let t = Obj.tag x in if t = Obj.forward_tag then (Obj.obj (Obj.field x 0) : 'arg) else diff --git a/stdlib/camlinternalMod.ml b/stdlib/camlinternalMod.ml index bfc3b12a..eb66d226 100644 --- a/stdlib/camlinternalMod.ml +++ b/stdlib/camlinternalMod.ml @@ -28,6 +28,38 @@ let overwrite o n = Obj.set_field o i (Obj.field n i) done +let overwrite_closure o n = + (* We need to use the [raw_field] functions at least on the code + pointer, which is not a valid value in -no-naked-pointers + mode. *) + assert (Obj.tag n = Obj.closure_tag); + assert (Obj.size o >= Obj.size n); + let n_start_env = Obj.Closure.((info n).start_env) in + let o_start_env = Obj.Closure.((info o).start_env) in + (* if the environment of n starts before the one of o, + clear the raw fields in between. *) + for i = n_start_env to o_start_env - 1 do + Obj.set_raw_field o i Nativeint.one + done; + (* if the environment of o starts before the one of n, + clear the environment fields in between. *) + for i = o_start_env to n_start_env - 1 do + Obj.set_field o i (Obj.repr ()) + done; + for i = 0 to n_start_env - 1 do + (* code pointers, closure info fields, infix headers *) + Obj.set_raw_field o i (Obj.raw_field n i) + done; + for i = n_start_env to Obj.size n - 1 do + (* environment fields *) + Obj.set_field o i (Obj.field n i) + done; + for i = Obj.size n to Obj.size o - 1 do + (* clear the leftover space *) + Obj.set_field o i (Obj.repr ()) + done; + () + let rec init_mod loc shape = match shape with | Function -> @@ -37,7 +69,7 @@ let rec init_mod loc shape = let template = Obj.repr (fun _ -> raise (Undefined_recursive_module loc)) in - overwrite closure template; + overwrite_closure closure template; closure | Lazy -> Obj.repr (lazy (raise (Undefined_recursive_module loc))) @@ -61,8 +93,8 @@ let rec update_mod shape o n = && (Obj.size n = Obj.size o || (Sys.backend_type = Sys.Native && Obj.size n <= Obj.size o)) - then begin overwrite o n end - else overwrite o (Obj.repr (fun x -> (Obj.obj n : _ -> _) x)) + then begin overwrite_closure o n end + else overwrite_closure o (Obj.repr (fun x -> (Obj.obj n : _ -> _) x)) | Lazy -> if Obj.tag n = Obj.lazy_tag then Obj.set_field o 0 (Obj.field n 0) diff --git a/stdlib/digest.mli b/stdlib/digest.mli index c69b41a5..5471b458 100644 --- a/stdlib/digest.mli +++ b/stdlib/digest.mli @@ -16,12 +16,12 @@ (** MD5 message digest. This module provides functions to compute 128-bit 'digests' of - arbitrary-length strings or files. The digests are of cryptographic - quality: it is very hard, given a digest, to forge a string having - that digest. The algorithm used is MD5. This module should not be - used for secure and sensitive cryptographic applications. For these - kind of applications more recent and stronger cryptographic - primitives should be used instead. + arbitrary-length strings or files. The algorithm used is MD5. + + The MD5 hash function is not cryptographically secure. + Hence, this module should not be used for security-sensitive + applications. More recent, stronger cryptographic primitives + should be used instead. *) type t = string diff --git a/stdlib/dune b/stdlib/dune index ee66f6e7..16471f8f 100644 --- a/stdlib/dune +++ b/stdlib/dune @@ -18,14 +18,22 @@ (exit_module std_exit) (internal_modules Camlinternal*) (modules_before_stdlib - camlinternalFormatBasics)) + camlinternalFormatBasics + camlinternalAtomic)) (flags (:standard -w -9 -nolabels)) (preprocess (per_module ((action - (run awk -v dune_wrapped=true - -f %{dep:expand_module_aliases.awk} %{input-file})) - stdlib)))) + (progn + ; FIXME: remove after 4.12 + (run sed -i s/loc_FUNCTION/loc_POS/ %{input-file}) + (run awk -v dune_wrapped=true + -f %{dep:expand_module_aliases.awk} %{input-file}))) + stdlib) + (; FIXME: remove after 4.12 (this erases injectivity annotations) + (action (run sed "s/\\!\\([-+]*'\\)/\\1/g" %{input-file})) + atomic bigarray camlinternalAtomic camlinternalOO ephemeron hashtbl map + moreLabels queue stack stream weak)))) (rule (targets sys.ml) diff --git a/stdlib/either.ml b/stdlib/either.ml new file mode 100644 index 00000000..9ea2f893 --- /dev/null +++ b/stdlib/either.ml @@ -0,0 +1,66 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Gabriel Scherer, projet Parsifal, INRIA Saclay *) +(* *) +(* Copyright 2019 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +type ('a, 'b) t = Left of 'a | Right of 'b + +let left v = Left v +let right v = Right v + +let is_left = function +| Left _ -> true +| Right _ -> false + +let is_right = function +| Left _ -> false +| Right _ -> true + +let find_left = function +| Left v -> Some v +| Right _ -> None + +let find_right = function +| Left _ -> None +| Right v -> Some v + +let map_left f = function +| Left v -> Left (f v) +| Right _ as e -> e + +let map_right f = function +| Left _ as e -> e +| Right v -> Right (f v) + +let map ~left ~right = function +| Left v -> Left (left v) +| Right v -> Right (right v) + +let fold ~left ~right = function +| Left v -> left v +| Right v -> right v + +let iter = fold + +let for_all = fold + +let equal ~left ~right e1 e2 = match e1, e2 with +| Left v1, Left v2 -> left v1 v2 +| Right v1, Right v2 -> right v1 v2 +| Left _, Right _ | Right _, Left _ -> false + +let compare ~left ~right e1 e2 = match e1, e2 with +| Left v1, Left v2 -> left v1 v2 +| Right v1, Right v2 -> right v1 v2 +| Left _, Right _ -> (-1) +| Right _, Left _ -> 1 diff --git a/stdlib/either.mli b/stdlib/either.mli new file mode 100644 index 00000000..3d907b4c --- /dev/null +++ b/stdlib/either.mli @@ -0,0 +1,115 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Gabriel Scherer, projet Parsifal, INRIA Saclay *) +(* *) +(* Copyright 2019 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(** Either type. + + Either is the simplest and most generic sum/variant type: + a value of [('a, 'b) Either.t] is either a [Left (v : 'a)] + or a [Right (v : 'b)]. + + It is a natural choice in the API of generic functions where values + could fall in two different cases, possibly at different types, + without assigning a specific meaning to what each case should be. + + For example: + +{[List.partition_map: + ('a -> ('b, 'c) Either.t) -> 'a list -> 'b list * 'c list]} + + If you are looking for a parametrized type where + one alternative means success and the other means failure, + you should use the more specific type {!Result.t}. + + @since 4.12 +*) + +(* Unlike [result], no [either] type is made available in Stdlib, + one needs to access [Either.t] explicitly: + + - This type is less common in typical OCaml codebases, + which prefer domain-specific variant types whose constructors + carry more meaning. + - Adding this to Stdlib would raise warnings in existing codebases + that already use a constructor named Left or Right: + + when opening a module that exports such a name, + warning 45 is raised + + adding a second constructor of the same name in scope kicks + in the disambiguation mechanisms, and warning 41 may now + be raised by existing code. + + If the use becomes more common in the future we can always + revisit this choice. +*) + +type ('a, 'b) t = Left of 'a | Right of 'b (**) +(** A value of [('a, 'b) Either.t] contains + either a value of ['a] or a value of ['b] *) + +val left : 'a -> ('a, 'b) t +(** [left v] is [Left v]. *) + +val right : 'b -> ('a, 'b) t +(** [right v] is [Right v]. *) + +val is_left : ('a, 'b) t -> bool +(** [is_left (Left v)] is [true], [is_left (Right v)] is [false]. *) + +val is_right : ('a, 'b) t -> bool +(** [is_right (Left v)] is [false], [is_right (Right v)] is [true]. *) + +val find_left : ('a, 'b) t -> 'a option +(** [find_left (Left v)] is [Some v], [find_left (Right _)] is [None] *) + +val find_right : ('a, 'b) t -> 'b option +(** [find_right (Right v)] is [Some v], [find_right (Left _)] is [None] *) + +val map_left : ('a1 -> 'a2) -> ('a1, 'b) t -> ('a2, 'b) t +(** [map_left f e] is [Left (f v)] if [e] is [Left v] + and [e] if [e] is [Right _]. *) + +val map_right : ('b1 -> 'b2) -> ('a, 'b1) t -> ('a, 'b2) t +(** [map_right f e] is [Right (f v)] if [e] is [Right v] + and [e] if [e] is [Left _]. *) + +val map : + left:('a1 -> 'a2) -> right:('b1 -> 'b2) -> ('a1, 'b1) t -> ('a2, 'b2) t +(** [map ~left ~right (Left v)] is [Left (left v)], + [map ~left ~right (Right v)] is [Right (right v)]. *) + +val fold : left:('a -> 'c) -> right:('b -> 'c) -> ('a, 'b) t -> 'c +(** [fold ~left ~right (Left v)] is [left v], and + [fold ~left ~right (Right v)] is [right v]. *) + +val iter : left:('a -> unit) -> right:('b -> unit) -> ('a, 'b) t -> unit +(** [iter ~left ~right (Left v)] is [left v], and + [iter ~left ~right (Right v)] is [right v]. *) + +val for_all : left:('a -> bool) -> right:('b -> bool) -> ('a, 'b) t -> bool +(** [for_all ~left ~right (Left v)] is [left v], and + [for_all ~left ~right (Right v)] is [right v]. *) + +val equal : + left:('a -> 'a -> bool) -> right:('b -> 'b -> bool) -> + ('a, 'b) t -> ('a, 'b) t -> bool +(** [equal ~left ~right e0 e1] tests equality of [e0] and [e1] using [left] + and [right] to respectively compare values wrapped by [Left _] and + [Right _]. *) + +val compare : + left:('a -> 'a -> int) -> right:('b -> 'b -> int) -> + ('a, 'b) t -> ('a, 'b) t -> int +(** [compare ~left ~right e0 e1] totally orders [e0] and [e1] using [left] and + [right] to respectively compare values wrapped by [Left _ ] and [Right _]. + [Left _] values are smaller than [Right _] values. *) diff --git a/stdlib/ephemeron.mli b/stdlib/ephemeron.mli index 434115e9..f1515124 100644 --- a/stdlib/ephemeron.mli +++ b/stdlib/ephemeron.mli @@ -13,9 +13,9 @@ (* *) (**************************************************************************) -(** Ephemerons and weak hash tables *) +(** Ephemerons and weak hash tables. -(** Ephemerons and weak hash tables are useful when one wants to cache + Ephemerons and weak hash tables are useful when one wants to cache or memorize the computation of a function, as long as the arguments and the function are used, without creating memory leaks by continuously keeping old computation results that are not @@ -188,6 +188,7 @@ module K1 : sig The seed is similar to the one of {!Hashtbl.MakeSeeded}. *) end +(** Ephemerons with one key. *) module K2 : sig type ('k1,'k2,'d) t (** an ephemeron with two keys *) @@ -266,6 +267,7 @@ module K2 : sig The seed is similar to the one of {!Hashtbl.MakeSeeded}. *) end +(** Emphemerons with two keys. *) module Kn : sig type ('k,'d) t (** an ephemeron with an arbitrary number of keys @@ -322,6 +324,7 @@ module Kn : sig The seed is similar to the one of {!Hashtbl.MakeSeeded}. *) end +(** Emphemerons with arbitrary number of keys of the same type. *) module GenHashTable: sig (** Define a hash table on generic containers which have a notion of @@ -329,7 +332,8 @@ module GenHashTable: sig automatically remove it. *) type equal = - | ETrue | EFalse + | ETrue + | EFalse | EDead (** the container is dead *) module MakeSeeded(H: @@ -369,3 +373,4 @@ module GenHashTable: sig for keeping the information given *) end +(** Hash tables on generic containers with notion of death and aliveness. *) diff --git a/stdlib/expand_module_aliases.awk b/stdlib/expand_module_aliases.awk index 7f1e49ba..515282d4 100644 --- a/stdlib/expand_module_aliases.awk +++ b/stdlib/expand_module_aliases.awk @@ -18,7 +18,8 @@ BEGIN { state=0 } NR == 1 { printf ("# 1 \"%s\"\n", FILENAME) } /\(\*MODULE_ALIASES\*\)\r?/ { state=1 } { if (state==0) - print; + { if (FILENAME ~ /Labels/ && + sub(/@since [^(]* \(/, "@since ")) sub(/ in [^)]*\)/, ""); print; } else if (state==1) state=2; else if ($1 == "module") diff --git a/stdlib/filename.mli b/stdlib/filename.mli index 9f99d2c5..443e06a5 100644 --- a/stdlib/filename.mli +++ b/stdlib/filename.mli @@ -222,4 +222,5 @@ val quote_command : Under Win32, additional quoting is performed as required by the [cmd.exe] shell that is called by {!Sys.command}. @raise Failure if the command cannot be escaped on the current platform. + @since 4.10.0 *) diff --git a/stdlib/float.ml b/stdlib/float.ml index 3145f1c6..4eb0451f 100644 --- a/stdlib/float.ml +++ b/stdlib/float.ml @@ -161,10 +161,8 @@ module Array = struct let unsafe_fill a ofs len v = for i = ofs to ofs + len - 1 do unsafe_set a i v done - let unsafe_blit src sofs dst dofs len = - for i = 0 to len - 1 do - unsafe_set dst (dofs + i) (unsafe_get src (sofs + i)) - done + external unsafe_blit: t -> int -> t -> int -> int -> unit = + "caml_floatarray_blit" [@@noalloc] let check a ofs len msg = if ofs < 0 || len < 0 || ofs + len < 0 || ofs + len > length a then diff --git a/stdlib/float.mli b/stdlib/float.mli index 51263be7..266e9e04 100644 --- a/stdlib/float.mli +++ b/stdlib/float.mli @@ -14,7 +14,15 @@ (* *) (**************************************************************************) -(** {1 Floating-point arithmetic} +(* NOTE: + If this file is float.template.mli, run tools/sync_stdlib_docs after editing + it to generate float.mli. + + If this file is float.mli, do not edit it directly -- edit + templates/float.template.mli instead. + *) + +(** Floating-point arithmetic. OCaml's floating-point numbers follow the IEEE 754 standard, using double precision (64 bits) numbers. @@ -24,8 +32,8 @@ [neg_infinity] for [-1.0 /. 0.0], and [nan] ('not a number') for [0.0 /. 0.0]. These special numbers then propagate through floating-point computations as expected: for instance, - [1.0 /. infinity] is [0.0], and any arithmetic operation with [nan] - as argument returns [nan] as result. + [1.0 /. infinity] is [0.0], basic arithmetic operations + ([+.], [-.], [*.], [/.]) with [nan] as an argument return [nan], ... @since 4.07.0 *) @@ -115,23 +123,24 @@ val epsilon : float floating-point number greater than [1.0]. *) val is_finite : float -> bool -(** [is_finite x] is [true] iff [x] is finite i.e., not infinite and +(** [is_finite x] is [true] if and only if [x] is finite i.e., not infinite and not {!nan}. @since 4.08.0 *) val is_infinite : float -> bool -(** [is_infinite x] is [true] iff [x] is {!infinity} or {!neg_infinity}. +(** [is_infinite x] is [true] if and only if [x] is {!infinity} or + {!neg_infinity}. @since 4.08.0 *) val is_nan : float -> bool -(** [is_nan x] is [true] iff [x] is not a number (see {!nan}). +(** [is_nan x] is [true] if and only if [x] is not a number (see {!nan}). @since 4.08.0 *) val is_integer : float -> bool -(** [is_integer x] is [true] iff [x] is an integer. +(** [is_integer x] is [true] if and only if [x] is an integer. @since 4.08.0 *) @@ -312,7 +321,7 @@ external copy_sign : float -> float -> float external sign_bit : (float [@unboxed]) -> bool = "caml_signbit_float" "caml_signbit" [@@noalloc] -(** [sign_bit x] is [true] iff the sign bit of [x] is set. +(** [sign_bit x] is [true] if and only if the sign bit of [x] is set. For example [sign_bit 1.] and [signbit 0.] are [false] while [sign_bit (-1.)] and [sign_bit (-0.)] are [true]. @@ -389,9 +398,10 @@ val hash: t -> int (** The hash function for floating-point numbers. *) module Array : sig - type t = floatarray - (** The type of float arrays with packed representation. @since 4.08.0 *) + (** The type of float arrays with packed representation. + @since 4.08.0 + *) val length : t -> int (** Return the length (number of elements) of the given floatarray. *) @@ -433,32 +443,33 @@ module Array : sig (** Same as {!append}, but concatenates a list of floatarrays. *) val sub : t -> int -> int -> t - (** [sub a start len] returns a fresh floatarray of length [len], - containing the elements number [start] to [start + len - 1] + (** [sub a pos len] returns a fresh floatarray of length [len], + containing the elements number [pos] to [pos + len - 1] of floatarray [a]. - @raise Invalid_argument if [start] and [len] do not + @raise Invalid_argument if [pos] and [len] do not designate a valid subarray of [a]; that is, if - [start < 0], or [len < 0], or [start + len > length a]. *) + [pos < 0], or [len < 0], or [pos + len > length a]. *) val copy : t -> t (** [copy a] returns a copy of [a], that is, a fresh floatarray containing the same elements as [a]. *) val fill : t -> int -> int -> float -> unit - (** [fill a ofs len x] modifies the floatarray [a] in place, - storing [x] in elements number [ofs] to [ofs + len - 1]. - @raise Invalid_argument if [ofs] and [len] do not + (** [fill a pos len x] modifies the floatarray [a] in place, + storing [x] in elements number [pos] to [pos + len - 1]. + @raise Invalid_argument if [pos] and [len] do not designate a valid subarray of [a]. *) val blit : t -> int -> t -> int -> int -> unit - (** [blit v1 o1 v2 o2 len] copies [len] elements - from floatarray [v1], starting at element number [o1], to floatarray [v2], - starting at element number [o2]. It works correctly even if - [v1] and [v2] are the same floatarray, and the source and + (** [blit src src_pos dst dst_pos len] copies [len] elements + from floatarray [src], starting at element number [src_pos], + to floatarray [dst], starting at element number [dst_pos]. + It works correctly even if + [src] and [dst] are the same floatarray, and the source and destination chunks overlap. - @raise Invalid_argument if [o1] and [len] do not - designate a valid subarray of [v1], or if [o2] and [len] do not - designate a valid subarray of [v2]. *) + @raise Invalid_argument if [src_pos] and [len] do not + designate a valid subarray of [src], or if [dst_pos] and [len] do not + designate a valid subarray of [dst]. *) val to_list : t -> float list (** [to_list a] returns the list of all the elements of [a]. *) @@ -491,13 +502,13 @@ module Array : sig and the element itself as second argument. *) val fold_left : ('a -> float -> 'a) -> 'a -> t -> 'a - (** [fold_left f x a] computes - [f (... (f (f x a.(0)) a.(1)) ...) a.(n-1)], - where [n] is the length of the floatarray [a]. *) + (** [fold_left f x init] computes + [f (... (f (f x init.(0)) init.(1)) ...) init.(n-1)], + where [n] is the length of the floatarray [init]. *) val fold_right : (float -> 'a -> 'a) -> t -> 'a -> 'a - (** [fold_right f a x] computes - [f a.(0) (f a.(1) ( ... (f a.(n-1) x) ...))], + (** [fold_right f a init] computes + [f a.(0) (f a.(1) ( ... (f a.(n-1) init) ...))], where [n] is the length of the floatarray [a]. *) (** {2 Iterators on two arrays} *) @@ -516,18 +527,18 @@ module Array : sig (** {2 Array scanning} *) val for_all : (float -> bool) -> t -> bool - (** [for_all p [|a1; ...; an|]] checks if all elements of the floatarray - satisfy the predicate [p]. That is, it returns - [(p a1) && (p a2) && ... && (p an)]. *) + (** [for_all f [|a1; ...; an|]] checks if all elements of the floatarray + satisfy the predicate [f]. That is, it returns + [(f a1) && (f a2) && ... && (f an)]. *) val exists : (float -> bool) -> t -> bool - (** [exists p [|a1; ...; an|]] checks if at least one element of - the floatarray satisfies the predicate [p]. That is, it returns - [(p a1) || (p a2) || ... || (p an)]. *) + (** [exists f [|a1; ...; an|]] checks if at least one element of + the floatarray satisfies the predicate [f]. That is, it returns + [(f a1) || (f a2) || ... || (f an)]. *) val mem : float -> t -> bool - (** [mem a l] is true if and only if there is an element of [l] that is - structurally equal to [a], i.e. there is an [x] in [l] such + (** [mem a set] is true if and only if there is an element of [set] that is + structurally equal to [a], i.e. there is an [x] in [set] such that [compare a x = 0]. *) val mem_ieee : float -> t -> bool @@ -552,12 +563,12 @@ module Array : sig Specification of the comparison function: Let [a] be the floatarray and [cmp] the comparison function. The following must be true for all [x], [y], [z] in [a] : -- [cmp x y] > 0 if and only if [cmp y x] < 0 -- if [cmp x y] >= 0 and [cmp y z] >= 0 then [cmp x z] >= 0 + - [cmp x y] > 0 if and only if [cmp y x] < 0 + - if [cmp x y] >= 0 and [cmp y z] >= 0 then [cmp x z] >= 0 When [sort] returns, [a] contains the same elements as before, reordered in such a way that for all i and j valid indices of [a] : -- [cmp a.(i) a.(j)] >= 0 if and only if i >= j + - [cmp a.(i) a.(j)] >= 0 if and only if i >= j *) val stable_sort : (float -> float -> int) -> t -> unit @@ -597,52 +608,235 @@ module Array : sig (** [map_from_array f a] applies function [f] to all the elements of [a], and builds a floatarray with the results returned by [f]. *) + (**/**) + (** {2 Undocumented functions} *) (* These functions are for system use only. Do not call directly. *) external unsafe_get : t -> int -> float = "%floatarray_unsafe_get" external unsafe_set : t -> int -> float -> unit = "%floatarray_unsafe_set" + end +(** Float arrays with packed representation. *) module ArrayLabels : sig - type t = floatarray + (** The type of float arrays with packed representation. + @since 4.08.0 + *) + val length : t -> int + (** Return the length (number of elements) of the given floatarray. *) + val get : t -> int -> float + (** [get a n] returns the element number [n] of floatarray [a]. + @raise Invalid_argument if [n] is outside the range 0 to + [(length a - 1)]. *) + val set : t -> int -> float -> unit + (** [set a n x] modifies floatarray [a] in place, replacing element + number [n] with [x]. + @raise Invalid_argument if [n] is outside the range 0 to + [(length a - 1)]. *) + val make : int -> float -> t + (** [make n x] returns a fresh floatarray of length [n], initialized with [x]. + @raise Invalid_argument if [n < 0] or [n > Sys.max_floatarray_length]. *) + val create : int -> t + (** [create n] returns a fresh floatarray of length [n], + with uninitialized data. + @raise Invalid_argument if [n < 0] or [n > Sys.max_floatarray_length]. *) + val init : int -> f:(int -> float) -> t + (** [init n ~f] returns a fresh floatarray of length [n], + with element number [i] initialized to the result of [f i]. + In other terms, [init n ~f] tabulates the results of [f] + applied to the integers [0] to [n-1]. + @raise Invalid_argument if [n < 0] or [n > Sys.max_floatarray_length]. *) + val append : t -> t -> t + (** [append v1 v2] returns a fresh floatarray containing the + concatenation of the floatarrays [v1] and [v2]. + @raise Invalid_argument if + [length v1 + length v2 > Sys.max_floatarray_length]. *) + val concat : t list -> t + (** Same as {!append}, but concatenates a list of floatarrays. *) + val sub : t -> pos:int -> len:int -> t + (** [sub a ~pos ~len] returns a fresh floatarray of length [len], + containing the elements number [pos] to [pos + len - 1] + of floatarray [a]. + @raise Invalid_argument if [pos] and [len] do not + designate a valid subarray of [a]; that is, if + [pos < 0], or [len < 0], or [pos + len > length a]. *) + val copy : t -> t + (** [copy a] returns a copy of [a], that is, a fresh floatarray + containing the same elements as [a]. *) + val fill : t -> pos:int -> len:int -> float -> unit + (** [fill a ~pos ~len x] modifies the floatarray [a] in place, + storing [x] in elements number [pos] to [pos + len - 1]. + @raise Invalid_argument if [pos] and [len] do not + designate a valid subarray of [a]. *) + val blit : src:t -> src_pos:int -> dst:t -> dst_pos:int -> len:int -> unit + (** [blit ~src ~src_pos ~dst ~dst_pos ~len] copies [len] elements + from floatarray [src], starting at element number [src_pos], + to floatarray [dst], starting at element number [dst_pos]. + It works correctly even if + [src] and [dst] are the same floatarray, and the source and + destination chunks overlap. + @raise Invalid_argument if [src_pos] and [len] do not + designate a valid subarray of [src], or if [dst_pos] and [len] do not + designate a valid subarray of [dst]. *) + val to_list : t -> float list + (** [to_list a] returns the list of all the elements of [a]. *) + val of_list : float list -> t + (** [of_list l] returns a fresh floatarray containing the elements + of [l]. + @raise Invalid_argument if the length of [l] is greater than + [Sys.max_floatarray_length].*) + + (** {2 Iterators} *) + val iter : f:(float -> unit) -> t -> unit + (** [iter ~f a] applies function [f] in turn to all + the elements of [a]. It is equivalent to + [f a.(0); f a.(1); ...; f a.(length a - 1); ()]. *) + val iteri : f:(int -> float -> unit) -> t -> unit + (** Same as {!iter}, but the + function is applied with the index of the element as first argument, + and the element itself as second argument. *) + val map : f:(float -> float) -> t -> t + (** [map ~f a] applies function [f] to all the elements of [a], + and builds a floatarray with the results returned by [f]. *) + val mapi : f:(int -> float -> float) -> t -> t + (** Same as {!map}, but the + function is applied to the index of the element as first argument, + and the element itself as second argument. *) + val fold_left : f:('a -> float -> 'a) -> init:'a -> t -> 'a + (** [fold_left ~f x ~init] computes + [f (... (f (f x init.(0)) init.(1)) ...) init.(n-1)], + where [n] is the length of the floatarray [init]. *) + val fold_right : f:(float -> 'a -> 'a) -> t -> init:'a -> 'a + (** [fold_right f a init] computes + [f a.(0) (f a.(1) ( ... (f a.(n-1) init) ...))], + where [n] is the length of the floatarray [a]. *) + + (** {2 Iterators on two arrays} *) + val iter2 : f:(float -> float -> unit) -> t -> t -> unit + (** [Array.iter2 ~f a b] applies function [f] to all the elements of [a] + and [b]. + @raise Invalid_argument if the floatarrays are not the same size. *) + val map2 : f:(float -> float -> float) -> t -> t -> t + (** [map2 ~f a b] applies function [f] to all the elements of [a] + and [b], and builds a floatarray with the results returned by [f]: + [[| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|]]. + @raise Invalid_argument if the floatarrays are not the same size. *) + + (** {2 Array scanning} *) + val for_all : f:(float -> bool) -> t -> bool + (** [for_all ~f [|a1; ...; an|]] checks if all elements of the floatarray + satisfy the predicate [f]. That is, it returns + [(f a1) && (f a2) && ... && (f an)]. *) + val exists : f:(float -> bool) -> t -> bool + (** [exists f [|a1; ...; an|]] checks if at least one element of + the floatarray satisfies the predicate [f]. That is, it returns + [(f a1) || (f a2) || ... || (f an)]. *) + val mem : float -> set:t -> bool + (** [mem a ~set] is true if and only if there is an element of [set] that is + structurally equal to [a], i.e. there is an [x] in [set] such + that [compare a x = 0]. *) + val mem_ieee : float -> set:t -> bool + (** Same as {!mem}, but uses IEEE equality instead of structural equality. *) + + (** {2 Sorting} *) + val sort : cmp:(float -> float -> int) -> t -> unit + (** Sort a floatarray in increasing order according to a comparison + function. The comparison function must return 0 if its arguments + compare as equal, a positive integer if the first is greater, + and a negative integer if the first is smaller (see below for a + complete specification). For example, {!Stdlib.compare} is + a suitable comparison function. After calling [sort], the + array is sorted in place in increasing order. + [sort] is guaranteed to run in constant heap space + and (at most) logarithmic stack space. + + The current implementation uses Heap Sort. It runs in constant + stack space. + + Specification of the comparison function: + Let [a] be the floatarray and [cmp] the comparison function. The following + must be true for all [x], [y], [z] in [a] : + - [cmp x y] > 0 if and only if [cmp y x] < 0 + - if [cmp x y] >= 0 and [cmp y z] >= 0 then [cmp x z] >= 0 + + When [sort] returns, [a] contains the same elements as before, + reordered in such a way that for all i and j valid indices of [a] : + - [cmp a.(i) a.(j)] >= 0 if and only if i >= j + *) + val stable_sort : cmp:(float -> float -> int) -> t -> unit + (** Same as {!sort}, but the sorting algorithm is stable (i.e. + elements that compare equal are kept in their original order) and + not guaranteed to run in constant heap space. + + The current implementation uses Merge Sort. It uses a temporary + floatarray of length [n/2], where [n] is the length of the floatarray. + It is usually faster than the current implementation of {!sort}. *) + val fast_sort : cmp:(float -> float -> int) -> t -> unit + (** Same as {!sort} or {!stable_sort}, whichever is faster + on typical input. *) + + (** {2 Iterators} *) + val to_seq : t -> float Seq.t + (** Iterate on the floatarray, in increasing order. Modifications of the + floatarray during iteration will be reflected in the iterator. *) + val to_seqi : t -> (int * float) Seq.t + (** Iterate on the floatarray, in increasing order, yielding indices along + elements. Modifications of the floatarray during iteration will be + reflected in the iterator. *) + val of_seq : float Seq.t -> t + (** Create an array from the generator. *) + + val map_to_array : f:(float -> 'a) -> t -> 'a array + (** [map_to_array ~f a] applies function [f] to all the elements of [a], + and builds an array with the results returned by [f]: + [[| f a.(0); f a.(1); ...; f a.(length a - 1) |]]. *) + val map_from_array : f:('a -> float) -> 'a array -> t + (** [map_from_array ~f a] applies function [f] to all the elements of [a], + and builds a floatarray with the results returned by [f]. *) + + (**/**) + + (** {2 Undocumented functions} *) (* These functions are for system use only. Do not call directly. *) external unsafe_get : t -> int -> float = "%floatarray_unsafe_get" external unsafe_set : t -> int -> float -> unit = "%floatarray_unsafe_set" + end +(** Float arrays with packed representation (labeled functions). *) diff --git a/stdlib/format.ml b/stdlib/format.ml index 2ed7bc6d..f1992924 100644 --- a/stdlib/format.ml +++ b/stdlib/format.ml @@ -1191,6 +1191,22 @@ let rec pp_print_list ?(pp_sep = pp_print_cut) pp_v ppf = function pp_sep ppf (); pp_print_list ~pp_sep pp_v ppf vs +(* To format a sequence *) +let rec pp_print_seq_in ~pp_sep pp_v ppf seq = + match seq () with + | Seq.Nil -> () + | Seq.Cons (v, seq) -> + pp_sep ppf (); + pp_v ppf v; + pp_print_seq_in ~pp_sep pp_v ppf seq + +let pp_print_seq ?(pp_sep = pp_print_cut) pp_v ppf seq = + match seq () with + | Seq.Nil -> () + | Seq.Cons (v, seq) -> + pp_v ppf v; + pp_print_seq_in ~pp_sep pp_v ppf seq + (* To format free-flowing text *) let pp_print_text ppf s = let len = String.length s in diff --git a/stdlib/format.mli b/stdlib/format.mli index 00aae365..d3ef2a62 100644 --- a/stdlib/format.mli +++ b/stdlib/format.mli @@ -807,7 +807,7 @@ type formatter_out_functions = { out_flush : unit -> unit; out_newline : unit -> unit; out_spaces : int -> unit; - out_indent : int -> unit; + out_indent : int -> unit;(** @since 4.06.0 *) } (** The set of output functions specific to a formatter: - the [out_string] function performs all the pretty-printer string output. @@ -1084,6 +1084,19 @@ val pp_print_list: @since 4.02.0 *) +val pp_print_seq: + ?pp_sep:(formatter -> unit -> unit) -> + (formatter -> 'a -> unit) -> (formatter -> 'a Seq.t -> unit) +(** [pp_print_seq ?pp_sep pp_v ppf s] prints items of sequence [s], + using [pp_v] to print each item, and calling [pp_sep] + between items ([pp_sep] defaults to {!pp_print_cut}. + Does nothing on empty sequences. + + This function does not terminate on infinite sequences. + + @since 4.12 +*) + val pp_print_text : formatter -> string -> unit (** [pp_print_text ppf s] prints [s] with spaces and newlines respectively printed using {!pp_print_space} and {!pp_force_newline}. diff --git a/stdlib/gc.ml b/stdlib/gc.ml index 9a5c004e..b4fc555b 100644 --- a/stdlib/gc.ml +++ b/stdlib/gc.ml @@ -31,6 +31,7 @@ type stat = { compactions : int; top_heap_words : int; stack_size : int; + forced_major_collections: int; } type control = { @@ -70,9 +71,10 @@ open Printf let print_stat c = let st = stat () in - fprintf c "minor_collections: %d\n" st.minor_collections; - fprintf c "major_collections: %d\n" st.major_collections; - fprintf c "compactions: %d\n" st.compactions; + fprintf c "minor_collections: %d\n" st.minor_collections; + fprintf c "major_collections: %d\n" st.major_collections; + fprintf c "compactions: %d\n" st.compactions; + fprintf c "forced_major_collections: %d\n" st.forced_major_collections; fprintf c "\n"; let l1 = String.length (sprintf "%.0f" st.minor_words) in fprintf c "minor_words: %*.0f\n" l1 st.minor_words; @@ -123,10 +125,11 @@ let delete_alarm a = a := false module Memprof = struct + type allocation_source = Normal | Marshal | Custom type allocation = { n_samples : int; size : int; - unmarshalled : bool; + source : allocation_source; callstack : Printexc.raw_backtrace } type ('minor, 'major) tracker = { diff --git a/stdlib/gc.mli b/stdlib/gc.mli index 567e4d78..ab615c3c 100644 --- a/stdlib/gc.mli +++ b/stdlib/gc.mli @@ -72,6 +72,10 @@ type stat = stack_size: int; (** Current size of the stack, in words. @since 3.12.0 *) + + forced_major_collections: int; + (** Number of forced full major collections completed since the program + was started. @since 4.12.0 *) } (** The memory management counters are returned in a [stat] record. @@ -111,7 +115,7 @@ type control = (** This value controls the GC messages on standard error output. It is a sum of some of the following flags, to print messages on the corresponding events: - - [0x001] Start of major GC cycle. + - [0x001] Start and end of major GC cycle. - [0x002] Minor collection and major GC slice. - [0x004] Growing and shrinking of the heap. - [0x008] Resizing of stacks and memory manager tables. @@ -459,6 +463,7 @@ external eventlog_resume : unit -> unit = "caml_eventlog_resume" notice. *) module Memprof : sig + type allocation_source = Normal | Marshal | Custom type allocation = private { n_samples : int; (** The number of samples in this block (>= 1). *) @@ -466,8 +471,8 @@ module Memprof : size : int; (** The size of the block, in words, excluding the header. *) - unmarshalled : bool; - (** Whether the block comes from unmarshalling. *) + source : allocation_source; + (** The type of the allocation. *) callstack : Printexc.raw_backtrace (** The callstack for the allocation. *) @@ -490,6 +495,9 @@ module Memprof : to keep for minor blocks, and ['major] the type of metadata for major blocks. + When using threads, it is guaranteed that allocation callbacks are + always run in the thread where the allocation takes place. + If an allocation-tracking or promotion-tracking function returns [None], memprof stops tracking the corresponding value. *) @@ -517,26 +525,22 @@ module Memprof : over their lifetime in the minor and major heap. Sampling is temporarily disabled when calling a callback - for the current thread. So they do not need to be reentrant if + for the current thread. So they do not need to be re-entrant if the program is single-threaded. However, if threads are used, it is possible that a context switch occurs during a callback, - in this case the callback functions must be reentrant. + in this case the callback functions must be re-entrant. Note that the callback can be postponed slightly after the actual event. The callstack passed to the callback is always - accurate, but the program state may have evolved. - - Calling [Thread.exit] in a callback is currently unsafe and can - result in undefined behavior. *) + accurate, but the program state may have evolved. *) val stop : unit -> unit (** Stop the sampling. Fails if sampling is not active. - This function does not allocate memory, but tries to run the - postponed callbacks for already allocated memory blocks (of - course, these callbacks may allocate). + This function does not allocate memory. - All the already tracked blocks are discarded. + All the already tracked blocks are discarded. If there are + pending postponed callbacks, they may be discarded. Calling [stop] when a callback is running can lead to callbacks not being called even though some events happened. *) diff --git a/stdlib/genlex.mli b/stdlib/genlex.mli index 47394926..875782c2 100644 --- a/stdlib/genlex.mli +++ b/stdlib/genlex.mli @@ -23,20 +23,20 @@ Example: a lexer suitable for a desk calculator is obtained by - {[ let lexer = make_lexer ["+";"-";"*";"/";"let";"="; "("; ")"] ]} +{[ let lexer = make_lexer ["+"; "-"; "*"; "/"; "let"; "="; "("; ")"]]} The associated parser would be a function from [token stream] to, for instance, [int], and would have rules such as: {[ - let rec parse_expr = parser - | [< n1 = parse_atom; n2 = parse_remainder n1 >] -> n2 - and parse_atom = parser - | [< 'Int n >] -> n - | [< 'Kwd "("; n = parse_expr; 'Kwd ")" >] -> n - and parse_remainder n1 = parser - | [< 'Kwd "+"; n2 = parse_expr >] -> n1+n2 - | [< >] -> n1 + let rec parse_expr = parser + | [< n1 = parse_atom; n2 = parse_remainder n1 >] -> n2 + and parse_atom = parser + | [< 'Int n >] -> n + | [< 'Kwd "("; n = parse_expr; 'Kwd ")" >] -> n + and parse_remainder n1 = parser + | [< 'Kwd "+"; n2 = parse_expr >] -> n1 + n2 + | [< >] -> n1 ]} One should notice that the use of the [parser] keyword and associated diff --git a/stdlib/hashtbl.ml b/stdlib/hashtbl.ml index 97bc5321..9c6792c1 100644 --- a/stdlib/hashtbl.ml +++ b/stdlib/hashtbl.ml @@ -112,39 +112,43 @@ let copy h = { h with data = Array.map copy_bucketlist h.data } let length h = h.size +let insert_all_buckets indexfun inplace odata ndata = + let nsize = Array.length ndata in + let ndata_tail = Array.make nsize Empty in + let rec insert_bucket = function + | Empty -> () + | Cons {key; data; next} as cell -> + let cell = + if inplace then cell + else Cons {key; data; next = Empty} + in + let nidx = indexfun key in + begin match ndata_tail.(nidx) with + | Empty -> ndata.(nidx) <- cell; + | Cons tail -> tail.next <- cell; + end; + ndata_tail.(nidx) <- cell; + insert_bucket next + in + for i = 0 to Array.length odata - 1 do + insert_bucket odata.(i) + done; + if inplace then + for i = 0 to nsize - 1 do + match ndata_tail.(i) with + | Empty -> () + | Cons tail -> tail.next <- Empty + done + let resize indexfun h = let odata = h.data in let osize = Array.length odata in let nsize = osize * 2 in if nsize < Sys.max_array_length then begin let ndata = Array.make nsize Empty in - let ndata_tail = Array.make nsize Empty in let inplace = not (ongoing_traversal h) in h.data <- ndata; (* so that indexfun sees the new bucket count *) - let rec insert_bucket = function - | Empty -> () - | Cons {key; data; next} as cell -> - let cell = - if inplace then cell - else Cons {key; data; next = Empty} - in - let nidx = indexfun h key in - begin match ndata_tail.(nidx) with - | Empty -> ndata.(nidx) <- cell; - | Cons tail -> tail.next <- cell; - end; - ndata_tail.(nidx) <- cell; - insert_bucket next - in - for i = 0 to osize - 1 do - insert_bucket odata.(i) - done; - if inplace then - for i = 0 to nsize - 1 do - match ndata_tail.(i) with - | Empty -> () - | Cons tail -> tail.next <- Empty - done; + insert_all_buckets (indexfun h) inplace odata ndata end let iter f h = @@ -192,7 +196,8 @@ let filter_map_inplace f h = try for i = 0 to Array.length d - 1 do filter_map_inplace_bucket f h i Empty h.data.(i) - done + done; + if not old_trav then flip_ongoing_traversal h with exn when not old_trav -> flip_ongoing_traversal h; raise exn @@ -283,7 +288,7 @@ module type SeededHashedType = module type S = sig type key - type 'a t + type !'a t val create: int -> 'a t val clear : 'a t -> unit val reset : 'a t -> unit @@ -311,7 +316,7 @@ module type S = module type SeededS = sig type key - type 'a t + type !'a t val create : ?random:bool -> int -> 'a t val clear : 'a t -> unit val reset : 'a t -> unit @@ -489,18 +494,15 @@ module Make(H: HashedType): (S with type key = H.t) = external seeded_hash_param : int -> int -> int -> 'a -> int = "caml_hash" [@@noalloc] -external old_hash_param : - int -> int -> 'a -> int = "caml_hash_univ_param" [@@noalloc] let hash x = seeded_hash_param 10 100 0 x let hash_param n1 n2 x = seeded_hash_param n1 n2 0 x let seeded_hash seed x = seeded_hash_param 10 100 seed x let key_index h key = - (* compatibility with old hash tables *) - if Obj.size (Obj.repr h) >= 3 + if Obj.size (Obj.repr h) >= 4 then (seeded_hash_param 10 100 h.seed key) land (Array.length h.data - 1) - else (old_hash_param 10 100 key) mod (Array.length h.data) + else invalid_arg "Hashtbl: unsupported hash table format" let add h key data = let i = key_index h key in @@ -611,3 +613,18 @@ let of_seq i = let tbl = create 16 in replace_seq tbl i; tbl + +let rebuild ?(random = !randomized) h = + let s = power_2_above 16 (Array.length h.data) in + let seed = + if random then Random.State.bits (Lazy.force prng) + else if Obj.size (Obj.repr h) >= 4 then h.seed + else 0 in + let h' = { + size = h.size; + data = Array.make s Empty; + seed = seed; + initial_size = if Obj.size (Obj.repr h) >= 4 then h.initial_size else s + } in + insert_all_buckets (key_index h') false h.data h'.data; + h' diff --git a/stdlib/hashtbl.mli b/stdlib/hashtbl.mli index 5a9d825a..47f1d9b2 100644 --- a/stdlib/hashtbl.mli +++ b/stdlib/hashtbl.mli @@ -13,6 +13,9 @@ (* *) (**************************************************************************) +(* NOTE: If this file is hashtbl.mli, do not edit it directly! Instead, + edit templates/hashtbl.template.mli and run tools/sync_stdlib_docs *) + (** Hash tables and hash functions. Hash tables are hashed association tables, with in-place modification. @@ -22,22 +25,23 @@ (** {1 Generic interface} *) -type ('a, 'b) t +type (!'a, !'b) t (** The type of hash tables from type ['a] to type ['b]. *) -val create : ?random:bool -> int -> ('a, 'b) t +val create : ?random: (* thwart tools/sync_stdlib_docs *) bool -> + int -> ('a, 'b) t (** [Hashtbl.create n] creates a new, empty hash table, with initial size [n]. For best results, [n] should be on the order of the expected number of elements that will be in the table. The table grows as needed, so [n] is just an initial guess. - The optional [random] parameter (a boolean) controls whether + The optional [~][random] parameter (a boolean) controls whether the internal organization of the hash table is randomized at each execution of [Hashtbl.create] or deterministic over all executions. - A hash table that is created with [~random:false] uses a - fixed hash function ({!Hashtbl.hash}) to distribute keys among + A hash table that is created with [~][random] set to [false] uses a + fixed hash function ({!hash}) to distribute keys among buckets. As a consequence, collisions between keys happen deterministically. In Web-facing applications or other security-sensitive applications, the deterministic collision @@ -45,23 +49,22 @@ val create : ?random:bool -> int -> ('a, 'b) t denial-of-service attack: the attacker sends input crafted to create many collisions in the table, slowing the application down. - A hash table that is created with [~random:true] uses the seeded - hash function {!Hashtbl.seeded_hash} with a seed that is randomly - chosen at hash table creation time. In effect, the hash function - used is randomly selected among [2^{30}] different hash functions. - All these hash functions have different collision patterns, - rendering ineffective the denial-of-service attack described above. - However, because of randomization, enumerating all elements of the - hash table using {!Hashtbl.fold} or {!Hashtbl.iter} is no longer - deterministic: elements are enumerated in different orders at - different runs of the program. - - If no [~random] parameter is given, hash tables are created + A hash table that is created with [~][random] set to [true] uses the seeded + hash function {!seeded_hash} with a seed that is randomly chosen at hash + table creation time. In effect, the hash function used is randomly + selected among [2^{30}] different hash functions. All these hash + functions have different collision patterns, rendering ineffective the + denial-of-service attack described above. However, because of + randomization, enumerating all elements of the hash table using {!fold} + or {!iter} is no longer deterministic: elements are enumerated in + different orders at different runs of the program. + + If no [~][random] parameter is given, hash tables are created in non-random mode by default. This default can be changed - either programmatically by calling {!Hashtbl.randomize} or by + either programmatically by calling {!randomize} or by setting the [R] flag in the [OCAMLRUNPARAM] environment variable. - @before 4.00.0 the [random] parameter was not present and all + @before 4.00.0 the [~][random] parameter was not present and all hash tables were created in non-randomized mode. *) val clear : ('a, 'b) t -> unit @@ -77,10 +80,11 @@ val copy : ('a, 'b) t -> ('a, 'b) t (** Return a copy of the given hashtable. *) val add : ('a, 'b) t -> 'a -> 'b -> unit -(** [Hashtbl.add tbl x y] adds a binding of [x] to [y] in table [tbl]. - Previous bindings for [x] are not removed, but simply - hidden. That is, after performing {!Hashtbl.remove}[ tbl x], - the previous binding for [x], if any, is restored. +(** [Hashtbl.add tbl key data] adds a binding of [key] to [data] + in table [tbl]. + Previous bindings for [key] are not removed, but simply + hidden. That is, after performing {!remove}[ tbl key], + the previous binding for [key], if any, is restored. (Same behavior as with association lists.) *) val find : ('a, 'b) t -> 'a -> 'b @@ -107,11 +111,11 @@ val remove : ('a, 'b) t -> 'a -> unit It does nothing if [x] is not bound in [tbl]. *) val replace : ('a, 'b) t -> 'a -> 'b -> unit -(** [Hashtbl.replace tbl x y] replaces the current binding of [x] - in [tbl] by a binding of [x] to [y]. If [x] is unbound in [tbl], - a binding of [x] to [y] is added to [tbl]. - This is functionally equivalent to {!Hashtbl.remove}[ tbl x] - followed by {!Hashtbl.add}[ tbl x y]. *) +(** [Hashtbl.replace tbl key data] replaces the current binding of [key] + in [tbl] by a binding of [key] to [data]. If [key] is unbound in [tbl], + a binding of [key] to [data] is added to [tbl]. + This is functionally equivalent to {!remove}[ tbl key] + followed by {!add}[ tbl key data]. *) val iter : ('a -> 'b -> unit) -> ('a, 'b) t -> unit (** [Hashtbl.iter f tbl] applies [f] to all bindings in table [tbl]. @@ -133,14 +137,15 @@ val iter : ('a -> 'b -> unit) -> ('a, 'b) t -> unit by [f] during the iteration. *) -val filter_map_inplace: ('a -> 'b -> 'b option) -> ('a, 'b) t -> unit +val filter_map_inplace: ('a -> 'b -> 'b option) -> ('a, 'b) t -> + unit (** [Hashtbl.filter_map_inplace f tbl] applies [f] to all bindings in table [tbl] and update each binding depending on the result of [f]. If [f] returns [None], the binding is discarded. If it returns [Some new_val], the binding is update to associate the key to [new_val]. - Other comments for {!Hashtbl.iter} apply as well. + Other comments for {!iter} apply as well. @since 4.03.0 *) val fold : ('a -> 'b -> 'c -> 'c) -> ('a, 'b) t -> 'c -> 'c @@ -173,33 +178,50 @@ val length : ('a, 'b) t -> int val randomize : unit -> unit (** After a call to [Hashtbl.randomize()], hash tables are created in - randomized mode by default: {!Hashtbl.create} returns randomized + randomized mode by default: {!create} returns randomized hash tables, unless the [~random:false] optional parameter is given. The same effect can be achieved by setting the [R] parameter in the [OCAMLRUNPARAM] environment variable. It is recommended that applications or Web frameworks that need to protect themselves against the denial-of-service attack described - in {!Hashtbl.create} call [Hashtbl.randomize()] at initialization + in {!create} call [Hashtbl.randomize()] at initialization time. Note that once [Hashtbl.randomize()] was called, there is no way - to revert to the non-randomized default behavior of {!Hashtbl.create}. + to revert to the non-randomized default behavior of {!create}. This is intentional. Non-randomized hash tables can still be created using [Hashtbl.create ~random:false]. @since 4.00.0 *) val is_randomized : unit -> bool -(** return if the tables are currently created in randomized mode by default - +(** Return [true] if the tables are currently created in randomized mode + by default, [false] otherwise. @since 4.03.0 *) +val rebuild : ?random (* thwart tools/sync_stdlib_docs *) :bool -> + ('a, 'b) t -> ('a, 'b) t +(** Return a copy of the given hashtable. Unlike {!copy}, + {!rebuild}[ h] re-hashes all the (key, value) entries of + the original table [h]. The returned hash table is randomized if + [h] was randomized, or the optional [random] parameter is true, or + if the default is to create randomized hash tables; see + {!create} for more information. + + {!rebuild} can safely be used to import a hash table built + by an old version of the {!Hashtbl} module, then marshaled to + persistent storage. After unmarshaling, apply {!rebuild} + to produce a hash table for the current version of the {!Hashtbl} + module. + + @since 4.12.0 *) + (** @since 4.00.0 *) type statistics = { num_bindings: int; (** Number of bindings present in the table. - Same value as returned by {!Hashtbl.length}. *) + Same value as returned by {!length}. *) num_buckets: int; (** Number of buckets in the table. *) max_bucket_length: int; @@ -297,20 +319,20 @@ module type HashedType = as computed by [hash]. Examples: suitable ([equal], [hash]) pairs for arbitrary key types include -- ([(=)], {!Hashtbl.hash}) for comparing objects by structure +- ([(=)], {!hash}) for comparing objects by structure (provided objects do not contain floats) -- ([(fun x y -> compare x y = 0)], {!Hashtbl.hash}) +- ([(fun x y -> compare x y = 0)], {!hash}) for comparing objects by structure and handling {!Stdlib.nan} correctly -- ([(==)], {!Hashtbl.hash}) for comparing objects by physical +- ([(==)], {!hash}) for comparing objects by physical equality (e.g. for mutable or cyclic objects). *) end -(** The input signature of the functor {!Hashtbl.Make}. *) +(** The input signature of the functor {!Make}. *) module type S = sig type key - type 'a t + type !'a t val create : int -> 'a t val clear : 'a t -> unit val reset : 'a t -> unit (** @since 4.00.0 *) @@ -326,7 +348,8 @@ module type S = val replace : 'a t -> key -> 'a -> unit val mem : 'a t -> key -> bool val iter : (key -> 'a -> unit) -> 'a t -> unit - val filter_map_inplace: (key -> 'a -> 'a option) -> 'a t -> unit + val filter_map_inplace: (key -> 'a -> 'a option) -> 'a t -> + unit (** @since 4.03.0 *) val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b @@ -351,7 +374,7 @@ module type S = val of_seq : (key * 'a) Seq.t -> 'a t (** @since 4.07 *) end -(** The output signature of the functor {!Hashtbl.Make}. *) +(** The output signature of the functor {!Make}. *) module Make (H : HashedType) : S with type key = H.t (** Functor building an implementation of the hashtable structure. @@ -377,17 +400,18 @@ module type SeededHashedType = (** A seeded hashing function on keys. The first argument is the seed. It must be the case that if [equal x y] is true, then [hash seed x = hash seed y] for any value of [seed]. - A suitable choice for [hash] is the function {!Hashtbl.seeded_hash} + A suitable choice for [hash] is the function {!seeded_hash} below. *) end -(** The input signature of the functor {!Hashtbl.MakeSeeded}. +(** The input signature of the functor {!MakeSeeded}. @since 4.00.0 *) module type SeededS = sig type key - type 'a t - val create : ?random:bool -> int -> 'a t + type !'a t + val create : ?random (* thwart tools/sync_stdlib_docs *) :bool -> + int -> 'a t val clear : 'a t -> unit val reset : 'a t -> unit val copy : 'a t -> 'a t @@ -400,7 +424,8 @@ module type SeededS = val replace : 'a t -> key -> 'a -> unit val mem : 'a t -> key -> bool val iter : (key -> 'a -> unit) -> 'a t -> unit - val filter_map_inplace: (key -> 'a -> 'a option) -> 'a t -> unit + val filter_map_inplace: (key -> 'a -> 'a option) -> 'a t -> + unit (** @since 4.03.0 *) val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b @@ -425,7 +450,7 @@ module type SeededS = val of_seq : (key * 'a) Seq.t -> 'a t (** @since 4.07 *) end -(** The output signature of the functor {!Hashtbl.MakeSeeded}. +(** The output signature of the functor {!MakeSeeded}. @since 4.00.0 *) module MakeSeeded (H : SeededHashedType) : SeededS with type key = H.t @@ -437,7 +462,7 @@ module MakeSeeded (H : SeededHashedType) : SeededS with type key = H.t interface, but use the seeded hashing and equality functions specified in the functor argument [H] instead of generic equality and hashing. The [create] operation of the - result structure supports the [~random] optional parameter + result structure supports the [~][random] optional parameter and returns randomized hash tables if [~random:true] is passed or if randomization is globally on (see {!Hashtbl.randomize}). @since 4.00.0 *) @@ -453,7 +478,7 @@ val hash : 'a -> int Moreover, [hash] always terminates, even on cyclic structures. *) val seeded_hash : int -> 'a -> int -(** A variant of {!Hashtbl.hash} that is further parameterized by +(** A variant of {!hash} that is further parameterized by an integer seed. @since 4.00.0 *) @@ -473,11 +498,11 @@ val hash_param : int -> int -> 'a -> int and therefore collisions are less likely to happen. However, hashing takes longer. The parameters [meaningful] and [total] govern the tradeoff between accuracy and speed. As default - choices, {!Hashtbl.hash} and {!Hashtbl.seeded_hash} take + choices, {!hash} and {!seeded_hash} take [meaningful = 10] and [total = 100]. *) val seeded_hash_param : int -> int -> int -> 'a -> int -(** A variant of {!Hashtbl.hash_param} that is further parameterized by +(** A variant of {!hash_param} that is further parameterized by an integer seed. Usage: [Hashtbl.seeded_hash_param meaningful total seed x]. @since 4.00.0 *) diff --git a/stdlib/int.mli b/stdlib/int.mli index 12a0167d..0c2a745e 100644 --- a/stdlib/int.mli +++ b/stdlib/int.mli @@ -103,7 +103,7 @@ external shift_right_logical : int -> int -> int = "%lsrint" (** {1:preds Predicates and comparisons} *) val equal : int -> int -> bool -(** [equal x y] is [true] iff [x = y]. *) +(** [equal x y] is [true] if and only if [x = y]. *) val compare : int -> int -> int (** [compare x y] is {!Stdlib.compare}[ x y] but more efficient. *) diff --git a/stdlib/list.ml b/stdlib/list.ml index a624f3b4..5efd72f0 100644 --- a/stdlib/list.ml +++ b/stdlib/list.ml @@ -283,6 +283,17 @@ let partition p l = | x :: l -> if p x then part (x :: yes) no l else part yes (x :: no) l in part [] [] l +let partition_map p l = + let rec part left right = function + | [] -> (rev left, rev right) + | x :: l -> + begin match p x with + | Either.Left v -> part (v :: left) right l + | Either.Right v -> part left (v :: right) l + end + in + part [] [] l + let rec split = function [] -> ([], []) | (x,y)::l -> @@ -538,6 +549,29 @@ let rec compare_length_with l n = compare_length_with l (n-1) ;; +(** {1 Comparison} *) + +(* Note: we are *not* shortcutting the list by using + [List.compare_lengths] first; this may be slower on long lists + immediately start with distinct elements. It is also incorrect for + [compare] below, and it is better (principle of least surprise) to + use the same approach for both functions. *) +let rec equal eq l1 l2 = + match l1, l2 with + | [], [] -> true + | [], _::_ | _::_, [] -> false + | a1::l1, a2::l2 -> eq a1 a2 && equal eq l1 l2 + +let rec compare cmp l1 l2 = + match l1, l2 with + | [], [] -> 0 + | [], _::_ -> -1 + | _::_, [] -> 1 + | a1::l1, a2::l2 -> + let c = cmp a1 a2 in + if c <> 0 then c + else compare cmp l1 l2 + (** {1 Iterators} *) let to_seq l = diff --git a/stdlib/list.mli b/stdlib/list.mli index 77714f1f..d86c609f 100644 --- a/stdlib/list.mli +++ b/stdlib/list.mli @@ -13,6 +13,14 @@ (* *) (**************************************************************************) +(* NOTE: + If this file is listLabels.mli, run tools/sync_stdlib_docs after editing it + to generate list.mli. + + If this file is list.mli, do not edit it directly -- edit + listLabels.mli instead. + *) + (** List operations. Some functions are flagged as not tail-recursive. A tail-recursive @@ -24,7 +32,10 @@ The above considerations can usually be ignored if your lists are not longer than about 10000 elements. -*) + + The labeled version of this module can be used as described in the + {!StdLabels} module. + *) type 'a t = 'a list = [] | (::) of 'a * 'a list (**) (** An alias for the type of lists. *) @@ -35,217 +46,278 @@ val length : 'a list -> int val compare_lengths : 'a list -> 'b list -> int (** Compare the lengths of two lists. [compare_lengths l1 l2] is equivalent to [compare (length l1) (length l2)], except that - the computation stops after itering on the shortest list. + the computation stops after reaching the end of the shortest list. @since 4.05.0 *) val compare_length_with : 'a list -> int -> int -(** Compare the length of a list to an integer. [compare_length_with l n] is - equivalent to [compare (length l) n], except that - the computation stops after at most [n] iterations on the list. +(** Compare the length of a list to an integer. [compare_length_with l len] is + equivalent to [compare (length l) len], except that the computation stops + after at most [len] iterations on the list. @since 4.05.0 -*) + *) val cons : 'a -> 'a list -> 'a list (** [cons x xs] is [x :: xs] - @since 4.03.0 -*) + @since 4.03.0 (4.05.0 in ListLabels) + *) val hd : 'a list -> 'a (** Return the first element of the given list. - @raise Failure if the list is empty. *) + @raise Failure if the list is empty. + *) val tl : 'a list -> 'a list (** Return the given list without its first element. - @raise Failure if the list is empty. *) + @raise Failure if the list is empty. + *) -val nth: 'a list -> int -> 'a +val nth : 'a list -> int -> 'a (** Return the [n]-th element of the given list. The first element (head of the list) is at position 0. @raise Failure if the list is too short. - @raise Invalid_argument if [n] is negative. *) + @raise Invalid_argument if [n] is negative. + *) -val nth_opt: 'a list -> int -> 'a option +val nth_opt : 'a list -> int -> 'a option (** Return the [n]-th element of the given list. The first element (head of the list) is at position 0. Return [None] if the list is too short. @raise Invalid_argument if [n] is negative. @since 4.05 -*) + *) val rev : 'a list -> 'a list (** List reversal. *) val init : int -> (int -> 'a) -> 'a list -(** [List.init len f] is [[f 0; f 1; ...; f (len-1)]], evaluated left to right. - - @raise Invalid_argument if len < 0. +(** [init len f] is [f 0; f 1; ...; f (len-1)], evaluated left to right. + @raise Invalid_argument if [len < 0]. @since 4.06.0 -*) + *) val append : 'a list -> 'a list -> 'a list -(** Concatenate two lists. Same as the infix operator [@]. - Not tail-recursive (length of the first argument). *) +(** Concatenate two lists. Same function as the infix operator [@]. + Not tail-recursive (length of the first argument). The [@] + operator is not tail-recursive either. + *) val rev_append : 'a list -> 'a list -> 'a list -(** [List.rev_append l1 l2] reverses [l1] and concatenates it to [l2]. - This is equivalent to {!List.rev}[ l1 @ l2], but [rev_append] is - tail-recursive and more efficient. *) +(** [rev_append l1 l2] reverses [l1] and concatenates it with [l2]. + This is equivalent to [(]{!rev}[ l1) @ l2], but [rev_append] is + tail-recursive and more efficient. + *) val concat : 'a list list -> 'a list -(** Concatenate a list of lists. The elements of the argument are all +(** Concatenate a list of lists. The elements of the argument are all concatenated together (in the same order) to give the result. Not tail-recursive - (length of the argument + length of the longest sub-list). *) + (length of the argument + length of the longest sub-list). + *) val flatten : 'a list list -> 'a list -(** An alias for [concat]. *) +(** Same as {!concat}. Not tail-recursive + (length of the argument + length of the longest sub-list). + *) + + +(** {1 Comparison} *) + +val equal : ('a -> 'a -> bool) -> 'a list -> 'a list -> bool +(** [equal eq [a1; ...; an] [b1; ..; bm]] holds when + the two input lists have the same length, and for each + pair of elements [ai], [bi] at the same position we have + [eq ai bi]. + Note: the [eq] function may be called even if the + lists have different length. If you know your equality + function is costly, you may want to check {!compare_lengths} + first. + + @since 4.12.0 +*) + +val compare : ('a -> 'a -> int) -> 'a list -> 'a list -> int +(** [compare cmp [a1; ...; an] [b1; ...; bm]] performs + a lexicographic comparison of the two input lists, + using the same ['a -> 'a -> int] interface as {!Stdlib.compare}: + + - [a1 :: l1] is smaller than [a2 :: l2] (negative result) + if [a1] is smaller than [a2], or if they are equal (0 result) + and [l1] is smaller than [l2] + - the empty list [[]] is strictly smaller than non-empty lists + + Note: the [cmp] function will be called even if the lists have + different lengths. + + @since 4.12.0 +*) (** {1 Iterators} *) val iter : ('a -> unit) -> 'a list -> unit -(** [List.iter f [a1; ...; an]] applies function [f] in turn to +(** [iter f [a1; ...; an]] applies function [f] in turn to [a1; ...; an]. It is equivalent to - [begin f a1; f a2; ...; f an; () end]. *) + [begin f a1; f a2; ...; f an; () end]. + *) val iteri : (int -> 'a -> unit) -> 'a list -> unit -(** Same as {!List.iter}, but the function is applied to the index of +(** Same as {!iter}, but the function is applied to the index of the element as first argument (counting from 0), and the element itself as second argument. @since 4.00.0 -*) + *) val map : ('a -> 'b) -> 'a list -> 'b list -(** [List.map f [a1; ...; an]] applies function [f] to [a1, ..., an], +(** [map f [a1; ...; an]] applies function [f] to [a1, ..., an], and builds the list [[f a1; ...; f an]] - with the results returned by [f]. Not tail-recursive. *) + with the results returned by [f]. Not tail-recursive. + *) val mapi : (int -> 'a -> 'b) -> 'a list -> 'b list -(** Same as {!List.map}, but the function is applied to the index of +(** Same as {!map}, but the function is applied to the index of the element as first argument (counting from 0), and the element - itself as second argument. Not tail-recursive. + itself as second argument. Not tail-recursive. @since 4.00.0 -*) + *) val rev_map : ('a -> 'b) -> 'a list -> 'b list -(** [List.rev_map f l] gives the same result as - {!List.rev}[ (]{!List.map}[ f l)], but is tail-recursive and - more efficient. *) +(** [rev_map f l] gives the same result as + {!rev}[ (]{!map}[ f l)], but is tail-recursive and + more efficient. + *) val filter_map : ('a -> 'b option) -> 'a list -> 'b list (** [filter_map f l] applies [f] to every element of [l], filters out the [None] elements and returns the list of the arguments of the [Some] elements. @since 4.08.0 -*) + *) val concat_map : ('a -> 'b list) -> 'a list -> 'b list -(** [List.concat_map f l] gives the same result as - {!List.concat}[ (]{!List.map}[ f l)]. Tail-recursive. - +(** [concat_map f l] gives the same result as + {!concat}[ (]{!map}[ f l)]. Tail-recursive. @since 4.10.0 *) -val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list +val fold_left_map : + ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list (** [fold_left_map] is a combination of [fold_left] and [map] that threads an - accumulator through calls to [f] + accumulator through calls to [f]. @since 4.11.0 *) val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a -(** [List.fold_left f a [b1; ...; bn]] is - [f (... (f (f a b1) b2) ...) bn]. *) +(** [fold_left f init [b1; ...; bn]] is + [f (... (f (f init b1) b2) ...) bn]. + *) val fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b -(** [List.fold_right f [a1; ...; an] b] is - [f a1 (f a2 (... (f an b) ...))]. Not tail-recursive. *) +(** [fold_right f [a1; ...; an] init] is + [f a1 (f a2 (... (f an init) ...))]. Not tail-recursive. + *) (** {1 Iterators on two lists} *) val iter2 : ('a -> 'b -> unit) -> 'a list -> 'b list -> unit -(** [List.iter2 f [a1; ...; an] [b1; ...; bn]] calls in turn +(** [iter2 f [a1; ...; an] [b1; ...; bn]] calls in turn [f a1 b1; ...; f an bn]. @raise Invalid_argument if the two lists are determined - to have different lengths. *) + to have different lengths. + *) val map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list -(** [List.map2 f [a1; ...; an] [b1; ...; bn]] is +(** [map2 f [a1; ...; an] [b1; ...; bn]] is [[f a1 b1; ...; f an bn]]. @raise Invalid_argument if the two lists are determined - to have different lengths. Not tail-recursive. *) + to have different lengths. Not tail-recursive. + *) val rev_map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list -(** [List.rev_map2 f l1 l2] gives the same result as - {!List.rev}[ (]{!List.map2}[ f l1 l2)], but is tail-recursive and - more efficient. *) +(** [rev_map2 f l1 l2] gives the same result as + {!rev}[ (]{!map2}[ f l1 l2)], but is tail-recursive and + more efficient. + *) -val fold_left2 : ('a -> 'b -> 'c -> 'a) -> 'a -> 'b list -> 'c list -> 'a -(** [List.fold_left2 f a [b1; ...; bn] [c1; ...; cn]] is - [f (... (f (f a b1 c1) b2 c2) ...) bn cn]. +val fold_left2 : + ('a -> 'b -> 'c -> 'a) -> 'a -> 'b list -> 'c list -> 'a +(** [fold_left2 f init [a1; ...; an] [b1; ...; bn]] is + [f (... (f (f init a1 b1) a2 b2) ...) an bn]. @raise Invalid_argument if the two lists are determined - to have different lengths. *) + to have different lengths. + *) -val fold_right2 : ('a -> 'b -> 'c -> 'c) -> 'a list -> 'b list -> 'c -> 'c -(** [List.fold_right2 f [a1; ...; an] [b1; ...; bn] c] is - [f a1 b1 (f a2 b2 (... (f an bn c) ...))]. +val fold_right2 : + ('a -> 'b -> 'c -> 'c) -> 'a list -> 'b list -> 'c -> 'c +(** [fold_right2 f [a1; ...; an] [b1; ...; bn] init] is + [f a1 b1 (f a2 b2 (... (f an bn init) ...))]. @raise Invalid_argument if the two lists are determined - to have different lengths. Not tail-recursive. *) + to have different lengths. Not tail-recursive. + *) (** {1 List scanning} *) val for_all : ('a -> bool) -> 'a list -> bool -(** [for_all p [a1; ...; an]] checks if all elements of the list - satisfy the predicate [p]. That is, it returns - [(p a1) && (p a2) && ... && (p an)] for a non-empty list and - [true] if the list is empty. *) +(** [for_all f [a1; ...; an]] checks if all elements of the list + satisfy the predicate [f]. That is, it returns + [(f a1) && (f a2) && ... && (f an)] for a non-empty list and + [true] if the list is empty. + *) val exists : ('a -> bool) -> 'a list -> bool -(** [exists p [a1; ...; an]] checks if at least one element of - the list satisfies the predicate [p]. That is, it returns - [(p a1) || (p a2) || ... || (p an)] for a non-empty list and - [false] if the list is empty. *) +(** [exists f [a1; ...; an]] checks if at least one element of + the list satisfies the predicate [f]. That is, it returns + [(f a1) || (f a2) || ... || (f an)] for a non-empty list and + [false] if the list is empty. + *) val for_all2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool -(** Same as {!List.for_all}, but for a two-argument predicate. +(** Same as {!for_all}, but for a two-argument predicate. @raise Invalid_argument if the two lists are determined - to have different lengths. *) + to have different lengths. + *) val exists2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool -(** Same as {!List.exists}, but for a two-argument predicate. +(** Same as {!exists}, but for a two-argument predicate. @raise Invalid_argument if the two lists are determined - to have different lengths. *) + to have different lengths. + *) val mem : 'a -> 'a list -> bool -(** [mem a l] is true if and only if [a] is equal - to an element of [l]. *) +(** [mem a set] is true if and only if [a] is equal + to an element of [set]. + *) val memq : 'a -> 'a list -> bool -(** Same as {!List.mem}, but uses physical equality instead of structural - equality to compare list elements. *) +(** Same as {!mem}, but uses physical equality instead of structural + equality to compare list elements. + *) (** {1 List searching} *) val find : ('a -> bool) -> 'a list -> 'a -(** [find p l] returns the first element of the list [l] - that satisfies the predicate [p]. - @raise Not_found if there is no value that satisfies [p] in the - list [l]. *) - -val find_opt: ('a -> bool) -> 'a list -> 'a option -(** [find_opt p l] returns the first element of the list [l] that - satisfies the predicate [p], or [None] if there is no value that - satisfies [p] in the list [l]. - @since 4.05 *) - -val find_map: ('a -> 'b option) -> 'a list -> 'b option +(** [find f l] returns the first element of the list [l] + that satisfies the predicate [f]. + @raise Not_found if there is no value that satisfies [f] in the + list [l]. + *) + +val find_opt : ('a -> bool) -> 'a list -> 'a option +(** [find f l] returns the first element of the list [l] + that satisfies the predicate [f]. + Returns [None] if there is no value that satisfies [f] in the + list [l]. + @since 4.05 + *) + +val find_map : ('a -> 'b option) -> 'a list -> 'b option (** [find_map f l] applies [f] to the elements of [l] in order, and returns the first result of the form [Some v], or [None] if none exist. @@ -253,26 +325,44 @@ val find_map: ('a -> 'b option) -> 'a list -> 'b option *) val filter : ('a -> bool) -> 'a list -> 'a list -(** [filter p l] returns all the elements of the list [l] - that satisfy the predicate [p]. The order of the elements - in the input list is preserved. *) +(** [filter f l] returns all the elements of the list [l] + that satisfy the predicate [f]. The order of the elements + in the input list is preserved. + *) val find_all : ('a -> bool) -> 'a list -> 'a list -(** [find_all] is another name for {!List.filter}. *) +(** [find_all] is another name for {!filter}. + *) val filteri : (int -> 'a -> bool) -> 'a list -> 'a list -(** Same as {!List.filter}, but the predicate is applied to the index of +(** Same as {!filter}, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument. @since 4.11.0 *) val partition : ('a -> bool) -> 'a list -> 'a list * 'a list -(** [partition p l] returns a pair of lists [(l1, l2)], where +(** [partition f l] returns a pair of lists [(l1, l2)], where [l1] is the list of all the elements of [l] that - satisfy the predicate [p], and [l2] is the list of all the - elements of [l] that do not satisfy [p]. - The order of the elements in the input list is preserved. *) + satisfy the predicate [f], and [l2] is the list of all the + elements of [l] that do not satisfy [f]. + The order of the elements in the input list is preserved. + *) + +val partition_map : ('a -> ('b, 'c) Either.t) -> 'a list -> 'b list * 'c list +(** [partition_map f l] returns a pair of lists [(l1, l2)] such that, + for each element [x] of the input list [l]: + - if [f x] is [Left y1], then [y1] is in [l1], and + - if [f x] is [Right y2], then [y2] is in [l2]. + + The output elements are included in [l1] and [l2] in the same + relative order as the corresponding input elements in [l]. + + In particular, [partition_map (fun x -> if f x then Left x else Right x) l] + is equivalent to [partition f l]. + + @since 4.12.0 +*) (** {1 Association lists} *) @@ -284,42 +374,50 @@ val assoc : 'a -> ('a * 'b) list -> 'b [assoc a [ ...; (a,b); ...] = b] if [(a,b)] is the leftmost binding of [a] in list [l]. @raise Not_found if there is no value associated with [a] in the - list [l]. *) + list [l]. + *) -val assoc_opt: 'a -> ('a * 'b) list -> 'b option +val assoc_opt : 'a -> ('a * 'b) list -> 'b option (** [assoc_opt a l] returns the value associated with key [a] in the list of - pairs [l]. That is, - [assoc_opt a [ ...; (a,b); ...] = b] - if [(a,b)] is the leftmost binding of [a] in list [l]. - Returns [None] if there is no value associated with [a] in the - list [l]. - @since 4.05 *) + pairs [l]. That is, + [assoc_opt a [ ...; (a,b); ...] = Some b] + if [(a,b)] is the leftmost binding of [a] in list [l]. + Returns [None] if there is no value associated with [a] in the + list [l]. + @since 4.05 + *) val assq : 'a -> ('a * 'b) list -> 'b -(** Same as {!List.assoc}, but uses physical equality instead of structural - equality to compare keys. *) +(** Same as {!assoc}, but uses physical equality instead of + structural equality to compare keys. + *) val assq_opt : 'a -> ('a * 'b) list -> 'b option -(** Same as {!List.assoc_opt}, but uses physical equality instead of structural - equality to compare keys. - @since 4.05 *) +(** Same as {!assoc_opt}, but uses physical equality instead of + structural equality to compare keys. + @since 4.05.0 + *) val mem_assoc : 'a -> ('a * 'b) list -> bool -(** Same as {!List.assoc}, but simply return true if a binding exists, - and false if no bindings exist for the given key. *) +(** Same as {!assoc}, but simply return [true] if a binding exists, + and [false] if no bindings exist for the given key. + *) val mem_assq : 'a -> ('a * 'b) list -> bool -(** Same as {!List.mem_assoc}, but uses physical equality instead of - structural equality to compare keys. *) +(** Same as {!mem_assoc}, but uses physical equality instead of + structural equality to compare keys. + *) val remove_assoc : 'a -> ('a * 'b) list -> ('a * 'b) list (** [remove_assoc a l] returns the list of pairs [l] without the first pair with key [a], if any. - Not tail-recursive. *) + Not tail-recursive. + *) val remove_assq : 'a -> ('a * 'b) list -> ('a * 'b) list -(** Same as {!List.remove_assoc}, but uses physical equality instead - of structural equality to compare keys. Not tail-recursive. *) +(** Same as {!remove_assoc}, but uses physical equality instead + of structural equality to compare keys. Not tail-recursive. + *) (** {1 Lists of pairs} *) @@ -329,14 +427,15 @@ val split : ('a * 'b) list -> 'a list * 'b list (** Transform a list of pairs into a pair of lists: [split [(a1,b1); ...; (an,bn)]] is [([a1; ...; an], [b1; ...; bn])]. Not tail-recursive. -*) + *) val combine : 'a list -> 'b list -> ('a * 'b) list (** Transform a pair of lists into a list of pairs: [combine [a1; ...; an] [b1; ...; bn]] is [[(a1,b1); ...; (an,bn)]]. @raise Invalid_argument if the two lists - have different lengths. Not tail-recursive. *) + have different lengths. Not tail-recursive. + *) (** {1 Sorting} *) @@ -344,36 +443,38 @@ val combine : 'a list -> 'b list -> ('a * 'b) list val sort : ('a -> 'a -> int) -> 'a list -> 'a list (** Sort a list in increasing order according to a comparison - function. The comparison function must return 0 if its arguments + function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see Array.sort for - a complete specification). For example, + a complete specification). For example, {!Stdlib.compare} is a suitable comparison function. The resulting list is sorted in increasing order. - [List.sort] is guaranteed to run in constant heap space + {!sort} is guaranteed to run in constant heap space (in addition to the size of the result list) and logarithmic stack space. The current implementation uses Merge Sort. It runs in constant heap space and logarithmic stack space. -*) + *) val stable_sort : ('a -> 'a -> int) -> 'a list -> 'a list -(** Same as {!List.sort}, but the sorting algorithm is guaranteed to +(** Same as {!sort}, but the sorting algorithm is guaranteed to be stable (i.e. elements that compare equal are kept in their - original order) . + original order). The current implementation uses Merge Sort. It runs in constant heap space and logarithmic stack space. -*) + *) val fast_sort : ('a -> 'a -> int) -> 'a list -> 'a list -(** Same as {!List.sort} or {!List.stable_sort}, whichever is faster - on typical input. *) +(** Same as {!sort} or {!stable_sort}, whichever is + faster on typical input. + *) val sort_uniq : ('a -> 'a -> int) -> 'a list -> 'a list -(** Same as {!List.sort}, but also remove duplicates. - @since 4.02.0 *) +(** Same as {!sort}, but also remove duplicates. + @since 4.02.0 (4.03.0 in ListLabels) + *) val merge : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list (** Merge two lists: @@ -383,14 +484,16 @@ val merge : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list If several elements compare equal, the elements of [l1] will be before the elements of [l2]. Not tail-recursive (sum of the lengths of the arguments). -*) + *) (** {1 Iterators} *) val to_seq : 'a list -> 'a Seq.t -(** Iterate on the list - @since 4.07 *) +(** Iterate on the list. + @since 4.07 + *) val of_seq : 'a Seq.t -> 'a list -(** Create a list from the iterator - @since 4.07 *) +(** Create a list from the iterator. + @since 4.07 + *) diff --git a/stdlib/listLabels.mli b/stdlib/listLabels.mli index c98eaeef..ce5a7920 100644 --- a/stdlib/listLabels.mli +++ b/stdlib/listLabels.mli @@ -13,8 +13,12 @@ (* *) (**************************************************************************) -type 'a t = 'a list = [] | (::) of 'a * 'a list (**) -(** An alias for the type of lists. +(* NOTE: + If this file is listLabels.mli, run tools/sync_stdlib_docs after editing it + to generate list.mli. + + If this file is list.mli, do not edit it directly -- edit + listLabels.mli instead. *) (** List operations. @@ -29,43 +33,38 @@ type 'a t = 'a list = [] | (::) of 'a * 'a list (**) The above considerations can usually be ignored if your lists are not longer than about 10000 elements. - This module is intended to be used through {!StdLabels} which replaces - {!Array}, {!Bytes}, {!List} and {!String} with their labeled counterparts. - - For example: - {[ - open StdLabels - - let seq len = List.init ~f:(function i -> i) ~len - ]} + The labeled version of this module can be used as described in the + {!StdLabels} module. *) -val length : 'a list -> int -(** Return the length (number of elements) of the given list. - *) +type 'a t = 'a list = [] | (::) of 'a * 'a list (**) +(** An alias for the type of lists. *) -val hd : 'a list -> 'a -(** Return the first element of the given list. - @raise Failure if the list is empty. - *) +val length : 'a list -> int +(** Return the length (number of elements) of the given list. *) val compare_lengths : 'a list -> 'b list -> int (** Compare the lengths of two lists. [compare_lengths l1 l2] is equivalent to [compare (length l1) (length l2)], except that - the computation stops after itering on the shortest list. + the computation stops after reaching the end of the shortest list. @since 4.05.0 *) val compare_length_with : 'a list -> len:int -> int -(** Compare the length of a list to an integer. [compare_length_with l n] is - equivalent to [compare (length l) n], except that - the computation stops after at most [n] iterations on the list. +(** Compare the length of a list to an integer. [compare_length_with l len] is + equivalent to [compare (length l) len], except that the computation stops + after at most [len] iterations on the list. @since 4.05.0 *) val cons : 'a -> 'a list -> 'a list (** [cons x xs] is [x :: xs] - @since 4.05.0 + @since 4.03.0 (4.05.0 in ListLabels) + *) + +val hd : 'a list -> 'a +(** Return the first element of the given list. + @raise Failure if the list is empty. *) val tl : 'a list -> 'a list @@ -80,7 +79,7 @@ val nth : 'a list -> int -> 'a @raise Invalid_argument if [n] is negative. *) -val nth_opt: 'a list -> int -> 'a option +val nth_opt : 'a list -> int -> 'a option (** Return the [n]-th element of the given list. The first element (head of the list) is at position 0. Return [None] if the list is too short. @@ -89,24 +88,23 @@ val nth_opt: 'a list -> int -> 'a option *) val rev : 'a list -> 'a list -(** List reversal. - *) +(** List reversal. *) val init : len:int -> f:(int -> 'a) -> 'a list -(** [List.init len f] is [f 0; f 1; ...; f (len-1)], evaluated left to right. +(** [init ~len ~f] is [f 0; f 1; ...; f (len-1)], evaluated left to right. @raise Invalid_argument if [len < 0]. @since 4.06.0 *) val append : 'a list -> 'a list -> 'a list -(** Catenate two lists. Same function as the infix operator [@]. +(** Concatenate two lists. Same function as the infix operator [@]. Not tail-recursive (length of the first argument). The [@] operator is not tail-recursive either. *) val rev_append : 'a list -> 'a list -> 'a list -(** [List.rev_append l1 l2] reverses [l1] and concatenates it with [l2]. - This is equivalent to [(]{!List.rev}[ l1) @ l2], but [rev_append] is +(** [rev_append l1 l2] reverses [l1] and concatenates it with [l2]. + This is equivalent to [(]{!rev}[ l1) @ l2], but [rev_append] is tail-recursive and more efficient. *) @@ -118,75 +116,106 @@ val concat : 'a list list -> 'a list *) val flatten : 'a list list -> 'a list -(** Same as [concat]. Not tail-recursive +(** Same as {!concat}. Not tail-recursive (length of the argument + length of the longest sub-list). *) +(** {1 Comparison} *) + +val equal : eq:('a -> 'a -> bool) -> 'a list -> 'a list -> bool +(** [equal eq [a1; ...; an] [b1; ..; bm]] holds when + the two input lists have the same length, and for each + pair of elements [ai], [bi] at the same position we have + [eq ai bi]. + + Note: the [eq] function may be called even if the + lists have different length. If you know your equality + function is costly, you may want to check {!compare_lengths} + first. + + @since 4.12.0 +*) + +val compare : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> int +(** [compare cmp [a1; ...; an] [b1; ...; bm]] performs + a lexicographic comparison of the two input lists, + using the same ['a -> 'a -> int] interface as {!Stdlib.compare}: + + - [a1 :: l1] is smaller than [a2 :: l2] (negative result) + if [a1] is smaller than [a2], or if they are equal (0 result) + and [l1] is smaller than [l2] + - the empty list [[]] is strictly smaller than non-empty lists + + Note: the [cmp] function will be called even if the lists have + different lengths. + + @since 4.12.0 +*) + (** {1 Iterators} *) val iter : f:('a -> unit) -> 'a list -> unit -(** [List.iter f [a1; ...; an]] applies function [f] in turn to +(** [iter ~f [a1; ...; an]] applies function [f] in turn to [a1; ...; an]. It is equivalent to [begin f a1; f a2; ...; f an; () end]. *) val iteri : f:(int -> 'a -> unit) -> 'a list -> unit -(** Same as {!List.iter}, but the function is applied to the index of +(** Same as {!iter}, but the function is applied to the index of the element as first argument (counting from 0), and the element itself as second argument. @since 4.00.0 *) val map : f:('a -> 'b) -> 'a list -> 'b list -(** [List.map f [a1; ...; an]] applies function [f] to [a1, ..., an], +(** [map ~f [a1; ...; an]] applies function [f] to [a1, ..., an], and builds the list [[f a1; ...; f an]] with the results returned by [f]. Not tail-recursive. *) val mapi : f:(int -> 'a -> 'b) -> 'a list -> 'b list -(** Same as {!List.map}, but the function is applied to the index of +(** Same as {!map}, but the function is applied to the index of the element as first argument (counting from 0), and the element - itself as second argument. + itself as second argument. Not tail-recursive. @since 4.00.0 *) val rev_map : f:('a -> 'b) -> 'a list -> 'b list -(** [List.rev_map f l] gives the same result as - {!List.rev}[ (]{!List.map}[ f l)], but is tail-recursive and +(** [rev_map ~f l] gives the same result as + {!rev}[ (]{!map}[ f l)], but is tail-recursive and more efficient. *) val filter_map : f:('a -> 'b option) -> 'a list -> 'b list -(** [filter_map f l] applies [f] to every element of [l], filters +(** [filter_map ~f l] applies [f] to every element of [l], filters out the [None] elements and returns the list of the arguments of the [Some] elements. @since 4.08.0 *) val concat_map : f:('a -> 'b list) -> 'a list -> 'b list -(** [List.concat_map f l] gives the same result as - {!List.concat}[ (]{!List.map}[ f l)]. Tail-recursive. - +(** [concat_map ~f l] gives the same result as + {!concat}[ (]{!map}[ f l)]. Tail-recursive. @since 4.10.0 *) val fold_left_map : f:('a -> 'b -> 'a * 'c) -> init:'a -> 'b list -> 'a * 'c list -(** [fold_left_map] is a combination of [fold_left] and [map] hat threads an - accumulator through calls to [f] +(** [fold_left_map] is a combination of [fold_left] and [map] that threads an + accumulator through calls to [f]. @since 4.11.0 *) val fold_left : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a -(** [List.fold_left f a [b1; ...; bn]] is - [f (... (f (f a b1) b2) ...) bn]. +(** [fold_left ~f ~init [b1; ...; bn]] is + [f (... (f (f init b1) b2) ...) bn]. *) val fold_right : f:('a -> 'b -> 'b) -> 'a list -> init:'b -> 'b -(** [List.fold_right f [a1; ...; an] b] is - [f a1 (f a2 (... (f an b) ...))]. Not tail-recursive. +(** [fold_right ~f [a1; ...; an] ~init] is + [f a1 (f a2 (... (f an init) ...))]. Not tail-recursive. *) @@ -194,37 +223,37 @@ val fold_right : f:('a -> 'b -> 'b) -> 'a list -> init:'b -> 'b val iter2 : f:('a -> 'b -> unit) -> 'a list -> 'b list -> unit -(** [List.iter2 f [a1; ...; an] [b1; ...; bn]] calls in turn +(** [iter2 ~f [a1; ...; an] [b1; ...; bn]] calls in turn [f a1 b1; ...; f an bn]. @raise Invalid_argument if the two lists are determined to have different lengths. *) val map2 : f:('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list -(** [List.map2 f [a1; ...; an] [b1; ...; bn]] is +(** [map2 ~f [a1; ...; an] [b1; ...; bn]] is [[f a1 b1; ...; f an bn]]. @raise Invalid_argument if the two lists are determined to have different lengths. Not tail-recursive. *) val rev_map2 : f:('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list -(** [List.rev_map2 f l1 l2] gives the same result as - {!List.rev}[ (]{!List.map2}[ f l1 l2)], but is tail-recursive and +(** [rev_map2 ~f l1 l2] gives the same result as + {!rev}[ (]{!map2}[ f l1 l2)], but is tail-recursive and more efficient. *) val fold_left2 : f:('a -> 'b -> 'c -> 'a) -> init:'a -> 'b list -> 'c list -> 'a -(** [List.fold_left2 f a [b1; ...; bn] [c1; ...; cn]] is - [f (... (f (f a b1 c1) b2 c2) ...) bn cn]. +(** [fold_left2 ~f ~init [a1; ...; an] [b1; ...; bn]] is + [f (... (f (f init a1 b1) a2 b2) ...) an bn]. @raise Invalid_argument if the two lists are determined to have different lengths. *) val fold_right2 : f:('a -> 'b -> 'c -> 'c) -> 'a list -> 'b list -> init:'c -> 'c -(** [List.fold_right2 f [a1; ...; an] [b1; ...; bn] c] is - [f a1 b1 (f a2 b2 (... (f an bn c) ...))]. +(** [fold_right2 ~f [a1; ...; an] [b1; ...; bn] ~init] is + [f a1 b1 (f a2 b2 (... (f an bn init) ...))]. @raise Invalid_argument if the two lists are determined to have different lengths. Not tail-recursive. *) @@ -234,36 +263,38 @@ val fold_right2 : val for_all : f:('a -> bool) -> 'a list -> bool -(** [for_all p [a1; ...; an]] checks if all elements of the list - satisfy the predicate [p]. That is, it returns - [(p a1) && (p a2) && ... && (p an)]. +(** [for_all ~f [a1; ...; an]] checks if all elements of the list + satisfy the predicate [f]. That is, it returns + [(f a1) && (f a2) && ... && (f an)] for a non-empty list and + [true] if the list is empty. *) val exists : f:('a -> bool) -> 'a list -> bool -(** [exists p [a1; ...; an]] checks if at least one element of - the list satisfies the predicate [p]. That is, it returns - [(p a1) || (p a2) || ... || (p an)]. +(** [exists ~f [a1; ...; an]] checks if at least one element of + the list satisfies the predicate [f]. That is, it returns + [(f a1) || (f a2) || ... || (f an)] for a non-empty list and + [false] if the list is empty. *) val for_all2 : f:('a -> 'b -> bool) -> 'a list -> 'b list -> bool -(** Same as {!List.for_all}, but for a two-argument predicate. +(** Same as {!for_all}, but for a two-argument predicate. @raise Invalid_argument if the two lists are determined to have different lengths. *) val exists2 : f:('a -> 'b -> bool) -> 'a list -> 'b list -> bool -(** Same as {!List.exists}, but for a two-argument predicate. +(** Same as {!exists}, but for a two-argument predicate. @raise Invalid_argument if the two lists are determined to have different lengths. *) val mem : 'a -> set:'a list -> bool -(** [mem a l] is true if and only if [a] is equal - to an element of [l]. +(** [mem a ~set] is true if and only if [a] is equal + to an element of [set]. *) val memq : 'a -> set:'a list -> bool -(** Same as {!List.mem}, but uses physical equality instead of structural +(** Same as {!mem}, but uses physical equality instead of structural equality to compare list elements. *) @@ -272,52 +303,67 @@ val memq : 'a -> set:'a list -> bool val find : f:('a -> bool) -> 'a list -> 'a -(** [find p l] returns the first element of the list [l] - that satisfies the predicate [p]. - @raise Not_found if there is no value that satisfies [p] in the +(** [find ~f l] returns the first element of the list [l] + that satisfies the predicate [f]. + @raise Not_found if there is no value that satisfies [f] in the list [l]. *) -val find_opt: f:('a -> bool) -> 'a list -> 'a option -(** [find p l] returns the first element of the list [l] - that satisfies the predicate [p]. - Returns [None] if there is no value that satisfies [p] in the +val find_opt : f:('a -> bool) -> 'a list -> 'a option +(** [find ~f l] returns the first element of the list [l] + that satisfies the predicate [f]. + Returns [None] if there is no value that satisfies [f] in the list [l]. @since 4.05 *) -val find_map: f:('a -> 'b option) -> 'a list -> 'b option -(** [find_map f l] applies [f] to the elements of [l] in order, +val find_map : f:('a -> 'b option) -> 'a list -> 'b option +(** [find_map ~f l] applies [f] to the elements of [l] in order, and returns the first result of the form [Some v], or [None] if none exist. @since 4.10.0 *) val filter : f:('a -> bool) -> 'a list -> 'a list -(** [filter p l] returns all the elements of the list [l] - that satisfy the predicate [p]. The order of the elements +(** [filter ~f l] returns all the elements of the list [l] + that satisfy the predicate [f]. The order of the elements in the input list is preserved. *) val find_all : f:('a -> bool) -> 'a list -> 'a list -(** [find_all] is another name for {!List.filter}. +(** [find_all] is another name for {!filter}. *) val filteri : f:(int -> 'a -> bool) -> 'a list -> 'a list -(** Same as {!List.filter}, but the predicate is applied to the index of +(** Same as {!filter}, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument. @since 4.11.0 *) val partition : f:('a -> bool) -> 'a list -> 'a list * 'a list -(** [partition p l] returns a pair of lists [(l1, l2)], where +(** [partition ~f l] returns a pair of lists [(l1, l2)], where [l1] is the list of all the elements of [l] that - satisfy the predicate [p], and [l2] is the list of all the - elements of [l] that do not satisfy [p]. + satisfy the predicate [f], and [l2] is the list of all the + elements of [l] that do not satisfy [f]. The order of the elements in the input list is preserved. *) +val partition_map : f:('a -> ('b, 'c) Either.t) -> 'a list -> 'b list * 'c list +(** [partition_map f l] returns a pair of lists [(l1, l2)] such that, + for each element [x] of the input list [l]: + - if [f x] is [Left y1], then [y1] is in [l1], and + - if [f x] is [Right y2], then [y2] is in [l2]. + + The output elements are included in [l1] and [l2] in the same + relative order as the corresponding input elements in [l]. + + In particular, [partition_map (fun x -> if f x then Left x else Right x) l] + is equivalent to [partition f l]. + + @since 4.12.0 +*) + (** {1 Association lists} *) @@ -331,10 +377,10 @@ val assoc : 'a -> ('a * 'b) list -> 'b list [l]. *) -val assoc_opt: 'a -> ('a * 'b) list -> 'b option +val assoc_opt : 'a -> ('a * 'b) list -> 'b option (** [assoc_opt a l] returns the value associated with key [a] in the list of pairs [l]. That is, - [assoc a [ ...; (a,b); ...] = b] + [assoc_opt a [ ...; (a,b); ...] = Some b] if [(a,b)] is the leftmost binding of [a] in list [l]. Returns [None] if there is no value associated with [a] in the list [l]. @@ -342,23 +388,23 @@ val assoc_opt: 'a -> ('a * 'b) list -> 'b option *) val assq : 'a -> ('a * 'b) list -> 'b -(** Same as {!List.assoc}, but uses physical equality instead of +(** Same as {!assoc}, but uses physical equality instead of structural equality to compare keys. *) -val assq_opt: 'a -> ('a * 'b) list -> 'b option -(** Same as {!List.assoc_opt}, but uses physical equality instead of +val assq_opt : 'a -> ('a * 'b) list -> 'b option +(** Same as {!assoc_opt}, but uses physical equality instead of structural equality to compare keys. @since 4.05.0 *) val mem_assoc : 'a -> map:('a * 'b) list -> bool -(** Same as {!List.assoc}, but simply return true if a binding exists, - and false if no bindings exist for the given key. +(** Same as {!assoc}, but simply return [true] if a binding exists, + and [false] if no bindings exist for the given key. *) val mem_assq : 'a -> map:('a * 'b) list -> bool -(** Same as {!List.mem_assoc}, but uses physical equality instead of +(** Same as {!mem_assoc}, but uses physical equality instead of structural equality to compare keys. *) @@ -369,7 +415,7 @@ val remove_assoc : 'a -> ('a * 'b) list -> ('a * 'b) list *) val remove_assq : 'a -> ('a * 'b) list -> ('a * 'b) list -(** Same as {!List.remove_assoc}, but uses physical equality instead +(** Same as {!remove_assoc}, but uses physical equality instead of structural equality to compare keys. Not tail-recursive. *) @@ -403,7 +449,7 @@ val sort : cmp:('a -> 'a -> int) -> 'a list -> 'a list a complete specification). For example, {!Stdlib.compare} is a suitable comparison function. The resulting list is sorted in increasing order. - [List.sort] is guaranteed to run in constant heap space + {!sort} is guaranteed to run in constant heap space (in addition to the size of the result list) and logarithmic stack space. @@ -412,28 +458,28 @@ val sort : cmp:('a -> 'a -> int) -> 'a list -> 'a list *) val stable_sort : cmp:('a -> 'a -> int) -> 'a list -> 'a list -(** Same as {!List.sort}, but the sorting algorithm is guaranteed to +(** Same as {!sort}, but the sorting algorithm is guaranteed to be stable (i.e. elements that compare equal are kept in their - original order) . + original order). The current implementation uses Merge Sort. It runs in constant heap space and logarithmic stack space. *) val fast_sort : cmp:('a -> 'a -> int) -> 'a list -> 'a list -(** Same as {!List.sort} or {!List.stable_sort}, whichever is +(** Same as {!sort} or {!stable_sort}, whichever is faster on typical input. *) val sort_uniq : cmp:('a -> 'a -> int) -> 'a list -> 'a list -(** Same as {!List.sort}, but also remove duplicates. - @since 4.03.0 +(** Same as {!sort}, but also remove duplicates. + @since 4.02.0 (4.03.0 in ListLabels) *) val merge : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list (** Merge two lists: Assuming that [l1] and [l2] are sorted according to the - comparison function [cmp], [merge cmp l1 l2] will return a + comparison function [cmp], [merge ~cmp l1 l2] will return a sorted list containing all the elements of [l1] and [l2]. If several elements compare equal, the elements of [l1] will be before the elements of [l2]. @@ -443,11 +489,11 @@ val merge : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list (** {1 Iterators} *) val to_seq : 'a list -> 'a Seq.t -(** Iterate on the list +(** Iterate on the list. @since 4.07 *) val of_seq : 'a Seq.t -> 'a list -(** Create a list from the iterator +(** Create a list from the iterator. @since 4.07 *) diff --git a/stdlib/map.ml b/stdlib/map.ml index 479f2646..236aaa5b 100644 --- a/stdlib/map.ml +++ b/stdlib/map.ml @@ -22,7 +22,7 @@ module type OrderedType = module type S = sig type key - type +'a t + type !+'a t val empty: 'a t val is_empty: 'a t -> bool val mem: key -> 'a t -> bool @@ -60,6 +60,7 @@ module type S = val map: ('a -> 'b) -> 'a t -> 'b t val mapi: (key -> 'a -> 'b) -> 'a t -> 'b t val to_seq : 'a t -> (key * 'a) Seq.t + val to_rev_seq : 'a t -> (key * 'a) Seq.t val to_seq_from : key -> 'a t -> (key * 'a) Seq.t val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t val of_seq : (key * 'a) Seq.t -> 'a t @@ -508,6 +509,19 @@ module Make(Ord: OrderedType) = struct let to_seq m = seq_of_enum_ (cons_enum m End) + let rec snoc_enum s e = + match s with + Empty -> e + | Node{l; v; d; r} -> snoc_enum r (More(v, d, l, e)) + + let rec rev_seq_of_enum_ c () = match c with + | End -> Seq.Nil + | More (k,v,t,rest) -> + Seq.Cons ((k,v), rev_seq_of_enum_ (snoc_enum t rest)) + + let to_rev_seq c = + rev_seq_of_enum_ (snoc_enum c End) + let to_seq_from low m = let rec aux low m c = match m with | Empty -> c diff --git a/stdlib/map.mli b/stdlib/map.mli index 6ec8249a..c3c6b586 100644 --- a/stdlib/map.mli +++ b/stdlib/map.mli @@ -13,6 +13,9 @@ (* *) (**************************************************************************) +(* NOTE: If this file is map.mli, do not edit it directly! Instead, + edit templates/map.template.mli and run tools/sync_stdlib_docs *) + (** Association tables over ordered types. This module implements applicative association tables, also known as @@ -57,14 +60,14 @@ module type OrderedType = Example: a suitable ordering function is the generic structural comparison function {!Stdlib.compare}. *) end -(** Input signature of the functor {!Map.Make}. *) +(** Input signature of the functor {!Make}. *) module type S = sig type key (** The type of the map keys. *) - type (+'a) t + type !+'a t (** The type of maps from type [key] to type ['a]. *) val empty: 'a t @@ -78,21 +81,21 @@ module type S = and [false] otherwise. *) val add: key -> 'a -> 'a t -> 'a t - (** [add x y m] returns a map containing the same bindings as - [m], plus a binding of [x] to [y]. If [x] was already bound - in [m] to a value that is physically equal to [y], + (** [add key data m] returns a map containing the same bindings as + [m], plus a binding of [key] to [data]. If [key] was already bound + in [m] to a value that is physically equal to [data], [m] is returned unchanged (the result of the function is then physically equal to [m]). Otherwise, the previous binding - of [x] in [m] disappears. + of [key] in [m] disappears. @before 4.03 Physical equality was not ensured. *) val update: key -> ('a option -> 'a option) -> 'a t -> 'a t - (** [update x f m] returns a map containing the same bindings as - [m], except for the binding of [x]. Depending on the value of - [y] where [y] is [f (find_opt x m)], the binding of [x] is + (** [update key f m] returns a map containing the same bindings as + [m], except for the binding of [key]. Depending on the value of + [y] where [y] is [f (find_opt key m)], the binding of [key] is added, removed or updated. If [y] is [None], the binding is - removed if it exists; otherwise, if [y] is [Some z] then [x] - is associated to [z] in the resulting map. If [x] was already + removed if it exists; otherwise, if [y] is [Some z] then [key] + is associated to [z] in the resulting map. If [key] was already bound in [m] to a value that is physically equal to [z], [m] is returned unchanged (the result of the function is then physically equal to [m]). @@ -100,8 +103,8 @@ module type S = *) val singleton: key -> 'a -> 'a t - (** [singleton x y] returns the one-element map that contains a binding [y] - for [x]. + (** [singleton x y] returns the one-element map that contains a binding + [y] for [x]. @since 3.12.0 *) @@ -113,7 +116,8 @@ module type S = @before 4.03 Physical equality was not ensured. *) val merge: - (key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t + (key -> 'a option -> 'b option -> 'c option) -> + 'a t -> 'b t -> 'c t (** [merge f m1 m2] computes a map whose keys are a subset of the keys of [m1] and of [m2]. The presence of each such binding, and the corresponding value, is determined with the function [f]. @@ -154,25 +158,25 @@ module type S = order with respect to the ordering over the type of the keys. *) val fold: (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b - (** [fold f m a] computes [(f kN dN ... (f k1 d1 a)...)], + (** [fold f m init] computes [(f kN dN ... (f k1 d1 init)...)], where [k1 ... kN] are the keys of all bindings in [m] (in increasing order), and [d1 ... dN] are the associated data. *) val for_all: (key -> 'a -> bool) -> 'a t -> bool - (** [for_all p m] checks if all the bindings of the map - satisfy the predicate [p]. + (** [for_all f m] checks if all the bindings of the map + satisfy the predicate [f]. @since 3.12.0 *) val exists: (key -> 'a -> bool) -> 'a t -> bool - (** [exists p m] checks if at least one binding of the map - satisfies the predicate [p]. + (** [exists f m] checks if at least one binding of the map + satisfies the predicate [f]. @since 3.12.0 *) val filter: (key -> 'a -> bool) -> 'a t -> 'a t - (** [filter p m] returns the map with all the bindings in [m] - that satisfy predicate [p]. If every binding in [m] satisfies [p], + (** [filter f m] returns the map with all the bindings in [m] + that satisfy predicate [p]. If every binding in [m] satisfies [f], [m] is returned unchanged (the result of the function is then physically equal to [m]) @since 3.12.0 @@ -200,10 +204,10 @@ module type S = *) val partition: (key -> 'a -> bool) -> 'a t -> 'a t * 'a t - (** [partition p m] returns a pair of maps [(m1, m2)], where + (** [partition f m] returns a pair of maps [(m1, m2)], where [m1] contains all the bindings of [m] that satisfy the - predicate [p], and [m2] is the map with all the bindings of - [m] that do not satisfy [p]. + predicate [f], and [m2] is the map with all the bindings of + [m] that do not satisfy [f]. @since 3.12.0 *) @@ -216,7 +220,7 @@ module type S = (** Return the list of all bindings of the given map. The returned list is sorted in increasing order of keys with respect to the ordering [Ord.compare], where [Ord] is the argument - given to {!Map.Make}. + given to {!Make}. @since 3.12.0 *) @@ -235,13 +239,13 @@ module type S = *) val max_binding: 'a t -> (key * 'a) - (** Same as {!Map.S.min_binding}, but returns the binding with + (** Same as {!S.min_binding}, but returns the binding with the largest key in the given map. @since 3.12.0 *) val max_binding_opt: 'a t -> (key * 'a) option - (** Same as {!Map.S.min_binding_opt}, but returns the binding with + (** Same as {!S.min_binding_opt}, but returns the binding with the largest key in the given map. @since 4.05 *) @@ -288,16 +292,16 @@ module type S = For example, [find_first (fun k -> Ord.compare k x >= 0) m] will return the first binding [k, v] of [m] where [Ord.compare k x >= 0] - (intuitively: [k >= x]), or raise [Not_found] if [x] is greater than any - element of [m]. + (intuitively: [k >= x]), or raise [Not_found] if [x] is greater than + any element of [m]. @since 4.05 *) val find_first_opt: (key -> bool) -> 'a t -> (key * 'a) option - (** [find_first_opt f m], where [f] is a monotonically increasing function, - returns an option containing the binding of [m] with the lowest key [k] - such that [f k], or [None] if no such key exists. + (** [find_first_opt f m], where [f] is a monotonically increasing + function, returns an option containing the binding of [m] with the + lowest key [k] such that [f k], or [None] if no such key exists. @since 4.05 *) @@ -309,9 +313,10 @@ module type S = *) val find_last_opt: (key -> bool) -> 'a t -> (key * 'a) option - (** [find_last_opt f m], where [f] is a monotonically decreasing function, - returns an option containing the binding of [m] with the highest key [k] - such that [f k], or [None] if no such key exists. + (** [find_last_opt f m], where [f] is a monotonically decreasing + function, returns an option containing the binding of [m] with + the highest key [k] such that [f k], or [None] if no such key + exists. @since 4.05 *) @@ -323,7 +328,7 @@ module type S = with respect to the ordering over the type of the keys. *) val mapi: (key -> 'a -> 'b) -> 'a t -> 'b t - (** Same as {!Map.S.map}, but the function receives as arguments both the + (** Same as {!S.map}, but the function receives as arguments both the key and the associated value for each binding of the map. *) (** {1 Iterators} *) @@ -332,6 +337,10 @@ module type S = (** Iterate on the whole map, in ascending order of keys @since 4.07 *) + val to_rev_seq : 'a t -> (key * 'a) Seq.t + (** Iterate on the whole map, in descending order of keys + @since 4.12 *) + val to_seq_from : key -> 'a t -> (key * 'a) Seq.t (** [to_seq_from k m] iterates on a subset of the bindings of [m], in ascending order of keys, from key [k] or above. @@ -345,7 +354,7 @@ module type S = (** Build a map from the given bindings @since 4.07 *) end -(** Output signature of the functor {!Map.Make}. *) +(** Output signature of the functor {!Make}. *) module Make (Ord : OrderedType) : S with type key = Ord.t (** Functor building an implementation of the map structure diff --git a/stdlib/moreLabels.mli b/stdlib/moreLabels.mli index eae749c7..5d266f16 100644 --- a/stdlib/moreLabels.mli +++ b/stdlib/moreLabels.mli @@ -13,223 +13,1169 @@ (* *) (**************************************************************************) +(* NOTE: Do not edit this file directly. Edit templates/ and run + tools/sync_stdlib_docs *) + (** Extra labeled libraries. - This meta-module provides labelized version of the {!Hashtbl}, - {!Map} and {!Set} modules. + This meta-module provides labelized versions of the {!Hashtbl}, {!Map} and + {!Set} modules. + + This module is intended to be used through [open MoreLabels] which replaces + {!Hashtbl}, {!Map}, and {!Set} with their labeled counterparts. - They only differ by their labels. They are provided to help - porting from previous versions of OCaml. - The contents of this module are subject to change. + For example: + {[ + open MoreLabels + + Hashtbl.iter ~f:(fun ~key ~data -> g key data) table + ]} *) module Hashtbl : sig - type ('a, 'b) t = ('a, 'b) Hashtbl.t - val create : ?random:bool -> int -> ('a, 'b) t + (** Hash tables and hash functions. + + Hash tables are hashed association tables, with in-place modification. + *) + + + (** {1 Generic interface} *) + + + type (!'a, !'b) t = ('a, 'b) Hashtbl.t + (** The type of hash tables from type ['a] to type ['b]. *) + + val create : ?random: (* thwart tools/sync_stdlib_docs *) bool -> + int -> ('a, 'b) t + (** [Hashtbl.create n] creates a new, empty hash table, with + initial size [n]. For best results, [n] should be on the + order of the expected number of elements that will be in + the table. The table grows as needed, so [n] is just an + initial guess. + + The optional [~][random] parameter (a boolean) controls whether + the internal organization of the hash table is randomized at each + execution of [Hashtbl.create] or deterministic over all executions. + + A hash table that is created with [~][random] set to [false] uses a + fixed hash function ({!hash}) to distribute keys among + buckets. As a consequence, collisions between keys happen + deterministically. In Web-facing applications or other + security-sensitive applications, the deterministic collision + patterns can be exploited by a malicious user to create a + denial-of-service attack: the attacker sends input crafted to + create many collisions in the table, slowing the application down. + + A hash table that is created with [~][random] set to [true] uses the seeded + hash function {!seeded_hash} with a seed that is randomly chosen at hash + table creation time. In effect, the hash function used is randomly + selected among [2^{30}] different hash functions. All these hash + functions have different collision patterns, rendering ineffective the + denial-of-service attack described above. However, because of + randomization, enumerating all elements of the hash table using {!fold} + or {!iter} is no longer deterministic: elements are enumerated in + different orders at different runs of the program. + + If no [~][random] parameter is given, hash tables are created + in non-random mode by default. This default can be changed + either programmatically by calling {!randomize} or by + setting the [R] flag in the [OCAMLRUNPARAM] environment variable. + + @before 4.00.0 the [~][random] parameter was not present and all + hash tables were created in non-randomized mode. *) + val clear : ('a, 'b) t -> unit + (** Empty a hash table. Use [reset] instead of [clear] to shrink the + size of the bucket table to its initial size. *) + val reset : ('a, 'b) t -> unit + (** Empty a hash table and shrink the size of the bucket table + to its initial size. + @since 4.00.0 *) + val copy : ('a, 'b) t -> ('a, 'b) t + (** Return a copy of the given hashtable. *) + val add : ('a, 'b) t -> key:'a -> data:'b -> unit + (** [Hashtbl.add tbl ~key ~data] adds a binding of [key] to [data] + in table [tbl]. + Previous bindings for [key] are not removed, but simply + hidden. That is, after performing {!remove}[ tbl key], + the previous binding for [key], if any, is restored. + (Same behavior as with association lists.) *) + val find : ('a, 'b) t -> 'a -> 'b + (** [Hashtbl.find tbl x] returns the current binding of [x] in [tbl], + or raises [Not_found] if no such binding exists. *) + val find_opt : ('a, 'b) t -> 'a -> 'b option + (** [Hashtbl.find_opt tbl x] returns the current binding of [x] in [tbl], + or [None] if no such binding exists. + @since 4.05 *) + val find_all : ('a, 'b) t -> 'a -> 'b list + (** [Hashtbl.find_all tbl x] returns the list of all data + associated with [x] in [tbl]. + The current binding is returned first, then the previous + bindings, in reverse order of introduction in the table. *) + val mem : ('a, 'b) t -> 'a -> bool + (** [Hashtbl.mem tbl x] checks if [x] is bound in [tbl]. *) + val remove : ('a, 'b) t -> 'a -> unit + (** [Hashtbl.remove tbl x] removes the current binding of [x] in [tbl], + restoring the previous binding if it exists. + It does nothing if [x] is not bound in [tbl]. *) + val replace : ('a, 'b) t -> key:'a -> data:'b -> unit + (** [Hashtbl.replace tbl ~key ~data] replaces the current binding of [key] + in [tbl] by a binding of [key] to [data]. If [key] is unbound in [tbl], + a binding of [key] to [data] is added to [tbl]. + This is functionally equivalent to {!remove}[ tbl key] + followed by {!add}[ tbl key data]. *) + val iter : f:(key:'a -> data:'b -> unit) -> ('a, 'b) t -> unit - val filter_map_inplace: - f:(key:'a -> data:'b -> 'b option) -> ('a, 'b) t -> unit - val fold : - f:(key:'a -> data:'b -> 'c -> 'c) -> - ('a, 'b) t -> init:'c -> 'c + (** [Hashtbl.iter ~f tbl] applies [f] to all bindings in table [tbl]. + [f] receives the key as first argument, and the associated value + as second argument. Each binding is presented exactly once to [f]. + + The order in which the bindings are passed to [f] is unspecified. + However, if the table contains several bindings for the same key, + they are passed to [f] in reverse order of introduction, that is, + the most recent binding is passed first. + + If the hash table was created in non-randomized mode, the order + in which the bindings are enumerated is reproducible between + successive runs of the program, and even between minor versions + of OCaml. For randomized hash tables, the order of enumeration + is entirely random. + + The behavior is not defined if the hash table is modified + by [f] during the iteration. + *) + + val filter_map_inplace: f:(key:'a -> data:'b -> 'b option) -> ('a, 'b) t -> + unit + (** [Hashtbl.filter_map_inplace ~f tbl] applies [f] to all bindings in + table [tbl] and update each binding depending on the result of + [f]. If [f] returns [None], the binding is discarded. If it + returns [Some new_val], the binding is update to associate the key + to [new_val]. + + Other comments for {!iter} apply as well. + @since 4.03.0 *) + + val fold : f:(key:'a -> data:'b -> 'c -> 'c) -> ('a, 'b) t -> init:'c -> 'c + (** [Hashtbl.fold ~f tbl ~init] computes + [(f kN dN ... (f k1 d1 init)...)], + where [k1 ... kN] are the keys of all bindings in [tbl], + and [d1 ... dN] are the associated values. + Each binding is presented exactly once to [f]. + + The order in which the bindings are passed to [f] is unspecified. + However, if the table contains several bindings for the same key, + they are passed to [f] in reverse order of introduction, that is, + the most recent binding is passed first. + + If the hash table was created in non-randomized mode, the order + in which the bindings are enumerated is reproducible between + successive runs of the program, and even between minor versions + of OCaml. For randomized hash tables, the order of enumeration + is entirely random. + + The behavior is not defined if the hash table is modified + by [f] during the iteration. + *) + val length : ('a, 'b) t -> int + (** [Hashtbl.length tbl] returns the number of bindings in [tbl]. + It takes constant time. Multiple bindings are counted once each, so + [Hashtbl.length] gives the number of times [Hashtbl.iter] calls its + first argument. *) + val randomize : unit -> unit + (** After a call to [Hashtbl.randomize()], hash tables are created in + randomized mode by default: {!create} returns randomized + hash tables, unless the [~random:false] optional parameter is given. + The same effect can be achieved by setting the [R] parameter in + the [OCAMLRUNPARAM] environment variable. + + It is recommended that applications or Web frameworks that need to + protect themselves against the denial-of-service attack described + in {!create} call [Hashtbl.randomize()] at initialization + time. + + Note that once [Hashtbl.randomize()] was called, there is no way + to revert to the non-randomized default behavior of {!create}. + This is intentional. Non-randomized hash tables can still be + created using [Hashtbl.create ~random:false]. + + @since 4.00.0 *) + val is_randomized : unit -> bool - type statistics = Hashtbl.statistics + (** Return [true] if the tables are currently created in randomized mode + by default, [false] otherwise. + @since 4.03.0 *) + + val rebuild : ?random (* thwart tools/sync_stdlib_docs *) :bool -> + ('a, 'b) t -> ('a, 'b) t + (** Return a copy of the given hashtable. Unlike {!copy}, + {!rebuild}[ h] re-hashes all the (key, value) entries of + the original table [h]. The returned hash table is randomized if + [h] was randomized, or the optional [random] parameter is true, or + if the default is to create randomized hash tables; see + {!create} for more information. + + {!rebuild} can safely be used to import a hash table built + by an old version of the {!Hashtbl} module, then marshaled to + persistent storage. After unmarshaling, apply {!rebuild} + to produce a hash table for the current version of the {!Hashtbl} + module. + + @since 4.12.0 *) + + (** @since 4.00.0 *) + type statistics = Hashtbl.statistics = { + num_bindings: int; + (** Number of bindings present in the table. + Same value as returned by {!length}. *) + num_buckets: int; + (** Number of buckets in the table. *) + max_bucket_length: int; + (** Maximal number of bindings per bucket. *) + bucket_histogram: int array + (** Histogram of bucket sizes. This array [histo] has + length [max_bucket_length + 1]. The value of + [histo.(i)] is the number of buckets whose size is [i]. *) + } + val stats : ('a, 'b) t -> statistics + (** [Hashtbl.stats tbl] returns statistics about the table [tbl]: + number of buckets, size of the biggest bucket, distribution of + buckets by size. + @since 4.00.0 *) + + (** {1 Iterators} *) + val to_seq : ('a,'b) t -> ('a * 'b) Seq.t + (** Iterate on the whole table. The order in which the bindings + appear in the sequence is unspecified. However, if the table contains + several bindings for the same key, they appear in reversed order of + introduction, that is, the most recent binding appears first. + + The behavior is not defined if the hash table is modified + during the iteration. + + @since 4.07 *) + val to_seq_keys : ('a,_) t -> 'a Seq.t + (** Same as [Seq.map fst (to_seq m)] + @since 4.07 *) + val to_seq_values : (_,'b) t -> 'b Seq.t + (** Same as [Seq.map snd (to_seq m)] + @since 4.07 *) + val add_seq : ('a,'b) t -> ('a * 'b) Seq.t -> unit + (** Add the given bindings to the table, using {!add} + @since 4.07 *) + val replace_seq : ('a,'b) t -> ('a * 'b) Seq.t -> unit + (** Add the given bindings to the table, using {!replace} + @since 4.07 *) + val of_seq : ('a * 'b) Seq.t -> ('a, 'b) t - module type HashedType = Hashtbl.HashedType - module type SeededHashedType = Hashtbl.SeededHashedType + (** Build a table from the given bindings. The bindings are added + in the same order they appear in the sequence, using {!replace_seq}, + which means that if two pairs have the same key, only the latest one + will appear in the table. + @since 4.07 *) + + (** {1 Functorial interface} *) + + (** The functorial interface allows the use of specific comparison + and hash functions, either for performance/security concerns, + or because keys are not hashable/comparable with the polymorphic builtins. + + For instance, one might want to specialize a table for integer keys: + {[ + module IntHash = + struct + type t = int + let equal i j = i=j + let hash i = i land max_int + end + + module IntHashtbl = Hashtbl.Make(IntHash) + + let h = IntHashtbl.create 17 in + IntHashtbl.add h 12 "hello" + ]} + + This creates a new module [IntHashtbl], with a new type ['a + IntHashtbl.t] of tables from [int] to ['a]. In this example, [h] + contains [string] values so its type is [string IntHashtbl.t]. + + Note that the new type ['a IntHashtbl.t] is not compatible with + the type [('a,'b) Hashtbl.t] of the generic interface. For + example, [Hashtbl.length h] would not type-check, you must use + [IntHashtbl.length]. + *) + + module type HashedType = + sig + type t + (** The type of the hashtable keys. *) + + val equal : t -> t -> bool + (** The equality predicate used to compare keys. *) + + val hash : t -> int + (** A hashing function on keys. It must be such that if two keys are + equal according to [equal], then they have identical hash values + as computed by [hash]. + Examples: suitable ([equal], [hash]) pairs for arbitrary key + types include + - ([(=)], {!hash}) for comparing objects by structure + (provided objects do not contain floats) + - ([(fun x y -> compare x y = 0)], {!hash}) + for comparing objects by structure + and handling {!Stdlib.nan} correctly + - ([(==)], {!hash}) for comparing objects by physical + equality (e.g. for mutable or cyclic objects). *) + end + (** The input signature of the functor {!Make}. *) + module type S = sig type key - and 'a t + type !'a t val create : int -> 'a t val clear : 'a t -> unit - val reset : 'a t -> unit + val reset : 'a t -> unit (** @since 4.00.0 *) + val copy : 'a t -> 'a t val add : 'a t -> key:key -> data:'a -> unit val remove : 'a t -> key -> unit val find : 'a t -> key -> 'a - val find_opt: 'a t -> key -> 'a option + val find_opt : 'a t -> key -> 'a option + (** @since 4.05.0 *) + val find_all : 'a t -> key -> 'a list val replace : 'a t -> key:key -> data:'a -> unit val mem : 'a t -> key -> bool val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit - val filter_map_inplace: - f:(key:key -> data:'a -> 'a option) -> 'a t -> unit - val fold : - f:(key:key -> data:'a -> 'b -> 'b) -> - 'a t -> init:'b -> 'b + val filter_map_inplace: f:(key:key -> data:'a -> 'a option) -> 'a t -> + unit + (** @since 4.03.0 *) + + val fold : f:(key:key -> data:'a -> 'b -> 'b) -> 'a t -> init:'b -> 'b val length : 'a t -> int - val stats: 'a t -> statistics + val stats: 'a t -> statistics (** @since 4.00.0 *) + val to_seq : 'a t -> (key * 'a) Seq.t + (** @since 4.07 *) + val to_seq_keys : _ t -> key Seq.t + (** @since 4.07 *) + val to_seq_values : 'a t -> 'a Seq.t + (** @since 4.07 *) + val add_seq : 'a t -> (key * 'a) Seq.t -> unit + (** @since 4.07 *) + val replace_seq : 'a t -> (key * 'a) Seq.t -> unit + (** @since 4.07 *) + val of_seq : (key * 'a) Seq.t -> 'a t + (** @since 4.07 *) end + (** The output signature of the functor {!Make}. *) + + module Make : functor (H : HashedType) -> S + with type key = H.t + and type 'a t = 'a Hashtbl.Make(H).t + (** Functor building an implementation of the hashtable structure. + The functor [Hashtbl.Make] returns a structure containing + a type [key] of keys and a type ['a t] of hash tables + associating data of type ['a] to keys of type [key]. + The operations perform similarly to those of the generic + interface, but use the hashing and equality functions + specified in the functor argument [H] instead of generic + equality and hashing. Since the hash function is not seeded, + the [create] operation of the result structure always returns + non-randomized hash tables. *) + + module type SeededHashedType = + sig + type t + (** The type of the hashtable keys. *) + + val equal: t -> t -> bool + (** The equality predicate used to compare keys. *) + + val hash: int -> t -> int + (** A seeded hashing function on keys. The first argument is + the seed. It must be the case that if [equal x y] is true, + then [hash seed x = hash seed y] for any value of [seed]. + A suitable choice for [hash] is the function {!seeded_hash} + below. *) + end + (** The input signature of the functor {!MakeSeeded}. + @since 4.00.0 *) + module type SeededS = sig type key - and 'a t - val create : ?random:bool -> int -> 'a t + type !'a t + val create : ?random (* thwart tools/sync_stdlib_docs *) :bool -> + int -> 'a t val clear : 'a t -> unit val reset : 'a t -> unit val copy : 'a t -> 'a t val add : 'a t -> key:key -> data:'a -> unit val remove : 'a t -> key -> unit val find : 'a t -> key -> 'a - val find_opt : 'a t -> key -> 'a option + val find_opt : 'a t -> key -> 'a option (** @since 4.05.0 *) + val find_all : 'a t -> key -> 'a list val replace : 'a t -> key:key -> data:'a -> unit val mem : 'a t -> key -> bool val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit - val filter_map_inplace: - f:(key:key -> data:'a -> 'a option) -> 'a t -> unit - val fold : - f:(key:key -> data:'a -> 'b -> 'b) -> - 'a t -> init:'b -> 'b + val filter_map_inplace: f:(key:key -> data:'a -> 'a option) -> 'a t -> + unit + (** @since 4.03.0 *) + + val fold : f:(key:key -> data:'a -> 'b -> 'b) -> 'a t -> init:'b -> 'b val length : 'a t -> int val stats: 'a t -> statistics + val to_seq : 'a t -> (key * 'a) Seq.t + (** @since 4.07 *) + val to_seq_keys : _ t -> key Seq.t + (** @since 4.07 *) + val to_seq_values : 'a t -> 'a Seq.t + (** @since 4.07 *) + val add_seq : 'a t -> (key * 'a) Seq.t -> unit + (** @since 4.07 *) + val replace_seq : 'a t -> (key * 'a) Seq.t -> unit + (** @since 4.07 *) + val of_seq : (key * 'a) Seq.t -> 'a t + (** @since 4.07 *) end - module Make : functor (H : HashedType) -> S - with type key = H.t - and type 'a t = 'a Hashtbl.Make(H).t - module MakeSeeded (H : SeededHashedType) : SeededS + (** The output signature of the functor {!MakeSeeded}. + @since 4.00.0 *) + + module MakeSeeded (H : SeededHashedType) : SeededS with type key = H.t and type 'a t = 'a Hashtbl.MakeSeeded(H).t + (** Functor building an implementation of the hashtable structure. + The functor [Hashtbl.MakeSeeded] returns a structure containing + a type [key] of keys and a type ['a t] of hash tables + associating data of type ['a] to keys of type [key]. + The operations perform similarly to those of the generic + interface, but use the seeded hashing and equality functions + specified in the functor argument [H] instead of generic + equality and hashing. The [create] operation of the + result structure supports the [~][random] optional parameter + and returns randomized hash tables if [~random:true] is passed + or if randomization is globally on (see {!Hashtbl.randomize}). + @since 4.00.0 *) + + + (** {1 The polymorphic hash functions} *) + + val hash : 'a -> int + (** [Hashtbl.hash x] associates a nonnegative integer to any value of + any type. It is guaranteed that + if [x = y] or [Stdlib.compare x y = 0], then [hash x = hash y]. + Moreover, [hash] always terminates, even on cyclic structures. *) + val seeded_hash : int -> 'a -> int + (** A variant of {!hash} that is further parameterized by + an integer seed. + @since 4.00.0 *) + val hash_param : int -> int -> 'a -> int + (** [Hashtbl.hash_param meaningful total x] computes a hash value for [x], + with the same properties as for [hash]. The two extra integer + parameters [meaningful] and [total] give more precise control over + hashing. Hashing performs a breadth-first, left-to-right traversal + of the structure [x], stopping after [meaningful] meaningful nodes + were encountered, or [total] nodes (meaningful or not) were + encountered. If [total] as specified by the user exceeds a certain + value, currently 256, then it is capped to that value. + Meaningful nodes are: integers; floating-point + numbers; strings; characters; booleans; and constant + constructors. Larger values of [meaningful] and [total] means that + more nodes are taken into account to compute the final hash value, + and therefore collisions are less likely to happen. However, + hashing takes longer. The parameters [meaningful] and [total] + govern the tradeoff between accuracy and speed. As default + choices, {!hash} and {!seeded_hash} take + [meaningful = 10] and [total = 100]. *) + val seeded_hash_param : int -> int -> int -> 'a -> int + (** A variant of {!hash_param} that is further parameterized by + an integer seed. Usage: + [Hashtbl.seeded_hash_param meaningful total seed x]. + @since 4.00.0 *) + end module Map : sig - module type OrderedType = Map.OrderedType + (** Association tables over ordered types. + + This module implements applicative association tables, also known as + finite maps or dictionaries, given a total ordering function + over the keys. + All operations over maps are purely applicative (no side-effects). + The implementation uses balanced binary trees, and therefore searching + and insertion take time logarithmic in the size of the map. + + For instance: + {[ + module IntPairs = + struct + type t = int * int + let compare (x0,y0) (x1,y1) = + match Stdlib.compare x0 x1 with + 0 -> Stdlib.compare y0 y1 + | c -> c + end + + module PairsMap = Map.Make(IntPairs) + + let m = PairsMap.(empty |> add (0,1) "hello" |> add (1,0) "world") + ]} + + This creates a new module [PairsMap], with a new type ['a PairsMap.t] + of maps from [int * int] to ['a]. In this example, [m] contains [string] + values so its type is [string PairsMap.t]. + *) + + module type OrderedType = + sig + type t + (** The type of the map keys. *) + + val compare : t -> t -> int + (** A total ordering function over the keys. + This is a two-argument function [f] such that + [f e1 e2] is zero if the keys [e1] and [e2] are equal, + [f e1 e2] is strictly negative if [e1] is smaller than [e2], + and [f e1 e2] is strictly positive if [e1] is greater than [e2]. + Example: a suitable ordering function is the generic structural + comparison function {!Stdlib.compare}. *) + end + (** Input signature of the functor {!Make}. *) + module type S = sig type key - and (+'a) t - val empty : 'a t + (** The type of the map keys. *) + + type !+'a t + (** The type of maps from type [key] to type ['a]. *) + + val empty: 'a t + (** The empty map. *) + val is_empty: 'a t -> bool - val mem : key -> 'a t -> bool - val add : key:key -> data:'a -> 'a t -> 'a t + (** Test whether a map is empty or not. *) + + val mem: key -> 'a t -> bool + (** [mem x m] returns [true] if [m] contains a binding for [x], + and [false] otherwise. *) + + val add: key:key -> data:'a -> 'a t -> 'a t + (** [add ~key ~data m] returns a map containing the same bindings as + [m], plus a binding of [key] to [data]. If [key] was already bound + in [m] to a value that is physically equal to [data], + [m] is returned unchanged (the result of the function is + then physically equal to [m]). Otherwise, the previous binding + of [key] in [m] disappears. + @before 4.03 Physical equality was not ensured. *) + val update: key:key -> f:('a option -> 'a option) -> 'a t -> 'a t + (** [update ~key ~f m] returns a map containing the same bindings as + [m], except for the binding of [key]. Depending on the value of + [y] where [y] is [f (find_opt key m)], the binding of [key] is + added, removed or updated. If [y] is [None], the binding is + removed if it exists; otherwise, if [y] is [Some z] then [key] + is associated to [z] in the resulting map. If [key] was already + bound in [m] to a value that is physically equal to [z], [m] + is returned unchanged (the result of the function is then + physically equal to [m]). + @since 4.06.0 + *) + val singleton: key -> 'a -> 'a t - val remove : key -> 'a t -> 'a t + (** [singleton x y] returns the one-element map that contains a binding + [y] for [x]. + @since 3.12.0 + *) + + val remove: key -> 'a t -> 'a t + (** [remove x m] returns a map containing the same bindings as + [m], except for [x] which is unbound in the returned map. + If [x] was not in [m], [m] is returned unchanged + (the result of the function is then physically equal to [m]). + @before 4.03 Physical equality was not ensured. *) + val merge: - f:(key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t + f:(key -> 'a option -> 'b option -> 'c option) -> + 'a t -> 'b t -> 'c t + (** [merge ~f m1 m2] computes a map whose keys are a subset of the keys of + [m1] and of [m2]. The presence of each such binding, and the + corresponding value, is determined with the function [f]. + In terms of the [find_opt] operation, we have + [find_opt x (merge f m1 m2) = f x (find_opt x m1) (find_opt x m2)] + for any key [x], provided that [f x None None = None]. + @since 3.12.0 + *) + val union: f:(key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t + (** [union ~f m1 m2] computes a map whose keys are a subset of the keys + of [m1] and of [m2]. When the same binding is defined in both + arguments, the function [f] is used to combine them. + This is a special case of [merge]: [union f m1 m2] is equivalent + to [merge f' m1 m2], where + - [f' _key None None = None] + - [f' _key (Some v) None = Some v] + - [f' _key None (Some v) = Some v] + - [f' key (Some v1) (Some v2) = f key v1 v2] + + @since 4.03.0 + *) + val compare: cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int + (** Total ordering between maps. The first argument is a total ordering + used to compare data associated with equal keys in the two maps. *) + val equal: cmp:('a -> 'a -> bool) -> 'a t -> 'a t -> bool - val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit - val fold : - f:(key:key -> data:'a -> 'b -> 'b) -> - 'a t -> init:'b -> 'b + (** [equal ~cmp m1 m2] tests whether the maps [m1] and [m2] are + equal, that is, contain equal keys and associate them with + equal data. [cmp] is the equality predicate used to compare + the data associated with the keys. *) + + val iter: f:(key:key -> data:'a -> unit) -> 'a t -> unit + (** [iter ~f m] applies [f] to all bindings in map [m]. + [f] receives the key as first argument, and the associated value + as second argument. The bindings are passed to [f] in increasing + order with respect to the ordering over the type of the keys. *) + + val fold: f:(key:key -> data:'a -> 'b -> 'b) -> 'a t -> init:'b -> 'b + (** [fold ~f m ~init] computes [(f kN dN ... (f k1 d1 init)...)], + where [k1 ... kN] are the keys of all bindings in [m] + (in increasing order), and [d1 ... dN] are the associated data. *) + val for_all: f:(key -> 'a -> bool) -> 'a t -> bool + (** [for_all ~f m] checks if all the bindings of the map + satisfy the predicate [f]. + @since 3.12.0 + *) + val exists: f:(key -> 'a -> bool) -> 'a t -> bool + (** [exists ~f m] checks if at least one binding of the map + satisfies the predicate [f]. + @since 3.12.0 + *) + val filter: f:(key -> 'a -> bool) -> 'a t -> 'a t + (** [filter ~f m] returns the map with all the bindings in [m] + that satisfy predicate [p]. If every binding in [m] satisfies [f], + [m] is returned unchanged (the result of the function is then + physically equal to [m]) + @since 3.12.0 + @before 4.03 Physical equality was not ensured. + *) + val filter_map: f:(key -> 'a -> 'b option) -> 'a t -> 'b t + (** [filter_map ~f m] applies the function [f] to every binding of + [m], and builds a map from the results. For each binding + [(k, v)] in the input map: + - if [f k v] is [None] then [k] is not in the result, + - if [f k v] is [Some v'] then the binding [(k, v')] + is in the output map. + + For example, the following function on maps whose values are lists + {[ + filter_map + (fun _k li -> match li with [] -> None | _::tl -> Some tl) + m + ]} + drops all bindings of [m] whose value is an empty list, and pops + the first element of each value that is non-empty. + + @since 4.11.0 + *) + val partition: f:(key -> 'a -> bool) -> 'a t -> 'a t * 'a t + (** [partition ~f m] returns a pair of maps [(m1, m2)], where + [m1] contains all the bindings of [m] that satisfy the + predicate [f], and [m2] is the map with all the bindings of + [m] that do not satisfy [f]. + @since 3.12.0 + *) + val cardinal: 'a t -> int + (** Return the number of bindings of a map. + @since 3.12.0 + *) + val bindings: 'a t -> (key * 'a) list + (** Return the list of all bindings of the given map. + The returned list is sorted in increasing order of keys with respect + to the ordering [Ord.compare], where [Ord] is the argument + given to {!Make}. + @since 3.12.0 + *) + val min_binding: 'a t -> (key * 'a) + (** Return the binding with the smallest key in a given map + (with respect to the [Ord.compare] ordering), or raise + [Not_found] if the map is empty. + @since 3.12.0 + *) + val min_binding_opt: 'a t -> (key * 'a) option + (** Return the binding with the smallest key in the given map + (with respect to the [Ord.compare] ordering), or [None] + if the map is empty. + @since 4.05 + *) + val max_binding: 'a t -> (key * 'a) + (** Same as {!S.min_binding}, but returns the binding with + the largest key in the given map. + @since 3.12.0 + *) + val max_binding_opt: 'a t -> (key * 'a) option + (** Same as {!S.min_binding_opt}, but returns the binding with + the largest key in the given map. + @since 4.05 + *) + val choose: 'a t -> (key * 'a) + (** Return one binding of the given map, or raise [Not_found] if + the map is empty. Which binding is chosen is unspecified, + but equal bindings will be chosen for equal maps. + @since 3.12.0 + *) + val choose_opt: 'a t -> (key * 'a) option + (** Return one binding of the given map, or [None] if + the map is empty. Which binding is chosen is unspecified, + but equal bindings will be chosen for equal maps. + @since 4.05 + *) + val split: key -> 'a t -> 'a t * 'a option * 'a t - val find : key -> 'a t -> 'a + (** [split x m] returns a triple [(l, data, r)], where + [l] is the map with all the bindings of [m] whose key + is strictly less than [x]; + [r] is the map with all the bindings of [m] whose key + is strictly greater than [x]; + [data] is [None] if [m] contains no binding for [x], + or [Some v] if [m] binds [v] to [x]. + @since 3.12.0 + *) + + val find: key -> 'a t -> 'a + (** [find x m] returns the current value of [x] in [m], + or raises [Not_found] if no binding for [x] exists. *) + val find_opt: key -> 'a t -> 'a option - val find_first : f:(key -> bool) -> 'a t -> key * 'a - val find_first_opt : f:(key -> bool) -> 'a t -> (key * 'a) option - val find_last : f:(key -> bool) -> 'a t -> key * 'a - val find_last_opt : f:(key -> bool) -> 'a t -> (key * 'a) option - val map : f:('a -> 'b) -> 'a t -> 'b t - val mapi : f:(key -> 'a -> 'b) -> 'a t -> 'b t + (** [find_opt x m] returns [Some v] if the current value of [x] + in [m] is [v], or [None] if no binding for [x] exists. + @since 4.05 + *) + + val find_first: f:(key -> bool) -> 'a t -> key * 'a + (** [find_first ~f m], where [f] is a monotonically increasing function, + returns the binding of [m] with the lowest key [k] such that [f k], + or raises [Not_found] if no such key exists. + + For example, [find_first (fun k -> Ord.compare k x >= 0) m] will return + the first binding [k, v] of [m] where [Ord.compare k x >= 0] + (intuitively: [k >= x]), or raise [Not_found] if [x] is greater than + any element of [m]. + + @since 4.05 + *) + + val find_first_opt: f:(key -> bool) -> 'a t -> (key * 'a) option + (** [find_first_opt ~f m], where [f] is a monotonically increasing + function, returns an option containing the binding of [m] with the + lowest key [k] such that [f k], or [None] if no such key exists. + @since 4.05 + *) + + val find_last: f:(key -> bool) -> 'a t -> key * 'a + (** [find_last ~f m], where [f] is a monotonically decreasing function, + returns the binding of [m] with the highest key [k] such that [f k], + or raises [Not_found] if no such key exists. + @since 4.05 + *) + + val find_last_opt: f:(key -> bool) -> 'a t -> (key * 'a) option + (** [find_last_opt ~f m], where [f] is a monotonically decreasing + function, returns an option containing the binding of [m] with + the highest key [k] such that [f k], or [None] if no such key + exists. + @since 4.05 + *) + + val map: f:('a -> 'b) -> 'a t -> 'b t + (** [map ~f m] returns a map with same domain as [m], where the + associated value [a] of all bindings of [m] has been + replaced by the result of the application of [f] to [a]. + The bindings are passed to [f] in increasing order + with respect to the ordering over the type of the keys. *) + + val mapi: f:(key -> 'a -> 'b) -> 'a t -> 'b t + (** Same as {!S.map}, but the function receives as arguments both the + key and the associated value for each binding of the map. *) + + (** {1 Iterators} *) + val to_seq : 'a t -> (key * 'a) Seq.t + (** Iterate on the whole map, in ascending order of keys + @since 4.07 *) + + val to_rev_seq : 'a t -> (key * 'a) Seq.t + (** Iterate on the whole map, in descending order of keys + @since 4.12 *) + val to_seq_from : key -> 'a t -> (key * 'a) Seq.t + (** [to_seq_from k m] iterates on a subset of the bindings of [m], + in ascending order of keys, from key [k] or above. + @since 4.07 *) + val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t + (** Add the given bindings to the map, in order. + @since 4.07 *) + val of_seq : (key * 'a) Seq.t -> 'a t - end - module Make : functor (Ord : OrderedType) -> S + (** Build a map from the given bindings + @since 4.07 *) + end + (** Output signature of the functor {!Make}. *) + + module Make : functor (Ord : OrderedType) -> S with type key = Ord.t and type 'a t = 'a Map.Make(Ord).t + (** Functor building an implementation of the map structure + given a totally ordered type. *) + end module Set : sig - module type OrderedType = Set.OrderedType + (** Sets over ordered types. + + This module implements the set data structure, given a total ordering + function over the set elements. All operations over sets + are purely applicative (no side-effects). + The implementation uses balanced binary trees, and is therefore + reasonably efficient: insertion and membership take time + logarithmic in the size of the set, for instance. + + The {!Make} functor constructs implementations for any type, given a + [compare] function. + For instance: + {[ + module IntPairs = + struct + type t = int * int + let compare (x0,y0) (x1,y1) = + match Stdlib.compare x0 x1 with + 0 -> Stdlib.compare y0 y1 + | c -> c + end + + module PairsSet = Set.Make(IntPairs) + + let m = PairsSet.(empty |> add (2,3) |> add (5,7) |> add (11,13)) + ]} + + This creates a new module [PairsSet], with a new type [PairsSet.t] + of sets of [int * int]. + *) + + module type OrderedType = + sig + type t + (** The type of the set elements. *) + + val compare : t -> t -> int + (** A total ordering function over the set elements. + This is a two-argument function [f] such that + [f e1 e2] is zero if the elements [e1] and [e2] are equal, + [f e1 e2] is strictly negative if [e1] is smaller than [e2], + and [f e1 e2] is strictly positive if [e1] is greater than [e2]. + Example: a suitable ordering function is the generic structural + comparison function {!Stdlib.compare}. *) + end + (** Input signature of the functor {!Make}. *) + module type S = sig type elt - and t - val empty : t - val is_empty : t -> bool - val mem : elt -> t -> bool - val add : elt -> t -> t - val singleton : elt -> t - val remove : elt -> t -> t - val union : t -> t -> t - val inter : t -> t -> t - val disjoint : t -> t -> bool - val diff : t -> t -> t - val compare : t -> t -> int - val equal : t -> t -> bool - val subset : t -> t -> bool - val iter : f:(elt -> unit) -> t -> unit - val map : f:(elt -> elt) -> t -> t - val fold : f:(elt -> 'a -> 'a) -> t -> init:'a -> 'a - val for_all : f:(elt -> bool) -> t -> bool - val exists : f:(elt -> bool) -> t -> bool - val filter : f:(elt -> bool) -> t -> t - val filter_map : f:(elt -> elt option) -> t -> t - val partition : f:(elt -> bool) -> t -> t * t - val cardinal : t -> int - val elements : t -> elt list - val min_elt : t -> elt + (** The type of the set elements. *) + + type t + (** The type of sets. *) + + val empty: t + (** The empty set. *) + + val is_empty: t -> bool + (** Test whether a set is empty or not. *) + + val mem: elt -> t -> bool + (** [mem x s] tests whether [x] belongs to the set [s]. *) + + val add: elt -> t -> t + (** [add x s] returns a set containing all elements of [s], + plus [x]. If [x] was already in [s], [s] is returned unchanged + (the result of the function is then physically equal to [s]). + @before 4.03 Physical equality was not ensured. *) + + val singleton: elt -> t + (** [singleton x] returns the one-element set containing only [x]. *) + + val remove: elt -> t -> t + (** [remove x s] returns a set containing all elements of [s], + except [x]. If [x] was not in [s], [s] is returned unchanged + (the result of the function is then physically equal to [s]). + @before 4.03 Physical equality was not ensured. *) + + val union: t -> t -> t + (** Set union. *) + + val inter: t -> t -> t + (** Set intersection. *) + + val disjoint: t -> t -> bool + (** Test if two sets are disjoint. + @since 4.08.0 *) + + val diff: t -> t -> t + (** Set difference: [diff s1 s2] contains the elements of [s1] + that are not in [s2]. *) + + val compare: t -> t -> int + (** Total ordering between sets. Can be used as the ordering function + for doing sets of sets. *) + + val equal: t -> t -> bool + (** [equal s1 s2] tests whether the sets [s1] and [s2] are + equal, that is, contain equal elements. *) + + val subset: t -> t -> bool + (** [subset s1 s2] tests whether the set [s1] is a subset of + the set [s2]. *) + + val iter: f:(elt -> unit) -> t -> unit + (** [iter ~f s] applies [f] in turn to all elements of [s]. + The elements of [s] are presented to [f] in increasing order + with respect to the ordering over the type of the elements. *) + + val map: f:(elt -> elt) -> t -> t + (** [map ~f s] is the set whose elements are [f a0],[f a1]... [f + aN], where [a0],[a1]...[aN] are the elements of [s]. + + The elements are passed to [f] in increasing order + with respect to the ordering over the type of the elements. + + If no element of [s] is changed by [f], [s] is returned + unchanged. (If each output of [f] is physically equal to its + input, the returned set is physically equal to [s].) + @since 4.04.0 *) + + val fold: f:(elt -> 'a -> 'a) -> t -> init:'a -> 'a + (** [fold ~f s init] computes [(f xN ... (f x2 (f x1 init))...)], + where [x1 ... xN] are the elements of [s], in increasing order. *) + + val for_all: f:(elt -> bool) -> t -> bool + (** [for_all ~f s] checks if all elements of the set + satisfy the predicate [f]. *) + + val exists: f:(elt -> bool) -> t -> bool + (** [exists ~f s] checks if at least one element of + the set satisfies the predicate [f]. *) + + val filter: f:(elt -> bool) -> t -> t + (** [filter ~f s] returns the set of all elements in [s] + that satisfy predicate [f]. If [f] satisfies every element in [s], + [s] is returned unchanged (the result of the function is then + physically equal to [s]). + @before 4.03 Physical equality was not ensured.*) + + val filter_map: f:(elt -> elt option) -> t -> t + (** [filter_map ~f s] returns the set of all [v] such that + [f x = Some v] for some element [x] of [s]. + + For example, + {[filter_map (fun n -> if n mod 2 = 0 then Some (n / 2) else None) s]} + is the set of halves of the even elements of [s]. + + If no element of [s] is changed or dropped by [f] (if + [f x = Some x] for each element [x]), then + [s] is returned unchanged: the result of the function + is then physically equal to [s]. + + @since 4.11.0 + *) + + val partition: f:(elt -> bool) -> t -> t * t + (** [partition ~f s] returns a pair of sets [(s1, s2)], where + [s1] is the set of all the elements of [s] that satisfy the + predicate [f], and [s2] is the set of all the elements of + [s] that do not satisfy [f]. *) + + val cardinal: t -> int + (** Return the number of elements of a set. *) + + val elements: t -> elt list + (** Return the list of all elements of the given set. + The returned list is sorted in increasing order with respect + to the ordering [Ord.compare], where [Ord] is the argument + given to {!Make}. *) + + val min_elt: t -> elt + (** Return the smallest element of the given set + (with respect to the [Ord.compare] ordering), or raise + [Not_found] if the set is empty. *) + val min_elt_opt: t -> elt option - val max_elt : t -> elt + (** Return the smallest element of the given set + (with respect to the [Ord.compare] ordering), or [None] + if the set is empty. + @since 4.05 + *) + + val max_elt: t -> elt + (** Same as {!S.min_elt}, but returns the largest element of the + given set. *) + val max_elt_opt: t -> elt option - val choose : t -> elt + (** Same as {!S.min_elt_opt}, but returns the largest element of the + given set. + @since 4.05 + *) + + val choose: t -> elt + (** Return one element of the given set, or raise [Not_found] if + the set is empty. Which element is chosen is unspecified, + but equal elements will be chosen for equal sets. *) + val choose_opt: t -> elt option + (** Return one element of the given set, or [None] if + the set is empty. Which element is chosen is unspecified, + but equal elements will be chosen for equal sets. + @since 4.05 + *) + val split: elt -> t -> t * bool * t + (** [split x s] returns a triple [(l, present, r)], where + [l] is the set of elements of [s] that are + strictly less than [x]; + [r] is the set of elements of [s] that are + strictly greater than [x]; + [present] is [false] if [s] contains no element equal to [x], + or [true] if [s] contains an element equal to [x]. *) + val find: elt -> t -> elt + (** [find x s] returns the element of [s] equal to [x] (according + to [Ord.compare]), or raise [Not_found] if no such element + exists. + @since 4.01.0 *) + val find_opt: elt -> t -> elt option + (** [find_opt x s] returns the element of [s] equal to [x] (according + to [Ord.compare]), or [None] if no such element + exists. + @since 4.05 *) + val find_first: f:(elt -> bool) -> t -> elt + (** [find_first ~f s], where [f] is a monotonically increasing function, + returns the lowest element [e] of [s] such that [f e], + or raises [Not_found] if no such element exists. + + For example, [find_first (fun e -> Ord.compare e x >= 0) s] will return + the first element [e] of [s] where [Ord.compare e x >= 0] (intuitively: + [e >= x]), or raise [Not_found] if [x] is greater than any element of + [s]. + + @since 4.05 + *) + val find_first_opt: f:(elt -> bool) -> t -> elt option + (** [find_first_opt ~f s], where [f] is a monotonically increasing + function, returns an option containing the lowest element [e] of [s] + such that [f e], or [None] if no such element exists. + @since 4.05 + *) + val find_last: f:(elt -> bool) -> t -> elt + (** [find_last ~f s], where [f] is a monotonically decreasing function, + returns the highest element [e] of [s] such that [f e], + or raises [Not_found] if no such element exists. + @since 4.05 + *) + val find_last_opt: f:(elt -> bool) -> t -> elt option + (** [find_last_opt ~f s], where [f] is a monotonically decreasing + function, returns an option containing the highest element [e] of [s] + such that [f e], or [None] if no such element exists. + @since 4.05 + *) + val of_list: elt list -> t + (** [of_list l] creates a set from a list of elements. + This is usually more efficient than folding [add] over the list, + except perhaps for lists with many duplicated elements. + @since 4.02.0 *) + + (** {1 Iterators} *) + val to_seq_from : elt -> t -> elt Seq.t + (** [to_seq_from x s] iterates on a subset of the elements of [s] + in ascending order, from [x] or above. + @since 4.07 *) + val to_seq : t -> elt Seq.t + (** Iterate on the whole set, in ascending order + @since 4.07 *) + + val to_rev_seq : t -> elt Seq.t + (** Iterate on the whole set, in descending order + @since 4.12 *) + val add_seq : elt Seq.t -> t -> t + (** Add the given elements to the set, in order. + @since 4.07 *) + val of_seq : elt Seq.t -> t + (** Build a set from the given bindings + @since 4.07 *) end - module Make : functor (Ord : OrderedType) -> S + (** Output signature of the functor {!Make}. *) + + module Make : functor (Ord : OrderedType) -> S with type elt = Ord.t and type t = Set.Make(Ord).t + (** Functor building an implementation of the set structure + given a totally ordered type. *) + end diff --git a/stdlib/nativeint.mli b/stdlib/nativeint.mli index fdf24eb8..73455e85 100644 --- a/stdlib/nativeint.mli +++ b/stdlib/nativeint.mli @@ -31,9 +31,9 @@ Literals for native integers are suffixed by n: {[ - let zero: nativeint = 0n - let one: nativeint = 1n - let m_one: nativeint = -1n + let zero: nativeint = 0n + let one: nativeint = 1n + let m_one: nativeint = -1n ]} *) diff --git a/stdlib/obj.ml b/stdlib/obj.ml index 32049d72..f2b6e37d 100644 --- a/stdlib/obj.ml +++ b/stdlib/obj.ml @@ -17,12 +17,14 @@ type t +type raw_data = nativeint + external repr : 'a -> t = "%identity" external obj : t -> 'a = "%identity" external magic : 'a -> 'b = "%identity" external is_int : t -> bool = "%obj_is_int" let [@inline always] is_block a = not (is_int a) -external tag : t -> int = "caml_obj_tag" +external tag : t -> int = "caml_obj_tag" [@@noalloc] external set_tag : t -> int -> unit = "caml_obj_set_tag" external size : t -> int = "%obj_size" external reachable_words : t -> int = "caml_obj_reachable_words" @@ -34,6 +36,10 @@ external floatarray_set : let [@inline always] double_field x i = floatarray_get (obj x : floatarray) i let [@inline always] set_double_field x i v = floatarray_set (obj x : floatarray) i v +external raw_field : t -> int -> raw_data = "caml_obj_raw_field" +external set_raw_field : t -> int -> raw_data -> unit + = "caml_obj_set_raw_field" + external new_block : int -> int -> t = "caml_obj_block" external dup : t -> t = "caml_obj_dup" external truncate : t -> int -> unit = "caml_obj_truncate" @@ -68,6 +74,33 @@ let int_tag = 1000 let out_of_heap_tag = 1001 let unaligned_tag = 1002 +module Closure = struct + type info = { + arity: int; + start_env: int; + } + + let info_of_raw (info : nativeint) = + let open Nativeint in + let arity = + (* signed: negative for tupled functions *) + if Sys.word_size = 64 then + to_int (shift_right info 56) + else + to_int (shift_right info 24) + in + let start_env = + (* start_env is unsigned, but we know it can always fit an OCaml + integer so we use [to_int] instead of [unsigned_to_int]. *) + to_int (shift_right_logical (shift_left info 8) 9) in + { arity; start_env } + + (* note: we expect a closure, not an infix pointer *) + let info (obj : t) = + assert (tag obj = closure_tag); + info_of_raw (raw_field obj 1) +end + module Extension_constructor = struct type t = extension_constructor diff --git a/stdlib/obj.mli b/stdlib/obj.mli index 818f315f..3270246b 100644 --- a/stdlib/obj.mli +++ b/stdlib/obj.mli @@ -20,18 +20,21 @@ type t +type raw_data = nativeint (* @since 4.12 *) + external repr : 'a -> t = "%identity" external obj : t -> 'a = "%identity" external magic : 'a -> 'b = "%identity" val [@inline always] is_block : t -> bool external is_int : t -> bool = "%obj_is_int" -external tag : t -> int = "caml_obj_tag" +external tag : t -> int = "caml_obj_tag" [@@noalloc] external size : t -> int = "%obj_size" external reachable_words : t -> int = "caml_obj_reachable_words" (** Computes the total size (in words, including the headers) of all heap blocks accessible from the argument. Statically - allocated blocks are excluded. + allocated blocks are excluded, unless the runtime system + was configured with [--disable-naked-pointers]. @Since 4.04 *) @@ -60,6 +63,13 @@ external set_tag : t -> int -> unit = "caml_obj_set_tag" val [@inline always] double_field : t -> int -> float (* @since 3.11.2 *) val [@inline always] set_double_field : t -> int -> float -> unit (* @since 3.11.2 *) + +external raw_field : t -> int -> raw_data = "caml_obj_raw_field" + (* @since 4.12 *) +external set_raw_field : t -> int -> raw_data -> unit + = "caml_obj_set_raw_field" + (* @since 4.12 *) + external new_block : int -> int -> t = "caml_obj_block" external dup : t -> t = "caml_obj_dup" external truncate : t -> int -> unit = "caml_obj_truncate" @@ -90,6 +100,14 @@ val int_tag : int val out_of_heap_tag : int val unaligned_tag : int (* should never happen @since 3.11.0 *) +module Closure : sig + type info = { + arity: int; + start_env: int; + } + val info : t -> info +end + module Extension_constructor : sig type t = extension_constructor diff --git a/stdlib/option.mli b/stdlib/option.mli index 01b665fc..260ba36f 100644 --- a/stdlib/option.mli +++ b/stdlib/option.mli @@ -55,14 +55,14 @@ val iter : ('a -> unit) -> 'a option -> unit (** {1:preds Predicates and comparisons} *) val is_none : 'a option -> bool -(** [is_none o] is [true] iff [o] is [None]. *) +(** [is_none o] is [true] if and only if [o] is [None]. *) val is_some : 'a option -> bool -(** [is_some o] is [true] iff [o] is [Some o]. *) +(** [is_some o] is [true] if and only if [o] is [Some o]. *) val equal : ('a -> 'a -> bool) -> 'a option -> 'a option -> bool -(** [equal eq o0 o1] is [true] iff [o0] and [o1] are both [None] or if - they are [Some v0] and [Some v1] and [eq v0 v1] is [true]. *) +(** [equal eq o0 o1] is [true] if and only if [o0] and [o1] are both [None] + or if they are [Some v0] and [Some v1] and [eq v0 v1] is [true]. *) val compare : ('a -> 'a -> int) -> 'a option -> 'a option -> int (** [compare cmp o0 o1] is a total order on options using [cmp] to compare diff --git a/stdlib/printexc.ml b/stdlib/printexc.ml index 8b6822d1..8f4ed339 100644 --- a/stdlib/printexc.ml +++ b/stdlib/printexc.ml @@ -17,7 +17,7 @@ open Printf type t = exn = .. -let printers = ref [] +let printers = Atomic.make [] let locfmt = format_of_string "File \"%s\", line %d, characters %d-%d: %s" @@ -50,7 +50,7 @@ let use_printers x = | None | exception _ -> conv tl | Some s -> Some s) | [] -> None in - conv !printers + conv (Atomic.get printers) let to_string_default = function | Out_of_memory -> "Out of memory" @@ -92,7 +92,10 @@ let catch fct arg = exit 2 type raw_backtrace_slot -type raw_backtrace +type raw_backtrace_entry = private int +type raw_backtrace = raw_backtrace_entry array + +let raw_backtrace_entries bt = bt external get_raw_backtrace: unit -> raw_backtrace = "caml_get_exception_raw_backtrace" @@ -234,6 +237,9 @@ let backtrace_slots raw_backtrace = then Some backtrace else None +let backtrace_slots_of_raw_entry entry = + backtrace_slots [| entry |] + module Slot = struct type t = backtrace_slot let format = format_backtrace_slot @@ -243,8 +249,7 @@ module Slot = struct let name = backtrace_slot_defname end -external raw_backtrace_length : - raw_backtrace -> int = "caml_raw_backtrace_length" [@@noalloc] +let raw_backtrace_length bt = Array.length bt external get_raw_backtrace_slot : raw_backtrace -> int -> raw_backtrace_slot = "caml_raw_backtrace_slot" @@ -260,8 +265,11 @@ let get_backtrace () = raw_backtrace_to_string (get_raw_backtrace ()) external record_backtrace: bool -> unit = "caml_record_backtrace" external backtrace_status: unit -> bool = "caml_backtrace_status" -let register_printer fn = - printers := fn :: !printers +let rec register_printer fn = + let old_printers = Atomic.get printers in + let new_printers = fn :: old_printers in + let success = Atomic.compare_and_set printers old_printers new_printers in + if not success then register_printer fn external get_callstack: int -> raw_backtrace = "caml_get_current_callstack" @@ -277,16 +285,38 @@ let exn_slot_name x = let slot = exn_slot x in (Obj.obj (Obj.field slot 0) : string) +external get_debug_info_status : unit -> int = "caml_ml_debug_info_status" + +(* Descriptions for errors in startup.h. See also backtrace.c *) +let errors = [| ""; + (* FILE_NOT_FOUND *) + "(Cannot print locations:\n \ + bytecode executable program file not found)"; + (* BAD_BYTECODE *) + "(Cannot print locations:\n \ + bytecode executable program file appears to be corrupt)"; + (* WRONG_MAGIC *) + "(Cannot print locations:\n \ + bytecode executable program file has wrong magic number)"; + (* NO_FDS *) + "(Cannot print locations:\n \ + bytecode executable program file cannot be opened;\n \ + -- too many open files. Try running with OCAMLRUNPARAM=b=2)" +|] + let default_uncaught_exception_handler exn raw_backtrace = eprintf "Fatal error: exception %s\n" (to_string exn); print_raw_backtrace stderr raw_backtrace; + let status = get_debug_info_status () in + if status < 0 then + prerr_endline errors.(abs status); flush stderr let uncaught_exception_handler = ref default_uncaught_exception_handler let set_uncaught_exception_handler fn = uncaught_exception_handler := fn -let empty_backtrace : raw_backtrace = Obj.obj (Obj.new_block Obj.abstract_tag 0) +let empty_backtrace : raw_backtrace = [| |] let try_get_raw_backtrace () = try diff --git a/stdlib/printexc.mli b/stdlib/printexc.mli index 585c4a69..cfedc097 100644 --- a/stdlib/printexc.mli +++ b/stdlib/printexc.mli @@ -110,13 +110,13 @@ val use_printers: exn -> string option (** {1 Raw backtraces} *) type raw_backtrace -(** The abstract type [raw_backtrace] stores a backtrace in - a low-level format, instead of directly exposing them as string as - the [get_backtrace()] function does. +(** The type [raw_backtrace] stores a backtrace in a low-level format, + which can be converted to usable form using [raw_backtrace_entries] + and [backtrace_slots_of_raw_entry] below. - This allows delaying the formatting of backtraces to when they are - actually printed, which may be useful if you record more - backtraces than you print. + Converting backtraces to [backtrace_slot]s is slower than capturing the + backtraces. If an application processes many backtraces, it can be useful + to use [raw_backtrace] to avoid or delay conversion. Raw backtraces cannot be marshalled. If you need marshalling, you should use the array returned by the [backtrace_slots] function of @@ -125,6 +125,30 @@ type raw_backtrace @since 4.01.0 *) +type raw_backtrace_entry = private int +(** A [raw_backtrace_entry] is an element of a [raw_backtrace]. + + Each [raw_backtrace_entry] is an opaque integer, whose value is not stable + between different programs, or even between different runs of the same + binary. + + A [raw_backtrace_entry] can be converted to a usable form using + [backtrace_slots_of_raw_entry] below. Note that, due to inlining, a + single [raw_backtrace_entry] may convert to several [backtrace_slot]s. + Since the values of a [raw_backtrace_entry] are not stable, they cannot + be marshalled. If they are to be converted, the conversion must be done + by the process that generated them. + + Again due to inlining, there may be multiple distinct raw_backtrace_entry + values that convert to equal [backtrace_slot]s. However, if two + [raw_backtrace_entry]s are equal as integers, then they represent the same + [backtrace_slot]s. + + @since 4.12.0 *) + +val raw_backtrace_entries : raw_backtrace -> raw_backtrace_entry array +(** @since 4.12.0 *) + val get_raw_backtrace: unit -> raw_backtrace (** [Printexc.get_raw_backtrace ()] returns the same exception backtrace that [Printexc.print_backtrace] would print, but in @@ -224,6 +248,19 @@ val backtrace_slots : raw_backtrace -> backtrace_slot array option @since 4.02.0 *) +val backtrace_slots_of_raw_entry : + raw_backtrace_entry -> backtrace_slot array option +(** Returns the slots of a single raw backtrace entry, or [None] if this + entry lacks debug information. + + Slots are returned in the same order as [backtrace_slots]: the slot + at index [0] is the most recent call, raise, or primitive, and + subsequent slots represent callers. + + @since 4.12 +*) + + type location = { filename : string; line_number : int; @@ -296,17 +333,17 @@ end (** {1 Raw backtrace slots} *) type raw_backtrace_slot -(** This type allows direct access to raw backtrace slots, without any - conversion in an OCaml-usable data-structure. Being - process-specific, they must absolutely not be marshalled, and are - unsafe to use for this reason (marshalling them may not fail, but - un-marshalling and using the result will result in - undefined behavior). - - Elements of this type can still be compared and hashed: when two - elements are equal, then they represent the same source location - (the converse is not necessarily true in presence of inlining, - for example). +(** This type is used to iterate over the slots of a [raw_backtrace]. + For most purposes, [backtrace_slots_of_raw_entry] is easier to use. + + Like [raw_backtrace_entry], values of this type are process-specific and + must absolutely not be marshalled, and are unsafe to use for this reason + (marshalling them may not fail, but un-marshalling and using the result + will result in undefined behavior). + + Elements of this type can still be compared and hashed: when two elements + are equal, then they represent the same source location (the converse is not + necessarily true in presence of inlining, for example). @since 4.02.0 *) diff --git a/stdlib/queue.mli b/stdlib/queue.mli index 12c99f3f..0eaf1a50 100644 --- a/stdlib/queue.mli +++ b/stdlib/queue.mli @@ -22,7 +22,7 @@ Failure to do so can lead to a crash. *) -type 'a t +type !'a t (** The type of queues containing elements of type ['a]. *) diff --git a/stdlib/result.mli b/stdlib/result.mli index 96f85dc4..507e20f8 100644 --- a/stdlib/result.mli +++ b/stdlib/result.mli @@ -68,10 +68,10 @@ val iter_error : ('e -> unit) -> ('a, 'e) result -> unit (** {1:preds Predicates and comparisons} *) val is_ok : ('a, 'e) result -> bool -(** [is_ok r] is [true] iff [r] is [Ok _]. *) +(** [is_ok r] is [true] if and only if [r] is [Ok _]. *) val is_error : ('a, 'e) result -> bool -(** [is_error r] is [true] iff [r] is [Error _]. *) +(** [is_error r] is [true] if and only if [r] is [Error _]. *) val equal : ok:('a -> 'a -> bool) -> error:('e -> 'e -> bool) -> ('a, 'e) result -> diff --git a/stdlib/seq.mli b/stdlib/seq.mli index 8f730318..b1d1d51b 100644 --- a/stdlib/seq.mli +++ b/stdlib/seq.mli @@ -13,18 +13,16 @@ (* *) (**************************************************************************) -(* Module [Seq]: functional iterators *) +(** Functional iterators. -(** {1 Functional Iterators} *) + The type ['a Seq.t] is a {b delayed list}, i.e. a list where some + evaluation is needed to access the next element. This makes it possible + to build infinite sequences, to build sequences as we traverse them, and + to transform them in a lazy fashion rather than upfront. -(** The type ['a t] is a {b delayed list}, i.e. a list where some evaluation - is needed to access the next element. This makes it possible to build - infinite sequences, to build sequences as we traverse them, and to transform - them in a lazy fashion rather than upfront. + @since 4.07 *) -(** @since 4.07 *) - type 'a t = unit -> 'a node (** The type of delayed lists containing elements of type ['a]. Note that the concrete list node ['a node] is delayed under a closure, diff --git a/stdlib/set.ml b/stdlib/set.ml index d8b8a459..81065173 100644 --- a/stdlib/set.ml +++ b/stdlib/set.ml @@ -64,6 +64,7 @@ module type S = val of_list: elt list -> t val to_seq_from : elt -> t -> elt Seq.t val to_seq : t -> elt Seq.t + val to_rev_seq : t -> elt Seq.t val add_seq : elt Seq.t -> t -> t val of_seq : elt Seq.t -> t end @@ -594,6 +595,17 @@ module Make(Ord: OrderedType) = let to_seq c = seq_of_enum_ (cons_enum c End) + let rec snoc_enum s e = + match s with + Empty -> e + | Node{l; v; r} -> snoc_enum r (More(v, l, e)) + + let rec rev_seq_of_enum_ c () = match c with + | End -> Seq.Nil + | More (x, t, rest) -> Seq.Cons (x, rev_seq_of_enum_ (snoc_enum t rest)) + + let to_rev_seq c = rev_seq_of_enum_ (snoc_enum c End) + let to_seq_from low s = let rec aux low s c = match s with | Empty -> c diff --git a/stdlib/set.mli b/stdlib/set.mli index 91e39238..fcd1e38b 100644 --- a/stdlib/set.mli +++ b/stdlib/set.mli @@ -13,6 +13,9 @@ (* *) (**************************************************************************) +(* NOTE: If this file is set.mli, do not edit it directly! Instead, + edit templates/set.template.mli and run tools/sync_stdlib_docs *) + (** Sets over ordered types. This module implements the set data structure, given a total ordering @@ -58,7 +61,7 @@ module type OrderedType = Example: a suitable ordering function is the generic structural comparison function {!Stdlib.compare}. *) end -(** Input signature of the functor {!Set.Make}. *) +(** Input signature of the functor {!Make}. *) module type S = sig @@ -136,20 +139,20 @@ module type S = @since 4.04.0 *) val fold: (elt -> 'a -> 'a) -> t -> 'a -> 'a - (** [fold f s a] computes [(f xN ... (f x2 (f x1 a))...)], + (** [fold f s init] computes [(f xN ... (f x2 (f x1 init))...)], where [x1 ... xN] are the elements of [s], in increasing order. *) val for_all: (elt -> bool) -> t -> bool - (** [for_all p s] checks if all elements of the set - satisfy the predicate [p]. *) + (** [for_all f s] checks if all elements of the set + satisfy the predicate [f]. *) val exists: (elt -> bool) -> t -> bool - (** [exists p s] checks if at least one element of - the set satisfies the predicate [p]. *) + (** [exists f s] checks if at least one element of + the set satisfies the predicate [f]. *) val filter: (elt -> bool) -> t -> t - (** [filter p s] returns the set of all elements in [s] - that satisfy predicate [p]. If [p] satisfies every element in [s], + (** [filter f s] returns the set of all elements in [s] + that satisfy predicate [f]. If [f] satisfies every element in [s], [s] is returned unchanged (the result of the function is then physically equal to [s]). @before 4.03 Physical equality was not ensured.*) @@ -171,10 +174,10 @@ module type S = *) val partition: (elt -> bool) -> t -> t * t - (** [partition p s] returns a pair of sets [(s1, s2)], where + (** [partition f s] returns a pair of sets [(s1, s2)], where [s1] is the set of all the elements of [s] that satisfy the - predicate [p], and [s2] is the set of all the elements of - [s] that do not satisfy [p]. *) + predicate [f], and [s2] is the set of all the elements of + [s] that do not satisfy [f]. *) val cardinal: t -> int (** Return the number of elements of a set. *) @@ -183,7 +186,7 @@ module type S = (** Return the list of all elements of the given set. The returned list is sorted in increasing order with respect to the ordering [Ord.compare], where [Ord] is the argument - given to {!Set.Make}. *) + given to {!Make}. *) val min_elt: t -> elt (** Return the smallest element of the given set @@ -198,11 +201,11 @@ module type S = *) val max_elt: t -> elt - (** Same as {!Set.S.min_elt}, but returns the largest element of the + (** Same as {!S.min_elt}, but returns the largest element of the given set. *) val max_elt_opt: t -> elt option - (** Same as {!Set.S.min_elt_opt}, but returns the largest element of the + (** Same as {!S.min_elt_opt}, but returns the largest element of the given set. @since 4.05 *) @@ -254,9 +257,9 @@ module type S = *) val find_first_opt: (elt -> bool) -> t -> elt option - (** [find_first_opt f s], where [f] is a monotonically increasing function, - returns an option containing the lowest element [e] of [s] such that - [f e], or [None] if no such element exists. + (** [find_first_opt f s], where [f] is a monotonically increasing + function, returns an option containing the lowest element [e] of [s] + such that [f e], or [None] if no such element exists. @since 4.05 *) @@ -268,9 +271,9 @@ module type S = *) val find_last_opt: (elt -> bool) -> t -> elt option - (** [find_last_opt f s], where [f] is a monotonically decreasing function, - returns an option containing the highest element [e] of [s] such that - [f e], or [None] if no such element exists. + (** [find_last_opt f s], where [f] is a monotonically decreasing + function, returns an option containing the highest element [e] of [s] + such that [f e], or [None] if no such element exists. @since 4.05 *) @@ -291,6 +294,10 @@ module type S = (** Iterate on the whole set, in ascending order @since 4.07 *) + val to_rev_seq : t -> elt Seq.t + (** Iterate on the whole set, in descending order + @since 4.12 *) + val add_seq : elt Seq.t -> t -> t (** Add the given elements to the set, in order. @since 4.07 *) @@ -299,7 +306,7 @@ module type S = (** Build a set from the given bindings @since 4.07 *) end -(** Output signature of the functor {!Set.Make}. *) +(** Output signature of the functor {!Make}. *) module Make (Ord : OrderedType) : S with type elt = Ord.t (** Functor building an implementation of the set structure diff --git a/stdlib/spacetime.ml b/stdlib/spacetime.ml deleted file mode 100644 index 3e8abe1d..00000000 --- a/stdlib/spacetime.ml +++ /dev/null @@ -1,91 +0,0 @@ -(**************************************************************************) -(* *) -(* OCaml *) -(* *) -(* Mark Shinwell and Leo White, Jane Street Europe *) -(* *) -(* Copyright 2015--2016 Jane Street Group LLC *) -(* *) -(* All rights reserved. This file is distributed under the terms of *) -(* the GNU Lesser General Public License version 2.1, with the *) -(* special exception on linking described in the file LICENSE. *) -(* *) -(**************************************************************************) - -external spacetime_enabled : unit -> bool - = "caml_spacetime_enabled" [@@noalloc] - -let enabled = spacetime_enabled () - -let if_spacetime_enabled f = - if enabled then f () else () - -module Series = struct - type t = { - channel : out_channel; - mutable closed : bool; - } - - external write_magic_number : out_channel -> unit - = "caml_spacetime_only_works_for_native_code" - "caml_spacetime_write_magic_number" - - external register_channel_for_spacetime : out_channel -> unit - = "caml_register_channel_for_spacetime" - - let create ~path = - if spacetime_enabled () then begin - let channel = open_out path in - register_channel_for_spacetime channel; - let t = - { channel = channel; - closed = false; - } - in - write_magic_number t.channel; - t - end else begin - { channel = stdout; (* arbitrary value *) - closed = true; - } - end - - external save_event : ?time:float -> out_channel -> event_name:string -> unit - = "caml_spacetime_only_works_for_native_code" - "caml_spacetime_save_event" - - let save_event ?time t ~event_name = - if_spacetime_enabled (fun () -> - save_event ?time t.channel ~event_name) - - external save_trie : ?time:float -> out_channel -> unit - = "caml_spacetime_only_works_for_native_code" - "caml_spacetime_save_trie" - - let save_and_close ?time t = - if_spacetime_enabled (fun () -> - if t.closed then failwith "Series is closed"; - save_trie ?time t.channel; - close_out t.channel; - t.closed <- true) -end - -module Snapshot = struct - external take : ?time:float -> out_channel -> unit - = "caml_spacetime_only_works_for_native_code" - "caml_spacetime_take_snapshot" - - let take ?time { Series.closed; channel } = - if_spacetime_enabled (fun () -> - if closed then failwith "Series is closed"; - Gc.minor (); - take ?time channel) -end - -external save_event_for_automatic_snapshots : event_name:string -> unit - = "caml_spacetime_only_works_for_native_code" - "caml_spacetime_save_event_for_automatic_snapshots" - -let save_event_for_automatic_snapshots ~event_name = - if_spacetime_enabled (fun () -> - save_event_for_automatic_snapshots ~event_name) diff --git a/stdlib/spacetime.mli b/stdlib/spacetime.mli deleted file mode 100644 index 1f770905..00000000 --- a/stdlib/spacetime.mli +++ /dev/null @@ -1,99 +0,0 @@ -(**************************************************************************) -(* *) -(* OCaml *) -(* *) -(* Mark Shinwell and Leo White, Jane Street Europe *) -(* *) -(* Copyright 2015--2016 Jane Street Group LLC *) -(* *) -(* All rights reserved. This file is distributed under the terms of *) -(* the GNU Lesser General Public License version 2.1, with the *) -(* special exception on linking described in the file LICENSE. *) -(* *) -(**************************************************************************) - -(** Profiling of a program's space behaviour over time. - Currently only supported on x86-64 platforms running 64-bit code. - - To use the functions in this module you must: - - configure the compiler with "-spacetime"; - - compile to native code. - Without these conditions being satisfied the functions in this module - will have no effect. - - Instead of manually taking profiling heap snapshots with this module it is - possible to use an automatic snapshot facility that writes profiling - information at fixed intervals to a file. To enable this, all that needs to - be done is to build the relevant program using a compiler configured with - -spacetime; and set the environment variable OCAML_SPACETIME_INTERVAL to an - integer number of milliseconds giving the interval between profiling heap - snapshots. This interval should not be made excessively small relative to - the running time of the program. A typical interval to start with might be - 1/100 of the running time of the program. The program must exit "normally" - (i.e. by calling [exit], with whatever exit code, rather than being - abnormally terminated by a signal) so that the snapshot file is - correctly completed. - - When using the automatic snapshot mode the profiling output is written - to a file called "spacetime-" where is the process ID of the - program. (If the program forks and continues executing then multiple - files may be produced with different pid numbers.) The profiling output - is by default written to the current working directory when the program - starts. This may be customised by setting the OCAML_SPACETIME_SNAPSHOT_DIR - environment variable to the name of the desired directory. - - If using automatic snapshots the presence of the - [save_event_for_automatic_snapshots] function, below, should be noted. - - The functions in this module are thread safe. - - For functions to decode the information recorded by the profiler, - see the Spacetime offline library in otherlibs/. *) - -(** [enabled] is [true] if the compiler is configured with spacetime and [false] - otherwise *) -val enabled : bool - -module Series : sig - (** Type representing a file that will hold a series of heap snapshots - together with additional information required to interpret those - snapshots. *) - type t - - (** [create ~path] creates a series file at [path]. *) - val create : path:string -> t - - (** [save_event] writes an event, which is an arbitrary string, into the - given series file. This may be used for identifying particular points - during program execution when analysing the profile. - The optional [time] parameter is as for {!Snapshot.take}. - *) - val save_event : ?time:float -> t -> event_name:string -> unit - - (** [save_and_close series] writes information into [series] required for - interpreting the snapshots that [series] contains and then closes the - [series] file. This function must be called to produce a valid series - file. - The optional [time] parameter is as for {!Snapshot.take}. - *) - val save_and_close : ?time:float -> t -> unit -end - -module Snapshot : sig - (** [take series] takes a snapshot of the profiling annotations on the values - in the minor and major heaps, together with GC stats, and write the - result to the [series] file. This function triggers a minor GC but does - not allocate any memory itself. - If the optional [time] is specified, it will be used instead of the - result of {!Sys.time} as the timestamp of the snapshot. Such [time]s - should start from zero and be monotonically increasing. This parameter - is intended to be used so that snapshots can be correlated against wall - clock time (which is not supported in the standard library) rather than - elapsed CPU time. - *) - val take : ?time:float -> Series.t -> unit -end - -(** Like {!Series.save_event}, but writes to the automatic snapshot file. - This function is a no-op if OCAML_SPACETIME_INTERVAL was not set. *) -val save_event_for_automatic_snapshots : event_name:string -> unit diff --git a/stdlib/stack.mli b/stdlib/stack.mli index 26ea3cc6..b2d19cdc 100644 --- a/stdlib/stack.mli +++ b/stdlib/stack.mli @@ -18,7 +18,7 @@ This module implements stacks (LIFOs), with in-place modification. *) -type 'a t +type !'a t (** The type of stacks containing elements of type ['a]. *) exception Empty diff --git a/stdlib/stdLabels.mli b/stdlib/stdLabels.mli index 4b24fd2b..6faba339 100644 --- a/stdlib/stdLabels.mli +++ b/stdlib/stdLabels.mli @@ -15,12 +15,19 @@ (** Standard labeled libraries. - This meta-module provides labelized version of the {!Array}, - {!Bytes}, {!List} and {!String} modules. + This meta-module provides versions of the {!Array}, {!Bytes}, + {!List} and {!String} modules where function arguments are + systematically labeled. It is intended to be opened at the top of + source files, as shown below. + + {[ + open StdLabels + + let to_upper = String.map ~f:Char.uppercase_ascii + let seq len = List.init ~f:(function i -> i) ~len + let everything = Array.create_matrix ~dimx:42 ~dimy:42 42 + ]} - They only differ by their labels. Detailed interfaces can be found - in [arrayLabels.mli], [bytesLabels.mli], [listLabels.mli] - and [stringLabels.mli]. *) module Array = ArrayLabels diff --git a/stdlib/stdlib.ml b/stdlib/stdlib.ml index 5cef512c..5daaf086 100644 --- a/stdlib/stdlib.ml +++ b/stdlib/stdlib.ml @@ -55,6 +55,7 @@ external __FILE__ : string = "%loc_FILE" external __LINE__ : int = "%loc_LINE" external __MODULE__ : string = "%loc_MODULE" external __POS__ : string * int * int * int = "%loc_POS" +external __FUNCTION__ : string = "%loc_FUNCTION" external __LOC_OF__ : 'a -> string * 'a = "%loc_LOC" external __LINE_OF__ : 'a -> int * 'a = "%loc_LINE" @@ -542,18 +543,21 @@ let ( ^^ ) (Format (fmt1, str1)) (Format (fmt2, str2)) = external sys_exit : int -> 'a = "caml_sys_exit" -let exit_function = ref flush_all +let exit_function = CamlinternalAtomic.make flush_all -let at_exit f = - let g = !exit_function in +let rec at_exit f = + let module Atomic = CamlinternalAtomic in (* MPR#7253, MPR#7796: make sure "f" is executed only once *) - let f_already_ran = ref false in - exit_function := - (fun () -> - if not !f_already_ran then begin f_already_ran := true; f() end; - g()) + let f_yet_to_run = Atomic.make true in + let old_exit = Atomic.get exit_function in + let new_exit () = + if Atomic.compare_and_set f_yet_to_run true false then f () ; + old_exit () + in + let success = Atomic.compare_and_set exit_function old_exit new_exit in + if not success then at_exit f -let do_at_exit () = (!exit_function) () +let do_at_exit () = (CamlinternalAtomic.get exit_function) () let exit retcode = do_at_exit (); @@ -561,10 +565,16 @@ let exit retcode = let _ = register_named_value "Pervasives.do_at_exit" do_at_exit +external major : unit -> unit = "caml_gc_major" +external naked_pointers_checked : unit -> bool + = "caml_sys_const_naked_pointers_checked" +let () = if naked_pointers_checked () then at_exit major + (*MODULE_ALIASES*) module Arg = Arg module Array = Array module ArrayLabels = ArrayLabels +module Atomic = Atomic module Bigarray = Bigarray module Bool = Bool module Buffer = Buffer @@ -574,6 +584,7 @@ module Callback = Callback module Char = Char module Complex = Complex module Digest = Digest +module Either = Either module Ephemeron = Ephemeron module Filename = Filename module Float = Float @@ -606,7 +617,6 @@ module Result = Result module Scanf = Scanf module Seq = Seq module Set = Set -module Spacetime = Spacetime module Stack = Stack module StdLabels = StdLabels module Stream = Stream diff --git a/stdlib/stdlib.mli b/stdlib/stdlib.mli index c16acb51..28c1381e 100644 --- a/stdlib/stdlib.mli +++ b/stdlib/stdlib.mli @@ -273,6 +273,12 @@ external __POS__ : string * int * int * int = "%loc_POS" @since 4.02.0 *) +external __FUNCTION__ : string = "%loc_FUNCTION" +(** [__FUNCTION__] returns the name of the current function or method, including + any enclosing modules or classes. + + @since 4.12.0 *) + external __LOC_OF__ : 'a -> string * 'a = "%loc_LOC" (** [__LOC_OF__ expr] returns a pair [(loc, expr)] where [loc] is the location of [expr] in the file currently being parsed by the @@ -438,8 +444,8 @@ external ( asr ) : int -> int -> int = "%asrint" [neg_infinity] for [-1.0 /. 0.0], and [nan] ('not a number') for [0.0 /. 0.0]. These special numbers then propagate through floating-point computations as expected: for instance, - [1.0 /. infinity] is [0.0], and any arithmetic operation with [nan] - as argument returns [nan] as result. + [1.0 /. infinity] is [0.0], basic arithmetic operations + ([+.], [-.], [*.], [/.]) with [nan] as an argument return [nan], ... *) external ( ~-. ) : float -> float = "%negfloat" @@ -992,7 +998,13 @@ val seek_out : out_channel -> int -> unit val pos_out : out_channel -> int (** Return the current writing position for the given channel. Does not work on channels opened with the [Open_append] flag (returns - unspecified results). *) + unspecified results). + For files opened in text mode under Windows, the returned position + is approximate (owing to end-of-line conversion); in particular, + saving the current position with [pos_out], then going back to + this position using [seek_out] will not work. For this + programming idiom to work reliably and portably, the file must be + opened in binary mode. *) val out_channel_length : out_channel -> int (** Return the size (number of characters) of the regular file @@ -1107,7 +1119,13 @@ val seek_in : in_channel -> int -> unit files of other kinds, the behavior is unspecified. *) val pos_in : in_channel -> int -(** Return the current reading position for the given channel. *) +(** Return the current reading position for the given channel. For + files opened in text mode under Windows, the returned position is + approximate (owing to end-of-line conversion); in particular, + saving the current position with [pos_in], then going back to this + position using [seek_in] will not work. For this programming + idiom to work reliably and portably, the file must be opened in + binary mode. *) val in_channel_length : in_channel -> int (** Return the size (number of characters) of the regular file @@ -1331,6 +1349,7 @@ val do_at_exit : unit -> unit module Arg = Arg module Array = Array module ArrayLabels = ArrayLabels +module Atomic = Atomic module Bigarray = Bigarray module Bool = Bool module Buffer = Buffer @@ -1340,6 +1359,7 @@ module Callback = Callback module Char = Char module Complex = Complex module Digest = Digest +module Either = Either module Ephemeron = Ephemeron module Filename = Filename module Float = Float @@ -1376,7 +1396,6 @@ module Result = Result module Scanf = Scanf module Seq = Seq module Set = Set -module Spacetime = Spacetime module Stack = Stack module StdLabels = StdLabels module Stream = Stream diff --git a/stdlib/stream.mli b/stdlib/stream.mli index 93c2c315..ea7d293a 100644 --- a/stdlib/stream.mli +++ b/stdlib/stream.mli @@ -15,7 +15,7 @@ (** Streams and parsers. *) -type 'a t +type !'a t (** The type of streams holding values of type ['a]. *) exception Failure diff --git a/stdlib/string.ml b/stdlib/string.ml index 12a627f3..f22f246d 100644 --- a/stdlib/string.ml +++ b/stdlib/string.ml @@ -197,11 +197,6 @@ let capitalize_ascii s = let uncapitalize_ascii s = B.uncapitalize_ascii (bos s) |> bts -type t = string - -let compare (x: t) (y: t) = Stdlib.compare x y -external equal : string -> string -> bool = "caml_string_equal" [@@noalloc] - let split_on_char sep s = let r = ref [] in let j = ref (length s) in @@ -224,6 +219,11 @@ let capitalize s = let uncapitalize s = B.uncapitalize (bos s) |> bts +type t = string + +let compare (x: t) (y: t) = Stdlib.compare x y +external equal : string -> string -> bool = "caml_string_equal" [@@noalloc] + (** {1 Iterators} *) let to_seq s = bos s |> B.to_seq diff --git a/stdlib/string.mli b/stdlib/string.mli index 82dda271..d1b0b847 100644 --- a/stdlib/string.mli +++ b/stdlib/string.mli @@ -13,323 +13,378 @@ (* *) (**************************************************************************) -(** String operations. - - A string is an immutable data structure that contains a - fixed-length sequence of (single-byte) characters. Each character - can be accessed in constant time through its index. - - Given a string [s] of length [l], we can access each of the [l] - characters of [s] via its index in the sequence. Indexes start at - [0], and we will call an index valid in [s] if it falls within the - range [[0...l-1]] (inclusive). A position is the point between two - characters or at the beginning or end of the string. We call a - position valid in [s] if it falls within the range [[0...l]] - (inclusive). Note that the character at index [n] is between - positions [n] and [n+1]. - - Two parameters [start] and [len] are said to designate a valid - substring of [s] if [len >= 0] and [start] and [start+len] are - valid positions in [s]. - - Note: OCaml strings used to be modifiable in place, for instance via - the {!String.set} and {!String.blit} functions described below. This - usage is only possible when the compiler is put in "unsafe-string" - mode by giving the [-unsafe-string] command-line option. This - compatibility mode makes the types [string] and [bytes] (see module - {!Bytes}) interchangeable so that functions expecting byte sequences - can also accept strings as arguments and modify them. - - The distinction between [bytes] and [string] was introduced in OCaml - 4.02, and the "unsafe-string" compatibility mode was the default - until OCaml 4.05. Starting with 4.06, the compatibility mode is - opt-in; we intend to remove the option in the future. +(* NOTE: + If this file is stringLabels.mli, run tools/sync_stdlib_docs after editing + it to generate string.mli. + + If this file is string.mli, do not edit it directly -- edit + stringLabels.mli instead. + *) + +(** Strings. + + A string [s] of length [n] is an indexable and immutable sequence + of [n] bytes. For historical reasons these bytes are referred to + as characters. + + The semantics of string functions is defined in terms of + indices and positions. These are depicted and described + as follows. + +{v +positions 0 1 2 3 4 n-1 n + +---+---+---+---+ +-----+ + indices | 0 | 1 | 2 | 3 | ... | n-1 | + +---+---+---+---+ +-----+ +v} + {ul + {- An {e index} [i] of [s] is an integer in the range \[[0];[n-1]\]. + It represents the [i]th byte (character) of [s] which can be + accessed using the constant time string indexing operator + [s.[i]].} + {- A {e position} [i] of [s] is an integer in the range + \[[0];[n]\]. It represents either the point at the beginning of + the string, or the point between two indices, or the point at + the end of the string. The [i]th byte index is between position + [i] and [i+1].}} + + Two integers [start] and [len] are said to define a {e valid + substring} of [s] if [len >= 0] and [start], [start+len] are + positions of [s]. + + {b Unicode text.} Strings being arbitrary sequences of bytes, they + can hold any kind of textual encoding. However the recommended + encoding for storing Unicode text in OCaml strings is UTF-8. This + is the encoding used by Unicode escapes in string literals. For + example the string ["\u{1F42B}"] is the UTF-8 encoding of the + Unicode character U+1F42B. + + {b Past mutability.} OCaml strings used to be modifiable in place, + for instance via the {!String.set} and {!String.blit} + functions. This use is nowadays only possible when the compiler is + put in "unsafe-string" mode by giving the [-unsafe-string] + command-line option. This compatibility mode makes the types + [string] and [bytes] (see {!Bytes.t}) interchangeable so that + functions expecting byte sequences can also accept strings as + arguments and modify them. + + The distinction between [bytes] and [string] was introduced in + OCaml 4.02, and the "unsafe-string" compatibility mode was the + default until OCaml 4.05. Starting with 4.06, the compatibility + mode is opt-in; we intend to remove the option in the future. + + The labeled version of this module can be used as described in the + {!StdLabels} module. *) +(** {1:strings Strings} *) + +type t = string +(** The type for strings. *) + +val make : int -> char -> string +(** [make n c] is a string of length [n] with each index holding the + character [c]. + + @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. *) + +val init : int -> (int -> char) -> string +(** [init n f] is a string of length [n] with index + [i] holding the character [f i] (called in increasing index order). + + @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. + @since 4.02.0 *) + external length : string -> int = "%string_length" -(** Return the length (number of characters) of the given string. *) +(** [length s] is the length (number of bytes/characters) of [s]. *) external get : string -> int -> char = "%string_safe_get" -(** [String.get s n] returns the character at index [n] in string [s]. - You can also write [s.[n]] instead of [String.get s n]. - @raise Invalid_argument if [n] not a valid index in [s]. *) +(** [get s i] is the character at index [i] in [s]. This is the same + as writing [s.[i]]. + @raise Invalid_argument if [i] not an index of [s]. *) -external set : bytes -> int -> char -> unit = "%string_safe_set" - [@@ocaml.deprecated "Use Bytes.set instead."] -(** [String.set s n c] modifies byte sequence [s] in place, - replacing the byte at index [n] with [c]. - You can also write [s.[n] <- c] instead of [String.set s n c]. - @raise Invalid_argument if [n] is not a valid index in [s]. +(** {1:concat Concatenating} - @deprecated This is a deprecated alias of {!Bytes.set}.[ ] *) + {b Note.} The {!Stdlib.( ^ )} binary operator concatenates two + strings. *) -external create : int -> bytes = "caml_create_string" - [@@ocaml.deprecated "Use Bytes.create instead."] -(** [String.create n] returns a fresh byte sequence of length [n]. - The sequence is uninitialized and contains arbitrary bytes. - @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. +val concat : string -> string list -> string +(** [concat sep ss] concatenates the list of strings [ss], inserting + the separator string [sep] between each. - @deprecated This is a deprecated alias of {!Bytes.create}.[ ] *) + @raise Invalid_argument if the result is longer than + {!Sys.max_string_length} bytes. *) -val make : int -> char -> string -(** [String.make n c] returns a fresh string of length [n], - filled with the character [c]. - @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. *) +(** {1:predicates Predicates and comparisons} *) -val init : int -> (int -> char) -> string -(** [String.init n f] returns a string of length [n], with character - [i] initialized to the result of [f i] (called in increasing - index order). +val equal : t -> t -> bool +(** [equal s0 s1] is [true] if and only if [s0] and [s1] are character-wise + equal. + @since 4.03.0 (4.05.0 in StringLabels) *) - @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. - @since 4.02.0 -*) +val compare : t -> t -> int +(** [compare s0 s1] sorts [s0] and [s1] in lexicographical order. [compare] + behaves like {!Stdlib.compare} on strings but may be more efficient. *) -val copy : string -> string [@@ocaml.deprecated] -(** Return a copy of the given string. +val contains_from : string -> int -> char -> bool +(** [contains_from s start c] is [true] if and only if [c] appears in [s] + after position [start]. - @deprecated Because strings are immutable, it doesn't make much - sense to make identical copies of them. *) + @raise Invalid_argument if [start] is not a valid position in [s]. *) -val sub : string -> int -> int -> string -(** [String.sub s start len] returns a fresh string of length [len], - containing the substring of [s] that starts at position [start] and - has length [len]. - @raise Invalid_argument if [start] and [len] do not - designate a valid substring of [s]. *) +val rcontains_from : string -> int -> char -> bool +(** [rcontains_from s stop c] is [true] if and only if [c] appears in [s] + before position [stop+1]. -val fill : bytes -> int -> int -> char -> unit - [@@ocaml.deprecated "Use Bytes.fill instead."] -(** [String.fill s start len c] modifies byte sequence [s] in place, - replacing [len] bytes with [c], starting at [start]. - @raise Invalid_argument if [start] and [len] do not - designate a valid range of [s]. + @raise Invalid_argument if [stop < 0] or [stop+1] is not a valid + position in [s]. *) - @deprecated This is a deprecated alias of {!Bytes.fill}.[ ] *) +val contains : string -> char -> bool +(** [contains s c] is {!String.contains_from}[ s 0 c]. *) -val blit : string -> int -> bytes -> int -> int -> unit -(** Same as {!Bytes.blit_string}. *) +(** {1:extract Extracting substrings} *) -val concat : string -> string list -> string -(** [String.concat sep sl] concatenates the list of strings [sl], - inserting the separator string [sep] between each. - @raise Invalid_argument if the result is longer than - {!Sys.max_string_length} bytes. *) +val sub : string -> int -> int -> string +(** [sub s pos len] is a string of length [len], containing the + substring of [s] that starts at position [pos] and has length + [len]. -val iter : (char -> unit) -> string -> unit -(** [String.iter f s] applies function [f] in turn to all - the characters of [s]. It is equivalent to - [f s.[0]; f s.[1]; ...; f s.[String.length s - 1]; ()]. *) + @raise Invalid_argument if [pos] and [len] do not designate a valid + substring of [s]. *) -val iteri : (int -> char -> unit) -> string -> unit -(** Same as {!String.iter}, but the - function is applied to the index of the element as first argument - (counting from 0), and the character itself as second argument. - @since 4.00.0 *) +val split_on_char : char -> string -> string list +(** [split_on_char sep s] is the list of all (possibly empty) + substrings of [s] that are delimited by the character [sep]. + + The function's result is specified by the following invariants: + {ul + {- The list is not empty.} + {- Concatenating its elements using [sep] as a separator returns a + string equal to the input ([concat (make 1 sep) + (split_on_char sep s) = s]).} + {- No string in the result contains the [sep] character.}} + + @since 4.04.0 (4.05.0 in StringLabels) *) + +(** {1:transforming Transforming} *) val map : (char -> char) -> string -> string -(** [String.map f s] applies function [f] in turn to all the - characters of [s] (in increasing index order) and stores the - results in a new string that is returned. +(** [map f s] is the string resulting from applying [f] to all the + characters of [s] in increasing order. + @since 4.00.0 *) val mapi : (int -> char -> char) -> string -> string -(** [String.mapi f s] calls [f] with each character of [s] and its - index (in increasing index order) and stores the results in a new - string that is returned. +(** [mapi f s] is like {!map} but the index of the character is also + passed to [f]. + @since 4.02.0 *) val trim : string -> string -(** Return a copy of the argument, without leading and trailing - whitespace. The characters regarded as whitespace are: [' '], - ['\012'], ['\n'], ['\r'], and ['\t']. If there is neither leading nor - trailing whitespace character in the argument, return the original - string itself, not a copy. - @since 4.00.0 *) +(** [trim s] is [s] without leading and trailing whitespace. Whitespace + characters are: [' '], ['\x0C'] (form feed), ['\n'], ['\r'], and ['\t']. + + @since 4.00.0 *) val escaped : string -> string -(** Return a copy of the argument, with special characters - represented by escape sequences, following the lexical - conventions of OCaml. - All characters outside the ASCII printable range (32..126) are - escaped, as well as backslash and double-quote. - - If there is no special character in the argument that needs - escaping, return the original string itself, not a copy. - @raise Invalid_argument if the result is longer than - {!Sys.max_string_length} bytes. +(** [escaped s] is [s] with special characters represented by escape + sequences, following the lexical conventions of OCaml. + + All characters outside the US-ASCII printable range \[0x20;0x7E\] are + escaped, as well as backslash (0x2F) and double-quote (0x22). The function {!Scanf.unescaped} is a left inverse of [escaped], i.e. [Scanf.unescaped (escaped s) = s] for any string [s] (unless - [escape s] fails). *) + [escaped s] fails). -val index : string -> char -> int -(** [String.index s c] returns the index of the first - occurrence of character [c] in string [s]. - @raise Not_found if [c] does not occur in [s]. *) - -val index_opt: string -> char -> int option -(** [String.index_opt s c] returns the index of the first - occurrence of character [c] in string [s], or - [None] if [c] does not occur in [s]. - @since 4.05 *) + @raise Invalid_argument if the result is longer than + {!Sys.max_string_length} bytes. *) -val rindex : string -> char -> int -(** [String.rindex s c] returns the index of the last - occurrence of character [c] in string [s]. - @raise Not_found if [c] does not occur in [s]. *) - -val rindex_opt: string -> char -> int option -(** [String.rindex_opt s c] returns the index of the last occurrence - of character [c] in string [s], or [None] if [c] does not occur in - [s]. - @since 4.05 *) +val uppercase_ascii : string -> string +(** [uppercase_ascii s] is [s] with all lowercase letters + translated to uppercase, using the US-ASCII character set. -val index_from : string -> int -> char -> int -(** [String.index_from s i c] returns the index of the - first occurrence of character [c] in string [s] after position [i]. - [String.index s c] is equivalent to [String.index_from s 0 c]. - @raise Invalid_argument if [i] is not a valid position in [s]. - @raise Not_found if [c] does not occur in [s] after position [i]. *) - -val index_from_opt: string -> int -> char -> int option -(** [String.index_from_opt s i c] returns the index of the - first occurrence of character [c] in string [s] after position [i] - or [None] if [c] does not occur in [s] after position [i]. - - [String.index_opt s c] is equivalent to [String.index_from_opt s 0 c]. - @raise Invalid_argument if [i] is not a valid position in [s]. + @since 4.03.0 (4.05.0 in StringLabels) *) - @since 4.05 -*) +val lowercase_ascii : string -> string +(** [lowercase_ascii s] is [s] with all uppercase letters translated + to lowercase, using the US-ASCII character set. -val rindex_from : string -> int -> char -> int -(** [String.rindex_from s i c] returns the index of the - last occurrence of character [c] in string [s] before position [i+1]. - [String.rindex s c] is equivalent to - [String.rindex_from s (String.length s - 1) c]. - @raise Invalid_argument if [i+1] is not a valid position in [s]. - @raise Not_found if [c] does not occur in [s] before position [i+1]. *) - -val rindex_from_opt: string -> int -> char -> int option -(** [String.rindex_from_opt s i c] returns the index of the - last occurrence of character [c] in string [s] before position [i+1] - or [None] if [c] does not occur in [s] before position [i+1]. - - [String.rindex_opt s c] is equivalent to - [String.rindex_from_opt s (String.length s - 1) c]. - @raise Invalid_argument if [i+1] is not a valid position in [s]. - - @since 4.05 -*) + @since 4.03.0 (4.05.0 in StringLabels) *) -val contains : string -> char -> bool -(** [String.contains s c] tests if character [c] - appears in the string [s]. *) +val capitalize_ascii : string -> string +(** [capitalize_ascii s] is [s] with the first character set to + uppercase, using the US-ASCII character set. -val contains_from : string -> int -> char -> bool -(** [String.contains_from s start c] tests if character [c] - appears in [s] after position [start]. - [String.contains s c] is equivalent to - [String.contains_from s 0 c]. - @raise Invalid_argument if [start] is not a valid position in [s]. *) + @since 4.03.0 (4.05.0 in StringLabels) *) -val rcontains_from : string -> int -> char -> bool -(** [String.rcontains_from s stop c] tests if character [c] - appears in [s] before position [stop+1]. - @raise Invalid_argument if [stop < 0] or [stop+1] is not a valid - position in [s]. *) +val uncapitalize_ascii : string -> string +(** [uncapitalize_ascii s] is [s] with the first character set to lowercase, + using the US-ASCII character set. -val uppercase : string -> string - [@@ocaml.deprecated "Use String.uppercase_ascii instead."] -(** Return a copy of the argument, with all lowercase letters - translated to uppercase, including accented letters of the ISO - Latin-1 (8859-1) character set. - @deprecated Functions operating on Latin-1 character set are deprecated. *) + @since 4.03.0 (4.05.0 in StringLabels) *) -val lowercase : string -> string - [@@ocaml.deprecated "Use String.lowercase_ascii instead."] -(** Return a copy of the argument, with all uppercase letters - translated to lowercase, including accented letters of the ISO - Latin-1 (8859-1) character set. - @deprecated Functions operating on Latin-1 character set are deprecated. *) +(** {1:traversing Traversing} *) -val capitalize : string -> string - [@@ocaml.deprecated "Use String.capitalize_ascii instead."] -(** Return a copy of the argument, with the first character set to uppercase, - using the ISO Latin-1 (8859-1) character set.. - @deprecated Functions operating on Latin-1 character set are deprecated. *) +val iter : (char -> unit) -> string -> unit +(** [iter f s] applies function [f] in turn to all the characters of [s]. + It is equivalent to [f s.[0]; f s.[1]; ...; f s.[length s - 1]; ()]. *) -val uncapitalize : string -> string - [@@ocaml.deprecated "Use String.uncapitalize_ascii instead."] -(** Return a copy of the argument, with the first character set to lowercase, - using the ISO Latin-1 (8859-1) character set.. - @deprecated Functions operating on Latin-1 character set are deprecated. *) +val iteri : (int -> char -> unit) -> string -> unit +(** [iteri] is like {!iter}, but the function is also given the + corresponding character index. -val uppercase_ascii : string -> string -(** Return a copy of the argument, with all lowercase letters - translated to uppercase, using the US-ASCII character set. - @since 4.03.0 *) + @since 4.00.0 *) -val lowercase_ascii : string -> string -(** Return a copy of the argument, with all uppercase letters - translated to lowercase, using the US-ASCII character set. - @since 4.03.0 *) +(** {1:searching Searching} *) -val capitalize_ascii : string -> string -(** Return a copy of the argument, with the first character set to uppercase, - using the US-ASCII character set. - @since 4.03.0 *) +val index_from : string -> int -> char -> int +(** [index_from s i c] is the index of the first occurrence of [c] in + [s] after position [i]. -val uncapitalize_ascii : string -> string -(** Return a copy of the argument, with the first character set to lowercase, - using the US-ASCII character set. - @since 4.03.0 *) + @raise Not_found if [c] does not occur in [s] after position [i]. + @raise Invalid_argument if [i] is not a valid position in [s]. *) -type t = string -(** An alias for the type of strings. *) -val compare: t -> t -> int -(** The comparison function for strings, with the same specification as - {!Stdlib.compare}. Along with the type [t], this function [compare] - allows the module [String] to be passed as argument to the functors - {!Set.Make} and {!Map.Make}. *) +val index_from_opt : string -> int -> char -> int option +(** [index_from_opt s i c] is the index of the first occurrence of [c] + in [s] after position [i] (if any). + + @raise Invalid_argument if [i] is not a valid position in [s]. + @since 4.05 *) + +val rindex_from : string -> int -> char -> int +(** [rindex_from s i c] is the index of the last occurrence of [c] in + [s] before position [i+1]. -val equal: t -> t -> bool -(** The equal function for strings. - @since 4.03.0 *) + @raise Not_found if [c] does not occur in [s] before position [i+1]. + @raise Invalid_argument if [i+1] is not a valid position in [s]. *) -val split_on_char: char -> string -> string list -(** [String.split_on_char sep s] returns the list of all (possibly empty) - substrings of [s] that are delimited by the [sep] character. +val rindex_from_opt : string -> int -> char -> int option +(** [rindex_from_opt s i c] is the index of the last occurrence of [c] + in [s] before position [i+1] (if any). - The function's output is specified by the following invariants: + @raise Invalid_argument if [i+1] is not a valid position in [s]. + @since 4.05 *) - - The list is not empty. - - Concatenating its elements using [sep] as a separator returns a - string equal to the input ([String.concat (String.make 1 sep) - (String.split_on_char sep s) = s]). - - No string in the result contains the [sep] character. +val index : string -> char -> int +(** [index s c] is {!String.index_from}[ s 0 c]. *) - @since 4.04.0 -*) +val index_opt : string -> char -> int option +(** [index_opt s c] is {!String.index_from_opt}[ s 0 c]. + + @since 4.05 *) + +val rindex : string -> char -> int +(** [rindex s c] is {!String.rindex_from}[ s (length s - 1) c]. *) -(** {1 Iterators} *) +val rindex_opt : string -> char -> int option +(** [rindex_opt s c] is {!String.rindex_from_opt}[ s (length s - 1) c]. + + @since 4.05 *) + +(** {1:converting Converting} *) val to_seq : t -> char Seq.t -(** Iterate on the string, in increasing index order. Modifications of the - string during iteration will be reflected in the iterator. +(** [to_seq s] is a sequence made of the string's characters in + increasing order. In ["unsafe-string"] mode, modifications of the string + during iteration will be reflected in the iterator. + @since 4.07 *) val to_seqi : t -> (int * char) Seq.t -(** Iterate on the string, in increasing order, yielding indices along chars +(** [to_seqi s] is like {!to_seq} but also tuples the corresponding index. + @since 4.07 *) val of_seq : char Seq.t -> t -(** Create a string from the generator +(** [of_seq s] is a string made of the sequence's characters. + @since 4.07 *) +(** {1:deprecated Deprecated functions} *) + +external create : int -> bytes = "caml_create_string" + [@@ocaml.deprecated "Use Bytes.create/BytesLabels.create instead."] +(** [create n] returns a fresh byte sequence of length [n]. + The sequence is uninitialized and contains arbitrary bytes. + @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. + + @deprecated This is a deprecated alias of + {!Bytes.create}/{!BytesLabels.create}. *) + +external set : bytes -> int -> char -> unit = "%string_safe_set" + [@@ocaml.deprecated "Use Bytes.set/BytesLabels.set instead."] +(** [set s n c] modifies byte sequence [s] in place, + replacing the byte at index [n] with [c]. + You can also write [s.[n] <- c] instead of [set s n c]. + @raise Invalid_argument if [n] is not a valid index in [s]. + + @deprecated This is a deprecated alias of + {!Bytes.set}/{!BytesLabels.set}. *) + +val blit : + string -> int -> bytes -> int -> int -> unit +(** [blit src src_pos dst dst_pos len] copies [len] bytes + from the string [src], starting at index [src_pos], + to byte sequence [dst], starting at character number [dst_pos]. + + @raise Invalid_argument if [src_pos] and [len] do not + designate a valid range of [src], or if [dst_pos] and [len] + do not designate a valid range of [dst]. *) + +val copy : string -> string + [@@ocaml.deprecated "Strings now immutable: no need to copy"] +(** Return a copy of the given string. + + @deprecated Because strings are immutable, it doesn't make much + sense to make identical copies of them. *) + +val fill : bytes -> int -> int -> char -> unit + [@@ocaml.deprecated "Use Bytes.fill/BytesLabels.fill instead."] +(** [fill s pos len c] modifies byte sequence [s] in place, + replacing [len] bytes by [c], starting at [pos]. + @raise Invalid_argument if [pos] and [len] do not + designate a valid substring of [s]. + + @deprecated This is a deprecated alias of + {!Bytes.fill}/{!BytesLabels.fill}. *) + +val uppercase : string -> string + [@@ocaml.deprecated + "Use String.uppercase_ascii/StringLabels.uppercase_ascii instead."] +(** Return a copy of the argument, with all lowercase letters + translated to uppercase, including accented letters of the ISO + Latin-1 (8859-1) character set. + + @deprecated Functions operating on Latin-1 character set are deprecated. *) + +val lowercase : string -> string + [@@ocaml.deprecated + "Use String.lowercase_ascii/StringLabels.lowercase_ascii instead."] +(** Return a copy of the argument, with all uppercase letters + translated to lowercase, including accented letters of the ISO + Latin-1 (8859-1) character set. + + @deprecated Functions operating on Latin-1 character set are deprecated. *) + +val capitalize : string -> string + [@@ocaml.deprecated + "Use String.capitalize_ascii/StringLabels.capitalize_ascii instead."] +(** Return a copy of the argument, with the first character set to uppercase, + using the ISO Latin-1 (8859-1) character set.. + + @deprecated Functions operating on Latin-1 character set are deprecated. *) + +val uncapitalize : string -> string + [@@ocaml.deprecated + "Use String.uncapitalize_ascii/StringLabels.uncapitalize_ascii instead."] +(** Return a copy of the argument, with the first character set to lowercase, + using the ISO Latin-1 (8859-1) character set. + + @deprecated Functions operating on Latin-1 character set are deprecated. *) + (**/**) (* The following is for system use only. Do not call directly. *) @@ -338,8 +393,8 @@ external unsafe_get : string -> int -> char = "%string_unsafe_get" external unsafe_set : bytes -> int -> char -> unit = "%string_unsafe_set" [@@ocaml.deprecated] external unsafe_blit : - string -> int -> bytes -> int -> int -> unit - = "caml_blit_string" [@@noalloc] + string -> int -> bytes -> int -> int -> + unit = "caml_blit_string" [@@noalloc] external unsafe_fill : bytes -> int -> int -> char -> unit = "caml_fill_string" [@@noalloc] [@@ocaml.deprecated] diff --git a/stdlib/stringLabels.mli b/stdlib/stringLabels.mli index ca4289df..77d732c3 100644 --- a/stdlib/stringLabels.mli +++ b/stdlib/stringLabels.mli @@ -13,290 +13,378 @@ (* *) (**************************************************************************) -(** String operations. - This module is intended to be used through {!StdLabels} which replaces - {!Array}, {!Bytes}, {!List} and {!String} with their labeled counterparts +(* NOTE: + If this file is stringLabels.mli, run tools/sync_stdlib_docs after editing + it to generate string.mli. + + If this file is string.mli, do not edit it directly -- edit + stringLabels.mli instead. + *) + +(** Strings. + + A string [s] of length [n] is an indexable and immutable sequence + of [n] bytes. For historical reasons these bytes are referred to + as characters. + + The semantics of string functions is defined in terms of + indices and positions. These are depicted and described + as follows. + +{v +positions 0 1 2 3 4 n-1 n + +---+---+---+---+ +-----+ + indices | 0 | 1 | 2 | 3 | ... | n-1 | + +---+---+---+---+ +-----+ +v} + {ul + {- An {e index} [i] of [s] is an integer in the range \[[0];[n-1]\]. + It represents the [i]th byte (character) of [s] which can be + accessed using the constant time string indexing operator + [s.[i]].} + {- A {e position} [i] of [s] is an integer in the range + \[[0];[n]\]. It represents either the point at the beginning of + the string, or the point between two indices, or the point at + the end of the string. The [i]th byte index is between position + [i] and [i+1].}} + + Two integers [start] and [len] are said to define a {e valid + substring} of [s] if [len >= 0] and [start], [start+len] are + positions of [s]. + + {b Unicode text.} Strings being arbitrary sequences of bytes, they + can hold any kind of textual encoding. However the recommended + encoding for storing Unicode text in OCaml strings is UTF-8. This + is the encoding used by Unicode escapes in string literals. For + example the string ["\u{1F42B}"] is the UTF-8 encoding of the + Unicode character U+1F42B. + + {b Past mutability.} OCaml strings used to be modifiable in place, + for instance via the {!String.set} and {!String.blit} + functions. This use is nowadays only possible when the compiler is + put in "unsafe-string" mode by giving the [-unsafe-string] + command-line option. This compatibility mode makes the types + [string] and [bytes] (see {!Bytes.t}) interchangeable so that + functions expecting byte sequences can also accept strings as + arguments and modify them. + + The distinction between [bytes] and [string] was introduced in + OCaml 4.02, and the "unsafe-string" compatibility mode was the + default until OCaml 4.05. Starting with 4.06, the compatibility + mode is opt-in; we intend to remove the option in the future. + + The labeled version of this module can be used as described in the + {!StdLabels} module. +*) + +(** {1:strings Strings} *) + +type t = string +(** The type for strings. *) - For example: - {[ - open StdLabels +val make : int -> char -> string +(** [make n c] is a string of length [n] with each index holding the + character [c]. + + @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. *) - let to_upper = String.map ~f:Char.uppercase_ascii - ]} *) +val init : int -> f:(int -> char) -> string +(** [init n ~f] is a string of length [n] with index + [i] holding the character [f i] (called in increasing index order). + + @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. + @since 4.02.0 *) external length : string -> int = "%string_length" -(** Return the length (number of characters) of the given string. *) +(** [length s] is the length (number of bytes/characters) of [s]. *) external get : string -> int -> char = "%string_safe_get" -(** [String.get s n] returns the character at index [n] in string [s]. - You can also write [s.[n]] instead of [String.get s n]. - @raise Invalid_argument if [n] not a valid index in [s]. *) +(** [get s i] is the character at index [i] in [s]. This is the same + as writing [s.[i]]. -external set : bytes -> int -> char -> unit = "%string_safe_set" - [@@ocaml.deprecated "Use BytesLabels.set instead."] -(** [String.set s n c] modifies byte sequence [s] in place, - replacing the byte at index [n] with [c]. - You can also write [s.[n] <- c] instead of [String.set s n c]. - @raise Invalid_argument if [n] is not a valid index in [s]. + @raise Invalid_argument if [i] not an index of [s]. *) - @deprecated This is a deprecated alias of {!BytesLabels.set}. *) +(** {1:concat Concatenating} -external create : int -> bytes = "caml_create_string" - [@@ocaml.deprecated "Use BytesLabels.create instead."] -(** [String.create n] returns a fresh byte sequence of length [n]. - The sequence is uninitialized and contains arbitrary bytes. - @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. + {b Note.} The {!Stdlib.( ^ )} binary operator concatenates two + strings. *) - @deprecated This is a deprecated alias of {!BytesLabels.create}. *) +val concat : sep:string -> string list -> string +(** [concat ~sep ss] concatenates the list of strings [ss], inserting + the separator string [sep] between each. -val make : int -> char -> string -(** [String.make n c] returns a fresh string of length [n], - filled with the character [c]. - @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. *) + @raise Invalid_argument if the result is longer than + {!Sys.max_string_length} bytes. *) -val init : int -> f:(int -> char) -> string -(** [init n f] returns a string of length [n], - with character [i] initialized to the result of [f i]. - @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. - @since 4.02.0 *) +(** {1:predicates Predicates and comparisons} *) -val copy : string -> string [@@ocaml.deprecated] -(** Return a copy of the given string. *) +val equal : t -> t -> bool +(** [equal s0 s1] is [true] if and only if [s0] and [s1] are character-wise + equal. + @since 4.03.0 (4.05.0 in StringLabels) *) -val sub : string -> pos:int -> len:int -> string -(** [String.sub s start len] returns a fresh string of length [len], - containing the substring of [s] that starts at position [start] and - has length [len]. - @raise Invalid_argument if [start] and [len] do not - designate a valid substring of [s]. *) +val compare : t -> t -> int +(** [compare s0 s1] sorts [s0] and [s1] in lexicographical order. [compare] + behaves like {!Stdlib.compare} on strings but may be more efficient. *) -val fill : bytes -> pos:int -> len:int -> char -> unit - [@@ocaml.deprecated "Use BytesLabels.fill instead."] -(** [String.fill s start len c] modifies byte sequence [s] in place, - replacing [len] bytes by [c], starting at [start]. - @raise Invalid_argument if [start] and [len] do not - designate a valid substring of [s]. +val contains_from : string -> int -> char -> bool +(** [contains_from s start c] is [true] if and only if [c] appears in [s] + after position [start]. - @deprecated This is a deprecated alias of {!BytesLabels.fill}. *) + @raise Invalid_argument if [start] is not a valid position in [s]. *) -val blit : - src:string -> src_pos:int -> dst:bytes -> dst_pos:int -> len:int - -> unit -(** [String.blit src srcoff dst dstoff len] copies [len] bytes - from the string [src], starting at index [srcoff], - to byte sequence [dst], starting at character number [dstoff]. - @raise Invalid_argument if [srcoff] and [len] do not - designate a valid range of [src], or if [dstoff] and [len] - do not designate a valid range of [dst]. *) +val rcontains_from : string -> int -> char -> bool +(** [rcontains_from s stop c] is [true] if and only if [c] appears in [s] + before position [stop+1]. -val concat : sep:string -> string list -> string -(** [String.concat sep sl] concatenates the list of strings [sl], - inserting the separator string [sep] between each. *) + @raise Invalid_argument if [stop < 0] or [stop+1] is not a valid + position in [s]. *) -val iter : f:(char -> unit) -> string -> unit -(** [String.iter f s] applies function [f] in turn to all - the characters of [s]. It is equivalent to - [f s.[0]; f s.[1]; ...; f s.[String.length s - 1]; ()]. *) +val contains : string -> char -> bool +(** [contains s c] is {!String.contains_from}[ s 0 c]. *) -val iteri : f:(int -> char -> unit) -> string -> unit -(** Same as {!String.iter}, but the - function is applied to the index of the element as first argument - (counting from 0), and the character itself as second argument. - @since 4.00.0 *) +(** {1:extract Extracting substrings} *) + +val sub : string -> pos:int -> len:int -> string +(** [sub s ~pos ~len] is a string of length [len], containing the + substring of [s] that starts at position [pos] and has length + [len]. + + @raise Invalid_argument if [pos] and [len] do not designate a valid + substring of [s]. *) + +val split_on_char : sep:char -> string -> string list +(** [split_on_char ~sep s] is the list of all (possibly empty) + substrings of [s] that are delimited by the character [sep]. + + The function's result is specified by the following invariants: + {ul + {- The list is not empty.} + {- Concatenating its elements using [sep] as a separator returns a + string equal to the input ([concat (make 1 sep) + (split_on_char sep s) = s]).} + {- No string in the result contains the [sep] character.}} + + @since 4.04.0 (4.05.0 in StringLabels) *) + +(** {1:transforming Transforming} *) val map : f:(char -> char) -> string -> string -(** [String.map f s] applies function [f] in turn to all - the characters of [s] and stores the results in a new string that - is returned. - @since 4.00.0 *) +(** [map f s] is the string resulting from applying [f] to all the + characters of [s] in increasing order. + + @since 4.00.0 *) val mapi : f:(int -> char -> char) -> string -> string -(** [String.mapi f s] calls [f] with each character of [s] and its - index (in increasing index order) and stores the results in a new - string that is returned. +(** [mapi ~f s] is like {!map} but the index of the character is also + passed to [f]. + @since 4.02.0 *) val trim : string -> string -(** Return a copy of the argument, without leading and trailing - whitespace. The characters regarded as whitespace are: [' '], - ['\012'], ['\n'], ['\r'], and ['\t']. If there is no leading nor - trailing whitespace character in the argument, return the original - string itself, not a copy. - @since 4.00.0 *) +(** [trim s] is [s] without leading and trailing whitespace. Whitespace + characters are: [' '], ['\x0C'] (form feed), ['\n'], ['\r'], and ['\t']. + + @since 4.00.0 *) val escaped : string -> string -(** Return a copy of the argument, with special characters - represented by escape sequences, following the lexical - conventions of OCaml. If there is no special - character in the argument, return the original string itself, - not a copy. Its inverse function is Scanf.unescaped. *) +(** [escaped s] is [s] with special characters represented by escape + sequences, following the lexical conventions of OCaml. -val index : string -> char -> int -(** [String.index s c] returns the index of the first - occurrence of character [c] in string [s]. - @raise Not_found if [c] does not occur in [s]. *) - -val index_opt: string -> char -> int option -(** [String.index_opt s c] returns the index of the first - occurrence of character [c] in string [s], or - [None] if [c] does not occur in [s]. - @since 4.05 *) + All characters outside the US-ASCII printable range \[0x20;0x7E\] are + escaped, as well as backslash (0x2F) and double-quote (0x22). -val rindex : string -> char -> int -(** [String.rindex s c] returns the index of the last - occurrence of character [c] in string [s]. - @raise Not_found if [c] does not occur in [s]. *) - -val rindex_opt: string -> char -> int option -(** [String.rindex_opt s c] returns the index of the last occurrence - of character [c] in string [s], or [None] if [c] does not occur in - [s]. - @since 4.05 *) + The function {!Scanf.unescaped} is a left inverse of [escaped], + i.e. [Scanf.unescaped (escaped s) = s] for any string [s] (unless + [escaped s] fails). -val index_from : string -> int -> char -> int -(** [String.index_from s i c] returns the index of the - first occurrence of character [c] in string [s] after position [i]. - [String.index s c] is equivalent to [String.index_from s 0 c]. - @raise Invalid_argument if [i] is not a valid position in [s]. - @raise Not_found if [c] does not occur in [s] after position [i]. *) - -val index_from_opt: string -> int -> char -> int option -(** [String.index_from_opt s i c] returns the index of the - first occurrence of character [c] in string [s] after position [i] - or [None] if [c] does not occur in [s] after position [i]. - - [String.index_opt s c] is equivalent to [String.index_from_opt s 0 c]. - @raise Invalid_argument if [i] is not a valid position in [s]. + @raise Invalid_argument if the result is longer than + {!Sys.max_string_length} bytes. *) - @since 4.05 -*) +val uppercase_ascii : string -> string +(** [uppercase_ascii s] is [s] with all lowercase letters + translated to uppercase, using the US-ASCII character set. -val rindex_from : string -> int -> char -> int -(** [String.rindex_from s i c] returns the index of the - last occurrence of character [c] in string [s] before position [i+1]. - [String.rindex s c] is equivalent to - [String.rindex_from s (String.length s - 1) c]. - @raise Invalid_argument if [i+1] is not a valid position in [s]. - @raise Not_found if [c] does not occur in [s] before position [i+1]. *) - -val rindex_from_opt: string -> int -> char -> int option -(** [String.rindex_from_opt s i c] returns the index of the - last occurrence of character [c] in string [s] before position [i+1] - or [None] if [c] does not occur in [s] before position [i+1]. - - [String.rindex_opt s c] is equivalent to - [String.rindex_from_opt s (String.length s - 1) c]. - @raise Invalid_argument if [i+1] is not a valid position in [s]. - - @since 4.05 -*) + @since 4.03.0 (4.05.0 in StringLabels) *) -val contains : string -> char -> bool -(** [String.contains s c] tests if character [c] - appears in the string [s]. *) +val lowercase_ascii : string -> string +(** [lowercase_ascii s] is [s] with all uppercase letters translated + to lowercase, using the US-ASCII character set. -val contains_from : string -> int -> char -> bool -(** [String.contains_from s start c] tests if character [c] - appears in [s] after position [start]. - [String.contains s c] is equivalent to - [String.contains_from s 0 c]. - @raise Invalid_argument if [start] is not a valid position in [s]. *) + @since 4.03.0 (4.05.0 in StringLabels) *) -val rcontains_from : string -> int -> char -> bool -(** [String.rcontains_from s stop c] tests if character [c] - appears in [s] before position [stop+1]. - @raise Invalid_argument if [stop < 0] or [stop+1] is not a valid - position in [s]. *) +val capitalize_ascii : string -> string +(** [capitalize_ascii s] is [s] with the first character set to + uppercase, using the US-ASCII character set. -val uppercase : string -> string - [@@ocaml.deprecated "Use String.uppercase_ascii instead."] -(** Return a copy of the argument, with all lowercase letters - translated to uppercase, including accented letters of the ISO - Latin-1 (8859-1) character set. - @deprecated Functions operating on Latin-1 character set are deprecated. *) + @since 4.03.0 (4.05.0 in StringLabels) *) -val lowercase : string -> string - [@@ocaml.deprecated "Use String.lowercase_ascii instead."] -(** Return a copy of the argument, with all uppercase letters - translated to lowercase, including accented letters of the ISO - Latin-1 (8859-1) character set. - @deprecated Functions operating on Latin-1 character set are deprecated. *) +val uncapitalize_ascii : string -> string +(** [uncapitalize_ascii s] is [s] with the first character set to lowercase, + using the US-ASCII character set. -val capitalize : string -> string - [@@ocaml.deprecated "Use String.capitalize_ascii instead."] -(** Return a copy of the argument, with the first character set to uppercase, - using the ISO Latin-1 (8859-1) character set.. - @deprecated Functions operating on Latin-1 character set are deprecated. *) + @since 4.03.0 (4.05.0 in StringLabels) *) -val uncapitalize : string -> string - [@@ocaml.deprecated "Use String.uncapitalize_ascii instead."] -(** Return a copy of the argument, with the first character set to lowercase, - using the ISO Latin-1 (8859-1) character set.. - @deprecated Functions operating on Latin-1 character set are deprecated. *) +(** {1:traversing Traversing} *) -val uppercase_ascii : string -> string -(** Return a copy of the argument, with all lowercase letters - translated to uppercase, using the US-ASCII character set. - @since 4.05.0 *) +val iter : f:(char -> unit) -> string -> unit +(** [iter ~f s] applies function [f] in turn to all the characters of [s]. + It is equivalent to [f s.[0]; f s.[1]; ...; f s.[length s - 1]; ()]. *) -val lowercase_ascii : string -> string -(** Return a copy of the argument, with all uppercase letters - translated to lowercase, using the US-ASCII character set. - @since 4.05.0 *) +val iteri : f:(int -> char -> unit) -> string -> unit +(** [iteri] is like {!iter}, but the function is also given the + corresponding character index. -val capitalize_ascii : string -> string -(** Return a copy of the argument, with the first character set to uppercase, - using the US-ASCII character set. - @since 4.05.0 *) + @since 4.00.0 *) -val uncapitalize_ascii : string -> string -(** Return a copy of the argument, with the first character set to lowercase, - using the US-ASCII character set. - @since 4.05.0 *) +(** {1:searching Searching} *) -type t = string -(** An alias for the type of strings. *) +val index_from : string -> int -> char -> int +(** [index_from s i c] is the index of the first occurrence of [c] in + [s] after position [i]. -val compare: t -> t -> int -(** The comparison function for strings, with the same specification as - {!Stdlib.compare}. Along with the type [t], this function [compare] - allows the module [String] to be passed as argument to the functors - {!Set.Make} and {!Map.Make}. *) + @raise Not_found if [c] does not occur in [s] after position [i]. + @raise Invalid_argument if [i] is not a valid position in [s]. *) -val equal: t -> t -> bool -(** The equal function for strings. - @since 4.05.0 *) -val split_on_char: sep:char -> string -> string list -(** [String.split_on_char sep s] returns the list of all (possibly empty) - substrings of [s] that are delimited by the [sep] character. +val index_from_opt : string -> int -> char -> int option +(** [index_from_opt s i c] is the index of the first occurrence of [c] + in [s] after position [i] (if any). - The function's output is specified by the following invariants: + @raise Invalid_argument if [i] is not a valid position in [s]. + @since 4.05 *) - - The list is not empty. - - Concatenating its elements using [sep] as a separator returns a - string equal to the input ([String.concat (String.make 1 sep) - (String.split_on_char sep s) = s]). - - No string in the result contains the [sep] character. +val rindex_from : string -> int -> char -> int +(** [rindex_from s i c] is the index of the last occurrence of [c] in + [s] before position [i+1]. - @since 4.05.0 -*) + @raise Not_found if [c] does not occur in [s] before position [i+1]. + @raise Invalid_argument if [i+1] is not a valid position in [s]. *) + +val rindex_from_opt : string -> int -> char -> int option +(** [rindex_from_opt s i c] is the index of the last occurrence of [c] + in [s] before position [i+1] (if any). + + @raise Invalid_argument if [i+1] is not a valid position in [s]. + @since 4.05 *) + +val index : string -> char -> int +(** [index s c] is {!String.index_from}[ s 0 c]. *) + +val index_opt : string -> char -> int option +(** [index_opt s c] is {!String.index_from_opt}[ s 0 c]. + + @since 4.05 *) + +val rindex : string -> char -> int +(** [rindex s c] is {!String.rindex_from}[ s (length s - 1) c]. *) -(** {1 Iterators} *) +val rindex_opt : string -> char -> int option +(** [rindex_opt s c] is {!String.rindex_from_opt}[ s (length s - 1) c]. + + @since 4.05 *) + +(** {1:converting Converting} *) val to_seq : t -> char Seq.t -(** Iterate on the string, in increasing index order. Modifications of the - string during iteration will be reflected in the iterator. +(** [to_seq s] is a sequence made of the string's characters in + increasing order. In ["unsafe-string"] mode, modifications of the string + during iteration will be reflected in the iterator. + @since 4.07 *) val to_seqi : t -> (int * char) Seq.t -(** Iterate on the string, in increasing order, yielding indices along chars +(** [to_seqi s] is like {!to_seq} but also tuples the corresponding index. + @since 4.07 *) val of_seq : char Seq.t -> t -(** Create a string from the generator +(** [of_seq s] is a string made of the sequence's characters. + @since 4.07 *) +(** {1:deprecated Deprecated functions} *) + +external create : int -> bytes = "caml_create_string" + [@@ocaml.deprecated "Use Bytes.create/BytesLabels.create instead."] +(** [create n] returns a fresh byte sequence of length [n]. + The sequence is uninitialized and contains arbitrary bytes. + @raise Invalid_argument if [n < 0] or [n > ]{!Sys.max_string_length}. + + @deprecated This is a deprecated alias of + {!Bytes.create}/{!BytesLabels.create}. *) + +external set : bytes -> int -> char -> unit = "%string_safe_set" + [@@ocaml.deprecated "Use Bytes.set/BytesLabels.set instead."] +(** [set s n c] modifies byte sequence [s] in place, + replacing the byte at index [n] with [c]. + You can also write [s.[n] <- c] instead of [set s n c]. + @raise Invalid_argument if [n] is not a valid index in [s]. + + @deprecated This is a deprecated alias of + {!Bytes.set}/{!BytesLabels.set}. *) + +val blit : + src:string -> src_pos:int -> dst:bytes -> dst_pos:int -> len:int -> unit +(** [blit ~src ~src_pos ~dst ~dst_pos ~len] copies [len] bytes + from the string [src], starting at index [src_pos], + to byte sequence [dst], starting at character number [dst_pos]. + + @raise Invalid_argument if [src_pos] and [len] do not + designate a valid range of [src], or if [dst_pos] and [len] + do not designate a valid range of [dst]. *) + +val copy : string -> string + [@@ocaml.deprecated "Strings now immutable: no need to copy"] +(** Return a copy of the given string. + + @deprecated Because strings are immutable, it doesn't make much + sense to make identical copies of them. *) + +val fill : bytes -> pos:int -> len:int -> char -> unit + [@@ocaml.deprecated "Use Bytes.fill/BytesLabels.fill instead."] +(** [fill s ~pos ~len c] modifies byte sequence [s] in place, + replacing [len] bytes by [c], starting at [pos]. + @raise Invalid_argument if [pos] and [len] do not + designate a valid substring of [s]. + + @deprecated This is a deprecated alias of + {!Bytes.fill}/{!BytesLabels.fill}. *) + +val uppercase : string -> string + [@@ocaml.deprecated + "Use String.uppercase_ascii/StringLabels.uppercase_ascii instead."] +(** Return a copy of the argument, with all lowercase letters + translated to uppercase, including accented letters of the ISO + Latin-1 (8859-1) character set. + + @deprecated Functions operating on Latin-1 character set are deprecated. *) + +val lowercase : string -> string + [@@ocaml.deprecated + "Use String.lowercase_ascii/StringLabels.lowercase_ascii instead."] +(** Return a copy of the argument, with all uppercase letters + translated to lowercase, including accented letters of the ISO + Latin-1 (8859-1) character set. + + @deprecated Functions operating on Latin-1 character set are deprecated. *) + +val capitalize : string -> string + [@@ocaml.deprecated + "Use String.capitalize_ascii/StringLabels.capitalize_ascii instead."] +(** Return a copy of the argument, with the first character set to uppercase, + using the ISO Latin-1 (8859-1) character set.. + + @deprecated Functions operating on Latin-1 character set are deprecated. *) + +val uncapitalize : string -> string + [@@ocaml.deprecated + "Use String.uncapitalize_ascii/StringLabels.uncapitalize_ascii instead."] +(** Return a copy of the argument, with the first character set to lowercase, + using the ISO Latin-1 (8859-1) character set. + + @deprecated Functions operating on Latin-1 character set are deprecated. *) + (**/**) (* The following is for system use only. Do not call directly. *) diff --git a/stdlib/sys.mli b/stdlib/sys.mli index 368baa0f..cbe8e46f 100644 --- a/stdlib/sys.mli +++ b/stdlib/sys.mli @@ -94,6 +94,18 @@ external time : unit -> (float [@unboxed]) = external chdir : string -> unit = "caml_sys_chdir" (** Change the current working directory of the process. *) +external mkdir : string -> int -> unit = "caml_sys_mkdir" +(** Create a directory with the given permissions. + + @since 4.12.0 +*) + +external rmdir : string -> unit = "caml_sys_rmdir" +(** Remove an empty directory. + + @since 4.12.0 +*) + external getcwd : unit -> string = "caml_sys_getcwd" (** Return the current working directory of the process. *) diff --git a/stdlib/sys.mlp b/stdlib/sys.mlp index e89dd458..03ffc515 100644 --- a/stdlib/sys.mlp +++ b/stdlib/sys.mlp @@ -66,6 +66,8 @@ external command: string -> int = "caml_sys_system_command" external time: unit -> (float [@unboxed]) = "caml_sys_time" "caml_sys_time_unboxed" [@@noalloc] external chdir: string -> unit = "caml_sys_chdir" +external mkdir: string -> int -> unit = "caml_sys_mkdir" +external rmdir: string -> unit = "caml_sys_rmdir" external getcwd: unit -> string = "caml_sys_getcwd" external readdir : string -> string array = "caml_sys_read_directory" diff --git a/stdlib/templates/README.adoc b/stdlib/templates/README.adoc new file mode 100644 index 00000000..e4b6fdbd --- /dev/null +++ b/stdlib/templates/README.adoc @@ -0,0 +1,4 @@ +These templates are fragments of OCaml source files, which +tools/sync_stdlib_docs uses to build the full labeled and unlabeled stdlib +modules. At present, tools/sync_stdlib_docs must be run manually -- it is not a +build task. diff --git a/stdlib/templates/float.template.mli b/stdlib/templates/float.template.mli new file mode 100644 index 00000000..a33a35d4 --- /dev/null +++ b/stdlib/templates/float.template.mli @@ -0,0 +1,408 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* Nicolas Ojeda Bar, LexiFi *) +(* *) +(* Copyright 2018 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* NOTE: + If this file is float.template.mli, run tools/sync_stdlib_docs after editing + it to generate float.mli. + + If this file is float.mli, do not edit it directly -- edit + templates/float.template.mli instead. + *) + +(** Floating-point arithmetic. + + OCaml's floating-point numbers follow the + IEEE 754 standard, using double precision (64 bits) numbers. + Floating-point operations never raise an exception on overflow, + underflow, division by zero, etc. Instead, special IEEE numbers + are returned as appropriate, such as [infinity] for [1.0 /. 0.0], + [neg_infinity] for [-1.0 /. 0.0], and [nan] ('not a number') + for [0.0 /. 0.0]. These special numbers then propagate through + floating-point computations as expected: for instance, + [1.0 /. infinity] is [0.0], basic arithmetic operations + ([+.], [-.], [*.], [/.]) with [nan] as an argument return [nan], ... + + @since 4.07.0 +*) + +val zero : float +(** The floating point 0. + @since 4.08.0 *) + +val one : float +(** The floating-point 1. + @since 4.08.0 *) + +val minus_one : float +(** The floating-point -1. + @since 4.08.0 *) + +external neg : float -> float = "%negfloat" +(** Unary negation. *) + +external add : float -> float -> float = "%addfloat" +(** Floating-point addition. *) + +external sub : float -> float -> float = "%subfloat" +(** Floating-point subtraction. *) + +external mul : float -> float -> float = "%mulfloat" +(** Floating-point multiplication. *) + +external div : float -> float -> float = "%divfloat" +(** Floating-point division. *) + +external fma : float -> float -> float -> float = + "caml_fma_float" "caml_fma" [@@unboxed] [@@noalloc] +(** [fma x y z] returns [x * y + z], with a best effort for computing + this expression with a single rounding, using either hardware + instructions (providing full IEEE compliance) or a software + emulation. Note: since software emulation of the fma is costly, + make sure that you are using hardware fma support if performance + matters. @since 4.08.0 *) + +external rem : float -> float -> float = "caml_fmod_float" "fmod" +[@@unboxed] [@@noalloc] +(** [rem a b] returns the remainder of [a] with respect to [b]. The returned + value is [a -. n *. b], where [n] is the quotient [a /. b] rounded towards + zero to an integer. *) + +val succ : float -> float +(** [succ x] returns the floating point number right after [x] i.e., + the smallest floating-point number greater than [x]. See also + {!next_after}. + @since 4.08.0 *) + +val pred : float -> float +(** [pred x] returns the floating-point number right before [x] i.e., + the greatest floating-point number smaller than [x]. See also + {!next_after}. + @since 4.08.0 *) + +external abs : float -> float = "%absfloat" +(** [abs f] returns the absolute value of [f]. *) + +val infinity : float +(** Positive infinity. *) + +val neg_infinity : float +(** Negative infinity. *) + +val nan : float +(** A special floating-point value denoting the result of an + undefined operation such as [0.0 /. 0.0]. Stands for + 'not a number'. Any floating-point operation with [nan] as + argument returns [nan] as result. As for floating-point comparisons, + [=], [<], [<=], [>] and [>=] return [false] and [<>] returns [true] + if one or both of their arguments is [nan]. *) + +val pi : float +(** The constant pi. *) + +val max_float : float +(** The largest positive finite value of type [float]. *) + +val min_float : float +(** The smallest positive, non-zero, non-denormalized value of type [float]. *) + +val epsilon : float +(** The difference between [1.0] and the smallest exactly representable + floating-point number greater than [1.0]. *) + +val is_finite : float -> bool +(** [is_finite x] is [true] if and only if [x] is finite i.e., not infinite and + not {!nan}. + + @since 4.08.0 *) + +val is_infinite : float -> bool +(** [is_infinite x] is [true] if and only if [x] is {!infinity} or + {!neg_infinity}. + + @since 4.08.0 *) + +val is_nan : float -> bool +(** [is_nan x] is [true] if and only if [x] is not a number (see {!nan}). + + @since 4.08.0 *) + +val is_integer : float -> bool +(** [is_integer x] is [true] if and only if [x] is an integer. + + @since 4.08.0 *) + +external of_int : int -> float = "%floatofint" +(** Convert an integer to floating-point. *) + +external to_int : float -> int = "%intoffloat" +(** Truncate the given floating-point number to an integer. + The result is unspecified if the argument is [nan] or falls outside the + range of representable integers. *) + +external of_string : string -> float = "caml_float_of_string" +(** Convert the given string to a float. The string is read in decimal + (by default) or in hexadecimal (marked by [0x] or [0X]). + The format of decimal floating-point numbers is + [ [-] dd.ddd (e|E) [+|-] dd ], where [d] stands for a decimal digit. + The format of hexadecimal floating-point numbers is + [ [-] 0(x|X) hh.hhh (p|P) [+|-] dd ], where [h] stands for an + hexadecimal digit and [d] for a decimal digit. + In both cases, at least one of the integer and fractional parts must be + given; the exponent part is optional. + The [_] (underscore) character can appear anywhere in the string + and is ignored. + Depending on the execution platforms, other representations of + floating-point numbers can be accepted, but should not be relied upon. + @raise Failure if the given string is not a valid + representation of a float. *) + +val of_string_opt: string -> float option +(** Same as [of_string], but returns [None] instead of raising. *) + +val to_string : float -> string +(** Return the string representation of a floating-point number. *) + +type fpclass = Stdlib.fpclass = + FP_normal (** Normal number, none of the below *) + | FP_subnormal (** Number very close to 0.0, has reduced precision *) + | FP_zero (** Number is 0.0 or -0.0 *) + | FP_infinite (** Number is positive or negative infinity *) + | FP_nan (** Not a number: result of an undefined operation *) +(** The five classes of floating-point numbers, as determined by + the {!classify_float} function. *) + +external classify_float : (float [@unboxed]) -> fpclass = + "caml_classify_float" "caml_classify_float_unboxed" [@@noalloc] +(** Return the class of the given floating-point number: + normal, subnormal, zero, infinite, or not a number. *) + +external pow : float -> float -> float = "caml_power_float" "pow" +[@@unboxed] [@@noalloc] +(** Exponentiation. *) + +external sqrt : float -> float = "caml_sqrt_float" "sqrt" +[@@unboxed] [@@noalloc] +(** Square root. *) + +external exp : float -> float = "caml_exp_float" "exp" [@@unboxed] [@@noalloc] +(** Exponential. *) + +external log : float -> float = "caml_log_float" "log" [@@unboxed] [@@noalloc] +(** Natural logarithm. *) + +external log10 : float -> float = "caml_log10_float" "log10" +[@@unboxed] [@@noalloc] +(** Base 10 logarithm. *) + +external expm1 : float -> float = "caml_expm1_float" "caml_expm1" +[@@unboxed] [@@noalloc] +(** [expm1 x] computes [exp x -. 1.0], giving numerically-accurate results + even if [x] is close to [0.0]. *) + +external log1p : float -> float = "caml_log1p_float" "caml_log1p" +[@@unboxed] [@@noalloc] +(** [log1p x] computes [log(1.0 +. x)] (natural logarithm), + giving numerically-accurate results even if [x] is close to [0.0]. *) + +external cos : float -> float = "caml_cos_float" "cos" [@@unboxed] [@@noalloc] +(** Cosine. Argument is in radians. *) + +external sin : float -> float = "caml_sin_float" "sin" [@@unboxed] [@@noalloc] +(** Sine. Argument is in radians. *) + +external tan : float -> float = "caml_tan_float" "tan" [@@unboxed] [@@noalloc] +(** Tangent. Argument is in radians. *) + +external acos : float -> float = "caml_acos_float" "acos" +[@@unboxed] [@@noalloc] +(** Arc cosine. The argument must fall within the range [[-1.0, 1.0]]. + Result is in radians and is between [0.0] and [pi]. *) + +external asin : float -> float = "caml_asin_float" "asin" +[@@unboxed] [@@noalloc] +(** Arc sine. The argument must fall within the range [[-1.0, 1.0]]. + Result is in radians and is between [-pi/2] and [pi/2]. *) + +external atan : float -> float = "caml_atan_float" "atan" +[@@unboxed] [@@noalloc] +(** Arc tangent. + Result is in radians and is between [-pi/2] and [pi/2]. *) + +external atan2 : float -> float -> float = "caml_atan2_float" "atan2" +[@@unboxed] [@@noalloc] +(** [atan2 y x] returns the arc tangent of [y /. x]. The signs of [x] + and [y] are used to determine the quadrant of the result. + Result is in radians and is between [-pi] and [pi]. *) + +external hypot : float -> float -> float = "caml_hypot_float" "caml_hypot" +[@@unboxed] [@@noalloc] +(** [hypot x y] returns [sqrt(x *. x + y *. y)], that is, the length + of the hypotenuse of a right-angled triangle with sides of length + [x] and [y], or, equivalently, the distance of the point [(x,y)] + to origin. If one of [x] or [y] is infinite, returns [infinity] + even if the other is [nan]. *) + +external cosh : float -> float = "caml_cosh_float" "cosh" +[@@unboxed] [@@noalloc] +(** Hyperbolic cosine. Argument is in radians. *) + +external sinh : float -> float = "caml_sinh_float" "sinh" +[@@unboxed] [@@noalloc] +(** Hyperbolic sine. Argument is in radians. *) + +external tanh : float -> float = "caml_tanh_float" "tanh" +[@@unboxed] [@@noalloc] +(** Hyperbolic tangent. Argument is in radians. *) + +external trunc : float -> float = "caml_trunc_float" "caml_trunc" + [@@unboxed] [@@noalloc] +(** [trunc x] rounds [x] to the nearest integer whose absolute value is + less than or equal to [x]. + + @since 4.08.0 *) + +external round : float -> float = "caml_round_float" "caml_round" + [@@unboxed] [@@noalloc] +(** [round x] rounds [x] to the nearest integer with ties (fractional + values of 0.5) rounded away from zero, regardless of the current + rounding direction. If [x] is an integer, [+0.], [-0.], [nan], or + infinite, [x] itself is returned. + + @since 4.08.0 *) + +external ceil : float -> float = "caml_ceil_float" "ceil" +[@@unboxed] [@@noalloc] +(** Round above to an integer value. + [ceil f] returns the least integer value greater than or equal to [f]. + The result is returned as a float. *) + +external floor : float -> float = "caml_floor_float" "floor" +[@@unboxed] [@@noalloc] +(** Round below to an integer value. + [floor f] returns the greatest integer value less than or + equal to [f]. + The result is returned as a float. *) + +external next_after : float -> float -> float + = "caml_nextafter_float" "caml_nextafter" [@@unboxed] [@@noalloc] +(** [next_after x y] returns the next representable floating-point + value following [x] in the direction of [y]. More precisely, if + [y] is greater (resp. less) than [x], it returns the smallest + (resp. largest) representable number greater (resp. less) than [x]. + If [x] equals [y], the function returns [y]. If [x] or [y] is + [nan], a [nan] is returned. + Note that [next_after max_float infinity = infinity] and that + [next_after 0. infinity] is the smallest denormalized positive number. + If [x] is the smallest denormalized positive number, + [next_after x 0. = 0.] + + @since 4.08.0 *) + +external copy_sign : float -> float -> float + = "caml_copysign_float" "caml_copysign" +[@@unboxed] [@@noalloc] +(** [copy_sign x y] returns a float whose absolute value is that of [x] + and whose sign is that of [y]. If [x] is [nan], returns [nan]. + If [y] is [nan], returns either [x] or [-. x], but it is not + specified which. *) + +external sign_bit : (float [@unboxed]) -> bool + = "caml_signbit_float" "caml_signbit" [@@noalloc] +(** [sign_bit x] is [true] if and only if the sign bit of [x] is set. + For example [sign_bit 1.] and [signbit 0.] are [false] while + [sign_bit (-1.)] and [sign_bit (-0.)] are [true]. + + @since 4.08.0 *) + +external frexp : float -> float * int = "caml_frexp_float" +(** [frexp f] returns the pair of the significant + and the exponent of [f]. When [f] is zero, the + significant [x] and the exponent [n] of [f] are equal to + zero. When [f] is non-zero, they are defined by + [f = x *. 2 ** n] and [0.5 <= x < 1.0]. *) + +external ldexp : (float [@unboxed]) -> (int [@untagged]) -> (float [@unboxed]) = + "caml_ldexp_float" "caml_ldexp_float_unboxed" [@@noalloc] +(** [ldexp x n] returns [x *. 2 ** n]. *) + +external modf : float -> float * float = "caml_modf_float" +(** [modf f] returns the pair of the fractional and integral + part of [f]. *) + +type t = float +(** An alias for the type of floating-point numbers. *) + +val compare: t -> t -> int +(** [compare x y] returns [0] if [x] is equal to [y], a negative integer if [x] + is less than [y], and a positive integer if [x] is greater than + [y]. [compare] treats [nan] as equal to itself and less than any other float + value. This treatment of [nan] ensures that [compare] defines a total + ordering relation. *) + +val equal: t -> t -> bool +(** The equal function for floating-point numbers, compared using {!compare}. *) + +val min : t -> t -> t +(** [min x y] returns the minimum of [x] and [y]. It returns [nan] + when [x] or [y] is [nan]. Moreover [min (-0.) (+0.) = -0.] + + @since 4.08.0 *) + +val max : float -> float -> float +(** [max x y] returns the maximum of [x] and [y]. It returns [nan] + when [x] or [y] is [nan]. Moreover [max (-0.) (+0.) = +0.] + + @since 4.08.0 *) + +val min_max : float -> float -> float * float +(** [min_max x y] is [(min x y, max x y)], just more efficient. + + @since 4.08.0 *) + +val min_num : t -> t -> t +(** [min_num x y] returns the minimum of [x] and [y] treating [nan] as + missing values. If both [x] and [y] are [nan], [nan] is returned. + Moreover [min_num (-0.) (+0.) = -0.] + + @since 4.08.0 *) + +val max_num : t -> t -> t +(** [max_num x y] returns the maximum of [x] and [y] treating [nan] as + missing values. If both [x] and [y] are [nan] [nan] is returned. + Moreover [max_num (-0.) (+0.) = +0.] + + @since 4.08.0 *) + +val min_max_num : float -> float -> float * float +(** [min_max_num x y] is [(min_num x y, max_num x y)], just more + efficient. Note that in particular [min_max_num x nan = (x, x)] + and [min_max_num nan y = (y, y)]. + + @since 4.08.0 *) + + +val hash: t -> int +(** The hash function for floating-point numbers. *) + +module Array : sig +FLOATARRAY +end +(** Float arrays with packed representation. *) + +module ArrayLabels : sig +FLOATARRAYLAB +end +(** Float arrays with packed representation (labeled functions). *) diff --git a/stdlib/templates/floatarraylabeled.template.mli b/stdlib/templates/floatarraylabeled.template.mli new file mode 100644 index 00000000..c76140b4 --- /dev/null +++ b/stdlib/templates/floatarraylabeled.template.mli @@ -0,0 +1,233 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* Nicolas Ojeda Bar, LexiFi *) +(* *) +(* Copyright 2018 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +type t = floatarray +(** The type of float arrays with packed representation. + @since 4.08.0 + *) + +val length : t -> int +(** Return the length (number of elements) of the given floatarray. *) + +val get : t -> int -> float +(** [get a n] returns the element number [n] of floatarray [a]. + @raise Invalid_argument if [n] is outside the range 0 to + [(length a - 1)]. *) + +val set : t -> int -> float -> unit +(** [set a n x] modifies floatarray [a] in place, replacing element + number [n] with [x]. + @raise Invalid_argument if [n] is outside the range 0 to + [(length a - 1)]. *) + +val make : int -> float -> t +(** [make n x] returns a fresh floatarray of length [n], initialized with [x]. + @raise Invalid_argument if [n < 0] or [n > Sys.max_floatarray_length]. *) + +val create : int -> t +(** [create n] returns a fresh floatarray of length [n], + with uninitialized data. + @raise Invalid_argument if [n < 0] or [n > Sys.max_floatarray_length]. *) + +val init : int -> f:(int -> float) -> t +(** [init n ~f] returns a fresh floatarray of length [n], + with element number [i] initialized to the result of [f i]. + In other terms, [init n ~f] tabulates the results of [f] + applied to the integers [0] to [n-1]. + @raise Invalid_argument if [n < 0] or [n > Sys.max_floatarray_length]. *) + +val append : t -> t -> t +(** [append v1 v2] returns a fresh floatarray containing the + concatenation of the floatarrays [v1] and [v2]. + @raise Invalid_argument if + [length v1 + length v2 > Sys.max_floatarray_length]. *) + +val concat : t list -> t +(** Same as {!append}, but concatenates a list of floatarrays. *) + +val sub : t -> pos:int -> len:int -> t +(** [sub a ~pos ~len] returns a fresh floatarray of length [len], + containing the elements number [pos] to [pos + len - 1] + of floatarray [a]. + @raise Invalid_argument if [pos] and [len] do not + designate a valid subarray of [a]; that is, if + [pos < 0], or [len < 0], or [pos + len > length a]. *) + +val copy : t -> t +(** [copy a] returns a copy of [a], that is, a fresh floatarray + containing the same elements as [a]. *) + +val fill : t -> pos:int -> len:int -> float -> unit +(** [fill a ~pos ~len x] modifies the floatarray [a] in place, + storing [x] in elements number [pos] to [pos + len - 1]. + @raise Invalid_argument if [pos] and [len] do not + designate a valid subarray of [a]. *) + +val blit : src:t -> src_pos:int -> dst:t -> dst_pos:int -> len:int -> unit +(** [blit ~src ~src_pos ~dst ~dst_pos ~len] copies [len] elements + from floatarray [src], starting at element number [src_pos], + to floatarray [dst], starting at element number [dst_pos]. + It works correctly even if + [src] and [dst] are the same floatarray, and the source and + destination chunks overlap. + @raise Invalid_argument if [src_pos] and [len] do not + designate a valid subarray of [src], or if [dst_pos] and [len] do not + designate a valid subarray of [dst]. *) + +val to_list : t -> float list +(** [to_list a] returns the list of all the elements of [a]. *) + +val of_list : float list -> t +(** [of_list l] returns a fresh floatarray containing the elements + of [l]. + @raise Invalid_argument if the length of [l] is greater than + [Sys.max_floatarray_length].*) + +(** {2 Iterators} *) + +val iter : f:(float -> unit) -> t -> unit +(** [iter ~f a] applies function [f] in turn to all + the elements of [a]. It is equivalent to + [f a.(0); f a.(1); ...; f a.(length a - 1); ()]. *) + +val iteri : f:(int -> float -> unit) -> t -> unit +(** Same as {!iter}, but the + function is applied with the index of the element as first argument, + and the element itself as second argument. *) + +val map : f:(float -> float) -> t -> t +(** [map ~f a] applies function [f] to all the elements of [a], + and builds a floatarray with the results returned by [f]. *) + +val mapi : f:(int -> float -> float) -> t -> t +(** Same as {!map}, but the + function is applied to the index of the element as first argument, + and the element itself as second argument. *) + +val fold_left : f:('a -> float -> 'a) -> init:'a -> t -> 'a +(** [fold_left ~f x ~init] computes + [f (... (f (f x init.(0)) init.(1)) ...) init.(n-1)], + where [n] is the length of the floatarray [init]. *) + +val fold_right : f:(float -> 'a -> 'a) -> t -> init:'a -> 'a +(** [fold_right f a init] computes + [f a.(0) (f a.(1) ( ... (f a.(n-1) init) ...))], + where [n] is the length of the floatarray [a]. *) + +(** {2 Iterators on two arrays} *) + +val iter2 : f:(float -> float -> unit) -> t -> t -> unit +(** [Array.iter2 ~f a b] applies function [f] to all the elements of [a] + and [b]. + @raise Invalid_argument if the floatarrays are not the same size. *) + +val map2 : f:(float -> float -> float) -> t -> t -> t +(** [map2 ~f a b] applies function [f] to all the elements of [a] + and [b], and builds a floatarray with the results returned by [f]: + [[| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|]]. + @raise Invalid_argument if the floatarrays are not the same size. *) + +(** {2 Array scanning} *) + +val for_all : f:(float -> bool) -> t -> bool +(** [for_all ~f [|a1; ...; an|]] checks if all elements of the floatarray + satisfy the predicate [f]. That is, it returns + [(f a1) && (f a2) && ... && (f an)]. *) + +val exists : f:(float -> bool) -> t -> bool +(** [exists f [|a1; ...; an|]] checks if at least one element of + the floatarray satisfies the predicate [f]. That is, it returns + [(f a1) || (f a2) || ... || (f an)]. *) + +val mem : float -> set:t -> bool +(** [mem a ~set] is true if and only if there is an element of [set] that is + structurally equal to [a], i.e. there is an [x] in [set] such + that [compare a x = 0]. *) + +val mem_ieee : float -> set:t -> bool +(** Same as {!mem}, but uses IEEE equality instead of structural equality. *) + +(** {2 Sorting} *) + +val sort : cmp:(float -> float -> int) -> t -> unit +(** Sort a floatarray in increasing order according to a comparison + function. The comparison function must return 0 if its arguments + compare as equal, a positive integer if the first is greater, + and a negative integer if the first is smaller (see below for a + complete specification). For example, {!Stdlib.compare} is + a suitable comparison function. After calling [sort], the + array is sorted in place in increasing order. + [sort] is guaranteed to run in constant heap space + and (at most) logarithmic stack space. + + The current implementation uses Heap Sort. It runs in constant + stack space. + + Specification of the comparison function: + Let [a] be the floatarray and [cmp] the comparison function. The following + must be true for all [x], [y], [z] in [a] : +- [cmp x y] > 0 if and only if [cmp y x] < 0 +- if [cmp x y] >= 0 and [cmp y z] >= 0 then [cmp x z] >= 0 + + When [sort] returns, [a] contains the same elements as before, + reordered in such a way that for all i and j valid indices of [a] : +- [cmp a.(i) a.(j)] >= 0 if and only if i >= j +*) + +val stable_sort : cmp:(float -> float -> int) -> t -> unit +(** Same as {!sort}, but the sorting algorithm is stable (i.e. + elements that compare equal are kept in their original order) and + not guaranteed to run in constant heap space. + + The current implementation uses Merge Sort. It uses a temporary + floatarray of length [n/2], where [n] is the length of the floatarray. + It is usually faster than the current implementation of {!sort}. *) + +val fast_sort : cmp:(float -> float -> int) -> t -> unit +(** Same as {!sort} or {!stable_sort}, whichever is faster + on typical input. *) + +(** {2 Iterators} *) + +val to_seq : t -> float Seq.t +(** Iterate on the floatarray, in increasing order. Modifications of the + floatarray during iteration will be reflected in the iterator. *) + +val to_seqi : t -> (int * float) Seq.t +(** Iterate on the floatarray, in increasing order, yielding indices along + elements. Modifications of the floatarray during iteration will be + reflected in the iterator. *) + +val of_seq : float Seq.t -> t +(** Create an array from the generator. *) + + +val map_to_array : f:(float -> 'a) -> t -> 'a array +(** [map_to_array ~f a] applies function [f] to all the elements of [a], + and builds an array with the results returned by [f]: + [[| f a.(0); f a.(1); ...; f a.(length a - 1) |]]. *) + +val map_from_array : f:('a -> float) -> 'a array -> t +(** [map_from_array ~f a] applies function [f] to all the elements of [a], + and builds a floatarray with the results returned by [f]. *) + +(**/**) + +(** {2 Undocumented functions} *) + +(* These functions are for system use only. Do not call directly. *) +external unsafe_get : t -> int -> float = "%floatarray_unsafe_get" +external unsafe_set : t -> int -> float -> unit = "%floatarray_unsafe_set" diff --git a/stdlib/templates/hashtbl.template.mli b/stdlib/templates/hashtbl.template.mli new file mode 100644 index 00000000..b63a2a3e --- /dev/null +++ b/stdlib/templates/hashtbl.template.mli @@ -0,0 +1,508 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* NOTE: If this file is hashtbl.mli, do not edit it directly! Instead, + edit templates/hashtbl.template.mli and run tools/sync_stdlib_docs *) + +(** Hash tables and hash functions. + + Hash tables are hashed association tables, with in-place modification. +*) + + +(** {1 Generic interface} *) + + +type (!'a, !'b) t +(** The type of hash tables from type ['a] to type ['b]. *) + +val create : ?random: (* thwart tools/sync_stdlib_docs *) bool -> + int -> ('a, 'b) t +(** [Hashtbl.create n] creates a new, empty hash table, with + initial size [n]. For best results, [n] should be on the + order of the expected number of elements that will be in + the table. The table grows as needed, so [n] is just an + initial guess. + + The optional [~][random] parameter (a boolean) controls whether + the internal organization of the hash table is randomized at each + execution of [Hashtbl.create] or deterministic over all executions. + + A hash table that is created with [~][random] set to [false] uses a + fixed hash function ({!hash}) to distribute keys among + buckets. As a consequence, collisions between keys happen + deterministically. In Web-facing applications or other + security-sensitive applications, the deterministic collision + patterns can be exploited by a malicious user to create a + denial-of-service attack: the attacker sends input crafted to + create many collisions in the table, slowing the application down. + + A hash table that is created with [~][random] set to [true] uses the seeded + hash function {!seeded_hash} with a seed that is randomly chosen at hash + table creation time. In effect, the hash function used is randomly + selected among [2^{30}] different hash functions. All these hash + functions have different collision patterns, rendering ineffective the + denial-of-service attack described above. However, because of + randomization, enumerating all elements of the hash table using {!fold} + or {!iter} is no longer deterministic: elements are enumerated in + different orders at different runs of the program. + + If no [~][random] parameter is given, hash tables are created + in non-random mode by default. This default can be changed + either programmatically by calling {!randomize} or by + setting the [R] flag in the [OCAMLRUNPARAM] environment variable. + + @before 4.00.0 the [~][random] parameter was not present and all + hash tables were created in non-randomized mode. *) + +val clear : ('a, 'b) t -> unit +(** Empty a hash table. Use [reset] instead of [clear] to shrink the + size of the bucket table to its initial size. *) + +val reset : ('a, 'b) t -> unit +(** Empty a hash table and shrink the size of the bucket table + to its initial size. + @since 4.00.0 *) + +val copy : ('a, 'b) t -> ('a, 'b) t +(** Return a copy of the given hashtable. *) + +val add : ('a, 'b) t -> key:'a -> data:'b -> unit +(** [Hashtbl.add tbl ~key ~data] adds a binding of [key] to [data] + in table [tbl]. + Previous bindings for [key] are not removed, but simply + hidden. That is, after performing {!remove}[ tbl key], + the previous binding for [key], if any, is restored. + (Same behavior as with association lists.) *) + +val find : ('a, 'b) t -> 'a -> 'b +(** [Hashtbl.find tbl x] returns the current binding of [x] in [tbl], + or raises [Not_found] if no such binding exists. *) + +val find_opt : ('a, 'b) t -> 'a -> 'b option +(** [Hashtbl.find_opt tbl x] returns the current binding of [x] in [tbl], + or [None] if no such binding exists. + @since 4.05 *) + +val find_all : ('a, 'b) t -> 'a -> 'b list +(** [Hashtbl.find_all tbl x] returns the list of all data + associated with [x] in [tbl]. + The current binding is returned first, then the previous + bindings, in reverse order of introduction in the table. *) + +val mem : ('a, 'b) t -> 'a -> bool +(** [Hashtbl.mem tbl x] checks if [x] is bound in [tbl]. *) + +val remove : ('a, 'b) t -> 'a -> unit +(** [Hashtbl.remove tbl x] removes the current binding of [x] in [tbl], + restoring the previous binding if it exists. + It does nothing if [x] is not bound in [tbl]. *) + +val replace : ('a, 'b) t -> key:'a -> data:'b -> unit +(** [Hashtbl.replace tbl ~key ~data] replaces the current binding of [key] + in [tbl] by a binding of [key] to [data]. If [key] is unbound in [tbl], + a binding of [key] to [data] is added to [tbl]. + This is functionally equivalent to {!remove}[ tbl key] + followed by {!add}[ tbl key data]. *) + +val iter : f:(key:'a -> data:'b -> unit) -> ('a, 'b) t -> unit +(** [Hashtbl.iter ~f tbl] applies [f] to all bindings in table [tbl]. + [f] receives the key as first argument, and the associated value + as second argument. Each binding is presented exactly once to [f]. + + The order in which the bindings are passed to [f] is unspecified. + However, if the table contains several bindings for the same key, + they are passed to [f] in reverse order of introduction, that is, + the most recent binding is passed first. + + If the hash table was created in non-randomized mode, the order + in which the bindings are enumerated is reproducible between + successive runs of the program, and even between minor versions + of OCaml. For randomized hash tables, the order of enumeration + is entirely random. + + The behavior is not defined if the hash table is modified + by [f] during the iteration. +*) + +val filter_map_inplace: f:(key:'a -> data:'b -> 'b option) -> ('a, 'b) t -> + unit +(** [Hashtbl.filter_map_inplace ~f tbl] applies [f] to all bindings in + table [tbl] and update each binding depending on the result of + [f]. If [f] returns [None], the binding is discarded. If it + returns [Some new_val], the binding is update to associate the key + to [new_val]. + + Other comments for {!iter} apply as well. + @since 4.03.0 *) + +val fold : f:(key:'a -> data:'b -> 'c -> 'c) -> ('a, 'b) t -> init:'c -> 'c +(** [Hashtbl.fold ~f tbl ~init] computes + [(f kN dN ... (f k1 d1 init)...)], + where [k1 ... kN] are the keys of all bindings in [tbl], + and [d1 ... dN] are the associated values. + Each binding is presented exactly once to [f]. + + The order in which the bindings are passed to [f] is unspecified. + However, if the table contains several bindings for the same key, + they are passed to [f] in reverse order of introduction, that is, + the most recent binding is passed first. + + If the hash table was created in non-randomized mode, the order + in which the bindings are enumerated is reproducible between + successive runs of the program, and even between minor versions + of OCaml. For randomized hash tables, the order of enumeration + is entirely random. + + The behavior is not defined if the hash table is modified + by [f] during the iteration. +*) + +val length : ('a, 'b) t -> int +(** [Hashtbl.length tbl] returns the number of bindings in [tbl]. + It takes constant time. Multiple bindings are counted once each, so + [Hashtbl.length] gives the number of times [Hashtbl.iter] calls its + first argument. *) + +val randomize : unit -> unit +(** After a call to [Hashtbl.randomize()], hash tables are created in + randomized mode by default: {!create} returns randomized + hash tables, unless the [~random:false] optional parameter is given. + The same effect can be achieved by setting the [R] parameter in + the [OCAMLRUNPARAM] environment variable. + + It is recommended that applications or Web frameworks that need to + protect themselves against the denial-of-service attack described + in {!create} call [Hashtbl.randomize()] at initialization + time. + + Note that once [Hashtbl.randomize()] was called, there is no way + to revert to the non-randomized default behavior of {!create}. + This is intentional. Non-randomized hash tables can still be + created using [Hashtbl.create ~random:false]. + + @since 4.00.0 *) + +val is_randomized : unit -> bool +(** Return [true] if the tables are currently created in randomized mode + by default, [false] otherwise. + @since 4.03.0 *) + +val rebuild : ?random (* thwart tools/sync_stdlib_docs *) :bool -> + ('a, 'b) t -> ('a, 'b) t +(** Return a copy of the given hashtable. Unlike {!copy}, + {!rebuild}[ h] re-hashes all the (key, value) entries of + the original table [h]. The returned hash table is randomized if + [h] was randomized, or the optional [random] parameter is true, or + if the default is to create randomized hash tables; see + {!create} for more information. + + {!rebuild} can safely be used to import a hash table built + by an old version of the {!Hashtbl} module, then marshaled to + persistent storage. After unmarshaling, apply {!rebuild} + to produce a hash table for the current version of the {!Hashtbl} + module. + + @since 4.12.0 *) + +(** @since 4.00.0 *) +type statistics = { + num_bindings: int; + (** Number of bindings present in the table. + Same value as returned by {!length}. *) + num_buckets: int; + (** Number of buckets in the table. *) + max_bucket_length: int; + (** Maximal number of bindings per bucket. *) + bucket_histogram: int array + (** Histogram of bucket sizes. This array [histo] has + length [max_bucket_length + 1]. The value of + [histo.(i)] is the number of buckets whose size is [i]. *) +} + +val stats : ('a, 'b) t -> statistics +(** [Hashtbl.stats tbl] returns statistics about the table [tbl]: + number of buckets, size of the biggest bucket, distribution of + buckets by size. + @since 4.00.0 *) + +(** {1 Iterators} *) + +val to_seq : ('a,'b) t -> ('a * 'b) Seq.t +(** Iterate on the whole table. The order in which the bindings + appear in the sequence is unspecified. However, if the table contains + several bindings for the same key, they appear in reversed order of + introduction, that is, the most recent binding appears first. + + The behavior is not defined if the hash table is modified + during the iteration. + + @since 4.07 *) + +val to_seq_keys : ('a,_) t -> 'a Seq.t +(** Same as [Seq.map fst (to_seq m)] + @since 4.07 *) + +val to_seq_values : (_,'b) t -> 'b Seq.t +(** Same as [Seq.map snd (to_seq m)] + @since 4.07 *) + +val add_seq : ('a,'b) t -> ('a * 'b) Seq.t -> unit +(** Add the given bindings to the table, using {!add} + @since 4.07 *) + +val replace_seq : ('a,'b) t -> ('a * 'b) Seq.t -> unit +(** Add the given bindings to the table, using {!replace} + @since 4.07 *) + +val of_seq : ('a * 'b) Seq.t -> ('a, 'b) t +(** Build a table from the given bindings. The bindings are added + in the same order they appear in the sequence, using {!replace_seq}, + which means that if two pairs have the same key, only the latest one + will appear in the table. + @since 4.07 *) + +(** {1 Functorial interface} *) + +(** The functorial interface allows the use of specific comparison + and hash functions, either for performance/security concerns, + or because keys are not hashable/comparable with the polymorphic builtins. + + For instance, one might want to specialize a table for integer keys: + {[ + module IntHash = + struct + type t = int + let equal i j = i=j + let hash i = i land max_int + end + + module IntHashtbl = Hashtbl.Make(IntHash) + + let h = IntHashtbl.create 17 in + IntHashtbl.add h 12 "hello" + ]} + + This creates a new module [IntHashtbl], with a new type ['a + IntHashtbl.t] of tables from [int] to ['a]. In this example, [h] + contains [string] values so its type is [string IntHashtbl.t]. + + Note that the new type ['a IntHashtbl.t] is not compatible with + the type [('a,'b) Hashtbl.t] of the generic interface. For + example, [Hashtbl.length h] would not type-check, you must use + [IntHashtbl.length]. +*) + +module type HashedType = + sig + type t + (** The type of the hashtable keys. *) + + val equal : t -> t -> bool + (** The equality predicate used to compare keys. *) + + val hash : t -> int + (** A hashing function on keys. It must be such that if two keys are + equal according to [equal], then they have identical hash values + as computed by [hash]. + Examples: suitable ([equal], [hash]) pairs for arbitrary key + types include +- ([(=)], {!hash}) for comparing objects by structure + (provided objects do not contain floats) +- ([(fun x y -> compare x y = 0)], {!hash}) + for comparing objects by structure + and handling {!Stdlib.nan} correctly +- ([(==)], {!hash}) for comparing objects by physical + equality (e.g. for mutable or cyclic objects). *) + end +(** The input signature of the functor {!Make}. *) + +module type S = + sig + type key + type !'a t + val create : int -> 'a t + val clear : 'a t -> unit + val reset : 'a t -> unit (** @since 4.00.0 *) + + val copy : 'a t -> 'a t + val add : 'a t -> key:key -> data:'a -> unit + val remove : 'a t -> key -> unit + val find : 'a t -> key -> 'a + val find_opt : 'a t -> key -> 'a option + (** @since 4.05.0 *) + + val find_all : 'a t -> key -> 'a list + val replace : 'a t -> key:key -> data:'a -> unit + val mem : 'a t -> key -> bool + val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit + val filter_map_inplace: f:(key:key -> data:'a -> 'a option) -> 'a t -> + unit + (** @since 4.03.0 *) + + val fold : f:(key:key -> data:'a -> 'b -> 'b) -> 'a t -> init:'b -> 'b + val length : 'a t -> int + val stats: 'a t -> statistics (** @since 4.00.0 *) + + val to_seq : 'a t -> (key * 'a) Seq.t + (** @since 4.07 *) + + val to_seq_keys : _ t -> key Seq.t + (** @since 4.07 *) + + val to_seq_values : 'a t -> 'a Seq.t + (** @since 4.07 *) + + val add_seq : 'a t -> (key * 'a) Seq.t -> unit + (** @since 4.07 *) + + val replace_seq : 'a t -> (key * 'a) Seq.t -> unit + (** @since 4.07 *) + + val of_seq : (key * 'a) Seq.t -> 'a t + (** @since 4.07 *) + end +(** The output signature of the functor {!Make}. *) + +module Make (H : HashedType) : S with type key = H.t +(** Functor building an implementation of the hashtable structure. + The functor [Hashtbl.Make] returns a structure containing + a type [key] of keys and a type ['a t] of hash tables + associating data of type ['a] to keys of type [key]. + The operations perform similarly to those of the generic + interface, but use the hashing and equality functions + specified in the functor argument [H] instead of generic + equality and hashing. Since the hash function is not seeded, + the [create] operation of the result structure always returns + non-randomized hash tables. *) + +module type SeededHashedType = + sig + type t + (** The type of the hashtable keys. *) + + val equal: t -> t -> bool + (** The equality predicate used to compare keys. *) + + val hash: int -> t -> int + (** A seeded hashing function on keys. The first argument is + the seed. It must be the case that if [equal x y] is true, + then [hash seed x = hash seed y] for any value of [seed]. + A suitable choice for [hash] is the function {!seeded_hash} + below. *) + end +(** The input signature of the functor {!MakeSeeded}. + @since 4.00.0 *) + +module type SeededS = + sig + type key + type !'a t + val create : ?random (* thwart tools/sync_stdlib_docs *) :bool -> + int -> 'a t + val clear : 'a t -> unit + val reset : 'a t -> unit + val copy : 'a t -> 'a t + val add : 'a t -> key:key -> data:'a -> unit + val remove : 'a t -> key -> unit + val find : 'a t -> key -> 'a + val find_opt : 'a t -> key -> 'a option (** @since 4.05.0 *) + + val find_all : 'a t -> key -> 'a list + val replace : 'a t -> key:key -> data:'a -> unit + val mem : 'a t -> key -> bool + val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit + val filter_map_inplace: f:(key:key -> data:'a -> 'a option) -> 'a t -> + unit + (** @since 4.03.0 *) + + val fold : f:(key:key -> data:'a -> 'b -> 'b) -> 'a t -> init:'b -> 'b + val length : 'a t -> int + val stats: 'a t -> statistics + + val to_seq : 'a t -> (key * 'a) Seq.t + (** @since 4.07 *) + + val to_seq_keys : _ t -> key Seq.t + (** @since 4.07 *) + + val to_seq_values : 'a t -> 'a Seq.t + (** @since 4.07 *) + + val add_seq : 'a t -> (key * 'a) Seq.t -> unit + (** @since 4.07 *) + + val replace_seq : 'a t -> (key * 'a) Seq.t -> unit + (** @since 4.07 *) + + val of_seq : (key * 'a) Seq.t -> 'a t + (** @since 4.07 *) + end +(** The output signature of the functor {!MakeSeeded}. + @since 4.00.0 *) + +module MakeSeeded (H : SeededHashedType) : SeededS with type key = H.t +(** Functor building an implementation of the hashtable structure. + The functor [Hashtbl.MakeSeeded] returns a structure containing + a type [key] of keys and a type ['a t] of hash tables + associating data of type ['a] to keys of type [key]. + The operations perform similarly to those of the generic + interface, but use the seeded hashing and equality functions + specified in the functor argument [H] instead of generic + equality and hashing. The [create] operation of the + result structure supports the [~][random] optional parameter + and returns randomized hash tables if [~random:true] is passed + or if randomization is globally on (see {!Hashtbl.randomize}). + @since 4.00.0 *) + + +(** {1 The polymorphic hash functions} *) + + +val hash : 'a -> int +(** [Hashtbl.hash x] associates a nonnegative integer to any value of + any type. It is guaranteed that + if [x = y] or [Stdlib.compare x y = 0], then [hash x = hash y]. + Moreover, [hash] always terminates, even on cyclic structures. *) + +val seeded_hash : int -> 'a -> int +(** A variant of {!hash} that is further parameterized by + an integer seed. + @since 4.00.0 *) + +val hash_param : int -> int -> 'a -> int +(** [Hashtbl.hash_param meaningful total x] computes a hash value for [x], + with the same properties as for [hash]. The two extra integer + parameters [meaningful] and [total] give more precise control over + hashing. Hashing performs a breadth-first, left-to-right traversal + of the structure [x], stopping after [meaningful] meaningful nodes + were encountered, or [total] nodes (meaningful or not) were + encountered. If [total] as specified by the user exceeds a certain + value, currently 256, then it is capped to that value. + Meaningful nodes are: integers; floating-point + numbers; strings; characters; booleans; and constant + constructors. Larger values of [meaningful] and [total] means that + more nodes are taken into account to compute the final hash value, + and therefore collisions are less likely to happen. However, + hashing takes longer. The parameters [meaningful] and [total] + govern the tradeoff between accuracy and speed. As default + choices, {!hash} and {!seeded_hash} take + [meaningful = 10] and [total = 100]. *) + +val seeded_hash_param : int -> int -> int -> 'a -> int +(** A variant of {!hash_param} that is further parameterized by + an integer seed. Usage: + [Hashtbl.seeded_hash_param meaningful total seed x]. + @since 4.00.0 *) diff --git a/stdlib/templates/map.template.mli b/stdlib/templates/map.template.mli new file mode 100644 index 00000000..8eb855d0 --- /dev/null +++ b/stdlib/templates/map.template.mli @@ -0,0 +1,361 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* NOTE: If this file is map.mli, do not edit it directly! Instead, + edit templates/map.template.mli and run tools/sync_stdlib_docs *) + +(** Association tables over ordered types. + + This module implements applicative association tables, also known as + finite maps or dictionaries, given a total ordering function + over the keys. + All operations over maps are purely applicative (no side-effects). + The implementation uses balanced binary trees, and therefore searching + and insertion take time logarithmic in the size of the map. + + For instance: + {[ + module IntPairs = + struct + type t = int * int + let compare (x0,y0) (x1,y1) = + match Stdlib.compare x0 x1 with + 0 -> Stdlib.compare y0 y1 + | c -> c + end + + module PairsMap = Map.Make(IntPairs) + + let m = PairsMap.(empty |> add (0,1) "hello" |> add (1,0) "world") + ]} + + This creates a new module [PairsMap], with a new type ['a PairsMap.t] + of maps from [int * int] to ['a]. In this example, [m] contains [string] + values so its type is [string PairsMap.t]. +*) + +module type OrderedType = + sig + type t + (** The type of the map keys. *) + + val compare : t -> t -> int + (** A total ordering function over the keys. + This is a two-argument function [f] such that + [f e1 e2] is zero if the keys [e1] and [e2] are equal, + [f e1 e2] is strictly negative if [e1] is smaller than [e2], + and [f e1 e2] is strictly positive if [e1] is greater than [e2]. + Example: a suitable ordering function is the generic structural + comparison function {!Stdlib.compare}. *) + end +(** Input signature of the functor {!Make}. *) + +module type S = + sig + type key + (** The type of the map keys. *) + + type !+'a t + (** The type of maps from type [key] to type ['a]. *) + + val empty: 'a t + (** The empty map. *) + + val is_empty: 'a t -> bool + (** Test whether a map is empty or not. *) + + val mem: key -> 'a t -> bool + (** [mem x m] returns [true] if [m] contains a binding for [x], + and [false] otherwise. *) + + val add: key:key -> data:'a -> 'a t -> 'a t + (** [add ~key ~data m] returns a map containing the same bindings as + [m], plus a binding of [key] to [data]. If [key] was already bound + in [m] to a value that is physically equal to [data], + [m] is returned unchanged (the result of the function is + then physically equal to [m]). Otherwise, the previous binding + of [key] in [m] disappears. + @before 4.03 Physical equality was not ensured. *) + + val update: key:key -> f:('a option -> 'a option) -> 'a t -> 'a t + (** [update ~key ~f m] returns a map containing the same bindings as + [m], except for the binding of [key]. Depending on the value of + [y] where [y] is [f (find_opt key m)], the binding of [key] is + added, removed or updated. If [y] is [None], the binding is + removed if it exists; otherwise, if [y] is [Some z] then [key] + is associated to [z] in the resulting map. If [key] was already + bound in [m] to a value that is physically equal to [z], [m] + is returned unchanged (the result of the function is then + physically equal to [m]). + @since 4.06.0 + *) + + val singleton: key -> 'a -> 'a t + (** [singleton x y] returns the one-element map that contains a binding + [y] for [x]. + @since 3.12.0 + *) + + val remove: key -> 'a t -> 'a t + (** [remove x m] returns a map containing the same bindings as + [m], except for [x] which is unbound in the returned map. + If [x] was not in [m], [m] is returned unchanged + (the result of the function is then physically equal to [m]). + @before 4.03 Physical equality was not ensured. *) + + val merge: + f:(key -> 'a option -> 'b option -> 'c option) -> + 'a t -> 'b t -> 'c t + (** [merge ~f m1 m2] computes a map whose keys are a subset of the keys of + [m1] and of [m2]. The presence of each such binding, and the + corresponding value, is determined with the function [f]. + In terms of the [find_opt] operation, we have + [find_opt x (merge f m1 m2) = f x (find_opt x m1) (find_opt x m2)] + for any key [x], provided that [f x None None = None]. + @since 3.12.0 + *) + + val union: f:(key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t + (** [union ~f m1 m2] computes a map whose keys are a subset of the keys + of [m1] and of [m2]. When the same binding is defined in both + arguments, the function [f] is used to combine them. + This is a special case of [merge]: [union f m1 m2] is equivalent + to [merge f' m1 m2], where + - [f' _key None None = None] + - [f' _key (Some v) None = Some v] + - [f' _key None (Some v) = Some v] + - [f' key (Some v1) (Some v2) = f key v1 v2] + + @since 4.03.0 + *) + + val compare: cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int + (** Total ordering between maps. The first argument is a total ordering + used to compare data associated with equal keys in the two maps. *) + + val equal: cmp:('a -> 'a -> bool) -> 'a t -> 'a t -> bool + (** [equal ~cmp m1 m2] tests whether the maps [m1] and [m2] are + equal, that is, contain equal keys and associate them with + equal data. [cmp] is the equality predicate used to compare + the data associated with the keys. *) + + val iter: f:(key:key -> data:'a -> unit) -> 'a t -> unit + (** [iter ~f m] applies [f] to all bindings in map [m]. + [f] receives the key as first argument, and the associated value + as second argument. The bindings are passed to [f] in increasing + order with respect to the ordering over the type of the keys. *) + + val fold: f:(key:key -> data:'a -> 'b -> 'b) -> 'a t -> init:'b -> 'b + (** [fold ~f m ~init] computes [(f kN dN ... (f k1 d1 init)...)], + where [k1 ... kN] are the keys of all bindings in [m] + (in increasing order), and [d1 ... dN] are the associated data. *) + + val for_all: f:(key -> 'a -> bool) -> 'a t -> bool + (** [for_all ~f m] checks if all the bindings of the map + satisfy the predicate [f]. + @since 3.12.0 + *) + + val exists: f:(key -> 'a -> bool) -> 'a t -> bool + (** [exists ~f m] checks if at least one binding of the map + satisfies the predicate [f]. + @since 3.12.0 + *) + + val filter: f:(key -> 'a -> bool) -> 'a t -> 'a t + (** [filter ~f m] returns the map with all the bindings in [m] + that satisfy predicate [p]. If every binding in [m] satisfies [f], + [m] is returned unchanged (the result of the function is then + physically equal to [m]) + @since 3.12.0 + @before 4.03 Physical equality was not ensured. + *) + + val filter_map: f:(key -> 'a -> 'b option) -> 'a t -> 'b t + (** [filter_map ~f m] applies the function [f] to every binding of + [m], and builds a map from the results. For each binding + [(k, v)] in the input map: + - if [f k v] is [None] then [k] is not in the result, + - if [f k v] is [Some v'] then the binding [(k, v')] + is in the output map. + + For example, the following function on maps whose values are lists + {[ + filter_map + (fun _k li -> match li with [] -> None | _::tl -> Some tl) + m + ]} + drops all bindings of [m] whose value is an empty list, and pops + the first element of each value that is non-empty. + + @since 4.11.0 + *) + + val partition: f:(key -> 'a -> bool) -> 'a t -> 'a t * 'a t + (** [partition ~f m] returns a pair of maps [(m1, m2)], where + [m1] contains all the bindings of [m] that satisfy the + predicate [f], and [m2] is the map with all the bindings of + [m] that do not satisfy [f]. + @since 3.12.0 + *) + + val cardinal: 'a t -> int + (** Return the number of bindings of a map. + @since 3.12.0 + *) + + val bindings: 'a t -> (key * 'a) list + (** Return the list of all bindings of the given map. + The returned list is sorted in increasing order of keys with respect + to the ordering [Ord.compare], where [Ord] is the argument + given to {!Make}. + @since 3.12.0 + *) + + val min_binding: 'a t -> (key * 'a) + (** Return the binding with the smallest key in a given map + (with respect to the [Ord.compare] ordering), or raise + [Not_found] if the map is empty. + @since 3.12.0 + *) + + val min_binding_opt: 'a t -> (key * 'a) option + (** Return the binding with the smallest key in the given map + (with respect to the [Ord.compare] ordering), or [None] + if the map is empty. + @since 4.05 + *) + + val max_binding: 'a t -> (key * 'a) + (** Same as {!S.min_binding}, but returns the binding with + the largest key in the given map. + @since 3.12.0 + *) + + val max_binding_opt: 'a t -> (key * 'a) option + (** Same as {!S.min_binding_opt}, but returns the binding with + the largest key in the given map. + @since 4.05 + *) + + val choose: 'a t -> (key * 'a) + (** Return one binding of the given map, or raise [Not_found] if + the map is empty. Which binding is chosen is unspecified, + but equal bindings will be chosen for equal maps. + @since 3.12.0 + *) + + val choose_opt: 'a t -> (key * 'a) option + (** Return one binding of the given map, or [None] if + the map is empty. Which binding is chosen is unspecified, + but equal bindings will be chosen for equal maps. + @since 4.05 + *) + + val split: key -> 'a t -> 'a t * 'a option * 'a t + (** [split x m] returns a triple [(l, data, r)], where + [l] is the map with all the bindings of [m] whose key + is strictly less than [x]; + [r] is the map with all the bindings of [m] whose key + is strictly greater than [x]; + [data] is [None] if [m] contains no binding for [x], + or [Some v] if [m] binds [v] to [x]. + @since 3.12.0 + *) + + val find: key -> 'a t -> 'a + (** [find x m] returns the current value of [x] in [m], + or raises [Not_found] if no binding for [x] exists. *) + + val find_opt: key -> 'a t -> 'a option + (** [find_opt x m] returns [Some v] if the current value of [x] + in [m] is [v], or [None] if no binding for [x] exists. + @since 4.05 + *) + + val find_first: f:(key -> bool) -> 'a t -> key * 'a + (** [find_first ~f m], where [f] is a monotonically increasing function, + returns the binding of [m] with the lowest key [k] such that [f k], + or raises [Not_found] if no such key exists. + + For example, [find_first (fun k -> Ord.compare k x >= 0) m] will return + the first binding [k, v] of [m] where [Ord.compare k x >= 0] + (intuitively: [k >= x]), or raise [Not_found] if [x] is greater than + any element of [m]. + + @since 4.05 + *) + + val find_first_opt: f:(key -> bool) -> 'a t -> (key * 'a) option + (** [find_first_opt ~f m], where [f] is a monotonically increasing + function, returns an option containing the binding of [m] with the + lowest key [k] such that [f k], or [None] if no such key exists. + @since 4.05 + *) + + val find_last: f:(key -> bool) -> 'a t -> key * 'a + (** [find_last ~f m], where [f] is a monotonically decreasing function, + returns the binding of [m] with the highest key [k] such that [f k], + or raises [Not_found] if no such key exists. + @since 4.05 + *) + + val find_last_opt: f:(key -> bool) -> 'a t -> (key * 'a) option + (** [find_last_opt ~f m], where [f] is a monotonically decreasing + function, returns an option containing the binding of [m] with + the highest key [k] such that [f k], or [None] if no such key + exists. + @since 4.05 + *) + + val map: f:('a -> 'b) -> 'a t -> 'b t + (** [map ~f m] returns a map with same domain as [m], where the + associated value [a] of all bindings of [m] has been + replaced by the result of the application of [f] to [a]. + The bindings are passed to [f] in increasing order + with respect to the ordering over the type of the keys. *) + + val mapi: f:(key -> 'a -> 'b) -> 'a t -> 'b t + (** Same as {!S.map}, but the function receives as arguments both the + key and the associated value for each binding of the map. *) + + (** {1 Iterators} *) + + val to_seq : 'a t -> (key * 'a) Seq.t + (** Iterate on the whole map, in ascending order of keys + @since 4.07 *) + + val to_rev_seq : 'a t -> (key * 'a) Seq.t + (** Iterate on the whole map, in descending order of keys + @since 4.12 *) + + val to_seq_from : key -> 'a t -> (key * 'a) Seq.t + (** [to_seq_from k m] iterates on a subset of the bindings of [m], + in ascending order of keys, from key [k] or above. + @since 4.07 *) + + val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t + (** Add the given bindings to the map, in order. + @since 4.07 *) + + val of_seq : (key * 'a) Seq.t -> 'a t + (** Build a map from the given bindings + @since 4.07 *) + end +(** Output signature of the functor {!Make}. *) + +module Make (Ord : OrderedType) : S with type key = Ord.t +(** Functor building an implementation of the map structure + given a totally ordered type. *) diff --git a/stdlib/templates/moreLabels.template.mli b/stdlib/templates/moreLabels.template.mli new file mode 100644 index 00000000..ee2cf484 --- /dev/null +++ b/stdlib/templates/moreLabels.template.mli @@ -0,0 +1,45 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Jacques Garrigue, Kyoto University RIMS *) +(* *) +(* Copyright 2001 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* NOTE: Do not edit this file directly. Edit templates/ and run + tools/sync_stdlib_docs *) + +(** Extra labeled libraries. + + This meta-module provides labelized versions of the {!Hashtbl}, {!Map} and + {!Set} modules. + + This module is intended to be used through [open MoreLabels] which replaces + {!Hashtbl}, {!Map}, and {!Set} with their labeled counterparts. + + For example: + {[ + open MoreLabels + + Hashtbl.iter ~f:(fun ~key ~data -> g key data) table + ]} +*) + +module Hashtbl : sig +HASHTBL +end + +module Map : sig +MAP +end + +module Set : sig +SET +end diff --git a/stdlib/templates/set.template.mli b/stdlib/templates/set.template.mli new file mode 100644 index 00000000..a48d1613 --- /dev/null +++ b/stdlib/templates/set.template.mli @@ -0,0 +1,313 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(* NOTE: If this file is set.mli, do not edit it directly! Instead, + edit templates/set.template.mli and run tools/sync_stdlib_docs *) + +(** Sets over ordered types. + + This module implements the set data structure, given a total ordering + function over the set elements. All operations over sets + are purely applicative (no side-effects). + The implementation uses balanced binary trees, and is therefore + reasonably efficient: insertion and membership take time + logarithmic in the size of the set, for instance. + + The {!Make} functor constructs implementations for any type, given a + [compare] function. + For instance: + {[ + module IntPairs = + struct + type t = int * int + let compare (x0,y0) (x1,y1) = + match Stdlib.compare x0 x1 with + 0 -> Stdlib.compare y0 y1 + | c -> c + end + + module PairsSet = Set.Make(IntPairs) + + let m = PairsSet.(empty |> add (2,3) |> add (5,7) |> add (11,13)) + ]} + + This creates a new module [PairsSet], with a new type [PairsSet.t] + of sets of [int * int]. +*) + +module type OrderedType = + sig + type t + (** The type of the set elements. *) + + val compare : t -> t -> int + (** A total ordering function over the set elements. + This is a two-argument function [f] such that + [f e1 e2] is zero if the elements [e1] and [e2] are equal, + [f e1 e2] is strictly negative if [e1] is smaller than [e2], + and [f e1 e2] is strictly positive if [e1] is greater than [e2]. + Example: a suitable ordering function is the generic structural + comparison function {!Stdlib.compare}. *) + end +(** Input signature of the functor {!Make}. *) + +module type S = + sig + type elt + (** The type of the set elements. *) + + type t + (** The type of sets. *) + + val empty: t + (** The empty set. *) + + val is_empty: t -> bool + (** Test whether a set is empty or not. *) + + val mem: elt -> t -> bool + (** [mem x s] tests whether [x] belongs to the set [s]. *) + + val add: elt -> t -> t + (** [add x s] returns a set containing all elements of [s], + plus [x]. If [x] was already in [s], [s] is returned unchanged + (the result of the function is then physically equal to [s]). + @before 4.03 Physical equality was not ensured. *) + + val singleton: elt -> t + (** [singleton x] returns the one-element set containing only [x]. *) + + val remove: elt -> t -> t + (** [remove x s] returns a set containing all elements of [s], + except [x]. If [x] was not in [s], [s] is returned unchanged + (the result of the function is then physically equal to [s]). + @before 4.03 Physical equality was not ensured. *) + + val union: t -> t -> t + (** Set union. *) + + val inter: t -> t -> t + (** Set intersection. *) + + val disjoint: t -> t -> bool + (** Test if two sets are disjoint. + @since 4.08.0 *) + + val diff: t -> t -> t + (** Set difference: [diff s1 s2] contains the elements of [s1] + that are not in [s2]. *) + + val compare: t -> t -> int + (** Total ordering between sets. Can be used as the ordering function + for doing sets of sets. *) + + val equal: t -> t -> bool + (** [equal s1 s2] tests whether the sets [s1] and [s2] are + equal, that is, contain equal elements. *) + + val subset: t -> t -> bool + (** [subset s1 s2] tests whether the set [s1] is a subset of + the set [s2]. *) + + val iter: f:(elt -> unit) -> t -> unit + (** [iter ~f s] applies [f] in turn to all elements of [s]. + The elements of [s] are presented to [f] in increasing order + with respect to the ordering over the type of the elements. *) + + val map: f:(elt -> elt) -> t -> t + (** [map ~f s] is the set whose elements are [f a0],[f a1]... [f + aN], where [a0],[a1]...[aN] are the elements of [s]. + + The elements are passed to [f] in increasing order + with respect to the ordering over the type of the elements. + + If no element of [s] is changed by [f], [s] is returned + unchanged. (If each output of [f] is physically equal to its + input, the returned set is physically equal to [s].) + @since 4.04.0 *) + + val fold: f:(elt -> 'a -> 'a) -> t -> init:'a -> 'a + (** [fold ~f s init] computes [(f xN ... (f x2 (f x1 init))...)], + where [x1 ... xN] are the elements of [s], in increasing order. *) + + val for_all: f:(elt -> bool) -> t -> bool + (** [for_all ~f s] checks if all elements of the set + satisfy the predicate [f]. *) + + val exists: f:(elt -> bool) -> t -> bool + (** [exists ~f s] checks if at least one element of + the set satisfies the predicate [f]. *) + + val filter: f:(elt -> bool) -> t -> t + (** [filter ~f s] returns the set of all elements in [s] + that satisfy predicate [f]. If [f] satisfies every element in [s], + [s] is returned unchanged (the result of the function is then + physically equal to [s]). + @before 4.03 Physical equality was not ensured.*) + + val filter_map: f:(elt -> elt option) -> t -> t + (** [filter_map ~f s] returns the set of all [v] such that + [f x = Some v] for some element [x] of [s]. + + For example, + {[filter_map (fun n -> if n mod 2 = 0 then Some (n / 2) else None) s]} + is the set of halves of the even elements of [s]. + + If no element of [s] is changed or dropped by [f] (if + [f x = Some x] for each element [x]), then + [s] is returned unchanged: the result of the function + is then physically equal to [s]. + + @since 4.11.0 + *) + + val partition: f:(elt -> bool) -> t -> t * t + (** [partition ~f s] returns a pair of sets [(s1, s2)], where + [s1] is the set of all the elements of [s] that satisfy the + predicate [f], and [s2] is the set of all the elements of + [s] that do not satisfy [f]. *) + + val cardinal: t -> int + (** Return the number of elements of a set. *) + + val elements: t -> elt list + (** Return the list of all elements of the given set. + The returned list is sorted in increasing order with respect + to the ordering [Ord.compare], where [Ord] is the argument + given to {!Make}. *) + + val min_elt: t -> elt + (** Return the smallest element of the given set + (with respect to the [Ord.compare] ordering), or raise + [Not_found] if the set is empty. *) + + val min_elt_opt: t -> elt option + (** Return the smallest element of the given set + (with respect to the [Ord.compare] ordering), or [None] + if the set is empty. + @since 4.05 + *) + + val max_elt: t -> elt + (** Same as {!S.min_elt}, but returns the largest element of the + given set. *) + + val max_elt_opt: t -> elt option + (** Same as {!S.min_elt_opt}, but returns the largest element of the + given set. + @since 4.05 + *) + + val choose: t -> elt + (** Return one element of the given set, or raise [Not_found] if + the set is empty. Which element is chosen is unspecified, + but equal elements will be chosen for equal sets. *) + + val choose_opt: t -> elt option + (** Return one element of the given set, or [None] if + the set is empty. Which element is chosen is unspecified, + but equal elements will be chosen for equal sets. + @since 4.05 + *) + + val split: elt -> t -> t * bool * t + (** [split x s] returns a triple [(l, present, r)], where + [l] is the set of elements of [s] that are + strictly less than [x]; + [r] is the set of elements of [s] that are + strictly greater than [x]; + [present] is [false] if [s] contains no element equal to [x], + or [true] if [s] contains an element equal to [x]. *) + + val find: elt -> t -> elt + (** [find x s] returns the element of [s] equal to [x] (according + to [Ord.compare]), or raise [Not_found] if no such element + exists. + @since 4.01.0 *) + + val find_opt: elt -> t -> elt option + (** [find_opt x s] returns the element of [s] equal to [x] (according + to [Ord.compare]), or [None] if no such element + exists. + @since 4.05 *) + + val find_first: f:(elt -> bool) -> t -> elt + (** [find_first ~f s], where [f] is a monotonically increasing function, + returns the lowest element [e] of [s] such that [f e], + or raises [Not_found] if no such element exists. + + For example, [find_first (fun e -> Ord.compare e x >= 0) s] will return + the first element [e] of [s] where [Ord.compare e x >= 0] (intuitively: + [e >= x]), or raise [Not_found] if [x] is greater than any element of + [s]. + + @since 4.05 + *) + + val find_first_opt: f:(elt -> bool) -> t -> elt option + (** [find_first_opt ~f s], where [f] is a monotonically increasing + function, returns an option containing the lowest element [e] of [s] + such that [f e], or [None] if no such element exists. + @since 4.05 + *) + + val find_last: f:(elt -> bool) -> t -> elt + (** [find_last ~f s], where [f] is a monotonically decreasing function, + returns the highest element [e] of [s] such that [f e], + or raises [Not_found] if no such element exists. + @since 4.05 + *) + + val find_last_opt: f:(elt -> bool) -> t -> elt option + (** [find_last_opt ~f s], where [f] is a monotonically decreasing + function, returns an option containing the highest element [e] of [s] + such that [f e], or [None] if no such element exists. + @since 4.05 + *) + + val of_list: elt list -> t + (** [of_list l] creates a set from a list of elements. + This is usually more efficient than folding [add] over the list, + except perhaps for lists with many duplicated elements. + @since 4.02.0 *) + + (** {1 Iterators} *) + + val to_seq_from : elt -> t -> elt Seq.t + (** [to_seq_from x s] iterates on a subset of the elements of [s] + in ascending order, from [x] or above. + @since 4.07 *) + + val to_seq : t -> elt Seq.t + (** Iterate on the whole set, in ascending order + @since 4.07 *) + + val to_rev_seq : t -> elt Seq.t + (** Iterate on the whole set, in descending order + @since 4.12 *) + + val add_seq : elt Seq.t -> t -> t + (** Add the given elements to the set, in order. + @since 4.07 *) + + val of_seq : elt Seq.t -> t + (** Build a set from the given bindings + @since 4.07 *) + end +(** Output signature of the functor {!Make}. *) + +module Make (Ord : OrderedType) : S with type elt = Ord.t +(** Functor building an implementation of the set structure + given a totally ordered type. *) diff --git a/stdlib/uchar.mli b/stdlib/uchar.mli index 8ce7a35a..0eca719b 100644 --- a/stdlib/uchar.mli +++ b/stdlib/uchar.mli @@ -58,7 +58,7 @@ val pred : t -> t @raise Invalid_argument if [u] is {!min}. *) val is_valid : int -> bool -(** [is_valid n] is [true] iff [n] is a Unicode scalar value +(** [is_valid n] is [true] if and only if [n] is a Unicode scalar value (i.e. in the ranges [0x0000]...[0xD7FF] or [0xE000]...[0x10FFFF]).*) val of_int : int -> t @@ -74,7 +74,7 @@ val to_int : t -> int (** [to_int u] is [u] as an integer. *) val is_char : t -> bool -(** [is_char u] is [true] iff [u] is a latin1 OCaml character. *) +(** [is_char u] is [true] if and only if [u] is a latin1 OCaml character. *) val of_char : char -> t (** [of_char c] is [c] as a Unicode character. *) diff --git a/stdlib/weak.ml b/stdlib/weak.ml index 1746574f..7816ffd4 100644 --- a/stdlib/weak.ml +++ b/stdlib/weak.ml @@ -15,7 +15,7 @@ (** Weak array operations *) -type 'a t +type !'a t external create : int -> 'a t = "caml_weak_create" diff --git a/stdlib/weak.mli b/stdlib/weak.mli index 878e590a..bf74525b 100644 --- a/stdlib/weak.mli +++ b/stdlib/weak.mli @@ -18,7 +18,7 @@ (** {1 Low-level functions} *) -type 'a t +type !'a t (** The type of arrays of weak pointers (weak arrays). A weak pointer is a value that the garbage collector may erase whenever the value is not used any more (through normal pointers) by the diff --git a/testsuite/Makefile b/testsuite/Makefile index 5cd2d6df..866521af 100644 --- a/testsuite/Makefile +++ b/testsuite/Makefile @@ -16,8 +16,6 @@ .NOTPARALLEL: BASEDIR := $(shell pwd) -NO_PRINT=`$(MAKE) empty --no-print-directory >/dev/null 2>&1 \ - && echo --no-print-directory` FIND=find TOPDIR := .. @@ -54,14 +52,19 @@ else # Windows endif endif -ifeq "$(FLEXLINK_ENV)" "" - ocamltest := MKDLL="$(MKDLL)" SORT=$(SORT) MAKE=$(MAKE) $(ocamltest_program) +ifeq "$(ocamltest_program)" "" + ocamltest = $(error ocamltest not found in $(ocamltest_directory)) else - MKDLL=$(WINTOPDIR)/boot/ocamlrun $(WINTOPDIR)/flexdll/flexlink.exe \ - $(FLEXLINK_FLAGS) + ifeq "$(FLEXLINK_ENV)" "" + ocamltest := MKDLL="$(MKDLL)" SORT=$(SORT) MAKE=$(MAKE) $(ocamltest_program) + else + FLEXLINK_DLL_LDFLAGS=$(if $(OC_DLL_LDFLAGS), -link "$(OC_DLL_LDFLAGS)") + MKDLL=$(WINTOPDIR)/boot/ocamlrun $(WINTOPDIR)/flexdll/flexlink.exe \ + $(FLEXLINK_FLAGS) $(FLEXLINK_DLL_LDFLAGS) - ocamltest := $(FLEXLINK_ENV) MKDLL="$(MKDLL)" SORT=$(SORT) MAKE=$(MAKE) \ - $(ocamltest_program) + ocamltest := $(FLEXLINK_ENV) MKDLL="$(MKDLL)" SORT=$(SORT) MAKE=$(MAKE) \ + $(ocamltest_program) + endif endif # PROMOTE is only meant to be used internally in recursive calls; @@ -75,7 +78,7 @@ endif # KEEP_TEST_DIR_ON_SUCCESS should be set by the user (to a non-empty value) # if they want to pass the -keep-test-dir-on-success option to ocamltest, -# to preserve test data of succesful tests. +# to preserve test data of successful tests. KEEP_TEST_DIR_ON_SUCCESS ?= ifeq "$(KEEP_TEST_DIR_ON_SUCCESS)" "" OCAMLTEST_KEEP_TEST_DIR_ON_SUCCESS_FLAG := @@ -95,8 +98,9 @@ default: @echo " parallel launch all tests using GNU parallel" @echo " parallel-foo launch all tests beginning with foo using \ GNU parallel" - @echo " list FILE=f launch the tests listed in f (one per line)" + @echo " one TEST=f launch just this single test" @echo " one DIR=p launch the tests located in path p" + @echo " one LIST=f launch the tests listed in f (one per line)" @echo " promote DIR=p promote the reference files for the tests in p" @echo " lib build library modules" @echo " tools build test tools" @@ -110,14 +114,14 @@ default: .PHONY: all all: @rm -f $(TESTLOG) - @$(MAKE) $(NO_PRINT) new-without-report - @$(MAKE) $(NO_PRINT) report + @$(MAKE) --no-print-directory new-without-report + @$(MAKE) --no-print-directory report .PHONY: new-without-report new-without-report: lib tools @rm -f $(failstamp) @(IFS=$$(printf "\r\n"); \ - $(ocamltest) -find-test-dirs tests | while read dir; do \ + $(ocamltest) -find-test-dirs tests | while IFS='' read -r dir; do \ echo Running tests from \'$$dir\' ... ; \ $(MAKE) exec-ocamltest DIR=$$dir \ OCAMLTESTENV=""; \ @@ -136,9 +140,8 @@ check-failstamp: .PHONY: all-% all-%: lib tools @for dir in tests/$**; do \ - $(MAKE) $(NO_PRINT) exec-one DIR=$$dir; \ + $(MAKE) --no-print-directory exec-one DIR=$$dir; \ done 2>&1 | tee $(TESTLOG) - @$(MAKE) $(NO_PRINT) retries @$(MAKE) report # The targets below use GNU parallel to parallelize tests @@ -177,9 +180,8 @@ parallel-%: lib tools exit 1) @for dir in tests/$**; do echo $$dir; done \ | parallel --gnu --no-notice --keep-order \ - "$(MAKE) $(NO_PRINT) exec-one DIR={} 2>&1" \ + "$(MAKE) --no-print-directory exec-one DIR={} 2>&1" \ | tee $(TESTLOG) - @$(MAKE) $(NO_PRINT) retries @$(MAKE) report .PHONY: parallel @@ -188,27 +190,37 @@ parallel: parallel-* .PHONY: list list: lib tools @if [ -z "$(FILE)" ]; \ - then echo "No value set for variable 'FILE'."; \ - exit 1; \ - fi - @while read LINE; do \ - $(MAKE) $(NO_PRINT) exec-one DIR=$$LINE; \ - done <$(FILE) 2>&1 | tee $(TESTLOG) - @$(MAKE) $(NO_PRINT) retries - @$(MAKE) report + then echo "No value set for variable 'FILE'."; \ + exit 1; \ + fi + @$(MAKE) --no-print-directory one LIST="$(FILE)" .PHONY: one one: lib tools - @if [ -z "$(DIR)" ]; then \ - echo "No value set for variable 'DIR'."; \ - exit 1; \ - fi - @if [ ! -d $(DIR) ]; then \ - echo "Directory '$(DIR)' does not exist."; \ - exit 1; \ - fi - @$(MAKE) $(NO_PRINT) exec-one DIR=$(DIR) + @case "$(words $(DIR) $(LIST) $(TEST))" in \ + 0) echo 'No value set for variable DIR, LIST or TEST'>&2; exit 1;; \ + 1) exit 0;; \ + *) echo 'Please specify just one of DIR, LIST or TEST'>&2; exit 1;; \ + esac + @if [ -n '$(DIR)' ] && [ ! -d '$(DIR)' ]; then \ + echo "Directory '$(DIR)' does not exist."; exit 1; \ + fi + @if [ -n '$(TEST)' ] && [ ! -e '$(TEST)' ]; then \ + echo "Test '$(TEST)' does not exist."; exit 1; \ + fi + @if [ -n '$(LIST)' ] && [ ! -e '$(LIST)' ]; then \ + echo "File '$(LIST)' does not exist."; exit 1; \ + fi + @if [ -n '$(DIR)' ] ; then \ + $(MAKE) --no-print-directory exec-one DIR=$(DIR); fi + @if [ -n '$(TEST)' ] ; then \ + TERM=dumb $(OCAMLTESTENV) $(ocamltest) $(OCAMLTESTFLAGS) $(TEST); fi @$(MAKE) check-failstamp + @if [ -n '$(LIST)' ] ; then \ + while IFS='' read -r LINE; do \ + $(MAKE) --no-print-directory exec-one DIR=$$LINE ; \ + done < $$LIST 2>&1 | tee $(TESTLOG) ; \ + $(MAKE) report ; fi .PHONY: exec-one exec-one: @@ -229,7 +241,7 @@ exec-ocamltest: @if [ -z "$(DIR)" ]; then exit 1; fi @if [ ! -d "$(DIR)" ]; then exit 1; fi @(IFS=$$(printf "\r\n"); \ - $(ocamltest) -list-tests $(DIR) | while read testfile; do \ + $(ocamltest) -list-tests $(DIR) | while IFS='' read -r testfile; do \ TERM=dumb $(OCAMLTESTENV) \ $(ocamltest) $(OCAMLTESTFLAGS) $(DIR)/$$testfile || \ echo " ... testing '$$testfile' => unexpected error"; \ @@ -284,24 +296,3 @@ clean: report: @if [ ! -f $(TESTLOG) ]; then echo "No $(TESTLOG) file."; exit 1; fi @$(AWK) -f ./summarize.awk < $(TESTLOG) - -.PHONY: retry-list -retry-list: - @while read LINE; do \ - if [ -n "$$LINE" ] ; then \ - echo re-ran $$LINE>> $(TESTLOG); \ - $(MAKE) $(NO_PRINT) clean-one DIR=$$LINE; \ - $(MAKE) $(NO_PRINT) exec-one DIR=$$LINE 2>&1 | tee -a $(TESTLOG) ; \ - fi \ - done <_retries; - @$(MAKE) $(NO_PRINT) retries - -.PHONY: retries -retries: - @$(AWK) -v retries=1 -v max_retries=$(MAX_TESTSUITE_DIR_RETRIES) \ - -f ./summarize.awk < $(TESTLOG) > _retries - @test `cat _retries | wc -l` -eq 0 || $(MAKE) $(NO_PRINT) retry-list - @rm -f _retries - -.PHONY: empty -empty: diff --git a/testsuite/summarize.awk b/testsuite/summarize.awk index b185c672..adf24c9a 100644 --- a/testsuite/summarize.awk +++ b/testsuite/summarize.awk @@ -70,6 +70,10 @@ function record_unexp() { clear(); } +/^> / { + next; +} + /Running tests from '[^']*'/ { if (in_test) record_unexp(); match($0, /Running tests from '[^']*'/); @@ -140,88 +144,74 @@ END { printf ("\n#### Some fatal error occurred during testing.\n\n"); exit (3); }else{ - if (!retries){ - for (key in SKIPPED){ - if (!SKIPPED[key]){ - ++ empty; - blanks[emptyidx++] = key; - delete SKIPPED[key]; - } - } - for (key in RESULTS){ - r = RESULTS[key]; - if (r == "p"){ - ++ passed; - }else if (r == "f"){ - ++ failed; - fail[failidx++] = key; - }else if (r == "e"){ - ++ unexped; - unexp[unexpidx++] = key; - }else if (r == "s"){ - ++ skipped; - curdir = DIRS[key]; - if (curdir in SKIPPED){ - if (SKIPPED[curdir]){ - SKIPPED[curdir] = 0; - skips[skipidx++] = curdir; - } - }else{ - skips[skipidx++] = key; - } - }else if (r == "n"){ - ++ ignored; - } - } - printf("\n"); - if (skipped != 0){ - printf("\nList of skipped tests:\n"); - for (i=0; i < skipidx; i++) printf(" %s\n", skips[i]); - } - if (empty != 0){ - printf("\nList of directories returning no results:\n"); - for (i=0; i < empty; i++) printf(" %s\n", blanks[i]); - } - if (failed != 0){ - printf("\nList of failed tests:\n"); - for (i=0; i < failed; i++) printf(" %s\n", fail[i]); - } - if (unexped != 0){ - printf("\nList of unexpected errors:\n"); - for (i=0; i < unexped; i++) printf(" %s\n", unexp[i]); - } - printf("\n"); - printf("Summary:\n"); - printf(" %3d tests passed\n", passed); - printf(" %3d tests skipped\n", skipped); - printf(" %3d tests failed\n", failed); - printf(" %3d tests not started (parent test skipped or failed)\n", - ignored); - printf(" %3d unexpected errors\n", unexped); - printf(" %3d tests considered", nresults); - if (nresults != passed + skipped + ignored + failed + unexped){ - printf (" (totals don't add up??)"); + for (key in SKIPPED){ + if (!SKIPPED[key]){ + ++ empty; + blanks[emptyidx++] = key; + delete SKIPPED[key]; } - printf ("\n"); - if (reran != 0){ - printf(" %3d test dir re-runs\n", reran); - } - if (failed || unexped){ - printf("#### Something failed. Exiting with error status.\n\n"); - exit 4; - } - }else{ - for (key in RESULTS){ - if (RESULTS[key] == "f" || RESULTS[key] == "e"){ - key = DIRS[key]; - if (!(key in RERUNS)){ - RERUNS[key] = 1; - if (RERAN[key] < max_retries){ - printf("%s\n", key); - } + } + for (key in RESULTS){ + r = RESULTS[key]; + if (r == "p"){ + ++ passed; + }else if (r == "f"){ + ++ failed; + fail[failidx++] = key; + }else if (r == "e"){ + ++ unexped; + unexp[unexpidx++] = key; + }else if (r == "s"){ + ++ skipped; + curdir = DIRS[key]; + if (curdir in SKIPPED){ + if (SKIPPED[curdir]){ + SKIPPED[curdir] = 0; + skips[skipidx++] = curdir; } + }else{ + skips[skipidx++] = key; } + }else if (r == "n"){ + ++ ignored; } } + printf("\n"); + if (skipped != 0){ + printf("\nList of skipped tests:\n"); + for (i=0; i < skipidx; i++) printf(" %s\n", skips[i]); + } + if (empty != 0){ + printf("\nList of directories returning no results:\n"); + for (i=0; i < empty; i++) printf(" %s\n", blanks[i]); + } + if (failed != 0){ + printf("\nList of failed tests:\n"); + for (i=0; i < failed; i++) printf(" %s\n", fail[i]); + } + if (unexped != 0){ + printf("\nList of unexpected errors:\n"); + for (i=0; i < unexped; i++) printf(" %s\n", unexp[i]); + } + printf("\n"); + printf("Summary:\n"); + printf(" %3d tests passed\n", passed); + printf(" %3d tests skipped\n", skipped); + printf(" %3d tests failed\n", failed); + printf(" %3d tests not started (parent test skipped or failed)\n", + ignored); + printf(" %3d unexpected errors\n", unexped); + printf(" %3d tests considered", nresults); + if (nresults != passed + skipped + ignored + failed + unexped){ + printf (" (totals don't add up??)"); + } + printf ("\n"); + if (reran != 0){ + printf(" %3d test dir re-runs\n", reran); + } + if (failed || unexped){ + printf("#### Something failed. Exiting with error status.\n\n"); + exit 4; + } } } diff --git a/testsuite/tests/asmcomp/0001-test.compilers.reference b/testsuite/tests/asmcomp/0001-test.compilers.reference index c2c5166b..caa67d4c 100644 --- a/testsuite/tests/asmcomp/0001-test.compilers.reference +++ b/testsuite/tests/asmcomp/0001-test.compilers.reference @@ -1,2 +1,2 @@ File "0001-test.ml", line 1: -Warning 24: bad source file name: "0001-test" is not a valid module name. +Warning 24 [bad-module-name]: bad source file name: "0001-test" is not a valid module name. diff --git a/testsuite/tests/asmcomp/is_static.ml b/testsuite/tests/asmcomp/is_static.ml index 60263692..b8a3bef0 100644 --- a/testsuite/tests/asmcomp/is_static.ml +++ b/testsuite/tests/asmcomp/is_static.ml @@ -1,6 +1,7 @@ (* TEST modules = "is_in_static_data.c" - * native + * naked_pointers + ** native *) (* Data that should be statically allocated by the compiler (all versions) *) diff --git a/testsuite/tests/asmcomp/is_static_flambda.ml b/testsuite/tests/asmcomp/is_static_flambda.ml index 7ddf7e92..63e53cfc 100644 --- a/testsuite/tests/asmcomp/is_static_flambda.ml +++ b/testsuite/tests/asmcomp/is_static_flambda.ml @@ -1,7 +1,8 @@ (* TEST modules = "is_in_static_data.c is_static_flambda_dep.ml" * flambda - ** native + ** naked_pointers + *** native *) (* Data that should be statically allocated by the compiler (flambda only) *) diff --git a/testsuite/tests/asmcomp/optargs.ml b/testsuite/tests/asmcomp/optargs.ml index ccc27dcb..65e4152b 100644 --- a/testsuite/tests/asmcomp/optargs.ml +++ b/testsuite/tests/asmcomp/optargs.ml @@ -1,6 +1,5 @@ (* TEST flags = "-g" - compare_programs = "false" * native *) diff --git a/testsuite/tests/asmcomp/static_float_array_flambda.ml b/testsuite/tests/asmcomp/static_float_array_flambda.ml index 8401ca1e..824a12ca 100644 --- a/testsuite/tests/asmcomp/static_float_array_flambda.ml +++ b/testsuite/tests/asmcomp/static_float_array_flambda.ml @@ -2,7 +2,8 @@ modules = "is_in_static_data.c simple_float_const.ml" * flambda ** flat-float-array - *** native + *** naked_pointers + **** native *) external is_in_static_data : 'a -> bool = "caml_is_in_static_data" diff --git a/testsuite/tests/asmcomp/static_float_array_flambda_opaque.ml b/testsuite/tests/asmcomp/static_float_array_flambda_opaque.ml index 63c08c1b..56ea9e17 100644 --- a/testsuite/tests/asmcomp/static_float_array_flambda_opaque.ml +++ b/testsuite/tests/asmcomp/static_float_array_flambda_opaque.ml @@ -3,7 +3,8 @@ flags = "-opaque" * flambda ** flat-float-array - *** native + *** naked_pointers + **** native *) external is_in_static_data : 'a -> bool = "caml_is_in_static_data" diff --git a/testsuite/tests/asmgen/immediates.cmm b/testsuite/tests/asmgen/immediates.cmm new file mode 100644 index 00000000..40fceda4 --- /dev/null +++ b/testsuite/tests/asmgen/immediates.cmm @@ -0,0 +1,48 @@ +(* TEST +files = "mainimmed.c" +arguments = "-I ${test_source_directory} mainimmed.c" +* asmgen +*) +(* Regenerate with cpp -P immediates.cmmpp > immediates.cmm *) +(function "testimm" () + (let x (load int "X") + (let r "R" + (letmut i int 0 +(addraset r i (+ x 0)) (assign i (+ i 1)) (addraset r i (- x 0)) (assign i (+ i 1)) (addraset r i ( * x 0)) (assign i (+ i 1)) (addraset r i (and x 0)) (assign i (+ i 1)) (addraset r i (or x 0)) (assign i (+ i 1)) (addraset r i (xor x 0)) (assign i (+ i 1)) (addraset r i (< x 0)) (assign i (+ i 1)) (checkbound i 0) +(addraset r i (+ x 1)) (assign i (+ i 1)) (addraset r i (- x 1)) (assign i (+ i 1)) (addraset r i ( * x 1)) (assign i (+ i 1)) (addraset r i (and x 1)) (assign i (+ i 1)) (addraset r i (or x 1)) (assign i (+ i 1)) (addraset r i (xor x 1)) (assign i (+ i 1)) (addraset r i (< x 1)) (assign i (+ i 1)) (checkbound i 1) +(addraset r i (+ x 0xFF)) (assign i (+ i 1)) (addraset r i (- x 0xFF)) (assign i (+ i 1)) (addraset r i ( * x 0xFF)) (assign i (+ i 1)) (addraset r i (and x 0xFF)) (assign i (+ i 1)) (addraset r i (or x 0xFF)) (assign i (+ i 1)) (addraset r i (xor x 0xFF)) (assign i (+ i 1)) (addraset r i (< x 0xFF)) (assign i (+ i 1)) (checkbound i 0xFF) +(addraset r i (+ x 0x100)) (assign i (+ i 1)) (addraset r i (- x 0x100)) (assign i (+ i 1)) (addraset r i ( * x 0x100)) (assign i (+ i 1)) (addraset r i (and x 0x100)) (assign i (+ i 1)) (addraset r i (or x 0x100)) (assign i (+ i 1)) (addraset r i (xor x 0x100)) (assign i (+ i 1)) (addraset r i (< x 0x100)) (assign i (+ i 1)) (checkbound i 0x100) +(addraset r i (+ x 0x3FC)) (assign i (+ i 1)) (addraset r i (- x 0x3FC)) (assign i (+ i 1)) (addraset r i ( * x 0x3FC)) (assign i (+ i 1)) (addraset r i (and x 0x3FC)) (assign i (+ i 1)) (addraset r i (or x 0x3FC)) (assign i (+ i 1)) (addraset r i (xor x 0x3FC)) (assign i (+ i 1)) (addraset r i (< x 0x3FC)) (assign i (+ i 1)) (checkbound i 0x3FC) +(addraset r i (+ x 0x3FF)) (assign i (+ i 1)) (addraset r i (- x 0x3FF)) (assign i (+ i 1)) (addraset r i ( * x 0x3FF)) (assign i (+ i 1)) (addraset r i (and x 0x3FF)) (assign i (+ i 1)) (addraset r i (or x 0x3FF)) (assign i (+ i 1)) (addraset r i (xor x 0x3FF)) (assign i (+ i 1)) (addraset r i (< x 0x3FF)) (assign i (+ i 1)) (checkbound i 0x3FF) +(addraset r i (+ x 0x7FF)) (assign i (+ i 1)) (addraset r i (- x 0x7FF)) (assign i (+ i 1)) (addraset r i ( * x 0x7FF)) (assign i (+ i 1)) (addraset r i (and x 0x7FF)) (assign i (+ i 1)) (addraset r i (or x 0x7FF)) (assign i (+ i 1)) (addraset r i (xor x 0x7FF)) (assign i (+ i 1)) (addraset r i (< x 0x7FF)) (assign i (+ i 1)) (checkbound i 0x7FF) +(addraset r i (+ x 0x800)) (assign i (+ i 1)) (addraset r i (- x 0x800)) (assign i (+ i 1)) (addraset r i ( * x 0x800)) (assign i (+ i 1)) (addraset r i (and x 0x800)) (assign i (+ i 1)) (addraset r i (or x 0x800)) (assign i (+ i 1)) (addraset r i (xor x 0x800)) (assign i (+ i 1)) (addraset r i (< x 0x800)) (assign i (+ i 1)) (checkbound i 0x800) +(addraset r i (+ x 0x801)) (assign i (+ i 1)) (addraset r i (- x 0x801)) (assign i (+ i 1)) (addraset r i ( * x 0x801)) (assign i (+ i 1)) (addraset r i (and x 0x801)) (assign i (+ i 1)) (addraset r i (or x 0x801)) (assign i (+ i 1)) (addraset r i (xor x 0x801)) (assign i (+ i 1)) (addraset r i (< x 0x801)) (assign i (+ i 1)) (checkbound i 0x801) +(addraset r i (+ x 0xFFF)) (assign i (+ i 1)) (addraset r i (- x 0xFFF)) (assign i (+ i 1)) (addraset r i ( * x 0xFFF)) (assign i (+ i 1)) (addraset r i (and x 0xFFF)) (assign i (+ i 1)) (addraset r i (or x 0xFFF)) (assign i (+ i 1)) (addraset r i (xor x 0xFFF)) (assign i (+ i 1)) (addraset r i (< x 0xFFF)) (assign i (+ i 1)) (checkbound i 0xFFF) +(addraset r i (+ x 0x1000)) (assign i (+ i 1)) (addraset r i (- x 0x1000)) (assign i (+ i 1)) (addraset r i ( * x 0x1000)) (assign i (+ i 1)) (addraset r i (and x 0x1000)) (assign i (+ i 1)) (addraset r i (or x 0x1000)) (assign i (+ i 1)) (addraset r i (xor x 0x1000)) (assign i (+ i 1)) (addraset r i (< x 0x1000)) (assign i (+ i 1)) (checkbound i 0x1000) +(addraset r i (+ x 0x1001)) (assign i (+ i 1)) (addraset r i (- x 0x1001)) (assign i (+ i 1)) (addraset r i ( * x 0x1001)) (assign i (+ i 1)) (addraset r i (and x 0x1001)) (assign i (+ i 1)) (addraset r i (or x 0x1001)) (assign i (+ i 1)) (addraset r i (xor x 0x1001)) (assign i (+ i 1)) (addraset r i (< x 0x1001)) (assign i (+ i 1)) (checkbound i 0x1001) +(addraset r i (+ x 0x7FFF)) (assign i (+ i 1)) (addraset r i (- x 0x7FFF)) (assign i (+ i 1)) (addraset r i ( * x 0x7FFF)) (assign i (+ i 1)) (addraset r i (and x 0x7FFF)) (assign i (+ i 1)) (addraset r i (or x 0x7FFF)) (assign i (+ i 1)) (addraset r i (xor x 0x7FFF)) (assign i (+ i 1)) (addraset r i (< x 0x7FFF)) (assign i (+ i 1)) (checkbound i 0x7FFF) +(addraset r i (+ x 0x8000)) (assign i (+ i 1)) (addraset r i (- x 0x8000)) (assign i (+ i 1)) (addraset r i ( * x 0x8000)) (assign i (+ i 1)) (addraset r i (and x 0x8000)) (assign i (+ i 1)) (addraset r i (or x 0x8000)) (assign i (+ i 1)) (addraset r i (xor x 0x8000)) (assign i (+ i 1)) (addraset r i (< x 0x8000)) (assign i (+ i 1)) (checkbound i 0x8000) +(addraset r i (+ x 0x8001)) (assign i (+ i 1)) (addraset r i (- x 0x8001)) (assign i (+ i 1)) (addraset r i ( * x 0x8001)) (assign i (+ i 1)) (addraset r i (and x 0x8001)) (assign i (+ i 1)) (addraset r i (or x 0x8001)) (assign i (+ i 1)) (addraset r i (xor x 0x8001)) (assign i (+ i 1)) (addraset r i (< x 0x8001)) (assign i (+ i 1)) (checkbound i 0x8001) +(addraset r i (+ x 0xFFF000)) (assign i (+ i 1)) (addraset r i (- x 0xFFF000)) (assign i (+ i 1)) (addraset r i ( * x 0xFFF000)) (assign i (+ i 1)) (addraset r i (and x 0xFFF000)) (assign i (+ i 1)) (addraset r i (or x 0xFFF000)) (assign i (+ i 1)) (addraset r i (xor x 0xFFF000)) (assign i (+ i 1)) (addraset r i (< x 0xFFF000)) (assign i (+ i 1)) (checkbound i 0xFFF000) +(addraset r i (+ x 0xFFFFFF)) (assign i (+ i 1)) (addraset r i (- x 0xFFFFFF)) (assign i (+ i 1)) (addraset r i ( * x 0xFFFFFF)) (assign i (+ i 1)) (addraset r i (and x 0xFFFFFF)) (assign i (+ i 1)) (addraset r i (or x 0xFFFFFF)) (assign i (+ i 1)) (addraset r i (xor x 0xFFFFFF)) (assign i (+ i 1)) (addraset r i (< x 0xFFFFFF)) (assign i (+ i 1)) (checkbound i 0xFFFFFF) +(addraset r i (+ x 0x1000000)) (assign i (+ i 1)) (addraset r i (- x 0x1000000)) (assign i (+ i 1)) (addraset r i ( * x 0x1000000)) (assign i (+ i 1)) (addraset r i (and x 0x1000000)) (assign i (+ i 1)) (addraset r i (or x 0x1000000)) (assign i (+ i 1)) (addraset r i (xor x 0x1000000)) (assign i (+ i 1)) (addraset r i (< x 0x1000000)) (assign i (+ i 1)) (checkbound i 0x1000000) +(addraset r i (+ x 0x1000001)) (assign i (+ i 1)) (addraset r i (- x 0x1000001)) (assign i (+ i 1)) (addraset r i ( * x 0x1000001)) (assign i (+ i 1)) (addraset r i (and x 0x1000001)) (assign i (+ i 1)) (addraset r i (or x 0x1000001)) (assign i (+ i 1)) (addraset r i (xor x 0x1000001)) (assign i (+ i 1)) (addraset r i (< x 0x1000001)) (assign i (+ i 1)) (checkbound i 0x1000001) +(addraset r i (+ x -1)) (assign i (+ i 1)) (addraset r i (- x -1)) (assign i (+ i 1)) (addraset r i ( * x -1)) (assign i (+ i 1)) (addraset r i (and x -1)) (assign i (+ i 1)) (addraset r i (or x -1)) (assign i (+ i 1)) (addraset r i (xor x -1)) (assign i (+ i 1)) (addraset r i (< x -1)) (assign i (+ i 1)) (checkbound i -1) +(addraset r i (+ x -0xFF)) (assign i (+ i 1)) (addraset r i (- x -0xFF)) (assign i (+ i 1)) (addraset r i ( * x -0xFF)) (assign i (+ i 1)) (addraset r i (and x -0xFF)) (assign i (+ i 1)) (addraset r i (or x -0xFF)) (assign i (+ i 1)) (addraset r i (xor x -0xFF)) (assign i (+ i 1)) (addraset r i (< x -0xFF)) (assign i (+ i 1)) (checkbound i -0xFF) +(addraset r i (+ x -0x100)) (assign i (+ i 1)) (addraset r i (- x -0x100)) (assign i (+ i 1)) (addraset r i ( * x -0x100)) (assign i (+ i 1)) (addraset r i (and x -0x100)) (assign i (+ i 1)) (addraset r i (or x -0x100)) (assign i (+ i 1)) (addraset r i (xor x -0x100)) (assign i (+ i 1)) (addraset r i (< x -0x100)) (assign i (+ i 1)) (checkbound i -0x100) +(addraset r i (+ x -0x3FC)) (assign i (+ i 1)) (addraset r i (- x -0x3FC)) (assign i (+ i 1)) (addraset r i ( * x -0x3FC)) (assign i (+ i 1)) (addraset r i (and x -0x3FC)) (assign i (+ i 1)) (addraset r i (or x -0x3FC)) (assign i (+ i 1)) (addraset r i (xor x -0x3FC)) (assign i (+ i 1)) (addraset r i (< x -0x3FC)) (assign i (+ i 1)) (checkbound i -0x3FC) +(addraset r i (+ x -0x3FF)) (assign i (+ i 1)) (addraset r i (- x -0x3FF)) (assign i (+ i 1)) (addraset r i ( * x -0x3FF)) (assign i (+ i 1)) (addraset r i (and x -0x3FF)) (assign i (+ i 1)) (addraset r i (or x -0x3FF)) (assign i (+ i 1)) (addraset r i (xor x -0x3FF)) (assign i (+ i 1)) (addraset r i (< x -0x3FF)) (assign i (+ i 1)) (checkbound i -0x3FF) +(addraset r i (+ x -0x7FF)) (assign i (+ i 1)) (addraset r i (- x -0x7FF)) (assign i (+ i 1)) (addraset r i ( * x -0x7FF)) (assign i (+ i 1)) (addraset r i (and x -0x7FF)) (assign i (+ i 1)) (addraset r i (or x -0x7FF)) (assign i (+ i 1)) (addraset r i (xor x -0x7FF)) (assign i (+ i 1)) (addraset r i (< x -0x7FF)) (assign i (+ i 1)) (checkbound i -0x7FF) +(addraset r i (+ x -0x800)) (assign i (+ i 1)) (addraset r i (- x -0x800)) (assign i (+ i 1)) (addraset r i ( * x -0x800)) (assign i (+ i 1)) (addraset r i (and x -0x800)) (assign i (+ i 1)) (addraset r i (or x -0x800)) (assign i (+ i 1)) (addraset r i (xor x -0x800)) (assign i (+ i 1)) (addraset r i (< x -0x800)) (assign i (+ i 1)) (checkbound i -0x800) +(addraset r i (+ x -0x801)) (assign i (+ i 1)) (addraset r i (- x -0x801)) (assign i (+ i 1)) (addraset r i ( * x -0x801)) (assign i (+ i 1)) (addraset r i (and x -0x801)) (assign i (+ i 1)) (addraset r i (or x -0x801)) (assign i (+ i 1)) (addraset r i (xor x -0x801)) (assign i (+ i 1)) (addraset r i (< x -0x801)) (assign i (+ i 1)) (checkbound i -0x801) +(addraset r i (+ x -0xFFF)) (assign i (+ i 1)) (addraset r i (- x -0xFFF)) (assign i (+ i 1)) (addraset r i ( * x -0xFFF)) (assign i (+ i 1)) (addraset r i (and x -0xFFF)) (assign i (+ i 1)) (addraset r i (or x -0xFFF)) (assign i (+ i 1)) (addraset r i (xor x -0xFFF)) (assign i (+ i 1)) (addraset r i (< x -0xFFF)) (assign i (+ i 1)) (checkbound i -0xFFF) +(addraset r i (+ x -0x1000)) (assign i (+ i 1)) (addraset r i (- x -0x1000)) (assign i (+ i 1)) (addraset r i ( * x -0x1000)) (assign i (+ i 1)) (addraset r i (and x -0x1000)) (assign i (+ i 1)) (addraset r i (or x -0x1000)) (assign i (+ i 1)) (addraset r i (xor x -0x1000)) (assign i (+ i 1)) (addraset r i (< x -0x1000)) (assign i (+ i 1)) (checkbound i -0x1000) +(addraset r i (+ x -0x1001)) (assign i (+ i 1)) (addraset r i (- x -0x1001)) (assign i (+ i 1)) (addraset r i ( * x -0x1001)) (assign i (+ i 1)) (addraset r i (and x -0x1001)) (assign i (+ i 1)) (addraset r i (or x -0x1001)) (assign i (+ i 1)) (addraset r i (xor x -0x1001)) (assign i (+ i 1)) (addraset r i (< x -0x1001)) (assign i (+ i 1)) (checkbound i -0x1001) +(addraset r i (+ x -0x7FFF)) (assign i (+ i 1)) (addraset r i (- x -0x7FFF)) (assign i (+ i 1)) (addraset r i ( * x -0x7FFF)) (assign i (+ i 1)) (addraset r i (and x -0x7FFF)) (assign i (+ i 1)) (addraset r i (or x -0x7FFF)) (assign i (+ i 1)) (addraset r i (xor x -0x7FFF)) (assign i (+ i 1)) (addraset r i (< x -0x7FFF)) (assign i (+ i 1)) (checkbound i -0x7FFF) +(addraset r i (+ x -0x8000)) (assign i (+ i 1)) (addraset r i (- x -0x8000)) (assign i (+ i 1)) (addraset r i ( * x -0x8000)) (assign i (+ i 1)) (addraset r i (and x -0x8000)) (assign i (+ i 1)) (addraset r i (or x -0x8000)) (assign i (+ i 1)) (addraset r i (xor x -0x8000)) (assign i (+ i 1)) (addraset r i (< x -0x8000)) (assign i (+ i 1)) (checkbound i -0x8000) +(addraset r i (+ x -0x8001)) (assign i (+ i 1)) (addraset r i (- x -0x8001)) (assign i (+ i 1)) (addraset r i ( * x -0x8001)) (assign i (+ i 1)) (addraset r i (and x -0x8001)) (assign i (+ i 1)) (addraset r i (or x -0x8001)) (assign i (+ i 1)) (addraset r i (xor x -0x8001)) (assign i (+ i 1)) (addraset r i (< x -0x8001)) (assign i (+ i 1)) (checkbound i -0x8001) +(addraset r i (+ x -0xFFF000)) (assign i (+ i 1)) (addraset r i (- x -0xFFF000)) (assign i (+ i 1)) (addraset r i ( * x -0xFFF000)) (assign i (+ i 1)) (addraset r i (and x -0xFFF000)) (assign i (+ i 1)) (addraset r i (or x -0xFFF000)) (assign i (+ i 1)) (addraset r i (xor x -0xFFF000)) (assign i (+ i 1)) (addraset r i (< x -0xFFF000)) (assign i (+ i 1)) (checkbound i -0xFFF000) +(addraset r i (+ x -0xFFFFFF)) (assign i (+ i 1)) (addraset r i (- x -0xFFFFFF)) (assign i (+ i 1)) (addraset r i ( * x -0xFFFFFF)) (assign i (+ i 1)) (addraset r i (and x -0xFFFFFF)) (assign i (+ i 1)) (addraset r i (or x -0xFFFFFF)) (assign i (+ i 1)) (addraset r i (xor x -0xFFFFFF)) (assign i (+ i 1)) (addraset r i (< x -0xFFFFFF)) (assign i (+ i 1)) (checkbound i -0xFFFFFF) +(addraset r i (+ x -0x1000000)) (assign i (+ i 1)) (addraset r i (- x -0x1000000)) (assign i (+ i 1)) (addraset r i ( * x -0x1000000)) (assign i (+ i 1)) (addraset r i (and x -0x1000000)) (assign i (+ i 1)) (addraset r i (or x -0x1000000)) (assign i (+ i 1)) (addraset r i (xor x -0x1000000)) (assign i (+ i 1)) (addraset r i (< x -0x1000000)) (assign i (+ i 1)) (checkbound i -0x1000000) +(addraset r i (+ x -0x1000001)) (assign i (+ i 1)) (addraset r i (- x -0x1000001)) (assign i (+ i 1)) (addraset r i ( * x -0x1000001)) (assign i (+ i 1)) (addraset r i (and x -0x1000001)) (assign i (+ i 1)) (addraset r i (or x -0x1000001)) (assign i (+ i 1)) (addraset r i (xor x -0x1000001)) (assign i (+ i 1)) (addraset r i (< x -0x1000001)) (assign i (+ i 1)) (checkbound i -0x1000001) +)))) diff --git a/testsuite/tests/asmgen/immediates.cmmpp b/testsuite/tests/asmgen/immediates.cmmpp new file mode 100644 index 00000000..d4988b99 --- /dev/null +++ b/testsuite/tests/asmgen/immediates.cmmpp @@ -0,0 +1,26 @@ +#define T TEST + +(* T +files = "mainimmed.c" +arguments = "-I ${test_source_directory} mainimmed.c" +* asmgen +*) + +(* Regenerate with cpp -P immediates.cmmpp > immediates.cmm *) + +#define F(N) \ + (addraset r i (+ x N)) (assign i (+ i 1)) \ + (addraset r i (- x N)) (assign i (+ i 1)) \ + (addraset r i ( * x N)) (assign i (+ i 1)) \ + (addraset r i (and x N)) (assign i (+ i 1)) \ + (addraset r i (or x N)) (assign i (+ i 1)) \ + (addraset r i (xor x N)) (assign i (+ i 1)) \ + (addraset r i (< x N)) (assign i (+ i 1)) \ + (checkbound i N) + +(function "testimm" () + (let x (load int "X") + (let r "R" + (letmut i int 0 +#include "immediates.tbl" +)))) diff --git a/testsuite/tests/asmgen/immediates.tbl b/testsuite/tests/asmgen/immediates.tbl new file mode 100644 index 00000000..f5f6c230 --- /dev/null +++ b/testsuite/tests/asmgen/immediates.tbl @@ -0,0 +1,37 @@ +F(0) +F(1) +F(0xFF) +F(0x100) +F(0x3FC) +F(0x3FF) +F(0x7FF) +F(0x800) +F(0x801) +F(0xFFF) +F(0x1000) +F(0x1001) +F(0x7FFF) +F(0x8000) +F(0x8001) +F(0xFFF000) +F(0xFFFFFF) +F(0x1000000) +F(0x1000001) +F(-1) +F(-0xFF) +F(-0x100) +F(-0x3FC) +F(-0x3FF) +F(-0x7FF) +F(-0x800) +F(-0x801) +F(-0xFFF) +F(-0x1000) +F(-0x1001) +F(-0x7FFF) +F(-0x8000) +F(-0x8001) +F(-0xFFF000) +F(-0xFFFFFF) +F(-0x1000000) +F(-0x1000001) diff --git a/testsuite/tests/asmgen/mainimmed.c b/testsuite/tests/asmgen/mainimmed.c new file mode 100644 index 00000000..6e120424 --- /dev/null +++ b/testsuite/tests/asmgen/mainimmed.c @@ -0,0 +1,78 @@ +#include +#include +#include + +#define NUMTESTS 37 +intnat R[NUMTESTS][7]; +intnat X; + +extern void call_gen_code(void (*)(void)); +extern void testimm(void); + +void caml_ml_array_bound_error(void) +{ + fprintf(stderr, "Fatal error: out-of-bound access in array or string\n"); + exit(2); +} + +/* One round of testing */ + +#define FMT ARCH_INTNAT_PRINTF_FORMAT + +static void check(int i, intnat x, intnat result, intnat expected) +{ + if (result != expected) { + printf("Test %d, argument %"FMT"d: got %"FMT"d, expected %"FMT"d\n", + i, x, result, expected); + } +} + +static void test_one(int i, intnat x, intnat y) +{ + check(i, x, R[i][0], x + y); + check(i, x, R[i][1], x - y); + check(i, x, R[i][2], x * y); + check(i, x, R[i][3], x & y); + check(i, x, R[i][4], x | y); + check(i, x, R[i][5], x ^ y); + check(i, x, R[i][6], x < y); +} + +static void do_test(intnat x) +{ + int i; + + X = x; + call_gen_code(testimm); + i = 0; +#define F(N) test_one(i++, x, N); +#include "immediates.tbl" +} + +/* A simple linear congruential PRNG */ + +#ifdef ARCH_SIXTYFOUR +#define RAND_A 6364136223846793005ULL +#define RAND_C 1442695040888963407ULL +#else +#define RAND_A 214013U +#define RAND_C 2531011U +#endif + +static intnat rnd(void) +{ + static uintnat seed = 0; + seed = seed * RAND_A + RAND_C; + return (intnat) seed; +} + +/* Test harness */ + +#define NUM_RANDOM_ITERATIONS 1000000 + +int main(int argc, char **argv) +{ + int i; + for (i = 0; i < NUM_RANDOM_ITERATIONS; i++) do_test(rnd()); + return 0; +} diff --git a/testsuite/tests/asmgen/soli.cmm b/testsuite/tests/asmgen/soli.cmm index 93be3aab..e80381f0 100644 --- a/testsuite/tests/asmgen/soli.cmm +++ b/testsuite/tests/asmgen/soli.cmm @@ -72,7 +72,7 @@ arguments = "-DUNIT_INT -DFUN=solitaire main.c" (intaset (addraref "board" i1) j1 1) (intaset (addraref "board" i2) j2 2) (if (app "solve" (+ m 1) int) - (raise_notrace 0a) + (raise_notrace 0) []) (intaset (addraref "board" i) j 2) (intaset (addraref "board" i1) j1 2) diff --git a/testsuite/tests/backtrace/backtrace.ml b/testsuite/tests/backtrace/backtrace.ml index 02a9343e..f3683751 100644 --- a/testsuite/tests/backtrace/backtrace.ml +++ b/testsuite/tests/backtrace/backtrace.ml @@ -1,7 +1,6 @@ (* TEST flags = "-g" ocamlrunparam += ",b=1" - compare_programs = "false" *) (* A test for stack backtraces *) @@ -19,5 +18,4 @@ let g msg = | Error "c" -> raise (Error "c") let _ = - Printexc.record_backtrace true; ignore (g Sys.argv.(1)) diff --git a/testsuite/tests/backtrace/backtrace.reference b/testsuite/tests/backtrace/backtrace.reference index ad4e1fa4..75defcaa 100644 --- a/testsuite/tests/backtrace/backtrace.reference +++ b/testsuite/tests/backtrace/backtrace.reference @@ -1,26 +1,26 @@ a b Fatal error: exception Backtrace.Error("b") -Raised at Backtrace.f in file "backtrace.ml", line 12, characters 16-32 -Called from Backtrace.f in file "backtrace.ml", line 12, characters 42-53 -Called from Backtrace.f in file "backtrace.ml", line 12, characters 42-53 -Called from Backtrace.f in file "backtrace.ml", line 12, characters 42-53 -Called from Backtrace.f in file "backtrace.ml", line 12, characters 42-53 -Called from Backtrace.f in file "backtrace.ml", line 12, characters 42-53 -Called from Backtrace.g in file "backtrace.ml", line 16, characters 4-11 -Re-raised at Backtrace.g in file "backtrace.ml", line 18, characters 62-71 -Called from Backtrace in file "backtrace.ml", line 23, characters 9-25 +Raised at Backtrace.f in file "backtrace.ml", line 11, characters 16-32 +Called from Backtrace.f in file "backtrace.ml", line 11, characters 42-53 +Called from Backtrace.f in file "backtrace.ml", line 11, characters 42-53 +Called from Backtrace.f in file "backtrace.ml", line 11, characters 42-53 +Called from Backtrace.f in file "backtrace.ml", line 11, characters 42-53 +Called from Backtrace.f in file "backtrace.ml", line 11, characters 42-53 +Called from Backtrace.g in file "backtrace.ml", line 15, characters 4-11 +Re-raised at Backtrace.g in file "backtrace.ml", line 17, characters 62-71 +Called from Backtrace in file "backtrace.ml", line 21, characters 9-25 Fatal error: exception Backtrace.Error("c") -Raised at Backtrace.g in file "backtrace.ml", line 19, characters 20-37 -Called from Backtrace in file "backtrace.ml", line 23, characters 9-25 +Raised at Backtrace.g in file "backtrace.ml", line 18, characters 20-37 +Called from Backtrace in file "backtrace.ml", line 21, characters 9-25 Fatal error: exception Backtrace.Error("d") -Raised at Backtrace.f in file "backtrace.ml", line 12, characters 16-32 -Called from Backtrace.f in file "backtrace.ml", line 12, characters 42-53 -Called from Backtrace.f in file "backtrace.ml", line 12, characters 42-53 -Called from Backtrace.f in file "backtrace.ml", line 12, characters 42-53 -Called from Backtrace.f in file "backtrace.ml", line 12, characters 42-53 -Called from Backtrace.f in file "backtrace.ml", line 12, characters 42-53 -Called from Backtrace.g in file "backtrace.ml", line 16, characters 4-11 -Called from Backtrace in file "backtrace.ml", line 23, characters 9-25 +Raised at Backtrace.f in file "backtrace.ml", line 11, characters 16-32 +Called from Backtrace.f in file "backtrace.ml", line 11, characters 42-53 +Called from Backtrace.f in file "backtrace.ml", line 11, characters 42-53 +Called from Backtrace.f in file "backtrace.ml", line 11, characters 42-53 +Called from Backtrace.f in file "backtrace.ml", line 11, characters 42-53 +Called from Backtrace.f in file "backtrace.ml", line 11, characters 42-53 +Called from Backtrace.g in file "backtrace.ml", line 15, characters 4-11 +Called from Backtrace in file "backtrace.ml", line 21, characters 9-25 Fatal error: exception Invalid_argument("index out of bounds") -Raised by primitive operation at Backtrace in file "backtrace.ml", line 23, characters 12-24 +Raised by primitive operation at Backtrace in file "backtrace.ml", line 21, characters 12-24 diff --git a/testsuite/tests/backtrace/backtrace2.ml b/testsuite/tests/backtrace/backtrace2.ml index 5b620866..747969a4 100644 --- a/testsuite/tests/backtrace/backtrace2.ml +++ b/testsuite/tests/backtrace/backtrace2.ml @@ -1,7 +1,6 @@ (* TEST flags = "-g" ocamlrunparam += ",b=1" - compare_programs = "false" *) (* A test for stack backtraces *) @@ -66,7 +65,6 @@ let run g args = Printexc.print_backtrace stdout let _ = - Printexc.record_backtrace true; run test_Error [| "a" |]; run test_Error [| "b" |]; run test_Error [| "c" |]; diff --git a/testsuite/tests/backtrace/backtrace2.reference b/testsuite/tests/backtrace/backtrace2.reference index 22666a7a..a1ca422c 100644 --- a/testsuite/tests/backtrace/backtrace2.reference +++ b/testsuite/tests/backtrace/backtrace2.reference @@ -2,57 +2,57 @@ a No exception b Uncaught exception Backtrace2.Error("b") -Raised at Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 18-34 -Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 44-55 -Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 44-55 -Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 44-55 -Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 44-55 -Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 44-55 -Called from Backtrace2.test_Error in file "backtrace2.ml", line 18, characters 4-11 -Re-raised at Backtrace2.test_Error in file "backtrace2.ml", line 20, characters 62-71 -Called from Backtrace2.run in file "backtrace2.ml", line 63, characters 11-23 +Raised at Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 18-34 +Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 44-55 +Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 44-55 +Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 44-55 +Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 44-55 +Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 44-55 +Called from Backtrace2.test_Error in file "backtrace2.ml", line 17, characters 4-11 +Re-raised at Backtrace2.test_Error in file "backtrace2.ml", line 19, characters 62-71 +Called from Backtrace2.run in file "backtrace2.ml", line 62, characters 11-23 Uncaught exception Backtrace2.Error("c") -Raised at Backtrace2.test_Error in file "backtrace2.ml", line 21, characters 20-37 -Called from Backtrace2.run in file "backtrace2.ml", line 63, characters 11-23 +Raised at Backtrace2.test_Error in file "backtrace2.ml", line 20, characters 20-37 +Called from Backtrace2.run in file "backtrace2.ml", line 62, characters 11-23 Uncaught exception Backtrace2.Error("d") -Raised at Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 18-34 -Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 44-55 -Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 44-55 -Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 44-55 -Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 44-55 -Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 13, characters 44-55 -Called from Backtrace2.test_Error in file "backtrace2.ml", line 18, characters 4-11 -Called from Backtrace2.run in file "backtrace2.ml", line 63, characters 11-23 +Raised at Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 18-34 +Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 44-55 +Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 44-55 +Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 44-55 +Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 44-55 +Called from Backtrace2.test_Error.f in file "backtrace2.ml", line 12, characters 44-55 +Called from Backtrace2.test_Error in file "backtrace2.ml", line 17, characters 4-11 +Called from Backtrace2.run in file "backtrace2.ml", line 62, characters 11-23 e Uncaught exception Backtrace2.Error("e") -Raised at Backtrace2.test_Error in file "backtrace2.ml", line 27, characters 50-59 -Called from Backtrace2.run in file "backtrace2.ml", line 63, characters 11-23 +Raised at Backtrace2.test_Error in file "backtrace2.ml", line 26, characters 50-59 +Called from Backtrace2.run in file "backtrace2.ml", line 62, characters 11-23 f Uncaught exception Backtrace2.Error("f") -Raised at Backtrace2.test_Error in file "backtrace2.ml", line 33, characters 62-71 -Called from Backtrace2.run in file "backtrace2.ml", line 63, characters 11-23 +Raised at Backtrace2.test_Error in file "backtrace2.ml", line 32, characters 62-71 +Called from Backtrace2.run in file "backtrace2.ml", line 62, characters 11-23 Uncaught exception Invalid_argument("index out of bounds") -Raised by primitive operation at Backtrace2.run in file "backtrace2.ml", line 63, characters 14-22 +Raised by primitive operation at Backtrace2.run in file "backtrace2.ml", line 62, characters 14-22 test_Not_found Uncaught exception Not_found -Raised at Stdlib__hashtbl.find in file "hashtbl.ml", line 537, characters 13-28 -Called from Backtrace2.test_Not_found in file "backtrace2.ml", line 44, characters 9-42 -Re-raised at Backtrace2.test_Not_found in file "backtrace2.ml", line 44, characters 61-70 -Called from Backtrace2.run in file "backtrace2.ml", line 63, characters 11-23 +Raised at Stdlib__hashtbl.find in file "hashtbl.ml", line 539, characters 13-28 +Called from Backtrace2.test_Not_found in file "backtrace2.ml", line 43, characters 9-42 +Re-raised at Backtrace2.test_Not_found in file "backtrace2.ml", line 43, characters 61-70 +Called from Backtrace2.run in file "backtrace2.ml", line 62, characters 11-23 Uncaught exception Not_found -Raised at Backtrace2.test_lazy.aux in file "backtrace2.ml", line 48, characters 18-33 -Called from Backtrace2.test_lazy.aux in file "backtrace2.ml", line 48, characters 43-52 -Called from Backtrace2.test_lazy.aux in file "backtrace2.ml", line 48, characters 43-52 -Called from Backtrace2.test_lazy.aux in file "backtrace2.ml", line 48, characters 43-52 -Called from Backtrace2.test_lazy.aux in file "backtrace2.ml", line 48, characters 43-52 -Called from Backtrace2.test_lazy.aux in file "backtrace2.ml", line 48, characters 43-52 +Raised at Backtrace2.test_lazy.aux in file "backtrace2.ml", line 47, characters 18-33 +Called from Backtrace2.test_lazy.aux in file "backtrace2.ml", line 47, characters 43-52 +Called from Backtrace2.test_lazy.aux in file "backtrace2.ml", line 47, characters 43-52 +Called from Backtrace2.test_lazy.aux in file "backtrace2.ml", line 47, characters 43-52 +Called from Backtrace2.test_lazy.aux in file "backtrace2.ml", line 47, characters 43-52 +Called from Backtrace2.test_lazy.aux in file "backtrace2.ml", line 47, characters 43-52 Called from CamlinternalLazy.force_lazy_block in file "camlinternalLazy.ml", line 31, characters 17-27 Re-raised at CamlinternalLazy.force_lazy_block in file "camlinternalLazy.ml", line 36, characters 4-11 -Called from Backtrace2.run in file "backtrace2.ml", line 63, characters 11-23 +Called from Backtrace2.run in file "backtrace2.ml", line 62, characters 11-23 Uncaught exception Not_found -Raised at Stdlib__hashtbl.find in file "hashtbl.ml", line 537, characters 13-28 -Called from Backtrace2.test_lazy.exception_raised_internally in file "backtrace2.ml", line 51, characters 8-41 +Raised at Stdlib__hashtbl.find in file "hashtbl.ml", line 539, characters 13-28 +Called from Backtrace2.test_lazy.exception_raised_internally in file "backtrace2.ml", line 50, characters 8-41 Re-raised at CamlinternalLazy.force_lazy_block.(fun) in file "camlinternalLazy.ml", line 35, characters 56-63 Called from CamlinternalLazy.force_lazy_block in file "camlinternalLazy.ml", line 31, characters 17-27 Re-raised at CamlinternalLazy.force_lazy_block in file "camlinternalLazy.ml", line 36, characters 4-11 -Called from Backtrace2.run in file "backtrace2.ml", line 63, characters 11-23 +Called from Backtrace2.run in file "backtrace2.ml", line 62, characters 11-23 diff --git a/testsuite/tests/backtrace/backtrace3.ml b/testsuite/tests/backtrace/backtrace3.ml index 5f81bb85..c91f0a03 100644 --- a/testsuite/tests/backtrace/backtrace3.ml +++ b/testsuite/tests/backtrace/backtrace3.ml @@ -1,7 +1,6 @@ (* TEST flags = "-g" ocamlrunparam += ",b=1" - compare_programs = "false" *) (* A test for stack backtraces *) @@ -53,7 +52,6 @@ let run args = Printexc.print_backtrace stdout let _ = - Printexc.record_backtrace true; run [| "a" |]; run [| "b" |]; run [| "c" |]; diff --git a/testsuite/tests/backtrace/backtrace3.reference b/testsuite/tests/backtrace/backtrace3.reference index b8b0456d..6ed30d05 100644 --- a/testsuite/tests/backtrace/backtrace3.reference +++ b/testsuite/tests/backtrace/backtrace3.reference @@ -2,65 +2,65 @@ a No exception b Uncaught exception Backtrace3.Error("b") -Raised at Backtrace3.f in file "backtrace3.ml", line 12, characters 16-32 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.g in file "backtrace3.ml", line 16, characters 4-11 -Re-raised at Backtrace3.g in file "backtrace3.ml", line 25, characters 41-50 -Called from Backtrace3.run in file "backtrace3.ml", line 50, characters 11-23 +Raised at Backtrace3.f in file "backtrace3.ml", line 11, characters 16-32 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.g in file "backtrace3.ml", line 15, characters 4-11 +Re-raised at Backtrace3.g in file "backtrace3.ml", line 24, characters 41-50 +Called from Backtrace3.run in file "backtrace3.ml", line 49, characters 11-23 c Uncaught exception Backtrace3.Error("c") -Raised at Backtrace3.g in file "backtrace3.ml", line 29, characters 41-58 -Called from Backtrace3.run in file "backtrace3.ml", line 50, characters 11-23 +Raised at Backtrace3.g in file "backtrace3.ml", line 28, characters 41-58 +Called from Backtrace3.run in file "backtrace3.ml", line 49, characters 11-23 d Uncaught exception Backtrace3.Error("d") -Raised at Backtrace3.f in file "backtrace3.ml", line 12, characters 16-32 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.g in file "backtrace3.ml", line 16, characters 4-11 -Re-raised at Backtrace3.g in file "backtrace3.ml", line 32, characters 41-50 -Called from Backtrace3.run in file "backtrace3.ml", line 50, characters 11-23 +Raised at Backtrace3.f in file "backtrace3.ml", line 11, characters 16-32 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.g in file "backtrace3.ml", line 15, characters 4-11 +Re-raised at Backtrace3.g in file "backtrace3.ml", line 31, characters 41-50 +Called from Backtrace3.run in file "backtrace3.ml", line 49, characters 11-23 e Uncaught exception Backtrace3.Error("e") -Raised at Backtrace3.f in file "backtrace3.ml", line 12, characters 16-32 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.g in file "backtrace3.ml", line 16, characters 4-11 -Re-raised at Backtrace3.g in file "backtrace3.ml", line 35, characters 41-51 -Called from Backtrace3.run in file "backtrace3.ml", line 50, characters 11-23 +Raised at Backtrace3.f in file "backtrace3.ml", line 11, characters 16-32 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.g in file "backtrace3.ml", line 15, characters 4-11 +Re-raised at Backtrace3.g in file "backtrace3.ml", line 34, characters 41-51 +Called from Backtrace3.run in file "backtrace3.ml", line 49, characters 11-23 f Uncaught exception Backtrace3.Error("f") -Raised at Backtrace3.f in file "backtrace3.ml", line 12, characters 16-32 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.g in file "backtrace3.ml", line 16, characters 4-11 -Re-raised at Backtrace3.g in file "backtrace3.ml", line 40, characters 45-54 -Called from Backtrace3.run in file "backtrace3.ml", line 50, characters 11-23 +Raised at Backtrace3.f in file "backtrace3.ml", line 11, characters 16-32 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.g in file "backtrace3.ml", line 15, characters 4-11 +Re-raised at Backtrace3.g in file "backtrace3.ml", line 39, characters 45-54 +Called from Backtrace3.run in file "backtrace3.ml", line 49, characters 11-23 g Uncaught exception Backtrace3.Error("g") -Raised at Backtrace3.f in file "backtrace3.ml", line 12, characters 16-32 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.f in file "backtrace3.ml", line 12, characters 42-53 -Called from Backtrace3.g in file "backtrace3.ml", line 16, characters 4-11 -Re-raised at Backtrace3.g in file "backtrace3.ml", line 43, characters 45-55 -Called from Backtrace3.run in file "backtrace3.ml", line 50, characters 11-23 +Raised at Backtrace3.f in file "backtrace3.ml", line 11, characters 16-32 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.f in file "backtrace3.ml", line 11, characters 42-53 +Called from Backtrace3.g in file "backtrace3.ml", line 15, characters 4-11 +Re-raised at Backtrace3.g in file "backtrace3.ml", line 42, characters 45-55 +Called from Backtrace3.run in file "backtrace3.ml", line 49, characters 11-23 Uncaught exception Backtrace3.Error("h") -Raised at Backtrace3.g in file "backtrace3.ml", line 46, characters 10-17 -Called from Backtrace3.run in file "backtrace3.ml", line 50, characters 11-23 +Raised at Backtrace3.g in file "backtrace3.ml", line 45, characters 10-17 +Called from Backtrace3.run in file "backtrace3.ml", line 49, characters 11-23 Uncaught exception Invalid_argument("index out of bounds") -Raised by primitive operation at Backtrace3.run in file "backtrace3.ml", line 50, characters 14-22 +Raised by primitive operation at Backtrace3.run in file "backtrace3.ml", line 49, characters 14-22 diff --git a/testsuite/tests/backtrace/backtrace_deprecated.ml b/testsuite/tests/backtrace/backtrace_deprecated.ml index 5840112b..41b3c4be 100644 --- a/testsuite/tests/backtrace/backtrace_deprecated.ml +++ b/testsuite/tests/backtrace/backtrace_deprecated.ml @@ -1,7 +1,6 @@ (* TEST flags = "-g" ocamlrunparam += ",b=1" - compare_programs = "false" *) (* A test for stack backtraces *) @@ -36,7 +35,6 @@ let run args = trace let _ = - Printexc.record_backtrace true; run [| "a" |]; run [| "b" |]; run [| "c" |]; diff --git a/testsuite/tests/backtrace/backtrace_deprecated.reference b/testsuite/tests/backtrace/backtrace_deprecated.reference index bbfd0205..0fa9f053 100644 --- a/testsuite/tests/backtrace/backtrace_deprecated.reference +++ b/testsuite/tests/backtrace/backtrace_deprecated.reference @@ -2,26 +2,26 @@ a No exception b Uncaught exception Backtrace_deprecated.Error("b") -Raised at Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 16-32 -Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 42-53 -Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 42-53 -Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 42-53 -Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 42-53 -Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 42-53 -Called from Backtrace_deprecated.g in file "backtrace_deprecated.ml", line 19, characters 4-11 -Re-raised at Backtrace_deprecated.g in file "backtrace_deprecated.ml", line 21, characters 62-71 -Called from Backtrace_deprecated.run in file "backtrace_deprecated.ml", line 26, characters 11-23 +Raised at Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 16-32 +Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 42-53 +Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 42-53 +Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 42-53 +Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 42-53 +Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 42-53 +Called from Backtrace_deprecated.g in file "backtrace_deprecated.ml", line 18, characters 4-11 +Re-raised at Backtrace_deprecated.g in file "backtrace_deprecated.ml", line 20, characters 62-71 +Called from Backtrace_deprecated.run in file "backtrace_deprecated.ml", line 25, characters 11-23 Uncaught exception Backtrace_deprecated.Error("c") -Raised at Backtrace_deprecated.g in file "backtrace_deprecated.ml", line 22, characters 20-37 -Called from Backtrace_deprecated.run in file "backtrace_deprecated.ml", line 26, characters 11-23 +Raised at Backtrace_deprecated.g in file "backtrace_deprecated.ml", line 21, characters 20-37 +Called from Backtrace_deprecated.run in file "backtrace_deprecated.ml", line 25, characters 11-23 Uncaught exception Backtrace_deprecated.Error("d") -Raised at Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 16-32 -Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 42-53 -Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 42-53 -Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 42-53 -Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 42-53 -Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 15, characters 42-53 -Called from Backtrace_deprecated.g in file "backtrace_deprecated.ml", line 19, characters 4-11 -Called from Backtrace_deprecated.run in file "backtrace_deprecated.ml", line 26, characters 11-23 +Raised at Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 16-32 +Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 42-53 +Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 42-53 +Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 42-53 +Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 42-53 +Called from Backtrace_deprecated.f in file "backtrace_deprecated.ml", line 14, characters 42-53 +Called from Backtrace_deprecated.g in file "backtrace_deprecated.ml", line 18, characters 4-11 +Called from Backtrace_deprecated.run in file "backtrace_deprecated.ml", line 25, characters 11-23 Uncaught exception Invalid_argument("index out of bounds") -Raised by primitive operation at Backtrace_deprecated.run in file "backtrace_deprecated.ml", line 26, characters 14-22 +Raised by primitive operation at Backtrace_deprecated.run in file "backtrace_deprecated.ml", line 25, characters 14-22 diff --git a/testsuite/tests/backtrace/backtrace_or_exception.ml b/testsuite/tests/backtrace/backtrace_or_exception.ml index cdb10cdd..dc8f53c0 100644 --- a/testsuite/tests/backtrace/backtrace_or_exception.ml +++ b/testsuite/tests/backtrace/backtrace_or_exception.ml @@ -1,7 +1,6 @@ (* TEST flags = "-g" ocamlrunparam += ",b=1" - compare_programs = "false" *) exception Exn @@ -44,7 +43,6 @@ let run f = Printf.printf "---------------------------\n%!" let _ = - Printexc.record_backtrace true; run without_reraise; run with_reraise; run trickier diff --git a/testsuite/tests/backtrace/backtrace_or_exception.reference b/testsuite/tests/backtrace/backtrace_or_exception.reference index 53baeb40..6e625f33 100644 --- a/testsuite/tests/backtrace/backtrace_or_exception.reference +++ b/testsuite/tests/backtrace/backtrace_or_exception.reference @@ -1,14 +1,14 @@ exception Backtrace_or_exception.Exn -Raised at Backtrace_or_exception.without_reraise in file "backtrace_or_exception.ml", line 20, characters 4-13 -Called from Backtrace_or_exception.run in file "backtrace_or_exception.ml", line 40, characters 6-10 +Raised at Backtrace_or_exception.without_reraise in file "backtrace_or_exception.ml", line 19, characters 4-13 +Called from Backtrace_or_exception.run in file "backtrace_or_exception.ml", line 39, characters 6-10 --------------------------- exception Backtrace_or_exception.Exn -Raised at Backtrace_or_exception.return_exn in file "backtrace_or_exception.ml", line 11, characters 4-13 -Called from Backtrace_or_exception.with_reraise in file "backtrace_or_exception.ml", line 24, characters 8-44 -Re-raised at Backtrace_or_exception.with_reraise in file "backtrace_or_exception.ml", line 27, characters 4-13 -Called from Backtrace_or_exception.run in file "backtrace_or_exception.ml", line 40, characters 6-10 +Raised at Backtrace_or_exception.return_exn in file "backtrace_or_exception.ml", line 10, characters 4-13 +Called from Backtrace_or_exception.with_reraise in file "backtrace_or_exception.ml", line 23, characters 8-44 +Re-raised at Backtrace_or_exception.with_reraise in file "backtrace_or_exception.ml", line 26, characters 4-13 +Called from Backtrace_or_exception.run in file "backtrace_or_exception.ml", line 39, characters 6-10 --------------------------- exception Backtrace_or_exception.Exn -Raised at Backtrace_or_exception.trickier in file "backtrace_or_exception.ml", line 36, characters 6-15 -Called from Backtrace_or_exception.run in file "backtrace_or_exception.ml", line 40, characters 6-10 +Raised at Backtrace_or_exception.trickier in file "backtrace_or_exception.ml", line 35, characters 6-15 +Called from Backtrace_or_exception.run in file "backtrace_or_exception.ml", line 39, characters 6-10 --------------------------- diff --git a/testsuite/tests/backtrace/backtrace_slots.ml b/testsuite/tests/backtrace/backtrace_slots.ml index 2d9cc20d..d6b95a0d 100644 --- a/testsuite/tests/backtrace/backtrace_slots.ml +++ b/testsuite/tests/backtrace/backtrace_slots.ml @@ -1,7 +1,6 @@ (* TEST flags = "-g" ocamlrunparam += ",b=1" - compare_programs = "false" *) (* A test for stack backtraces *) @@ -58,7 +57,6 @@ let run args = | Some line -> print_endline line) let _ = - Printexc.record_backtrace true; run [| "a" |]; run [| "b" |]; run [| "c" |]; diff --git a/testsuite/tests/backtrace/backtrace_slots.reference b/testsuite/tests/backtrace/backtrace_slots.reference index a012b5cf..1c0a8b52 100644 --- a/testsuite/tests/backtrace/backtrace_slots.reference +++ b/testsuite/tests/backtrace/backtrace_slots.reference @@ -2,26 +2,26 @@ a No exception b Uncaught exception Backtrace_slots.Error("b") -Raised at Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 16-32 -Called from Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 42-53 -Called from Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 42-53 -Called from Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 42-53 -Called from Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 42-53 -Called from Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 42-53 -Called from Backtrace_slots.g in file "backtrace_slots.ml", line 45, characters 4-11 -Re-raised at Backtrace_slots.g in file "backtrace_slots.ml", line 47, characters 62-71 -Called from Backtrace_slots.run in file "backtrace_slots.ml", line 52, characters 11-23 +Raised at Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 16-32 +Called from Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 42-53 +Called from Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 42-53 +Called from Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 42-53 +Called from Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 42-53 +Called from Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 42-53 +Called from Backtrace_slots.g in file "backtrace_slots.ml", line 44, characters 4-11 +Re-raised at Backtrace_slots.g in file "backtrace_slots.ml", line 46, characters 62-71 +Called from Backtrace_slots.run in file "backtrace_slots.ml", line 51, characters 11-23 Uncaught exception Backtrace_slots.Error("c") -Raised at Backtrace_slots.g in file "backtrace_slots.ml", line 48, characters 20-37 -Called from Backtrace_slots.run in file "backtrace_slots.ml", line 52, characters 11-23 +Raised at Backtrace_slots.g in file "backtrace_slots.ml", line 47, characters 20-37 +Called from Backtrace_slots.run in file "backtrace_slots.ml", line 51, characters 11-23 Uncaught exception Backtrace_slots.Error("d") -Raised at Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 16-32 -Called from Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 42-53 -Called from Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 42-53 -Called from Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 42-53 -Called from Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 42-53 -Called from Backtrace_slots.f in file "backtrace_slots.ml", line 41, characters 42-53 -Called from Backtrace_slots.g in file "backtrace_slots.ml", line 45, characters 4-11 -Called from Backtrace_slots.run in file "backtrace_slots.ml", line 52, characters 11-23 +Raised at Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 16-32 +Called from Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 42-53 +Called from Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 42-53 +Called from Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 42-53 +Called from Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 42-53 +Called from Backtrace_slots.f in file "backtrace_slots.ml", line 40, characters 42-53 +Called from Backtrace_slots.g in file "backtrace_slots.ml", line 44, characters 4-11 +Called from Backtrace_slots.run in file "backtrace_slots.ml", line 51, characters 11-23 Uncaught exception Invalid_argument("index out of bounds") -Raised by primitive operation at Backtrace_slots.run in file "backtrace_slots.ml", line 52, characters 14-22 +Raised by primitive operation at Backtrace_slots.run in file "backtrace_slots.ml", line 51, characters 14-22 diff --git a/testsuite/tests/backtrace/backtraces_and_finalizers.ml b/testsuite/tests/backtrace/backtraces_and_finalizers.ml index 8ea69593..60c02f48 100644 --- a/testsuite/tests/backtrace/backtraces_and_finalizers.ml +++ b/testsuite/tests/backtrace/backtraces_and_finalizers.ml @@ -1,12 +1,9 @@ (* TEST flags = "-g -inline 0" ocamlrunparam += ",b=1" - compare_programs = "false" * native *) -let () = Printexc.record_backtrace true - let finaliser _ = try raise Exit with _ -> () let create () = diff --git a/testsuite/tests/backtrace/callstack.ml b/testsuite/tests/backtrace/callstack.ml index fc39ec1a..5c33816e 100644 --- a/testsuite/tests/backtrace/callstack.ml +++ b/testsuite/tests/backtrace/callstack.ml @@ -2,7 +2,6 @@ flags = "-g" * hassysthreads include systhreads - compare_programs = "false" ** no-flambda *** native *** bytecode diff --git a/testsuite/tests/backtrace/callstack.reference b/testsuite/tests/backtrace/callstack.reference index e6c202d4..38ca17d9 100644 --- a/testsuite/tests/backtrace/callstack.reference +++ b/testsuite/tests/backtrace/callstack.reference @@ -1,15 +1,15 @@ main thread: -Raised by primitive operation at Callstack.f0 in file "callstack.ml", line 12, characters 38-66 -Called from Callstack.f1 in file "callstack.ml", line 13, characters 27-32 -Called from Callstack.f2 in file "callstack.ml", line 14, characters 27-32 -Called from Callstack.f3 in file "callstack.ml", line 15, characters 27-32 -Called from Callstack in file "callstack.ml", line 18, characters 9-14 +Raised by primitive operation at Callstack.f0 in file "callstack.ml", line 11, characters 38-66 +Called from Callstack.f1 in file "callstack.ml", line 12, characters 27-32 +Called from Callstack.f2 in file "callstack.ml", line 13, characters 27-32 +Called from Callstack.f3 in file "callstack.ml", line 14, characters 27-32 +Called from Callstack in file "callstack.ml", line 17, characters 9-14 from finalizer: -Raised by primitive operation at Callstack.f0 in file "callstack.ml", line 12, characters 38-66 -Called from Callstack in file "callstack.ml", line 23, characters 2-18 +Raised by primitive operation at Callstack.f0 in file "callstack.ml", line 11, characters 38-66 +Called from Callstack in file "callstack.ml", line 22, characters 2-18 new thread: -Raised by primitive operation at Callstack.f0 in file "callstack.ml", line 12, characters 38-66 -Called from Callstack.f1 in file "callstack.ml", line 13, characters 27-32 -Called from Callstack.f2 in file "callstack.ml", line 14, characters 27-32 -Called from Callstack.f3 in file "callstack.ml", line 15, characters 27-32 -Called from Thread.create.(fun) in file "thread.ml", line 39, characters 8-14 +Raised by primitive operation at Callstack.f0 in file "callstack.ml", line 11, characters 38-66 +Called from Callstack.f1 in file "callstack.ml", line 12, characters 27-32 +Called from Callstack.f2 in file "callstack.ml", line 13, characters 27-32 +Called from Callstack.f3 in file "callstack.ml", line 14, characters 27-32 +Called from Thread.create.(fun) in file "thread.ml", line 41, characters 8-14 diff --git a/testsuite/tests/backtrace/event_after_prim.ml b/testsuite/tests/backtrace/event_after_prim.ml index f57b00bb..6af09a5f 100644 --- a/testsuite/tests/backtrace/event_after_prim.ml +++ b/testsuite/tests/backtrace/event_after_prim.ml @@ -1,6 +1,6 @@ (* TEST flags = "-g" - compare_programs = "false" *) +*) let f n b = let arr = Array.make n 42 in diff --git a/testsuite/tests/backtrace/filter-locations.sh b/testsuite/tests/backtrace/filter-locations.sh index 6d9757f4..56a1485d 100755 --- a/testsuite/tests/backtrace/filter-locations.sh +++ b/testsuite/tests/backtrace/filter-locations.sh @@ -1,2 +1,5 @@ #!/bin/sh -grep -oE '[a-zA-Z_]+\.ml(:[0-9]+)?|(line|characters) [0-9-]+' +# This location filter is erasing information from the backtrace +# to be robust to different inlining choices made by different compiler settings. +# It checks that the expected locations occur (in the expected order). +sed -e "s/^.*in file/File/" -e 's/ (inlined)//' | grep ^File diff --git a/testsuite/tests/backtrace/inline_test.ml b/testsuite/tests/backtrace/inline_test.ml index 756dc148..f8ffe38f 100644 --- a/testsuite/tests/backtrace/inline_test.ml +++ b/testsuite/tests/backtrace/inline_test.ml @@ -3,11 +3,9 @@ ocamlrunparam += ",b=1" * bytecode * native - compare_programs = "false" * native ocamlopt_flags = "-O3" compiler_directory_suffix = ".O3" - compare_programs = "false" *) (* A test for inlined stack backtraces *) @@ -25,5 +23,4 @@ let i x = if h x = () then () let () = - Printexc.record_backtrace true; i () diff --git a/testsuite/tests/backtrace/inline_test.reference b/testsuite/tests/backtrace/inline_test.reference index 556ef2fc..526d2ecd 100644 --- a/testsuite/tests/backtrace/inline_test.reference +++ b/testsuite/tests/backtrace/inline_test.reference @@ -1,15 +1,5 @@ -inline_test.ml -line 16 -characters 2-24 -inline_test.ml -line 19 -characters 2-5 -inline_test.ml -line 22 -characters 12-17 -inline_test.ml -line 25 -characters 5-8 -inline_test.ml -line 29 -characters 2-6 +File "inline_test.ml", line 14, characters 2-24 +File "inline_test.ml", line 17, characters 2-5 +File "inline_test.ml", line 20, characters 12-17 +File "inline_test.ml", line 23, characters 5-8 +File "inline_test.ml", line 26, characters 2-6 diff --git a/testsuite/tests/backtrace/inline_traversal_test.ml b/testsuite/tests/backtrace/inline_traversal_test.ml index c4393bc9..d70c7fc5 100644 --- a/testsuite/tests/backtrace/inline_traversal_test.ml +++ b/testsuite/tests/backtrace/inline_traversal_test.ml @@ -3,11 +3,9 @@ ocamlrunparam += ",b=1" * bytecode * native - compare_programs = "false" * native ocamlopt_flags = "-O3" compiler_directory_suffix = ".O3" - compare_programs = "false" *) (* A test for inlined stack backtraces *) @@ -26,7 +24,6 @@ let i x = let () = let open Printexc in - record_backtrace true; try i () with _ -> let trace = get_raw_backtrace () in @@ -39,9 +36,9 @@ let () = | Some {filename; line_number; _} -> filename ^ ":" ^ Int.to_string line_number in - Printf.printf "- %s%s%s\n" + Printf.printf "File %s%s%s\n" location - (if is_inline then " inlined" else "") + (if is_inline then " (inlined)" else "") (if is_raise then ", raise" else "") in let rec print_slots = function diff --git a/testsuite/tests/backtrace/inline_traversal_test.reference b/testsuite/tests/backtrace/inline_traversal_test.reference index 8dcdf455..00c02fc6 100644 --- a/testsuite/tests/backtrace/inline_traversal_test.reference +++ b/testsuite/tests/backtrace/inline_traversal_test.reference @@ -1,5 +1,5 @@ -inline_traversal_test.ml:16 -inline_traversal_test.ml:19 -inline_traversal_test.ml:22 -inline_traversal_test.ml:25 -inline_traversal_test.ml:30 +File inline_traversal_test.ml:14, raise +File inline_traversal_test.ml:17 +File inline_traversal_test.ml:20 +File inline_traversal_test.ml:23 +File inline_traversal_test.ml:27 diff --git a/testsuite/tests/backtrace/lazy.ml b/testsuite/tests/backtrace/lazy.ml new file mode 100644 index 00000000..44dbb043 --- /dev/null +++ b/testsuite/tests/backtrace/lazy.ml @@ -0,0 +1,27 @@ +(* TEST + flags = "-g" + * native +*) + + +let l1 : unit lazy_t = lazy (raise Not_found) + +let test1 () = + let () = Lazy.force l1 in () + +let l2 : unit lazy_t = lazy (raise Not_found) + +let test2 () = + let (lazy ()) = l2 in () + +let run test = + try + test (); + with exn -> + Printf.printf "Uncaught exception %s\n" (Printexc.to_string exn); + Printexc.print_backtrace stdout + +let () = + Printexc.record_backtrace true; + run test1; + run test2 diff --git a/testsuite/tests/backtrace/lazy.reference b/testsuite/tests/backtrace/lazy.reference new file mode 100644 index 00000000..ccb2a21e --- /dev/null +++ b/testsuite/tests/backtrace/lazy.reference @@ -0,0 +1,12 @@ +Uncaught exception Not_found +Raised at Lazy.l1 in file "lazy.ml", line 7, characters 28-45 +Called from CamlinternalLazy.force_lazy_block in file "camlinternalLazy.ml", line 31, characters 17-27 +Re-raised at CamlinternalLazy.force_lazy_block in file "camlinternalLazy.ml", line 36, characters 4-11 +Called from Lazy.test1 in file "lazy.ml", line 10, characters 11-24 +Called from Lazy.run in file "lazy.ml", line 19, characters 4-11 +Uncaught exception Not_found +Raised at Lazy.l2 in file "lazy.ml", line 12, characters 28-45 +Called from CamlinternalLazy.force_lazy_block in file "camlinternalLazy.ml", line 31, characters 17-27 +Re-raised at CamlinternalLazy.force_lazy_block in file "camlinternalLazy.ml", line 36, characters 4-11 +Called from Lazy.test2 in file "lazy.ml", line 15, characters 6-15 +Called from Lazy.run in file "lazy.ml", line 19, characters 4-11 diff --git a/testsuite/tests/backtrace/methods.ml b/testsuite/tests/backtrace/methods.ml index 0ea147c1..f016fb51 100644 --- a/testsuite/tests/backtrace/methods.ml +++ b/testsuite/tests/backtrace/methods.ml @@ -1,6 +1,6 @@ (* TEST flags = "-g" - compare_programs = "false" *) +*) let[@inline never] id x = Sys.opaque_identity x diff --git a/testsuite/tests/backtrace/names.ml b/testsuite/tests/backtrace/names.ml index ff4af583..06fc9ddf 100644 --- a/testsuite/tests/backtrace/names.ml +++ b/testsuite/tests/backtrace/names.ml @@ -1,6 +1,5 @@ (* TEST flags = "-g" - compare_programs = "false" *) diff --git a/testsuite/tests/backtrace/names.reference b/testsuite/tests/backtrace/names.reference index 8ded55a4..52935684 100644 --- a/testsuite/tests/backtrace/names.reference +++ b/testsuite/tests/backtrace/names.reference @@ -1,26 +1,26 @@ -Raised at Names.bang in file "names.ml", line 9, characters 29-39 -Called from Names.inline_object.object#othermeth in file "names.ml", line 97, characters 6-10 -Called from Names.inline_object.object#meth in file "names.ml", line 95, characters 6-26 -Called from Names.klass2#othermeth.(fun) in file "names.ml", line 89, characters 18-22 -Called from Names.klass2#othermeth in file "names.ml", line 89, characters 4-30 -Called from Names.klass#meth in file "names.ml", line 85, characters 4-27 -Called from Names.(+@+) in file "names.ml", line 80, characters 31-35 -Called from Names.Rec2.fn in file "names.ml", line 77, characters 28-32 -Called from Names.Rec1.fn in file "names.ml", line 72, characters 28-34 -Called from Names.Functor.fn in file "names.ml", line 64, characters 28-32 -Called from Names.local_module.N.foo in file "names.ml", line 58, characters 6-10 -Called from Names.local_module.N in file "names.ml", line 59, characters 38-49 -Called from Names.local_no_arg.inner in file "names.ml", line 48, characters 16-20 -Called from Names.local_no_arg.(fun) in file "names.ml", line 49, characters 26-38 -Called from Names.double_local.inner1.inner2 in file "names.ml", line 43, characters 20-24 -Called from Names.double_local.inner1 in file "names.ml", line 44, characters 4-18 -Called from Names.double_local in file "names.ml", line 45, characters 2-16 -Called from Names.local.inner in file "names.ml", line 38, characters 32-36 -Called from Names.local in file "names.ml", line 39, characters 2-15 -Called from Names.double_anon.(fun) in file "names.ml", line 33, characters 6-10 -Called from Names.anon.(fun) in file "names.ml", line 27, characters 25-29 -Called from Names.Mod1.Nested.apply in file "names.ml", line 22, characters 33-37 -Called from Names.fn_poly in file "names.ml", line 18, characters 2-5 -Called from Names.fn_function in file "names.ml", line 15, characters 9-13 -Called from Names.fn_multi in file "names.ml", line 12, characters 36-40 -Called from Names in file "names.ml", line 104, characters 4-445 +Raised at Names.bang in file "names.ml", line 8, characters 29-39 +Called from Names.inline_object.object#othermeth in file "names.ml", line 96, characters 6-10 +Called from Names.inline_object.object#meth in file "names.ml", line 94, characters 6-26 +Called from Names.klass2#othermeth.(fun) in file "names.ml", line 88, characters 18-22 +Called from Names.klass2#othermeth in file "names.ml", line 88, characters 4-30 +Called from Names.klass#meth in file "names.ml", line 84, characters 4-27 +Called from Names.(+@+) in file "names.ml", line 79, characters 31-35 +Called from Names.Rec2.fn in file "names.ml", line 76, characters 28-32 +Called from Names.Rec1.fn in file "names.ml", line 71, characters 28-34 +Called from Names.Functor.fn in file "names.ml", line 63, characters 28-32 +Called from Names.local_module.N.foo in file "names.ml", line 57, characters 6-10 +Called from Names.local_module.N in file "names.ml", line 58, characters 38-49 +Called from Names.local_no_arg.inner in file "names.ml", line 47, characters 16-20 +Called from Names.local_no_arg.(fun) in file "names.ml", line 48, characters 26-38 +Called from Names.double_local.inner1.inner2 in file "names.ml", line 42, characters 20-24 +Called from Names.double_local.inner1 in file "names.ml", line 43, characters 4-18 +Called from Names.double_local in file "names.ml", line 44, characters 2-16 +Called from Names.local.inner in file "names.ml", line 37, characters 32-36 +Called from Names.local in file "names.ml", line 38, characters 2-15 +Called from Names.double_anon.(fun) in file "names.ml", line 32, characters 6-10 +Called from Names.anon.(fun) in file "names.ml", line 26, characters 25-29 +Called from Names.Mod1.Nested.apply in file "names.ml", line 21, characters 33-37 +Called from Names.fn_poly in file "names.ml", line 17, characters 2-5 +Called from Names.fn_function in file "names.ml", line 14, characters 9-13 +Called from Names.fn_multi in file "names.ml", line 11, characters 36-40 +Called from Names in file "names.ml", line 103, characters 4-445 diff --git a/testsuite/tests/backtrace/pr2195-locs.byte.reference b/testsuite/tests/backtrace/pr2195-locs.byte.reference new file mode 100644 index 00000000..ad64bd9f --- /dev/null +++ b/testsuite/tests/backtrace/pr2195-locs.byte.reference @@ -0,0 +1,4 @@ +Fatal error: exception Stdlib.Exit +Raised by primitive operation at Stdlib.open_in_gen in file "stdlib.ml", line 399, characters 28-54 +Called from Pr2195 in file "pr2195.ml", line 24, characters 6-19 +Re-raised at Pr2195 in file "pr2195.ml", line 29, characters 4-41 diff --git a/testsuite/tests/backtrace/pr2195-nolocs.byte.reference b/testsuite/tests/backtrace/pr2195-nolocs.byte.reference new file mode 100644 index 00000000..40d8e5a6 --- /dev/null +++ b/testsuite/tests/backtrace/pr2195-nolocs.byte.reference @@ -0,0 +1,6 @@ +Fatal error: exception Stdlib.Exit +Raised by primitive operation at unknown location +Called from unknown location +(Cannot print locations: + bytecode executable program file cannot be opened; + -- too many open files. Try running with OCAMLRUNPARAM=b=2) diff --git a/testsuite/tests/backtrace/pr2195.ml b/testsuite/tests/backtrace/pr2195.ml new file mode 100644 index 00000000..e0442a34 --- /dev/null +++ b/testsuite/tests/backtrace/pr2195.ml @@ -0,0 +1,29 @@ +(* TEST + flags += "-g" + exit_status = "2" + * bytecode + ocamlrunparam += ",b=0" + reference = "${test_source_directory}/pr2195-nolocs.byte.reference" + * bytecode + ocamlrunparam += ",b=1" + reference = "${test_source_directory}/pr2195-nolocs.byte.reference" + * bytecode + ocamlrunparam += ",b=2" + reference = "${test_source_directory}/pr2195-locs.byte.reference" + * native + reference = "${test_source_directory}/pr2195.opt.reference" + compare_programs = "false" +*) + +let () = + Printexc.record_backtrace true; + let c = open_out "foo" in + close_out c; + try + while true do + open_in "foo" |> ignore + done + with Sys_error _ -> + (* The message is platform-specific, so convert the exception to Exit *) + let bt = Printexc.get_raw_backtrace () in + Printexc.raise_with_backtrace Exit bt diff --git a/testsuite/tests/backtrace/pr2195.opt.reference b/testsuite/tests/backtrace/pr2195.opt.reference new file mode 100644 index 00000000..f43c865a --- /dev/null +++ b/testsuite/tests/backtrace/pr2195.opt.reference @@ -0,0 +1,5 @@ +Fatal error: exception Stdlib.Exit +Raised by primitive operation at Stdlib.open_in_gen in file "stdlib.ml", line 399, characters 28-54 +Called from Stdlib.open_in in file "stdlib.ml" (inlined), line 404, characters 2-45 +Called from Pr2195 in file "pr2195.ml", line 24, characters 6-19 +Re-raised at Pr2195 in file "pr2195.ml", line 29, characters 4-41 diff --git a/testsuite/tests/backtrace/pr2195.run b/testsuite/tests/backtrace/pr2195.run new file mode 100755 index 00000000..1dc6d478 --- /dev/null +++ b/testsuite/tests/backtrace/pr2195.run @@ -0,0 +1,9 @@ +#!/bin/sh + +# ulimit -n will have no effect on the Windows builds. The number of open files +# on Windows is theoretically limited by available memory only, however the CRT +# is limited to 8192 open files (including the standard handles). +ulimit -n 32 + +${program} > ${output} 2>&1 +echo 'exit_status="'$?'"' > ${ocamltest_response} diff --git a/testsuite/tests/backtrace/pr6920_why_at.ml b/testsuite/tests/backtrace/pr6920_why_at.ml index 4b955667..1a0583a6 100644 --- a/testsuite/tests/backtrace/pr6920_why_at.ml +++ b/testsuite/tests/backtrace/pr6920_why_at.ml @@ -3,7 +3,6 @@ ocamlrunparam += ",b=1" ocamlopt_flags = "-inline 0" exit_status = "2" - compare_programs = "false" *) let why : unit -> unit = fun () -> raise Exit [@@inline never] @@ -13,5 +12,4 @@ let f () = () [@@inline never] let () = - Printexc.record_backtrace true; f () diff --git a/testsuite/tests/backtrace/pr6920_why_at.reference b/testsuite/tests/backtrace/pr6920_why_at.reference index 5f71d817..258e6d49 100644 --- a/testsuite/tests/backtrace/pr6920_why_at.reference +++ b/testsuite/tests/backtrace/pr6920_why_at.reference @@ -1,4 +1,4 @@ Fatal error: exception Stdlib.Exit -Raised at Pr6920_why_at.why in file "pr6920_why_at.ml", line 9, characters 35-45 -Called from Pr6920_why_at.f in file "pr6920_why_at.ml", line 11, characters 2-11 -Called from Pr6920_why_at in file "pr6920_why_at.ml", line 17, characters 2-6 +Raised at Pr6920_why_at.why in file "pr6920_why_at.ml", line 8, characters 35-45 +Called from Pr6920_why_at.f in file "pr6920_why_at.ml", line 10, characters 2-11 +Called from Pr6920_why_at in file "pr6920_why_at.ml", line 15, characters 2-6 diff --git a/testsuite/tests/backtrace/pr6920_why_swallow.ml b/testsuite/tests/backtrace/pr6920_why_swallow.ml index b67e034d..b1e5d60f 100644 --- a/testsuite/tests/backtrace/pr6920_why_swallow.ml +++ b/testsuite/tests/backtrace/pr6920_why_swallow.ml @@ -3,7 +3,6 @@ ocamlrunparam += ",b=1" ocamlopt_flags = "-inline 0" exit_status = "2" - compare_programs = "false" *) let why : unit -> unit = fun () -> raise Exit [@@inline never] @@ -15,5 +14,4 @@ let f () = () [@@inline never] let () = - Printexc.record_backtrace true; f () diff --git a/testsuite/tests/backtrace/pr6920_why_swallow.reference b/testsuite/tests/backtrace/pr6920_why_swallow.reference index dda5d39d..c5769128 100644 --- a/testsuite/tests/backtrace/pr6920_why_swallow.reference +++ b/testsuite/tests/backtrace/pr6920_why_swallow.reference @@ -1,4 +1,4 @@ Fatal error: exception Stdlib.Exit -Raised at Pr6920_why_swallow.why in file "pr6920_why_swallow.ml", line 9, characters 35-45 -Called from Pr6920_why_swallow.f in file "pr6920_why_swallow.ml", line 12, characters 4-13 -Called from Pr6920_why_swallow in file "pr6920_why_swallow.ml", line 19, characters 2-6 +Raised at Pr6920_why_swallow.why in file "pr6920_why_swallow.ml", line 8, characters 35-45 +Called from Pr6920_why_swallow.f in file "pr6920_why_swallow.ml", line 11, characters 4-13 +Called from Pr6920_why_swallow in file "pr6920_why_swallow.ml", line 17, characters 2-6 diff --git a/testsuite/tests/backtrace/raw_backtrace.ml b/testsuite/tests/backtrace/raw_backtrace.ml index f200c797..a685133a 100644 --- a/testsuite/tests/backtrace/raw_backtrace.ml +++ b/testsuite/tests/backtrace/raw_backtrace.ml @@ -1,7 +1,6 @@ (* TEST flags = "-g" ocamlrunparam += ",b=1" - compare_programs = "false" *) (* A test for stack backtraces *) @@ -54,7 +53,6 @@ let run args = flush stdout let _ = - Printexc.record_backtrace true; run [| "a" |]; run [| "b" |]; run [| "c" |]; diff --git a/testsuite/tests/backtrace/raw_backtrace.reference b/testsuite/tests/backtrace/raw_backtrace.reference index 5416fa72..3f5a4030 100644 --- a/testsuite/tests/backtrace/raw_backtrace.reference +++ b/testsuite/tests/backtrace/raw_backtrace.reference @@ -2,48 +2,48 @@ a No exception b Uncaught exception Raw_backtrace.Error("b") -Raised at Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 16-32 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.g in file "raw_backtrace.ml", line 21, characters 4-11 -Re-raised at Raw_backtrace.g in file "raw_backtrace.ml", line 23, characters 62-71 -Called from Raw_backtrace.backtrace in file "raw_backtrace.ml", line 38, characters 11-23 +Raised at Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 16-32 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.g in file "raw_backtrace.ml", line 20, characters 4-11 +Re-raised at Raw_backtrace.g in file "raw_backtrace.ml", line 22, characters 62-71 +Called from Raw_backtrace.backtrace in file "raw_backtrace.ml", line 37, characters 11-23 Uncaught exception Raw_backtrace.Error("c") -Raised at Raw_backtrace.g in file "raw_backtrace.ml", line 24, characters 20-37 -Called from Raw_backtrace.backtrace in file "raw_backtrace.ml", line 38, characters 11-23 +Raised at Raw_backtrace.g in file "raw_backtrace.ml", line 23, characters 20-37 +Called from Raw_backtrace.backtrace in file "raw_backtrace.ml", line 37, characters 11-23 Uncaught exception Raw_backtrace.Error("d") -Raised at Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 16-32 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.g in file "raw_backtrace.ml", line 21, characters 4-11 -Called from Raw_backtrace.backtrace in file "raw_backtrace.ml", line 38, characters 11-23 +Raised at Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 16-32 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.g in file "raw_backtrace.ml", line 20, characters 4-11 +Called from Raw_backtrace.backtrace in file "raw_backtrace.ml", line 37, characters 11-23 e Uncaught exception Raw_backtrace.Error("e") -Raised at Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 16-32 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.g in file "raw_backtrace.ml", line 21, characters 4-11 -Re-raised at Raw_backtrace.g in file "raw_backtrace.ml", line 30, characters 9-45 -Called from Raw_backtrace.backtrace in file "raw_backtrace.ml", line 38, characters 11-23 +Raised at Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 16-32 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.g in file "raw_backtrace.ml", line 20, characters 4-11 +Re-raised at Raw_backtrace.g in file "raw_backtrace.ml", line 29, characters 9-45 +Called from Raw_backtrace.backtrace in file "raw_backtrace.ml", line 37, characters 11-23 f Uncaught exception Raw_backtrace.Localized(_) -Raised at Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 16-32 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.f in file "raw_backtrace.ml", line 12, characters 42-53 -Called from Raw_backtrace.g in file "raw_backtrace.ml", line 21, characters 4-11 -Re-raised at Raw_backtrace.g in file "raw_backtrace.ml", line 34, characters 9-57 -Called from Raw_backtrace.backtrace in file "raw_backtrace.ml", line 38, characters 11-23 +Raised at Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 16-32 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.f in file "raw_backtrace.ml", line 11, characters 42-53 +Called from Raw_backtrace.g in file "raw_backtrace.ml", line 20, characters 4-11 +Re-raised at Raw_backtrace.g in file "raw_backtrace.ml", line 33, characters 9-57 +Called from Raw_backtrace.backtrace in file "raw_backtrace.ml", line 37, characters 11-23 Uncaught exception Invalid_argument("index out of bounds") -Raised by primitive operation at Raw_backtrace.backtrace in file "raw_backtrace.ml", line 38, characters 14-22 +Raised by primitive operation at Raw_backtrace.backtrace in file "raw_backtrace.ml", line 37, characters 14-22 diff --git a/testsuite/tests/basic-modules/anonymous.ocamlc.reference b/testsuite/tests/basic-modules/anonymous.ocamlc.reference index aba92cbd..dd27f037 100644 --- a/testsuite/tests/basic-modules/anonymous.ocamlc.reference +++ b/testsuite/tests/basic-modules/anonymous.ocamlc.reference @@ -13,11 +13,11 @@ (apply (field 1 (global CamlinternalMod!)) [0: [0]] B (module-defn(B) Anonymous anonymous.ml(33):703-773 (let (x = [0: "foo" "bar"]) (makeblock 0)))) - (let (f = (function param 0a) s = (makemutable 0 "")) + (let (f = (function param 0) s = (makemutable 0 "")) (seq (ignore (let (*match* = (setfield_ptr 0 s "Hello World!")) (makeblock 0))) (let - (drop = (function param 0a) *match* = (apply drop (field 0 s))) + (drop = (function param 0) *match* = (apply drop (field 0 s))) (makeblock 0 A B f s drop)))))))) diff --git a/testsuite/tests/basic-modules/anonymous.ocamlopt.flambda.reference b/testsuite/tests/basic-modules/anonymous.ocamlopt.flambda.reference index 6f9a7cba..16b747f1 100644 --- a/testsuite/tests/basic-modules/anonymous.ocamlopt.flambda.reference +++ b/testsuite/tests/basic-modules/anonymous.ocamlopt.flambda.reference @@ -12,10 +12,9 @@ (apply (field 1 (global CamlinternalMod!)) [0: [0]] B (module-defn(B) Anonymous anonymous.ml(33):703-773 (let (x = [0: "foo" "bar"]) (makeblock 0)))) - (let (f = (function param 0a) s = (makemutable 0 "")) + (let (f = (function param 0) s = (makemutable 0 "")) (seq (ignore (let (*match* = (setfield_ptr 0 s "Hello World!")) (makeblock 0))) - (let - (drop = (function param 0a) *match* = (apply drop (field 0 s))) + (let (drop = (function param 0) *match* = (apply drop (field 0 s))) (makeblock 0 A B f s drop))))))) diff --git a/testsuite/tests/basic-modules/anonymous.ocamlopt.reference b/testsuite/tests/basic-modules/anonymous.ocamlopt.reference index 6d29841f..c0ed05cc 100644 --- a/testsuite/tests/basic-modules/anonymous.ocamlopt.reference +++ b/testsuite/tests/basic-modules/anonymous.ocamlopt.reference @@ -12,7 +12,7 @@ (let (x = [0: "foo" "bar"]) (makeblock 0))) (setfield_ptr(root-init) 0 (global Anonymous!) A) (setfield_ptr(root-init) 1 (global Anonymous!) B) - (let (f = (function param 0a)) + (let (f = (function param 0)) (setfield_ptr(root-init) 2 (global Anonymous!) f)) (let (s = (makemutable 0 "")) (setfield_ptr(root-init) 3 (global Anonymous!) s)) @@ -21,11 +21,11 @@ (*match* = (setfield_ptr 0 (field 3 (global Anonymous!)) "Hello World!")) (makeblock 0))) - (let (drop = (function param 0a)) + (let (drop = (function param 0)) (setfield_ptr(root-init) 4 (global Anonymous!) drop)) (let (*match* = (apply (field 4 (global Anonymous!)) (field 0 (field 3 (global Anonymous!))))) - 0a) - 0a))) + 0) + 0))) diff --git a/testsuite/tests/basic-more/morematch.compilers.reference b/testsuite/tests/basic-more/morematch.compilers.reference index 9404040d..ce9a2d31 100644 --- a/testsuite/tests/basic-more/morematch.compilers.reference +++ b/testsuite/tests/basic-more/morematch.compilers.reference @@ -1,60 +1,60 @@ File "morematch.ml", line 67, characters 2-5: 67 | | 4|5|7 -> 100 ^^^ -Warning 12: this sub-pattern is unused. +Warning 12 [redundant-subpat]: this sub-pattern is unused. File "morematch.ml", line 68, characters 2-3: 68 | | 7 | 8 -> 6 ^ -Warning 12: this sub-pattern is unused. +Warning 12 [redundant-subpat]: this sub-pattern is unused. File "morematch.ml", line 219, characters 33-47: 219 | let f = function (([]|[_]) as x)|(_::([] as x))|(_::_::x) -> x ^^^^^^^^^^^^^^ -Warning 12: this sub-pattern is unused. +Warning 12 [redundant-subpat]: this sub-pattern is unused. File "morematch.ml", line 388, characters 2-15: 388 | | A,_,(100|103) -> 5 ^^^^^^^^^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. File "morematch.ml", line 401, characters 2-20: 401 | | [],_,(100|103|104) -> 5 ^^^^^^^^^^^^^^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. File "morematch.ml", line 402, characters 2-16: 402 | | [],_,(100|103) -> 6 ^^^^^^^^^^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. File "morematch.ml", line 403, characters 2-29: 403 | | [],_,(1000|1001|1002|20000) -> 7 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. File "morematch.ml", line 413, characters 5-12: 413 | | (100|103|101) -> 2 ^^^^^^^ -Warning 12: this sub-pattern is unused. +Warning 12 [redundant-subpat]: this sub-pattern is unused. File "morematch.ml", line 432, characters 43-44: 432 | | (J,J,((C|D) as x |E x|F (_,x))) | (J,_,((C|J) as x)) -> autre (x,x,x) ^ -Warning 12: this sub-pattern is unused. +Warning 12 [redundant-subpat]: this sub-pattern is unused. File "morematch.ml", line 455, characters 7-8: 455 | | _,_,(X|U _) -> 8 ^ -Warning 12: this sub-pattern is unused. +Warning 12 [redundant-subpat]: this sub-pattern is unused. File "morematch.ml", line 456, characters 2-7: 456 | | _,_,Y -> 5 ^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. File "morematch.ml", lines 1050-1053, characters 8-10: 1050 | ........function 1051 | | A (`A|`C) -> 0 1052 | | B (`B,`D) -> 1 1053 | | C -> 2 -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: -(A `D|B (`B, (`A|`C))) +A `D File "morematch.ml", line 1084, characters 5-51: 1084 | | _, _, _, _, _, A, _, _, _, _, B, _, _, _, _, _ -> "11" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. File "morematch.ml", line 1086, characters 5-51: 1086 | | _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ -> "13" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. diff --git a/testsuite/tests/basic-more/robustmatch.compilers.reference b/testsuite/tests/basic-more/robustmatch.compilers.reference index fc580197..241b7395 100644 --- a/testsuite/tests/basic-more/robustmatch.compilers.reference +++ b/testsuite/tests/basic-more/robustmatch.compilers.reference @@ -4,7 +4,7 @@ File "robustmatch.ml", lines 33-37, characters 6-23: 35 | | MAB, _, A -> () 36 | | _, AB, B -> () 37 | | _, MAB, B -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (AB, MAB, A) File "robustmatch.ml", lines 43-47, characters 4-21: @@ -13,42 +13,42 @@ File "robustmatch.ml", lines 43-47, characters 4-21: 45 | | MAB, _, A -> () 46 | | _, AB, B -> () 47 | | _, MAB, B -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (AB, MAB, A) File "robustmatch.ml", lines 54-56, characters 4-27: 54 | ....match r1, r2, a with 55 | | R1, _, 0 -> () 56 | | _, R2, "coucou" -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, 1) File "robustmatch.ml", lines 64-66, characters 4-27: 64 | ....match r1, r2, a with 65 | | R1, _, A -> () 66 | | _, R2, "coucou" -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, (B|C)) File "robustmatch.ml", lines 69-71, characters 4-20: 69 | ....match r1, r2, a with 70 | | _, R2, "coucou" -> () 71 | | R1, _, A -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, (B|C)) File "robustmatch.ml", lines 74-76, characters 4-20: 74 | ....match r1, r2, a with 75 | | _, R2, "coucou" -> () 76 | | R1, _, _ -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R2, R2, "") File "robustmatch.ml", lines 85-87, characters 4-20: 85 | ....match r1, r2, a with 86 | | R1, _, A -> () 87 | | _, R2, X -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, (B|C)) File "robustmatch.ml", lines 90-93, characters 4-20: @@ -56,35 +56,35 @@ File "robustmatch.ml", lines 90-93, characters 4-20: 91 | | R1, _, A -> () 92 | | _, R2, X -> () 93 | | R1, _, _ -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R2, R2, (Y|Z)) File "robustmatch.ml", lines 96-98, characters 4-20: 96 | ....match r1, r2, a with 97 | | R1, _, _ -> () 98 | | _, R2, X -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R2, R2, (Y|Z)) File "robustmatch.ml", lines 107-109, characters 4-20: 107 | ....match r1, r2, a with 108 | | R1, _, A -> () 109 | | _, R2, X -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, (B|C)) File "robustmatch.ml", lines 129-131, characters 4-20: 129 | ....match r1, r2, a with 130 | | R1, _, A -> () 131 | | _, R2, X -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, B) File "robustmatch.ml", lines 151-153, characters 4-20: 151 | ....match r1, r2, a with 152 | | R1, _, A -> () 153 | | _, R2, X -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, B) File "robustmatch.ml", lines 156-159, characters 4-20: @@ -92,21 +92,21 @@ File "robustmatch.ml", lines 156-159, characters 4-20: 157 | | R1, _, A -> () 158 | | _, R2, X -> () 159 | | R1, _, _ -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R2, R2, Y) File "robustmatch.ml", lines 162-164, characters 4-20: 162 | ....match r1, r2, a with 163 | | R1, _, _ -> () 164 | | _, R2, X -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R2, R2, Y) File "robustmatch.ml", lines 167-169, characters 4-20: 167 | ....match r1, r2, a with 168 | | R1, _, C -> () 169 | | _, R2, Y -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, A) File "robustmatch.ml", lines 176-179, characters 4-20: @@ -114,14 +114,14 @@ File "robustmatch.ml", lines 176-179, characters 4-20: 177 | | _, R1, 0 -> () 178 | | R2, _, [||] -> () 179 | | _, R1, 1 -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R2, R2, [| _ |]) File "robustmatch.ml", lines 182-184, characters 4-23: 182 | ....match r1, r2, a with 183 | | R1, _, _ -> () 184 | | _, R2, [||] -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R2, R2, [| _ |]) File "robustmatch.ml", lines 187-190, characters 4-20: @@ -129,7 +129,7 @@ File "robustmatch.ml", lines 187-190, characters 4-20: 188 | | _, R2, [||] -> () 189 | | R1, _, 0 -> () 190 | | R1, _, _ -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R2, R2, [| _ |]) File "robustmatch.ml", lines 200-203, characters 4-19: @@ -137,62 +137,62 @@ File "robustmatch.ml", lines 200-203, characters 4-19: 201 | | _, R2, [||] -> () 202 | | R1, _, 0 -> () 203 | | _, _, _ -> () -Warning 4: this pattern-matching is fragile. +Warning 4 [fragile-match]: this pattern-matching is fragile. It will remain exhaustive when constructors are added to type repr. File "robustmatch.ml", lines 210-212, characters 4-27: 210 | ....match r1, r2, a with 211 | | R1, _, 'c' -> () 212 | | _, R2, "coucou" -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, 'a') File "robustmatch.ml", lines 219-221, characters 4-27: 219 | ....match r1, r2, a with 220 | | R1, _, `A -> () 221 | | _, R2, "coucou" -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, `B) File "robustmatch.ml", lines 228-230, characters 4-37: 228 | ....match r1, r2, a with 229 | | R1, _, (3, "") -> () 230 | | _, R2, (1, "coucou", 'a') -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, (3, "*")) File "robustmatch.ml", lines 239-241, characters 4-51: 239 | ....match r1, r2, a with 240 | | R1, _, { x = 3; y = "" } -> () 241 | | _, R2, { a = 1; b = "coucou"; c = 'a' } -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, {x=3; y="*"}) File "robustmatch.ml", lines 244-246, characters 4-36: 244 | ....match r1, r2, a with 245 | | R2, _, { a = 1; b = "coucou"; c = 'a' } -> () 246 | | _, R1, { x = 3; y = "" } -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R2, R2, {a=1; b="coucou"; c='b'}) File "robustmatch.ml", lines 253-255, characters 4-20: 253 | ....match r1, r2, a with 254 | | R1, _, (3, "") -> () 255 | | _, R2, 1 -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, (3, "*")) File "robustmatch.ml", lines 263-265, characters 4-20: 263 | ....match r1, r2, a with 264 | | R1, _, { x = 3; y = "" } -> () 265 | | _, R2, 1 -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, {x=3; y="*"}) File "robustmatch.ml", lines 272-274, characters 4-20: 272 | ....match r1, r2, a with 273 | | R1, _, lazy 1 -> () 274 | | _, R2, 1 -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R1, R1, lazy 0) File "robustmatch.ml", lines 281-284, characters 4-24: @@ -200,6 +200,6 @@ File "robustmatch.ml", lines 281-284, characters 4-24: 282 | | R1, _, () -> () 283 | | _, R2, "coucou" -> () 284 | | _, R2, "foo" -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (R2, R2, "") diff --git a/testsuite/tests/basic/equality.ml b/testsuite/tests/basic/equality.ml index 19d76e09..8c11a8fd 100644 --- a/testsuite/tests/basic/equality.ml +++ b/testsuite/tests/basic/equality.ml @@ -12,6 +12,11 @@ let eqtrue (b:bool) = b let eqftffff = function (false,true,false,false,false,false) -> true | _ -> false +let eqfun delayed_check = + match delayed_check () with + | exception Invalid_argument _ -> true + | _ -> false + let x = [1;2;3] let f x = 1 :: 2 :: 3 :: x @@ -33,6 +38,9 @@ let mkleftlist len = for i = 1 to len do l := Cons(!l, i) done; !l +(* use an existential to check equality with different tags *) +type any = Any : 'a -> any + let _ = test 1 eq0 (compare 0 0); test 2 eqm1 (compare 0 1); @@ -103,4 +111,25 @@ let _ = test 52 eqtrue (testcmpfloat 0.0 nan); test 53 eqtrue (testcmpfloat 0.0 0.0); test 54 eqtrue (testcmpfloat 1.0 0.0); - test 55 eqtrue (testcmpfloat 0.0 1.0) + test 55 eqtrue (testcmpfloat 0.0 1.0); + test 56 eqfun (fun () -> compare (fun x -> x) (fun x -> x)); + test 57 eqfun (fun () -> + (* #9521 *) + let rec f x = g x and g x = f x in compare f g); + + (* this is the current behavior of comparison + with values of incoherent types (packed below + an existential), but it may not be the only specification. *) + test 58 eqm1 + (compare (Any 0) (Any 2)); + begin + (* comparing two function fails *) + test 59 eqfun (fun () -> + compare (Any (fun x -> x)) (Any (fun x -> x + 1))); + (* comparing a function and a non-function succeeds *) + test 60 (Fun.negate eq0) + (compare (Any (fun x -> x)) (Any 0)); + test 61 (Fun.negate eq0) + (compare (Any 0) (Any (fun x -> x))); + end; + () diff --git a/testsuite/tests/basic/equality.reference b/testsuite/tests/basic/equality.reference index 6070a6b0..75cfa164 100644 --- a/testsuite/tests/basic/equality.reference +++ b/testsuite/tests/basic/equality.reference @@ -47,3 +47,9 @@ Test 52 passed. Test 53 passed. Test 54 passed. Test 55 passed. +Test 56 passed. +Test 57 passed. +Test 58 passed. +Test 59 passed. +Test 60 passed. +Test 61 passed. diff --git a/testsuite/tests/basic/patmatch_for_multiple.ml b/testsuite/tests/basic/patmatch_for_multiple.ml new file mode 100644 index 00000000..d3146823 --- /dev/null +++ b/testsuite/tests/basic/patmatch_for_multiple.ml @@ -0,0 +1,59 @@ +(* TEST + flags = "-drawlambda" + * expect +*) + +(* Successful flattening *) + +match (3, 2, 1) with +| (_, 3, _) +| (1, _, _) -> true +| _ -> false +;; +[%%expect{| +(let + (*match*/88 = 3 + *match*/89 = 2 + *match*/90 = 1 + *match*/91 = *match*/88 + *match*/92 = *match*/89 + *match*/93 = *match*/90) + (catch + (catch + (catch (if (!= *match*/92 3) (exit 3) (exit 1)) with (3) + (if (!= *match*/91 1) (exit 2) (exit 1))) + with (2) 0) + with (1) 1)) +- : bool = false +|}];; + +(* Failed flattening: we need to allocate the tuple to bind x. *) + +match (3, 2, 1) with +| ((_, 3, _) as x) +| ((1, _, _) as x) -> ignore x; true +| _ -> false +;; +[%%expect{| +(let + (*match*/96 = 3 + *match*/97 = 2 + *match*/98 = 1 + *match*/99 = (makeblock 0 *match*/96 *match*/97 *match*/98)) + (catch + (catch + (let (*match*/100 =a (field 0 *match*/99)) + (catch + (let (*match*/101 =a (field 1 *match*/99)) + (if (!= *match*/101 3) (exit 7) + (let (*match*/102 =a (field 2 *match*/99)) (exit 5 *match*/99)))) + with (7) + (if (!= *match*/100 1) (exit 6) + (let + (*match*/104 =a (field 2 *match*/99) + *match*/103 =a (field 1 *match*/99)) + (exit 5 *match*/99))))) + with (6) 0) + with (5 x/94) (seq (ignore x/94) 1))) +- : bool = false +|}];; diff --git a/testsuite/tests/basic/patmatch_incoherence.ml b/testsuite/tests/basic/patmatch_incoherence.ml index c54fd918..584b4c2a 100644 --- a/testsuite/tests/basic/patmatch_incoherence.ml +++ b/testsuite/tests/basic/patmatch_incoherence.ml @@ -39,7 +39,7 @@ Lines 1-3, characters 0-20: 1 | match { x = assert false } with 2 | | { x = 3 } -> () 3 | | { x = None } -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {x=Some _} Exception: Assert_failure ("", 1, 12). @@ -54,7 +54,7 @@ Lines 1-3, characters 0-18: 1 | match { x = assert false } with 2 | | { x = None } -> () 3 | | { x = "" } -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {x="*"} Exception: Assert_failure ("", 1, 12). @@ -69,7 +69,7 @@ Lines 1-3, characters 0-18: 1 | match { x = assert false } with 2 | | { x = None } -> () 3 | | { x = `X } -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {x=`AnyOtherTag} Exception: Assert_failure ("", 1, 12). @@ -84,7 +84,7 @@ Lines 1-3, characters 0-17: 1 | match { x = assert false } with 2 | | { x = [||] } -> () 3 | | { x = 3 } -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {x=0} Exception: Assert_failure ("", 1, 12). @@ -99,7 +99,7 @@ Lines 1-3, characters 0-17: 1 | match { x = assert false } with 2 | | { x = `X } -> () 3 | | { x = 3 } -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {x=0} Exception: Assert_failure ("", 1, 12). @@ -114,7 +114,7 @@ Lines 1-3, characters 0-17: 1 | match { x = assert false } with 2 | | { x = `X "lol" } -> () 3 | | { x = 3 } -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {x=0} Exception: Assert_failure ("", 1, 12). @@ -131,7 +131,7 @@ Lines 1-4, characters 0-17: 2 | | { x = (2., "") } -> () 3 | | { x = None } -> () 4 | | { x = 3 } -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {x=0} Exception: Assert_failure ("", 1, 12). diff --git a/testsuite/tests/basic/patmatch_split_no_or.ml b/testsuite/tests/basic/patmatch_split_no_or.ml index 4f494656..86a689fb 100644 --- a/testsuite/tests/basic/patmatch_split_no_or.ml +++ b/testsuite/tests/basic/patmatch_split_no_or.ml @@ -49,7 +49,7 @@ val last_is_vars : bool * bool -> int = type t = .. type t += A | B of unit | C of bool * int;; [%%expect{| -0a +0 type t = .. (let (A/25 = (makeblock 248 "A" (caml_fresh_oo_id 0)) diff --git a/testsuite/tests/callback/callbackprim.c b/testsuite/tests/callback/callbackprim.c index 45879a01..4a0ad05c 100644 --- a/testsuite/tests/callback/callbackprim.c +++ b/testsuite/tests/callback/callbackprim.c @@ -13,6 +13,7 @@ /* */ /**************************************************************************/ +#include #include "caml/mlvalues.h" #include "caml/memory.h" #include "caml/callback.h" @@ -67,3 +68,9 @@ value mycamlparam (value v, value fun, value arg) v = x; CAMLreturn (v); } + +value raise_sigusr1(value unused) +{ + raise(SIGUSR1); + return Val_unit; +} diff --git a/testsuite/tests/callback/signals_alloc.ml b/testsuite/tests/callback/signals_alloc.ml index ae5f0d7f..27ed2f7d 100644 --- a/testsuite/tests/callback/signals_alloc.ml +++ b/testsuite/tests/callback/signals_alloc.ml @@ -1,11 +1,11 @@ (* TEST include unix + modules = "callbackprim.c" * libunix ** bytecode ** native *) - -let pid = Unix.getpid () +external raise_sigusr1 : unit -> unit = "raise_sigusr1" let do_test () = let seen_states = Array.make 5 (-1) in @@ -19,12 +19,13 @@ let do_test () = seen_states.(!pos) <- 0; pos := !pos + 1; Sys.set_signal Sys.sigusr1 (Sys.Signal_handle sighandler); seen_states.(!pos) <- 1; pos := !pos + 1; - Unix.kill pid Sys.sigusr1; + raise_sigusr1 (); seen_states.(!pos) <- 2; pos := !pos + 1; let _ = Sys.opaque_identity (ref 1) in seen_states.(!pos) <- 4; pos := !pos + 1; Sys.set_signal Sys.sigusr1 Sys.Signal_default; - assert (seen_states = [|0;1;2;3;4|]) + Array.iter (Printf.printf "%d") seen_states; + print_newline () let () = for _ = 0 to 10 do do_test () done; diff --git a/testsuite/tests/callback/signals_alloc.reference b/testsuite/tests/callback/signals_alloc.reference index d86bac9d..3e5c37f9 100644 --- a/testsuite/tests/callback/signals_alloc.reference +++ b/testsuite/tests/callback/signals_alloc.reference @@ -1 +1,12 @@ +01234 +01234 +01234 +01234 +01234 +01234 +01234 +01234 +01234 +01234 +01234 OK diff --git a/testsuite/tests/callback/tcallback.ml b/testsuite/tests/callback/tcallback.ml index 9e4e09f5..cf9568a8 100644 --- a/testsuite/tests/callback/tcallback.ml +++ b/testsuite/tests/callback/tcallback.ml @@ -52,17 +52,14 @@ let sighandler signo = (* Thoroughly wipe the minor heap *) ignore (tak (18, 12, 6)) -external unix_getpid : unit -> int = "unix_getpid" [@@noalloc] -external unix_kill : int -> int -> unit = "unix_kill" [@@noalloc] +external raise_sigusr1 : unit -> unit = "raise_sigusr1" [@@noalloc] let callbacksig () = - let pid = unix_getpid() in (* Allocate a block in the minor heap *) let s = String.make 5 'b' in (* Send a signal to self. We want s to remain in a register and - not be spilled on the stack, hence we declare unix_kill - [@@noalloc]. *) - unix_kill pid Sys.sigusr1; + not be spilled on the stack, hence we use a [@@noalloc] stub *) + raise_sigusr1 (); (* Allocate some more so that the signal will be tested *) let u = (s, s) in fst u diff --git a/testsuite/tests/flambda/afl_lazy.ml b/testsuite/tests/flambda/afl_lazy.ml new file mode 100644 index 00000000..fd5178da --- /dev/null +++ b/testsuite/tests/flambda/afl_lazy.ml @@ -0,0 +1,11 @@ +(* TEST + * flambda + ** native + ocamlopt_flags = "-O3 -afl-instrument" +*) + +let f l = + Lazy.force l + +let _ = + Sys.opaque_identity (f (lazy "Hello")) diff --git a/testsuite/tests/float-unboxing/float_subst_boxed_number.ml b/testsuite/tests/float-unboxing/float_subst_boxed_number.ml index 4ca01612..459e3eba 100644 --- a/testsuite/tests/float-unboxing/float_subst_boxed_number.ml +++ b/testsuite/tests/float-unboxing/float_subst_boxed_number.ml @@ -4,7 +4,6 @@ ocamlc_flags = "config.cmo" ocamlopt_flags = "-inline 20 config.cmx" * native - compare_programs = "false" *) let eliminate_intermediate_float_record () = diff --git a/testsuite/tests/formatting/test_locations.dlocations.ocamlc.reference b/testsuite/tests/formatting/test_locations.dlocations.ocamlc.reference index d5b96eb9..33368c57 100644 --- a/testsuite/tests/formatting/test_locations.dlocations.ocamlc.reference +++ b/testsuite/tests/formatting/test_locations.dlocations.ocamlc.reference @@ -1,75 +1,75 @@ [ - structure_item (test_locations.ml[42,1260+0]..[44,1298+34]) + structure_item (test_locations.ml[17,534+0]..[19,572+34]) Pstr_value Rec [ - pattern (test_locations.ml[42,1260+8]..[42,1260+11]) - Ppat_var "fib" (test_locations.ml[42,1260+8]..[42,1260+11]) - expression (test_locations.ml[42,1260+14]..[44,1298+34]) + pattern (test_locations.ml[17,534+8]..[17,534+11]) + Ppat_var "fib" (test_locations.ml[17,534+8]..[17,534+11]) + expression (test_locations.ml[17,534+14]..[19,572+34]) Pexp_function [ - pattern (test_locations.ml[43,1283+4]..[43,1283+9]) + pattern (test_locations.ml[18,557+4]..[18,557+9]) Ppat_or - pattern (test_locations.ml[43,1283+4]..[43,1283+5]) + pattern (test_locations.ml[18,557+4]..[18,557+5]) Ppat_constant PConst_int (0,None) - pattern (test_locations.ml[43,1283+8]..[43,1283+9]) + pattern (test_locations.ml[18,557+8]..[18,557+9]) Ppat_constant PConst_int (1,None) - expression (test_locations.ml[43,1283+13]..[43,1283+14]) + expression (test_locations.ml[18,557+13]..[18,557+14]) Pexp_constant PConst_int (1,None) - pattern (test_locations.ml[44,1298+4]..[44,1298+5]) - Ppat_var "n" (test_locations.ml[44,1298+4]..[44,1298+5]) - expression (test_locations.ml[44,1298+9]..[44,1298+34]) + pattern (test_locations.ml[19,572+4]..[19,572+5]) + Ppat_var "n" (test_locations.ml[19,572+4]..[19,572+5]) + expression (test_locations.ml[19,572+9]..[19,572+34]) Pexp_apply - expression (test_locations.ml[44,1298+21]..[44,1298+22]) - Pexp_ident "+" (test_locations.ml[44,1298+21]..[44,1298+22]) + expression (test_locations.ml[19,572+21]..[19,572+22]) + Pexp_ident "+" (test_locations.ml[19,572+21]..[19,572+22]) [ Nolabel - expression (test_locations.ml[44,1298+9]..[44,1298+20]) + expression (test_locations.ml[19,572+9]..[19,572+20]) Pexp_apply - expression (test_locations.ml[44,1298+9]..[44,1298+12]) - Pexp_ident "fib" (test_locations.ml[44,1298+9]..[44,1298+12]) + expression (test_locations.ml[19,572+9]..[19,572+12]) + Pexp_ident "fib" (test_locations.ml[19,572+9]..[19,572+12]) [ Nolabel - expression (test_locations.ml[44,1298+13]..[44,1298+20]) + expression (test_locations.ml[19,572+13]..[19,572+20]) Pexp_apply - expression (test_locations.ml[44,1298+16]..[44,1298+17]) - Pexp_ident "-" (test_locations.ml[44,1298+16]..[44,1298+17]) + expression (test_locations.ml[19,572+16]..[19,572+17]) + Pexp_ident "-" (test_locations.ml[19,572+16]..[19,572+17]) [ Nolabel - expression (test_locations.ml[44,1298+14]..[44,1298+15]) - Pexp_ident "n" (test_locations.ml[44,1298+14]..[44,1298+15]) + expression (test_locations.ml[19,572+14]..[19,572+15]) + Pexp_ident "n" (test_locations.ml[19,572+14]..[19,572+15]) Nolabel - expression (test_locations.ml[44,1298+18]..[44,1298+19]) + expression (test_locations.ml[19,572+18]..[19,572+19]) Pexp_constant PConst_int (1,None) ] ] Nolabel - expression (test_locations.ml[44,1298+23]..[44,1298+34]) + expression (test_locations.ml[19,572+23]..[19,572+34]) Pexp_apply - expression (test_locations.ml[44,1298+23]..[44,1298+26]) - Pexp_ident "fib" (test_locations.ml[44,1298+23]..[44,1298+26]) + expression (test_locations.ml[19,572+23]..[19,572+26]) + Pexp_ident "fib" (test_locations.ml[19,572+23]..[19,572+26]) [ Nolabel - expression (test_locations.ml[44,1298+27]..[44,1298+34]) + expression (test_locations.ml[19,572+27]..[19,572+34]) Pexp_apply - expression (test_locations.ml[44,1298+30]..[44,1298+31]) - Pexp_ident "-" (test_locations.ml[44,1298+30]..[44,1298+31]) + expression (test_locations.ml[19,572+30]..[19,572+31]) + Pexp_ident "-" (test_locations.ml[19,572+30]..[19,572+31]) [ Nolabel - expression (test_locations.ml[44,1298+28]..[44,1298+29]) - Pexp_ident "n" (test_locations.ml[44,1298+28]..[44,1298+29]) + expression (test_locations.ml[19,572+28]..[19,572+29]) + Pexp_ident "n" (test_locations.ml[19,572+28]..[19,572+29]) Nolabel - expression (test_locations.ml[44,1298+32]..[44,1298+33]) + expression (test_locations.ml[19,572+32]..[19,572+33]) Pexp_constant PConst_int (2,None) ] ] @@ -78,80 +78,80 @@ ] ] -let rec fib = function | 0|1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2)) +let rec fib = function | 0 | 1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2)) [ - structure_item (test_locations.ml[42,1260+0]..test_locations.ml[44,1298+34]) + structure_item (test_locations.ml[17,534+0]..test_locations.ml[19,572+34]) Tstr_value Rec [ - pattern (test_locations.ml[42,1260+8]..test_locations.ml[42,1260+11]) - Tpat_var "fib/80" - expression (test_locations.ml[42,1260+14]..test_locations.ml[44,1298+34]) + pattern (test_locations.ml[17,534+8]..test_locations.ml[17,534+11]) + Tpat_var "fib" + expression (test_locations.ml[17,534+14]..test_locations.ml[19,572+34]) Texp_function Nolabel [ - pattern (test_locations.ml[43,1283+4]..test_locations.ml[43,1283+9]) + pattern (test_locations.ml[18,557+4]..test_locations.ml[18,557+9]) Tpat_or - pattern (test_locations.ml[43,1283+4]..test_locations.ml[43,1283+5]) + pattern (test_locations.ml[18,557+4]..test_locations.ml[18,557+5]) Tpat_constant Const_int 0 - pattern (test_locations.ml[43,1283+8]..test_locations.ml[43,1283+9]) + pattern (test_locations.ml[18,557+8]..test_locations.ml[18,557+9]) Tpat_constant Const_int 1 - expression (test_locations.ml[43,1283+13]..test_locations.ml[43,1283+14]) + expression (test_locations.ml[18,557+13]..test_locations.ml[18,557+14]) Texp_constant Const_int 1 - pattern (test_locations.ml[44,1298+4]..test_locations.ml[44,1298+5]) - Tpat_var "n/81" - expression (test_locations.ml[44,1298+9]..test_locations.ml[44,1298+34]) + pattern (test_locations.ml[19,572+4]..test_locations.ml[19,572+5]) + Tpat_var "n" + expression (test_locations.ml[19,572+9]..test_locations.ml[19,572+34]) Texp_apply - expression (test_locations.ml[44,1298+21]..test_locations.ml[44,1298+22]) + expression (test_locations.ml[19,572+21]..test_locations.ml[19,572+22]) Texp_ident "Stdlib!.+" [ Nolabel - expression (test_locations.ml[44,1298+9]..test_locations.ml[44,1298+20]) + expression (test_locations.ml[19,572+9]..test_locations.ml[19,572+20]) Texp_apply - expression (test_locations.ml[44,1298+9]..test_locations.ml[44,1298+12]) - Texp_ident "fib/80" + expression (test_locations.ml[19,572+9]..test_locations.ml[19,572+12]) + Texp_ident "fib" [ Nolabel - expression (test_locations.ml[44,1298+13]..test_locations.ml[44,1298+20]) + expression (test_locations.ml[19,572+13]..test_locations.ml[19,572+20]) Texp_apply - expression (test_locations.ml[44,1298+16]..test_locations.ml[44,1298+17]) + expression (test_locations.ml[19,572+16]..test_locations.ml[19,572+17]) Texp_ident "Stdlib!.-" [ Nolabel - expression (test_locations.ml[44,1298+14]..test_locations.ml[44,1298+15]) - Texp_ident "n/81" + expression (test_locations.ml[19,572+14]..test_locations.ml[19,572+15]) + Texp_ident "n" Nolabel - expression (test_locations.ml[44,1298+18]..test_locations.ml[44,1298+19]) + expression (test_locations.ml[19,572+18]..test_locations.ml[19,572+19]) Texp_constant Const_int 1 ] ] Nolabel - expression (test_locations.ml[44,1298+23]..test_locations.ml[44,1298+34]) + expression (test_locations.ml[19,572+23]..test_locations.ml[19,572+34]) Texp_apply - expression (test_locations.ml[44,1298+23]..test_locations.ml[44,1298+26]) - Texp_ident "fib/80" + expression (test_locations.ml[19,572+23]..test_locations.ml[19,572+26]) + Texp_ident "fib" [ Nolabel - expression (test_locations.ml[44,1298+27]..test_locations.ml[44,1298+34]) + expression (test_locations.ml[19,572+27]..test_locations.ml[19,572+34]) Texp_apply - expression (test_locations.ml[44,1298+30]..test_locations.ml[44,1298+31]) + expression (test_locations.ml[19,572+30]..test_locations.ml[19,572+31]) Texp_ident "Stdlib!.-" [ Nolabel - expression (test_locations.ml[44,1298+28]..test_locations.ml[44,1298+29]) - Texp_ident "n/81" + expression (test_locations.ml[19,572+28]..test_locations.ml[19,572+29]) + Texp_ident "n" Nolabel - expression (test_locations.ml[44,1298+32]..test_locations.ml[44,1298+33]) + expression (test_locations.ml[19,572+32]..test_locations.ml[19,572+33]) Texp_constant Const_int 2 ] ] @@ -162,15 +162,15 @@ let rec fib = function | 0|1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2)) (setglobal Test_locations! (letrec - (fib/80 - (function n/81[int] : int - (funct-body Test_locations.fib test_locations.ml(42):1274-1332 - (if (isout 1 n/81) - (before Test_locations.fib test_locations.ml(44):1307-1332 + (fib + (function n[int] : int + (funct-body Test_locations.fib test_locations.ml(17):548-606 + (if (isout 1 n) + (before Test_locations.fib test_locations.ml(19):581-606 (+ - (after Test_locations.fib test_locations.ml(44):1307-1318 - (apply fib/80 (- n/81 1))) - (after Test_locations.fib test_locations.ml(44):1321-1332 - (apply fib/80 (- n/81 2))))) - (before Test_locations.fib test_locations.ml(43):1296-1297 1))))) - (pseudo (makeblock 0 fib/80)))) + (after Test_locations.fib test_locations.ml(19):581-592 + (apply fib (- n 1))) + (after Test_locations.fib test_locations.ml(19):595-606 + (apply fib (- n 2))))) + (before Test_locations.fib test_locations.ml(18):570-571 1))))) + (pseudo (makeblock 0 fib)))) diff --git a/testsuite/tests/formatting/test_locations.dlocations.ocamlopt.clambda.reference b/testsuite/tests/formatting/test_locations.dlocations.ocamlopt.clambda.reference deleted file mode 100644 index 04e12174..00000000 --- a/testsuite/tests/formatting/test_locations.dlocations.ocamlopt.clambda.reference +++ /dev/null @@ -1,31 +0,0 @@ - -cmm: -(data) -(data - int 3063 - "camlTest_locations__1": - addr "camlTest_locations__fib_80" - int 3) -(data int 1792 global "camlTest_locations" "camlTest_locations": int 1) -(data - global "camlTest_locations__gc_roots" - "camlTest_locations__gc_roots": - addr "camlTest_locations" - int 0) -(function{test_locations.ml:42,14-72} camlTest_locations__fib_80 (n/81: val) - (if ( 1 | n -> (fib (n - 1)) + (fib (n - 2)) +let rec fib = function | 0 | 1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2)) [ structure_item Tstr_value Rec [ pattern - Tpat_var "fib/80" + Tpat_var "fib" expression Texp_function Nolabel @@ -101,7 +101,7 @@ let rec fib = function | 0|1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2)) Texp_constant Const_int 1 pattern - Tpat_var "n/81" + Tpat_var "n" expression Texp_apply expression @@ -112,7 +112,7 @@ let rec fib = function | 0|1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2)) expression Texp_apply expression - Texp_ident "fib/80" + Texp_ident "fib" [ Nolabel @@ -124,7 +124,7 @@ let rec fib = function | 0|1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2)) Nolabel expression - Texp_ident "n/81" + Texp_ident "n" Nolabel expression @@ -136,7 +136,7 @@ let rec fib = function | 0|1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2)) expression Texp_apply expression - Texp_ident "fib/80" + Texp_ident "fib" [ Nolabel @@ -148,7 +148,7 @@ let rec fib = function | 0|1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2)) Nolabel expression - Texp_ident "n/81" + Texp_ident "n" Nolabel expression @@ -162,8 +162,7 @@ let rec fib = function | 0|1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2)) (setglobal Test_locations! (letrec - (fib/80 - (function n/81[int] : int - (if (isout 1 n/81) - (+ (apply fib/80 (- n/81 1)) (apply fib/80 (- n/81 2))) 1))) - (makeblock 0 fib/80))) + (fib + (function n[int] : int + (if (isout 1 n) (+ (apply fib (- n 1)) (apply fib (- n 2))) 1))) + (makeblock 0 fib))) diff --git a/testsuite/tests/formatting/test_locations.dno-locations.ocamlopt.clambda.reference b/testsuite/tests/formatting/test_locations.dno-locations.ocamlopt.clambda.reference deleted file mode 100644 index 983555b6..00000000 --- a/testsuite/tests/formatting/test_locations.dno-locations.ocamlopt.clambda.reference +++ /dev/null @@ -1,28 +0,0 @@ - -cmm: -(data) -(data - int 3063 - "camlTest_locations__1": - addr "camlTest_locations__fib_80" - int 3) -(data int 1792 global "camlTest_locations" "camlTest_locations": int 1) -(data - global "camlTest_locations__gc_roots" - "camlTest_locations__gc_roots": - addr "camlTest_locations" - int 0) -(function camlTest_locations__fib_80 (n/81: val) - (if ( 1 diff --git a/testsuite/tests/generalized-open/accepted_expect.ml b/testsuite/tests/generalized-open/accepted_expect.ml index d4b5ddcb..ed1edd20 100644 --- a/testsuite/tests/generalized-open/accepted_expect.ml +++ b/testsuite/tests/generalized-open/accepted_expect.ml @@ -45,6 +45,7 @@ val find_last_opt : (elt -> bool) -> t -> elt option = val of_list : elt list -> t = val to_seq_from : elt -> t -> elt Seq.t = val to_seq : t -> elt Seq.t = +val to_rev_seq : t -> elt Seq.t = val add_seq : elt Seq.t -> t -> t = val of_seq : elt Seq.t -> t = |}] diff --git a/testsuite/tests/generalized-open/gpr1506.ml b/testsuite/tests/generalized-open/gpr1506.ml index 3cbd819f..c01c6db9 100644 --- a/testsuite/tests/generalized-open/gpr1506.ml +++ b/testsuite/tests/generalized-open/gpr1506.ml @@ -103,9 +103,9 @@ include struct open struct type t = T end let x = T end Line 1, characters 15-41: 1 | include struct open struct type t = T end let x = T end ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Error: The type t/149 introduced by this open appears in the signature +Error: The type t/150 introduced by this open appears in the signature Line 1, characters 46-47: - The value x has no valid type if t/149 is hidden + The value x has no valid type if t/150 is hidden |}];; module A = struct @@ -123,9 +123,9 @@ Lines 3-6, characters 4-7: 4 | type t = T 5 | let x = T 6 | end -Error: The type t/154 introduced by this open appears in the signature +Error: The type t/155 introduced by this open appears in the signature Line 7, characters 8-9: - The value y has no valid type if t/154 is hidden + The value y has no valid type if t/155 is hidden |}];; module A = struct @@ -142,9 +142,9 @@ Lines 3-5, characters 4-7: 3 | ....open struct 4 | type t = T 5 | end -Error: The type t/159 introduced by this open appears in the signature +Error: The type t/160 introduced by this open appears in the signature Line 6, characters 8-9: - The value y has no valid type if t/159 is hidden + The value y has no valid type if t/160 is hidden |}] (* It was decided to not allow this anymore. *) @@ -384,9 +384,9 @@ val print_list_of_int : Print_int.t list -> unit = let f () = let open functor(X: sig end) -> struct end in ();; [%%expect{| -Line 1, characters 20-53: +Line 1, characters 27-53: 1 | let f () = let open functor(X: sig end) -> struct end in ();; - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: This module is not a structure; it has type functor (X : sig end) -> sig end |}] diff --git a/testsuite/tests/generalized-open/pr10048.ml b/testsuite/tests/generalized-open/pr10048.ml new file mode 100644 index 00000000..d6f29322 --- /dev/null +++ b/testsuite/tests/generalized-open/pr10048.ml @@ -0,0 +1,17 @@ +(* TEST + * expect +*) +module Ext (X : sig type 'a t end) = struct + type t = T : 'a X.t -> t +end;; + +let foo (x : Ext(List).t) = + match x with + | T l -> + let open Ext(Array) in + T (Array.of_list l);; +[%%expect {| +module Ext : + functor (X : sig type 'a t end) -> sig type t = T : 'a X.t -> t end +val foo : Ext(List).t -> Ext(Array).t = +|}] diff --git a/testsuite/tests/let-syntax/let_syntax.ml b/testsuite/tests/let-syntax/let_syntax.ml index 9f19e0e4..787c5b33 100644 --- a/testsuite/tests/let-syntax/let_syntax.ml +++ b/testsuite/tests/let-syntax/let_syntax.ml @@ -587,7 +587,8 @@ val let_not_principal : unit = () Line 3, characters 9-10: 3 | let+ A = A.A in ^ -Error: Unbound constructor A +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. +val let_not_principal : unit = () |}];; module And_not_principal = struct @@ -615,7 +616,8 @@ val and_not_principal : A.t -> A.t -> unit = Line 5, characters 11-12: 5 | and+ A = y in ^ -Error: Unbound constructor A +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. +val and_not_principal : A.t -> A.t -> unit = |}];; module Let_not_propagated = struct @@ -713,12 +715,16 @@ let bad_location = [%%expect{| val bad_location : 'a GADT_ordering.is_point -> 'a -> int = |}, Principal{| -Line 4, characters 6-10: +Line 4, characters 11-19: 4 | let+ Is_point = is_point - ^^^^ -Error: This pattern matches values of type - GADT_ordering.point GADT_ordering.is_point * GADT_ordering.point - but a pattern was expected which matches values of type - a GADT_ordering.is_point * a - Type GADT_ordering.point is not compatible with type a + ^^^^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering GADT_ordering.point and a as equal. +But the knowledge of these types is not principal. +Line 5, characters 13-14: +5 | and+ { x; y } = a in + ^ +Error: The record field x belongs to the type GADT_ordering.point + but is mixed here with fields of type a = GADT_ordering.point + This instance of GADT_ordering.point is ambiguous: + it would escape the scope of its equation |}];; diff --git a/testsuite/tests/letrec-check/pr7231.ocaml.reference b/testsuite/tests/letrec-check/pr7231.ocaml.reference index 9b1a5a13..5257588c 100644 --- a/testsuite/tests/letrec-check/pr7231.ocaml.reference +++ b/testsuite/tests/letrec-check/pr7231.ocaml.reference @@ -1,7 +1,7 @@ Line 5, characters 58-64: 5 | let rec r = let rec x () = r and y () = x () in y () in r "oops";; ^^^^^^ -Warning 20: this argument will not be used by the function. +Warning 20 [ignored-extra-argument]: this argument will not be used by the function. Line 5, characters 12-52: 5 | let rec r = let rec x () = r and y () = x () in y () in r "oops";; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/testsuite/tests/lexing/escape.ocaml.reference b/testsuite/tests/lexing/escape.ocaml.reference index 2e9d9fd5..0b716cb1 100644 --- a/testsuite/tests/lexing/escape.ocaml.reference +++ b/testsuite/tests/lexing/escape.ocaml.reference @@ -1,7 +1,7 @@ Line 7, characters 15-17: 7 | let invalid = "\99" ;; ^^ -Warning 14: illegal backslash escape in string. +Warning 14 [illegal-backslash]: illegal backslash escape in string. val invalid : string = "\\99" Line 1, characters 15-19: 1 | let invalid = "\999" ;; @@ -14,11 +14,11 @@ Error: Illegal backslash escape in string or character (\o777): o777 (=511) is o Line 1, characters 15-17: 1 | let invalid = "\o77" ;; ^^ -Warning 14: illegal backslash escape in string. +Warning 14 [illegal-backslash]: illegal backslash escape in string. val invalid : string = "\\o77" Line 1, characters 15-17: 1 | let invalid = "\o99" ;; ^^ -Warning 14: illegal backslash escape in string. +Warning 14 [illegal-backslash]: illegal backslash escape in string. val invalid : string = "\\o99" diff --git a/testsuite/tests/lexing/uchar_esc.ocaml.reference b/testsuite/tests/lexing/uchar_esc.ocaml.reference index 953104ae..1873a4d7 100644 --- a/testsuite/tests/lexing/uchar_esc.ocaml.reference +++ b/testsuite/tests/lexing/uchar_esc.ocaml.reference @@ -25,11 +25,11 @@ Error: Illegal backslash escape in string or character (\u{01234567}): too many Line 1, characters 21-23: 1 | let no_hex_digits = "\u{}" ;; ^^ -Warning 14: illegal backslash escape in string. +Warning 14 [illegal-backslash]: illegal backslash escape in string. val no_hex_digits : string = "\\u{}" Line 1, characters 25-27: 1 | let illegal_hex_digit = "\u{u}" ;; ^^ -Warning 14: illegal backslash escape in string. +Warning 14 [illegal-backslash]: illegal backslash escape in string. val illegal_hex_digit : string = "\\u{u}" diff --git a/testsuite/tests/lib-arg/test_rest_all.ml b/testsuite/tests/lib-arg/test_rest_all.ml new file mode 100644 index 00000000..b0ac3c1e --- /dev/null +++ b/testsuite/tests/lib-arg/test_rest_all.ml @@ -0,0 +1,80 @@ +(* TEST + * expect +*) + +type arg = AString of string | ARest of string | ARest_all of string list + +let push acc s = + acc := s :: !acc + +let f_str acc s = push acc (AString s) + +let f_rest acc s = push acc (ARest s) + +let f_rest_all acc ss = push acc (ARest_all ss) + +let test args = + let acc = ref [] in + Arg.parse_argv ~current:(ref 0) args Arg.[ + "-str", String (f_str acc), "String (1)"; + "-rest", Rest (f_rest acc), "Rest (*)"; + "-rest-all", Rest_all (f_rest_all acc), "Rest_all (*)"; + ] failwith ""; + List.rev !acc + +[%%expect{| +type arg = AString of string | ARest of string | ARest_all of string list +val push : 'a list ref -> 'a -> unit = +val f_str : arg list ref -> string -> unit = +val f_rest : arg list ref -> string -> unit = +val f_rest_all : arg list ref -> string list -> unit = +val test : string array -> arg list = +|}];; + +let _ = test [| + "prog"; + "-str"; "foo"; + "-str"; "bar"; + "-rest"; + "foobar"; + "-str"; "foobaz" +|];; +[%%expect{| +- : arg list = +[AString "foo"; AString "bar"; ARest "foobar"; ARest "-str"; ARest "foobaz"] +|}];; + +let _ = test [| + "prog"; + "-str"; "foo"; + "-str"; "bar"; + "-rest-all"; + "foobar"; + "-str"; "foobaz" +|];; +[%%expect{| +- : arg list = +[AString "foo"; AString "bar"; ARest_all ["foobar"; "-str"; "foobaz"]] +|}];; + +(* Rest does nothing when there are no following arguments *) +let _ = test [| + "prog"; + "-str"; "foo"; + "-str"; "bar"; + "-rest"; +|];; +[%%expect{| +- : arg list = [AString "foo"; AString "bar"] +|}];; + +(* Rest_all lets us detect that there were no rest arguments *) +let _ = test [| + "prog"; + "-str"; "foo"; + "-str"; "bar"; + "-rest-all"; +|];; +[%%expect{| +- : arg list = [AString "foo"; AString "bar"; ARest_all []] +|}];; diff --git a/testsuite/tests/lib-arg/testarg.ml b/testsuite/tests/lib-arg/testarg.ml index 5fb9f5b8..9b402559 100644 --- a/testsuite/tests/lib-arg/testarg.ml +++ b/testsuite/tests/lib-arg/testarg.ml @@ -1,6 +1,4 @@ -(* TEST - compare_programs = "false" (* See https://github.com/ocaml/ocaml/pull/8853 *) -*) +(* TEST *) let current = ref 0;; diff --git a/testsuite/tests/lib-arg/testerror.ml b/testsuite/tests/lib-arg/testerror.ml index 6ae29205..6bcf0fde 100644 --- a/testsuite/tests/lib-arg/testerror.ml +++ b/testsuite/tests/lib-arg/testerror.ml @@ -1,6 +1,5 @@ (* TEST * native - compare_programs = "false" *) (** Test that the right message errors are emitted by Arg *) diff --git a/testsuite/tests/lib-atomic/test_atomic.ml b/testsuite/tests/lib-atomic/test_atomic.ml new file mode 100644 index 00000000..fba6952c --- /dev/null +++ b/testsuite/tests/lib-atomic/test_atomic.ml @@ -0,0 +1,39 @@ +(* TEST *) + +let r = Atomic.make 1 +let () = assert (Atomic.get r = 1) + +let () = Atomic.set r 2 +let () = assert (Atomic.get r = 2) + +let () = assert (Atomic.exchange r 3 = 2) + +let () = assert (Atomic.compare_and_set r 3 4 = true) +let () = assert (Atomic.get r = 4) + +let () = assert (Atomic.compare_and_set r 3 (-4) = false) +let () = assert (Atomic.get r = 4 ) + +let () = assert (Atomic.compare_and_set r 3 4 = false) + +let () = assert (Atomic.fetch_and_add r 2 = 4) +let () = assert (Atomic.get r = 6) + +let () = assert (Atomic.fetch_and_add r (-2) = 6) +let () = assert (Atomic.get r = 4) + +let () = assert ((Atomic.incr r; Atomic.get r) = 5) + +let () = assert ((Atomic.decr r; Atomic.get r) = 4) + +let () = + let r = Atomic.make 0 in + let cur = Atomic.get r in + ignore (Atomic.set r (cur + 1), Atomic.set r (cur - 1)); + assert (Atomic.get r <> cur) + +let () = + let r = Atomic.make 0 in + let cur = Atomic.get r in + ignore (Atomic.incr r, Atomic.decr r); + assert (Atomic.get r = cur) diff --git a/testsuite/tests/lib-bigarray-2/bigarrfml.ml b/testsuite/tests/lib-bigarray-2/bigarrfml.ml index 40020b23..63bbf1d3 100644 --- a/testsuite/tests/lib-bigarray-2/bigarrfml.ml +++ b/testsuite/tests/lib-bigarray-2/bigarrfml.ml @@ -8,7 +8,7 @@ script = "sh ${test_source_directory}/has-gfortran.sh" ** setup-ocamlc.byte-build-env *** script -script = "gfortran -c bigarrf.f" +script = "sh ${test_source_directory}/call-gfortran.sh ${cc} -c bigarrf.f" **** ocamlc.byte all_modules = "bigarrf.o bigarrfstub.c bigarrfml.ml" ***** run @@ -18,7 +18,7 @@ stdout = "${output}" ** setup-ocamlopt.byte-build-env *** script -script = "gfortran -c bigarrf.f" +script = "sh ${test_source_directory}/call-gfortran.sh ${cc} -c bigarrf.f" **** ocamlopt.byte all_modules = "bigarrf.o bigarrfstub.c bigarrfml.ml" ***** run diff --git a/testsuite/tests/lib-bigarray-2/call-gfortran.sh b/testsuite/tests/lib-bigarray-2/call-gfortran.sh new file mode 100644 index 00000000..5a250eb4 --- /dev/null +++ b/testsuite/tests/lib-bigarray-2/call-gfortran.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +# This somewhat hackily passes any extra words in CC to gfortran +# This means for a 32-bit build (configured with CC="gcc -m32" the -m32 +# gets passed to gfortran) +shift 1 +gfortran "$@" diff --git a/testsuite/tests/lib-bigarray/bigarrays.ml b/testsuite/tests/lib-bigarray/bigarrays.ml index 57536d67..b144b2e6 100644 --- a/testsuite/tests/lib-bigarray/bigarrays.ml +++ b/testsuite/tests/lib-bigarray/bigarrays.ml @@ -28,6 +28,12 @@ let test test_number answer correct_answer = printf " %d..." test_number end +let with_trace f = + let events = ref [] in + let trace e = events := e :: !events in + let v = f trace in + (v, List.rev !events) + (* One-dimensional arrays *) (* flambda can cause some of these values not to be reclaimed by the Gc, which @@ -489,6 +495,26 @@ let tests () = test 7 (Array1.slice a 2) (Array0.of_value int fortran_layout 4); test 8 (Array1.slice a 3) (Array0.of_value int fortran_layout 3); + testing_function "init"; + let check1 arr graph = List.for_all (fun (i, fi) -> arr.{i} = fi) graph in + + let ba, log = with_trace @@ fun trace -> + Array1.init int c_layout 5 (fun x -> trace (x,x); x) in + test 1 log [0,0; + 1,1; + 2,2; + 3,3; + 4,4]; + test 2 true (check1 ba log); + + let ba, log = with_trace @@ fun trace -> + Array1.init int fortran_layout 5 (fun x -> trace (x,x); x) in + test 3 log [1,1; + 2,2; + 3,3; + 4,4; + 5,5]; + test 4 true (check1 ba log); (* Bi-dimensional arrays *) @@ -651,6 +677,25 @@ let tests () = test 8 (Array2.slice_right a 3) (from_list_fortran int [1003;2003;3003;4003;5003]); + testing_function "init"; + let check2 arr graph = List.for_all (fun ((i,j), fij) -> arr.{i,j} = fij) graph in + + let ba, log = with_trace @@ fun trace -> + Array2.init int c_layout 4 2 + (fun x y -> let v = 10*x + y in trace ((x,y),v); v) in + test 1 log [(0,0), 00; (0,1), 01; + (1,0), 10; (1,1), 11; + (2,0), 20; (2,1), 21; + (3,0), 30; (3,1), 31]; + test 2 true (check2 ba log); + + let ba, log = with_trace @@ fun trace -> + Array2.init int fortran_layout 4 2 + (fun x y -> let v = 10*x + y in trace ((x,y),v); v) in + test 3 log [(1,1), 11; (2,1), 21; (3,1), 31; (4,1), 41; + (1,2), 12; (2,2), 22; (3,2), 32; (4,2), 42]; + test 4 true (check2 ba log); + (* Tri-dimensional arrays *) print_newline(); @@ -778,10 +823,125 @@ let tests () = test 6 (Array3.slice_right_1 a 1 2) (from_list_fortran int [112;212;312]); test 7 (Array3.slice_right_1 a 3 1) (from_list_fortran int [131;231;331]); + testing_function "init"; + let check3 arr graph = + List.for_all (fun ((i,j,k), fijk) -> arr.{i,j,k} = fijk) graph in + + let ba, log = with_trace @@ fun trace -> + Array3.init int c_layout 4 2 3 + (fun x y z -> let v = 100*x + 10*y + z in trace ((x,y,z),v); v) in + test 1 log [(0,0,0), 000; (0,0,1), 001; (0,0,2), 002; + (0,1,0), 010; (0,1,1), 011; (0,1,2), 012; + + (1,0,0), 100; (1,0,1), 101; (1,0,2), 102; + (1,1,0), 110; (1,1,1), 111; (1,1,2), 112; + + (2,0,0), 200; (2,0,1), 201; (2,0,2), 202; + (2,1,0), 210; (2,1,1), 211; (2,1,2), 212; + + (3,0,0), 300; (3,0,1), 301; (3,0,2), 302; + (3,1,0), 310; (3,1,1), 311; (3,1,2), 312]; + test 2 true (check3 ba log); + + let ba, log = with_trace @@ fun trace -> + Array3.init int fortran_layout 4 2 3 + (fun x y z -> let v = 100*x + 10*y + z in trace ((x,y,z), v); v) in + test 3 log [(1,1,1), 111; (2,1,1), 211; (3,1,1), 311; (4,1,1), 411; + (1,2,1), 121; (2,2,1), 221; (3,2,1), 321; (4,2,1), 421; + + (1,1,2), 112; (2,1,2), 212; (3,1,2), 312; (4,1,2), 412; + (1,2,2), 122; (2,2,2), 222; (3,2,2), 322; (4,2,2), 422; + + (1,1,3), 113; (2,1,3), 213; (3,1,3), 313; (4,1,3), 413; + (1,2,3), 123; (2,2,3), 223; (3,2,3), 323; (4,2,3), 423]; + test 4 true (check3 ba log); + testing_function "size_in_bytes_general"; let a = Genarray.create int c_layout [|2;2;2;2;2|] in test 1 (Genarray.size_in_bytes a) (32 * (kind_size_in_bytes int)); + testing_function "init"; + let checkgen arr graph = + List.for_all (fun (i, fi) -> Genarray.get arr i = fi) graph in + + let ba, log = with_trace @@ fun trace -> + Genarray.init int c_layout [|4; 2; 3; 2|] + (fun i -> let v = 1000*i.(0) + 100*i.(1) + 10*i.(2) + i.(3) in + trace (Array.copy i, v); v) in + test 1 log [[|0;0;0;0|], 0000; [|0;0;0;1|], 0001; + [|0;0;1;0|], 0010; [|0;0;1;1|], 0011; + [|0;0;2;0|], 0020; [|0;0;2;1|], 0021; + + [|0;1;0;0|], 0100; [|0;1;0;1|], 0101; + [|0;1;1;0|], 0110; [|0;1;1;1|], 0111; + [|0;1;2;0|], 0120; [|0;1;2;1|], 0121; + + [|1;0;0;0|], 1000; [|1;0;0;1|], 1001; + [|1;0;1;0|], 1010; [|1;0;1;1|], 1011; + [|1;0;2;0|], 1020; [|1;0;2;1|], 1021; + + [|1;1;0;0|], 1100; [|1;1;0;1|], 1101; + [|1;1;1;0|], 1110; [|1;1;1;1|], 1111; + [|1;1;2;0|], 1120; [|1;1;2;1|], 1121; + + [|2;0;0;0|], 2000; [|2;0;0;1|], 2001; + [|2;0;1;0|], 2010; [|2;0;1;1|], 2011; + [|2;0;2;0|], 2020; [|2;0;2;1|], 2021; + + [|2;1;0;0|], 2100; [|2;1;0;1|], 2101; + [|2;1;1;0|], 2110; [|2;1;1;1|], 2111; + [|2;1;2;0|], 2120; [|2;1;2;1|], 2121; + + [|3;0;0;0|], 3000; [|3;0;0;1|], 3001; + [|3;0;1;0|], 3010; [|3;0;1;1|], 3011; + [|3;0;2;0|], 3020; [|3;0;2;1|], 3021; + + [|3;1;0;0|], 3100; [|3;1;0;1|], 3101; + [|3;1;1;0|], 3110; [|3;1;1;1|], 3111; + [|3;1;2;0|], 3120; [|3;1;2;1|], 3121;]; + test 2 true (checkgen ba log); + + let ba, log = with_trace @@ fun trace -> + Genarray.init int fortran_layout [|4; 2; 3; 2|] + (fun i -> let v = 1000*i.(0) + 100*i.(1) + 10*i.(2) + i.(3) in + trace (Array.copy i, v); v) in + test 3 log [[|1;1;1;1|], 1111; [|2;1;1;1|], 2111; + [|3;1;1;1|], 3111; [|4;1;1;1|], 4111; + + [|1;2;1;1|], 1211; [|2;2;1;1|], 2211; + [|3;2;1;1|], 3211; [|4;2;1;1|], 4211; + + [|1;1;2;1|], 1121; [|2;1;2;1|], 2121; + [|3;1;2;1|], 3121; [|4;1;2;1|], 4121; + + [|1;2;2;1|], 1221; [|2;2;2;1|], 2221; + [|3;2;2;1|], 3221; [|4;2;2;1|], 4221; + + [|1;1;3;1|], 1131; [|2;1;3;1|], 2131; + [|3;1;3;1|], 3131; [|4;1;3;1|], 4131; + + [|1;2;3;1|], 1231; [|2;2;3;1|], 2231; + [|3;2;3;1|], 3231; [|4;2;3;1|], 4231; + + [|1;1;1;2|], 1112; [|2;1;1;2|], 2112; + [|3;1;1;2|], 3112; [|4;1;1;2|], 4112; + + [|1;2;1;2|], 1212; [|2;2;1;2|], 2212; + [|3;2;1;2|], 3212; [|4;2;1;2|], 4212; + + [|1;1;2;2|], 1122; [|2;1;2;2|], 2122; + [|3;1;2;2|], 3122; [|4;1;2;2|], 4122; + + [|1;2;2;2|], 1222; [|2;2;2;2|], 2222; + [|3;2;2;2|], 3222; [|4;2;2;2|], 4222; + + [|1;1;3;2|], 1132; [|2;1;3;2|], 2132; + [|3;1;3;2|], 3132; [|4;1;3;2|], 4132; + + [|1;2;3;2|], 1232; [|2;2;3;2|], 2232; + [|3;2;3;2|], 3232; [|4;2;3;2|], 4232]; + test 4 true (checkgen ba log); + (* Zero-dimensional arrays *) testing_function "------ Array0 --------"; testing_function "create/set/get"; @@ -886,6 +1046,12 @@ let tests () = {im=0.5;re= -2.0}, {im=0.5;re= -2.0}; {im=3.1415;re=1.2345678}, {im=3.1415;re=1.2345678}]); + testing_function "init"; + let ba = Array0.init int c_layout 10 in + test 1 ba (Array0.of_value int c_layout 10); + + let ba = Array0.init int fortran_layout 10 in + test 2 ba (Array0.of_value int fortran_layout 10); (* Kind size *) testing_function "kind_size_in_bytes"; @@ -945,7 +1111,7 @@ let tests () = test 9 (Genarray.get c [|0|]) 3; test 10 (Genarray.get (Genarray.slice_left c [|0|]) [||]) 3; -(* I/O *) + (* I/O *) print_newline(); testing_function "------ I/O --------"; diff --git a/testsuite/tests/lib-bigarray/bigarrays.reference b/testsuite/tests/lib-bigarray/bigarrays.reference index 1c80e50e..6162fb38 100644 --- a/testsuite/tests/lib-bigarray/bigarrays.reference +++ b/testsuite/tests/lib-bigarray/bigarrays.reference @@ -21,6 +21,8 @@ blit, fill 1... 2... 3... 4... 5... 6... 7... 8... 9... 10... 11... 12... slice 1... 2... 3... 6... 7... 8... +init + 1... 2... 3... 4... ------ Array2 -------- @@ -38,6 +40,8 @@ sub 1... 2... slice 1... 2... 3... 4... 5... 6... 7... 8... +init + 1... 2... 3... 4... ------ Array3 -------- @@ -53,12 +57,18 @@ size_in_bytes_three 1... slice1 1... 2... 3... 4... 5... 6... 7... +init + 1... 2... 3... 4... size_in_bytes_general 1... +init + 1... 2... 3... 4... ------ Array0 -------- create/set/get 1... 2... 3... 4... 5... 6... 7... 8... 9... 10... 11... 12... +init + 1... 2... kind_size_in_bytes 1... 2... 3... 4... 5... 6... 7... 8... 9... 10... 11... 12... 13... diff --git a/testsuite/tests/lib-bigarray/change_layout.ml b/testsuite/tests/lib-bigarray/change_layout.ml index 2456cdc5..160aeb66 100644 --- a/testsuite/tests/lib-bigarray/change_layout.ml +++ b/testsuite/tests/lib-bigarray/change_layout.ml @@ -1,6 +1,4 @@ -(* TEST - compare_programs = "false" (* See https://github.com/ocaml/ocaml/pull/8853 *) -*) +(* TEST *) (** Test the various change_layout for Genarray and the various Array[n] *) diff --git a/testsuite/tests/lib-channels/in_channel_length.ml b/testsuite/tests/lib-channels/in_channel_length.ml new file mode 100644 index 00000000..0bdeae4e --- /dev/null +++ b/testsuite/tests/lib-channels/in_channel_length.ml @@ -0,0 +1,20 @@ +(* TEST *) + +let len = 15000 +let rounds = 10 + +let () = + let oc = open_out "data.txt" in + for i = 1 to rounds do + Printf.fprintf oc "%s\n%!" (String.make len 'x'); + done; + close_out oc; + let ic = open_in "data.txt" in + let l1 = in_channel_length ic in + for i = 1 to rounds do + let s = input_line ic in + assert (String.length s = len); + let l = in_channel_length ic in + assert (l = l1) + done; + close_in ic diff --git a/testsuite/tests/lib-channels/seek_in.ml b/testsuite/tests/lib-channels/seek_in.ml new file mode 100644 index 00000000..33f7146b --- /dev/null +++ b/testsuite/tests/lib-channels/seek_in.ml @@ -0,0 +1,19 @@ +(* TEST *) + +let () = + let oc = open_out_bin "data.txt" in + output_string oc "0\r\n1\r\n"; + close_out oc; + (* Open in text mode to trigger EOL conversion under Windows *) + let ic = open_in "data.txt" in + ignore (input_line ic); + seek_in ic 3; + (* Normally we should be looking at "1\r\n", which will be read as + "1" under Windows because of EOL conversion and "1\r" otherwise. + What goes wrong with the old implementation of seek_in is that + we have "0\n\1\n" in the channel buffer and have read "0\n" already, + so we think we are at position 2, and the seek to position 3 + just advances by one in the buffer, pointing to "\n" instead of "1\n". *) + let l = input_line ic in + close_in ic; + assert (l = "1" || l = "1\r") diff --git a/testsuite/tests/lib-dynlink-bytecode/stub2.c b/testsuite/tests/lib-dynlink-bytecode/stub2.c index f4cd3a7e..403bcd55 100644 --- a/testsuite/tests/lib-dynlink-bytecode/stub2.c +++ b/testsuite/tests/lib-dynlink-bytecode/stub2.c @@ -18,7 +18,7 @@ #include "caml/alloc.h" #include -extern value stub1(void); +CAMLextern value stub1(void); value stub2(void) { printf("This is stub2, calling stub1:\n"); fflush(stdout); diff --git a/testsuite/tests/lib-dynlink-init-info/test.ml b/testsuite/tests/lib-dynlink-init-info/test.ml new file mode 100644 index 00000000..c6105dd7 --- /dev/null +++ b/testsuite/tests/lib-dynlink-init-info/test.ml @@ -0,0 +1,13 @@ +(* TEST + include dynlink +*) + +(* Make sure dynlink state info is accurate before any load + occurs #9338. *) + +let test () = + assert (List.mem "Dynlink" (Dynlink.main_program_units ())); + assert (List.mem "Dynlink" (Dynlink.all_units ())); + () + +let () = test (); print_endline "OK" diff --git a/testsuite/tests/lib-dynlink-init-info/test.reference b/testsuite/tests/lib-dynlink-init-info/test.reference new file mode 100644 index 00000000..d86bac9d --- /dev/null +++ b/testsuite/tests/lib-dynlink-init-info/test.reference @@ -0,0 +1 @@ +OK diff --git a/testsuite/tests/lib-dynlink-initializers/test10_main.byte.reference b/testsuite/tests/lib-dynlink-initializers/test10_main.byte.reference index 97ec42cd..a947322d 100755 --- a/testsuite/tests/lib-dynlink-initializers/test10_main.byte.reference +++ b/testsuite/tests/lib-dynlink-initializers/test10_main.byte.reference @@ -5,8 +5,8 @@ Called from Test10_plugin.f in file "test10_plugin.ml", line 6, characters 2-6 Called from Test10_plugin in file "test10_plugin.ml", line 10, characters 2-6 Called from Dynlink.Bytecode.run in file "otherlibs/dynlink/dynlink.ml", line 137, characters 16-25 Re-raised at Dynlink.Bytecode.run in file "otherlibs/dynlink/dynlink.ml", line 139, characters 6-137 -Called from Dynlink_common.Make.load.(fun) in file "otherlibs/dynlink/dynlink_common.ml", line 344, characters 13-44 +Called from Dynlink_common.Make.load.(fun) in file "otherlibs/dynlink/dynlink_common.ml", line 347, characters 13-44 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Dynlink_common.Make.load in file "otherlibs/dynlink/dynlink_common.ml", line 342, characters 8-240 -Re-raised at Dynlink_common.Make.load in file "otherlibs/dynlink/dynlink_common.ml", line 352, characters 8-17 +Called from Dynlink_common.Make.load in file "otherlibs/dynlink/dynlink_common.ml", line 345, characters 8-240 +Re-raised at Dynlink_common.Make.load in file "otherlibs/dynlink/dynlink_common.ml", line 355, characters 8-17 Called from Test10_main in file "test10_main.ml", line 51, characters 13-69 diff --git a/testsuite/tests/lib-dynlink-initializers/test10_main.native.reference b/testsuite/tests/lib-dynlink-initializers/test10_main.native.reference index 364eb760..30d99843 100755 --- a/testsuite/tests/lib-dynlink-initializers/test10_main.native.reference +++ b/testsuite/tests/lib-dynlink-initializers/test10_main.native.reference @@ -6,9 +6,9 @@ Called from Dynlink.Native.run.(fun) in file "otherlibs/dynlink/native/dynlink.m Called from Dynlink.Native.run.(fun) in file "otherlibs/dynlink/native/dynlink.ml", line 85, characters 12-29 Re-raised at Dynlink.Native.run.(fun) in file "otherlibs/dynlink/native/dynlink.ml", line 87, characters 10-149 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Dynlink_common.Make.load.(fun) in file "otherlibs/dynlink/dynlink_common.ml", line 344, characters 13-44 +Called from Dynlink_common.Make.load.(fun) in file "otherlibs/dynlink/dynlink_common.ml", line 347, characters 13-44 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Dynlink_common.Make.load in file "otherlibs/dynlink/dynlink_common.ml", line 342, characters 8-240 -Re-raised at Dynlink_common.Make.load in file "otherlibs/dynlink/dynlink_common.ml", line 352, characters 8-17 -Called from Dynlink_common.Make.loadfile in file "otherlibs/dynlink/dynlink_common.ml" (inlined), line 354, characters 26-45 +Called from Dynlink_common.Make.load in file "otherlibs/dynlink/dynlink_common.ml", line 345, characters 8-240 +Re-raised at Dynlink_common.Make.load in file "otherlibs/dynlink/dynlink_common.ml", line 355, characters 8-17 +Called from Dynlink_common.Make.loadfile in file "otherlibs/dynlink/dynlink_common.ml" (inlined), line 357, characters 26-45 Called from Test10_main in file "test10_main.ml", line 49, characters 30-87 diff --git a/testsuite/tests/lib-either/test.ml b/testsuite/tests/lib-either/test.ml new file mode 100644 index 00000000..4ca9712a --- /dev/null +++ b/testsuite/tests/lib-either/test.ml @@ -0,0 +1,108 @@ +(* TEST + * expect +*) + +open Either;; + +[left 1; right true];; +[%%expect {| +- : (int, bool) Either.t list = [Left 1; Right true] +|}];; + +List.map is_left [left 1; right true];; +[%%expect {| +- : bool list = [true; false] +|}];; + +List.map is_right [left 1; right true];; +[%%expect {| +- : bool list = [false; true] +|}];; + +[find_left (Left 1); find_left (Right 1)];; +[%%expect {| +- : int option list = [Some 1; None] +|}];; + +[find_right (Left 1); find_right (Right 1)];; +[%%expect {| +- : int option list = [None; Some 1] +|}];; + +[map_left succ (Left 1); map_left succ (Right true)];; +[%%expect {| +- : (int, bool) Either.t list = [Left 2; Right true] +|}];; + +[map_right succ (Left ()); map_right succ (Right 2)];; +[%%expect {| +- : (unit, int) Either.t list = [Left (); Right 3] +|}];; + +[map succ not (Left 1); map succ not (Right true)];; +[%%expect {| +- : (int, bool) Either.t list = [Left 2; Right false] +|}];; + +[fold ~left:succ ~right:int_of_string (Left 1); + fold ~left:succ ~right:int_of_string (Right "2")];; +[%%expect {| +- : int list = [2; 2] +|}];; + +let li = ref [] in +let add to_str x = li := to_str x :: !li in +iter ~left:(add Fun.id) ~right:(add string_of_int) (Left "foo"); +iter ~left:(add Fun.id) ~right:(add string_of_int) (Right 2); +List.rev !li;; +[%%expect {| +- : string list = ["foo"; "2"] +|}];; + +( + for_all ~left:((=) 1) ~right:((=) "foo") (Left 1), + for_all ~left:((=) 1) ~right:((=) "foo") (Right "foo"), + for_all ~left:((=) 1) ~right:((=) "foo") (Left 2), + for_all ~left:((=) 1) ~right:((=) "foo") (Right "bar") +);; +[%%expect {| +- : bool * bool * bool * bool = (true, true, false, false) +|}];; + +equal ~left:(=) ~right:(=) (Left 1) (Left 1), +equal ~left:(=) ~right:(=) (Right true) (Right true);; +[%%expect {| +- : bool * bool = (true, true) +|}];; + +(equal ~left:(=) ~right:(=) (Left 1) (Left 2), + equal ~left:(=) ~right:(=) (Right true) (Right false), + equal ~left:(=) ~right:(=) (Left 1) (Right true), + equal ~left:(=) ~right:(=) (Right 1) (Left true));; +[%%expect {| +- : bool * bool * bool * bool = (false, false, false, false) +|}];; + +equal ~left:(fun _ _ -> false) ~right:(=) (Left 1) (Left 1), +equal ~left:(=) ~right:(fun _ _ -> false) (Right true) (Right true);; +[%%expect {| +- : bool * bool = (false, false) +|}];; + +let cmp = Stdlib.compare in +( + (compare ~left:cmp ~right:cmp (Left 0) (Left 1), + compare ~left:cmp ~right:cmp (Left 1) (Left 1), + compare ~left:cmp ~right:cmp (Left 1) (Left 0)), + + (compare ~left:cmp ~right:cmp (Right 0) (Right 1), + compare ~left:cmp ~right:cmp (Right 1) (Right 1), + compare ~left:cmp ~right:cmp (Right 1) (Right 0)), + + (compare ~left:cmp ~right:cmp (Left 1) (Right true), + compare ~left:cmp ~right:cmp (Right 1) (Left true)) +);; +[%%expect {| +- : (int * int * int) * (int * int * int) * (int * int) = +((-1, 0, 1), (-1, 0, 1), (-1, 1)) +|}];; diff --git a/testsuite/tests/lib-floatarray/floatarray.ml b/testsuite/tests/lib-floatarray/floatarray.ml index 7c0434f7..3229725e 100644 --- a/testsuite/tests/lib-floatarray/floatarray.ml +++ b/testsuite/tests/lib-floatarray/floatarray.ml @@ -42,6 +42,14 @@ module type S = sig val map_from_array : ('a -> float) -> 'a array -> t val unsafe_get : t -> int -> float val unsafe_set : t -> int -> float -> unit + + (* From Sys, rather than Float.Array *) + val max_length : int +end + +module Flat_float_array : S = struct + include Stdlib.Float.Array + let max_length = Sys.max_floatarray_length end (* module [Array] specialized to [float] and with a few changes, @@ -53,6 +61,7 @@ module Float_array : S = struct let map_from_array f a = map f a let mem_ieee x a = exists ((=) x) a type t = float array + let max_length = Sys.max_array_length end module Test (A : S) : sig end = struct @@ -91,9 +100,9 @@ module Test (A : S) : sig end = struct check_inval (fun i -> A.set a i 1.0) (-1); check_inval (fun i -> A.set a i 1.0) 1000; check_inval A.create (-1); - check_inval A.create (Sys.max_floatarray_length + 1); + check_inval A.create (A.max_length + 1); check_inval (fun i -> A.make i 1.0) (-1); - check_inval (fun i -> A.make i 1.0) (Sys.max_floatarray_length + 1); + check_inval (fun i -> A.make i 1.0) (A.max_length + 1); (* [length] *) let test_length l = assert (l = (A.length (A.create l))) in @@ -109,7 +118,7 @@ module Test (A : S) : sig end = struct let a = A.init 1000 Float.of_int in check_i a; check_inval (fun i -> A.init i Float.of_int) (-1); - check_inval (fun i -> A.init i Float.of_int) (Sys.max_floatarray_length + 1); + check_inval (fun i -> A.init i Float.of_int) (A.max_length + 1); (* [append] *) let check m n = @@ -202,6 +211,15 @@ module Test (A : S) : sig end = struct check_inval (A.blit a 0 a (-1)) 0; check_inval (A.blit a 0 a 100) 1; check_inval (A.blit a 0 a 101) 0; + let test_blit_overlap a ofs1 ofs2 len = + let a = A.of_list a in + let b = A.copy a in + A.blit a ofs1 a ofs2 len; + for i = 0 to len - 1 do + assert (A.get b (ofs1 + i) = A.get a (ofs2 + i)) + done + in + test_blit_overlap [1.; 2.; 3.; 4.] 1 2 2; (* [to_list] [of_list] *) let a = A.init 1000 Float.of_int in @@ -524,5 +542,5 @@ module Test (A : S) : sig end = struct end (* We run the same tests on [Float.Array] and [Array]. *) -module T1 = Test (Stdlib.Float.Array) +module T1 = Test (Flat_float_array) module T2 = Test (Float_array) diff --git a/testsuite/tests/lib-format/print_seq.ml b/testsuite/tests/lib-format/print_seq.ml new file mode 100644 index 00000000..4113ded9 --- /dev/null +++ b/testsuite/tests/lib-format/print_seq.ml @@ -0,0 +1,33 @@ +(* TEST + include testing +*) + +(* + +A test file for the Format module. + +*) + +open Testing;; +open Format;; + +let say s = Printf.printf s;; + +let pp_print_intseq = pp_print_seq ~pp_sep:(fun fmt () -> pp_print_char fmt ' ') pp_print_int;; + +try + + say "empty\n%!"; + test (asprintf "%a%!" pp_print_intseq Seq.empty = ""); + + say "\nmisc\n%!"; + test (asprintf "%a" pp_print_intseq (List.to_seq [0]) = "0"); + test (asprintf "%a" pp_print_intseq (List.to_seq [0;1;2]) = "0 1 2"); + test (asprintf "%a" pp_print_intseq (List.to_seq [0;0]) = "0 0"); + + say "\nend of tests\n%!"; + +with e -> + say "unexpected exception: %s\n%!" (Printexc.to_string e); + test false; +;; diff --git a/testsuite/tests/lib-format/print_seq.reference b/testsuite/tests/lib-format/print_seq.reference new file mode 100644 index 00000000..1b34bf68 --- /dev/null +++ b/testsuite/tests/lib-format/print_seq.reference @@ -0,0 +1,7 @@ +empty + 0 +misc + 1 2 3 +end of tests + +All tests succeeded. diff --git a/testsuite/tests/lib-hashtbl/compatibility.ml b/testsuite/tests/lib-hashtbl/compatibility.ml new file mode 100644 index 00000000..9ad3a477 --- /dev/null +++ b/testsuite/tests/lib-hashtbl/compatibility.ml @@ -0,0 +1,45 @@ +(* TEST +*) + +let check_contents (h: (string, int) Hashtbl.t) + (expected: (string * int) list) = + List.iter + (fun (k, v) -> assert (Hashtbl.find_opt h k = Some v)) + expected; + List.iter + (fun k -> assert (Hashtbl.find_opt h k = None)) + [""; "n"; "no"; "non"; "none"]; + Hashtbl.iter + (fun k v -> assert (List.assoc_opt k expected = Some v)) + h + +let check_failure (h: (string, int) Hashtbl.t) = + try + ignore (Hashtbl.find_opt h ""); assert false + with Invalid_argument _ -> + () + +let check_table supported h expected = + if supported + then check_contents h expected + else check_failure h; + check_contents (Hashtbl.rebuild h) expected + +(* Hash table version 1, produced with OCaml 3.12.1 *) +let h1 : (string, int) Hashtbl.t = + Marshal.from_string + "\132\149\166\190\000\000\000/\000\000\000\n\000\000\000+\000\000\000)\ + \160D\b\000\0004\000@@@@@\176%threeC@@@@\176#twoB@@@\176$fourD\176#oneA@" + 0 + +(* Hash table version 2, produced with OCaml 4.09.0 *) +let h2 : (string, int) Hashtbl.t = + Marshal.from_string + "\132\149\166\190\000\000\000;\000\000\000\012\000\000\0008\000\000\0004\ + \192E\b\000\000@\000@@@@@@@@@\176$septG\176#sixF@\176$cinqE@\176$neufI\ + \176$huitH@@@@@@P" + 0 + +let _ = + check_table false h1 ["one", 1; "two", 2; "three", 3; "four", 4]; + check_table true h2 ["cinq", 5; "six", 6; "sept", 7; "huit", 8; "neuf", 9] diff --git a/testsuite/tests/lib-hashtbl/htbl.ml b/testsuite/tests/lib-hashtbl/htbl.ml index 7dd6f287..c42decd8 100644 --- a/testsuite/tests/lib-hashtbl/htbl.ml +++ b/testsuite/tests/lib-hashtbl/htbl.ml @@ -274,6 +274,12 @@ let () = let h = Hashtbl.create 16 in for i = 1 to 1000 do Hashtbl.add h i (i * 2) done; Printf.printf "%i elements\n" (Hashtbl.length h); + let () = + (* Check that filter_map_inplace of nothing changes nothing *) + let marshaled_before = Marshal.to_string h [Marshal.No_sharing] in + Hashtbl.filter_map_inplace (fun _k v -> Some v) h; + let marshaled_after = Marshal.to_string h [Marshal.No_sharing] in + assert (marshaled_before = marshaled_after) in Hashtbl.filter_map_inplace (fun k v -> if k mod 100 = 0 then ((*Hashtbl.add h v v;*) Some (v / 100)) else None) h; diff --git a/testsuite/tests/lib-list/test.ml b/testsuite/tests/lib-list/test.ml index d0b75e6a..8f7be225 100644 --- a/testsuite/tests/lib-list/test.ml +++ b/testsuite/tests/lib-list/test.ml @@ -1,12 +1,20 @@ (* TEST *) +let is_even x = (x mod 2 = 0) + let string_of_even_opt x = - if x mod 2 = 0 then + if is_even x then Some (string_of_int x) else None +let string_of_even_or_int x = + if is_even x then + Either.Left (string_of_int x) + else + Either.Right x + (* Standard test case *) let () = let l = List.init 10 (fun x -> x) in @@ -27,6 +35,24 @@ let () = assert (not (List.exists (fun a -> a > 9) l)); assert (List.exists (fun _ -> true) l); + assert (List.equal (=) [1; 2; 3] [1; 2; 3]); + assert (not (List.equal (=) [1; 2; 3] [1; 2])); + assert (not (List.equal (=) [1; 2; 3] [1; 3; 2])); + + (* The current implementation of List.equal calls the comparison + function even for different-size lists. This is not part of the + specification, so it would be valid to change this behavior, but + we don't want to change it without noticing so here is a test for + it. *) + assert (let c = ref 0 in + not (List.equal (fun _ _ -> incr c; true) [1; 2] [1; 2; 3]) + && !c = 2); + + assert (List.compare compare [1; 2; 3] [1; 2; 3] = 0); + assert (List.compare compare [1; 2; 3] [1; 2] > 0); + assert (List.compare compare [1; 2; 3] [1; 3; 2] < 0); + assert (List.compare compare [3] [2; 1] > 0); + begin let f ~limit a = if a >= limit then Some (a, limit) else None in assert (List.find_map (f ~limit:3) [] = None); @@ -36,6 +62,11 @@ let () = assert (List.filteri (fun i _ -> i < 2) (List.rev l) = [9; 8]); + assert (List.partition is_even [1; 2; 3; 4; 5] + = ([2; 4], [1; 3; 5])); + assert (List.partition_map string_of_even_or_int [1; 2; 3; 4; 5] + = (["2"; "4"], [1; 3; 5])); + assert (List.compare_lengths [] [] = 0); assert (List.compare_lengths [1;2] ['a';'b'] = 0); assert (List.compare_lengths [] [1;2] < 0); diff --git a/testsuite/tests/lib-marshal/intext.ml b/testsuite/tests/lib-marshal/intext.ml index 5ed2bbc5..382df98f 100644 --- a/testsuite/tests/lib-marshal/intext.ml +++ b/testsuite/tests/lib-marshal/intext.ml @@ -321,91 +321,88 @@ let test_size() = let s = Marshal.to_bytes (G(A, G(B 2, G(C 3.14, G(D "glop", E 'e'))))) [] in test 300 (Marshal.header_size + Marshal.data_size s 0 = Bytes.length s) -external marshal_to_block - : string -> int -> 'a -> Marshal.extern_flags list -> unit - = "marshal_to_block" -external marshal_from_block : string -> int -> 'a = "marshal_from_block" -external static_alloc : int -> string = "caml_static_alloc" +external marshal_to_block : int -> 'a -> Marshal.extern_flags list -> unit + = "marshal_to_block" +external marshal_from_block : int -> 'a = "marshal_from_block" let test_block () = - let s = static_alloc 512 in - marshal_to_block s 512 1 []; - test 401 (marshal_from_block s 512 = 1); - marshal_to_block s 512 (-1) []; - test 402 (marshal_from_block s 512 = (-1)); - marshal_to_block s 512 258 []; - test 403 (marshal_from_block s 512 = 258); - marshal_to_block s 512 20000 []; - test 404 (marshal_from_block s 512 = 20000); - marshal_to_block s 512 0x12345678 []; - test 405 (marshal_from_block s 512 = 0x12345678); - marshal_to_block s 512 bigint []; - test 406 (marshal_from_block s 512 = bigint); - marshal_to_block s 512 "foobargeebuz" []; - test 407 (marshal_from_block s 512 = "foobargeebuz"); - marshal_to_block s 512 longstring []; - test 408 (marshal_from_block s 512 = longstring); + marshal_to_block 512 1 []; + test 401 (marshal_from_block 512 = 1); + marshal_to_block 512 (-1) []; + test 402 (marshal_from_block 512 = (-1)); + marshal_to_block 512 258 []; + test 403 (marshal_from_block 512 = 258); + marshal_to_block 512 20000 []; + test 404 (marshal_from_block 512 = 20000); + marshal_to_block 512 0x12345678 []; + test 405 (marshal_from_block 512 = 0x12345678); + marshal_to_block 512 bigint []; + test 406 (marshal_from_block 512 = bigint); + marshal_to_block 512 "foobargeebuz" []; + test 407 (marshal_from_block 512 = "foobargeebuz"); + marshal_to_block 512 longstring []; + test 408 (marshal_from_block 512 = longstring); test 409 - (try marshal_to_block s 512 verylongstring []; false + (try marshal_to_block 512 verylongstring []; false with Failure s when s = "Marshal.to_buffer: buffer overflow" -> true); - marshal_to_block s 512 3.141592654 []; - test 410 (marshal_from_block s 512 = 3.141592654); - marshal_to_block s 512 () []; - test 411 (marshal_from_block s 512 = ()); - marshal_to_block s 512 A []; - test 412 (match marshal_from_block s 512 with + marshal_to_block 512 3.141592654 []; + test 410 (marshal_from_block 512 = 3.141592654); + marshal_to_block 512 () []; + test 411 (marshal_from_block 512 = ()); + marshal_to_block 512 A []; + test 412 (match marshal_from_block 512 with A -> true | _ -> false); - marshal_to_block s 512 (B 1) []; - test 413 (match marshal_from_block s 512 with + marshal_to_block 512 (B 1) []; + test 413 (match marshal_from_block 512 with (B 1) -> true | _ -> false); - marshal_to_block s 512 (C 2.718) []; - test 414 (match marshal_from_block s 512 with + marshal_to_block 512 (C 2.718) []; + test 414 (match marshal_from_block 512 with (C f) -> f = 2.718 | _ -> false); - marshal_to_block s 512 (D "hello, world!") []; - test 415 (match marshal_from_block s 512 with + marshal_to_block 512 (D "hello, world!") []; + test 415 (match marshal_from_block 512 with (D "hello, world!") -> true | _ -> false); - marshal_to_block s 512 (E 'l') []; - test 416 (match marshal_from_block s 512 with + marshal_to_block 512 (E 'l') []; + test 416 (match marshal_from_block 512 with (E 'l') -> true | _ -> false); - marshal_to_block s 512 (F(B 1)) []; - test 417 (match marshal_from_block s 512 with + marshal_to_block 512 (F(B 1)) []; + test 417 (match marshal_from_block 512 with (F(B 1)) -> true | _ -> false); - marshal_to_block s 512 (G(A, G(B 2, G(C 3.14, G(D "glop", E 'e'))))) []; - test 418 (match marshal_from_block s 512 with + marshal_to_block 512 (G(A, G(B 2, G(C 3.14, G(D "glop", E 'e'))))) []; + test 418 (match marshal_from_block 512 with (G(A, G(B 2, G(C 3.14, G(D "glop", E 'e'))))) -> true | _ -> false); - marshal_to_block s 512 (H(1, A)) []; - test 419 (match marshal_from_block s 512 with + marshal_to_block 512 (H(1, A)) []; + test 419 (match marshal_from_block 512 with (H(1, A)) -> true | _ -> false); - marshal_to_block s 512 (I(B 2, 1e-6)) []; - test 420 (match marshal_from_block s 512 with + marshal_to_block 512 (I(B 2, 1e-6)) []; + test 420 (match marshal_from_block 512 with (I(B 2, 1e-6)) -> true | _ -> false); let x = D "sharing" in let y = G(x, x) in let z = G(y, G(x, y)) in - marshal_to_block s 512 z []; - test 421 (match marshal_from_block s 512 with + marshal_to_block 512 z []; + test 421 (match marshal_from_block 512 with G((G((D "sharing" as t1), t2) as t3), G(t4, t5)) -> t1 == t2 && t3 == t5 && t4 == t1 | _ -> false); - marshal_to_block s 512 [|1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16|] []; - test 422 (marshal_from_block s 512 = + marshal_to_block 512 [|1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16|] []; + test 422 (marshal_from_block 512 = [|1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16|]); let rec big n = if n <= 0 then A else H(n, big(n-1)) in test 423 - (try marshal_to_block s 512 (big 1000) []; false + (try marshal_to_block 512 (big 1000) []; false with Failure _ -> true); test 424 - (try marshal_to_block s 512 "Hello, world!" []; - ignore (marshal_from_block s 8); + (try marshal_to_block 512 "Hello, world!" []; + ignore (marshal_from_block 8); false with Failure _ -> true) diff --git a/testsuite/tests/lib-marshal/intextaux.c b/testsuite/tests/lib-marshal/intextaux.c index d8ea180a..d55cb711 100644 --- a/testsuite/tests/lib-marshal/intextaux.c +++ b/testsuite/tests/lib-marshal/intextaux.c @@ -19,15 +19,20 @@ #define CAML_INTERNALS -value marshal_to_block(value vbuf, value vlen, value v, value vflags) +#define BLOCK_SIZE 512 +static char marshal_block[BLOCK_SIZE]; + +value marshal_to_block(value vlen, value v, value vflags) { - return Val_long(caml_output_value_to_block(v, vflags, - (char *) vbuf, Long_val(vlen))); + CAMLassert(Long_val(vlen) <= BLOCK_SIZE); + caml_output_value_to_block(v, vflags, marshal_block, Long_val(vlen)); + return Val_unit; } -value marshal_from_block(value vbuf, value vlen) +value marshal_from_block(value vlen) { - return caml_input_value_from_block((char *) vbuf, Long_val(vlen)); + CAMLassert(Long_val(vlen) <= BLOCK_SIZE); + return caml_input_value_from_block(marshal_block, Long_val(vlen)); } static void bad_serialize(value v, uintnat* sz_32, uintnat* sz_64) diff --git a/testsuite/tests/lib-obj/new_obj.ml b/testsuite/tests/lib-obj/new_obj.ml new file mode 100644 index 00000000..049a300f --- /dev/null +++ b/testsuite/tests/lib-obj/new_obj.ml @@ -0,0 +1,16 @@ +(* TEST +*) + +let _ = + + begin match Obj.new_block 255 1 with + | v -> failwith "Expected failure for custom block" + | exception (Invalid_argument _) -> () + end; + + begin match Obj.new_block 252 0 with + | v -> failwith "Expected failure for zero length string block" + | exception (Invalid_argument _) -> () + end; + + print_endline "OK" diff --git a/testsuite/tests/lib-obj/new_obj.reference b/testsuite/tests/lib-obj/new_obj.reference new file mode 100644 index 00000000..d86bac9d --- /dev/null +++ b/testsuite/tests/lib-obj/new_obj.reference @@ -0,0 +1 @@ +OK diff --git a/testsuite/tests/lib-obj/reachable_words.ml b/testsuite/tests/lib-obj/reachable_words.ml index 1c1709ad..8ec72434 100644 --- a/testsuite/tests/lib-obj/reachable_words.ml +++ b/testsuite/tests/lib-obj/reachable_words.ml @@ -1,11 +1,6 @@ (* TEST *) -let native = - match Sys.backend_type with - | Sys.Native -> true - | Sys.Bytecode -> false - | Sys.Other s -> print_endline s; assert false let size x = Obj.reachable_words (Obj.repr x) @@ -22,7 +17,6 @@ type t = let f () = let x = Random.int 10 in expect_size 0 42; - expect_size (if native then 0 else 3) (1, 2); expect_size 2 [| x |]; expect_size 3 [| x; 0 |]; diff --git a/testsuite/tests/lib-obj/reachable_words_np.ml b/testsuite/tests/lib-obj/reachable_words_np.ml new file mode 100644 index 00000000..8a50268d --- /dev/null +++ b/testsuite/tests/lib-obj/reachable_words_np.ml @@ -0,0 +1,21 @@ +(* TEST + * naked_pointers + ** bytecode + ** native +*) + +let native = + match Sys.backend_type with + | Sys.Native -> true + | Sys.Bytecode -> false + | Sys.Other s -> print_endline s; assert false + +let size x = Obj.reachable_words (Obj.repr x) + +let expect_size s x = + let i = size x in + if i <> s then + Printf.printf "size = %i; expected = %i\n%!" i s + +let () = + expect_size (if native then 0 else 3) (1, 2) diff --git a/testsuite/tests/lib-random/rand.ml b/testsuite/tests/lib-random/rand.ml index 50e74d13..1664907d 100644 --- a/testsuite/tests/lib-random/rand.ml +++ b/testsuite/tests/lib-random/rand.ml @@ -4,12 +4,12 @@ (* Test that two Random.self_init() in close succession will not result in the same PRNG state. Note that even when the code is correct this test is expected to fail - once in 10000 runs. + once in 2^30 runs. *) let () = Random.self_init (); - let x = Random.int 10000 in + let x = Random.bits () in Random.self_init (); - let y = Random.int 10000 in + let y = Random.bits () in if x = y then print_endline "FAILED" else print_endline "PASSED" diff --git a/testsuite/tests/lib-scanf/tscanf.ml b/testsuite/tests/lib-scanf/tscanf.ml index cebc76d4..e932f960 100644 --- a/testsuite/tests/lib-scanf/tscanf.ml +++ b/testsuite/tests/lib-scanf/tscanf.ml @@ -1,6 +1,5 @@ (* TEST include testing - compare_programs = "false" (* See https://github.com/ocaml/ocaml/pull/8853 *) *) (* diff --git a/testsuite/tests/lib-set/testmap.ml b/testsuite/tests/lib-set/testmap.ml index 500f00b0..b41c020d 100644 --- a/testsuite/tests/lib-set/testmap.ml +++ b/testsuite/tests/lib-set/testmap.ml @@ -177,6 +177,9 @@ let test x v s1 s2 = checkbool "to_seq_of_seq" (M.equal (=) s1 (M.of_seq @@ M.to_seq s1)); + checkbool "to_rev_seq_of_seq" + (M.equal (=) s1 (M.of_seq @@ M.to_rev_seq s1)); + checkbool "to_seq_from" (let seq = M.to_seq_from x s1 in let ok1 = List.of_seq seq |> List.for_all (fun (y,_) -> y >= x) in @@ -187,6 +190,18 @@ let test x v s1 s2 = in ok1 && ok2); + checkbool "to_seq_increasing" + (let seq = M.to_seq s1 in + let last = ref min_int in + Seq.iter (fun (x, _) -> assert (!last <= x); last := x) seq; + true); + + checkbool "to_rev_seq_decreasing" + (let seq = M.to_rev_seq s1 in + let last = ref max_int in + Seq.iter (fun (x, _) -> assert (x <= !last); last := x) seq; + true); + () let rkey() = Random.int 10 diff --git a/testsuite/tests/lib-set/testset.ml b/testsuite/tests/lib-set/testset.ml index 36d450eb..764987c0 100644 --- a/testsuite/tests/lib-set/testset.ml +++ b/testsuite/tests/lib-set/testset.ml @@ -190,6 +190,9 @@ let test x s1 s2 = checkbool "to_seq_of_seq" (S.equal s1 (S.of_seq @@ S.to_seq s1)); + checkbool "to_seq_of_seq" + (S.equal s1 (S.of_seq @@ S.to_rev_seq s1)); + checkbool "to_seq_from" (let seq = S.to_seq_from x s1 in let ok1 = List.of_seq seq |> List.for_all (fun y -> y >= x) in @@ -200,6 +203,18 @@ let test x s1 s2 = in ok1 && ok2); + checkbool "to_seq_increasing" + (let seq = S.to_seq s1 in + let last = ref min_int in + Seq.iter (fun x -> assert (!last <= x); last := x) seq; + true); + + checkbool "to_rev_seq_decreasing" + (let seq = S.to_rev_seq s1 in + let last = ref max_int in + Seq.iter (fun x -> assert (x <= !last); last := x) seq; + true); + () let relt() = Random.int 10 diff --git a/testsuite/tests/lib-stdlabels/test_stdlabels.ml b/testsuite/tests/lib-stdlabels/test_stdlabels.ml index fe7ae4f6..c846bcb7 100644 --- a/testsuite/tests/lib-stdlabels/test_stdlabels.ml +++ b/testsuite/tests/lib-stdlabels/test_stdlabels.ml @@ -13,35 +13,8 @@ module M : module type of struct include Map end [@remove_aliases] = module Se : module type of struct include Set end [@remove_aliases] = MoreLabels.Set - -(* For *) -(* module H : module type of Hashtbl = MoreLabels.Hashtbl *) -(* we will have following error: *) -(* Error: Signature mismatch: *) -(* ... *) -(* Type declarations do not match: *) -(* type statistics = Hashtbl.statistics *) -(* is not included in *) -(* type statistics = { *) -(* num_bindings : int; *) -(* num_buckets : int; *) -(* max_bucket_length : int; *) -(* bucket_histogram : int array; *) -(* } *) -(* Their kinds differ. *) -(* This is workaround:*) -module Indirection = struct - type t = Hashtbl.statistics = { num_bindings: int; - num_buckets: int; - max_bucket_length: int; - bucket_histogram: int array} -end -module type HS = sig - type statistics = Indirection.t - include module type of struct include Hashtbl end [@remove_aliases] - with type statistics := Indirection.t -end -module H : HS = MoreLabels.Hashtbl +module H : module type of struct include Hashtbl end [@remove_aliases] = + MoreLabels.Hashtbl let () = () diff --git a/testsuite/tests/lib-string/test_string.ml b/testsuite/tests/lib-string/test_string.ml index cd45af62..07bdd28c 100644 --- a/testsuite/tests/lib-string/test_string.ml +++ b/testsuite/tests/lib-string/test_string.ml @@ -51,5 +51,5 @@ let () = while !sz >= 0 do push big l; sz += Sys.max_string_length done; while !sz <= 0 do push big l; sz += Sys.max_string_length done; try ignore (String.concat "" !l); assert false - with Invalid_argument _ -> () + with Invalid_argument _ -> (); end diff --git a/testsuite/tests/lib-systhreads/eintr.ml b/testsuite/tests/lib-systhreads/eintr.ml new file mode 100644 index 00000000..5c0a4d04 --- /dev/null +++ b/testsuite/tests/lib-systhreads/eintr.ml @@ -0,0 +1,91 @@ +(* TEST + +* hassysthreads +include systhreads +** not-windows +*** bytecode +*** native +*) + +let signals_requested = Atomic.make 0 +let signal_delay = 0.1 +let _ = Thread.create (fun () -> + let signals_sent = ref 0 in + ignore (Thread.sigmask Unix.SIG_BLOCK [Sys.sigint]); + while true do + if Atomic.get signals_requested > !signals_sent then begin + Thread.delay signal_delay; + Unix.kill (Unix.getpid ()) Sys.sigint; + incr signals_sent + end else begin + Thread.yield () + end + done) () +let request_signal () = Atomic.incr signals_requested + +let () = + let (rd, wr) = Unix.pipe () in + Sys.catch_break true; + request_signal (); + begin match Unix.read rd (Bytes.make 1 'a') 0 1 with + | _ -> assert false + | exception Sys.Break -> print_endline "break: ok" end; + Sys.catch_break false; + Unix.close rd; + Unix.close wr + +let () = + let (rd, wr) = Unix.pipe () in + Sys.set_signal Sys.sigint (Signal_handle (fun _ -> Gc.full_major ())); + request_signal (); + begin match Unix.read rd (Bytes.make 1 'a') 0 1 with + | _ -> assert false + | exception Unix.Unix_error(Unix.EINTR, "read", _) -> + print_endline "eintr: ok" end; + Sys.set_signal Sys.sigint Signal_default; + Unix.close rd; + Unix.close wr + + +(* Doing I/O on stdout would be more realistic, but seeking has the + same locking & scheduling effects, without actually producing any + output *) +let poke_stdout () = + match out_channel_length stdout with + | _ -> () + | exception Sys_error _ -> () + +let () = + let r = Atomic.make true in + Sys.set_signal Sys.sigint (Signal_handle (fun _ -> + poke_stdout (); Atomic.set r false)); + request_signal (); + while Atomic.get r do + poke_stdout () + done; + Sys.set_signal Sys.sigint Signal_default; + print_endline "chan: ok" + +let () = + let mklist () = List.init 1000 (fun i -> (i, i)) in + let before = Sys.opaque_identity (ref (mklist ())) in + let during = Atomic.make (Sys.opaque_identity (mklist ())) in + let siglist = ref [] in + Sys.set_signal Sys.sigint (Signal_handle (fun _ -> + Gc.full_major (); poke_stdout (); Gc.compact (); + siglist := mklist (); + raise Sys.Break)); + request_signal (); + begin match + while true do + poke_stdout (); + Atomic.set during (mklist ()) + done + with + | () -> assert false + | exception Sys.Break -> () end; + let expected = Sys.opaque_identity (mklist ()) in + assert (!before = expected); + assert (Atomic.get during = expected); + assert (!siglist = expected); + print_endline "gc: ok" diff --git a/testsuite/tests/lib-systhreads/eintr.reference b/testsuite/tests/lib-systhreads/eintr.reference new file mode 100644 index 00000000..89355b9d --- /dev/null +++ b/testsuite/tests/lib-systhreads/eintr.reference @@ -0,0 +1,4 @@ +break: ok +eintr: ok +chan: ok +gc: ok diff --git a/testsuite/tests/lib-threads/fileio.ml b/testsuite/tests/lib-threads/fileio.ml index 596721c4..0e23128d 100644 --- a/testsuite/tests/lib-threads/fileio.ml +++ b/testsuite/tests/lib-threads/fileio.ml @@ -20,7 +20,7 @@ let test msg producer consumer src dst = let cons = Thread.create consumer (ipipe, oc) in Thread.join prod; Thread.join cons; - if Unix.system ("cmp " ^ src ^ " " ^ dst) = Unix.WEXITED 0 + if Sys.command ("cmp " ^ src ^ " " ^ dst) = 0 then print_string "passed" else print_string "FAILED"; print_newline() diff --git a/testsuite/tests/lib-threads/mutex_errors.ml b/testsuite/tests/lib-threads/mutex_errors.ml new file mode 100644 index 00000000..25d33309 --- /dev/null +++ b/testsuite/tests/lib-threads/mutex_errors.ml @@ -0,0 +1,68 @@ +(* TEST + +* hassysthreads +include systhreads +** bytecode +** native + +*) + +let log s = + Printf.printf "%s\n%!" s + +let mutex_lock_must_fail m = + try + Mutex.lock m; log "Should have failed!" + with Sys_error _ -> + log "Error reported" + +let mutex_unlock_must_fail m = + try + Mutex.unlock m; log "Should have failed!" + with Sys_error _ -> + log "Error reported" + +let mutex_deadlock () = + let m = Mutex.create() in + log "Acquiring mutex"; + Mutex.lock m; + log "Acquiring mutex again"; + mutex_lock_must_fail m; + log "Releasing mutex"; + Mutex.unlock m; + let f () = + log "Acquiring mutex from another thread"; + Mutex.lock m; + log "Success"; + Mutex.unlock m in + Thread.join (Thread.create f ()) + +let mutex_unlock_twice () = + let m = Mutex.create() in + log "Acquiring mutex"; + Mutex.lock m; + log "Releasing mutex"; + Mutex.unlock m; + log "Releasing mutex again"; + mutex_unlock_must_fail m; + log "Releasing mutex one more time"; + mutex_unlock_must_fail m + +let mutex_unlock_other_thread () = + let m = Mutex.create() in + log "Acquiring mutex"; + Mutex.lock m; + let f () = + log "Releasing mutex from another thread"; + mutex_unlock_must_fail m; + log "Releasing mutex from another thread (again)"; + mutex_unlock_must_fail m in + Thread.join (Thread.create f ()) + +let _ = + log "---- Self deadlock"; + mutex_deadlock(); + log "---- Unlock twice"; + mutex_unlock_twice(); + log "---- Unlock in other thread"; + mutex_unlock_other_thread() diff --git a/testsuite/tests/lib-threads/mutex_errors.reference b/testsuite/tests/lib-threads/mutex_errors.reference new file mode 100644 index 00000000..7e8285bf --- /dev/null +++ b/testsuite/tests/lib-threads/mutex_errors.reference @@ -0,0 +1,20 @@ +---- Self deadlock +Acquiring mutex +Acquiring mutex again +Error reported +Releasing mutex +Acquiring mutex from another thread +Success +---- Unlock twice +Acquiring mutex +Releasing mutex +Releasing mutex again +Error reported +Releasing mutex one more time +Error reported +---- Unlock in other thread +Acquiring mutex +Releasing mutex from another thread +Error reported +Releasing mutex from another thread (again) +Error reported diff --git a/testsuite/tests/lib-threads/pr4466.ml b/testsuite/tests/lib-threads/pr4466.ml index 0cda04a7..6df8f6d4 100644 --- a/testsuite/tests/lib-threads/pr4466.ml +++ b/testsuite/tests/lib-threads/pr4466.ml @@ -3,8 +3,6 @@ * hassysthreads include systhreads ** native - compare_programs = "false" - *) open Printf diff --git a/testsuite/tests/lib-threads/pr9971.ml b/testsuite/tests/lib-threads/pr9971.ml new file mode 100644 index 00000000..dc016f3f --- /dev/null +++ b/testsuite/tests/lib-threads/pr9971.ml @@ -0,0 +1,15 @@ +(* TEST + +* hassysthreads +include systhreads +** bytecode +** native + +*) + +let t = + let t = Thread.create (fun _ -> ())() in + Thread.join t + +let () = + Thread.exit () diff --git a/testsuite/tests/lib-unix/common/channel_of.ml b/testsuite/tests/lib-unix/common/channel_of.ml index f61dd949..b0be29d0 100644 --- a/testsuite/tests/lib-unix/common/channel_of.ml +++ b/testsuite/tests/lib-unix/common/channel_of.ml @@ -22,7 +22,8 @@ let shouldfail msg fn arg = let _ = (* Files *) begin - let fd = Unix.(openfile "file.tmp" [O_WRONLY;O_CREAT;O_TRUNC] 0o666) in + let fd = Unix.(openfile "file.tmp" + [O_WRONLY;O_CREAT;O_TRUNC;O_SHARE_DELETE] 0o666) in shouldpass "File 1" Unix.in_channel_of_descr fd; shouldpass "File 2" Unix.out_channel_of_descr fd; Unix.close fd @@ -57,7 +58,8 @@ let _ = end; (* A closed file descriptor should now fail *) begin - let fd = Unix.(openfile "file.tmp" [O_WRONLY;O_CREAT;O_TRUNC] 0o666) in + let fd = Unix.(openfile "file.tmp" + [O_WRONLY;O_CREAT;O_TRUNC;O_SHARE_DELETE] 0o666) in Unix.close fd; shouldfail "Closed file 1" Unix.in_channel_of_descr fd; shouldfail "Closed file 2" Unix.out_channel_of_descr fd diff --git a/testsuite/tests/lib-unix/common/redirections.ml b/testsuite/tests/lib-unix/common/redirections.ml index 65fbd60c..df70e280 100644 --- a/testsuite/tests/lib-unix/common/redirections.ml +++ b/testsuite/tests/lib-unix/common/redirections.ml @@ -96,6 +96,22 @@ let test_swap12 () = (* swapping stdout and stderr *) if status <> Unix.WEXITED 0 then out Unix.stdout "!!! reflector exited with an error\n" +let test_12tofile () = (* > file 2>&1 *) + let f = + Unix.(openfile "./tmpout.txt" [O_WRONLY;O_TRUNC;O_CREAT;O_CLOEXEC] 0o600) in + let pid = + Unix.create_process + refl + [| refl; "-o"; "123"; "-e"; "456"; "-o"; "789" |] + Unix.stdin f f in + let (_, status) = Unix.waitpid [] pid in + Unix.close f; + if status <> Unix.WEXITED 0 then + out Unix.stdout "!!! reflector exited with an error\n"; + out Unix.stdout "---- File tmpout.txt\n"; + cat "./tmpout.txt"; + Sys.remove "./tmpout.txt" + let test_open_process_in () = let ic = Unix.open_process_in (refl ^ " -o 123 -o 456") in out Unix.stdout (input_line ic ^ "\n"); @@ -139,6 +155,8 @@ let _ = test_2ampsup1(); out Unix.stdout "** create_process swap 1-2\n"; test_swap12(); + out Unix.stdout "** create_process >file 2>&1\n"; + test_12tofile(); out Unix.stdout "** open_process_in\n"; test_open_process_in(); out Unix.stdout "** open_process_out\n"; diff --git a/testsuite/tests/lib-unix/common/redirections.reference b/testsuite/tests/lib-unix/common/redirections.reference index c0da174c..8c92a910 100644 --- a/testsuite/tests/lib-unix/common/redirections.reference +++ b/testsuite/tests/lib-unix/common/redirections.reference @@ -13,6 +13,11 @@ bbbb 789 ** create_process swap 1-2 123 +** create_process >file 2>&1 +---- File tmpout.txt +123 +456 +789 ** open_process_in 123 456 diff --git a/testsuite/tests/lib-unix/common/test_unixlabels.ml b/testsuite/tests/lib-unix/common/test_unixlabels.ml new file mode 100644 index 00000000..fc0335b5 --- /dev/null +++ b/testsuite/tests/lib-unix/common/test_unixlabels.ml @@ -0,0 +1,12 @@ +(* TEST +include unix +flags += " -nolabels " +* hasunix +** bytecode +** native +*) + +module U : module type of Unix = UnixLabels + +let () = + () diff --git a/testsuite/tests/lib-unix/common/test_unixlabels.reference b/testsuite/tests/lib-unix/common/test_unixlabels.reference new file mode 100644 index 00000000..e69de29b diff --git a/testsuite/tests/lib-unix/common/uexit.ml b/testsuite/tests/lib-unix/common/uexit.ml new file mode 100644 index 00000000..b80f3208 --- /dev/null +++ b/testsuite/tests/lib-unix/common/uexit.ml @@ -0,0 +1,11 @@ +(* TEST +* hasunix +include unix +** bytecode +** native +*) + +let _ = + at_exit (fun () -> print_string "B\n"; flush stdout); + print_string "A\n"; (* don't flush *) + Unix._exit 0 diff --git a/testsuite/tests/lib-unix/kill/unix_kill.ml b/testsuite/tests/lib-unix/kill/unix_kill.ml new file mode 100644 index 00000000..2ace3849 --- /dev/null +++ b/testsuite/tests/lib-unix/kill/unix_kill.ml @@ -0,0 +1,26 @@ +(* TEST +include unix +* libunix +** bytecode +** native +*) + +let () = + let r = ref false in + Sys.set_signal Sys.sigint (Signal_handle (fun _ -> r := true)); + Unix.kill (Unix.getpid ()) Sys.sigint; + let x = !r in + Printf.printf "%b " x; + Printf.printf "%b\n" !r + +let () = + let r = ref false in + let _ = Unix.sigprocmask SIG_BLOCK [Sys.sigint] in + Sys.set_signal Sys.sigint (Signal_handle (fun _ -> r := true)); + Unix.kill (Unix.getpid ()) Sys.sigint; + Gc.full_major (); + let a = !r in + let _ = Unix.sigprocmask SIG_UNBLOCK [Sys.sigint] in + let b = !r in + Printf.printf "%b %b " a b; + Printf.printf "%b\n" !r diff --git a/testsuite/tests/lib-unix/kill/unix_kill.reference b/testsuite/tests/lib-unix/kill/unix_kill.reference new file mode 100644 index 00000000..bb03effa --- /dev/null +++ b/testsuite/tests/lib-unix/kill/unix_kill.reference @@ -0,0 +1,2 @@ +true true +false true true diff --git a/testsuite/tests/link-test/empty.ml b/testsuite/tests/link-test/empty.ml new file mode 100644 index 00000000..d38300bb --- /dev/null +++ b/testsuite/tests/link-test/empty.ml @@ -0,0 +1,29 @@ +(* TEST + +* setup-ocamlc.byte-build-env +** ocamlc.byte +module = "empty.ml" +*** ocamlc.byte +module = "" +flags = "-a" +all_modules = "" +program = "empty.cma" +**** ocamlc.byte +flags = "" +program = "${test_build_directory}/empty.byte" +all_modules = "empty.cma empty.cmo" +***** check-ocamlc.byte-output +* setup-ocamlopt.byte-build-env +** ocamlopt.byte +module = "empty.ml" +*** ocamlopt.byte +module = "" +flags = "-a" +all_modules = "" +program = "empty.cmxa" +**** ocamlopt.byte +flags = "" +program = "${test_build_directory}/empty.native" +all_modules = "empty.cmxa empty.cmx" +***** check-ocamlopt.byte-output +*) diff --git a/testsuite/tests/match-exception-warnings/exhaustiveness_warnings.ml b/testsuite/tests/match-exception-warnings/exhaustiveness_warnings.ml index 4a16ada8..d6bcd397 100644 --- a/testsuite/tests/match-exception-warnings/exhaustiveness_warnings.ml +++ b/testsuite/tests/match-exception-warnings/exhaustiveness_warnings.ml @@ -21,7 +21,7 @@ Lines 8-11, characters 4-16: 9 | | exception e -> () 10 | | Some false -> () 11 | | None -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Some true val test_match_exhaustiveness : unit -> unit = @@ -39,7 +39,7 @@ Lines 2-4, characters 4-30: 2 | ....match None with 3 | | Some false -> () 4 | | None | exception _ -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Some true val test_match_exhaustiveness_nest1 : unit -> unit = @@ -57,7 +57,7 @@ Lines 2-4, characters 4-16: 2 | ....match None with 3 | | Some false | exception _ -> () 4 | | None -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Some true val test_match_exhaustiveness_nest2 : unit -> unit = @@ -77,17 +77,17 @@ Lines 2-5, characters 4-30: 3 | | exception e -> () 4 | | Some false | exception _ -> () 5 | | None | exception _ -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Some true Line 4, characters 29-30: 4 | | Some false | exception _ -> () ^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. Line 5, characters 23-24: 5 | | None | exception _ -> () ^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. val test_match_exhaustiveness_full : unit -> unit = |}] ;; diff --git a/testsuite/tests/messages/precise_locations.ml b/testsuite/tests/messages/precise_locations.ml index efbc15a4..aecd8a5a 100644 --- a/testsuite/tests/messages/precise_locations.ml +++ b/testsuite/tests/messages/precise_locations.ml @@ -86,7 +86,7 @@ end);; Line 2, characters 0-9: 2 | open List ^^^^^^^^^ -Error (warning 33): unused open Stdlib.List. +Error (warning 33 [unused-open]): unused open Stdlib.List. |}];; type unknown += Foo;; diff --git a/testsuite/tests/misc/ephe_infix.ml b/testsuite/tests/misc/ephe_infix.ml new file mode 100644 index 00000000..3204d5be --- /dev/null +++ b/testsuite/tests/misc/ephe_infix.ml @@ -0,0 +1,26 @@ +(* TEST *) + +(* Testing handling of infix_tag by ephemeron *) + +let infix n = let rec f () = n and g () = f () in g + +(* Issue #9485 *) +let () = + let w = Weak.create 1 in + Weak.set w 0 (Some (infix 12)); + match Weak.get_copy w 0 with Some h -> ignore (h ()) | _ -> () + +(* Issue #7810 *) +let ephe x = + let open Ephemeron.K1 in + let e = create () in + set_key e x; + set_data e 42; + Gc.full_major (); + (x, get_data e) + +let () = + assert (ephe (ref 1000) = (ref 1000, Some 42)); + match ephe (infix 12) with + | (h, Some 42) -> () + | _ -> assert false diff --git a/testsuite/tests/misc/weaklifetime.ml b/testsuite/tests/misc/weaklifetime.ml index 49c701a9..2e700290 100644 --- a/testsuite/tests/misc/weaklifetime.ml +++ b/testsuite/tests/misc/weaklifetime.ml @@ -29,6 +29,8 @@ let data = let gccount () = (Gc.quick_stat ()).Gc.major_collections;; +type change = No_change | Fill | Erase;; + (* Check the correctness condition on the data at (i,j): 1. if the block is present, the weak pointer must be full 2. if the block was removed at GC n, and the weak pointer is still @@ -40,19 +42,28 @@ let gccount () = (Gc.quick_stat ()).Gc.major_collections;; *) let check_and_change i j = let gc1 = gccount () in - match data.(i).objs.(j), Weak.check data.(i).wp j with - | Present x, false -> assert false - | Absent n, true -> assert (gc1 <= n+1) - | Absent _, false -> + let change = + (* we only read data.(i).objs.(j) in this local binding to ensure + that it does not remain reachable on the bytecode stack + in the rest of the function below, when we overwrite the value + and try to observe its collection. *) + match data.(i).objs.(j), Weak.check data.(i).wp j with + | Present x, false -> assert false + | Absent n, true -> assert (gc1 <= n+1); No_change + | Absent _, false -> Fill + | Present _, true -> + if Random.int 10 = 0 then Erase else No_change + in + match change with + | No_change -> () + | Fill -> let x = Array.make (1 + Random.int 10) 42 in data.(i).objs.(j) <- Present x; Weak.set data.(i).wp j (Some x); - | Present _, true -> - if Random.int 10 = 0 then begin - data.(i).objs.(j) <- Absent gc1; - let gc2 = gccount () in - if gc1 <> gc2 then data.(i).objs.(j) <- Absent gc2; - end + | Erase -> + data.(i).objs.(j) <- Absent gc1; + let gc2 = gccount () in + if gc1 <> gc2 then data.(i).objs.(j) <- Absent gc2; ;; let dummy = ref [||];; diff --git a/testsuite/tests/no-alias-deps/aliases.compilers.reference b/testsuite/tests/no-alias-deps/aliases.compilers.reference index 16b8ef98..5e421986 100644 --- a/testsuite/tests/no-alias-deps/aliases.compilers.reference +++ b/testsuite/tests/no-alias-deps/aliases.compilers.reference @@ -1,9 +1,9 @@ File "aliases.ml", line 17, characters 12-13: 17 | module A' = A (* missing a.cmi *) ^ -Warning 49: no cmi file was found in path for module A +Warning 49 [no-cmi-file]: no cmi file was found in path for module A File "aliases.ml", line 18, characters 12-13: 18 | module B' = B (* broken b.cmi *) ^ -Warning 49: no valid cmi file was found in path for module B. b.cmi +Warning 49 [no-cmi-file]: no valid cmi file was found in path for module B. b.cmi is not a compiled interface diff --git a/testsuite/tests/parsetree/locations_test.compilers.reference b/testsuite/tests/parsetree/locations_test.compilers.reference new file mode 100644 index 00000000..9b0ff79e --- /dev/null +++ b/testsuite/tests/parsetree/locations_test.compilers.reference @@ -0,0 +1,1103 @@ +Ptop_def + [ + structure_item (//toplevel//[10,215+0]..[10,215+39]) + Pstr_modtype "S" (//toplevel//[10,215+12]..[10,215+13]) + module_type (//toplevel//[10,215+16]..[10,215+23]) + attribute "attr" + [ + structure_item (//toplevel//[10,215+31]..[10,215+38]) + Pstr_eval + expression (//toplevel//[10,215+31]..[10,215+38]) + Pexp_ident "payload" (//toplevel//[10,215+31]..[10,215+38]) + ] + Pmty_signature + [] + ] + +module type S = sig end +Ptop_def + [ + structure_item (//toplevel//[3,2+0]..[3,2+37]) + Pstr_module + "M" (//toplevel//[3,2+7]..[3,2+8]) + module_expr (//toplevel//[3,2+11]..[3,2+21]) + attribute "attr" + [ + structure_item (//toplevel//[3,2+29]..[3,2+36]) + Pstr_eval + expression (//toplevel//[3,2+29]..[3,2+36]) + Pexp_ident "payload" (//toplevel//[3,2+29]..[3,2+36]) + ] + Pmod_structure + [] + ] + +module M : sig end +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+28]) + Pstr_type Rec + [ + type_declaration "t" (//toplevel//[2,1+5]..[2,1+6]) (//toplevel//[2,1+0]..[2,1+28]) + ptype_params = + [] + ptype_cstrs = + [] + ptype_kind = + Ptype_abstract + ptype_private = Public + ptype_manifest = + Some + core_type (//toplevel//[2,1+9]..[2,1+12]) + attribute "attr" + [ + structure_item (//toplevel//[2,1+20]..[2,1+27]) + Pstr_eval + expression (//toplevel//[2,1+20]..[2,1+27]) + Pexp_ident "payload" (//toplevel//[2,1+20]..[2,1+27]) + ] + Ptyp_constr "int" (//toplevel//[2,1+9]..[2,1+12]) + [] + ] + ] + +type t = int +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+1]) + Pstr_eval + expression (//toplevel//[2,1+0]..[2,1+1]) + attribute "attr" + [ + structure_item (//toplevel//[2,1+9]..[2,1+16]) + Pstr_eval + expression (//toplevel//[2,1+9]..[2,1+16]) + Pexp_ident "payload" (//toplevel//[2,1+9]..[2,1+16]) + ] + Pexp_constant PConst_int (3,None) + ] + +- : int = 3 +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+30]) + Pstr_exception + type_exception + attribute "attr" + [ + structure_item (//toplevel//[2,1+22]..[2,1+29]) + Pstr_eval + expression (//toplevel//[2,1+22]..[2,1+29]) + Pexp_ident "payload" (//toplevel//[2,1+22]..[2,1+29]) + ] + ptyext_constructor = + extension_constructor (//toplevel//[2,1+0]..[2,1+13]) + pext_name = "Exn" + pext_kind = + Pext_decl + [] + None + ] + +exception Exn +Ptop_def + [ + structure_item (//toplevel//[4,17+0]..[4,17+50]) + Pstr_modtype "F" (//toplevel//[4,17+12]..[4,17+13]) + module_type (//toplevel//[4,17+24]..[4,17+50]) + Pmty_functor "A" (//toplevel//[4,17+25]..[4,17+26]) + module_type (//toplevel//[4,17+29]..[4,17+30]) + Pmty_ident "S" (//toplevel//[4,17+29]..[4,17+30]) + module_type (//toplevel//[4,17+32]..[4,17+50]) + Pmty_functor "B" (//toplevel//[4,17+33]..[4,17+34]) + module_type (//toplevel//[4,17+37]..[4,17+38]) + Pmty_ident "S" (//toplevel//[4,17+37]..[4,17+38]) + module_type (//toplevel//[4,17+43]..[4,17+50]) + Pmty_signature + [] + ] + +module type F = functor (A : S) (B : S) -> sig end +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+48]) + Pstr_module + "F" (//toplevel//[2,1+7]..[2,1+8]) + module_expr (//toplevel//[2,1+19]..[2,1+48]) + Pmod_functor "A" (//toplevel//[2,1+20]..[2,1+21]) + module_type (//toplevel//[2,1+24]..[2,1+25]) + Pmty_ident "S" (//toplevel//[2,1+24]..[2,1+25]) + module_expr (//toplevel//[2,1+27]..[2,1+48]) + Pmod_functor "B" (//toplevel//[2,1+28]..[2,1+29]) + module_type (//toplevel//[2,1+32]..[2,1+33]) + Pmty_ident "S" (//toplevel//[2,1+32]..[2,1+33]) + module_expr (//toplevel//[2,1+38]..[2,1+48]) + Pmod_structure + [] + ] + +module F : functor (A : S) (B : S) -> sig end +Ptop_def + [ + structure_item (//toplevel//[4,18+0]..[4,18+31]) + Pstr_modtype "S1" (//toplevel//[4,18+12]..[4,18+14]) + module_type (//toplevel//[4,18+17]..[4,18+31]) + Pmty_signature + [ + signature_item (//toplevel//[4,18+21]..[4,18+27]) + Psig_type Rec + [ + type_declaration "t" (//toplevel//[4,18+26]..[4,18+27]) (//toplevel//[4,18+21]..[4,18+27]) + ptype_params = + [] + ptype_cstrs = + [] + ptype_kind = + Ptype_abstract + ptype_private = Public + ptype_manifest = + None + ] + ] + ] + +module type S1 = sig type t end +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+37]) + Pstr_modtype "T1" (//toplevel//[2,1+12]..[2,1+14]) + module_type (//toplevel//[2,1+17]..[2,1+37]) + Pmty_with + module_type (//toplevel//[2,1+17]..[2,1+19]) + Pmty_ident "S1" (//toplevel//[2,1+17]..[2,1+19]) + [ + Pwith_type "t" (//toplevel//[2,1+30]..[2,1+31]) + type_declaration "t" (//toplevel//[2,1+30]..[2,1+31]) (//toplevel//[2,1+25]..[2,1+37]) + ptype_params = + [] + ptype_cstrs = + [] + ptype_kind = + Ptype_abstract + ptype_private = Public + ptype_manifest = + Some + core_type (//toplevel//[2,1+34]..[2,1+37]) + Ptyp_constr "int" (//toplevel//[2,1+34]..[2,1+37]) + [] + ] + ] + +module type T1 = sig type t = int end +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+38]) + Pstr_modtype "T1" (//toplevel//[2,1+12]..[2,1+14]) + module_type (//toplevel//[2,1+17]..[2,1+38]) + Pmty_with + module_type (//toplevel//[2,1+17]..[2,1+19]) + Pmty_ident "S1" (//toplevel//[2,1+17]..[2,1+19]) + [ + Pwith_typesubst "t" (//toplevel//[2,1+30]..[2,1+31]) + type_declaration "t" (//toplevel//[2,1+30]..[2,1+31]) (//toplevel//[2,1+25]..[2,1+38]) + ptype_params = + [] + ptype_cstrs = + [] + ptype_kind = + Ptype_abstract + ptype_private = Public + ptype_manifest = + Some + core_type (//toplevel//[2,1+35]..[2,1+38]) + Ptyp_constr "int" (//toplevel//[2,1+35]..[2,1+38]) + [] + ] + ] + +module type T1 = sig end +Ptop_def + [ + structure_item (//toplevel//[4,29+0]..[4,29+15]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[4,29+4]..[4,29+11]) ghost + Ppat_constraint + pattern (//toplevel//[4,29+4]..[4,29+5]) + Ppat_var "x" (//toplevel//[4,29+4]..[4,29+5]) + core_type (//toplevel//[4,29+8]..[4,29+11]) ghost + Ptyp_poly + core_type (//toplevel//[4,29+8]..[4,29+11]) + Ptyp_constr "int" (//toplevel//[4,29+8]..[4,29+11]) + [] + expression (//toplevel//[4,29+4]..[4,29+15]) ghost + Pexp_constraint + expression (//toplevel//[4,29+14]..[4,29+15]) + Pexp_constant PConst_int (3,None) + core_type (//toplevel//[4,29+8]..[4,29+11]) + Ptyp_constr "int" (//toplevel//[4,29+8]..[4,29+11]) + [] + ] + ] + +val x : int = 3 +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+35]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[2,1+4]..[2,1+22]) ghost + Ppat_constraint + pattern (//toplevel//[2,1+4]..[2,1+5]) + Ppat_var "x" (//toplevel//[2,1+4]..[2,1+5]) + core_type (//toplevel//[2,1+4]..[2,1+35]) ghost + Ptyp_poly 'a + core_type (//toplevel//[2,1+16]..[2,1+22]) + Ptyp_arrow + Nolabel + core_type (//toplevel//[2,1+16]..[2,1+17]) + Ptyp_var a + core_type (//toplevel//[2,1+21]..[2,1+22]) + Ptyp_var a + expression (//toplevel//[2,1+4]..[2,1+35]) + Pexp_newtype "a" + expression (//toplevel//[2,1+4]..[2,1+35]) + Pexp_constraint + expression (//toplevel//[2,1+25]..[2,1+35]) + Pexp_fun + Nolabel + None + pattern (//toplevel//[2,1+29]..[2,1+30]) + Ppat_var "x" (//toplevel//[2,1+29]..[2,1+30]) + expression (//toplevel//[2,1+34]..[2,1+35]) + Pexp_ident "x" (//toplevel//[2,1+34]..[2,1+35]) + core_type (//toplevel//[2,1+16]..[2,1+22]) + Ptyp_arrow + Nolabel + core_type (//toplevel//[2,1+16]..[2,1+17]) + Ptyp_constr "a" (//toplevel//[2,1+16]..[2,1+17]) + [] + core_type (//toplevel//[2,1+21]..[2,1+22]) + Ptyp_constr "a" (//toplevel//[2,1+21]..[2,1+22]) + [] + ] + ] + +val x : 'a -> 'a = +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[5,61+3]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[2,1+4]..[2,1+5]) + Ppat_any + expression (//toplevel//[2,1+8]..[5,61+3]) + Pexp_object + class_structure + pattern (//toplevel//[2,1+14]..[2,1+14]) ghost + Ppat_any + [ + class_field (//toplevel//[3,16+2]..[4,46+14]) + Pcf_method Public + "x" (//toplevel//[3,16+9]..[3,16+10]) + Concrete Fresh + expression (//toplevel//[3,16+18]..[4,46+14]) ghost + Pexp_poly + expression (//toplevel//[3,16+9]..[4,46+14]) + Pexp_newtype "a" + expression (//toplevel//[3,16+9]..[4,46+14]) + Pexp_constraint + expression (//toplevel//[4,46+4]..[4,46+14]) + Pexp_fun + Nolabel + None + pattern (//toplevel//[4,46+8]..[4,46+9]) + Ppat_var "x" (//toplevel//[4,46+8]..[4,46+9]) + expression (//toplevel//[4,46+13]..[4,46+14]) + Pexp_ident "x" (//toplevel//[4,46+13]..[4,46+14]) + core_type (//toplevel//[3,16+21]..[3,16+27]) + Ptyp_arrow + Nolabel + core_type (//toplevel//[3,16+21]..[3,16+22]) + Ptyp_constr "a" (//toplevel//[3,16+21]..[3,16+22]) + [] + core_type (//toplevel//[3,16+26]..[3,16+27]) + Ptyp_constr "a" (//toplevel//[3,16+26]..[3,16+27]) + [] + Some + core_type (//toplevel//[3,16+9]..[4,46+14]) ghost + Ptyp_poly 'a + core_type (//toplevel//[3,16+21]..[3,16+27]) + Ptyp_arrow + Nolabel + core_type (//toplevel//[3,16+21]..[3,16+22]) + Ptyp_var a + core_type (//toplevel//[3,16+26]..[3,16+27]) + Ptyp_var a + ] + ] + ] + +- : < x : 'a. 'a -> 'a > = +Ptop_def + [ + structure_item (//toplevel//[4,17+0]..[4,17+29]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[4,17+4]..[4,17+5]) + Ppat_var "x" (//toplevel//[4,17+4]..[4,17+5]) + expression (//toplevel//[4,17+6]..[4,17+29]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[4,17+6]..[4,17+14]) + Ppat_var "contents" (//toplevel//[4,17+6]..[4,17+14]) + expression (//toplevel//[4,17+17]..[4,17+29]) + Pexp_record + [ + "contents" (//toplevel//[4,17+19]..[4,17+27]) + expression (//toplevel//[4,17+19]..[4,17+27]) ghost + Pexp_ident "contents" (//toplevel//[4,17+19]..[4,17+27]) ghost + ] + None + ] + ] + +val x : 'a -> 'a ref = +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+30]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[2,1+4]..[2,1+5]) + Ppat_var "x" (//toplevel//[2,1+4]..[2,1+5]) + expression (//toplevel//[2,1+8]..[2,1+30]) + Pexp_record + [ + "contents" (//toplevel//[2,1+10]..[2,1+18]) + expression (//toplevel//[2,1+10]..[2,1+28]) ghost + Pexp_constraint + expression (//toplevel//[2,1+27]..[2,1+28]) + Pexp_constant PConst_int (3,None) + core_type (//toplevel//[2,1+21]..[2,1+24]) + Ptyp_constr "int" (//toplevel//[2,1+21]..[2,1+24]) + [] + ] + None + ] + ] + +val x : int ref = {contents = 3} +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+35]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[2,1+4]..[2,1+5]) + Ppat_var "x" (//toplevel//[2,1+4]..[2,1+5]) + expression (//toplevel//[2,1+6]..[2,1+35]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[2,1+6]..[2,1+14]) + Ppat_var "contents" (//toplevel//[2,1+6]..[2,1+14]) + expression (//toplevel//[2,1+17]..[2,1+35]) + Pexp_record + [ + "contents" (//toplevel//[2,1+19]..[2,1+27]) + expression (//toplevel//[2,1+19]..[2,1+33]) ghost + Pexp_constraint + expression (//toplevel//[2,1+19]..[2,1+33]) ghost + Pexp_ident "contents" (//toplevel//[2,1+19]..[2,1+27]) ghost + core_type (//toplevel//[2,1+30]..[2,1+33]) + Ptyp_constr "int" (//toplevel//[2,1+30]..[2,1+33]) + [] + ] + None + ] + ] + +val x : int -> int ref = +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+41]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[2,1+4]..[2,1+5]) + Ppat_var "x" (//toplevel//[2,1+4]..[2,1+5]) + expression (//toplevel//[2,1+8]..[2,1+41]) + Pexp_function + [ + + pattern (//toplevel//[2,1+17]..[2,1+29]) + Ppat_record Closed + [ + "contents" (//toplevel//[2,1+19]..[2,1+27]) ghost + pattern (//toplevel//[2,1+19]..[2,1+27]) + Ppat_var "contents" (//toplevel//[2,1+19]..[2,1+27]) + ] + expression (//toplevel//[2,1+33]..[2,1+41]) + Pexp_ident "contents" (//toplevel//[2,1+33]..[2,1+41]) + ] + ] + ] + +val x : 'a ref -> 'a = +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+47]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[2,1+4]..[2,1+5]) + Ppat_var "x" (//toplevel//[2,1+4]..[2,1+5]) + expression (//toplevel//[2,1+8]..[2,1+47]) + Pexp_function + [ + + pattern (//toplevel//[2,1+17]..[2,1+35]) + Ppat_record Closed + [ + "contents" (//toplevel//[2,1+19]..[2,1+27]) ghost + pattern (//toplevel//[2,1+19]..[2,1+33]) ghost + Ppat_constraint + pattern (//toplevel//[2,1+19]..[2,1+27]) + Ppat_var "contents" (//toplevel//[2,1+19]..[2,1+27]) + core_type (//toplevel//[2,1+30]..[2,1+33]) + Ptyp_constr "int" (//toplevel//[2,1+30]..[2,1+33]) + [] + ] + expression (//toplevel//[2,1+39]..[2,1+47]) + Pexp_ident "contents" (//toplevel//[2,1+39]..[2,1+47]) + ] + ] + ] + +val x : int ref -> int = +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+44]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[2,1+4]..[2,1+5]) + Ppat_var "x" (//toplevel//[2,1+4]..[2,1+5]) + expression (//toplevel//[2,1+8]..[2,1+44]) + Pexp_function + [ + + pattern (//toplevel//[2,1+17]..[2,1+39]) + Ppat_record Closed + [ + "contents" (//toplevel//[2,1+19]..[2,1+27]) + pattern (//toplevel//[2,1+19]..[2,1+37]) ghost + Ppat_constraint + pattern (//toplevel//[2,1+36]..[2,1+37]) + Ppat_var "i" (//toplevel//[2,1+36]..[2,1+37]) + core_type (//toplevel//[2,1+30]..[2,1+33]) + Ptyp_constr "int" (//toplevel//[2,1+30]..[2,1+33]) + [] + ] + expression (//toplevel//[2,1+43]..[2,1+44]) + Pexp_ident "i" (//toplevel//[2,1+43]..[2,1+44]) + ] + ] + ] + +val x : int ref -> int = +Ptop_def + [ + structure_item (//toplevel//[4,19+0]..[4,19+26]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[4,19+4]..[4,19+5]) + Ppat_var "x" (//toplevel//[4,19+4]..[4,19+5]) + expression (//toplevel//[4,19+8]..[4,19+26]) + Pexp_open Fresh + module_expr (//toplevel//[4,19+8]..[4,19+9]) + Pmod_ident "M" (//toplevel//[4,19+8]..[4,19+9]) + expression (//toplevel//[4,19+10]..[4,19+26]) + Pexp_record + [ + "contents" (//toplevel//[4,19+12]..[4,19+20]) + expression (//toplevel//[4,19+23]..[4,19+24]) + Pexp_constant PConst_int (3,None) + ] + None + ] + ] + +val x : int ref = {contents = 3} +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+18]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[2,1+4]..[2,1+5]) + Ppat_var "x" (//toplevel//[2,1+4]..[2,1+5]) + expression (//toplevel//[2,1+8]..[2,1+18]) + Pexp_open Fresh + module_expr (//toplevel//[2,1+8]..[2,1+9]) + Pmod_ident "M" (//toplevel//[2,1+8]..[2,1+9]) + expression (//toplevel//[2,1+10]..[2,1+18]) + Pexp_construct "::" (//toplevel//[2,1+12]..[2,1+18]) ghost + Some + expression (//toplevel//[2,1+12]..[2,1+18]) ghost + Pexp_tuple + [ + expression (//toplevel//[2,1+12]..[2,1+13]) + Pexp_constant PConst_int (3,None) + expression (//toplevel//[2,1+15]..[2,1+18]) ghost + Pexp_construct "::" (//toplevel//[2,1+15]..[2,1+18]) ghost + Some + expression (//toplevel//[2,1+15]..[2,1+18]) ghost + Pexp_tuple + [ + expression (//toplevel//[2,1+15]..[2,1+16]) + Pexp_constant PConst_int (4,None) + expression (//toplevel//[2,1+17]..[2,1+18]) ghost + Pexp_construct "[]" (//toplevel//[2,1+17]..[2,1+18]) ghost + None + ] + ] + ] + ] + +val x : int list = [3; 4] +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+18]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[2,1+4]..[2,1+5]) + Ppat_var "x" (//toplevel//[2,1+4]..[2,1+5]) + expression (//toplevel//[2,1+8]..[2,1+18]) + Pexp_open Fresh + module_expr (//toplevel//[2,1+8]..[2,1+9]) + Pmod_ident "M" (//toplevel//[2,1+8]..[2,1+9]) + expression (//toplevel//[2,1+12]..[2,1+16]) + Pexp_sequence + expression (//toplevel//[2,1+12]..[2,1+13]) + Pexp_constant PConst_int (3,None) + expression (//toplevel//[2,1+15]..[2,1+16]) + Pexp_constant PConst_int (4,None) + ] + ] + +Line 2, characters 12-13: +2 | let x = M.( 3; 4 );; + ^ +Warning 10 [non-unit-statement]: this expression should have type unit. +val x : int = 4 +Ptop_def + [ + structure_item (//toplevel//[6,56+0]..[6,56+24]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[6,56+4]..[6,56+12]) + Ppat_var ".@()" (//toplevel//[6,56+4]..[6,56+12]) + expression (//toplevel//[6,56+13]..[6,56+24]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[6,56+13]..[6,56+14]) + Ppat_var "x" (//toplevel//[6,56+13]..[6,56+14]) + expression (//toplevel//[6,56+15]..[6,56+24]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[6,56+15]..[6,56+16]) + Ppat_var "y" (//toplevel//[6,56+15]..[6,56+16]) + expression (//toplevel//[6,56+19]..[6,56+24]) + Pexp_apply + expression (//toplevel//[6,56+21]..[6,56+22]) + Pexp_ident "+" (//toplevel//[6,56+21]..[6,56+22]) + [ + + Nolabel + expression (//toplevel//[6,56+19]..[6,56+20]) + Pexp_ident "x" (//toplevel//[6,56+19]..[6,56+20]) + + Nolabel + expression (//toplevel//[6,56+23]..[6,56+24]) + Pexp_ident "y" (//toplevel//[6,56+23]..[6,56+24]) + ] + ] + structure_item (//toplevel//[7,81+0]..[7,81+32]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[7,81+4]..[7,81+14]) + Ppat_var ".@()<-" (//toplevel//[7,81+4]..[7,81+14]) + expression (//toplevel//[7,81+15]..[7,81+32]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[7,81+15]..[7,81+16]) + Ppat_var "x" (//toplevel//[7,81+15]..[7,81+16]) + expression (//toplevel//[7,81+17]..[7,81+32]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[7,81+17]..[7,81+18]) + Ppat_var "y" (//toplevel//[7,81+17]..[7,81+18]) + expression (//toplevel//[7,81+19]..[7,81+32]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[7,81+19]..[7,81+20]) + Ppat_var "z" (//toplevel//[7,81+19]..[7,81+20]) + expression (//toplevel//[7,81+23]..[7,81+32]) + Pexp_apply + expression (//toplevel//[7,81+29]..[7,81+30]) + Pexp_ident "+" (//toplevel//[7,81+29]..[7,81+30]) + [ + + Nolabel + expression (//toplevel//[7,81+23]..[7,81+28]) + Pexp_apply + expression (//toplevel//[7,81+25]..[7,81+26]) + Pexp_ident "+" (//toplevel//[7,81+25]..[7,81+26]) + [ + + Nolabel + expression (//toplevel//[7,81+23]..[7,81+24]) + Pexp_ident "x" (//toplevel//[7,81+23]..[7,81+24]) + + Nolabel + expression (//toplevel//[7,81+27]..[7,81+28]) + Pexp_ident "y" (//toplevel//[7,81+27]..[7,81+28]) + ] + + Nolabel + expression (//toplevel//[7,81+31]..[7,81+32]) + Pexp_ident "z" (//toplevel//[7,81+31]..[7,81+32]) + ] + ] + structure_item (//toplevel//[8,114+0]..[8,114+25]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[8,114+4]..[8,114+13]) + Ppat_var ".%.{}" (//toplevel//[8,114+4]..[8,114+13]) + expression (//toplevel//[8,114+14]..[8,114+25]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[8,114+14]..[8,114+15]) + Ppat_var "x" (//toplevel//[8,114+14]..[8,114+15]) + expression (//toplevel//[8,114+16]..[8,114+25]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[8,114+16]..[8,114+17]) + Ppat_var "y" (//toplevel//[8,114+16]..[8,114+17]) + expression (//toplevel//[8,114+20]..[8,114+25]) + Pexp_apply + expression (//toplevel//[8,114+22]..[8,114+23]) + Pexp_ident "+" (//toplevel//[8,114+22]..[8,114+23]) + [ + + Nolabel + expression (//toplevel//[8,114+20]..[8,114+21]) + Pexp_ident "x" (//toplevel//[8,114+20]..[8,114+21]) + + Nolabel + expression (//toplevel//[8,114+24]..[8,114+25]) + Pexp_ident "y" (//toplevel//[8,114+24]..[8,114+25]) + ] + ] + structure_item (//toplevel//[9,140+0]..[9,140+33]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[9,140+4]..[9,140+15]) + Ppat_var ".%.{}<-" (//toplevel//[9,140+4]..[9,140+15]) + expression (//toplevel//[9,140+16]..[9,140+33]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[9,140+16]..[9,140+17]) + Ppat_var "x" (//toplevel//[9,140+16]..[9,140+17]) + expression (//toplevel//[9,140+18]..[9,140+33]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[9,140+18]..[9,140+19]) + Ppat_var "y" (//toplevel//[9,140+18]..[9,140+19]) + expression (//toplevel//[9,140+20]..[9,140+33]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[9,140+20]..[9,140+21]) + Ppat_var "z" (//toplevel//[9,140+20]..[9,140+21]) + expression (//toplevel//[9,140+24]..[9,140+33]) + Pexp_apply + expression (//toplevel//[9,140+30]..[9,140+31]) + Pexp_ident "+" (//toplevel//[9,140+30]..[9,140+31]) + [ + + Nolabel + expression (//toplevel//[9,140+24]..[9,140+29]) + Pexp_apply + expression (//toplevel//[9,140+26]..[9,140+27]) + Pexp_ident "+" (//toplevel//[9,140+26]..[9,140+27]) + [ + + Nolabel + expression (//toplevel//[9,140+24]..[9,140+25]) + Pexp_ident "x" (//toplevel//[9,140+24]..[9,140+25]) + + Nolabel + expression (//toplevel//[9,140+28]..[9,140+29]) + Pexp_ident "y" (//toplevel//[9,140+28]..[9,140+29]) + ] + + Nolabel + expression (//toplevel//[9,140+32]..[9,140+33]) + Pexp_ident "z" (//toplevel//[9,140+32]..[9,140+33]) + ] + ] + structure_item (//toplevel//[10,174+0]..[10,174+25]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[10,174+4]..[10,174+13]) + Ppat_var ".%.[]" (//toplevel//[10,174+4]..[10,174+13]) + expression (//toplevel//[10,174+14]..[10,174+25]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[10,174+14]..[10,174+15]) + Ppat_var "x" (//toplevel//[10,174+14]..[10,174+15]) + expression (//toplevel//[10,174+16]..[10,174+25]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[10,174+16]..[10,174+17]) + Ppat_var "y" (//toplevel//[10,174+16]..[10,174+17]) + expression (//toplevel//[10,174+20]..[10,174+25]) + Pexp_apply + expression (//toplevel//[10,174+22]..[10,174+23]) + Pexp_ident "+" (//toplevel//[10,174+22]..[10,174+23]) + [ + + Nolabel + expression (//toplevel//[10,174+20]..[10,174+21]) + Pexp_ident "x" (//toplevel//[10,174+20]..[10,174+21]) + + Nolabel + expression (//toplevel//[10,174+24]..[10,174+25]) + Pexp_ident "y" (//toplevel//[10,174+24]..[10,174+25]) + ] + ] + structure_item (//toplevel//[11,200+0]..[11,200+33]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[11,200+4]..[11,200+15]) + Ppat_var ".%.[]<-" (//toplevel//[11,200+4]..[11,200+15]) + expression (//toplevel//[11,200+16]..[11,200+33]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[11,200+16]..[11,200+17]) + Ppat_var "x" (//toplevel//[11,200+16]..[11,200+17]) + expression (//toplevel//[11,200+18]..[11,200+33]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[11,200+18]..[11,200+19]) + Ppat_var "y" (//toplevel//[11,200+18]..[11,200+19]) + expression (//toplevel//[11,200+20]..[11,200+33]) ghost + Pexp_fun + Nolabel + None + pattern (//toplevel//[11,200+20]..[11,200+21]) + Ppat_var "z" (//toplevel//[11,200+20]..[11,200+21]) + expression (//toplevel//[11,200+24]..[11,200+33]) + Pexp_apply + expression (//toplevel//[11,200+30]..[11,200+31]) + Pexp_ident "+" (//toplevel//[11,200+30]..[11,200+31]) + [ + + Nolabel + expression (//toplevel//[11,200+24]..[11,200+29]) + Pexp_apply + expression (//toplevel//[11,200+26]..[11,200+27]) + Pexp_ident "+" (//toplevel//[11,200+26]..[11,200+27]) + [ + + Nolabel + expression (//toplevel//[11,200+24]..[11,200+25]) + Pexp_ident "x" (//toplevel//[11,200+24]..[11,200+25]) + + Nolabel + expression (//toplevel//[11,200+28]..[11,200+29]) + Pexp_ident "y" (//toplevel//[11,200+28]..[11,200+29]) + ] + + Nolabel + expression (//toplevel//[11,200+32]..[11,200+33]) + Pexp_ident "z" (//toplevel//[11,200+32]..[11,200+33]) + ] + ] + ] + +val ( .@() ) : int -> int -> int = +val ( .@()<- ) : int -> int -> int -> int = +val ( .%.{} ) : int -> int -> int = +val ( .%.{}<- ) : int -> int -> int -> int = +val ( .%.[] ) : int -> int -> int = +val ( .%.[]<- ) : int -> int -> int -> int = +Ptop_def + [ + structure_item (//toplevel//[4,27+0]..[4,27+6]) + Pstr_eval + expression (//toplevel//[4,27+0]..[4,27+6]) + Pexp_apply + expression (//toplevel//[4,27+0]..[4,27+6]) ghost + Pexp_ident ".@()" (//toplevel//[4,27+0]..[4,27+6]) ghost + [ + + Nolabel + expression (//toplevel//[4,27+0]..[4,27+1]) + Pexp_ident "x" (//toplevel//[4,27+0]..[4,27+1]) + + Nolabel + expression (//toplevel//[4,27+4]..[4,27+5]) + Pexp_constant PConst_int (4,None) + ] + ] + +- : int = 8 +Ptop_def + [ + structure_item (//toplevel//[1,0+0]..[1,0+11]) + Pstr_eval + expression (//toplevel//[1,0+0]..[1,0+11]) + Pexp_apply + expression (//toplevel//[1,0+0]..[1,0+11]) ghost + Pexp_ident ".@()<-" (//toplevel//[1,0+0]..[1,0+11]) ghost + [ + + Nolabel + expression (//toplevel//[1,0+0]..[1,0+1]) + Pexp_ident "x" (//toplevel//[1,0+0]..[1,0+1]) + + Nolabel + expression (//toplevel//[1,0+4]..[1,0+5]) + Pexp_constant PConst_int (4,None) + + Nolabel + expression (//toplevel//[1,0+10]..[1,0+11]) + Pexp_constant PConst_int (4,None) + ] + ] + +- : int = 12 +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+7]) + Pstr_eval + expression (//toplevel//[2,1+0]..[2,1+7]) + Pexp_apply + expression (//toplevel//[2,1+0]..[2,1+7]) ghost + Pexp_ident ".%.{}" (//toplevel//[2,1+0]..[2,1+7]) ghost + [ + + Nolabel + expression (//toplevel//[2,1+0]..[2,1+1]) + Pexp_ident "x" (//toplevel//[2,1+0]..[2,1+1]) + + Nolabel + expression (//toplevel//[2,1+5]..[2,1+6]) + Pexp_constant PConst_int (4,None) + ] + ] + +- : int = 8 +Ptop_def + [ + structure_item (//toplevel//[1,0+0]..[1,0+12]) + Pstr_eval + expression (//toplevel//[1,0+0]..[1,0+12]) + Pexp_apply + expression (//toplevel//[1,0+0]..[1,0+12]) ghost + Pexp_ident ".%.{}<-" (//toplevel//[1,0+0]..[1,0+12]) ghost + [ + + Nolabel + expression (//toplevel//[1,0+0]..[1,0+1]) + Pexp_ident "x" (//toplevel//[1,0+0]..[1,0+1]) + + Nolabel + expression (//toplevel//[1,0+5]..[1,0+6]) + Pexp_constant PConst_int (4,None) + + Nolabel + expression (//toplevel//[1,0+11]..[1,0+12]) + Pexp_constant PConst_int (4,None) + ] + ] + +- : int = 12 +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[2,1+7]) + Pstr_eval + expression (//toplevel//[2,1+0]..[2,1+7]) + Pexp_apply + expression (//toplevel//[2,1+0]..[2,1+7]) ghost + Pexp_ident ".%.[]" (//toplevel//[2,1+0]..[2,1+7]) ghost + [ + + Nolabel + expression (//toplevel//[2,1+0]..[2,1+1]) + Pexp_ident "x" (//toplevel//[2,1+0]..[2,1+1]) + + Nolabel + expression (//toplevel//[2,1+5]..[2,1+6]) + Pexp_constant PConst_int (4,None) + ] + ] + +- : int = 8 +Ptop_def + [ + structure_item (//toplevel//[1,0+0]..[1,0+12]) + Pstr_eval + expression (//toplevel//[1,0+0]..[1,0+12]) + Pexp_apply + expression (//toplevel//[1,0+0]..[1,0+12]) ghost + Pexp_ident ".%.[]<-" (//toplevel//[1,0+0]..[1,0+12]) ghost + [ + + Nolabel + expression (//toplevel//[1,0+0]..[1,0+1]) + Pexp_ident "x" (//toplevel//[1,0+0]..[1,0+1]) + + Nolabel + expression (//toplevel//[1,0+5]..[1,0+6]) + Pexp_constant PConst_int (4,None) + + Nolabel + expression (//toplevel//[1,0+11]..[1,0+12]) + Pexp_constant PConst_int (4,None) + ] + ] + +- : int = 12 +Ptop_def + [ + structure_item (//toplevel//[4,28+0]..[4,28+37]) + Pstr_value Nonrec + [ + + pattern (//toplevel//[4,28+4]..[4,28+5]) + Ppat_var "f" (//toplevel//[4,28+4]..[4,28+5]) + expression (//toplevel//[4,28+8]..[4,28+37]) + Pexp_function + [ + + pattern (//toplevel//[4,28+17]..[4,28+31]) + Ppat_constraint + pattern (//toplevel//[4,28+25]..[4,28+26]) + Ppat_unpack "M" (//toplevel//[4,28+25]..[4,28+26]) + core_type (//toplevel//[4,28+29]..[4,28+30]) + Ptyp_package "S" (//toplevel//[4,28+29]..[4,28+30]) + [] + expression (//toplevel//[4,28+35]..[4,28+37]) + Pexp_construct "()" (//toplevel//[4,28+35]..[4,28+37]) + None + ] + ] + ] + +val f : (module S) -> unit = +Ptop_def + [ + structure_item (//toplevel//[4,45+0]..[6,71+12]) + Pstr_class + [ + class_declaration (//toplevel//[4,45+0]..[6,71+12]) + pci_virt = Concrete + pci_params = + [] + pci_name = "c" (//toplevel//[4,45+6]..[4,45+7]) + pci_expr = + class_expr (//toplevel//[5,55+2]..[6,71+12]) + Pcl_open Fresh "M" (//toplevel//[5,55+11]..[5,55+12]) + class_expr (//toplevel//[6,71+2]..[6,71+12]) + Pcl_structure + class_structure + pattern (//toplevel//[6,71+8]..[6,71+8]) ghost + Ppat_any + [] + ] + ] + +class c : object end +Ptop_def + [ + structure_item (//toplevel//[2,1+0]..[4,33+12]) + Pstr_class_type + [ + class_type_declaration (//toplevel//[2,1+0]..[4,33+12]) + pci_virt = Concrete + pci_params = + [] + pci_name = "ct" (//toplevel//[2,1+11]..[2,1+13]) + pci_expr = + class_type (//toplevel//[3,17+2]..[4,33+12]) + Pcty_open Fresh "M" (//toplevel//[3,17+11]..[3,17+12]) + class_type (//toplevel//[4,33+2]..[4,33+12]) + Pcty_signature + class_signature + core_type (//toplevel//[4,33+8]..[4,33+8]) + Ptyp_any + [] + ] + ] + +class type ct = object end +Ptop_def + [ + structure_item (//toplevel//[5,56+0]..[6,64+4]) + Pstr_value Nonrec + [ + + attribute "ocaml.doc" + [ + structure_item (//toplevel//[4,19+0]..[4,19+36]) + Pstr_eval + expression (//toplevel//[4,19+0]..[4,19+36]) + Pexp_constant PConst_string(" Some docstring attached to x. ",(//toplevel//[4,19+0]..[4,19+36]),None) + ] + attribute "ocaml.doc" + [ + structure_item (//toplevel//[7,69+0]..[7,69+39]) + Pstr_eval + expression (//toplevel//[7,69+0]..[7,69+39]) + Pexp_constant PConst_string(" Another docstring attached to x. ",(//toplevel//[7,69+0]..[7,69+39]),None) + ] + pattern (//toplevel//[5,56+4]..[5,56+5]) + Ppat_var "x" (//toplevel//[5,56+4]..[5,56+5]) + expression (//toplevel//[6,64+2]..[6,64+4]) + Pexp_constant PConst_int (42,None) + ] + ] + +val x : int = 42 + diff --git a/testsuite/tests/parsetree/locations_test.ml b/testsuite/tests/parsetree/locations_test.ml new file mode 100644 index 00000000..6ed67eb4 --- /dev/null +++ b/testsuite/tests/parsetree/locations_test.ml @@ -0,0 +1,112 @@ +(* TEST + flags = "-dparsetree" + * toplevel *) + +(* Using a toplevel test and not an expect test, because the locs get shifted + by the expect blocks and the output is therefore not stable. *) + +(* Attributes *) + +module type S = sig end [@attr payload];; + + +module M = struct end [@attr payload];; + +type t = int [@attr payload];; + +3 [@attr payload];; + +exception Exn [@@attr payload];; + +(* Functors *) + +module type F = functor (A : S) (B : S) -> sig end;; + +module F = functor (A : S) (B : S) -> struct end;; + +(* with type *) + +module type S1 = sig type t end;; + +module type T1 = S1 with type t = int;; + +module type T1 = S1 with type t := int;; + +(* Constrained bindings *) + +let x : int = 3;; + +let x : type a. a -> a = fun x -> x;; + +let _ = object + method x : type a. a -> a = + fun x -> x +end;; + +(* Punning. *) + +let x contents = { contents };; + +let x = { contents : int = 3 };; + +let x contents = { contents : int };; + +let x = function { contents } -> contents;; + +let x = function { contents : int } -> contents;; + +let x = function { contents : int = i } -> i;; + +(* Local open *) + +let x = M.{ contents = 3 };; + +let x = M.[ 3; 4 ];; + +let x = M.( 3; 4 );; + +(* Indexing operators *) + + (* some prerequisites. *) + +let ( .@() ) x y = x + y +let ( .@()<- ) x y z = x + y + z +let ( .%.{} ) x y = x + y +let ( .%.{}<- ) x y z = x + y + z +let ( .%.[] ) x y = x + y +let ( .%.[]<- ) x y z = x + y + z;; + + (* the actual issue *) + +x.@(4);; +x.@(4) <- 4;; + +x.%.{4};; +x.%.{4} <- 4;; + +x.%.[4];; +x.%.[4] <- 4;; + +(* Constrained unpacks *) + +let f = function (module M : S) -> ();; + +(* local opens in class and class types *) + +class c = + let open M in + object end +;; + +class type ct = + let open M in + object end +;; + +(* Docstrings *) + +(** Some docstring attached to x. *) +let x = + 42 +(** Another docstring attached to x. *) +;; diff --git a/testsuite/tests/parsetree/source.ml b/testsuite/tests/parsetree/source.ml index 93a0d263..af7bc580 100644 --- a/testsuite/tests/parsetree/source.ml +++ b/testsuite/tests/parsetree/source.ml @@ -171,11 +171,14 @@ and[@foo] y = x type%foo[@foo] t = int and[@foo] t = int type%foo[@foo] t += T +type t += A = M.A[@a] +type t += B = M.A[@b] | C = M.A[@c][@@t] class%foo[@foo] x = x class type%foo[@foo] x = x external%foo[@foo] x : _ = "" exception%foo[@foo] X +exception A = M.A[@a] module%foo[@foo] M = M module%foo[@foo] rec M : S = M @@ -7372,3 +7375,42 @@ let f = function let () = f (fun (type t) -> x) + +(* #9778 *) + +type t = unit + +let rec equal : 'a. ('a -> 'a -> bool) -> 'a t -> 'a t -> bool = + (fun poly_a (_ : unit) (_ : unit) -> true) [@ocaml.warning "-A"] + [@@ocaml.warning "-39"] + +(* Issue #9548, PR #9591 *) + +type u = [ `A ] ;; +type v = [ u | `B ] ;; +let f = fun (x : [ | u ]) -> x ;; + +(* Issue #9999 *) +let test = function + | `A | `B as x -> ignore x + +let test = function + | `A as x | (`B as x) -> ignore x + +let test = function + | `A as x | (`B as x) as z -> ignore (z, x) + +let test = function + | (`A as x) | (`B as x) as z -> ignore (z, x) + +let test = function + | (`A | `B) | `C -> () + +let test = function + | `A | (`B | `C) -> () + +let test = function + | `A | `B | `C -> () + +let test = function + | (`A | `B) as x | `C -> () diff --git a/testsuite/tests/parsing/attributes.compilers.reference b/testsuite/tests/parsing/attributes.compilers.reference index 30f1620e..4f222027 100644 --- a/testsuite/tests/parsing/attributes.compilers.reference +++ b/testsuite/tests/parsing/attributes.compilers.reference @@ -5,7 +5,7 @@ attribute "foo" [] ptyext_constructor = - extension_constructor (attributes.ml[8,120+0]..[8,120+28]) + extension_constructor (attributes.ml[8,120+0]..[8,120+20]) attribute "foo" [] pext_name = "Foo" @@ -19,7 +19,7 @@ attribute "foo" [] ptyext_constructor = - extension_constructor (attributes.ml[10,150+0]..[10,150+44]) + extension_constructor (attributes.ml[10,150+0]..[10,150+36]) attribute "foo" [] pext_name = "Bar" @@ -150,7 +150,7 @@ attribute "foo" [] ptyext_constructor = - extension_constructor (attributes.ml[37,450+2]..[37,450+46]) + extension_constructor (attributes.ml[37,450+2]..[37,450+38]) attribute "foo" [] pext_name = "Bar" @@ -203,5 +203,106 @@ structure_item (attributes.ml[47,610+0]..[47,610+8]) Pstr_attribute "foo" [] + structure_item (attributes.ml[49,620+0]..[49,620+30]) + Pstr_modtype "T" (attributes.ml[49,620+12]..[49,620+13]) + module_type (attributes.ml[49,620+16]..[49,620+30]) + Pmty_signature + [ + signature_item (attributes.ml[49,620+20]..[49,620+26]) + Psig_type Rec + [ + type_declaration "t" (attributes.ml[49,620+25]..[49,620+26]) (attributes.ml[49,620+20]..[49,620+26]) + ptype_params = + [] + ptype_cstrs = + [] + ptype_kind = + Ptype_abstract + ptype_private = Public + ptype_manifest = + None + ] + ] + structure_item (attributes.ml[51,652+0]..[51,652+27]) + Pstr_module + "_" (attributes.ml[51,652+7]..[51,652+8]) + module_expr (attributes.ml[51,652+11]..[51,652+27]) + Pmod_constraint + module_expr (attributes.ml[51,652+12]..[51,652+15]) + Pmod_ident "Int" (attributes.ml[51,652+12]..[51,652+15]) + module_type (attributes.ml[51,652+18]..[51,652+19]) + attribute "foo" + [] + Pmty_ident "T" (attributes.ml[51,652+18]..[51,652+19]) + structure_item (attributes.ml[53,681+0]..[53,681+45]) + Pstr_module + "_" (attributes.ml[53,681+7]..[53,681+8]) + module_expr (attributes.ml[53,681+11]..[53,681+45]) + Pmod_constraint + module_expr (attributes.ml[53,681+12]..[53,681+15]) + Pmod_ident "Int" (attributes.ml[53,681+12]..[53,681+15]) + module_type (attributes.ml[53,681+18]..[53,681+37]) + attribute "foo" + [] + Pmty_with + module_type (attributes.ml[53,681+18]..[53,681+19]) + Pmty_ident "T" (attributes.ml[53,681+18]..[53,681+19]) + [ + Pwith_type "t" (attributes.ml[53,681+30]..[53,681+31]) + type_declaration "t" (attributes.ml[53,681+30]..[53,681+31]) (attributes.ml[53,681+25]..[53,681+37]) + ptype_params = + [] + ptype_cstrs = + [] + ptype_kind = + Ptype_abstract + ptype_private = Public + ptype_manifest = + Some + core_type (attributes.ml[53,681+34]..[53,681+37]) + Ptyp_constr "int" (attributes.ml[53,681+34]..[53,681+37]) + [] + ] + structure_item (attributes.ml[55,728+0]..[55,728+31]) + Pstr_value Nonrec + [ + + pattern (attributes.ml[55,728+4]..[55,728+5]) + Ppat_any + expression (attributes.ml[55,728+8]..[55,728+31]) + Pexp_constraint + expression (attributes.ml[55,728+8]..[55,728+31]) ghost + Pexp_pack + module_expr (attributes.ml[55,728+16]..[55,728+19]) + Pmod_ident "Int" (attributes.ml[55,728+16]..[55,728+19]) + core_type (attributes.ml[55,728+22]..[55,728+30]) + attribute "foo" + [] + Ptyp_package "T" (attributes.ml[55,728+22]..[55,728+23]) + [] + ] + structure_item (attributes.ml[57,761+0]..[57,761+49]) + Pstr_value Nonrec + [ + + pattern (attributes.ml[57,761+4]..[57,761+5]) + Ppat_any + expression (attributes.ml[57,761+8]..[57,761+49]) + Pexp_constraint + expression (attributes.ml[57,761+8]..[57,761+49]) ghost + Pexp_pack + module_expr (attributes.ml[57,761+16]..[57,761+19]) + Pmod_ident "Int" (attributes.ml[57,761+16]..[57,761+19]) + core_type (attributes.ml[57,761+22]..[57,761+48]) + attribute "foo" + [] + Ptyp_package "T" (attributes.ml[57,761+22]..[57,761+23]) + [ + with type "t" (attributes.ml[57,761+34]..[57,761+35]) + core_type (attributes.ml[57,761+38]..[57,761+41]) + Ptyp_constr "int" (attributes.ml[57,761+38]..[57,761+41]) + [] + ] + ] ] diff --git a/testsuite/tests/parsing/attributes.ml b/testsuite/tests/parsing/attributes.ml index b89df9ca..14a00083 100644 --- a/testsuite/tests/parsing/attributes.ml +++ b/testsuite/tests/parsing/attributes.ml @@ -45,3 +45,13 @@ end[@foo] [@@foo] [@@@foo] + +module type T = sig type t end + +module _ = (Int : T [@foo]) + +module _ = (Int : T with type t = int [@foo]) + +let _ = (module Int : T [@foo]) + +let _ = (module Int : T with type t = int [@foo]) diff --git a/testsuite/tests/parsing/extension_operators.ml b/testsuite/tests/parsing/extension_operators.ml new file mode 100644 index 00000000..683ec595 --- /dev/null +++ b/testsuite/tests/parsing/extension_operators.ml @@ -0,0 +1,67 @@ +(* TEST + * expect +*) + +let f o x = o##x;; +[%%expect {| +Line 1, characters 13-15: +1 | let f o x = o##x;; + ^^ +Error: '##' is not a valid value identifier. +|}] + +let f x = !#x +[%%expect {| +Line 1, characters 10-12: +1 | let f x = !#x + ^^ +Error: '!#' is not a valid value identifier. +|}] + +let f x = ?#x +[%%expect {| +Line 1, characters 10-12: +1 | let f x = ?#x + ^^ +Error: '?#' is not a valid value identifier. +|}] + +let f x = ~#x +[%%expect {| +Line 1, characters 10-12: +1 | let f x = ~#x + ^^ +Error: '~#' is not a valid value identifier. +|}] + +let f o x = o#-#x +[%%expect {| +Line 1, characters 13-16: +1 | let f o x = o#-#x + ^^^ +Error: '#-#' is not a valid value identifier. +|}] + +let f x = !-#x +[%%expect {| +Line 1, characters 10-13: +1 | let f x = !-#x + ^^^ +Error: '!-#' is not a valid value identifier. +|}] + +let f x = ?-#x +[%%expect {| +Line 1, characters 10-13: +1 | let f x = ?-#x + ^^^ +Error: '?-#' is not a valid value identifier. +|}] + +let f x = ~-#x +[%%expect {| +Line 1, characters 10-13: +1 | let f x = ~-#x + ^^^ +Error: '~-#' is not a valid value identifier. +|}] diff --git a/testsuite/tests/parsing/extensions.compilers.reference b/testsuite/tests/parsing/extensions.compilers.reference index 31850eb2..1d8a29bf 100644 --- a/testsuite/tests/parsing/extensions.compilers.reference +++ b/testsuite/tests/parsing/extensions.compilers.reference @@ -234,7 +234,7 @@ pattern (extensions.ml[20,445+54]..[20,445+59]) Ppat_record Closed [ - "x" (extensions.ml[20,445+56]..[20,445+57]) + "x" (extensions.ml[20,445+56]..[20,445+57]) ghost pattern (extensions.ml[20,445+56]..[20,445+57]) Ppat_var "x" (extensions.ml[20,445+56]..[20,445+57]) ] diff --git a/testsuite/tests/parsing/shortcut_ext_attr.compilers.reference b/testsuite/tests/parsing/shortcut_ext_attr.compilers.reference index 414aa824..d389cefd 100644 --- a/testsuite/tests/parsing/shortcut_ext_attr.compilers.reference +++ b/testsuite/tests/parsing/shortcut_ext_attr.compilers.reference @@ -510,7 +510,7 @@ structure_item (shortcut_ext_attr.ml[64,1353+0]..[67,1409+22]) Pstr_module "M" (shortcut_ext_attr.ml[64,1353+7]..[64,1353+8]) - module_expr (shortcut_ext_attr.ml[65,1364+2]..[67,1409+22]) + module_expr (shortcut_ext_attr.ml[65,1364+16]..[67,1409+22]) attribute "foo" [] Pmod_functor "M" (shortcut_ext_attr.ml[65,1364+17]..[65,1364+18]) @@ -531,7 +531,7 @@ [] structure_item (shortcut_ext_attr.ml[70,1462+0]..[73,1535+19]) Pstr_modtype "S" (shortcut_ext_attr.ml[70,1462+12]..[70,1462+13]) - module_type (shortcut_ext_attr.ml[71,1478+2]..[73,1535+19]) + module_type (shortcut_ext_attr.ml[71,1478+16]..[73,1535+19]) attribute "foo" [] Pmty_functor "M" (shortcut_ext_attr.ml[71,1478+17]..[71,1478+18]) diff --git a/testsuite/tests/printing-types/disambiguation.ml b/testsuite/tests/printing-types/disambiguation.ml index 24c431a1..e27bba9f 100644 --- a/testsuite/tests/printing-types/disambiguation.ml +++ b/testsuite/tests/printing-types/disambiguation.ml @@ -6,14 +6,14 @@ type 'a x = private [> `x] as 'a;; [%%expect {| Line 1: Error: Type declarations do not match: - type 'a x = private [> `x ] constraint 'a = 'a x + type !'a x = private [> `x ] constraint 'a = 'a x is not included in type 'a x Their constraints differ. |}, Principal{| Line 1: Error: Type declarations do not match: - type 'a x = private 'a constraint 'a = [> `x ] + type !'a x = private 'a constraint 'a = [> `x ] is not included in type 'a x Their constraints differ. diff --git a/testsuite/tests/reproducibility/cmis_on_file_system.ml b/testsuite/tests/reproducibility/cmis_on_file_system.ml index 188fed77..92066e71 100644 --- a/testsuite/tests/reproducibility/cmis_on_file_system.ml +++ b/testsuite/tests/reproducibility/cmis_on_file_system.ml @@ -4,7 +4,7 @@ ** ocamlc.byte compile_only = "true" module = "cmis_on_file_system.ml" - flags="-bin-annot" + flags="-bin-annot -no-alias-deps -w '-49'" *** script script= "mv cmis_on_file_system.cmt lone.cmt" **** ocamlc.byte @@ -12,9 +12,9 @@ compile_only="true" ***** ocamlc.byte compile_only = "true" - flags="-bin-annot" + flags="-bin-annot -no-alias-deps -w '-49'" module="cmis_on_file_system.ml" - ****** compare-native-programs + ****** compare-binary-files program="cmis_on_file_system.cmt" program2="lone.cmt" *) @@ -24,3 +24,5 @@ at a given point in time *) type t = int let () = () + +module M = Cmis_on_file_system_companion diff --git a/testsuite/tests/runtime-naked-pointers/cstubs.c b/testsuite/tests/runtime-naked-pointers/cstubs.c new file mode 100644 index 00000000..e9315f3a --- /dev/null +++ b/testsuite/tests/runtime-naked-pointers/cstubs.c @@ -0,0 +1,20 @@ +#include +#include "caml/mlvalues.h" +#include "caml/gc.h" +#include "caml/memory.h" + +static int colors[4] = { Caml_white, Caml_gray, Caml_blue, Caml_black }; + +value make_block(value header_size, value color, value size) +{ + intnat sz = Nativeint_val(size); + value * p = caml_stat_alloc((1 + sz) * sizeof(value)); + p[0] = Make_header(Nativeint_val(header_size), 0, colors[Int_val(color)]); + memset(p + 1, 0x80, sz * sizeof(value)); + return (value) (p + 1); +} + +value make_raw_pointer (value v) +{ + return (value) Nativeint_val(v); +} diff --git a/testsuite/tests/runtime-naked-pointers/np.ml b/testsuite/tests/runtime-naked-pointers/np.ml new file mode 100644 index 00000000..1738934f --- /dev/null +++ b/testsuite/tests/runtime-naked-pointers/np.ml @@ -0,0 +1,11 @@ +type color = White | Gray | Blue | Black + +external make_block: nativeint -> color -> nativeint -> Obj.t + = "make_block" + +external make_raw_pointer: nativeint -> Obj.t + = "make_raw_pointer" + +let do_gc root = + Gc.compact(); (* full major + compaction *) + root diff --git a/testsuite/tests/runtime-naked-pointers/np1.ml b/testsuite/tests/runtime-naked-pointers/np1.ml new file mode 100644 index 00000000..be4c677a --- /dev/null +++ b/testsuite/tests/runtime-naked-pointers/np1.ml @@ -0,0 +1,12 @@ +(* TEST + modules = "cstubs.c np.ml" + * bytecode + * native +*) + +open Np + +(* Out-of-heap object with black header is accepted even in no-naked-pointers + mode. GC doesn't scan black objects. *) + +let x = do_gc [ make_block 100n Black 100n ] diff --git a/testsuite/tests/runtime-naked-pointers/np2.ml b/testsuite/tests/runtime-naked-pointers/np2.ml new file mode 100644 index 00000000..f24c813c --- /dev/null +++ b/testsuite/tests/runtime-naked-pointers/np2.ml @@ -0,0 +1,13 @@ +(* TEST + modules = "cstubs.c np.ml" + * bytecode + * native +*) + +open Np + +(* Out-of-heap object with black header is accepted even in no-naked-pointers + mode. GC doesn't scan black objects. However, if the size in the + head is crazily big, the naked pointer detector will warn. *) + +let x = do_gc [ make_block (-1n) Black 100n ] diff --git a/testsuite/tests/runtime-naked-pointers/np2.run b/testsuite/tests/runtime-naked-pointers/np2.run new file mode 100755 index 00000000..c03f6f68 --- /dev/null +++ b/testsuite/tests/runtime-naked-pointers/np2.run @@ -0,0 +1,3 @@ +#!/bin/sh + +exec ${test_source_directory}/runtest.sh diff --git a/testsuite/tests/runtime-naked-pointers/np3.ml b/testsuite/tests/runtime-naked-pointers/np3.ml new file mode 100644 index 00000000..d207279d --- /dev/null +++ b/testsuite/tests/runtime-naked-pointers/np3.ml @@ -0,0 +1,15 @@ +(* TEST + modules = "cstubs.c np.ml" + * naked_pointers + ** bytecode + ** native +*) + +open Np + +(* Out-of-heap object with non-black header is OK in naked pointers mode only *) +(* Note that the header size can be wrong as it should not be used by the GC *) + +let x = do_gc [ make_block 10000n White 10n; + make_block 1n Blue 0n; + make_block (-1n) Gray 5n ] diff --git a/testsuite/tests/runtime-naked-pointers/np3.run b/testsuite/tests/runtime-naked-pointers/np3.run new file mode 100755 index 00000000..c03f6f68 --- /dev/null +++ b/testsuite/tests/runtime-naked-pointers/np3.run @@ -0,0 +1,3 @@ +#!/bin/sh + +exec ${test_source_directory}/runtest.sh diff --git a/testsuite/tests/runtime-naked-pointers/np4.ml b/testsuite/tests/runtime-naked-pointers/np4.ml new file mode 100644 index 00000000..98966ddf --- /dev/null +++ b/testsuite/tests/runtime-naked-pointers/np4.ml @@ -0,0 +1,13 @@ +(* TEST + modules = "cstubs.c np.ml" + * naked_pointers + ** bytecode + ** native +*) + +open Np + +(* Null pointers and bad pointers outside the heap are OK + in naked pointers mode only *) + +let x = do_gc [ make_raw_pointer 0n; make_raw_pointer 42n ] diff --git a/testsuite/tests/runtime-naked-pointers/np4.run b/testsuite/tests/runtime-naked-pointers/np4.run new file mode 100755 index 00000000..c03f6f68 --- /dev/null +++ b/testsuite/tests/runtime-naked-pointers/np4.run @@ -0,0 +1,3 @@ +#!/bin/sh + +exec ${test_source_directory}/runtest.sh diff --git a/testsuite/tests/runtime-naked-pointers/runtest.sh b/testsuite/tests/runtime-naked-pointers/runtest.sh new file mode 100755 index 00000000..f5d4df56 --- /dev/null +++ b/testsuite/tests/runtime-naked-pointers/runtest.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +if grep -q "#define NAKED_POINTERS_CHECKER" ${ocamlsrcdir}/runtime/caml/m.h \ +&& (echo ${program} | grep -q '\.opt') +then + (${program} > ${output}) 2>&1 | grep -q '^Out-of-heap ' + exit $? +else + exec ${program} > ${output} +fi diff --git a/testsuite/tests/self-contained-toplevel/main.ml b/testsuite/tests/self-contained-toplevel/main.ml index 4be67c87..aa1b7bc6 100644 --- a/testsuite/tests/self-contained-toplevel/main.ml +++ b/testsuite/tests/self-contained-toplevel/main.ml @@ -37,4 +37,4 @@ let () = Env.add_persistent_structure (Ident.create_persistent "Foo") !Toploop.toplevel_env | _ -> ()); - Topmain.main () + exit (Topmain.main ()) diff --git a/testsuite/tests/shadow_include/shadow_all.ml b/testsuite/tests/shadow_include/shadow_all.ml index 443541c1..b9467cfe 100644 --- a/testsuite/tests/shadow_include/shadow_all.ml +++ b/testsuite/tests/shadow_include/shadow_all.ml @@ -100,11 +100,11 @@ end Line 4, characters 2-11: 4 | include S ^^^^^^^^^ -Error: Illegal shadowing of included type t/144 by t/161 +Error: Illegal shadowing of included type t/146 by t/163 Line 2, characters 2-11: - Type t/144 came from this include + Type t/146 came from this include Line 3, characters 2-24: - The value ignore has no valid type if t/144 is shadowed + The value ignore has no valid type if t/146 is shadowed |}] module type Module = sig @@ -140,11 +140,11 @@ end Line 4, characters 2-11: 4 | include S ^^^^^^^^^ -Error: Illegal shadowing of included module M/232 by M/249 +Error: Illegal shadowing of included module M/237 by M/254 Line 2, characters 2-11: - Module M/232 came from this include + Module M/237 came from this include Line 3, characters 2-26: - The value ignore has no valid type if M/232 is shadowed + The value ignore has no valid type if M/237 is shadowed |}] @@ -181,11 +181,11 @@ end Line 4, characters 2-11: 4 | include S ^^^^^^^^^ -Error: Illegal shadowing of included module type T/317 by T/334 +Error: Illegal shadowing of included module type T/324 by T/341 Line 2, characters 2-11: - Module type T/317 came from this include + Module type T/324 came from this include Line 3, characters 2-39: - The module F has no valid type if T/317 is shadowed + The module F has no valid type if T/324 is shadowed |}] module type Extension = sig @@ -198,11 +198,11 @@ end Line 4, characters 2-11: 4 | include S ^^^^^^^^^ -Error: Illegal shadowing of included type ext/352 by ext/369 +Error: Illegal shadowing of included type ext/360 by ext/377 Line 2, characters 2-11: - Type ext/352 came from this include + Type ext/360 came from this include Line 3, characters 14-16: - The extension constructor C2 has no valid type if ext/352 is shadowed + The extension constructor C2 has no valid type if ext/360 is shadowed |}] module type Class = sig diff --git a/testsuite/tests/statmemprof/alloc_counts.ml b/testsuite/tests/statmemprof/alloc_counts.ml new file mode 100644 index 00000000..f8cbb565 --- /dev/null +++ b/testsuite/tests/statmemprof/alloc_counts.ml @@ -0,0 +1,53 @@ +(* TEST *) +module MP = Gc.Memprof + +let allocs_by_memprof f = + let minor = ref 0 in + let major = ref 0 in + let alloc_minor (info : MP.allocation) = + minor := !minor + info.n_samples; + None in + let alloc_major (info : MP.allocation) = + major := !major + info.n_samples; + None in + MP.start ~sampling_rate:1. ({MP.null_tracker with alloc_minor; alloc_major}); + match Sys.opaque_identity f () with + | _ -> MP.stop (); (!minor, !major) + | exception e -> MP.stop (); raise e + +let allocs_by_counters f = + let minor1, prom1, major1 = Gc.counters () in + let minor2, prom2, major2 = Gc.counters () in + ignore (Sys.opaque_identity f ()); + let minor3, prom3, major3 = Gc.counters () in + let minor = + minor3 -. minor2 (* allocations *) + -. (minor2 -. minor1) (* Gc.counters overhead *) + in + let prom = + prom3 -. prom2 -. (prom2 -. prom1) in + let major = + major3 -. major2 -. (major2 -. major1) in + int_of_float minor, + int_of_float (major -. prom) + +let compare name f = + let mp_minor, mp_major = allocs_by_memprof f in + let ct_minor, ct_major = allocs_by_counters f in + if mp_minor <> ct_minor || mp_major <> ct_major then + Printf.printf "%20s: minor: %d / %d; major: %d / %d\n" + name ct_minor mp_minor ct_major mp_major + +let many f = + fun () -> + for i = 1 to 10 do + ignore (Sys.opaque_identity f ()) + done + +let () = + compare "ref" (many (fun () -> ref (ref (ref 42)))); + compare "short array" (many (fun () -> Array.make 10 'a')); + compare "long array" (many (fun () -> Array.make 1000 'a')); + compare "curried closure" (many (fun () -> fun a b -> a + b)); + compare "marshalling" (many (fun () -> + Marshal.from_string (Marshal.to_string (ref (ref (ref 42))) []) 0)) diff --git a/testsuite/tests/statmemprof/alloc_counts.reference b/testsuite/tests/statmemprof/alloc_counts.reference new file mode 100644 index 00000000..e69de29b diff --git a/testsuite/tests/statmemprof/arrays_in_major.ml b/testsuite/tests/statmemprof/arrays_in_major.ml index f3c5b8a6..78907a18 100644 --- a/testsuite/tests/statmemprof/arrays_in_major.ml +++ b/testsuite/tests/statmemprof/arrays_in_major.ml @@ -1,6 +1,5 @@ (* TEST flags = "-g" - compare_programs = "false" *) open Gc.Memprof @@ -113,7 +112,7 @@ let check_distrib lo hi cnt rate = alloc_major = (fun info -> assert (info.size >= lo && info.size <= hi); assert (info.n_samples > 0); - assert (not info.unmarshalled); + assert (info.source = Normal); smp := !smp + info.n_samples; None ); diff --git a/testsuite/tests/statmemprof/arrays_in_minor.ml b/testsuite/tests/statmemprof/arrays_in_minor.ml index ec6131f1..432f8b1d 100644 --- a/testsuite/tests/statmemprof/arrays_in_minor.ml +++ b/testsuite/tests/statmemprof/arrays_in_minor.ml @@ -1,6 +1,5 @@ (* TEST flags = "-g" - compare_programs = "false" *) open Gc.Memprof @@ -127,7 +126,7 @@ let check_distrib lo hi cnt rate = alloc_minor = (fun info -> assert (info.size >= lo && info.size <= hi); assert (info.n_samples > 0); - assert (not info.unmarshalled); + assert (info.source = Normal); smp := !smp + info.n_samples; None ); diff --git a/testsuite/tests/statmemprof/blocking_in_callback.ml b/testsuite/tests/statmemprof/blocking_in_callback.ml index d5e8d2ce..00f49cfc 100644 --- a/testsuite/tests/statmemprof/blocking_in_callback.ml +++ b/testsuite/tests/statmemprof/blocking_in_callback.ml @@ -6,8 +6,7 @@ include systhreads *) let cnt = ref 0 -let alloc_num = ref 0 -let alloc_tot = 100000 +let alloc_thread = 50000 let (rd1, wr1) = Unix.pipe () let (rd2, wr2) = Unix.pipe () @@ -15,20 +14,26 @@ let (rd2, wr2) = Unix.pipe () let main_thread = Thread.self () let cb_main = ref 0 and cb_other = ref 0 let stopped = ref false -let minor_alloc_callback _ = +let alloc_callback alloc = if !stopped then None else begin - let do_stop = !cb_main + !cb_other >= alloc_tot in - if do_stop then stopped := true; let t = Thread.self () in if t == main_thread then begin + assert (alloc.Gc.Memprof.size < 10 || alloc.Gc.Memprof.size mod 2 = 0); + let do_stop = !cb_main >= alloc_thread in + if do_stop then stopped := true; incr cb_main; + assert (Unix.write wr2 (Bytes.make 1 'a') 0 1 = 1); if not do_stop then assert (Unix.read rd1 (Bytes.make 1 'a') 0 1 = 1) end else begin + assert (alloc.Gc.Memprof.size < 10 || alloc.Gc.Memprof.size mod 2 = 1); + let do_stop = !cb_other >= alloc_thread in + if do_stop then stopped := true; incr cb_other; + assert (Unix.write wr1 (Bytes.make 1 'a') 0 1 = 1); if not do_stop then assert (Unix.read rd2 (Bytes.make 1 'a') 0 1 = 1) @@ -39,31 +44,34 @@ let minor_alloc_callback _ = let mut = Mutex.create () let () = Mutex.lock mut -let rec go () = +let rec go alloc_num tid = Mutex.lock mut; Mutex.unlock mut; - if !alloc_num < alloc_tot then begin - alloc_num := !alloc_num + 1; - Sys.opaque_identity (Bytes.make (Random.int 300) 'a') |> ignore; - go () + if alloc_num < alloc_thread then begin + let len = 2 * (Random.int 200 + 1) + tid in + Sys.opaque_identity (Array.make len 0) |> ignore; + go (alloc_num + 1) tid end else begin cnt := !cnt + 1; if !cnt < 2 then begin Gc.minor (); (* check for callbacks *) Thread.yield (); - go () + go alloc_num tid end else begin Gc.minor () (* check for callbacks *) end end let () = - let t = Thread.create go () in + let t = Thread.create (fun () -> go 0 1) () in Gc.Memprof.(start ~callstack_size:10 ~sampling_rate:1. - { null_tracker with alloc_minor = minor_alloc_callback; }); + { null_tracker with + alloc_minor = alloc_callback; + alloc_major = alloc_callback }); Mutex.unlock mut; - go (); + go 0 0; Thread.join t; Gc.Memprof.stop (); - assert (abs (!cb_main - !cb_other) <= 1); - assert (!cb_main + !cb_other >= alloc_tot) + assert (!cb_main >= alloc_thread); + assert (!cb_other >= alloc_thread); + assert (abs (!cb_main - !cb_other) <= 1) diff --git a/testsuite/tests/statmemprof/callstacks.flat-float-array.reference b/testsuite/tests/statmemprof/callstacks.flat-float-array.reference index 3a1c8c91..3de29235 100644 --- a/testsuite/tests/statmemprof/callstacks.flat-float-array.reference +++ b/testsuite/tests/statmemprof/callstacks.flat-float-array.reference @@ -1,74 +1,74 @@ ----------- -Raised by primitive operation at Callstacks.alloc_list_literal in file "callstacks.ml", line 21, characters 30-53 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_list_literal in file "callstacks.ml", line 18, characters 30-53 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_pair in file "callstacks.ml", line 24, characters 30-76 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_pair in file "callstacks.ml", line 21, characters 30-76 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_record in file "callstacks.ml", line 29, characters 12-66 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_record in file "callstacks.ml", line 26, characters 12-66 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_some in file "callstacks.ml", line 32, characters 30-60 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_some in file "callstacks.ml", line 29, characters 30-60 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_array_literal in file "callstacks.ml", line 35, characters 30-55 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_array_literal in file "callstacks.ml", line 32, characters 30-55 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_float_array_literal in file "callstacks.ml", line 39, characters 12-62 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_float_array_literal in file "callstacks.ml", line 36, characters 12-62 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.do_alloc_unknown_array_literal in file "callstacks.ml", line 42, characters 22-27 -Called from Callstacks.alloc_unknown_array_literal in file "callstacks.ml", line 44, characters 30-65 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.do_alloc_unknown_array_literal in file "callstacks.ml", line 39, characters 22-27 +Called from Callstacks.alloc_unknown_array_literal in file "callstacks.ml", line 41, characters 30-65 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_small_array in file "callstacks.ml", line 47, characters 30-69 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_small_array in file "callstacks.ml", line 44, characters 30-69 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_large_array in file "callstacks.ml", line 50, characters 30-73 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_large_array in file "callstacks.ml", line 47, characters 30-73 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_closure.(fun) in file "callstacks.ml", line 54, characters 30-43 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_closure.(fun) in file "callstacks.ml", line 51, characters 30-43 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.get0 in file "callstacks.ml", line 57, characters 28-33 -Called from Callstacks.getfloatfield in file "callstacks.ml", line 59, characters 30-47 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.get0 in file "callstacks.ml", line 54, characters 28-33 +Called from Callstacks.getfloatfield in file "callstacks.ml", line 56, characters 30-47 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- Raised by primitive operation at Stdlib__marshal.from_bytes in file "marshal.ml", line 61, characters 9-35 -Called from Callstacks.alloc_unmarshal in file "callstacks.ml", line 65, characters 12-87 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Called from Callstacks.alloc_unmarshal in file "callstacks.ml", line 62, characters 12-87 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_ref in file "callstacks.ml", line 68, characters 30-59 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_ref in file "callstacks.ml", line 65, characters 30-59 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.prod_floats in file "callstacks.ml", line 71, characters 37-43 -Called from Callstacks.alloc_boxedfloat in file "callstacks.ml", line 73, characters 30-49 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.prod_floats in file "callstacks.ml", line 68, characters 37-43 +Called from Callstacks.alloc_boxedfloat in file "callstacks.ml", line 70, characters 30-49 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 diff --git a/testsuite/tests/statmemprof/callstacks.ml b/testsuite/tests/statmemprof/callstacks.ml index e7c29cea..ec5a4199 100644 --- a/testsuite/tests/statmemprof/callstacks.ml +++ b/testsuite/tests/statmemprof/callstacks.ml @@ -1,18 +1,15 @@ (* TEST flags = "-g -w -5" - compare_programs = "false" - * no-spacetime + * flat-float-array + reference = "${test_source_directory}/callstacks.flat-float-array.reference" + ** native + ** bytecode - ** flat-float-array - reference = "${test_source_directory}/callstacks.flat-float-array.reference" - *** native - *** bytecode - - ** no-flat-float-array - reference = "${test_source_directory}/callstacks.no-flat-float-array.reference" - *** native - *** bytecode + * no-flat-float-array + reference = "${test_source_directory}/callstacks.no-flat-float-array.reference" + ** native + ** bytecode *) open Gc.Memprof diff --git a/testsuite/tests/statmemprof/callstacks.no-flat-float-array.reference b/testsuite/tests/statmemprof/callstacks.no-flat-float-array.reference index bd7bd193..0fa12e79 100644 --- a/testsuite/tests/statmemprof/callstacks.no-flat-float-array.reference +++ b/testsuite/tests/statmemprof/callstacks.no-flat-float-array.reference @@ -1,70 +1,70 @@ ----------- -Raised by primitive operation at Callstacks.alloc_list_literal in file "callstacks.ml", line 21, characters 30-53 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_list_literal in file "callstacks.ml", line 18, characters 30-53 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_pair in file "callstacks.ml", line 24, characters 30-76 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_pair in file "callstacks.ml", line 21, characters 30-76 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_record in file "callstacks.ml", line 29, characters 12-66 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_record in file "callstacks.ml", line 26, characters 12-66 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_some in file "callstacks.ml", line 32, characters 30-60 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_some in file "callstacks.ml", line 29, characters 30-60 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_array_literal in file "callstacks.ml", line 35, characters 30-55 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_array_literal in file "callstacks.ml", line 32, characters 30-55 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_float_array_literal in file "callstacks.ml", line 39, characters 12-62 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_float_array_literal in file "callstacks.ml", line 36, characters 12-62 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.do_alloc_unknown_array_literal in file "callstacks.ml", line 42, characters 22-27 -Called from Callstacks.alloc_unknown_array_literal in file "callstacks.ml", line 44, characters 30-65 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.do_alloc_unknown_array_literal in file "callstacks.ml", line 39, characters 22-27 +Called from Callstacks.alloc_unknown_array_literal in file "callstacks.ml", line 41, characters 30-65 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_small_array in file "callstacks.ml", line 47, characters 30-69 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_small_array in file "callstacks.ml", line 44, characters 30-69 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_large_array in file "callstacks.ml", line 50, characters 30-73 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_large_array in file "callstacks.ml", line 47, characters 30-73 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_closure.(fun) in file "callstacks.ml", line 54, characters 30-43 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_closure.(fun) in file "callstacks.ml", line 51, characters 30-43 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- No callstack ----------- Raised by primitive operation at Stdlib__marshal.from_bytes in file "marshal.ml", line 61, characters 9-35 -Called from Callstacks.alloc_unmarshal in file "callstacks.ml", line 65, characters 12-87 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Called from Callstacks.alloc_unmarshal in file "callstacks.ml", line 62, characters 12-87 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.alloc_ref in file "callstacks.ml", line 68, characters 30-59 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.alloc_ref in file "callstacks.ml", line 65, characters 30-59 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 ----------- -Raised by primitive operation at Callstacks.prod_floats in file "callstacks.ml", line 71, characters 37-43 -Called from Callstacks.alloc_boxedfloat in file "callstacks.ml", line 73, characters 30-49 -Called from Callstacks.test in file "callstacks.ml", line 95, characters 2-10 +Raised by primitive operation at Callstacks.prod_floats in file "callstacks.ml", line 68, characters 37-43 +Called from Callstacks.alloc_boxedfloat in file "callstacks.ml", line 70, characters 30-49 +Called from Callstacks.test in file "callstacks.ml", line 92, characters 2-10 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Callstacks in file "callstacks.ml", line 102, characters 2-27 +Called from Callstacks in file "callstacks.ml", line 99, characters 2-27 diff --git a/testsuite/tests/statmemprof/comballoc.byte.reference b/testsuite/tests/statmemprof/comballoc.byte.reference index aa6736ef..60f8b1b3 100644 --- a/testsuite/tests/statmemprof/comballoc.byte.reference +++ b/testsuite/tests/statmemprof/comballoc.byte.reference @@ -1,49 +1,49 @@ 2: 0.42 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 2-19 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 2-19 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 3: 0.42 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 6-18 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 6-18 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 4: 0.42 true -Raised by primitive operation at Comballoc.f4 in file "comballoc.ml", line 13, characters 11-20 -Called from Comballoc.f in file "comballoc.ml", line 16, characters 13-17 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f4 in file "comballoc.ml", line 11, characters 11-20 +Called from Comballoc.f in file "comballoc.ml", line 14, characters 13-17 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 2: 0.01 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 2-19 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 2-19 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 3: 0.01 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 6-18 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 6-18 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 4: 0.01 true -Raised by primitive operation at Comballoc.f4 in file "comballoc.ml", line 13, characters 11-20 -Called from Comballoc.f in file "comballoc.ml", line 16, characters 13-17 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f4 in file "comballoc.ml", line 11, characters 11-20 +Called from Comballoc.f in file "comballoc.ml", line 14, characters 13-17 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 2: 0.83 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 2-19 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 2-19 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 3: 0.83 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 6-18 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 6-18 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 4: 0.83 true -Raised by primitive operation at Comballoc.f4 in file "comballoc.ml", line 13, characters 11-20 -Called from Comballoc.f in file "comballoc.ml", line 16, characters 13-17 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f4 in file "comballoc.ml", line 11, characters 11-20 +Called from Comballoc.f in file "comballoc.ml", line 14, characters 13-17 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 OK diff --git a/testsuite/tests/statmemprof/comballoc.ml b/testsuite/tests/statmemprof/comballoc.ml index f3c712f4..22b25471 100644 --- a/testsuite/tests/statmemprof/comballoc.ml +++ b/testsuite/tests/statmemprof/comballoc.ml @@ -1,11 +1,9 @@ (* TEST flags = "-g" - * no-spacetime - ** bytecode - reference = "${test_source_directory}/comballoc.byte.reference" - ** native - reference = "${test_source_directory}/comballoc.opt.reference" - compare_programs = "false" + * bytecode + reference = "${test_source_directory}/comballoc.byte.reference" + * native + reference = "${test_source_directory}/comballoc.opt.reference" *) open Gc.Memprof diff --git a/testsuite/tests/statmemprof/comballoc.opt.reference b/testsuite/tests/statmemprof/comballoc.opt.reference index ffe09c66..79d5a85d 100644 --- a/testsuite/tests/statmemprof/comballoc.opt.reference +++ b/testsuite/tests/statmemprof/comballoc.opt.reference @@ -1,49 +1,49 @@ 2: 0.42 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 2-19 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 2-19 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 3: 0.42 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 6-18 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 6-18 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 4: 0.42 true -Raised by primitive operation at Comballoc.f4 in file "comballoc.ml" (inlined), line 13, characters 11-20 -Called from Comballoc.f in file "comballoc.ml", line 16, characters 13-17 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f4 in file "comballoc.ml" (inlined), line 11, characters 11-20 +Called from Comballoc.f in file "comballoc.ml", line 14, characters 13-17 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 2: 0.01 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 2-19 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 2-19 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 3: 0.01 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 6-18 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 6-18 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 4: 0.01 true -Raised by primitive operation at Comballoc.f4 in file "comballoc.ml" (inlined), line 13, characters 11-20 -Called from Comballoc.f in file "comballoc.ml", line 16, characters 13-17 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f4 in file "comballoc.ml" (inlined), line 11, characters 11-20 +Called from Comballoc.f in file "comballoc.ml", line 14, characters 13-17 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 2: 0.83 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 2-19 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 2-19 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 3: 0.83 false -Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 16, characters 6-18 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f in file "comballoc.ml", line 14, characters 6-18 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 4: 0.83 true -Raised by primitive operation at Comballoc.f4 in file "comballoc.ml" (inlined), line 13, characters 11-20 -Called from Comballoc.f in file "comballoc.ml", line 16, characters 13-17 -Called from Comballoc.test in file "comballoc.ml", line 41, characters 25-48 +Raised by primitive operation at Comballoc.f4 in file "comballoc.ml" (inlined), line 11, characters 11-20 +Called from Comballoc.f in file "comballoc.ml", line 14, characters 13-17 +Called from Comballoc.test in file "comballoc.ml", line 39, characters 25-48 Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15 -Called from Comballoc in file "comballoc.ml", line 71, characters 2-35 +Called from Comballoc in file "comballoc.ml", line 69, characters 2-35 OK diff --git a/testsuite/tests/statmemprof/custom.ml b/testsuite/tests/statmemprof/custom.ml new file mode 100644 index 00000000..f0ddfa7e --- /dev/null +++ b/testsuite/tests/statmemprof/custom.ml @@ -0,0 +1,44 @@ +(* TEST *) + +open Gc.Memprof + +let bigstring_create sz = + Bigarray.Array1.create Bigarray.char Bigarray.c_layout sz + +let keep = ref [] + +let test sampling_rate = + let size = 256 in + let iters = 100_000 in + let size_words = size / (Sys.word_size / 8) in + let alloc = ref 0 and collect = ref 0 and promote = ref 0 in + let tracker = + { null_tracker with + alloc_minor = (fun info -> + if info.source <> Custom then None + else begin + alloc := !alloc + info.n_samples; + Some info.n_samples + end); + promote = (fun ns -> + promote := !promote + ns; None); + dealloc_minor = (fun ns -> + collect := !collect + ns) } in + start ~sampling_rate tracker; + for i = 1 to iters do + let str = Sys.opaque_identity bigstring_create size in + if i mod 10 = 0 then keep := str :: !keep + done; + keep := []; + Gc.full_major (); + stop (); + assert (!alloc = !promote + !collect); + let iters = float_of_int iters and size_words = float_of_int size_words in + (* see comballoc.ml for notes on precision *) + Printf.printf "%.2f %.1f\n" + ((float_of_int !alloc /. iters) /. size_words) + ((float_of_int !promote /. iters) /. size_words *. 10.) + + +let () = + [0.01; 0.5; 0.17] |> List.iter test diff --git a/testsuite/tests/statmemprof/custom.reference b/testsuite/tests/statmemprof/custom.reference new file mode 100644 index 00000000..3cf0f777 --- /dev/null +++ b/testsuite/tests/statmemprof/custom.reference @@ -0,0 +1,3 @@ +0.01 0.0 +0.50 0.5 +0.17 0.2 diff --git a/testsuite/tests/statmemprof/exception_callback.ml b/testsuite/tests/statmemprof/exception_callback.ml index 55dd5e55..e1589372 100644 --- a/testsuite/tests/statmemprof/exception_callback.ml +++ b/testsuite/tests/statmemprof/exception_callback.ml @@ -16,6 +16,11 @@ let alloc_tracker on_alloc = its uncaught exception handler. *) let _ = Printexc.record_backtrace false +let () = + start ~callstack_size:10 ~sampling_rate:1. + (alloc_tracker (fun _ -> stop ())); + ignore (Sys.opaque_identity (Array.make 200 0)) + let _ = start ~callstack_size:10 ~sampling_rate:1. (alloc_tracker (fun _ -> failwith "callback failed")); diff --git a/testsuite/tests/statmemprof/intern.ml b/testsuite/tests/statmemprof/intern.ml index 5a5ff558..bce6f89c 100644 --- a/testsuite/tests/statmemprof/intern.ml +++ b/testsuite/tests/statmemprof/intern.ml @@ -1,8 +1,5 @@ (* TEST flags = "-g" - * bytecode - * native - compare_programs = "false" *) open Gc.Memprof @@ -137,7 +134,7 @@ let check_distrib lo hi cnt rate = let alloc info = (* We also allocate the list constructor in the minor heap, so we filter that out. *) - if info.unmarshalled then begin + if info.source = Marshal then begin assert (info.size = 1 || info.size = 2); assert (info.n_samples > 0); smp := !smp + info.n_samples diff --git a/testsuite/tests/statmemprof/lists_in_minor.ml b/testsuite/tests/statmemprof/lists_in_minor.ml index 7a3736a2..ebd43485 100644 --- a/testsuite/tests/statmemprof/lists_in_minor.ml +++ b/testsuite/tests/statmemprof/lists_in_minor.ml @@ -1,8 +1,5 @@ (* TEST flags = "-g" - * bytecode - * native - compare_programs = "false" *) open Gc.Memprof @@ -25,7 +22,7 @@ let check_distrib len cnt rate = alloc_minor = (fun info -> assert (info.size = 2); assert (info.n_samples > 0); - assert (not info.unmarshalled); + assert (info.source = Normal); smp := !smp + info.n_samples; None); }; diff --git a/testsuite/tests/statmemprof/minor_no_postpone.ml b/testsuite/tests/statmemprof/minor_no_postpone.ml index 9d9ecd79..fcb94cf8 100644 --- a/testsuite/tests/statmemprof/minor_no_postpone.ml +++ b/testsuite/tests/statmemprof/minor_no_postpone.ml @@ -32,5 +32,6 @@ let () = ignore (Sys.opaque_identity (alloc_stub ())); assert(not !callback_done); callback_ok := true; - stop (); - assert(!callback_done) + ignore (Sys.opaque_identity (ref ())); + assert(!callback_done); + stop () diff --git a/testsuite/tests/statmemprof/moved_while_blocking.ml b/testsuite/tests/statmemprof/moved_while_blocking.ml new file mode 100644 index 00000000..8efc172a --- /dev/null +++ b/testsuite/tests/statmemprof/moved_while_blocking.ml @@ -0,0 +1,76 @@ +(* TEST +* hassysthreads +include systhreads +** bytecode +** native +*) + +let t2_begin = Atomic.make false +let t2_promoting = Atomic.make false +let t2_finish_promote = Atomic.make false +let t2_done = Atomic.make false +let t2_quit = Atomic.make false +let await a = + while not (Atomic.get a) do Thread.yield () done +let set a = + Atomic.set a true + +(* no-alloc printing to stdout *) +let say msg = + Unix.write Unix.stdout (Bytes.unsafe_of_string msg) 0 (String.length msg) |> ignore + +let static_ref = ref 0 +let global = ref static_ref +let thread_fn () = + await t2_begin; + say "T2: alloc\n"; + let r = ref 0 in + global := r; + say "T2: minor GC\n"; + Gc.minor (); + global := static_ref; + say "T2: done\n"; + set t2_done; + await t2_quit + +let big = ref [| |] + +let fill_big () = big := Array.make 1000 42 + [@@inline never] (* Prevent flambda to move the allocated array in a global + root (see #9978). *) +let empty_big () = big := [| |] + [@@inline never] + +let () = + let th = Thread.create thread_fn () in + Gc.Memprof.(start ~sampling_rate:1. + { null_tracker with + alloc_minor = (fun _ -> + say " minor alloc\n"; + Some ()); + alloc_major = (fun _ -> + say " major alloc\n"; + Some "major block\n"); + promote = (fun () -> + say " promoting...\n"; + set t2_promoting; + await t2_finish_promote; + say " ...done promoting\n"; + Some "promoted block\n"); + dealloc_major = (fun msg -> + say " major dealloc: "; say msg) }); + say "T1: alloc\n"; + fill_big (); + set t2_begin; + await t2_promoting; + say "T1: major GC\n"; + empty_big (); + Gc.full_major (); + set t2_finish_promote; + await t2_done; + say "T1: major GC\n"; + Gc.full_major (); + say "T1: done\n"; + Gc.Memprof.stop (); + set t2_quit; + Thread.join th diff --git a/testsuite/tests/statmemprof/moved_while_blocking.reference b/testsuite/tests/statmemprof/moved_while_blocking.reference new file mode 100644 index 00000000..ef99432b --- /dev/null +++ b/testsuite/tests/statmemprof/moved_while_blocking.reference @@ -0,0 +1,13 @@ +T1: alloc + major alloc +T2: alloc + minor alloc +T2: minor GC + promoting... +T1: major GC + major dealloc: major block + ...done promoting +T2: done +T1: major GC + major dealloc: promoted block +T1: done diff --git a/testsuite/tests/statmemprof/thread_exit_in_callback.ml b/testsuite/tests/statmemprof/thread_exit_in_callback.ml index 97c1a3ae..753f7726 100644 --- a/testsuite/tests/statmemprof/thread_exit_in_callback.ml +++ b/testsuite/tests/statmemprof/thread_exit_in_callback.ml @@ -1,18 +1,26 @@ (* TEST -modules = "thread_exit_in_callback_stub.c" -exit_status = "42" * hassysthreads include systhreads ** bytecode ** native *) -(* We cannot tell Ocamltest that this program is supposed to stop with - a fatal error. Instead, we install a fatal error hook and call exit(42) *) -external install_fatal_error_hook : unit -> unit = "install_fatal_error_hook" +let _ = + let main_thread = Thread.id (Thread.self ()) in + Gc.Memprof.(start ~callstack_size:10 ~sampling_rate:1. + { null_tracker with alloc_minor = fun _ -> + if Thread.id (Thread.self ()) <> main_thread then + Thread.exit (); + None }); + let t = Thread.create (fun () -> + ignore (Sys.opaque_identity (ref 1)); + assert false) () + in + Thread.join t; + Gc.Memprof.stop () let _ = - install_fatal_error_hook (); Gc.Memprof.(start ~callstack_size:10 ~sampling_rate:1. { null_tracker with alloc_minor = fun _ -> Thread.exit (); None }); - ignore (Sys.opaque_identity (ref 1)) + ignore (Sys.opaque_identity (ref 1)); + assert false diff --git a/testsuite/tests/statmemprof/thread_exit_in_callback.reference b/testsuite/tests/statmemprof/thread_exit_in_callback.reference deleted file mode 100644 index 4d745f0c..00000000 --- a/testsuite/tests/statmemprof/thread_exit_in_callback.reference +++ /dev/null @@ -1 +0,0 @@ -Fatal error hook: Thread.exit called from a memprof callback. diff --git a/testsuite/tests/statmemprof/thread_exit_in_callback_stub.c b/testsuite/tests/statmemprof/thread_exit_in_callback_stub.c deleted file mode 100644 index 91ed43cc..00000000 --- a/testsuite/tests/statmemprof/thread_exit_in_callback_stub.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include "caml/misc.h" -#include "caml/mlvalues.h" - -void fatal_error_hook_exit_3 (char *msg, va_list args) { - fprintf(stderr, "Fatal error hook: "); - vfprintf(stderr, msg, args); - fprintf(stderr, "\n"); - exit(42); -} - - -value install_fatal_error_hook (value unit) { - caml_fatal_error_hook = fatal_error_hook_exit_3; - return Val_unit; -} diff --git a/testsuite/tests/tool-caml-tex/ellipses.reference b/testsuite/tests/tool-caml-tex/ellipses.reference index 35c6b849..65380f79 100644 --- a/testsuite/tests/tool-caml-tex/ellipses.reference +++ b/testsuite/tests/tool-caml-tex/ellipses.reference @@ -1,48 +1,48 @@ \begin{camlexample}{verbatim} \begin{caml} \begin{camlinput} -$\?$let start = 0 -$\?$$\ldots$ -$\?$let mid = succ hidden -$\?$$\ldots$ +let start = 0 +$\ldots$ +let mid = succ hidden +$\ldots$ -$\?$module E = struct end -$\?$$\ldots$ +module E = struct end +$\ldots$ -$\?$let expr = $\ldots$ +let expr = $\ldots$ -$\?$let pat = match start with -$\?$ | $\ldots$ | 1 -> succ expr -$\?$ | _ -> succ expr +let pat = match start with + | $\ldots$ | 1 -> succ expr + | _ -> succ expr -$\?$let case = match start with -$\?$ | 0 -> succ pat -$\?$ | $\ldots$ +let case = match start with + | 0 -> succ pat + | $\ldots$ -$\?$let annot: $\ldots$ = succ case +let annot: $\ldots$ = succ case -$\?$let subexpr = succ annot + ($\ldots$ * 2) - 2 +let subexpr = succ annot + ($\ldots$ * 2) - 2 -$\?$$\ldots$ +$\ldots$ -$\?$class c2 = object -$\?$ $\ldots$ -$\?$ val y = 1 -$\?$ $\ldots$ -$\?$ method n = 3 -$\?$ $\ldots$ -$\?$end +class c2 = object + $\ldots$ + val y = 1 + $\ldots$ + method n = 3 + $\ldots$ +end -$\?$type t = $\ldots$ | B $\ldots$ | F -$\?$type arrow = int -> ($\ldots$) -$\?$type record = { a:int; $\ldots$ c:int; -$\?$ $\ldots$ -$\?$ g:int } -$\?$type polyvar = [`A|$\ldots$ |`C -$\?$ |$\ldots$ -$\?$ | `G ] -$\?$type exn += $\ldots$ | B $\ldots$ | F +type t = $\ldots$ | B $\ldots$ | F +type arrow = int -> ($\ldots$) +type record = { a:int; $\ldots$ c:int; + $\ldots$ + g:int } +type polyvar = [`A|$\ldots$ |`C + |$\ldots$ + | `G ] +type exn += $\ldots$ | B $\ldots$ | F \end{camlinput} \end{caml} \end{camlexample} diff --git a/testsuite/tests/tool-caml-tex/redirections.reference b/testsuite/tests/tool-caml-tex/redirections.reference index 538b45f9..e8df37d1 100644 --- a/testsuite/tests/tool-caml-tex/redirections.reference +++ b/testsuite/tests/tool-caml-tex/redirections.reference @@ -1,25 +1,25 @@ \begin{camlexample}{toplevel} \begin{caml} \begin{camlinput} -$\?$[@@@warning "+A"];; +$\?$ [@@@warning "+A"];; \end{camlinput} \end{caml} \begin{caml} \begin{camlinput} -$\?$1 + <<2.>> ;; +$\?$ 1 + <<2.>> ;; \end{camlinput} \begin{camlerror} -$\:$Error: This expression has type float but an expression was expected of type -$\:$ int +Error: This expression has type float but an expression was expected of type + int \end{camlerror} \end{caml} \begin{caml} \begin{camlinput} -$\?$let f <> = () ;; +$\?$ let f <> = () ;; \end{camlinput} \begin{camlwarn} -$\:$Warning 27: unused variable x. -$\:$val f : 'a -> unit = +Warning 27 [unused-var-strict]: unused variable x. +val f : 'a -> unit = \end{camlwarn} \end{caml} \end{camlexample} @@ -27,13 +27,13 @@ $\:$val f : 'a -> unit = \begin{camlexample}{toplevel} \begin{caml} \begin{camlinput} -$\?$Format.printf "Hello@."; -$\?$print_endline "world";; +$\?$ Format.printf "Hello@."; + print_endline "world";; \end{camlinput} \begin{camloutput} -$\:$Hello -$\:$world -$\:$- : unit = () +Hello +world +- : unit = () \end{camloutput} \end{caml} \end{camlexample} diff --git a/testsuite/tests/tool-ocamlc-open/tool-ocamlc-open-error.compilers.reference b/testsuite/tests/tool-ocamlc-open/tool-ocamlc-open-error.compilers.reference index 4c75c9fe..dcf6f4f9 100644 --- a/testsuite/tests/tool-ocamlc-open/tool-ocamlc-open-error.compilers.reference +++ b/testsuite/tests/tool-ocamlc-open/tool-ocamlc-open-error.compilers.reference @@ -1,4 +1,4 @@ File "tool-ocamlc-open-error.ml", line 1: -Warning 24: bad source file name: "Tool-ocamlc-open-error" is not a valid module name. +Warning 24 [bad-module-name]: bad source file name: "Tool-ocamlc-open-error" is not a valid module name. File "command line argument: -open "F("", line 1, characters 1-2: Error: Syntax error diff --git a/testsuite/tests/tool-ocamlc-stop-after/stop_after_typing_impl.compilers.reference b/testsuite/tests/tool-ocamlc-stop-after/stop_after_typing_impl.compilers.reference index 257eeb74..a82c28e5 100644 --- a/testsuite/tests/tool-ocamlc-stop-after/stop_after_typing_impl.compilers.reference +++ b/testsuite/tests/tool-ocamlc-stop-after/stop_after_typing_impl.compilers.reference @@ -1,15 +1,15 @@ [ - structure_item (stop_after_typing_impl.ml[13,349+0]..stop_after_typing_impl.ml[13,349+37]) + structure_item (stop_after_typing_impl.ml[13,365+0]..stop_after_typing_impl.ml[13,365+37]) Tstr_primitive - value_description apply/80 (stop_after_typing_impl.ml[13,349+0]..stop_after_typing_impl.ml[13,349+37]) - core_type (stop_after_typing_impl.ml[13,349+16]..stop_after_typing_impl.ml[13,349+26]) + value_description apply (stop_after_typing_impl.ml[13,365+0]..stop_after_typing_impl.ml[13,365+37]) + core_type (stop_after_typing_impl.ml[13,365+16]..stop_after_typing_impl.ml[13,365+26]) Ttyp_arrow Nolabel - core_type (stop_after_typing_impl.ml[13,349+16]..stop_after_typing_impl.ml[13,349+19]) - Ttyp_constr "int/1!" + core_type (stop_after_typing_impl.ml[13,365+16]..stop_after_typing_impl.ml[13,365+19]) + Ttyp_constr "int!" [] - core_type (stop_after_typing_impl.ml[13,349+23]..stop_after_typing_impl.ml[13,349+26]) - Ttyp_constr "int/1!" + core_type (stop_after_typing_impl.ml[13,365+23]..stop_after_typing_impl.ml[13,365+26]) + Ttyp_constr "int!" [] [ "%apply" diff --git a/testsuite/tests/tool-ocamlc-stop-after/stop_after_typing_impl.ml b/testsuite/tests/tool-ocamlc-stop-after/stop_after_typing_impl.ml index e7e9d089..f7395095 100644 --- a/testsuite/tests/tool-ocamlc-stop-after/stop_after_typing_impl.ml +++ b/testsuite/tests/tool-ocamlc-stop-after/stop_after_typing_impl.ml @@ -1,7 +1,7 @@ (* TEST * setup-ocamlc.byte-build-env ** ocamlc.byte - flags = "-stop-after typing -dtypedtree" + flags = "-stop-after typing -dno-unique-ids -dtypedtree" ocamlc_byte_exit_status = "0" *** check-ocamlc.byte-output *) diff --git a/testsuite/tests/tool-ocamlobjinfo/has-lib-bfd.sh b/testsuite/tests/tool-ocamlobjinfo/has-lib-bfd.sh deleted file mode 100644 index 1b268740..00000000 --- a/testsuite/tests/tool-ocamlobjinfo/has-lib-bfd.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -if grep -q "#define HAS_LIBBFD" ${ocamlsrcdir}/runtime/caml/s.h; then - exit ${TEST_PASS}; -fi -echo libbfd not available > ${ocamltest_response} -exit ${TEST_SKIP} diff --git a/testsuite/tests/tool-ocamlobjinfo/question.ml b/testsuite/tests/tool-ocamlobjinfo/question.ml index b8848e68..0b42dd1f 100644 --- a/testsuite/tests/tool-ocamlobjinfo/question.ml +++ b/testsuite/tests/tool-ocamlobjinfo/question.ml @@ -1,15 +1,13 @@ (* TEST -script = "sh ${test_source_directory}/has-lib-bfd.sh" * shared-libraries -** script -*** setup-ocamlopt.byte-build-env -**** ocamlopt.byte +** setup-ocamlopt.byte-build-env +*** ocamlopt.byte flags = "-shared" all_modules = "question.ml" program = "question.cmxs" -***** check-ocamlopt.byte-output -****** ocamlobjinfo -******* check-program-output +**** check-ocamlopt.byte-output +***** ocamlobjinfo +****** check-program-output *) let answer = 42 diff --git a/testsuite/tests/tool-ocamlopt-save-ir/check_for_pack.compilers.reference b/testsuite/tests/tool-ocamlopt-save-ir/check_for_pack.compilers.reference new file mode 100644 index 00000000..df07426a --- /dev/null +++ b/testsuite/tests/tool-ocamlopt-save-ir/check_for_pack.compilers.reference @@ -0,0 +1,2 @@ +File "check_for_pack.cmir-linear", line 1: +Error: This input file cannot be compiled with -for-pack foo: it was generated without -for-pack. diff --git a/testsuite/tests/tool-ocamlopt-save-ir/check_for_pack.ml b/testsuite/tests/tool-ocamlopt-save-ir/check_for_pack.ml new file mode 100644 index 00000000..610abbdc --- /dev/null +++ b/testsuite/tests/tool-ocamlopt-save-ir/check_for_pack.ml @@ -0,0 +1,19 @@ +(* TEST + * native-compiler + ** setup-ocamlopt.byte-build-env + *** ocamlopt.byte + flags = "-save-ir-after scheduling" + ocamlopt_byte_exit_status = "0" + **** script + script = "touch empty.ml" + ***** ocamlopt.byte + flags = "-S check_for_pack.cmir-linear -for-pack foo" + module = "empty.ml" + ocamlopt_byte_exit_status = "2" + ****** check-ocamlopt.byte-output +*) + +let foo f x = + if x > 0 then x * 7 else f x + +let bar x y = x + y diff --git a/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_scheduling.ml b/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_scheduling.ml new file mode 100644 index 00000000..1d815978 --- /dev/null +++ b/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_scheduling.ml @@ -0,0 +1,14 @@ +(* TEST + * native-compiler + ** setup-ocamlopt.byte-build-env + *** ocamlopt.byte + flags = "-save-ir-after scheduling -S" + **** check-ocamlopt.byte-output + ***** script + script = "sh ${test_source_directory}/save_ir_after_scheduling.sh" +*) + +let foo f x = + if x > 0 then x * 7 else f x + +let bar x y = x + y diff --git a/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_scheduling.sh b/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_scheduling.sh new file mode 100755 index 00000000..9c30b9e2 --- /dev/null +++ b/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_scheduling.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +set -e + +cmir=save_ir_after_scheduling.cmir-linear + +# Check that cmir is generated +if [ -e "$cmir" ] ; then + test_result=${TEST_PASS} +else + echo "not found $cmir" > ${ocamltest_response} + test_result=${TEST_FAIL} +fi +exit ${test_result} diff --git a/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.compilers.reference b/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.compilers.reference new file mode 100644 index 00000000..38ac104a --- /dev/null +++ b/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.compilers.reference @@ -0,0 +1 @@ +wrong argument 'typing'; option '-save-ir-after' expects one of: scheduling. diff --git a/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.ml b/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.ml new file mode 100644 index 00000000..15c2379f --- /dev/null +++ b/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.ml @@ -0,0 +1,15 @@ +(* TEST + * native-compiler + ** setup-ocamlopt.byte-build-env + compiler_output = "compiler-output.raw" + *** ocamlopt.byte + flags = "-save-ir-after typing" + ocamlopt_byte_exit_status = "2" + *** script + script = "sh ${test_source_directory}/save_ir_after_typing.sh" + output = "compiler-output" + **** check-ocamlopt.byte-output + compiler_output = "compiler-output" +*) + +(* this file is just a test driver, the test does not contain real OCaml code *) diff --git a/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.sh b/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.sh new file mode 100755 index 00000000..8f26ee2d --- /dev/null +++ b/testsuite/tests/tool-ocamlopt-save-ir/save_ir_after_typing.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +grep "wrong argument 'typing'" compiler-output.raw | grep "save-ir-after" | sed 's/^.*: wrong argument/wrong argument/' diff --git a/testsuite/tests/tool-ocamlopt-save-ir/start_from_emit.ml b/testsuite/tests/tool-ocamlopt-save-ir/start_from_emit.ml new file mode 100644 index 00000000..6f6cdf0f --- /dev/null +++ b/testsuite/tests/tool-ocamlopt-save-ir/start_from_emit.ml @@ -0,0 +1,31 @@ +(* TEST + * native-compiler + ** setup-ocamlopt.byte-build-env + *** ocamlopt.byte + flags = "-save-ir-after scheduling -stop-after scheduling" + ocamlopt_byte_exit_status = "0" + **** script + script = "touch empty.ml" + ***** ocamlopt.byte + flags = "-S start_from_emit.cmir-linear" + module = "empty.ml" + ocamlopt_byte_exit_status = "0" + ****** check-ocamlopt.byte-output + ******* script + script = "sh ${test_source_directory}/start_from_emit.sh" + ******** ocamlopt.byte + flags = "-S start_from_emit.cmir-linear -save-ir-after scheduling" + module = "empty.ml" + ocamlopt_byte_exit_status = "0" + ********* script + script = "cp start_from_emit.cmir-linear expected.cmir_linear" + ********** check-ocamlopt.byte-output + *********** script + script = "cmp start_from_emit.cmir-linear expected.cmir_linear" + +*) + +let foo f x = + if x > 0 then x * 7 else f x + +let bar x y = x + y diff --git a/testsuite/tests/tool-ocamlopt-save-ir/start_from_emit.sh b/testsuite/tests/tool-ocamlopt-save-ir/start_from_emit.sh new file mode 100755 index 00000000..99eb8136 --- /dev/null +++ b/testsuite/tests/tool-ocamlopt-save-ir/start_from_emit.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +set -e + +obj=start_from_emit.${objext} + +# Check that obj is generated +if [ -e "$obj" ] ; then + test_result=${TEST_PASS} +else + echo "not found $obj" > ${ocamltest_response} + test_result=${TEST_FAIL} +fi +exit ${test_result} diff --git a/testsuite/tests/tool-ocamltest/norm1.ml b/testsuite/tests/tool-ocamltest/norm1.ml new file mode 100644 index 00000000..ea32acff --- /dev/null +++ b/testsuite/tests/tool-ocamltest/norm1.ml @@ -0,0 +1,5 @@ +(* TEST + *) +let () = set_binary_mode_out stdout true in +(* ocamltest must normalise the \r\n *) +print_string "line1\r\n"; flush stdout diff --git a/testsuite/tests/tool-ocamltest/norm1.reference b/testsuite/tests/tool-ocamltest/norm1.reference new file mode 100644 index 00000000..495181cc --- /dev/null +++ b/testsuite/tests/tool-ocamltest/norm1.reference @@ -0,0 +1 @@ +line1 diff --git a/testsuite/tests/tool-ocamltest/norm2.ml b/testsuite/tests/tool-ocamltest/norm2.ml new file mode 100644 index 00000000..284e99d6 --- /dev/null +++ b/testsuite/tests/tool-ocamltest/norm2.ml @@ -0,0 +1,5 @@ +(* TEST + *) +let () = set_binary_mode_out stdout true in +(* ocamltest must normalise the \r\n *) +print_string "line1\r\nline2\r\n"; flush stdout diff --git a/testsuite/tests/tool-ocamltest/norm2.reference b/testsuite/tests/tool-ocamltest/norm2.reference new file mode 100644 index 00000000..8561d5d6 --- /dev/null +++ b/testsuite/tests/tool-ocamltest/norm2.reference @@ -0,0 +1,2 @@ +line1 +line2 diff --git a/testsuite/tests/tool-ocamltest/norm3.ml b/testsuite/tests/tool-ocamltest/norm3.ml new file mode 100644 index 00000000..eb7baa75 --- /dev/null +++ b/testsuite/tests/tool-ocamltest/norm3.ml @@ -0,0 +1,5 @@ +(* TEST + *) +let () = set_binary_mode_out stdout true in +(* ocamltest must normalise the \r\n but preserve the final \r *) +print_string "line1\r\nline2\r"; flush stdout diff --git a/testsuite/tests/tool-ocamltest/norm3.reference b/testsuite/tests/tool-ocamltest/norm3.reference new file mode 100644 index 00000000..cad2bf9e --- /dev/null +++ b/testsuite/tests/tool-ocamltest/norm3.reference @@ -0,0 +1,2 @@ +line1 +line2 \ No newline at end of file diff --git a/testsuite/tests/tool-ocamltest/norm4.ml b/testsuite/tests/tool-ocamltest/norm4.ml new file mode 100644 index 00000000..7b06b922 --- /dev/null +++ b/testsuite/tests/tool-ocamltest/norm4.ml @@ -0,0 +1,5 @@ +(* TEST + *) +let () = set_binary_mode_out stdout true in +(* ocamltest must normalise the \r\n *) +print_string "line1\r\nline2"; flush stdout diff --git a/testsuite/tests/tool-ocamltest/norm4.reference b/testsuite/tests/tool-ocamltest/norm4.reference new file mode 100644 index 00000000..3a1bd7a5 --- /dev/null +++ b/testsuite/tests/tool-ocamltest/norm4.reference @@ -0,0 +1,2 @@ +line1 +line2 \ No newline at end of file diff --git a/testsuite/tests/tool-toplevel/pr6468.compilers.reference b/testsuite/tests/tool-toplevel/pr6468.compilers.reference index 2f942ec6..55123b7c 100644 --- a/testsuite/tests/tool-toplevel/pr6468.compilers.reference +++ b/testsuite/tests/tool-toplevel/pr6468.compilers.reference @@ -3,10 +3,12 @@ val f : unit -> 'a = Line 1, characters 11-15: 1 | let g () = f (); 1;; ^^^^ -Warning 21: this statement never returns (or has an unsound type.) +Warning 21 [nonreturning-statement]: this statement never returns (or has an unsound type.) val g : unit -> int = Exception: Not_found. Raised at f in file "//toplevel//", line 2, characters 11-26 Called from g in file "//toplevel//", line 1, characters 11-15 -Called from Toploop.load_lambda in file "toplevel/toploop.ml", line 212, characters 17-27 +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 diff --git a/testsuite/tests/tool-toplevel/pr7060.compilers.reference b/testsuite/tests/tool-toplevel/pr7060.compilers.reference index 3538e007..9f661b83 100644 --- a/testsuite/tests/tool-toplevel/pr7060.compilers.reference +++ b/testsuite/tests/tool-toplevel/pr7060.compilers.reference @@ -3,7 +3,7 @@ type u = C of t Line 1, characters 18-54: 1 | let print_t out = function A -> Format.fprintf out "A";; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: B val print_t : Format.formatter -> t -> unit = diff --git a/testsuite/tests/tool-toplevel/printval.ml b/testsuite/tests/tool-toplevel/printval.ml new file mode 100644 index 00000000..17c27444 --- /dev/null +++ b/testsuite/tests/tool-toplevel/printval.ml @@ -0,0 +1,60 @@ +(* TEST + * expect +*) + +(* Test a success case *) +type 'a t = T of 'a +;; +T 123 +[%%expect {| +type 'a t = T of 'a +- : int t = T 123 +|}] + +(* no after fix *) +type _ t = .. +type 'a t += T of 'a +;; +T 123 +[%%expect {| +type _ t = .. +type 'a t += T of 'a +- : int t = T 123 +|}] + + +(* GADT with fixed arg type *) +type _ t += T: char -> int t +;; +T 'x' +[%%expect {| +type _ t += T : char -> int t +- : int t = T 'x' +|}] + + +(* GADT with poly arg type.... and the expected T *) +type _ t += T: 'a -> int t +;; +T 'x' +[%%expect {| +type _ t += T : 'a -> int t +- : int t = T +|}] + +(* the rest are expected without *) +type _ t += T: 'a * bool -> 'a t +;; +T ('x',true) +[%%expect {| +type _ t += T : 'a * bool -> 'a t +- : char t = T ('x', true) +|}] + +type _ t += T: 'a -> ('a * bool) t +;; +T 'x' +[%%expect {| +type _ t += T : 'a -> ('a * bool) t +- : (char * bool) t = T 'x' +|}] diff --git a/testsuite/tests/translprim/comparison_table.compilers.reference b/testsuite/tests/translprim/comparison_table.compilers.reference index a9a7cce9..2ff6e791 100644 --- a/testsuite/tests/translprim/comparison_table.compilers.reference +++ b/testsuite/tests/translprim/comparison_table.compilers.reference @@ -137,14 +137,14 @@ eta_int32_ge = (function prim prim stub (Int32.>= prim prim)) eta_int64_ge = (function prim prim stub (Int64.>= prim prim)) eta_nativeint_ge = (function prim prim stub (Nativeint.>= prim prim)) - int_vec = [0: [0: 1 1] [0: [0: 1 2] [0: [0: 2 1] 0a]]] - bool_vec = [0: [0: 0a 0a] [0: [0: 0a 1a] [0: [0: 1a 0a] 0a]]] - intlike_vec = [0: [0: 0a 0a] [0: [0: 0a 1a] [0: [0: 1a 0a] 0a]]] - float_vec = [0: [0: 1. 1.] [0: [0: 1. 2.] [0: [0: 2. 1.] 0a]]] - string_vec = [0: [0: "1" "1"] [0: [0: "1" "2"] [0: [0: "2" "1"] 0a]]] - int32_vec = [0: [0: 1l 1l] [0: [0: 1l 2l] [0: [0: 2l 1l] 0a]]] - int64_vec = [0: [0: 1L 1L] [0: [0: 1L 2L] [0: [0: 2L 1L] 0a]]] - nativeint_vec = [0: [0: 1n 1n] [0: [0: 1n 2n] [0: [0: 2n 1n] 0a]]] + int_vec = [0: [0: 1 1] [0: [0: 1 2] [0: [0: 2 1] 0]]] + bool_vec = [0: [0: 0 0] [0: [0: 0 1] [0: [0: 1 0] 0]]] + intlike_vec = [0: [0: 0 0] [0: [0: 0 1] [0: [0: 1 0] 0]]] + float_vec = [0: [0: 1. 1.] [0: [0: 1. 2.] [0: [0: 2. 1.] 0]]] + string_vec = [0: [0: "1" "1"] [0: [0: "1" "2"] [0: [0: "2" "1"] 0]]] + int32_vec = [0: [0: 1l 1l] [0: [0: 1l 2l] [0: [0: 2l 1l] 0]]] + int64_vec = [0: [0: 1L 1L] [0: [0: 1L 2L] [0: [0: 2L 1L] 0]]] + nativeint_vec = [0: [0: 1n 1n] [0: [0: 1n 2n] [0: [0: 2n 1n] 0]]] test_vec = (function cmp eq ne lt gt le ge vec (let @@ -152,7 +152,7 @@ (function f param (apply f (field 0 param) (field 1 param))) map = (function f l - (apply (field 16 (global Stdlib__list!)) (apply uncurry f) l))) + (apply (field 18 (global Stdlib__list!)) (apply uncurry f) l))) (makeblock 0 (makeblock 0 (apply map gen_cmp vec) (apply map cmp vec)) (apply map @@ -163,7 +163,7 @@ (makeblock 0 (makeblock 0 gen_lt lt) (makeblock 0 (makeblock 0 gen_gt gt) (makeblock 0 (makeblock 0 gen_le le) - (makeblock 0 (makeblock 0 gen_ge ge) 0a))))))))))) + (makeblock 0 (makeblock 0 gen_ge ge) 0))))))))))) (seq (apply test_vec int_cmp int_eq int_ne int_lt int_gt int_le int_ge int_vec) @@ -190,7 +190,7 @@ (apply f (field 0 param) (field 1 param))) map = (function f l - (apply (field 16 (global Stdlib__list!)) + (apply (field 18 (global Stdlib__list!)) (apply uncurry f) l))) (makeblock 0 (makeblock 0 (apply map eta_gen_cmp vec) @@ -203,7 +203,7 @@ (makeblock 0 (makeblock 0 eta_gen_lt lt) (makeblock 0 (makeblock 0 eta_gen_gt gt) (makeblock 0 (makeblock 0 eta_gen_le le) - (makeblock 0 (makeblock 0 eta_gen_ge ge) 0a))))))))))) + (makeblock 0 (makeblock 0 eta_gen_ge ge) 0))))))))))) (seq (apply eta_test_vec eta_int_cmp eta_int_eq eta_int_ne eta_int_lt eta_int_gt eta_int_le eta_int_ge int_vec) diff --git a/testsuite/tests/translprim/locs.ml b/testsuite/tests/translprim/locs.ml index 78343cda..79e46468 100644 --- a/testsuite/tests/translprim/locs.ml +++ b/testsuite/tests/translprim/locs.ml @@ -42,3 +42,120 @@ let pos, s3 = __POS_OF__ "yet another expression" let () = print_pos pos let () = print_endline s3 + +let id x = Sys.opaque_identity x + +let bang () = print_endline __FUNCTION__ + +let fn_multi _ _ = print_endline __FUNCTION__ + +let fn_function = function + | f -> print_endline __FUNCTION__ + +let fn_poly : 'a . 'a -> unit = fun _ -> + print_endline __FUNCTION__ + +module Mod1 = struct + module Nested = struct + let apply () = print_endline __FUNCTION__ + end +end + +let anon () = + print_endline __FUNCTION__; + let fn = print_endline __FUNCTION__; id (fun () -> print_endline __FUNCTION__) in + fn () + +let double_anon f = + print_endline __FUNCTION__; + let fn = id (fun () -> + print_endline __FUNCTION__; + let fn = id (fun () -> print_endline __FUNCTION__) in + fn ()) in + fn () + +let local () = + print_endline __FUNCTION__; + let inner () = print_endline __FUNCTION__ in + (id inner) () + +let double_local () = + print_endline __FUNCTION__; + let inner1 () = + print_endline __FUNCTION__; + let inner2 () = print_endline __FUNCTION__ in + (id inner2) () in + (id inner1) () + +let local_no_arg = + print_endline __FUNCTION__; + let inner () = print_endline __FUNCTION__ in + fun () -> print_endline __FUNCTION__; id inner () + +let curried () = + print_endline __FUNCTION__; + let inner () () = print_endline __FUNCTION__ in + id (inner ()) + +let local_module () = + print_endline __FUNCTION__; + let module N = struct + let foo () = + print_endline __FUNCTION__ + let r = print_endline __FUNCTION__; ref () + let () = r := id (id foo ()) + end in + !N.r + +module Functor (X : sig end) = struct + let fn () = print_endline __FUNCTION__ +end +module Inst = Functor (struct end) + +module rec Rec1 : sig + val fn : unit -> unit +end = struct + module M = Rec2 (struct end) + let fn () = print_endline __FUNCTION__; M.fn () +end +and Rec2 : functor (X : sig end) -> sig + val fn : unit -> unit +end = functor (X : sig end) -> struct + let fn () = print_endline __FUNCTION__ +end + +let (+@+) _ _ = print_endline __FUNCTION__ + +class klass = object (self) + method meth () = + print_endline __FUNCTION__ +end + +let inline_object () = + let obj = object (self) + method meth = + print_endline __FUNCTION__; + self#othermeth + method othermeth = + print_endline __FUNCTION__ + end in + obj#meth + +let () = + fn_multi 1 1; + fn_function (); + fn_poly 42; + Mod1.Nested.apply (); + anon (); + double_anon (); + local (); + double_local (); + local_no_arg (); + curried () (); + local_module (); + Inst.fn (); + Rec1.fn (); + 42 +@+ 32; + (new klass)#meth (); + inline_object (); + bang () diff --git a/testsuite/tests/translprim/locs.reference b/testsuite/tests/translprim/locs.reference index abb22875..1126c654 100644 --- a/testsuite/tests/translprim/locs.reference +++ b/testsuite/tests/translprim/locs.reference @@ -9,3 +9,34 @@ an expression another expression locs.ml, 40, 14, 49 yet another expression +Locs.local_no_arg +Locs.fn_multi +Locs.fn_function +Locs.fn_poly +Locs.Mod1.Nested.apply +Locs.anon +Locs.anon +Locs.anon.(fun) +Locs.double_anon +Locs.double_anon.(fun) +Locs.double_anon.(fun) +Locs.local +Locs.local.inner +Locs.double_local +Locs.double_local.inner1 +Locs.double_local.inner1.inner2 +Locs.local_no_arg.(fun) +Locs.local_no_arg.inner +Locs.curried +Locs.curried.inner +Locs.local_module +Locs.local_module.N.r +Locs.local_module.N.foo +Locs.Functor.fn +Locs.Rec1.fn +Locs.Rec2.fn +Locs.(+@+) +Locs.klass#meth +Locs.inline_object.object#meth +Locs.inline_object.object#othermeth +Locs.bang diff --git a/testsuite/tests/translprim/ref_spec.compilers.reference b/testsuite/tests/translprim/ref_spec.compilers.reference index 72b48d4f..8e27f04b 100644 --- a/testsuite/tests/translprim/ref_spec.compilers.reference +++ b/testsuite/tests/translprim/ref_spec.compilers.reference @@ -1,27 +1,27 @@ (setglobal Ref_spec! (let (int_ref = (makemutable 0 (int) 1) - var_ref = (makemutable 0 65a) - vargen_ref = (makemutable 0 65a) - cst_ref = (makemutable 0 0a) - gen_ref = (makemutable 0 0a) + var_ref = (makemutable 0 65) + vargen_ref = (makemutable 0 65) + cst_ref = (makemutable 0 0) + gen_ref = (makemutable 0 0) flt_ref = (makemutable 0 (float) 0.)) - (seq (setfield_imm 0 int_ref 2) (setfield_imm 0 var_ref 66a) - (setfield_ptr 0 vargen_ref [0: 66 0]) (setfield_ptr 0 vargen_ref 67a) - (setfield_imm 0 cst_ref 1a) (setfield_ptr 0 gen_ref [0: "foo"]) - (setfield_ptr 0 gen_ref 0a) (setfield_ptr 0 flt_ref 1.) + (seq (setfield_imm 0 int_ref 2) (setfield_imm 0 var_ref 66) + (setfield_ptr 0 vargen_ref [0: 66 0]) (setfield_ptr 0 vargen_ref 67) + (setfield_imm 0 cst_ref 1) (setfield_ptr 0 gen_ref [0: "foo"]) + (setfield_ptr 0 gen_ref 0) (setfield_ptr 0 flt_ref 1.) (let - (int_rec = (makemutable 0 (*,int) 0a 1) - var_rec = (makemutable 0 0a 65a) - vargen_rec = (makemutable 0 0a 65a) - cst_rec = (makemutable 0 0a 0a) - gen_rec = (makemutable 0 0a 0a) - flt_rec = (makemutable 0 (*,float) 0a 0.) + (int_rec = (makemutable 0 (*,int) 0 1) + var_rec = (makemutable 0 0 65) + vargen_rec = (makemutable 0 0 65) + cst_rec = (makemutable 0 0 0) + gen_rec = (makemutable 0 0 0) + flt_rec = (makemutable 0 (*,float) 0 0.) flt_rec' = (makearray[float] 0. 0.)) - (seq (setfield_imm 1 int_rec 2) (setfield_imm 1 var_rec 66a) + (seq (setfield_imm 1 int_rec 2) (setfield_imm 1 var_rec 66) (setfield_ptr 1 vargen_rec [0: 66 0]) - (setfield_ptr 1 vargen_rec 67a) (setfield_imm 1 cst_rec 1a) - (setfield_ptr 1 gen_rec [0: "foo"]) (setfield_ptr 1 gen_rec 0a) + (setfield_ptr 1 vargen_rec 67) (setfield_imm 1 cst_rec 1) + (setfield_ptr 1 gen_rec [0: "foo"]) (setfield_ptr 1 gen_rec 0) (setfield_ptr 1 flt_rec 1.) (setfloatfield 1 flt_rec' 1.) (let (set_open_poly = (function r y (setfield_ptr 0 r y)) diff --git a/testsuite/tests/typing-core-bugs/const_int_hint.ml b/testsuite/tests/typing-core-bugs/const_int_hint.ml index bc4b528b..b103791b 100644 --- a/testsuite/tests/typing-core-bugs/const_int_hint.ml +++ b/testsuite/tests/typing-core-bugs/const_int_hint.ml @@ -75,12 +75,6 @@ Line 2, characters 4-5: Error: This pattern matches values of type int but a pattern was expected which matches values of type int32 Hint: Did you mean `0l'? -|}, Principal{| -Line 2, characters 4-5: -2 | | 0 -> 0l - ^ -Error: This pattern matches values of type int - but a pattern was expected which matches values of type int32 |}] let _ : int64 -> int64 = function diff --git a/testsuite/tests/typing-core-bugs/type_expected_explanation.ml b/testsuite/tests/typing-core-bugs/type_expected_explanation.ml index e01aa267..c51c95fa 100644 --- a/testsuite/tests/typing-core-bugs/type_expected_explanation.ml +++ b/testsuite/tests/typing-core-bugs/type_expected_explanation.ml @@ -187,3 +187,14 @@ Error: This expression has type int but an expression was expected of type bool because it is in a when-guard |}];; + +(* #10106 *) +if false then (match () with () -> true);; +[%%expect{| +Line 1, characters 35-39: +1 | if false then (match () with () -> true);; + ^^^^ +Error: This variant expression is expected to have type unit + because it is in the result of a conditional with no else branch + The constructor true does not belong to type unit +|}] diff --git a/testsuite/tests/typing-deprecated/alerts.ml b/testsuite/tests/typing-deprecated/alerts.ml index 016ccf55..e909858e 100644 --- a/testsuite/tests/typing-deprecated/alerts.ml +++ b/testsuite/tests/typing-deprecated/alerts.ml @@ -257,17 +257,17 @@ end Line 2, characters 13-25: 2 | val x: int [@@alert 42] ^^^^^^^^^^^^ -Warning 47: illegal payload for attribute 'alert'. +Warning 47 [attribute-payload]: illegal payload for attribute 'alert'. Invalid payload Line 3, characters 13-29: 3 | val y: int [@@alert bla 42] ^^^^^^^^^^^^^^^^ -Warning 47: illegal payload for attribute 'alert'. +Warning 47 [attribute-payload]: illegal payload for attribute 'alert'. Invalid payload Line 4, characters 13-28: 4 | val z: int [@@alert "bla"] ^^^^^^^^^^^^^^^ -Warning 47: illegal payload for attribute 'alert'. +Warning 47 [attribute-payload]: illegal payload for attribute 'alert'. Ill-formed list of alert settings module X : sig val x : int val y : int val z : int end |}] diff --git a/testsuite/tests/typing-deprecated/deprecated.ml b/testsuite/tests/typing-deprecated/deprecated.ml index 8429df43..56ac05d5 100644 --- a/testsuite/tests/typing-deprecated/deprecated.ml +++ b/testsuite/tests/typing-deprecated/deprecated.ml @@ -530,7 +530,7 @@ type t = [ `A of X.t | `B of X.s | `C of X.u ] Line 1, characters 20-33: 1 | [@@@ocaml.ppwarning "Pp warning!"] ^^^^^^^^^^^^^ -Warning 22: Pp warning! +Warning 22 [preprocessor]: Pp warning! |}] @@ -541,11 +541,11 @@ let x = () [@ocaml.ppwarning "Pp warning 1!"] Line 2, characters 24-39: 2 | [@@ocaml.ppwarning "Pp warning 2!"] ^^^^^^^^^^^^^^^ -Warning 22: Pp warning 2! +Warning 22 [preprocessor]: Pp warning 2! Line 1, characters 29-44: 1 | let x = () [@ocaml.ppwarning "Pp warning 1!"] ^^^^^^^^^^^^^^^ -Warning 22: Pp warning 1! +Warning 22 [preprocessor]: Pp warning 1! val x : unit = () |}] @@ -556,7 +556,7 @@ type t = unit Line 2, characters 22-35: 2 | [@ocaml.ppwarning "Pp warning!"] ^^^^^^^^^^^^^ -Warning 22: Pp warning! +Warning 22 [preprocessor]: Pp warning! type t = unit |}] @@ -574,7 +574,7 @@ end Line 8, characters 22-36: 8 | [@@@ocaml.ppwarning "Pp warning2!"] ^^^^^^^^^^^^^^ -Warning 22: Pp warning2! +Warning 22 [preprocessor]: Pp warning2! module X : sig end |}] @@ -586,7 +586,7 @@ let x = Line 3, characters 23-38: 3 | [@ocaml.ppwarning "Pp warning 2!"] ^^^^^^^^^^^^^^^ -Warning 22: Pp warning 2! +Warning 22 [preprocessor]: Pp warning 2! val x : unit = () |}] @@ -599,11 +599,11 @@ type t = Line 4, characters 21-36: 4 | [@@ocaml.ppwarning "Pp warning 3!"] ^^^^^^^^^^^^^^^ -Warning 22: Pp warning 3! +Warning 22 [preprocessor]: Pp warning 3! Line 3, characters 21-36: 3 | [@ocaml.ppwarning "Pp warning 2!"] ^^^^^^^^^^^^^^^ -Warning 22: Pp warning 2! +Warning 22 [preprocessor]: Pp warning 2! type t = unit |}] @@ -613,11 +613,11 @@ let ([][@ocaml.ppwarning "XX"]) = [] Line 1, characters 25-29: 1 | let ([][@ocaml.ppwarning "XX"]) = [] ^^^^ -Warning 22: XX +Warning 22 [preprocessor]: XX Line 1, characters 4-31: 1 | let ([][@ocaml.ppwarning "XX"]) = [] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: _::_ |}] diff --git a/testsuite/tests/typing-extensions/disambiguation.ml b/testsuite/tests/typing-extensions/disambiguation.ml index feae4c71..9b0a7c3a 100644 --- a/testsuite/tests/typing-extensions/disambiguation.ml +++ b/testsuite/tests/typing-extensions/disambiguation.ml @@ -242,7 +242,7 @@ type b = Unique Line 7, characters 8-14: 7 | let x = Unique;; ^^^^^^ -Warning 41: Unique belongs to several types: b M.s t a +Warning 41 [ambiguous-name]: Unique belongs to several types: b M.s t a The first one was selected. Please disambiguate if this is wrong. val x : b = Unique |}] diff --git a/testsuite/tests/typing-extensions/extensions.ml b/testsuite/tests/typing-extensions/extensions.ml index da85b9ec..259712b2 100644 --- a/testsuite/tests/typing-extensions/extensions.ml +++ b/testsuite/tests/typing-extensions/extensions.ml @@ -198,7 +198,7 @@ type 'a inline += X of { x : 'a; } let _ = X {x = 1};; [%%expect {| -- : int inline = X {x = } +- : int inline = X {x = 1} |}] let must_be_polymorphic = fun x -> X {x};; diff --git a/testsuite/tests/typing-extensions/open_types.ml b/testsuite/tests/typing-extensions/open_types.ml index dd5ed138..21025441 100644 --- a/testsuite/tests/typing-extensions/open_types.ml +++ b/testsuite/tests/typing-extensions/open_types.ml @@ -306,7 +306,7 @@ type foo += Foo Line 3, characters 8-26: 3 | let f = function Foo -> () ^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: *extension* Matching over values of extensible variant types (the *extension* above) @@ -327,7 +327,7 @@ Lines 1-4, characters 8-11: 2 | | [Foo] -> 1 3 | | _::_::_ -> 3 4 | | [] -> 2 -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: *extension*::[] Matching over values of extensible variant types (the *extension* above) @@ -350,7 +350,7 @@ let f = function IPair (i, j) -> Format.sprintf "(%d, %d)" i j ;; Line 1, characters 8-62: 1 | let f = function IPair (i, j) -> Format.sprintf "(%d, %d)" i j ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: *extension* Matching over values of extensible variant types (the *extension* above) diff --git a/testsuite/tests/typing-fstclassmod/aliases.ml b/testsuite/tests/typing-fstclassmod/aliases.ml new file mode 100644 index 00000000..f6043ed4 --- /dev/null +++ b/testsuite/tests/typing-fstclassmod/aliases.ml @@ -0,0 +1,22 @@ +(* TEST + * expect +*) + +module M = struct end + +module type S = sig + module Alias = M + + type t +end + +module type T = S with type t = int + +let h x = (x : (module S with type t = int) :> (module T)) +;; +[%%expect {| +module M : sig end +module type S = sig module Alias = M type t end +module type T = sig module Alias = M type t = int end +val h : (module S with type t = int) -> (module T) = +|}] diff --git a/testsuite/tests/typing-fstclassmod/nondep_instance.ml b/testsuite/tests/typing-fstclassmod/nondep_instance.ml new file mode 100644 index 00000000..34f37b1c --- /dev/null +++ b/testsuite/tests/typing-fstclassmod/nondep_instance.ml @@ -0,0 +1,51 @@ +(* TEST + * expect *) + +module type Vector_space = sig + type t + type scalar + val scale : scalar -> t -> t +end;; +[%%expect{| +module type Vector_space = + sig type t type scalar val scale : scalar -> t -> t end +|}];; + +module type Scalar = sig + type t + include Vector_space with type t := t + and type scalar = t +end;; +[%%expect{| +module type Scalar = + sig type t type scalar = t val scale : scalar -> t -> t end +|}];; + +module type Linear_map = sig + type ('a, 'b) t + val scale : + (module Vector_space with type t = 'a and type scalar = 'l) -> + 'l -> ('a, 'a) t +end;; +[%%expect{| +module type Linear_map = + sig + type ('a, 'b) t + val scale : + (module Vector_space with type scalar = 'l and type t = 'a) -> + 'l -> ('a, 'a) t + end +|}];; + +module Primitive(Linear_map : Linear_map) = struct + let f (type s) (s : (module Scalar with type t = s)) x = + Linear_map.scale s x +end;; +[%%expect{| +Line 3, characters 21-22: +3 | Linear_map.scale s x + ^ +Error: This expression has type (module Scalar with type t = s) + but an expression was expected of type + (module Vector_space with type scalar = 'a and type t = 'b) +|}];; diff --git a/testsuite/tests/typing-gadts/didier.ml b/testsuite/tests/typing-gadts/didier.ml index 7c13cb4f..3ede9312 100644 --- a/testsuite/tests/typing-gadts/didier.ml +++ b/testsuite/tests/typing-gadts/didier.ml @@ -15,7 +15,7 @@ type 'a ty = Int : int ty | Bool : bool ty Lines 6-7, characters 2-13: 6 | ..match tag with 7 | | Bool -> x -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Int val fbool : 't -> 't ty -> 't = @@ -31,7 +31,7 @@ let fint (type t) (x : t) (tag : t ty) = Lines 2-3, characters 2-16: 2 | ..match tag with 3 | | Int -> x > 0 -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Bool val fint : 't -> 't ty -> bool = diff --git a/testsuite/tests/typing-gadts/or_patterns.ml b/testsuite/tests/typing-gadts/or_patterns.ml index 6fc7f8c2..eeafa254 100644 --- a/testsuite/tests/typing-gadts/or_patterns.ml +++ b/testsuite/tests/typing-gadts/or_patterns.ml @@ -124,13 +124,6 @@ Line 4, characters 4-11: Error: This pattern matches values of type bool t but a pattern was expected which matches values of type int t Type bool is not compatible with type int -|}, Principal{| -Line 4, characters 4-17: -4 | | BoolLit, true -> () - ^^^^^^^^^^^^^ -Error: This pattern matches values of type bool t * bool - but a pattern was expected which matches values of type int t * int - Type bool is not compatible with type int |}] let simple_annotated (type a) (t : a t) (a : a) = @@ -240,11 +233,7 @@ let simple_merged_annotated_return_annotated (type a) (t : a t) (a : a) = ;; [%%expect{| -Lines 3-4, characters 4-30: -3 | ....IntLit, ((3 : a) as x) -4 | | BoolLit, ((true : a) as x)............ -Error: The variable x on the left-hand side of this or-pattern has type - a but on the right-hand side it has type bool +val simple_merged_annotated_return_annotated : 'a t -> 'a -> unit = |}] (* test more scenarios: when the or-pattern itself is not at toplevel but under @@ -392,13 +381,6 @@ Line 4, characters 4-11: Error: This pattern matches values of type bool t but a pattern was expected which matches values of type int t Type bool is not compatible with type int -|}, Principal{| -Line 4, characters 4-14: -4 | | BoolLit, x -> x - ^^^^^^^^^^ -Error: This pattern matches values of type bool t * 'a - but a pattern was expected which matches values of type int t * 'b - Type bool is not compatible with type int |}] let noop_annotated (type a) (t : a t) (a : a) : a = @@ -593,12 +575,7 @@ let lambiguity (type a) (t2 : a t2) = ;; [%%expect{| -Line 3, characters 8-22: -3 | | Int ((_ : a) as x) - ^^^^^^^^^^^^^^ -Error: This pattern matches values of type a - This instance of a is ambiguous: - it would escape the scope of its equation +val lambiguity : 'a t2 -> 'a = |}] let rambiguity (type a) (t2 : a t2) = @@ -608,12 +585,11 @@ let rambiguity (type a) (t2 : a t2) = ;; [%%expect{| -Line 4, characters 9-23: -4 | | Bool ((_ : a) as x) -> x - ^^^^^^^^^^^^^^ -Error: This pattern matches values of type a - This instance of a is ambiguous: - it would escape the scope of its equation +Lines 3-4, characters 4-23: +3 | ....Int (_ as x) +4 | | Bool ((_ : a) as x)..... +Error: The variable x on the left-hand side of this or-pattern has type + int but on the right-hand side it has type a |}] diff --git a/testsuite/tests/typing-gadts/pr5785.ml b/testsuite/tests/typing-gadts/pr5785.ml index 00420834..aebad418 100644 --- a/testsuite/tests/typing-gadts/pr5785.ml +++ b/testsuite/tests/typing-gadts/pr5785.ml @@ -17,9 +17,9 @@ Lines 7-9, characters 43-24: 7 | ...........................................function 8 | | One, One -> "two" 9 | | Two, Two -> "four" -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: -(Two, One) +(One, Two) module Add : functor (T : sig type two end) -> sig diff --git a/testsuite/tests/typing-gadts/pr5906.ml b/testsuite/tests/typing-gadts/pr5906.ml index c722ec27..048c6ef4 100644 --- a/testsuite/tests/typing-gadts/pr5906.ml +++ b/testsuite/tests/typing-gadts/pr5906.ml @@ -33,7 +33,7 @@ Lines 12-16, characters 2-36: 14 | | Leq, Int x, Int y -> Bool (x <= y) 15 | | Leq, Bool x, Bool y -> Bool (x <= y) 16 | | Add, Int x, Int y -> Int (x + y) -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (Eq, Int _, _) val eval : ('a, 'b, 'c) binop -> 'a constant -> 'b constant -> 'c constant = diff --git a/testsuite/tests/typing-gadts/pr5981.ml b/testsuite/tests/typing-gadts/pr5981.ml index 9431a1ca..7462a02e 100644 --- a/testsuite/tests/typing-gadts/pr5981.ml +++ b/testsuite/tests/typing-gadts/pr5981.ml @@ -15,7 +15,7 @@ end;; Lines 7-8, characters 47-21: 7 | ...............................................match l, r with 8 | | A, B -> "f A B" -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (A, A) module F : @@ -42,7 +42,7 @@ end;; Lines 10-11, characters 15-21: 10 | ...............match l, r with 11 | | A, B -> "f A B" -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (A, A) module F : diff --git a/testsuite/tests/typing-gadts/pr5985.ml b/testsuite/tests/typing-gadts/pr5985.ml index c8a9c6f2..ca9d793e 100644 --- a/testsuite/tests/typing-gadts/pr5985.ml +++ b/testsuite/tests/typing-gadts/pr5985.ml @@ -70,16 +70,15 @@ Error: In this definition, a type variable cannot be deduced (* It is not OK to allow modules exported by other compilation units *) type (_,_) eq = Eq : ('a,'a) eq;; let eq = Obj.magic Eq;; -(* pretend that Queue.t is not injective *) -let eq : ('a Queue.t, 'b Queue.t) eq = eq;; -type _ t = T : 'a -> 'a Queue.t t;; (* fail *) +let eq : (('a, 'b) Ephemeron.K1.t, ('c, 'd) Ephemeron.K1.t) eq = eq;; +type _ t = T : 'a -> ('a, 'b) Ephemeron.K1.t t;; (* fail *) [%%expect{| type (_, _) eq = Eq : ('a, 'a) eq val eq : 'a = -val eq : ('a Queue.t, 'b Queue.t) eq = Eq -Line 5, characters 0-33: -5 | type _ t = T : 'a -> 'a Queue.t t;; (* fail *) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +val eq : (('a, 'b) Ephemeron.K1.t, ('c, 'd) Ephemeron.K1.t) eq = Eq +Line 4, characters 0-46: +4 | type _ t = T : 'a -> ('a, 'b) Ephemeron.K1.t t;; (* fail *) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: In this definition, a type variable cannot be deduced from the type parameters. |}];; diff --git a/testsuite/tests/typing-gadts/pr5989.ml b/testsuite/tests/typing-gadts/pr5989.ml index def3e533..3911e77a 100644 --- a/testsuite/tests/typing-gadts/pr5989.ml +++ b/testsuite/tests/typing-gadts/pr5989.ml @@ -28,7 +28,7 @@ module M : sig type s = private [> `A ] val eq : (s, [ `A | `B ]) t end Lines 16-17, characters 39-16: 16 | .......................................function 17 | | Any -> "Any" -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Eq val f : (M.s, [ `A | `B ]) t -> string = @@ -58,7 +58,7 @@ module N : Lines 12-13, characters 49-16: 12 | .................................................function 13 | | Any -> "Any" -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Eq val f : (N.s, < a : int; b : bool >) t -> string = diff --git a/testsuite/tests/typing-gadts/pr5997.ml b/testsuite/tests/typing-gadts/pr5997.ml index 27e35b35..d2e0f3c2 100644 --- a/testsuite/tests/typing-gadts/pr5997.ml +++ b/testsuite/tests/typing-gadts/pr5997.ml @@ -25,7 +25,7 @@ module M : sig type t = T val comp : (U.t, t) comp end Line 16, characters 0-33: 16 | match M.comp with | Diff -> false;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Eq Exception: Match_failure ("", 16, 0). @@ -48,7 +48,7 @@ module M : sig type t = { x : int; } val comp : (U.t, t) comp end Line 11, characters 0-33: 11 | match M.comp with | Diff -> false;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Eq Exception: Match_failure ("", 11, 0). diff --git a/testsuite/tests/typing-gadts/pr6174.ml b/testsuite/tests/typing-gadts/pr6174.ml index 9f672c4f..bf710891 100644 --- a/testsuite/tests/typing-gadts/pr6174.ml +++ b/testsuite/tests/typing-gadts/pr6174.ml @@ -11,5 +11,5 @@ Line 3, characters 24-25: 3 | fun C k -> k (fun x -> x);; ^ Error: This expression has type $0 but an expression was expected of type - $1 = ($2 -> $1) -> $1 + $1 = o |}];; diff --git a/testsuite/tests/typing-gadts/pr6241.ml b/testsuite/tests/typing-gadts/pr6241.ml index 330965f7..bd9e295c 100644 --- a/testsuite/tests/typing-gadts/pr6241.ml +++ b/testsuite/tests/typing-gadts/pr6241.ml @@ -24,7 +24,7 @@ type (_, _) t = A : ('a, 'a) t | B : string -> ('a, 'b) t Lines 8-9, characters 52-13: 8 | ....................................................function 9 | | B s -> s -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: A module M : diff --git a/testsuite/tests/typing-gadts/pr6690.ml b/testsuite/tests/typing-gadts/pr6690.ml index 858547ea..ebf308d0 100644 --- a/testsuite/tests/typing-gadts/pr6690.ml +++ b/testsuite/tests/typing-gadts/pr6690.ml @@ -34,19 +34,6 @@ Error: This pattern matches values of type but a pattern was expected which matches values of type ($0, $0 * insert, visit_action) context The type constructor $0 would escape its scope -|}, Principal{| -type 'a visit_action -type insert -type 'a local_visit_action -type ('a, 'result, 'visit_action) context = - Local : ('a, 'a * insert, 'a local_visit_action) context - | Global : ('a, 'a, 'a visit_action) context -Line 15, characters 4-9: -15 | | Local -> fun _ -> raise Exit - ^^^^^ -Error: This pattern matches values of type - ($0, $0 * insert, visit_action) context - The type constructor $0 would escape its scope |}];; let vexpr (type visit_action) @@ -64,13 +51,6 @@ Error: This pattern matches values of type but a pattern was expected which matches values of type ($'a, $'a * insert, visit_action) context The type constructor $'a would escape its scope -|}, Principal{| -Line 4, characters 4-9: -4 | | Local -> fun _ -> raise Exit - ^^^^^ -Error: This pattern matches values of type - ($0, $0 * insert, visit_action) context - The type constructor $0 would escape its scope |}];; let vexpr (type result) (type visit_action) diff --git a/testsuite/tests/typing-gadts/pr6993_bad.ml b/testsuite/tests/typing-gadts/pr6993_bad.ml index e33808a7..7f71417e 100644 --- a/testsuite/tests/typing-gadts/pr6993_bad.ml +++ b/testsuite/tests/typing-gadts/pr6993_bad.ml @@ -20,7 +20,7 @@ type (_, _) eqp = Y : ('a, 'a) eqp | N : string -> ('a, 'b) eqp Line 2, characters 36-66: 2 | let f : ('a list, 'a) eqp -> unit = function N s -> print_string s;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Y val f : ('a list, 'a) eqp -> unit = diff --git a/testsuite/tests/typing-gadts/pr7016.ml b/testsuite/tests/typing-gadts/pr7016.ml index be4f1a87..a0b92fab 100644 --- a/testsuite/tests/typing-gadts/pr7016.ml +++ b/testsuite/tests/typing-gadts/pr7016.ml @@ -14,7 +14,7 @@ type (_, _) t = Line 5, characters 9-43: 5 | let get1 (Cons (x, _) : (_ * 'a, 'a) t) = x ;; (* warn, cf PR#6993 *) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Nil val get1 : ('b * 'a, 'a) t -> 'b = @@ -24,8 +24,6 @@ let get1' = function | (Cons (x, _) : (_ * 'a, 'a) t) -> x | Nil -> assert false ;; (* ok *) [%%expect{| -val get1' : ('b * 'a as 'a, 'a) t -> 'b = -|}, Principal{| Line 3, characters 4-7: 3 | | Nil -> assert false ;; (* ok *) ^^^ diff --git a/testsuite/tests/typing-gadts/pr7222.ml b/testsuite/tests/typing-gadts/pr7222.ml index 683458b4..d0177e23 100644 --- a/testsuite/tests/typing-gadts/pr7222.ml +++ b/testsuite/tests/typing-gadts/pr7222.ml @@ -27,16 +27,4 @@ Error: This pattern matches values of type ($Cons_'x, 'a -> $Cons_'x) elt but a pattern was expected which matches values of type ($Cons_'x, 'a -> $'b -> nil) elt The type constructor $'b would escape its scope -|}, Principal{| -type +'a n = private int -type nil = private Nil_type -type (_, _) elt = - Elt_fine : 'nat n -> ('l, 'nat * 'l) elt - | Elt : 'nat n -> ('l, 'nat -> 'l) elt -type _ t = Nil : nil t | Cons : ('x, 'fx) elt * 'x t -> 'fx t -Line 9, characters 6-22: -9 | let Cons(Elt dim, _) = sh in () - ^^^^^^^^^^^^^^^^ -Error: This pattern matches values of type ('a -> $0 -> nil) t - The type constructor $0 would escape its scope |}];; diff --git a/testsuite/tests/typing-gadts/pr7234.ml b/testsuite/tests/typing-gadts/pr7234.ml index ae98e02c..fa7fb742 100644 --- a/testsuite/tests/typing-gadts/pr7234.ml +++ b/testsuite/tests/typing-gadts/pr7234.ml @@ -11,7 +11,7 @@ type 'a t Line 3, characters 15-40: 3 | let f (type a) (Neq n : (a, a t) eq) = n;; (* warn! *) ^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Eq val f : ('a, 'a t) eq -> int = @@ -24,7 +24,7 @@ end;; Line 2, characters 16-43: 2 | let f (type a) (Neq n : (a, a T.t) eq) = n (* warn! *) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Eq module F : diff --git a/testsuite/tests/typing-gadts/pr7269.ml b/testsuite/tests/typing-gadts/pr7269.ml index 9293eb3b..a3b967ad 100644 --- a/testsuite/tests/typing-gadts/pr7269.ml +++ b/testsuite/tests/typing-gadts/pr7269.ml @@ -14,7 +14,7 @@ type +'a t = T : [< `Conj of 'a & sub | `Other of string ] -> 'a t Line 4, characters 6-47: 4 | let f (T (`Other msg) : s t) = print_string msg;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: T (`Conj _) val f : s t -> unit = @@ -42,7 +42,7 @@ module M : Line 11, characters 12-59: 11 | let () = M.(match x with T (`Other msg) -> print_string msg);; (* warn *) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: T (`Conj _) Exception: Match_failure ("", 11, 12). @@ -74,7 +74,7 @@ module M : Line 13, characters 21-57: 13 | let () = M.(e { ex = fun (`Other msg) -> print_string msg });; (* warn *) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: `Conj _ Exception: Match_failure ("", 13, 21). diff --git a/testsuite/tests/typing-gadts/pr7374.ml b/testsuite/tests/typing-gadts/pr7374.ml index 1eb4166c..6e2d5e42 100644 --- a/testsuite/tests/typing-gadts/pr7374.ml +++ b/testsuite/tests/typing-gadts/pr7374.ml @@ -29,16 +29,22 @@ Error: This expression has type (a, a) eq Type a is not compatible with type t = [ `Rec of 'a ] X.t as 'a |}] -(* trigger segfault +(* Trigger the unsoundness if Fix were definable *) module Id = struct type 'a t = 'b constraint 'a = [ `Rec of 'b ] end - module Bad = Fix(Id) - -let segfault () = - print_endline (cast (trans (Bad.uniq Refl) (Bad.uniq Refl)) 0) -*) +let magic : type a b. a -> b = + fun x -> + let Refl = (Bad.uniq Refl : (a,Bad.t) eq) in + let Refl = (Bad.uniq Refl : (b,Bad.t) eq) in x +[%%expect{| +module Id : sig type 'a t = 'b constraint 'a = [ `Rec of 'b ] end +Line 4, characters 13-16: +4 | module Bad = Fix(Id) + ^^^ +Error: Unbound module Fix +|}] (* addendum: ensure that hidden paths are checked too *) module F (X : sig type 'a t end) = struct diff --git a/testsuite/tests/typing-gadts/pr7390.ml b/testsuite/tests/typing-gadts/pr7390.ml index 2a988e1c..4c7b65b3 100644 --- a/testsuite/tests/typing-gadts/pr7390.ml +++ b/testsuite/tests/typing-gadts/pr7390.ml @@ -24,7 +24,7 @@ let f (* : filled either -> string *) = Line 2, characters 2-28: 2 | fun (Either (Y a, N)) -> a;; ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Either (N, Y _) val f : filled either -> string = diff --git a/testsuite/tests/typing-gadts/pr7432.ml b/testsuite/tests/typing-gadts/pr7432.ml index 014fd7e4..f7efea65 100644 --- a/testsuite/tests/typing-gadts/pr7432.ml +++ b/testsuite/tests/typing-gadts/pr7432.ml @@ -24,7 +24,7 @@ let f : [`L of (s, t) eql | `R of silly] -> 'a = Line 2, characters 2-30: 2 | function `R {silly} -> silly ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: `L Refl val f : [ `L of (s, t) eql | `R of silly ] -> 'a = diff --git a/testsuite/tests/typing-gadts/pr7902.ml b/testsuite/tests/typing-gadts/pr7902.ml new file mode 100644 index 00000000..b88fc23e --- /dev/null +++ b/testsuite/tests/typing-gadts/pr7902.ml @@ -0,0 +1,33 @@ +(* TEST + * expect +*) + +type ('a, 'b) segment = + | SegNil : ('a, 'a) segment + | SegCons : ('a * 'a, 'b) segment -> ('a, 'b) segment + +let color : type a b . (a, b) segment -> int = function + | SegNil -> 0 + | SegCons SegNil -> 0 + | SegCons _ -> 0 +[%%expect{| +type ('a, 'b) segment = + SegNil : ('a, 'a) segment + | SegCons : ('a * 'a, 'b) segment -> ('a, 'b) segment +val color : ('a, 'b) segment -> int = +|}] + +(* Fail *) +let color (* : type a b . (a, b) segment -> int *) = function + | SegNil -> 0 + | SegCons SegNil -> 0 + | SegCons _ -> 0 +[%%expect{| +Line 3, characters 12-18: +3 | | SegCons SegNil -> 0 + ^^^^^^ +Error: This pattern matches values of type ('a * 'a, 'a * 'a) segment + but a pattern was expected which matches values of type + ('a * 'a, 'a) segment + The type variable 'a occurs inside 'a * 'a +|}] diff --git a/testsuite/tests/typing-gadts/pr9019.ml b/testsuite/tests/typing-gadts/pr9019.ml index 7a946bfb..f90cd232 100644 --- a/testsuite/tests/typing-gadts/pr9019.ml +++ b/testsuite/tests/typing-gadts/pr9019.ml @@ -36,7 +36,7 @@ Lines 4-8, characters 2-18: 6 | | MAB, _, A -> 2 7 | | _, AB, B -> 3 8 | | _, MAB, B -> 4 -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (AB, MAB, A) val f : 'x M.t -> 'x M.t -> 'x -> int = @@ -137,7 +137,7 @@ let f (type x) (t1 : x t) (t2 : x t) (x : x) = Line 7, characters 4-22: 7 | | _, AB, { a = _ } -> 3 ^^^^^^^^^^^^^^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. val f : 'x M.t -> 'x M.t -> 'x -> int = |}] @@ -167,7 +167,7 @@ Lines 9-11, characters 2-37: 9 | ..match a, a_or_b, x with 10 | | Not_A, A_or_B, `B i -> print_int i 11 | | _, A_or_B, `A s -> print_string s -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (A, A_or_B, `B _) val f : 'x a -> 'x a_or_b -> 'x -> unit = @@ -198,7 +198,7 @@ Lines 9-11, characters 2-18: 9 | ..match b, x, y with 10 | | B, `B String_option, Some s -> print_string s 11 | | A, `A, _ -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (B, `B String_option, None) val f : ('x, 'y ty) b -> 'x -> 'y -> unit = @@ -218,7 +218,7 @@ type 'a a = private [< `A of 'a ] Line 2, characters 18-44: 2 | let f (x : _ a) = match x with `A None -> ();; ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: `A (Some _) val f : 'a option a -> unit = @@ -229,7 +229,7 @@ let f (x : [> `A] a) = match x with `A `B -> ();; Line 1, characters 23-47: 1 | let f (x : [> `A] a) = match x with `A `B -> ();; ^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: `A `A val f : [< `A | `B > `A ] a -> unit = diff --git a/testsuite/tests/typing-gadts/pr9759.ml b/testsuite/tests/typing-gadts/pr9759.ml new file mode 100644 index 00000000..165eccdd --- /dev/null +++ b/testsuite/tests/typing-gadts/pr9759.ml @@ -0,0 +1,31 @@ +(* TEST + * expect +*) + +(* #9759 by Thomas Refis *) + +type 'a general = { indir: 'a desc; unit: unit } +and 'a desc = + | C : unit general -> unit desc ;; +[%%expect{| +type 'a general = { indir : 'a desc; unit : unit; } +and 'a desc = C : unit general -> unit desc +|}] + +let rec foo : type k . k general -> k general = fun g -> + match g.indir with + | C g' -> + let new_g' = foo g' in + if true then + {g with indir = C new_g'} + else + new_g' + | indir -> + {g with indir} ;; +[%%expect{| +Line 9, characters 4-9: +9 | | indir -> + ^^^^^ +Warning 11 [redundant-case]: this match case is unused. +val foo : 'k general -> 'k general = +|}] diff --git a/testsuite/tests/typing-gadts/pr9799.ml b/testsuite/tests/typing-gadts/pr9799.ml new file mode 100644 index 00000000..5d083684 --- /dev/null +++ b/testsuite/tests/typing-gadts/pr9799.ml @@ -0,0 +1,22 @@ +(* TEST + * expect +*) + +type 'a t = + | A: [`a|`z] t + | B: [`b|`z] t +;; +[%%expect{| +type 'a t = A : [ `a | `z ] t | B : [ `b | `z ] t +|}];; + +let fn: type a. a t -> a -> int = fun x y -> + match (x, y) with + | (A, `a) + | (B, `b) -> 0 + | (A, `z) + | (B, `z) -> 1 +;; +[%%expect{| +val fn : 'a t -> 'a -> int = +|}];; diff --git a/testsuite/tests/typing-gadts/principality-and-gadts.ml b/testsuite/tests/typing-gadts/principality-and-gadts.ml new file mode 100644 index 00000000..d2ca4ca2 --- /dev/null +++ b/testsuite/tests/typing-gadts/principality-and-gadts.ml @@ -0,0 +1,442 @@ +(* TEST + * expect *) + +module M = struct type t = A | B end;; +[%%expect{| +module M : sig type t = A | B end +|}];; + +type 'a t = I : int t | M : M.t t;; +[%%expect{| +type 'a t = I : int t | M : M.t t +|}];; + +type dyn = Sigma : 'a t * 'a -> dyn;; +[%%expect{| +type dyn = Sigma : 'a t * 'a -> dyn +|}];; + +let f = function Sigma (M, A) -> ();; +[%%expect{| +Line 1, characters 8-35: +1 | let f = function Sigma (M, A) -> ();; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Warning 8 [partial-match]: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +Sigma (M, B) +val f : dyn -> unit = +|}];; + +type _ t = IntLit : int t | BoolLit : bool t;; +[%%expect{| +type _ t = IntLit : int t | BoolLit : bool t +|}] + +(* The following should warn *) + +let f (type a) t (x : a) = + ignore (t : a t); + match t, x with + | IntLit, n -> n+1 + | BoolLit, b -> 1 +;; +[%%expect{| +val f : 'a t -> 'a -> int = +|}, Principal{| +Line 4, characters 4-10: +4 | | IntLit, n -> n+1 + ^^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering int and a as equal. +But the knowledge of these types is not principal. +Line 5, characters 4-11: +5 | | BoolLit, b -> 1 + ^^^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering bool and a as equal. +But the knowledge of these types is not principal. +val f : 'a t -> 'a -> int = +|}] + +let f (type a) t (x : a) = + ignore (t : a t); + match t, x with + | IntLit, n -> n+1 + | _, _ -> 1 +;; +[%%expect{| +val f : 'a t -> 'a -> int = +|}, Principal{| +Line 4, characters 4-10: +4 | | IntLit, n -> n+1 + ^^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering int and a as equal. +But the knowledge of these types is not principal. +val f : 'a t -> 'a -> int = +|}] + + +let f (type a) t (x : a) = + begin match t, x with + | IntLit, n -> n+1 + | BoolLit, b -> 1 + end; + ignore (t : a t) +;; +[%%expect{| +Line 4, characters 4-11: +4 | | BoolLit, b -> 1 + ^^^^^^^ +Error: This pattern matches values of type bool t + but a pattern was expected which matches values of type int t + Type bool is not compatible with type int +|}] + +let f (type a) t (x : a) = + begin match t, x with + | IntLit, n -> n+1 + | _, _ -> 1 + end; + ignore (t : a t) +;; +[%%expect{| +Line 3, characters 17-18: +3 | | IntLit, n -> n+1 + ^ +Error: This expression has type a but an expression was expected of type int +|}] + +(**********************) +(* Derived from #9019 *) +(**********************) + +type _ ab = A | B + +module M : sig + type _ mab + type _ t = AB : unit ab t | MAB : unit mab t +end = struct + type 'a mab = 'a ab = A | B + type _ t = AB : unit ab t | MAB : unit mab t +end;; +[%%expect{| +type _ ab = A | B +module M : sig type _ mab type _ t = AB : unit ab t | MAB : unit mab t end +|}] + +open M;; +[%%expect{| +|}] + +let f1 t1 = + match t1 with + | AB -> true + | MAB -> false;; +[%%expect{| +val f1 : unit ab M.t -> bool = +|}, Principal{| +Line 4, characters 4-7: +4 | | MAB -> false;; + ^^^ +Warning 18 [not-principal]: typing this pattern requires considering unit M.mab and unit ab as equal. +But the knowledge of these types is not principal. +val f1 : unit ab M.t -> bool = +|}] + +let f2 (type x) t1 = + ignore (t1 : x t); + match t1 with + | AB -> true + | MAB -> false;; +[%%expect{| +val f2 : 'x M.t -> bool = +|}, Principal{| +Line 4, characters 4-6: +4 | | AB -> true + ^^ +Warning 18 [not-principal]: typing this pattern requires considering unit ab and x as equal. +But the knowledge of these types is not principal. +Line 5, characters 4-7: +5 | | MAB -> false;; + ^^^ +Warning 18 [not-principal]: typing this pattern requires considering unit M.mab and x as equal. +But the knowledge of these types is not principal. +val f2 : 'x M.t -> bool = +|}] + +(* This should warn *) +let f3 t1 = + ignore (t1 : unit ab t); + match t1 with + | AB -> true + | MAB -> false;; +[%%expect{| +val f3 : unit ab M.t -> bool = +|}, Principal{| +Line 5, characters 4-7: +5 | | MAB -> false;; + ^^^ +Warning 18 [not-principal]: typing this pattern requires considering unit M.mab and unit ab as equal. +But the knowledge of these types is not principal. +val f3 : unit ab M.t -> bool = +|}] + +(* Example showing we need to warn when any part of the type is non generic. *) +type (_,_) eq = Refl : ('a,'a) eq;; +[%%expect{| +type (_, _) eq = Refl : ('a, 'a) eq +|}] + +let g1 (type x) (e : (x, int option) eq) (x : x) : int option = + let Refl = e in x;; +[%%expect{| +val g1 : ('x, int option) eq -> 'x -> int option = +|}] + +(* This should warn *) +let g2 (type x) (e : (x, _ option) eq) (x : x) : int option = + ignore (e : (x, int option) eq); + let Refl = e in x;; +[%%expect{| +val g2 : ('x, int option) eq -> 'x -> int option = +|}, Principal{| +Line 3, characters 7-11: +3 | let Refl = e in x;; + ^^^^ +Warning 18 [not-principal]: typing this pattern requires considering x and int option as equal. +But the knowledge of these types is not principal. +val g2 : ('x, int option) eq -> 'x -> int option = +|}] + +(* Issues with "principal level" *) + +module Foo : sig + type t +end = struct + type t = int +end + +type _ gadt = F : Foo.t gadt + +type 'a t = { a: 'a; b: 'a gadt } ;; +[%%expect{| +module Foo : sig type t end +type _ gadt = F : Foo.t gadt +type 'a t = { a : 'a; b : 'a gadt; } +|}] + +let () = + match [] with + | [ { a = 3; _ } ; { b = F; _ }] -> () + | _ -> ();; +[%%expect{| +|}, Principal{| +Line 3, characters 27-28: +3 | | [ { a = 3; _ } ; { b = F; _ }] -> () + ^ +Warning 18 [not-principal]: typing this pattern requires considering Foo.t and int as equal. +But the knowledge of these types is not principal. +|}] + +let () = + match [] with + | [ { b = F; _ } ; { a = 3; _ }] -> () + | _ -> ();; +[%%expect{| +Line 3, characters 27-28: +3 | | [ { b = F; _ } ; { a = 3; _ }] -> () + ^ +Error: This pattern matches values of type int + but a pattern was expected which matches values of type Foo.t +|}] + +type (_, _, _) eq3 = Refl3 : ('a, 'a, 'a) eq3 + +type 'a t = { a: 'a; b: (int, Foo.t, 'a) eq3 } +;; +[%%expect{| +type (_, _, _) eq3 = Refl3 : ('a, 'a, 'a) eq3 +type 'a t = { a : 'a; b : (int, Foo.t, 'a) eq3; } +|}] + +let () = + match [] with + | [ { a = 3; _ }; { b = Refl3 ; _ }] -> () + | _ -> () +;; +[%%expect{| +|}, Principal{| +Line 3, characters 26-31: +3 | | [ { a = 3; _ }; { b = Refl3 ; _ }] -> () + ^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering int and Foo.t as equal. +But the knowledge of these types is not principal. +|}] + +let () = + match [] with + | [ { b = Refl3 ; _ }; { a = 3; _ } ] -> () + | _ -> () +;; +[%%expect{| +|}, Principal{| +Line 3, characters 12-17: +3 | | [ { b = Refl3 ; _ }; { a = 3; _ } ] -> () + ^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering int and Foo.t as equal. +But the knowledge of these types is not principal. +|}] + +(* Unify with 'a first *) + +type 'a t = { a: 'a; b: ('a, int, Foo.t) eq3 } +;; +[%%expect{| +type 'a t = { a : 'a; b : ('a, int, Foo.t) eq3; } +|}] + +let () = + match [] with + | [ { a = 3; _ }; { b = Refl3 ; _ }] -> () + | _ -> () +[%%expect{| +|}, Principal{| +Line 3, characters 26-31: +3 | | [ { a = 3; _ }; { b = Refl3 ; _ }] -> () + ^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering int and Foo.t as equal. +But the knowledge of these types is not principal. +|}] + +let () = + match [] with + | [ { b = Refl3 ; _ }; { a = 3; _ } ] -> () + | _ -> () +[%%expect{| +|}, Principal{| +Line 3, characters 12-17: +3 | | [ { b = Refl3 ; _ }; { a = 3; _ } ] -> () + ^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering int and Foo.t as equal. +But the knowledge of these types is not principal. +|}] + + +(*************) +(* Some more *) +(*************) + +module M : sig type t end = struct type t = int end +module N : sig type t end = struct type t = int end +;; +[%%expect{| +module M : sig type t end +module N : sig type t end +|}] + +type 'a foo = { x : 'a; eq : (M.t, N.t, 'a) eq3 };; +[%%expect{| +type 'a foo = { x : 'a; eq : (M.t, N.t, 'a) eq3; } +|}] + +let foo x = + match x with + | { x = x; eq = Refl3 } -> x +;; +[%%expect{| +val foo : M.t foo -> M.t = +|}, Principal{| +Line 3, characters 18-23: +3 | | { x = x; eq = Refl3 } -> x + ^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering M.t and N.t as equal. +But the knowledge of these types is not principal. +val foo : M.t foo -> M.t = +|}] + +let foo x = + match x with + | { x = (x : int); eq = Refl3 } -> x +;; +[%%expect{| +val foo : int foo -> int = +|}, Principal{| +Line 3, characters 26-31: +3 | | { x = (x : int); eq = Refl3 } -> x + ^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering M.t and N.t as equal. +But the knowledge of these types is not principal. +val foo : int foo -> int = +|}] + +let foo x = + match x with + | { x = (x : N.t); eq = Refl3 } -> x +;; +[%%expect{| +Line 3, characters 4-33: +3 | | { x = (x : N.t); eq = Refl3 } -> x + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This pattern matches values of type N.t foo + but a pattern was expected which matches values of type 'a + This instance of M.t is ambiguous: + it would escape the scope of its equation +|}, Principal{| +Line 3, characters 26-31: +3 | | { x = (x : N.t); eq = Refl3 } -> x + ^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering M.t and N.t as equal. +But the knowledge of these types is not principal. +Line 3, characters 4-33: +3 | | { x = (x : N.t); eq = Refl3 } -> x + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This pattern matches values of type N.t foo + but a pattern was expected which matches values of type 'a + This instance of M.t is ambiguous: + it would escape the scope of its equation +|}] + +let foo x = + match x with + | { x = (x : string); eq = Refl3 } -> x +;; +[%%expect{| +val foo : string foo -> string = +|}, Principal{| +Line 3, characters 29-34: +3 | | { x = (x : string); eq = Refl3 } -> x + ^^^^^ +Warning 18 [not-principal]: typing this pattern requires considering M.t and string as equal. +But the knowledge of these types is not principal. +val foo : string foo -> string = +|}] + +let bar x = + match x with + | { x = x; _ } -> x +;; +[%%expect{| +val bar : 'a foo -> 'a = +|}] + +let bar x = + match x with + | { x = (x : int); _ } -> x +;; +[%%expect{| +val bar : int foo -> int = +|}] + +let bar x = + match x with + | { x = (x : N.t); _ } -> x +;; +[%%expect{| +val bar : N.t foo -> N.t = +|}] + +let bar x = + match x with + | { x = (x : string); _ } -> x +;; +[%%expect{| +val bar : string foo -> string = +|}] diff --git a/testsuite/tests/typing-gadts/test.ml b/testsuite/tests/typing-gadts/test.ml index a91f685e..d210724a 100644 --- a/testsuite/tests/typing-gadts/test.ml +++ b/testsuite/tests/typing-gadts/test.ml @@ -106,16 +106,16 @@ module Nonexhaustive = Lines 11-12, characters 6-19: 11 | ......function 12 | | C2 x -> x -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: C1 _ Lines 24-26, characters 6-30: 24 | ......function 25 | | Foo _ , Foo _ -> true 26 | | Bar _, Bar _ -> true -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: -(Bar _, Foo _) +(Foo _, Bar _) module Nonexhaustive : sig type 'a u = C1 : int -> int u | C2 : bool -> bool u @@ -160,13 +160,13 @@ end;; Line 2, characters 10-18: 2 | class c (Some x) = object method x : int = x end ^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: None Line 4, characters 10-18: 4 | class d (Just x) = object method x : int = x end ^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Nothing module PR6862 : @@ -195,7 +195,7 @@ end;; Line 4, characters 43-44: 4 | let g : int t -> int = function I -> 1 | _ -> 2 (* warn *) ^ -Warning 56: this match case is unreachable. +Warning 56 [unreachable-case]: this match case is unreachable. Consider replacing it with a refutation case ' -> .' module PR6220 : sig @@ -263,7 +263,7 @@ end;; Lines 8-9, characters 4-33: 8 | ....match x with 9 | | String s -> print_endline s................. -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Any module PR6801 : @@ -385,12 +385,6 @@ Line 5, characters 28-29: ^ Error: This variant pattern is expected to have type a The constructor B does not belong to type a -|}, Principal{| -Line 5, characters 28-29: -5 | let f = function A -> 1 | B -> 2 - ^ -Error: This pattern matches values of type b - but a pattern was expected which matches values of type a |}];; module PR6849 = struct @@ -924,7 +918,7 @@ Lines 2-8, characters 2-16: 6 | | TE TC, D [|1.0|] -> 14 7 | | TA, D 0 -> -1 8 | | TA, D z -> z -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (TE TC, D [| 0. |]) val f : 'a ty -> 'a t -> int = @@ -988,7 +982,7 @@ Lines 4-10, characters 2-29: 8 | | {left=TE TC; right=D [|1.0|]} -> 14 9 | | {left=TA; right=D 0} -> -1 10 | | {left=TA; right=D z} -> z -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {left=TE TC; right=D [| 0. |]} val f : 'a ty -> 'a t -> int = diff --git a/testsuite/tests/typing-gadts/yallop_bugs.ml b/testsuite/tests/typing-gadts/yallop_bugs.ml index d94e63fd..7cbaf3ec 100644 --- a/testsuite/tests/typing-gadts/yallop_bugs.ml +++ b/testsuite/tests/typing-gadts/yallop_bugs.ml @@ -60,9 +60,9 @@ Lines 5-7, characters 39-23: 5 | .......................................function 6 | | BoolLit, false -> false 7 | | IntLit , 6 -> false -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: -(IntLit, 0) +(BoolLit, true) val check : 's t * 's -> bool = |}];; @@ -78,8 +78,8 @@ Lines 3-5, characters 45-38: 3 | .............................................function 4 | | {fst = BoolLit; snd = false} -> false 5 | | {fst = IntLit ; snd = 6} -> false -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: -{fst=IntLit; snd=0} +{fst=BoolLit; snd=true} val check : ('s t, 's) pair -> bool = |}];; diff --git a/testsuite/tests/typing-implicit_unpack/implicit_unpack.ml b/testsuite/tests/typing-implicit_unpack/implicit_unpack.ml index 04334d66..5a4b2941 100644 --- a/testsuite/tests/typing-implicit_unpack/implicit_unpack.ml +++ b/testsuite/tests/typing-implicit_unpack/implicit_unpack.ml @@ -50,9 +50,9 @@ val f : (module S with type t = int) -> int = let f (module M : S with type t = 'a) = M.x;; (* Error *) [%%expect{| -Line 1, characters 6-37: +Line 1, characters 14-15: 1 | let f (module M : S with type t = 'a) = M.x;; (* Error *) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ^ Error: The type of this packed module contains variables: (module S with type t = 'a) |}];; @@ -303,7 +303,7 @@ end module type MapT = sig type key - type +'a t + type +!'a t val empty : 'a t val is_empty : 'a t -> bool val mem : key -> 'a t -> bool @@ -341,6 +341,7 @@ module type MapT = val map : ('a -> 'b) -> 'a t -> 'b t val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t val to_seq : 'a t -> (key * 'a) Seq.t + val to_rev_seq : 'a t -> (key * 'a) Seq.t val to_seq_from : key -> 'a t -> (key * 'a) Seq.t val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t val of_seq : (key * 'a) Seq.t -> 'a t @@ -393,6 +394,7 @@ module SSMap : val map : ('a -> 'b) -> 'a t -> 'b t val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t val to_seq : 'a t -> (key * 'a) Seq.t + val to_rev_seq : 'a t -> (key * 'a) Seq.t val to_seq_from : key -> 'a t -> (key * 'a) Seq.t val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t val of_seq : (key * 'a) Seq.t -> 'a t diff --git a/testsuite/tests/typing-misc/build_as_type.ml b/testsuite/tests/typing-misc/build_as_type.ml new file mode 100644 index 00000000..6e5efcb1 --- /dev/null +++ b/testsuite/tests/typing-misc/build_as_type.ml @@ -0,0 +1,155 @@ +(* TEST + * expect +*) + +let f = function + | ([] : int list) as x -> x + | _ :: _ -> assert false;; +[%%expect{| +val f : int list -> int list = +|}] + +let f = + let f' = function + | ([] : 'a list) as x -> x + | _ :: _ -> assert false + in + f', f';; +[%%expect{| +val f : ('a list -> 'a list) * ('a list -> 'a list) = (, ) +|}] + +let f = + let f' = function + | ([] : _ list) as x -> x + | _ :: _ -> assert false + in + f', f';; +[%%expect{| +val f : ('a list -> 'b list) * ('c list -> 'd list) = (, ) +|}] + +let f = + let f' (type a) = function + | ([] : a list) as x -> x + | _ :: _ -> assert false + in + f', f';; +[%%expect{| +val f : ('a list -> 'a list) * ('b list -> 'b list) = (, ) +|}] + +type t = [ `A | `B ];; +[%%expect{| +type t = [ `A | `B ] +|}] + +let f = function `A as x -> x | `B -> `A;; +[%%expect{| +val f : [< `A | `B ] -> [> `A ] = +|}] + +let f = function (`A : t) as x -> x | `B -> `A;; +[%%expect{| +val f : t -> t = +|}] + +let f : t -> _ = function `A as x -> x | `B -> `A;; +[%%expect{| +val f : t -> [> `A ] = +|}] + +let f = function + | (`A : t) as x -> + (* This should be flagged as non-exhaustive: because of the constraint [x] + is of type [t]. *) + begin match x with + | `A -> () + end + | `B -> ();; +[%%expect{| +Lines 5-7, characters 4-7: +5 | ....begin match x with +6 | | `A -> () +7 | end +Warning 8 [partial-match]: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +`B +val f : t -> unit = +|}] + + +let f = function + | (`A : t) as x -> + begin match x with + | `A -> () + | `B -> () + end + | `B -> ();; +[%%expect{| +val f : t -> unit = +|}] + + +let f = function + | (`A : t) as x -> + begin match x with + | `A -> () + | `B -> () + | `C -> () + end + | `B -> ();; +[%%expect{| +Line 6, characters 6-8: +6 | | `C -> () + ^^ +Error: This pattern matches values of type [? `C ] + but a pattern was expected which matches values of type t + The second variant type does not allow tag(s) `C +|}] + +let f = function (`A, _ : _ * int) as x -> x;; +[%%expect{| +val f : [< `A ] * int -> [> `A ] * int = +|}] + +(* Make sure *all* the constraints are respected: *) + +let f = function + | ((`A : _) : t) as x -> + (* This should be flagged as non-exhaustive: because of the constraint [x] + is of type [t]. *) + begin match x with + | `A -> () + end + | `B -> ();; +[%%expect{| +Lines 5-7, characters 4-7: +5 | ....begin match x with +6 | | `A -> () +7 | end +Warning 8 [partial-match]: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +`B +val f : t -> unit = +|}] + +let f = function + | ((`A : t) : _) as x -> + (* This should be flagged as non-exhaustive: because of the constraint [x] + is of type [t]. *) + begin match x with + | `A -> () + end + | `B -> ();; + +[%%expect{| +Lines 5-7, characters 4-7: +5 | ....begin match x with +6 | | `A -> () +7 | end +Warning 8 [partial-match]: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +`B +val f : t -> unit = +|}] diff --git a/testsuite/tests/typing-misc/constraints.ml b/testsuite/tests/typing-misc/constraints.ml index 0fe7387a..a612030e 100644 --- a/testsuite/tests/typing-misc/constraints.ml +++ b/testsuite/tests/typing-misc/constraints.ml @@ -85,17 +85,31 @@ Error: The definition of abs contains a cycle: 'a is_an_object as 'a |}];; -module PR6505a = struct +module PR6505a_old = struct type 'o is_an_object = < .. > as 'o and ('k,'l) abs = 'l constraint 'k = 'l is_an_object let y : ('o, 'o) abs = object end end;; +[%%expect{| +Line 3, characters 7-9: +3 | and ('k,'l) abs = 'l constraint 'k = 'l is_an_object + ^^ +Error: Constraints are not satisfied in this type. + Type 'l is_an_object should be an instance of < .. > is_an_object +|}] + +module PR6505a = struct + type 'o is_an_object = < .. > as 'o + type ('k,'l) abs = 'l constraint 'k = 'l is_an_object + let y : ('o, 'o) abs = object end +end;; let _ = PR6505a.y#bang;; (* fails *) [%%expect{| module PR6505a : sig type 'o is_an_object = 'o constraint 'o = < .. > - and ('a, 'l) abs = 'l constraint 'a = 'l is_an_object + type ('a, 'b) abs = 'b constraint 'a = 'b is_an_object + constraint 'b = < .. > val y : (< > is_an_object, < > is_an_object) abs end Line 6, characters 8-17: @@ -108,7 +122,8 @@ Error: This expression has type module PR6505a : sig type 'o is_an_object = 'o constraint 'o = < .. > - and ('a, 'l) abs = 'l constraint 'a = 'l is_an_object + type ('a, 'b) abs = 'b constraint 'a = 'b is_an_object + constraint 'b = < .. > val y : (< >, < >) abs end Line 6, characters 8-17: @@ -120,7 +135,7 @@ Error: This expression has type (< >, < >) PR6505a.abs module PR6505b = struct type 'o is_an_object = [> ] as 'o - and ('k,'l) abs = 'l constraint 'k = 'l is_an_object + type ('k,'l) abs = 'l constraint 'k = 'l is_an_object let x : ('a, 'a) abs = `Foo 6 end;; let () = print_endline (match PR6505b.x with `Bar s -> s);; (* fails *) @@ -128,14 +143,119 @@ let () = print_endline (match PR6505b.x with `Bar s -> s);; (* fails *) module PR6505b : sig type 'o is_an_object = 'o constraint 'o = [> ] - and ('a, 'l) abs = 'l constraint 'a = 'l is_an_object + type ('a, 'b) abs = 'b constraint 'a = 'b is_an_object + constraint 'b = [> ] val x : (([> `Foo of int ] as 'a) is_an_object, 'a is_an_object) abs end Line 6, characters 23-57: 6 | let () = print_endline (match PR6505b.x with `Bar s -> s);; (* fails *) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: `Foo _ Exception: Match_failure ("", 6, 23). |}] + + +(* #9866, #9873 *) + +type 'a t = 'b constraint 'a = 'b t;; +[%%expect{| +Line 1, characters 0-36: +1 | type 'a t = 'b constraint 'a = 'b t;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This recursive type is not regular. + The type constructor t is defined as + type 'b t t + but it is used as + 'b t. + All uses need to match the definition for the recursive type to be regular. +|}] + +type 'a t = 'b constraint 'a = ('b * 'b) t;; +[%%expect{| +Line 1, characters 0-42: +1 | type 'a t = 'b constraint 'a = ('b * 'b) t;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This recursive type is not regular. + The type constructor t is defined as + type ('b * 'b) t t + but it is used as + ('b * 'b) t. + All uses need to match the definition for the recursive type to be regular. +|}] + +type 'a t = 'a * 'b constraint _ * 'a = 'b t;; +type 'a t = 'a * 'b constraint 'a = 'b t;; +[%%expect{| +type 'b t = 'b * 'b +Line 2, characters 0-40: +2 | type 'a t = 'a * 'b constraint 'a = 'b t;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: The type abbreviation t is cyclic +|}] + +type 'a t = constraint 'a = 'b t;; +[%%expect{| +Line 1, characters 0-49: +1 | type 'a t = constraint 'a = 'b t;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This recursive type is not regular. + The type constructor t is defined as + type 'b t t + but it is used as + 'b t. + All uses need to match the definition for the recursive type to be regular. +|}] + +type 'a t = constraint = 'b t;; +[%%expect{| +Line 1, characters 0-59: +1 | type 'a t = constraint = 'b t;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: A type variable is unbound in this type declaration. +In method b: 'b the variable 'b is unbound +|}] + +module rec M : sig type 'a t = 'b constraint 'a = 'b t end = M;; +[%%expect{| +Line 1, characters 19-54: +1 | module rec M : sig type 'a t = 'b constraint 'a = 'b t end = M;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This recursive type is not regular. + The type constructor t is defined as + type 'b t t + but it is used as + 'b t. + All uses need to match the definition for the recursive type to be regular. +|}] +module rec M : sig type 'a t = 'b constraint 'a = ('b * 'b) t end = M;; +[%%expect{| +Line 1, characters 19-61: +1 | module rec M : sig type 'a t = 'b constraint 'a = ('b * 'b) t end = M;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This recursive type is not regular. + The type constructor t is defined as + type ('b * 'b) t t + but it is used as + ('b * 'b) t. + All uses need to match the definition for the recursive type to be regular. +|}] + +module type S = +sig + type !'a s + type !'a t = 'b constraint 'a = 'b s +end +[%%expect{| +module type S = sig type !'a s type 'a t = 'b constraint 'a = 'b s end +|}] + +(* This still causes a stack overflow *) +(* +module rec M : S = +struct + type !'a s = 'a M.t + type !'a t = 'b constraint 'a = 'b s +end +*) diff --git a/testsuite/tests/typing-misc/disambiguate_principality.ml b/testsuite/tests/typing-misc/disambiguate_principality.ml index d1b61f03..8fb21545 100644 --- a/testsuite/tests/typing-misc/disambiguate_principality.ml +++ b/testsuite/tests/typing-misc/disambiguate_principality.ml @@ -37,7 +37,7 @@ let after_a = Line 3, characters 2-20: 3 | { x with lbl = 4 } ^^^^^^^^^^^^^^^^^^ -Warning 23: all the fields are explicitly listed in this record: +Warning 23 [useless-record-with]: all the fields are explicitly listed in this record: the 'with' clause is useless. val after_a : M.r = {M.lbl = 4} |}] @@ -52,7 +52,7 @@ val b : unit = () Line 3, characters 7-18: 3 | x := { lbl = 4 } ^^^^^^^^^^^ -Warning 18: this type-based record disambiguation is not principal. +Warning 18 [not-principal]: this type-based record disambiguation is not principal. val b : unit = () |}] @@ -110,13 +110,18 @@ let h x = Line 4, characters 4-15: 4 | | { lbl = _ } -> () ^^^^^^^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. val h : M.r -> unit = |}, Principal{| -Line 4, characters 6-9: +Line 4, characters 4-15: 4 | | { lbl = _ } -> () - ^^^ -Error: Unbound record field lbl + ^^^^^^^^^^^ +Warning 18 [not-principal]: this type-based record disambiguation is not principal. +Line 4, characters 4-15: +4 | | { lbl = _ } -> () + ^^^^^^^^^^^ +Warning 11 [redundant-case]: this match case is unused. +val h : M.r -> unit = |}] let i x = @@ -140,7 +145,17 @@ let j x = Line 4, characters 4-15: 4 | | { lbl = _ } -> () ^^^^^^^^^^^ -Warning 12: this sub-pattern is unused. +Warning 12 [redundant-subpat]: this sub-pattern is unused. +val j : M.r -> unit = +|}, Principal{| +Line 4, characters 4-15: +4 | | { lbl = _ } -> () + ^^^^^^^^^^^ +Warning 18 [not-principal]: this type-based record disambiguation is not principal. +Line 4, characters 4-15: +4 | | { lbl = _ } -> () + ^^^^^^^^^^^ +Warning 12 [redundant-subpat]: this sub-pattern is unused. val j : M.r -> unit = |}] @@ -184,13 +199,18 @@ let n x = Line 4, characters 4-30: 4 | | { contents = { lbl = _ } } -> () ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. val n : M.r ref -> unit = |}, Principal{| -Line 4, characters 19-22: +Line 4, characters 17-28: 4 | | { contents = { lbl = _ } } -> () - ^^^ -Error: Unbound record field lbl + ^^^^^^^^^^^ +Warning 18 [not-principal]: this type-based record disambiguation is not principal. +Line 4, characters 4-30: +4 | | { contents = { lbl = _ } } -> () + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Warning 11 [redundant-case]: this match case is unused. +val n : M.r ref -> unit = |}] let o x = @@ -214,7 +234,17 @@ let p x = Line 4, characters 4-30: 4 | | { contents = { lbl = _ } } -> () ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 12: this sub-pattern is unused. +Warning 12 [redundant-subpat]: this sub-pattern is unused. +val p : M.r ref -> unit = +|}, Principal{| +Line 4, characters 17-28: +4 | | { contents = { lbl = _ } } -> () + ^^^^^^^^^^^ +Warning 18 [not-principal]: this type-based record disambiguation is not principal. +Line 4, characters 4-30: +4 | | { contents = { lbl = _ } } -> () + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Warning 12 [redundant-subpat]: this sub-pattern is unused. val p : M.r ref -> unit = |}] @@ -250,7 +280,7 @@ val s : M.r ref -> unit = Line 4, characters 9-20: 4 | x := { lbl = 4 } ^^^^^^^^^^^ -Warning 18: this type-based record disambiguation is not principal. +Warning 18 [not-principal]: this type-based record disambiguation is not principal. val s : M.r ref -> unit = |}] @@ -264,7 +294,7 @@ val t : M.r ref -> unit = Line 3, characters 9-20: 3 | x := { lbl = 4 } ^^^^^^^^^^^ -Warning 18: this type-based record disambiguation is not principal. +Warning 18 [not-principal]: this type-based record disambiguation is not principal. val t : M.r ref -> unit = |}] @@ -274,12 +304,6 @@ let u = function ;; [%%expect{| val u : M.r ref -> int = -|}, Principal{| -Line 3, characters 7-10: -3 | !x.lbl - ^^^ -Warning 18: this type-based field disambiguation is not principal. -val u : M.r ref -> int = |}] @@ -320,7 +344,7 @@ val b : unit = () Line 3, characters 7-8: 3 | x := B ^ -Warning 18: this type-based constructor disambiguation is not principal. +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. val b : unit = () |}] @@ -364,7 +388,8 @@ val h : M.t -> unit = Line 4, characters 4-5: 4 | | B -> () ^ -Error: Unbound constructor B +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. +val h : M.t -> unit = |}] let i x = @@ -386,6 +411,12 @@ let j x = ;; [%%expect{| val j : M.t -> unit = +|}, Principal{| +Line 4, characters 4-5: +4 | | B -> () + ^ +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. +val j : M.t -> unit = |}] let k x = @@ -428,13 +459,18 @@ let n x = Line 4, characters 4-20: 4 | | { contents = A } -> () ^^^^^^^^^^^^^^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. val n : M.t ref -> unit = |}, Principal{| Line 4, characters 17-18: 4 | | { contents = A } -> () ^ -Error: Unbound constructor A +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. +Line 4, characters 4-20: +4 | | { contents = A } -> () + ^^^^^^^^^^^^^^^^ +Warning 11 [redundant-case]: this match case is unused. +val n : M.t ref -> unit = |}] let o x = @@ -458,7 +494,17 @@ let p x = Line 4, characters 4-20: 4 | | { contents = A } -> () ^^^^^^^^^^^^^^^^ -Warning 12: this sub-pattern is unused. +Warning 12 [redundant-subpat]: this sub-pattern is unused. +val p : M.t ref -> unit = +|}, Principal{| +Line 4, characters 17-18: +4 | | { contents = A } -> () + ^ +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. +Line 4, characters 4-20: +4 | | { contents = A } -> () + ^^^^^^^^^^^^^^^^ +Warning 12 [redundant-subpat]: this sub-pattern is unused. val p : M.t ref -> unit = |}] @@ -485,7 +531,7 @@ val s : M.t ref -> unit = Line 4, characters 9-10: 4 | x := A ^ -Warning 18: this type-based constructor disambiguation is not principal. +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. val s : M.t ref -> unit = |}] @@ -498,7 +544,7 @@ Lines 1-3, characters 8-10: 1 | ........function 2 | | ({ contents = M.A } : M.t ref) as x -> 3 | x := B -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {contents=B} val t : M.t ref -> unit = @@ -506,12 +552,12 @@ val t : M.t ref -> unit = Line 3, characters 9-10: 3 | x := B ^ -Warning 18: this type-based constructor disambiguation is not principal. +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. Lines 1-3, characters 8-10: 1 | ........function 2 | | ({ contents = M.A } : M.t ref) as x -> 3 | x := B -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {contents=B} val t : M.t ref -> unit = diff --git a/testsuite/tests/typing-misc/empty_variant.ml b/testsuite/tests/typing-misc/empty_variant.ml index 40a81602..aaa1f0d6 100644 --- a/testsuite/tests/typing-misc/empty_variant.ml +++ b/testsuite/tests/typing-misc/empty_variant.ml @@ -57,7 +57,7 @@ module Runner : sig val ac : f:((unit, 'a, unit) t -> unit) -> unit end Lines 16-17, characters 8-18: 16 | ........match abc with 17 | | A _ -> 1 -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: C () val f : unit -> unit = @@ -72,7 +72,7 @@ type 'b t = A | B of 'b | C Line 3, characters 22-42: 3 | let g (x:nothing t) = match x with A -> () ^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: C val g : nothing t -> unit = diff --git a/testsuite/tests/typing-misc/injectivity.ml b/testsuite/tests/typing-misc/injectivity.ml new file mode 100644 index 00000000..afe16e4b --- /dev/null +++ b/testsuite/tests/typing-misc/injectivity.ml @@ -0,0 +1,437 @@ +(* TEST + * expect +*) + +(* Syntax *) + +type ! 'a t = private 'a ref +type +! 'a t = private 'a +type -!'a t = private 'a -> unit +type + !'a t = private 'a +type - ! 'a t = private 'a -> unit +type !+ 'a t = private 'a +type !-'a t = private 'a -> unit +type ! +'a t = private 'a +type ! -'a t = private 'a -> unit +[%%expect{| +type 'a t = private 'a ref +type +'a t = private 'a +type -'a t = private 'a -> unit +type +'a t = private 'a +type -'a t = private 'a -> unit +type +'a t = private 'a +type -'a t = private 'a -> unit +type +'a t = private 'a +type -'a t = private 'a -> unit +|}] +(* Expect doesn't support syntax errors +type -+ 'a t +[%%expect] +type -!! 'a t +[%%expect] +*) + +(* Define an injective abstract type, and use it in a GADT + and a constrained type *) +module M : sig type +!'a t end = struct type 'a t = 'a list end +[%%expect{| +module M : sig type +!'a t end +|}] +type _ t = M : 'a -> 'a M.t t (* OK *) +type 'a u = 'b constraint 'a = 'b M.t +[%%expect{| +type _ t = M : 'a -> 'a M.t t +type 'a u = 'b constraint 'a = 'b M.t +|}] + +(* Without the injectivity annotation, the cannot be defined *) +module N : sig type +'a t end = struct type 'a t = 'a list end +[%%expect{| +module N : sig type +'a t end +|}] +type _ t = N : 'a -> 'a N.t t (* KO *) +[%%expect{| +Line 1, characters 0-29: +1 | type _ t = N : 'a -> 'a N.t t (* KO *) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: In this definition, a type variable cannot be deduced + from the type parameters. +|}] +type 'a u = 'b constraint 'a = 'b N.t +[%%expect{| +Line 1, characters 0-37: +1 | type 'a u = 'b constraint 'a = 'b N.t + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: In this definition, a type variable cannot be deduced + from the type parameters. +|}] + +(* Of course, the internal type should be injective in this parameter *) +module M : sig type +!'a t end = struct type 'a t = int end (* KO *) +[%%expect{| +Line 1, characters 33-59: +1 | module M : sig type +!'a t end = struct type 'a t = int end (* KO *) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: Signature mismatch: + Modules do not match: + sig type 'a t = int end + is not included in + sig type +!'a t end + Type declarations do not match: + type 'a t = int + is not included in + type +!'a t + Their variances do not agree. +|}] + +(* Annotations in type abbreviations allow to check injectivity *) +type !'a t = 'a list +type !'a u = int +[%%expect{| +type 'a t = 'a list +Line 2, characters 0-16: +2 | type !'a u = int + ^^^^^^^^^^^^^^^^ +Error: In this definition, expected parameter variances are not satisfied. + The 1st type parameter was expected to be injective invariant, + but it is unrestricted. +|}] +type !'a t = private 'a list +type !'a t = private int +[%%expect{| +type 'a t = private 'a list +Line 2, characters 0-24: +2 | type !'a t = private int + ^^^^^^^^^^^^^^^^^^^^^^^^ +Error: In this definition, expected parameter variances are not satisfied. + The 1st type parameter was expected to be injective invariant, + but it is unrestricted. +|}] + +(* Can also use to add injectivity in private row types *) +module M : sig type !'a t = private < m : int ; .. > end = + struct type 'a t = < m : int ; n : 'a > end +type 'a u = M : 'a -> 'a M.t u +[%%expect{| +module M : sig type !'a t = private < m : int; .. > end +type 'a u = M : 'a -> 'a M.t u +|}] +module M : sig type 'a t = private < m : int ; .. > end = + struct type 'a t = < m : int ; n : 'a > end +type 'a u = M : 'a -> 'a M.t u +[%%expect{| +module M : sig type 'a t = private < m : int; .. > end +Line 3, characters 0-30: +3 | type 'a u = M : 'a -> 'a M.t u + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: In this definition, a type variable cannot be deduced + from the type parameters. +|}] +module M : sig type !'a t = private < m : int ; .. > end = + struct type 'a t = < m : int > end +[%%expect{| +Line 2, characters 2-36: +2 | struct type 'a t = < m : int > end + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: Signature mismatch: + Modules do not match: + sig type 'a t = < m : int > end + is not included in + sig type !'a t = private < m : int; .. > end + Type declarations do not match: + type 'a t = < m : int > + is not included in + type !'a t + Their variances do not agree. +|}] + +(* Injectivity annotations are inferred correctly for constrained parameters *) +type 'a t = 'b constraint 'a = +type !'b u = t +[%%expect{| +type 'a t = 'b constraint 'a = < b : 'b > +type 'b u = < b : 'b > t +|}] + +(* Ignore injectivity for nominal types *) +type !_ t = X +[%%expect{| +type _ t = X +|}] + +(* Beware of constrained parameters *) +type (_,_) eq = Refl : ('a,'a) eq +type !'a t = private 'b constraint 'a = < b : 'b > (* OK *) +[%%expect{| +type (_, _) eq = Refl : ('a, 'a) eq +type 'a t = private 'b constraint 'a = < b : 'b > +|}] + +type !'a t = private 'b constraint 'a = < b : 'b; c : 'c > (* KO *) +module M : sig type !'a t constraint 'a = < b : 'b; c : 'c > end = + struct type nonrec 'a t = 'a t end +let inj_t : type a b. ( M.t, M.t) eq -> (a, b) eq = + fun Refl -> Refl +[%%expect{| +Line 1, characters 0-58: +1 | type !'a t = private 'b constraint 'a = < b : 'b; c : 'c > (* KO *) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: In this definition, expected parameter variances are not satisfied. + The 1st type parameter was expected to be injective invariant, + but it is unrestricted. +|}] + +(* One cannot assume that abstract types are not injective *) +module F(X : sig type 'a t end) = struct + type 'a u = unit constraint 'a = 'b X.t + type _ x = G : 'a -> 'a u x +end +module M = F(struct type 'a t = 'a end) +let M.G (x : bool) = M.G 3 +[%%expect{| +Line 3, characters 2-29: +3 | type _ x = G : 'a -> 'a u x + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: In this definition, a type variable cannot be deduced + from the type parameters. +|}] + +(* Try to be clever *) +type 'a t = unit +type !'a u = int constraint 'a = 'b t +[%%expect{| +type 'a t = unit +type 'a u = int constraint 'a = 'b t +|}] +module F(X : sig type 'a t end) = struct + type !'a u = 'b constraint 'a = constraint 'b = _ X.t +end +[%%expect{| +module F : + functor (X : sig type 'a t end) -> + sig type 'a u = 'b X.t constraint 'a = < b : 'b X.t > end +|}] +(* But not too clever *) +module F(X : sig type 'a t end) = struct + type !'a u = 'b X.t constraint 'a = +end +[%%expect{| +Line 2, characters 2-50: +2 | type !'a u = 'b X.t constraint 'a = + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: In this definition, expected parameter variances are not satisfied. + The 1st type parameter was expected to be injective invariant, + but it is unrestricted. +|}] +module F(X : sig type 'a t end) = struct + type !'a u = 'b constraint 'a = +end +[%%expect{| +module F : + functor (X : sig type 'a t end) -> + sig type 'a u = 'b X.t constraint 'a = < b : 'b X.t > end +|}, Principal{| +Line 2, characters 2-51: +2 | type !'a u = 'b constraint 'a = + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: In this definition, expected parameter variances are not satisfied. + The 1st type parameter was expected to be injective invariant, + but it is unrestricted. +|}] + +(* Motivating examples with GADTs *) + +type (_,_) eq = Refl : ('a,'a) eq + +module Vec : sig + type +!'a t + val make : int -> (int -> 'a) -> 'a t + val get : 'a t -> int -> 'a +end = struct + type 'a t = Vec of Obj.t array + let make n f = Vec (Obj.magic Array.init n f) + let get (Vec v) n = Obj.obj (Array.get v n) +end + +type _ ty = + | Int : int ty + | Fun : 'a ty * 'b ty -> ('a -> 'b) ty + | Vec : 'a ty -> 'a Vec.t ty + +type dyn = Dyn : 'a ty * 'a -> dyn + +let rec eq_ty : type a b. a ty -> b ty -> (a,b) eq option = + fun t1 t2 -> match t1, t2 with + | Int, Int -> Some Refl + | Fun (t11, t12), Fun (t21, t22) -> + begin match eq_ty t11 t21, eq_ty t12 t22 with + | Some Refl, Some Refl -> Some Refl + | _ -> None + end + | Vec t1, Vec t2 -> + begin match eq_ty t1 t2 with + | Some Refl -> Some Refl + | None -> None + end + | _ -> None + +let undyn : type a. a ty -> dyn -> a option = + fun t1 (Dyn (t2, v)) -> + match eq_ty t1 t2 with + | Some Refl -> Some v + | None -> None + +let v = Vec.make 3 (fun n -> Vec.make n (fun m -> (m*n))) + +let int_vec_vec = Vec (Vec Int) + +let d = Dyn (int_vec_vec, v) + +let Some v' = undyn int_vec_vec d +[%%expect{| +type (_, _) eq = Refl : ('a, 'a) eq +module Vec : + sig + type +!'a t + val make : int -> (int -> 'a) -> 'a t + val get : 'a t -> int -> 'a + end +type _ ty = + Int : int ty + | Fun : 'a ty * 'b ty -> ('a -> 'b) ty + | Vec : 'a ty -> 'a Vec.t ty +type dyn = Dyn : 'a ty * 'a -> dyn +val eq_ty : 'a ty -> 'b ty -> ('a, 'b) eq option = +val undyn : 'a ty -> dyn -> 'a option = +val v : int Vec.t Vec.t = +val int_vec_vec : int Vec.t Vec.t ty = Vec (Vec Int) +val d : dyn = Dyn (Vec (Vec Int), ) +Line 47, characters 4-11: +47 | let Some v' = undyn int_vec_vec d + ^^^^^^^ +Warning 8 [partial-match]: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +None +val v' : int Vec.t Vec.t = +|}] + +(* Break it (using magic) *) +module Vec : sig + type +!'a t + val eqt : ('a t, 'b t) eq +end = struct + type 'a t = 'a + let eqt = Obj.magic Refl (* Never do that! *) +end + +type _ ty = + | Int : int ty + | Vec : 'a ty -> 'a Vec.t ty + +let coe : type a b. (a,b) eq -> a ty -> b ty = + fun Refl x -> x +let eq_int_any : type a. unit -> (int, a) eq = fun () -> + let vec_ty : a Vec.t ty = coe Vec.eqt (Vec Int) in + let Vec Int = vec_ty in Refl +[%%expect{| +module Vec : sig type +!'a t val eqt : ('a t, 'b t) eq end +type _ ty = Int : int ty | Vec : 'a ty -> 'a Vec.t ty +val coe : ('a, 'b) eq -> 'a ty -> 'b ty = +Line 17, characters 2-30: +17 | let Vec Int = vec_ty in Refl + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Warning 8 [partial-match]: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +Vec (Vec Int) +val eq_int_any : unit -> (int, 'a) eq = +|}] + +(* Not directly related: injectivity and constraints *) +type 'a t = 'b constraint 'a = +class type ['a] ct = object method m : 'b constraint 'a = < b : 'b > end +[%%expect{| +type 'a t = 'b constraint 'a = < b : 'b > +class type ['a] ct = object constraint 'a = < b : 'b > method m : 'b end +|}] + +type _ u = M : 'a -> 'a t u (* OK *) +[%%expect{| +type _ u = M : < b : 'a > -> < b : 'a > t u +|}] +type _ v = M : 'a -> 'a ct v (* OK *) +[%%expect{| +type _ v = M : < b : 'a > -> < b : 'a > ct v +|}] + +type 'a t = 'b constraint 'a = +type _ u = M : 'a -> 'a t u (* KO *) +[%%expect{| +type 'a t = 'b constraint 'a = < b : 'b; c : 'c > +Line 2, characters 0-27: +2 | type _ u = M : 'a -> 'a t u (* KO *) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: In this definition, a type variable cannot be deduced + from the type parameters. +|}] + + +(* #9721 by Jeremy Yallop *) + +(* First, some standard bits and pieces for equality & injectivity: *) + +type (_,_) eql = Refl : ('a, 'a) eql + +module Uninj(X: sig type !'a t end) : +sig val uninj : ('a X.t, 'b X.t) eql -> ('a, 'b) eql end = +struct let uninj : type a b. (a X.t, b X.t) eql -> (a, b) eql = fun Refl -> Refl end + +let coerce : type a b. (a, b) eql -> a -> b = fun Refl x -> x;; +[%%expect{| +type (_, _) eql = Refl : ('a, 'a) eql +module Uninj : + functor (X : sig type !'a t end) -> + sig val uninj : ('a X.t, 'b X.t) eql -> ('a, 'b) eql end +val coerce : ('a, 'b) eql -> 'a -> 'b = +|}] + +(* Now the questionable part, defining two "injective" type definitions in + a pair of mutually-recursive modules. These definitions are correctly + rejected if given as a pair of mutually-recursive types, but wrongly + accepted when defined as follows: +*) + +module rec R : sig type !'a t = [ `A of 'a S.t] end = R + and S : sig type !'a t = 'a R.t end = S ;; +[%%expect{| +Line 1, characters 19-47: +1 | module rec R : sig type !'a t = [ `A of 'a S.t] end = R + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: In this definition, expected parameter variances are not satisfied. + The 1st type parameter was expected to be injective invariant, + but it is invariant. +|}] + +(* The parameter of R.t is never used, so we can build an equality witness + for any instantiation: *) + +let x_eq_y : (int R.t, string R.t) eql = Refl +let boom = let module U = Uninj(R) in print_endline (coerce (U.uninj x_eq_y) 0) +;; +[%%expect{| +Line 1, characters 18-21: +1 | let x_eq_y : (int R.t, string R.t) eql = Refl + ^^^ +Error: Unbound module R +|}] + +(* #10028 by Stephen Dolan *) + +module rec A : sig + type _ t = Foo : 'a -> 'a A.s t + type 'a s = T of 'a +end = + A +;; +[%%expect{| +module rec A : sig type _ t = Foo : 'a -> 'a A.s t type 'a s = T of 'a end +|}] diff --git a/testsuite/tests/typing-misc/labels.ml b/testsuite/tests/typing-misc/labels.ml index 62e1c07b..3b2d32b8 100644 --- a/testsuite/tests/typing-misc/labels.ml +++ b/testsuite/tests/typing-misc/labels.ml @@ -10,7 +10,7 @@ val f : x:int -> int = Line 2, characters 5-6: 2 | f ?x:0;; ^ -Warning 43: the label x is not optional. +Warning 43 [nonoptional-label]: the label x is not optional. - : int = 1 |}];; @@ -65,7 +65,7 @@ val f : (?x:int -> unit -> int) -> int = Line 1, characters 51-52: 1 | let f g = ignore (g : ?x:int -> unit -> int); g ~x:3 () ;; ^ -Warning 18: using an optional argument here is not principal. +Warning 18 [not-principal]: using an optional argument here is not principal. val f : (?x:int -> unit -> int) -> int = |}];; @@ -76,7 +76,7 @@ val f : (?x:int -> unit -> int) -> int = Line 1, characters 46-47: 1 | let f g = ignore (g : ?x:int -> unit -> int); g ();; ^ -Warning 19: eliminated optional argument without principality. +Warning 19 [non-principal-labels]: eliminated optional argument without principality. val f : (?x:int -> unit -> int) -> int = |}];; @@ -87,7 +87,7 @@ val f : (x:int -> unit -> int) -> x:int -> int = Line 1, characters 45-46: 1 | let f g = ignore (g : x:int -> unit -> int); g ();; ^ -Warning 19: commuted an argument without principality. +Warning 19 [non-principal-labels]: commuted an argument without principality. val f : (x:int -> unit -> int) -> x:int -> int = |}];; diff --git a/testsuite/tests/typing-misc/normalize_type.ml b/testsuite/tests/typing-misc/normalize_type.ml new file mode 100644 index 00000000..0b21b183 --- /dev/null +++ b/testsuite/tests/typing-misc/normalize_type.ml @@ -0,0 +1,20 @@ +(* TEST + * expect +*) + +(* #8907 *) + +module M = struct + type t = int + let f (x : [< `Foo of t & int & string]) = () +end;; +[%%expect{| +module M : sig type t = int val f : [< `Foo of t & int & string ] -> unit end +|}] + +type t = int +let f (x : [< `Foo of t & int & string]) = () ;; +[%%expect{| +type t = int +val f : [< `Foo of t & int & string ] -> unit = +|}] diff --git a/testsuite/tests/typing-misc/polyvars.ml b/testsuite/tests/typing-misc/polyvars.ml index 52bc178f..e5647f61 100644 --- a/testsuite/tests/typing-misc/polyvars.ml +++ b/testsuite/tests/typing-misc/polyvars.ml @@ -37,7 +37,7 @@ let f (x : [< `A | `B]) = match x with `A | `B | `C -> 0;; (* warn *) Line 1, characters 49-51: 1 | let f (x : [< `A | `B]) = match x with `A | `B | `C -> 0;; (* warn *) ^^ -Warning 12: this sub-pattern is unused. +Warning 12 [redundant-subpat]: this sub-pattern is unused. val f : [< `A | `B ] -> int = |}];; let f (x : [`A | `B]) = match x with `A | `B | `C -> 0;; (* fail *) @@ -73,31 +73,31 @@ type t = A | B Line 9, characters 0-41: 9 | function (`A|`B), _ -> 0 | _,(`A|`B) -> 1;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (`AnyOtherTag, `AnyOtherTag) - : [> `A | `B ] * [> `A | `B ] -> int = Line 10, characters 0-29: 10 | function `B,1 -> 1 | _,1 -> 2;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (_, 0) Line 10, characters 21-24: 10 | function `B,1 -> 1 | _,1 -> 2;; ^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. - : [< `B ] * int -> int = Line 11, characters 0-29: 11 | function 1,`B -> 1 | 1,_ -> 2;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (0, _) Line 11, characters 21-24: 11 | function 1,`B -> 1 | 1,_ -> 2;; ^^^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. - : int * [< `B ] -> int = |}];; @@ -138,7 +138,7 @@ type t = private [> `A of string ] Line 2, characters 0-24: 2 | function (`A x : t) -> x;; ^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: ` - : t -> string = @@ -149,7 +149,7 @@ let f = function `AnyOtherTag, _ -> 1 | _, (`AnyOtherTag|`AnyOtherTag') -> 2;; Line 1, characters 8-76: 1 | let f = function `AnyOtherTag, _ -> 1 | _, (`AnyOtherTag|`AnyOtherTag') -> 2;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (`AnyOtherTag', `AnyOtherTag'') val f : [> `AnyOtherTag ] * [> `AnyOtherTag | `AnyOtherTag' ] -> int = diff --git a/testsuite/tests/typing-misc/pr6416.ml b/testsuite/tests/typing-misc/pr6416.ml index bda17f1d..43edff68 100644 --- a/testsuite/tests/typing-misc/pr6416.ml +++ b/testsuite/tests/typing-misc/pr6416.ml @@ -385,7 +385,7 @@ module Foo : sig type info = { doc : unit; } type t = { info : info; } end Line 5, characters 38-41: 5 | let add_extra_info arg = arg.Foo.info.doc ^^^ -Warning 40: doc was selected from type Foo.info. +Warning 40 [name-out-of-scope]: doc was selected from type Foo.info. It is not visible in the current scope, and will not be selected if the type becomes unknown. val add_extra_info : Foo.t -> unit = @@ -407,7 +407,7 @@ module Bar : sig end Line 8, characters 38-41: 8 | let add_extra_info arg = arg.Foo.info.doc ^^^ -Warning 40: doc was selected from type Bar/2.info. +Warning 40 [name-out-of-scope]: doc was selected from type Bar/2.info. It is not visible in the current scope, and will not be selected if the type becomes unknown. val add_extra_info : Foo.t -> unit = diff --git a/testsuite/tests/typing-misc/pr6939-flat-float-array.ml b/testsuite/tests/typing-misc/pr6939-flat-float-array.ml index 2fe2fcd5..d869300c 100644 --- a/testsuite/tests/typing-misc/pr6939-flat-float-array.ml +++ b/testsuite/tests/typing-misc/pr6939-flat-float-array.ml @@ -8,7 +8,7 @@ let rec x = [| x |]; 1.;; Line 1, characters 12-19: 1 | let rec x = [| x |]; 1.;; ^^^^^^^ -Warning 10: this expression should have type unit. +Warning 10 [non-unit-statement]: this expression should have type unit. Line 1, characters 12-23: 1 | let rec x = [| x |]; 1.;; ^^^^^^^^^^^ diff --git a/testsuite/tests/typing-misc/pr6939-no-flat-float-array.ml b/testsuite/tests/typing-misc/pr6939-no-flat-float-array.ml index a08bb57a..1450efc7 100644 --- a/testsuite/tests/typing-misc/pr6939-no-flat-float-array.ml +++ b/testsuite/tests/typing-misc/pr6939-no-flat-float-array.ml @@ -8,7 +8,7 @@ let rec x = [| x |]; 1.;; Line 1, characters 12-19: 1 | let rec x = [| x |]; 1.;; ^^^^^^^ -Warning 10: this expression should have type unit. +Warning 10 [non-unit-statement]: this expression should have type unit. val x : float = 1. |}];; @@ -17,7 +17,7 @@ let rec x = let u = [|y|] in 10. and y = 1.;; Line 1, characters 16-17: 1 | let rec x = let u = [|y|] in 10. and y = 1.;; ^ -Warning 26: unused variable u. +Warning 26 [unused-var]: unused variable u. val x : float = 10. val y : float = 1. |}];; diff --git a/testsuite/tests/typing-misc/pr7937.ml b/testsuite/tests/typing-misc/pr7937.ml index c4e42c7d..731252b2 100644 --- a/testsuite/tests/typing-misc/pr7937.ml +++ b/testsuite/tests/typing-misc/pr7937.ml @@ -15,13 +15,11 @@ Error: This expression has type bool but an expression was expected of type Types for tag `X are incompatible |}, Principal{| type 'a r = 'a constraint 'a = [< `X of int & 'a ] -Line 3, characters 30-31: +Line 3, characters 35-39: 3 | let f: 'a. 'a r -> 'a r = fun x -> true;; - ^ -Error: This pattern matches values of type + ^^^^ +Error: This expression has type bool but an expression was expected of type ([< `X of 'b & 'a & 'c & 'd & 'e ] as 'a) r - but a pattern was expected which matches values of type - ([< `X of int & 'f ] as 'f) r Types for tag `X are incompatible |}] @@ -34,13 +32,12 @@ Error: This expression has type int ref but an expression was expected of type ([< `X of int & 'a ] as 'a) r Types for tag `X are incompatible |}, Principal{| -Line 1, characters 30-31: +Line 1, characters 35-51: 1 | let g: 'a. 'a r -> 'a r = fun x -> { contents = 0 };; - ^ -Error: This pattern matches values of type + ^^^^^^^^^^^^^^^^ +Error: This expression has type int ref + but an expression was expected of type ([< `X of 'b & 'a & 'c & 'd & 'e ] as 'a) r - but a pattern was expected which matches values of type - ([< `X of int & 'f ] as 'f) r Types for tag `X are incompatible |}] @@ -53,14 +50,6 @@ Error: This pattern matches values of type bool but a pattern was expected which matches values of type ([< `X of int & 'a ] as 'a) r Types for tag `X are incompatible -|}, Principal{| -Line 1, characters 32-36: -1 | let h: 'a. 'a r -> _ = function true | false -> ();; - ^^^^ -Error: This pattern matches values of type bool - but a pattern was expected which matches values of type - ([< `X of 'b & 'a & 'c ] as 'a) r - Types for tag `X are incompatible |}] @@ -73,12 +62,4 @@ Error: This pattern matches values of type int ref but a pattern was expected which matches values of type ([< `X of int & 'a ] as 'a) r Types for tag `X are incompatible -|}, Principal{| -Line 1, characters 32-48: -1 | let i: 'a. 'a r -> _ = function { contents = 0 } -> ();; - ^^^^^^^^^^^^^^^^ -Error: This pattern matches values of type int ref - but a pattern was expected which matches values of type - ([< `X of 'b & 'a & 'c ] as 'a) r - Types for tag `X are incompatible |}] diff --git a/testsuite/tests/typing-misc/printing.ml b/testsuite/tests/typing-misc/printing.ml index 911ba30e..526bfa8f 100644 --- a/testsuite/tests/typing-misc/printing.ml +++ b/testsuite/tests/typing-misc/printing.ml @@ -99,3 +99,20 @@ Error: This expression has type t1 but an expression was expected of type t2 but the expected method type was 'a. 'a * ('a * < m : 'a. 'b >) as 'b The universal variable 'a would escape its scope |}] + +(* #9739 + Recursive occurence checks are only done on type variables. + However, we are not guaranteed to still have a type variable when printing. +*) + +let rec foo () = [42] +and bar () = + let x = foo () in + x |> List.fold_left max 0 x +[%%expect {| +Line 4, characters 7-29: +4 | x |> List.fold_left max 0 x + ^^^^^^^^^^^^^^^^^^^^^^ +Error: This expression has type int but an expression was expected of type + int list -> 'a +|}] diff --git a/testsuite/tests/typing-misc/records.ml b/testsuite/tests/typing-misc/records.ml index d11f1b4e..51623ef2 100644 --- a/testsuite/tests/typing-misc/records.ml +++ b/testsuite/tests/typing-misc/records.ml @@ -171,7 +171,7 @@ let r = { (assert false) with contents = 1 } ;; Line 1, characters 8-44: 1 | let r = { (assert false) with contents = 1 } ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 23: all the fields are explicitly listed in this record: +Warning 23 [useless-record-with]: all the fields are explicitly listed in this record: the 'with' clause is useless. Exception: Assert_failure ("", 1, 10). |}] diff --git a/testsuite/tests/typing-misc/typecore_nolabel_errors.ml b/testsuite/tests/typing-misc/typecore_nolabel_errors.ml index 6a3ba99b..04ecb525 100644 --- a/testsuite/tests/typing-misc/typecore_nolabel_errors.ml +++ b/testsuite/tests/typing-misc/typecore_nolabel_errors.ml @@ -27,15 +27,15 @@ Error: The function applied to this argument has type x:'a -> unit This argument cannot be applied with label ~y |}] -let f ?x ~a ?y ~z = () +let f ?x ~a ?y ~z () = () let g = f ?y:None ?x:None ~a:() [%%expect {| -val f : ?x:'a -> a:'b -> ?y:'c -> z:'d -> unit = +val f : ?x:'a -> a:'b -> ?y:'c -> z:'d -> unit -> unit = Line 2, characters 13-17: 2 | let g = f ?y:None ?x:None ~a:() ^^^^ Error: The function applied to this argument has type - ?x:'a -> a:'b -> ?y:'c -> z:'d -> unit + ?x:'a -> a:'b -> ?y:'c -> z:'d -> unit -> unit This argument cannot be applied with label ?y Since OCaml 4.11, optional arguments do not commute when -nolabels is given |}] diff --git a/testsuite/tests/typing-missing-cmi-3/middle.ml b/testsuite/tests/typing-missing-cmi-3/middle.ml index cc4b1322..82e64582 100644 --- a/testsuite/tests/typing-missing-cmi-3/middle.ml +++ b/testsuite/tests/typing-missing-cmi-3/middle.ml @@ -3,3 +3,6 @@ type 'a t = 'a Original.t = T let f: (module Original.T with type t = int) -> unit = fun _ -> () let x = (module struct type t end: Original.T ) let g: (module Original.T) -> unit = fun _ -> () +type pack1 = (module Original.T with type t = int) +module type T = sig module M : Original.T end +type pack2 = (module T with type M.t = int) diff --git a/testsuite/tests/typing-missing-cmi-3/user.ml b/testsuite/tests/typing-missing-cmi-3/user.ml index aacd19f7..9543db9d 100644 --- a/testsuite/tests/typing-missing-cmi-3/user.ml +++ b/testsuite/tests/typing-missing-cmi-3/user.ml @@ -45,3 +45,45 @@ Line 1, characters 26-36: Error: Signature mismatch: Modules do not match: sig end is not included in Original.T |}] + +let foo (x : Middle.pack1) = + let module M = (val x) in + () +[%%expect {| +Line 2, characters 17-24: +2 | let module M = (val x) in + ^^^^^^^ +Error: The type of this packed module refers to Original.T, which is missing +|}] + +let foo (x : Middle.pack2) = + let module M = (val x) in + () +[%%expect {| +Line 2, characters 17-24: +2 | let module M = (val x) in + ^^^^^^^ +Error: The type of this packed module refers to Original.T, which is missing +|}] + +module type T1 = sig type t = int end +let foo x = (x : Middle.pack1 :> (module T1)) +[%%expect {| +module type T1 = sig type t = int end +Line 2, characters 12-45: +2 | let foo x = (x : Middle.pack1 :> (module T1)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: Type Middle.pack1 = (module Original.T with type t = int) + is not a subtype of (module T1) +|}] + +module type T2 = sig module M : sig type t = int end end +let foo x = (x : Middle.pack2 :> (module T2)) +[%%expect {| +module type T2 = sig module M : sig type t = int end end +Line 2, characters 12-45: +2 | let foo x = (x : Middle.pack2 :> (module T2)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: Type Middle.pack2 = (module Middle.T with type M.t = int) + is not a subtype of (module T2) +|}] diff --git a/testsuite/tests/typing-modules/aliases.ml b/testsuite/tests/typing-modules/aliases.ml index aac8c2a0..440498b5 100644 --- a/testsuite/tests/typing-modules/aliases.ml +++ b/testsuite/tests/typing-modules/aliases.ml @@ -318,6 +318,7 @@ module StringSet : val of_list : elt list -> t val to_seq_from : elt -> t -> elt Seq.t val to_seq : t -> elt Seq.t + val to_rev_seq : t -> elt Seq.t val add_seq : elt Seq.t -> t -> t val of_seq : elt Seq.t -> t end @@ -364,6 +365,7 @@ module SSet : val of_list : elt list -> t val to_seq_from : elt -> t -> elt Seq.t val to_seq : t -> elt Seq.t + val to_rev_seq : t -> elt Seq.t val add_seq : elt Seq.t -> t -> t val of_seq : elt Seq.t -> t end @@ -442,6 +444,7 @@ module A : val of_list : elt list -> t val to_seq_from : elt -> t -> elt Seq.t val to_seq : t -> elt Seq.t + val to_rev_seq : t -> elt Seq.t val add_seq : elt Seq.t -> t -> t val of_seq : elt Seq.t -> t end @@ -451,27 +454,44 @@ module A1 = A - : bool = true |}];; -(* PR#3476 *) -(* Does not work yet *) +(* PR#3476: *) module FF(X : sig end) = struct type t end module M = struct module X = struct end - module Y = FF (X) (* XXX *) + module Y = FF (X) type t = Y.t end module F (Y : sig type t end) (M : sig type t = Y.t end) = struct end;; module G = F (M.Y);; -(*module N = G (M);; -module N = F (M.Y) (M);;*) +module N = G (M);; +module N = F (M.Y) (M);; [%%expect{| module FF : functor (X : sig end) -> sig type t end module M : sig module X : sig end module Y : sig type t = FF(X).t end type t = Y.t end module F : functor (Y : sig type t end) (M : sig type t = Y.t end) -> sig end module G : functor (M : sig type t = M.Y.t end) -> sig end +module N : sig end +module N : sig end |}];; +(* PR#5058 *) +module F (M : sig end) : sig type t end = struct type t = int end +module T = struct +module M = struct end +include F(M) +end +include T +let f (x : t) : T.t = x +[%%expect {| +module F : functor (M : sig end) -> sig type t end +module T : sig module M : sig end type t = F(M).t end +module M = T.M +type t = F(M).t +val f : t -> T.t = +|}] + (* PR#6307 *) module A1 = struct end @@ -555,6 +575,7 @@ module SInt : val of_list : elt list -> t val to_seq_from : elt -> t -> elt Seq.t val to_seq : t -> elt Seq.t + val to_rev_seq : t -> elt Seq.t val add_seq : elt Seq.t -> t -> t val of_seq : elt Seq.t -> t end diff --git a/testsuite/tests/typing-modules/applicative_functor_type.ml b/testsuite/tests/typing-modules/applicative_functor_type.ml index e62b7e63..04678757 100644 --- a/testsuite/tests/typing-modules/applicative_functor_type.ml +++ b/testsuite/tests/typing-modules/applicative_functor_type.ml @@ -25,7 +25,7 @@ Error: The type of M does not match Set.Make's parameter is not included in Set.OrderedType The value `compare' is required but not provided - File "set.mli", line 52, characters 4-31: Expected declaration + File "set.mli", line 55, characters 4-31: Expected declaration |} ] diff --git a/testsuite/tests/typing-modules/nondep.ml b/testsuite/tests/typing-modules/nondep.ml index 6662dc5b..cade7075 100644 --- a/testsuite/tests/typing-modules/nondep.ml +++ b/testsuite/tests/typing-modules/nondep.ml @@ -19,3 +19,19 @@ Error: This functor has type The parameter cannot be eliminated in the result type. Please bind the argument to a module identifier. |}] + +module M (X : sig type 'a t constraint 'a = float end) = struct + module type S = sig + type t = float + val foo : t X.t + end +end + +module N = M (struct type 'a t = int constraint 'a = float end) + +[%%expect{| +module M : + functor (X : sig type 'a t constraint 'a = float end) -> + sig module type S = sig type t = float val foo : t X.t end end +module N : sig module type S = sig type t = float val foo : int end end +|}] diff --git a/testsuite/tests/typing-modules/pr6633.ml b/testsuite/tests/typing-modules/pr6633.ml new file mode 100644 index 00000000..084cc63c --- /dev/null +++ b/testsuite/tests/typing-modules/pr6633.ml @@ -0,0 +1,69 @@ +(* TEST + * expect +*) + + +(* If a module is used as a module type it should trigger the hint. *) +module Equal = struct end +module Foo = functor (E : Equal) -> struct end;; +[%%expect{| +module Equal : sig end +Line 2, characters 26-31: +2 | module Foo = functor (E : Equal) -> struct end;; + ^^^^^ +Error: Unbound module type Equal +Hint: There is a module named Equal, but modules are not module types +|}] + +(* If there is a typo in the module type name it should trigger the + spellcheck. +*) +module type Equals = sig end +module Foo = functor (E : EqualF) -> struct end;; +[%%expect{| +module type Equals = sig end +Line 2, characters 26-32: +2 | module Foo = functor (E : EqualF) -> struct end;; + ^^^^^^ +Error: Unbound module type EqualF +Hint: Did you mean Equals? +|}] + +(* If a module is used as a module type it should trigger the hint + (even it is a typo). *) +module type Equal = sig end +module EqualF = struct end +module Foo = functor (E : EqualF) -> struct end;; +[%%expect{| +module type Equal = sig end +module EqualF : sig end +Line 3, characters 26-32: +3 | module Foo = functor (E : EqualF) -> struct end;; + ^^^^^^ +Error: Unbound module type EqualF +Hint: There is a module named EqualF, but modules are not module types +|}] + +(* If a module type is used as a module it should trigger the hint. *) +module type S = sig type t val show: t -> string end +let f (x: S.t ) = ();; +[%%expect{| +module type S = sig type t val show : t -> string end +Line 2, characters 10-13: +2 | let f (x: S.t ) = ();; + ^^^ +Error: Unbound module S +Hint: There is a module type named S, but module types are not modules +|}] + +(* If a class type is used as a class it should trigger the hint. *) +class type ct = object method m: int end +class c = object inherit ct end +[%%expect{| +class type ct = object method m : int end +Line 2, characters 25-27: +2 | class c = object inherit ct end + ^^ +Error: Unbound class ct +Hint: There is a class type named ct, but classes are not class types +|}] diff --git a/testsuite/tests/typing-modules/pr7818.ml b/testsuite/tests/typing-modules/pr7818.ml index 62ed82fa..84f7d8f7 100644 --- a/testsuite/tests/typing-modules/pr7818.ml +++ b/testsuite/tests/typing-modules/pr7818.ml @@ -274,6 +274,7 @@ module MkT : val of_list : elt list -> t val to_seq_from : elt -> t -> elt Seq.t val to_seq : t -> elt Seq.t + val to_rev_seq : t -> elt Seq.t val add_seq : elt Seq.t -> t -> t val of_seq : elt Seq.t -> t end diff --git a/testsuite/tests/typing-objects-bugs/pr7284_bad.compilers.reference b/testsuite/tests/typing-objects-bugs/pr7284_bad.compilers.reference index de957e79..648d3fea 100644 --- a/testsuite/tests/typing-objects-bugs/pr7284_bad.compilers.reference +++ b/testsuite/tests/typing-objects-bugs/pr7284_bad.compilers.reference @@ -1,6 +1,6 @@ File "pr7284_bad.ml", line 35, characters 30-62: 35 | let f : X.v1 wit -> unit = function V1 s -> print_endline s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Error (warning 8): this pattern-matching is not exhaustive. +Error (warning 8 [partial-match]): this pattern-matching is not exhaustive. Here is an example of a case that is not matched: V2 _ diff --git a/testsuite/tests/typing-objects/Exemples.ml b/testsuite/tests/typing-objects/Exemples.ml index 00cbde53..dca5d1b8 100644 --- a/testsuite/tests/typing-objects/Exemples.ml +++ b/testsuite/tests/typing-objects/Exemples.ml @@ -289,7 +289,7 @@ end;; Line 3, characters 10-27: 3 | inherit printable_point y as super ^^^^^^^^^^^^^^^^^ -Warning 13: the following instance variables are overridden by the class printable_point : +Warning 13 [instance-variable-override]: the following instance variables are overridden by the class printable_point : x The behaviour changed in ocaml 3.10 (previous behaviour was hiding.) class printable_color_point : @@ -618,7 +618,7 @@ let pr l = Line 2, characters 2-69: 2 | List.map (fun c -> Format.print_int c#x; Format.print_string " ") l; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 10: this expression should have type unit. +Warning 10 [non-unit-statement]: this expression should have type unit. val pr : < x : int; .. > list -> unit = |}];; let l = [new int_comparable 5; (new int_comparable3 2 :> int_comparable); diff --git a/testsuite/tests/typing-objects/Tests.ml b/testsuite/tests/typing-objects/Tests.ml index 82a2bbc9..7bd13f19 100644 --- a/testsuite/tests/typing-objects/Tests.ml +++ b/testsuite/tests/typing-objects/Tests.ml @@ -472,24 +472,24 @@ end;; Line 3, characters 10-13: 3 | inherit c 5 ^^^ -Warning 13: the following instance variables are overridden by the class c : +Warning 13 [instance-variable-override]: the following instance variables are overridden by the class c : x The behaviour changed in ocaml 3.10 (previous behaviour was hiding.) Line 4, characters 6-7: 4 | val y = 3 ^ -Warning 13: the instance variable y is overridden. +Warning 13 [instance-variable-override]: the instance variable y is overridden. The behaviour changed in ocaml 3.10 (previous behaviour was hiding.) Line 6, characters 10-13: 6 | inherit d 7 ^^^ -Warning 13: the following instance variables are overridden by the class d : +Warning 13 [instance-variable-override]: the following instance variables are overridden by the class d : t z The behaviour changed in ocaml 3.10 (previous behaviour was hiding.) Line 7, characters 6-7: 7 | val u = 3 ^ -Warning 13: the instance variable u is overridden. +Warning 13 [instance-variable-override]: the instance variable u is overridden. The behaviour changed in ocaml 3.10 (previous behaviour was hiding.) class e : unit -> @@ -791,7 +791,7 @@ fun (x : 'a t) -> (x : 'a); ();; Line 1, characters 18-26: 1 | fun (x : 'a t) -> (x : 'a); ();; ^^^^^^^^ -Warning 10: this expression should have type unit. +Warning 10 [non-unit-statement]: this expression should have type unit. - : ('a t as 'a) t -> unit = |}];; diff --git a/testsuite/tests/typing-ocamlc-i/pervasives_leitmotiv.compilers.reference b/testsuite/tests/typing-ocamlc-i/pervasives_leitmotiv.compilers.reference index def5d748..ec49bdc0 100644 --- a/testsuite/tests/typing-ocamlc-i/pervasives_leitmotiv.compilers.reference +++ b/testsuite/tests/typing-ocamlc-i/pervasives_leitmotiv.compilers.reference @@ -1,5 +1,5 @@ File "pervasives_leitmotiv.ml", line 1: -Warning 63: The printed interface differs from the inferred interface. +Warning 63 [erroneous-printed-signature]: The printed interface differs from the inferred interface. The inferred interface contained items which could not be printed properly due to name collisions between identifiers. File "pervasives_leitmotiv.ml", lines 10-12, characters 0-3: diff --git a/testsuite/tests/typing-ocamlc-i/pr4791.compilers.reference b/testsuite/tests/typing-ocamlc-i/pr4791.compilers.reference index b4938f16..0ea6e282 100644 --- a/testsuite/tests/typing-ocamlc-i/pr4791.compilers.reference +++ b/testsuite/tests/typing-ocamlc-i/pr4791.compilers.reference @@ -1,5 +1,5 @@ File "pr4791.ml", line 1: -Warning 63: The printed interface differs from the inferred interface. +Warning 63 [erroneous-printed-signature]: The printed interface differs from the inferred interface. The inferred interface contained items which could not be printed properly due to name collisions between identifiers. File "pr4791.ml", line 11, characters 2-12: diff --git a/testsuite/tests/typing-ocamlc-i/pr6323.compilers.reference b/testsuite/tests/typing-ocamlc-i/pr6323.compilers.reference index c06cebec..29e3342f 100644 --- a/testsuite/tests/typing-ocamlc-i/pr6323.compilers.reference +++ b/testsuite/tests/typing-ocamlc-i/pr6323.compilers.reference @@ -1,5 +1,5 @@ File "pr6323.ml", line 1: -Warning 63: The printed interface differs from the inferred interface. +Warning 63 [erroneous-printed-signature]: The printed interface differs from the inferred interface. The inferred interface contained items which could not be printed properly due to name collisions between identifiers. File "pr6323.ml", line 15, characters 2-24: diff --git a/testsuite/tests/typing-ocamlc-i/pr7402.compilers.reference b/testsuite/tests/typing-ocamlc-i/pr7402.compilers.reference index 46811961..df578593 100644 --- a/testsuite/tests/typing-ocamlc-i/pr7402.compilers.reference +++ b/testsuite/tests/typing-ocamlc-i/pr7402.compilers.reference @@ -1,5 +1,5 @@ File "pr7402.ml", line 1: -Warning 63: The printed interface differs from the inferred interface. +Warning 63 [erroneous-printed-signature]: The printed interface differs from the inferred interface. The inferred interface contained items which could not be printed properly due to name collisions between identifiers. File "pr7402.ml", lines 14-16, characters 0-5: diff --git a/testsuite/tests/typing-poly/poly.ml b/testsuite/tests/typing-poly/poly.ml index 655a1ee9..9687949d 100644 --- a/testsuite/tests/typing-poly/poly.ml +++ b/testsuite/tests/typing-poly/poly.ml @@ -52,7 +52,7 @@ Lines 1-4, characters 0-24: 2 | | {pv=[]} -> "OK" 3 | | {pv=5::_} -> "int" 4 | | {pv=true::_} -> "bool" -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {pv=false::_} - : string = "OK" @@ -69,7 +69,7 @@ Lines 1-4, characters 0-20: 2 | | {pv=[]} -> "OK" 3 | | {pv=true::_} -> "bool" 4 | | {pv=5::_} -> "int" -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {pv=0::_} - : string = "OK" @@ -304,7 +304,7 @@ class ['a] ostream1 : Line 8, characters 4-16: 8 | self#tl#fold ~f ~init:(f self#hd init) ^^^^^^^^^^^^ -Warning 18: this use of a polymorphic method is not principal. +Warning 18 [not-principal]: this use of a polymorphic method is not principal. class ['a] ostream1 : hd:'a -> tl:'b -> @@ -1089,7 +1089,7 @@ val f : unit -> c = Line 4, characters 11-60: 4 | let f () = object method private n = 1 method m = {<>}#n end;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 15: the following private methods were made public implicitly: +Warning 15 [implicit-public-methods]: the following private methods were made public implicitly: n. val f : unit -> < m : int; n : int > = Line 5, characters 11-56: @@ -1259,19 +1259,19 @@ val f : < m : 'a. 'a -> 'a > -> < m : 'a. 'a -> 'a > = Line 2, characters 9-16: 2 | fun x -> (f x)#m;; (* Warning 18 *) ^^^^^^^ -Warning 18: this use of a polymorphic method is not principal. +Warning 18 [not-principal]: this use of a polymorphic method is not principal. - : < m : 'a. 'a -> 'a > -> 'b -> 'b = val f : < m : 'a. 'a -> 'a > * 'b -> < m : 'a. 'a -> 'a > = Line 4, characters 9-20: 4 | fun x -> (f (x,x))#m;; (* Warning 18 *) ^^^^^^^^^^^ -Warning 18: this use of a polymorphic method is not principal. +Warning 18 [not-principal]: this use of a polymorphic method is not principal. - : < m : 'a. 'a -> 'a > -> 'b -> 'b = val f : < m : 'a. 'a -> 'a > -> < m : 'a. 'a -> 'a > array = Line 6, characters 9-20: 6 | fun x -> (f x).(0)#m;; (* Warning 18 *) ^^^^^^^^^^^ -Warning 18: this use of a polymorphic method is not principal. +Warning 18 [not-principal]: this use of a polymorphic method is not principal. - : < m : 'a. 'a -> 'a > -> 'b -> 'b = |}];; @@ -1300,12 +1300,12 @@ val just : 'a option -> 'a = Line 4, characters 42-62: 4 | let f x = let l = [Some x; (None : u)] in (just(List.hd l))#id;; ^^^^^^^^^^^^^^^^^^^^ -Warning 18: this use of a polymorphic method is not principal. +Warning 18 [not-principal]: this use of a polymorphic method is not principal. val f : c -> 'a -> 'a = Line 7, characters 36-47: 7 | let x = List.hd [Some x; none] in (just x)#id;; ^^^^^^^^^^^ -Warning 18: this use of a polymorphic method is not principal. +Warning 18 [not-principal]: this use of a polymorphic method is not principal. val g : c -> 'a -> 'a = val h : < id : 'a; .. > -> 'a = |}];; @@ -1486,7 +1486,7 @@ match fun x -> x with x -> x, x;; - : ('a -> 'a) * ('b -> 'b) = (, ) |}];; -(* PR#6747 *) +(* PR#6744 *) (* ok *) let n = object method m : 'x 'o. ([< `Foo of 'x] as 'o) -> 'x = fun x -> assert false @@ -1524,6 +1524,39 @@ Error: This expression has type < m : 'x. [< `Foo of 'x ] -> 'x > < m : 'a. [< `Foo of int ] -> 'a > The universal variable 'x would escape its scope |}];; +(* ok *) +let f (n : < m : 'a 'r. [< `Foo of 'a & int | `Bar] as 'r >) = + (n : < m : 'b 'r. [< `Foo of 'b & int | `Bar] as 'r >) +[%%expect{| +val f : + < m : 'a 'c. [< `Bar | `Foo of 'a & int ] as 'c > -> + < m : 'b 'd. [< `Bar | `Foo of 'b & int ] as 'd > = +|}] +(* fail? *) +let f (n : < m : 'a 'r. [< `Foo of 'a & int | `Bar] as 'r >) = + (n : < m : 'b 'r. [< `Foo of int & 'b | `Bar] as 'r >) +[%%expect{| +Line 2, characters 3-4: +2 | (n : < m : 'b 'r. [< `Foo of int & 'b | `Bar] as 'r >) + ^ +Error: This expression has type + < m : 'a 'c. [< `Bar | `Foo of 'a & int ] as 'c > + but an expression was expected of type + < m : 'b 'd. [< `Bar | `Foo of int & 'b ] as 'd > + Types for tag `Foo are incompatible +|}] +(* fail? *) +let f (n : < m : 'a. [< `Foo of 'a & int | `Bar] >) = + (n : < m : 'b. [< `Foo of 'b & int | `Bar] >) +[%%expect{| +Line 1: +Error: Values do not match: + val f : + < m : 'a. [< `Bar | `Foo of 'a & int ] as 'c > -> < m : 'b. 'c > + is not included in + val f : + < m : 'a. [< `Bar | `Foo of 'b & int ] as 'c > -> < m : 'b. 'c > +|}] (* PR#6171 *) let f b (x: 'x) = diff --git a/testsuite/tests/typing-poly/pr9603.ml b/testsuite/tests/typing-poly/pr9603.ml index 382b1c2b..9052a1a4 100644 --- a/testsuite/tests/typing-poly/pr9603.ml +++ b/testsuite/tests/typing-poly/pr9603.ml @@ -33,16 +33,4 @@ Error: This expression has type is not compatible with type < left : 'left0; right : 'right0 > pair The method left has type 'a, but the expected method type was 'left The universal variable 'left would escape its scope -|}, Principal{| -Line 4, characters 6-7: -4 | = fun x -> x - ^ -Error: This pattern matches values of type - < m : 'left 'right. < left : 'left; right : 'right > pair > - but a pattern was expected which matches values of type - < m : 'left 'right. < left : 'left; right : 'right > pair > - Type < left : 'left; right : 'right > pair = 'a * 'b - is not compatible with type < left : 'left0; right : 'right0 > pair - The method left has type 'a, but the expected method type was 'left - The universal variable 'left would escape its scope |}] diff --git a/testsuite/tests/typing-polyvariants-bugs/pr7824.ml b/testsuite/tests/typing-polyvariants-bugs/pr7824.ml index a4484494..0af60a0c 100644 --- a/testsuite/tests/typing-polyvariants-bugs/pr7824.ml +++ b/testsuite/tests/typing-polyvariants-bugs/pr7824.ml @@ -40,7 +40,7 @@ let f x = Lines 4-5, characters 2-38: 4 | ..match [] with 5 | | _::_ -> (x :> [`A | `C] Element.t) -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: [] val f : [ `A ] Element.t -> [ `A | `C ] Element.t = diff --git a/testsuite/tests/typing-private/private.compilers.principal.reference b/testsuite/tests/typing-private/private.compilers.principal.reference index ee60a677..2be849e1 100644 --- a/testsuite/tests/typing-private/private.compilers.principal.reference +++ b/testsuite/tests/typing-private/private.compilers.principal.reference @@ -114,7 +114,7 @@ type t = private < x : int > type t = private < x : int > Line 1: Error: Type declarations do not match: - type 'a t = private 'a constraint 'a = < x : int; .. > + type !'a t = private 'a constraint 'a = < x : int; .. > is not included in type 'a t Their constraints differ. diff --git a/testsuite/tests/typing-private/private.compilers.reference b/testsuite/tests/typing-private/private.compilers.reference index bead385a..06968cd0 100644 --- a/testsuite/tests/typing-private/private.compilers.reference +++ b/testsuite/tests/typing-private/private.compilers.reference @@ -114,7 +114,7 @@ type t = private < x : int > type t = private < x : int > Line 1: Error: Type declarations do not match: - type 'a t = private < x : int; .. > constraint 'a = 'a t + type !'a t = private < x : int; .. > constraint 'a = 'a t is not included in type 'a t Their constraints differ. diff --git a/testsuite/tests/typing-safe-linking/b_bad.compilers.reference b/testsuite/tests/typing-safe-linking/b_bad.compilers.reference index 4f9cd7e5..8911d384 100644 --- a/testsuite/tests/typing-safe-linking/b_bad.compilers.reference +++ b/testsuite/tests/typing-safe-linking/b_bad.compilers.reference @@ -1,7 +1,7 @@ File "b_bad.ml", lines 13-14, characters 29-28: 13 | .............................function 14 | A.X s -> print_endline s -Error (warning 8): this pattern-matching is not exhaustive. +Error (warning 8 [partial-match]): this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Y File "b_bad.ml", line 18, characters 11-14: diff --git a/testsuite/tests/typing-shadowing-of-pervasives-submodules/redefine_largefile.ml b/testsuite/tests/typing-shadowing-of-pervasives-submodules/redefine_largefile.ml index 5d4ac627..68401fa5 100644 --- a/testsuite/tests/typing-shadowing-of-pervasives-submodules/redefine_largefile.ml +++ b/testsuite/tests/typing-shadowing-of-pervasives-submodules/redefine_largefile.ml @@ -1,4 +1,4 @@ (* TEST modules = "largeFile.ml" *) -print_string LargeFile.message +print_endline LargeFile.message diff --git a/testsuite/tests/typing-short-paths/short-paths.compilers.reference b/testsuite/tests/typing-short-paths/short-paths.compilers.reference index 1619e340..7265fe11 100644 --- a/testsuite/tests/typing-short-paths/short-paths.compilers.reference +++ b/testsuite/tests/typing-short-paths/short-paths.compilers.reference @@ -54,6 +54,7 @@ module Core : val map : ('a -> 'b) -> 'a t -> 'b t val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t val to_seq : 'a t -> (key * 'a) Seq.t + val to_rev_seq : 'a t -> (key * 'a) Seq.t val to_seq_from : key -> 'a t -> (key * 'a) Seq.t val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t val of_seq : (key * 'a) Seq.t -> 'a t diff --git a/testsuite/tests/typing-sigsubst/sigsubst.ml b/testsuite/tests/typing-sigsubst/sigsubst.ml index b2b835e9..7cfa2902 100644 --- a/testsuite/tests/typing-sigsubst/sigsubst.ml +++ b/testsuite/tests/typing-sigsubst/sigsubst.ml @@ -24,11 +24,11 @@ end Line 3, characters 2-36: 3 | include Comparable with type t = t ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Error: Illegal shadowing of included type t/97 by t/101 +Error: Illegal shadowing of included type t/98 by t/102 Line 2, characters 2-19: - Type t/97 came from this include + Type t/98 came from this include Line 3, characters 2-23: - The value print has no valid type if t/97 is shadowed + The value print has no valid type if t/98 is shadowed |}] module type Sunderscore = sig diff --git a/testsuite/tests/typing-unboxed/test.ml b/testsuite/tests/typing-unboxed/test.ml index 741ac3d9..fb1ecb82 100644 --- a/testsuite/tests/typing-unboxed/test.ml +++ b/testsuite/tests/typing-unboxed/test.ml @@ -413,7 +413,7 @@ type i = I of int Line 2, characters 0-34: 2 | external id : i -> i = "%identity";; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 61: This primitive declaration uses type i, whose representation +Warning 61 [unboxable-type-in-prim-decl]: This primitive declaration uses type i, whose representation may be either boxed or unboxed. Without an annotation to indicate which representation is intended, the boxed representation has been selected by default. This default choice may change in future @@ -433,7 +433,7 @@ type j = J of int Line 3, characters 0-34: 3 | external id : i -> j = "%identity";; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 61: This primitive declaration uses type i, whose representation +Warning 61 [unboxable-type-in-prim-decl]: This primitive declaration uses type i, whose representation may be either boxed or unboxed. Without an annotation to indicate which representation is intended, the boxed representation has been selected by default. This default choice may change in future @@ -444,7 +444,7 @@ remains stable in the future. Line 3, characters 0-34: 3 | external id : i -> j = "%identity";; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 61: This primitive declaration uses type j, whose representation +Warning 61 [unboxable-type-in-prim-decl]: This primitive declaration uses type j, whose representation may be either boxed or unboxed. Without an annotation to indicate which representation is intended, the boxed representation has been selected by default. This default choice may change in future diff --git a/testsuite/tests/typing-warnings/ambiguous_guarded_disjunction.ml b/testsuite/tests/typing-warnings/ambiguous_guarded_disjunction.ml index 27b12920..ef472aec 100644 --- a/testsuite/tests/typing-warnings/ambiguous_guarded_disjunction.ml +++ b/testsuite/tests/typing-warnings/ambiguous_guarded_disjunction.ml @@ -27,7 +27,7 @@ let ambiguous_typical_example = function Line 2, characters 4-29: 2 | | ((Val x, _) | (_, Val x)) when x < 0 -> () ^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variable x may match different arguments. (See manual section 9.5) val ambiguous_typical_example : expr * expr -> unit = |}] @@ -94,7 +94,7 @@ let ambiguous__y = function Line 2, characters 4-43: 2 | | (`B (x, _, Some y) | `B (x, Some y, _)) when y -> ignore x ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variable y may match different arguments. (See manual section 9.5) val ambiguous__y : [> `B of 'a * bool option * bool option ] -> unit = |}] @@ -125,7 +125,7 @@ let ambiguous__x_y = function Line 2, characters 4-43: 2 | | (`B (x, _, Some y) | `B (x, Some y, _)) when x < y -> () ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variable y may match different arguments. (See manual section 9.5) val ambiguous__x_y : [> `B of 'a * 'a option * 'a option ] -> unit = |}] @@ -138,7 +138,7 @@ let ambiguous__x_y_z = function Line 2, characters 4-43: 2 | | (`B (x, z, Some y) | `B (x, Some y, z)) when x < y || Some x = z -> () ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variables y,z may match different arguments. (See manual section 9.5) val ambiguous__x_y_z : [> `B of 'a * 'a option * 'a option ] -> unit = |}] @@ -169,7 +169,7 @@ let ambiguous__in_depth = function Line 2, characters 4-40: 2 | | `A (`B (Some x, _) | `B (_, Some x)) when x -> () ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variable x may match different arguments. (See manual section 9.5) val ambiguous__in_depth : [> `A of [> `B of bool option * bool option ] ] -> unit = @@ -200,7 +200,7 @@ let ambiguous__first_orpat = function Lines 2-3, characters 4-58: 2 | ....`A ((`B (Some x, _) | `B (_, Some x)), 3 | (`C (Some y, Some _, _) | `C (Some y, _, Some _)))................. -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variable x may match different arguments. (See manual section 9.5) val ambiguous__first_orpat : [> `A of @@ -218,7 +218,7 @@ let ambiguous__second_orpat = function Lines 2-3, characters 4-42: 2 | ....`A ((`B (Some x, Some _, _) | `B (Some x, _, Some _)), 3 | (`C (Some y, _) | `C (_, Some y)))................. -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variable y may match different arguments. (See manual section 9.5) val ambiguous__second_orpat : [> `A of @@ -311,7 +311,7 @@ let ambiguous__amoi a = match a with Lines 2-3, characters 2-17: 2 | ..X (Z x,Y (y,0)) 3 | | X (Z y,Y (x,_)) -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variables x,y may match different arguments. (See manual section 9.5) val ambiguous__amoi : amoi -> int = |}] @@ -331,7 +331,7 @@ let ambiguous__module_variable x b = match x with Lines 2-3, characters 4-24: 2 | ....(module M:S),_,(1,_) 3 | | _,(module M:S),(_,1)................... -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variable M may match different arguments. (See manual section 9.5) val ambiguous__module_variable : (module S) * (module S) * (int * int) -> bool -> int = @@ -346,7 +346,7 @@ let not_ambiguous__module_variable x b = match x with Line 2, characters 12-13: 2 | | (module M:S),_,(1,_) ^ -Warning 60: unused module M. +Warning 60 [unused-module]: unused module M. val not_ambiguous__module_variable : (module S) * (module S) * (int * int) -> bool -> int = |}] @@ -367,18 +367,47 @@ let ambiguous_xy_but_not_ambiguous_z g = function Line 2, characters 4-5: 2 | | A (x as z,(0 as y))|A (0 as y as z,x)|B (x,(y as z)) when g x (y+z) -> 1 ^ -Warning 41: A belongs to several types: t2 t +Warning 41 [ambiguous-name]: A belongs to several types: t2 t The first one was selected. Please disambiguate if this is wrong. Lines 1-3, characters 41-10: 1 | .........................................function 2 | | A (x as z,(0 as y))|A (0 as y as z,x)|B (x,(y as z)) when g x (y+z) -> 1 3 | | _ -> 2 -Warning 4: this pattern-matching is fragile. +Warning 4 [fragile-match]: this pattern-matching is fragile. It will remain exhaustive when constructors are added to type t2. Line 2, characters 4-56: 2 | | A (x as z,(0 as y))|A (0 as y as z,x)|B (x,(y as z)) when g x (y+z) -> 1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; +variables x,y may match different arguments. (See manual section 9.5) +val ambiguous_xy_but_not_ambiguous_z : (int -> int -> bool) -> t2 -> int = + +|}, Principal{| +Line 2, characters 4-5: +2 | | A (x as z,(0 as y))|A (0 as y as z,x)|B (x,(y as z)) when g x (y+z) -> 1 + ^ +Warning 41 [ambiguous-name]: A belongs to several types: t2 t +The first one was selected. Please disambiguate if this is wrong. +Line 2, characters 24-25: +2 | | A (x as z,(0 as y))|A (0 as y as z,x)|B (x,(y as z)) when g x (y+z) -> 1 + ^ +Warning 41 [ambiguous-name]: A belongs to several types: t2 t +The first one was selected. Please disambiguate if this is wrong. +Line 2, characters 42-43: +2 | | A (x as z,(0 as y))|A (0 as y as z,x)|B (x,(y as z)) when g x (y+z) -> 1 + ^ +Warning 41 [ambiguous-name]: B belongs to several types: t2 t +The first one was selected. Please disambiguate if this is wrong. +Lines 1-3, characters 41-10: +1 | .........................................function +2 | | A (x as z,(0 as y))|A (0 as y as z,x)|B (x,(y as z)) when g x (y+z) -> 1 +3 | | _ -> 2 +Warning 4 [fragile-match]: this pattern-matching is fragile. +It will remain exhaustive when constructors are added to type t2. +Line 2, characters 4-56: +2 | | A (x as z,(0 as y))|A (0 as y as z,x)|B (x,(y as z)) when g x (y+z) -> 1 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variables x,y may match different arguments. (See manual section 9.5) val ambiguous_xy_but_not_ambiguous_z : (int -> int -> bool) -> t2 -> int = @@ -437,7 +466,7 @@ let guarded_ambiguity = function Line 3, characters 4-29: 3 | | ((Val y, _) | (_, Val y)) when y < 0 -> () ^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variable y may match different arguments. (See manual section 9.5) val guarded_ambiguity : expr * expr -> unit = |}] @@ -466,7 +495,7 @@ let cmp (pred : a -> bool) (x : a alg) (y : a alg) = Line 4, characters 4-29: 4 | | ((Val x, _) | (_, Val x)) when pred x -> () ^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 57: Ambiguous or-pattern variables under guard; +Warning 57 [ambiguous-var-in-pattern-guard]: Ambiguous or-pattern variables under guard; variable x may match different arguments. (See manual section 9.5) val cmp : (a -> bool) -> a alg -> a alg -> unit = |}] diff --git a/testsuite/tests/typing-warnings/application.ml b/testsuite/tests/typing-warnings/application.ml index 6a5105f7..0ba9f75f 100644 --- a/testsuite/tests/typing-warnings/application.ml +++ b/testsuite/tests/typing-warnings/application.ml @@ -19,7 +19,7 @@ let _ = Array.get [||];; Line 1, characters 8-22: 1 | let _ = Array.get [||];; ^^^^^^^^^^^^^^ -Warning 5: this function application is partial, +Warning 5 [ignored-partial-application]: this function application is partial, maybe some arguments are missing. - : int -> 'a = |}] @@ -33,7 +33,7 @@ let () = ignore (Array.get [||]);; Line 1, characters 16-32: 1 | let () = ignore (Array.get [||]);; ^^^^^^^^^^^^^^^^ -Warning 5: this function application is partial, +Warning 5 [ignored-partial-application]: this function application is partial, maybe some arguments are missing. |}] @@ -48,7 +48,7 @@ let _ = if true then Array.get [||] else (fun _ -> 12);; Line 1, characters 21-35: 1 | let _ = if true then Array.get [||] else (fun _ -> 12);; ^^^^^^^^^^^^^^ -Warning 5: this function application is partial, +Warning 5 [ignored-partial-application]: this function application is partial, maybe some arguments are missing. - : int -> int = |}] @@ -71,7 +71,7 @@ let f x = let _ = x.r 1 in ();; Line 1, characters 18-23: 1 | let f x = let _ = x.r 1 in ();; ^^^^^ -Warning 5: this function application is partial, +Warning 5 [ignored-partial-application]: this function application is partial, maybe some arguments are missing. val f : t -> unit = |}] @@ -81,6 +81,26 @@ let _ = raise Exit 3;; Line 1, characters 19-20: 1 | let _ = raise Exit 3;; ^ -Warning 20: this argument will not be used by the function. +Warning 20 [ignored-extra-argument]: this argument will not be used by the function. Exception: Stdlib.Exit. |}] + +let f a b = a + b;; +[%%expect {| +val f : int -> int -> int = +|}] +let g x = x + 1 +let _ = g (f 1);; +[%%expect {| +val g : int -> int = +Line 2, characters 10-15: +2 | let _ = g (f 1);; + ^^^^^ +Warning 5 [ignored-partial-application]: this function application is partial, +maybe some arguments are missing. +Line 2, characters 10-15: +2 | let _ = g (f 1);; + ^^^^^ +Error: This expression has type int -> int + but an expression was expected of type int +|}] diff --git a/testsuite/tests/typing-warnings/coercions.ml b/testsuite/tests/typing-warnings/coercions.ml index ac238bef..0900975c 100644 --- a/testsuite/tests/typing-warnings/coercions.ml +++ b/testsuite/tests/typing-warnings/coercions.ml @@ -12,7 +12,7 @@ fun b -> if b then format_of_string "x" else "y" Line 1, characters 45-48: 1 | fun b -> if b then format_of_string "x" else "y" ^^^ -Warning 18: this coercion to format6 is not principal. +Warning 18 [not-principal]: this coercion to format6 is not principal. - : bool -> ('a, 'b, 'c, 'd, 'd, 'a) format6 = |}] ;; @@ -65,6 +65,6 @@ module Test1 : sig type t = private int val f : t -> int end Line 3, characters 49-59: 3 | let f x = let y = if true then x else (x:t) in (y :> int) ^^^^^^^^^^ -Warning 18: this ground coercion is not principal. +Warning 18 [not-principal]: this ground coercion is not principal. module Test1 : sig type t = private int val f : t -> int end |}] diff --git a/testsuite/tests/typing-warnings/exhaustiveness.ml b/testsuite/tests/typing-warnings/exhaustiveness.ml index 1ed1aefc..888034aa 100644 --- a/testsuite/tests/typing-warnings/exhaustiveness.ml +++ b/testsuite/tests/typing-warnings/exhaustiveness.ml @@ -3,7 +3,6 @@ * expect *) -(* Warn about all relevant cases when possible *) let f = function None, None -> 1 | Some _, Some _ -> 2;; @@ -12,13 +11,12 @@ Lines 1-3, characters 8-23: 1 | ........function 2 | None, None -> 1 3 | | Some _, Some _ -> 2.. -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: -((Some _, None)|(None, Some _)) +(None, Some _) val f : 'a option * 'b option -> int = |}] -(* Exhaustiveness check is very slow *) type _ t = A : int t | B : bool t | C : char t | D : float t type (_,_,_,_) u = U : (int, int, int, int) u @@ -30,42 +28,18 @@ type (_, _, _, _) u = U : (int, int, int, int) u type v = E | F | G |}] -let f : type a b c d e f g. - a t * b t * c t * d t * e t * f t * g t * v - * (a,b,c,d) u * (e,f,g,g) u -> int = - function A, A, A, A, A, A, A, _, U, U -> 1 - | _, _, _, _, _, _, _, G, _, _ -> 1 - (*| _ -> _ *) -;; -[%%expect {| -Lines 4-5, characters 1-38: -4 | .function A, A, A, A, A, A, A, _, U, U -> 1 -5 | | _, _, _, _, _, _, _, G, _, _ -> 1 -Warning 8: this pattern-matching is not exhaustive. -Here is an example of a case that is not matched: -(A, A, A, A, A, A, B, (E|F), _, _) -Line 5, characters 5-33: -5 | | _, _, _, _, _, _, _, G, _, _ -> 1 - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 56: this match case is unreachable. -Consider replacing it with a refutation case ' -> .' -val f : - 'a t * 'b t * 'c t * 'd t * 'e t * 'f t * 'g t * v * ('a, 'b, 'c, 'd) u * - ('e, 'f, 'g, 'g) u -> int = -|}] - (* Unused cases *) let f (x : int t) = match x with A -> 1 | _ -> 2;; (* warn *) [%%expect {| Line 1, characters 20-48: 1 | let f (x : int t) = match x with A -> 1 | _ -> 2;; (* warn *) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 4: this pattern-matching is fragile. +Warning 4 [fragile-match]: this pattern-matching is fragile. It will remain exhaustive when constructors are added to type t. Line 1, characters 42-43: 1 | let f (x : int t) = match x with A -> 1 | _ -> 2;; (* warn *) ^ -Warning 56: this match case is unreachable. +Warning 56 [unreachable-case]: this match case is unreachable. Consider replacing it with a refutation case ' -> .' val f : int t -> int = |}] @@ -75,7 +49,7 @@ let f (x : unit t option) = match x with None -> 1 | _ -> 2 ;; (* warn? *) Line 1, characters 53-54: 1 | let f (x : unit t option) = match x with None -> 1 | _ -> 2 ;; (* warn? *) ^ -Warning 56: this match case is unreachable. +Warning 56 [unreachable-case]: this match case is unreachable. Consider replacing it with a refutation case ' -> .' val f : unit t option -> int = |}] @@ -85,7 +59,7 @@ let f (x : unit t option) = match x with None -> 1 | Some _ -> 2 ;; (* warn *) Line 1, characters 53-59: 1 | let f (x : unit t option) = match x with None -> 1 | Some _ -> 2 ;; (* warn *) ^^^^^^ -Warning 56: this match case is unreachable. +Warning 56 [unreachable-case]: this match case is unreachable. Consider replacing it with a refutation case ' -> .' val f : unit t option -> int = |}] @@ -100,7 +74,7 @@ let f (x : int t option) = match x with None -> 1;; (* warn *) Line 1, characters 27-49: 1 | let f (x : int t option) = match x with None -> 1;; (* warn *) ^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Some A val f : int t option -> int = @@ -120,7 +94,7 @@ let f : (int t box pair * bool) option -> unit = function None -> ();; Line 1, characters 49-68: 1 | let f : (int t box pair * bool) option -> unit = function None -> ();; ^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Some ({left=Box A; right=Box A}, _) val f : (int t box pair * bool) option -> unit = @@ -136,7 +110,7 @@ let f = function {left=Box 0; _ } -> ();; Line 1, characters 8-39: 1 | let f = function {left=Box 0; _ } -> ();; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: {left=Box 1; _ } val f : int box pair -> unit = @@ -147,9 +121,9 @@ let f = function {left=Box 0;right=Box 1} -> ();; Line 1, characters 8-47: 1 | let f = function {left=Box 0;right=Box 1} -> ();; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: -({left=Box 0; right=Box 0}|{left=Box 1; right=Box _}) +{left=Box 0; right=Box 0} val f : int box pair -> unit = |}] @@ -204,7 +178,7 @@ let f : (A.a, A.b) cmp -> unit = function Any -> () Line 1, characters 33-51: 1 | let f : (A.a, A.b) cmp -> unit = function Any -> () ^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Eq val f : (A.a, A.b) cmp -> unit = @@ -257,7 +231,7 @@ let harder : (zero succ, zero succ, zero succ) plus option -> bool = Line 2, characters 2-24: 2 | function None -> false ^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Some (PlusS _) val harder : (zero succ, zero succ, zero succ) plus option -> bool = @@ -334,7 +308,7 @@ let f x y = match 1 with 1 when x = y -> 1;; Line 1, characters 12-42: 1 | let f x y = match 1 with 1 when x = y -> 1;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. All clauses in this pattern-matching are guarded. val f : 'a -> 'a -> int = |}] @@ -345,7 +319,7 @@ let f = function {contents=_}, 0 -> 0;; Line 1, characters 8-37: 1 | let f = function {contents=_}, 0 -> 0;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (_, 1) val f : 'a ref * int -> int = @@ -363,9 +337,45 @@ Lines 1-4, characters 8-28: 2 | | None -> () 3 | | Some x when x > 0 -> () 4 | | Some x when x <= 0 -> () -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Some _ (However, some guarded clause may match this value.) val f : int option -> unit = |}] + +(* in the single-row case we can generate more compact witnesses *) +module Single_row_optim = struct +type t = A | B + +(* This synthetic program is representative of user-written programs + that try to distinguish the cases "only A" and "at least one B" + while avoiding a fragile pattern-matching (using just _ in the last + row would be fragile). + + It is a "single row" program from the point of view of + exhaustiveness checking because the first row is subsumed by the + second and thus removed by the [get_mins] preprocessing of + Parmatch. + + With the single-row optimization implemented in the compiler, it + generates a single counter-example that contains + or-patterns. Without this optimization, it would generate 2^(N-1) + counter-examples (here N=4 so 8), one for each possible expansion + of the or-patterns. +*) +let non_exhaustive : t * t * t * t -> unit = function +| A, A, A, A -> () +| (A|B), (A|B), (A|B), A (*missing B here*) -> () +end;; +[%%expect {| +Lines 20-22, characters 45-49: +20 | .............................................function +21 | | A, A, A, A -> () +22 | | (A|B), (A|B), (A|B), A (*missing B here*) -> () +Warning 8 [partial-match]: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +((A|B), (A|B), (A|B), B) +module Single_row_optim : + sig type t = A | B val non_exhaustive : t * t * t * t -> unit end +|}] diff --git a/testsuite/tests/typing-warnings/fragile_matching.ml b/testsuite/tests/typing-warnings/fragile_matching.ml new file mode 100644 index 00000000..eef69e0d --- /dev/null +++ b/testsuite/tests/typing-warnings/fragile_matching.ml @@ -0,0 +1,108 @@ +(* TEST *) + +(* Tests for stack-overflow crashes caused by a combinatorial + explosition in fragile pattern checking. *) + +[@@@warning "+4"] + +module SyntheticTest = struct + (* from Luc Maranget *) + type t = A | B + + let f = function + | A,A,A,A,A, A,A,A,A,A, A,A,A,A,A, A,A,A -> 1 + | (A|B),(A|B),(A|B),(A|B),(A|B), + (A|B),(A|B),(A|B),(A|B),(A|B), + (A|B),(A|B),(A|B),(A|B),(A|B), + (A|B),(A|B),(A|B) -> 2 +end + +module RealCodeTest = struct + (* from Alex Fedoseev *) + + type visibility = Shown | Hidden + + type ('outputValue, 'message) fieldStatus = + | Pristine + | Dirty of ('outputValue, 'message) result * visibility + + type message = string + + type fieldsStatuses = { + iaasStorageConfigurations : + iaasStorageConfigurationFieldsStatuses array; + } + + and iaasStorageConfigurationFieldsStatuses = { + startDate : (int, message) fieldStatus; + term : (int, message) fieldStatus; + rawStorageCapacity : (int, message) fieldStatus; + diskType : (string option, message) fieldStatus; + connectivityMethod : (string option, message) fieldStatus; + getRequest : (int option, message) fieldStatus; + getRequestUnit : (string option, message) fieldStatus; + putRequest : (int option, message) fieldStatus; + putRequestUnit : (string option, message) fieldStatus; + transferOut : (int option, message) fieldStatus; + transferOutUnit : (string option, message) fieldStatus; + region : (string option, message) fieldStatus; + cloudType : (string option, message) fieldStatus; + description : (string option, message) fieldStatus; + features : (string array, message) fieldStatus; + accessTypes : (string array, message) fieldStatus; + certifications : (string array, message) fieldStatus; + additionalRequirements : (string option, message) fieldStatus; + } + + type interface = { dirty : unit -> bool } + + let useForm () = { + dirty = fun () -> + Array.for_all + (fun item -> + match item with + | { + additionalRequirements = Pristine; + certifications = Pristine; + accessTypes = Pristine; + features = Pristine; + description = Pristine; + cloudType = Pristine; + region = Pristine; + transferOutUnit = Pristine; + transferOut = Pristine; + putRequestUnit = Pristine; + putRequest = Pristine; + getRequestUnit = Pristine; + getRequest = Pristine; + connectivityMethod = Pristine; + diskType = Pristine; + rawStorageCapacity = Pristine; + term = Pristine; + startDate = Pristine; + } -> + false + | { + additionalRequirements = Pristine | Dirty (_, _); + certifications = Pristine | Dirty (_, _); + accessTypes = Pristine | Dirty (_, _); + features = Pristine | Dirty (_, _); + description = Pristine | Dirty (_, _); + cloudType = Pristine | Dirty (_, _); + region = Pristine | Dirty (_, _); + transferOutUnit = Pristine | Dirty (_, _); + transferOut = Pristine | Dirty (_, _); + putRequestUnit = Pristine | Dirty (_, _); + putRequest = Pristine | Dirty (_, _); + getRequestUnit = Pristine | Dirty (_, _); + getRequest = Pristine | Dirty (_, _); + connectivityMethod = Pristine | Dirty (_, _); + diskType = Pristine | Dirty (_, _); + rawStorageCapacity = Pristine | Dirty (_, _); + term = Pristine | Dirty (_, _); + startDate = Pristine | Dirty (_, _); + } -> + true) + [||] + } +end diff --git a/testsuite/tests/typing-warnings/never_returns.ml b/testsuite/tests/typing-warnings/never_returns.ml index 6b5aac60..8ee4127f 100644 --- a/testsuite/tests/typing-warnings/never_returns.ml +++ b/testsuite/tests/typing-warnings/never_returns.ml @@ -8,7 +8,7 @@ let () = (let module L = List in raise Exit); () ;; Line 1, characters 33-43: 1 | let () = (let module L = List in raise Exit); () ;; ^^^^^^^^^^ -Warning 21: this statement never returns (or has an unsound type.) +Warning 21 [nonreturning-statement]: this statement never returns (or has an unsound type.) Exception: Stdlib.Exit. |}] let () = (let exception E in raise Exit); ();; @@ -16,7 +16,7 @@ let () = (let exception E in raise Exit); ();; Line 1, characters 29-39: 1 | let () = (let exception E in raise Exit); ();; ^^^^^^^^^^ -Warning 21: this statement never returns (or has an unsound type.) +Warning 21 [nonreturning-statement]: this statement never returns (or has an unsound type.) Exception: Stdlib.Exit. |}] let () = (raise Exit : _); ();; @@ -24,7 +24,7 @@ let () = (raise Exit : _); ();; Line 1, characters 10-20: 1 | let () = (raise Exit : _); ();; ^^^^^^^^^^ -Warning 21: this statement never returns (or has an unsound type.) +Warning 21 [nonreturning-statement]: this statement never returns (or has an unsound type.) Exception: Stdlib.Exit. |}] let () = (let open Stdlib in raise Exit); ();; @@ -32,6 +32,6 @@ let () = (let open Stdlib in raise Exit); ();; Line 1, characters 29-39: 1 | let () = (let open Stdlib in raise Exit); ();; ^^^^^^^^^^ -Warning 21: this statement never returns (or has an unsound type.) +Warning 21 [nonreturning-statement]: this statement never returns (or has an unsound type.) Exception: Stdlib.Exit. |}] diff --git a/testsuite/tests/typing-warnings/open_warnings.ml b/testsuite/tests/typing-warnings/open_warnings.ml index e6c65691..29980951 100644 --- a/testsuite/tests/typing-warnings/open_warnings.ml +++ b/testsuite/tests/typing-warnings/open_warnings.ml @@ -10,11 +10,11 @@ end;; Line 2, characters 20-26: 2 | module M = struct type t end (* unused type t *) ^^^^^^ -Warning 34: unused type t. +Warning 34 [unused-type-declaration]: unused type t. Line 3, characters 2-8: 3 | open M (* unused open *) ^^^^^^ -Warning 33: unused open M. +Warning 33 [unused-open]: unused open M. module T1 : sig end |}] @@ -38,15 +38,15 @@ end;; Line 4, characters 2-8: 4 | open M (* used by line below; shadow constructor A *) ^^^^^^ -Warning 45: this open statement shadows the constructor A (which is later used) +Warning 45 [open-shadow-label-constructor]: this open statement shadows the constructor A (which is later used) Line 2, characters 2-13: 2 | type t0 = A (* unused type and constructor *) ^^^^^^^^^^^ -Warning 34: unused type t0. +Warning 34 [unused-type-declaration]: unused type t0. Line 2, characters 12-13: 2 | type t0 = A (* unused type and constructor *) ^ -Warning 37: unused constructor A. +Warning 37 [unused-constructor]: unused constructor A. module T3 : sig end |}] @@ -60,15 +60,15 @@ end;; Line 3, characters 20-30: 3 | module M = struct type t = A end (* unused type and constructor *) ^^^^^^^^^^ -Warning 34: unused type t. +Warning 34 [unused-type-declaration]: unused type t. Line 3, characters 29-30: 3 | module M = struct type t = A end (* unused type and constructor *) ^ -Warning 37: unused constructor A. +Warning 37 [unused-constructor]: unused constructor A. Line 4, characters 2-8: 4 | open M (* unused open; no shadowing (A below refers to the one in t0) *) ^^^^^^ -Warning 33: unused open M. +Warning 33 [unused-open]: unused open M. module T4 : sig end |}] @@ -82,15 +82,15 @@ end;; Line 4, characters 2-8: 4 | open M (* shadow constructor A *) ^^^^^^ -Warning 45: this open statement shadows the constructor A (which is later used) +Warning 45 [open-shadow-label-constructor]: this open statement shadows the constructor A (which is later used) Line 2, characters 2-13: 2 | type t0 = A (* unused type and constructor *) ^^^^^^^^^^^ -Warning 34: unused type t0. +Warning 34 [unused-type-declaration]: unused type t0. Line 2, characters 12-13: 2 | type t0 = A (* unused type and constructor *) ^ -Warning 37: unused constructor A. +Warning 37 [unused-constructor]: unused constructor A. module T5 : sig end |}] @@ -103,11 +103,11 @@ end;; Line 2, characters 20-26: 2 | module M = struct type t end (* unused type t *) ^^^^^^ -Warning 34: unused type t. +Warning 34 [unused-type-declaration]: unused type t. Line 3, characters 2-9: 3 | open! M (* unused open *) ^^^^^^^ -Warning 66: unused open! M. +Warning 66 [unused-open-bang]: unused open! M. module T1_bis : sig end |}] @@ -130,11 +130,11 @@ end;; Line 2, characters 2-13: 2 | type t0 = A (* unused type and constructor *) ^^^^^^^^^^^ -Warning 34: unused type t0. +Warning 34 [unused-type-declaration]: unused type t0. Line 2, characters 12-13: 2 | type t0 = A (* unused type and constructor *) ^ -Warning 37: unused constructor A. +Warning 37 [unused-constructor]: unused constructor A. module T3_bis : sig end |}] @@ -148,15 +148,15 @@ end;; Line 3, characters 20-30: 3 | module M = struct type t = A end (* unused type and constructor *) ^^^^^^^^^^ -Warning 34: unused type t. +Warning 34 [unused-type-declaration]: unused type t. Line 3, characters 29-30: 3 | module M = struct type t = A end (* unused type and constructor *) ^ -Warning 37: unused constructor A. +Warning 37 [unused-constructor]: unused constructor A. Line 4, characters 2-9: 4 | open! M (* unused open; no shadowing (A below refers to the one in t0) *) ^^^^^^^ -Warning 66: unused open! M. +Warning 66 [unused-open-bang]: unused open! M. module T4_bis : sig end |}] @@ -170,11 +170,11 @@ end;; Line 2, characters 2-13: 2 | type t0 = A (* unused type and constructor *) ^^^^^^^^^^^ -Warning 34: unused type t0. +Warning 34 [unused-type-declaration]: unused type t0. Line 2, characters 12-13: 2 | type t0 = A (* unused type and constructor *) ^ -Warning 37: unused constructor A. +Warning 37 [unused-constructor]: unused constructor A. module T5_bis : sig end |}] diff --git a/testsuite/tests/typing-warnings/pr5892.ml b/testsuite/tests/typing-warnings/pr5892.ml index 46213d74..5b318ef4 100644 --- a/testsuite/tests/typing-warnings/pr5892.ml +++ b/testsuite/tests/typing-warnings/pr5892.ml @@ -17,7 +17,7 @@ let f : label choice -> bool = function Left -> true;; (* warn *) Line 1, characters 31-52: 1 | let f : label choice -> bool = function Left -> true;; (* warn *) ^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Right val f : CamlinternalOO.label choice -> bool = diff --git a/testsuite/tests/typing-warnings/pr6872.ml b/testsuite/tests/typing-warnings/pr6872.ml index 2bf9b848..3ca37433 100644 --- a/testsuite/tests/typing-warnings/pr6872.ml +++ b/testsuite/tests/typing-warnings/pr6872.ml @@ -27,7 +27,7 @@ A Line 1, characters 0-1: 1 | A ^ -Warning 41: A belongs to several types: a exn +Warning 41 [ambiguous-name]: A belongs to several types: a exn The first one was selected. Please disambiguate if this is wrong. - : a = A |}] @@ -38,7 +38,7 @@ raise A Line 1, characters 6-7: 1 | raise A ^ -Warning 42: this use of A relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of A relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Exception: A. |}] @@ -55,20 +55,20 @@ function Not_found -> 1 | A -> 2 | _ -> 3 Line 1, characters 26-27: 1 | function Not_found -> 1 | A -> 2 | _ -> 3 ^ -Warning 42: this use of A relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of A relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. - : exn -> int = |}, Principal{| Line 1, characters 26-27: 1 | function Not_found -> 1 | A -> 2 | _ -> 3 ^ -Warning 41: A belongs to several types: a exn -The first one was selected. Please disambiguate if this is wrong. +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. Line 1, characters 26-27: 1 | function Not_found -> 1 | A -> 2 | _ -> 3 ^ -Error: This pattern matches values of type a - but a pattern was expected which matches values of type exn +Warning 42 [disambiguated-name]: this use of A relies on type-directed disambiguation, +it will not compile with OCaml 4.00 or earlier. +- : exn -> int = |}] ;; @@ -77,12 +77,12 @@ try raise A with A -> 2 Line 1, characters 10-11: 1 | try raise A with A -> 2 ^ -Warning 42: this use of A relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of A relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 1, characters 17-18: 1 | try raise A with A -> 2 ^ -Warning 42: this use of A relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of A relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. - : int = 2 |}] diff --git a/testsuite/tests/typing-warnings/pr7085.ml b/testsuite/tests/typing-warnings/pr7085.ml index 0307b468..3516ee4d 100644 --- a/testsuite/tests/typing-warnings/pr7085.ml +++ b/testsuite/tests/typing-warnings/pr7085.ml @@ -31,7 +31,7 @@ module type T = Line 17, characters 5-35: 17 | match M.is_t () with None -> 0 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Some (Is Eq) module Make : functor (M : T) -> sig val f : unit -> int end diff --git a/testsuite/tests/typing-warnings/pr7115.ml b/testsuite/tests/typing-warnings/pr7115.ml index f4f5c35b..43e06cad 100644 --- a/testsuite/tests/typing-warnings/pr7115.ml +++ b/testsuite/tests/typing-warnings/pr7115.ml @@ -16,7 +16,7 @@ end;; Line 2, characters 10-11: 2 | let _f ~x (* x unused argument *) = function ^ -Warning 27: unused variable x. +Warning 27 [unused-var-strict]: unused variable x. module X1 : sig end |}] @@ -29,7 +29,7 @@ end;; Line 2, characters 6-7: 2 | let x = 42 (* unused value *) ^ -Warning 32: unused value x. +Warning 32 [unused-value-declaration]: unused value x. module X2 : sig end |}] @@ -44,10 +44,10 @@ end;; Line 2, characters 24-25: 2 | module O = struct let x = 42 (* unused *) end ^ -Warning 32: unused value x. +Warning 32 [unused-value-declaration]: unused value x. Line 3, characters 2-8: 3 | open O (* unused open *) ^^^^^^ -Warning 33: unused open O. +Warning 33 [unused-open]: unused open O. module X3 : sig end |}] diff --git a/testsuite/tests/typing-warnings/pr7261.compilers.reference b/testsuite/tests/typing-warnings/pr7261.compilers.reference index 671e51d8..57b41730 100644 --- a/testsuite/tests/typing-warnings/pr7261.compilers.reference +++ b/testsuite/tests/typing-warnings/pr7261.compilers.reference @@ -5,6 +5,6 @@ Error: Syntax error Line 2, characters 35-49: 2 | Foo: 'b * 'b -> foo constraint 'b = [> `Bla ];; ^^^^^^^^^^^^^^ -Warning 62: Type constraints do not apply to GADT cases of variant types. +Warning 62 [constraint-on-gadt]: Type constraints do not apply to GADT cases of variant types. type foo = Foo : 'b * 'b -> foo diff --git a/testsuite/tests/typing-warnings/pr7297.ml b/testsuite/tests/typing-warnings/pr7297.ml index 99131274..08a2a4be 100644 --- a/testsuite/tests/typing-warnings/pr7297.ml +++ b/testsuite/tests/typing-warnings/pr7297.ml @@ -14,6 +14,6 @@ let () = raise Exit; () ;; (* warn *) Line 1, characters 9-19: 1 | let () = raise Exit; () ;; (* warn *) ^^^^^^^^^^ -Warning 21: this statement never returns (or has an unsound type.) +Warning 21 [nonreturning-statement]: this statement never returns (or has an unsound type.) Exception: Stdlib.Exit. |}] diff --git a/testsuite/tests/typing-warnings/pr7553.ml b/testsuite/tests/typing-warnings/pr7553.ml index d479c419..a76f19d4 100644 --- a/testsuite/tests/typing-warnings/pr7553.ml +++ b/testsuite/tests/typing-warnings/pr7553.ml @@ -23,7 +23,7 @@ end = C;; Line 2, characters 2-8: 2 | open A ^^^^^^ -Warning 33: unused open A. +Warning 33 [unused-open]: unused open A. module rec C : sig end |}] @@ -39,12 +39,12 @@ end = D;; Line 5, characters 10-14: 5 | let None = None ^^^^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: Some _ Line 4, characters 6-12: 4 | open A ^^^^^^ -Warning 33: unused open A. +Warning 33 [unused-open]: unused open A. module rec D : sig module M : sig module X : sig end end end |}] diff --git a/testsuite/tests/typing-warnings/pr9244.ml b/testsuite/tests/typing-warnings/pr9244.ml index 01b9d08e..28bf91ff 100644 --- a/testsuite/tests/typing-warnings/pr9244.ml +++ b/testsuite/tests/typing-warnings/pr9244.ml @@ -22,7 +22,7 @@ end Line 5, characters 8-9: 5 | let x = 13 ^ -Warning 32: unused value x. +Warning 32 [unused-value-declaration]: unused value x. module M : sig module F2 : U -> U end |}] @@ -40,7 +40,7 @@ end Line 5, characters 8-9: 5 | let x = 13 ^ -Warning 32: unused value x. +Warning 32 [unused-value-declaration]: unused value x. module N : sig module F2 : U -> U end |}] @@ -50,6 +50,6 @@ module F (X : sig type t type s end) = struct type t = X.t end Line 1, characters 25-31: 1 | module F (X : sig type t type s end) = struct type t = X.t end ^^^^^^ -Warning 34: unused type s. +Warning 34 [unused-type-declaration]: unused type s. module F : functor (X : sig type t type s end) -> sig type t = X.t end |}] diff --git a/testsuite/tests/typing-warnings/records.ml b/testsuite/tests/typing-warnings/records.ml index ed7ff7e7..73938fc7 100644 --- a/testsuite/tests/typing-warnings/records.ml +++ b/testsuite/tests/typing-warnings/records.ml @@ -25,58 +25,58 @@ end;; Line 3, characters 19-20: 3 | let f1 (r:t) = r.x (* ok *) ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 4, characters 29-30: 4 | let f2 r = ignore (r:t); r.x (* non principal *) ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 7, characters 18-19: 7 | match r with {x; y} -> y + y (* ok *) ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 7, characters 21-22: 7 | match r with {x; y} -> y + y (* ok *) ^ -Warning 42: this use of y relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of y relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 7, characters 18-19: 7 | match r with {x; y} -> y + y (* ok *) ^ -Warning 27: unused variable x. +Warning 27 [unused-var-strict]: unused variable x. module OK : sig val f1 : M1.t -> int val f2 : M1.t -> int val f3 : M1.t -> int end |}, Principal{| Line 3, characters 19-20: 3 | let f1 (r:t) = r.x (* ok *) ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 4, characters 29-30: 4 | let f2 r = ignore (r:t); r.x (* non principal *) ^ -Warning 18: this type-based field disambiguation is not principal. +Warning 18 [not-principal]: this type-based field disambiguation is not principal. Line 4, characters 29-30: 4 | let f2 r = ignore (r:t); r.x (* non principal *) ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 7, characters 18-19: 7 | match r with {x; y} -> y + y (* ok *) ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 7, characters 21-22: 7 | match r with {x; y} -> y + y (* ok *) ^ -Warning 42: this use of y relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of y relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 7, characters 18-19: 7 | match r with {x; y} -> y + y (* ok *) ^ -Warning 27: unused variable x. +Warning 27 [unused-var-strict]: unused variable x. module OK : sig val f1 : M1.t -> int val f2 : M1.t -> int val f3 : M1.t -> int end |}] @@ -89,7 +89,7 @@ end;; (* fails *) Line 3, characters 25-31: 3 | let f r = match r with {x; y} -> y + y ^^^^^^ -Warning 41: these field labels belong to several types: M1.u M1.t +Warning 41 [ambiguous-name]: these field labels belong to several types: M1.u M1.t The first one was selected. Please disambiguate if this is wrong. Line 3, characters 35-36: 3 | let f r = match r with {x; y} -> y + y @@ -109,29 +109,38 @@ end;; (* fails for -principal *) Line 6, characters 8-9: 6 | {x; y} -> y + y ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 6, characters 11-12: 6 | {x; y} -> y + y ^ -Warning 42: this use of y relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of y relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 6, characters 8-9: 6 | {x; y} -> y + y ^ -Warning 27: unused variable x. +Warning 27 [unused-var-strict]: unused variable x. module F2 : sig val f : M1.t -> int end |}, Principal{| -Line 6, characters 7-13: +Line 6, characters 8-9: 6 | {x; y} -> y + y - ^^^^^^ -Warning 41: these field labels belong to several types: M1.u M1.t -The first one was selected. Please disambiguate if this is wrong. + ^ +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, +it will not compile with OCaml 4.00 or earlier. +Line 6, characters 11-12: +6 | {x; y} -> y + y + ^ +Warning 42 [disambiguated-name]: this use of y relies on type-directed disambiguation, +it will not compile with OCaml 4.00 or earlier. Line 6, characters 7-13: 6 | {x; y} -> y + y ^^^^^^ -Error: This pattern matches values of type M1.u - but a pattern was expected which matches values of type M1.t +Warning 18 [not-principal]: this type-based record disambiguation is not principal. +Line 6, characters 8-9: +6 | {x; y} -> y + y + ^ +Warning 27 [unused-var-strict]: unused variable x. +module F2 : sig val f : M1.t -> int end |}] (* Use type information with modules*) @@ -147,7 +156,7 @@ let f (r:M.t) = r.M.x;; (* ok *) Line 1, characters 18-21: 1 | let f (r:M.t) = r.M.x;; (* ok *) ^^^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. val f : M.t -> int = |}] @@ -156,13 +165,13 @@ let f (r:M.t) = r.x;; (* warning *) Line 1, characters 18-19: 1 | let f (r:M.t) = r.x;; (* warning *) ^ -Warning 40: x was selected from type M.t. +Warning 40 [name-out-of-scope]: x was selected from type M.t. It is not visible in the current scope, and will not be selected if the type becomes unknown. Line 1, characters 18-19: 1 | let f (r:M.t) = r.x;; (* warning *) ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. val f : M.t -> int = |}] @@ -171,12 +180,12 @@ let f ({x}:M.t) = x;; (* warning *) Line 1, characters 8-9: 1 | let f ({x}:M.t) = x;; (* warning *) ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 1, characters 7-10: 1 | let f ({x}:M.t) = x;; (* warning *) ^^^ -Warning 40: this record of type M.t contains fields that are +Warning 40 [name-out-of-scope]: this record of type M.t contains fields that are not visible in the current scope: x. They will not be selected if the type becomes unknown. val f : M.t -> int = @@ -203,12 +212,12 @@ end;; Line 4, characters 20-21: 4 | let f (r:M.t) = r.x ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 3, characters 2-8: 3 | open N ^^^^^^ -Warning 33: unused open N. +Warning 33 [unused-open]: unused open N. module OK : sig val f : M.t -> int end |}] @@ -253,12 +262,12 @@ end;; (* ok *) Line 3, characters 9-10: 3 | let f {x;z} = x,z ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 3, characters 8-13: 3 | let f {x;z} = x,z ^^^^^ -Warning 9: the following labels are not bound in this record pattern: +Warning 9 [missing-record-field-pattern]: the following labels are not bound in this record pattern: y Either bind these labels explicitly or add '; _' to the pattern. module OK : sig val f : M.u -> bool * char end @@ -271,7 +280,7 @@ end;; (* fail for missing label *) Line 3, characters 11-12: 3 | let r = {x=true;z='z'} ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 3, characters 10-24: 3 | let r = {x=true;z='z'} @@ -288,12 +297,12 @@ end;; (* ok *) Line 4, characters 11-12: 4 | let r = {x=3; y=true} ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 4, characters 16-17: 4 | let r = {x=3; y=true} ^ -Warning 42: this use of y relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of y relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. module OK : sig @@ -354,12 +363,12 @@ let r = {MN.x = 3; NM.y = 4};; (* error: type would change with order *) Line 1, characters 8-28: 1 | let r = {MN.x = 3; NM.y = 4};; (* error: type would change with order *) ^^^^^^^^^^^^^^^^^^^^ -Warning 41: x belongs to several types: MN.bar MN.foo +Warning 41 [ambiguous-name]: x belongs to several types: MN.bar MN.foo The first one was selected. Please disambiguate if this is wrong. Line 1, characters 8-28: 1 | let r = {MN.x = 3; NM.y = 4};; (* error: type would change with order *) ^^^^^^^^^^^^^^^^^^^^ -Warning 41: y belongs to several types: NM.foo NM.bar +Warning 41 [ambiguous-name]: y belongs to several types: NM.foo NM.bar The first one was selected. Please disambiguate if this is wrong. Line 1, characters 19-23: 1 | let r = {MN.x = 3; NM.y = 4};; (* error: type would change with order *) @@ -389,7 +398,7 @@ end;; Line 3, characters 37-38: 3 | let f r = ignore (r: foo); {r with x = 2; z = 3} ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 3, characters 44-45: 3 | let f r = ignore (r: foo); {r with x = 2; z = 3} @@ -417,7 +426,7 @@ end;; Line 3, characters 38-39: 3 | let f r = ignore (r: foo); { r with x = 3; a = 4 } ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 3, characters 45-46: 3 | let f r = ignore (r: foo); { r with x = 3; a = 4 } @@ -434,12 +443,12 @@ end;; Line 3, characters 11-12: 3 | let r = {x=1; y=2} ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 3, characters 16-17: 3 | let r = {x=1; y=2} ^ -Warning 42: this use of y relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of y relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 4, characters 18-19: 4 | let r: other = {x=1; y=2} @@ -496,7 +505,7 @@ class f (_ : 'a) (_ : 'a) = object end;; Line 1, characters 12-13: 1 | class g = f A;; (* ok *) ^ -Warning 42: this use of A relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of A relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. class g : f class f : 'a -> 'a -> object end @@ -506,28 +515,28 @@ class g = f (A : t) A;; (* warn with -principal *) Line 1, characters 13-14: 1 | class g = f (A : t) A;; (* warn with -principal *) ^ -Warning 42: this use of A relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of A relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 1, characters 20-21: 1 | class g = f (A : t) A;; (* warn with -principal *) ^ -Warning 42: this use of A relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of A relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. class g : f |}, Principal{| Line 1, characters 13-14: 1 | class g = f (A : t) A;; (* warn with -principal *) ^ -Warning 42: this use of A relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of A relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 1, characters 20-21: 1 | class g = f (A : t) A;; (* warn with -principal *) ^ -Warning 18: this type-based constructor disambiguation is not principal. +Warning 18 [not-principal]: this type-based constructor disambiguation is not principal. Line 1, characters 20-21: 1 | class g = f (A : t) A;; (* warn with -principal *) ^ -Warning 42: this use of A relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of A relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. class g : f |}] @@ -547,12 +556,12 @@ end;; Line 7, characters 15-16: 7 | let y : t = {x = 0} ^ -Warning 42: this use of x relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of x relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. Line 6, characters 2-8: 6 | open M (* this open is unused, it isn't reported as shadowing 'x' *) ^^^^^^ -Warning 33: unused open M. +Warning 33 [unused-open]: unused open M. module Shadow1 : sig type t = { x : int; } @@ -572,11 +581,11 @@ end;; Line 6, characters 2-8: 6 | open M (* this open shadows label 'x' *) ^^^^^^ -Warning 45: this open statement shadows the label x (which is later used) +Warning 45 [open-shadow-label-constructor]: this open statement shadows the label x (which is later used) Line 7, characters 10-18: 7 | let y = {x = ""} ^^^^^^^^ -Warning 41: these field labels belong to several types: M.s t +Warning 41 [ambiguous-name]: these field labels belong to several types: M.s t The first one was selected. Please disambiguate if this is wrong. module Shadow2 : sig @@ -598,7 +607,7 @@ end;; Line 5, characters 37-40: 5 | let f (u : u) = match u with `Key {loc} -> loc ^^^ -Warning 42: this use of loc relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of loc relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. module P6235 : sig @@ -623,7 +632,7 @@ end;; Line 7, characters 11-14: 7 | |`Key {loc} -> loc ^^^ -Warning 42: this use of loc relies on type-directed disambiguation, +Warning 42 [disambiguated-name]: this use of loc relies on type-directed disambiguation, it will not compile with OCaml 4.00 or earlier. module P6235' : sig @@ -633,23 +642,22 @@ module P6235' : val f : u -> string end |}, Principal{| -Line 7, characters 10-15: +Line 7, characters 11-14: 7 | |`Key {loc} -> loc - ^^^^^ -Warning 41: these field labels belong to several types: v t -The first one was selected. Please disambiguate if this is wrong. + ^^^ +Warning 42 [disambiguated-name]: this use of loc relies on type-directed disambiguation, +it will not compile with OCaml 4.00 or earlier. Line 7, characters 10-15: 7 | |`Key {loc} -> loc ^^^^^ -Warning 9: the following labels are not bound in this record pattern: -x -Either bind these labels explicitly or add '; _' to the pattern. -Line 7, characters 5-15: -7 | |`Key {loc} -> loc - ^^^^^^^^^^ -Error: This pattern matches values of type [? `Key of v ] - but a pattern was expected which matches values of type u - Types for tag `Key are incompatible +Warning 18 [not-principal]: this type-based record disambiguation is not principal. +module P6235' : + sig + type t = { loc : string; } + type v = { loc : string; x : int; } + type u = [ `Key of t ] + val f : u -> string + end |}] (** no candidates after filtering; @@ -670,3 +678,59 @@ Line 5, characters 12-15: Error: The field M.x belongs to the record type M.t but a field was expected belonging to the record type u |}] + +(* PR#8747 *) +module M = struct type t = { x : int; y: char } end +let f (x : M.t) = { x with y = 'a' } +let g (x : M.t) = { x with y = 'a' } :: [] +let h (x : M.t) = { x with y = 'a' } :: { x with y = 'b' } :: [];; +[%%expect{| +module M : sig type t = { x : int; y : char; } end +Line 2, characters 27-28: +2 | let f (x : M.t) = { x with y = 'a' } + ^ +Warning 42 [disambiguated-name]: this use of y relies on type-directed disambiguation, +it will not compile with OCaml 4.00 or earlier. +Line 2, characters 18-36: +2 | let f (x : M.t) = { x with y = 'a' } + ^^^^^^^^^^^^^^^^^^ +Warning 40 [name-out-of-scope]: this record of type M.t contains fields that are +not visible in the current scope: y. +They will not be selected if the type becomes unknown. +val f : M.t -> M.t = +Line 3, characters 27-28: +3 | let g (x : M.t) = { x with y = 'a' } :: [] + ^ +Warning 42 [disambiguated-name]: this use of y relies on type-directed disambiguation, +it will not compile with OCaml 4.00 or earlier. +Line 3, characters 18-36: +3 | let g (x : M.t) = { x with y = 'a' } :: [] + ^^^^^^^^^^^^^^^^^^ +Warning 40 [name-out-of-scope]: this record of type M.t contains fields that are +not visible in the current scope: y. +They will not be selected if the type becomes unknown. +val g : M.t -> M.t list = +Line 4, characters 27-28: +4 | let h (x : M.t) = { x with y = 'a' } :: { x with y = 'b' } :: [];; + ^ +Warning 42 [disambiguated-name]: this use of y relies on type-directed disambiguation, +it will not compile with OCaml 4.00 or earlier. +Line 4, characters 18-36: +4 | let h (x : M.t) = { x with y = 'a' } :: { x with y = 'b' } :: [];; + ^^^^^^^^^^^^^^^^^^ +Warning 40 [name-out-of-scope]: this record of type M.t contains fields that are +not visible in the current scope: y. +They will not be selected if the type becomes unknown. +Line 4, characters 49-50: +4 | let h (x : M.t) = { x with y = 'a' } :: { x with y = 'b' } :: [];; + ^ +Warning 42 [disambiguated-name]: this use of y relies on type-directed disambiguation, +it will not compile with OCaml 4.00 or earlier. +Line 4, characters 40-58: +4 | let h (x : M.t) = { x with y = 'a' } :: { x with y = 'b' } :: [];; + ^^^^^^^^^^^^^^^^^^ +Warning 40 [name-out-of-scope]: this record of type M.t contains fields that are +not visible in the current scope: y. +They will not be selected if the type becomes unknown. +val h : M.t -> M.t list = +|}] diff --git a/testsuite/tests/typing-warnings/unused_functor_parameter.ml b/testsuite/tests/typing-warnings/unused_functor_parameter.ml index c8691af9..997fca26 100644 --- a/testsuite/tests/typing-warnings/unused_functor_parameter.ml +++ b/testsuite/tests/typing-warnings/unused_functor_parameter.ml @@ -8,7 +8,7 @@ module Foo(Unused : sig end) = struct end;; Line 1, characters 11-17: 1 | module Foo(Unused : sig end) = struct end;; ^^^^^^ -Warning 60: unused module Unused. +Warning 60 [unused-module]: unused module Unused. module Foo : functor (Unused : sig end) -> sig end |}] @@ -17,7 +17,7 @@ module type S = functor (Unused : sig end) -> sig end;; Line 1, characters 25-31: 1 | module type S = functor (Unused : sig end) -> sig end;; ^^^^^^ -Warning 67: unused functor parameter Unused. +Warning 67 [unused-functor-parameter]: unused functor parameter Unused. module type S = functor (Unused : sig end) -> sig end |}] @@ -28,6 +28,6 @@ end;; Line 2, characters 12-18: 2 | module M (Unused : sig end) : sig end ^^^^^^ -Warning 67: unused functor parameter Unused. +Warning 67 [unused-functor-parameter]: unused functor parameter Unused. module type S = sig module M : functor (Unused : sig end) -> sig end end |}] diff --git a/testsuite/tests/typing-warnings/unused_rec.ml b/testsuite/tests/typing-warnings/unused_rec.ml index 0ba9849f..5f5dc4e2 100644 --- a/testsuite/tests/typing-warnings/unused_rec.ml +++ b/testsuite/tests/typing-warnings/unused_rec.ml @@ -9,7 +9,7 @@ let rec f () = 3;; Line 3, characters 8-9: 3 | let rec f () = 3;; ^ -Warning 39: unused rec flag. +Warning 39 [unused-rec-flag]: unused rec flag. val f : unit -> int = |}];; @@ -23,7 +23,7 @@ let[@warning "+39"] rec h () = 3;; Line 1, characters 24-25: 1 | let[@warning "+39"] rec h () = 3;; ^ -Warning 39: unused rec flag. +Warning 39 [unused-rec-flag]: unused rec flag. val h : unit -> int = |}];; @@ -44,6 +44,6 @@ let[@warning "+39"] rec h () = 3;; Line 1, characters 24-25: 1 | let[@warning "+39"] rec h () = 3;; ^ -Warning 39: unused rec flag. +Warning 39 [unused-rec-flag]: unused rec flag. val h : unit -> int = |}];; diff --git a/testsuite/tests/typing-warnings/unused_recmodule.ml b/testsuite/tests/typing-warnings/unused_recmodule.ml index 78ce42ef..223de358 100644 --- a/testsuite/tests/typing-warnings/unused_recmodule.ml +++ b/testsuite/tests/typing-warnings/unused_recmodule.ml @@ -26,6 +26,6 @@ end;; Line 14, characters 4-10: 14 | type t ^^^^^^ -Warning 34: unused type t. +Warning 34 [unused-type-declaration]: unused type t. module M : sig end |}];; diff --git a/testsuite/tests/typing-warnings/unused_types.ml b/testsuite/tests/typing-warnings/unused_types.ml index a7385e76..3522069f 100644 --- a/testsuite/tests/typing-warnings/unused_types.ml +++ b/testsuite/tests/typing-warnings/unused_types.ml @@ -12,7 +12,7 @@ end Line 3, characters 2-19: 3 | type unused = int ^^^^^^^^^^^^^^^^^ -Warning 34: unused type unused. +Warning 34 [unused-type-declaration]: unused type unused. module Unused : sig end |}] @@ -26,7 +26,7 @@ end Line 4, characters 2-27: 4 | type nonrec unused = used ^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 34: unused type unused. +Warning 34 [unused-type-declaration]: unused type unused. module Unused_nonrec : sig end |}] @@ -39,11 +39,11 @@ end Line 3, characters 2-27: 3 | type unused = A of unused ^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 34: unused type unused. +Warning 34 [unused-type-declaration]: unused type unused. Line 3, characters 16-27: 3 | type unused = A of unused ^^^^^^^^^^^ -Warning 37: unused constructor A. +Warning 37 [unused-constructor]: unused constructor A. module Unused_rec : sig end |}] @@ -69,7 +69,7 @@ end Line 4, characters 11-12: 4 | type t = T ^ -Warning 37: unused constructor T. +Warning 37 [unused-constructor]: unused constructor T. module Unused_constructor : sig type t end |}] @@ -86,7 +86,7 @@ end Line 5, characters 11-12: 5 | type t = T ^ -Warning 37: constructor T is never used to build values. +Warning 37 [unused-constructor]: constructor T is never used to build values. (However, this constructor appears in patterns.) module Unused_constructor_outside_patterns : sig type t val nothing : t -> unit end @@ -102,7 +102,7 @@ end Line 4, characters 11-12: 4 | type t = T ^ -Warning 37: constructor T is never used to build values. +Warning 37 [unused-constructor]: constructor T is never used to build values. Its type is exported as a private type. module Unused_constructor_exported_private : sig type t = private T end |}] @@ -130,7 +130,7 @@ end Line 4, characters 19-20: 4 | type t = private T ^ -Warning 37: unused constructor T. +Warning 37 [unused-constructor]: unused constructor T. module Unused_private_constructor : sig type t end |}] @@ -177,7 +177,7 @@ end Line 3, characters 2-26: 3 | exception Nobody_uses_me ^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 38: unused exception Nobody_uses_me +Warning 38 [unused-extension]: unused exception Nobody_uses_me module Unused_exception : sig end |}] @@ -192,7 +192,7 @@ end Line 5, characters 12-26: 5 | type t += Nobody_uses_me ^^^^^^^^^^^^^^ -Warning 38: unused extension constructor Nobody_uses_me +Warning 38 [unused-extension]: unused extension constructor Nobody_uses_me module Unused_extension_constructor : sig type t = .. end |}] @@ -209,7 +209,7 @@ end Line 4, characters 2-32: 4 | exception Nobody_constructs_me ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 38: exception Nobody_constructs_me is never used to build values. +Warning 38 [unused-extension]: exception Nobody_constructs_me is never used to build values. (However, this constructor appears in patterns.) module Unused_exception_outside_patterns : sig val falsity : exn -> bool end |}] @@ -229,7 +229,7 @@ end Line 6, characters 12-27: 6 | type t += Noone_builds_me ^^^^^^^^^^^^^^^ -Warning 38: extension constructor Noone_builds_me is never used to build values. +Warning 38 [unused-extension]: extension constructor Noone_builds_me is never used to build values. (However, this constructor appears in patterns.) module Unused_extension_outside_patterns : sig type t = .. val falsity : t -> bool end @@ -245,7 +245,7 @@ end Line 4, characters 2-23: 4 | exception Private_exn ^^^^^^^^^^^^^^^^^^^^^ -Warning 38: exception Private_exn is never used to build values. +Warning 38 [unused-extension]: exception Private_exn is never used to build values. It is exported or rebound as a private extension. module Unused_exception_exported_private : sig type exn += private Private_exn end @@ -263,7 +263,7 @@ end Line 6, characters 12-23: 6 | type t += Private_ext ^^^^^^^^^^^ -Warning 38: extension constructor Private_ext is never used to build values. +Warning 38 [unused-extension]: extension constructor Private_ext is never used to build values. It is exported or rebound as a private extension. module Unused_extension_exported_private : sig type t = .. type t += private Private_ext end @@ -294,7 +294,7 @@ end Line 5, characters 20-31: 5 | type t += private Private_ext ^^^^^^^^^^^ -Warning 38: unused extension constructor Private_ext +Warning 38 [unused-extension]: unused extension constructor Private_ext module Unused_private_extension : sig type t end |}] @@ -330,7 +330,7 @@ end;; Line 3, characters 11-12: 3 | type t = A [@@warning "-34"] ^ -Warning 37: unused constructor A. +Warning 37 [unused-constructor]: unused constructor A. module Unused_type_disable_warning : sig end |}] @@ -342,6 +342,6 @@ end;; Line 3, characters 2-30: 3 | type t = A [@@warning "-37"] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 34: unused type t. +Warning 34 [unused-type-declaration]: unused type t. module Unused_constructor_disable_warning : sig end |}] diff --git a/testsuite/tests/typing-warnings/warning16.ml b/testsuite/tests/typing-warnings/warning16.ml new file mode 100644 index 00000000..a7e97d6d --- /dev/null +++ b/testsuite/tests/typing-warnings/warning16.ml @@ -0,0 +1,58 @@ +(* TEST + * expect +*) +let foo ?x = () +[%%expect{| +Line 1, characters 9-10: +1 | let foo ?x = () + ^ +Warning 16 [unerasable-optional-argument]: this optional argument cannot be erased. +val foo : ?x:'a -> unit = +|}] + +let foo ?x ~y = () +[%%expect{| +Line 1, characters 9-10: +1 | let foo ?x ~y = () + ^ +Warning 16 [unerasable-optional-argument]: this optional argument cannot be erased. +val foo : ?x:'a -> y:'b -> unit = +|}] + +let foo ?x () = () +[%%expect{| +val foo : ?x:'a -> unit -> unit = +|}] + +let foo ?x ~y () = () +[%%expect{| +val foo : ?x:'a -> y:'b -> unit -> unit = +|}] + +class bar ?x = object end +[%%expect{| +Line 1, characters 11-12: +1 | class bar ?x = object end + ^ +Warning 16 [unerasable-optional-argument]: this optional argument cannot be erased. +class bar : ?x:'a -> object end +|}] + +class bar ?x ~y = object end +[%%expect{| +Line 1, characters 11-12: +1 | class bar ?x ~y = object end + ^ +Warning 16 [unerasable-optional-argument]: this optional argument cannot be erased. +class bar : ?x:'a -> y:'b -> object end +|}] + +class bar ?x () = object end +[%%expect{| +class bar : ?x:'a -> unit -> object end +|}] + +class foo ?x ~y () = object end +[%%expect{| +class foo : ?x:'a -> y:'b -> unit -> object end +|}] diff --git a/testsuite/tests/unboxed-primitive-args/test.ml b/testsuite/tests/unboxed-primitive-args/test.ml index 62104351..0ce5217e 100644 --- a/testsuite/tests/unboxed-primitive-args/test.ml +++ b/testsuite/tests/unboxed-primitive-args/test.ml @@ -1,22 +1,19 @@ (* TEST -* hasunix -include unix - files = "common.mli common.ml test_common.c test_common.h" -** setup-ocamlopt.byte-build-env -*** ocaml +* setup-ocamlopt.byte-build-env +** ocaml test_file = "${test_source_directory}/gen_test.ml" ocaml_script_as_argument = "true" arguments = "c" compiler_output = "stubs.c" -**** ocaml +*** ocaml arguments = "ml" compiler_output = "main.ml" -***** ocamlopt.byte +**** ocamlopt.byte all_modules = "test_common.c stubs.c common.mli common.ml main.ml" -****** run -******* check-program-output +***** run +****** check-program-output *) diff --git a/testsuite/tests/unwind/driver.ml b/testsuite/tests/unwind/driver.ml index 421f85a6..38fd7f06 100644 --- a/testsuite/tests/unwind/driver.ml +++ b/testsuite/tests/unwind/driver.ml @@ -4,17 +4,18 @@ script = "sh ${test_source_directory}/check-linker-version.sh" files = "mylib.mli mylib.ml stack_walker.c" * macos -** script -*** setup-ocamlopt.byte-build-env -**** ocamlopt.byte +** arch_amd64 +*** script +**** setup-ocamlopt.byte-build-env +***** ocamlopt.byte flags = "-opaque" module = "mylib.mli" -***** ocamlopt.byte +****** ocamlopt.byte module = "" flags = "-cclib -Wl,-keep_dwarf_unwind" all_modules = "mylib.ml driver.ml stack_walker.c" program = "${test_build_directory}/unwind_test" -****** run +******* run *) diff --git a/testsuite/tests/unwind/stack_walker.c b/testsuite/tests/unwind/stack_walker.c index 09afcadd..342eb932 100644 --- a/testsuite/tests/unwind/stack_walker.c +++ b/testsuite/tests/unwind/stack_walker.c @@ -11,18 +11,17 @@ value ml_func_with_10_params_native(value x1, value x2, value x3, value x4, return Val_unit; } -void error() { - exit(1); -} - -void perform_stack_walk() { +int perform_stack_walk(int dbg) { unw_context_t ctxt; unw_getcontext(&ctxt); unw_cursor_t cursor; { int result = unw_init_local(&cursor, &ctxt); - if (result != 0) error(); + if (result != 0) { + if (dbg) printf("unw_init_local failed: %d\n", result); + return -1; + } } int reached_main = 0; @@ -33,27 +32,40 @@ void perform_stack_walk() { unw_word_t ip_offset; // IP - start_of_proc int result = unw_get_proc_name(&cursor, procname, sizeof(procname), &ip_offset); - if (result != 0) error(); + if (result != 0) { + if (dbg) printf("unw_get_proc_name failed: %d\n", result); + return -1; + } + if (strcmp(procname, "main") == 0) reached_main = 1; - //printf("%s + %lld\n", procname, (long long int)ip_offset); + if (dbg) printf("%s + %lld\n", procname, (long long int)ip_offset); } { int result = unw_step(&cursor); if (result == 0) break; - if (result < 0) error(); + if (result < 0) { + if (dbg) printf("unw_step failed: %d\n", result); + return -1; + } } } - //printf("Reached end of stack.\n"); + if (dbg) printf("Reached end of stack.\n"); if (!reached_main) { - //printf("Failure: Did not reach main.\n"); - error(); + if (dbg) printf("Failure: Did not reach main.\n"); + return -1; } + return 0; } value ml_perform_stack_walk() { - perform_stack_walk(); + if (perform_stack_walk(0) != 0) { + printf("TEST FAILED\n"); + /* Re-run the test to produce a trace */ + perform_stack_walk(1); + exit(1); + } return Val_unit; } diff --git a/testsuite/tests/warnings/mnemonics.mll b/testsuite/tests/warnings/mnemonics.mll new file mode 100644 index 00000000..1071c3a1 --- /dev/null +++ b/testsuite/tests/warnings/mnemonics.mll @@ -0,0 +1,84 @@ +(* TEST + +ocamllex_flags = "-q" + +*) + +{ +} + +let ws = [' ''\t'] +let nl = '\n' +let constr = ['A'-'Z']['a'-'z''A'-'Z''0'-'9''_']* +let int = ['0'-'9']+ +let mnemo = ['a'-'z']['a'-'z''-']*['a'-'z'] + +rule seek_let_number_function = parse +| ws* "let" ws+ "number" ws* "=" ws* "function" ws* '\n' + { () } +| [^'\n']* '\n' + { seek_let_number_function lexbuf } + +and constructors = parse +| ws* '|' ws* (constr as c) (ws* '_')? ws* "->" ws* (int as n) [^'\n']* '\n' + { (c, int_of_string n) :: constructors lexbuf } +| ws* ";;" ws* '\n' + { [] } + +and mnemonics = parse +| ws* (int as n) ws+ '[' (mnemo as s) ']' [^'\n']* '\n' + { (s, int_of_string n) :: mnemonics lexbuf } +| [^'\n']* '\n' + { mnemonics lexbuf } +| eof + { [] } + +{ +let ocamlsrcdir = Sys.getenv "ocamlsrcdir" + +let ocamlrun = Sys.getenv "ocamlrun" + +let constructors = + let ic = open_in Filename.(concat ocamlsrcdir (concat "utils" "warnings.ml")) in + Fun.protect ~finally:(fun () -> close_in_noerr ic) + (fun () -> + let lexbuf = Lexing.from_channel ic in + seek_let_number_function lexbuf; + constructors lexbuf + ) + +let mnemonics = + let stdout = "warn-help.out" in + let n = + Sys.command + Filename.(quote_command ~stdout + ocamlrun [concat ocamlsrcdir "ocamlc"; "-warn-help"]) + in + assert (n = 0); + let ic = open_in stdout in + Fun.protect ~finally:(fun () -> close_in_noerr ic) + (fun () -> + let lexbuf = Lexing.from_channel ic in + mnemonics lexbuf + ) + +let mnemonic_of_constructor s = + String.map (function '_' -> '-' | c -> Char.lowercase_ascii c) s + +let () = + List.iter (fun (s, n) -> + let f (c, m) = mnemonic_of_constructor c = s && n = m in + if not (List.exists f constructors) then + Printf.printf "Could not find constructor corresponding to mnemonic %S (%d)\n%!" s n + ) mnemonics + +let _ = + List.fold_left (fun first (c, m) -> + if List.mem (mnemonic_of_constructor c, m) mnemonics then first + else begin + if first then print_endline "Constructors without associated mnemonic:"; + print_endline c; + false + end + ) true constructors +} diff --git a/testsuite/tests/warnings/mnemonics.reference b/testsuite/tests/warnings/mnemonics.reference new file mode 100644 index 00000000..3cd3dfa2 --- /dev/null +++ b/testsuite/tests/warnings/mnemonics.reference @@ -0,0 +1,2 @@ +Constructors without associated mnemonic: +All_clauses_guarded diff --git a/testsuite/tests/warnings/w01.compilers.reference b/testsuite/tests/warnings/w01.compilers.reference index 6973f4d5..e46fa9de 100644 --- a/testsuite/tests/warnings/w01.compilers.reference +++ b/testsuite/tests/warnings/w01.compilers.reference @@ -1,27 +1,27 @@ File "w01.ml", line 14, characters 12-14: 14 | let foo = ( *);; ^^ -Warning 2: this is not the end of a comment. +Warning 2 [comment-not-end]: this is not the end of a comment. File "w01.ml", line 20, characters 0-3: 20 | f 1; f 1;; ^^^ -Warning 5: this function application is partial, +Warning 5 [ignored-partial-application]: this function application is partial, maybe some arguments are missing. File "w01.ml", line 30, characters 4-5: 30 | let 1 = 1;; ^ -Warning 8: this pattern-matching is not exhaustive. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: 0 File "w01.ml", line 35, characters 0-1: 35 | 1; 1;; ^ -Warning 10: this expression should have type unit. +Warning 10 [non-unit-statement]: this expression should have type unit. File "w01.ml", line 42, characters 2-3: 42 | | 1 -> () ^ -Warning 11: this match case is unused. +Warning 11 [redundant-case]: this match case is unused. File "w01.ml", line 19, characters 8-9: 19 | let f x y = x;; ^ -Warning 27: unused variable y. +Warning 27 [unused-var-strict]: unused variable y. diff --git a/testsuite/tests/warnings/w03.compilers.reference b/testsuite/tests/warnings/w03.compilers.reference index 3e75b2ef..fc79e8cc 100644 --- a/testsuite/tests/warnings/w03.compilers.reference +++ b/testsuite/tests/warnings/w03.compilers.reference @@ -5,4 +5,4 @@ Alert deprecated: A File "w03.ml", line 17, characters 12-26: 17 | exception B [@@deprecated] ^^^^^^^^^^^^^^ -Warning 53: the "deprecated" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "deprecated" attribute cannot appear in this context diff --git a/testsuite/tests/warnings/w04.compilers.reference b/testsuite/tests/warnings/w04.compilers.reference index bb39fb4d..1c6cc55c 100644 --- a/testsuite/tests/warnings/w04.compilers.reference +++ b/testsuite/tests/warnings/w04.compilers.reference @@ -2,5 +2,5 @@ File "w04.ml", lines 21-23, characters 10-8: 21 | ..........match x with 22 | | A -> 0 23 | | _ -> 1 -Warning 4: this pattern-matching is fragile. +Warning 4 [fragile-match]: this pattern-matching is fragile. It will remain exhaustive when constructors are added to type t. diff --git a/testsuite/tests/warnings/w04_failure.compilers.reference b/testsuite/tests/warnings/w04_failure.compilers.reference index d0fac4da..8b24c630 100644 --- a/testsuite/tests/warnings/w04_failure.compilers.reference +++ b/testsuite/tests/warnings/w04_failure.compilers.reference @@ -3,19 +3,19 @@ File "w04_failure.ml", lines 20-23, characters 2-17: 21 | | AB, _, A -> () 22 | | _, XY, X -> () 23 | | _, _, _ -> () -Warning 4: this pattern-matching is fragile. +Warning 4 [fragile-match]: this pattern-matching is fragile. It will remain exhaustive when constructors are added to type repr. File "w04_failure.ml", lines 20-23, characters 2-17: 20 | ..match r1, r2, t with 21 | | AB, _, A -> () 22 | | _, XY, X -> () 23 | | _, _, _ -> () -Warning 4: this pattern-matching is fragile. +Warning 4 [fragile-match]: this pattern-matching is fragile. It will remain exhaustive when constructors are added to type ab. File "w04_failure.ml", lines 20-23, characters 2-17: 20 | ..match r1, r2, t with 21 | | AB, _, A -> () 22 | | _, XY, X -> () 23 | | _, _, _ -> () -Warning 4: this pattern-matching is fragile. +Warning 4 [fragile-match]: this pattern-matching is fragile. It will remain exhaustive when constructors are added to type xy. diff --git a/testsuite/tests/warnings/w06.compilers.reference b/testsuite/tests/warnings/w06.compilers.reference index 4a118e20..3d46d10e 100644 --- a/testsuite/tests/warnings/w06.compilers.reference +++ b/testsuite/tests/warnings/w06.compilers.reference @@ -1,8 +1,8 @@ File "w06.ml", line 16, characters 9-12: 16 | let () = foo 2 ^^^ -Warning 6: label bar was omitted in the application of this function. +Warning 6 [labels-omitted]: label bar was omitted in the application of this function. File "w06.ml", line 17, characters 9-12: 17 | let () = bar 4 2 ^^^ -Warning 6: labels foo, baz were omitted in the application of this function. +Warning 6 [labels-omitted]: labels foo, baz were omitted in the application of this function. diff --git a/testsuite/tests/warnings/w32.compilers.reference b/testsuite/tests/warnings/w32.compilers.reference index 6cf44b0b..74934294 100644 --- a/testsuite/tests/warnings/w32.compilers.reference +++ b/testsuite/tests/warnings/w32.compilers.reference @@ -1,63 +1,63 @@ File "w32.mli", line 12, characters 10-11: 12 | module F (X : sig val x : int end) : sig end ^ -Warning 67: unused functor parameter X. +Warning 67 [unused-functor-parameter]: unused functor parameter X. File "w32.mli", line 14, characters 10-11: 14 | module G (X : sig val x : int end) : sig end ^ -Warning 67: unused functor parameter X. +Warning 67 [unused-functor-parameter]: unused functor parameter X. File "w32.mli", line 16, characters 10-11: 16 | module H (X : sig val x : int end) : sig val x : int end ^ -Warning 67: unused functor parameter X. +Warning 67 [unused-functor-parameter]: unused functor parameter X. File "w32.ml", line 40, characters 24-25: 40 | let[@warning "-32"] rec q x = x ^ -Warning 39: unused rec flag. +Warning 39 [unused-rec-flag]: unused rec flag. File "w32.ml", line 43, characters 24-25: 43 | let[@warning "-32"] rec s x = x ^ -Warning 39: unused rec flag. +Warning 39 [unused-rec-flag]: unused rec flag. File "w32.ml", line 20, characters 4-5: 20 | let h x = x ^ -Warning 32: unused value h. +Warning 32 [unused-value-declaration]: unused value h. File "w32.ml", line 26, characters 4-5: 26 | and j x = x ^ -Warning 32: unused value j. +Warning 32 [unused-value-declaration]: unused value j. File "w32.ml", line 28, characters 4-5: 28 | let k x = x ^ -Warning 32: unused value k. +Warning 32 [unused-value-declaration]: unused value k. File "w32.ml", line 41, characters 4-5: 41 | and r x = x ^ -Warning 32: unused value r. +Warning 32 [unused-value-declaration]: unused value r. File "w32.ml", line 44, characters 20-21: 44 | and[@warning "-39"] t x = x ^ -Warning 32: unused value t. +Warning 32 [unused-value-declaration]: unused value t. File "w32.ml", line 46, characters 24-25: 46 | let[@warning "-39"] rec u x = x ^ -Warning 32: unused value u. +Warning 32 [unused-value-declaration]: unused value u. File "w32.ml", line 47, characters 4-5: 47 | and v x = v x ^ -Warning 32: unused value v. +Warning 32 [unused-value-declaration]: unused value v. File "w32.ml", line 55, characters 22-23: 55 | let[@warning "+32"] g x = x ^ -Warning 32: unused value g. +Warning 32 [unused-value-declaration]: unused value g. File "w32.ml", line 56, characters 22-23: 56 | let[@warning "+32"] h x = x ^ -Warning 32: unused value h. +Warning 32 [unused-value-declaration]: unused value h. File "w32.ml", line 59, characters 22-23: 59 | and[@warning "+32"] k x = x ^ -Warning 32: unused value k. +Warning 32 [unused-value-declaration]: unused value k. File "w32.ml", lines 52-60, characters 0-3: 52 | module M = struct 53 | [@@@warning "-32"] @@ -68,16 +68,16 @@ File "w32.ml", lines 52-60, characters 0-3: 58 | let j x = x 59 | and[@warning "+32"] k x = x 60 | end -Warning 60: unused module M. +Warning 60 [unused-module]: unused module M. File "w32.ml", line 63, characters 18-29: 63 | module F (X : sig val x : int end) = struct end ^^^^^^^^^^^ -Warning 32: unused value x. +Warning 32 [unused-value-declaration]: unused value x. File "w32.ml", line 63, characters 10-11: 63 | module F (X : sig val x : int end) = struct end ^ -Warning 60: unused module X. +Warning 60 [unused-module]: unused module X. File "w32.ml", line 65, characters 18-29: 65 | module G (X : sig val x : int end) = X ^^^^^^^^^^^ -Warning 32: unused value x. +Warning 32 [unused-value-declaration]: unused value x. diff --git a/testsuite/tests/warnings/w32b.compilers.reference b/testsuite/tests/warnings/w32b.compilers.reference index 79ba5c85..fdaa92e5 100644 --- a/testsuite/tests/warnings/w32b.compilers.reference +++ b/testsuite/tests/warnings/w32b.compilers.reference @@ -1,8 +1,8 @@ File "w32b.ml", line 13, characters 18-24: 13 | module Q (M : sig type t end) = struct end ^^^^^^ -Warning 34: unused type t. +Warning 34 [unused-type-declaration]: unused type t. File "w32b.ml", line 13, characters 10-11: 13 | module Q (M : sig type t end) = struct end ^ -Warning 60: unused module M. +Warning 60 [unused-module]: unused module M. diff --git a/testsuite/tests/warnings/w33.compilers.reference b/testsuite/tests/warnings/w33.compilers.reference index 52b77b10..6931c135 100644 --- a/testsuite/tests/warnings/w33.compilers.reference +++ b/testsuite/tests/warnings/w33.compilers.reference @@ -1,12 +1,12 @@ File "w33.ml", line 19, characters 6-11: 19 | let f M.(x) = x (* useless open *) ^^^^^ -Warning 33: unused open M. +Warning 33 [unused-open]: unused open M. File "w33.ml", line 26, characters 0-7: 26 | open! M (* useless open! *) ^^^^^^^ -Warning 66: unused open! M. +Warning 66 [unused-open-bang]: unused open! M. File "w33.ml", line 27, characters 0-6: 27 | open M (* useless open *) ^^^^^^ -Warning 33: unused open M. +Warning 33 [unused-open]: unused open M. diff --git a/testsuite/tests/warnings/w45.compilers.reference b/testsuite/tests/warnings/w45.compilers.reference index 74830f68..93640dd3 100644 --- a/testsuite/tests/warnings/w45.compilers.reference +++ b/testsuite/tests/warnings/w45.compilers.reference @@ -1,13 +1,13 @@ File "w45.ml", line 24, characters 2-9: 24 | open T2 (* shadow X, which is later used; but not A, see #6762 *) ^^^^^^^ -Warning 45: this open statement shadows the constructor X (which is later used) +Warning 45 [open-shadow-label-constructor]: this open statement shadows the constructor X (which is later used) File "w45.ml", line 26, characters 14-15: 26 | let _ = (A, X) (* X belongs to several types *) ^ -Warning 41: X belongs to several types: T2.s T1.s +Warning 41 [ambiguous-name]: X belongs to several types: T2.s T1.s The first one was selected. Please disambiguate if this is wrong. File "w45.ml", line 23, characters 2-9: 23 | open T1 (* unused open *) ^^^^^^^ -Warning 33: unused open T1. +Warning 33 [unused-open]: unused open T1. diff --git a/testsuite/tests/warnings/w47_inline.compilers.reference b/testsuite/tests/warnings/w47_inline.compilers.reference index c9048adc..f8478ff2 100644 --- a/testsuite/tests/warnings/w47_inline.compilers.reference +++ b/testsuite/tests/warnings/w47_inline.compilers.reference @@ -1,42 +1,42 @@ File "w47_inline.ml", line 30, characters 20-22: 30 | let[@local never] f2 x = x (* ok *) in ^^ -Warning 26: unused variable f2. +Warning 26 [unused-var]: unused variable f2. File "w47_inline.ml", line 31, characters 24-26: 31 | let[@local malformed] f3 x = x (* bad payload *) in ^^ -Warning 26: unused variable f3. +Warning 26 [unused-var]: unused variable f3. File "w47_inline.ml", line 15, characters 23-29: 15 | let d = (fun x -> x) [@inline malformed attribute] (* rejected *) ^^^^^^ -Warning 47: illegal payload for attribute 'inline'. +Warning 47 [attribute-payload]: illegal payload for attribute 'inline'. It must be either 'never', 'always', 'hint' or empty File "w47_inline.ml", line 16, characters 23-29: 16 | let e = (fun x -> x) [@inline malformed_attribute] (* rejected *) ^^^^^^ -Warning 47: illegal payload for attribute 'inline'. +Warning 47 [attribute-payload]: illegal payload for attribute 'inline'. It must be either 'never', 'always', 'hint' or empty File "w47_inline.ml", line 17, characters 23-29: 17 | let f = (fun x -> x) [@inline : malformed_attribute] (* rejected *) ^^^^^^ -Warning 47: illegal payload for attribute 'inline'. +Warning 47 [attribute-payload]: illegal payload for attribute 'inline'. It must be either 'never', 'always', 'hint' or empty File "w47_inline.ml", line 18, characters 23-29: 18 | let g = (fun x -> x) [@inline ? malformed_attribute] (* rejected *) ^^^^^^ -Warning 47: illegal payload for attribute 'inline'. +Warning 47 [attribute-payload]: illegal payload for attribute 'inline'. It must be either 'never', 'always', 'hint' or empty File "w47_inline.ml", line 23, characters 15-22: 23 | let k x = (a [@inlined malformed]) x (* rejected *) ^^^^^^^ -Warning 47: illegal payload for attribute 'inlined'. +Warning 47 [attribute-payload]: illegal payload for attribute 'inlined'. It must be either 'never', 'always', 'hint' or empty File "w47_inline.ml", line 31, characters 7-12: 31 | let[@local malformed] f3 x = x (* bad payload *) in ^^^^^ -Warning 47: illegal payload for attribute 'local'. +Warning 47 [attribute-payload]: illegal payload for attribute 'local'. It must be either 'never', 'always', 'maybe' or empty File "w47_inline.ml", line 32, characters 17-26: 32 | let[@local] f4 x = 2 * x (* not local *) in ^^^^^^^^^ -Warning 55: Cannot inline: This function cannot be compiled into a static continuation +Warning 55 [inlining-impossible]: Cannot inline: This function cannot be compiled into a static continuation diff --git a/testsuite/tests/warnings/w50.compilers.reference b/testsuite/tests/warnings/w50.compilers.reference index 5b41948c..13c026e3 100644 --- a/testsuite/tests/warnings/w50.compilers.reference +++ b/testsuite/tests/warnings/w50.compilers.reference @@ -1,8 +1,8 @@ File "w50.ml", line 13, characters 2-17: 13 | module L = List ^^^^^^^^^^^^^^^ -Warning 60: unused module L. +Warning 60 [unused-module]: unused module L. File "w50.ml", line 17, characters 2-16: 17 | module Y1 = X1 ^^^^^^^^^^^^^^ -Warning 60: unused module Y1. +Warning 60 [unused-module]: unused module Y1. diff --git a/testsuite/tests/warnings/w51.compilers.reference b/testsuite/tests/warnings/w51.compilers.reference deleted file mode 100644 index b09e55a9..00000000 --- a/testsuite/tests/warnings/w51.compilers.reference +++ /dev/null @@ -1,4 +0,0 @@ -File "w51.ml", line 14, characters 13-37: -14 | | n -> n * (fact [@tailcall]) (n-1) - ^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 51: expected tailcall diff --git a/testsuite/tests/warnings/w51.ml b/testsuite/tests/warnings/w51.ml index 18d03ffe..7f89800c 100644 --- a/testsuite/tests/warnings/w51.ml +++ b/testsuite/tests/warnings/w51.ml @@ -1,15 +1,76 @@ (* TEST - -flags = "-w A" - -* setup-ocamlc.byte-build-env -** ocamlc.byte -compile_only = "true" -*** check-ocamlc.byte-output - + flags = "-w A" + * expect *) let rec fact = function | 1 -> 1 | n -> n * (fact [@tailcall]) (n-1) ;; +[%%expect {| +Line 3, characters 13-37: +3 | | n -> n * (fact [@tailcall]) (n-1) + ^^^^^^^^^^^^^^^^^^^^^^^^ +Warning 51 [wrong-tailcall-expectation]: expected tailcall +val fact : int -> int = +|}] + +let rec fact = function + | 1 -> 1 + | n -> n * (fact [@tailcall true]) (n-1) +;; +[%%expect {| +Line 3, characters 13-42: +3 | | n -> n * (fact [@tailcall true]) (n-1) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Warning 51 [wrong-tailcall-expectation]: expected tailcall +val fact : int -> int = +|}] + +let rec fact = function + | 1 -> 1 + | n -> n * (fact [@tailcall false]) (n-1) +;; +[%%expect {| +val fact : int -> int = +|}] + +let rec fact_tail acc = function + | 1 -> acc + | n -> (fact_tail [@tailcall]) (n * acc) (n - 1) +;; +[%%expect{| +val fact_tail : int -> int -> int = +|}] + +let rec fact_tail acc = function + | 1 -> acc + | n -> (fact_tail [@tailcall true]) (n * acc) (n - 1) +;; +[%%expect{| +val fact_tail : int -> int -> int = +|}] + +let rec fact_tail acc = function + | 1 -> acc + | n -> (fact_tail [@tailcall false]) (n * acc) (n - 1) +;; +[%%expect{| +Line 3, characters 9-56: +3 | | n -> (fact_tail [@tailcall false]) (n * acc) (n - 1) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Warning 51 [wrong-tailcall-expectation]: expected non-tailcall +val fact_tail : int -> int -> int = +|}] + + +(* explicitly test the "invalid payload" case *) +let rec test x = (test[@tailcall foobar]) x;; +[%%expect{| +Line 1, characters 24-32: +1 | let rec test x = (test[@tailcall foobar]) x;; + ^^^^^^^^ +Warning 47 [attribute-payload]: illegal payload for attribute 'tailcall'. +Only an optional boolean literal is supported. +val test : 'a -> 'b = +|}] diff --git a/testsuite/tests/warnings/w51_bis.compilers.reference b/testsuite/tests/warnings/w51_bis.compilers.reference index 79163112..e89c2a74 100644 --- a/testsuite/tests/warnings/w51_bis.compilers.reference +++ b/testsuite/tests/warnings/w51_bis.compilers.reference @@ -1,4 +1,4 @@ File "w51_bis.ml", line 15, characters 12-48: 15 | try (foldl [@tailcall]) op (op x acc) xs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 51: expected tailcall +Warning 51 [wrong-tailcall-expectation]: expected tailcall diff --git a/testsuite/tests/warnings/w52.ml b/testsuite/tests/warnings/w52.ml index 2f9e77be..bf6bd684 100644 --- a/testsuite/tests/warnings/w52.ml +++ b/testsuite/tests/warnings/w52.ml @@ -8,7 +8,7 @@ let () = try () with Invalid_argument "Any" -> ();; Line 1, characters 38-43: 1 | let () = try () with Invalid_argument "Any" -> ();; ^^^^^ -Warning 52: Code should not depend on the actual values of +Warning 52 [fragile-literal-pattern]: Code should not depend on the actual values of this constructor's arguments. They are only for information and may change in future versions. (See manual section 9.5) |}];; @@ -18,7 +18,7 @@ let () = try () with Match_failure ("Any",_,_) -> ();; Line 1, characters 35-46: 1 | let () = try () with Match_failure ("Any",_,_) -> ();; ^^^^^^^^^^^ -Warning 52: Code should not depend on the actual values of +Warning 52 [fragile-literal-pattern]: Code should not depend on the actual values of this constructor's arguments. They are only for information and may change in future versions. (See manual section 9.5) |}];; @@ -28,7 +28,7 @@ let () = try () with Match_failure (_,0,_) -> ();; Line 1, characters 35-42: 1 | let () = try () with Match_failure (_,0,_) -> ();; ^^^^^^^ -Warning 52: Code should not depend on the actual values of +Warning 52 [fragile-literal-pattern]: Code should not depend on the actual values of this constructor's arguments. They are only for information and may change in future versions. (See manual section 9.5) |}];; @@ -53,7 +53,7 @@ let f = function Line 2, characters 7-17: 2 | | Warn "anything" -> () ^^^^^^^^^^ -Warning 52: Code should not depend on the actual values of +Warning 52 [fragile-literal-pattern]: Code should not depend on the actual values of this constructor's arguments. They are only for information and may change in future versions. (See manual section 9.5) val f : t -> unit = @@ -66,7 +66,7 @@ let g = function Line 2, characters 8-10: 2 | | Warn' 0n -> () ^^ -Warning 52: Code should not depend on the actual values of +Warning 52 [fragile-literal-pattern]: Code should not depend on the actual values of this constructor's arguments. They are only for information and may change in future versions. (See manual section 9.5) val g : t -> unit = @@ -93,7 +93,7 @@ let j = function Line 2, characters 7-34: 2 | | Deep (_ :: _ :: ("deep",_) :: _) -> () ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 52: Code should not depend on the actual values of +Warning 52 [fragile-literal-pattern]: Code should not depend on the actual values of this constructor's arguments. They are only for information and may change in future versions. (See manual section 9.5) val j : t -> unit = diff --git a/testsuite/tests/warnings/w53.compilers.reference b/testsuite/tests/warnings/w53.compilers.reference index e8ee95f3..75b91048 100644 --- a/testsuite/tests/warnings/w53.compilers.reference +++ b/testsuite/tests/warnings/w53.compilers.reference @@ -1,52 +1,68 @@ File "w53.ml", line 12, characters 4-5: 12 | let h x = x [@inline] (* rejected *) ^ -Warning 32: unused value h. +Warning 32 [unused-value-declaration]: unused value h. File "w53.ml", line 12, characters 14-20: 12 | let h x = x [@inline] (* rejected *) ^^^^^^ -Warning 53: the "inline" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "inline" attribute cannot appear in this context File "w53.ml", line 13, characters 14-26: 13 | let h x = x [@ocaml.inline] (* rejected *) ^^^^^^^^^^^^ -Warning 53: the "ocaml.inline" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "ocaml.inline" attribute cannot appear in this context File "w53.ml", line 15, characters 14-21: 15 | let i x = x [@inlined] (* rejected *) ^^^^^^^ -Warning 53: the "inlined" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "inlined" attribute cannot appear in this context File "w53.ml", line 16, characters 14-27: 16 | let j x = x [@ocaml.inlined] (* rejected *) ^^^^^^^^^^^^^ -Warning 53: the "ocaml.inlined" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "ocaml.inlined" attribute cannot appear in this context File "w53.ml", line 19, characters 16-23: 19 | let l x = h x [@inlined] (* rejected *) ^^^^^^^ -Warning 53: the "inlined" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "inlined" attribute cannot appear in this context File "w53.ml", line 21, characters 14-22: 21 | let m x = x [@tailcall] (* rejected *) ^^^^^^^^ -Warning 53: the "tailcall" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "tailcall" attribute cannot appear in this context File "w53.ml", line 22, characters 14-28: 22 | let n x = x [@ocaml.tailcall] (* rejected *) ^^^^^^^^^^^^^^ -Warning 53: the "ocaml.tailcall" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "ocaml.tailcall" attribute cannot appear in this context File "w53.ml", line 25, characters 16-24: 25 | let q x = h x [@tailcall] (* rejected *) ^^^^^^^^ -Warning 53: the "tailcall" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "tailcall" attribute cannot appear in this context File "w53.ml", line 33, characters 0-32: 33 | module C = struct end [@@inline] (* rejected *) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 53: the "inline" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "inline" attribute cannot appear in this context File "w53.ml", line 34, characters 0-39: 34 | module C' = struct end [@@ocaml.inline] (* rejected *) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 53: the "inline" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "inline" attribute cannot appear in this context File "w53.ml", line 40, characters 16-22: 40 | module G = (A [@inline])(struct end) (* rejected *) ^^^^^^ -Warning 53: the "inline" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "inline" attribute cannot appear in this context File "w53.ml", line 41, characters 17-29: 41 | module G' = (A [@ocaml.inline])(struct end) (* rejected *) ^^^^^^^^^^^^ -Warning 53: the "ocaml.inline" attribute cannot appear in this context +Warning 53 [misplaced-attribute]: the "ocaml.inline" attribute cannot appear in this context +File "w53.ml", line 45, characters 22-29: +45 | module I = Set.Make [@inlined] + ^^^^^^^ +Warning 53 [misplaced-attribute]: the "inlined" attribute cannot appear in this context +File "w53.ml", line 46, characters 23-36: +46 | module I' = Set.Make [@ocaml.inlined] + ^^^^^^^^^^^^^ +Warning 53 [misplaced-attribute]: the "ocaml.inlined" attribute cannot appear in this context +File "w53.ml", line 48, characters 23-30: +48 | module J = Set.Make [@@inlined] + ^^^^^^^ +Warning 53 [misplaced-attribute]: the "inlined" attribute cannot appear in this context +File "w53.ml", line 49, characters 24-37: +49 | module J' = Set.Make [@@ocaml.inlined] + ^^^^^^^^^^^^^ +Warning 53 [misplaced-attribute]: the "ocaml.inlined" attribute cannot appear in this context diff --git a/testsuite/tests/warnings/w53.ml b/testsuite/tests/warnings/w53.ml index 63a0a83b..2de8a054 100644 --- a/testsuite/tests/warnings/w53.ml +++ b/testsuite/tests/warnings/w53.ml @@ -41,3 +41,9 @@ module G = (A [@inline])(struct end) (* rejected *) module G' = (A [@ocaml.inline])(struct end) (* rejected *) module H = Set.Make [@inlined] (Int32) (* GPR#1808 *) + +module I = Set.Make [@inlined] +module I' = Set.Make [@ocaml.inlined] + +module J = Set.Make [@@inlined] +module J' = Set.Make [@@ocaml.inlined] diff --git a/testsuite/tests/warnings/w54.compilers.reference b/testsuite/tests/warnings/w54.compilers.reference index e476122c..110da823 100644 --- a/testsuite/tests/warnings/w54.compilers.reference +++ b/testsuite/tests/warnings/w54.compilers.reference @@ -1,16 +1,16 @@ File "w54.ml", line 12, characters 33-39: 12 | let f = (fun x -> x) [@inline] [@inline never] ^^^^^^ -Warning 54: the "inline" attribute is used more than once on this expression +Warning 54 [duplicated-attribute]: the "inline" attribute is used more than once on this expression File "w54.ml", line 13, characters 51-63: 13 | let g = (fun x -> x) [@inline] [@something_else] [@ocaml.inline] ^^^^^^^^^^^^ -Warning 54: the "ocaml.inline" attribute is used more than once on this expression +Warning 54 [duplicated-attribute]: the "ocaml.inline" attribute is used more than once on this expression File "w54.ml", line 15, characters 26-39: 15 | let h x = (g [@inlined] [@ocaml.inlined never]) x ^^^^^^^^^^^^^ -Warning 54: the "ocaml.inlined" attribute is used more than once on this expression +Warning 54 [duplicated-attribute]: the "ocaml.inlined" attribute is used more than once on this expression File "w54.ml", line 19, characters 0-43: 19 | let i = ((fun x -> x) [@inline]) [@@inline] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 54: the "inline" attribute is used more than once on this expression +Warning 54 [duplicated-attribute]: the "inline" attribute is used more than once on this expression diff --git a/testsuite/tests/warnings/w55.flambda.reference b/testsuite/tests/warnings/w55.flambda.reference index 16012145..00bd36c0 100644 --- a/testsuite/tests/warnings/w55.flambda.reference +++ b/testsuite/tests/warnings/w55.flambda.reference @@ -1,12 +1,12 @@ File "w55.ml", line 33, characters 10-26: 33 | let h x = (j [@inlined]) x ^^^^^^^^^^^^^^^^ -Warning 55: Cannot inline: [@inlined] attributes may not be used on partial applications +Warning 55 [inlining-impossible]: Cannot inline: [@inlined] attributes may not be used on partial applications File "w55.ml", line 29, characters 10-27: 29 | let i x = (!r [@inlined]) x ^^^^^^^^^^^^^^^^^ -Warning 55: Cannot inline: [@inlined] attribute was not used on this function application (the optimizer did not know what function was being applied) +Warning 55 [inlining-impossible]: Cannot inline: [@inlined] attribute was not used on this function application (the optimizer did not know what function was being applied) File "w55.ml", line 39, characters 12-30: 39 | let b x y = (a [@inlined]) x y ^^^^^^^^^^^^^^^^^^ -Warning 55: Cannot inline: [@inlined] attribute was not used on this function application (the optimizer did not know what function was being applied) +Warning 55 [inlining-impossible]: Cannot inline: [@inlined] attribute was not used on this function application (the optimizer did not know what function was being applied) diff --git a/testsuite/tests/warnings/w55.native.reference b/testsuite/tests/warnings/w55.native.reference index 9ffb78f0..d701efcb 100644 --- a/testsuite/tests/warnings/w55.native.reference +++ b/testsuite/tests/warnings/w55.native.reference @@ -1,24 +1,24 @@ File "w55.ml", line 25, characters 10-26: 25 | let g x = (f [@inlined]) x ^^^^^^^^^^^^^^^^ -Warning 55: Cannot inline: Function information unavailable +Warning 55 [inlining-impossible]: Cannot inline: Function information unavailable File "w55.ml", line 29, characters 10-27: 29 | let i x = (!r [@inlined]) x ^^^^^^^^^^^^^^^^^ -Warning 55: Cannot inline: Unknown function +Warning 55 [inlining-impossible]: Cannot inline: Unknown function File "w55.ml", line 33, characters 10-26: 33 | let h x = (j [@inlined]) x ^^^^^^^^^^^^^^^^ -Warning 55: Cannot inline: Partial application +Warning 55 [inlining-impossible]: Cannot inline: Partial application File "w55.ml", line 39, characters 12-30: 39 | let b x y = (a [@inlined]) x y ^^^^^^^^^^^^^^^^^^ -Warning 55: Cannot inline: Over-application +Warning 55 [inlining-impossible]: Cannot inline: Over-application File "w55.ml", line 39, characters 12-30: 39 | let b x y = (a [@inlined]) x y ^^^^^^^^^^^^^^^^^^ -Warning 55: Cannot inline: Function information unavailable +Warning 55 [inlining-impossible]: Cannot inline: Function information unavailable File "w55.ml", line 42, characters 10-26: 42 | let d x = (c [@inlined]) x ^^^^^^^^^^^^^^^^ -Warning 55: Cannot inline: Function information unavailable +Warning 55 [inlining-impossible]: Cannot inline: Function information unavailable diff --git a/testsuite/tests/warnings/w58.native.reference b/testsuite/tests/warnings/w58.native.reference index f913ef94..4fb0badf 100644 --- a/testsuite/tests/warnings/w58.native.reference +++ b/testsuite/tests/warnings/w58.native.reference @@ -1,2 +1,2 @@ File "_none_", line 1: -Warning 58: no cmx file was found in path for module Module_without_cmx, and its interface was not compiled with -opaque +Warning 58 [no-cmx-file]: no cmx file was found in path for module Module_without_cmx, and its interface was not compiled with -opaque diff --git a/testsuite/tests/warnings/w59.flambda.reference b/testsuite/tests/warnings/w59.flambda.reference index 912da659..8277d948 100644 --- a/testsuite/tests/warnings/w59.flambda.reference +++ b/testsuite/tests/warnings/w59.flambda.reference @@ -1,30 +1,30 @@ File "w59.ml", line 46, characters 2-43: 46 | Obj.set_field (Obj.repr o) 0 (Obj.repr 3); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 59: A potential assignment to a non-mutable value was detected +Warning 59 [flambda-assignment-to-non-mutable-value]: A potential assignment to a non-mutable value was detected in this source file. Such assignments may generate incorrect code when using Flambda. File "w59.ml", line 47, characters 2-43: 47 | Obj.set_field (Obj.repr p) 0 (Obj.repr 3); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 59: A potential assignment to a non-mutable value was detected +Warning 59 [flambda-assignment-to-non-mutable-value]: A potential assignment to a non-mutable value was detected in this source file. Such assignments may generate incorrect code when using Flambda. File "w59.ml", line 48, characters 2-43: 48 | Obj.set_field (Obj.repr q) 0 (Obj.repr 3); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 59: A potential assignment to a non-mutable value was detected +Warning 59 [flambda-assignment-to-non-mutable-value]: A potential assignment to a non-mutable value was detected in this source file. Such assignments may generate incorrect code when using Flambda. File "w59.ml", line 49, characters 2-43: 49 | Obj.set_field (Obj.repr r) 0 (Obj.repr 3) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Warning 59: A potential assignment to a non-mutable value was detected +Warning 59 [flambda-assignment-to-non-mutable-value]: A potential assignment to a non-mutable value was detected in this source file. Such assignments may generate incorrect code when using Flambda. File "w59.ml", line 56, characters 2-7: 56 | set o ^^^^^ -Warning 59: A potential assignment to a non-mutable value was detected +Warning 59 [flambda-assignment-to-non-mutable-value]: A potential assignment to a non-mutable value was detected in this source file. Such assignments may generate incorrect code when using Flambda. diff --git a/testsuite/tests/warnings/w60.compilers.reference b/testsuite/tests/warnings/w60.compilers.reference index 9eec5d1e..6eec1357 100644 --- a/testsuite/tests/warnings/w60.compilers.reference +++ b/testsuite/tests/warnings/w60.compilers.reference @@ -1,4 +1,4 @@ File "w60.ml", line 40, characters 13-14: 40 | let module M = struct end in ^ -Warning 60: unused module M. +Warning 60 [unused-module]: unused module M. diff --git a/testsuite/tests/warnings/w68.compilers.reference b/testsuite/tests/warnings/w68.compilers.reference new file mode 100644 index 00000000..198706c3 --- /dev/null +++ b/testsuite/tests/warnings/w68.compilers.reference @@ -0,0 +1,11 @@ +File "w68.ml", line 34, characters 33-43: +34 | let dont_warn_with_partial_match None x = x + ^^^^^^^^^^ +Warning 8 [partial-match]: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +Some _ +File "w68.ml", line 14, characters 10-13: +14 | let alloc {a} b = a + b + ^^^ +Warning 68 [match-on-mutable-state-prevent-uncurry]: This pattern depends on mutable state. +It prevents the remaining arguments from being uncurried, which will cause additional closure allocations. diff --git a/testsuite/tests/warnings/w68.ml b/testsuite/tests/warnings/w68.ml new file mode 100644 index 00000000..01b9c203 --- /dev/null +++ b/testsuite/tests/warnings/w68.ml @@ -0,0 +1,34 @@ +(* TEST + +flags = "-w A" + +* setup-ocamlopt.byte-build-env +** ocamlopt.byte +*** check-ocamlopt.byte-output +**** run +***** check-program-output +*) + +type a = { mutable a : int } + +let alloc {a} b = a + b + +let noalloc b {a} = b + a + +let measure name f = + let a = {a = 1} in + let b = 2 in + let before = Gc.minor_words () in + let (_ : int) = f ~a ~b in + let after = Gc.minor_words () in + let alloc = int_of_float (after -. before) in + match alloc with + | 0 -> Printf.printf "%S doesn't allocate\n" name + | _ -> Printf.printf "%S allocates\n" name + +let () = + measure "noalloc" (fun ~a ~b -> noalloc b a); + measure "alloc" (fun ~a ~b -> alloc a b) + + +let dont_warn_with_partial_match None x = x diff --git a/testsuite/tests/warnings/w68.reference b/testsuite/tests/warnings/w68.reference new file mode 100644 index 00000000..1e8a8cca --- /dev/null +++ b/testsuite/tests/warnings/w68.reference @@ -0,0 +1,2 @@ +"noalloc" doesn't allocate +"alloc" allocates diff --git a/testsuite/tools/asmgen_arm64.S b/testsuite/tools/asmgen_arm64.S index 4b803d20..6a06f8d7 100644 --- a/testsuite/tools/asmgen_arm64.S +++ b/testsuite/tools/asmgen_arm64.S @@ -13,9 +13,15 @@ /* */ /**************************************************************************/ - .globl call_gen_code +#if defined(SYS_macosx) +#define G(sym) _##sym +#else +#define G(sym) sym +#endif + + .globl G(call_gen_code) .align 2 -call_gen_code: +G(call_gen_code): /* Set up stack frame and save callee-save registers */ stp x29, x30, [sp, -160]! add x29, sp, #0 @@ -51,8 +57,10 @@ call_gen_code: .globl caml_c_call .align 2 -caml_c_call: +G(caml_c_call): br x15 +#if !defined(SYS_macosx) /* Mark stack as non-executable */ .section .note.GNU-stack,"",%progbits +#endif diff --git a/testsuite/tools/lexcmm.mll b/testsuite/tools/lexcmm.mll index fa5ecd1d..026c2ed3 100644 --- a/testsuite/tools/lexcmm.mll +++ b/testsuite/tools/lexcmm.mll @@ -191,9 +191,6 @@ rule token = parse | '-'? (['0'-'9']+ | "0x" ['0'-'9' 'a'-'f' 'A'-'F']+ | "0o" ['0'-'7']+ | "0b" ['0'-'1']+) { INTCONST(int_of_string(Lexing.lexeme lexbuf)) } - | '-'? ['0'-'9']+ 'a' - { let s = Lexing.lexeme lexbuf in - POINTER(int_of_string(String.sub s 0 (String.length s - 1))) } | '-'? ['0'-'9']+ ('.' ['0'-'9']*)? (['e' 'E'] ['+' '-']? ['0'-'9']+)? { FLOATCONST(Lexing.lexeme lexbuf) } | ['A'-'Z' 'a'-'z' '\223'-'\246' '\248'-'\255' ] diff --git a/testsuite/tools/parsecmm.mly b/testsuite/tools/parsecmm.mly index aa254da8..2f2076c5 100644 --- a/testsuite/tools/parsecmm.mly +++ b/testsuite/tools/parsecmm.mly @@ -133,7 +133,6 @@ let access_array base numelt size = %token NLEF %token NLTF %token OR -%token POINTER %token PROJ %token RAISE %token RBRACKET @@ -211,7 +210,6 @@ expr: INTCONST { Cconst_int ($1, debuginfo ()) } | FLOATCONST { Cconst_float (float_of_string $1, debuginfo ()) } | STRING { Cconst_symbol ($1, debuginfo ()) } - | POINTER { Cconst_pointer ($1, debuginfo ()) } | IDENT { Cvar(find_ident $1) } | LBRACKET RBRACKET { Ctuple [] } | LPAREN LET letdef sequence RPAREN { make_letdef $3 $4 } @@ -220,7 +218,8 @@ expr: | LPAREN APPLY location expr exprlist machtype RPAREN { Cop(Capply $6, $4 :: List.rev $5, debuginfo ?loc:$3 ()) } | LPAREN EXTCALL STRING exprlist machtype RPAREN - {Cop(Cextcall($3, $5, false, None), List.rev $4, debuginfo ())} + {Cop(Cextcall($3, $5, [], false), + List.rev $4, debuginfo ())} | LPAREN ALLOC exprlist RPAREN { Cop(Calloc, List.rev $3, debuginfo ()) } | LPAREN SUBF expr RPAREN { Cop(Cnegf, [$3], debuginfo ()) } | LPAREN SUBF expr expr RPAREN { Cop(Csubf, [$3; $4], debuginfo ()) } diff --git a/testsuite/tools/parsecmmaux.ml b/testsuite/tools/parsecmmaux.ml index 89d8b2a3..af7aaea2 100644 --- a/testsuite/tools/parsecmmaux.ml +++ b/testsuite/tools/parsecmmaux.ml @@ -55,4 +55,8 @@ let report_error = function prerr_string "Unbound identifier "; prerr_string s; prerr_endline "." let debuginfo ?(loc=Location.symbol_rloc ()) () = - Debuginfo.(from_location (Scoped_location.of_location ~scopes:[] loc)) + Debuginfo.(from_location + (Scoped_location.of_location + ~scopes:Scoped_location.empty_scopes loc + ) + ) diff --git a/tools/.depend b/tools/.depend index 109cb1f3..2158c038 100644 --- a/tools/.depend +++ b/tools/.depend @@ -92,14 +92,14 @@ objinfo.cmo : \ ../middle_end/linkage_name.cmi \ ../typing/ident.cmi \ ../middle_end/flambda/export_info.cmi \ - ../utils/config.cmi \ ../middle_end/compilation_unit.cmi \ ../file_formats/cmxs_format.cmi \ ../file_formats/cmx_format.cmi \ ../file_formats/cmt_format.cmi \ ../file_formats/cmo_format.cmi \ ../file_formats/cmi_format.cmi \ - ../bytecomp/bytesections.cmi + ../bytecomp/bytesections.cmi \ + ../utils/binutils.cmi objinfo.cmx : \ ../bytecomp/symtable.cmx \ ../middle_end/symbol.cmx \ @@ -108,18 +108,44 @@ objinfo.cmx : \ ../middle_end/linkage_name.cmx \ ../typing/ident.cmx \ ../middle_end/flambda/export_info.cmx \ - ../utils/config.cmx \ ../middle_end/compilation_unit.cmx \ ../file_formats/cmxs_format.cmi \ ../file_formats/cmx_format.cmi \ ../file_formats/cmt_format.cmx \ ../file_formats/cmo_format.cmi \ ../file_formats/cmi_format.cmx \ - ../bytecomp/bytesections.cmx + ../bytecomp/bytesections.cmx \ + ../utils/binutils.cmx +ocamlcmt.cmo : \ + ../typing/untypeast.cmi \ + ../typing/stypes.cmi \ + ../parsing/pprintast.cmi \ + ../parsing/location.cmi \ + ../utils/load_path.cmi \ + ../typing/envaux.cmi \ + ../driver/compmisc.cmi \ + ../file_formats/cmt_format.cmi \ + ../typing/cmt2annot.cmo \ + ../utils/clflags.cmi \ + ../typing/annot.cmi +ocamlcmt.cmx : \ + ../typing/untypeast.cmx \ + ../typing/stypes.cmx \ + ../parsing/pprintast.cmx \ + ../parsing/location.cmx \ + ../utils/load_path.cmx \ + ../typing/envaux.cmx \ + ../driver/compmisc.cmx \ + ../file_formats/cmt_format.cmx \ + ../typing/cmt2annot.cmx \ + ../utils/clflags.cmx \ + ../typing/annot.cmi ocamlcp.cmo : \ - ../driver/main_args.cmi + ../driver/main_args.cmi \ + ../driver/compenv.cmi ocamlcp.cmx : \ - ../driver/main_args.cmx + ../driver/main_args.cmx \ + ../driver/compenv.cmx ocamldep.cmo : \ ../driver/makedepend.cmi ocamldep.cmx : \ @@ -135,13 +161,17 @@ ocamlmklib.cmx : \ ocamlmklibconfig.cmo : ocamlmklibconfig.cmx : ocamlmktop.cmo : \ + ../utils/config.cmi \ ../utils/ccomp.cmi ocamlmktop.cmx : \ + ../utils/config.cmx \ ../utils/ccomp.cmx ocamloptp.cmo : \ - ../driver/main_args.cmi + ../driver/main_args.cmi \ + ../driver/compenv.cmi ocamloptp.cmx : \ - ../driver/main_args.cmx + ../driver/main_args.cmx \ + ../driver/compenv.cmx ocamlprof.cmo : \ ../utils/warnings.cmi \ ../parsing/parsetree.cmi \ @@ -167,30 +197,6 @@ profiling.cmo : \ profiling.cmx : \ profiling.cmi profiling.cmi : -read_cmt.cmo : \ - ../typing/untypeast.cmi \ - ../typing/stypes.cmi \ - ../parsing/pprintast.cmi \ - ../parsing/location.cmi \ - ../utils/load_path.cmi \ - ../typing/envaux.cmi \ - ../driver/compmisc.cmi \ - ../file_formats/cmt_format.cmi \ - ../typing/cmt2annot.cmo \ - ../utils/clflags.cmi \ - ../typing/annot.cmi -read_cmt.cmx : \ - ../typing/untypeast.cmx \ - ../typing/stypes.cmx \ - ../parsing/pprintast.cmx \ - ../parsing/location.cmx \ - ../utils/load_path.cmx \ - ../typing/envaux.cmx \ - ../driver/compmisc.cmx \ - ../file_formats/cmt_format.cmx \ - ../typing/cmt2annot.cmx \ - ../utils/clflags.cmx \ - ../typing/annot.cmi stripdebug.cmo : \ ../utils/misc.cmi \ ../bytecomp/bytesections.cmi diff --git a/tools/Makefile b/tools/Makefile index dbad0b74..07e2eda1 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -16,15 +16,7 @@ MAKEFLAGS := -r -R ROOTDIR = .. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common - -ifeq ($(SYSTEM),unix) -override define shellquote -$i := $$(subst ",\",$$(subst $$$$,\$$$$,$$(subst `,\`,$i)))#")# -endef -$(foreach i,BINDIR LIBDIR STUBLIBDIR MANDIR,$(eval $(shellquote))) -endif +include $(ROOTDIR)/Makefile.common DESTDIR ?= # Setup GNU make variables storing per-target source and target, @@ -47,10 +39,14 @@ define byte_and_opt_ # This check is defensive programming $(and $(filter-out 1,$(words $1)),$(error \ cannot build file with whitespace in name)) -$1: $3 $2 +$(call PROGRAM_SYNONYM, $1) + +$1$(EXE): $3 $2 $$(CAMLC) $$(LINKFLAGS) -I $$(ROOTDIR) -o $$@ $2 -$1.opt: $3 $$(call byte2native,$2) +$(call PROGRAM_SYNONYM, $1.opt) + +$1.opt$(EXE): $3 $$(call byte2native,$2) $$(CAMLOPT_CMD) $$(LINKFLAGS) -I $$(ROOTDIR) -o $$@ \ $$(call byte2native,$2) @@ -62,7 +58,7 @@ ifeq '$(filter $(installed_tools),$1)' '$1' install_files += $1 endif clean:: - rm -f -- $1 $1.opt + rm -f -- $1 $1.opt $1.exe $1.opt.exe endef @@ -74,7 +70,7 @@ endef CAMLC = $(BOOT_OCAMLC) -g -nostdlib -I $(ROOTDIR)/boot \ -use-prims $(ROOTDIR)/runtime/primitives -I $(ROOTDIR) -CAMLOPT = $(CAMLRUN) $(ROOTDIR)/ocamlopt -g -nostdlib -I $(ROOTDIR)/stdlib +CAMLOPT = $(CAMLRUN) $(ROOTDIR)/ocamlopt$(EXE) -g -nostdlib -I $(ROOTDIR)/stdlib CAMLLEX = $(CAMLRUN) $(ROOTDIR)/boot/ocamllex INCLUDES = $(addprefix -I $(ROOTDIR)/,utils parsing typing bytecomp \ middle_end middle_end/closure middle_end/flambda \ @@ -94,17 +90,13 @@ CAMLDEP_OBJ=ocamldep.cmo CAMLDEP_IMPORTS= \ $(ROOTDIR)/compilerlibs/ocamlcommon.cma \ $(ROOTDIR)/compilerlibs/ocamlbytecomp.cma -ocamldep: LINKFLAGS += -compat-32 +ocamldep$(EXE): LINKFLAGS += -compat-32 $(call byte_and_opt,ocamldep,$(CAMLDEP_IMPORTS) $(CAMLDEP_OBJ),) -ocamldep: depend.cmi -ocamldep.opt: depend.cmi +ocamldep$(EXE): depend.cmi +ocamldep.opt$(EXE): depend.cmi -# ocamldep is precious: sometimes we are stuck in the middle of a -# bootstrap and we need to remake the dependencies clean:: - if test -f ocamldep; then mv -f ocamldep ocamldep.bak; else :; fi - rm -f ocamldep.opt - + rm -f ocamldep ocamldep.exe ocamldep.opt ocamldep.opt.exe # The profiler @@ -121,7 +113,7 @@ $(call byte_and_opt,ocamlprof,$(CSLPROF_IMPORTS) profiling.cmo $(CSLPROF),) ocamlcp_cmos = config.cmo build_path_prefix_map.cmo misc.cmo profile.cmo \ warnings.cmo identifiable.cmo numbers.cmo arg_helper.cmo \ - clflags.cmo \ + clflags.cmo local_store.cmo \ terminfo.cmo location.cmo load_path.cmo ccomp.cmo compenv.cmo \ main_args.cmo @@ -169,7 +161,7 @@ clean:: OCAMLMKTOP=ocamlmktop.cmo OCAMLMKTOP_IMPORTS=config.cmo build_path_prefix_map.cmo misc.cmo \ identifiable.cmo numbers.cmo arg_helper.cmo clflags.cmo \ - load_path.cmo profile.cmo ccomp.cmo + local_store.cmo load_path.cmo profile.cmo ccomp.cmo $(call byte_and_opt,ocamlmktop,$(OCAMLMKTOP_IMPORTS) $(OCAMLMKTOP),) @@ -187,61 +179,57 @@ install:: ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" for i in $(install_files); \ do \ - $(INSTALL_PROG) "$$i" "$(INSTALL_BINDIR)/$$i.byte$(EXE)"; \ - if test -f "$$i".opt; then \ - $(INSTALL_PROG) "$$i.opt" "$(INSTALL_BINDIR)/$$i.opt$(EXE)" && \ - (cd "$(INSTALL_BINDIR)/" && $(LN) "$$i.opt$(EXE)" "$$i$(EXE)"); \ + $(INSTALL_PROG) "$$i$(EXE)" "$(INSTALL_BINDIR)/$$i.byte$(EXE)"; \ + if test -f "$$i".opt$(EXE); then \ + $(INSTALL_PROG) "$$i.opt$(EXE)" "$(INSTALL_BINDIR)" && \ + (cd "$(INSTALL_BINDIR)" && $(LN) "$$i.opt$(EXE)" "$$i$(EXE)"); \ else \ - (cd "$(INSTALL_BINDIR)/" && $(LN) "$$i.byte$(EXE)" "$$i$(EXE)"); \ + (cd "$(INSTALL_BINDIR)" && $(LN) "$$i.byte$(EXE)" "$$i$(EXE)"); \ fi; \ done else for i in $(install_files); \ do \ - if test -f "$$i".opt; then \ - $(INSTALL_PROG) "$$i.opt" "$(INSTALL_BINDIR)/$$i.opt$(EXE)"; \ - (cd "$(INSTALL_BINDIR)/" && $(LN) "$$i.opt$(EXE)" "$$i$(EXE)"); \ + if test -f "$$i".opt$(EXE); then \ + $(INSTALL_PROG) "$$i.opt$(EXE)" "$(INSTALL_BINDIR)"; \ + (cd "$(INSTALL_BINDIR)" && $(LN) "$$i.opt$(EXE)" "$$i$(EXE)"); \ fi; \ done endif # The preprocessor for asm generators -CVT_EMIT=cvt_emit.cmo +cvt_emit := cvt_emit$(EXE) -cvt_emit: $(CVT_EMIT) - $(CAMLC) $(LINKFLAGS) -o cvt_emit $(CVT_EMIT) +$(eval $(call PROGRAM_SYNONYM,cvt_emit)) -# cvt_emit is precious: sometimes we are stuck in the middle of a -# bootstrap and we need to remake the dependencies -.PRECIOUS: cvt_emit -clean:: - if test -f cvt_emit; then mv -f cvt_emit cvt_emit.bak; else :; fi +$(cvt_emit): cvt_emit.cmo + $(CAMLC) $(LINKFLAGS) -o $@ $^ clean:: - rm -f cvt_emit.ml + rm -f cvt_emit.ml cvt_emit cvt_emit.exe beforedepend:: cvt_emit.ml # Reading cmt files -READ_CMT= \ +ocamlcmt_objects= \ $(ROOTDIR)/compilerlibs/ocamlcommon.cma \ $(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \ \ - read_cmt.cmo + ocamlcmt.cmo # Reading cmt files -$(call byte_and_opt,read_cmt,$(READ_CMT),) +$(call byte_and_opt,ocamlcmt,$(ocamlcmt_objects),) install:: - if test -f read_cmt.opt; then \ - $(INSTALL_PROG) read_cmt.opt "$(INSTALL_BINDIR)/ocamlcmt$(EXE)"; \ + if test -f ocamlcmt.opt$(EXE); then \ + $(INSTALL_PROG)\ + ocamlcmt.opt$(EXE) "$(INSTALL_BINDIR)/ocamlcmt$(EXE)"; \ else \ - $(INSTALL_PROG) read_cmt "$(INSTALL_BINDIR)/ocamlcmt$(EXE)"; \ + $(INSTALL_PROG) ocamlcmt$(EXE) "$(INSTALL_BINDIR)"; \ fi - # The bytecode disassembler DUMPOBJ= \ @@ -252,14 +240,18 @@ DUMPOBJ= \ $(call byte_and_opt,dumpobj,$(DUMPOBJ),) -make_opcodes: make_opcodes.ml - $(CAMLC) make_opcodes.ml -o $@ +make_opcodes := make_opcodes$(EXE) + +$(eval $(call PROGRAM_SYNONYM,make_opcodes)) + +$(make_opcodes): make_opcodes.ml + $(CAMLC) $< -o $@ -opnames.ml: $(ROOTDIR)/runtime/caml/instruct.h make_opcodes - $(ROOTDIR)/runtime/ocamlrun make_opcodes -opnames < $< > $@ +opnames.ml: $(ROOTDIR)/runtime/caml/instruct.h $(make_opcodes) + $(ROOTDIR)/runtime/ocamlrun$(EXE) $(make_opcodes) -opnames < $< > $@ clean:: - rm -f opnames.ml make_opcodes make_opcodes.ml + rm -f opnames.ml make_opcodes make_opcodes.exe make_opcodes.ml beforedepend:: opnames.ml @@ -275,24 +267,12 @@ ifeq "$(SYSTEM)" "cygwin" DEF_SYMBOL_PREFIX = '-Dsymbol_prefix="_"' endif -objinfo_helper$(EXE): objinfo_helper.$(O) - $(CC) $(BFD_LDFLAGS) $(OC_CFLAGS) $(OUTPUTEXE)$@ $< $(BFD_LDLIBS) - -objinfo_helper.$(O): $(ROOTDIR)/runtime/caml/s.h - -objinfo_helper.$(O): \ - OC_CPPFLAGS += -I$(ROOTDIR)/runtime $(DEF_SYMBOL_PREFIX) $(BFD_CPPFLAGS) - OBJINFO=$(ROOTDIR)/compilerlibs/ocamlcommon.cma \ $(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \ $(ROOTDIR)/compilerlibs/ocamlmiddleend.cma \ objinfo.cmo -$(call byte_and_opt,ocamlobjinfo,$(OBJINFO),objinfo_helper$(EXE)) - -install:: - $(INSTALL_PROG) \ - objinfo_helper$(EXE) "$(INSTALL_LIBDIR)/objinfo_helper$(EXE)" +$(call byte_and_opt,ocamlobjinfo,$(OBJINFO),) primreq=$(ROOTDIR)/compilerlibs/ocamlcommon.cma \ $(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \ @@ -307,16 +287,12 @@ LINTAPIDIFF=$(ROOTDIR)/compilerlibs/ocamlcommon.cmxa \ $(ROOTDIR)/otherlibs/str/str.cmxa \ lintapidiff.cmx -lintapidiff.opt: INCLUDES+= -I $(ROOTDIR)/otherlibs/str -lintapidiff.opt: $(LINTAPIDIFF) +lintapidiff.opt$(EXE): INCLUDES+= -I $(ROOTDIR)/otherlibs/str +lintapidiff.opt$(EXE): $(LINTAPIDIFF) $(CAMLOPT_CMD) $(LINKFLAGS) -I $(ROOTDIR) -o $@ $(LINTAPIDIFF) clean:: - rm -f -- lintapidiff.opt lintapidiff.cm? lintapidiff.o lintapidiff.obj - - -clean:: - rm -f "objinfo_helper" "objinfo_helper.manifest" - rm -f "objinfo_helper.exe" "objinfo_helper.exe.manifest" + rm -f -- lintapidiff.opt lintapidiff.opt.exe + rm -f lintapidiff.cm? lintapidiff.o lintapidiff.obj # Eventlog metadata file @@ -341,28 +317,31 @@ CMPBYT=$(ROOTDIR)/compilerlibs/ocamlcommon.cma \ $(call byte_and_opt,cmpbyt,$(CMPBYT),) -CAMLTEX= $(ROOTDIR)/compilerlibs/ocamlcommon.cma \ - $(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \ - $(ROOTDIR)/compilerlibs/ocamltoplevel.cma \ - $(ROOTDIR)/otherlibs/str/str.cma \ - $(ROOTDIR)/otherlibs/$(UNIXLIB)/unix.cma \ - caml_tex.ml +caml_tex_files := \ + $(ROOTDIR)/compilerlibs/ocamlcommon.cma \ + $(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \ + $(ROOTDIR)/compilerlibs/ocamltoplevel.cma \ + $(ROOTDIR)/otherlibs/str/str.cma \ + $(ROOTDIR)/otherlibs/$(UNIXLIB)/unix.cma \ + caml_tex.ml #Scan latex files, and run ocaml code examples -caml-tex: INCLUDES += $(addprefix -I $(ROOTDIR)/otherlibs/,str $(UNIXLIB)) -caml-tex: $(CAMLTEX) - $(ROOTDIR)/runtime/ocamlrun $(ROOTDIR)/ocamlc -nostdlib \ +caml_tex := caml-tex$(EXE) + +$(caml_tex): INCLUDES += $(addprefix -I $(ROOTDIR)/otherlibs/,str $(UNIXLIB)) +$(caml_tex): $(caml_tex_files) + $(ROOTDIR)/runtime/ocamlrun$(EXE) $(ROOTDIR)/ocamlc$(EXE) -nostdlib \ -I $(ROOTDIR)/stdlib $(LINKFLAGS) -linkall \ - -o $@ -no-alias-deps $(CAMLTEX) + -o $@ -no-alias-deps $^ # we need str and unix which depend on the bytecode version of other tools # thus we delay building caml-tex to the opt.opt stage ifneq "$(WITH_CAMLTEX)" "" -opt.opt:caml-tex +opt.opt: $(caml_tex) endif clean:: - rm -f -- caml-tex caml_tex.cm? + rm -f -- caml-tex caml-tex.exe caml_tex.cm? # Common stuff diff --git a/tools/caml_tex.ml b/tools/caml_tex.ml index ae89477d..b2b6e2e2 100644 --- a/tools/caml_tex.ml +++ b/tools/caml_tex.ml @@ -22,8 +22,8 @@ open Str let camlprefix = "caml" let latex_escape s = String.concat "" ["$"; s; "$"] -let camlin = latex_escape {|\\?|} ^ {|\1|} -let camlout = latex_escape {|\\:|} ^ {|\1|} +let toplevel_prompt= latex_escape {|\?|} ^ " " + let camlbunderline = "<<" let camleunderline = ">>" @@ -352,7 +352,7 @@ module Output = struct let catch_warning = function | [] -> None - | s :: _ when string_match ~!{|Warning \([0-9]+\):|} s 0 -> + | s :: _ when string_match ~!{|Warning \([0-9]+\)\( \[[a-z-]+\]\)?:|} s 0 -> Some (Warning (int_of_string @@ matched_group 1 s)) | _ -> None @@ -573,6 +573,13 @@ module Ellipsis = struct end +let format_input mode s = match mode with + | Verbatim | Signature -> s + | Toplevel -> + match String.split_on_char '\n' s with + | [] -> assert false + | a :: q -> String.concat ~sep:"\n " ((toplevel_prompt^a)::q) + let process_file file = let ic = try open_in file with _ -> failwith "Cannot read input file" in let phrase_start = ref 1 and phrase_stop = ref 1 in @@ -690,13 +697,8 @@ let process_file file = file !phrase_stop phrase in (* Special characters may also appear in output strings -Didier *) let output = Text_transform.escape_specials output in - let phrase = global_replace ~!{|^\(.\)|} camlin phrase - and output = global_replace ~!{|^\(.\)|} camlout output in - let final_output = - if omit_answer && String.length error_msgs > 0 then - global_replace ~!{|^\(.\)|} camlout error_msgs - else if omit_answer then "" - else output in + let phrase = format_input mode phrase in + let final_output = if omit_answer then error_msgs else output in start tex_fmt phrase_env []; code_env input_env tex_fmt phrase; if String.length final_output > 0 then diff --git a/tools/check-typo b/tools/check-typo index 6da3c3e6..6bd5b384 100755 --- a/tools/check-typo +++ b/tools/check-typo @@ -170,9 +170,8 @@ IGNORE_DIRS=" # is faster to optimistically run check-typo on them (and maybe get # out in the middle) than to first check then run. -TEST_AWK='BEGIN {if ("a{1}" ~ /a{1}/) exit 0}' -if $OCAML_CT_AWK "$TEST_AWK" ; then - TEST_AWK='BEGIN {if ("a" ~ /a{1}/) exit 0}' +TEST_AWK='BEGIN {if ("a{1}" ~ /a{1}$/) exit 1}' +if ! $OCAML_CT_AWK "$TEST_AWK" ; then if $OCAML_CT_AWK --re-interval "$TEST_AWK" 2>/dev/null ; then OCAML_CT_AWK="$OCAML_CT_AWK --re-interval" else diff --git a/tools/ci/actions/runner.sh b/tools/ci/actions/runner.sh new file mode 100755 index 00000000..9fcc6169 --- /dev/null +++ b/tools/ci/actions/runner.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env bash +#************************************************************************** +#* * +#* OCaml * +#* * +#* Anil Madhavapeddy, OCaml Labs * +#* * +#* Copyright 2014 Institut National de Recherche en Informatique et * +#* en Automatique. * +#* * +#* All rights reserved. This file is distributed under the terms of * +#* the GNU Lesser General Public License version 2.1, with the * +#* special exception on linking described in the file LICENSE. * +#* * +#************************************************************************** + +set -xe + +PREFIX=~/local + +MAKE="make $MAKE_ARG" +SHELL=dash + +export PATH=$PREFIX/bin:$PATH + +Configure () { + mkdir -p $PREFIX + cat</dev/null ; then + echo Check the code examples in the manual + $MAKE manual-pregen + fi + # check_all_arches checks tries to compile all backends in place, + # we would need to redo (small parts of) world.opt afterwards to + # use the compiler again + $MAKE check_all_arches + # Ensure that .gitignore is up-to-date - this will fail if any untreacked or + # altered files exist. + test -z "$(git status --porcelain)" + # check that the 'clean' target also works + $MAKE clean + $MAKE -C manual clean + # check that the `distclean` target definitely cleans the tree + $MAKE distclean + # Check the working tree is clean + test -z "$(git status --porcelain)" + # Check that there are no ignored files + test -z "$(git ls-files --others -i --exclude-standard)" +} + +CheckManual () { + cat<2; + exit 1; + fi + tools/check-typo + ''' + } + } + } + post { + regression { + emailext ( + to: 'ocaml-ci-notifications@inria.fr', + subject: 'Job $JOB_NAME $BUILD_STATUS (build #$BUILD_NUMBER)', + body: 'Changes since the last successful build:\n\n' + + '${CHANGES, format="%r %a %m"}\n\n' + + 'See the attached build log or check console output here:\n' + + '$BUILD_URL\n', + /* recipientProviders: [[$class: 'DevelopersRecipientProvider']], */ + attachLog: true + ) + } + } +} diff --git a/tools/ci/inria/dune-build/Jenkinsfile b/tools/ci/inria/dune-build/Jenkinsfile new file mode 100644 index 00000000..83522359 --- /dev/null +++ b/tools/ci/inria/dune-build/Jenkinsfile @@ -0,0 +1,44 @@ +/**************************************************************************/ +/* */ +/* OCaml */ +/* */ +/* Sebastien Hinderer, INRIA Paris */ +/* */ +/* Copyright 2020 Institut National de Recherche en Informatique et */ +/* en Automatique. */ +/* */ +/* All rights reserved. This file is distributed under the terms of */ +/* the GNU Lesser General Public License version 2.1, with the */ +/* special exception on linking described in the file LICENSE. */ +/* */ +/**************************************************************************/ + +/* Pipeline for the dune-build job on Inria's CI */ + +pipeline { + agent { label 'ocaml-linux-64' } + options { + timeout(time: 1, unit: 'HOURS') + } + stages { + stage('Building the OCaml compiler with Dune') { + steps { + sh 'tools/ci/inria/dune-build/script' + } + } + } + post { + regression { + emailext ( + to: 'Sebastien.Hinderer@inria.fr, thomas.refis@gmail.com', + subject: 'Job $JOB_NAME $BUILD_STATUS (build #$BUILD_NUMBER)', + body: 'Changes since the last successful build:\n\n' + + '${CHANGES, format="%r %a %m"}\n\n' + + 'See the attached build log or check console output here:\n' + + '$BUILD_URL\n', + /* recipientProviders: [[$class: 'DevelopersRecipientProvider']], */ + attachLog: true + ) + } + } +} diff --git a/tools/ci/inria/dune-build b/tools/ci/inria/dune-build/script similarity index 100% rename from tools/ci/inria/dune-build rename to tools/ci/inria/dune-build/script diff --git a/tools/ci/inria/light b/tools/ci/inria/light new file mode 100755 index 00000000..d32d2f87 --- /dev/null +++ b/tools/ci/inria/light @@ -0,0 +1,90 @@ +#!/bin/sh +#************************************************************************** +#* * +#* OCaml * +#* * +#* Damien Doligez and Xavier Leroy, projet Cambium, INRIA Paris * +#* * +#* Copyright 2020 Institut National de Recherche en Informatique et * +#* en Automatique. * +#* * +#* All rights reserved. This file is distributed under the terms of * +#* the GNU Lesser General Public License version 2.1, with the * +#* special exception on linking described in the file LICENSE. * +#* * +#************************************************************************** + +# This script performs a minimal build of the OCaml system +# sufficient to run the test suite. +# It is a lightweight version of the 'main' script, intended to run +# on slow machines such as QEMU virtual machines. +# It does not work under Windows. + +# Environment variables that are honored: +# OCAML_ARCH architecture of the test machine +# OCAML_JOBS number of jobs to run in parallel (make -j) + +# Command-line arguments: +# -jNN pass "-jNN" option to make for parallel builds + +error () { + echo "$1" >&2 + exit 3 +} + +# be verbose and stop on error +set -ex + +# set up variables + +# default values +make=make +jobs='' + +case "${OCAML_ARCH}" in + bsd|solaris) + make=gmake + ;; + cygwin|cygwin64|mingw|mingw64|msvc|msvc64) + error "Unsupported architecture ${OCAML_ARCH}" + ;; +esac + +case "${OCAML_JOBS}" in + [1-9]|[1-9][0-9]) jobs="-j${OCAML_JOBS}" ;; +esac + +######################################################################### +# parse optional command-line arguments + +while [ $# -gt 0 ]; do + case $1 in + -j[1-9]|-j[1-9][0-9]) jobs="$1";; + *) error "unknown option $1";; + esac + shift +done + +######################################################################### +# Do the work + +# Tell gcc to use only ASCII in its diagnostic outputs. +export LC_ALL=C + +git clean -q -f -d -x + +./configure \ + --disable-shared \ + --disable-debug-runtime \ + --disable-instrumented-runtime \ + --disable-dependency-generation \ + --disable-ocamldoc \ + --disable-stdlib-manpages + +$make $jobs --warn-undefined-variables + +cd testsuite +if test -n "$jobs" && test -x /usr/bin/parallel +then PARALLEL="$jobs $PARALLEL" $make --warn-undefined-variables parallel +else $make --warn-undefined-variables all +fi diff --git a/tools/ci/inria/main b/tools/ci/inria/main index 3404c99c..4c133fa5 100755 --- a/tools/ci/inria/main +++ b/tools/ci/inria/main @@ -71,7 +71,7 @@ echo jenkinsdir=${jenkinsdir} # Unix environment variables (e.g. PATH). case "${OCAML_ARCH}" in - bsd|macos|linux) ;; + bsd|macos|linux|solaris) ;; cygwin|cygwin64|mingw|mingw64) . /etc/profile . "$HOME/.profile" @@ -86,10 +86,6 @@ case "${OCAML_ARCH}" in . "$HOME/.profile" . "$HOME/.msenv64" ;; - solaris) - echo OCaml 4.11 does not support Solaris. Exiting. - exit - ;; *) arch_error;; esac @@ -116,8 +112,6 @@ case $NODE_NAME in ocaml-ppc-64) CCOMP="CC='gcc -m64'" OCAML_CONFIGURE_OPTIONS=;; - ocaml-openbsd-64) - OCAML_CONFIGURE_OPTIONS='--with-bfd' esac ######################################################################### @@ -129,19 +123,21 @@ host='' conffile=Makefile.config make=make instdir="$HOME/ocaml-tmp-install" -confoptions="--enable-ocamltest ${OCAML_CONFIGURE_OPTIONS}" +confoptions="--enable-ocamltest --enable-dependency-generation \ +${OCAML_CONFIGURE_OPTIONS}" make_native=true cleanup=false check_make_alldepend=false dorebase=false jobs='' +bootstrap=false case "${OCAML_ARCH}" in - bsd) + bsd|solaris) make=gmake ;; macos) - confoptions="$confoptions --with-bfd " + # Nothing special but we must not fall through the "arch_error" case ;; linux) check_make_alldepend=true @@ -215,6 +211,7 @@ while [ $# -gt 0 ]; do -patch1) patch -f -p1 <"$2"; shift;; -no-native) make_native=false;; -j[1-9]|-j[1-9][0-9]) jobs="$1";; + -with-bootstrap) bootstrap=true;; *) error "unknown option $1";; esac shift @@ -229,28 +226,45 @@ export LC_ALL=C git clean -q -f -d -x if $flambda; then - confoptions="$confoptions --enable-flambda --enable-flambda-invariants" + confoptions="$confoptions --enable-flambda --enable-flambda-invariants \ +--disable-naked-pointers" fi eval ./configure "$CCOMP" $build $host --prefix='$instdir' $confoptions -if $make_native; then - $make $jobs --warn-undefined-variables - if $check_make_alldepend; then $make --warn-undefined-variables alldepend; fi +if $bootstrap; then + $make $jobs --warn-undefined-variables core + $make $jobs --warn-undefined-variables coreboot + if $make_native; then + $make $jobs --warn-undefined-variables opt.opt + else + $make $jobs --warn-undefined-variables all + fi else $make $jobs --warn-undefined-variables fi + + +if $make_native && $check_make_alldepend; then + $make --warn-undefined-variables alldepend +fi + if $dorebase; then # temporary solution to the cygwin fork problem # see https://github.com/alainfrisch/flexdll/issues/50 rebase -b 0x7cd20000 otherlibs/unix/dllunix.so rebase -b 0x7cdc0000 otherlibs/systhreads/dllthreads.so fi -$make --warn-undefined-variables install +$make --warn-undefined-variables install rm -rf "$instdir" + cd testsuite if test -n "$jobs" && test -x /usr/bin/parallel then PARALLEL="$jobs $PARALLEL" $make --warn-undefined-variables parallel else $make --warn-undefined-variables all fi + +if $bootstrap; then + git checkout ../boot/ocamlc ../boot/ocamllex +fi diff --git a/tools/ci/inria/other-configs/Jenkinsfile b/tools/ci/inria/other-configs/Jenkinsfile new file mode 100644 index 00000000..7eaab11b --- /dev/null +++ b/tools/ci/inria/other-configs/Jenkinsfile @@ -0,0 +1,46 @@ +/**************************************************************************/ +/* */ +/* OCaml */ +/* */ +/* Sebastien Hinderer, INRIA Paris */ +/* */ +/* Copyright 2020 Institut National de Recherche en Informatique et */ +/* en Automatique. */ +/* */ +/* All rights reserved. This file is distributed under the terms of */ +/* the GNU Lesser General Public License version 2.1, with the */ +/* special exception on linking described in the file LICENSE. */ +/* */ +/**************************************************************************/ + +/* Pipeline for the other-configs job on Inria's CI */ + +/* Test various other compiler configurations */ + +pipeline { + agent { label 'ocaml-linux-64' } + options { + timeout(time: 45, unit: 'MINUTES') + } + stages { + stage('Testing various other compiler configurations') { + steps { + sh 'tools/ci/inria/other-configs/script' + } + } + } + post { + regression { + emailext ( + to: 'ocaml-ci-notifications@inria.fr', + subject: 'Job $JOB_NAME $BUILD_STATUS (build #$BUILD_NUMBER)', + body: 'Changes since the last successful build:\n\n' + + '${CHANGES, format="%r %a %m"}\n\n' + + 'See the attached build log or check console output here:\n' + + '$BUILD_URL\n', + /* recipientProviders: [[$class: 'DevelopersRecipientProvider']], */ + attachLog: true + ) + } + } +} diff --git a/tools/ci/inria/other-configs b/tools/ci/inria/other-configs/script similarity index 61% rename from tools/ci/inria/other-configs rename to tools/ci/inria/other-configs/script index accd724f..c3279f63 100755 --- a/tools/ci/inria/other-configs +++ b/tools/ci/inria/other-configs/script @@ -22,8 +22,25 @@ set -e mainjob=./tools/ci/inria/main main="${mainjob} -j8" -${main} -conf --disable-native-compiler -no-native +# The "MIN_BUILD" (formerly on Travis) builds with everything disabled (apart +# from ocamltest). Its goals: +# - Ensure that the system builds correctly without native compilation +# - Ensure ocamltest builds correctly with Unix +# - Ensure the testsuite runs correctly with everything switched off +${main} -conf --disable-native-compiler \ + -conf --disable-shared \ + -conf --disable-debug-runtime \ + -conf --disable-instrumented-runtime \ + -conf --disable-systhreads \ + -conf --disable-str-lib \ + -conf --disable-unix-lib \ + -conf --disable-bigarray-lib \ + -conf --disable-ocamldoc \ + -conf --disable-native-compiler \ + -conf --disable-dependency-generation \ + -no-native ${main} -conf --disable-naked-pointers -${main} -conf --disable-flat-float-array +${main} -with-bootstrap -conf --disable-flat-float-array ${main} -conf --enable-flambda -conf --disable-naked-pointers +${main} -conf --enable-reserved-header-bits=27 OCAMLRUNPARAM="c=1" ${main} diff --git a/otherlibs/win32unix/mkdir.c b/tools/ci/inria/sanitizers/Jenkinsfile similarity index 50% rename from otherlibs/win32unix/mkdir.c rename to tools/ci/inria/sanitizers/Jenkinsfile index 1b2a33a5..65402fae 100644 --- a/otherlibs/win32unix/mkdir.c +++ b/tools/ci/inria/sanitizers/Jenkinsfile @@ -2,9 +2,9 @@ /* */ /* OCaml */ /* */ -/* Xavier Leroy and Pascal Cuoq, projet Cristal, INRIA Rocquencourt */ +/* Sebastien Hinderer, INRIA Paris */ /* */ -/* Copyright 1996 Institut National de Recherche en Informatique et */ +/* Copyright 2020 Institut National de Recherche en Informatique et */ /* en Automatique. */ /* */ /* All rights reserved. This file is distributed under the terms of */ @@ -13,22 +13,32 @@ /* */ /**************************************************************************/ -#define CAML_INTERNALS +/* Pipeline for the sanitizers job on Inria's CI */ -#include -#include -#include -#include "unixsupport.h" - -CAMLprim value unix_mkdir(path, perm) - value path, perm; -{ - int err; - wchar_t * wpath; - caml_unix_check_path(path, "mkdir"); - wpath = caml_stat_strdup_to_utf16(String_val(path)); - err = _wmkdir(wpath); - caml_stat_free(wpath); - if (err == -1) uerror("mkdir", path); - return Val_unit; +pipeline { + agent { label 'ocaml-linux-64' } + options { + timeout(time: 1, unit: 'HOURS') + } + stages { + stage('Compiling and testing OCaml with sanitizers') { + steps { + sh 'tools/ci/inria/sanitizers/script' + } + } + } + post { + regression { + emailext ( + to: 'ocaml-ci-notifications@inria.fr', + subject: 'Job $JOB_NAME $BUILD_STATUS (build #$BUILD_NUMBER)', + body: 'Changes since the last successful build:\n\n' + + '${CHANGES, format="%r %a %m"}\n\n' + + 'See the attached build log or check console output here:\n' + + '$BUILD_URL\n', + /* recipientProviders: [[$class: 'DevelopersRecipientProvider']], */ + attachLog: true + ) + } + } } diff --git a/tools/ci/inria/lsan-suppr.txt b/tools/ci/inria/sanitizers/lsan-suppr.txt similarity index 100% rename from tools/ci/inria/lsan-suppr.txt rename to tools/ci/inria/sanitizers/lsan-suppr.txt diff --git a/tools/ci/inria/extra-checks b/tools/ci/inria/sanitizers/script similarity index 57% rename from tools/ci/inria/extra-checks rename to tools/ci/inria/sanitizers/script index a33e3d3b..61081e37 100755 --- a/tools/ci/inria/extra-checks +++ b/tools/ci/inria/sanitizers/script @@ -24,81 +24,17 @@ export OCAMLTEST_SKIP_TESTS="tests/afl-instrumentation/afltest.ml \ tests/runtime-errors/stackoverflow.ml" -# To know the slave's architecture, this script looks at the OCAML_ARCH -# environment variable. For a given node NODE, this variable can be defined -# in Jenkins at the following address: -# https://ci.inria.fr/ocaml/computer/NODE/configure - -# Other environment variables that are honored: -# OCAML_JOBS number of jobs to run in parallel (make -j) - -# Command-line arguments: -# -jNN pass "-jNN" option to make for parallel builds - -error () { - echo "$1" >&2 - exit 3 -} - -arch_error() { - configure_url="https://ci.inria.fr/ocaml/computer/${NODE_NAME}/configure" - msg="Unknown architecture. Make sure the OCAML_ARCH environment" - msg="$msg variable has been defined." - msg="$msg\nSee ${configure_url}" - error "$msg" -} - -# Change a variable in Makefile.config -# Usage: set_config_var +jobs=-j8 +make=make +######################################################################### -set_config_var() { - conffile=Makefile.config - mv ${conffile} ${conffile}.bak - (grep -v "^$1=" ${conffile}.bak; echo "$1=$2") > ${conffile} -} +# Print each command before its execution +set -x -######################################################################### # stop on error set -e -# be considerate towards other potential users of the test machine -case "${OCAML_ARCH}" in - bsd|macos|linux) renice 10 $$ ;; -esac - -# set up variables - -make=make -jobs='' - -case "${OCAML_ARCH}" in - bsd) make=gmake ;; - macos) ;; - linux) ;; - cygwin|cygwin64|mingw|mingw64|msvc|msvc64) - error "Don't run this test under Windows";; - solaris) - echo OCaml 4.11 does not support Solaris. Exiting. - exit - ;; - *) arch_error;; -esac - -case "${OCAML_JOBS}" in - [1-9]|[1-9][0-9]) jobs="-j${OCAML_JOBS}" ;; -esac - -# parse optional command-line arguments - -while [ $# -gt 0 ]; do - case $1 in - -j[1-9]|-j[1-9][0-9]) jobs="$1";; - *) error "unknown option $1";; - esac - shift -done - # Tell gcc to use only ASCII in its diagnostic outputs. export LC_ALL=C @@ -110,7 +46,7 @@ else run_testsuite="$make -C testsuite all" fi -# A tool that make error backtrace nicer +# A tool that makes error backtraces nicer # Need to pick the one that matches clang-9 and is named "llvm-symbolizer" # (/usr/bin/llvm-symbolizer-9 doesn't work, that would be too easy) export ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-9/bin/llvm-symbolizer @@ -118,43 +54,11 @@ export TSAN_SYMBOLIZER_PATH="$ASAN_SYMBOLIZER_PATH" ######################################################################### -# Cleanup repository -git clean -q -f -d -x - -# Ensure that the repo still passes the check-typo script -if [ ! -x tools/check-typo ] ; then - error "tools/check-typo does not appear to be executable?" -fi -tools/check-typo - -######################################################################### - -echo "======== old school build ==========" - -instdir="$HOME/ocaml-tmp-install-$$" -./configure --prefix "$instdir" - -# Build the system without using world.opt -make $jobs world -make $jobs opt -make $jobs opt.opt -make install - -rm -rf "$instdir" - -# It's a build system test only, so we don't bother testing the compiler - -######################################################################### - echo "======== clang 9, address sanitizer, UB sanitizer ==========" git clean -q -f -d -x # Use clang 9 -# We cannot give the sanitizer options as part of -cc because -# then various autoconfiguration tests fail. -# Instead, we'll fix OC_CFLAGS a posteriori. -./configure CC=clang-9 --disable-stdlib-manpages # These are the undefined behaviors we want to check # Others occur on purpose e.g. signed arithmetic overflow @@ -172,20 +76,22 @@ shift-exponent,\ unreachable" # Select address sanitizer and UB sanitizer, with trap-on-error behavior +sanitizers="-fsanitize=address -fsanitize-trap=$ubsan" + # Don't optimize too much to get better backtraces of errors -set_config_var OC_CFLAGS "-O1 \ --fno-strict-aliasing -fwrapv -fno-omit-frame-pointer \ --Wall -Werror \ --fsanitize=address \ --fsanitize-trap=$ubsan" + +./configure \ + CC=clang-9 \ + CFLAGS="-O1 -fno-omit-frame-pointer $sanitizers" \ + --disable-stdlib-manpages --enable-dependency-generation # Build the system. We want to check for memory leaks, hence # 1- force ocamlrun to free memory before exiting # 2- add an exception for ocamlyacc, which doesn't free memory OCAMLRUNPARAM="c=1" \ -LSAN_OPTIONS="suppressions=$(pwd)/tools/ci/inria/lsan-suppr.txt" \ -make $jobs world.opt +LSAN_OPTIONS="suppressions=$(pwd)/tools/ci/inria/sanitizers/lsan-suppr.txt" \ +make $jobs # Run the testsuite. # We deactivate leak detection for two reasons: @@ -205,17 +111,26 @@ echo "======== clang 9, thread sanitizer ==========" git clean -q -f -d -x -./configure CC=clang-9 --disable-stdlib-manpages - # Select thread sanitizer # Don't optimize too much to get better backtraces of errors -set_config_var OC_CFLAGS "-O1 \ --fno-strict-aliasing -fwrapv -fno-omit-frame-pointer \ --Wall -Werror \ --fsanitize=thread" + +./configure \ + CC=clang-9 \ + CFLAGS="-O1 -fno-omit-frame-pointer -fsanitize=thread" \ + --disable-stdlib-manpages --enable-dependency-generation # Build the system -make $jobs world.opt +make $jobs + +# ThreadSanitizer has problems with processes that exit via +# pthread_exit in the last thread. +# It also reports errors for the error case of unlocking an +# error-checking mutex. +# Exclude the corresponding test +export OCAMLTEST_SKIP_TESTS="$OCAMLTEST_SKIP_TESTS \ +tests/lib-threads/pr9971.ml \ +tests/statmemprof/thread_exit_in_callback.ml \ +tests/lib-threads/mutex_errors.ml" # Run the testsuite. # ThreadSanitizer complains about fork() in threaded programs, @@ -234,24 +149,19 @@ TSAN_OPTIONS="die_after_fork=0" $run_testsuite # git clean -q -f -d -x # # Use clang 6.0 -# # We cannot give the sanitizer options as part of -cc because -# # then various autoconfiguration tests fail. -# # Instead, we'll fix OC_CFLAGS a posteriori. # # Memory sanitizer doesn't like the static data generated by ocamlopt, # # hence build bytecode only -# ./configure CC=clang-9 --disable-native-compiler - # # Select memory sanitizer # # Don't optimize at all to get better backtraces of errors -# set_config_var OC_CFLAGS "-O0 -g \ -# -fno-strict-aliasing -fwrapv -fno-omit-frame-pointer \ -# -Wall -Werror \ -# -fsanitize=memory" -# # A tool that make error backtrace nicer +# ./configure \ +# CC=clang-9 \ +# CFLAGS="-O0 -g -fno-omit-frame-pointer -fsanitize=memory" \ +# --disable-native-compiler +# # A tool that makes error backtraces nicer # # Need to pick the one that matches clang-6.0 # export MSAN_SYMBOLIZER_PATH=/usr/lib/llvm-6.0/bin/llvm-symbolizer # # Build the system (bytecode only) and test -# make $jobs world +# make $jobs # $run_testsuite diff --git a/tools/ci/inria/step-by-step-build/Jenkinsfile b/tools/ci/inria/step-by-step-build/Jenkinsfile new file mode 100644 index 00000000..fe26c17e --- /dev/null +++ b/tools/ci/inria/step-by-step-build/Jenkinsfile @@ -0,0 +1,48 @@ +/**************************************************************************/ +/* */ +/* OCaml */ +/* */ +/* Sebastien Hinderer, INRIA Paris */ +/* */ +/* Copyright 2020 Institut National de Recherche en Informatique et */ +/* en Automatique. */ +/* */ +/* All rights reserved. This file is distributed under the terms of */ +/* the GNU Lesser General Public License version 2.1, with the */ +/* special exception on linking described in the file LICENSE. */ +/* */ +/**************************************************************************/ + +/* Pipeline for the step-by-step-build job on Inria's CI */ + +/* Build OCaml the legacy way (without using the world.opt target) */ + +pipeline { + agent { label 'ocaml-linux-64' } + options { + timeout(time: 1, unit: 'HOURS') + } + stages { + stage( + 'Building the OCaml compiler step by step (without using world.opt)' + ) { + steps { + sh 'tools/ci/inria/step-by-step-build/script' + } + } + } + post { + regression { + emailext ( + to: 'ocaml-ci-notifications@inria.fr', + subject: 'Job $JOB_NAME $BUILD_STATUS (build #$BUILD_NUMBER)', + body: 'Changes since the last successful build:\n\n' + + '${CHANGES, format="%r %a %m"}\n\n' + + 'See the attached build log or check console output here:\n' + + '$BUILD_URL\n', + /* recipientProviders: [[$class: 'DevelopersRecipientProvider']], */ + attachLog: true + ) + } + } +} diff --git a/ocamldoc/remove_DEBUG b/tools/ci/inria/step-by-step-build/script similarity index 69% rename from ocamldoc/remove_DEBUG rename to tools/ci/inria/step-by-step-build/script index 0eee2df9..8397e683 100755 --- a/ocamldoc/remove_DEBUG +++ b/tools/ci/inria/step-by-step-build/script @@ -1,12 +1,11 @@ #!/bin/sh - #************************************************************************** #* * #* OCaml * #* * -#* Damien Doligez, projet Moscova, INRIA Rocquencourt * +#* Sebastien Hinderer projet Cambium, INRIA Paris * #* * -#* Copyright 2003 Institut National de Recherche en Informatique et * +#* Copyright 2020 Institut National de Recherche en Informatique et * #* en Automatique. * #* * #* All rights reserved. This file is distributed under the terms of * @@ -15,9 +14,12 @@ #* * #************************************************************************** -# usage: remove_DEBUG -# remove from every line that contains the string "DEBUG", -# respecting the cpp # line annotation conventions - -echo "# 1 \"$1\"" -LC_ALL=C sed -e '/DEBUG/s/^.*$/(* DEBUG statement removed *)/' "$1" +jobs=-j8 +instdir="$HOME/ocaml-tmp-install-$$" +./configure --prefix "$instdir" --disable-dependency-generation +make $jobs world +make $jobs opt +make $jobs opt.opt +make install +rm -rf "$instdir" +# It's a build system test only, so we don't bother testing the compiler diff --git a/tools/ci/travis/travis-ci.sh b/tools/ci/travis/travis-ci.sh index 410c63d3..81774562 100755 --- a/tools/ci/travis/travis-ci.sh +++ b/tools/ci/travis/travis-ci.sh @@ -60,7 +60,8 @@ set -x PREFIX=~/local -MAKE=make SHELL=dash +MAKE="make $MAKE_ARG" +SHELL=dash TRAVIS_CUR_HEAD=${TRAVIS_COMMIT_RANGE%%...*} TRAVIS_PR_HEAD=${TRAVIS_COMMIT_RANGE##*...} @@ -77,6 +78,60 @@ case $TRAVIS_EVENT_TYPE in TRAVIS_MERGE_BASE=$(git merge-base "$TRAVIS_CUR_HEAD" "$TRAVIS_PR_HEAD");; esac +CheckSyncStdlibDocs () { + cat</dev/null ; then echo Ensuring that all library documentation compiles - make -C ocamldoc html_doc pdf_doc texi_doc + $MAKE -C ocamldoc html_doc pdf_doc texi_doc fi $MAKE install + if command -v hevea &>/dev/null ; then + echo Ensuring that the manual compiles + # These steps rely on the compiler being installed and in PATH + $MAKE -C manual/manual/html_processing duniverse + $MAKE -C manual web + fi if fgrep 'SUPPORTS_SHARED_LIBRARIES=true' Makefile.config &>/dev/null ; then echo Check the code examples in the manual $MAKE manual-pregen @@ -172,6 +236,7 @@ EOF $MAKE -C manual clean # check that the `distclean` target definitely cleans the tree $MAKE distclean + $MAKE -C manual distclean # Check the working tree is clean test -z "$(git status --porcelain)" # Check that there are no ignored files @@ -352,6 +417,9 @@ tests) check-typo) set +x CheckTypo;; +check-depend) + CheckSyncStdlibDocs + CheckDepend;; *) echo unknown CI kind exit 1 ;; diff --git a/tools/dumpobj.ml b/tools/dumpobj.ml index a1fce610..bb683afb 100644 --- a/tools/dumpobj.ml +++ b/tools/dumpobj.ml @@ -92,7 +92,6 @@ let rec print_struct_const = function | Const_base(Const_int32 i) -> printf "%ldl" i | Const_base(Const_nativeint i) -> printf "%ndn" i | Const_base(Const_int64 i) -> printf "%LdL" i - | Const_pointer n -> printf "%da" n | Const_block(tag, args) -> printf "<%d>" tag; begin match args with @@ -297,13 +296,13 @@ let op_shapes = [ opGRAB, Uint; opCLOSURE, Uint_Disp; opCLOSUREREC, Closurerec; - opOFFSETCLOSUREM2, Nothing; + opOFFSETCLOSUREM3, Nothing; opOFFSETCLOSURE0, Nothing; - opOFFSETCLOSURE2, Nothing; + opOFFSETCLOSURE3, Nothing; opOFFSETCLOSURE, Sint; (* was Uint *) - opPUSHOFFSETCLOSUREM2, Nothing; + opPUSHOFFSETCLOSUREM3, Nothing; opPUSHOFFSETCLOSURE0, Nothing; - opPUSHOFFSETCLOSURE2, Nothing; + opPUSHOFFSETCLOSURE3, Nothing; opPUSHOFFSETCLOSURE, Sint; (* was Nothing *) opGETGLOBAL, Getglobal; opPUSHGETGLOBAL, Getglobal; diff --git a/tools/make-package-macosx b/tools/make-package-macosx deleted file mode 100755 index 1ac36a01..00000000 --- a/tools/make-package-macosx +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/sh - -#************************************************************************** -#* * -#* OCaml * -#* * -#* Damien Doligez, projet Moscova, INRIA Rocquencourt * -#* * -#* Copyright 2003 Institut National de Recherche en Informatique et * -#* en Automatique. * -#* * -#* All rights reserved. This file is distributed under the terms of * -#* the GNU Lesser General Public License version 2.1, with the * -#* special exception on linking described in the file LICENSE. * -#* * -#************************************************************************** - -cd package-macosx -rm -rf ocaml.pkg ocaml-rw.dmg - -VERSION=`sed -e 1q ../VERSION` -VERSION_MAJOR=`sed -n -e '1s/^\([0-9]*\)\..*/\1/p' ../VERSION` -VERSION_MINOR=`sed -n -e '1s/^[0-9]*\.\([0-9]*\)[.+].*/\1/p' ../VERSION` - -cat >Description.plist < - - - - IFPkgDescriptionDeleteWarning - - IFPkgDescriptionDescription - The OCaml compiler and tools - IFPkgDescriptionTitle - OCaml - IFPkgDescriptionVersion - ${VERSION} - - -EOF - -cat >Info.plist < - - - - CFBundleGetInfoString - OCaml ${VERSION} - CFBundleIdentifier - fr.inria.ocaml - CFBundleName - OCaml - CFBundleShortVersionString - ${VERSION} - IFMajorVersion - ${VERSION_MAJOR} - IFMinorVersion - ${VERSION_MINOR} - IFPkgFlagAllowBackRev - - IFPkgFlagAuthorizationAction - AdminAuthorization - IFPkgFlagDefaultLocation - /usr/local - IFPkgFlagInstallFat - - IFPkgFlagIsRequired - - IFPkgFlagRelocatable - - IFPkgFlagRestartAction - NoRestart - IFPkgFlagRootVolumeOnly - - IFPkgFlagUpdateInstalledLanguages - - IFPkgFormatVersion - 0.10000000149011612 - - -EOF - -mkdir -p resources - -# stop here -> | -cat >resources/ReadMe.txt <&2 - exit 3 -fi -open "/Volumes/$volname" -sleep 2 -hdiutil detach $name - -rm -rf "ocaml-${VERSION}.dmg" -hdiutil convert ocaml-rw.dmg -format UDZO -o "ocaml-${VERSION}.dmg" diff --git a/tools/objinfo.ml b/tools/objinfo.ml index d2a01995..63b1a77e 100644 --- a/tools/objinfo.ml +++ b/tools/objinfo.ml @@ -244,25 +244,11 @@ let dump_byte ic = toc let find_dyn_offset filename = - let helper = Filename.concat Config.standard_library "objinfo_helper" in - let tempfile = Filename.temp_file "objinfo" ".out" in - match - Fun.protect - ~finally:(fun () -> remove_file tempfile) - (fun () -> - let rc = - Sys.command - (Filename.quote_command helper ~stdout:tempfile [filename]) - in - if rc <> 0 then failwith "cannot read"; - let tc = Scanf.Scanning.from_file tempfile in - Fun.protect - ~finally:(fun () -> Scanf.Scanning.close_in tc) - (fun () -> - Scanf.bscanf tc "%Ld" (fun x -> x))) - with - | offset -> Some offset - | exception (Failure _ | Sys_error _) -> None + match Binutils.read filename with + | Ok t -> + Binutils.symbol_offset t "caml_plugin_header" + | Error _ -> + None let exit_err msg = print_endline msg; exit 2 let exit_errf fmt = Printf.ksprintf exit_err fmt diff --git a/tools/objinfo_helper.c b/tools/objinfo_helper.c deleted file mode 100644 index fe3ebd42..00000000 --- a/tools/objinfo_helper.c +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************/ -/* */ -/* OCaml */ -/* */ -/* Mehdi Dogguy, PPS laboratory, University Paris Diderot */ -/* */ -/* Copyright 2010 Mehdi Dogguy */ -/* */ -/* All rights reserved. This file is distributed under the terms of */ -/* the GNU Lesser General Public License version 2.1, with the */ -/* special exception on linking described in the file LICENSE. */ -/* */ -/**************************************************************************/ - -#include "caml/s.h" -#include - -#ifdef HAS_LIBBFD -#include -#include -#include - -// PACKAGE: protect against binutils change -// https://sourceware.org/bugzilla/show_bug.cgi?id=14243 -#define PACKAGE "ocamlobjinfo" -#include -#undef PACKAGE - -#define plugin_header_sym (symbol_prefix "caml_plugin_header") - -/* We need to refer to a few functions of the BFD library that are */ -/* actually defined as macros. We thus define equivalent */ -/* functions below */ - -long get_static_symtab_upper_bound(bfd *fd) -{ - return bfd_get_symtab_upper_bound(fd); -} - -long get_dynamic_symtab_upper_bound(bfd *fd) -{ - return bfd_get_dynamic_symtab_upper_bound(fd); -} - -long canonicalize_static_symtab(bfd * fd, asymbol **symbolTable) -{ - return bfd_canonicalize_symtab(fd, symbolTable); -} - -long canonicalize_dynamic_symtab(bfd * fd, asymbol **symbolTable) -{ - return bfd_canonicalize_dynamic_symtab(fd, symbolTable); -} - -typedef struct { - long (*get_upper_bound)(bfd *); - long (*canonicalize)(bfd *, asymbol **); -} symTable_ops; - -symTable_ops staticSymTable_ops = { - &get_static_symtab_upper_bound, - &canonicalize_static_symtab -}; - -symTable_ops dynamicSymTable_ops = { - &get_dynamic_symtab_upper_bound, - &canonicalize_dynamic_symtab -}; - -/* Print an error message and exit */ -static void error(bfd *fd, char *msg, ...) -{ - va_list ap; - va_start(ap, msg); - vfprintf (stderr, msg, ap); - va_end(ap); - fprintf(stderr, "\n"); - if (fd!=NULL) bfd_close(fd); - exit(2); -} - -/* Look for plugin_header_sym in the specified symbol table */ -/* Return its address, -1 if not found */ -long lookup(bfd* fd, symTable_ops *ops) -{ - long st_size; - asymbol ** symbol_table; - long sym_count, i; - - st_size = ops->get_upper_bound (fd); - if (st_size <= 0) return -1; - - symbol_table = malloc(st_size); - if (! symbol_table) - error(fd, "Error: out of memory"); - - sym_count = ops->canonicalize (fd, symbol_table); - - for (i = 0; i < sym_count; i++) { - if (strcmp(symbol_table[i]->name, plugin_header_sym) == 0) - return symbol_table[i]->value; - } - return -1; -} - -int main(int argc, char ** argv) -{ - bfd *fd; - asection *sec; - file_ptr offset; - long value; - - if (argc != 2) - error(NULL, "Usage: objinfo_helper "); - - fd = bfd_openr(argv[1], "default"); - if (!fd) - error(NULL, "Error opening file %s", argv[1]); - if (! bfd_check_format (fd, bfd_object)) - error(fd, "Error: wrong format"); - - sec = bfd_get_section_by_name(fd, ".data"); - if (! sec) - error(fd, "Error: section .data not found"); - - offset = sec->filepos; - - value = lookup(fd, &dynamicSymTable_ops); - - if (value == -1) - value = lookup(fd, &staticSymTable_ops); - bfd_close(fd); - - if (value == -1) - error(NULL, "Error: missing symbol %s", plugin_header_sym); - - printf("%ld\n", (long) offset + value); -} - -#else - -int main(int argc, char ** argv) -{ - fprintf(stderr,"BFD library unavailable, cannot print info on .cmxs files\n"); - return 2; -} - -#endif diff --git a/tools/ocaml-objcopy-macosx b/tools/ocaml-objcopy-macosx deleted file mode 100755 index 2a51773f..00000000 --- a/tools/ocaml-objcopy-macosx +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -#************************************************************************** -#* * -#* OCaml * -#* * -#* Damien Doligez, projet Cristal, INRIA Rocquencourt * -#* * -#* Copyright 2005 Institut National de Recherche en Informatique et * -#* en Automatique. * -#* * -#* All rights reserved. This file is distributed under the terms of * -#* the GNU Lesser General Public License version 2.1, with the * -#* special exception on linking described in the file LICENSE. * -#* * -#************************************************************************** - -TMP="${TMPDIR=/tmp}" -TEMP="${TMP}"/ocaml-objcopy-$$.o -UNDEF="${TMP}"/ocaml-objcopy-$$.sym - -usage () { - echo "usage: objcopy {--redefine-sym =} file.o" >&2 - exit 2 -} - -: > "$UNDEF" - -while : ; do - case $# in - 0) break;; - *) case $1 in - --redefine-sym) - case $2 in - *=*) ALIAS="$ALIAS -i${2#*=}:${2%%=*}" - echo ${2%%=*} >>"$UNDEF" - ;; - *) usage;; - esac - shift 2 - ;; - -*) usage;; - *) case $FILE in - "") FILE=$1; shift;; - *) usage;; - esac;; - esac;; - esac -done - -ld -o "$TEMP" -r $ALIAS "$FILE" -ld -o "$FILE" -r -unexported_symbols_list "$UNDEF" "$TEMP" - -rm -f "$TEMP" "$UNDEF" diff --git a/tools/read_cmt.ml b/tools/ocamlcmt.ml similarity index 96% rename from tools/read_cmt.ml rename to tools/ocamlcmt.ml index ae6b97fd..359b28aa 100644 --- a/tools/read_cmt.ml +++ b/tools/ocamlcmt.ml @@ -41,7 +41,7 @@ let arg_list = Arg.align [ ] let arg_usage = - "read_cmt [OPTIONS] FILE.cmt : read FILE.cmt and print related information" + "ocamlcmt [OPTIONS] FILE.cmt : read FILE.cmt and print related information" let dummy_crc = String.make 32 '-' @@ -149,8 +149,7 @@ let record_cmt_info cmt = Annot.Idef (location_file value))) in let open Cmt_format in - (* record in reverse order to get them in correct order... *) - List.iter (fun dir -> record_info "include" dir) (List.rev cmt.cmt_loadpath); + List.iter (fun dir -> record_info "include" dir) cmt.cmt_loadpath; record_info "chdir" cmt.cmt_builddir; (match cmt.cmt_sourcefile with None -> () | Some file -> record_info "source" file) @@ -175,7 +174,7 @@ let main () = | Some _ as x -> x in Envaux.reset_cache (); - List.iter Load_path.add_dir (List.rev cmt.cmt_loadpath); + List.iter Load_path.add_dir cmt.cmt_loadpath; Cmt2annot.gen_annot target_filename ~sourcefile:cmt.cmt_sourcefile ~use_summaries:cmt.cmt_use_summaries diff --git a/tools/ocamlcp.ml b/tools/ocamlcp.ml index d799fff4..ad1b9043 100644 --- a/tools/ocamlcp.ml +++ b/tools/ocamlcp.ml @@ -66,7 +66,10 @@ let optlist = :: ("-p", Arg.String add_profarg, "[afilmt] Same as option -P") :: Main_args.options_with_command_line_syntax Options.list rev_compargs in -Arg.parse_expand optlist anon usage; +begin try + Arg.parse_expand optlist anon usage +with Compenv.Exit_with_status n -> exit n +end; if !with_impl && !with_intf then begin fprintf stderr "ocamlcp cannot deal with both \"-impl\" and \"-intf\"\n"; fprintf stderr "please compile interfaces and implementations separately\n"; diff --git a/tools/ocamlmktop.ml b/tools/ocamlmktop.ml index ab333966..2b47ebb0 100644 --- a/tools/ocamlmktop.ml +++ b/tools/ocamlmktop.ml @@ -20,9 +20,8 @@ let _ = cmd.exe has special quoting rules (see 'cmd.exe /?' for details). Short version: if the string passed to cmd.exe starts with '"', the first and last '"' are removed *) - let ocamlc,extra_quote = - if Sys.win32 then "ocamlc.exe","\"" else "ocamlc","" - in + let ocamlc = "ocamlc" ^ Config.ext_exe in + let extra_quote = if Sys.win32 then "\"" else "" in let ocamlc = Filename.(quote (concat (dirname ocamlmktop) ocamlc)) in let cmdline = extra_quote ^ ocamlc ^ " -I +compiler-libs -linkall ocamlcommon.cma " ^ diff --git a/tools/ocamloptp.ml b/tools/ocamloptp.ml index 9b92d3b0..89c10630 100644 --- a/tools/ocamloptp.ml +++ b/tools/ocamloptp.ml @@ -67,7 +67,10 @@ let optlist = \032 t try ... with") :: Main_args.options_with_command_line_syntax Options.list rev_compargs in -Arg.parse_expand optlist anon usage; +begin try + Arg.parse_expand optlist anon usage +with Compenv.Exit_with_status n -> exit n +end; if !with_impl && !with_intf then begin fprintf stderr "ocamloptp cannot deal with both \"-impl\" and \"-intf\"\n"; fprintf stderr "please compile interfaces and implementations separately\n"; diff --git a/tools/sync_stdlib_docs b/tools/sync_stdlib_docs new file mode 100755 index 00000000..edf50a2a --- /dev/null +++ b/tools/sync_stdlib_docs @@ -0,0 +1,145 @@ +#!/usr/bin/env bash +#************************************************************************** +#* * +#* OCaml * +#* * +#* John Whitington * +#* * +#* Copyright 2020 Institut National de Recherche en Informatique et * +#* en automatique * +#* * +#* All rights reserved. This file is distributed under the terms of * +#* the GNU Lesser General Public License version 2.1, with the * +#* special exception on linking described in the file LICENSE. * +#* * +#************************************************************************** + +#Allow to be run from outside tools/ +cd $(dirname "$0")/.. + +if [[ ! -d stdlib || ! -d otherlibs ]] ; then + echo 'Cannot find the stdlib and otherlibs directories' >&2 + exit 1 +fi + +#Removes a label, i.e a space, a variable name, followed by a colon followed by +#an alphabetic character or ( or '. This should avoid altering the contents of +#comments. +LABREGEX="s/ [a-z_]+:([a-z\('])/ \1/g" + +#A second, slightly different round sometimes required to deal with f:(key:key +LABLABREGEX="s/\([a-z_]+:([a-z\('])/\(\1/g" + +#Remove a tilde if it is followed by a label name and a space or closing +#OCamldoc code section with ] +TILDEREGEX="s/~([a-z_]+[ \]])/\1/g" + +#Indent a non-blank line by two characters, for moreLabels templates +INDENTREGEX="s/^(.+)$/ \1/m" + +#Stdlib +perl -p -e "$LABREGEX" stdlib/listLabels.mli > stdlib/list.temp.mli +perl -p -e "$LABREGEX" stdlib/arrayLabels.mli > stdlib/array.temp.mli +perl -p -e "$LABREGEX" stdlib/stringLabels.mli > stdlib/string.temp.mli +perl -p -e "$LABREGEX" stdlib/bytesLabels.mli > stdlib/bytes.temp.mli + +#Stdlib tildes +perl -p -e "$TILDEREGEX" stdlib/list.temp.mli > stdlib/list.mli +perl -p -e "$TILDEREGEX" stdlib/array.temp.mli > stdlib/array.mli +perl -p -e "$TILDEREGEX" stdlib/string.temp.mli > stdlib/string.mli +perl -p -e "$TILDEREGEX" stdlib/bytes.temp.mli > stdlib/bytes.mli + +#FloatArrayLabels +perl -p -e "$LABREGEX" \ + stdlib/templates/floatarraylabeled.template.mli > \ + stdlib/templates/floatarrayunlabeled.temp.mli +perl -p -e "$TILDEREGEX" stdlib/templates/floatarrayunlabeled.temp.mli > \ + stdlib/templates/floatarrayunlabeled.2temp.mli +perl -p -e "$INDENTREGEX" stdlib/templates/floatarraylabeled.template.mli > \ + stdlib/templates/fal.indented.temp.mli +perl -p -e "$INDENTREGEX" stdlib/templates/floatarrayunlabeled.2temp.mli > \ + stdlib/templates/fau.indented.temp.mli +perl -p -e\ + 's/FLOATARRAYLAB/`tail -n +17 stdlib\/templates\/fal.indented.temp.mli`/e' \ + stdlib/templates/float.template.mli > \ + stdlib/templates/float.template.temp.mli +perl -p -e\ + 's/FLOATARRAY/`tail -n +17 stdlib\/templates\/fau.indented.temp.mli`/e' \ + stdlib/templates/float.template.temp.mli > \ + stdlib/float.mli + +#MoreLabels +perl -p -e "$LABREGEX" \ + stdlib/templates/hashtbl.template.mli > stdlib/hashtbl.temp.mli +perl -p -e "$LABLABREGEX" \ + stdlib/hashtbl.temp.mli > stdlib/hashtbl.2temp.mli +perl -p -e "$LABREGEX" \ + stdlib/templates/map.template.mli > stdlib/map.temp.mli +perl -p -e "$LABLABREGEX" \ + stdlib/map.temp.mli > stdlib/map.2temp.mli +perl -p -e "$LABREGEX" \ + stdlib/templates/set.template.mli > stdlib/set.temp.mli +perl -p -e "$LABLABREGEX" \ + stdlib/set.temp.mli > stdlib/set.2temp.mli + +#MoreLabels tildes +perl -p -e "$TILDEREGEX" stdlib/hashtbl.2temp.mli > stdlib/hashtbl.mli +perl -p -e "$TILDEREGEX" stdlib/map.2temp.mli > stdlib/map.mli +perl -p -e "$TILDEREGEX" stdlib/set.2temp.mli > stdlib/set.mli + +#Indent the labeled modules +perl -p -e "$INDENTREGEX" stdlib/templates/hashtbl.template.mli > \ + stdlib/templates/hashtbl.template.temp.mli +perl -p -e "$INDENTREGEX" stdlib/templates/map.template.mli > \ + stdlib/templates/map.template.temp.mli +perl -p -e "$INDENTREGEX" stdlib/templates/set.template.mli > \ + stdlib/templates/set.template.temp.mli + +#Substitute the labeled modules in to moreLabels.mli +perl -p -e\ + 's/HASHTBL/`tail -n +19 stdlib\/templates\/hashtbl.template.temp.mli`/e' \ + stdlib/templates/moreLabels.template.mli > stdlib/moreLabels.temp.mli +perl -p -e 's/MAP/`tail -n +19 stdlib\/templates\/map.template.temp.mli`/e' \ + stdlib/moreLabels.temp.mli > stdlib/moreLabels.2temp.mli +perl -p -e 's/SET/`tail -n +19 stdlib\/templates\/set.template.temp.mli`/e' \ + stdlib/moreLabels.2temp.mli > stdlib/moreLabels.mli + +#Fix up with templates in tools/unlabel-patches +perl -p -e "s/type statistics =/type statistics = Hashtbl\.statistics =/" \ + stdlib/moreLabels.mli > stdlib/moreLabels.temp.mli +perl -p -e "s/type \(!'a, !'b\) t/type \(!'a, !'b\) t = \('a, 'b) Hashtbl.t/" \ + stdlib/moreLabels.temp.mli > stdlib/moreLabels.2temp.mli +perl -p -e\ + "s/module Make \(H : HashedType\) : S with type key = H.t\ +/`cat tools/unlabel-patches/1.mli`/" \ + stdlib/moreLabels.2temp.mli > stdlib/moreLabels.3temp.mli +perl -p -e\ + "s/module MakeSeeded \(H : SeededHashedType\) : SeededS with type key = H.t\ +/`cat tools/unlabel-patches/2.mli`/" \ + stdlib/moreLabels.3temp.mli > stdlib/moreLabels.4temp.mli +perl -p -e\ + "s/module Make \(Ord : OrderedType\) : S with type key = Ord.t\ +/`cat tools/unlabel-patches/3.mli`/" \ + stdlib/moreLabels.4temp.mli > stdlib/moreLabels.5temp.mli +perl -p -e\ + "s/module Make \(Ord : OrderedType\) : S with type elt = Ord.t\ +/`cat tools/unlabel-patches/4.mli`/" \ + stdlib/moreLabels.5temp.mli > stdlib/moreLabels.mli + +#Unix +perl -p -e "$LABREGEX" \ + otherlibs/unix/unixLabels.mli > otherlibs/unix/unix.temp.mli +#Tildes +perl -p -e "$TILDEREGEX" \ + otherlibs/unix/unix.temp.mli > otherlibs/unix/unix.2temp.mli + +#Remove type equivalences from unix.mli +perl -p -e 's/ = Unix.[a-z_]+//' \ + otherlibs/unix/unix.2temp.mli > otherlibs/unix/unix.3temp.mli +perl -p -e 's/ = Unix.LargeFile.stats//' \ + otherlibs/unix/unix.3temp.mli > otherlibs/unix/unix.mli + +#Clean up +rm -f stdlib/*temp.mli +rm -f otherlibs/unix/*temp.mli +rm -f stdlib/templates/*temp.mli diff --git a/tools/unlabel-patches/1.mli b/tools/unlabel-patches/1.mli new file mode 100644 index 00000000..70e0a9ee --- /dev/null +++ b/tools/unlabel-patches/1.mli @@ -0,0 +1,3 @@ + module Make : functor (H : HashedType) -> S + with type key = H.t + and type 'a t = 'a Hashtbl.Make(H).t diff --git a/tools/unlabel-patches/2.mli b/tools/unlabel-patches/2.mli new file mode 100644 index 00000000..4ff662e8 --- /dev/null +++ b/tools/unlabel-patches/2.mli @@ -0,0 +1,3 @@ + module MakeSeeded (H : SeededHashedType) : SeededS + with type key = H.t + and type 'a t = 'a Hashtbl.MakeSeeded(H).t diff --git a/tools/unlabel-patches/3.mli b/tools/unlabel-patches/3.mli new file mode 100644 index 00000000..0b20cff9 --- /dev/null +++ b/tools/unlabel-patches/3.mli @@ -0,0 +1,3 @@ + module Make : functor (Ord : OrderedType) -> S + with type key = Ord.t + and type 'a t = 'a Map.Make(Ord).t diff --git a/tools/unlabel-patches/4.mli b/tools/unlabel-patches/4.mli new file mode 100644 index 00000000..5c8b1837 --- /dev/null +++ b/tools/unlabel-patches/4.mli @@ -0,0 +1,3 @@ + module Make : functor (Ord : OrderedType) -> S + with type elt = Ord.t + and type t = Set.Make(Ord).t diff --git a/toplevel/dune b/toplevel/dune index 476274b9..dff689b3 100644 --- a/toplevel/dune +++ b/toplevel/dune @@ -37,7 +37,6 @@ (targets ocaml.byte) (action (run %{ocaml_where}/expunge %{dep:topstart.exe} %{targets} ; FIXME: inlined $(STDLIB_MODULES) ... minus Labels ones ... - stdlib__Spacetime stdlib__Arg stdlib__Array ; stdlib__ArrayLabels @@ -54,6 +53,7 @@ stdlib__Char stdlib__Complex stdlib__Digest + stdlib__Either stdlib__Ephemeron stdlib__Filename stdlib__Float diff --git a/toplevel/genprintval.ml b/toplevel/genprintval.ml index 27ee2425..29b8f48d 100644 --- a/toplevel/genprintval.ml +++ b/toplevel/genprintval.ml @@ -360,8 +360,11 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct a case (PR#6669). Unfortunately, there is a corner-case that *is* - a real cycle: using -rectypes one can define - let rec x = lazy x + a real cycle: using unboxed types one can define + + type t = T : t Lazy.t -> t [@@unboxed] + let rec x = lazy (T x) + which creates a Forward_tagged block that points to itself. For this reason, we still "nest" (detect head cycles) on forward tags. @@ -381,8 +384,7 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct Oval_stuff "" | {type_kind = Type_abstract; type_manifest = Some body} -> tree_of_val depth obj - (try Ctype.apply env decl.type_params body ty_list with - Ctype.Cannot_apply -> abstract_type) + (instantiate_type env decl.type_params ty_list body) | {type_kind = Type_variant constr_list; type_unboxed} -> let unbx = type_unboxed.unboxed in let tag = @@ -405,12 +407,7 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct match cd_args with | Cstr_tuple l -> let ty_args = - List.map - (function ty -> - try Ctype.apply env type_params ty ty_list with - Ctype.Cannot_apply -> abstract_type) - l - in + instantiate_types env type_params ty_list l in tree_of_constr_with_args (tree_of_constr env path) (Ident.name cd_id) false 0 depth obj ty_args unbx @@ -441,7 +438,7 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct lbl_list pos obj unbx end | {type_kind = Type_open} -> - tree_of_extension path depth obj + tree_of_extension path ty_list depth obj with Not_found -> (* raised by Env.find_type *) Oval_stuff "" @@ -491,12 +488,7 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct let rec tree_of_fields pos = function | [] -> [] | {ld_id; ld_type} :: remainder -> - let ty_arg = - try - Ctype.apply env type_params ld_type - ty_list - with - Ctype.Cannot_apply -> abstract_type in + let ty_arg = instantiate_type env type_params ty_list ld_type in let name = Ident.name ld_id in (* PR#5722: print full module path only for first record field *) @@ -541,7 +533,7 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct in Oval_constr (lid, args) - and tree_of_extension type_path depth bucket = + and tree_of_extension type_path ty_list depth bucket = let slot = if O.tag bucket <> 0 then bucket else O.field bucket 0 @@ -568,10 +560,17 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct identifier contained in the exception bucket *) if not (EVP.same_value slot (EVP.eval_address addr)) then raise Not_found; + let type_params = + match (Ctype.repr cstr.cstr_res).desc with + Tconstr (_,params,_) -> + params + | _ -> assert false + in + let args = instantiate_types env type_params ty_list cstr.cstr_args in tree_of_constr_with_args (fun x -> Oide_ident x) name (cstr.cstr_inlined <> None) 1 depth bucket - cstr.cstr_args false + args false with Not_found | EVP.Error -> match check_depth depth bucket ty with Some x -> x @@ -580,6 +579,13 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct | None -> Oval_stuff "" + and instantiate_type env type_params ty_list ty = + try Ctype.apply env type_params ty ty_list + with Ctype.Cannot_apply -> abstract_type + + and instantiate_types env type_params ty_list args = + List.map (instantiate_type env type_params ty_list) args + and find_printer depth env ty = let rec find = function | [] -> raise Not_found @@ -610,6 +616,6 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct Oval_printer printer) - in nest tree_of_val max_depth obj ty + in nest tree_of_val max_depth obj (Ctype.correct_levels ty) end diff --git a/toplevel/opttopdirs.ml b/toplevel/opttopdirs.ml index b8e1c012..c5effee1 100644 --- a/toplevel/opttopdirs.ml +++ b/toplevel/opttopdirs.ml @@ -26,7 +26,7 @@ let std_out = std_formatter (* To quit *) -let dir_quit () = exit 0 +let dir_quit () = raise (Compenv.Exit_with_status 0) let _ = Hashtbl.add directive_table "quit" (Directive_none dir_quit) diff --git a/toplevel/opttoploop.ml b/toplevel/opttoploop.ml index 6c5e10b3..bafc673f 100644 --- a/toplevel/opttoploop.ml +++ b/toplevel/opttoploop.ml @@ -653,7 +653,7 @@ let loop ppf = if !Clflags.dump_source then Pprintast.top_phrase ppf phr; ignore(execute_phrase true ppf phr) with - | End_of_file -> exit 0 + | End_of_file -> raise (Compenv.Exit_with_status 0) | Sys.Break -> fprintf ppf "Interrupted.@."; Btype.backtrack snap | PPerror -> () | x -> Location.report_exception ppf x; Btype.backtrack snap diff --git a/toplevel/opttopmain.ml b/toplevel/opttopmain.ml index b0573173..182e52fd 100644 --- a/toplevel/opttopmain.ml +++ b/toplevel/opttopmain.ml @@ -13,7 +13,7 @@ (* *) (**************************************************************************) -open Clflags +open Compenv let usage = "Usage: ocamlnat [script-file]\noptions are:" @@ -67,15 +67,15 @@ let file_argument name = Printf.eprintf "For implementation reasons, the toplevel does not support\ \ having script files (here %S) inside expanded arguments passed through\ \ the -args{,0} command-line option.\n" name; - exit 2 + raise (Exit_with_status 2) end else begin let newargs = Array.sub !argv !Arg.current (Array.length !argv - !Arg.current) in Compmisc.read_clflags_from_env (); if prepare ppf && Opttoploop.run_script ppf name newargs - then exit 0 - else exit 2 + then raise (Exit_with_status 0) + else raise (Exit_with_status 2) end let wrap_expand f s = @@ -101,16 +101,23 @@ let () = Clflags.include_dirs := List.rev_append extra_paths !Clflags.include_dirs let main () = - native_code := true; + Clflags.native_code := true; let list = ref Options.list in begin try Arg.parse_and_expand_argv_dynamic current argv list file_argument usage; with - | Arg.Bad msg -> Format.fprintf Format.err_formatter "%s%!" msg; exit 2 - | Arg.Help msg -> Format.fprintf Format.std_formatter "%s%!" msg; exit 0 + | Arg.Bad msg -> Format.fprintf Format.err_formatter "%s%!" msg; + raise (Exit_with_status 2) + | Arg.Help msg -> Format.fprintf Format.std_formatter "%s%!" msg; + raise (Exit_with_status 0) end; Compmisc.read_clflags_from_env (); - if not (prepare Format.err_formatter) then exit 2; + if not (prepare Format.err_formatter) then raise (Exit_with_status 2); Compmisc.init_path (); Opttoploop.loop Format.std_formatter + +let main () = + match main () with + | exception Exit_with_status n -> n + | () -> 0 diff --git a/toplevel/opttopmain.mli b/toplevel/opttopmain.mli index 93fea4c7..8be7680e 100644 --- a/toplevel/opttopmain.mli +++ b/toplevel/opttopmain.mli @@ -15,4 +15,4 @@ (* Start the [ocaml] toplevel loop *) -val main: unit -> unit +val main: unit -> int diff --git a/toplevel/opttopstart.ml b/toplevel/opttopstart.ml index a8127208..0cdb5420 100644 --- a/toplevel/opttopstart.ml +++ b/toplevel/opttopstart.ml @@ -13,4 +13,4 @@ (* *) (**************************************************************************) -let _ = Opttopmain.main() +let _ = exit (Opttopmain.main()) diff --git a/toplevel/topdirs.ml b/toplevel/topdirs.ml index 530a927f..6fbbc6c1 100644 --- a/toplevel/topdirs.ml +++ b/toplevel/topdirs.ml @@ -58,7 +58,7 @@ let order_of_sections = (* To quit *) -let dir_quit () = exit 0 +let dir_quit () = raise (Compenv.Exit_with_status 0) let _ = add_directive "quit" (Directive_none dir_quit) { diff --git a/toplevel/toploop.ml b/toplevel/toploop.ml index f2b3845a..6f0c12b5 100644 --- a/toplevel/toploop.ml +++ b/toplevel/toploop.ml @@ -207,15 +207,15 @@ let load_lambda ppf lam = Symtable.update_global_table(); let initial_bindings = !toplevel_value_bindings in let bytecode, closure = Meta.reify_bytecode code [| events |] None in - try + match may_trace := true; - let retval = closure () in - may_trace := false; - if can_free then Meta.release_bytecode bytecode; - Result retval - with x -> - may_trace := false; - if can_free then Meta.release_bytecode bytecode; + Fun.protect + ~finally:(fun () -> may_trace := false; + if can_free then Meta.release_bytecode bytecode) + closure + with + | retval -> Result retval + | exception x -> record_backtrace (); toplevel_value_bindings := initial_bindings; (* PR#6211 *) Symtable.restore_state initial_symtable; @@ -590,7 +590,7 @@ let loop ppf = begin try initialize_toplevel_env () with Env.Error _ | Typetexp.Error _ as exn -> - Location.report_exception ppf exn; exit 2 + Location.report_exception ppf exn; raise (Compenv.Exit_with_status 2) end; let lb = Lexing.from_function refill_lexbuf in Location.init lb "//toplevel//"; @@ -614,7 +614,7 @@ let loop ppf = Env.reset_cache_toplevel (); ignore(execute_phrase true ppf phr) with - | End_of_file -> exit 0 + | End_of_file -> raise (Compenv.Exit_with_status 0) | Sys.Break -> fprintf ppf "Interrupted.@."; Btype.backtrack snap | PPerror -> () | x -> Location.report_exception ppf x; Btype.backtrack snap @@ -636,7 +636,7 @@ let run_script ppf name args = begin try toplevel_env := Compmisc.initial_env() with Env.Error _ | Typetexp.Error _ as exn -> - Location.report_exception ppf exn; exit 2 + Location.report_exception ppf exn; raise (Compenv.Exit_with_status 2) end; Sys.interactive := false; run_hooks After_setup; diff --git a/toplevel/topmain.ml b/toplevel/topmain.ml index dec1659d..a0020b68 100644 --- a/toplevel/topmain.ml +++ b/toplevel/topmain.ml @@ -13,8 +13,6 @@ (* *) (**************************************************************************) -open Compenv - let usage = "Usage: ocaml [script-file [arguments]]\n\ options are:" @@ -43,7 +41,7 @@ let prepare ppf = try let res = let objects = - List.rev (!preload_objects @ !first_objfiles) + List.rev (!preload_objects @ !Compenv.first_objfiles) in List.for_all (Topdirs.load_file ppf) objects in @@ -68,7 +66,7 @@ let file_argument name = Printf.eprintf "For implementation reasons, the toplevel does not support\ \ having script files (here %S) inside expanded arguments passed through the\ \ -args{,0} command-line option.\n" name; - exit 2 + raise (Compenv.Exit_with_status 2) end else begin let newargs = Array.sub !argv !current (Array.length !argv - !current) @@ -76,8 +74,8 @@ let file_argument name = Compenv.readenv ppf Before_link; Compmisc.read_clflags_from_env (); if prepare ppf && Toploop.run_script ppf name newargs - then exit 0 - else exit 2 + then raise (Compenv.Exit_with_status 0) + else raise (Compenv.Exit_with_status 2) end @@ -111,11 +109,16 @@ let main () = try Arg.parse_and_expand_argv_dynamic current argv list file_argument usage; with - | Arg.Bad msg -> Printf.eprintf "%s" msg; exit 2 - | Arg.Help msg -> Printf.printf "%s" msg; exit 0 + | Arg.Bad msg -> Printf.eprintf "%s" msg; raise (Compenv.Exit_with_status 2) + | Arg.Help msg -> Printf.printf "%s" msg; raise (Compenv.Exit_with_status 0) end; Compenv.readenv ppf Before_link; Compmisc.read_clflags_from_env (); - if not (prepare ppf) then exit 2; + if not (prepare ppf) then raise (Compenv.Exit_with_status 2); Compmisc.init_path (); Toploop.loop Format.std_formatter + +let main () = + match main () with + | exception Compenv.Exit_with_status n -> n + | () -> 0 diff --git a/toplevel/topmain.mli b/toplevel/topmain.mli index 93fea4c7..18f779dd 100644 --- a/toplevel/topmain.mli +++ b/toplevel/topmain.mli @@ -13,6 +13,6 @@ (* *) (**************************************************************************) -(* Start the [ocaml] toplevel loop *) +(* Start the [ocaml] toplevel loop, and return the exit code *) -val main: unit -> unit +val main: unit -> int diff --git a/toplevel/topstart.ml b/toplevel/topstart.ml index e3dd62c9..57d58e41 100644 --- a/toplevel/topstart.ml +++ b/toplevel/topstart.ml @@ -13,4 +13,4 @@ (* *) (**************************************************************************) -let _ = Topmain.main() +let _ = exit (Topmain.main()) diff --git a/toplevel/trace.ml b/toplevel/trace.ml index cc732a61..36839909 100644 --- a/toplevel/trace.ml +++ b/toplevel/trace.ml @@ -21,7 +21,7 @@ open Longident open Types open Toploop -type codeptr = Obj.t +type codeptr = Obj.raw_data type traced_function = { path: Path.t; (* Name under which it is traced *) @@ -42,9 +42,13 @@ let is_traced clos = (* Get or overwrite the code pointer of a closure *) -let get_code_pointer cls = Obj.field cls 0 +let get_code_pointer cls = + assert (let t = Obj.tag cls in t = Obj.closure_tag || t = Obj.infix_tag); + Obj.raw_field cls 0 -let set_code_pointer cls ptr = Obj.set_field cls 0 ptr +let set_code_pointer cls ptr = + assert (let t = Obj.tag cls in t = Obj.closure_tag || t = Obj.infix_tag); + Obj.set_raw_field cls 0 ptr (* Call a traced function (use old code pointer, but new closure as environment so that recursive calls are also traced). diff --git a/typing/btype.ml b/typing/btype.ml index bec31496..98531f15 100644 --- a/typing/btype.ml +++ b/typing/btype.ml @@ -18,6 +18,8 @@ open Asttypes open Types +open Local_store + (**** Sets, maps and hashtables of types ****) module TypeSet = Set.Make(TypeOps) @@ -40,7 +42,7 @@ let pivot_level = 2 * lowest_level - 1 (**** Some type creators ****) -let new_id = ref (-1) +let new_id = s_ref (-1) let newty2 level desc = incr new_id; { desc; level; scope = lowest_level; id = !new_id } @@ -82,14 +84,14 @@ type changes = | Unchanged | Invalid -let trail = Weak.create 1 +let trail = s_table Weak.create 1 let log_change ch = - match Weak.get trail 0 with None -> () + match Weak.get !trail 0 with None -> () | Some r -> let r' = ref Unchanged in r := Change (ch, r'); - Weak.set trail 0 (Some r') + Weak.set !trail 0 (Some r') (**** Representative of a type ****) @@ -633,7 +635,7 @@ let rec check_expans visited ty = | _ -> () *) -let memo = ref [] +let memo = s_ref [] (* Contains the list of saved abbreviation expansions. *) let cleanup_abbrev () = @@ -718,7 +720,7 @@ let undo_change = function | Ctypeset (r, v) -> r := v type snapshot = changes ref * int -let last_snapshot = ref 0 +let last_snapshot = s_ref 0 let log_type ty = if ty.id <= !last_snapshot then log_change (Ctype (ty, ty.desc)) @@ -771,10 +773,10 @@ let set_typeset rs s = let snapshot () = let old = !last_snapshot in last_snapshot := !new_id; - match Weak.get trail 0 with Some r -> (r, old) + match Weak.get !trail 0 with Some r -> (r, old) | None -> let r = ref Unchanged in - Weak.set trail 0 (Some r); + Weak.set !trail 0 (Some r); (r, old) let rec rev_log accu = function @@ -795,7 +797,7 @@ let backtrack (changes, old) = List.iter undo_change backlog; changes := Unchanged; last_snapshot := old; - Weak.set trail 0 (Some changes) + Weak.set !trail 0 (Some changes) let rec rev_compress_log log r = match !r with diff --git a/typing/ctype.ml b/typing/ctype.ml index 826b048a..00bce3b7 100644 --- a/typing/ctype.ml +++ b/typing/ctype.ml @@ -20,6 +20,8 @@ open Asttypes open Types open Btype +open Local_store + (* Type manipulation after type inference ====================================== @@ -181,10 +183,10 @@ exception Cannot_apply (**** Type level management ****) -let current_level = ref 0 -let nongen_level = ref 0 -let global_level = ref 1 -let saved_level = ref [] +let current_level = s_ref 0 +let nongen_level = s_ref 0 +let global_level = s_ref 1 +let saved_level = s_ref [] type levels = { current_level: int; nongen_level: int; global_level: int; @@ -301,15 +303,27 @@ type unification_mode = | Expression (* unification in expression *) | Pattern (* unification in pattern which may add local constraints *) +type equations_generation = + | Forbidden + | Allowed of { equated_types : unit TypePairs.t } + let umode = ref Expression -let generate_equations = ref false +let equations_generation = ref Forbidden let assume_injective = ref false +let allow_recursive_equation = ref false + +let can_generate_equations () = + match !equations_generation with + | Forbidden -> false + | _ -> true -let set_mode_pattern ~generate ~injective f = +let set_mode_pattern ~generate ~injective ~allow_recursive f = Misc.protect_refs - [Misc.R (umode, Pattern); - Misc.R (generate_equations, generate); - Misc.R (assume_injective, injective)] f + [ Misc.R (umode, Pattern); + Misc.R (equations_generation, generate); + Misc.R (assume_injective, injective); + Misc.R (allow_recursive_equation, allow_recursive); + ] f (*** Checks for type definitions ***) @@ -800,34 +814,45 @@ let rec normalize_package_path env p = normalize_package_path env (Path.Pdot (p1', s)) | _ -> p -let check_scope_escape env level ty = - let rec loop ty = - let ty = repr ty in - if ty.level >= lowest_level then begin - ty.level <- pivot_level - ty.level; - if level < ty.scope then - raise(Trace.scope_escape ty); - begin match ty.desc with - | Tconstr (p, _, _) when level < Path.scope p -> - begin match !forward_try_expand_once env ty with - | ty' -> aux ty' - | exception Cannot_expand -> - raise Trace.(Unify [escape (Constructor p)]) - end - | Tpackage (p, nl, tl) when level < Path.scope p -> - let p' = normalize_package_path env p in - if Path.same p p' then raise Trace.(Unify [escape (Module_type p)]); - aux { ty with desc = Tpackage (p', nl, tl) } - | _ -> - iter_type_expr loop ty - end; - end - and aux ty = - loop ty; - unmark_type ty +let rec check_scope_escape env level ty = + let mark ty = + (* Mark visited types with [ty.level < lowest_level]. *) + set_level ty (pivot_level - ty.level) in - try aux ty; + let ty = repr ty in + (* If the type hasn't been marked, check it. Otherwise, we have already + checked it. + *) + if ty.level >= lowest_level then begin + if level < ty.scope then + raise(Trace.scope_escape ty); + begin match ty.desc with + | Tconstr (p, _, _) when level < Path.scope p -> + begin match !forward_try_expand_once env ty with + | ty' -> + mark ty; + check_scope_escape env level ty' + | exception Cannot_expand -> + raise Trace.(Unify [escape (Constructor p)]) + end + | Tpackage (p, nl, tl) when level < Path.scope p -> + let p' = normalize_package_path env p in + if Path.same p p' then raise Trace.(Unify [escape (Module_type p)]); + let orig_level = ty.level in + mark ty; + check_scope_escape env level + (Btype.newty2 orig_level (Tpackage (p', nl, tl))) + | _ -> + mark ty; + iter_type_expr (check_scope_escape env level) ty + end; + end + +let check_scope_escape env level ty = + let snap = snapshot () in + try check_scope_escape env level ty; backtrack snap with Unify [Trace.Escape x] -> + backtrack snap; raise Trace.(Unify[Escape { x with context = Some ty }]) let update_scope scope ty = @@ -860,7 +885,7 @@ let rec update_level env level expand ty = | Tconstr(p, (_ :: _ as tl), _) -> let variance = try (Env.find_type p env).type_variance - with Not_found -> List.map (fun _ -> Variance.may_inv) tl in + with Not_found -> List.map (fun _ -> Variance.unknown) tl in let needs_expand = expand || List.exists2 @@ -939,7 +964,7 @@ let rec lower_contravariant env var_level visited contra ty = typ.type_kind = Type_abstract with Not_found -> (* See testsuite/tests/typing-missing-cmi-2 for an example *) - List.map (fun _ -> Variance.may_inv) tyl, + List.map (fun _ -> Variance.unknown) tyl, false in if List.for_all ((=) Variance.null) variance then () else @@ -1062,6 +1087,22 @@ let compute_univars ty = try !(TypeHash.find node_univars ty) with Not_found -> TypeSet.empty +let fully_generic ty = + let rec aux acc ty = + acc && + let ty = repr ty in + ty.level < lowest_level || ( + ty.level = generic_level && ( + mark_type_node ty; + fold_type_expr aux true ty + ) + ) + in + let res = aux true ty in + unmark_type ty; + res + + (*******************) (* Instantiation *) (*******************) @@ -1796,7 +1837,8 @@ let type_changed = ref false (* trace possible changes to the studied type *) let merge r b = if b then r := true let occur env ty0 ty = - let allow_recursive = !Clflags.recursive_types || !umode = Pattern in + let allow_recursive = + !Clflags.recursive_types || !umode = Pattern && !allow_recursive_equation in let old = !type_changed in try while @@ -1819,18 +1861,18 @@ let occur_in env ty0 t = (* PR#6992: we actually need it for contractiveness *) (* This is a simplified version of occur, only for the rectypes case *) -let rec local_non_recursive_abbrev strict visited env p ty = +let rec local_non_recursive_abbrev ~allow_rec strict visited env p ty = (*Format.eprintf "@[Check %s =@ %a@]@." (Path.name p) !Btype.print_raw ty;*) let ty = repr ty in if not (List.memq ty visited) then begin match ty.desc with Tconstr(p', args, _abbrev) -> if Path.same p p' then raise Occur; - if not strict && is_contractive env p' then () else + if allow_rec && not strict && is_contractive env p' then () else let visited = ty :: visited in begin try (* try expanding, since [p] could be hidden *) - local_non_recursive_abbrev strict visited env p + local_non_recursive_abbrev ~allow_rec strict visited env p (try_expand_head try_expand_once_opt env ty) with Cannot_expand -> let params = @@ -1840,19 +1882,24 @@ let rec local_non_recursive_abbrev strict visited env p ty = List.iter2 (fun tv ty -> let strict = strict || not (is_Tvar (repr tv)) in - local_non_recursive_abbrev strict visited env p ty) + local_non_recursive_abbrev ~allow_rec strict visited env p ty) params args end + | Tobject _ | Tvariant _ when not strict -> + () | _ -> - if strict then (* PR#7374 *) + if strict || not allow_rec then (* PR#7374 *) let visited = ty :: visited in - iter_type_expr (local_non_recursive_abbrev true visited env p) ty + iter_type_expr + (local_non_recursive_abbrev ~allow_rec true visited env p) ty end let local_non_recursive_abbrev env p ty = + let allow_rec = + !Clflags.recursive_types || !umode = Pattern && !allow_recursive_equation in try (* PR#7397: need to check trace_gadt_instances *) wrap_trace_gadt_instances env - (local_non_recursive_abbrev false [] env p) ty; + (local_non_recursive_abbrev ~allow_rec false [] env p) ty; true with Occur -> false @@ -2058,7 +2105,7 @@ let expand_trace env trace = let deep_occur t0 ty = let rec occur_rec ty = let ty = repr ty in - if ty.level >= lowest_level then begin + if ty.level >= t0.level then begin if ty == t0 then raise Occur; ty.level <- pivot_level - ty.level; iter_type_expr occur_rec ty @@ -2439,6 +2486,8 @@ let eq_package_path env p1 p2 = let nondep_type' = ref (fun _ _ _ -> assert false) let package_subtype = ref (fun _ _ _ _ _ _ _ -> assert false) +exception Nondep_cannot_erase of Ident.t + let rec concat_longident lid1 = let open Longident in function @@ -2480,7 +2529,14 @@ let complete_type_list ?(allow_absent=false) env nl1 lv2 mty2 nl2 tl2 = match Env.find_type_by_name lid env' with | (_, {type_arity = 0; type_kind = Type_abstract; type_private = Public; type_manifest = Some t2}) -> - (n, nondep_instance env' lv2 id2 t2) :: complete nl ntl2 + begin match nondep_instance env' lv2 id2 t2 with + | t -> (n, t) :: complete nl ntl2 + | exception Nondep_cannot_erase _ -> + if allow_absent then + complete nl ntl2 + else + raise Exit + end | (_, {type_arity = 0; type_kind = Type_abstract; type_private = Public; type_manifest = None}) when allow_absent -> @@ -2527,6 +2583,12 @@ let unify1_var env t1 t2 = t1.desc <- d1; raise e +(* Can only be called when generate_equations is true *) +let record_equation t1 t2 = + match !equations_generation with + | Forbidden -> assert false + | Allowed { equated_types } -> TypePairs.add equated_types (t1, t2) () + let rec unify (env:Env.t ref) t1 t2 = (* First step: special cases (optimizations) *) if t1 == t2 then () else @@ -2656,11 +2718,12 @@ and unify3 env t1 t1' t2 t2' = | (Ttuple tl1, Ttuple tl2) -> unify_list env tl1 tl2 | (Tconstr (p1, tl1, _), Tconstr (p2, tl2, _)) when Path.same p1 p2 -> - if !umode = Expression || not !generate_equations then + if !umode = Expression || !equations_generation = Forbidden then unify_list env tl1 tl2 else if !assume_injective then - set_mode_pattern ~generate:true ~injective:false - (fun () -> unify_list env tl1 tl2) + set_mode_pattern ~generate:!equations_generation ~injective:false + ~allow_recursive:!allow_recursive_equation + (fun () -> unify_list env tl1 tl2) else if in_current_module p1 (* || in_pervasives p1 *) || List.exists (expands_to_datatype !env) [t1'; t1; t2] then unify_list env tl1 tl2 @@ -2673,7 +2736,8 @@ and unify3 env t1 t1' t2 t2' = List.iter2 (fun i (t1, t2) -> if i then unify env t1 t2 else - set_mode_pattern ~generate:false ~injective:false + set_mode_pattern ~generate:Forbidden ~injective:false + ~allow_recursive:!allow_recursive_equation begin fun () -> let snap = snapshot () in try unify env t1 t2 with Unify _ -> @@ -2684,25 +2748,31 @@ and unify3 env t1 t1' t2 t2' = | (Tconstr (path,[],_), Tconstr (path',[],_)) when is_instantiable !env path && is_instantiable !env path' - && !generate_equations -> + && can_generate_equations () -> let source, destination = if Path.scope path > Path.scope path' then path , t2' else path', t1' in + record_equation t1' t2'; add_gadt_equation env source destination | (Tconstr (path,[],_), _) - when is_instantiable !env path && !generate_equations -> + when is_instantiable !env path && can_generate_equations () -> reify env t2'; + record_equation t1' t2'; add_gadt_equation env path t2' | (_, Tconstr (path,[],_)) - when is_instantiable !env path && !generate_equations -> + when is_instantiable !env path && can_generate_equations () -> reify env t1'; + record_equation t1' t2'; add_gadt_equation env path t1' | (Tconstr (_,_,_), _) | (_, Tconstr (_,_,_)) when !umode = Pattern -> reify env t1'; reify env t2'; - if !generate_equations then mcomp !env t1' t2' + if can_generate_equations () then ( + mcomp !env t1' t2'; + record_equation t1' t2' + ) | (Tobject (fi1, nm1), Tobject (fi2, _)) -> unify_fields env fi1 fi2; (* Type [t2'] may have been instantiated by [unify_fields] *) @@ -2724,7 +2794,10 @@ and unify3 env t1 t1' t2 t2' = backtrack snap; reify env t1'; reify env t2'; - if !generate_equations then mcomp !env t1' t2' + if can_generate_equations () then ( + mcomp !env t1' t2'; + record_equation t1' t2' + ) end | (Tfield(f,kind,_,rem), Tnil) | (Tnil, Tfield(f,kind,_,rem)) -> begin match field_kind_repr kind with @@ -3047,14 +3120,19 @@ let unify env ty1 ty2 = undo_compress snap; raise (Unify (expand_trace !env trace)) -let unify_gadt ~equations_level:lev (env:Env.t ref) ty1 ty2 = +let unify_gadt ~equations_level:lev ~allow_recursive (env:Env.t ref) ty1 ty2 = try univar_pairs := []; gadt_equations_level := Some lev; - set_mode_pattern ~generate:true ~injective:true - (fun () -> unify env ty1 ty2); + let equated_types = TypePairs.create 0 in + set_mode_pattern + ~generate:(Allowed { equated_types }) + ~injective:true + ~allow_recursive + (fun () -> unify env ty1 ty2); gadt_equations_level := None; TypePairs.clear unify_eq_set; + equated_types with e -> gadt_equations_level := None; TypePairs.clear unify_eq_set; @@ -4468,7 +4546,7 @@ let closed_schema env ty = (* Normalize a type before printing, saving... *) (* Cannot use mark_type because deep_occur uses it too *) -let rec normalize_type_rec env visited ty = +let rec normalize_type_rec visited ty = let ty = repr ty in if not (TypeSet.mem ty !visited) then begin visited := TypeSet.add ty !visited; @@ -4489,7 +4567,8 @@ let rec normalize_type_rec env visited ty = let tyl' = List.fold_left (fun tyl ty -> - if List.exists (fun ty' -> equal env false [ty] [ty']) tyl + if List.exists + (fun ty' -> equal Env.empty false [ty] [ty']) tyl then tyl else ty::tyl) [ty] tyl in @@ -4527,11 +4606,11 @@ let rec normalize_type_rec env visited ty = set_type_desc fi fi'.desc | _ -> () end; - iter_type_expr (normalize_type_rec env visited) ty + iter_type_expr (normalize_type_rec visited) ty end -let normalize_type env ty = - normalize_type_rec env (ref TypeSet.empty) ty +let normalize_type ty = + normalize_type_rec (ref TypeSet.empty) ty (*************************) @@ -4551,8 +4630,6 @@ let nondep_variants = TypeHash.create 17 let clear_hash () = TypeHash.clear nondep_hash; TypeHash.clear nondep_variants -exception Nondep_cannot_erase of Ident.t - let rec nondep_type_rec ?(expand_private=false) env ids ty = let expand_abbrev env t = if expand_private then expand_abbrev_opt env t else expand_abbrev env t diff --git a/typing/ctype.mli b/typing/ctype.mli index 05fb78ce..4215e14f 100644 --- a/typing/ctype.mli +++ b/typing/ctype.mli @@ -18,6 +18,8 @@ open Asttypes open Types +module TypePairs : Hashtbl.S with type key = type_expr * type_expr + module Unification_trace: sig (** Unification traces are used to explain unification errors when printing error messages *) @@ -132,8 +134,24 @@ val repr: type_expr -> type_expr val object_fields: type_expr -> type_expr val flatten_fields: type_expr -> (string * field_kind * type_expr) list * type_expr - (* Transform a field type into a list of pairs label-type *) - (* The fields are sorted *) +(** Transform a field type into a list of pairs label-type. + The fields are sorted. + + Beware of the interaction with GADTs: + + Due to the introduction of object indexes for GADTs, the row variable of + an object may now be an expansible type abbreviation. + A first consequence is that [flatten_fields] will not completely flatten + the object, since the type abbreviation will not be expanded + ([flatten_fields] does not receive the current environment). + Another consequence is that various functions may be called with the + expansion of this type abbreviation, which is a Tfield, e.g. during + printing. + + Concrete problems have been fixed, but new bugs may appear in the + future. (Test cases were added to typing-gadts/test.ml) +*) + val associate_fields: (string * field_kind * type_expr) list -> (string * field_kind * type_expr) list -> @@ -173,6 +191,8 @@ val limited_generalize: type_expr -> type_expr -> unit (* Only generalize some part of the type Make the remaining of the type non-generalizable *) +val fully_generic: type_expr -> bool + val check_scope_escape : Env.t -> int -> type_expr -> unit (* [check_scope_escape env lvl ty] ensures that [ty] could be raised to the level [lvl] without any scope escape. @@ -236,9 +256,11 @@ val enforce_constraints: Env.t -> type_expr -> unit val unify: Env.t -> type_expr -> type_expr -> unit (* Unify the two types given. Raise [Unify] if not possible. *) val unify_gadt: - equations_level:int -> Env.t ref -> type_expr -> type_expr -> unit + equations_level:int -> allow_recursive:bool -> + Env.t ref -> type_expr -> type_expr -> unit TypePairs.t (* Unify the two types given and update the environment with the - local constraints. Raise [Unify] if not possible. *) + local constraints. Raise [Unify] if not possible. + Returns the pairs of types that have been equated. *) val unify_var: Env.t -> type_expr -> type_expr -> unit (* Same as [unify], but allow free univars when first type is a variable. *) @@ -327,7 +349,7 @@ val nondep_cltype_declaration: (*val correct_abbrev: Env.t -> Path.t -> type_expr list -> type_expr -> unit*) val cyclic_abbrev: Env.t -> Ident.t -> type_expr -> bool val is_contractive: Env.t -> Path.t -> bool -val normalize_type: Env.t -> type_expr -> unit +val normalize_type: type_expr -> unit val closed_schema: Env.t -> type_expr -> bool (* Check whether the given type scheme contains no non-generic diff --git a/typing/datarepr.ml b/typing/datarepr.ml index 818d60ad..989395c0 100644 --- a/typing/datarepr.ml +++ b/typing/datarepr.ml @@ -85,7 +85,7 @@ let constructor_args ~current_unit priv cd_args cd_res path rep = type_kind = Type_record (lbls, rep); type_private = priv; type_manifest = None; - type_variance = List.map (fun _ -> Variance.full) type_params; + type_variance = Variance.unknown_signature ~injective:true ~arity; type_separability = Types.Separability.default_signature ~arity; type_is_newtype = false; type_expansion_scope = Btype.lowest_level; diff --git a/typing/env.ml b/typing/env.ml index 9abbd089..108bb71a 100644 --- a/typing/env.ml +++ b/typing/env.ml @@ -23,6 +23,8 @@ open Path open Types open Btype +open Local_store + module String = Misc.Stdlib.String let add_delayed_check_forward = ref (fun _ -> assert false) @@ -35,9 +37,9 @@ type 'a usage_tbl = ('a -> unit) Types.Uid.Tbl.t (inclusion test between signatures, cf Includemod.value_descriptions, ...). *) -let value_declarations : unit usage_tbl = Types.Uid.Tbl.create 16 -let type_declarations : unit usage_tbl = Types.Uid.Tbl.create 16 -let module_declarations : unit usage_tbl = Types.Uid.Tbl.create 16 +let value_declarations : unit usage_tbl ref = s_table Types.Uid.Tbl.create 16 +let type_declarations : unit usage_tbl ref = s_table Types.Uid.Tbl.create 16 +let module_declarations : unit usage_tbl ref = s_table Types.Uid.Tbl.create 16 type constructor_usage = Positive | Pattern | Privatize type constructor_usages = @@ -64,7 +66,8 @@ let add_constructor_usage ~rebind priv cu usage = let constructor_usages () = {cu_positive = false; cu_pattern = false; cu_privatize = false} -let used_constructors : constructor_usage usage_tbl = Types.Uid.Tbl.create 16 +let used_constructors : constructor_usage usage_tbl ref = + s_table Types.Uid.Tbl.create 16 (** Map indexed by the name of module components. *) module NameMap = String.Map @@ -667,7 +670,8 @@ module Current_unit_name : sig val get : unit -> modname val set : modname -> unit val is : modname -> bool - val is_name_of : Ident.t -> bool + val is_ident : Ident.t -> bool + val is_path : Path.t -> bool end = struct let current_unit = ref "" @@ -677,8 +681,11 @@ end = struct current_unit := name let is name = !current_unit = name - let is_name_of id = - is (Ident.name id) + let is_ident id = + Ident.persistent id && is (Ident.name id) + let is_path = function + | Pident id -> is_ident id + | Pdot _ | Papply _ -> false end let set_unit_name = Current_unit_name.set @@ -688,7 +695,7 @@ let find_same_module id tbl = match IdTbl.find_same id tbl with | x -> x | exception Not_found - when Ident.persistent id && not (Current_unit_name.is_name_of id) -> + when Ident.persistent id && not (Current_unit_name.is_ident id) -> Mod_persistent let find_name_module ~mark name tbl = @@ -700,20 +707,34 @@ let find_name_module ~mark name tbl = let add_persistent_structure id env = if not (Ident.persistent id) then invalid_arg "Env.add_persistent_structure"; - if not (Current_unit_name.is_name_of id) then - let summary = + if Current_unit_name.is_ident id then env + else begin + let material = + (* This addition only observably changes the environment if it shadows a + non-persistent module already in the environment. + (See PR#9345) *) match IdTbl.find_name wrap_module ~mark:false (Ident.name id) env.modules with - | exception Not_found | _, Mod_persistent -> env.summary - | _ -> Env_persistent (env.summary, id) + | exception Not_found | _, Mod_persistent -> false + | _ -> true in - { env with - modules = IdTbl.add id Mod_persistent env.modules; - summary - } - else - env + let summary = + if material then Env_persistent (env.summary, id) + else env.summary + in + let modules = + (* With [-no-alias-deps], non-material additions should not + affect the environment at all. We should only observe the + existence of a cmi when accessing components of the module. + (See #9991). *) + if material || not !Clflags.transparent_modules then + IdTbl.add id Mod_persistent env.modules + else + env.modules + in + { env with modules; summary } + end let components_of_module ~alerts ~uid env fs ps path addr mty = { @@ -769,57 +790,57 @@ let read_sign_of_cmi = sign_of_cmi ~freshen:true let save_sign_of_cmi = sign_of_cmi ~freshen:false -let persistent_env : module_data Persistent_env.t = - Persistent_env.empty () +let persistent_env : module_data Persistent_env.t ref = + s_table Persistent_env.empty () let without_cmis f x = - Persistent_env.without_cmis persistent_env f x + Persistent_env.without_cmis !persistent_env f x -let imports () = Persistent_env.imports persistent_env +let imports () = Persistent_env.imports !persistent_env let import_crcs ~source crcs = - Persistent_env.import_crcs persistent_env ~source crcs + Persistent_env.import_crcs !persistent_env ~source crcs let read_pers_mod modname filename = - Persistent_env.read persistent_env read_sign_of_cmi modname filename + Persistent_env.read !persistent_env read_sign_of_cmi modname filename let find_pers_mod name = - Persistent_env.find persistent_env read_sign_of_cmi name + Persistent_env.find !persistent_env read_sign_of_cmi name let check_pers_mod ~loc name = - Persistent_env.check persistent_env read_sign_of_cmi ~loc name + Persistent_env.check !persistent_env read_sign_of_cmi ~loc name let crc_of_unit name = - Persistent_env.crc_of_unit persistent_env read_sign_of_cmi name + Persistent_env.crc_of_unit !persistent_env read_sign_of_cmi name let is_imported_opaque modname = - Persistent_env.is_imported_opaque persistent_env modname + Persistent_env.is_imported_opaque !persistent_env modname let register_import_as_opaque modname = - Persistent_env.register_import_as_opaque persistent_env modname + Persistent_env.register_import_as_opaque !persistent_env modname let reset_declaration_caches () = - Types.Uid.Tbl.clear value_declarations; - Types.Uid.Tbl.clear type_declarations; - Types.Uid.Tbl.clear module_declarations; - Types.Uid.Tbl.clear used_constructors; + Types.Uid.Tbl.clear !value_declarations; + Types.Uid.Tbl.clear !type_declarations; + Types.Uid.Tbl.clear !module_declarations; + Types.Uid.Tbl.clear !used_constructors; () let reset_cache () = Current_unit_name.set ""; - Persistent_env.clear persistent_env; + Persistent_env.clear !persistent_env; reset_declaration_caches (); () let reset_cache_toplevel () = - Persistent_env.clear_missing persistent_env; + Persistent_env.clear_missing !persistent_env; reset_declaration_caches (); () (* get_components *) let get_components_res c = - match Persistent_env.can_load_cmis persistent_env with + match Persistent_env.can_load_cmis !persistent_env with | Persistent_env.Can_load_cmis -> EnvLazy.force !components_of_module_maker' c.comps | Persistent_env.Cannot_load_cmis log -> @@ -1066,7 +1087,7 @@ let find_hash_type path env = | Papply _ -> raise Not_found -let required_globals = ref [] +let required_globals = s_ref [] let reset_required_globals () = required_globals := [] let get_required_globals () = !required_globals let add_required_global id = @@ -1243,7 +1264,7 @@ let rec scrape_alias_for_visit env (sub : Subst.t option) mty = begin match may_subst Subst.module_path sub path with | Pident id when Ident.persistent id - && not (Persistent_env.looked_up persistent_env (Ident.name id)) -> + && not (Persistent_env.looked_up !persistent_env (Ident.name id)) -> false | path -> (* PR#6600: find_module may raise Not_found *) try scrape_alias_for_visit env sub (find_module path env).md_type @@ -1283,7 +1304,7 @@ let iter_env wrap proj1 proj2 f env () = iter_components (Pident id) path data.mda_components | Mod_persistent -> let modname = Ident.name id in - match Persistent_env.find_in_cache persistent_env modname with + match Persistent_env.find_in_cache !persistent_env modname with | None -> () | Some data -> iter_components (Pident id) path data.mda_components) @@ -1304,7 +1325,7 @@ let same_types env1 env2 = env1.types == env2.types && env1.modules == env2.modules let used_persistent () = - Persistent_env.fold persistent_env + Persistent_env.fold !persistent_env (fun s _m r -> Concr.add s r) Concr.empty @@ -1479,6 +1500,16 @@ let module_declaration_address env id presence md = | Mp_present -> EnvLazy.create_forced (Aident id) +let is_identchar c = + (* This should be kept in sync with the [identchar_latin1] character class + in [lexer.mll] *) + match c with + | 'A'..'Z' | 'a'..'z' | '_' | '\192'..'\214' + | '\216'..'\246' | '\248'..'\255' | '\'' | '0'..'9' -> + true + | _ -> + false + let rec components_of_module_maker {cm_env; cm_freshening_subst; cm_prefixing_subst; cm_path; cm_addr; cm_mty} : _ result = @@ -1655,7 +1686,7 @@ and check_value_name name loc = (* Note: we could also check here general validity of the identifier, to protect against bad identifiers forged by -pp or -ppx preprocessors. *) - if String.length name > 0 && (name.[0] = '#') then + if String.length name > 0 && not (is_identchar name.[0]) then for i = 1 to String.length name - 1 do if name.[i] = '#' then error (Illegal_value_name(loc, name)) @@ -1664,7 +1695,7 @@ and check_value_name name loc = and store_value ?check id addr decl env = check_value_name (Ident.name id) decl.val_loc; Option.iter - (fun f -> check_usage decl.val_loc id decl.val_uid f value_declarations) + (fun f -> check_usage decl.val_loc id decl.val_uid f !value_declarations) check; let vda = { vda_description = decl; vda_address = addr } in { env with @@ -1676,7 +1707,7 @@ and store_type ~check id info env = if check then check_usage loc id info.type_uid (fun s -> Warnings.Unused_type_declaration s) - type_declarations; + !type_declarations; let path = Pident id in let constructors = Datarepr.constructors_of_type path info @@ -1695,9 +1726,9 @@ and store_type ~check id info env = let name = cstr.cstr_name in let loc = cstr.cstr_loc in let k = cstr.cstr_uid in - if not (Types.Uid.Tbl.mem used_constructors k) then + if not (Types.Uid.Tbl.mem !used_constructors k) then let used = constructor_usages () in - Types.Uid.Tbl.add used_constructors k + Types.Uid.Tbl.add !used_constructors k (add_constructor_usage ~rebind:false priv used); if not (ty_name = "" || ty_name.[0] = '_') then !add_delayed_check_forward @@ -1747,9 +1778,9 @@ and store_extension ~check ~rebind id addr ext env = let is_exception = Path.same ext.ext_type_path Predef.path_exn in let name = cstr.cstr_name in let k = cstr.cstr_uid in - if not (Types.Uid.Tbl.mem used_constructors k) then begin + if not (Types.Uid.Tbl.mem !used_constructors k) then begin let used = constructor_usages () in - Types.Uid.Tbl.add used_constructors k + Types.Uid.Tbl.add !used_constructors k (add_constructor_usage ~rebind priv used); !add_delayed_check_forward (fun () -> @@ -1768,7 +1799,7 @@ and store_extension ~check ~rebind id addr ext env = and store_module ~check ~freshening_sub id addr presence md env = let loc = md.md_loc in Option.iter - (fun f -> check_usage loc id md.md_uid f module_declarations) check; + (fun f -> check_usage loc id md.md_uid f !module_declarations) check; let alerts = Builtin_attributes.alerts_of_attrs md.md_attributes in let module_decl_lazy = match freshening_sub with @@ -2115,11 +2146,11 @@ let save_signature_with_transform cmi_transform ~alerts sg modname filename = Subst.reset_for_saving (); let sg = Subst.signature Make_local (Subst.for_saving Subst.identity) sg in let cmi = - Persistent_env.make_cmi persistent_env modname sg alerts + Persistent_env.make_cmi !persistent_env modname sg alerts |> cmi_transform in let pm = save_sign_of_cmi { Persistent_env.Persistent_signature.cmi; filename } in - Persistent_env.save_cmi persistent_env + Persistent_env.save_cmi !persistent_env { Persistent_env.Persistent_signature.filename; cmi } pm; cmi @@ -2142,19 +2173,19 @@ let (initial_safe_string, initial_unsafe_string) = (* Tracking usage *) let mark_module_used uid = - match Types.Uid.Tbl.find module_declarations uid with + match Types.Uid.Tbl.find !module_declarations uid with | mark -> mark () | exception Not_found -> () let mark_modtype_used _uid = () let mark_value_used uid = - match Types.Uid.Tbl.find value_declarations uid with + match Types.Uid.Tbl.find !value_declarations uid with | mark -> mark () | exception Not_found -> () let mark_type_used uid = - match Types.Uid.Tbl.find type_declarations uid with + match Types.Uid.Tbl.find !type_declarations uid with | mark -> mark () | exception Not_found -> () @@ -2164,12 +2195,12 @@ let mark_type_path_used env path = | exception Not_found -> () let mark_constructor_used usage cd = - match Types.Uid.Tbl.find used_constructors cd.cd_uid with + match Types.Uid.Tbl.find !used_constructors cd.cd_uid with | mark -> mark usage | exception Not_found -> () let mark_extension_used usage ext = - match Types.Uid.Tbl.find used_constructors ext.ext_uid with + match Types.Uid.Tbl.find !used_constructors ext.ext_uid with | mark -> mark usage | exception Not_found -> () @@ -2180,7 +2211,7 @@ let mark_constructor_description_used usage env cstr = | _ -> assert false in mark_type_path_used env ty_path; - match Types.Uid.Tbl.find used_constructors cstr.cstr_uid with + match Types.Uid.Tbl.find !used_constructors cstr.cstr_uid with | mark -> mark usage | exception Not_found -> () @@ -2193,25 +2224,26 @@ let mark_label_description_used () env lbl = mark_type_path_used env ty_path let mark_class_used uid = - match Types.Uid.Tbl.find type_declarations uid with + match Types.Uid.Tbl.find !type_declarations uid with | mark -> mark () | exception Not_found -> () let mark_cltype_used uid = - match Types.Uid.Tbl.find type_declarations uid with + match Types.Uid.Tbl.find !type_declarations uid with | mark -> mark () | exception Not_found -> () let set_value_used_callback vd callback = - Types.Uid.Tbl.add value_declarations vd.val_uid callback + Types.Uid.Tbl.add !value_declarations vd.val_uid callback let set_type_used_callback td callback = if Uid.for_actual_declaration td.type_uid then let old = - try Types.Uid.Tbl.find type_declarations td.type_uid + try Types.Uid.Tbl.find !type_declarations td.type_uid with Not_found -> ignore in - Types.Uid.Tbl.replace type_declarations td.type_uid (fun () -> callback old) + Types.Uid.Tbl.replace !type_declarations td.type_uid + (fun () -> callback old) (* Lookup by name *) @@ -2856,7 +2888,7 @@ let fold_modules f lid env acc = in f name p md acc | Mod_persistent -> - match Persistent_env.find_in_cache persistent_env name with + match Persistent_env.find_in_cache !persistent_env name with | None -> acc | Some mda -> let md = @@ -2917,7 +2949,7 @@ let filter_non_loaded_persistent f env = | Mod_local _ -> acc | Mod_unbound _ -> acc | Mod_persistent -> - match Persistent_env.find_in_cache persistent_env name with + match Persistent_env.find_in_cache !persistent_env name with | Some _ -> acc | None -> if f (Ident.create_persistent name) then @@ -2982,8 +3014,8 @@ let summary env = if Path.Map.is_empty env.local_constraints then env.summary else Env_constraints (env.summary, env.local_constraints) -let last_env = ref empty -let last_reduced_env = ref empty +let last_env = s_ref empty +let last_reduced_env = s_ref empty let keep_only_summary env = if !last_env == env then !last_reduced_env @@ -3076,21 +3108,45 @@ let report_lookup_error _loc env ppf = function | Unbound_type lid -> fprintf ppf "Unbound type constructor %a" !print_longident lid; spellcheck ppf extract_types env lid; - | Unbound_module lid -> + | Unbound_module lid -> begin fprintf ppf "Unbound module %a" !print_longident lid; - spellcheck ppf extract_modules env lid; + match find_modtype_by_name lid env with + | exception Not_found -> spellcheck ppf extract_modules env lid; + | _ -> + fprintf ppf + "@.@[%s %a, %s@]" + "Hint: There is a module type named" + !print_longident lid + "but module types are not modules" + end | Unbound_constructor lid -> fprintf ppf "Unbound constructor %a" !print_longident lid; spellcheck ppf extract_constructors env lid; | Unbound_label lid -> fprintf ppf "Unbound record field %a" !print_longident lid; spellcheck ppf extract_labels env lid; - | Unbound_class lid -> + | Unbound_class lid -> begin fprintf ppf "Unbound class %a" !print_longident lid; - spellcheck ppf extract_classes env lid; - | Unbound_modtype lid -> + match find_cltype_by_name lid env with + | exception Not_found -> spellcheck ppf extract_classes env lid; + | _ -> + fprintf ppf + "@.@[%s %a, %s@]" + "Hint: There is a class type named" + !print_longident lid + "but classes are not class types" + end + | Unbound_modtype lid -> begin fprintf ppf "Unbound module type %a" !print_longident lid; - spellcheck ppf extract_modtypes env lid; + match find_module_by_name lid env with + | exception Not_found -> spellcheck ppf extract_modtypes env lid; + | _ -> + fprintf ppf + "@.@[%s %a, %s@]" + "Hint: There is a module named" + !print_longident lid + "but modules are not module types" + end | Unbound_cltype lid -> fprintf ppf "Unbound class type %a" !print_longident lid; spellcheck ppf extract_cltypes env lid; @@ -3133,9 +3189,13 @@ let report_lookup_error _loc env ppf = function fprintf ppf "@[The functor %a is generative,@ it@ cannot@ be@ \ applied@ in@ type@ expressions@]" !print_longident lid | Cannot_scrape_alias(lid, p) -> + let cause = + if Current_unit_name.is_path p then "is the current compilation unit" + else "is missing" + in fprintf ppf - "The module %a is an alias for module %a, which is missing" - !print_longident lid !print_path p + "The module %a is an alias for module %a, which %s" + !print_longident lid !print_path p cause let report_error ppf = function | Missing_module(_, path1, path2) -> diff --git a/typing/env.mli b/typing/env.mli index e43a5efd..76c3ff7e 100644 --- a/typing/env.mli +++ b/typing/env.mli @@ -436,9 +436,34 @@ val print_path: (Format.formatter -> Path.t -> unit) ref (** Folds *) +val fold_values: + (string -> Path.t -> value_description -> 'a -> 'a) -> + Longident.t option -> t -> 'a -> 'a +val fold_types: + (string -> Path.t -> type_declaration -> 'a -> 'a) -> + Longident.t option -> t -> 'a -> 'a val fold_constructors: (constructor_description -> 'a -> 'a) -> Longident.t option -> t -> 'a -> 'a +val fold_labels: + (label_description -> 'a -> 'a) -> + Longident.t option -> t -> 'a -> 'a + +(** Persistent structures are only traversed if they are already loaded. *) +val fold_modules: + (string -> Path.t -> module_declaration -> 'a -> 'a) -> + Longident.t option -> t -> 'a -> 'a + +val fold_modtypes: + (string -> Path.t -> modtype_declaration -> 'a -> 'a) -> + Longident.t option -> t -> 'a -> 'a +val fold_classes: + (string -> Path.t -> class_declaration -> 'a -> 'a) -> + Longident.t option -> t -> 'a -> 'a +val fold_cltypes: + (string -> Path.t -> class_type_declaration -> 'a -> 'a) -> + Longident.t option -> t -> 'a -> 'a + (** Utilities *) val scrape_alias: t -> module_type -> module_type diff --git a/typing/ident.ml b/typing/ident.ml index 6296398b..feb590d0 100644 --- a/typing/ident.ml +++ b/typing/ident.ml @@ -13,6 +13,8 @@ (* *) (**************************************************************************) +open Local_store + let lowest_scope = 0 let highest_scope = 100000000 @@ -26,8 +28,8 @@ type t = (* A stamp of 0 denotes a persistent identifier *) -let currentstamp = ref 0 -let predefstamp = ref 0 +let currentstamp = s_ref 0 +let predefstamp = s_ref 0 let create_scoped ~scope s = incr currentstamp; diff --git a/typing/ident.mli b/typing/ident.mli index 65ddb9fc..ff48efb3 100644 --- a/typing/ident.mli +++ b/typing/ident.mli @@ -37,7 +37,7 @@ val create_predef: string -> t val rename: t -> t (** Creates an identifier with the same name as the input, a fresh stamp, and no scope. - @raises [Fatal_error] if called on a persistent / predef ident. *) + @raise [Fatal_error] if called on a persistent / predef ident. *) val name: t -> string val unique_name: t -> string diff --git a/typing/mtype.ml b/typing/mtype.ml index edb4e1b7..07b28b34 100644 --- a/typing/mtype.ml +++ b/typing/mtype.ml @@ -222,6 +222,8 @@ and nondep_sig_item env va ids = function Sig_class_type(id, Ctype.nondep_cltype_declaration env ids d, rs, vis) and nondep_sig env va ids sg = + let scope = Ctype.create_scope () in + let sg, env = Env.enter_signature ~scope sg env in List.map (nondep_sig_item env va ids) sg and nondep_modtype_decl env ids mtd = diff --git a/typing/oprint.ml b/typing/oprint.ml index bf6f5f90..b28641c4 100644 --- a/typing/oprint.ml +++ b/typing/oprint.ml @@ -400,9 +400,11 @@ let out_type = ref print_out_type let print_type_parameter ppf s = if s = "_" then fprintf ppf "_" else pr_var ppf s -let type_parameter ppf (ty, (co, cn)) = - fprintf ppf "%s%a" - (if not cn then "+" else if not co then "-" else "") +let type_parameter ppf (ty, (var, inj)) = + let open Asttypes in + fprintf ppf "%s%s%a" + (match var with Covariant -> "+" | Contravariant -> "-" | NoVariance -> "") + (match inj with Injective -> "!" | NoInjectivity -> "") print_type_parameter ty let print_out_class_params ppf = diff --git a/typing/outcometree.mli b/typing/outcometree.mli index bb53d235..2ab89f46 100644 --- a/typing/outcometree.mli +++ b/typing/outcometree.mli @@ -56,6 +56,8 @@ type out_value = | Oval_tuple of out_value list | Oval_variant of string * out_value option +type out_type_param = string * (Asttypes.variance * Asttypes.injectivity) + type out_type = | Otyp_abstract | Otyp_open @@ -97,10 +99,10 @@ type out_module_type = | Omty_alias of out_ident and out_sig_item = | Osig_class of - bool * string * (string * (bool * bool)) list * out_class_type * + bool * string * out_type_param list * out_class_type * out_rec_status | Osig_class_type of - bool * string * (string * (bool * bool)) list * out_class_type * + bool * string * out_type_param list * out_class_type * out_rec_status | Osig_typext of out_extension_constructor * out_ext_status | Osig_modtype of string * out_module_type @@ -110,7 +112,7 @@ and out_sig_item = | Osig_ellipsis and out_type_decl = { otype_name: string; - otype_params: (string * (bool * bool)) list; + otype_params: out_type_param list; otype_type: out_type; otype_private: Asttypes.private_flag; otype_immediate: Type_immediacy.t; diff --git a/typing/parmatch.ml b/typing/parmatch.ml index 1209ef8c..57834d3d 100644 --- a/typing/parmatch.ml +++ b/typing/parmatch.ml @@ -20,6 +20,7 @@ open Asttypes open Types open Typedtree + (*************************************) (* Utilities for building patterns *) (*************************************) @@ -30,168 +31,15 @@ let make_pat desc ty tenv = pat_attributes = []; } -let omega = make_pat Tpat_any Ctype.none Env.empty +let omega = Patterns.omega +let omegas = Patterns.omegas +let omega_list = Patterns.omega_list let extra_pat = make_pat (Tpat_var (Ident.create_local "+", mknoloc "+")) Ctype.none Env.empty -let rec omegas i = - if i <= 0 then [] else omega :: omegas (i-1) - -let omega_list l = List.map (fun _ -> omega) l - -module Pattern_head : sig - type desc = - | Any - | Construct of constructor_description - | Constant of constant - | Tuple of int - | Record of label_description list - | Variant of - { tag: label; has_arg: bool; - cstr_row: row_desc ref; - type_row : unit -> row_desc; } - (* the row of the type may evolve if [close_variant] is called, - hence the (unit -> ...) delay *) - | Array of int - | Lazy - - type t - - val desc : t -> desc - val env : t -> Env.t - val loc : t -> Location.t - val typ : t -> Types.type_expr - - (** [deconstruct p] returns the head of [p] and the list of sub patterns. - - @raises [Invalid_arg _] if [p] is an or- or an exception-pattern. *) - val deconstruct : pattern -> t * pattern list - - (** reconstructs a pattern, putting wildcards as sub-patterns. *) - val to_omega_pattern : t -> pattern - - val make - : loc:Location.t - -> typ:Types.type_expr - -> env:Env.t - -> desc - -> t - - val omega : t - -end = struct - type desc = - | Any - | Construct of constructor_description - | Constant of constant - | Tuple of int - | Record of label_description list - | Variant of - { tag: label; - has_arg: bool; - cstr_row: row_desc ref; - type_row: unit -> row_desc; } - | Array of int - | Lazy - - type t = { - desc: desc; - typ : Types.type_expr; - loc : Location.t; - env : Env.t; - attributes : attributes; - } - - let desc { desc } = desc - let env { env } = env - let loc { loc } = loc - let typ { typ } = typ - - let deconstruct q = - let rec deconstruct_desc = function - | Tpat_any - | Tpat_var _ -> Any, [] - | Tpat_constant c -> Constant c, [] - | Tpat_alias (p,_,_) -> deconstruct_desc p.pat_desc - | Tpat_tuple args -> - Tuple (List.length args), args - | Tpat_construct (_, c, args) -> - Construct c, args - | Tpat_variant (tag, arg, cstr_row) -> - let has_arg, pats = - match arg with - | None -> false, [] - | Some a -> true, [a] - in - let type_row () = - match Ctype.expand_head q.pat_env q.pat_type with - | {desc = Tvariant type_row} -> Btype.row_repr type_row - | _ -> assert false - in - Variant {tag; has_arg; cstr_row; type_row}, pats - | Tpat_array args -> - Array (List.length args), args - | Tpat_record (largs, _) -> - let lbls = List.map (fun (_,lbl,_) -> lbl) largs in - let pats = List.map (fun (_,_,pat) -> pat) largs in - Record lbls, pats - | Tpat_lazy p -> - Lazy, [p] - | Tpat_or _ -> invalid_arg "Parmatch.Pattern_head.deconstruct: (P | Q)" - in - let desc, pats = deconstruct_desc q.pat_desc in - { desc; typ = q.pat_type; loc = q.pat_loc; - env = q.pat_env; attributes = q.pat_attributes }, pats - - let to_omega_pattern t = - let pat_desc = - match t.desc with - | Any -> Tpat_any - | Lazy -> Tpat_lazy omega - | Constant c -> Tpat_constant c - | Tuple n -> Tpat_tuple (omegas n) - | Array n -> Tpat_array (omegas n) - | Construct c -> - let lid_loc = Location.mkloc (Longident.Lident c.cstr_name) t.loc in - Tpat_construct (lid_loc, c, omegas c.cstr_arity) - | Variant { tag; has_arg; cstr_row } -> - let arg_opt = if has_arg then Some omega else None in - Tpat_variant (tag, arg_opt, cstr_row) - | Record lbls -> - let lst = - List.map (fun lbl -> - let lid_loc = - Location.mkloc (Longident.Lident lbl.lbl_name) t.loc - in - (lid_loc, lbl, omega) - ) lbls - in - Tpat_record (lst, Closed) - in - { pat_desc; pat_type = t.typ; pat_loc = t.loc; pat_extra = []; - pat_env = t.env; pat_attributes = t.attributes } - - let make ~loc ~typ ~env desc = - { desc; loc; typ; env; attributes = [] } - - let omega = - { desc = Any - ; loc = Location.none - ; typ = Ctype.none - ; env = Env.empty - ; attributes = [] - } -end - -(* - Normalize a pattern -> - all arguments are omega (simple pattern) and no more variables -*) - -let normalize_pat p = Pattern_head.(to_omega_pattern @@ fst @@ deconstruct p) (*******************) (* Coherence check *) @@ -269,8 +117,9 @@ let normalize_pat p = Pattern_head.(to_omega_pattern @@ fst @@ deconstruct p) check that every other head pattern in the column is coherent with that one. *) let all_coherent column = + let open Patterns.Head in let coherent_heads hp1 hp2 = - match Pattern_head.desc hp1, Pattern_head.desc hp2 with + match hp1.pat_desc, hp2.pat_desc with | Construct c, Construct c' -> c.cstr_consts = c'.cstr_consts && c.cstr_nonconsts = c'.cstr_nonconsts @@ -303,11 +152,11 @@ let all_coherent column = | _, _ -> false in match - List.find (fun head_pat -> - match Pattern_head.desc head_pat with - | Any -> false - | _ -> true - ) column + List.find + (function + | { pat_desc = Any } -> false + | _ -> true) + column with | exception Not_found -> (* only omegas on the column: the column is coherent. *) @@ -385,8 +234,8 @@ let first_column simplified_matrix = let is_absent tag row = Btype.row_field tag !row = Rabsent let is_absent_pat d = - match Pattern_head.desc d with - | Variant { tag; cstr_row; _ } -> is_absent tag cstr_row + match d.pat_desc with + | Patterns.Head.Variant { tag; cstr_row; _ } -> is_absent tag cstr_row | _ -> false let const_compare x y = @@ -505,7 +354,8 @@ let get_constructor_type_path ty tenv = (* Check top matching *) let simple_match d h = - match Pattern_head.desc d, Pattern_head.desc h with + let open Patterns.Head in + match d.pat_desc, h.pat_desc with | Construct c1, Construct c2 -> Types.equal_tag c1.cstr_tag c2.cstr_tag | Variant { tag = t1; _ }, Variant { tag = t2 } -> @@ -521,10 +371,12 @@ let simple_match d h = (* extract record fields as a whole *) -let record_arg ph = match Pattern_head.desc ph with -| Any -> [] -| Record args -> args -| _ -> fatal_error "Parmatch.as_record" +let record_arg ph = + let open Patterns.Head in + match ph.pat_desc with + | Any -> [] + | Record args -> args + | _ -> fatal_error "Parmatch.as_record" let extract_fields lbls arg = @@ -536,26 +388,28 @@ let extract_fields lbls arg = List.map (fun lbl -> get_field lbl.lbl_pos arg) lbls (* Build argument list when p2 >= p1, where p1 is a simple pattern *) -let simple_match_args discr head args = match Pattern_head.desc head with -| Constant _ -> [] -| Construct _ -| Variant _ -| Tuple _ -| Array _ -| Lazy -> args -| Record lbls -> extract_fields (record_arg discr) (List.combine lbls args) -| Any -> - begin match Pattern_head.desc discr with - | Construct cstr -> omegas cstr.cstr_arity - | Variant { has_arg = true } - | Lazy -> [omega] - | Record lbls -> omega_list lbls - | Array len - | Tuple len -> omegas len - | Variant { has_arg = false } - | Any - | Constant _ -> [] - end +let simple_match_args discr head args = + let open Patterns.Head in + match head.pat_desc with + | Constant _ -> [] + | Construct _ + | Variant _ + | Tuple _ + | Array _ + | Lazy -> args + | Record lbls -> extract_fields (record_arg discr) (List.combine lbls args) + | Any -> + begin match discr.pat_desc with + | Construct cstr -> Patterns.omegas cstr.cstr_arity + | Variant { has_arg = true } + | Lazy -> [Patterns.omega] + | Record lbls -> omega_list lbls + | Array len + | Tuple len -> Patterns.omegas len + | Variant { has_arg = false } + | Any + | Constant _ -> [] + end (* Consider a pattern matrix whose first column has been simplified to contain only _ or a head constructor @@ -585,10 +439,11 @@ let simple_match_args discr head args = match Pattern_head.desc head with stop and return our accumulator. *) let discr_pat q pss = + let open Patterns.Head in let rec refine_pat acc = function | [] -> acc | ((head, _), _) :: rows -> - match Pattern_head.desc head with + match head.pat_desc with | Any -> refine_pat acc rows | Tuple _ | Lazy -> head | Record lbls -> @@ -606,15 +461,12 @@ let discr_pat q pss = lbl :: r ) lbls (record_arg acc) in - let d = - let open Pattern_head in - make ~loc:(loc head) ~typ:(typ head) ~env:(env head) (Record fields) - in + let d = { head with pat_desc = Record fields } in refine_pat d rows | _ -> acc in - let q, _ = Pattern_head.deconstruct q in - match Pattern_head.desc q with + let q, _ = deconstruct q in + match q.pat_desc with (* short-circuiting: clearly if we have anything other than [Record] or [Any] to start with, we're not going to be able refine at all. So there's no point going over the matrix. *) @@ -711,13 +563,10 @@ and set_args_erase_mutable q r = do_set_args ~erase_mutable:true q r *) let simplify_head_pat ~add_column p ps k = let rec simplify_head_pat p ps k = - match p.pat_desc with - | Tpat_alias (p,_,_) -> - (* We have to handle aliases here, because there can be or-patterns - underneath, that [Pattern_head.deconstruct] won't handle. *) - simplify_head_pat p ps k - | Tpat_or (p1,p2,_) -> simplify_head_pat p1 ps (simplify_head_pat p2 ps k) - | _ -> add_column (Pattern_head.deconstruct p) ps k + match Patterns.General.(view p |> strip_vars).pat_desc with + | `Or (p1,p2,_) -> simplify_head_pat p1 ps (simplify_head_pat p2 ps k) + | #Patterns.Simple.view as view -> + add_column (Patterns.Head.deconstruct { p with pat_desc = view }) ps k in simplify_head_pat p ps k let rec simplify_first_col = function @@ -751,7 +600,7 @@ let build_specialized_submatrix ~extend_row discr pss = *) type 'matrix specialized_matrices = { default : 'matrix; - constrs : (Pattern_head.t * 'matrix) list; + constrs : (Patterns.Head.t * 'matrix) list; } (* Consider a pattern matrix whose first column has been simplified @@ -785,7 +634,13 @@ let build_specialized_submatrices ~extend_row discr rows = (discr, r :: rs) in - (* insert a row of head [p] and rest [r] into the right group *) + (* insert a row of head [p] and rest [r] into the right group + + Note: with this implementation, the order of the groups + is the order of their first row in the source order. + This is a nice property to get exhaustivity counter-examples + in source order. + *) let rec insert_constr head args r = function | [] -> (* if no group matched this row, it has a head constructor that @@ -799,14 +654,14 @@ let build_specialized_submatrices ~extend_row discr rows = (* insert a row of head omega into all groups *) let insert_omega r env = - List.map (fun (q0,rs) -> extend_group q0 Pattern_head.omega [] r rs) env + List.map (fun (q0,rs) -> extend_group q0 Patterns.Head.omega [] r rs) env in let rec form_groups constr_groups omega_tails = function | [] -> (constr_groups, omega_tails) | ((head, args), tail) :: rest -> - match Pattern_head.desc head with - | Any -> + match head.pat_desc with + | Patterns.Head.Any -> (* note that calling insert_omega here would be wrong as some groups may not have been formed yet, if the first row with this head pattern comes after in the list *) @@ -818,7 +673,8 @@ let build_specialized_submatrices ~extend_row discr rows = let constr_groups, omega_tails = let initial_constr_group = - match Pattern_head.desc discr with + let open Patterns.Head in + match discr.pat_desc with | Record _ | Tuple _ | Lazy -> (* [discr] comes from [discr_pat], and in this case subsumes any of the patterns we could find on the first column of [rows]. So it is better @@ -829,31 +685,34 @@ let build_specialized_submatrices ~extend_row discr rows = in form_groups initial_constr_group [] rows in - { - default = omega_tails; - constrs = - (* insert omega rows in all groups *) - List.fold_right insert_omega omega_tails constr_groups; - } + + (* groups are accumulated in reverse order; + we restore the order of rows in the source code *) + let default = List.rev omega_tails in + let constrs = + List.fold_right insert_omega omega_tails constr_groups + |> List.map (fun (discr, rs) -> (discr, List.rev rs)) + in + { default; constrs; } (* Variant related functions *) let set_last a = let rec loop = function | [] -> assert false - | [_] -> [a] + | [_] -> [Patterns.General.erase a] | x::l -> x :: loop l in function - | (_, []) -> (Pattern_head.deconstruct a, []) + | (_, []) -> (Patterns.Head.deconstruct a, []) | (first, row) -> (first, loop row) (* mark constructor lines for failure when they are incomplete *) let mark_partial = - let zero = make_pat (Tpat_constant (Const_int 0)) Ctype.none Env.empty in + let zero = make_pat (`Constant (Const_int 0)) Ctype.none Env.empty in List.map (fun ((hp, _), _ as ps) -> - match Pattern_head.desc hp with - | Any -> ps + match hp.pat_desc with + | Patterns.Head.Any -> ps | _ -> set_last zero ps ) @@ -885,7 +744,8 @@ let close_variant env row = let full_match closing env = match env with | [] -> false | (discr, _) :: _ -> - match Pattern_head.desc discr with + let open Patterns.Head in + match discr.pat_desc with | Any -> assert false | Construct { cstr_tag = Cstr_extension _ ; _ } -> false | Construct c -> List.length env = c.cstr_consts + c.cstr_nonconsts @@ -893,7 +753,7 @@ let full_match closing env = match env with let fields = List.map (fun (d, _) -> - match Pattern_head.desc d with + match d.pat_desc with | Variant { tag } -> tag | _ -> assert false) env @@ -930,11 +790,10 @@ let should_extend ext env = match ext with | Some ext -> begin match env with | [] -> assert false | (p,_)::_ -> - begin match Pattern_head.desc p with + let open Patterns.Head in + begin match p.pat_desc with | Construct {cstr_tag=(Cstr_constant _|Cstr_block _|Cstr_unboxed)} -> - let path = - get_constructor_type_path (Pattern_head.typ p) (Pattern_head.env p) - in + let path = get_constructor_type_path p.pat_type p.pat_env in Path.same path ext | Construct {cstr_tag=(Cstr_extension _)} -> false | Constant _ | Tuple _ | Variant _ | Record _ | Array _ | Lazy -> false @@ -986,7 +845,7 @@ let rec orify_many = function (* build an or-pattern from a constructor list *) let pat_of_constrs ex_pat cstrs = - let ex_pat = Pattern_head.to_omega_pattern ex_pat in + let ex_pat = Patterns.Head.to_omega_pattern ex_pat in if cstrs = [] then raise Empty else orify_many (List.map (pat_of_constr ex_pat) cstrs) @@ -1031,10 +890,10 @@ let rec get_variant_constructors env ty = | _ -> fatal_error "Parmatch.get_variant_constructors" (* Sends back a pattern that complements constructor tags all_tag *) -let complete_constrs p all_tags = - let c = match Pattern_head.desc p with Construct c -> c | _ -> assert false in +let complete_constrs constr all_tags = + let c = constr.pat_desc in let not_tags = complete_tags c.cstr_consts c.cstr_nonconsts all_tags in - let constrs = get_variant_constructors (Pattern_head.env p) c.cstr_res in + let constrs = get_variant_constructors constr.pat_env c.cstr_res in let others = List.filter (fun cnstr -> ConstructorTagHashtbl.mem not_tags cnstr.cstr_tag) @@ -1044,30 +903,26 @@ let complete_constrs p all_tags = const @ nonconst let build_other_constrs env p = - match Pattern_head.desc p with - | Construct { cstr_tag = Cstr_constant _ | Cstr_block _ } -> + let open Patterns.Head in + match p.pat_desc with + | Construct ({ cstr_tag = Cstr_constant _ | Cstr_block _ } as c) -> + let constr = { p with pat_desc = c } in let get_tag q = - match Pattern_head.desc q with + match q.pat_desc with | Construct c -> c.cstr_tag | _ -> fatal_error "Parmatch.get_tag" in let all_tags = List.map (fun (p,_) -> get_tag p) env in - pat_of_constrs p (complete_constrs p all_tags) + pat_of_constrs p (complete_constrs constr all_tags) | _ -> extra_pat -let complete_constrs p all_tags = - (* This wrapper is here for [Matching], which (indirectly) calls this function - from [combine_constructor], and nowhere else. - So we know patterns have been fully simplified. *) - complete_constrs (fst @@ Pattern_head.deconstruct p) all_tags - (* Auxiliary for build_other *) let build_other_constant proj make first next p env = - let all = List.map (fun (p, _) -> proj (Pattern_head.desc p)) env in + let all = List.map (fun (p, _) -> proj p.pat_desc) env in let rec try_const i = if List.mem i all then try_const (next i) - else make_pat (make i) (Pattern_head.typ p) (Pattern_head.env p) + else make_pat (make i) p.pat_type p.pat_env in try_const first (* @@ -1081,19 +936,18 @@ let build_other ext env = match env with | [] -> omega | (d, _) :: _ -> - match Pattern_head.desc d with + let open Patterns.Head in + match d.pat_desc with | Construct { cstr_tag = Cstr_extension _ } -> (* let c = {c with cstr_name = "*extension*"} in *) (* PR#7330 *) make_pat (Tpat_var (Ident.create_local "*extension*", - {txt="*extension*"; loc = Pattern_head.loc d})) + {txt="*extension*"; loc = d.pat_loc})) Ctype.none Env.empty | Construct _ -> begin match ext with | Some ext -> - if Path.same ext - (get_constructor_type_path - (Pattern_head.typ d) (Pattern_head.env d)) + if Path.same ext (get_constructor_type_path d.pat_type d.pat_env) then extra_pat else @@ -1105,15 +959,14 @@ let build_other ext env = let tags = List.map (fun (d, _) -> - match Pattern_head.desc d with + match d.pat_desc with | Variant { tag } -> tag | _ -> assert false) env in let make_other_pat tag const = - let arg = if const then None else Some omega in - make_pat (Tpat_variant(tag, arg, cstr_row)) - (Pattern_head.typ d) (Pattern_head.env d) + let arg = if const then None else Some Patterns.omega in + make_pat (Tpat_variant(tag, arg, cstr_row)) d.pat_type d.pat_env in let row = type_row () in begin match @@ -1137,14 +990,13 @@ let build_other ext env = | pat::other_pats -> List.fold_left (fun p_res pat -> - make_pat (Tpat_or (pat, p_res, None)) - (Pattern_head.typ d) (Pattern_head.env d)) + make_pat (Tpat_or (pat, p_res, None)) d.pat_type d.pat_env) pat other_pats end | Constant Const_char _ -> let all_chars = List.map - (fun (p,_) -> match Pattern_head.desc p with + (fun (p,_) -> match p.pat_desc with | Constant (Const_char c) -> c | _ -> assert false) env @@ -1156,11 +1008,10 @@ let build_other ext env = if List.mem ci all_chars then find_other (i+1) imax else - make_pat (Tpat_constant (Const_char ci)) - (Pattern_head.typ d) (Pattern_head.env d) + make_pat (Tpat_constant (Const_char ci)) d.pat_type d.pat_env in let rec try_chars = function - | [] -> omega + | [] -> Patterns.omega | (c1,c2) :: rest -> try find_other (Char.code c1) (Char.code c2) @@ -1207,18 +1058,16 @@ let build_other ext env = | Array _ -> let all_lengths = List.map - (fun (p,_) -> match Pattern_head.desc p with + (fun (p,_) -> match p.pat_desc with | Array len -> len | _ -> assert false) env in let rec try_arrays l = if List.mem l all_lengths then try_arrays (l+1) else - make_pat - (Tpat_array (omegas l)) - (Pattern_head.typ d) (Pattern_head.env d) in + make_pat (Tpat_array (omegas l)) d.pat_type d.pat_env in try_arrays 0 - | _ -> omega + | _ -> Patterns.omega let rec has_instance p = match p.pat_desc with | Tpat_variant (l,_,r) when is_absent l r -> false @@ -1263,39 +1112,40 @@ let rec satisfiable pss qs = match pss with | _ -> match qs with | [] -> false - | {pat_desc = Tpat_or(q1,q2,_)}::qs -> - satisfiable pss (q1::qs) || satisfiable pss (q2::qs) - | {pat_desc = Tpat_alias(q,_,_)}::qs -> - satisfiable pss (q::qs) - | {pat_desc = (Tpat_any | Tpat_var(_))}::qs -> - let pss = simplify_first_col pss in - if not (all_coherent (first_column pss)) then - false - else begin - let { default; constrs } = - let q0 = discr_pat omega pss in - build_specialized_submatrices ~extend_row:(@) q0 pss in - if not (full_match false constrs) then - satisfiable default qs - else - List.exists - (fun (p,pss) -> - not (is_absent_pat p) && - satisfiable pss - (simple_match_args p Pattern_head.omega [] @ qs)) - constrs - end - | {pat_desc=Tpat_variant (l,_,r)}::_ when is_absent l r -> false | q::qs -> - let pss = simplify_first_col pss in - let hq, qargs = Pattern_head.deconstruct q in - if not (all_coherent (hq :: first_column pss)) then - false - else begin - let q0 = discr_pat q pss in - satisfiable (build_specialized_submatrix ~extend_row:(@) q0 pss) - (simple_match_args q0 hq qargs @ qs) - end + match Patterns.General.(view q |> strip_vars).pat_desc with + | `Or(q1,q2,_) -> + satisfiable pss (q1::qs) || satisfiable pss (q2::qs) + | `Any -> + let pss = simplify_first_col pss in + if not (all_coherent (first_column pss)) then + false + else begin + let { default; constrs } = + let q0 = discr_pat Patterns.Simple.omega pss in + build_specialized_submatrices ~extend_row:(@) q0 pss in + if not (full_match false constrs) then + satisfiable default qs + else + List.exists + (fun (p,pss) -> + not (is_absent_pat p) && + satisfiable pss + (simple_match_args p Patterns.Head.omega [] @ qs)) + constrs + end + | `Variant (l,_,r) when is_absent l r -> false + | #Patterns.Simple.view as view -> + let q = { q with pat_desc = view } in + let pss = simplify_first_col pss in + let hq, qargs = Patterns.Head.deconstruct q in + if not (all_coherent (hq :: first_column pss)) then + false + else begin + let q0 = discr_pat q pss in + satisfiable (build_specialized_submatrix ~extend_row:(@) q0 pss) + (simple_match_args q0 hq qargs @ qs) + end (* While [satisfiable] only checks whether the last row of [pss + qs] is satisfiable, this function returns the (possibly empty) list of vectors [es] @@ -1313,60 +1163,62 @@ let rec list_satisfying_vectors pss qs = | _ -> match qs with | [] -> [] - | {pat_desc = Tpat_or(q1,q2,_)}::qs -> - list_satisfying_vectors pss (q1::qs) @ - list_satisfying_vectors pss (q2::qs) - | {pat_desc = Tpat_alias(q,_,_)}::qs -> - list_satisfying_vectors pss (q::qs) - | {pat_desc = (Tpat_any | Tpat_var(_))}::qs -> - let pss = simplify_first_col pss in - if not (all_coherent (first_column pss)) then - [] - else begin - let q0 = discr_pat omega pss in - let wild default_matrix p = - List.map (fun qs -> p::qs) - (list_satisfying_vectors default_matrix qs) - in - match build_specialized_submatrices ~extend_row:(@) q0 pss with - | { default; constrs = [] } -> - (* first column of pss is made of variables only *) - wild default omega - | { default; constrs = ((p,_)::_ as constrs) } -> - let for_constrs () = - List.flatten ( - List.map (fun (p,pss) -> - if is_absent_pat p then - [] - else - let witnesses = - list_satisfying_vectors pss - (simple_match_args p Pattern_head.omega [] @ qs) - in - let p = Pattern_head.to_omega_pattern p in - List.map (set_args p) witnesses - ) constrs - ) - in - if full_match false constrs then for_constrs () else - begin match Pattern_head.desc p with - | Construct _ -> - (* activate this code for checking non-gadt constructors *) - wild default (build_other_constrs constrs p) - @ for_constrs () - | _ -> - wild default omega - end + | q :: qs -> + match Patterns.General.(view q |> strip_vars).pat_desc with + | `Or(q1,q2,_) -> + list_satisfying_vectors pss (q1::qs) @ + list_satisfying_vectors pss (q2::qs) + | `Any -> + let pss = simplify_first_col pss in + if not (all_coherent (first_column pss)) then + [] + else begin + let q0 = discr_pat Patterns.Simple.omega pss in + let wild default_matrix p = + List.map (fun qs -> p::qs) + (list_satisfying_vectors default_matrix qs) + in + match build_specialized_submatrices ~extend_row:(@) q0 pss with + | { default; constrs = [] } -> + (* first column of pss is made of variables only *) + wild default omega + | { default; constrs = ((p,_)::_ as constrs) } -> + let for_constrs () = + List.flatten ( + List.map (fun (p,pss) -> + if is_absent_pat p then + [] + else + let witnesses = + list_satisfying_vectors pss + (simple_match_args p Patterns.Head.omega [] @ qs) + in + let p = Patterns.Head.to_omega_pattern p in + List.map (set_args p) witnesses + ) constrs + ) + in + if full_match false constrs then for_constrs () else + begin match p.pat_desc with + | Construct _ -> + (* activate this code + for checking non-gadt constructors *) + wild default (build_other_constrs constrs p) + @ for_constrs () + | _ -> + wild default Patterns.omega + end end - | {pat_desc=Tpat_variant (l,_,r)}::_ when is_absent l r -> [] - | q::qs -> - let hq, qargs = Pattern_head.deconstruct q in + | `Variant (l, _, r) when is_absent l r -> [] + | #Patterns.Simple.view as view -> + let q = { q with pat_desc = view } in + let hq, qargs = Patterns.Head.deconstruct q in let pss = simplify_first_col pss in if not (all_coherent (hq :: first_column pss)) then [] else begin let q0 = discr_pat q pss in - List.map (set_args (Pattern_head.to_omega_pattern q0)) + List.map (set_args (Patterns.Head.to_omega_pattern q0)) (list_satisfying_vectors (build_specialized_submatrix ~extend_row:(@) q0 pss) (simple_match_args q0 hq qargs @ qs)) @@ -1388,20 +1240,18 @@ let rec do_match pss qs = match qs with | []::_ -> true | _ -> false end -| q::qs -> match q with - | {pat_desc = Tpat_or (q1,q2,_)} -> +| q::qs -> match Patterns.General.(view q |> strip_vars).pat_desc with + | `Or (q1,q2,_) -> do_match pss (q1::qs) || do_match pss (q2::qs) - | {pat_desc = Tpat_any} -> + | `Any -> let rec remove_first_column = function | (_::ps)::rem -> ps::remove_first_column rem | _ -> [] in do_match (remove_first_column pss) qs - | _ -> - (* [q] is generated by us, it doesn't come from the source. So we know - it's not of the form [P as name]. - Therefore there is no risk of [deconstruct] raising. *) - let q0, qargs = Pattern_head.deconstruct q in + | #Patterns.Simple.view as view -> + let q = { q with pat_desc = view } in + let q0, qargs = Patterns.Head.deconstruct q in let pss = simplify_first_col pss in (* [pss] will (or won't) match [q0 :: qs] regardless of the coherence of its first column. *) @@ -1409,22 +1259,6 @@ let rec do_match pss qs = match qs with (build_specialized_submatrix ~extend_row:(@) q0 pss) (qargs @ qs) - -type 'a exhaust_result = - | No_matching_value - | Witnesses of 'a list - -let rappend r1 r2 = - match r1, r2 with - | No_matching_value, _ -> r2 - | _, No_matching_value -> r1 - | Witnesses l1, Witnesses l2 -> Witnesses (l1 @ l2) - -let rec try_many f = function - | [] -> No_matching_value - | (p,pss)::rest -> - rappend (f (p, pss)) (try_many f rest) - (* let print_pat pat = let rec string_of_pat pat = @@ -1455,84 +1289,116 @@ let print_pat pat = This function should be called for exhaustiveness check only. *) let rec exhaust (ext:Path.t option) pss n = match pss with -| [] -> Witnesses [omegas n] -| []::_ -> No_matching_value -| pss -> - let pss = simplify_first_col pss in - if not (all_coherent (first_column pss)) then - (* We're considering an ill-typed branch, we won't actually be able to - produce a well typed value taking that branch. *) - No_matching_value - else begin - (* Assuming the first column is ill-typed but considered coherent, we - might end up producing an ill-typed witness of non-exhaustivity - corresponding to the current branch. - - If [exhaust] has been called by [do_check_partial], then the witnesses - produced get typechecked and the ill-typed ones are discarded. - - If [exhaust] has been called by [do_check_fragile], then it is possible - we might fail to warn the user that the matching is fragile. See for - example testsuite/tests/warnings/w04_failure.ml. *) - let q0 = discr_pat omega pss in - match build_specialized_submatrices ~extend_row:(@) q0 pss with - | { default; constrs = [] } -> - (* first column of pss is made of variables only *) - begin match exhaust ext default (n-1) with - | Witnesses r -> - let q0 = Pattern_head.to_omega_pattern q0 in - Witnesses (List.map (fun row -> q0::row) r) - | r -> r - end - | { default; constrs } -> - let try_non_omega (p,pss) = - if is_absent_pat p then - No_matching_value - else - match - exhaust - ext pss - (List.length (simple_match_args p Pattern_head.omega []) - + n - 1) - with - | Witnesses r -> - let p = Pattern_head.to_omega_pattern p in - Witnesses (List.map (set_args p) r) - | r -> r in - let before = try_many try_non_omega constrs in - if - full_match false constrs && not (should_extend ext constrs) - then - before +| [] -> Seq.return (omegas n) +| []::_ -> Seq.empty +| [(p :: ps)] -> exhaust_single_row ext p ps n +| pss -> specialize_and_exhaust ext pss n + +and exhaust_single_row ext p ps n = + (* Shortcut: in the single-row case p :: ps we know that all + counter-examples are either of the form + counter-example(p) :: omegas + or + p :: counter-examples(ps) + + This is very interesting in the case where p contains + or-patterns, as the non-shortcut path below would do a separate + search for each constructor of the or-pattern, which can lead to + an exponential blowup on examples such as + + | (A|B), (A|B), (A|B), (A|B) -> foo + + Note that this shortcut also applies to examples such as + + | A, A, A, A -> foo | (A|B), (A|B), (A|B), (A|B) -> bar + + thanks to the [get_mins] preprocessing step which will drop the + first row (subsumed by the second). Code with this shape does + occur naturally when people want to avoid fragile pattern + matches: if A and B are the only two constructors, this is the + best way to make a non-fragile distinction between "all As" and + "at least one B". + *) + List.to_seq [Some p; None] |> Seq.flat_map + (function + | Some p -> + let sub_witnesses = exhaust ext [ps] (n - 1) in + Seq.map (fun row -> p :: row) sub_witnesses + | None -> + (* note: calling [exhaust] recursively of p would + result in an infinite loop in the case n=1 *) + let p_witnesses = specialize_and_exhaust ext [[p]] 1 in + Seq.map (fun p_row -> p_row @ omegas (n - 1)) p_witnesses + ) + +and specialize_and_exhaust ext pss n = + let pss = simplify_first_col pss in + if not (all_coherent (first_column pss)) then + (* We're considering an ill-typed branch, we won't actually be able to + produce a well typed value taking that branch. *) + Seq.empty + else begin + (* Assuming the first column is ill-typed but considered coherent, we + might end up producing an ill-typed witness of non-exhaustivity + corresponding to the current branch. + + If [exhaust] has been called by [do_check_partial], then the witnesses + produced get typechecked and the ill-typed ones are discarded. + + If [exhaust] has been called by [do_check_fragile], then it is possible + we might fail to warn the user that the matching is fragile. See for + example testsuite/tests/warnings/w04_failure.ml. *) + let q0 = discr_pat Patterns.Simple.omega pss in + match build_specialized_submatrices ~extend_row:(@) q0 pss with + | { default; constrs = [] } -> + (* first column of pss is made of variables only *) + let sub_witnesses = exhaust ext default (n-1) in + let q0 = Patterns.Head.to_omega_pattern q0 in + Seq.map (fun row -> q0::row) sub_witnesses + | { default; constrs } -> + let try_non_omega (p,pss) = + if is_absent_pat p then + Seq.empty else - let r = exhaust ext default (n-1) in - match r with - | No_matching_value -> before - | Witnesses r -> - try - let p = build_other ext constrs in - let dug = List.map (fun tail -> p :: tail) r in - match before with - | No_matching_value -> Witnesses dug - | Witnesses x -> Witnesses (x @ dug) - with - (* cannot occur, since constructors don't make a full signature *) - | Empty -> fatal_error "Parmatch.exhaust" + let sub_witnesses = + exhaust + ext pss + (List.length (simple_match_args p Patterns.Head.omega []) + + n - 1) + in + let p = Patterns.Head.to_omega_pattern p in + Seq.map (set_args p) sub_witnesses + in + let try_omega () = + if full_match false constrs && not (should_extend ext constrs) then + Seq.empty + else + let sub_witnesses = exhaust ext default (n-1) in + match build_other ext constrs with + | exception Empty -> + (* cannot occur, since constructors don't make + a full signature *) + fatal_error "Parmatch.exhaust" + | p -> + Seq.map (fun tail -> p :: tail) sub_witnesses + in + (* Lazily compute witnesses for all constructor submatrices + (Some constr_mat) then the wildcard/default submatrix (None). + Note that the call to [try_omega ()] is delayed to after + all constructor matrices have been traversed. *) + List.map (fun constr_mat -> Some constr_mat) constrs @ [None] + |> List.to_seq + |> Seq.flat_map + (function + | Some constr_mat -> try_non_omega constr_mat + | None -> try_omega ()) end let exhaust ext pss n = - let ret = exhaust ext pss n in - match ret with - No_matching_value -> No_matching_value - | Witnesses lst -> - let singletons = - List.map - (function - [x] -> x - | _ -> assert false) - lst - in - Witnesses [orify_many singletons] + exhaust ext pss n + |> Seq.map (function + | [x] -> x + | _ -> assert false) (* Another exhaustiveness check, enforcing variant typing. @@ -1554,7 +1420,7 @@ let rec pressure_variants tdefs = function if not (all_coherent (first_column pss)) then true else begin - let q0 = discr_pat omega pss in + let q0 = discr_pat Patterns.Simple.omega pss in match build_specialized_submatrices ~extend_row:(@) q0 pss with | { default; constrs = [] } -> pressure_variants tdefs default | { default; constrs } -> @@ -1589,7 +1455,7 @@ let rec pressure_variants tdefs = function | [], _ | _, None -> () | (d, _) :: _, Some env -> - match Pattern_head.desc d with + match d.pat_desc with | Variant { type_row; _ } -> let row = type_row () in if Btype.row_fixed row @@ -1645,15 +1511,10 @@ let make_row ps = {ors=[] ; no_ors=[]; active=ps} let make_rows pss = List.map make_row pss -(* Useful to detect and expand or pats inside as pats *) -let rec unalias p = match p.pat_desc with -| Tpat_alias (p,_,_) -> unalias p -| _ -> p - - -let is_var p = match (unalias p).pat_desc with -| Tpat_any|Tpat_var _ -> true -| _ -> false +(* Useful to detect and expand or pats inside as pats *) +let is_var p = match Patterns.General.(view p |> strip_vars).pat_desc with +| `Any -> true +| _ -> false let is_var_column rs = List.for_all @@ -1767,41 +1628,41 @@ let rec every_satisfiables pss qs = match qs.active with Used end | q::rem -> - let uq = unalias q in - begin match uq.pat_desc with - | Tpat_any | Tpat_var _ -> + begin match Patterns.General.(view q |> strip_vars).pat_desc with + | `Any -> if is_var_column pss then -(* forget about ``all-variable'' columns now *) + (* forget about ``all-variable'' columns now *) every_satisfiables (remove_column pss) (remove qs) else -(* otherwise this is direct food for satisfiable *) + (* otherwise this is direct food for satisfiable *) every_satisfiables (push_no_or_column pss) (push_no_or qs) - | Tpat_or (q1,q2,_) -> + | `Or (q1,q2,_) -> if q1.pat_loc.Location.loc_ghost && q2.pat_loc.Location.loc_ghost then -(* syntactically generated or-pats should not be expanded *) + (* syntactically generated or-pats should not be expanded *) every_satisfiables (push_no_or_column pss) (push_no_or qs) else -(* this is a real or-pattern *) + (* this is a real or-pattern *) every_satisfiables (push_or_column pss) (push_or qs) - | Tpat_variant (l,_,r) when is_absent l r -> (* Ah Jacques... *) + | `Variant (l,_,r) when is_absent l r -> (* Ah Jacques... *) Unused - | _ -> -(* standard case, filter matrix *) + | #Patterns.Simple.view as view -> + let q = { q with pat_desc = view } in + (* standard case, filter matrix *) let pss = simplify_first_usefulness_col pss in - let huq, args = Pattern_head.deconstruct uq in + let hq, args = Patterns.Head.deconstruct q in (* The handling of incoherent matrices is kept in line with [satisfiable] *) - if not (all_coherent (huq :: first_column pss)) then + if not (all_coherent (hq :: first_column pss)) then Unused else begin let q0 = discr_pat q pss in every_satisfiables (build_specialized_submatrix q0 pss ~extend_row:(fun ps r -> { r with active = ps @ r.active })) - {qs with active=simple_match_args q0 huq args @ rem} + {qs with active=simple_match_args q0 hq args @ rem} end end @@ -2095,6 +1956,10 @@ let ppat_of_type env ty = let (ppat, constrs, labels) = Conv.conv (orify_many pats) in PT_pattern (PE_gadt_cases, ppat, constrs, labels) +let typecheck ~pred p = + let (pattern,constrs,labels) = Conv.conv p in + pred constrs labels pattern + let do_check_partial ~pred loc casel pss = match pss with | [] -> (* @@ -2113,48 +1978,34 @@ let do_check_partial ~pred loc casel pss = match pss with end ; Partial | ps::_ -> - begin match exhaust None pss (List.length ps) with - | No_matching_value -> Total - | Witnesses [u] -> - let v = - let (pattern,constrs,labels) = Conv.conv u in - let u' = pred constrs labels pattern in - (* pretty_pat u; - begin match u' with - None -> prerr_endline ": impossible" - | Some _ -> prerr_endline ": possible" - end; *) - u' + let counter_examples = + exhaust None pss (List.length ps) + |> Seq.filter_map (typecheck ~pred) in + match counter_examples () with + | Seq.Nil -> Total + | Seq.Cons (v, _rest) -> + if Warnings.is_active (Warnings.Partial_match "") then begin + let errmsg = + try + let buf = Buffer.create 16 in + let fmt = Format.formatter_of_buffer buf in + Printpat.top_pretty fmt v; + if do_match (initial_only_guarded casel) [v] then + Buffer.add_string buf + "\n(However, some guarded clause may match this value.)"; + if contains_extension v then + Buffer.add_string buf + "\nMatching over values of extensible variant types \ + (the *extension* above)\n\ + must include a wild card pattern in order to be exhaustive." + ; + Buffer.contents buf + with _ -> + "" in - begin match v with - None -> Total - | Some v -> - if Warnings.is_active (Warnings.Partial_match "") then begin - let errmsg = - try - let buf = Buffer.create 16 in - let fmt = Format.formatter_of_buffer buf in - Printpat.top_pretty fmt v; - if do_match (initial_only_guarded casel) [v] then - Buffer.add_string buf - "\n(However, some guarded clause may match this value.)"; - if contains_extension v then - Buffer.add_string buf - "\nMatching over values of extensible variant types \ - (the *extension* above)\n\ - must include a wild card pattern in order to be exhaustive." - ; - Buffer.contents buf - with _ -> - "" - in - Location.prerr_warning loc (Warnings.Partial_match errmsg) - end; - Partial - end - | _ -> - fatal_error "Parmatch.check_partial" - end + Location.prerr_warning loc (Warnings.Partial_match errmsg) + end; + Partial (*****************) (* Fragile check *) @@ -2218,12 +2069,13 @@ let do_check_fragile loc casel pss = | ps::_ -> List.iter (fun ext -> - match exhaust (Some ext) pss (List.length ps) with - | No_matching_value -> + let witnesses = exhaust (Some ext) pss (List.length ps) in + match witnesses () with + | Seq.Nil -> Location.prerr_warning loc (Warnings.Fragile_match (Path.name ext)) - | Witnesses _ -> ()) + | Seq.Cons _ -> ()) exts (********************************) @@ -2231,7 +2083,7 @@ let do_check_fragile loc casel pss = (********************************) let check_unused pred casel = - if Warnings.is_active Warnings.Unused_match + if Warnings.is_active Warnings.Redundant_case || List.exists (fun c -> c.c_rhs.exp_desc = Texp_unreachable) casel then let rec do_rec pref = function | [] -> () @@ -2239,7 +2091,11 @@ let check_unused pred casel = let qs = [q] in begin try let pss = - get_mins le_pats (List.filter (compats qs) pref) in + (* prev was accumulated in reverse order; + restore source order to get ordered counter-examples *) + List.rev pref + |> List.filter (compats qs) + |> get_mins le_pats in (* First look for redundant or partially redundant patterns *) let r = every_satisfiables (make_rows pss) (make_row qs) in let refute = (c_rhs.exp_desc = Texp_unreachable) in @@ -2278,12 +2134,12 @@ let check_unused pred casel = match r with | Unused -> Location.prerr_warning - q.pat_loc Warnings.Unused_match + q.pat_loc Warnings.Redundant_case | Upartial ps -> List.iter (fun p -> Location.prerr_warning - p.pat_loc Warnings.Unused_pat) + p.pat_loc Warnings.Redundant_subpat) ps | Used -> () with Empty | Not_found -> assert false @@ -2438,19 +2294,16 @@ type amb_row = { row : pattern list ; varsets : Ident.Set.t list; } let simplify_head_amb_pat head_bound_variables varsets ~add_column p ps k = let rec simpl head_bound_variables varsets p ps k = - match p.pat_desc with - | Tpat_alias (p,x,_) -> + match (Patterns.General.view p).pat_desc with + | `Alias (p,x,_) -> simpl (Ident.Set.add x head_bound_variables) varsets p ps k - | Tpat_var (x,_) -> - let rest_of_the_row = - { row = ps; varsets = Ident.Set.add x head_bound_variables :: varsets; } - in - add_column (Pattern_head.deconstruct omega) rest_of_the_row k - | Tpat_or (p1,p2,_) -> + | `Var (x, _) -> + simpl (Ident.Set.add x head_bound_variables) varsets Patterns.omega ps k + | `Or (p1,p2,_) -> simpl head_bound_variables varsets p1 ps (simpl head_bound_variables varsets p2 ps k) - | _ -> - add_column (Pattern_head.deconstruct p) + | #Patterns.Simple.view as view -> + add_column (Patterns.Head.deconstruct { p with pat_desc = view }) { row = ps; varsets = head_bound_variables :: varsets; } k in simpl head_bound_variables varsets p ps k @@ -2552,7 +2405,7 @@ let rec matrix_stable_vars m = match m with let extend_row columns = function | Negative r -> Negative (columns @ r) | Positive r -> Positive { r with row = columns @ r.row } in - let q0 = discr_pat omega m in + let q0 = discr_pat Patterns.Simple.omega m in let { default; constrs } = build_specialized_submatrices ~extend_row q0 m in let non_default = List.map snd constrs in @@ -2625,7 +2478,7 @@ let all_rhs_idents exp = let check_ambiguous_bindings = let open Warnings in - let warn0 = Ambiguous_pattern [] in + let warn0 = Ambiguous_var_in_pattern_guard [] in fun cases -> if is_active warn0 then let check_case ns case = match case with @@ -2641,7 +2494,7 @@ let check_ambiguous_bindings = if not (Ident.Set.is_empty ambiguous) then begin let pps = Ident.Set.elements ambiguous |> List.map Ident.name in - let warn = Ambiguous_pattern pps in + let warn = Ambiguous_var_in_pattern_guard pps in Location.prerr_warning p.pat_loc warn end end; diff --git a/typing/parmatch.mli b/typing/parmatch.mli index e6952be7..8736ed2e 100644 --- a/typing/parmatch.mli +++ b/typing/parmatch.mli @@ -19,61 +19,6 @@ open Asttypes open Typedtree open Types -val omega : pattern -(** aka. "Tpat_any" or "_" *) - -val omegas : int -> pattern list -(** [List.init (fun _ -> omega)] *) - -val omega_list : 'a list -> pattern list -(** [List.map (fun _ -> omega)] *) - -module Pattern_head : sig - type desc = - | Any - | Construct of constructor_description - | Constant of constant - | Tuple of int - | Record of label_description list - | Variant of - { tag: label; has_arg: bool; - cstr_row: row_desc ref; - type_row : unit -> row_desc; } - (* the row of the type may evolve if [close_variant] is called, - hence the (unit -> ...) delay *) - | Array of int - | Lazy - - type t - - val desc : t -> desc - val env : t -> Env.t - val loc : t -> Location.t - val typ : t -> Types.type_expr - - (** [deconstruct p] returns the head of [p] and the list of sub patterns. - - @raises [Invalid_arg _] if [p] is an or- or an exception-pattern. *) - val deconstruct : pattern -> t * pattern list - - (** reconstructs a pattern, putting wildcards as sub-patterns. *) - val to_omega_pattern : t -> pattern - - val make - : loc:Location.t - -> typ:Types.type_expr - -> env:Env.t - -> desc - -> t - - val omega : t - -end - -val normalize_pat : pattern -> pattern -(** Keep only the "head" of a pattern: all arguments are replaced by [omega], so - are variables. *) - val const_compare : constant -> constant -> int (** [const_compare c1 c2] compares the actual values represented by [c1] and [c2], while simply using [Stdlib.compare] would compare the @@ -122,7 +67,9 @@ val set_args_erase_mutable : pattern -> pattern list -> pattern list val pat_of_constr : pattern -> constructor_description -> pattern val complete_constrs : - pattern -> constructor_tag list -> constructor_description list + constructor_description pattern_data -> + constructor_tag list -> + constructor_description list (** [ppat_of_type] builds an untyped pattern from its expected type, for explosion of wildcard patterns in Typecore.type_pat. diff --git a/typing/patterns.ml b/typing/patterns.ml new file mode 100644 index 00000000..a67ac9d6 --- /dev/null +++ b/typing/patterns.ml @@ -0,0 +1,254 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Gabriel Scherer, projet Partout, INRIA Paris-Saclay *) +(* Thomas Refis, Jane Street Europe *) +(* *) +(* Copyright 2019 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +open Asttypes +open Types +open Typedtree + +(* useful pattern auxiliary functions *) + +let omega = { + pat_desc = Tpat_any; + pat_loc = Location.none; + pat_extra = []; + pat_type = Ctype.none; + pat_env = Env.empty; + pat_attributes = []; +} + +let rec omegas i = + if i <= 0 then [] else omega :: omegas (i-1) + +let omega_list l = List.map (fun _ -> omega) l + +module Non_empty_row = struct + type 'a t = 'a * Typedtree.pattern list + + let of_initial = function + | [] -> assert false + | pat :: patl -> (pat, patl) + + let map_first f (p, patl) = (f p, patl) +end + +(* "views" on patterns are polymorphic variants + that allow to restrict the set of pattern constructors + statically allowed at a particular place *) + +module Simple = struct + type view = [ + | `Any + | `Constant of constant + | `Tuple of pattern list + | `Construct of + Longident.t loc * constructor_description * pattern list + | `Variant of label * pattern option * row_desc ref + | `Record of + (Longident.t loc * label_description * pattern) list * closed_flag + | `Array of pattern list + | `Lazy of pattern + ] + + type pattern = view pattern_data + + let omega = { omega with pat_desc = `Any } +end + +module Half_simple = struct + type view = [ + | Simple.view + | `Or of pattern * pattern * row_desc option + ] + + type pattern = view pattern_data +end + +module General = struct + type view = [ + | Half_simple.view + | `Var of Ident.t * string loc + | `Alias of pattern * Ident.t * string loc + ] + type pattern = view pattern_data + + let view_desc = function + | Tpat_any -> + `Any + | Tpat_var (id, str) -> + `Var (id, str) + | Tpat_alias (p, id, str) -> + `Alias (p, id, str) + | Tpat_constant cst -> + `Constant cst + | Tpat_tuple ps -> + `Tuple ps + | Tpat_construct (cstr, cstr_descr, args) -> + `Construct (cstr, cstr_descr, args) + | Tpat_variant (cstr, arg, row_desc) -> + `Variant (cstr, arg, row_desc) + | Tpat_record (fields, closed) -> + `Record (fields, closed) + | Tpat_array ps -> `Array ps + | Tpat_or (p, q, row_desc) -> `Or (p, q, row_desc) + | Tpat_lazy p -> `Lazy p + + let view p : pattern = + { p with pat_desc = view_desc p.pat_desc } + + let erase_desc = function + | `Any -> Tpat_any + | `Var (id, str) -> Tpat_var (id, str) + | `Alias (p, id, str) -> Tpat_alias (p, id, str) + | `Constant cst -> Tpat_constant cst + | `Tuple ps -> Tpat_tuple ps + | `Construct (cstr, cst_descr, args) -> + Tpat_construct (cstr, cst_descr, args) + | `Variant (cstr, arg, row_desc) -> + Tpat_variant (cstr, arg, row_desc) + | `Record (fields, closed) -> + Tpat_record (fields, closed) + | `Array ps -> Tpat_array ps + | `Or (p, q, row_desc) -> Tpat_or (p, q, row_desc) + | `Lazy p -> Tpat_lazy p + + let erase p : Typedtree.pattern = + { p with pat_desc = erase_desc p.pat_desc } + + let rec strip_vars (p : pattern) : Half_simple.pattern = + match p.pat_desc with + | `Alias (p, _, _) -> strip_vars (view p) + | `Var _ -> { p with pat_desc = `Any } + | #Half_simple.view as view -> { p with pat_desc = view } +end + +(* the head constructor of a simple pattern *) + +module Head : sig + type desc = + | Any + | Construct of constructor_description + | Constant of constant + | Tuple of int + | Record of label_description list + | Variant of + { tag: label; has_arg: bool; + cstr_row: row_desc ref; + type_row : unit -> row_desc; } + | Array of int + | Lazy + + type t = desc pattern_data + + val arity : t -> int + + (** [deconstruct p] returns the head of [p] and the list of sub patterns. *) + val deconstruct : Simple.pattern -> t * pattern list + + (** reconstructs a pattern, putting wildcards as sub-patterns. *) + val to_omega_pattern : t -> pattern + + val omega : t +end = struct + type desc = + | Any + | Construct of constructor_description + | Constant of constant + | Tuple of int + | Record of label_description list + | Variant of + { tag: label; has_arg: bool; + cstr_row: row_desc ref; + type_row : unit -> row_desc; } + (* the row of the type may evolve if [close_variant] is called, + hence the (unit -> ...) delay *) + | Array of int + | Lazy + + type t = desc pattern_data + + let deconstruct (q : Simple.pattern) = + let deconstruct_desc = function + | `Any -> Any, [] + | `Constant c -> Constant c, [] + | `Tuple args -> + Tuple (List.length args), args + | `Construct (_, c, args) -> + Construct c, args + | `Variant (tag, arg, cstr_row) -> + let has_arg, pats = + match arg with + | None -> false, [] + | Some a -> true, [a] + in + let type_row () = + match Ctype.expand_head q.pat_env q.pat_type with + | {desc = Tvariant type_row} -> Btype.row_repr type_row + | _ -> assert false + in + Variant {tag; has_arg; cstr_row; type_row}, pats + | `Array args -> + Array (List.length args), args + | `Record (largs, _) -> + let lbls = List.map (fun (_,lbl,_) -> lbl) largs in + let pats = List.map (fun (_,_,pat) -> pat) largs in + Record lbls, pats + | `Lazy p -> + Lazy, [p] + in + let desc, pats = deconstruct_desc q.pat_desc in + { q with pat_desc = desc }, pats + + let arity t = + match t.pat_desc with + | Any -> 0 + | Constant _ -> 0 + | Construct c -> c.cstr_arity + | Tuple n | Array n -> n + | Record l -> List.length l + | Variant { has_arg; _ } -> if has_arg then 1 else 0 + | Lazy -> 1 + + let to_omega_pattern t = + let pat_desc = + let mkloc x = Location.mkloc x t.pat_loc in + match t.pat_desc with + | Any -> Tpat_any + | Lazy -> Tpat_lazy omega + | Constant c -> Tpat_constant c + | Tuple n -> Tpat_tuple (omegas n) + | Array n -> Tpat_array (omegas n) + | Construct c -> + let lid_loc = mkloc (Longident.Lident c.cstr_name) in + Tpat_construct (lid_loc, c, omegas c.cstr_arity) + | Variant { tag; has_arg; cstr_row } -> + let arg_opt = if has_arg then Some omega else None in + Tpat_variant (tag, arg_opt, cstr_row) + | Record lbls -> + let lst = + List.map (fun lbl -> + let lid_loc = mkloc (Longident.Lident lbl.lbl_name) in + (lid_loc, lbl, omega) + ) lbls + in + Tpat_record (lst, Closed) + in + { t with + pat_desc; + pat_extra = []; + } + + let omega = { omega with pat_desc = Any } +end diff --git a/typing/patterns.mli b/typing/patterns.mli new file mode 100644 index 00000000..66dd2d05 --- /dev/null +++ b/typing/patterns.mli @@ -0,0 +1,109 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Gabriel Scherer, projet Partout, INRIA Paris-Saclay *) +(* Thomas Refis, Jane Street Europe *) +(* *) +(* Copyright 2019 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +open Asttypes +open Typedtree +open Types + +val omega : pattern +(** aka. "Tpat_any" or "_" *) + +val omegas : int -> pattern list +(** [List.init (fun _ -> omega)] *) + +val omega_list : 'a list -> pattern list +(** [List.map (fun _ -> omega)] *) + +module Non_empty_row : sig + type 'a t = 'a * Typedtree.pattern list + + val of_initial : Typedtree.pattern list -> Typedtree.pattern t + (** 'assert false' on empty rows *) + + val map_first : ('a -> 'b) -> 'a t -> 'b t +end + +module Simple : sig + type view = [ + | `Any + | `Constant of constant + | `Tuple of pattern list + | `Construct of + Longident.t loc * constructor_description * pattern list + | `Variant of label * pattern option * row_desc ref + | `Record of + (Longident.t loc * label_description * pattern) list * closed_flag + | `Array of pattern list + | `Lazy of pattern + ] + type pattern = view pattern_data + + val omega : [> view ] pattern_data +end + +module Half_simple : sig + type view = [ + | Simple.view + | `Or of pattern * pattern * row_desc option + ] + type pattern = view pattern_data +end + +module General : sig + type view = [ + | Half_simple.view + | `Var of Ident.t * string loc + | `Alias of pattern * Ident.t * string loc + ] + type pattern = view pattern_data + + val view : Typedtree.pattern -> pattern + val erase : [< view ] pattern_data -> Typedtree.pattern + + val strip_vars : pattern -> Half_simple.pattern +end + +module Head : sig + type desc = + | Any + | Construct of constructor_description + | Constant of constant + | Tuple of int + | Record of label_description list + | Variant of + { tag: label; has_arg: bool; + cstr_row: row_desc ref; + type_row : unit -> row_desc; } + (* the row of the type may evolve if [close_variant] is called, + hence the (unit -> ...) delay *) + | Array of int + | Lazy + + type t = desc pattern_data + + val arity : t -> int + + (** [deconstruct p] returns the head of [p] and the list of sub patterns. + + @raise [Invalid_arg _] if [p] is an or- or an exception-pattern. *) + val deconstruct : Simple.pattern -> t * pattern list + + (** reconstructs a pattern, putting wildcards as sub-patterns. *) + val to_omega_pattern : t -> pattern + + val omega : t + +end diff --git a/typing/printtyp.ml b/typing/printtyp.ml index 5cdd914f..9e32969a 100644 --- a/typing/printtyp.ml +++ b/typing/printtyp.ml @@ -490,8 +490,8 @@ let rec raw_type ppf ty = let ty = safe_repr [] ty in if List.memq ty !visited then fprintf ppf "{id=%d}" ty.id else begin visited := ty :: !visited; - fprintf ppf "@[<1>{id=%d;level=%d;desc=@,%a}@]" ty.id ty.level - raw_type_desc ty.desc + fprintf ppf "@[<1>{id=%d;level=%d;scope=%d;desc=@,%a}@]" ty.id ty.level + ty.scope raw_type_desc ty.desc end and raw_type_list tl = raw_list raw_type tl and raw_type_desc ppf = function @@ -591,11 +591,25 @@ let apply_subst s1 tyl = type best_path = Paths of Path.t list | Best of Path.t -let printing_depth = ref 0 -let printing_cont = ref ([] : Env.iter_cont list) +(** Short-paths cache: the five mutable variables below implement a one-slot + cache for short-paths + *) let printing_old = ref Env.empty let printing_pers = ref Concr.empty +(** {!printing_old} and {!printing_pers} are the keys of the one-slot cache *) + +let printing_depth = ref 0 +let printing_cont = ref ([] : Env.iter_cont list) let printing_map = ref Path.Map.empty +(** + - {!printing_map} is the main value stored in the cache. + Note that it is evaluated lazily and its value is updated during printing. + - {!printing_dep} is the current exploration depth of the environment, + it is used to determine whenever the {!printing_map} should be evaluated + further before completing a request. + - {!printing_cont} is the list of continuations needed to evaluate + the {!printing_map} one level further (see also {!Env.run_iter_cont}) +*) let same_type t t' = repr t == repr t' @@ -909,7 +923,7 @@ let rec mark_loops_rec visited ty = | Tunivar _ -> add_named_var ty let mark_loops ty = - normalize_type Env.empty ty; + normalize_type ty; mark_loops_rec [] ty;; let reset_loop_marks () = @@ -1229,8 +1243,20 @@ let rec tree_of_type_decl id decl = let vari = List.map2 (fun ty v -> - if abstr || not (is_Tvar (repr ty)) then Variance.get_upper v - else (true,true)) + let is_var = is_Tvar (repr ty) in + if abstr || not is_var then + let inj = + decl.type_kind = Type_abstract && Variance.mem Inj v && + match decl.type_manifest with + | None -> true + | Some ty -> (* only abstract or private row types *) + decl.type_private = Private && + Btype.is_constr_row ~allow_ident:true (Btype.row_of_type ty) + and (co, cn) = Variance.get_upper v in + (if not cn then Covariant else + if not co then Contravariant else NoVariance), + (if inj then Injective else NoInjectivity) + else (NoVariance, NoInjectivity)) decl.type_params decl.type_variance in (Ident.name id, @@ -1503,10 +1529,15 @@ let tree_of_class_param param variance = (match tree_of_typexp true param with Otyp_var (_, s) -> s | _ -> "?"), - if is_Tvar (repr param) then (true, true) else variance + if is_Tvar (repr param) then Asttypes.(NoVariance, NoInjectivity) + else variance let class_variance = - List.map Variance.(fun v -> mem May_pos v, mem May_neg v) + let open Variance in let open Asttypes in + List.map (fun v -> + (if not (mem May_pos v) then Contravariant else + if not (mem May_neg v) then Covariant else NoVariance), + NoInjectivity) let tree_of_class_declaration id cl rs = let params = filter_params cl.cty_params in @@ -1566,9 +1597,28 @@ let cltype_declaration id ppf cl = (* Print a module type *) let wrap_env fenv ftree arg = + (* We save the current value of the short-path cache *) + (* From keys *) let env = !printing_env in + let old_pers = !printing_pers in + (* to data *) + let old_map = !printing_map in + let old_depth = !printing_depth in + let old_cont = !printing_cont in set_printing_env (fenv env); let tree = ftree arg in + if !Clflags.real_paths + || same_printing_env env then () + (* our cached key is still live in the cache, and we want to keep all + progress made on the computation of the [printing_map] *) + else begin + (* we restore the snapshotted cache before calling set_printing_env *) + printing_old := env; + printing_pers := old_pers; + printing_depth := old_depth; + printing_cont := old_cont; + printing_map := old_map + end; set_printing_env env; tree @@ -2041,8 +2091,19 @@ let explanation intro prev env = function | Trace.Obj o -> explain_object o | Trace.Rec_occur(x,y) -> reset_and_mark_loops y; - Some(dprintf "@,@[The type variable %a occurs inside@ %a@]" - marked_type_expr x marked_type_expr y) + begin match x.desc with + | Tvar _ | Tunivar _ -> + Some(dprintf "@,@[The type variable %a occurs inside@ %a@]" + marked_type_expr x marked_type_expr y) + | _ -> + (* We had a delayed unification of the type variable with + a non-variable after the occur check. *) + Some ignore + (* There is no need to search further for an explanation, but + we don't want to print a message of the form: + {[ The type int occurs inside int list -> 'a |} + *) + end let mismatch intro env trace = Trace.explain trace (fun ~prev h -> explanation intro prev env h) diff --git a/typing/subst.ml b/typing/subst.ml index 9d209b2f..9ad1ecb5 100644 --- a/typing/subst.ml +++ b/typing/subst.ml @@ -20,6 +20,8 @@ open Path open Types open Btype +open Local_store + type type_replacement = | Path of Path.t | Type_function of { params : type_expr list; body : type_expr } @@ -124,7 +126,7 @@ let to_subst_by_type_function s p = (* Special type ids for saved signatures *) -let new_id = ref (-1) +let new_id = s_ref (-1) let reset_for_saving () = new_id := -1 let newpersty desc = diff --git a/typing/typeclass.ml b/typing/typeclass.ml index 31d4bc89..12dec437 100644 --- a/typing/typeclass.ml +++ b/typing/typeclass.ml @@ -1049,8 +1049,9 @@ and class_expr_aux cl_num val_env met_env scl = end pv in - let not_function = function - Cty_arrow _ -> false + let rec not_nolabel_function = function + | Cty_arrow(Nolabel, _, _) -> false + | Cty_arrow(_, _, cty) -> not_nolabel_function cty | _ -> true in let partial = @@ -1061,7 +1062,7 @@ and class_expr_aux cl_num val_env met_env scl = Ctype.raise_nongen_level (); let cl = class_expr cl_num val_env' met_env scl' in Ctype.end_def (); - if Btype.is_optional l && not_function cl.cl_type then + if Btype.is_optional l && not_nolabel_function cl.cl_type then Location.prerr_warning pat.pat_loc Warnings.Unerasable_optional_argument; rc {cl_desc = Tcl_fun (l, pat, pv, cl, partial); @@ -1180,7 +1181,7 @@ and class_expr_aux cl_num val_env met_env scl = } | Pcl_let (rec_flag, sdefs, scl') -> let (defs, val_env) = - Typecore.type_let In_class_def val_env rec_flag sdefs None in + Typecore.type_let In_class_def val_env rec_flag sdefs in let (vals, met_env) = List.fold_right (fun (id, _id_loc, _typ) (vals, met_env) -> @@ -1310,7 +1311,7 @@ let temp_abbrev loc env id arity uid = type_kind = Type_abstract; type_private = Public; type_manifest = Some ty; - type_variance = Misc.replicate_list Variance.full arity; + type_variance = Variance.unknown_signature ~injective:false ~arity; type_separability = Types.Separability.default_signature ~arity; type_is_newtype = false; type_expansion_scope = Btype.lowest_level; @@ -1488,7 +1489,8 @@ let class_infos define_class kind end; (* Class and class type temporary definitions *) - let cty_variance = List.map (fun _ -> Variance.full) params in + let cty_variance = + Variance.unknown_signature ~injective:false ~arity:(List.length params) in let cltydef = {clty_params = params; clty_type = class_body typ; clty_variance = cty_variance; @@ -1570,7 +1572,7 @@ let class_infos define_class kind type_kind = Type_abstract; type_private = Public; type_manifest = Some obj_ty; - type_variance = List.map (fun _ -> Variance.full) obj_params; + type_variance = Variance.unknown_signature ~injective:false ~arity; type_separability = Types.Separability.default_signature ~arity; type_is_newtype = false; type_expansion_scope = Btype.lowest_level; @@ -1594,7 +1596,7 @@ let class_infos define_class kind type_kind = Type_abstract; type_private = Public; type_manifest = Some cl_ty; - type_variance = List.map (fun _ -> Variance.full) cl_params; + type_variance = Variance.unknown_signature ~injective:false ~arity; type_separability = Types.Separability.default_signature ~arity; type_is_newtype = false; type_expansion_scope = Btype.lowest_level; diff --git a/typing/typecore.ml b/typing/typecore.ml index 4b2ce97c..2c17714a 100644 --- a/typing/typecore.ml +++ b/typing/typecore.ml @@ -302,19 +302,27 @@ let get_gadt_equations_level () = Some y -> y | None -> assert false +let nothing_equated = TypePairs.create 0 + (* unification inside type_pat*) -let unify_pat_types ?(refine=false) loc env ty ty' = +let unify_pat_types_return_equated_pairs ?(refine = None) loc env ty ty' = try - if refine then - unify_gadt ~equations_level:(get_gadt_equations_level ()) env ty ty' - else - unify !env ty ty' + match refine with + | Some allow_recursive -> + unify_gadt ~equations_level:(get_gadt_equations_level ()) + ~allow_recursive env ty ty' + | None -> + unify !env ty ty'; + nothing_equated with | Unify trace -> raise(Error(loc, !env, Pattern_type_clash(trace, None))) | Tags(l1,l2) -> raise(Typetexp.Error(loc, !env, Typetexp.Variant_tags (l1, l2))) +let unify_pat_types ?refine loc env ty ty' = + ignore (unify_pat_types_return_equated_pairs ?refine loc env ty ty') + let unify_pat ?refine env pat expected_ty = try unify_pat_types ?refine pat.pat_loc env pat.pat_type expected_ty with Error (loc, env, Pattern_type_clash(trace, None)) -> @@ -375,13 +383,11 @@ type module_variable = let pattern_variables = ref ([] : pattern_variable list) let pattern_force = ref ([] : (unit -> unit) list) -let pattern_scope = ref (None : Annot.ident option);; let allow_modules = ref false let module_variables = ref ([] : module_variable list) -let reset_pattern scope allow = +let reset_pattern allow = pattern_variables := []; pattern_force := []; - pattern_scope := scope; allow_modules := allow; module_variables := []; ;; @@ -458,6 +464,22 @@ let enter_orpat_variables loc env p1_vs p2_vs = unify_vars p1_vs p2_vs let rec build_as_type env p = + let as_ty = build_as_type_aux env p in + (* Cf. #1655 *) + List.fold_left (fun as_ty (extra, _loc, _attrs) -> + match extra with + | Tpat_type _ | Tpat_open _ | Tpat_unpack -> as_ty + | Tpat_constraint cty -> + begin_def (); + let ty = instance cty.ctyp_type in + end_def (); + generalize_structure ty; + (* This call to unify can't fail since the pattern is well typed. *) + unify !env (instance as_ty) (instance ty); + ty + ) as_ty p.pat_extra + +and build_as_type_aux env p = match p.pat_desc with Tpat_alias(p1,_, _) -> build_as_type env p1 | Tpat_tuple pl -> @@ -964,7 +986,7 @@ let check_recordpat_labels loc lbl_pat_list closed = else defined.(label.lbl_pos) <- true in List.iter check_defined lbl_pat_list; if closed = Closed - && Warnings.is_active (Warnings.Non_closed_record_pattern "") + && Warnings.is_active (Warnings.Missing_record_field_pattern "") then begin let undefined = ref [] in for i = 0 to Array.length all - 1 do @@ -972,7 +994,7 @@ let check_recordpat_labels loc lbl_pat_list closed = done; if !undefined <> [] then begin let u = String.concat ", " (List.rev !undefined) in - Location.prerr_warning loc (Warnings.Non_closed_record_pattern u) + Location.prerr_warning loc (Warnings.Missing_record_field_pattern u) end end @@ -1317,7 +1339,8 @@ and type_pat_aux type_pat category ~no_existentials ~mode ~env in let loc = sp.ppat_loc in - let refine = match mode with Normal -> false | Counter_example _ -> true in + let refine = + match mode with Normal -> None | Counter_example _ -> Some true in let unif (x : pattern) : pattern = unify_pat ~refine env x (instance expected_ty); x @@ -1411,16 +1434,15 @@ and type_pat_aux ({ptyp_desc=Ptyp_poly _} as sty)) -> (* explicitly polymorphic type *) assert construction_not_used_in_counterexamples; - let cty, force = Typetexp.transl_simple_type_delayed !env sty in - let ty = cty.ctyp_type in + let cty, ty, force = Typetexp.transl_simple_type_delayed !env sty in unify_pat_types ~refine lloc env ty (instance expected_ty); pattern_force := force :: !pattern_force; begin match ty.desc with | Tpoly (body, tyl) -> begin_def (); + init_def generic_level; let _, ty' = instance_poly ~keep_names:true false tyl body in end_def (); - generalize ty'; let id = enter_variable lloc name ty' attrs in rvp k { pat_desc = Tpat_var (id, name); @@ -1476,10 +1498,7 @@ and type_pat_aux assert (List.length spl >= 2); let spl_ann = List.map (fun p -> (p,newgenvar ())) spl in let ty = newgenty (Ttuple(List.map snd spl_ann)) in - begin_def (); - let expected_ty = instance expected_ty in - end_def (); - generalize_structure expected_ty; + let expected_ty = generic_instance expected_ty in unify_pat_types ~refine loc env ty expected_ty; map_fold_cont (fun (p,t) -> type_pat Value p t) spl_ann (fun pl -> rvp k { @@ -1492,7 +1511,10 @@ and type_pat_aux let expected_type = try let (p0, p, _) = extract_concrete_variant !env expected_ty in - Some (p0, p, true) + let principal = + (repr expected_ty).level = generic_level || not !Clflags.principal + in + Some (p0, p, principal) with Not_found -> None in let constr = @@ -1551,12 +1573,38 @@ and type_pat_aux in let expected_ty = instance expected_ty in (* PR#7214: do not use gadt unification for toplevel lets *) - unify_pat_types loc env ty_res expected_ty - ~refine:(refine || constr.cstr_generalized && no_existentials = None); + let refine = + if refine = None && constr.cstr_generalized && no_existentials = None + then Some false + else refine + in + let equated_types = + unify_pat_types_return_equated_pairs ~refine loc env ty_res expected_ty + in end_def (); generalize_structure expected_ty; generalize_structure ty_res; List.iter generalize_structure ty_args; + if !Clflags.principal then ( + let exception Warn_only_once in + try + TypePairs.iter (fun (t1, t2) () -> + generalize_structure t1; + generalize_structure t2; + if not (fully_generic t1 && fully_generic t2) then + let msg = + Format.asprintf + "typing this pattern requires considering@ %a@ and@ %a@ as \ + equal.@,\ + But the knowledge of these types" + Printtyp.type_expr t1 + Printtyp.type_expr t2 + in + Location.prerr_warning loc (Warnings.Not_principal msg); + raise Warn_only_once + ) equated_types + with Warn_only_once -> () + ); let rec check_non_escaping p = match p.ppat_desc with @@ -1591,10 +1639,7 @@ and type_pat_aux row_more = newgenvar (); row_fixed = None; row_name = None } in - begin_def (); - let expected_ty = instance expected_ty in - end_def (); - generalize_structure expected_ty; + let expected_ty = generic_instance expected_ty in (* PR#7404: allow some_private_tag blindly, as it would not unify with the abstract row variable *) if l = Parmatch.some_private_tag @@ -1618,11 +1663,11 @@ and type_pat_aux let expected_type, record_ty = try let (p0, p,_) = extract_concrete_record !env expected_ty in - begin_def (); - let ty = instance expected_ty in - end_def (); - generalize_structure ty; - Some (p0, p, true), ty + let ty = generic_instance expected_ty in + let principal = + (repr expected_ty).level = generic_level || not !Clflags.principal + in + Some (p0, p, principal), ty with Not_found -> None, newvar () in let type_label_pat (label_lid, label, sarg) k = @@ -1664,10 +1709,7 @@ and type_pat_aux end | Ppat_array spl -> let ty_elt = newgenvar() in - begin_def (); - let expected_ty = instance expected_ty in - end_def (); - generalize_structure expected_ty; + let expected_ty = generic_instance expected_ty in unify_pat_types ~refine loc env (Predef.type_array ty_elt) expected_ty; map_fold_cont (fun p -> type_pat Value p ty_elt) spl (fun pl -> @@ -1757,7 +1799,8 @@ and type_pat_aux end | Ppat_lazy sp1 -> let nv = newgenvar () in - unify_pat_types ~refine loc env (Predef.type_lazy_t nv) expected_ty; + unify_pat_types ~refine loc env (Predef.type_lazy_t nv) + (generic_instance expected_ty); (* do not explode under lazy: PR#7421 *) type_pat Value ~mode:(no_explosion mode) sp1 nv (fun p1 -> rvp k { @@ -1769,8 +1812,7 @@ and type_pat_aux | Ppat_constraint(sp, sty) -> (* Pretend separate = true *) begin_def(); - let cty, force = Typetexp.transl_simple_type_delayed !env sty in - let ty = cty.ctyp_type in + let cty, ty, force = Typetexp.transl_simple_type_delayed !env sty in end_def(); generalize_structure ty; let ty, expected_ty' = instance ty, ty in @@ -1825,11 +1867,8 @@ and type_pat_aux let type_pat category ?no_existentials ?(mode=Normal) ?(lev=get_current_level()) env sp expected_ty = Misc.protect_refs [Misc.R (gadt_equations_level, Some lev)] (fun () -> - let r = type_pat category ~no_existentials ~mode ~env sp expected_ty (fun x -> x) - in - map_general_pattern { f = fun p -> { p with pat_env = !env } } r ) (* this function is passed to Partial.parmatch @@ -1845,7 +1884,7 @@ let partial_pred ~lev ~splitting_mode ?(explode=0) constrs; labels; } in try - reset_pattern None true; + reset_pattern true; let typed_p = type_pat Value ~lev ~mode env p expected_ty in set_state state env; (* types are invalidated but we don't need them here *) @@ -1887,8 +1926,8 @@ let add_pattern_variables ?check ?check_as env pv = ) pv env -let type_pattern category ~lev env spat scope expected_ty = - reset_pattern scope true; +let type_pattern category ~lev env spat expected_ty = + reset_pattern true; let new_env = ref env in let pat = type_pat category ~lev new_env spat expected_ty in let pvs = get_ref pattern_variables in @@ -1896,9 +1935,9 @@ let type_pattern category ~lev env spat scope expected_ty = (pat, !new_env, get_ref pattern_force, pvs, unpacks) let type_pattern_list - category no_existentials env spatl scope expected_tys allow + category no_existentials env spatl expected_tys allow = - reset_pattern scope allow; + reset_pattern allow; let new_env = ref env in let type_pat (attrs, pat) ty = Builtin_attributes.warning_scope ~ppwarning:false attrs @@ -1917,7 +1956,7 @@ let type_pattern_list (patl, new_env, get_ref pattern_force, pvs, unpacks) let type_class_arg_pattern cl_num val_env met_env l spat = - reset_pattern None false; + reset_pattern false; let nv = newvar () in let pat = type_pat Value ~no_existentials:In_class_args (ref val_env) spat nv in @@ -1967,7 +2006,7 @@ let type_self_pattern cl_num privty val_env met_env par_env spat = Pat.mk (Ppat_alias (Pat.mk(Ppat_alias (spat, mknoloc "selfpat-*")), mknoloc ("selfpat-" ^ cl_num))) in - reset_pattern None false; + reset_pattern false; let nv = newvar() in let pat = type_pat Value ~no_existentials:In_self_pattern (ref val_env) spat nv in @@ -2312,7 +2351,7 @@ let check_partial_application statement exp = | Some (_, loc, _) -> loc | None -> exp_loc in - Location.prerr_warning loc Warnings.Statement_type + Location.prerr_warning loc Warnings.Non_unit_statement in loop exp in @@ -2343,7 +2382,8 @@ let check_partial_application statement exp = | Texp_letexception (_, e) | Texp_letmodule (_, _, _, _, e) -> check e | Texp_apply _ | Texp_send _ | Texp_new _ | Texp_letop _ -> - Location.prerr_warning exp_loc Warnings.Partial_application + Location.prerr_warning exp_loc + Warnings.Ignored_partial_application end in check exp @@ -2632,14 +2672,8 @@ and type_expect_ if rec_flag = Recursive then In_rec else if List.compare_length_with spat_sexp_list 1 > 0 then In_group else With_attributes in - let scp = - match sexp.pexp_attributes, rec_flag with - | [{attr_name = {txt="#default"}; _}], _ -> None - | _, Recursive -> Some (Annot.Idef loc) - | _, Nonrecursive -> Some (Annot.Idef sbody.pexp_loc) - in let (pat_exp_list, new_env, unpacks) = - type_let existential_context env rec_flag spat_sexp_list scp true in + type_let existential_context env rec_flag spat_sexp_list true in let body = type_unpacks new_env unpacks sbody ty_expected_explained in let () = if rec_flag = Recursive then @@ -2718,12 +2752,18 @@ and type_expect_ let (args, ty_res) = type_application env funct sargs in end_def (); unify_var env (newvar()) funct.exp_type; - rue { - exp_desc = Texp_apply(funct, args); - exp_loc = loc; exp_extra = []; - exp_type = ty_res; - exp_attributes = sexp.pexp_attributes; - exp_env = env } + let exp = + { exp_desc = Texp_apply(funct, args); + exp_loc = loc; exp_extra = []; + exp_type = ty_res; + exp_attributes = sexp.pexp_attributes; + exp_env = env } in + begin + try rue exp + with Error (_, _, Expr_type_clash _) as err -> + Misc.reraise_preserving_backtrace err (fun () -> + check_partial_application false exp) + end | Pexp_match(sarg, caselist) -> begin_def (); let arg = type_exp env sarg in @@ -2731,7 +2771,8 @@ and type_expect_ if maybe_expansive arg then lower_contravariant env arg.exp_type; generalize arg.exp_type; let cases, partial = - type_cases Computation env arg.exp_type ty_expected true loc caselist in + type_cases Computation env + arg.exp_type ty_expected_explained true loc caselist in re { exp_desc = Texp_match(arg, cases, partial); exp_loc = loc; exp_extra = []; @@ -2741,7 +2782,8 @@ and type_expect_ | Pexp_try(sbody, caselist) -> let body = type_expect env sbody ty_expected_explained in let cases, _ = - type_cases Value env Predef.type_exn ty_expected false loc caselist in + type_cases Value env + Predef.type_exn ty_expected_explained false loc caselist in re { exp_desc = Texp_try(body, cases); exp_loc = loc; exp_extra = []; @@ -2753,7 +2795,7 @@ and type_expect_ let subtypes = List.map (fun _ -> newgenvar ()) sexpl in let to_unify = newgenty (Ttuple subtypes) in with_explanation (fun () -> - unify_exp_types loc env to_unify ty_expected); + unify_exp_types loc env to_unify (generic_instance ty_expected)); let expl = List.map2 (fun body ty -> type_expect env body (mk_expected ty)) sexpl subtypes @@ -2825,23 +2867,26 @@ and type_expect_ Some (p0, p, principal) with Not_found -> None in - match get_path ty_expected with - None -> + let opath = get_path ty_expected in + match opath with + None | Some (_, _, false) -> + let ty = if opath = None then newvar () else ty_expected in begin match opt_exp with - None -> newvar (), None + None -> ty, opath | Some exp -> match get_path exp.exp_type with - None -> newvar (), None - | Some (_, p', _) as op -> + None -> + ty, opath + | Some (_, p', _) as opath -> let decl = Env.find_type p' env in begin_def (); let ty = newconstr p' (instance_list decl.type_params) in end_def (); generalize_structure ty; - ty, op + ty, opath end - | op -> ty_expected, op + | _ -> ty_expected, opath in let closed = (opt_sexp = None) in let lbl_exp_list = @@ -2853,7 +2898,7 @@ and type_expect_ (fun x -> x) in with_explanation (fun () -> - unify_exp_types loc env ty_record (instance ty_expected)); + unify_exp_types loc env (instance ty_record) (instance ty_expected)); (* type_label_a_list returns a list of labels sorted by lbl_pos *) (* note: check_duplicates would better be implemented in @@ -2969,7 +3014,7 @@ and type_expect_ let ty = newgenvar() in let to_unify = Predef.type_array ty in with_explanation (fun () -> - unify_exp_types loc env to_unify ty_expected); + unify_exp_types loc env to_unify (generic_instance ty_expected)); let argl = List.map (fun sarg -> type_expect env sarg (mk_expected ty)) sargl in re { @@ -3074,10 +3119,9 @@ and type_expect_ let (arg, ty',cty,cty') = match sty with | None -> - let (cty', force) = + let (cty', ty', force) = Typetexp.transl_simple_type_delayed env sty' in - let ty' = cty'.ctyp_type in begin_def (); let arg = type_exp env sarg in end_def (); @@ -3121,13 +3165,11 @@ and type_expect_ (arg, ty', None, cty') | Some sty -> begin_def (); - let (cty, force) = + let (cty, ty, force) = Typetexp.transl_simple_type_delayed env sty - and (cty', force') = + and (cty', ty', force') = Typetexp.transl_simple_type_delayed env sty' in - let ty = cty.ctyp_type in - let ty' = cty'.ctyp_type in begin try let force'' = subtype env ty ty' in force (); force' (); force'' () @@ -3416,7 +3458,7 @@ and type_expect_ let ty = newgenvar () in let to_unify = Predef.type_lazy_t ty in with_explanation (fun () -> - unify_exp_types loc env to_unify ty_expected); + unify_exp_types loc env to_unify (generic_instance ty_expected)); let arg = type_expect env e (mk_expected ty) in re { exp_desc = Texp_lazy arg; @@ -3555,9 +3597,13 @@ and type_expect_ exp_attributes = sexp.pexp_attributes; exp_env = env } | Pexp_open (od, e) -> + let tv = newvar () in let (od, _, newenv) = !type_open_decl env od in let exp = type_expect newenv e ty_expected_explained in - rue { + (* Force the return type to be well-formed in the original + environment. *) + unify_var newenv tv exp.exp_type; + re { exp_desc = Texp_open (od, exp); exp_type = exp.exp_type; exp_loc = loc; @@ -3604,7 +3650,8 @@ and type_expect_ let exp, ands = type_andops env slet.pbop_exp sands ty_andops in let scase = Ast_helper.Exp.case spat_params sbody in let cases, partial = - type_cases Value env ty_params ty_func_result true loc [scase] + type_cases Value env + ty_params (mk_expected ty_func_result) true loc [scase] in let body = match cases with @@ -3735,13 +3782,13 @@ and type_function ?in_function loc attrs env ty_expected_explained l caselist = generalize_structure ty_res end; let cases, partial = - type_cases Value ~in_function:(loc_fun,ty_fun) env ty_arg ty_res - true loc caselist in - let not_function ty = + type_cases Value ~in_function:(loc_fun,ty_fun) env + ty_arg (mk_expected ty_res) true loc caselist in + let not_nolabel_function ty = let ls, tvar = list_labels env ty in - ls = [] && not tvar + List.for_all ((<>) Nolabel) ls && not tvar in - if is_optional l && not_function ty_res then + if is_optional l && not_nolabel_function ty_res then Location.prerr_warning (List.hd cases).c_lhs.pat_loc Warnings.Unerasable_optional_argument; let param = name_cases "param" cases in @@ -4162,7 +4209,7 @@ and type_argument ?explanation ?recarg env sarg ty_expected' ty_expected = (Warnings.Eliminated_optional_arguments (List.map (fun (l, _) -> Printtyp.string_of_label l) args)); if warn then Location.prerr_warning texp.exp_loc - (Warnings.Without_principality "eliminated optional argument"); + (Warnings.Non_principal_labels "eliminated optional argument"); (* let-expand to have side effects *) let let_pat, let_var = var_pair "arg" texp.exp_type in re { texp with exp_type = ty_fun; exp_desc = @@ -4200,7 +4247,8 @@ and type_application env funct sargs = if ty_fun.level >= t1.level && not (is_prim ~name:"%identity" funct) then - Location.prerr_warning sarg.pexp_loc Warnings.Unused_argument; + Location.prerr_warning sarg.pexp_loc + Warnings.Ignored_extra_argument; unify env ty_fun (newty (Tarrow(lbl,t1,t2,Clink(ref Cunknown)))); (t1, t2) | Tarrow (l,t1,t2,_) when l = lbl @@ -4278,7 +4326,7 @@ and type_application env funct sargs = in let eliminate_optional_arg () = may_warn funct.exp_loc - (Warnings.Without_principality "eliminated optional argument"); + (Warnings.Non_principal_labels "eliminated optional argument"); eliminated_optional_arguments := (l,ty,lv) :: !eliminated_optional_arguments; Some (fun () -> option_none env (instance ty) Location.none) @@ -4323,7 +4371,7 @@ and type_application env funct sargs = (* No argument was given for this parameter, we abstract over it. *) may_warn funct.exp_loc - (Warnings.Without_principality "commuted an argument"); + (Warnings.Non_principal_labels "commuted an argument"); omitted_parameters := (l,ty,lv) :: !omitted_parameters; None end @@ -4527,8 +4575,10 @@ and type_cases : type k . k pattern_category -> ?in_function:_ -> _ -> _ -> _ -> _ -> _ -> Parsetree.case list -> k case list * partial - = fun category ?in_function env ty_arg ty_res partial_flag loc caselist -> + = fun category ?in_function env + ty_arg ty_res_explained partial_flag loc caselist -> (* ty_arg is _fully_ generalized *) + let { ty = ty_res; explanation } = ty_res_explained in let patterns = List.map (fun {pc_lhs=p} -> p) caselist in let contains_polyvars = List.exists contains_polymorphic_variant patterns in let erase_either = contains_polyvars && contains_variant_either ty_arg in @@ -4554,7 +4604,7 @@ and type_cases get_current_level () in let take_partial_instance = - if !Clflags.principal || erase_either + if erase_either then Some false else None in begin_def (); (* propagation of the argument *) @@ -4563,21 +4613,14 @@ and type_cases Printtyp.raw_type_expr ty_arg; *) let half_typed_cases = List.map - (fun ({pc_lhs; pc_guard; pc_rhs} as case) -> - let loc = - let open Location in - match pc_guard with - | None -> pc_rhs.pexp_loc - | Some g -> {pc_rhs.pexp_loc with loc_start=g.pexp_loc.loc_start} - in + (fun ({pc_lhs; pc_guard = _; pc_rhs = _} as case) -> if !Clflags.principal then begin_def (); (* propagation of pattern *) - let scope = Some (Annot.Idef loc) in begin_def (); let ty_arg = instance ?partial:take_partial_instance ty_arg in end_def (); generalize_structure ty_arg; let (pat, ext_env, force, pvs, unpacks) = - type_pattern category ~lev env pc_lhs scope ty_arg + type_pattern category ~lev env pc_lhs ty_arg in pattern_force := force @ !pattern_force; let pat = @@ -4664,14 +4707,9 @@ and type_cases generalize_structure ty; ty end else if contains_gadt then - (* Even though we've already done that, apparently we need to do it - again. - stdlib/camlinternalFormat.ml:2288 is an example of use of this - call to [correct_levels]... *) + (* allow propagation from preceding branches *) correct_levels ty_res else ty_res in -(* Format.printf "@[%i %i, ty_res' =@ %a@]@." lev (get_current_level()) - Printtyp.raw_type_expr ty_res'; *) let guard = match pc_guard with | None -> None @@ -4681,7 +4719,8 @@ and type_cases (mk_expected ~explanation:When_guard Predef.type_bool)) in let exp = - type_unpacks ?in_function ext_env unpacks pc_rhs (mk_expected ty_res') + type_unpacks ?in_function ext_env + unpacks pc_rhs (mk_expected ?explanation ty_res') in { c_lhs = pat; @@ -4743,7 +4782,7 @@ and type_let ?(check = fun s -> Warnings.Unused_var s) ?(check_strict = fun s -> Warnings.Unused_var_strict s) existential_context - env rec_flag spat_sexp_list scope allow = + env rec_flag spat_sexp_list allow = let open Ast_helper in begin_def(); if !Clflags.principal then begin_def (); @@ -4776,7 +4815,7 @@ and type_let spat_sexp_list in let nvs = List.map (fun _ -> newvar ()) spatl in let (pat_list, new_env, force, pvs, unpacks) = - type_pattern_list Value existential_context env spatl scope nvs allow in + type_pattern_list Value existential_context env spatl nvs allow in let attrs_list = List.map fst spatl in let is_recursive = (rec_flag = Recursive) in (* If recursive, first unify with an approximation of the expression *) @@ -5052,20 +5091,20 @@ and type_andops env sarg sands expected_ty = (* Typing of toplevel bindings *) -let type_binding env rec_flag spat_sexp_list scope = +let type_binding env rec_flag spat_sexp_list = Typetexp.reset_type_variables(); let (pat_exp_list, new_env, _unpacks) = type_let ~check:(fun s -> Warnings.Unused_value_declaration s) ~check_strict:(fun s -> Warnings.Unused_value_declaration s) At_toplevel - env rec_flag spat_sexp_list scope false + env rec_flag spat_sexp_list false in (pat_exp_list, new_env) -let type_let existential_ctx env rec_flag spat_sexp_list scope = +let type_let existential_ctx env rec_flag spat_sexp_list = let (pat_exp_list, new_env, _unpacks) = - type_let existential_ctx env rec_flag spat_sexp_list scope false in + type_let existential_ctx env rec_flag spat_sexp_list false in (pat_exp_list, new_env) (* Typing of toplevel expressions *) diff --git a/typing/typecore.mli b/typing/typecore.mli index 2c8d177e..bfaab734 100644 --- a/typing/typecore.mli +++ b/typing/typecore.mli @@ -80,12 +80,10 @@ type existential_restriction = val type_binding: Env.t -> rec_flag -> Parsetree.value_binding list -> - Annot.ident option -> Typedtree.value_binding list * Env.t val type_let: existential_restriction -> Env.t -> rec_flag -> Parsetree.value_binding list -> - Annot.ident option -> Typedtree.value_binding list * Env.t val type_expression: Env.t -> Parsetree.expression -> Typedtree.expression diff --git a/typing/typedecl.ml b/typing/typedecl.ml index e9e0cfa6..b9bb0746 100644 --- a/typing/typedecl.ml +++ b/typing/typedecl.ml @@ -114,7 +114,7 @@ let enter_type rec_flag env sdecl (id, uid) = type_manifest = begin match sdecl.ptype_manifest with None -> None | Some _ -> Some(Ctype.newvar ()) end; - type_variance = List.map (fun _ -> Variance.full) sdecl.ptype_params; + type_variance = Variance.unknown_signature ~injective:false ~arity; type_separability = Types.Separability.default_signature ~arity; type_is_newtype = false; type_expansion_scope = Btype.lowest_level; @@ -403,7 +403,7 @@ let transl_declaration env sdecl (id, uid) = type_kind = kind; type_private = sdecl.ptype_private; type_manifest = man; - type_variance = List.map (fun _ -> Variance.full) params; + type_variance = Variance.unknown_signature ~injective:false ~arity; type_separability = Types.Separability.default_signature ~arity; type_is_newtype = false; type_expansion_scope = Btype.lowest_level; @@ -502,6 +502,9 @@ let check_constraints_labels env visited l pl = let check_constraints env sdecl (_, decl) = let visited = ref TypeSet.empty in + List.iter2 + (fun (sty, _) ty -> check_constraints_rec env sty.ptyp_loc visited ty) + sdecl.ptype_params decl.type_params; begin match decl.type_kind with | Type_abstract -> () | Type_variant l -> @@ -668,7 +671,7 @@ let check_well_founded_decl env loc path decl to_check = (* Check for ill-defined abbrevs *) -let check_recursion env loc path decl to_check = +let check_recursion ~orig_env env loc path decl to_check = (* to_check is true for potentially mutually recursive paths. (path, decl) is the type declaration to be checked. *) @@ -683,7 +686,7 @@ let check_recursion env loc path decl to_check = match ty.desc with | Tconstr(path', args', _) -> if Path.same path path' then begin - if not (Ctype.equal env false args args') then + if not (Ctype.equal orig_env false args args') then raise (Error(loc, Non_regular { definition=path; @@ -705,7 +708,7 @@ let check_recursion env loc path decl to_check = let (params, body) = Ctype.instance_parameterized_type params0 body0 in begin - try List.iter2 (Ctype.unify env) params args' + try List.iter2 (Ctype.unify orig_env) params args' with Ctype.Unify _ -> raise (Error(loc, Constraint_failed (ty, Ctype.newconstr path' params0))); @@ -729,13 +732,15 @@ let check_recursion env loc path decl to_check = let (args, body) = Ctype.instance_parameterized_type ~keep_names:true decl.type_params body in + List.iter (check_regular path args [] []) args; check_regular path args [] [] body) decl.type_manifest -let check_abbrev_recursion env id_loc_list to_check tdecl = +let check_abbrev_recursion ~orig_env env id_loc_list to_check tdecl = let decl = tdecl.typ_type in let id = tdecl.typ_id in - check_recursion env (List.assoc id id_loc_list) (Path.Pident id) decl to_check + check_recursion ~orig_env env (List.assoc id id_loc_list) (Path.Pident id) + decl to_check let check_duplicates sdecl_list = let labels = Hashtbl.create 7 and constrs = Hashtbl.create 7 in @@ -902,7 +907,8 @@ let transl_type_decl env rec_flag sdecl_list = check_well_founded_decl new_env (List.assoc id id_loc_list) (Path.Pident id) decl to_check) decls; - List.iter (check_abbrev_recursion new_env id_loc_list to_check) tdecls; + List.iter + (check_abbrev_recursion ~orig_env:env new_env id_loc_list to_check) tdecls; (* Check that all type variables are closed *) List.iter2 (fun sdecl tdecl -> @@ -1437,7 +1443,7 @@ let transl_with_constraint id row_path ~sig_env ~sig_decl ~outer_env sdecl = raise(Error(cty.ctyp_loc, Inconsistent_constraint (env, tr))) ) tparams sig_decl.type_params; List.iter (fun (cty, cty', loc) -> - (* Note: contraints must also be enforced in [sig_env] because + (* Note: constraints must also be enforced in [sig_env] because they may contain parameter variables from [tparams] that have now be unified in [sig_env]. *) try Ctype.unify env cty.ctyp_type cty'.ctyp_type @@ -1534,7 +1540,7 @@ let transl_with_constraint id row_path ~sig_env ~sig_decl ~outer_env sdecl = (* Approximate a type declaration: just make all types abstract *) -let abstract_type_decl arity = +let abstract_type_decl ~injective arity = let rec make_params n = if n <= 0 then [] else Ctype.newvar() :: make_params (n-1) in Ctype.begin_def(); @@ -1544,7 +1550,7 @@ let abstract_type_decl arity = type_kind = Type_abstract; type_private = Public; type_manifest = None; - type_variance = replicate_list Variance.full arity; + type_variance = Variance.unknown_signature ~injective ~arity; type_separability = Types.Separability.default_signature ~arity; type_is_newtype = false; type_expansion_scope = Btype.lowest_level; @@ -1562,8 +1568,9 @@ let approx_type_decl sdecl_list = let scope = Ctype.create_scope () in List.map (fun sdecl -> + let injective = sdecl.ptype_kind <> Ptype_abstract in (Ident.create_scoped ~scope sdecl.ptype_name.txt, - abstract_type_decl (List.length sdecl.ptype_params))) + abstract_type_decl ~injective (List.length sdecl.ptype_params))) sdecl_list (* Variant of check_abbrev_recursion to check the well-formedness @@ -1574,7 +1581,7 @@ let check_recmod_typedecl env loc recmod_ids path decl = (path, decl) is the type declaration to be checked. *) let to_check path = Path.exists_free recmod_ids path in check_well_founded_decl env loc path decl to_check; - check_recursion env loc path decl to_check; + check_recursion ~orig_env:env env loc path decl to_check; (* additionally check coherece, as one might build an incoherent signature, and use it to build an incoherent module, cf. #7851 *) check_coherence env loc path decl diff --git a/typing/typedecl.mli b/typing/typedecl.mli index 88f5b2f1..fec0bd65 100644 --- a/typing/typedecl.mli +++ b/typing/typedecl.mli @@ -44,7 +44,7 @@ val transl_with_constraint: outer_env:Env.t -> Parsetree.type_declaration -> Typedtree.type_declaration -val abstract_type_decl: int -> type_declaration +val abstract_type_decl: injective:bool -> int -> type_declaration val approx_type_decl: Parsetree.type_declaration list -> (Ident.t * type_declaration) list diff --git a/typing/typedecl_variance.ml b/typing/typedecl_variance.ml index 6b3bd288..26f5e0e7 100644 --- a/typing/typedecl_variance.ml +++ b/typing/typedecl_variance.ml @@ -87,7 +87,7 @@ let compute_variance env visited vari ty = compute_variance_rec v2 ty) tl decl.type_variance with Not_found -> - List.iter (compute_variance_rec may_inv) tl + List.iter (compute_variance_rec unknown) tl end | Tobject (ty, _) -> compute_same ty @@ -121,7 +121,7 @@ let compute_variance env visited vari ty = | Tvar _ | Tnil | Tlink _ | Tunivar _ -> () | Tpackage (_, _, tyl) -> let v = - Variance.(if mem Pos vari || mem Neg vari then full else may_inv) + Variance.(if mem Pos vari || mem Neg vari then full else unknown) in List.iter (compute_variance_rec v) tyl in @@ -131,10 +131,16 @@ let make p n i = let open Variance in set May_pos p (set May_neg n (set May_weak n (set Inj i null))) +let injective = Variance.(set Inj true null) + let compute_variance_type env ~check (required, loc) decl tyl = (* Requirements *) + let check_injectivity = decl.type_kind = Type_abstract in let required = - List.map (fun (c,n,i) -> if c || n then (c,n,i) else (true,true,i)) + List.map + (fun (c,n,i) -> + let i = if check_injectivity then i else false in + if c || n then (c,n,i) else (true,true,i)) required in (* Prepare *) @@ -146,6 +152,34 @@ let compute_variance_type env ~check (required, loc) decl tyl = (fun (cn,ty) -> compute_variance env tvl (if cn then full else covariant) ty) tyl; + (* Infer injectivity of constrained parameters *) + if check_injectivity then + List.iter + (fun ty -> + if Btype.is_Tvar ty || mem Inj (get_variance ty tvl) then () else + let visited = ref TypeSet.empty in + let rec check ty = + let ty = Ctype.repr ty in + if TypeSet.mem ty !visited then () else begin + visited := TypeSet.add ty !visited; + if mem Inj (get_variance ty tvl) then () else + match ty.desc with + | Tvar _ -> raise Exit + | Tconstr _ -> + let old = !visited in + begin try + Btype.iter_type_expr check ty + with Exit -> + visited := old; + let ty' = Ctype.expand_head_opt env ty in + if ty == ty' then raise Exit else check ty' + end + | _ -> Btype.iter_type_expr check ty + end + in + try check ty; compute_variance env tvl injective ty + with Exit -> ()) + params; if check then begin (* Check variance of parameters *) let pos = ref 0 in @@ -154,7 +188,7 @@ let compute_variance_type env ~check (required, loc) decl tyl = incr pos; let var = get_variance ty tvl in let (co,cn) = get_upper var and ij = mem Inj var in - if Btype.is_Tvar ty && (co && not c || cn && not n || not ij && i) + if Btype.is_Tvar ty && (co && not c || cn && not n) || not ij && i then raise (Error(loc, Bad_variance (Variance_not_satisfied !pos, (co,cn,ij), @@ -350,10 +384,14 @@ let property : (prop, req) Typedecl_properties.property = check; } -let transl_variance : Asttypes.variance -> _ = function - | Covariant -> (true, false, false) - | Contravariant -> (false, true, false) - | Invariant -> (false, false, false) +let transl_variance (v, i) = + let co, cn = + match v with + | Covariant -> (true, false) + | Contravariant -> (false, true) + | NoVariance -> (false, false) + in + (co, cn, match i with Injective -> true | NoInjectivity -> false) let variance_of_params ptype_params = List.map transl_variance (List.map snd ptype_params) diff --git a/typing/typedecl_variance.mli b/typing/typedecl_variance.mli index 99ce18d6..941ab992 100644 --- a/typing/typedecl_variance.mli +++ b/typing/typedecl_variance.mli @@ -20,7 +20,8 @@ open Typedecl_properties type surface_variance = bool * bool * bool val variance_of_params : - (Parsetree.core_type * Asttypes.variance) list -> surface_variance list + (Parsetree.core_type * (Asttypes.variance * Asttypes.injectivity)) list -> + surface_variance list val variance_of_sdecl : Parsetree.type_declaration -> surface_variance list diff --git a/typing/typedtree.ml b/typing/typedtree.ml index c2d0a0c1..ca81b0f0 100644 --- a/typing/typedtree.ml +++ b/typing/typedtree.ml @@ -483,7 +483,7 @@ and value_description = and type_declaration = { typ_id: Ident.t; typ_name: string loc; - typ_params: (core_type * variance) list; + typ_params: (core_type * (variance * injectivity)) list; typ_type: Types.type_declaration; typ_cstrs: (core_type * core_type * Location.t) list; typ_kind: type_kind; @@ -527,7 +527,7 @@ and type_extension = { tyext_path: Path.t; tyext_txt: Longident.t loc; - tyext_params: (core_type * variance) list; + tyext_params: (core_type * (variance * injectivity)) list; tyext_constructors: extension_constructor list; tyext_private: private_flag; tyext_loc: Location.t; @@ -600,7 +600,7 @@ and class_type_declaration = and 'a class_infos = { ci_virt: virtual_flag; - ci_params: (core_type * variance) list; + ci_params: (core_type * (variance * injectivity)) list; ci_id_name: string loc; ci_id_class: Ident.t; ci_id_class_type: Ident.t; @@ -714,15 +714,6 @@ let iter_pattern (f : pattern -> unit) = | Value -> f p | Computation -> () } -let rec map_general_pattern - : type k . pattern_transformation -> k general_pattern -> k general_pattern - = fun f p -> - let pat_desc = - shallow_map_pattern_desc - { f = fun p -> map_general_pattern f p } - p.pat_desc in - f.f { p with pat_desc } - type pattern_predicate = { f : 'k . 'k general_pattern -> bool } let exists_general_pattern (f : pattern_predicate) p = let exception Found in diff --git a/typing/typedtree.mli b/typing/typedtree.mli index a8f8d249..1323505c 100644 --- a/typing/typedtree.mli +++ b/typing/typedtree.mli @@ -622,7 +622,7 @@ and type_declaration = { typ_id: Ident.t; typ_name: string loc; - typ_params: (core_type * variance) list; + typ_params: (core_type * (variance * injectivity)) list; typ_type: Types.type_declaration; typ_cstrs: (core_type * core_type * Location.t) list; typ_kind: type_kind; @@ -666,7 +666,7 @@ and type_extension = { tyext_path: Path.t; tyext_txt: Longident.t loc; - tyext_params: (core_type * variance) list; + tyext_params: (core_type * (variance * injectivity)) list; tyext_constructors: extension_constructor list; tyext_private: private_flag; tyext_loc: Location.t; @@ -739,7 +739,7 @@ and class_type_declaration = and 'a class_infos = { ci_virt: virtual_flag; - ci_params: (core_type * variance) list; + ci_params: (core_type * (variance * injectivity)) list; ci_id_name : string loc; ci_id_class: Ident.t; ci_id_class_type : Ident.t; @@ -780,11 +780,6 @@ type pattern_predicate = { f : 'k . 'k general_pattern -> bool } val exists_general_pattern: pattern_predicate -> 'k general_pattern -> bool val exists_pattern: (pattern -> bool) -> pattern -> bool -(** bottom-up mapping of patterns: the transformation function is - called on the children before being called on the parent *) -val map_general_pattern: - pattern_transformation -> 'k general_pattern -> 'k general_pattern - val let_bound_idents: value_binding list -> Ident.t list val let_bound_idents_full: value_binding list -> (Ident.t * string loc * Types.type_expr) list diff --git a/typing/typemod.ml b/typing/typemod.ml index 1f7c480c..98a5946f 100644 --- a/typing/typemod.ml +++ b/typing/typemod.ml @@ -98,6 +98,7 @@ type error = | Recursive_module_require_explicit_type | Apply_generative | Cannot_scrape_alias of Path.t + | Cannot_scrape_package_type of Path.t | Badly_formed_signature of string * Typedecl.error | Cannot_hide_id of hiding_error | Invalid_type_subst_rhs @@ -164,7 +165,7 @@ let initial_env ~loc ~safe_string ~initially_opened_module env in let units = - List.rev_map Env.persistent_structures_of_dir (Load_path.get ()) + List.map Env.persistent_structures_of_dir (Load_path.get ()) in let env, units = match initially_opened_module with @@ -477,14 +478,14 @@ let merge_constraint initial_env remove_aliases loc sg constr = type_manifest = None; type_variance = List.map - (fun (_, v) -> + (fun (_, (v, i)) -> let (c, n) = match v with | Covariant -> true, false | Contravariant -> false, true - | Invariant -> false, false + | NoVariance -> false, false in - make_variance (not n) (not c) false + make_variance (not n) (not c) (i = Injective) ) sdecl.ptype_params; type_separability = @@ -1797,43 +1798,43 @@ let check_recmodule_inclusion env bindings = (* Helper for unpack *) -let rec package_constraints env loc mty constrs = +let rec package_constraints_sig env loc sg constrs = + List.map + (function + | Sig_type (id, ({type_params=[]} as td), rs, priv) + when List.mem_assoc [Ident.name id] constrs -> + let ty = List.assoc [Ident.name id] constrs in + Sig_type (id, {td with type_manifest = Some ty}, rs, priv) + | Sig_module (id, pres, md, rs, priv) -> + let rec aux = function + | (m :: ((_ :: _) as l), t) :: rest when m = Ident.name id -> + (l, t) :: aux rest + | _ :: rest -> aux rest + | [] -> [] + in + let md = + {md with + md_type = package_constraints env loc md.md_type (aux constrs) + } + in + Sig_module (id, pres, md, rs, priv) + | item -> item + ) + sg + +and package_constraints env loc mty constrs = if constrs = [] then mty - else let sg = extract_sig env loc mty in - let sg' = - List.map - (function - | Sig_type (id, ({type_params=[]} as td), rs, priv) - when List.mem_assoc [Ident.name id] constrs -> - let ty = List.assoc [Ident.name id] constrs in - Sig_type (id, {td with type_manifest = Some ty}, rs, priv) - | Sig_module (id, _, md, rs, priv) -> - let rec aux = function - | (m :: ((_ :: _) as l), t) :: rest when m = Ident.name id -> - (l, t) :: aux rest - | _ :: rest -> aux rest - | [] -> [] - in - let md = - {md with - md_type = package_constraints env loc md.md_type (aux constrs) - } - in - Sig_module (id, Mp_present, md, rs, priv) - | item -> item - ) - sg - in - Mty_signature sg' + else begin + match Mtype.scrape env mty with + | Mty_signature sg -> + Mty_signature (package_constraints_sig env loc sg constrs) + | Mty_functor _ | Mty_alias _ -> assert false + | Mty_ident p -> raise(Error(loc, env, Cannot_scrape_package_type p)) + end let modtype_of_package env loc p nl tl = - match (Env.find_modtype p env).mtd_type with - | Some mty when nl <> [] -> - package_constraints env loc mty - (List.combine (List.map Longident.flatten nl) tl) - | _ | exception Not_found (* missing cmi *) -> - if nl = [] then Mty_ident p - else raise(Error(loc, env, Signature_expected)) + package_constraints env loc (Mty_ident p) + (List.combine (List.map Longident.flatten nl) tl) let package_subtype env p1 nl1 tl1 p2 nl2 tl2 = let mkmty p nl tl = @@ -1843,11 +1844,13 @@ let package_subtype env p1 nl1 tl1 p2 nl2 tl2 = let (nl, tl) = List.split ntl in modtype_of_package env Location.none p nl tl in - let mty1 = mkmty p1 nl1 tl1 and mty2 = mkmty p2 nl2 tl2 in - let loc = Location.none in - match Includemod.modtypes ~loc ~mark:Mark_both env mty1 mty2 with - | Tcoerce_none -> true - | _ | exception Includemod.Error _ -> false + match mkmty p1 nl1 tl1, mkmty p2 nl2 tl2 with + | exception Error(_, _, Cannot_scrape_package_type _) -> false + | mty1, mty2 -> + let loc = Location.none in + match Includemod.modtypes ~loc ~mark:Mark_both env mty1 mty2 with + | Tcoerce_none -> true + | _ | exception Includemod.Error _ -> false let () = Ctype.package_subtype := package_subtype @@ -1905,7 +1908,7 @@ and type_module_aux ~alias sttn funct_body anchor env smod = in md | Pmod_structure sstr -> let (str, sg, names, _finalenv) = - type_structure funct_body anchor env sstr smod.pmod_loc in + type_structure funct_body anchor env sstr in let md = { mod_desc = Tmod_structure str; mod_type = Mty_signature sg; @@ -2135,10 +2138,10 @@ and type_open_decl_aux ?used_slot ?toplevel funct_body names env od = } in open_descr, sg, newenv -and type_structure ?(toplevel = false) funct_body anchor env sstr scope = +and type_structure ?(toplevel = false) funct_body anchor env sstr = let names = Signature_names.create () in - let type_str_item env srem {pstr_loc = loc; pstr_desc = desc} = + let type_str_item env {pstr_loc = loc; pstr_desc = desc} = match desc with | Pstr_eval (sexpr, attrs) -> let expr = @@ -2147,21 +2150,8 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope = in Tstr_eval (expr, attrs), [], env | Pstr_value(rec_flag, sdefs) -> - let scope = - match rec_flag with - | Recursive -> - Some (Annot.Idef {scope with - Location.loc_start = loc.Location.loc_start}) - | Nonrecursive -> - let start = - match srem with - | [] -> loc.Location.loc_end - | {pstr_loc = loc2} :: _ -> loc2.Location.loc_start - in - Some (Annot.Idef {scope with Location.loc_start = start}) - in let (defs, newenv) = - Typecore.type_binding env rec_flag sdefs scope in + Typecore.type_binding env rec_flag sdefs in let () = if rec_flag = Recursive then Typecore.check_recursive_bindings env defs in @@ -2437,7 +2427,7 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope = | [] -> ([], [], env) | pstr :: srem -> let previous_saved_types = Cmt_format.get_saved_types () in - let desc, sg, new_env = type_str_item env srem pstr in + let desc, sg, new_env = type_str_item env pstr in let str = { str_desc = desc; str_loc = pstr.pstr_loc; str_env = env } in Cmt_format.set_saved_types (Cmt_format.Partial_structure_item str :: previous_saved_types); @@ -2458,7 +2448,7 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope = let type_toplevel_phrase env s = Env.reset_required_globals (); let (str, sg, to_remove_from_sg, env) = - type_structure ~toplevel:true false None env s Location.none in + type_structure ~toplevel:true false None env s in (str, sg, to_remove_from_sg, env) let type_module_alias = type_module ~alias:true true false None @@ -2467,17 +2457,17 @@ let type_structure = type_structure false None (* Normalize types in a signature *) -let rec normalize_modtype env = function +let rec normalize_modtype = function Mty_ident _ | Mty_alias _ -> () - | Mty_signature sg -> normalize_signature env sg - | Mty_functor(_param, body) -> normalize_modtype env body + | Mty_signature sg -> normalize_signature sg + | Mty_functor(_param, body) -> normalize_modtype body -and normalize_signature env = List.iter (normalize_signature_item env) +and normalize_signature sg = List.iter normalize_signature_item sg -and normalize_signature_item env = function - Sig_value(_id, desc, _) -> Ctype.normalize_type env desc.val_type - | Sig_module(_id, _, md, _, _) -> normalize_modtype env md.md_type +and normalize_signature_item = function + Sig_value(_id, desc, _) -> Ctype.normalize_type desc.val_type + | Sig_module(_id, _, md, _, _) -> normalize_modtype md.md_type | _ -> () (* Extract the module type of a module expression *) @@ -2638,7 +2628,7 @@ let type_implementation sourcefile outputprefix modulename initial_env ast = if !Clflags.print_types then (* #7656 *) Warnings.parse_options false "-32-34-37-38-60"; let (str, sg, names, finalenv) = - type_structure initial_env ast (Location.in_file sourcefile) in + type_structure initial_env ast in let simple_sg = Signature_names.simplify finalenv names sg in if !Clflags.print_types then begin Typecore.force_delayed_checks (); @@ -2678,7 +2668,7 @@ let type_implementation sourcefile outputprefix modulename initial_env ast = sourcefile sg "(inferred signature)" simple_sg in check_nongen_schemes finalenv simple_sg; - normalize_signature finalenv simple_sg; + normalize_signature simple_sg; Typecore.force_delayed_checks (); (* See comment above. Here the target signature contains all the value being exported. We can still capture unused @@ -2902,6 +2892,10 @@ let report_error ppf = function fprintf ppf "This is an alias for module %a, which is missing" path p + | Cannot_scrape_package_type p -> + fprintf ppf + "The type of this packed module refers to %a, which is missing" + path p | Badly_formed_signature (context, err) -> fprintf ppf "@[In %s:@ %a@]" context Typedecl.report_error err | Cannot_hide_id Illegal_shadowing diff --git a/typing/typemod.mli b/typing/typemod.mli index f74a57d8..c24aa5e2 100644 --- a/typing/typemod.mli +++ b/typing/typemod.mli @@ -32,7 +32,7 @@ end val type_module: Env.t -> Parsetree.module_expr -> Typedtree.module_expr val type_structure: - Env.t -> Parsetree.structure -> Location.t -> + Env.t -> Parsetree.structure -> Typedtree.structure * Types.signature * Signature_names.t * Env.t val type_toplevel_phrase: Env.t -> Parsetree.structure -> @@ -127,6 +127,7 @@ type error = | Recursive_module_require_explicit_type | Apply_generative | Cannot_scrape_alias of Path.t + | Cannot_scrape_package_type of Path.t | Badly_formed_signature of string * Typedecl.error | Cannot_hide_id of hiding_error | Invalid_type_subst_rhs diff --git a/typing/types.ml b/typing/types.ml index f03a4bc6..d723a304 100644 --- a/typing/types.ml +++ b/typing/types.ml @@ -179,7 +179,7 @@ module Variance = struct if b then v lor single x else v land (lnot (single x)) let mem x = subset (single x) let null = 0 - let may_inv = 7 + let unknown = 7 let full = 127 let covariant = single May_pos lor single Pos lor single Inj let swap f1 f2 v = @@ -187,6 +187,9 @@ module Variance = struct let conjugate v = swap May_pos May_neg (swap Pos Neg v) let get_upper v = (mem May_pos v, mem May_neg v) let get_lower v = (mem Pos v, mem Neg v, mem Inv v, mem Inj v) + let unknown_signature ~injective ~arity = + let v = if injective then set Inj true unknown else unknown in + Misc.replicate_list v arity end module Separability = struct @@ -212,7 +215,7 @@ module Separability = struct let default_signature ~arity = let default_mode = if Config.flat_float_array then Deepsep else Ind in - List.init arity (fun _ -> default_mode) + Misc.replicate_list default_mode arity end (* Type definitions *) diff --git a/typing/types.mli b/typing/types.mli index 7dc20535..98bd408f 100644 --- a/typing/types.mli +++ b/typing/types.mli @@ -287,11 +287,18 @@ and value_kind = module Variance : sig type t - type f = May_pos | May_neg | May_weak | Inj | Pos | Neg | Inv - val null : t (* no occurrence *) - val full : t (* strictly invariant *) - val covariant : t (* strictly covariant *) - val may_inv : t (* maybe invariant *) + type f = + May_pos (* allow positive occurrences *) + | May_neg (* allow negative occurrences *) + | May_weak (* allow occurrences under a negative position *) + | Inj (* type is injective in this parameter *) + | Pos (* there is a positive occurrence *) + | Neg (* there is a negative occurrence *) + | Inv (* both negative and positive occurrences *) + val null : t (* no occurrence *) + val full : t (* strictly invariant (all flags) *) + val covariant : t (* strictly covariant (May_pos, Pos and Inj) *) + val unknown : t (* allow everything, guarantee nothing *) val union : t -> t -> t val inter : t -> t -> t val subset : t -> t -> bool @@ -301,6 +308,8 @@ module Variance : sig val conjugate : t -> t (* exchange positive and negative *) val get_upper : t -> bool * bool (* may_pos, may_neg *) val get_lower : t -> bool * bool * bool * bool (* pos, neg, inv, inj *) + val unknown_signature : injective:bool -> arity:int -> t list + (** The most pessimistic variance for a completely unknown type. *) end module Separability : sig diff --git a/typing/typetexp.ml b/typing/typetexp.ml index a55e53d0..84c5de3d 100644 --- a/typing/typetexp.ml +++ b/typing/typetexp.ml @@ -423,14 +423,7 @@ and transl_type_aux env policy styp = {desc=Tconstr(p, tl, _)} -> Some(p, tl) | _ -> None in - begin try - (* Set name if there are no fields yet *) - Hashtbl.iter (fun _ _ -> raise Exit) hfields; - name := nm - with Exit -> - (* Unset it otherwise *) - name := None - end; + name := if Hashtbl.length hfields <> 0 then None else nm; let fl = match expand_head env cty.ctyp_type, nm with {desc=Tvariant row}, _ when Btype.static_row row -> let row = Btype.row_repr row in @@ -687,9 +680,17 @@ let transl_simple_type_univars env styp = let transl_simple_type_delayed env styp = univars := []; used_variables := TyVarMap.empty; + begin_def (); let typ = transl_type env Extensible styp in + end_def (); make_fixed_univars typ.ctyp_type; - (typ, globalize_used_variables env false) + (* This brings the used variables to the global level, but doesn't link them + to their other occurrences just yet. This will be done when [force] is + called. *) + let force = globalize_used_variables env false in + (* Generalizes everything except the variables that were just globalized. *) + generalize typ.ctyp_type; + (typ, instance typ.ctyp_type, force) let transl_type_scheme env styp = reset_type_variables(); diff --git a/typing/typetexp.mli b/typing/typetexp.mli index 5475abbc..602b7c7a 100644 --- a/typing/typetexp.mli +++ b/typing/typetexp.mli @@ -23,10 +23,13 @@ val transl_simple_type: Env.t -> bool -> Parsetree.core_type -> Typedtree.core_type val transl_simple_type_univars: Env.t -> Parsetree.core_type -> Typedtree.core_type -val transl_simple_type_delayed: - Env.t -> Parsetree.core_type -> Typedtree.core_type * (unit -> unit) +val transl_simple_type_delayed + : Env.t + -> Parsetree.core_type + -> Typedtree.core_type * type_expr * (unit -> unit) (* Translate a type, but leave type variables unbound. Returns - the type and a function that binds the type variable. *) + the type, an instance of the corresponding type_expr, and a + function that binds the type variable. *) val transl_type_scheme: Env.t -> Parsetree.core_type -> Typedtree.core_type val reset_type_variables: unit -> unit diff --git a/typing/untypeast.ml b/typing/untypeast.ml index 7106da5b..dc36aaf4 100644 --- a/typing/untypeast.ml +++ b/typing/untypeast.ml @@ -887,3 +887,9 @@ let untype_structure ?(mapper=default_mapper) structure = let untype_signature ?(mapper=default_mapper) signature = mapper.signature mapper signature + +let untype_expression ?(mapper=default_mapper) expression = + mapper.expr mapper expression + +let untype_pattern ?(mapper=default_mapper) pattern = + mapper.pat mapper pattern diff --git a/typing/untypeast.mli b/typing/untypeast.mli index d8a01519..809df9ad 100644 --- a/typing/untypeast.mli +++ b/typing/untypeast.mli @@ -81,5 +81,7 @@ val default_mapper : mapper val untype_structure : ?mapper:mapper -> Typedtree.structure -> structure val untype_signature : ?mapper:mapper -> Typedtree.signature -> signature +val untype_expression : ?mapper:mapper -> Typedtree.expression -> expression +val untype_pattern : ?mapper:mapper -> _ Typedtree.general_pattern -> pattern val constant : Asttypes.constant -> Parsetree.constant diff --git a/utils/Makefile b/utils/Makefile index 6b7febe4..11e2cebe 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -17,7 +17,7 @@ ROOTDIR = .. -include $(ROOTDIR)/Makefile.config +include $(ROOTDIR)/Makefile.common ifeq "$(UNIX_OR_WIN32)" "win32" ifeq "$(wildcard $(ROOTDIR)/flexdll/Makefile)" "" @@ -31,36 +31,15 @@ endif FLEXLINK_FLAGS ?= -# Escape special characters in the argument string. -# There are four characters that need escaping: -# - backslash and ampersand, which are special in the replacement text -# of sed's "s" command -# - exclamation mark, which is the delimiter we use for sed's "s" command -# - single quote, which interferes with shell quoting. We are inside -# single quotes already, so the proper escape is '\'' -# (close single quotation, insert single quote character, -# reopen single quotation). -SED_ESCAPE=$(subst ','\'',$(subst !,\!,$(subst &,\&,$(subst \,\\,$1)))) - -# Escape special characters in an OCaml string literal "..." -# There are two: backslash and double quote. -OCAML_ESCAPE=$(subst ",\",$(subst \,\\,$1)) - -# SUBST generates the sed substitution for the variable *named* in $1 -SUBST=-e 's!%%$1%%!$(call SED_ESCAPE,$($1))!' - -# SUBST_STRING does the same, for a variable that occurs between "..." -# in config.mlp. Thus, backslashes and double quotes must be escaped. -SUBST_STRING=-e 's!%%$1%%!$(call SED_ESCAPE,$(call OCAML_ESCAPE,$($1)))!' - -# SUBST_QUOTE does the same, adding OCaml quotes around non-empty strings -# (see FLEXDLL_DIR which must empty if FLEXDLL_DIR is empty but an OCaml -# string otherwise) +# SUBST_QUOTE does the same as SUBST_STRING, adding OCaml quotes around +# non-empty strings (see FLEXDLL_DIR which must empty if FLEXDLL_DIR is empty +# but an OCaml string otherwise) SUBST_QUOTE2=\ -e 's!%%$1%%!$(if $2,$(call SED_ESCAPE,"$(call OCAML_ESCAPE,$2)"))!' SUBST_QUOTE=$(call SUBST_QUOTE2,$1,$($1)) FLEXLINK_LDFLAGS=$(if $(OC_LDFLAGS), -link "$(OC_LDFLAGS)") +FLEXLINK_DLL_LDFLAGS=$(if $(OC_DLL_LDFLAGS), -link "$(OC_DLL_LDFLAGS)") config.ml: config.mlp $(ROOTDIR)/Makefile.config Makefile sed $(call SUBST,AFL_INSTRUMENT) \ @@ -83,11 +62,10 @@ config.ml: config.mlp $(ROOTDIR)/Makefile.config Makefile $(call SUBST_QUOTE,FLEXDLL_DIR) \ $(call SUBST,HOST) \ $(call SUBST_STRING,LIBDIR) \ - $(call SUBST,LIBUNWIND_AVAILABLE) \ - $(call SUBST,LIBUNWIND_LINK_FLAGS) \ $(call SUBST_STRING,MKDLL) \ $(call SUBST_STRING,MKEXE) \ $(call SUBST_STRING,FLEXLINK_LDFLAGS) \ + $(call SUBST_STRING,FLEXLINK_DLL_LDFLAGS) \ $(call SUBST_STRING,MKMAINDLL) \ $(call SUBST,MODEL) \ $(call SUBST_STRING,NATIVECCLIBS) \ @@ -107,8 +85,6 @@ config.ml: config.mlp $(ROOTDIR)/Makefile.config Makefile $(call SUBST,TARGET) \ $(call SUBST,WITH_FRAME_POINTERS) \ $(call SUBST,WITH_PROFINFO) \ - $(call SUBST,WITH_SPACETIME) \ - $(call SUBST,ENABLE_CALL_COUNTS) \ $(call SUBST,FLAT_FLOAT_ARRAY) \ $(call SUBST,FUNCTION_SECTIONS) \ $(call SUBST,CC_HAS_DEBUG_PREFIX_MAP) \ diff --git a/utils/binutils.ml b/utils/binutils.ml new file mode 100644 index 00000000..f3c92c8c --- /dev/null +++ b/utils/binutils.ml @@ -0,0 +1,689 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Nicolas Ojeda Bar, LexiFi *) +(* *) +(* Copyright 2020 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +let char_to_hex c = + Printf.sprintf "0x%02x" (Char.code c) + +let int_to_hex n = + Printf.sprintf "0x%x" n + +type error = + | Truncated_file + | Unrecognized of string + | Unsupported of string * int64 + | Out_of_range of string + +let error_to_string = function + | Truncated_file -> + "Truncated file" + | Unrecognized magic -> + Printf.sprintf "Unrecognized magic: %s" + (String.concat " " + (List.init (String.length magic) + (fun i -> char_to_hex magic.[i]))) + | Unsupported (s, n) -> + Printf.sprintf "Unsupported: %s: 0x%Lx" s n + | Out_of_range s -> + Printf.sprintf "Out of range constant: %s" s + +exception Error of error + +let name_at ?max_len buf start = + if start < 0 || start > Bytes.length buf then + raise (Error (Out_of_range (int_to_hex start))); + let max_pos = + match max_len with + | None -> Bytes.length buf + | Some n -> min (Bytes.length buf) (start + n) + in + let rec loop pos = + if pos >= max_pos || Bytes.get buf pos = '\000' + then + Bytes.sub_string buf start (pos - start) + else + loop (succ pos) + in + loop start + +let array_find_map f a = + let rec loop i = + if i >= Array.length a then None + else begin + match f a.(i) with + | None -> loop (succ i) + | Some _ as r -> r + end + in + loop 0 + +let array_find f a = + array_find_map (fun x -> if f x then Some x else None) a + +let really_input_bytes ic len = + let buf = Bytes.create len in + really_input ic buf 0 len; + buf + +let uint64_of_uint32 n = + Int64.(logand (of_int32 n) 0xffffffffL) + +type endianness = + | LE + | BE + +type bitness = + | B32 + | B64 + +type decoder = + { + ic: in_channel; + endianness: endianness; + bitness: bitness; + } + +let word_size = function + | {bitness = B64; _} -> 8 + | {bitness = B32; _} -> 4 + +let get_uint16 {endianness; _} buf idx = + match endianness with + | LE -> Bytes.get_uint16_le buf idx + | BE -> Bytes.get_uint16_be buf idx + +let get_uint32 {endianness; _} buf idx = + match endianness with + | LE -> Bytes.get_int32_le buf idx + | BE -> Bytes.get_int32_be buf idx + +let get_uint s d buf idx = + let n = get_uint32 d buf idx in + match Int32.unsigned_to_int n with + | None -> raise (Error (Unsupported (s, Int64.of_int32 n))) + | Some n -> n + +let get_uint64 {endianness; _} buf idx = + match endianness with + | LE -> Bytes.get_int64_le buf idx + | BE -> Bytes.get_int64_be buf idx + +let get_word d buf idx = + match d.bitness with + | B64 -> get_uint64 d buf idx + | B32 -> uint64_of_uint32 (get_uint32 d buf idx) + +let uint64_to_int s n = + match Int64.unsigned_to_int n with + | None -> raise (Error (Unsupported (s, n))) + | Some n -> n + +let load_bytes d off len = + LargeFile.seek_in d.ic off; + really_input_bytes d.ic len + +type t = + { + defines_symbol: string -> bool; + symbol_offset: string -> int64 option; + } + +module ELF = struct + + (* Reference: http://man7.org/linux/man-pages/man5/elf.5.html *) + + let header_size d = + 40 + 3 * word_size d + + type header = + { + e_shoff: int64; + e_shentsize: int; + e_shnum: int; + e_shstrndx: int; + } + + let read_header d = + let buf = load_bytes d 0L (header_size d) in + let word_size = word_size d in + let e_shnum = get_uint16 d buf (36 + 3 * word_size) in + let e_shentsize = get_uint16 d buf (34 + 3 * word_size) in + let e_shoff = get_word d buf (24 + 2 * word_size) in + let e_shstrndx = get_uint16 d buf (38 + 3 * word_size) in + {e_shnum; e_shentsize; e_shoff; e_shstrndx} + + type sh_type = + | SHT_STRTAB + | SHT_DYNSYM + | SHT_OTHER + + type section = + { + sh_name: int; + sh_type: sh_type; + sh_addr: int64; + sh_offset: int64; + sh_size: int; + sh_entsize: int; + sh_name_str: string; + } + + let load_section_body d {sh_offset; sh_size; _} = + load_bytes d sh_offset sh_size + + let read_sections d {e_shoff; e_shnum; e_shentsize; e_shstrndx; _} = + let buf = load_bytes d e_shoff (e_shnum * e_shentsize) in + let word_size = word_size d in + let mk i = + let base = i * e_shentsize in + let sh_name = get_uint "sh_name" d buf (base + 0) in + let sh_type = + match get_uint32 d buf (base + 4) with + | 3l -> SHT_STRTAB + | 11l -> SHT_DYNSYM + | _ -> SHT_OTHER + in + let sh_addr = get_word d buf (base + 8 + word_size) in + let sh_offset = get_word d buf (base + 8 + 2 * word_size) in + let sh_size = + uint64_to_int "sh_size" + (get_word d buf (base + 8 + 3 * word_size)) + in + let sh_entsize = + uint64_to_int "sh_entsize" + (get_word d buf (base + 16 + 5 * word_size)) + in + {sh_name; sh_type; sh_addr; sh_offset; + sh_size; sh_entsize; sh_name_str = ""} + in + let sections = Array.init e_shnum mk in + if e_shstrndx = 0 then + (* no string table *) + sections + else + let shstrtbl = load_section_body d sections.(e_shstrndx) in + let set_name sec = + let sh_name_str = name_at shstrtbl sec.sh_name in + {sec with sh_name_str} + in + Array.map set_name sections + + let read_sections d h = + let {e_shoff; e_shentsize; e_shnum; e_shstrndx} = h in + if e_shoff = 0L then + [||] + else begin + let buf = lazy (load_bytes d e_shoff e_shentsize) in + let word_size = word_size d in + let e_shnum = + if e_shnum = 0 then + (* The real e_shnum is the sh_size of the initial section.*) + uint64_to_int "e_shnum" + (get_word d (Lazy.force buf) (8 + 3 * word_size)) + else + e_shnum + in + let e_shstrndx = + if e_shstrndx = 0xffff then + (* The real e_shstrndx is the sh_link of the initial section. *) + get_uint "e_shstrndx" d (Lazy.force buf) (8 + 4 * word_size) + else + e_shstrndx + in + read_sections d {h with e_shnum; e_shstrndx} + end + + type symbol = + { + st_name: string; + st_value: int64; + st_shndx: int; + } + + let find_section sections type_ sectname = + let f {sh_type; sh_name_str; _} = + sh_type = type_ && sh_name_str = sectname + in + array_find f sections + + let read_symbols d sections = + match find_section sections SHT_DYNSYM ".dynsym" with + | None -> [| |] + | Some {sh_entsize = 0; _} -> + raise (Error (Out_of_range "sh_entsize=0")) + | Some dynsym -> + begin match find_section sections SHT_STRTAB ".dynstr" with + | None -> [| |] + | Some dynstr -> + let strtbl = load_section_body d dynstr in + let buf = load_section_body d dynsym in + let word_size = word_size d in + let mk i = + let base = i * dynsym.sh_entsize in + let st_name = name_at strtbl (get_uint "st_name" d buf base) in + let st_value = get_word d buf (base + word_size (* ! *)) in + let st_shndx = + let off = match d.bitness with B64 -> 6 | B32 -> 14 in + get_uint16 d buf (base + off) + in + {st_name; st_value; st_shndx} + in + Array.init (dynsym.sh_size / dynsym.sh_entsize) mk + end + + let find_symbol symbols symname = + let f = function + | {st_shndx = 0; _} -> false + | {st_name; _} -> st_name = symname + in + array_find f symbols + + let symbol_offset sections symbols symname = + match find_symbol symbols symname with + | None -> + None + | Some {st_shndx; st_value; _} -> + (* st_value in executables and shared objects holds a virtual (absolute) + address. See https://refspecs.linuxfoundation.org/elf/elf.pdf, page + 1-21, "Symbol Values". *) + Some Int64.(add sections.(st_shndx).sh_offset + (sub st_value sections.(st_shndx).sh_addr)) + + let defines_symbol symbols symname = + Option.is_some (find_symbol symbols symname) + + let read ic = + seek_in ic 0; + let identification = really_input_bytes ic 16 in + let bitness = + match Bytes.get identification 4 with + | '\x01' -> B32 + | '\x02' -> B64 + | _ as c -> + raise (Error (Unsupported ("ELFCLASS", Int64.of_int (Char.code c)))) + in + let endianness = + match Bytes.get identification 5 with + | '\x01' -> LE + | '\x02' -> BE + | _ as c -> + raise (Error (Unsupported ("ELFDATA", Int64.of_int (Char.code c)))) + in + let d = {ic; bitness; endianness} in + let header = read_header d in + let sections = read_sections d header in + let symbols = read_symbols d sections in + let symbol_offset = symbol_offset sections symbols in + let defines_symbol = defines_symbol symbols in + {symbol_offset; defines_symbol} +end + +module Mach_O = struct + + (* Reference: + https://github.com/aidansteele/osx-abi-macho-file-format-reference *) + + let size_int = 4 + + let header_size {bitness; _} = + (match bitness with B64 -> 6 | B32 -> 5) * 4 + 2 * size_int + + type header = + { + ncmds: int; + sizeofcmds: int; + } + + let read_header d = + let buf = load_bytes d 0L (header_size d) in + let ncmds = get_uint "ncmds" d buf (8 + 2 * size_int) in + let sizeofcmds = get_uint "sizeofcmds" d buf (12 + 2 * size_int) in + {ncmds; sizeofcmds} + + type lc_symtab = + { + symoff: int32; + nsyms: int; + stroff: int32; + strsize: int; + } + + type load_command = + | LC_SYMTAB of lc_symtab + | OTHER + + let read_load_commands d {ncmds; sizeofcmds} = + let buf = load_bytes d (Int64.of_int (header_size d)) sizeofcmds in + let base = ref 0 in + let mk _ = + let cmd = get_uint32 d buf (!base + 0) in + let cmdsize = get_uint "cmdsize" d buf (!base + 4) in + let lc = + match cmd with + | 0x2l -> + let symoff = get_uint32 d buf (!base + 8) in + let nsyms = get_uint "nsyms" d buf (!base + 12) in + let stroff = get_uint32 d buf (!base + 16) in + let strsize = get_uint "strsize" d buf (!base + 20) in + LC_SYMTAB {symoff; nsyms; stroff; strsize} + | _ -> + OTHER + in + base := !base + cmdsize; + lc + in + Array.init ncmds mk + + type symbol = + { + n_name: string; + n_type: int; + n_value: int64; + } + + let size_nlist d = + 8 + word_size d + + let read_symbols d load_commands = + match + (* Can it happen there be more than one LC_SYMTAB? *) + array_find_map (function + | LC_SYMTAB symtab -> Some symtab + | _ -> None + ) load_commands + with + | None -> [| |] + | Some {symoff; nsyms; stroff; strsize} -> + let strtbl = load_bytes d (uint64_of_uint32 stroff) strsize in + let buf = + load_bytes d (uint64_of_uint32 symoff) (nsyms * size_nlist d) in + let size_nlist = size_nlist d in + let mk i = + let base = i * size_nlist in + let n_name = name_at strtbl (get_uint "n_name" d buf (base + 0)) in + let n_type = Bytes.get_uint8 buf (base + 4) in + let n_value = get_word d buf (base + 8) in + {n_name; n_type; n_value} + in + Array.init nsyms mk + + let fix symname = + "_" ^ symname + + let find_symbol symbols symname = + let f {n_name; n_type; _} = + n_type land 0b1111 = 0b1111 (* N_EXT + N_SECT *) && + n_name = symname + in + array_find f symbols + + let symbol_offset symbols symname = + let symname = fix symname in + match find_symbol symbols symname with + | None -> None + | Some {n_value; _} -> Some n_value + + let defines_symbol symbols symname = + let symname = fix symname in + Option.is_some (find_symbol symbols symname) + + type magic = + | MH_MAGIC + | MH_CIGAM + | MH_MAGIC_64 + | MH_CIGAM_64 + + let read ic = + seek_in ic 0; + let magic = really_input_bytes ic 4 in + let magic = + match Bytes.get_int32_ne magic 0 with + | 0xFEEDFACEl -> MH_MAGIC + | 0xCEFAEDFEl -> MH_CIGAM + | 0xFEEDFACFl -> MH_MAGIC_64 + | 0xCFFAEDFEl -> MH_CIGAM_64 + | _ -> (* should not happen *) + raise (Error (Unrecognized (Bytes.to_string magic))) + in + let bitness = + match magic with + | MH_MAGIC | MH_CIGAM -> B32 + | MH_MAGIC_64 | MH_CIGAM_64 -> B64 + in + let endianness = + match magic, Sys.big_endian with + | (MH_MAGIC | MH_MAGIC_64), false + | (MH_CIGAM | MH_CIGAM_64), true -> LE + | (MH_MAGIC | MH_MAGIC_64), true + | (MH_CIGAM | MH_CIGAM_64), false -> BE + in + let d = {ic; endianness; bitness} in + let header = read_header d in + let load_commands = read_load_commands d header in + let symbols = read_symbols d load_commands in + let symbol_offset = symbol_offset symbols in + let defines_symbol = defines_symbol symbols in + {symbol_offset; defines_symbol} +end + +module FlexDLL = struct + + (* Reference: + https://docs.microsoft.com/en-us/windows/win32/debug/pe-format *) + + let header_size = 24 + + type header = + { + e_lfanew: int64; + number_of_sections: int; + size_of_optional_header: int; + characteristics: int; + } + + let read_header e_lfanew d buf = + let number_of_sections = get_uint16 d buf 6 in + let size_of_optional_header = get_uint16 d buf 20 in + let characteristics = get_uint16 d buf 22 in + {e_lfanew; number_of_sections; size_of_optional_header; characteristics} + + type optional_header_magic = + | PE32 + | PE32PLUS + + type optional_header = + { + magic: optional_header_magic; + image_base: int64; + } + + let read_optional_header d {e_lfanew; size_of_optional_header; _} = + if size_of_optional_header = 0 then + raise (Error (Unrecognized "SizeOfOptionalHeader=0")); + let buf = + load_bytes d Int64.(add e_lfanew (of_int header_size)) + size_of_optional_header + in + let magic = + match get_uint16 d buf 0 with + | 0x10b -> PE32 + | 0x20b -> PE32PLUS + | n -> + raise (Error (Unsupported ("optional_header_magic", Int64.of_int n))) + in + let image_base = + match magic with + | PE32 -> uint64_of_uint32 (get_uint32 d buf 28) + | PE32PLUS -> get_uint64 d buf 24 + in + {magic; image_base} + + type section = + { + name: string; + virtual_size: int; + virtual_address: int64; + size_of_raw_data: int; + pointer_to_raw_data: int64; + } + + let section_header_size = 40 + + let read_sections d + {e_lfanew; number_of_sections; size_of_optional_header; _} = + let buf = + load_bytes d + Int64.(add e_lfanew (of_int (header_size + size_of_optional_header))) + (number_of_sections * section_header_size) + in + let mk i = + let base = i * section_header_size in + let name = name_at ~max_len:8 buf (base + 0) in + let virtual_size = get_uint "virtual_size" d buf (base + 8) in + let virtual_address = uint64_of_uint32 (get_uint32 d buf (base + 12)) in + let size_of_raw_data = get_uint "size_of_raw_data" d buf (base + 16) in + let pointer_to_raw_data = + uint64_of_uint32 (get_uint32 d buf (base + 20)) in + {name; virtual_size; virtual_address; + size_of_raw_data; pointer_to_raw_data} + in + Array.init number_of_sections mk + + type symbol = + { + name: string; + address: int64; + } + + let load_section_body d {size_of_raw_data; pointer_to_raw_data; _} = + load_bytes d pointer_to_raw_data size_of_raw_data + + let find_section sections sectname = + array_find (function ({name; _} : section) -> name = sectname) sections + + (* We extract the list of exported symbols as encoded by flexlink, see + https://github.com/alainfrisch/flexdll/blob/bd636def70d941674275b2f4b6c13a34ba23f9c9/reloc.ml + #L500-L525 *) + + let read_symbols d {image_base; _} sections = + match find_section sections ".exptbl" with + | None -> [| |] + | Some ({virtual_address; _} as exptbl) -> + let buf = load_section_body d exptbl in + let numexports = + uint64_to_int "numexports" (get_word d buf 0) + in + let word_size = word_size d in + let mk i = + let address = get_word d buf (word_size * (2 * i + 1)) in + let nameoff = get_word d buf (word_size * (2 * i + 2)) in + let name = + let off = Int64.(sub nameoff (add virtual_address image_base)) in + name_at buf (uint64_to_int "exptbl name offset" off) + in + {name; address} + in + Array.init numexports mk + + let symbol_offset {image_base; _} sections symbols = + match find_section sections ".data" with + | None -> Fun.const None + | Some {virtual_address; pointer_to_raw_data; _} -> + fun symname -> + begin match + array_find (function {name; _} -> name = symname) symbols + with + | None -> None + | Some {address; _} -> + Some Int64.(add pointer_to_raw_data + (sub address (add virtual_address image_base))) + end + + let defines_symbol symbols symname = + Array.exists (fun {name; _} -> name = symname) symbols + + type machine_type = + | IMAGE_FILE_MACHINE_ARM + | IMAGE_FILE_MACHINE_ARM64 + | IMAGE_FILE_MACHINE_AMD64 + | IMAGE_FILE_MACHINE_I386 + + let read ic = + let e_lfanew = + seek_in ic 0x3c; + let buf = really_input_bytes ic 4 in + uint64_of_uint32 (Bytes.get_int32_le buf 0) + in + LargeFile.seek_in ic e_lfanew; + let buf = really_input_bytes ic header_size in + let magic = Bytes.sub_string buf 0 4 in + if magic <> "PE\000\000" then raise (Error (Unrecognized magic)); + let machine = + match Bytes.get_uint16_le buf 4 with + | 0x1c0 -> IMAGE_FILE_MACHINE_ARM + | 0xaa64 -> IMAGE_FILE_MACHINE_ARM64 + | 0x8664 -> IMAGE_FILE_MACHINE_AMD64 + | 0x14c -> IMAGE_FILE_MACHINE_I386 + | n -> raise (Error (Unsupported ("MACHINETYPE", Int64.of_int n))) + in + let bitness = + match machine with + | IMAGE_FILE_MACHINE_AMD64 + | IMAGE_FILE_MACHINE_ARM64 -> B64 + | IMAGE_FILE_MACHINE_I386 + | IMAGE_FILE_MACHINE_ARM -> B32 + in + let d = {ic; endianness = LE; bitness} in + let header = read_header e_lfanew d buf in + let opt_header = read_optional_header d header in + let sections = read_sections d header in + let symbols = read_symbols d opt_header sections in + let symbol_offset = symbol_offset opt_header sections symbols in + let defines_symbol = defines_symbol symbols in + {symbol_offset; defines_symbol} +end + +let read ic = + seek_in ic 0; + let magic = really_input_string ic 4 in + match magic.[0], magic.[1], magic.[2], magic.[3] with + | '\x7F', 'E', 'L', 'F' -> + ELF.read ic + | '\xFE', '\xED', '\xFA', '\xCE' + | '\xCE', '\xFA', '\xED', '\xFE' + | '\xFE', '\xED', '\xFA', '\xCF' + | '\xCF', '\xFA', '\xED', '\xFE' -> + Mach_O.read ic + | 'M', 'Z', _, _ -> + FlexDLL.read ic + | _ -> + raise (Error (Unrecognized magic)) + +let with_open_in fn f = + let ic = open_in_bin fn in + Fun.protect ~finally:(fun () -> close_in_noerr ic) (fun () -> f ic) + +let read filename = + match with_open_in filename read with + | t -> Ok t + | exception End_of_file -> + Result.Error Truncated_file + | exception Error err -> + Result.Error err + +let defines_symbol {defines_symbol; _} symname = + defines_symbol symname + +let symbol_offset {symbol_offset; _} symname = + symbol_offset symname diff --git a/utils/binutils.mli b/utils/binutils.mli new file mode 100644 index 00000000..44e17fec --- /dev/null +++ b/utils/binutils.mli @@ -0,0 +1,30 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Nicolas Ojeda Bar, LexiFi *) +(* *) +(* Copyright 2020 Institut National de Recherche en Informatique et *) +(* en Automatique. *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +type error = + | Truncated_file + | Unrecognized of string + | Unsupported of string * int64 + | Out_of_range of string + +val error_to_string: error -> string + +type t + +val read: string -> (t, error) Result.t + +val defines_symbol: t -> string -> bool + +val symbol_offset: t -> string -> int64 option diff --git a/utils/ccomp.ml b/utils/ccomp.ml index 2de6bb16..22b60a8b 100644 --- a/utils/ccomp.ml +++ b/utils/ccomp.ml @@ -128,36 +128,18 @@ let compile_file ?output ?(opt="") ?stable_name name = then display_msvc_output file name; exit -let macos_create_empty_archive ~quoted_archive = - let result = - command (Printf.sprintf "%s rc %s /dev/null" Config.ar quoted_archive) - in - if result <> 0 then result - else - let result = - command (Printf.sprintf "%s %s 2> /dev/null" Config.ranlib quoted_archive) - in - if result <> 0 then result - else - command (Printf.sprintf "%s d %s /dev/null" Config.ar quoted_archive) - let create_archive archive file_list = Misc.remove_file archive; let quoted_archive = Filename.quote archive in - match Config.ccomp_type with - "msvc" -> - command(Printf.sprintf "link /lib /nologo /out:%s %s" - quoted_archive (quote_files file_list)) - | _ -> - assert(String.length Config.ar > 0); - let is_macosx = - match Config.system with - | "macosx" -> true - | _ -> false - in - if is_macosx && file_list = [] then (* PR#6550 *) - macos_create_empty_archive ~quoted_archive - else + if file_list = [] then + 0 (* Don't call the archiver: #6550/#1094/#9011 *) + else + match Config.ccomp_type with + "msvc" -> + command(Printf.sprintf "link /lib /nologo /out:%s %s" + quoted_archive (quote_files file_list)) + | _ -> + assert(String.length Config.ar > 0); let r1 = command(Printf.sprintf "%s rc %s %s" Config.ar quoted_archive (quote_files file_list)) in @@ -224,3 +206,9 @@ let call_linker mode output_name files extra = in command cmd ) + +let linker_is_flexlink = + (* Config.mkexe, Config.mkdll and Config.mkmaindll are all flexlink + invocations for the native Windows ports and for Cygwin, if shared library + support is enabled. *) + Sys.win32 || Config.supports_shared_libraries && Sys.cygwin diff --git a/utils/ccomp.mli b/utils/ccomp.mli index 89724252..fb520e2a 100644 --- a/utils/ccomp.mli +++ b/utils/ccomp.mli @@ -37,3 +37,5 @@ type link_mode = | Partial val call_linker: link_mode -> string -> string list -> string -> int + +val linker_is_flexlink : bool diff --git a/utils/clflags.ml b/utils/clflags.ml index 4035c28c..a193d53d 100644 --- a/utils/clflags.ml +++ b/utils/clflags.ml @@ -414,6 +414,48 @@ let error_style_reader = { let unboxed_types = ref false +(* This is used by the -save-ir-after option. *) +module Compiler_ir = struct + type t = Linear + + let all = [ + Linear; + ] + + let extension t = + let ext = + match t with + | Linear -> "linear" + in + ".cmir-" ^ ext + + (** [extract_extension_with_pass filename] returns the IR whose extension + is a prefix of the extension of [filename], and the suffix, + which can be used to distinguish different passes on the same IR. + For example, [extract_extension_with_pass "foo.cmir-linear123"] + returns [Some (Linear, "123")]. *) + let extract_extension_with_pass filename = + let ext = Filename.extension filename in + let ext_len = String.length ext in + if ext_len <= 0 then None + else begin + let is_prefix ir = + let s = extension ir in + let s_len = String.length s in + s_len <= ext_len && s = String.sub ext 0 s_len + in + let drop_prefix ir = + let s = extension ir in + let s_len = String.length s in + String.sub ext s_len (ext_len - s_len) + in + let ir = List.find_opt is_prefix all in + match ir with + | None -> None + | Some ir -> Some (ir, drop_prefix ir) + end +end + (* This is used by the -stop-after option. *) module Compiler_pass = struct (* If you add a new pass, the following must be updated: @@ -421,40 +463,62 @@ module Compiler_pass = struct - the manpages in man/ocaml{c,opt}.m - the manual manual/manual/cmds/unified-options.etex *) - type t = Parsing | Typing | Scheduling + type t = Parsing | Typing | Scheduling | Emit let to_string = function | Parsing -> "parsing" | Typing -> "typing" | Scheduling -> "scheduling" + | Emit -> "emit" let of_string = function | "parsing" -> Some Parsing | "typing" -> Some Typing | "scheduling" -> Some Scheduling + | "emit" -> Some Emit | _ -> None let rank = function | Parsing -> 0 | Typing -> 1 | Scheduling -> 50 + | Emit -> 60 let passes = [ Parsing; Typing; Scheduling; + Emit; ] let is_compilation_pass _ = true let is_native_only = function | Scheduling -> true + | Emit -> true | _ -> false let enabled is_native t = not (is_native_only t) || is_native + let can_save_ir_after = function + | Scheduling -> true + | _ -> false - let available_pass_names ~native = + let available_pass_names ~filter ~native = passes |> List.filter (enabled native) + |> List.filter filter |> List.map to_string + + let compare a b = + compare (rank a) (rank b) + + let to_output_filename t ~prefix = + match t with + | Scheduling -> prefix ^ Compiler_ir.(extension Linear) + | _ -> Misc.fatal_error "Not supported" + + let of_input_filename name = + match Compiler_ir.extract_extension_with_pass name with + | Some (Linear, _) -> Some Emit + | None -> None end let stop_after = ref None (* -stop-after *) @@ -466,6 +530,21 @@ let should_stop_after pass = | None -> false | Some stop -> Compiler_pass.rank stop <= Compiler_pass.rank pass +let save_ir_after = ref [] + +let should_save_ir_after pass = + List.mem pass !save_ir_after + +let set_save_ir_after pass enabled = + let other_passes = List.filter ((<>) pass) !save_ir_after in + let new_passes = + if enabled then + pass :: other_passes + else + other_passes + in + save_ir_after := new_passes + module String = Misc.Stdlib.String let arg_spec = ref [] @@ -494,10 +573,10 @@ let print_arguments usage = (* This function is almost the same as [Arg.parse_expand], except that [Arg.parse_expand] could not be used because it does not take a reference for [arg_spec].*) -let parse_arguments f msg = +let parse_arguments argv f msg = try - let argv = ref Sys.argv in - let current = ref (!Arg.current) in + let argv = ref argv in + let current = ref 0 in Arg.parse_and_expand_argv_dynamic current argv arg_spec f msg with | Arg.Bad msg -> Printf.eprintf "%s" msg; exit 2 diff --git a/utils/clflags.mli b/utils/clflags.mli index 5be371a0..645ff4aa 100644 --- a/utils/clflags.mli +++ b/utils/clflags.mli @@ -236,14 +236,20 @@ val insn_sched : bool ref val insn_sched_default : bool module Compiler_pass : sig - type t = Parsing | Typing | Scheduling + type t = Parsing | Typing | Scheduling | Emit val of_string : string -> t option val to_string : t -> string val is_compilation_pass : t -> bool - val available_pass_names : native:bool -> string list + val available_pass_names : filter:(t -> bool) -> native:bool -> string list + val can_save_ir_after : t -> bool + val compare : t -> t -> int + val to_output_filename: t -> prefix:string -> string + val of_input_filename: string -> t option end val stop_after : Compiler_pass.t option ref val should_stop_after : Compiler_pass.t -> bool +val set_save_ir_after : Compiler_pass.t -> bool -> unit +val should_save_ir_after : Compiler_pass.t -> bool val arg_spec : (string * Arg.spec * string) list ref @@ -254,10 +260,10 @@ val arg_spec : (string * Arg.spec * string) list ref added. *) val add_arguments : string -> (string * Arg.spec * string) list -> unit -(* [parse_arguments anon_arg usage] will parse the arguments, using +(* [parse_arguments argv anon_arg usage] will parse the arguments, using the arguments provided in [Clflags.arg_spec]. *) -val parse_arguments : Arg.anon_fun -> string -> unit +val parse_arguments : string array -> Arg.anon_fun -> string -> unit (* [print_arguments usage] print the standard usage message *) val print_arguments : string -> unit diff --git a/utils/config.mli b/utils/config.mli index 515a428d..1b73eed0 100644 --- a/utils/config.mli +++ b/utils/config.mli @@ -118,6 +118,9 @@ val cmxs_magic_number: string val cmt_magic_number: string (** Magic number for compiled interface files *) +val linear_magic_number: string +(** Magic number for Linear internal representation files *) + val max_tag: int (** Biggest tag that can be stored in the header of a regular block. *) @@ -170,6 +173,11 @@ val ext_lib: string val ext_dll: string (** Extension for dynamically-loaded libraries, e.g. [.so] under Unix.*) +val ext_exe: string +(** Extension for executable programs, e.g. [.exe] under Windows. + + @since 4.12.0 *) + val default_executable_name: string (** Name of executable produced by linking if none is given with -o, e.g. [a.out] under Unix. *) @@ -192,12 +200,6 @@ val flambda : bool val with_flambda_invariants : bool (** Whether the invariants checks for flambda are enabled *) -val spacetime : bool -(** Whether the compiler was configured for Spacetime profiling *) - -val enable_call_counts : bool -(** Whether call counts are to be available when Spacetime profiling *) - val profinfo : bool (** Whether the compiler was configured for profiling *) @@ -205,12 +207,6 @@ val profinfo_width : int (** How many bits are to be used in values' headers for profiling information *) -val libunwind_available : bool -(** Whether the libunwind library is available on the target *) - -val libunwind_link_flags : string -(** Linker flags to use libunwind *) - val safe_string: bool (** Whether the compiler was configured with -force-safe-string; in that case, the -unsafe-string compile-time option is unavailable @@ -248,3 +244,9 @@ val print_config : out_channel -> unit val config_var : string -> string option (** the configuration value of a variable, if it exists *) + +(**/**) + +val merlin : bool + +(**/**) diff --git a/utils/config.mlp b/utils/config.mlp index 49ffc5bd..5bfa30d6 100644 --- a/utils/config.mlp +++ b/utils/config.mlp @@ -65,9 +65,9 @@ let mkdll, mkexe, mkmaindll = let c = flexlink.[i] in if c = '/' then '\\' else c in (String.init (String.length flexlink) f) ^ " %%FLEXLINK_FLAGS%%" in - flexlink, + flexlink ^ "%%FLEXLINK_DLL_LDFLAGS%%", flexlink ^ " -exe%%FLEXLINK_LDFLAGS%%", - flexlink ^ " -maindll" + flexlink ^ " -maindll%%FLEXLINK_DLL_LDFLAGS%%" with Not_found -> "%%MKDLL%%", "%%MKEXE%%", "%%MKMAINDLL%%" else @@ -85,25 +85,26 @@ let flat_float_array = %%FLAT_FLOAT_ARRAY%% let function_sections = %%FUNCTION_SECTIONS%% let afl_instrument = %%AFL_INSTRUMENT%% -let exec_magic_number = "Caml1999X028" +let exec_magic_number = "Caml1999X029" (* exec_magic_number is duplicated in runtime/caml/exec.h *) -and cmi_magic_number = "Caml1999I028" -and cmo_magic_number = "Caml1999O028" -and cma_magic_number = "Caml1999A028" +and cmi_magic_number = "Caml1999I029" +and cmo_magic_number = "Caml1999O029" +and cma_magic_number = "Caml1999A029" and cmx_magic_number = if flambda then - "Caml1999y028" + "Caml1999y029" else - "Caml1999Y028" + "Caml1999Y029" and cmxa_magic_number = if flambda then - "Caml1999z028" + "Caml1999z029" else - "Caml1999Z028" -and ast_impl_magic_number = "Caml1999M028" -and ast_intf_magic_number = "Caml1999N028" -and cmxs_magic_number = "Caml1999D028" -and cmt_magic_number = "Caml1999T028" + "Caml1999Z029" +and ast_impl_magic_number = "Caml1999M029" +and ast_intf_magic_number = "Caml1999N029" +and cmxs_magic_number = "Caml1999D029" +and cmt_magic_number = "Caml1999T029" +and linear_magic_number = "Caml1999L029" let interface_suffix = ref ".mli" @@ -124,10 +125,6 @@ let system = "%%SYSTEM%%" let asm = "%%ASM%%" let asm_cfi_supported = %%ASM_CFI_SUPPORTED%% let with_frame_pointers = %%WITH_FRAME_POINTERS%% -let spacetime = %%WITH_SPACETIME%% -let enable_call_counts = %%ENABLE_CALL_COUNTS%% -let libunwind_available = %%LIBUNWIND_AVAILABLE%% -let libunwind_link_flags = "%%LIBUNWIND_LINK_FLAGS%%" let profinfo = %%WITH_PROFINFO%% let profinfo_width = %%PROFINFO_WIDTH%% @@ -194,7 +191,6 @@ let configuration_variables = p "host" host; p "target" target; p_bool "flambda" flambda; - p_bool "spacetime" spacetime; p_bool "safe_string" safe_string; p_bool "default_safe_string" default_safe_string; p_bool "flat_float_array" flat_float_array; @@ -213,6 +209,7 @@ let configuration_variables = p "ast_intf_magic_number" ast_intf_magic_number; p "cmxs_magic_number" cmxs_magic_number; p "cmt_magic_number" cmt_magic_number; + p "linear_magic_number" linear_magic_number; ] let print_config_value oc = function @@ -240,3 +237,5 @@ let config_var x = | Bool b -> string_of_bool b in Some s + +let merlin = false diff --git a/utils/dune b/utils/dune index 39c76af3..de234e73 100644 --- a/utils/dune +++ b/utils/dune @@ -17,6 +17,7 @@ (mode fallback) (deps (:mk Makefile) ../Makefile.config + ; for now the utils Makefile does not use build_config config.mlp) (action (system "make -f %{mk} %{targets}"))) diff --git a/utils/load_path.ml b/utils/load_path.ml index d95ef079..41eb22e9 100644 --- a/utils/load_path.ml +++ b/utils/load_path.ml @@ -12,13 +12,15 @@ (* *) (**************************************************************************) +open Local_store + module SMap = Misc.Stdlib.String.Map (* Mapping from basenames to full filenames *) type registry = string SMap.t ref -let files : registry = ref SMap.empty -let files_uncap : registry = ref SMap.empty +let files : registry = s_ref SMap.empty +let files_uncap : registry = s_ref SMap.empty module Dir = struct type t = { @@ -42,47 +44,78 @@ module Dir = struct { path; files = Array.to_list (readdir_compat path) } end -let dirs = ref [] +let dirs = s_ref [] let reset () = + assert (not Config.merlin || Local_store.is_bound ()); files := SMap.empty; files_uncap := SMap.empty; dirs := [] -let get () = !dirs -let get_paths () = List.map Dir.path !dirs +let get () = List.rev !dirs +let get_paths () = List.rev_map Dir.path !dirs + +let add_to_maps fn basenames files files_uncap = + List.fold_left (fun (files, files_uncap) base -> + let fn = fn base in + SMap.add base fn files, + SMap.add (String.uncapitalize_ascii base) fn files_uncap + ) (files, files_uncap) basenames +(* Optimized version of [add] below, for use in [init] and [remove_dir]: since + we are starting from an empty cache, we can avoid checking whether a unit + name already exists in the cache simply by adding entries in reverse + order. *) let add dir = - let add_file base = - let fn = Filename.concat dir.Dir.path base in - files := SMap.add base fn !files; - files_uncap := SMap.add (String.uncapitalize_ascii base) fn !files_uncap; + assert (not Config.merlin || Local_store.is_bound ()); + let new_files, new_files_uncap = + add_to_maps (Filename.concat dir.Dir.path) + dir.Dir.files !files !files_uncap in - List.iter add_file dir.Dir.files; - dirs := dir :: !dirs + files := new_files; + files_uncap := new_files_uncap + +let init l = + reset (); + dirs := List.rev_map Dir.create l; + List.iter add !dirs let remove_dir dir = + assert (not Config.merlin || Local_store.is_bound ()); let new_dirs = List.filter (fun d -> Dir.path d <> dir) !dirs in - if new_dirs <> !dirs then begin + if List.compare_lengths new_dirs !dirs <> 0 then begin reset (); - List.iter add (List.rev new_dirs) + List.iter add new_dirs; + dirs := new_dirs end -let add_dir dir = add (Dir.create dir) +(* General purpose version of function to add a new entry to load path: We only + add a basename to the cache if it is not already present in the cache, in + order to enforce left-to-right precedence. *) +let add dir = + assert (not Config.merlin || Local_store.is_bound ()); + let new_files, new_files_uncap = + add_to_maps (Filename.concat dir.Dir.path) dir.Dir.files + SMap.empty SMap.empty + in + let first _ fn _ = Some fn in + files := SMap.union first !files new_files; + files_uncap := SMap.union first !files_uncap new_files_uncap; + dirs := dir :: !dirs -let init l = - reset (); - List.iter add_dir (List.rev l) +let add_dir dir = add (Dir.create dir) let is_basename fn = Filename.basename fn = fn let find fn = + assert (not Config.merlin || Local_store.is_bound ()); if is_basename fn then SMap.find fn !files else Misc.find_in_path (get_paths ()) fn let find_uncap fn = + assert (not Config.merlin || Local_store.is_bound ()); if is_basename fn then SMap.find (String.uncapitalize_ascii fn) !files_uncap else diff --git a/utils/load_path.mli b/utils/load_path.mli index 433eaab7..ea9fe3d3 100644 --- a/utils/load_path.mli +++ b/utils/load_path.mli @@ -35,8 +35,7 @@ val init : string list -> unit (** [init l] is the same as [reset (); List.iter add_dir (List.rev l)] *) val get_paths : unit -> string list -(** Return the list of directories passed to [add_dir] so far, in - reverse order. *) +(** Return the list of directories passed to [add_dir] so far. *) val find : string -> string (** Locate a file in the load path. Raise [Not_found] if the file diff --git a/utils/local_store.ml b/utils/local_store.ml new file mode 100644 index 00000000..4babf61d --- /dev/null +++ b/utils/local_store.ml @@ -0,0 +1,74 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Frederic Bour, Tarides *) +(* Thomas Refis, Tarides *) +(* *) +(* Copyright 2020 Tarides *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +type ref_and_reset = + | Table : { ref: 'a ref; init: unit -> 'a } -> ref_and_reset + | Ref : { ref: 'a ref; mutable snapshot: 'a } -> ref_and_reset + +type bindings = { + mutable refs: ref_and_reset list; + mutable frozen : bool; + mutable is_bound: bool; +} + +let global_bindings = + { refs = []; is_bound = false; frozen = false } + +let is_bound () = global_bindings.is_bound + +let reset () = + assert (is_bound ()); + List.iter (function + | Table { ref; init } -> ref := init () + | Ref { ref; snapshot } -> ref := snapshot + ) global_bindings.refs + +let s_table create size = + let init () = create size in + let ref = ref (init ()) in + assert (not global_bindings.frozen); + global_bindings.refs <- (Table { ref; init }) :: global_bindings.refs; + ref + +let s_ref k = + let ref = ref k in + assert (not global_bindings.frozen); + global_bindings.refs <- + (Ref { ref; snapshot = k }) :: global_bindings.refs; + ref + +type slot = Slot : { ref : 'a ref; mutable value : 'a } -> slot +type store = slot list + +let fresh () = + let slots = + List.map (function + | Table { ref; init } -> Slot {ref; value = init ()} + | Ref r -> + if not global_bindings.frozen then r.snapshot <- !(r.ref); + Slot { ref = r.ref; value = r.snapshot } + ) global_bindings.refs + in + global_bindings.frozen <- true; + slots + +let with_store slots f = + assert (not global_bindings.is_bound); + global_bindings.is_bound <- true; + List.iter (fun (Slot {ref;value}) -> ref := value) slots; + Fun.protect f ~finally:(fun () -> + List.iter (fun (Slot s) -> s.value <- !(s.ref)) slots; + global_bindings.is_bound <- false; + ) diff --git a/utils/local_store.mli b/utils/local_store.mli new file mode 100644 index 00000000..f39cd123 --- /dev/null +++ b/utils/local_store.mli @@ -0,0 +1,66 @@ +(**************************************************************************) +(* *) +(* OCaml *) +(* *) +(* Frederic Bour, Tarides *) +(* Thomas Refis, Tarides *) +(* *) +(* Copyright 2020 Tarides *) +(* *) +(* All rights reserved. This file is distributed under the terms of *) +(* the GNU Lesser General Public License version 2.1, with the *) +(* special exception on linking described in the file LICENSE. *) +(* *) +(**************************************************************************) + +(** This module provides some facilities for creating references (and hash + tables) which can easily be snapshoted and restored to an arbitrary version. + + It is used throughout the frontend (read: typechecker), to register all + (well, hopefully) the global state. Thus making it easy for tools like + Merlin to go back and forth typechecking different files. *) + +(** {1 Creators} *) + +val s_ref : 'a -> 'a ref +(** Similar to {!ref}, except the allocated reference is registered into the + store. *) + +val s_table : ('a -> 'b) -> 'a -> 'b ref +(** Used to register hash tables. Those also need to be placed into refs to be + easily swapped out, but one can't just "snapshot" the initial value to + create fresh instances, so instead an initializer is required. + + Use it like this: + {[ + let my_table = s_table Hashtbl.create 42 + ]} +*) + +(** {1 State management} + + Note: all the following functions are currently unused inside the compiler + codebase. Merlin is their only user at the moment. *) + +type store + +val fresh : unit -> store +(** Returns a fresh instance of the store. + + The first time this function is called, it snapshots the value of all the + registered references, later calls to [fresh] will return instances + initialized to those values. *) + +val with_store : store -> (unit -> 'a) -> 'a +(** [with_scope s f] resets all the registered references to the value they have + in [s] for the run of [f]. + If [f] updates any of the registered refs, [s] is updated to remember those + changes. *) + +val reset : unit -> unit +(** Resets all the references to the initial snapshot (i.e. to the same values + that new instances start with). *) + +val is_bound : unit -> bool +(** Returns [true] when a scope is active (i.e. when called from the callback + passed to {!with_scope}), [false] otherwise. *) diff --git a/utils/misc.ml b/utils/misc.ml index df2e74d0..40979030 100644 --- a/utils/misc.ml +++ b/utils/misc.ml @@ -49,6 +49,11 @@ let try_finally ?(always=(fun () -> ())) ?(exceptionally=(fun () -> ())) work = Printexc.raise_with_backtrace always_exn always_bt end +let reraise_preserving_backtrace e f = + let bt = Printexc.get_raw_backtrace () in + f (); + Printexc.raise_with_backtrace e bt + type ref_and_value = R : 'a ref * 'a -> ref_and_value let protect_refs = @@ -110,14 +115,6 @@ module Stdlib = struct | (hd1 :: tl1, hd2 :: tl2) -> eq hd1 hd2 && equal eq tl1 tl2 | (_, _) -> false - let rec find_map f = function - | x :: xs -> - begin match f x with - | None -> find_map f xs - | Some _ as y -> y - end - | [] -> None - let map2_prefix f l1 l2 = let rec aux acc l1 l2 = match l1, l2 with diff --git a/utils/misc.mli b/utils/misc.mli index 9af10596..44437c9d 100644 --- a/utils/misc.mli +++ b/utils/misc.mli @@ -59,6 +59,10 @@ val try_finally : for easier debugging. *) +val reraise_preserving_backtrace : exn -> (unit -> unit) -> 'a +(** [reraise_preserving_backtrace e f] is (f (); raise e) except that the + current backtrace is preserved, even if [f] uses exceptions internally. *) + val map_end: ('a -> 'b) -> 'a list -> 'b list -> 'b list (* [map_end f l t] is [map f l @ t], just more efficient. *) @@ -94,12 +98,8 @@ module Stdlib : sig There is no constraint on the relative lengths of the lists. *) val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool - (** Returns [true] iff the given lists have the same length and content - with respect to the given equality function. *) - - val find_map : ('a -> 'b option) -> 'a t -> 'b option - (** [find_map f l] returns the first evaluation of [f] that returns [Some], - or returns None if there is no such element. *) + (** Returns [true] if and only if the given lists have the same length and + content with respect to the given equality function. *) val some_if_all_elements_are_some : 'a option t -> 'a t option (** If all elements of the given list are [Some _] then [Some xs] @@ -121,8 +121,8 @@ module Stdlib : sig -> 'a list -> of_:'a list -> bool - (** Returns [true] iff the given list, with respect to the given equality - function on list members, is a prefix of the list [of_]. *) + (** Returns [true] if and only if the given list, with respect to the given + equality function on list members, is a prefix of the list [of_]. *) type 'a longest_common_prefix_result = private { longest_common_prefix : 'a list; diff --git a/utils/warnings.ml b/utils/warnings.ml index 7adb3495..df2bb305 100644 --- a/utils/warnings.ml +++ b/utils/warnings.ml @@ -29,22 +29,22 @@ type t = | Comment_not_end (* 2 *) (*| Deprecated --> alert "deprecated" *) (* 3 *) | Fragile_match of string (* 4 *) - | Partial_application (* 5 *) + | Ignored_partial_application (* 5 *) | Labels_omitted of string list (* 6 *) | Method_override of string list (* 7 *) | Partial_match of string (* 8 *) - | Non_closed_record_pattern of string (* 9 *) - | Statement_type (* 10 *) - | Unused_match (* 11 *) - | Unused_pat (* 12 *) + | Missing_record_field_pattern of string (* 9 *) + | Non_unit_statement (* 10 *) + | Redundant_case (* 11 *) + | Redundant_subpat (* 12 *) | Instance_variable_override of string list (* 13 *) | Illegal_backslash (* 14 *) | Implicit_public_methods of string list (* 15 *) | Unerasable_optional_argument (* 16 *) | Undeclared_virtual_method of string (* 17 *) | Not_principal of string (* 18 *) - | Without_principality of string (* 19 *) - | Unused_argument (* 20 *) + | Non_principal_labels of string (* 19 *) + | Ignored_extra_argument (* 20 *) | Nonreturning_statement (* 21 *) | Preprocessor of string (* 22 *) | Useless_record_with (* 23 *) @@ -55,7 +55,7 @@ type t = | Wildcard_arg_to_constant_constr (* 28 *) | Eol_in_string (* 29 *) | Duplicate_definitions of string * string * string * string (*30 *) - | Multiple_definition of string * string * string (* 31 *) + | Module_linked_twice of string * string * string (* 31 *) | Unused_value_declaration of string (* 32 *) | Unused_open of string (* 33 *) | Unused_type_declaration of string (* 34 *) @@ -74,24 +74,25 @@ type t = | Attribute_payload of string * string (* 47 *) | Eliminated_optional_arguments of string list (* 48 *) | No_cmi_file of string * string option (* 49 *) - | Bad_docstring of bool (* 50 *) - | Expect_tailcall (* 51 *) + | Unexpected_docstring of bool (* 50 *) + | Wrong_tailcall_expectation of bool (* 51 *) | Fragile_literal_pattern (* 52 *) | Misplaced_attribute of string (* 53 *) | Duplicated_attribute of string (* 54 *) | Inlining_impossible of string (* 55 *) | Unreachable_case (* 56 *) - | Ambiguous_pattern of string list (* 57 *) + | Ambiguous_var_in_pattern_guard of string list (* 57 *) | No_cmx_file of string (* 58 *) - | Assignment_to_non_mutable_value (* 59 *) + | Flambda_assignment_to_non_mutable_value (* 59 *) | Unused_module of string (* 60 *) | Unboxable_type_in_prim_decl of string (* 61 *) | Constraint_on_gadt (* 62 *) | Erroneous_printed_signature of string (* 63 *) - | Unsafe_without_parsing (* 64 *) + | Unsafe_array_syntax_without_parsing (* 64 *) | Redefining_unit of string (* 65 *) | Unused_open_bang of string (* 66 *) | Unused_functor_parameter of string (* 67 *) + | Match_on_mutable_state_prevent_uncurry (* 68 *) ;; (* If you remove a warning, leave a hole in the numbering. NEVER change @@ -102,27 +103,26 @@ type t = type alert = {kind:string; message:string; def:loc; use:loc} - let number = function | Comment_start -> 1 | Comment_not_end -> 2 | Fragile_match _ -> 4 - | Partial_application -> 5 + | Ignored_partial_application -> 5 | Labels_omitted _ -> 6 | Method_override _ -> 7 | Partial_match _ -> 8 - | Non_closed_record_pattern _ -> 9 - | Statement_type -> 10 - | Unused_match -> 11 - | Unused_pat -> 12 + | Missing_record_field_pattern _ -> 9 + | Non_unit_statement -> 10 + | Redundant_case -> 11 + | Redundant_subpat -> 12 | Instance_variable_override _ -> 13 | Illegal_backslash -> 14 | Implicit_public_methods _ -> 15 | Unerasable_optional_argument -> 16 | Undeclared_virtual_method _ -> 17 | Not_principal _ -> 18 - | Without_principality _ -> 19 - | Unused_argument -> 20 + | Non_principal_labels _ -> 19 + | Ignored_extra_argument -> 20 | Nonreturning_statement -> 21 | Preprocessor _ -> 22 | Useless_record_with -> 23 @@ -133,7 +133,7 @@ let number = function | Wildcard_arg_to_constant_constr -> 28 | Eol_in_string -> 29 | Duplicate_definitions _ -> 30 - | Multiple_definition _ -> 31 + | Module_linked_twice _ -> 31 | Unused_value_declaration _ -> 32 | Unused_open _ -> 33 | Unused_type_declaration _ -> 34 @@ -152,27 +152,195 @@ let number = function | Attribute_payload _ -> 47 | Eliminated_optional_arguments _ -> 48 | No_cmi_file _ -> 49 - | Bad_docstring _ -> 50 - | Expect_tailcall -> 51 + | Unexpected_docstring _ -> 50 + | Wrong_tailcall_expectation _ -> 51 | Fragile_literal_pattern -> 52 | Misplaced_attribute _ -> 53 | Duplicated_attribute _ -> 54 | Inlining_impossible _ -> 55 | Unreachable_case -> 56 - | Ambiguous_pattern _ -> 57 + | Ambiguous_var_in_pattern_guard _ -> 57 | No_cmx_file _ -> 58 - | Assignment_to_non_mutable_value -> 59 + | Flambda_assignment_to_non_mutable_value -> 59 | Unused_module _ -> 60 | Unboxable_type_in_prim_decl _ -> 61 | Constraint_on_gadt -> 62 | Erroneous_printed_signature _ -> 63 - | Unsafe_without_parsing -> 64 + | Unsafe_array_syntax_without_parsing -> 64 | Redefining_unit _ -> 65 | Unused_open_bang _ -> 66 | Unused_functor_parameter _ -> 67 + | Match_on_mutable_state_prevent_uncurry -> 68 +;; + +let last_warning_number = 68 ;; -let last_warning_number = 67 +(* Third component of each tuple is the list of names for each warning. The + first element of the list is the current name, any following ones are + deprecated. The current name should always be derived mechanically from the + constructor name. *) + +let descriptions = + [ + 1, "Suspicious-looking start-of-comment mark.", + ["comment-start"]; + 2, "Suspicious-looking end-of-comment mark.", + ["comment-not-end"]; + 3, "Deprecated synonym for the 'deprecated' alert.", + []; + 4, "Fragile pattern matching: matching that will remain complete even\n\ + \ if additional constructors are added to one of the variant types\n\ + \ matched.", + ["fragile-match"]; + 5, "Partially applied function: expression whose result has function\n\ + \ type and is ignored.", + ["ignored-partial-application"]; + 6, "Label omitted in function application.", + ["labels-omitted"]; + 7, "Method overridden.", + ["method-override"]; + 8, "Partial match: missing cases in pattern-matching.", + ["partial-match"]; + 9, "Missing fields in a record pattern.", + ["missing-record-field-pattern"]; + 10, + "Expression on the left-hand side of a sequence that doesn't have type\n\ + \ \"unit\" (and that is not a function, see warning number 5).", + ["non-unit-statement"]; + 11, "Redundant case in a pattern matching (unused match case).", + ["redundant-case"]; + 12, "Redundant sub-pattern in a pattern-matching.", + ["redundant-subpat"]; + 13, "Instance variable overridden.", + ["instance-variable-override"]; + 14, "Illegal backslash escape in a string constant.", + ["illegal-backslash"]; + 15, "Private method made public implicitly.", + ["implicit-public-methods"]; + 16, "Unerasable optional argument.", + ["unerasable-optional-argument"]; + 17, "Undeclared virtual method.", + ["undeclared-virtual-method"]; + 18, "Non-principal type.", + ["not-principal"]; + 19, "Type without principality.", + ["non-principal-labels"]; + 20, "Unused function argument.", + ["ignored-extra-argument"]; + 21, "Non-returning statement.", + ["nonreturning-statement"]; + 22, "Preprocessor warning.", + ["preprocessor"]; + 23, "Useless record \"with\" clause.", + ["useless-record-with"]; + 24, + "Bad module name: the source file name is not a valid OCaml module name.", + ["bad-module-name"]; + 25, "Ignored: now part of warning 8.", + []; + 26, + "Suspicious unused variable: unused variable that is bound\n\ + \ with \"let\" or \"as\", and doesn't start with an underscore (\"_\")\n\ + \ character.", + ["unused-var"]; + 27, "Innocuous unused variable: unused variable that is not bound with\n\ + \ \"let\" nor \"as\", and doesn't start with an underscore (\"_\")\n\ + \ character.", + ["unused-var-strict"]; + 28, "Wildcard pattern given as argument to a constant constructor.", + ["wildcard-arg-to-constant-constr"]; + 29, "Unescaped end-of-line in a string constant (non-portable code).", + ["eol-in-string"]; + 30, "Two labels or constructors of the same name are defined in two\n\ + \ mutually recursive types.", + ["duplicate-definitions"]; + 31, "A module is linked twice in the same executable.", + ["module-linked-twice"]; + 32, "Unused value declaration.", + ["unused-value-declaration"]; + 33, "Unused open statement.", + ["unused-open"]; + 34, "Unused type declaration.", + ["unused-type-declaration"]; + 35, "Unused for-loop index.", + ["unused-for-index"]; + 36, "Unused ancestor variable.", + ["unused-ancestor"]; + 37, "Unused constructor.", + ["unused-constructor"]; + 38, "Unused extension constructor.", + ["unused-extension"]; + 39, "Unused rec flag.", + ["unused-rec-flag"]; + 40, "Constructor or label name used out of scope.", + ["name-out-of-scope"]; + 41, "Ambiguous constructor or label name.", + ["ambiguous-name"]; + 42, "Disambiguated constructor or label name (compatibility warning).", + ["disambiguated-name"]; + 43, "Nonoptional label applied as optional.", + ["nonoptional-label"]; + 44, "Open statement shadows an already defined identifier.", + ["open-shadow-identifier"]; + 45, "Open statement shadows an already defined label or constructor.", + ["open-shadow-label-constructor"]; + 46, "Error in environment variable.", + ["bad-env-variable"]; + 47, "Illegal attribute payload.", + ["attribute-payload"]; + 48, "Implicit elimination of optional arguments.", + ["eliminated-optional-arguments"]; + 49, "Absent cmi file when looking up module alias.", + ["no-cmi-file"]; + 50, "Unexpected documentation comment.", + ["unexpected-docstring"]; + 51, "Function call annotated with an incorrect @tailcall attribute", + ["wrong-tailcall-expectation"]; + 52, "Fragile constant pattern.", + ["fragile-literal-pattern"]; + 53, "Attribute cannot appear in this context.", + ["misplaced-attribute"]; + 54, "Attribute used more than once on an expression.", + ["duplicated-attribute"]; + 55, "Inlining impossible.", + ["inlining-impossible"]; + 56, "Unreachable case in a pattern-matching (based on type information).", + ["unreachable-case"]; + 57, "Ambiguous or-pattern variables under guard.", + ["ambiguous-var-in-pattern-guard"]; + 58, "Missing cmx file.", + ["no-cmx-file"]; + 59, "Assignment to non-mutable value.", + ["flambda-assignment-to-non-mutable-value"]; + 60, "Unused module declaration.", + ["unused-module"]; + 61, "Unboxable type in primitive declaration.", + ["unboxable-type-in-prim-decl"]; + 62, "Type constraint on GADT type declaration.", + ["constraint-on-gadt"]; + 63, "Erroneous printed signature.", + ["erroneous-printed-signature"]; + 64, "-unsafe used with a preprocessor returning a syntax tree.", + ["unsafe-array-syntax-without-parsing"]; + 65, "Type declaration defining a new '()' constructor.", + ["redefining-unit"]; + 66, "Unused open! statement.", + ["unused-open-bang"]; + 67, "Unused functor parameter.", + ["unused-functor-parameter"]; + 68, "Pattern-matching depending on mutable state prevents the remaining \ + arguments from being uncurried.", + ["match-on-mutable-state-prevent-uncurry"]; + ] +;; + +let name_to_number = + let h = Hashtbl.create last_warning_number in + List.iter (fun (num, _, names) -> + List.iter (fun name -> Hashtbl.add h name num) names + ) descriptions; + fun s -> Hashtbl.find_opt h s ;; (* Must be the max number returned by the [number] function. *) @@ -383,7 +551,18 @@ let parse_opt error active errflag s = loop (i+1) | _ -> error () in - loop 0 + match name_to_number s with + | Some n -> set n + | None -> + if s = "" then loop 0 + else begin + let rest = String.sub s 1 (String.length s - 1) in + match s.[0], name_to_number rest with + | '+', Some n -> set n + | '-', Some n -> clear n + | '@', Some n -> set_all n + | _ -> loop 0 + end ;; let parse_options errflag s = @@ -393,7 +572,7 @@ let parse_options errflag s = current := {(!current) with error; active} (* If you change these, don't forget to change them in man/ocamlc.m *) -let defaults_w = "+a-4-6-7-9-27-29-30-32..42-44-45-48-50-60-66-67";; +let defaults_w = "+a-4-6-7-9-27-29-30-32..42-44-45-48-50-60-66-67-68";; let defaults_warn_error = "-a+31";; let () = parse_options false defaults_w;; @@ -415,7 +594,7 @@ let message = function | Fragile_match s -> "this pattern-matching is fragile.\n\ It will remain exhaustive when constructors are added to type " ^ s ^ "." - | Partial_application -> + | Ignored_partial_application -> "this function application is partial,\n\ maybe some arguments are missing." | Labels_omitted [] -> assert false @@ -435,13 +614,13 @@ let message = function | Partial_match s -> "this pattern-matching is not exhaustive.\n\ Here is an example of a case that is not matched:\n" ^ s - | Non_closed_record_pattern s -> + | Missing_record_field_pattern s -> "the following labels are not bound in this record pattern:\n" ^ s ^ "\nEither bind these labels explicitly or add '; _' to the pattern." - | Statement_type -> + | Non_unit_statement -> "this expression should have type unit." - | Unused_match -> "this match case is unused." - | Unused_pat -> "this sub-pattern is unused." + | Redundant_case -> "this match case is unused." + | Redundant_subpat -> "this sub-pattern is unused." | Instance_variable_override [lab] -> "the instance variable " ^ lab ^ " is overridden.\n" ^ "The behaviour changed in ocaml 3.10 (previous behaviour was hiding.)" @@ -458,8 +637,8 @@ let message = function | Unerasable_optional_argument -> "this optional argument cannot be erased." | Undeclared_virtual_method m -> "the virtual method "^m^" is not declared." | Not_principal s -> s^" is not principal." - | Without_principality s -> s^" without principality." - | Unused_argument -> "this argument will not be used by the function." + | Non_principal_labels s -> s^" without principality." + | Ignored_extra_argument -> "this argument will not be used by the function." | Nonreturning_statement -> "this statement never returns (or has an unsound type.)" | Preprocessor s -> s @@ -479,7 +658,7 @@ let message = function | Duplicate_definitions (kind, cname, tc1, tc2) -> Printf.sprintf "the %s %s is defined in both types %s and %s." kind cname tc1 tc2 - | Multiple_definition(modname, file1, file2) -> + | Module_linked_twice(modname, file1, file2) -> Printf.sprintf "files %s and %s both define a module named %s" file1 file2 modname @@ -562,11 +741,12 @@ let message = function Printf.sprintf "no valid cmi file was found in path for module %s. %s" name msg - | Bad_docstring unattached -> + | Unexpected_docstring unattached -> if unattached then "unattached documentation comment (ignored)" else "ambiguous documentation comment" - | Expect_tailcall -> - Printf.sprintf "expected tailcall" + | Wrong_tailcall_expectation b -> + Printf.sprintf "expected %s" + (if b then "tailcall" else "non-tailcall") | Fragile_literal_pattern -> Printf.sprintf "Code should not depend on the actual values of\n\ @@ -583,7 +763,7 @@ let message = function attr_name | Inlining_impossible reason -> Printf.sprintf "Cannot inline: %s" reason - | Ambiguous_pattern vars -> + | Ambiguous_var_in_pattern_guard vars -> let msg = let vars = List.sort String.compare vars in match vars with @@ -599,7 +779,7 @@ let message = function Printf.sprintf "no cmx file was found in path for module %s, \ and its interface was not compiled with -opaque" name - | Assignment_to_non_mutable_value -> + | Flambda_assignment_to_non_mutable_value -> "A potential assignment to a non-mutable value was detected \n\ in this source file. Such assignments may generate incorrect code \n\ when using Flambda." @@ -623,7 +803,7 @@ let message = function ^ s ^ "\nBeware that this warning is purely informational and will not catch\n\ all instances of erroneous printed interface." - | Unsafe_without_parsing -> + | Unsafe_array_syntax_without_parsing -> "option -unsafe used with a preprocessor returning a syntax tree" | Redefining_unit name -> Printf.sprintf @@ -631,6 +811,10 @@ let message = function which shadows the existing one.\n\ Hint: Did you mean 'type %s = unit'?" name | Unused_functor_parameter s -> "unused functor parameter " ^ s ^ "." + | Match_on_mutable_state_prevent_uncurry -> + "This pattern depends on mutable state.\n\ + It prevents the remaining arguments from being uncurried, which will \ + cause additional closure allocations." ;; let nerrors = ref 0;; @@ -642,13 +826,21 @@ type reporting_information = ; sub_locs : (loc * string) list; } +let id_name w = + let n = number w in + match List.find_opt (fun (m, _, _) -> m = n) descriptions with + | Some (_, _, s :: _) -> + Printf.sprintf "%d [%s]" n s + | _ -> + string_of_int n + let report w = match is_active w with | false -> `Inactive | true -> if is_error w then incr nerrors; `Active - { id = string_of_int (number w); + { id = id_name w; message = message w; is_error = is_error w; sub_locs = []; @@ -696,91 +888,16 @@ let check_fatal () = end; ;; -let descriptions = - [ - 1, "Suspicious-looking start-of-comment mark."; - 2, "Suspicious-looking end-of-comment mark."; - 3, "Deprecated synonym for the 'deprecated' alert."; - 4, "Fragile pattern matching: matching that will remain complete even\n\ - \ if additional constructors are added to one of the variant types\n\ - \ matched."; - 5, "Partially applied function: expression whose result has function\n\ - \ type and is ignored."; - 6, "Label omitted in function application."; - 7, "Method overridden."; - 8, "Partial match: missing cases in pattern-matching."; - 9, "Missing fields in a record pattern."; - 10, "Expression on the left-hand side of a sequence that doesn't have \ - type\n\ - \ \"unit\" (and that is not a function, see warning number 5)."; - 11, "Redundant case in a pattern matching (unused match case)."; - 12, "Redundant sub-pattern in a pattern-matching."; - 13, "Instance variable overridden."; - 14, "Illegal backslash escape in a string constant."; - 15, "Private method made public implicitly."; - 16, "Unerasable optional argument."; - 17, "Undeclared virtual method."; - 18, "Non-principal type."; - 19, "Type without principality."; - 20, "Unused function argument."; - 21, "Non-returning statement."; - 22, "Preprocessor warning."; - 23, "Useless record \"with\" clause."; - 24, "Bad module name: the source file name is not a valid OCaml module \ - name."; - 25, "Deprecated: now part of warning 8."; - 26, "Suspicious unused variable: unused variable that is bound\n\ - \ with \"let\" or \"as\", and doesn't start with an underscore (\"_\")\n\ - \ character."; - 27, "Innocuous unused variable: unused variable that is not bound with\n\ - \ \"let\" nor \"as\", and doesn't start with an underscore (\"_\")\n\ - \ character."; - 28, "Wildcard pattern given as argument to a constant constructor."; - 29, "Unescaped end-of-line in a string constant (non-portable code)."; - 30, "Two labels or constructors of the same name are defined in two\n\ - \ mutually recursive types."; - 31, "A module is linked twice in the same executable."; - 32, "Unused value declaration."; - 33, "Unused open statement."; - 34, "Unused type declaration."; - 35, "Unused for-loop index."; - 36, "Unused ancestor variable."; - 37, "Unused constructor."; - 38, "Unused extension constructor."; - 39, "Unused rec flag."; - 40, "Constructor or label name used out of scope."; - 41, "Ambiguous constructor or label name."; - 42, "Disambiguated constructor or label name (compatibility warning)."; - 43, "Nonoptional label applied as optional."; - 44, "Open statement shadows an already defined identifier."; - 45, "Open statement shadows an already defined label or constructor."; - 46, "Error in environment variable."; - 47, "Illegal attribute payload."; - 48, "Implicit elimination of optional arguments."; - 49, "Absent cmi file when looking up module alias."; - 50, "Unexpected documentation comment."; - 51, "Warning on non-tail calls if @tailcall present."; - 52, "Fragile constant pattern."; - 53, "Attribute cannot appear in this context."; - 54, "Attribute used more than once on an expression."; - 55, "Inlining impossible."; - 56, "Unreachable case in a pattern-matching (based on type information)."; - 57, "Ambiguous or-pattern variables under guard."; - 58, "Missing cmx file."; - 59, "Assignment to non-mutable value."; - 60, "Unused module declaration."; - 61, "Unboxable type in primitive declaration."; - 62, "Type constraint on GADT type declaration."; - 63, "Erroneous printed signature."; - 64, "-unsafe used with a preprocessor returning a syntax tree."; - 65, "Type declaration defining a new '()' constructor."; - 66, "Unused open! statement."; - 67, "Unused functor parameter."; - ] -;; - let help_warnings () = - List.iter (fun (i, s) -> Printf.printf "%3i %s\n" i s) descriptions; + List.iter + (fun (i, s, names) -> + let name = + match names with + | s :: _ -> " [" ^ s ^ "]" + | [] -> "" + in + Printf.printf "%3i%s %s\n" i name s) + descriptions; print_endline " A all warnings"; for i = Char.code 'b' to Char.code 'z' do let c = Char.chr i in diff --git a/utils/warnings.mli b/utils/warnings.mli index b80ab34c..c94ea72f 100644 --- a/utils/warnings.mli +++ b/utils/warnings.mli @@ -31,22 +31,22 @@ type t = | Comment_not_end (* 2 *) (*| Deprecated --> alert "deprecated" *) (* 3 *) | Fragile_match of string (* 4 *) - | Partial_application (* 5 *) + | Ignored_partial_application (* 5 *) | Labels_omitted of string list (* 6 *) | Method_override of string list (* 7 *) | Partial_match of string (* 8 *) - | Non_closed_record_pattern of string (* 9 *) - | Statement_type (* 10 *) - | Unused_match (* 11 *) - | Unused_pat (* 12 *) + | Missing_record_field_pattern of string (* 9 *) + | Non_unit_statement (* 10 *) + | Redundant_case (* 11 *) + | Redundant_subpat (* 12 *) | Instance_variable_override of string list (* 13 *) | Illegal_backslash (* 14 *) | Implicit_public_methods of string list (* 15 *) | Unerasable_optional_argument (* 16 *) | Undeclared_virtual_method of string (* 17 *) | Not_principal of string (* 18 *) - | Without_principality of string (* 19 *) - | Unused_argument (* 20 *) + | Non_principal_labels of string (* 19 *) + | Ignored_extra_argument (* 20 *) | Nonreturning_statement (* 21 *) | Preprocessor of string (* 22 *) | Useless_record_with (* 23 *) @@ -57,7 +57,7 @@ type t = | Wildcard_arg_to_constant_constr (* 28 *) | Eol_in_string (* 29 *) | Duplicate_definitions of string * string * string * string (* 30 *) - | Multiple_definition of string * string * string (* 31 *) + | Module_linked_twice of string * string * string (* 31 *) | Unused_value_declaration of string (* 32 *) | Unused_open of string (* 33 *) | Unused_type_declaration of string (* 34 *) @@ -76,24 +76,25 @@ type t = | Attribute_payload of string * string (* 47 *) | Eliminated_optional_arguments of string list (* 48 *) | No_cmi_file of string * string option (* 49 *) - | Bad_docstring of bool (* 50 *) - | Expect_tailcall (* 51 *) + | Unexpected_docstring of bool (* 50 *) + | Wrong_tailcall_expectation of bool (* 51 *) | Fragile_literal_pattern (* 52 *) | Misplaced_attribute of string (* 53 *) | Duplicated_attribute of string (* 54 *) | Inlining_impossible of string (* 55 *) | Unreachable_case (* 56 *) - | Ambiguous_pattern of string list (* 57 *) + | Ambiguous_var_in_pattern_guard of string list (* 57 *) | No_cmx_file of string (* 58 *) - | Assignment_to_non_mutable_value (* 59 *) + | Flambda_assignment_to_non_mutable_value (* 59 *) | Unused_module of string (* 60 *) | Unboxable_type_in_prim_decl of string (* 61 *) | Constraint_on_gadt (* 62 *) | Erroneous_printed_signature of string (* 63 *) - | Unsafe_without_parsing (* 64 *) + | Unsafe_array_syntax_without_parsing (* 64 *) | Redefining_unit of string (* 65 *) | Unused_open_bang of string (* 66 *) | Unused_functor_parameter of string (* 67 *) + | Match_on_mutable_state_prevent_uncurry (* 68 *) ;; type alert = {kind:string; message:string; def:loc; use:loc} diff --git a/yacc/Makefile b/yacc/Makefile index 82b91980..3c4425a8 100644 --- a/yacc/Makefile +++ b/yacc/Makefile @@ -17,8 +17,7 @@ ROOTDIR = .. --include $(ROOTDIR)/Makefile.config --include $(ROOTDIR)/Makefile.common +include $(ROOTDIR)/Makefile.common OC_CPPFLAGS += -I$(ROOTDIR)/runtime -- 2.30.2

    6%~!S?pC91G1N^eSEfBX}4_WLHC+`GkGWkQ+ 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≻Q3wB33-hb$$Gnv3(ialbR;B$ip8Q#$67K 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%0AE;S=vh7Uo51sVM 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