merge branch 4.02 from 4.02.1 (rev 15540) to a few fixes after 4.02.2 (rev 16205)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16214 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02master
parent
7fdba8f533
commit
860c670848
61
.depend
61
.depend
|
@ -28,12 +28,13 @@ parsing/ast_helper.cmi : parsing/parsetree.cmi parsing/longident.cmi \
|
||||||
parsing/location.cmi parsing/docstrings.cmi parsing/asttypes.cmi
|
parsing/location.cmi parsing/docstrings.cmi parsing/asttypes.cmi
|
||||||
parsing/ast_mapper.cmi : parsing/parsetree.cmi parsing/location.cmi
|
parsing/ast_mapper.cmi : parsing/parsetree.cmi parsing/location.cmi
|
||||||
parsing/asttypes.cmi : parsing/location.cmi
|
parsing/asttypes.cmi : parsing/location.cmi
|
||||||
parsing/docstrings.cmi : parsing/location.cmi parsing/parsetree.cmi
|
parsing/docstrings.cmi : parsing/parsetree.cmi parsing/location.cmi
|
||||||
parsing/lexer.cmi : parsing/parser.cmi parsing/location.cmi
|
parsing/lexer.cmi : parsing/parser.cmi parsing/location.cmi
|
||||||
parsing/location.cmi : utils/warnings.cmi
|
parsing/location.cmi : utils/warnings.cmi
|
||||||
parsing/longident.cmi :
|
parsing/longident.cmi :
|
||||||
parsing/parse.cmi : parsing/parsetree.cmi
|
parsing/parse.cmi : parsing/parsetree.cmi
|
||||||
parsing/parser.cmi : parsing/parsetree.cmi parsing/location.cmi
|
parsing/parser.cmi : parsing/parsetree.cmi parsing/location.cmi \
|
||||||
|
parsing/docstrings.cmi
|
||||||
parsing/parsetree.cmi : parsing/longident.cmi parsing/location.cmi \
|
parsing/parsetree.cmi : parsing/longident.cmi parsing/location.cmi \
|
||||||
parsing/asttypes.cmi
|
parsing/asttypes.cmi
|
||||||
parsing/pprintast.cmi : parsing/parsetree.cmi parsing/longident.cmi \
|
parsing/pprintast.cmi : parsing/parsetree.cmi parsing/longident.cmi \
|
||||||
|
@ -54,10 +55,10 @@ parsing/ast_mapper.cmx : parsing/parsetree.cmi utils/misc.cmx \
|
||||||
parsing/longident.cmx parsing/location.cmx utils/config.cmx \
|
parsing/longident.cmx parsing/location.cmx utils/config.cmx \
|
||||||
utils/clflags.cmx parsing/asttypes.cmi parsing/ast_helper.cmx \
|
utils/clflags.cmx parsing/asttypes.cmi parsing/ast_helper.cmx \
|
||||||
parsing/ast_mapper.cmi
|
parsing/ast_mapper.cmi
|
||||||
parsing/docstrings.cmo : utils/warnings.cmi parsing/location.cmi \
|
parsing/docstrings.cmo : utils/warnings.cmi parsing/parsetree.cmi \
|
||||||
parsing/docstrings.cmi
|
parsing/location.cmi parsing/asttypes.cmi parsing/docstrings.cmi
|
||||||
parsing/docstrings.cmx : utils/warnings.cmx parsing/location.cmx \
|
parsing/docstrings.cmx : utils/warnings.cmx parsing/parsetree.cmi \
|
||||||
parsing/docstrings.cmi
|
parsing/location.cmx parsing/asttypes.cmi parsing/docstrings.cmi
|
||||||
parsing/lexer.cmo : utils/warnings.cmi parsing/parser.cmi utils/misc.cmi \
|
parsing/lexer.cmo : utils/warnings.cmi parsing/parser.cmi utils/misc.cmi \
|
||||||
parsing/location.cmi parsing/docstrings.cmi parsing/lexer.cmi
|
parsing/location.cmi parsing/docstrings.cmi parsing/lexer.cmi
|
||||||
parsing/lexer.cmx : utils/warnings.cmx parsing/parser.cmx utils/misc.cmx \
|
parsing/lexer.cmx : utils/warnings.cmx parsing/parser.cmx utils/misc.cmx \
|
||||||
|
@ -75,11 +76,13 @@ parsing/parse.cmx : parsing/syntaxerr.cmx parsing/parser.cmx \
|
||||||
parsing/location.cmx parsing/lexer.cmx parsing/docstrings.cmx \
|
parsing/location.cmx parsing/lexer.cmx parsing/docstrings.cmx \
|
||||||
parsing/parse.cmi
|
parsing/parse.cmi
|
||||||
parsing/parser.cmo : parsing/syntaxerr.cmi parsing/parsetree.cmi \
|
parsing/parser.cmo : parsing/syntaxerr.cmi parsing/parsetree.cmi \
|
||||||
parsing/longident.cmi parsing/location.cmi utils/clflags.cmi \
|
parsing/longident.cmi parsing/location.cmi parsing/docstrings.cmi \
|
||||||
parsing/asttypes.cmi parsing/ast_helper.cmi parsing/parser.cmi
|
utils/clflags.cmi parsing/asttypes.cmi parsing/ast_helper.cmi \
|
||||||
|
parsing/parser.cmi
|
||||||
parsing/parser.cmx : parsing/syntaxerr.cmx parsing/parsetree.cmi \
|
parsing/parser.cmx : parsing/syntaxerr.cmx parsing/parsetree.cmi \
|
||||||
parsing/longident.cmx parsing/location.cmx utils/clflags.cmx \
|
parsing/longident.cmx parsing/location.cmx parsing/docstrings.cmx \
|
||||||
parsing/asttypes.cmi parsing/ast_helper.cmx parsing/parser.cmi
|
utils/clflags.cmx parsing/asttypes.cmi parsing/ast_helper.cmx \
|
||||||
|
parsing/parser.cmi
|
||||||
parsing/pprintast.cmo : parsing/parsetree.cmi utils/misc.cmi \
|
parsing/pprintast.cmo : parsing/parsetree.cmi utils/misc.cmi \
|
||||||
parsing/longident.cmi parsing/location.cmi parsing/asttypes.cmi \
|
parsing/longident.cmi parsing/location.cmi parsing/asttypes.cmi \
|
||||||
parsing/pprintast.cmi
|
parsing/pprintast.cmi
|
||||||
|
@ -458,15 +461,17 @@ bytecomp/bytelibrarian.cmx : utils/misc.cmx parsing/location.cmx \
|
||||||
utils/config.cmx bytecomp/cmo_format.cmi utils/clflags.cmx \
|
utils/config.cmx bytecomp/cmo_format.cmi utils/clflags.cmx \
|
||||||
bytecomp/bytelink.cmx bytecomp/bytelibrarian.cmi
|
bytecomp/bytelink.cmx bytecomp/bytelibrarian.cmi
|
||||||
bytecomp/bytelink.cmo : utils/warnings.cmi bytecomp/symtable.cmi \
|
bytecomp/bytelink.cmo : utils/warnings.cmi bytecomp/symtable.cmi \
|
||||||
bytecomp/opcodes.cmo utils/misc.cmi parsing/location.cmi typing/ident.cmi \
|
bytecomp/opcodes.cmo utils/misc.cmi parsing/location.cmi \
|
||||||
bytecomp/dll.cmi utils/consistbl.cmi utils/config.cmi \
|
bytecomp/instruct.cmi typing/ident.cmi bytecomp/dll.cmi \
|
||||||
bytecomp/cmo_format.cmi utils/clflags.cmi utils/ccomp.cmi \
|
utils/consistbl.cmi utils/config.cmi bytecomp/cmo_format.cmi \
|
||||||
bytecomp/bytesections.cmi bytecomp/bytelink.cmi
|
utils/clflags.cmi utils/ccomp.cmi bytecomp/bytesections.cmi \
|
||||||
|
bytecomp/bytelink.cmi
|
||||||
bytecomp/bytelink.cmx : utils/warnings.cmx bytecomp/symtable.cmx \
|
bytecomp/bytelink.cmx : utils/warnings.cmx bytecomp/symtable.cmx \
|
||||||
bytecomp/opcodes.cmx utils/misc.cmx parsing/location.cmx typing/ident.cmx \
|
bytecomp/opcodes.cmx utils/misc.cmx parsing/location.cmx \
|
||||||
bytecomp/dll.cmx utils/consistbl.cmx utils/config.cmx \
|
bytecomp/instruct.cmx typing/ident.cmx bytecomp/dll.cmx \
|
||||||
bytecomp/cmo_format.cmi utils/clflags.cmx utils/ccomp.cmx \
|
utils/consistbl.cmx utils/config.cmx bytecomp/cmo_format.cmi \
|
||||||
bytecomp/bytesections.cmx bytecomp/bytelink.cmi
|
utils/clflags.cmx utils/ccomp.cmx bytecomp/bytesections.cmx \
|
||||||
|
bytecomp/bytelink.cmi
|
||||||
bytecomp/bytepackager.cmo : typing/typemod.cmi bytecomp/translmod.cmi \
|
bytecomp/bytepackager.cmo : typing/typemod.cmi bytecomp/translmod.cmi \
|
||||||
typing/subst.cmi bytecomp/printlambda.cmi typing/path.cmi utils/misc.cmi \
|
typing/subst.cmi bytecomp/printlambda.cmi typing/path.cmi utils/misc.cmi \
|
||||||
parsing/location.cmi bytecomp/instruct.cmi typing/ident.cmi \
|
parsing/location.cmi bytecomp/instruct.cmi typing/ident.cmi \
|
||||||
|
@ -549,12 +554,12 @@ bytecomp/switch.cmo : bytecomp/switch.cmi
|
||||||
bytecomp/switch.cmx : bytecomp/switch.cmi
|
bytecomp/switch.cmx : bytecomp/switch.cmi
|
||||||
bytecomp/symtable.cmo : utils/tbl.cmi bytecomp/runtimedef.cmi \
|
bytecomp/symtable.cmo : utils/tbl.cmi bytecomp/runtimedef.cmi \
|
||||||
typing/predef.cmi utils/misc.cmi bytecomp/meta.cmi parsing/location.cmi \
|
typing/predef.cmi utils/misc.cmi bytecomp/meta.cmi parsing/location.cmi \
|
||||||
bytecomp/lambda.cmi typing/ident.cmi bytecomp/dll.cmi \
|
bytecomp/lambda.cmi typing/ident.cmi bytecomp/dll.cmi utils/config.cmi \
|
||||||
bytecomp/cmo_format.cmi utils/clflags.cmi bytecomp/bytesections.cmi \
|
bytecomp/cmo_format.cmi utils/clflags.cmi bytecomp/bytesections.cmi \
|
||||||
parsing/asttypes.cmi bytecomp/symtable.cmi
|
parsing/asttypes.cmi bytecomp/symtable.cmi
|
||||||
bytecomp/symtable.cmx : utils/tbl.cmx bytecomp/runtimedef.cmx \
|
bytecomp/symtable.cmx : utils/tbl.cmx bytecomp/runtimedef.cmx \
|
||||||
typing/predef.cmx utils/misc.cmx bytecomp/meta.cmx parsing/location.cmx \
|
typing/predef.cmx utils/misc.cmx bytecomp/meta.cmx parsing/location.cmx \
|
||||||
bytecomp/lambda.cmx typing/ident.cmx bytecomp/dll.cmx \
|
bytecomp/lambda.cmx typing/ident.cmx bytecomp/dll.cmx utils/config.cmx \
|
||||||
bytecomp/cmo_format.cmi utils/clflags.cmx bytecomp/bytesections.cmx \
|
bytecomp/cmo_format.cmi utils/clflags.cmx bytecomp/bytesections.cmx \
|
||||||
parsing/asttypes.cmi bytecomp/symtable.cmi
|
parsing/asttypes.cmi bytecomp/symtable.cmi
|
||||||
bytecomp/translclass.cmo : typing/types.cmi bytecomp/typeopt.cmi \
|
bytecomp/translclass.cmo : typing/types.cmi bytecomp/typeopt.cmi \
|
||||||
|
@ -611,6 +616,8 @@ asmcomp/asmgen.cmi : bytecomp/lambda.cmi asmcomp/cmm.cmi
|
||||||
asmcomp/asmlibrarian.cmi :
|
asmcomp/asmlibrarian.cmi :
|
||||||
asmcomp/asmlink.cmi : asmcomp/cmx_format.cmi
|
asmcomp/asmlink.cmi : asmcomp/cmx_format.cmi
|
||||||
asmcomp/asmpackager.cmi : typing/env.cmi
|
asmcomp/asmpackager.cmi : typing/env.cmi
|
||||||
|
asmcomp/branch_relaxation.cmi : asmcomp/linearize.cmi \
|
||||||
|
asmcomp/branch_relaxation_intf.cmo
|
||||||
asmcomp/clambda.cmi : bytecomp/lambda.cmi typing/ident.cmi \
|
asmcomp/clambda.cmi : bytecomp/lambda.cmi typing/ident.cmi \
|
||||||
asmcomp/debuginfo.cmi parsing/asttypes.cmi
|
asmcomp/debuginfo.cmi parsing/asttypes.cmi
|
||||||
asmcomp/closure.cmi : bytecomp/lambda.cmi asmcomp/clambda.cmi
|
asmcomp/closure.cmi : bytecomp/lambda.cmi asmcomp/clambda.cmi
|
||||||
|
@ -705,6 +712,14 @@ asmcomp/asmpackager.cmx : typing/typemod.cmx bytecomp/translmod.cmx \
|
||||||
utils/config.cmx asmcomp/compilenv.cmx asmcomp/cmx_format.cmi \
|
utils/config.cmx asmcomp/compilenv.cmx asmcomp/cmx_format.cmi \
|
||||||
utils/clflags.cmx utils/ccomp.cmx asmcomp/asmlink.cmx asmcomp/asmgen.cmx \
|
utils/clflags.cmx utils/ccomp.cmx asmcomp/asmlink.cmx asmcomp/asmgen.cmx \
|
||||||
asmcomp/asmpackager.cmi
|
asmcomp/asmpackager.cmi
|
||||||
|
asmcomp/branch_relaxation_intf.cmo : asmcomp/linearize.cmi asmcomp/arch.cmo
|
||||||
|
asmcomp/branch_relaxation_intf.cmx : asmcomp/linearize.cmx asmcomp/arch.cmx
|
||||||
|
asmcomp/branch_relaxation.cmo : utils/misc.cmi asmcomp/mach.cmi \
|
||||||
|
asmcomp/linearize.cmi asmcomp/cmm.cmi asmcomp/branch_relaxation_intf.cmo \
|
||||||
|
asmcomp/branch_relaxation.cmi
|
||||||
|
asmcomp/branch_relaxation.cmx : utils/misc.cmx asmcomp/mach.cmx \
|
||||||
|
asmcomp/linearize.cmx asmcomp/cmm.cmx asmcomp/branch_relaxation_intf.cmx \
|
||||||
|
asmcomp/branch_relaxation.cmi
|
||||||
asmcomp/clambda.cmo : bytecomp/lambda.cmi typing/ident.cmi \
|
asmcomp/clambda.cmo : bytecomp/lambda.cmi typing/ident.cmi \
|
||||||
asmcomp/debuginfo.cmi parsing/asttypes.cmi asmcomp/clambda.cmi
|
asmcomp/debuginfo.cmi parsing/asttypes.cmi asmcomp/clambda.cmi
|
||||||
asmcomp/clambda.cmx : bytecomp/lambda.cmx typing/ident.cmx \
|
asmcomp/clambda.cmx : bytecomp/lambda.cmx typing/ident.cmx \
|
||||||
|
@ -778,13 +793,15 @@ asmcomp/emit.cmo : asmcomp/x86_proc.cmi asmcomp/x86_masm.cmi \
|
||||||
asmcomp/reg.cmi asmcomp/proc.cmi utils/misc.cmi asmcomp/mach.cmi \
|
asmcomp/reg.cmi asmcomp/proc.cmi utils/misc.cmi asmcomp/mach.cmi \
|
||||||
asmcomp/linearize.cmi bytecomp/lambda.cmi asmcomp/emitaux.cmi \
|
asmcomp/linearize.cmi bytecomp/lambda.cmi asmcomp/emitaux.cmi \
|
||||||
asmcomp/debuginfo.cmi utils/config.cmi asmcomp/compilenv.cmi \
|
asmcomp/debuginfo.cmi utils/config.cmi asmcomp/compilenv.cmi \
|
||||||
asmcomp/cmm.cmi utils/clflags.cmi asmcomp/arch.cmo asmcomp/emit.cmi
|
asmcomp/cmm.cmi utils/clflags.cmi asmcomp/arch.cmo asmcomp/emit.cmi \
|
||||||
|
asmcomp/branch_relaxation.cmi
|
||||||
asmcomp/emit.cmx : asmcomp/x86_proc.cmx asmcomp/x86_masm.cmx \
|
asmcomp/emit.cmx : asmcomp/x86_proc.cmx asmcomp/x86_masm.cmx \
|
||||||
asmcomp/x86_gas.cmx asmcomp/x86_dsl.cmx asmcomp/x86_ast.cmi \
|
asmcomp/x86_gas.cmx asmcomp/x86_dsl.cmx asmcomp/x86_ast.cmi \
|
||||||
asmcomp/reg.cmx asmcomp/proc.cmx utils/misc.cmx asmcomp/mach.cmx \
|
asmcomp/reg.cmx asmcomp/proc.cmx utils/misc.cmx asmcomp/mach.cmx \
|
||||||
asmcomp/linearize.cmx bytecomp/lambda.cmx asmcomp/emitaux.cmx \
|
asmcomp/linearize.cmx bytecomp/lambda.cmx asmcomp/emitaux.cmx \
|
||||||
asmcomp/debuginfo.cmx utils/config.cmx asmcomp/compilenv.cmx \
|
asmcomp/debuginfo.cmx utils/config.cmx asmcomp/compilenv.cmx \
|
||||||
asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx asmcomp/emit.cmi
|
asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx asmcomp/emit.cmi \
|
||||||
|
asmcomp/branch_relaxation.cmi
|
||||||
asmcomp/interf.cmo : asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/mach.cmi \
|
asmcomp/interf.cmo : asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/mach.cmi \
|
||||||
asmcomp/interf.cmi
|
asmcomp/interf.cmi
|
||||||
asmcomp/interf.cmx : asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/mach.cmx \
|
asmcomp/interf.cmx : asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/mach.cmx \
|
||||||
|
|
|
@ -3,13 +3,13 @@ i386)
|
||||||
./configure
|
./configure
|
||||||
make world.opt
|
make world.opt
|
||||||
sudo make install
|
sudo make install
|
||||||
cd testsuite && make all && cd ..
|
(cd testsuite && make all)
|
||||||
mkdir external-packages
|
mkdir external-packages
|
||||||
cd external-packages
|
cd external-packages
|
||||||
git clone git://github.com/ocaml/camlp4
|
git clone git://github.com/ocaml/camlp4
|
||||||
cd camlp4 && ./configure && make && sudo make install && cd ..
|
(cd camlp4 && ./configure && make && sudo make install)
|
||||||
git clone git://github.com/ocaml/opam
|
git clone git://github.com/ocaml/opam
|
||||||
cd opam && ./configure && make lib-ext && make && sudo make install && cd ..
|
(cd opam && ./configure && make lib-ext && make && sudo make install)
|
||||||
git config --global user.email "some@name.com"
|
git config --global user.email "some@name.com"
|
||||||
git config --global user.name "Some Name"
|
git config --global user.name "Some Name"
|
||||||
opam init -y -a git://github.com/ocaml/opam-repository
|
opam init -y -a git://github.com/ocaml/opam-repository
|
||||||
|
|
117
Changes
117
Changes
|
@ -1,5 +1,6 @@
|
||||||
OCaml 4.03.0:
|
OCaml 4.03.0:
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
(Changes that can break existing programs are marked with a "*")
|
(Changes that can break existing programs are marked with a "*")
|
||||||
|
|
||||||
Language features:
|
Language features:
|
||||||
|
@ -22,8 +23,6 @@ Language features:
|
||||||
- PR#5528: inline records for constructor arguments (Alain Frisch)
|
- PR#5528: inline records for constructor arguments (Alain Frisch)
|
||||||
|
|
||||||
Compilers:
|
Compilers:
|
||||||
- PR#6475: accept -o in ocamlc when compiling C files
|
|
||||||
(Vincent Laporte, Peter Zotov)
|
|
||||||
- PR#6501: harden the native-code generator against certain uses of "%identity"
|
- PR#6501: harden the native-code generator against certain uses of "%identity"
|
||||||
(Xavier Leroy, report by Antoine Miné).
|
(Xavier Leroy, report by Antoine Miné).
|
||||||
- PR#6636: add --version option
|
- PR#6636: add --version option
|
||||||
|
@ -156,9 +155,18 @@ Features wishes:
|
||||||
- GPR#191: Making gc.h and some part of memory.h public
|
- GPR#191: Making gc.h and some part of memory.h public
|
||||||
(Thomas Refis)
|
(Thomas Refis)
|
||||||
|
|
||||||
OCaml 4.02.2:
|
OCaml 4.02.3:
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- PR#6919: corrupted final_table
|
||||||
|
(ygrek)
|
||||||
|
- PR#6930: Aliased result type of GADT constructor results in assertion failure
|
||||||
|
(Jacques Garrigue)
|
||||||
|
|
||||||
|
OCaml 4.02.2 (17 Jun 2015):
|
||||||
|
---------------------------
|
||||||
|
|
||||||
(Changes that can break existing programs are marked with a "*")
|
(Changes that can break existing programs are marked with a "*")
|
||||||
|
|
||||||
Language features:
|
Language features:
|
||||||
|
@ -178,11 +186,15 @@ Compilers:
|
||||||
(Jacques Garrigue)
|
(Jacques Garrigue)
|
||||||
- PR#6642: replace $CAMLORIGIN in -ccopt with the path to cma or cmxa
|
- PR#6642: replace $CAMLORIGIN in -ccopt with the path to cma or cmxa
|
||||||
(Peter Zotov, Gabriel Scherer, review by Damien Doligez)
|
(Peter Zotov, Gabriel Scherer, review by Damien Doligez)
|
||||||
|
- PR#6797: new option -output-complete-obj
|
||||||
|
to output an object file with included runtime and autolink libraries
|
||||||
|
(Peter Zotov)
|
||||||
- PR#6845: -no-check-prims to tell ocamlc not to check primitives in runtime
|
- PR#6845: -no-check-prims to tell ocamlc not to check primitives in runtime
|
||||||
(Alain Frisch)
|
(Alain Frisch)
|
||||||
|
- GPR#149: Attach documentation comments to parse tree
|
||||||
|
(Leo White)
|
||||||
- GPR#159: Better locations for structure/signature items
|
- GPR#159: Better locations for structure/signature items
|
||||||
(Leo White)
|
(Leo White)
|
||||||
- GPR#149: Attach documentation comments to parse tree (Leo White)
|
|
||||||
|
|
||||||
Toplevel and debugger:
|
Toplevel and debugger:
|
||||||
- PR#5958: generalized polymorphic #install_printer
|
- PR#5958: generalized polymorphic #install_printer
|
||||||
|
@ -207,6 +219,14 @@ OCamlbuild:
|
||||||
- PR#6774: new menhir-specific flags "only_tokens" and "external_tokens(Foo)"
|
- PR#6774: new menhir-specific flags "only_tokens" and "external_tokens(Foo)"
|
||||||
(François Pottier)
|
(François Pottier)
|
||||||
|
|
||||||
|
Libraries:
|
||||||
|
- PR#6285: Add support for nanosecond precision in Unix.stat()
|
||||||
|
(Jérémie Dimino, report by user 'gfxmonk')
|
||||||
|
- PR#6781: Add higher baud rates to Unix termios
|
||||||
|
(Damien Doligez, report by Berke Durak)
|
||||||
|
- PR#6834: Add Obj.{first,last}_non_constant_constructor_tag
|
||||||
|
(Mark Shinwell, request by Gabriel Scherer)
|
||||||
|
|
||||||
Libraries:
|
Libraries:
|
||||||
- PR#6285: Add support for nanosecond precision in Unix.stat()
|
- PR#6285: Add support for nanosecond precision in Unix.stat()
|
||||||
(Jérémie Dimino, report by user 'gfxmonk')
|
(Jérémie Dimino, report by user 'gfxmonk')
|
||||||
|
@ -214,17 +234,42 @@ Libraries:
|
||||||
Runtime:
|
Runtime:
|
||||||
- PR#6078: Release the runtime system when calling caml_dlopen
|
- PR#6078: Release the runtime system when calling caml_dlopen
|
||||||
(Jérémie Dimino)
|
(Jérémie Dimino)
|
||||||
|
- PR#6675: GC hooks
|
||||||
|
(Damien Doligez and Roshan James)
|
||||||
|
|
||||||
|
Build system:
|
||||||
|
- PR#5418 (comments) : generate dependencies with $(CC) instead of gcc
|
||||||
|
(Damien Doligez and Michael Grünewald)
|
||||||
|
- PR#6266: Cross compilation for iOs, Android etc
|
||||||
|
(Peter Zotov, review by Damien Doligez and Mark Shinwell)
|
||||||
|
|
||||||
|
Installation procedure:
|
||||||
|
- Update instructions for x86-64 PIC mode and POWER architecture builds
|
||||||
|
(Mark Shinwell)
|
||||||
|
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
|
- PR#5271: Location.prerr_warning is hard-coded to use Format.err_formatter
|
||||||
|
(Damien Doligez, report by Rolf Rolles)
|
||||||
|
- PR#5395: OCamlbuild mishandles relative symlinks and include paths
|
||||||
|
(Damien Doligez, report by Didier Le Botlan)
|
||||||
|
- PR#5822: wrong value of Options.ext_dll on windows
|
||||||
|
(Damien Doligez and Daniel Weil)
|
||||||
- PR#5836, PR#6684: printing lazy values in ocamldebug may segfault
|
- PR#5836, PR#6684: printing lazy values in ocamldebug may segfault
|
||||||
(Gabriel Scherer, request by the Coq team)
|
(Gabriel Scherer, request by the Coq team)
|
||||||
- PR#5887: move the byterun/*.h headers to byterun/caml/*.h to avoid
|
- PR#5887: move the byterun/*.h headers to byterun/caml/*.h to avoid
|
||||||
header name clashes
|
header name clashes
|
||||||
(Jérôme Vouillon and Adrien Nader and Peter Zotov)
|
(Jérôme Vouillon and Adrien Nader and Peter Zotov)
|
||||||
|
- PR#6281: Graphics window does not acknowledge second click (double click)
|
||||||
|
(Kyle Headley)
|
||||||
|
- PR#6490: incorrect backtraces in gdb on AArch64. Also fixes incorrect
|
||||||
|
backtraces on 32-bit ARM.
|
||||||
|
(Mark Shinwell)
|
||||||
- PR#6573: extern "C" for systhreads/threads.h
|
- PR#6573: extern "C" for systhreads/threads.h
|
||||||
(Mickaël Delahaye)
|
(Mickaël Delahaye)
|
||||||
- PR#6575: Array.init evaluates callback although it should not do so
|
- PR#6575: Array.init evaluates callback although it should not do so
|
||||||
(Alain Frisch, report by Gerd Stolpmann)
|
(Alain Frisch, report by Gerd Stolpmann)
|
||||||
|
- PR#6607: The manual doesn't mention 0x200 flag for OCAMLRUNPARAM=v
|
||||||
|
(Alain Frisch)
|
||||||
- PR#6616: allow meaningful use of -use-runtime without -custom.
|
- PR#6616: allow meaningful use of -use-runtime without -custom.
|
||||||
(Peter Zotov)
|
(Peter Zotov)
|
||||||
- PR#6617: allow android build with pthreads support (since SDK r10c)
|
- PR#6617: allow android build with pthreads support (since SDK r10c)
|
||||||
|
@ -233,12 +278,23 @@ Bug fixes:
|
||||||
(Gergely Szilvasy)
|
(Gergely Szilvasy)
|
||||||
- PR#6628: Configure script rejects legitimate arguments
|
- PR#6628: Configure script rejects legitimate arguments
|
||||||
(Michael Grünewald, Damien Doligez)
|
(Michael Grünewald, Damien Doligez)
|
||||||
|
- PR#6630: Failure of tests/prim-bigstring/{big,}string.ml on big-endian
|
||||||
|
architectures
|
||||||
|
(Pierre Chambart, testing by Mark Shinwell)
|
||||||
- PR#6640: ocamlbuild: wrong "unused tag" warning on "precious"
|
- PR#6640: ocamlbuild: wrong "unused tag" warning on "precious"
|
||||||
(report by user 'william')
|
(report by user 'william')
|
||||||
|
- PR#6652: ocamlbuild -clean does not print a newline after output
|
||||||
|
(Damien Doligez, report by Andi McClure)
|
||||||
|
- PR#6658: cross-compiler: version check not working on OS X
|
||||||
|
(Gerd Stolpmann)
|
||||||
- PR#6665: Failure of tests/asmcomp on sparc
|
- PR#6665: Failure of tests/asmcomp on sparc
|
||||||
(Stéphane Glondu)
|
(Stéphane Glondu)
|
||||||
|
- PR#6667: wrong implementation of %bswap16 on ARM64
|
||||||
|
(Xavier Leroy)
|
||||||
- PR#6669: fix 4.02 regression in toplevel printing of lazy values
|
- PR#6669: fix 4.02 regression in toplevel printing of lazy values
|
||||||
(Leo White, review by Gabriel Scherer)
|
(Leo White, review by Gabriel Scherer)
|
||||||
|
- PR#6671: Windows: environment variable 'TZ' affects Unix.gettimeofday
|
||||||
|
(Mickael Delahaye and Damien Doligez)
|
||||||
- PR#6680: Missing parentheses in warning about polymorphic variant value
|
- PR#6680: Missing parentheses in warning about polymorphic variant value
|
||||||
(Jacques Garrigue and Gabriel Scherer, report by Philippe Veber)
|
(Jacques Garrigue and Gabriel Scherer, report by Philippe Veber)
|
||||||
- PR#6686: Bug in [subst_boxed_number]
|
- PR#6686: Bug in [subst_boxed_number]
|
||||||
|
@ -252,46 +308,89 @@ Bug fixes:
|
||||||
(Gabriel Scherer, report by Peter Zotov)
|
(Gabriel Scherer, report by Peter Zotov)
|
||||||
- PR#6727: Printf.sprintf "%F" misbehavior
|
- PR#6727: Printf.sprintf "%F" misbehavior
|
||||||
(Benoît Vaugon, report by Vassili Karpov)
|
(Benoît Vaugon, report by Vassili Karpov)
|
||||||
|
- PR#6747: ocamlobjinfo: missing symbol caml_plugin_header due to underscore
|
||||||
|
(Damien Doligez, Maverick Woo)
|
||||||
- PR#6749: ocamlopt returns n for (n mod 1) instead of 0
|
- PR#6749: ocamlopt returns n for (n mod 1) instead of 0
|
||||||
(Mark Shinwell and Jérémie Dimino)
|
(Mark Shinwell and Jérémie Dimino)
|
||||||
|
- PR#6753: Num.quo_num and Num.mod_num incorrect for some negative arguments
|
||||||
|
(Xavier Leroy)
|
||||||
|
- PR#6758: Ocamldoc "analyse_module: parsetree and typedtree don't match"
|
||||||
|
(Damien Doligez, report by user 'maro')
|
||||||
|
- PR#6759: big_int_of_string incorrectly parses some hexa literals
|
||||||
|
(Damien Doligez, report by Pierre-yves Strub)
|
||||||
- PR#6763: #show with -short-paths doesn't select shortest type paths
|
- PR#6763: #show with -short-paths doesn't select shortest type paths
|
||||||
(Jacques Garrigue, report by David Sheets)
|
(Jacques Garrigue, report by David Sheets)
|
||||||
- PR#6768: Typechecker overflow the stack on cyclic type
|
- PR#6768: Typechecker overflow the stack on cyclic type
|
||||||
(Jacques Garrigue, report by user 'darktenaibre')
|
(Jacques Garrigue, report by user 'darktenaibre')
|
||||||
|
- PR#6770: (duplicate of PR#6686)
|
||||||
|
- PR#6772: asmrun/signals_asm.c doesn't compile on NetBSD/i386
|
||||||
|
(Kenji Tokudome)
|
||||||
- PR#6775: Digest.file leaks file descriptor on error
|
- PR#6775: Digest.file leaks file descriptor on error
|
||||||
(Valentin Gatien-Baron)
|
(Valentin Gatien-Baron)
|
||||||
|
- PR#6779: Cross-compilers cannot link bytecode using custom primitives
|
||||||
|
(Damien Doligez, request by Peter Zotov)
|
||||||
- PR#6787: Soundness bug with polymorphic variants
|
- PR#6787: Soundness bug with polymorphic variants
|
||||||
(Jacques Garrigue, with help from Leo White and Grégoire Henry,
|
(Jacques Garrigue, with help from Leo White and Grégoire Henry,
|
||||||
report by Michael O'Connor)
|
report by Michael O'Connor)
|
||||||
|
- PR#6790: otherlibs should be built with -g
|
||||||
|
(Damien Doligez, report by Peter Zotov)
|
||||||
- PR#6791: "%s@[", "%s@{" regression in Scanf
|
- PR#6791: "%s@[", "%s@{" regression in Scanf
|
||||||
(Benoît Vaugon)
|
(Benoît Vaugon)
|
||||||
- PR#6793: ocamlbuild passes nonsensical "-ocamlc ..." commands to menhir
|
- PR#6793: ocamlbuild passes nonsensical "-ocamlc ..." commands to menhir
|
||||||
(Gabriel Scherer, report by Damien Doligez)
|
(Gabriel Scherer, report by Damien Doligez)
|
||||||
|
- PR#6799: include guards missing for unixsupport.h and other files
|
||||||
|
(Andreas Hauptmann)
|
||||||
|
- PR#6810: Improve documentation of Bigarray.Genarray.map_file
|
||||||
|
(Mark Shinwell and Daniel Bünzli)
|
||||||
- PR#6812: -short-paths and -no-alias-deps can create inconsistent assumptions
|
- PR#6812: -short-paths and -no-alias-deps can create inconsistent assumptions
|
||||||
(Jacques Garrigue, report by Valentin Gatien-Baron)
|
(Jacques Garrigue, report by Valentin Gatien-Baron)
|
||||||
- PR#6817: GADT exhaustiveness breakage with modules
|
- PR#6817: GADT exhaustiveness breakage with modules
|
||||||
(Leo White, report by Pierre Chambart)
|
(Leo White, report by Pierre Chambart)
|
||||||
- PR#6824: fix buffer sharing on partial application of Format.asprintf
|
- PR#6824: fix buffer sharing on partial application of Format.asprintf
|
||||||
(Gabriel Scherer, report by Alain Frisch)
|
(Gabriel Scherer, report by Alain Frisch)
|
||||||
|
- PR#6831: Build breaks for -aspp gcc on solaris-like OSs
|
||||||
|
(John Tibble)
|
||||||
- PR#6836: Assertion failure using -short-paths
|
- PR#6836: Assertion failure using -short-paths
|
||||||
(Jacques Garrigue, report by David Sheets)
|
(Jacques Garrigue, report by David Sheets)
|
||||||
|
- PR#6837: Build profiling libraries on FreeBSD and NetBSD x86-64
|
||||||
|
(Mark Shinwell, report by Michael Grünewald)
|
||||||
- PR#6841: Changing compilation unit name with -o breaks ocamldebug
|
- PR#6841: Changing compilation unit name with -o breaks ocamldebug
|
||||||
(Jacques Garrigue, report by Jordan Walke)
|
(Jacques Garrigue, report by Jordan Walke)
|
||||||
|
- PR#6842: export Typemod.modtype_of_package
|
||||||
- PR#6843: record weak dependencies even when the .cmi is missing
|
- PR#6843: record weak dependencies even when the .cmi is missing
|
||||||
(Leo White, Gabriel Scherer)
|
(Leo White, Gabriel Scherer)
|
||||||
- PR#6849: Inverted pattern unification error
|
- PR#6849: Inverted pattern unification error
|
||||||
(Jacques Garrigue, report by Leo White)
|
(Jacques Garrigue, report by Leo White)
|
||||||
|
- PR#6857: __MODULE__ doesn't give the current module with -o
|
||||||
|
(Jacques Garrigue, report by Valentin Gatien-Baron)
|
||||||
- PR#6862: Exhaustiveness check wrong for class constructor arguments
|
- PR#6862: Exhaustiveness check wrong for class constructor arguments
|
||||||
(Jacques Garrigue)
|
(Jacques Garrigue)
|
||||||
|
- PR#6869: Improve comment on [Hashtbl.hash_param]
|
||||||
|
(Mark Shinwell, report by Jun Furuse)
|
||||||
- PR#6870: Unsoundness when -rectypes fails to detect non-contractive type
|
- PR#6870: Unsoundness when -rectypes fails to detect non-contractive type
|
||||||
(Jacques Garrigue, report by Stephen Dolan)
|
(Jacques Garrigue, report by Stephen Dolan)
|
||||||
- PR#6872: Type-directed propagation fails to disambiguate variants
|
- PR#6872: Type-directed propagation fails to disambiguate variants
|
||||||
that are also exception constructors
|
that are also exception constructors
|
||||||
(Jacques Garrigue, report by Romain Beauxis)
|
(Jacques Garrigue, report by Romain Beauxis)
|
||||||
|
- PR#6878: AArch64 backend generates invalid asm: conditional branch
|
||||||
|
out of range (Mark Shinwell, report by Richard Jones, testing by Richard
|
||||||
|
Jones and Xavier Leroy, code review by Xavier Leroy and Thomas Refis)
|
||||||
|
- PR#6879: Wrong optimization of 1 mod n
|
||||||
|
(Mark Shinwell, report by Jean-Christophe Filliâtre)
|
||||||
|
- PR#6884: The __CYGWIN32__ #define should be replaced with __CYGWIN__
|
||||||
|
(Adrien Nader)
|
||||||
- PR#6886: -no-alias-deps allows to build self-referential compilation units
|
- PR#6886: -no-alias-deps allows to build self-referential compilation units
|
||||||
(Jacques Garrigue, report by sliquister)
|
(Jacques Garrigue, report by Valentin Gatien-Baron)
|
||||||
|
- PR#6889: ast_mapper fails to rewrite class attributes
|
||||||
|
(Sébastien Briais)
|
||||||
|
- PR#6893: ocamlbuild: "tag not used" warning when using (p)dep
|
||||||
|
(Gabriel Scherer, report by Christiano Haesbaert)
|
||||||
- GPR#143: fix getsockopt behaviour for boolean socket options
|
- GPR#143: fix getsockopt behaviour for boolean socket options
|
||||||
(Anil Madhavapeddy and Andrew Ray)
|
(Anil Madhavapeddy and Andrew Ray)
|
||||||
|
- GPR#190: typo in pervasives
|
||||||
|
(Guillaume Bury)
|
||||||
|
- Misplaced assertion in major_gc.c for no-naked-pointers mode
|
||||||
|
(Stephen Dolan, Mark Shinwell)
|
||||||
|
|
||||||
Feature wishes:
|
Feature wishes:
|
||||||
- PR#6452, GPR#140: add internal suport for custom printing formats
|
- PR#6452, GPR#140: add internal suport for custom printing formats
|
||||||
|
@ -302,6 +401,14 @@ Feature wishes:
|
||||||
(Peter Zotov, review by Mark Shinwell)
|
(Peter Zotov, review by Mark Shinwell)
|
||||||
- PR#6842: export Typemod.modtype_of_package
|
- PR#6842: export Typemod.modtype_of_package
|
||||||
(Jacques Garrigue, request by Jun Furuse)
|
(Jacques Garrigue, request by Jun Furuse)
|
||||||
|
- GPR#139: more versatile specification of locations of .annot
|
||||||
|
(Christophe Troestler, review by Damien Doligez)
|
||||||
|
- GPR#171: allow custom warning printers / catchers
|
||||||
|
(Benjamin Canou, review by Damien Doligez)
|
||||||
|
- Misplaced assertion in major_gc.c for no-naked-pointers mode
|
||||||
|
(Stephen Dolan, Mark Shinwell)
|
||||||
|
- GPR#191: Making gc.h and some part of memory.h public
|
||||||
|
(Thomas Refis)
|
||||||
|
|
||||||
OCaml 4.02.1 (14 Oct 2014):
|
OCaml 4.02.1 (14 Oct 2014):
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
17
INSTALL
17
INSTALL
|
@ -140,15 +140,24 @@ Examples:
|
||||||
or:
|
or:
|
||||||
./configure -prefix /usr -mandir '$(PREFIX)/man/manl'
|
./configure -prefix /usr -mandir '$(PREFIX)/man/manl'
|
||||||
|
|
||||||
On a Linux x86/64 bits host, to build a 32-bit version of OCaml:
|
On a Linux x86-64 host, to build a 32-bit version of OCaml:
|
||||||
./configure -cc "gcc -m32" -as "as --32" -aspp "gcc -m32 -c" \
|
./configure -cc "gcc -m32" -as "as --32" -aspp "gcc -m32 -c" \
|
||||||
-host i386-linux -partialld "ld -r -melf_i386"
|
-host i386-linux -partialld "ld -r -melf_i386"
|
||||||
|
|
||||||
On a Linux x86/64 bits host, to build the run-time system in PIC mode
|
On a Linux x86-64 host, to build the run-time system in PIC mode,
|
||||||
(enables putting the runtime in a shared library,
|
no special options should be required---the libraries should be built
|
||||||
at a small performance cost):
|
automatically. The old instructions were:
|
||||||
./configure -cc "gcc -fPIC" -aspp "gcc -c -fPIC"
|
./configure -cc "gcc -fPIC" -aspp "gcc -c -fPIC"
|
||||||
|
|
||||||
|
On a 64-bit POWER architecture host running Linux, OCaml only operates
|
||||||
|
in a 32-bit environment. If your system compiler is configured as 32-bit,
|
||||||
|
e.g. Red Hat 5.9, you don't need to do anything special. If that is
|
||||||
|
not the case (e.g. Red Hat 6.4), then IBM's "Advance Toolchain" can
|
||||||
|
be used. For example:
|
||||||
|
export PATH=/opt/at7.0/bin:$PATH
|
||||||
|
./configure -cc "gcc -m32" -as "as -a32" -aspp "gcc -m32 -c" \
|
||||||
|
-partialld "ld -r -m elf32ppc"
|
||||||
|
|
||||||
On a MacOSX 10.5/Intel Core 2 or MacOSX 10.5/PowerPC host,
|
On a MacOSX 10.5/Intel Core 2 or MacOSX 10.5/PowerPC host,
|
||||||
to build a 64-bit version of OCaml:
|
to build a 64-bit version of OCaml:
|
||||||
./configure -cc "gcc -m64"
|
./configure -cc "gcc -m64"
|
||||||
|
|
23
Makefile
23
Makefile
|
@ -13,20 +13,20 @@
|
||||||
# The main Makefile
|
# The main Makefile
|
||||||
|
|
||||||
include config/Makefile
|
include config/Makefile
|
||||||
|
CAMLRUN ?= boot/ocamlrun
|
||||||
|
CAMLYACC ?= boot/ocamlyacc
|
||||||
include stdlib/StdlibModules
|
include stdlib/StdlibModules
|
||||||
|
|
||||||
CAMLC=boot/ocamlrun boot/ocamlc -nostdlib -I boot
|
CAMLC=$(CAMLRUN) boot/ocamlc -nostdlib -I boot
|
||||||
CAMLOPT=boot/ocamlrun ./ocamlopt -nostdlib -I stdlib -I otherlibs/dynlink
|
CAMLOPT=$(CAMLRUN) ./ocamlopt -nostdlib -I stdlib -I otherlibs/dynlink
|
||||||
COMPFLAGS=-strict-sequence -w +33..39+48+50 -warn-error A -bin-annot \
|
COMPFLAGS=-strict-sequence -w +33..39+48+50 -warn-error A -bin-annot \
|
||||||
-safe-string $(INCLUDES)
|
-safe-string $(INCLUDES)
|
||||||
LINKFLAGS=
|
LINKFLAGS=
|
||||||
|
|
||||||
CAMLYACC=boot/ocamlyacc
|
|
||||||
YACCFLAGS=-v
|
YACCFLAGS=-v
|
||||||
CAMLLEX=boot/ocamlrun boot/ocamllex
|
CAMLLEX=$(CAMLRUN) boot/ocamllex
|
||||||
CAMLDEP=boot/ocamlrun tools/ocamldep
|
CAMLDEP=$(CAMLRUN) tools/ocamldep
|
||||||
DEPFLAGS=$(INCLUDES)
|
DEPFLAGS=$(INCLUDES)
|
||||||
CAMLRUN=byterun/ocamlrun
|
|
||||||
SHELL=/bin/sh
|
SHELL=/bin/sh
|
||||||
MKDIR=mkdir -p
|
MKDIR=mkdir -p
|
||||||
|
|
||||||
|
@ -112,6 +112,8 @@ ASMCOMP=\
|
||||||
asmcomp/deadcode.cmo \
|
asmcomp/deadcode.cmo \
|
||||||
asmcomp/printlinear.cmo asmcomp/linearize.cmo \
|
asmcomp/printlinear.cmo asmcomp/linearize.cmo \
|
||||||
asmcomp/schedgen.cmo asmcomp/scheduling.cmo \
|
asmcomp/schedgen.cmo asmcomp/scheduling.cmo \
|
||||||
|
asmcomp/branch_relaxation_intf.cmo \
|
||||||
|
asmcomp/branch_relaxation.cmo \
|
||||||
asmcomp/emitaux.cmo asmcomp/emit.cmo asmcomp/asmgen.cmo \
|
asmcomp/emitaux.cmo asmcomp/emit.cmo asmcomp/asmgen.cmo \
|
||||||
asmcomp/asmlink.cmo asmcomp/asmlibrarian.cmo asmcomp/asmpackager.cmo \
|
asmcomp/asmlink.cmo asmcomp/asmlibrarian.cmo asmcomp/asmpackager.cmo \
|
||||||
driver/opterrors.cmo driver/optcompile.cmo
|
driver/opterrors.cmo driver/optcompile.cmo
|
||||||
|
@ -335,7 +337,7 @@ install:
|
||||||
cp ocaml $(INSTALL_BINDIR)/ocaml$(EXE)
|
cp ocaml $(INSTALL_BINDIR)/ocaml$(EXE)
|
||||||
cd stdlib; $(MAKE) install
|
cd stdlib; $(MAKE) install
|
||||||
cp lex/ocamllex $(INSTALL_BINDIR)/ocamllex$(EXE)
|
cp lex/ocamllex $(INSTALL_BINDIR)/ocamllex$(EXE)
|
||||||
cp yacc/ocamlyacc$(EXE) $(INSTALL_BINDIR)/ocamlyacc$(EXE)
|
cp $(CAMLYACC)$(EXE) $(INSTALL_BINDIR)/ocamlyacc$(EXE)
|
||||||
cp utils/*.cmi utils/*.cmt utils/*.cmti \
|
cp utils/*.cmi utils/*.cmt utils/*.cmti \
|
||||||
parsing/*.cmi parsing/*.cmt parsing/*.cmti \
|
parsing/*.cmi parsing/*.cmt parsing/*.cmti \
|
||||||
typing/*.cmi typing/*.cmt typing/*.cmti \
|
typing/*.cmi typing/*.cmt typing/*.cmti \
|
||||||
|
@ -651,8 +653,7 @@ partialclean::
|
||||||
beforedepend:: asmcomp/emit.ml
|
beforedepend:: asmcomp/emit.ml
|
||||||
|
|
||||||
tools/cvt_emit: tools/cvt_emit.mll
|
tools/cvt_emit: tools/cvt_emit.mll
|
||||||
cd tools; \
|
cd tools && $(MAKE) cvt_emit
|
||||||
$(MAKE) CAMLC="../$(CAMLRUN) ../boot/ocamlc -I ../stdlib" cvt_emit
|
|
||||||
|
|
||||||
# The "expunge" utility
|
# The "expunge" utility
|
||||||
|
|
||||||
|
@ -700,7 +701,7 @@ library: ocamlc
|
||||||
cd stdlib; $(MAKE) all
|
cd stdlib; $(MAKE) all
|
||||||
|
|
||||||
library-cross:
|
library-cross:
|
||||||
cd stdlib; $(MAKE) RUNTIME=../byterun/ocamlrun all
|
cd stdlib; $(MAKE) CAMLRUN=../byterun/ocamlrun all
|
||||||
|
|
||||||
libraryopt:
|
libraryopt:
|
||||||
cd stdlib; $(MAKE) allopt
|
cd stdlib; $(MAKE) allopt
|
||||||
|
@ -774,7 +775,7 @@ alldepend::
|
||||||
|
|
||||||
otherlibraries: ocamltools
|
otherlibraries: ocamltools
|
||||||
for i in $(OTHERLIBRARIES); do \
|
for i in $(OTHERLIBRARIES); do \
|
||||||
(cd otherlibs/$$i; $(MAKE) RUNTIME=$(RUNTIME) all) || exit $$?; \
|
(cd otherlibs/$$i; $(MAKE) all) || exit $$?; \
|
||||||
done
|
done
|
||||||
|
|
||||||
otherlibrariesopt:
|
otherlibrariesopt:
|
||||||
|
|
41
Makefile.nt
41
Makefile.nt
|
@ -13,18 +13,18 @@
|
||||||
# The main Makefile
|
# The main Makefile
|
||||||
|
|
||||||
include config/Makefile
|
include config/Makefile
|
||||||
|
CAMLRUN ?= boot/ocamlrun
|
||||||
|
CAMLYACC ?= boot/ocamlyacc
|
||||||
include stdlib/StdlibModules
|
include stdlib/StdlibModules
|
||||||
|
|
||||||
CAMLC=boot/ocamlrun boot/ocamlc -nostdlib -I boot
|
CAMLC=$(CAMLRUN) boot/ocamlc -nostdlib -I boot
|
||||||
CAMLOPT=boot/ocamlrun ./ocamlopt -nostdlib -I stdlib -I otherlibs/dynlink
|
CAMLOPT=$(CAMLRUN) ./ocamlopt -nostdlib -I stdlib -I otherlibs/dynlink
|
||||||
COMPFLAGS=-strict-sequence -w +33..39+48 -warn-error A -bin-annot $(INCLUDES)
|
COMPFLAGS=-strict-sequence -w +33..39+48 -warn-error A -bin-annot $(INCLUDES)
|
||||||
LINKFLAGS=
|
LINKFLAGS=
|
||||||
CAMLYACC=boot/ocamlyacc
|
|
||||||
YACCFLAGS=
|
YACCFLAGS=
|
||||||
CAMLLEX=boot/ocamlrun boot/ocamllex
|
CAMLLEX=$(CAMLRUN) boot/ocamllex
|
||||||
CAMLDEP=boot/ocamlrun tools/ocamldep
|
CAMLDEP=$(CAMLRUN) tools/ocamldep
|
||||||
DEPFLAGS=$(INCLUDES)
|
DEPFLAGS=$(INCLUDES)
|
||||||
CAMLRUN=byterun/ocamlrun
|
|
||||||
|
|
||||||
OCAMLBUILDBYTE=$(WITH_OCAMLBUILD:=.byte)
|
OCAMLBUILDBYTE=$(WITH_OCAMLBUILD:=.byte)
|
||||||
OCAMLBUILDNATIVE=$(WITH_OCAMLBUILD:=.native)
|
OCAMLBUILDNATIVE=$(WITH_OCAMLBUILD:=.native)
|
||||||
|
@ -299,7 +299,9 @@ installopt:
|
||||||
if test -n "$(WITH_OCAMLDOC)"; then (cd ocamldoc; $(MAKEREC) installopt); fi
|
if test -n "$(WITH_OCAMLDOC)"; then (cd ocamldoc; $(MAKEREC) installopt); fi
|
||||||
if test -n "$(WITH_OCAMLBUILD)"; then (cd ocamlbuild; $(MAKE) installopt); \
|
if test -n "$(WITH_OCAMLBUILD)"; then (cd ocamlbuild; $(MAKE) installopt); \
|
||||||
else :; fi
|
else :; fi
|
||||||
for i in $(OTHERLIBRARIES); do $(MAKEREC) -C otherlibs/$$i installopt; done
|
for i in $(OTHERLIBRARIES); do \
|
||||||
|
$(MAKEREC) -C otherlibs/$$i installopt || exit $$?; \
|
||||||
|
done
|
||||||
if test -f ocamlopt.opt ; then $(MAKEREC) installoptopt; fi
|
if test -f ocamlopt.opt ; then $(MAKEREC) installoptopt; fi
|
||||||
cd tools; $(MAKE) installopt
|
cd tools; $(MAKE) installopt
|
||||||
|
|
||||||
|
@ -566,7 +568,7 @@ beforedepend:: asmcomp/scheduling.ml
|
||||||
# Preprocess the code emitters
|
# Preprocess the code emitters
|
||||||
|
|
||||||
asmcomp/emit.ml: asmcomp/$(ARCH)/emit.mlp tools/cvt_emit
|
asmcomp/emit.ml: asmcomp/$(ARCH)/emit.mlp tools/cvt_emit
|
||||||
boot/ocamlrun tools/cvt_emit < asmcomp/$(ARCH)/emit.mlp > asmcomp/emit.ml
|
$(CAMLRUN) tools/cvt_emit < asmcomp/$(ARCH)/emit.mlp > asmcomp/emit.ml
|
||||||
|
|
||||||
partialclean::
|
partialclean::
|
||||||
rm -f asmcomp/emit.ml
|
rm -f asmcomp/emit.ml
|
||||||
|
@ -619,7 +621,7 @@ alldepend::
|
||||||
library:
|
library:
|
||||||
cd stdlib ; $(MAKEREC) all
|
cd stdlib ; $(MAKEREC) all
|
||||||
library-cross:
|
library-cross:
|
||||||
cd stdlib ; $(MAKEREC) RUNTIME=../byterun/ocamlrun all
|
cd stdlib ; $(MAKEREC) CAMLRUN=../byterun/ocamlrun all
|
||||||
libraryopt:
|
libraryopt:
|
||||||
cd stdlib ; $(MAKEREC) allopt
|
cd stdlib ; $(MAKEREC) allopt
|
||||||
partialclean::
|
partialclean::
|
||||||
|
@ -675,15 +677,25 @@ alldepend::
|
||||||
# The extra libraries
|
# The extra libraries
|
||||||
|
|
||||||
otherlibraries:
|
otherlibraries:
|
||||||
for i in $(OTHERLIBRARIES); do $(MAKEREC) -C otherlibs/$$i all; done
|
for i in $(OTHERLIBRARIES); do \
|
||||||
|
$(MAKEREC) -C otherlibs/$$i all || exit $$?; \
|
||||||
|
done
|
||||||
otherlibrariesopt:
|
otherlibrariesopt:
|
||||||
for i in $(OTHERLIBRARIES); do $(MAKEREC) -C otherlibs/$$i allopt; done
|
for i in $(OTHERLIBRARIES); \
|
||||||
|
do $(MAKEREC) -C otherlibs/$$i allopt || exit $$?; \
|
||||||
|
done
|
||||||
partialclean::
|
partialclean::
|
||||||
for i in $(OTHERLIBRARIES); do $(MAKEREC) -C otherlibs/$$i partialclean; done
|
for i in $(OTHERLIBRARIES); \
|
||||||
|
do $(MAKEREC) -C otherlibs/$$i partialclean || exit $$?; \
|
||||||
|
done
|
||||||
clean::
|
clean::
|
||||||
for i in $(OTHERLIBRARIES); do $(MAKEREC) -C otherlibs/$$i clean; done
|
for i in $(OTHERLIBRARIES); do \
|
||||||
|
$(MAKEREC) -C otherlibs/$$i clean || exit $$?; \
|
||||||
|
done
|
||||||
alldepend::
|
alldepend::
|
||||||
for i in $(OTHERLIBRARIES); do $(MAKEREC) -C otherlibs/$$i depend; done
|
for i in $(OTHERLIBRARIES); do \
|
||||||
|
$(MAKEREC) -C otherlibs/$$i depend || exit $$?; \
|
||||||
|
done
|
||||||
|
|
||||||
# The replay debugger
|
# The replay debugger
|
||||||
|
|
||||||
|
@ -745,6 +757,7 @@ alldepend:: depend
|
||||||
|
|
||||||
distclean:
|
distclean:
|
||||||
$(MAKE) clean
|
$(MAKE) clean
|
||||||
|
rm -f asmrun/.depend.nt byterun/.depend.nt
|
||||||
rm -f boot/ocamlrun boot/ocamlrun.exe boot/camlheader boot/ocamlyacc \
|
rm -f boot/ocamlrun boot/ocamlrun.exe boot/camlheader boot/ocamlyacc \
|
||||||
boot/*.cm* boot/libcamlrun.a
|
boot/*.cm* boot/libcamlrun.a
|
||||||
rm -f config/Makefile config/m.h config/s.h
|
rm -f config/Makefile config/m.h config/s.h
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1,4 +1,4 @@
|
||||||
4.03.0+dev7-2015-02-08
|
4.03.0+dev8-2015-07-15
|
||||||
|
|
||||||
# The version string is the first line of this file.
|
# The version string is the first line of this file.
|
||||||
# It must be in the format described in stdlib/sys.mli
|
# It must be in the format described in stdlib/sys.mli
|
||||||
|
|
|
@ -26,6 +26,12 @@ open X86_ast
|
||||||
open X86_proc
|
open X86_proc
|
||||||
open X86_dsl
|
open X86_dsl
|
||||||
|
|
||||||
|
(* [Branch_relaxation] is not used in this file, but is required by
|
||||||
|
emit.mlp files for certain other targets; the reference here ensures
|
||||||
|
that when releases are being prepared the .depend files are correct
|
||||||
|
for all targets. *)
|
||||||
|
open! Branch_relaxation
|
||||||
|
|
||||||
let _label s = D.label ~typ:QWORD s
|
let _label s = D.label ~typ:QWORD s
|
||||||
|
|
||||||
(* Override proc.ml *)
|
(* Override proc.ml *)
|
||||||
|
|
|
@ -852,8 +852,10 @@ let fundecl fundecl =
|
||||||
let n = frame_size() in
|
let n = frame_size() in
|
||||||
if n > 0 then begin
|
if n > 0 then begin
|
||||||
ignore(emit_stack_adjustment (-n));
|
ignore(emit_stack_adjustment (-n));
|
||||||
if !contains_calls then
|
if !contains_calls then begin
|
||||||
|
cfi_offset ~reg:14 (* lr *) ~offset:(-4);
|
||||||
` str lr, [sp, #{emit_int(n - 4)}]\n`
|
` str lr, [sp, #{emit_int(n - 4)}]\n`
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
`{emit_label !tailrec_entry_point}:\n`;
|
`{emit_label !tailrec_entry_point}:\n`;
|
||||||
emit_all 0 fundecl.fun_body;
|
emit_all 0 fundecl.fun_body;
|
||||||
|
|
|
@ -34,8 +34,12 @@ type addressing_mode =
|
||||||
(* Specific operations *)
|
(* Specific operations *)
|
||||||
|
|
||||||
type specific_operation =
|
type specific_operation =
|
||||||
|
| Ifar_alloc of int
|
||||||
|
| Ifar_intop_checkbound
|
||||||
|
| Ifar_intop_imm_checkbound of int
|
||||||
| Ishiftarith of arith_operation * int
|
| Ishiftarith of arith_operation * int
|
||||||
| Ishiftcheckbound of int
|
| Ishiftcheckbound of int
|
||||||
|
| Ifar_shiftcheckbound of int
|
||||||
| Imuladd (* multiply and add *)
|
| Imuladd (* multiply and add *)
|
||||||
| Imulsub (* multiply and subtract *)
|
| Imulsub (* multiply and subtract *)
|
||||||
| Inegmulf (* floating-point negate and multiply *)
|
| Inegmulf (* floating-point negate and multiply *)
|
||||||
|
@ -91,6 +95,12 @@ let print_addressing printreg addr ppf arg =
|
||||||
|
|
||||||
let print_specific_operation printreg op ppf arg =
|
let print_specific_operation printreg op ppf arg =
|
||||||
match op with
|
match op with
|
||||||
|
| Ifar_alloc n ->
|
||||||
|
fprintf ppf "(far) alloc %i" n
|
||||||
|
| Ifar_intop_checkbound ->
|
||||||
|
fprintf ppf "%a (far) check > %a" printreg arg.(0) printreg arg.(1)
|
||||||
|
| Ifar_intop_imm_checkbound n ->
|
||||||
|
fprintf ppf "%a (far) check > %i" printreg arg.(0) n
|
||||||
| Ishiftarith(op, shift) ->
|
| Ishiftarith(op, shift) ->
|
||||||
let op_name = function
|
let op_name = function
|
||||||
| Ishiftadd -> "+"
|
| Ishiftadd -> "+"
|
||||||
|
@ -103,6 +113,9 @@ let print_specific_operation printreg op ppf arg =
|
||||||
printreg arg.(0) (op_name op) printreg arg.(1) shift_mark
|
printreg arg.(0) (op_name op) printreg arg.(1) shift_mark
|
||||||
| Ishiftcheckbound n ->
|
| Ishiftcheckbound n ->
|
||||||
fprintf ppf "check %a >> %i > %a" printreg arg.(0) n printreg arg.(1)
|
fprintf ppf "check %a >> %i > %a" printreg arg.(0) n printreg arg.(1)
|
||||||
|
| Ifar_shiftcheckbound n ->
|
||||||
|
fprintf ppf
|
||||||
|
"(far) check %a >> %i > %a" printreg arg.(0) n printreg arg.(1)
|
||||||
| Imuladd ->
|
| Imuladd ->
|
||||||
fprintf ppf "(%a * %a) + %a"
|
fprintf ppf "(%a * %a) + %a"
|
||||||
printreg arg.(0)
|
printreg arg.(0)
|
||||||
|
|
|
@ -231,6 +231,32 @@ let emit_intconst dst n =
|
||||||
in
|
in
|
||||||
if n < 0n then emit_neg true 48 else emit_pos true 48
|
if n < 0n then emit_neg true 48 else emit_pos true 48
|
||||||
|
|
||||||
|
let num_instructions_for_intconst n =
|
||||||
|
let num_instructions = ref 0 in
|
||||||
|
let rec count_pos first shift =
|
||||||
|
if shift < 0 then begin
|
||||||
|
if first then incr num_instructions
|
||||||
|
end else begin
|
||||||
|
let s = Nativeint.(logand (shift_right_logical n shift) 0xFFFFn) in
|
||||||
|
if s = 0n then count_pos first (shift - 16) else begin
|
||||||
|
incr num_instructions;
|
||||||
|
count_pos false (shift - 16)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
and count_neg first shift =
|
||||||
|
if shift < 0 then begin
|
||||||
|
if first then incr num_instructions
|
||||||
|
end else begin
|
||||||
|
let s = Nativeint.(logand (shift_right_logical n shift) 0xFFFFn) in
|
||||||
|
if s = 0xFFFFn then count_neg first (shift - 16) else begin
|
||||||
|
incr num_instructions;
|
||||||
|
count_neg false (shift - 16)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
in
|
||||||
|
if n < 0n then count_neg true 48 else count_pos true 48;
|
||||||
|
!num_instructions
|
||||||
|
|
||||||
(* Recognize float constants appropriate for FMOV dst, #fpimm instruction:
|
(* Recognize float constants appropriate for FMOV dst, #fpimm instruction:
|
||||||
"a normalized binary floating point encoding with 1 sign bit, 4
|
"a normalized binary floating point encoding with 1 sign bit, 4
|
||||||
bits of fraction and a 3-bit exponent" *)
|
bits of fraction and a 3-bit exponent" *)
|
||||||
|
@ -302,6 +328,217 @@ let emit_load_symbol_addr dst s =
|
||||||
` ldr {emit_reg dst}, [{emit_reg dst}, #:got_lo12:{emit_symbol s}]\n`
|
` ldr {emit_reg dst}, [{emit_reg dst}, #:got_lo12:{emit_symbol s}]\n`
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(* The following functions are used for calculating the sizes of the
|
||||||
|
call GC and bounds check points emitted out-of-line from the function
|
||||||
|
body. See branch_relaxation.mli. *)
|
||||||
|
|
||||||
|
let num_call_gc_and_check_bound_points instr =
|
||||||
|
let rec loop instr ((call_gc, check_bound) as totals) =
|
||||||
|
match instr.desc with
|
||||||
|
| Lend -> totals
|
||||||
|
| Lop (Ialloc _) when !fastcode_flag ->
|
||||||
|
loop instr.next (call_gc + 1, check_bound)
|
||||||
|
| 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. *)
|
||||||
|
if not !Clflags.debug then 1
|
||||||
|
else check_bound + 1
|
||||||
|
in
|
||||||
|
loop instr.next (call_gc, check_bound)
|
||||||
|
(* 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_imm_checkbound _))
|
||||||
|
| Lop (Ispecific (Ifar_shiftcheckbound _)) -> assert false
|
||||||
|
| _ -> loop instr.next totals
|
||||||
|
in
|
||||||
|
loop instr (0, 0)
|
||||||
|
|
||||||
|
let max_out_of_line_code_offset instr ~num_call_gc ~num_check_bound =
|
||||||
|
if num_call_gc < 1 && num_check_bound < 1 then 0
|
||||||
|
else begin
|
||||||
|
let size_of_call_gc = 2 in
|
||||||
|
let size_of_check_bound = 1 in
|
||||||
|
let size_of_last_thing =
|
||||||
|
(* Call-GC points come before check-bound points. *)
|
||||||
|
if num_check_bound >= 1 then size_of_check_bound else size_of_call_gc
|
||||||
|
in
|
||||||
|
let total_size =
|
||||||
|
size_of_call_gc*num_call_gc + size_of_check_bound*num_check_bound
|
||||||
|
in
|
||||||
|
let max_offset = total_size - size_of_last_thing in
|
||||||
|
assert (max_offset >= 0);
|
||||||
|
max_offset
|
||||||
|
end
|
||||||
|
|
||||||
|
module BR = Branch_relaxation.Make (struct
|
||||||
|
(* CR-someday mshinwell: B and BL have +/- 128Mb ranges; for the moment we
|
||||||
|
assume we will never exceed this. It would seem to be most likely to
|
||||||
|
occur for branches between functions; in this case, the linker should be
|
||||||
|
able to insert veneers anyway. (See section 4.6.7 of the document
|
||||||
|
"ELF for the ARM 64-bit architecture (AArch64)".) *)
|
||||||
|
|
||||||
|
type distance = int
|
||||||
|
|
||||||
|
module Cond_branch = struct
|
||||||
|
type t = TB | CB | Bcc
|
||||||
|
|
||||||
|
let all = [TB; CB; Bcc]
|
||||||
|
|
||||||
|
(* AArch64 instructions are 32 bits wide, so [distance] in this module
|
||||||
|
means units of 32-bit words. *)
|
||||||
|
let max_displacement = function
|
||||||
|
| TB -> 32 * 1024 / 4 (* +/- 32Kb *)
|
||||||
|
| CB | Bcc -> 1 * 1024 * 1024 / 4 (* +/- 1Mb *)
|
||||||
|
|
||||||
|
let classify_instr = function
|
||||||
|
| Lop (Ialloc _)
|
||||||
|
| 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
|
||||||
|
conditional branches that might need relaxing. *)
|
||||||
|
| Lcondbranch (Itruetest, _)
|
||||||
|
| Lcondbranch (Ifalsetest, _) -> Some CB
|
||||||
|
| Lcondbranch (Iinttest _, _)
|
||||||
|
| Lcondbranch (Iinttest_imm _, _)
|
||||||
|
| Lcondbranch (Ifloattest _, _) -> Some Bcc
|
||||||
|
| Lcondbranch (Ioddtest, _)
|
||||||
|
| Lcondbranch (Ieventest, _) -> Some TB
|
||||||
|
| Lcondbranch3 _ -> Some Bcc
|
||||||
|
| _ -> None
|
||||||
|
end
|
||||||
|
|
||||||
|
let offset_pc_at_branch = 0
|
||||||
|
|
||||||
|
let epilogue_size () =
|
||||||
|
if !contains_calls then 3 else 2
|
||||||
|
|
||||||
|
let instr_size = function
|
||||||
|
| Lend -> 0
|
||||||
|
| Lop (Imove | Ispill | Ireload) -> 1
|
||||||
|
| Lop (Iconst_int n | Iconst_blockheader n) ->
|
||||||
|
num_instructions_for_intconst n
|
||||||
|
| Lop (Iconst_float _) -> 2
|
||||||
|
| Lop (Iconst_symbol _) -> 2
|
||||||
|
| Lop (Icall_ind) -> 1
|
||||||
|
| Lop (Icall_imm _) -> 1
|
||||||
|
| Lop (Itailcall_ind) -> epilogue_size ()
|
||||||
|
| Lop (Itailcall_imm s) ->
|
||||||
|
if s = !function_name then 1 else epilogue_size ()
|
||||||
|
| Lop (Iextcall (_, false)) -> 1
|
||||||
|
| Lop (Iextcall (_, true)) -> 3
|
||||||
|
| Lop (Istackoffset _) -> 2
|
||||||
|
| Lop (Iload (size, addr)) | Lop (Istore (size, addr, _)) ->
|
||||||
|
let based = match addr with Iindexed _ -> 0 | Ibased _ -> 1 in
|
||||||
|
based + begin match size with Single -> 2 | _ -> 1 end
|
||||||
|
| Lop (Ialloc _) when !fastcode_flag -> 4
|
||||||
|
| Lop (Ispecific (Ifar_alloc _)) when !fastcode_flag -> 5
|
||||||
|
| Lop (Ialloc num_words) | Lop (Ispecific (Ifar_alloc num_words)) ->
|
||||||
|
begin match num_words with
|
||||||
|
| 16 | 24 | 32 -> 1
|
||||||
|
| _ -> 1 + num_instructions_for_intconst (Nativeint.of_int num_words)
|
||||||
|
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 (Ispecific (Ifar_intop_imm_checkbound _)) -> 3
|
||||||
|
| Lop (Ispecific (Ishiftcheckbound _)) -> 2
|
||||||
|
| Lop (Ispecific (Ifar_shiftcheckbound _)) -> 3
|
||||||
|
| Lop (Iintop Imod) -> 2
|
||||||
|
| Lop (Iintop Imulh) -> 1
|
||||||
|
| Lop (Iintop _) -> 1
|
||||||
|
| Lop (Iintop_imm _) -> 1
|
||||||
|
| Lop (Ifloatofint | Iintoffloat | Iabsf | Inegf | Ispecific Isqrtf) -> 1
|
||||||
|
| Lop (Iaddf | Isubf | Imulf | Idivf | Ispecific Inegmulf) -> 1
|
||||||
|
| Lop (Ispecific (Imuladdf | Inegmuladdf | Imulsubf | Inegmulsubf)) -> 1
|
||||||
|
| Lop (Ispecific (Ishiftarith _)) -> 1
|
||||||
|
| Lop (Ispecific (Imuladd | Imulsub)) -> 1
|
||||||
|
| Lop (Ispecific (Ibswap 16)) -> 2
|
||||||
|
| Lop (Ispecific (Ibswap _)) -> 1
|
||||||
|
| Lreloadretaddr -> 0
|
||||||
|
| Lreturn -> epilogue_size ()
|
||||||
|
| Llabel _ -> 0
|
||||||
|
| Lbranch _ -> 1
|
||||||
|
| Lcondbranch (tst, _) ->
|
||||||
|
begin match tst with
|
||||||
|
| Itruetest -> 1
|
||||||
|
| Ifalsetest -> 1
|
||||||
|
| Iinttest _ -> 2
|
||||||
|
| Iinttest_imm _ -> 2
|
||||||
|
| Ifloattest _ -> 2
|
||||||
|
| Ioddtest -> 1
|
||||||
|
| Ieventest -> 1
|
||||||
|
end
|
||||||
|
| Lcondbranch3 (lbl0, lbl1, lbl2) ->
|
||||||
|
1 + begin match lbl0 with None -> 0 | Some _ -> 1 end
|
||||||
|
+ begin match lbl1 with None -> 0 | Some _ -> 1 end
|
||||||
|
+ begin match lbl2 with None -> 0 | Some _ -> 1 end
|
||||||
|
| Lswitch jumptbl -> 3 + Array.length jumptbl
|
||||||
|
| Lsetuptrap _ -> 2
|
||||||
|
| Lpushtrap -> 3
|
||||||
|
| Lpoptrap -> 1
|
||||||
|
| Lraise k ->
|
||||||
|
begin match !Clflags.debug, k with
|
||||||
|
| true, (Lambda.Raise_regular | Lambda.Raise_reraise) -> 1
|
||||||
|
| false, _
|
||||||
|
| true, Lambda.Raise_notrace -> 4
|
||||||
|
end
|
||||||
|
|
||||||
|
let relax_allocation ~num_words =
|
||||||
|
Lop (Ispecific (Ifar_alloc num_words))
|
||||||
|
|
||||||
|
let relax_intop_checkbound () =
|
||||||
|
Lop (Ispecific Ifar_intop_checkbound)
|
||||||
|
|
||||||
|
let relax_intop_imm_checkbound ~bound =
|
||||||
|
Lop (Ispecific (Ifar_intop_imm_checkbound bound))
|
||||||
|
|
||||||
|
let relax_specific_op = function
|
||||||
|
| Ishiftcheckbound shift -> Lop (Ispecific (Ifar_shiftcheckbound shift))
|
||||||
|
| _ -> assert false
|
||||||
|
end)
|
||||||
|
|
||||||
|
(* Output the assembly code for allocation. *)
|
||||||
|
|
||||||
|
let assembly_code_for_allocation i ~n ~far =
|
||||||
|
let lbl_frame = record_frame_label i.live i.dbg in
|
||||||
|
if !fastcode_flag then begin
|
||||||
|
let lbl_redo = new_label() in
|
||||||
|
let lbl_call_gc = new_label() in
|
||||||
|
`{emit_label lbl_redo}:`;
|
||||||
|
` sub {emit_reg reg_alloc_ptr}, {emit_reg reg_alloc_ptr}, #{emit_int n}\n`;
|
||||||
|
` cmp {emit_reg reg_alloc_ptr}, {emit_reg reg_alloc_limit}\n`;
|
||||||
|
` add {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, #8\n`;
|
||||||
|
if not far then begin
|
||||||
|
` b.lo {emit_label lbl_call_gc}\n`
|
||||||
|
end else begin
|
||||||
|
let lbl = new_label () in
|
||||||
|
` b.cs {emit_label lbl}\n`;
|
||||||
|
` b {emit_label lbl_call_gc}\n`;
|
||||||
|
`{emit_label lbl}:\n`
|
||||||
|
end;
|
||||||
|
call_gc_sites :=
|
||||||
|
{ gc_lbl = lbl_call_gc;
|
||||||
|
gc_return_lbl = lbl_redo;
|
||||||
|
gc_frame_lbl = lbl_frame } :: !call_gc_sites
|
||||||
|
end else begin
|
||||||
|
begin match n with
|
||||||
|
| 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);
|
||||||
|
` bl {emit_symbol "caml_allocN"}\n`
|
||||||
|
end;
|
||||||
|
`{emit_label lbl_frame}: add {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, #8\n`
|
||||||
|
end
|
||||||
|
|
||||||
(* Output the assembly code for an instruction *)
|
(* Output the assembly code for an instruction *)
|
||||||
|
|
||||||
let emit_instr i =
|
let emit_instr i =
|
||||||
|
@ -410,29 +647,9 @@ let emit_instr i =
|
||||||
` str {emit_reg src}, {emit_addressing addr base}\n`
|
` str {emit_reg src}, {emit_addressing addr base}\n`
|
||||||
end
|
end
|
||||||
| Lop(Ialloc n) ->
|
| Lop(Ialloc n) ->
|
||||||
let lbl_frame = record_frame_label i.live i.dbg in
|
assembly_code_for_allocation i ~n ~far:false
|
||||||
if !fastcode_flag then begin
|
| Lop(Ispecific (Ifar_alloc n)) ->
|
||||||
let lbl_redo = new_label() in
|
assembly_code_for_allocation i ~n ~far:true
|
||||||
let lbl_call_gc = new_label() in
|
|
||||||
`{emit_label lbl_redo}:`;
|
|
||||||
` sub {emit_reg reg_alloc_ptr}, {emit_reg reg_alloc_ptr}, #{emit_int n}\n`;
|
|
||||||
` cmp {emit_reg reg_alloc_ptr}, {emit_reg reg_alloc_limit}\n`;
|
|
||||||
` add {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, #8\n`;
|
|
||||||
` b.lo {emit_label lbl_call_gc}\n`;
|
|
||||||
call_gc_sites :=
|
|
||||||
{ gc_lbl = lbl_call_gc;
|
|
||||||
gc_return_lbl = lbl_redo;
|
|
||||||
gc_frame_lbl = lbl_frame } :: !call_gc_sites
|
|
||||||
end else begin
|
|
||||||
begin match n with
|
|
||||||
| 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);
|
|
||||||
` bl {emit_symbol "caml_allocN"}\n`
|
|
||||||
end;
|
|
||||||
`{emit_label lbl_frame}: add {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, #8\n`
|
|
||||||
end
|
|
||||||
| Lop(Iintop(Icomp cmp)) ->
|
| Lop(Iintop(Icomp cmp)) ->
|
||||||
` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
|
` 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`
|
` cset {emit_reg i.res.(0)}, {emit_string (name_for_comparison cmp)}\n`
|
||||||
|
@ -443,14 +660,35 @@ let emit_instr i =
|
||||||
let lbl = bound_error_label i.dbg in
|
let lbl = bound_error_label i.dbg in
|
||||||
` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
|
` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
|
||||||
` b.ls {emit_label lbl}\n`
|
` b.ls {emit_label lbl}\n`
|
||||||
|
| 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, n)) ->
|
| Lop(Iintop_imm(Icheckbound, n)) ->
|
||||||
let lbl = bound_error_label i.dbg in
|
let lbl = bound_error_label i.dbg in
|
||||||
` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`;
|
` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`;
|
||||||
` b.ls {emit_label lbl}\n`
|
` b.ls {emit_label lbl}\n`
|
||||||
|
| Lop(Ispecific(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)) ->
|
| Lop(Ispecific(Ishiftcheckbound shift)) ->
|
||||||
let lbl = bound_error_label i.dbg in
|
let lbl = bound_error_label i.dbg in
|
||||||
` cmp {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}, lsr #{emit_int shift}\n`;
|
` cmp {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}, lsr #{emit_int shift}\n`;
|
||||||
` b.cs {emit_label lbl}\n`
|
` b.cs {emit_label lbl}\n`
|
||||||
|
| 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`;
|
||||||
|
` b {emit_label lbl}\n`;
|
||||||
|
`{emit_label lbl2}:\n`;
|
||||||
| Lop(Iintop Imod) ->
|
| Lop(Iintop Imod) ->
|
||||||
` sdiv {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
|
` sdiv {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
|
||||||
` msub {emit_reg i.res.(0)}, {emit_reg reg_tmp1}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`
|
` msub {emit_reg i.res.(0)}, {emit_reg reg_tmp1}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`
|
||||||
|
@ -506,7 +744,7 @@ let emit_instr i =
|
||||||
begin match size with
|
begin match size with
|
||||||
| 16 ->
|
| 16 ->
|
||||||
` rev16 {emit_wreg i.res.(0)}, {emit_wreg i.arg.(0)}\n`;
|
` rev16 {emit_wreg i.res.(0)}, {emit_wreg i.arg.(0)}\n`;
|
||||||
` ubfm {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, #0, #16\n`
|
` ubfm {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, #0, #15\n`
|
||||||
| 32 ->
|
| 32 ->
|
||||||
` rev {emit_wreg i.res.(0)}, {emit_wreg i.arg.(0)}\n`
|
` rev {emit_wreg i.res.(0)}, {emit_wreg i.arg.(0)}\n`
|
||||||
| 64 ->
|
| 64 ->
|
||||||
|
@ -654,12 +892,24 @@ let fundecl fundecl =
|
||||||
let n = frame_size() in
|
let n = frame_size() in
|
||||||
if n > 0 then
|
if n > 0 then
|
||||||
emit_stack_adjustment (-n);
|
emit_stack_adjustment (-n);
|
||||||
if !contains_calls then
|
if !contains_calls then begin
|
||||||
` str x30, [sp, #{emit_int (n-8)}]\n`;
|
cfi_offset ~reg:30 (* return address *) ~offset:(-8);
|
||||||
|
` str x30, [sp, #{emit_int (n-8)}]\n`
|
||||||
|
end;
|
||||||
`{emit_label !tailrec_entry_point}:\n`;
|
`{emit_label !tailrec_entry_point}:\n`;
|
||||||
|
let num_call_gc, num_check_bound =
|
||||||
|
num_call_gc_and_check_bound_points fundecl.fun_body
|
||||||
|
in
|
||||||
|
let max_out_of_line_code_offset =
|
||||||
|
max_out_of_line_code_offset fundecl.fun_body ~num_call_gc
|
||||||
|
~num_check_bound
|
||||||
|
in
|
||||||
|
BR.relax fundecl.fun_body ~max_out_of_line_code_offset;
|
||||||
emit_all fundecl.fun_body;
|
emit_all fundecl.fun_body;
|
||||||
List.iter emit_call_gc !call_gc_sites;
|
List.iter emit_call_gc !call_gc_sites;
|
||||||
List.iter emit_call_bound_error !bound_error_sites;
|
List.iter emit_call_bound_error !bound_error_sites;
|
||||||
|
assert (List.length !call_gc_sites = num_call_gc);
|
||||||
|
assert (List.length !bound_error_sites = num_check_bound);
|
||||||
cfi_endproc();
|
cfi_endproc();
|
||||||
` .type {emit_symbol fundecl.fun_name}, %function\n`;
|
` .type {emit_symbol fundecl.fun_name}, %function\n`;
|
||||||
` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`;
|
` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`;
|
||||||
|
|
|
@ -277,12 +277,13 @@ let link_shared ppf objfiles output_name =
|
||||||
let call_linker file_list startup_file output_name =
|
let call_linker file_list startup_file output_name =
|
||||||
let main_dll = !Clflags.output_c_object
|
let main_dll = !Clflags.output_c_object
|
||||||
&& Filename.check_suffix output_name Config.ext_dll
|
&& Filename.check_suffix output_name Config.ext_dll
|
||||||
|
and main_obj_runtime = !Clflags.output_complete_object
|
||||||
in
|
in
|
||||||
let files = startup_file :: (List.rev file_list) in
|
let files = startup_file :: (List.rev file_list) in
|
||||||
let files, c_lib =
|
let files, c_lib =
|
||||||
if (not !Clflags.output_c_object) || main_dll then
|
if (not !Clflags.output_c_object) || main_dll || main_obj_runtime then
|
||||||
files @ (List.rev !Clflags.ccobjs) @ runtime_lib (),
|
files @ (List.rev !Clflags.ccobjs) @ runtime_lib (),
|
||||||
(if !Clflags.nopervasives then "" else Config.native_c_libraries)
|
(if !Clflags.nopervasives || main_obj_runtime then "" else Config.native_c_libraries)
|
||||||
else
|
else
|
||||||
files, ""
|
files, ""
|
||||||
in
|
in
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
(***********************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* OCaml *)
|
||||||
|
(* *)
|
||||||
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
||||||
|
(* Mark Shinwell, Jane Street Europe *)
|
||||||
|
(* *)
|
||||||
|
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
||||||
|
(* en Automatique. All rights reserved. This file is distributed *)
|
||||||
|
(* under the terms of the Q Public License version 1.0. *)
|
||||||
|
(* *)
|
||||||
|
(***********************************************************************)
|
||||||
|
|
||||||
|
open Mach
|
||||||
|
open Linearize
|
||||||
|
|
||||||
|
module Make (T : Branch_relaxation_intf.S) = struct
|
||||||
|
let label_map code =
|
||||||
|
let map = Hashtbl.create 37 in
|
||||||
|
let rec fill_map pc instr =
|
||||||
|
match instr.desc with
|
||||||
|
| Lend -> (pc, map)
|
||||||
|
| Llabel lbl -> Hashtbl.add map lbl pc; fill_map pc instr.next
|
||||||
|
| op -> fill_map (pc + T.instr_size op) instr.next
|
||||||
|
in
|
||||||
|
fill_map 0 code
|
||||||
|
|
||||||
|
let branch_overflows map pc_branch lbl_dest max_branch_offset =
|
||||||
|
let pc_dest = Hashtbl.find map lbl_dest in
|
||||||
|
let delta = pc_dest - (pc_branch + T.offset_pc_at_branch) in
|
||||||
|
delta <= -max_branch_offset || delta >= max_branch_offset
|
||||||
|
|
||||||
|
let opt_branch_overflows map pc_branch opt_lbl_dest max_branch_offset =
|
||||||
|
match opt_lbl_dest with
|
||||||
|
| None -> false
|
||||||
|
| Some lbl_dest ->
|
||||||
|
branch_overflows map pc_branch lbl_dest max_branch_offset
|
||||||
|
|
||||||
|
let instr_overflows ~code_size ~max_out_of_line_code_offset instr map pc =
|
||||||
|
match T.Cond_branch.classify_instr instr.desc with
|
||||||
|
| None -> false
|
||||||
|
| Some branch ->
|
||||||
|
let max_branch_offset =
|
||||||
|
(* Remember to cut some slack for multi-word instructions (in the
|
||||||
|
[Linearize] sense of the word) where the branch can be anywhere in
|
||||||
|
the middle. 12 words of slack is plenty. *)
|
||||||
|
T.Cond_branch.max_displacement branch - 12
|
||||||
|
in
|
||||||
|
match instr.desc with
|
||||||
|
| Lop (Ialloc _)
|
||||||
|
| 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
|
||||||
|
that any of these may branch to an out-of-line code block. *)
|
||||||
|
code_size + max_out_of_line_code_offset - pc >= max_branch_offset
|
||||||
|
| Lcondbranch (_, lbl) ->
|
||||||
|
branch_overflows map pc lbl max_branch_offset
|
||||||
|
| Lcondbranch3 (lbl0, lbl1, lbl2) ->
|
||||||
|
opt_branch_overflows map pc lbl0 max_branch_offset
|
||||||
|
|| opt_branch_overflows map pc lbl1 max_branch_offset
|
||||||
|
|| opt_branch_overflows map pc lbl2 max_branch_offset
|
||||||
|
| _ ->
|
||||||
|
Misc.fatal_error "Unsupported instruction for branch relaxation"
|
||||||
|
|
||||||
|
let fixup_branches ~code_size ~max_out_of_line_code_offset map code =
|
||||||
|
let expand_optbranch lbl n arg next =
|
||||||
|
match lbl with
|
||||||
|
| None -> next
|
||||||
|
| Some l ->
|
||||||
|
instr_cons (Lcondbranch (Iinttest_imm (Isigned Cmm.Ceq, n), l))
|
||||||
|
arg [||] next
|
||||||
|
in
|
||||||
|
let rec fixup did_fix pc instr =
|
||||||
|
match instr.desc with
|
||||||
|
| Lend -> did_fix
|
||||||
|
| _ ->
|
||||||
|
let overflows =
|
||||||
|
instr_overflows ~code_size ~max_out_of_line_code_offset instr map pc
|
||||||
|
in
|
||||||
|
if not overflows then
|
||||||
|
fixup did_fix (pc + T.instr_size instr.desc) instr.next
|
||||||
|
else
|
||||||
|
match instr.desc with
|
||||||
|
| Lop (Ialloc num_words) ->
|
||||||
|
instr.desc <- T.relax_allocation ~num_words;
|
||||||
|
fixup true (pc + T.instr_size instr.desc) instr.next
|
||||||
|
| Lop (Iintop Icheckbound) ->
|
||||||
|
instr.desc <- T.relax_intop_checkbound ();
|
||||||
|
fixup true (pc + T.instr_size instr.desc) instr.next
|
||||||
|
| Lop (Iintop_imm (Icheckbound, bound)) ->
|
||||||
|
instr.desc <- 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;
|
||||||
|
fixup true (pc + T.instr_size instr.desc) instr.next
|
||||||
|
| Lcondbranch (test, lbl) ->
|
||||||
|
let lbl2 = new_label() in
|
||||||
|
let cont =
|
||||||
|
instr_cons (Lbranch lbl) [||] [||]
|
||||||
|
(instr_cons (Llabel lbl2) [||] [||] instr.next)
|
||||||
|
in
|
||||||
|
instr.desc <- Lcondbranch (invert_test test, lbl2);
|
||||||
|
instr.next <- cont;
|
||||||
|
fixup true (pc + T.instr_size instr.desc) instr.next
|
||||||
|
| Lcondbranch3 (lbl0, lbl1, lbl2) ->
|
||||||
|
let cont =
|
||||||
|
expand_optbranch lbl0 0 instr.arg
|
||||||
|
(expand_optbranch lbl1 1 instr.arg
|
||||||
|
(expand_optbranch lbl2 2 instr.arg instr.next))
|
||||||
|
in
|
||||||
|
instr.desc <- cont.desc;
|
||||||
|
instr.next <- cont.next;
|
||||||
|
fixup true pc instr
|
||||||
|
| _ ->
|
||||||
|
(* Any other instruction has already been rejected in
|
||||||
|
[instr_overflows] above.
|
||||||
|
We can *never* get here. *)
|
||||||
|
assert false
|
||||||
|
in
|
||||||
|
fixup false 0 code
|
||||||
|
|
||||||
|
(* Iterate branch expansion till all conditional branches are OK *)
|
||||||
|
|
||||||
|
let rec relax code ~max_out_of_line_code_offset =
|
||||||
|
let min_of_max_branch_offsets =
|
||||||
|
List.fold_left (fun min_of_max_branch_offsets branch ->
|
||||||
|
min min_of_max_branch_offsets
|
||||||
|
(T.Cond_branch.max_displacement branch))
|
||||||
|
max_int T.Cond_branch.all
|
||||||
|
in
|
||||||
|
let (code_size, map) = label_map code in
|
||||||
|
if code_size >= min_of_max_branch_offsets
|
||||||
|
&& fixup_branches ~code_size ~max_out_of_line_code_offset map code
|
||||||
|
then relax code ~max_out_of_line_code_offset
|
||||||
|
else ()
|
||||||
|
end
|
|
@ -0,0 +1,26 @@
|
||||||
|
(***********************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* OCaml *)
|
||||||
|
(* *)
|
||||||
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
||||||
|
(* Mark Shinwell, Jane Street Europe *)
|
||||||
|
(* *)
|
||||||
|
(* Copyright 2015 Institut National de Recherche en Informatique et *)
|
||||||
|
(* en Automatique. All rights reserved. This file is distributed *)
|
||||||
|
(* under the terms of the Q Public License version 1.0. *)
|
||||||
|
(* *)
|
||||||
|
(***********************************************************************)
|
||||||
|
|
||||||
|
(* Fix up conditional branches that exceed hardware-allowed ranges. *)
|
||||||
|
|
||||||
|
module Make (T : Branch_relaxation_intf.S) : sig
|
||||||
|
val relax
|
||||||
|
: Linearize.instruction
|
||||||
|
(* [max_offset_of_out_of_line_code] specifies the furthest distance,
|
||||||
|
measured from the first address immediately after the last instruction
|
||||||
|
of the function, that may be branched to from within the function in
|
||||||
|
order to execute "out of line" code blocks such as call GC and
|
||||||
|
bounds check points. *)
|
||||||
|
-> max_out_of_line_code_offset:T.distance
|
||||||
|
-> unit
|
||||||
|
end
|
|
@ -0,0 +1,64 @@
|
||||||
|
(***********************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* OCaml *)
|
||||||
|
(* *)
|
||||||
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
||||||
|
(* Mark Shinwell, Jane Street Europe *)
|
||||||
|
(* *)
|
||||||
|
(* Copyright 2015 Institut National de Recherche en Informatique et *)
|
||||||
|
(* en Automatique. All rights reserved. This file is distributed *)
|
||||||
|
(* under the terms of the Q Public License version 1.0. *)
|
||||||
|
(* *)
|
||||||
|
(***********************************************************************)
|
||||||
|
|
||||||
|
module type S = sig
|
||||||
|
(* The distance between two instructions, in arbitrary units (typically
|
||||||
|
the natural word size of instructions). *)
|
||||||
|
type distance = int
|
||||||
|
|
||||||
|
module Cond_branch : sig
|
||||||
|
(* The various types of conditional branches for a given target that
|
||||||
|
may require relaxation. *)
|
||||||
|
type t
|
||||||
|
|
||||||
|
(* All values of type [t] that the emitter may produce. *)
|
||||||
|
val all : t list
|
||||||
|
|
||||||
|
(* If [max_displacement branch] is [n] then [branch] is assumed to
|
||||||
|
reach any address in the range [pc - n, pc + n] (inclusive), after
|
||||||
|
the [pc] of the branch has been adjusted by [offset_pc_at_branch]
|
||||||
|
(see below). *)
|
||||||
|
val max_displacement : t -> distance
|
||||||
|
|
||||||
|
(* Which variety of conditional branch may be produced by the emitter for a
|
||||||
|
given instruction description. For the moment we assume that only one
|
||||||
|
such variety per instruction description is needed.
|
||||||
|
|
||||||
|
N.B. The only instructions supported are the following:
|
||||||
|
- Lop (Ialloc _)
|
||||||
|
- Lop (Iintop Icheckbound)
|
||||||
|
- Lop (Iintop_imm (Icheckbound, _))
|
||||||
|
- Lop (Ispecific _)
|
||||||
|
- Lcondbranch (_, _)
|
||||||
|
- Lcondbranch3 (_, _, _)
|
||||||
|
[classify_instr] is expected to return [None] when called on any
|
||||||
|
instruction not in this list. *)
|
||||||
|
val classify_instr : Linearize.instruction_desc -> t option
|
||||||
|
end
|
||||||
|
|
||||||
|
(* The value to be added to the program counter (in [distance] units)
|
||||||
|
when it is at a branch instruction, prior to calculating the distance
|
||||||
|
to a branch target. *)
|
||||||
|
val offset_pc_at_branch : distance
|
||||||
|
|
||||||
|
(* The maximum size of a given instruction. *)
|
||||||
|
val instr_size : Linearize.instruction_desc -> distance
|
||||||
|
|
||||||
|
(* Insertion of target-specific code to relax operations that cannot be
|
||||||
|
relaxed generically. It is assumed that these rewrites do not change
|
||||||
|
the size of out-of-line code (cf. branch_relaxation.mli). *)
|
||||||
|
val relax_allocation : num_words:int -> Linearize.instruction_desc
|
||||||
|
val relax_intop_checkbound : unit -> Linearize.instruction_desc
|
||||||
|
val relax_intop_imm_checkbound : bound:int -> Linearize.instruction_desc
|
||||||
|
val relax_specific_op : Arch.specific_operation -> Linearize.instruction_desc
|
||||||
|
end
|
|
@ -349,8 +349,8 @@ let mod_int c1 c2 dbg =
|
||||||
[Cconst_symbol "caml_exn_Division_by_zero"]))
|
[Cconst_symbol "caml_exn_Division_by_zero"]))
|
||||||
| (c1, Cconst_int (1 | (-1))) ->
|
| (c1, Cconst_int (1 | (-1))) ->
|
||||||
Csequence(c1, Cconst_int 0)
|
Csequence(c1, Cconst_int 0)
|
||||||
| (Cconst_int(0 | 1 | (-1)) as c1, c2) ->
|
| (Cconst_int 0, c2) ->
|
||||||
Csequence(c2, c1)
|
Csequence(c2, Cconst_int 0)
|
||||||
| (Cconst_int n1, Cconst_int n2) ->
|
| (Cconst_int n1, Cconst_int n2) ->
|
||||||
Cconst_int (n1 mod n2)
|
Cconst_int (n1 mod n2)
|
||||||
| (c1, (Cconst_int n as c2)) when n <> min_int ->
|
| (c1, (Cconst_int n as c2)) when n <> min_int ->
|
||||||
|
|
|
@ -195,6 +195,15 @@ let cfi_adjust_cfa_offset n =
|
||||||
emit_string "\t.cfi_adjust_cfa_offset\t"; emit_int n; emit_string "\n";
|
emit_string "\t.cfi_adjust_cfa_offset\t"; emit_int n; emit_string "\n";
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let cfi_offset ~reg ~offset =
|
||||||
|
if is_cfi_enabled () then begin
|
||||||
|
emit_string "\t.cfi_offset ";
|
||||||
|
emit_int reg;
|
||||||
|
emit_string ", ";
|
||||||
|
emit_int offset;
|
||||||
|
emit_string "\n"
|
||||||
|
end
|
||||||
|
|
||||||
(* Emit debug information *)
|
(* Emit debug information *)
|
||||||
|
|
||||||
(* This assoc list is expected to be very short *)
|
(* This assoc list is expected to be very short *)
|
||||||
|
|
|
@ -60,6 +60,7 @@ val is_generic_function: string -> bool
|
||||||
val cfi_startproc : unit -> unit
|
val cfi_startproc : unit -> unit
|
||||||
val cfi_endproc : unit -> unit
|
val cfi_endproc : unit -> unit
|
||||||
val cfi_adjust_cfa_offset : int -> unit
|
val cfi_adjust_cfa_offset : int -> unit
|
||||||
|
val cfi_offset : reg:int -> offset:int -> unit
|
||||||
|
|
||||||
|
|
||||||
val binary_backend_available: bool ref
|
val binary_backend_available: bool ref
|
||||||
|
|
|
@ -308,126 +308,87 @@ let defined_functions = ref StringSet.empty
|
||||||
(* Label of glue code for calling the GC *)
|
(* Label of glue code for calling the GC *)
|
||||||
let call_gc_label = ref 0
|
let call_gc_label = ref 0
|
||||||
|
|
||||||
(* Fixup conditional branches that exceed hardware allowed range *)
|
module BR = Branch_relaxation.Make (struct
|
||||||
|
type distance = int
|
||||||
|
|
||||||
let load_store_size = function
|
module Cond_branch = struct
|
||||||
Ibased(s, d) -> 2
|
type t = Branch
|
||||||
| Iindexed ofs -> if is_immediate ofs then 1 else 3
|
|
||||||
| Iindexed2 -> 1
|
|
||||||
|
|
||||||
let instr_size = function
|
let all = [Branch]
|
||||||
Lend -> 0
|
|
||||||
| Lop(Imove | Ispill | Ireload) -> 1
|
let max_displacement = function
|
||||||
| Lop(Iconst_int n | Iconst_blockheader n) ->
|
(* 14-bit signed offset in words. *)
|
||||||
if is_native_immediate n then 1 else 2
|
| Branch -> 8192
|
||||||
| Lop(Iconst_float s) -> 2
|
|
||||||
| Lop(Iconst_symbol s) -> 2
|
let classify_instr = function
|
||||||
| Lop(Icall_ind) -> 2
|
| Lop (Ialloc _)
|
||||||
| Lop(Icall_imm s) -> 1
|
(* [Ialloc_far] does not need to be here, since its code sequence
|
||||||
| Lop(Itailcall_ind) -> 5
|
never involves any conditional branches that might need relaxing. *)
|
||||||
| Lop(Itailcall_imm s) -> if s = !function_name then 1 else 4
|
| Lcondbranch _
|
||||||
| Lop(Iextcall(s, true)) -> 3
|
| Lcondbranch3 _ -> Some Branch
|
||||||
| Lop(Iextcall(s, false)) -> if pic_externals then 4 else 1
|
| _ -> None
|
||||||
| Lop(Istackoffset n) -> 1
|
end
|
||||||
| Lop(Iload(chunk, addr)) ->
|
|
||||||
|
let offset_pc_at_branch = 1
|
||||||
|
|
||||||
|
let load_store_size = function
|
||||||
|
| Ibased(s, d) -> 2
|
||||||
|
| Iindexed ofs -> if is_immediate ofs then 1 else 3
|
||||||
|
| Iindexed2 -> 1
|
||||||
|
|
||||||
|
let instr_size = function
|
||||||
|
| Lend -> 0
|
||||||
|
| Lop(Imove | Ispill | Ireload) -> 1
|
||||||
|
| Lop(Iconst_int n | Iconst_blockheader n) ->
|
||||||
|
if is_native_immediate n then 1 else 2
|
||||||
|
| Lop(Iconst_float s) -> 2
|
||||||
|
| Lop(Iconst_symbol s) -> 2
|
||||||
|
| Lop(Icall_ind) -> 2
|
||||||
|
| Lop(Icall_imm s) -> 1
|
||||||
|
| Lop(Itailcall_ind) -> 5
|
||||||
|
| Lop(Itailcall_imm s) -> if s = !function_name then 1 else 4
|
||||||
|
| Lop(Iextcall(s, true)) -> 3
|
||||||
|
| Lop(Iextcall(s, false)) -> if pic_externals then 4 else 1
|
||||||
|
| Lop(Istackoffset n) -> 1
|
||||||
|
| Lop(Iload(chunk, addr)) ->
|
||||||
if chunk = Byte_signed
|
if chunk = Byte_signed
|
||||||
then load_store_size addr + 1
|
then load_store_size addr + 1
|
||||||
else load_store_size addr
|
else load_store_size addr
|
||||||
| Lop(Istore(chunk, addr, _)) -> load_store_size addr
|
| Lop(Istore(chunk, addr, _)) -> load_store_size addr
|
||||||
| Lop(Ialloc n) -> 4
|
| Lop(Ialloc n) -> 4
|
||||||
| Lop(Ispecific(Ialloc_far n)) -> 5
|
| Lop(Ispecific(Ialloc_far n)) -> 5
|
||||||
| Lop(Iintop Imod) -> 3
|
| Lop(Iintop Imod) -> 3
|
||||||
| Lop(Iintop(Icomp cmp)) -> 4
|
| Lop(Iintop(Icomp cmp)) -> 4
|
||||||
| Lop(Iintop op) -> 1
|
| Lop(Iintop op) -> 1
|
||||||
| Lop(Iintop_imm(Icomp cmp, n)) -> 4
|
| Lop(Iintop_imm(Icomp cmp, n)) -> 4
|
||||||
| Lop(Iintop_imm(op, n)) -> 1
|
| Lop(Iintop_imm(op, n)) -> 1
|
||||||
| Lop(Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf) -> 1
|
| Lop(Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf) -> 1
|
||||||
| Lop(Ifloatofint) -> 9
|
| Lop(Ifloatofint) -> 9
|
||||||
| Lop(Iintoffloat) -> 4
|
| Lop(Iintoffloat) -> 4
|
||||||
| Lop(Ispecific sop) -> 1
|
| Lop(Ispecific sop) -> 1
|
||||||
| Lreloadretaddr -> 2
|
| Lreloadretaddr -> 2
|
||||||
| Lreturn -> 2
|
| Lreturn -> 2
|
||||||
| Llabel lbl -> 0
|
| Llabel lbl -> 0
|
||||||
| Lbranch lbl -> 1
|
| Lbranch lbl -> 1
|
||||||
| Lcondbranch(tst, lbl) -> 2
|
| Lcondbranch(tst, lbl) -> 2
|
||||||
| Lcondbranch3(lbl0, lbl1, lbl2) ->
|
| Lcondbranch3(lbl0, lbl1, lbl2) ->
|
||||||
1 + (if lbl0 = None then 0 else 1)
|
1 + (if lbl0 = None then 0 else 1)
|
||||||
+ (if lbl1 = None then 0 else 1)
|
+ (if lbl1 = None then 0 else 1)
|
||||||
+ (if lbl2 = None then 0 else 1)
|
+ (if lbl2 = None then 0 else 1)
|
||||||
| Lswitch jumptbl -> 8
|
| Lswitch jumptbl -> 8
|
||||||
| Lsetuptrap lbl -> 1
|
| Lsetuptrap lbl -> 1
|
||||||
| Lpushtrap -> 4
|
| Lpushtrap -> 4
|
||||||
| Lpoptrap -> 2
|
| Lpoptrap -> 2
|
||||||
| Lraise _ -> 6
|
| Lraise _ -> 6
|
||||||
|
|
||||||
let label_map code =
|
let relax_allocation ~num_words = Lop (Ispecific (Ialloc_far num_words))
|
||||||
let map = Hashtbl.create 37 in
|
|
||||||
let rec fill_map pc instr =
|
|
||||||
match instr.desc with
|
|
||||||
Lend -> (pc, map)
|
|
||||||
| Llabel lbl -> Hashtbl.add map lbl pc; fill_map pc instr.next
|
|
||||||
| op -> fill_map (pc + instr_size op) instr.next
|
|
||||||
in fill_map 0 code
|
|
||||||
|
|
||||||
let max_branch_offset = 8180
|
|
||||||
(* 14-bit signed offset in words. Remember to cut some slack
|
|
||||||
for multi-word instructions where the branch can be anywhere in
|
|
||||||
the middle. 12 words of slack is plenty. *)
|
|
||||||
|
|
||||||
let branch_overflows map pc_branch lbl_dest =
|
|
||||||
let pc_dest = Hashtbl.find map lbl_dest in
|
|
||||||
let delta = pc_dest - (pc_branch + 1) in
|
|
||||||
delta <= -max_branch_offset || delta >= max_branch_offset
|
|
||||||
|
|
||||||
let opt_branch_overflows map pc_branch opt_lbl_dest =
|
|
||||||
match opt_lbl_dest with
|
|
||||||
None -> false
|
|
||||||
| Some lbl_dest -> branch_overflows map pc_branch lbl_dest
|
|
||||||
|
|
||||||
let fixup_branches codesize map code =
|
|
||||||
let expand_optbranch lbl n arg next =
|
|
||||||
match lbl with
|
|
||||||
None -> next
|
|
||||||
| Some l ->
|
|
||||||
instr_cons (Lcondbranch(Iinttest_imm(Isigned Ceq, n), l))
|
|
||||||
arg [||] next in
|
|
||||||
let rec fixup did_fix pc instr =
|
|
||||||
match instr.desc with
|
|
||||||
Lend -> did_fix
|
|
||||||
| Lcondbranch(test, lbl) when branch_overflows map pc lbl ->
|
|
||||||
let lbl2 = new_label() in
|
|
||||||
let cont =
|
|
||||||
instr_cons (Lbranch lbl) [||] [||]
|
|
||||||
(instr_cons (Llabel lbl2) [||] [||] instr.next) in
|
|
||||||
instr.desc <- Lcondbranch(invert_test test, lbl2);
|
|
||||||
instr.next <- cont;
|
|
||||||
fixup true (pc + 2) instr.next
|
|
||||||
| Lcondbranch3(lbl0, lbl1, lbl2)
|
|
||||||
when opt_branch_overflows map pc lbl0
|
|
||||||
|| opt_branch_overflows map pc lbl1
|
|
||||||
|| opt_branch_overflows map pc lbl2 ->
|
|
||||||
let cont =
|
|
||||||
expand_optbranch lbl0 0 instr.arg
|
|
||||||
(expand_optbranch lbl1 1 instr.arg
|
|
||||||
(expand_optbranch lbl2 2 instr.arg instr.next)) in
|
|
||||||
instr.desc <- cont.desc;
|
|
||||||
instr.next <- cont.next;
|
|
||||||
fixup true pc instr
|
|
||||||
| Lop(Ialloc n) when codesize - pc >= max_branch_offset ->
|
|
||||||
instr.desc <- Lop(Ispecific(Ialloc_far n));
|
|
||||||
fixup true (pc + 4) instr.next
|
|
||||||
| op ->
|
|
||||||
fixup did_fix (pc + instr_size op) instr.next
|
|
||||||
in fixup false 0 code
|
|
||||||
|
|
||||||
(* Iterate branch expansion till all conditional branches are OK *)
|
|
||||||
|
|
||||||
let rec branch_normalization code =
|
|
||||||
let (codesize, map) = label_map code in
|
|
||||||
if codesize >= max_branch_offset && fixup_branches codesize map code
|
|
||||||
then branch_normalization code
|
|
||||||
else ()
|
|
||||||
|
|
||||||
|
(* [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 () = assert false
|
||||||
|
let relax_intop_imm_checkbound ~bound:_ = assert false
|
||||||
|
end)
|
||||||
|
|
||||||
(* Output the assembly code for an instruction *)
|
(* Output the assembly code for an instruction *)
|
||||||
|
|
||||||
|
@ -848,7 +809,10 @@ let fundecl fundecl =
|
||||||
` addi {emit_gpr 1}, {emit_gpr 1}, {emit_int(-n)}\n`
|
` addi {emit_gpr 1}, {emit_gpr 1}, {emit_int(-n)}\n`
|
||||||
end;
|
end;
|
||||||
`{emit_label !tailrec_entry_point}:\n`;
|
`{emit_label !tailrec_entry_point}:\n`;
|
||||||
branch_normalization fundecl.fun_body;
|
(* On this target, there is at most one "out of line" code block per
|
||||||
|
function: a single "call GC" point. It comes immediately after the
|
||||||
|
function's body. *)
|
||||||
|
BR.relax fundecl.fun_body ~max_out_of_line_code_offset:0;
|
||||||
emit_all fundecl.fun_body;
|
emit_all fundecl.fun_body;
|
||||||
(* Emit the glue code to call the GC *)
|
(* Emit the glue code to call the GC *)
|
||||||
if !call_gc_label > 0 then begin
|
if !call_gc_label > 0 then begin
|
||||||
|
|
|
@ -283,6 +283,11 @@ roots.o: roots.c ../byterun/caml/finalise.h ../byterun/caml/roots.h \
|
||||||
../byterun/caml/misc.h ../byterun/caml/mlvalues.h stack.h \
|
../byterun/caml/misc.h ../byterun/caml/mlvalues.h stack.h \
|
||||||
../byterun/caml/roots.h
|
../byterun/caml/roots.h
|
||||||
signals_asm.o: signals_asm.c ../byterun/caml/fail.h \
|
signals_asm.o: signals_asm.c ../byterun/caml/fail.h \
|
||||||
|
../byterun/caml/minor_gc.h ../byterun/caml/address_class.h \
|
||||||
|
../byterun/caml/globroots.h ../byterun/caml/memory.h \
|
||||||
|
../byterun/caml/major_gc.h ../byterun/caml/minor_gc.h \
|
||||||
|
../byterun/caml/misc.h ../byterun/caml/mlvalues.h stack.h \
|
||||||
|
../byterun/caml/roots.h ../byterun/caml/address_class.h \
|
||||||
../byterun/caml/misc.h ../byterun/caml/config.h \
|
../byterun/caml/misc.h ../byterun/caml/config.h \
|
||||||
../byterun/caml/../../config/m.h ../byterun/caml/../../config/s.h \
|
../byterun/caml/../../config/m.h ../byterun/caml/../../config/s.h \
|
||||||
../byterun/caml/mlvalues.h ../byterun/caml/memory.h ../byterun/caml/gc.h \
|
../byterun/caml/mlvalues.h ../byterun/caml/memory.h ../byterun/caml/gc.h \
|
||||||
|
@ -641,6 +646,7 @@ roots.d.o: roots.c ../byterun/caml/finalise.h ../byterun/caml/roots.h \
|
||||||
../byterun/caml/misc.h ../byterun/caml/mlvalues.h stack.h \
|
../byterun/caml/misc.h ../byterun/caml/mlvalues.h stack.h \
|
||||||
../byterun/caml/roots.h
|
../byterun/caml/roots.h
|
||||||
signals_asm.d.o: signals_asm.c ../byterun/caml/fail.h \
|
signals_asm.d.o: signals_asm.c ../byterun/caml/fail.h \
|
||||||
|
../byterun/caml/address_class.h \
|
||||||
../byterun/caml/misc.h ../byterun/caml/config.h \
|
../byterun/caml/misc.h ../byterun/caml/config.h \
|
||||||
../byterun/caml/../../config/m.h ../byterun/caml/../../config/s.h \
|
../byterun/caml/../../config/m.h ../byterun/caml/../../config/s.h \
|
||||||
../byterun/caml/mlvalues.h ../byterun/caml/memory.h ../byterun/caml/gc.h \
|
../byterun/caml/mlvalues.h ../byterun/caml/memory.h ../byterun/caml/gc.h \
|
||||||
|
|
|
@ -16,7 +16,7 @@ include ../config/Makefile
|
||||||
CC=$(NATIVECC)
|
CC=$(NATIVECC)
|
||||||
FLAGS=-I../byterun -DCAML_NAME_SPACE -DNATIVE_CODE \
|
FLAGS=-I../byterun -DCAML_NAME_SPACE -DNATIVE_CODE \
|
||||||
-DTARGET_$(ARCH) -DSYS_$(SYSTEM) $(IFLEXDIR)
|
-DTARGET_$(ARCH) -DSYS_$(SYSTEM) $(IFLEXDIR)
|
||||||
CFLAGS=$(FLAGS) -O $(NATIVECCCOMPOPTS)
|
CFLAGS=$(FLAGS) $(NATIVECCCOMPOPTS)
|
||||||
DFLAGS=$(FLAGS) -g -DDEBUG $(NATIVECCCOMPOPTS)
|
DFLAGS=$(FLAGS) -g -DDEBUG $(NATIVECCCOMPOPTS)
|
||||||
PFLAGS=$(FLAGS) -pg -O -DPROFILING $(NATIVECCPROFOPTS)
|
PFLAGS=$(FLAGS) -pg -O -DPROFILING $(NATIVECCPROFOPTS)
|
||||||
PICFLAGS=$(FLAGS) -O $(SHAREDCCCOMPOPTS) $(NATIVECCCOMPOPTS)
|
PICFLAGS=$(FLAGS) -O $(SHAREDCCCOMPOPTS) $(NATIVECCCOMPOPTS)
|
||||||
|
@ -120,6 +120,9 @@ power.o: power-$(SYSTEM).o
|
||||||
power.p.o: power-$(SYSTEM).o
|
power.p.o: power-$(SYSTEM).o
|
||||||
cp power-$(SYSTEM).o power.p.o
|
cp power-$(SYSTEM).o power.p.o
|
||||||
|
|
||||||
|
power.pic.o: power-$(SYSTEM).pic.o
|
||||||
|
cp power-$(SYSTEM).pic.o power.pic.o
|
||||||
|
|
||||||
main.c: ../byterun/main.c
|
main.c: ../byterun/main.c
|
||||||
ln -s ../byterun/main.c main.c
|
ln -s ../byterun/main.c main.c
|
||||||
startup_aux.c: ../byterun/startup_aux.c
|
startup_aux.c: ../byterun/startup_aux.c
|
||||||
|
|
|
@ -70,7 +70,7 @@ win32.$(O): ../byterun/win32.c
|
||||||
$(CC) -c $(NATIVECCCOMPOPTS) -DNATIVE_CODE $(IFLEXDIR) ../byterun/win32.c
|
$(CC) -c $(NATIVECCCOMPOPTS) -DNATIVE_CODE $(IFLEXDIR) ../byterun/win32.c
|
||||||
|
|
||||||
%.$(O): %.c
|
%.$(O): %.c
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
clean::
|
clean::
|
||||||
rm -f $(LINKEDFILES)
|
rm -f $(LINKEDFILES)
|
||||||
|
|
|
@ -205,17 +205,8 @@ CAMLprim value caml_get_current_callstack(value max_frames_value) {
|
||||||
|
|
||||||
/* Extract location information for the given frame descriptor */
|
/* Extract location information for the given frame descriptor */
|
||||||
|
|
||||||
struct loc_info {
|
CAMLexport void extract_location_info(frame_descr * d,
|
||||||
int loc_valid;
|
/*out*/ struct caml_loc_info * li)
|
||||||
int loc_is_raise;
|
|
||||||
char * loc_filename;
|
|
||||||
int loc_lnum;
|
|
||||||
int loc_startchr;
|
|
||||||
int loc_endchr;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void extract_location_info(frame_descr * d,
|
|
||||||
/*out*/ struct loc_info * li)
|
|
||||||
{
|
{
|
||||||
uintnat infoptr;
|
uintnat infoptr;
|
||||||
uint32_t info1, info2;
|
uint32_t info1, info2;
|
||||||
|
@ -261,7 +252,7 @@ static void extract_location_info(frame_descr * d,
|
||||||
useless. We kept it to keep code identical to the byterun/
|
useless. We kept it to keep code identical to the byterun/
|
||||||
implementation. */
|
implementation. */
|
||||||
|
|
||||||
static void print_location(struct loc_info * li, int index)
|
static void print_location(struct caml_loc_info * li, int index)
|
||||||
{
|
{
|
||||||
char * info;
|
char * info;
|
||||||
|
|
||||||
|
@ -294,7 +285,7 @@ static void print_location(struct loc_info * li, int index)
|
||||||
void caml_print_exception_backtrace(void)
|
void caml_print_exception_backtrace(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct loc_info li;
|
struct caml_loc_info li;
|
||||||
|
|
||||||
for (i = 0; i < caml_backtrace_pos; i++) {
|
for (i = 0; i < caml_backtrace_pos; i++) {
|
||||||
extract_location_info((frame_descr *) (caml_backtrace_buffer[i]), &li);
|
extract_location_info((frame_descr *) (caml_backtrace_buffer[i]), &li);
|
||||||
|
@ -307,7 +298,7 @@ void caml_print_exception_backtrace(void)
|
||||||
CAMLprim value caml_convert_raw_backtrace_slot(value backtrace_slot) {
|
CAMLprim value caml_convert_raw_backtrace_slot(value backtrace_slot) {
|
||||||
CAMLparam1(backtrace_slot);
|
CAMLparam1(backtrace_slot);
|
||||||
CAMLlocal2(p, fname);
|
CAMLlocal2(p, fname);
|
||||||
struct loc_info li;
|
struct caml_loc_info li;
|
||||||
|
|
||||||
extract_location_info(Descrptr_Val(backtrace_slot), &li);
|
extract_location_info(Descrptr_Val(backtrace_slot), &li);
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
/* Linux/BSD with ELF binaries and Solaris do not prefix identifiers with _.
|
/* Linux/BSD with ELF binaries and Solaris do not prefix identifiers with _.
|
||||||
Linux/BSD with a.out binaries and NextStep do. */
|
Linux/BSD with a.out binaries and NextStep do. */
|
||||||
|
|
||||||
#if defined(SYS_solaris)
|
#if (defined(SYS_solaris) && !defined(__GNUC__))
|
||||||
#define CONCAT(a,b) a/**/b
|
#define CONCAT(a,b) a/**/b
|
||||||
#else
|
#else
|
||||||
#define CONCAT(a,b) a##b
|
#define CONCAT(a,b) a##b
|
||||||
|
|
|
@ -152,14 +152,24 @@
|
||||||
|
|
||||||
#elif defined(TARGET_i386) && defined(SYS_bsd_elf)
|
#elif defined(TARGET_i386) && defined(SYS_bsd_elf)
|
||||||
|
|
||||||
#define DECLARE_SIGNAL_HANDLER(name) \
|
#if defined (__NetBSD__)
|
||||||
static void name(int sig, siginfo_t * info, struct sigcontext * context)
|
#include <ucontext.h>
|
||||||
|
#define DECLARE_SIGNAL_HANDLER(name) \
|
||||||
|
static void name(int sig, siginfo_t * info, ucontext_t * context)
|
||||||
|
#else
|
||||||
|
#define DECLARE_SIGNAL_HANDLER(name) \
|
||||||
|
static void name(int sig, siginfo_t * info, struct sigcontext * context)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SET_SIGACT(sigact,name) \
|
#define SET_SIGACT(sigact,name) \
|
||||||
sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \
|
sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \
|
||||||
sigact.sa_flags = SA_SIGINFO
|
sigact.sa_flags = SA_SIGINFO
|
||||||
|
|
||||||
#define CONTEXT_PC (context->sc_eip)
|
#if defined (__NetBSD__)
|
||||||
|
#define CONTEXT_PC (_UC_MACHINE_PC(context))
|
||||||
|
#else
|
||||||
|
#define CONTEXT_PC (context->sc_eip)
|
||||||
|
#endif
|
||||||
#define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr)
|
#define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr)
|
||||||
|
|
||||||
/****************** I386, BSD */
|
/****************** I386, BSD */
|
||||||
|
|
|
@ -78,6 +78,15 @@ typedef struct {
|
||||||
unsigned short live_ofs[1];
|
unsigned short live_ofs[1];
|
||||||
} frame_descr;
|
} frame_descr;
|
||||||
|
|
||||||
|
struct caml_loc_info {
|
||||||
|
int loc_valid;
|
||||||
|
int loc_is_raise;
|
||||||
|
char * loc_filename;
|
||||||
|
int loc_lnum;
|
||||||
|
int loc_startchr;
|
||||||
|
int loc_endchr;
|
||||||
|
};
|
||||||
|
|
||||||
/* Hash table of frame descriptors */
|
/* Hash table of frame descriptors */
|
||||||
|
|
||||||
extern frame_descr ** caml_frame_descriptors;
|
extern frame_descr ** caml_frame_descriptors;
|
||||||
|
@ -90,6 +99,10 @@ extern void caml_init_frame_descriptors(void);
|
||||||
extern void caml_register_frametable(intnat *);
|
extern void caml_register_frametable(intnat *);
|
||||||
extern void caml_register_dyn_global(void *);
|
extern void caml_register_dyn_global(void *);
|
||||||
|
|
||||||
|
CAMLextern void extract_location_info(frame_descr * d,
|
||||||
|
/*out*/ struct caml_loc_info * li);
|
||||||
|
|
||||||
|
|
||||||
extern uintnat caml_stack_usage (void);
|
extern uintnat caml_stack_usage (void);
|
||||||
extern uintnat (*caml_stack_usage_hook)(void);
|
extern uintnat (*caml_stack_usage_hook)(void);
|
||||||
|
|
||||||
|
|
|
@ -197,7 +197,7 @@ let clear_crc_interfaces () =
|
||||||
|
|
||||||
(* Record compilation events *)
|
(* Record compilation events *)
|
||||||
|
|
||||||
let debug_info = ref ([] : (int * LongString.t) list)
|
let debug_info = ref ([] : (int * Instruct.debug_event list * string list) list)
|
||||||
|
|
||||||
(* Link in a compilation unit *)
|
(* Link in a compilation unit *)
|
||||||
|
|
||||||
|
@ -208,8 +208,14 @@ let link_compunit ppf output_fun currpos_fun inchan file_name compunit =
|
||||||
Symtable.ls_patch_object code_block compunit.cu_reloc;
|
Symtable.ls_patch_object code_block compunit.cu_reloc;
|
||||||
if !Clflags.debug && compunit.cu_debug > 0 then begin
|
if !Clflags.debug && compunit.cu_debug > 0 then begin
|
||||||
seek_in inchan compunit.cu_debug;
|
seek_in inchan compunit.cu_debug;
|
||||||
let buffer = LongString.input_bytes inchan compunit.cu_debugsize in
|
let debug_event_list : Instruct.debug_event list = input_value inchan in
|
||||||
debug_info := (currpos_fun(), buffer) :: !debug_info
|
let debug_dirs : string list = input_value inchan in
|
||||||
|
let file_path = Filename.dirname (Location.absolute_path file_name) in
|
||||||
|
let debug_dirs =
|
||||||
|
if List.mem file_path debug_dirs
|
||||||
|
then debug_dirs
|
||||||
|
else file_path :: debug_dirs in
|
||||||
|
debug_info := (currpos_fun(), debug_event_list, debug_dirs) :: !debug_info
|
||||||
end;
|
end;
|
||||||
Array.iter output_fun code_block;
|
Array.iter output_fun code_block;
|
||||||
if !Clflags.link_everything then
|
if !Clflags.link_everything then
|
||||||
|
@ -264,9 +270,10 @@ let link_file ppf output_fun currpos_fun = function
|
||||||
let output_debug_info oc =
|
let output_debug_info oc =
|
||||||
output_binary_int oc (List.length !debug_info);
|
output_binary_int oc (List.length !debug_info);
|
||||||
List.iter
|
List.iter
|
||||||
(fun (ofs, evl) ->
|
(fun (ofs, evl, debug_dirs) ->
|
||||||
output_binary_int oc ofs;
|
output_binary_int oc ofs;
|
||||||
Array.iter (output_bytes oc) evl)
|
output_value oc evl;
|
||||||
|
output_value oc debug_dirs)
|
||||||
!debug_info;
|
!debug_info;
|
||||||
debug_info := []
|
debug_info := []
|
||||||
|
|
||||||
|
@ -573,8 +580,15 @@ let link ppf objfiles output_name =
|
||||||
raise x
|
raise x
|
||||||
end else begin
|
end else begin
|
||||||
let basename = Filename.chop_extension output_name in
|
let basename = Filename.chop_extension output_name in
|
||||||
let c_file = basename ^ ".c"
|
let c_file =
|
||||||
and obj_file = basename ^ Config.ext_obj in
|
if !Clflags.output_complete_object
|
||||||
|
then Filename.temp_file "camlobj" ".c"
|
||||||
|
else basename ^ ".c"
|
||||||
|
and obj_file =
|
||||||
|
if !Clflags.output_complete_object
|
||||||
|
then Filename.temp_file "camlobj" Config.ext_obj
|
||||||
|
else basename ^ Config.ext_obj
|
||||||
|
in
|
||||||
if Sys.file_exists c_file then raise(Error(File_exists c_file));
|
if Sys.file_exists c_file then raise(Error(File_exists c_file));
|
||||||
let temps = ref [] in
|
let temps = ref [] in
|
||||||
try
|
try
|
||||||
|
@ -583,13 +597,19 @@ let link ppf objfiles output_name =
|
||||||
temps := c_file :: !temps;
|
temps := c_file :: !temps;
|
||||||
if Ccomp.compile_file ~output_name:(Some obj_file) c_file <> 0 then
|
if Ccomp.compile_file ~output_name:(Some obj_file) c_file <> 0 then
|
||||||
raise(Error Custom_runtime);
|
raise(Error Custom_runtime);
|
||||||
if not (Filename.check_suffix output_name Config.ext_obj) then begin
|
if not (Filename.check_suffix output_name Config.ext_obj) ||
|
||||||
|
!Clflags.output_complete_object then begin
|
||||||
temps := obj_file :: !temps;
|
temps := obj_file :: !temps;
|
||||||
|
let mode, c_libs =
|
||||||
|
if Filename.check_suffix output_name Config.ext_obj
|
||||||
|
then Ccomp.Partial, ""
|
||||||
|
else Ccomp.MainDll, Config.bytecomp_c_libraries
|
||||||
|
in
|
||||||
if not (
|
if not (
|
||||||
let runtime_lib = "-lcamlrun" ^ !Clflags.runtime_variant in
|
let runtime_lib = "-lcamlrun" ^ !Clflags.runtime_variant in
|
||||||
Ccomp.call_linker Ccomp.MainDll output_name
|
Ccomp.call_linker mode output_name
|
||||||
([obj_file] @ List.rev !Clflags.ccobjs @ [runtime_lib])
|
([obj_file] @ List.rev !Clflags.ccobjs @ [runtime_lib])
|
||||||
Config.bytecomp_c_libraries
|
c_libs
|
||||||
) then raise (Error Custom_runtime);
|
) then raise (Error Custom_runtime);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
|
@ -558,10 +558,9 @@ let lam_of_loc kind loc =
|
||||||
| Loc_FILE -> Lconst (Const_immstring file)
|
| Loc_FILE -> Lconst (Const_immstring file)
|
||||||
| Loc_MODULE ->
|
| Loc_MODULE ->
|
||||||
let filename = Filename.basename file in
|
let filename = Filename.basename file in
|
||||||
let module_name =
|
let name = Env.get_unit_name () in
|
||||||
try String.capitalize_ascii (Filename.chop_extension filename)
|
let module_name = if name = "" then "//"^filename^"//" else name in
|
||||||
with Invalid_argument _ -> "//"^filename^"//"
|
Lconst (Const_immstring module_name)
|
||||||
in Lconst (Const_immstring module_name)
|
|
||||||
| Loc_LOC ->
|
| Loc_LOC ->
|
||||||
let loc = Printf.sprintf "File %S, line %d, characters %d-%d"
|
let loc = Printf.sprintf "File %S, line %d, characters %d-%d"
|
||||||
file lnum cnum enum in
|
file lnum cnum enum in
|
||||||
|
|
|
@ -81,7 +81,9 @@ let num_of_prim name =
|
||||||
try
|
try
|
||||||
find_numtable !c_prim_table name
|
find_numtable !c_prim_table name
|
||||||
with Not_found ->
|
with Not_found ->
|
||||||
if !Clflags.custom_runtime || !Clflags.no_check_prims then
|
if !Clflags.custom_runtime || Config.host <> Config.target
|
||||||
|
|| !Clflags.no_check_prims
|
||||||
|
then
|
||||||
enter_numtable c_prim_table name
|
enter_numtable c_prim_table name
|
||||||
else begin
|
else begin
|
||||||
let symb =
|
let symb =
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
include Makefile.common
|
include Makefile.common
|
||||||
|
|
||||||
CFLAGS=-DCAML_NAME_SPACE -O $(BYTECCCOMPOPTS) $(IFLEXDIR)
|
CFLAGS=-DCAML_NAME_SPACE $(BYTECCCOMPOPTS) $(IFLEXDIR)
|
||||||
DFLAGS=-DCAML_NAME_SPACE -g -DDEBUG $(BYTECCCOMPOPTS) $(IFLEXDIR)
|
DFLAGS=-DCAML_NAME_SPACE -g -DDEBUG $(BYTECCCOMPOPTS) $(IFLEXDIR)
|
||||||
|
|
||||||
OBJS=$(COMMONOBJS) $(UNIX_OR_WIN32).o main.o
|
OBJS=$(COMMONOBJS) $(UNIX_OR_WIN32).o main.o
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
include ../config/Makefile
|
include ../config/Makefile
|
||||||
|
CAMLRUN ?= ../boot/ocamlrun
|
||||||
|
CAMLYACC ?= ../boot/ocamlyacc
|
||||||
|
|
||||||
CC=$(BYTECC)
|
CC=$(BYTECC)
|
||||||
|
|
||||||
|
@ -57,7 +59,7 @@ INSTALL_LIBDIR=$(DESTDIR)$(LIBDIR)
|
||||||
|
|
||||||
|
|
||||||
install::
|
install::
|
||||||
cp ocamlrun$(EXE) $(INSTALL_BINDIR)/ocamlrun$(EXE)
|
cp $(CAMLRUN)$(EXE) $(INSTALL_BINDIR)/ocamlrun$(EXE)
|
||||||
cp libcamlrun.$(A) $(INSTALL_LIBDIR)/libcamlrun.$(A)
|
cp libcamlrun.$(A) $(INSTALL_LIBDIR)/libcamlrun.$(A)
|
||||||
cd $(INSTALL_LIBDIR); $(RANLIB) libcamlrun.$(A)
|
cd $(INSTALL_LIBDIR); $(RANLIB) libcamlrun.$(A)
|
||||||
if test -d $(INSTALL_LIBDIR)/caml; then : ; \
|
if test -d $(INSTALL_LIBDIR)/caml; then : ; \
|
||||||
|
@ -73,6 +75,10 @@ install:: install-$(RUNTIMED)
|
||||||
install-noruntimed:
|
install-noruntimed:
|
||||||
.PHONY: install-noruntimed
|
.PHONY: install-noruntimed
|
||||||
|
|
||||||
|
# TODO: when cross-compiling, do not install ocamlrund
|
||||||
|
# it doesn't hurt to install it, but it's useless and might be confusing
|
||||||
|
# because it's an executable for the target machine, while we're installing
|
||||||
|
# binaries for the host.
|
||||||
install-runtimed:
|
install-runtimed:
|
||||||
cp ocamlrund$(EXE) $(INSTALL_BINDIR)/ocamlrund$(EXE)
|
cp ocamlrund$(EXE) $(INSTALL_BINDIR)/ocamlrund$(EXE)
|
||||||
cp libcamlrund.$(A) $(INSTALL_LIBDIR)/libcamlrund.$(A)
|
cp libcamlrund.$(A) $(INSTALL_LIBDIR)/libcamlrund.$(A)
|
||||||
|
|
|
@ -24,7 +24,7 @@ ocamlrun$(EXE): libcamlrun.$(A) prims.$(O)
|
||||||
$(EXTRALIBS) libcamlrun.$(A)
|
$(EXTRALIBS) libcamlrun.$(A)
|
||||||
|
|
||||||
ocamlrund$(EXE): libcamlrund.$(A) prims.$(O) main.$(O)
|
ocamlrund$(EXE): libcamlrund.$(A) prims.$(O) main.$(O)
|
||||||
$(MKEXE) -o ocamlrun$(EXE) $(BYTECCDBGCOMPOPTS) prims.$(O) \
|
$(MKEXE) -o ocamlrund$(EXE) $(BYTECCDBGCOMPOPTS) prims.$(O) \
|
||||||
$(call SYSLIB,ws2_32) $(EXTRALIBS) libcamlrund.$(A)
|
$(call SYSLIB,ws2_32) $(EXTRALIBS) libcamlrund.$(A)
|
||||||
|
|
||||||
libcamlrun.$(A): $(OBJS)
|
libcamlrun.$(A): $(OBJS)
|
||||||
|
@ -34,7 +34,7 @@ libcamlrund.$(A): $(DOBJS)
|
||||||
$(call MKLIB,libcamlrund.$(A),$(DOBJS))
|
$(call MKLIB,libcamlrund.$(A),$(DOBJS))
|
||||||
|
|
||||||
%.$(O): %.c
|
%.$(O): %.c
|
||||||
$(CC) $(CFLAGS) $(BYTECCCOMPOPTS) -c -o $@ $<
|
$(CC) $(CFLAGS) $(BYTECCCOMPOPTS) -c $<
|
||||||
|
|
||||||
%.$(DBGO): %.c
|
%.$(DBGO): %.c
|
||||||
$(CC) $(CFLAGS) $(BYTECCDBGCOMPOPTS) -c -o $@ $<
|
$(CC) $(CFLAGS) $(BYTECCDBGCOMPOPTS) -c -o $@ $<
|
||||||
|
|
|
@ -198,3 +198,7 @@ CAMLprim value caml_update_dummy(value dummy, value newval)
|
||||||
}
|
}
|
||||||
return Val_unit;
|
return Val_unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -306,15 +306,15 @@ void caml_stash_backtrace(value exn, code_t pc, value * sp, int reraise)
|
||||||
#define Codet_Val(v) ((code_t)(Long_val(v)<<1))
|
#define Codet_Val(v) ((code_t)(Long_val(v)<<1))
|
||||||
|
|
||||||
/* returns the next frame pointer (or NULL if none is available);
|
/* returns the next frame pointer (or NULL if none is available);
|
||||||
updates *sp to point to the following one, and *trapsp to the next
|
updates *sp to point to the following one, and *trsp to the next
|
||||||
trap frame, which we will skip when we reach it */
|
trap frame, which we will skip when we reach it */
|
||||||
|
|
||||||
code_t caml_next_frame_pointer(value ** sp, value ** trapsp)
|
code_t caml_next_frame_pointer(value ** sp, value ** trsp)
|
||||||
{
|
{
|
||||||
while (*sp < caml_stack_high) {
|
while (*sp < caml_stack_high) {
|
||||||
code_t *p = (code_t*) (*sp)++;
|
code_t *p = (code_t*) (*sp)++;
|
||||||
if(&Trap_pc(*trapsp) == p) {
|
if(&Trap_pc(*trsp) == p) {
|
||||||
*trapsp = Trap_link(*trapsp);
|
*trsp = Trap_link(*trsp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,10 +343,10 @@ CAMLprim value caml_get_current_callstack(value max_frames_value) {
|
||||||
/* first compute the size of the trace */
|
/* first compute the size of the trace */
|
||||||
{
|
{
|
||||||
value * sp = caml_extern_sp;
|
value * sp = caml_extern_sp;
|
||||||
value * trapsp = caml_trapsp;
|
value * trsp = caml_trapsp;
|
||||||
|
|
||||||
for (trace_size = 0; trace_size < max_frames; trace_size++) {
|
for (trace_size = 0; trace_size < max_frames; trace_size++) {
|
||||||
code_t p = caml_next_frame_pointer(&sp, &trapsp);
|
code_t p = caml_next_frame_pointer(&sp, &trsp);
|
||||||
if (p == NULL) break;
|
if (p == NULL) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,11 +356,11 @@ CAMLprim value caml_get_current_callstack(value max_frames_value) {
|
||||||
/* then collect the trace */
|
/* then collect the trace */
|
||||||
{
|
{
|
||||||
value * sp = caml_extern_sp;
|
value * sp = caml_extern_sp;
|
||||||
value * trapsp = caml_trapsp;
|
value * trsp = caml_trapsp;
|
||||||
uintnat trace_pos;
|
uintnat trace_pos;
|
||||||
|
|
||||||
for (trace_pos = 0; trace_pos < trace_size; trace_pos++) {
|
for (trace_pos = 0; trace_pos < trace_size; trace_pos++) {
|
||||||
code_t p = caml_next_frame_pointer(&sp, &trapsp);
|
code_t p = caml_next_frame_pointer(&sp, &trsp);
|
||||||
Assert(p != NULL);
|
Assert(p != NULL);
|
||||||
Field(trace, trace_pos) = Val_Codet(p);
|
Field(trace, trace_pos) = Val_Codet(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,3 +245,14 @@ CAMLexport value * caml_named_value(char const *name)
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CAMLexport void caml_iterate_named_values(caml_named_action f)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < Named_value_size; i++){
|
||||||
|
struct named_value * nv;
|
||||||
|
for (nv = named_value_table[i]; nv != NULL; nv = nv->next) {
|
||||||
|
f( &nv->val, nv->name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@ CAMLextern value caml_callbackN_exn (value closure, int narg, value args[]);
|
||||||
#define Extract_exception(v) ((v) & ~3)
|
#define Extract_exception(v) ((v) & ~3)
|
||||||
|
|
||||||
CAMLextern value * caml_named_value (char const * name);
|
CAMLextern value * caml_named_value (char const * name);
|
||||||
|
typedef void (*caml_named_action) (value*, char *);
|
||||||
|
CAMLextern void caml_iterate_named_values(caml_named_action f);
|
||||||
|
|
||||||
CAMLextern void caml_main (char ** argv);
|
CAMLextern void caml_main (char ** argv);
|
||||||
CAMLextern void caml_startup (char ** argv);
|
CAMLextern void caml_startup (char ** argv);
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
|
|
||||||
#include "mlvalues.h"
|
#include "mlvalues.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
CAMLextern uint32_t caml_hash_mix_uint32(uint32_t h, uint32_t d);
|
CAMLextern uint32_t caml_hash_mix_uint32(uint32_t h, uint32_t d);
|
||||||
CAMLextern uint32_t caml_hash_mix_intnat(uint32_t h, intnat d);
|
CAMLextern uint32_t caml_hash_mix_intnat(uint32_t h, intnat d);
|
||||||
CAMLextern uint32_t caml_hash_mix_int64(uint32_t h, int64_t d);
|
CAMLextern uint32_t caml_hash_mix_int64(uint32_t h, int64_t d);
|
||||||
|
@ -25,5 +29,9 @@ CAMLextern uint32_t caml_hash_mix_double(uint32_t h, double d);
|
||||||
CAMLextern uint32_t caml_hash_mix_float(uint32_t h, float d);
|
CAMLextern uint32_t caml_hash_mix_float(uint32_t h, float d);
|
||||||
CAMLextern uint32_t caml_hash_mix_string(uint32_t h, value s);
|
CAMLextern uint32_t caml_hash_mix_string(uint32_t h, value s);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* CAML_HASH_H */
|
||||||
|
|
|
@ -59,6 +59,17 @@ typedef char * addr;
|
||||||
#define CAMLweakdef
|
#define CAMLweakdef
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GC timing hooks. These can be assigned by the user. The hook functions
|
||||||
|
must not allocate or change the heap in any way. */
|
||||||
|
typedef void (*caml_timing_hook) (void);
|
||||||
|
extern caml_timing_hook caml_major_slice_begin_hook, caml_major_slice_end_hook;
|
||||||
|
extern caml_timing_hook caml_minor_gc_begin_hook, caml_minor_gc_end_hook;
|
||||||
|
extern caml_timing_hook caml_finalise_begin_hook, caml_finalise_end_hook;
|
||||||
|
|
||||||
/* Assertions */
|
/* Assertions */
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -156,4 +167,8 @@ extern int caml_snprintf(char * buf, size_t size, const char * format, ...);
|
||||||
|
|
||||||
/* </private> */
|
/* </private> */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* CAML_MISC_H */
|
#endif /* CAML_MISC_H */
|
||||||
|
|
|
@ -296,10 +296,10 @@ CAMLextern header_t caml_atom_table[];
|
||||||
|
|
||||||
extern value caml_global_data;
|
extern value caml_global_data;
|
||||||
|
|
||||||
|
CAMLextern value caml_set_oo_id(value obj);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CAMLextern value caml_set_oo_id(value obj);
|
|
||||||
|
|
||||||
#endif /* CAML_MLVALUES_H */
|
#endif /* CAML_MLVALUES_H */
|
||||||
|
|
|
@ -95,33 +95,44 @@ void caml_fixup_endianness(code_t code, asize_t len)
|
||||||
char ** caml_instr_table;
|
char ** caml_instr_table;
|
||||||
char * caml_instr_base;
|
char * caml_instr_base;
|
||||||
|
|
||||||
|
static int* opcode_nargs = NULL;
|
||||||
|
int* caml_init_opcode_nargs()
|
||||||
|
{
|
||||||
|
if( opcode_nargs == NULL ){
|
||||||
|
int* l = (int*)caml_stat_alloc(sizeof(int) * FIRST_UNIMPLEMENTED_OP);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < FIRST_UNIMPLEMENTED_OP; i++) {
|
||||||
|
l [i] = 0;
|
||||||
|
}
|
||||||
|
/* Instructions with one operand */
|
||||||
|
l[PUSHACC] = l[ACC] = l[POP] = l[ASSIGN] =
|
||||||
|
l[PUSHENVACC] = l[ENVACC] = l[PUSH_RETADDR] = l[APPLY] =
|
||||||
|
l[APPTERM1] = l[APPTERM2] = l[APPTERM3] = l[RETURN] =
|
||||||
|
l[GRAB] = l[PUSHGETGLOBAL] = l[GETGLOBAL] = l[SETGLOBAL] =
|
||||||
|
l[PUSHATOM] = l[ATOM] = l[MAKEBLOCK1] = l[MAKEBLOCK2] =
|
||||||
|
l[MAKEBLOCK3] = l[MAKEFLOATBLOCK] = l[GETFIELD] =
|
||||||
|
l[GETFLOATFIELD] = l[SETFIELD] = l[SETFLOATFIELD] =
|
||||||
|
l[BRANCH] = l[BRANCHIF] = l[BRANCHIFNOT] = l[PUSHTRAP] =
|
||||||
|
l[C_CALL1] = l[C_CALL2] = l[C_CALL3] = l[C_CALL4] = l[C_CALL5] =
|
||||||
|
l[CONSTINT] = l[PUSHCONSTINT] = l[OFFSETINT] =
|
||||||
|
l[OFFSETREF] = l[OFFSETCLOSURE] = l[PUSHOFFSETCLOSURE] = 1;
|
||||||
|
|
||||||
|
/* Instructions with two operands */
|
||||||
|
l[APPTERM] = l[CLOSURE] = l[PUSHGETGLOBALFIELD] =
|
||||||
|
l[GETGLOBALFIELD] = l[MAKEBLOCK] = l[C_CALLN] =
|
||||||
|
l[BEQ] = l[BNEQ] = l[BLTINT] = l[BLEINT] = l[BGTINT] = l[BGEINT] =
|
||||||
|
l[BULTINT] = l[BUGEINT] = l[GETPUBMET] = 2;
|
||||||
|
|
||||||
|
opcode_nargs = l;
|
||||||
|
}
|
||||||
|
return opcode_nargs;
|
||||||
|
}
|
||||||
|
|
||||||
void caml_thread_code (code_t code, asize_t len)
|
void caml_thread_code (code_t code, asize_t len)
|
||||||
{
|
{
|
||||||
code_t p;
|
code_t p;
|
||||||
int l [FIRST_UNIMPLEMENTED_OP];
|
int* l = caml_init_opcode_nargs();
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < FIRST_UNIMPLEMENTED_OP; i++) {
|
|
||||||
l [i] = 0;
|
|
||||||
}
|
|
||||||
/* Instructions with one operand */
|
|
||||||
l[PUSHACC] = l[ACC] = l[POP] = l[ASSIGN] =
|
|
||||||
l[PUSHENVACC] = l[ENVACC] = l[PUSH_RETADDR] = l[APPLY] =
|
|
||||||
l[APPTERM1] = l[APPTERM2] = l[APPTERM3] = l[RETURN] =
|
|
||||||
l[GRAB] = l[PUSHGETGLOBAL] = l[GETGLOBAL] = l[SETGLOBAL] =
|
|
||||||
l[PUSHATOM] = l[ATOM] = l[MAKEBLOCK1] = l[MAKEBLOCK2] =
|
|
||||||
l[MAKEBLOCK3] = l[MAKEFLOATBLOCK] = l[GETFIELD] =
|
|
||||||
l[GETFLOATFIELD] = l[SETFIELD] = l[SETFLOATFIELD] =
|
|
||||||
l[BRANCH] = l[BRANCHIF] = l[BRANCHIFNOT] = l[PUSHTRAP] =
|
|
||||||
l[C_CALL1] = l[C_CALL2] = l[C_CALL3] = l[C_CALL4] = l[C_CALL5] =
|
|
||||||
l[CONSTINT] = l[PUSHCONSTINT] = l[OFFSETINT] =
|
|
||||||
l[OFFSETREF] = l[OFFSETCLOSURE] = l[PUSHOFFSETCLOSURE] = 1;
|
|
||||||
|
|
||||||
/* Instructions with two operands */
|
|
||||||
l[APPTERM] = l[CLOSURE] = l[PUSHGETGLOBALFIELD] =
|
|
||||||
l[GETGLOBALFIELD] = l[MAKEBLOCK] = l[C_CALLN] =
|
|
||||||
l[BEQ] = l[BNEQ] = l[BLTINT] = l[BLEINT] = l[BGTINT] = l[BGEINT] =
|
|
||||||
l[BULTINT] = l[BUGEINT] = l[GETPUBMET] = 2;
|
|
||||||
len /= sizeof(opcode_t);
|
len /= sizeof(opcode_t);
|
||||||
for (p = code; p < code + len; /*nothing*/) {
|
for (p = code; p < code + len; /*nothing*/) {
|
||||||
opcode_t instr = *p;
|
opcode_t instr = *p;
|
||||||
|
@ -149,6 +160,13 @@ void caml_thread_code (code_t code, asize_t len)
|
||||||
Assert(p == code + len);
|
Assert(p == code + len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int* caml_init_opcode_nargs()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* THREADED_CODE */
|
#endif /* THREADED_CODE */
|
||||||
|
|
||||||
void caml_set_instruction(code_t pos, opcode_t instr)
|
void caml_set_instruction(code_t pos, opcode_t instr)
|
||||||
|
|
|
@ -150,6 +150,7 @@ CAMLprim value caml_float_of_string(value vs)
|
||||||
error:
|
error:
|
||||||
if (buf != parse_buffer) caml_stat_free(buf);
|
if (buf != parse_buffer) caml_stat_free(buf);
|
||||||
caml_failwith("float_of_string");
|
caml_failwith("float_of_string");
|
||||||
|
return Val_unit; /* not reached */
|
||||||
}
|
}
|
||||||
|
|
||||||
CAMLprim value caml_int_of_float(value f)
|
CAMLprim value caml_int_of_float(value f)
|
||||||
|
@ -452,7 +453,8 @@ enum { FP_normal, FP_subnormal, FP_zero, FP_infinite, FP_nan };
|
||||||
CAMLprim value caml_classify_float(value vd)
|
CAMLprim value caml_classify_float(value vd)
|
||||||
{
|
{
|
||||||
/* Cygwin 1.3 has problems with fpclassify (PR#1293), so don't use it */
|
/* Cygwin 1.3 has problems with fpclassify (PR#1293), so don't use it */
|
||||||
#if defined(fpclassify) && !defined(__CYGWIN32__) && !defined(__MINGW32__)
|
/* FIXME Cygwin 1.3 is ancient! Revisit this decision. */
|
||||||
|
#if defined(fpclassify) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||||
switch (fpclassify(Double_val(vd))) {
|
switch (fpclassify(Double_val(vd))) {
|
||||||
case FP_NAN:
|
case FP_NAN:
|
||||||
return Val_int(FP_nan);
|
return Val_int(FP_nan);
|
||||||
|
|
|
@ -59,6 +59,8 @@ static value *weak_prev;
|
||||||
static unsigned long major_gc_counter = 0;
|
static unsigned long major_gc_counter = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void (*caml_major_gc_hook)(void) = NULL;
|
||||||
|
|
||||||
static void realloc_gray_vals (void)
|
static void realloc_gray_vals (void)
|
||||||
{
|
{
|
||||||
value *new;
|
value *new;
|
||||||
|
@ -90,13 +92,6 @@ void caml_darken (value v, value *p /* not used */)
|
||||||
{
|
{
|
||||||
#ifdef NATIVE_CODE_AND_NO_NAKED_POINTERS
|
#ifdef NATIVE_CODE_AND_NO_NAKED_POINTERS
|
||||||
if (Is_block (v) && Wosize_val (v) > 0) {
|
if (Is_block (v) && Wosize_val (v) > 0) {
|
||||||
/* 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.) */
|
|
||||||
CAMLassert (Is_in_heap (v) || Is_black_hd (Hd_val (v)));
|
|
||||||
#else
|
#else
|
||||||
if (Is_block (v) && Is_in_heap (v)) {
|
if (Is_block (v) && Is_in_heap (v)) {
|
||||||
#endif
|
#endif
|
||||||
|
@ -107,6 +102,15 @@ void caml_darken (value v, value *p /* not used */)
|
||||||
h = Hd_val (v);
|
h = Hd_val (v);
|
||||||
t = Tag_hd (h);
|
t = Tag_hd (h);
|
||||||
}
|
}
|
||||||
|
#ifdef NATIVE_CODE_AND_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.) */
|
||||||
|
CAMLassert (Is_in_heap (v) || Is_black_hd (h));
|
||||||
|
#endif
|
||||||
CAMLassert (!Is_blue_hd (h));
|
CAMLassert (!Is_blue_hd (h));
|
||||||
if (Is_white_hd (h)){
|
if (Is_white_hd (h)){
|
||||||
if (t < No_scan_tag){
|
if (t < No_scan_tag){
|
||||||
|
@ -145,6 +149,7 @@ static void mark_slice (intnat work)
|
||||||
int marking_closure = 0;
|
int marking_closure = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (caml_major_slice_begin_hook != NULL) (*caml_major_slice_begin_hook) ();
|
||||||
caml_gc_message (0x40, "Marking %ld words\n", work);
|
caml_gc_message (0x40, "Marking %ld words\n", work);
|
||||||
caml_gc_message (0x40, "Subphase = %ld\n", caml_gc_subphase);
|
caml_gc_message (0x40, "Subphase = %ld\n", caml_gc_subphase);
|
||||||
gray_vals_ptr = gray_vals_cur;
|
gray_vals_ptr = gray_vals_cur;
|
||||||
|
@ -169,8 +174,6 @@ static void mark_slice (intnat work)
|
||||||
be reliably determined, so we always use the page table when
|
be reliably determined, so we always use the page table when
|
||||||
marking such values. */
|
marking such values. */
|
||||||
&& (!marking_closure || Is_in_heap (child))) {
|
&& (!marking_closure || Is_in_heap (child))) {
|
||||||
/* See [caml_darken] for a description of this assertion. */
|
|
||||||
CAMLassert (Is_in_heap (child) || Is_black_hd (Hd_val (child)));
|
|
||||||
#else
|
#else
|
||||||
if (Is_block (child) && Is_in_heap (child)) {
|
if (Is_block (child) && Is_in_heap (child)) {
|
||||||
#endif
|
#endif
|
||||||
|
@ -189,6 +192,10 @@ static void mark_slice (intnat work)
|
||||||
child -= Infix_offset_val(child);
|
child -= Infix_offset_val(child);
|
||||||
hd = Hd_val(child);
|
hd = Hd_val(child);
|
||||||
}
|
}
|
||||||
|
#ifdef NATIVE_CODE_AND_NO_NAKED_POINTERS
|
||||||
|
/* See [caml_darken] for a description of this assertion. */
|
||||||
|
CAMLassert (Is_in_heap (child) || Is_black_hd (hd));
|
||||||
|
#endif
|
||||||
if (Is_white_hd (hd)){
|
if (Is_white_hd (hd)){
|
||||||
Hd_val (child) = Grayhd_hd (hd);
|
Hd_val (child) = Grayhd_hd (hd);
|
||||||
*gray_vals_ptr++ = child;
|
*gray_vals_ptr++ = child;
|
||||||
|
@ -307,6 +314,7 @@ static void mark_slice (intnat work)
|
||||||
limit = chunk + Chunk_size (chunk);
|
limit = chunk + Chunk_size (chunk);
|
||||||
work = 0;
|
work = 0;
|
||||||
caml_fl_wsz_at_phase_change = caml_fl_cur_wsz;
|
caml_fl_wsz_at_phase_change = caml_fl_cur_wsz;
|
||||||
|
if (caml_major_gc_hook) (*caml_major_gc_hook)();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: Assert (0);
|
default: Assert (0);
|
||||||
|
@ -314,6 +322,7 @@ static void mark_slice (intnat work)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gray_vals_cur = gray_vals_ptr;
|
gray_vals_cur = gray_vals_ptr;
|
||||||
|
if (caml_major_slice_end_hook != NULL) (*caml_major_slice_end_hook) ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sweep_slice (intnat work)
|
static void sweep_slice (intnat work)
|
||||||
|
@ -321,6 +330,7 @@ static void sweep_slice (intnat work)
|
||||||
char *hp;
|
char *hp;
|
||||||
header_t hd;
|
header_t hd;
|
||||||
|
|
||||||
|
if (caml_major_slice_begin_hook != NULL) (*caml_major_slice_begin_hook) ();
|
||||||
caml_gc_message (0x40, "Sweeping %ld words\n", work);
|
caml_gc_message (0x40, "Sweeping %ld words\n", work);
|
||||||
while (work > 0){
|
while (work > 0){
|
||||||
if (caml_gc_sweep_hp < limit){
|
if (caml_gc_sweep_hp < limit){
|
||||||
|
@ -359,6 +369,7 @@ static void sweep_slice (intnat work)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (caml_major_slice_end_hook != NULL) (*caml_major_slice_end_hook) ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The main entry point for the GC. Called after each minor GC.
|
/* The main entry point for the GC. Called after each minor GC.
|
||||||
|
|
|
@ -33,18 +33,16 @@ CAMLprim value caml_md5_string(value str, value ofs, value len)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAMLprim value caml_md5_chan(value vchan, value len)
|
CAMLexport value caml_md5_channel(struct channel *chan, intnat toread)
|
||||||
{
|
{
|
||||||
CAMLparam2 (vchan, len);
|
CAMLparam0();
|
||||||
struct channel * chan = Channel(vchan);
|
|
||||||
struct MD5Context ctx;
|
struct MD5Context ctx;
|
||||||
value res;
|
value res;
|
||||||
intnat toread, read;
|
intnat read;
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
|
|
||||||
Lock(chan);
|
Lock(chan);
|
||||||
caml_MD5Init(&ctx);
|
caml_MD5Init(&ctx);
|
||||||
toread = Long_val(len);
|
|
||||||
if (toread < 0){
|
if (toread < 0){
|
||||||
while (1){
|
while (1){
|
||||||
read = caml_getblock (chan, buffer, sizeof(buffer));
|
read = caml_getblock (chan, buffer, sizeof(buffer));
|
||||||
|
@ -66,6 +64,12 @@ CAMLprim value caml_md5_chan(value vchan, value len)
|
||||||
CAMLreturn (res);
|
CAMLreturn (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CAMLprim value caml_md5_chan(value vchan, value len)
|
||||||
|
{
|
||||||
|
CAMLparam2 (vchan, len);
|
||||||
|
CAMLreturn (caml_md5_channel(Channel(vchan), Long_val(len)));
|
||||||
|
}
|
||||||
|
|
||||||
CAMLexport void caml_md5_block(unsigned char digest[16],
|
CAMLexport void caml_md5_block(unsigned char digest[16],
|
||||||
void * data, uintnat len)
|
void * data, uintnat len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -227,8 +227,11 @@ void caml_oldify_mopup (void)
|
||||||
void caml_empty_minor_heap (void)
|
void caml_empty_minor_heap (void)
|
||||||
{
|
{
|
||||||
value **r;
|
value **r;
|
||||||
|
uintnat prev_alloc_words;
|
||||||
|
|
||||||
if (caml_young_ptr != caml_young_end){
|
if (caml_young_ptr != caml_young_end){
|
||||||
|
if (caml_minor_gc_begin_hook != NULL) (*caml_minor_gc_begin_hook) ();
|
||||||
|
prev_alloc_words = caml_allocated_words;
|
||||||
caml_in_minor_collection = 1;
|
caml_in_minor_collection = 1;
|
||||||
caml_gc_message (0x02, "<", 0);
|
caml_gc_message (0x02, "<", 0);
|
||||||
caml_oldify_local_roots();
|
caml_oldify_local_roots();
|
||||||
|
@ -253,8 +256,13 @@ void caml_empty_minor_heap (void)
|
||||||
clear_table (&caml_weak_ref_table);
|
clear_table (&caml_weak_ref_table);
|
||||||
caml_gc_message (0x02, ">", 0);
|
caml_gc_message (0x02, ">", 0);
|
||||||
caml_in_minor_collection = 0;
|
caml_in_minor_collection = 0;
|
||||||
|
caml_stat_promoted_words += caml_allocated_words - prev_alloc_words;
|
||||||
|
++ caml_stat_minor_collections;
|
||||||
|
caml_final_empty_young ();
|
||||||
|
if (caml_minor_gc_end_hook != NULL) (*caml_minor_gc_end_hook) ();
|
||||||
|
}else{
|
||||||
|
caml_final_empty_young ();
|
||||||
}
|
}
|
||||||
caml_final_empty_young ();
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
value *p;
|
value *p;
|
||||||
|
@ -272,16 +280,14 @@ void caml_empty_minor_heap (void)
|
||||||
*/
|
*/
|
||||||
CAMLexport void caml_minor_collection (void)
|
CAMLexport void caml_minor_collection (void)
|
||||||
{
|
{
|
||||||
intnat prev_alloc_words = caml_allocated_words;
|
|
||||||
|
|
||||||
caml_empty_minor_heap ();
|
caml_empty_minor_heap ();
|
||||||
|
|
||||||
caml_stat_promoted_words += caml_allocated_words - prev_alloc_words;
|
|
||||||
++ caml_stat_minor_collections;
|
|
||||||
caml_major_collection_slice (0);
|
caml_major_collection_slice (0);
|
||||||
caml_force_major_slice = 0;
|
caml_force_major_slice = 0;
|
||||||
|
|
||||||
|
if (caml_finalise_begin_hook != NULL) (*caml_finalise_begin_hook) ();
|
||||||
caml_final_do_calls ();
|
caml_final_do_calls ();
|
||||||
|
if (caml_finalise_end_hook != NULL) (*caml_finalise_end_hook) ();
|
||||||
|
|
||||||
caml_empty_minor_heap ();
|
caml_empty_minor_heap ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,13 @@
|
||||||
#include "caml/misc.h"
|
#include "caml/misc.h"
|
||||||
#include "caml/memory.h"
|
#include "caml/memory.h"
|
||||||
|
|
||||||
|
caml_timing_hook caml_major_slice_begin_hook = NULL;
|
||||||
|
caml_timing_hook caml_major_slice_end_hook = NULL;
|
||||||
|
caml_timing_hook caml_minor_gc_begin_hook = NULL;
|
||||||
|
caml_timing_hook caml_minor_gc_end_hook = NULL;
|
||||||
|
caml_timing_hook caml_finalise_begin_hook = NULL;
|
||||||
|
caml_timing_hook caml_finalise_end_hook = NULL;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
int caml_failed_assert (char * expr, char * file, int line)
|
int caml_failed_assert (char * expr, char * file, int line)
|
||||||
|
|
|
@ -280,7 +280,7 @@ CAMLprim value caml_sys_getenv(value var)
|
||||||
}
|
}
|
||||||
|
|
||||||
char * caml_exe_name;
|
char * caml_exe_name;
|
||||||
static char ** caml_main_argv;
|
char ** caml_main_argv;
|
||||||
|
|
||||||
CAMLprim value caml_sys_get_argv(value unit)
|
CAMLprim value caml_sys_get_argv(value unit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "caml/config.h"
|
#include "caml/config.h"
|
||||||
#ifdef SUPPORT_DYNAMIC_LINKING
|
#ifdef SUPPORT_DYNAMIC_LINKING
|
||||||
#ifdef __CYGWIN32__
|
#ifdef __CYGWIN__
|
||||||
#include "flexdll.h"
|
#include "flexdll.h"
|
||||||
#else
|
#else
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
@ -86,7 +86,7 @@ char * caml_search_in_path(struct ext_table * path, char * name)
|
||||||
return caml_strdup(name);
|
return caml_strdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __CYGWIN32__
|
#ifdef __CYGWIN__
|
||||||
|
|
||||||
/* Cygwin needs special treatment because of the implicit ".exe" at the
|
/* Cygwin needs special treatment because of the implicit ".exe" at the
|
||||||
end of executable file names */
|
end of executable file names */
|
||||||
|
@ -137,7 +137,7 @@ char * caml_search_exe_in_path(char * name)
|
||||||
|
|
||||||
caml_ext_table_init(&path, 8);
|
caml_ext_table_init(&path, 8);
|
||||||
tofree = caml_decompose_path(&path, getenv("PATH"));
|
tofree = caml_decompose_path(&path, getenv("PATH"));
|
||||||
#ifndef __CYGWIN32__
|
#ifndef __CYGWIN__
|
||||||
res = caml_search_in_path(&path, name);
|
res = caml_search_in_path(&path, name);
|
||||||
#else
|
#else
|
||||||
res = cygwin_search_exe_in_path(&path, name);
|
res = cygwin_search_exe_in_path(&path, name);
|
||||||
|
@ -159,7 +159,7 @@ char * caml_search_dll_in_path(struct ext_table * path, char * name)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SUPPORT_DYNAMIC_LINKING
|
#ifdef SUPPORT_DYNAMIC_LINKING
|
||||||
#ifdef __CYGWIN32__
|
#ifdef __CYGWIN__
|
||||||
/* Use flexdll */
|
/* Use flexdll */
|
||||||
|
|
||||||
void * caml_dlopen(char * libname, int for_execution, int global)
|
void * caml_dlopen(char * libname, int for_execution, int global)
|
||||||
|
|
|
@ -68,7 +68,7 @@ X11_INCLUDES=
|
||||||
X11_LINK=
|
X11_LINK=
|
||||||
BYTECCRPATH=
|
BYTECCRPATH=
|
||||||
SUPPORTS_SHARED_LIBRARIES=true
|
SUPPORTS_SHARED_LIBRARIES=true
|
||||||
SHAREDCCCOMPOPTS=
|
SHAREDCCCOMPOPTS=-O
|
||||||
MKSHAREDLIBRPATH=
|
MKSHAREDLIBRPATH=
|
||||||
NATIVECCPROFOPTS=
|
NATIVECCPROFOPTS=
|
||||||
NATIVECCRPATH=
|
NATIVECCRPATH=
|
||||||
|
|
|
@ -68,7 +68,7 @@ X11_INCLUDES=
|
||||||
X11_LINK=
|
X11_LINK=
|
||||||
BYTECCRPATH=
|
BYTECCRPATH=
|
||||||
SUPPORTS_SHARED_LIBRARIES=true
|
SUPPORTS_SHARED_LIBRARIES=true
|
||||||
SHAREDCCCOMPOPTS=
|
SHAREDCCCOMPOPTS=-O
|
||||||
MKSHAREDLIBRPATH=
|
MKSHAREDLIBRPATH=
|
||||||
NATIVECCPROFOPTS=
|
NATIVECCPROFOPTS=
|
||||||
NATIVECCRPATH=
|
NATIVECCRPATH=
|
||||||
|
|
|
@ -60,7 +60,7 @@ X11_INCLUDES=
|
||||||
X11_LINK=
|
X11_LINK=
|
||||||
BYTECCRPATH=
|
BYTECCRPATH=
|
||||||
SUPPORTS_SHARED_LIBRARIES=true
|
SUPPORTS_SHARED_LIBRARIES=true
|
||||||
SHAREDCCCOMPOPTS=
|
SHAREDCCCOMPOPTS=-Ox
|
||||||
NATIVECCPROFOPTS=
|
NATIVECCPROFOPTS=
|
||||||
NATIVECCRPATH=
|
NATIVECCRPATH=
|
||||||
ASM=ml -nologo -coff -Cp -c -Fo
|
ASM=ml -nologo -coff -Cp -c -Fo
|
||||||
|
|
|
@ -60,7 +60,7 @@ X11_INCLUDES=
|
||||||
X11_LINK=
|
X11_LINK=
|
||||||
BYTECCRPATH=
|
BYTECCRPATH=
|
||||||
SUPPORTS_SHARED_LIBRARIES=true
|
SUPPORTS_SHARED_LIBRARIES=true
|
||||||
SHAREDCCCOMPOPTS=
|
SHAREDCCCOMPOPTS=-Ox
|
||||||
NATIVECCPROFOPTS=
|
NATIVECCPROFOPTS=
|
||||||
NATIVECCRPATH=
|
NATIVECCRPATH=
|
||||||
ASM=ml64 -nologo -Cp -c -Fo
|
ASM=ml64 -nologo -Cp -c -Fo
|
||||||
|
|
|
@ -15,9 +15,18 @@
|
||||||
|
|
||||||
# Find a program in the path
|
# Find a program in the path
|
||||||
|
|
||||||
|
doprint=false
|
||||||
|
case $1 in
|
||||||
|
-p) shift; doprint=true;;
|
||||||
|
*) ;;
|
||||||
|
esac
|
||||||
|
|
||||||
IFS=':'
|
IFS=':'
|
||||||
for dir in $PATH; do
|
for dir in $PATH; do
|
||||||
if test -z "$dir"; then dir=.; fi
|
if test -z "$dir"; then dir=.; fi
|
||||||
if test -f $dir/$1; then exit 0; fi
|
if test -f $dir/$1 -a -x $dir/$1; then
|
||||||
|
if $doprint; then echo "$dir/$1"; fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
@ -18,6 +18,7 @@ echo Configuring OCaml version `head -1 VERSION`
|
||||||
configure_options="$*"
|
configure_options="$*"
|
||||||
prefix=/usr/local
|
prefix=/usr/local
|
||||||
bindir=''
|
bindir=''
|
||||||
|
target_bindir=''
|
||||||
libdir=''
|
libdir=''
|
||||||
mandir=''
|
mandir=''
|
||||||
manext=1
|
manext=1
|
||||||
|
@ -94,6 +95,8 @@ while : ; do
|
||||||
prefix=$2; shift;;
|
prefix=$2; shift;;
|
||||||
-bindir|--bindir)
|
-bindir|--bindir)
|
||||||
bindir=$2; shift;;
|
bindir=$2; shift;;
|
||||||
|
-target-bindir|--target-bindir)
|
||||||
|
target_bindir="$2"; shift;;
|
||||||
-libdir|--libdir)
|
-libdir|--libdir)
|
||||||
libdir=$2; shift;;
|
libdir=$2; shift;;
|
||||||
-mandir|--mandir)
|
-mandir|--mandir)
|
||||||
|
@ -239,17 +242,23 @@ else
|
||||||
fi
|
fi
|
||||||
inf "Configuring for target $target ..."
|
inf "Configuring for target $target ..."
|
||||||
|
|
||||||
|
if [ x"$host" = x"$target" ]; then
|
||||||
|
cross_compiler=false
|
||||||
|
else
|
||||||
|
cross_compiler=true
|
||||||
|
fi
|
||||||
|
|
||||||
# Do we have gcc?
|
# Do we have gcc?
|
||||||
|
|
||||||
if test -z "$ccoption"; then
|
if test -z "$ccoption"; then
|
||||||
if sh ./searchpath "${TOOLPREF}gcc"; then
|
if sh ./searchpath "${TOOLPREF}gcc"; then
|
||||||
cc="${TOOLPREF}gcc"
|
cc="${TOOLPREF}gcc"
|
||||||
else
|
else
|
||||||
if test x"$host" = x"$target"; then
|
if $cross_compiler; then
|
||||||
cc="cc"
|
|
||||||
else
|
|
||||||
err "No cross-compiler found for ${target}.\n" \
|
err "No cross-compiler found for ${target}.\n" \
|
||||||
"It should be named ${TOOLPREF}gcc and be in the PATH."
|
"It should be named ${TOOLPREF}gcc and be in the PATH."
|
||||||
|
else
|
||||||
|
cc="cc"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
@ -450,7 +459,7 @@ case $? in
|
||||||
1) err "The C compiler $cc is not ANSI-compliant.\n" \
|
1) err "The C compiler $cc is not ANSI-compliant.\n" \
|
||||||
"You need an ANSI C compiler to build OCaml.";;
|
"You need an ANSI C compiler to build OCaml.";;
|
||||||
*)
|
*)
|
||||||
if test x"$host" != x"$target"; then
|
if $cross_compiler; then
|
||||||
wrn "Unable to compile the test program.\n" \
|
wrn "Unable to compile the test program.\n" \
|
||||||
"This failure is expected for cross-compilation:\n" \
|
"This failure is expected for cross-compilation:\n" \
|
||||||
"we will assume the C compiler is ANSI-compliant."
|
"we will assume the C compiler is ANSI-compliant."
|
||||||
|
@ -460,29 +469,43 @@ case $? in
|
||||||
fi;;
|
fi;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Determine which ocamlrun executable to use; for cross-compilation, a native
|
# For cross-compilation, we need a host-based ocamlrun and ocamlyacc,
|
||||||
# "ocamlrun" executable must be available on the system.
|
# and the user must specify the target BINDIR
|
||||||
if test x"$target" != x"$host"; then
|
if $cross_compiler; then
|
||||||
if ! sh ./searchpath ocamlrun; then
|
if ! sh ./searchpath ocamlrun; then
|
||||||
err "Cross-compilation requires an ocaml runtime environment\n" \
|
err "Cross-compilation requires an ocaml runtime environment\n" \
|
||||||
"(the ocamlrun binary). Moreover, its version must be the same\n" \
|
"(the ocamlrun binary). Moreover, its version must be the same\n" \
|
||||||
"as the one you're trying to build (`cut -f1 -d+ < ../../VERSION`)."
|
"as the one you're trying to build (`cut -f1 -d+ < ../../VERSION`)."
|
||||||
else
|
else
|
||||||
ocaml_system_version=`ocamlrun -version | sed 's/[^0-9]*\([0-9.]\+\).*/\1/'`
|
ocaml_system_version=`ocamlrun -version | sed 's/[^0-9]*\([0-9.]*\).*/\1/'`
|
||||||
ocaml_source_version=`sed -n '1 s/\([0-9\.]\+\).*/\1/ p' < ../../VERSION`
|
ocaml_source_version=`sed -n '1 s/\([0-9\.]*\).*/\1/ p' < ../../VERSION`
|
||||||
if test x"$ocaml_system_version" != x"$ocaml_source_version"; then
|
if test x"$ocaml_system_version" != x"$ocaml_source_version"; then
|
||||||
err "While you have an ocaml runtime environment, its version\n" \
|
err "While you have an ocaml runtime environment, its version\n" \
|
||||||
"($ocaml_system_version) doesn't match the version of these sources\n" \
|
"($ocaml_system_version) doesn't match the version of these sources\n" \
|
||||||
"($ocaml_source_version)."
|
"($ocaml_source_version)."
|
||||||
else
|
else
|
||||||
CAMLRUN="ocamlrun"
|
echo "CAMLRUN=`./searchpath -p ocamlrun`" >> Makefile
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
CAMLRUN=`cd ../.. && pwd`/boot/ocamlrun
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "CAMLRUN=$CAMLRUN" >> Makefile
|
if ! sh ./searchpath ocamlyacc; then
|
||||||
|
err "Cross-compilation requires an ocamlyacc binary."
|
||||||
|
else
|
||||||
|
ocamlyacc 2>/dev/null
|
||||||
|
if test "$?" -ne 1; then
|
||||||
|
err "While you have an ocamlyacc binary, it cannot be executed successfully."
|
||||||
|
else
|
||||||
|
echo "CAMLYACC=`./searchpath -p ocamlyacc`" >> Makefile
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$target_bindir" ]; then
|
||||||
|
err "Cross-compilation requires -target-bindir."
|
||||||
|
else
|
||||||
|
echo "TARGET_BINDIR=$target_bindir" >> Makefile
|
||||||
|
fi
|
||||||
|
fi # cross-compiler
|
||||||
|
|
||||||
|
|
||||||
# Check the sizes of data types
|
# Check the sizes of data types
|
||||||
# OCaml needs a 32 or 64 bit architecture, a 32-bit integer type and
|
# OCaml needs a 32 or 64 bit architecture, a 32-bit integer type and
|
||||||
|
@ -914,6 +937,8 @@ case "$arch,$system" in
|
||||||
case "$nativecc" in gcc*) ;; *) cc_profile='-xpg';; esac;;
|
case "$nativecc" in gcc*) ;; *) cc_profile='-xpg';; esac;;
|
||||||
amd64,linux) profiling='prof';;
|
amd64,linux) profiling='prof';;
|
||||||
amd64,openbsd) profiling='prof';;
|
amd64,openbsd) profiling='prof';;
|
||||||
|
amd64,freebsd) profiling='prof';;
|
||||||
|
amd64,netbsd) profiling='prof';;
|
||||||
amd64,gnu) profiling='prof';;
|
amd64,gnu) profiling='prof';;
|
||||||
arm,linux*) profiling='prof';;
|
arm,linux*) profiling='prof';;
|
||||||
power,elf) profiling='prof';;
|
power,elf) profiling='prof';;
|
||||||
|
@ -955,7 +980,8 @@ if (SHELL=/bin/sh; export SHELL; (./sharpbang || ./sharpbang2) >/dev/null); then
|
||||||
"under Cygwin"
|
"under Cygwin"
|
||||||
echo "SHARPBANGSCRIPTS=false" >> Makefile;;
|
echo "SHARPBANGSCRIPTS=false" >> Makefile;;
|
||||||
*-*-mingw*)
|
*-*-mingw*)
|
||||||
inf "We won't use it, though, because it's on the target platform it would be used and windows doesn't support it."
|
inf "We won't use it, though, because it's on the target platform " \
|
||||||
|
"it would be used and windows doesn't support it."
|
||||||
echo "SHARPBANGSCRIPTS=false" >> Makefile;;
|
echo "SHARPBANGSCRIPTS=false" >> Makefile;;
|
||||||
*)
|
*)
|
||||||
echo "SHARPBANGSCRIPTS=true" >> Makefile;;
|
echo "SHARPBANGSCRIPTS=true" >> Makefile;;
|
||||||
|
@ -1659,6 +1685,12 @@ if $no_naked_pointers; then
|
||||||
echo "#define NO_NAKED_POINTERS" >> m.h
|
echo "#define NO_NAKED_POINTERS" >> m.h
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Add Unix-style optimization flag
|
||||||
|
bytecccompopts="-O $bytecccompopts"
|
||||||
|
dllcccompopts="-O $dllcccompopts"
|
||||||
|
nativecccompopts="-O $nativecccompopts"
|
||||||
|
sharedcccompopts="-O $sharedcccompopts"
|
||||||
|
|
||||||
# Final twiddling of compiler options to work around known bugs
|
# Final twiddling of compiler options to work around known bugs
|
||||||
|
|
||||||
nativeccprofopts="$nativecccompopts"
|
nativeccprofopts="$nativecccompopts"
|
||||||
|
|
|
@ -11,15 +11,15 @@
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
include ../config/Makefile
|
include ../config/Makefile
|
||||||
|
CAMLRUN ?= ../boot/ocamlrun
|
||||||
|
CAMLYACC ?= ../boot/ocamlyacc
|
||||||
|
|
||||||
ROOTDIR=..
|
CAMLC=$(CAMLRUN) ../ocamlc -nostdlib -I ../stdlib
|
||||||
CAMLC=$(ROOTDIR)/boot/ocamlrun $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
|
||||||
COMPFLAGS=-warn-error A -safe-string $(INCLUDES)
|
COMPFLAGS=-warn-error A -safe-string $(INCLUDES)
|
||||||
LINKFLAGS=-linkall -I $(UNIXDIR)
|
LINKFLAGS=-linkall -I $(UNIXDIR)
|
||||||
CAMLYACC=../boot/ocamlyacc
|
|
||||||
YACCFLAGS=
|
YACCFLAGS=
|
||||||
CAMLLEX=../boot/ocamlrun ../boot/ocamllex
|
CAMLLEX=$(CAMLRUN) ../boot/ocamllex
|
||||||
CAMLDEP=../boot/ocamlrun ../tools/ocamldep
|
CAMLDEP=$(CAMLRUN) ../tools/ocamldep
|
||||||
DEPFLAGS=$(INCLUDES)
|
DEPFLAGS=$(INCLUDES)
|
||||||
|
|
||||||
INSTALL_BINDIR=$(DESTDIR)$(BINDIR)
|
INSTALL_BINDIR=$(DESTDIR)$(BINDIR)
|
||||||
|
|
|
@ -56,26 +56,28 @@ let first_objfiles = ref []
|
||||||
let last_objfiles = ref []
|
let last_objfiles = ref []
|
||||||
|
|
||||||
(* Check validity of module name *)
|
(* Check validity of module name *)
|
||||||
let check_unit_name ppf filename name =
|
let is_unit_name name =
|
||||||
try
|
try
|
||||||
begin match name.[0] with
|
begin match name.[0] with
|
||||||
| 'A'..'Z' -> ()
|
| 'A'..'Z' -> ()
|
||||||
| _ ->
|
| _ ->
|
||||||
Location.print_warning (Location.in_file filename) ppf
|
|
||||||
(Warnings.Bad_module_name name);
|
|
||||||
raise Exit;
|
raise Exit;
|
||||||
end;
|
end;
|
||||||
for i = 1 to String.length name - 1 do
|
for i = 1 to String.length name - 1 do
|
||||||
match name.[i] with
|
match name.[i] with
|
||||||
| 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' | '\'' -> ()
|
| 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' | '\'' -> ()
|
||||||
| _ ->
|
| _ ->
|
||||||
Location.print_warning (Location.in_file filename) ppf
|
|
||||||
(Warnings.Bad_module_name name);
|
|
||||||
raise Exit;
|
raise Exit;
|
||||||
done;
|
done;
|
||||||
with Exit -> ()
|
true
|
||||||
|
with Exit -> false
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
let check_unit_name ppf filename name =
|
||||||
|
if not (is_unit_name name) then
|
||||||
|
Location.print_warning (Location.in_file filename) ppf
|
||||||
|
(Warnings.Bad_module_name name);;
|
||||||
|
|
||||||
(* Compute name of module from output file name *)
|
(* Compute name of module from output file name *)
|
||||||
let module_of_filename ppf inputfile outputprefix =
|
let module_of_filename ppf inputfile outputprefix =
|
||||||
let basename = Filename.basename outputprefix in
|
let basename = Filename.basename outputprefix in
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
(* *)
|
(* *)
|
||||||
(***********************************************************************)
|
(***********************************************************************)
|
||||||
|
|
||||||
(* val check_unit_name : Format.formatter -> string -> string -> unit *)
|
|
||||||
val module_of_filename : Format.formatter -> string -> string -> string
|
val module_of_filename : Format.formatter -> string -> string -> string
|
||||||
|
|
||||||
val output_prefix : string -> string
|
val output_prefix : string -> string
|
||||||
|
@ -35,3 +34,10 @@ type readenv_position =
|
||||||
Before_args | Before_compile | Before_link
|
Before_args | Before_compile | Before_link
|
||||||
|
|
||||||
val readenv : Format.formatter -> readenv_position -> unit
|
val readenv : Format.formatter -> readenv_position -> unit
|
||||||
|
|
||||||
|
(* [is_unit_name name] returns true only if [name] can be used as a
|
||||||
|
correct module name *)
|
||||||
|
val is_unit_name : string -> bool
|
||||||
|
(* [check_unit_name ppf filename name] prints a warning in [filename]
|
||||||
|
on [ppf] if [name] should not be used as a module name. *)
|
||||||
|
val check_unit_name : Format.formatter -> string -> string -> unit
|
||||||
|
|
|
@ -60,50 +60,44 @@ let implementation ppf sourcefile outputprefix =
|
||||||
let modulename = module_of_filename ppf sourcefile outputprefix in
|
let modulename = module_of_filename ppf sourcefile outputprefix in
|
||||||
Env.set_unit_name modulename;
|
Env.set_unit_name modulename;
|
||||||
let env = Compmisc.initial_env() in
|
let env = Compmisc.initial_env() in
|
||||||
if !Clflags.print_types then begin
|
try
|
||||||
let comp ast =
|
let (typedtree, coercion) =
|
||||||
ast
|
Pparse.parse_implementation ~tool_name ppf sourcefile
|
||||||
++ print_if ppf Clflags.dump_parsetree Printast.implementation
|
++ print_if ppf Clflags.dump_parsetree Printast.implementation
|
||||||
++ print_if ppf Clflags.dump_source Pprintast.structure
|
++ print_if ppf Clflags.dump_source Pprintast.structure
|
||||||
++ Typemod.type_implementation sourcefile outputprefix modulename env
|
++ Typemod.type_implementation sourcefile outputprefix modulename env
|
||||||
++ print_if ppf Clflags.dump_typedtree
|
++ print_if ppf Clflags.dump_typedtree
|
||||||
Printtyped.implementation_with_coercion
|
Printtyped.implementation_with_coercion
|
||||||
++ (fun _ -> ());
|
in
|
||||||
|
if !Clflags.print_types then begin
|
||||||
Warnings.check_fatal ();
|
Warnings.check_fatal ();
|
||||||
Stypes.dump (Some (outputprefix ^ ".annot"))
|
Stypes.dump (Some (outputprefix ^ ".annot"))
|
||||||
in
|
end else begin
|
||||||
try comp (Pparse.parse_implementation ~tool_name ppf sourcefile)
|
let bytecode =
|
||||||
with x ->
|
(typedtree, coercion)
|
||||||
Stypes.dump (Some (outputprefix ^ ".annot"));
|
++ Translmod.transl_implementation modulename
|
||||||
raise x
|
++ print_if ppf Clflags.dump_rawlambda Printlambda.lambda
|
||||||
end else begin
|
++ Simplif.simplify_lambda
|
||||||
let objfile = outputprefix ^ ".cmo" in
|
++ print_if ppf Clflags.dump_lambda Printlambda.lambda
|
||||||
let oc = open_out_bin objfile in
|
++ Bytegen.compile_implementation modulename
|
||||||
let comp ast =
|
++ print_if ppf Clflags.dump_instr Printinstr.instrlist
|
||||||
ast
|
in
|
||||||
++ print_if ppf Clflags.dump_parsetree Printast.implementation
|
let objfile = outputprefix ^ ".cmo" in
|
||||||
++ print_if ppf Clflags.dump_source Pprintast.structure
|
let oc = open_out_bin objfile in
|
||||||
++ Typemod.type_implementation sourcefile outputprefix modulename env
|
try
|
||||||
++ print_if ppf Clflags.dump_typedtree
|
bytecode
|
||||||
Printtyped.implementation_with_coercion
|
++ Emitcode.to_file oc modulename objfile;
|
||||||
++ Translmod.transl_implementation modulename
|
Warnings.check_fatal ();
|
||||||
++ print_if ppf Clflags.dump_rawlambda Printlambda.lambda
|
close_out oc;
|
||||||
++ Simplif.simplify_lambda
|
Stypes.dump (Some (outputprefix ^ ".annot"))
|
||||||
++ print_if ppf Clflags.dump_lambda Printlambda.lambda
|
with x ->
|
||||||
++ Bytegen.compile_implementation modulename
|
close_out oc;
|
||||||
++ print_if ppf Clflags.dump_instr Printinstr.instrlist
|
remove_file objfile;
|
||||||
++ Emitcode.to_file oc modulename objfile;
|
raise x
|
||||||
Warnings.check_fatal ();
|
end
|
||||||
close_out oc;
|
with x ->
|
||||||
Stypes.dump (Some (outputprefix ^ ".annot"))
|
Stypes.dump (Some (outputprefix ^ ".annot"));
|
||||||
in
|
raise x
|
||||||
try comp (Pparse.parse_implementation ~tool_name ppf sourcefile)
|
|
||||||
with x ->
|
|
||||||
close_out oc;
|
|
||||||
remove_file objfile;
|
|
||||||
Stypes.dump (Some (outputprefix ^ ".annot"));
|
|
||||||
raise x
|
|
||||||
end
|
|
||||||
|
|
||||||
let c_file name =
|
let c_file name =
|
||||||
Location.input_name := name;
|
Location.input_name := name;
|
||||||
|
|
|
@ -104,6 +104,8 @@ module Options = Main_args.Make_bytecomp_options (struct
|
||||||
let _o s = output_name := Some s
|
let _o s = output_name := Some s
|
||||||
let _open s = open_modules := s :: !open_modules
|
let _open s = open_modules := s :: !open_modules
|
||||||
let _output_obj () = output_c_object := true; custom_runtime := true
|
let _output_obj () = output_c_object := true; custom_runtime := true
|
||||||
|
let _output_complete_obj () =
|
||||||
|
output_c_object := true; output_complete_object := true; custom_runtime := true
|
||||||
let _pack = set make_package
|
let _pack = set make_package
|
||||||
let _pp s = preprocessor := Some s
|
let _pp s = preprocessor := Some s
|
||||||
let _ppx s = first_ppx := s :: !first_ppx
|
let _ppx s = first_ppx := s :: !first_ppx
|
||||||
|
@ -194,3 +196,7 @@ let main () =
|
||||||
exit 2
|
exit 2
|
||||||
|
|
||||||
let _ = main ()
|
let _ = main ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,12 @@ let mk_open f =
|
||||||
"-open", Arg.String f, "<module> Opens the module <module> before typing"
|
"-open", Arg.String f, "<module> Opens the module <module> before typing"
|
||||||
|
|
||||||
let mk_output_obj f =
|
let mk_output_obj f =
|
||||||
"-output-obj", Arg.Unit f, " Output a C object file instead of an executable"
|
"-output-obj", Arg.Unit f, " Output an object file instead of an executable"
|
||||||
|
;;
|
||||||
|
|
||||||
|
let mk_output_complete_obj f =
|
||||||
|
"-output-complete-obj", Arg.Unit f,
|
||||||
|
" Output an object file, including runtime, instead of an executable"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let mk_p f =
|
let mk_p f =
|
||||||
|
@ -534,6 +539,7 @@ module type Compiler_options = sig
|
||||||
val _noautolink : unit -> unit
|
val _noautolink : unit -> unit
|
||||||
val _o : string -> unit
|
val _o : string -> unit
|
||||||
val _output_obj : unit -> unit
|
val _output_obj : unit -> unit
|
||||||
|
val _output_complete_obj : unit -> unit
|
||||||
val _pack : unit -> unit
|
val _pack : unit -> unit
|
||||||
val _pp : string -> unit
|
val _pp : string -> unit
|
||||||
val _principal : unit -> unit
|
val _principal : unit -> unit
|
||||||
|
@ -685,6 +691,7 @@ struct
|
||||||
mk_o F._o;
|
mk_o F._o;
|
||||||
mk_open F._open;
|
mk_open F._open;
|
||||||
mk_output_obj F._output_obj;
|
mk_output_obj F._output_obj;
|
||||||
|
mk_output_complete_obj F._output_complete_obj;
|
||||||
mk_pack_byt F._pack;
|
mk_pack_byt F._pack;
|
||||||
mk_pp F._pp;
|
mk_pp F._pp;
|
||||||
mk_ppx F._ppx;
|
mk_ppx F._ppx;
|
||||||
|
@ -803,6 +810,7 @@ struct
|
||||||
mk_o F._o;
|
mk_o F._o;
|
||||||
mk_open F._open;
|
mk_open F._open;
|
||||||
mk_output_obj F._output_obj;
|
mk_output_obj F._output_obj;
|
||||||
|
mk_output_complete_obj F._output_complete_obj;
|
||||||
mk_p F._p;
|
mk_p F._p;
|
||||||
mk_pack_opt F._pack;
|
mk_pack_opt F._pack;
|
||||||
mk_pp F._pp;
|
mk_pp F._pp;
|
||||||
|
|
|
@ -68,6 +68,7 @@ module type Compiler_options = sig
|
||||||
val _noautolink : unit -> unit
|
val _noautolink : unit -> unit
|
||||||
val _o : string -> unit
|
val _o : string -> unit
|
||||||
val _output_obj : unit -> unit
|
val _output_obj : unit -> unit
|
||||||
|
val _output_complete_obj : unit -> unit
|
||||||
val _pack : unit -> unit
|
val _pack : unit -> unit
|
||||||
val _pp : string -> unit
|
val _pp : string -> unit
|
||||||
val _principal : unit -> unit
|
val _principal : unit -> unit
|
||||||
|
|
|
@ -66,22 +66,16 @@ let implementation ppf sourcefile outputprefix =
|
||||||
let cmxfile = outputprefix ^ ".cmx" in
|
let cmxfile = outputprefix ^ ".cmx" in
|
||||||
let objfile = outputprefix ^ ext_obj in
|
let objfile = outputprefix ^ ext_obj in
|
||||||
let comp ast =
|
let comp ast =
|
||||||
if !Clflags.print_types
|
let (typedtree, coercion) =
|
||||||
then
|
|
||||||
ast
|
ast
|
||||||
++ print_if ppf Clflags.dump_parsetree Printast.implementation
|
++ print_if ppf Clflags.dump_parsetree Printast.implementation
|
||||||
++ print_if ppf Clflags.dump_source Pprintast.structure
|
++ print_if ppf Clflags.dump_source Pprintast.structure
|
||||||
++ Typemod.type_implementation sourcefile outputprefix modulename env
|
++ Typemod.type_implementation sourcefile outputprefix modulename env
|
||||||
++ print_if ppf Clflags.dump_typedtree
|
++ print_if ppf Clflags.dump_typedtree
|
||||||
Printtyped.implementation_with_coercion
|
Printtyped.implementation_with_coercion
|
||||||
++ (fun _ -> ())
|
in
|
||||||
else begin
|
if not !Clflags.print_types then begin
|
||||||
ast
|
(typedtree, coercion)
|
||||||
++ print_if ppf Clflags.dump_parsetree Printast.implementation
|
|
||||||
++ print_if ppf Clflags.dump_source Pprintast.structure
|
|
||||||
++ Typemod.type_implementation sourcefile outputprefix modulename env
|
|
||||||
++ print_if ppf Clflags.dump_typedtree
|
|
||||||
Printtyped.implementation_with_coercion
|
|
||||||
++ Translmod.transl_store_implementation modulename
|
++ Translmod.transl_store_implementation modulename
|
||||||
+++ print_if ppf Clflags.dump_rawlambda Printlambda.lambda
|
+++ print_if ppf Clflags.dump_rawlambda Printlambda.lambda
|
||||||
+++ Simplif.simplify_lambda
|
+++ Simplif.simplify_lambda
|
||||||
|
|
|
@ -104,6 +104,8 @@ module Options = Main_args.Make_optcomp_options (struct
|
||||||
let _o s = output_name := Some s
|
let _o s = output_name := Some s
|
||||||
let _open s = open_modules := s :: !open_modules
|
let _open s = open_modules := s :: !open_modules
|
||||||
let _output_obj = set output_c_object
|
let _output_obj = set output_c_object
|
||||||
|
let _output_complete_obj s =
|
||||||
|
set output_c_object s; set output_complete_object s
|
||||||
let _p = set gprofile
|
let _p = set gprofile
|
||||||
let _pack = set make_package
|
let _pack = set make_package
|
||||||
let _pp s = preprocessor := Some s
|
let _pp s = preprocessor := Some s
|
||||||
|
|
|
@ -20,10 +20,7 @@ exception Error of error
|
||||||
|
|
||||||
(* Optionally preprocess a source file *)
|
(* Optionally preprocess a source file *)
|
||||||
|
|
||||||
let preprocess sourcefile =
|
let call_external_preprocessor sourcefile pp =
|
||||||
match !Clflags.preprocessor with
|
|
||||||
None -> sourcefile
|
|
||||||
| Some pp ->
|
|
||||||
let tmpfile = Filename.temp_file "ocamlpp" "" in
|
let tmpfile = Filename.temp_file "ocamlpp" "" in
|
||||||
let comm = Printf.sprintf "%s %s > %s"
|
let comm = Printf.sprintf "%s %s > %s"
|
||||||
pp (Filename.quote sourcefile) tmpfile
|
pp (Filename.quote sourcefile) tmpfile
|
||||||
|
@ -34,6 +31,12 @@ let preprocess sourcefile =
|
||||||
end;
|
end;
|
||||||
tmpfile
|
tmpfile
|
||||||
|
|
||||||
|
let preprocess sourcefile =
|
||||||
|
match !Clflags.preprocessor with
|
||||||
|
None -> sourcefile
|
||||||
|
| Some pp -> call_external_preprocessor sourcefile pp
|
||||||
|
|
||||||
|
|
||||||
let remove_preprocessed inputfile =
|
let remove_preprocessed inputfile =
|
||||||
match !Clflags.preprocessor with
|
match !Clflags.preprocessor with
|
||||||
None -> ()
|
None -> ()
|
||||||
|
@ -124,7 +127,7 @@ let apply_rewriters ?restore ~tool_name magic ast =
|
||||||
|
|
||||||
exception Outdated_version
|
exception Outdated_version
|
||||||
|
|
||||||
let file ppf ~tool_name inputfile parse_fun ast_magic =
|
let open_and_check_magic inputfile ast_magic =
|
||||||
let ic = open_in_bin inputfile in
|
let ic = open_in_bin inputfile in
|
||||||
let is_ast_file =
|
let is_ast_file =
|
||||||
try
|
try
|
||||||
|
@ -138,6 +141,10 @@ let file ppf ~tool_name inputfile parse_fun ast_magic =
|
||||||
Misc.fatal_error "OCaml and preprocessor have incompatible versions"
|
Misc.fatal_error "OCaml and preprocessor have incompatible versions"
|
||||||
| _ -> false
|
| _ -> false
|
||||||
in
|
in
|
||||||
|
(ic, is_ast_file)
|
||||||
|
|
||||||
|
let file ppf ~tool_name inputfile parse_fun ast_magic =
|
||||||
|
let (ic, is_ast_file) = open_and_check_magic inputfile ast_magic in
|
||||||
let ast =
|
let ast =
|
||||||
try
|
try
|
||||||
if is_ast_file then begin
|
if is_ast_file then begin
|
||||||
|
@ -159,6 +166,7 @@ let file ppf ~tool_name inputfile parse_fun ast_magic =
|
||||||
close_in ic;
|
close_in ic;
|
||||||
apply_rewriters ~restore:false ~tool_name ast_magic ast
|
apply_rewriters ~restore:false ~tool_name ast_magic ast
|
||||||
|
|
||||||
|
|
||||||
let report_error ppf = function
|
let report_error ppf = function
|
||||||
| CannotRun cmd ->
|
| CannotRun cmd ->
|
||||||
fprintf ppf "Error while running external preprocessor@.\
|
fprintf ppf "Error while running external preprocessor@.\
|
||||||
|
|
|
@ -34,3 +34,8 @@ val report_error : formatter -> error -> unit
|
||||||
|
|
||||||
val parse_implementation: formatter -> tool_name:string -> string -> Parsetree.structure
|
val parse_implementation: formatter -> tool_name:string -> string -> Parsetree.structure
|
||||||
val parse_interface: formatter -> tool_name:string -> string -> Parsetree.signature
|
val parse_interface: formatter -> tool_name:string -> string -> Parsetree.signature
|
||||||
|
|
||||||
|
(* [call_external_preprocessor sourcefile pp] *)
|
||||||
|
val call_external_preprocessor : string -> string -> string
|
||||||
|
val open_and_check_magic : string -> string -> in_channel * bool
|
||||||
|
val read_ast : string -> string -> 'a
|
||||||
|
|
|
@ -20,6 +20,18 @@
|
||||||
(require 'caml-emacs)))
|
(require 'caml-emacs)))
|
||||||
|
|
||||||
|
|
||||||
|
(defvar caml-types-build-dirs '("_build" "_obuild")
|
||||||
|
"List of possible compilation directories created by build systems.
|
||||||
|
It is expected that the files under `caml-types-build-dir' preserve
|
||||||
|
the paths relative to the parent directory of `caml-types-build-dir'.")
|
||||||
|
(make-variable-buffer-local 'caml-types-build-dir)
|
||||||
|
|
||||||
|
(defvar caml-annot-dir nil
|
||||||
|
"A directory, generally relative to the file location, containing the
|
||||||
|
.annot file. Intended to be set as a local variable in the .ml file.
|
||||||
|
See \"Specifying File Variables\" in the Emacs info manual.")
|
||||||
|
(make-variable-buffer-local 'caml-annot-dir)
|
||||||
|
(put 'caml-annot-dir 'safe-local-variable #'stringp)
|
||||||
|
|
||||||
(defvar caml-types-location-re nil "Regexp to parse *.annot files.
|
(defvar caml-types-location-re nil "Regexp to parse *.annot files.
|
||||||
|
|
||||||
|
@ -349,21 +361,36 @@ See `caml-types-location-re' for annotation file format.
|
||||||
(defun caml-types-parent-dir (d) (file-name-directory (directory-file-name d)))
|
(defun caml-types-parent-dir (d) (file-name-directory (directory-file-name d)))
|
||||||
|
|
||||||
(defun caml-types-locate-type-file (target-path)
|
(defun caml-types-locate-type-file (target-path)
|
||||||
(let ((sibling (concat (file-name-sans-extension target-path) ".annot")))
|
"Given the path to an OCaml file, this function tries to locate
|
||||||
(if (file-exists-p sibling)
|
and return the corresponding .annot file."
|
||||||
sibling
|
(let ((sibling (concat (file-name-sans-extension target-path) ".annot")))
|
||||||
(let ((project-dir (file-name-directory sibling))
|
(if (file-exists-p sibling)
|
||||||
type-path)
|
sibling
|
||||||
(while (not (file-exists-p
|
(let* ((dir (file-name-directory sibling)))
|
||||||
(setq type-path
|
(if caml-annot-dir
|
||||||
(expand-file-name
|
;; Use the relative path set by the user
|
||||||
(file-relative-name sibling project-dir)
|
(let* ((annot-dir (expand-file-name caml-annot-dir dir))
|
||||||
(expand-file-name "_build" project-dir)))))
|
(fname (file-name-nondirectory sibling))
|
||||||
(if (equal project-dir (caml-types-parent-dir project-dir))
|
(path-fname (expand-file-name fname annot-dir)))
|
||||||
(error (concat "No annotation file. "
|
(if (file-exists-p path-fname)
|
||||||
"You should compile with option \"-annot\".")))
|
path-fname
|
||||||
(setq project-dir (caml-types-parent-dir project-dir)))
|
(error (concat "No annotation file in " caml-annot-dir
|
||||||
type-path))))
|
". Compile with option \"-annot\"."))))
|
||||||
|
;; Else, try to get the .annot from one of build dirs.
|
||||||
|
(let* ((is-build (regexp-opt caml-types-build-dirs))
|
||||||
|
(project-dir (locate-dominating-file
|
||||||
|
dir
|
||||||
|
(lambda(d) (directory-files d nil is-build))))
|
||||||
|
(annot
|
||||||
|
(if project-dir
|
||||||
|
(locate-file
|
||||||
|
(file-relative-name sibling project-dir)
|
||||||
|
(mapcar (lambda(d) (expand-file-name d project-dir))
|
||||||
|
caml-types-build-dirs)))))
|
||||||
|
(if annot
|
||||||
|
annot
|
||||||
|
(error (concat "No annotation file. Compile with option "
|
||||||
|
"\"-annot\" or set `caml-annot-dir'.")))))))))
|
||||||
|
|
||||||
(defun caml-types-date< (date1 date2)
|
(defun caml-types-date< (date1 date2)
|
||||||
(or (< (car date1) (car date2))
|
(or (< (car date1) (car date2))
|
||||||
|
|
14
lex/Makefile
14
lex/Makefile
|
@ -11,13 +11,17 @@
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
# The lexer generator
|
# The lexer generator
|
||||||
CAMLC=../boot/ocamlrun ../boot/ocamlc -strict-sequence -nostdlib -I ../boot
|
include ../config/Makefile
|
||||||
CAMLOPT=../boot/ocamlrun ../ocamlopt -nostdlib -I ../stdlib
|
CAMLRUN ?= ../boot/ocamlrun
|
||||||
|
CAMLYACC ?= ../boot/ocamlyacc
|
||||||
|
|
||||||
|
CAMLC=$(CAMLRUN) ../boot/ocamlc -strict-sequence -nostdlib -I ../boot
|
||||||
|
CAMLOPT=$(CAMLRUN) ../ocamlopt -nostdlib -I ../stdlib
|
||||||
COMPFLAGS=-w +33..39 -warn-error A -bin-annot -safe-string
|
COMPFLAGS=-w +33..39 -warn-error A -bin-annot -safe-string
|
||||||
CAMLYACC=../boot/ocamlyacc
|
LINKFLAGS=
|
||||||
YACCFLAGS=-v
|
YACCFLAGS=-v
|
||||||
CAMLLEX=../boot/ocamlrun ../boot/ocamllex
|
CAMLLEX=$(CAMLRUN) ../boot/ocamllex
|
||||||
CAMLDEP=../boot/ocamlrun ../tools/ocamldep
|
CAMLDEP=$(CAMLRUN) ../tools/ocamldep
|
||||||
|
|
||||||
|
|
||||||
OBJS=cset.cmo syntax.cmo parser.cmo lexer.cmo table.cmo lexgen.cmo \
|
OBJS=cset.cmo syntax.cmo parser.cmo lexer.cmo table.cmo lexgen.cmo \
|
||||||
|
|
|
@ -13,15 +13,16 @@
|
||||||
# The lexer generator
|
# The lexer generator
|
||||||
|
|
||||||
include ../config/Makefile
|
include ../config/Makefile
|
||||||
|
CAMLRUN ?= ../boot/ocamlrun
|
||||||
|
CAMLYACC ?= ../boot/ocamlyacc
|
||||||
|
|
||||||
CAMLC=../boot/ocamlrun ../boot/ocamlc -I ../boot
|
CAMLC=$(CAMLRUN) ../boot/ocamlc -I ../boot
|
||||||
CAMLOPT=../boot/ocamlrun ../ocamlopt -I ../stdlib
|
CAMLOPT=$(CAMLRUN) ../ocamlopt -I ../stdlib
|
||||||
COMPFLAGS=-warn-error A
|
COMPFLAGS=-warn-error A
|
||||||
LINKFLAGS=
|
LINKFLAGS=
|
||||||
CAMLYACC=../boot/ocamlyacc
|
|
||||||
YACCFLAGS=-v
|
YACCFLAGS=-v
|
||||||
CAMLLEX=../boot/ocamlrun ../boot/ocamllex
|
CAMLLEX=$(CAMLRUN) ../boot/ocamllex
|
||||||
CAMLDEP=../boot/ocamlrun ../tools/ocamldep
|
CAMLDEP=$(CAMLRUN) ../tools/ocamldep
|
||||||
DEPFLAGS=
|
DEPFLAGS=
|
||||||
|
|
||||||
OBJS=cset.cmo syntax.cmo parser.cmo lexer.cmo table.cmo lexgen.cmo \
|
OBJS=cset.cmo syntax.cmo parser.cmo lexer.cmo table.cmo lexgen.cmo \
|
||||||
|
|
|
@ -929,7 +929,8 @@ compiling your program with later versions of OCaml when they add new
|
||||||
warnings or modify existing warnings.
|
warnings or modify existing warnings.
|
||||||
|
|
||||||
The default setting is
|
The default setting is
|
||||||
.B \-warn\-error\ -a (all warnings are non-fatal).
|
.B \-warn\-error \-a
|
||||||
|
(all warnings are non-fatal).
|
||||||
.TP
|
.TP
|
||||||
.B \-warn\-help
|
.B \-warn\-help
|
||||||
Show the description of all available warning numbers.
|
Show the description of all available warning numbers.
|
||||||
|
|
|
@ -603,7 +603,8 @@ compiling your program with later versions of OCaml when they add new
|
||||||
warnings or modify existing warnings.
|
warnings or modify existing warnings.
|
||||||
|
|
||||||
The default setting is
|
The default setting is
|
||||||
.B \-warn\-error\ -a (all warnings are non-fatal).
|
.B \-warn\-error \-a
|
||||||
|
(all warnings are non-fatal).
|
||||||
.TP
|
.TP
|
||||||
.B \-warn\-help
|
.B \-warn\-help
|
||||||
Show the description of all available warning numbers.
|
Show the description of all available warning numbers.
|
||||||
|
|
|
@ -197,6 +197,9 @@ Calling of finalisation functions.
|
||||||
Startup messages (loading the bytecode executable file, resolving
|
Startup messages (loading the bytecode executable file, resolving
|
||||||
shared libraries).
|
shared libraries).
|
||||||
|
|
||||||
|
.BR 0x200
|
||||||
|
Computation of compaction-triggering condition.
|
||||||
|
|
||||||
The multiplier is
|
The multiplier is
|
||||||
.BR k ,
|
.BR k ,
|
||||||
.BR M ,\ or
|
.BR M ,\ or
|
||||||
|
|
|
@ -11,13 +11,14 @@
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
include ../config/Makefile
|
include ../config/Makefile
|
||||||
|
CAMLRUN ?= ../boot/ocamlrun
|
||||||
|
CAMLYACC ?= ../boot/ocamlyacc
|
||||||
|
|
||||||
ROOTDIR = ..
|
ROOTDIR = ..
|
||||||
OCAMLRUN = $(ROOTDIR)/boot/ocamlrun
|
OCAMLC = $(CAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
||||||
OCAMLC = $(OCAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
OCAMLOPT = $(CAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib
|
||||||
OCAMLOPT = $(OCAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib
|
OCAMLDEP = $(CAMLRUN) $(ROOTDIR)/tools/ocamldep
|
||||||
OCAMLDEP = $(OCAMLRUN) $(ROOTDIR)/tools/ocamldep
|
OCAMLLEX = $(CAMLRUN) $(ROOTDIR)/boot/ocamllex
|
||||||
OCAMLLEX = $(OCAMLRUN) $(ROOTDIR)/boot/ocamllex
|
|
||||||
CP = cp
|
CP = cp
|
||||||
COMPFLAGS= -warn-error A -w L -w R -w Z -I ../otherlibs/$(UNIXLIB) -safe-string
|
COMPFLAGS= -warn-error A -w L -w R -w Z -I ../otherlibs/$(UNIXLIB) -safe-string
|
||||||
LINKFLAGS= -I ../otherlibs/$(UNIXLIB)
|
LINKFLAGS= -I ../otherlibs/$(UNIXLIB)
|
||||||
|
@ -137,13 +138,14 @@ ocamlbuild_pack.cmx: $(PACK_CMX)
|
||||||
|
|
||||||
ocamlbuild_config.ml: ../config/Makefile
|
ocamlbuild_config.ml: ../config/Makefile
|
||||||
(echo 'let bindir = "$(BINDIR)"'; \
|
(echo 'let bindir = "$(BINDIR)"'; \
|
||||||
echo 'let libdir = "$(LIBDIR)"'; \
|
echo 'let libdir = "$(LIBDIR)"'; \
|
||||||
echo 'let supports_shared_libraries = $(SUPPORTS_SHARED_LIBRARIES)';\
|
echo 'let supports_shared_libraries = $(SUPPORTS_SHARED_LIBRARIES)';\
|
||||||
echo 'let a = "$(A)"'; \
|
echo 'let a = "$(A)"'; \
|
||||||
echo 'let o = "$(O)"'; \
|
echo 'let o = "$(O)"'; \
|
||||||
echo 'let so = "$(SO)"'; \
|
echo 'let so = "$(SO)"'; \
|
||||||
echo 'let exe = "$(EXE)"'; \
|
echo 'let ext_dll = "$(EXT_DLL)"'; \
|
||||||
) > ocamlbuild_config.ml
|
echo 'let exe = "$(EXE)"'; \
|
||||||
|
) > ocamlbuild_config.ml
|
||||||
clean::
|
clean::
|
||||||
rm -f ocamlbuild_config.ml
|
rm -f ocamlbuild_config.ml
|
||||||
beforedepend:: ocamlbuild_config.ml
|
beforedepend:: ocamlbuild_config.ml
|
||||||
|
|
|
@ -1,227 +0,0 @@
|
||||||
#(***********************************************************************)
|
|
||||||
#(* *)
|
|
||||||
#(* ocamlbuild *)
|
|
||||||
#(* *)
|
|
||||||
#(* Wojciech Meyer *)
|
|
||||||
#(* *)
|
|
||||||
#(* Copyright 2012 Institut National de Recherche en Informatique et *)
|
|
||||||
#(* en Automatique. All rights reserved. This file is distributed *)
|
|
||||||
#(* under the terms of the Q Public License version 1.0. *)
|
|
||||||
#(* *)
|
|
||||||
#(***********************************************************************)
|
|
||||||
|
|
||||||
# This file removes the dependency on ocamlbuild itself, thus removes need
|
|
||||||
# for bootstrap. The base for this Makefile was ocamldoc Makefile.
|
|
||||||
|
|
||||||
include ../config/Makefile
|
|
||||||
|
|
||||||
# Various commands and dir
|
|
||||||
##########################
|
|
||||||
|
|
||||||
ROOTDIR = ..
|
|
||||||
OCAMLRUN = $(ROOTDIR)/boot/ocamlrun
|
|
||||||
OCAMLC = $(OCAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
|
||||||
OCAMLOPT = $(OCAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib
|
|
||||||
OCAMLDEP = $(OCAMLRUN) $(ROOTDIR)/tools/ocamldep
|
|
||||||
OCAMLLEX = $(OCAMLRUN) $(ROOTDIR)/boot/ocamllex
|
|
||||||
OCAMLLIB = $(LIBDIR)
|
|
||||||
OCAMLBIN = $(BINDIR)
|
|
||||||
|
|
||||||
# For installation
|
|
||||||
##############
|
|
||||||
MKDIR=mkdir -p
|
|
||||||
CP=cp -f
|
|
||||||
OCAMLBUILD=ocamlbuild
|
|
||||||
OCAMLBUILD_OPT=$(OCAMLBUILD).opt
|
|
||||||
OCAMLBUILD_LIBCMA=ocamlbuildlib.cma
|
|
||||||
OCAMLBUILD_LIBCMI=ocamlbuildlib.cmi
|
|
||||||
OCAMLBUILD_LIBCMXA=ocamlbuild.cmxa
|
|
||||||
OCAMLBUILD_LIBA=ocamlbuild.$(A)
|
|
||||||
INSTALL_LIBDIR=$(DESTDIR)$(OCAMLLIB)/ocamlbuild
|
|
||||||
INSTALL_CUSTOMDIR=$(INSTALL_LIBDIR)/custom
|
|
||||||
INSTALL_BINDIR=$(DESTDIR)$(OCAMLBIN)
|
|
||||||
|
|
||||||
INSTALL_MLIS=
|
|
||||||
INSTALL_CMIS=$(INSTALL_MLIS:.mli=.cmi)
|
|
||||||
|
|
||||||
# Compilation
|
|
||||||
#############
|
|
||||||
OCAMLSRCDIR=..
|
|
||||||
INCLUDES_DEP=
|
|
||||||
|
|
||||||
INCLUDES_NODEP= -I $(OCAMLSRCDIR)/stdlib \
|
|
||||||
-I $(OCAMLSRCDIR)/otherlibs/str \
|
|
||||||
-I $(OCAMLSRCDIR)/otherlibs/dynlink \
|
|
||||||
-I $(OCAMLSRCDIR)/otherlibs/$(UNIXLIB)
|
|
||||||
|
|
||||||
INCLUDES=$(INCLUDES_DEP) $(INCLUDES_NODEP)
|
|
||||||
|
|
||||||
COMPFLAGS=$(INCLUDES) -warn-error A -safe-string
|
|
||||||
LINKFLAGS=$(INCLUDES)
|
|
||||||
|
|
||||||
CMOFILES_PACK= \
|
|
||||||
ocamlbuild_Myocamlbuild_config.cmo \
|
|
||||||
discard_printf.cmo \
|
|
||||||
my_std.cmo \
|
|
||||||
bool.cmo \
|
|
||||||
glob_ast.cmo \
|
|
||||||
glob_lexer.cmo \
|
|
||||||
glob.cmo \
|
|
||||||
lexers.cmo \
|
|
||||||
my_unix.cmo \
|
|
||||||
tags.cmo \
|
|
||||||
display.cmo \
|
|
||||||
log.cmo \
|
|
||||||
param_tags.cmo \
|
|
||||||
shell.cmo \
|
|
||||||
slurp.cmo \
|
|
||||||
ocamlbuild_where.cmo \
|
|
||||||
command.cmo \
|
|
||||||
options.cmo \
|
|
||||||
pathname.cmo \
|
|
||||||
digest_cache.cmo \
|
|
||||||
resource.cmo \
|
|
||||||
rule.cmo \
|
|
||||||
flags.cmo \
|
|
||||||
solver.cmo \
|
|
||||||
report.cmo \
|
|
||||||
ocaml_arch.cmo \
|
|
||||||
hygiene.cmo \
|
|
||||||
configuration.cmo \
|
|
||||||
tools.cmo \
|
|
||||||
fda.cmo \
|
|
||||||
plugin.cmo \
|
|
||||||
ocaml_utils.cmo \
|
|
||||||
ocaml_dependencies.cmo \
|
|
||||||
ocaml_compiler.cmo \
|
|
||||||
ocaml_tools.cmo \
|
|
||||||
hooks.cmo \
|
|
||||||
findlib.cmo \
|
|
||||||
ocaml_specific.cmo \
|
|
||||||
exit_codes.cmo \
|
|
||||||
main.cmo
|
|
||||||
|
|
||||||
BASE_CMOFILES= ocamlbuild_executor.cmo \
|
|
||||||
ocamlbuild_unix_plugin.cmo
|
|
||||||
|
|
||||||
INSTALL_LIBFILES = $(BASE_CMOFILES) \
|
|
||||||
$(BASE_CMOFILES:.cmo=.cmi) \
|
|
||||||
$(OCAMLBUILD_LIBCMA) \
|
|
||||||
$(OCAMLBUILD).cmo \
|
|
||||||
$(OCAMLBUILD)_pack.cmi
|
|
||||||
|
|
||||||
INSTALL_BINFILES = $(OCAMLBUILD)
|
|
||||||
|
|
||||||
CMXFILES= $(CMOFILES:.cmo=.cmx)
|
|
||||||
|
|
||||||
CMXFILES_PACK= $(CMOFILES_PACK:.cmo=.cmx)
|
|
||||||
CMIFILES_PACK= $(CMOFILES_PACK:.cmo=.cmi) signatures.cmi
|
|
||||||
|
|
||||||
EXECMOFILES_PACK= $(CMOFILES_PACK)
|
|
||||||
EXECMXFILES_PACK= $(EXECMOFILES_PACK:.cmo=.cmx)
|
|
||||||
EXECMIFILES_PACK= $(EXECMOFILES_PACK:.cmo=.cmi)
|
|
||||||
|
|
||||||
LIBCMOFILES_PACK= $(CMOFILES_PACK)
|
|
||||||
LIBCMXFILES_PACK= $(LIBCMOFILES_PACK:.cmo=.cmx)
|
|
||||||
LIBCMIFILES_PACK= $(LIBCMOFILES_PACK:.cmo=.cmi)
|
|
||||||
|
|
||||||
# Les cmo et cmx de la distrib OCAML
|
|
||||||
OCAMLCMOFILES=
|
|
||||||
OCAMLCMXFILES=$(OCAMLCMOFILES_PACK:.cmo=.cmx)
|
|
||||||
|
|
||||||
all: exe lib
|
|
||||||
opt: $(OCAMLBUILD).native
|
|
||||||
exe: $(OCAMLBUILD)
|
|
||||||
lib: $(OCAMLBUILD_LIBCMA)
|
|
||||||
|
|
||||||
opt.opt: exeopt libopt
|
|
||||||
exeopt: $(OCAMLBUILD_OPT)
|
|
||||||
libopt: $(OCAMLBUILD_LIBCMXA) $(OCAMLBUILD_LIBCMI)
|
|
||||||
|
|
||||||
debug:
|
|
||||||
$(MAKE) OCAMLPP=""
|
|
||||||
|
|
||||||
$(OCAMLBUILD)_pack.cmo: $(CMOFILES_PACK) $(CMIFILES_PACK)
|
|
||||||
$(OCAMLC) -pack -o $@ $(LINKFLAGS) $(OCAMLCMOFILES_PACK) $(EXECMOFILES_PACK) signatures.mli
|
|
||||||
|
|
||||||
$(OCAMLBUILD)_pack.cmx: $(EXECMXFILES_PACK)
|
|
||||||
$(OCAMLOPT) -pack -o $@ $(LINKFLAGS) $(OCAMLCMOFILES_PACK) $(EXECMXFILES_PACK)
|
|
||||||
|
|
||||||
$(OCAMLBUILD): $(OCAMLBUILD)_pack.cmo $(CMOFILES) $(OCAMLBUILD).cmo $(BASE_CMOFILES)
|
|
||||||
$(OCAMLC) -o $@ unix.cma $(LINKFLAGS) $(OCAMLBUILD)_pack.cmo $(CMOFILES)
|
|
||||||
|
|
||||||
$(OCAMLBUILD).native: $(OCAMLBUILD)_pack.cmx $(CMXFILES)
|
|
||||||
$(OCAMLOPT) -o $@ $(LINKFLAGS) $(CMXFILES)
|
|
||||||
|
|
||||||
$(OCAMLBUILD_LIBCMA): $(LIBCMOFILES_PACK)
|
|
||||||
$(OCAMLC) -a -o $@ $(LINKFLAGS) $(OCAMLSRCDIR)/tools/depend.cmo $(LIBCMOFILES_PACK)
|
|
||||||
$(OCAMLBUILD_LIBCMXA): $(LIBCMXFILES)
|
|
||||||
$(OCAMLOPT) -a -o $@ $(LINKFLAGS) $(OCAMLSRCDIR)/tools/depend.cmx $(LIBCMXFILES)
|
|
||||||
|
|
||||||
# generic rules :
|
|
||||||
#################
|
|
||||||
|
|
||||||
.SUFFIXES: .mll .mly .ml .mli .cmo .cmi .cmx .cmxs
|
|
||||||
|
|
||||||
.ml.cmo:
|
|
||||||
$(OCAMLC) $(OCAMLPP) $(COMPFLAGS) -c $<
|
|
||||||
|
|
||||||
.mli.cmi:
|
|
||||||
$(OCAMLC) $(OCAMLPP) $(COMPFLAGS) -c $<
|
|
||||||
|
|
||||||
.ml.cmx:
|
|
||||||
$(OCAMLOPT) $(OCAMLPP) $(COMPFLAGS) -c $<
|
|
||||||
|
|
||||||
.ml.cmxs:
|
|
||||||
$(OCAMLOPT) -shared -o $@ $(OCAMLPP) $(COMPFLAGS) $<
|
|
||||||
|
|
||||||
.mll.ml:
|
|
||||||
$(OCAMLLEX) $<
|
|
||||||
|
|
||||||
.mly.ml:
|
|
||||||
$(OCAMLYACC) -v $<
|
|
||||||
|
|
||||||
.mly.mli:
|
|
||||||
$(OCAMLYACC) -v $<
|
|
||||||
|
|
||||||
# Installation targets
|
|
||||||
######################
|
|
||||||
install: dummy
|
|
||||||
if test -d $(INSTALL_BINDIR); then : ; else $(MKDIR) $(INSTALL_BINDIR); fi
|
|
||||||
if test -d $(INSTALL_LIBDIR); then : ; else $(MKDIR) $(INSTALL_LIBDIR); fi
|
|
||||||
if test -d $(INSTALL_CUSTOMDIR); then : ; else $(MKDIR) $(INSTALL_CUSTOMDIR); fi
|
|
||||||
$(CP) $(OCAMLBUILD) $(INSTALL_BINDIR)/$(OCAMLBUILD)$(EXE)
|
|
||||||
$(CP) $(INSTALL_LIBFILES) $(INSTALL_LIBDIR)
|
|
||||||
$(CP) $(INSTALL_BINFILES) $(INSTALL_BINDIR)
|
|
||||||
|
|
||||||
installopt:
|
|
||||||
if test -f $(OCAMLBUILD_OPT) ; then $(MAKE) installopt_really ; fi
|
|
||||||
|
|
||||||
installopt_really:
|
|
||||||
if test -d $(INSTALL_BINDIR); then : ; else $(MKDIR) $(INSTALL_BINDIR); fi
|
|
||||||
if test -d $(INSTALL_LIBDIR); then : ; else $(MKDIR) $(INSTALL_LIBDIR); fi
|
|
||||||
$(CP) ocamlbuild.hva $(OCAMLBUILD_LIBA) $(OCAMLBUILD_LIBCMXA) $(INSTALL_LIBDIR)
|
|
||||||
$(CP) $(INSTALL_MLIS) $(INSTALL_CMIS) $(INSTALL_LIBDIR)
|
|
||||||
|
|
||||||
|
|
||||||
# backup, clean and depend :
|
|
||||||
############################
|
|
||||||
|
|
||||||
clean:: dummy
|
|
||||||
@rm -f *~ \#*\#
|
|
||||||
@rm -f $(OCAMLBUILD) $(OCAMLBUILD_OPT) *.cma *.cmxa *.cmo *.cmi *.cmx *.$(A) *.$(O)
|
|
||||||
@rm -f glob_lexer.ml lexers.ml
|
|
||||||
|
|
||||||
depend::
|
|
||||||
$(OCAMLDEP) $(INCLUDES_DEP) *.mli *.mll *.mly *.ml > .depend
|
|
||||||
|
|
||||||
dummy:
|
|
||||||
|
|
||||||
include .depend
|
|
||||||
|
|
||||||
# Additional rules
|
|
||||||
glob_lexer.cmo: glob_lexer.cmi
|
|
||||||
lexers.cmo: lexers.cmi
|
|
||||||
|
|
||||||
glob_lexer.cmx: glob_lexer.cmi
|
|
||||||
lexers.cmx: lexers.cmi
|
|
|
@ -393,6 +393,9 @@ let pdep tags ptag deps =
|
||||||
Param_tags.declare ptag
|
Param_tags.declare ptag
|
||||||
(fun param -> dep (Param_tags.make ptag param :: tags) (deps param))
|
(fun param -> dep (Param_tags.make ptag param :: tags) (deps param))
|
||||||
|
|
||||||
|
let list_all_deps () =
|
||||||
|
!all_deps_of_tags
|
||||||
|
|
||||||
(*
|
(*
|
||||||
let to_string_for_digest x =
|
let to_string_for_digest x =
|
||||||
let rec cmd_of_spec =
|
let rec cmd_of_spec =
|
||||||
|
|
|
@ -46,4 +46,6 @@ val dep : Tags.elt list -> pathname list -> unit
|
||||||
|
|
||||||
val pdep : Tags.elt list -> Tags.elt -> (string -> pathname list) -> unit
|
val pdep : Tags.elt list -> Tags.elt -> (string -> pathname list) -> unit
|
||||||
|
|
||||||
|
val list_all_deps : unit -> (Tags.t * pathname list) list
|
||||||
|
|
||||||
val file_or_exe_exists: string -> bool
|
val file_or_exe_exists: string -> bool
|
||||||
|
|
|
@ -81,10 +81,11 @@ let tag_any tags =
|
||||||
let check_tags_usage useful_tags =
|
let check_tags_usage useful_tags =
|
||||||
let check_tag (tag, loc) =
|
let check_tag (tag, loc) =
|
||||||
if not (Tags.mem tag useful_tags) then
|
if not (Tags.mem tag useful_tags) then
|
||||||
Log.eprintf "%aWarning: the tag %S is not used in any flag declaration, \
|
|
||||||
so it will have no effect; it may be a typo. Otherwise use \
|
Log.eprintf "%aWarning: the tag %S is not used in any flag or dependency \
|
||||||
`mark_tag_used` in your myocamlbuild.ml to disable \
|
declaration, so it will have no effect; it may be a typo. \
|
||||||
this warning."
|
Otherwise you can use `mark_tag_used` in your myocamlbuild.ml \
|
||||||
|
to disable this warning."
|
||||||
Loc.print_loc loc tag
|
Loc.print_loc loc tag
|
||||||
in
|
in
|
||||||
let check_conf (_, values) =
|
let check_conf (_, values) =
|
||||||
|
|
|
@ -25,7 +25,6 @@ exception Exit_build_error of string
|
||||||
exception Exit_silently
|
exception Exit_silently
|
||||||
|
|
||||||
let clean () =
|
let clean () =
|
||||||
Log.finish ();
|
|
||||||
Shell.rm_rf !Options.build_dir;
|
Shell.rm_rf !Options.build_dir;
|
||||||
if !Options.make_links then begin
|
if !Options.make_links then begin
|
||||||
let entry =
|
let entry =
|
||||||
|
@ -34,6 +33,7 @@ let clean () =
|
||||||
in
|
in
|
||||||
Slurp.force (Resource.clean_up_links entry)
|
Slurp.force (Resource.clean_up_links entry)
|
||||||
end;
|
end;
|
||||||
|
Log.finish ();
|
||||||
raise Exit_silently
|
raise Exit_silently
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
@ -67,6 +67,8 @@ let builtin_useful_tags =
|
||||||
let proceed () =
|
let proceed () =
|
||||||
Hooks.call_hook Hooks.Before_options;
|
Hooks.call_hook Hooks.Before_options;
|
||||||
Options.init ();
|
Options.init ();
|
||||||
|
Options.include_dirs := List.map Pathname.normalize !Options.include_dirs;
|
||||||
|
Options.exclude_dirs := List.map Pathname.normalize !Options.exclude_dirs;
|
||||||
if !Options.must_clean then clean ();
|
if !Options.must_clean then clean ();
|
||||||
Hooks.call_hook Hooks.After_options;
|
Hooks.call_hook Hooks.After_options;
|
||||||
let options_wd = Sys.getcwd () in
|
let options_wd = Sys.getcwd () in
|
||||||
|
@ -203,7 +205,14 @@ let proceed () =
|
||||||
raise Exit_silently
|
raise Exit_silently
|
||||||
end;
|
end;
|
||||||
|
|
||||||
let all_tags = Tags.union builtin_useful_tags (Flags.get_used_tags ()) in
|
let all_tags =
|
||||||
|
let builtin = builtin_useful_tags in
|
||||||
|
let used_in_flags = Flags.get_used_tags () in
|
||||||
|
let used_in_deps =
|
||||||
|
List.fold_left (fun acc (tags, _deps) -> Tags.union acc tags)
|
||||||
|
Tags.empty (Command.list_all_deps ())
|
||||||
|
in
|
||||||
|
Tags.union builtin (Tags.union used_in_flags used_in_deps) in
|
||||||
Configuration.check_tags_usage all_tags;
|
Configuration.check_tags_usage all_tags;
|
||||||
|
|
||||||
Digest_cache.init ();
|
Digest_cache.init ();
|
||||||
|
|
|
@ -84,6 +84,12 @@ let rec readlink x =
|
||||||
if sys_file_exists x then
|
if sys_file_exists x then
|
||||||
try
|
try
|
||||||
let y = readlinkcmd x in
|
let y = readlinkcmd x in
|
||||||
|
let y =
|
||||||
|
if Filename.is_relative y then
|
||||||
|
Filename.concat (Filename.dirname x) y
|
||||||
|
else
|
||||||
|
y
|
||||||
|
in
|
||||||
if (lstat y).stat_file_kind = FK_dir then raise Link_to_directories_not_supported else y
|
if (lstat y).stat_file_kind = FK_dir then raise Link_to_directories_not_supported else y
|
||||||
with Failure(_) -> raise Not_a_link
|
with Failure(_) -> raise Not_a_link
|
||||||
else raise No_such_file
|
else raise No_such_file
|
||||||
|
|
|
@ -72,13 +72,22 @@ let execute_many =
|
||||||
in
|
in
|
||||||
Ocamlbuild_executor.execute ~exit
|
Ocamlbuild_executor.execute ~exit
|
||||||
|
|
||||||
|
(* Ocamlbuild code assumes throughout that [readlink] will return a file name
|
||||||
|
relative to the current directory. Let's make it so. *)
|
||||||
|
let myunixreadlink x =
|
||||||
|
let y = Unix.readlink x in
|
||||||
|
if Filename.is_relative y then
|
||||||
|
Filename.concat (Filename.dirname x) y
|
||||||
|
else
|
||||||
|
y
|
||||||
|
|
||||||
let setup () =
|
let setup () =
|
||||||
implem.is_degraded <- false;
|
implem.is_degraded <- false;
|
||||||
implem.stdout_isatty <- stdout_isatty;
|
implem.stdout_isatty <- stdout_isatty;
|
||||||
implem.gettimeofday <- Unix.gettimeofday;
|
implem.gettimeofday <- Unix.gettimeofday;
|
||||||
implem.report_error <- report_error;
|
implem.report_error <- report_error;
|
||||||
implem.execute_many <- execute_many;
|
implem.execute_many <- execute_many;
|
||||||
implem.readlink <- Unix.readlink;
|
implem.readlink <- myunixreadlink;
|
||||||
implem.run_and_open <- run_and_open;
|
implem.run_and_open <- run_and_open;
|
||||||
implem.at_exit_once <- at_exit_once;
|
implem.at_exit_once <- at_exit_once;
|
||||||
implem.is_link <- is_link;
|
implem.is_link <- is_link;
|
||||||
|
|
|
@ -101,7 +101,9 @@ let show_documentation = ref false
|
||||||
let recursive = ref false
|
let recursive = ref false
|
||||||
let ext_lib = ref Ocamlbuild_config.a
|
let ext_lib = ref Ocamlbuild_config.a
|
||||||
let ext_obj = ref Ocamlbuild_config.o
|
let ext_obj = ref Ocamlbuild_config.o
|
||||||
let ext_dll = ref Ocamlbuild_config.so
|
let ext_dll =
|
||||||
|
let s = Ocamlbuild_config.ext_dll in
|
||||||
|
ref (String.sub s 1 (String.length s - 1))
|
||||||
let exe = ref Ocamlbuild_config.exe
|
let exe = ref Ocamlbuild_config.exe
|
||||||
|
|
||||||
let targets_internal = ref []
|
let targets_internal = ref []
|
||||||
|
|
|
@ -321,11 +321,4 @@ let () = test "OpenDependencies"
|
||||||
~matching:[M.f "b.byte"]
|
~matching:[M.f "b.byte"]
|
||||||
~targets:("b.byte",[]) ();;
|
~targets:("b.byte",[]) ();;
|
||||||
|
|
||||||
let () = test "OCamlcC"
|
|
||||||
~options:[`no_ocamlfind]
|
|
||||||
~description:"Build a C file using ocamlc (PR#6475)"
|
|
||||||
~tree:[T.d "nested" [T.f "foo.c" ~content:"void f(){}"]]
|
|
||||||
~matching:[_build [M.d "nested" [M.f "foo.o"]]]
|
|
||||||
~targets:("nested/foo.o",[]) ();;
|
|
||||||
|
|
||||||
run ~root:"_test_internal";;
|
run ~root:"_test_internal";;
|
||||||
|
|
|
@ -11,16 +11,16 @@
|
||||||
#(***********************************************************************)
|
#(***********************************************************************)
|
||||||
|
|
||||||
include ../config/Makefile
|
include ../config/Makefile
|
||||||
|
CAMLRUN ?= ../boot/ocamlrun
|
||||||
|
CAMLYACC ?= ../boot/ocamlyacc
|
||||||
|
|
||||||
# Various commands and dir
|
# Various commands and dir
|
||||||
##########################
|
##########################
|
||||||
ROOTDIR = ..
|
ROOTDIR = ..
|
||||||
OCAMLRUN = $(ROOTDIR)/boot/ocamlrun
|
OCAMLC = $(CAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
||||||
OCAMLC = $(OCAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
OCAMLOPT = $(CAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib
|
||||||
OCAMLOPT = $(OCAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib
|
OCAMLDEP = $(CAMLRUN) $(ROOTDIR)/tools/ocamldep
|
||||||
OCAMLDEP = $(OCAMLRUN) $(ROOTDIR)/tools/ocamldep
|
OCAMLLEX = $(CAMLRUN) $(ROOTDIR)/boot/ocamllex
|
||||||
OCAMLLEX = $(OCAMLRUN) $(ROOTDIR)/boot/ocamllex
|
|
||||||
OCAMLYACC = $(ROOTDIR)/yacc/ocamlyacc
|
|
||||||
OCAMLLIB = $(LIBDIR)
|
OCAMLLIB = $(LIBDIR)
|
||||||
OCAMLBIN = $(BINDIR)
|
OCAMLBIN = $(BINDIR)
|
||||||
|
|
||||||
|
@ -233,10 +233,10 @@ odoc_see_lexer.ml: odoc_see_lexer.mll
|
||||||
$(OCAMLLEX) $<
|
$(OCAMLLEX) $<
|
||||||
|
|
||||||
.mly.ml:
|
.mly.ml:
|
||||||
$(OCAMLYACC) -v $<
|
$(CAMLYACC) -v $<
|
||||||
|
|
||||||
.mly.mli:
|
.mly.mli:
|
||||||
$(OCAMLYACC) -v $<
|
$(CAMLYACC) -v $<
|
||||||
|
|
||||||
# Installation targets
|
# Installation targets
|
||||||
######################
|
######################
|
||||||
|
@ -343,8 +343,8 @@ clean:: dummy
|
||||||
@rm -f generators/*.cm[aiox] generators/*.$(A) generators/*.$(O) generators/*.cmx[as]
|
@rm -f generators/*.cm[aiox] generators/*.$(A) generators/*.$(O) generators/*.cmx[as]
|
||||||
|
|
||||||
depend::
|
depend::
|
||||||
$(OCAMLYACC) odoc_text_parser.mly
|
$(CAMLYACC) odoc_text_parser.mly
|
||||||
$(OCAMLYACC) odoc_parser.mly
|
$(CAMLYACC) odoc_parser.mly
|
||||||
$(OCAMLLEX) odoc_text_lexer.mll
|
$(OCAMLLEX) odoc_text_lexer.mll
|
||||||
$(OCAMLLEX) odoc_lexer.mll
|
$(OCAMLLEX) odoc_lexer.mll
|
||||||
$(OCAMLLEX) odoc_ocamlhtml.mll
|
$(OCAMLLEX) odoc_ocamlhtml.mll
|
||||||
|
|
|
@ -11,16 +11,16 @@
|
||||||
#(***********************************************************************)
|
#(***********************************************************************)
|
||||||
|
|
||||||
include ../config/Makefile
|
include ../config/Makefile
|
||||||
|
CAMLRUN ?= ../boot/ocamlrun
|
||||||
|
CAMLYACC ?= ../boot/ocamlyacc
|
||||||
|
|
||||||
# Various commands and dir
|
# Various commands and dir
|
||||||
##########################
|
##########################
|
||||||
ROOTDIR = ..
|
ROOTDIR = ..
|
||||||
OCAMLRUN = $(ROOTDIR)/boot/ocamlrun
|
OCAMLC = $(CAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
||||||
OCAMLC = $(OCAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
OCAMLOPT = $(CAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib
|
||||||
OCAMLOPT = $(OCAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib
|
OCAMLDEP = $(CAMLRUN) $(ROOTDIR)/tools/ocamldep
|
||||||
OCAMLDEP = $(OCAMLRUN) $(ROOTDIR)/tools/ocamldep
|
OCAMLLEX = $(CAMLRUN) $(ROOTDIR)/boot/ocamllex
|
||||||
OCAMLLEX = $(OCAMLRUN) $(ROOTDIR)/boot/ocamllex
|
|
||||||
OCAMLYACC = $(ROOTDIR)/yacc/ocamlyacc
|
|
||||||
OCAMLLIB = $(LIBDIR)
|
OCAMLLIB = $(LIBDIR)
|
||||||
OCAMLBIN = $(BINDIR)
|
OCAMLBIN = $(BINDIR)
|
||||||
|
|
||||||
|
@ -202,10 +202,10 @@ odoc_see_lexer.ml: odoc_see_lexer.mll
|
||||||
$(OCAMLLEX) $<
|
$(OCAMLLEX) $<
|
||||||
|
|
||||||
.mly.ml:
|
.mly.ml:
|
||||||
$(OCAMLYACC) -v $<
|
$(CAMLYACC) -v $<
|
||||||
|
|
||||||
.mly.mli:
|
.mly.mli:
|
||||||
$(OCAMLYACC) -v $<
|
$(CAMLYACC) -v $<
|
||||||
|
|
||||||
# Installation targets
|
# Installation targets
|
||||||
######################
|
######################
|
||||||
|
@ -240,8 +240,8 @@ clean:: dummy
|
||||||
@rm -f generators/*.cm[aiox] generators/*.$(A) generators/*.$(O) generators/*.cmx[as]
|
@rm -f generators/*.cm[aiox] generators/*.$(A) generators/*.$(O) generators/*.cmx[as]
|
||||||
|
|
||||||
depend::
|
depend::
|
||||||
$(OCAMLYACC) odoc_text_parser.mly
|
$(CAMLYACC) odoc_text_parser.mly
|
||||||
$(OCAMLYACC) odoc_parser.mly
|
$(CAMLYACC) odoc_parser.mly
|
||||||
$(OCAMLLEX) odoc_text_lexer.mll
|
$(OCAMLLEX) odoc_text_lexer.mll
|
||||||
$(OCAMLLEX) odoc_lexer.mll
|
$(OCAMLLEX) odoc_lexer.mll
|
||||||
$(OCAMLLEX) odoc_ocamlhtml.mll
|
$(OCAMLLEX) odoc_ocamlhtml.mll
|
||||||
|
|
|
@ -1719,7 +1719,11 @@ module Analyser =
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
match (p_module_expr.Parsetree.pmod_desc, tt_module_expr.Typedtree.mod_desc) with
|
match (p_module_expr.Parsetree.pmod_desc, tt_module_expr.Typedtree.mod_desc) with
|
||||||
(Parsetree.Pmod_ident longident, Typedtree.Tmod_ident (path, _)) ->
|
(Parsetree.Pmod_ident longident, Typedtree.Tmod_ident (path, _))
|
||||||
|
| (Parsetree.Pmod_ident longident,
|
||||||
|
Typedtree.Tmod_constraint
|
||||||
|
({Typedtree.mod_desc = Typedtree.Tmod_ident (path, _)}, _, _, _))
|
||||||
|
->
|
||||||
let alias_name = Odoc_env.full_module_name env (Name.from_path path) in
|
let alias_name = Odoc_env.full_module_name env (Name.from_path path) in
|
||||||
{ m_base with m_kind = Module_alias { ma_name = alias_name ;
|
{ m_base with m_kind = Module_alias { ma_name = alias_name ;
|
||||||
ma_module = None ; } }
|
ma_module = None ; } }
|
||||||
|
@ -1869,6 +1873,7 @@ module Analyser =
|
||||||
(*DEBUG*) | Parsetree.Pmod_apply _ -> "Pmod_apply"
|
(*DEBUG*) | Parsetree.Pmod_apply _ -> "Pmod_apply"
|
||||||
(*DEBUG*) | Parsetree.Pmod_constraint _ -> "Pmod_constraint"
|
(*DEBUG*) | Parsetree.Pmod_constraint _ -> "Pmod_constraint"
|
||||||
(*DEBUG*) | Parsetree.Pmod_unpack _ -> "Pmod_unpack"
|
(*DEBUG*) | Parsetree.Pmod_unpack _ -> "Pmod_unpack"
|
||||||
|
(*DEBUG*) | Parsetree.Pmod_extension _ -> "Pmod_extension"
|
||||||
(*DEBUG*)in
|
(*DEBUG*)in
|
||||||
(*DEBUG*)let s_typed =
|
(*DEBUG*)let s_typed =
|
||||||
(*DEBUG*) match typedtree with
|
(*DEBUG*) match typedtree with
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
|
|
||||||
# Common Makefile for otherlibs on the Unix ports
|
# Common Makefile for otherlibs on the Unix ports
|
||||||
|
|
||||||
CAMLC=$(ROOTDIR)/boot/ocamlrun $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
CAMLC=$(CAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
||||||
CAMLOPT=$(ROOTDIR)/boot/ocamlrun $(ROOTDIR)/ocamlopt -nostdlib \
|
CAMLOPT=$(CAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib \
|
||||||
-I $(ROOTDIR)/stdlib
|
-I $(ROOTDIR)/stdlib
|
||||||
COPTFLAG=-O
|
COPTFLAG=-O
|
||||||
CFLAGS=-I$(ROOTDIR)/byterun $(COPTFLAG) $(SHAREDCCCOMPOPTS) $(EXTRACFLAGS)
|
CFLAGS=-I$(ROOTDIR)/byterun $(COPTFLAG) $(SHAREDCCCOMPOPTS) $(EXTRACFLAGS)
|
||||||
|
|
|
@ -15,10 +15,11 @@
|
||||||
|
|
||||||
ROOTDIR=../..
|
ROOTDIR=../..
|
||||||
include $(ROOTDIR)/config/Makefile
|
include $(ROOTDIR)/config/Makefile
|
||||||
|
CAMLRUN ?= $(ROOTDIR)/boot/ocamlrun
|
||||||
|
CAMLYACC ?= $(ROOTDIR)/boot/ocamlyacc
|
||||||
|
|
||||||
# Compilation options
|
# Compilation options
|
||||||
CC=$(BYTECC)
|
CC=$(BYTECC)
|
||||||
CAMLRUN=$(ROOTDIR)/boot/ocamlrun
|
|
||||||
COMPFLAGS=-w +33..39 -warn-error A -bin-annot -g -safe-string $(EXTRACAMLFLAGS)
|
COMPFLAGS=-w +33..39 -warn-error A -bin-annot -g -safe-string $(EXTRACAMLFLAGS)
|
||||||
MKLIB=$(CAMLRUN) $(ROOTDIR)/tools/ocamlmklib
|
MKLIB=$(CAMLRUN) $(ROOTDIR)/tools/ocamlmklib
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ bigarray_stubs.o: bigarray_stubs.c ../../byterun/caml/alloc.h \
|
||||||
../../byterun/caml/io.h ../../byterun/caml/hash.h \
|
../../byterun/caml/io.h ../../byterun/caml/hash.h \
|
||||||
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
||||||
../../byterun/caml/major_gc.h ../../byterun/caml/freelist.h \
|
../../byterun/caml/major_gc.h ../../byterun/caml/freelist.h \
|
||||||
../../byterun/caml/minor_gc.h ../../byterun/caml/signals.h
|
../../byterun/caml/minor_gc.h ../../byterun/caml/signals.h \
|
||||||
|
../../byterun/caml/address_class.h
|
||||||
mmap_unix.o: mmap_unix.c bigarray.h ../../byterun/caml/config.h \
|
mmap_unix.o: mmap_unix.c bigarray.h ../../byterun/caml/config.h \
|
||||||
../../byterun/caml/../../config/m.h ../../byterun/caml/../../config/s.h \
|
../../byterun/caml/../../config/m.h ../../byterun/caml/../../config/s.h \
|
||||||
../../byterun/caml/mlvalues.h ../../byterun/caml/config.h \
|
../../byterun/caml/mlvalues.h ../../byterun/caml/config.h \
|
||||||
|
|
|
@ -22,6 +22,6 @@ include ../Makefile
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
$(CC) -MM $(CFLAGS) *.c > .depend
|
$(CC) -MM $(CFLAGS) *.c > .depend
|
||||||
../../boot/ocamlrun ../../tools/ocamldep *.mli *.ml >> .depend
|
$(CAMLRUN) ../../tools/ocamldep *.mli *.ml >> .depend
|
||||||
|
|
||||||
include .depend
|
include .depend
|
||||||
|
|
|
@ -22,6 +22,6 @@ include ../Makefile.nt
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
$(CC) -MM $(CFLAGS) *.c > .depend
|
$(CC) -MM $(CFLAGS) *.c > .depend
|
||||||
../../boot/ocamlrun ../../tools/ocamldep *.mli *.ml >> .depend
|
$(CAMLRUN) ../../tools/ocamldep *.mli *.ml >> .depend
|
||||||
|
|
||||||
include .depend
|
include .depend
|
||||||
|
|
|
@ -106,10 +106,18 @@ struct caml_ba_array {
|
||||||
#define CAMLBAextern CAMLextern
|
#define CAMLBAextern CAMLextern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
CAMLBAextern value
|
CAMLBAextern value
|
||||||
caml_ba_alloc(int flags, int num_dims, void * data, intnat * dim);
|
caml_ba_alloc(int flags, int num_dims, void * data, intnat * dim);
|
||||||
CAMLBAextern value caml_ba_alloc_dims(int flags, int num_dims, void * data,
|
CAMLBAextern value caml_ba_alloc_dims(int flags, int num_dims, void * data,
|
||||||
... /*dimensions, with type intnat */);
|
... /*dimensions, with type intnat */);
|
||||||
CAMLBAextern uintnat caml_ba_byte_size(struct caml_ba_array * b);
|
CAMLBAextern uintnat caml_ba_byte_size(struct caml_ba_array * b);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* CAML_BIGARRAY_H */
|
||||||
|
|
|
@ -452,7 +452,11 @@ module Genarray :
|
||||||
the initial call to [map_file]. Therefore, you should make sure no
|
the initial call to [map_file]. Therefore, you should make sure no
|
||||||
other process modifies the mapped file while you're accessing it,
|
other process modifies the mapped file while you're accessing it,
|
||||||
or a SIGBUS signal may be raised. This happens, for instance, if the
|
or a SIGBUS signal may be raised. This happens, for instance, if the
|
||||||
file is shrinked. *)
|
file is shrunk.
|
||||||
|
|
||||||
|
This function raises [Sys_error] in the case of any errors from the
|
||||||
|
underlying system calls. [Invalid_argument] or [Failure] may be
|
||||||
|
raised in cases where argument validation fails. *)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -13,15 +13,18 @@
|
||||||
|
|
||||||
# Makefile for the dynamic link library
|
# Makefile for the dynamic link library
|
||||||
|
|
||||||
|
# FIXME reduce redundancy by including ../Makefile
|
||||||
|
|
||||||
include ../../config/Makefile
|
include ../../config/Makefile
|
||||||
|
CAMLRUN ?= ../../boot/ocamlrun
|
||||||
|
CAMLYACC ?= ../../boot/ocamlyacc
|
||||||
|
|
||||||
ROOTDIR = ../..
|
ROOTDIR = ../..
|
||||||
OCAMLRUN = $(ROOTDIR)/boot/ocamlrun
|
OCAMLC = $(CAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
||||||
OCAMLC = $(OCAMLRUN) $(ROOTDIR)/ocamlc -nostdlib -I $(ROOTDIR)/stdlib
|
OCAMLOPT = $(CAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib
|
||||||
OCAMLOPT = $(OCAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib -I $(ROOTDIR)/stdlib
|
|
||||||
|
|
||||||
INCLUDES=-I ../../utils -I ../../typing -I ../../bytecomp -I ../../asmcomp
|
INCLUDES=-I ../../utils -I ../../typing -I ../../bytecomp -I ../../asmcomp
|
||||||
COMPFLAGS=-w +33..39 -warn-error A -bin-annot -safe-string \
|
COMPFLAGS=-w +33..39 -warn-error A -bin-annot -g -safe-string \
|
||||||
-I ../../stdlib $(INCLUDES)
|
-I ../../stdlib $(INCLUDES)
|
||||||
|
|
||||||
OBJS=dynlinkaux.cmo dynlink.cmo
|
OBJS=dynlinkaux.cmo dynlink.cmo
|
||||||
|
@ -69,7 +72,7 @@ dynlink.cmx: dynlink.cmi natdynlink.ml
|
||||||
rm -f dynlink.mlopt
|
rm -f dynlink.mlopt
|
||||||
|
|
||||||
extract_crc: dynlink.cma extract_crc.cmo
|
extract_crc: dynlink.cma extract_crc.cmo
|
||||||
$(OCAMLC) $(COMPFLAGS) -o extract_crc dynlink.cma extract_crc.cmo
|
$(OCAMLC) -o extract_crc dynlink.cma extract_crc.cmo
|
||||||
|
|
||||||
INSTALL_LIBDIR=$(DESTDIR)$(LIBDIR)
|
INSTALL_LIBDIR=$(DESTDIR)$(LIBDIR)
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ dump_img.o: dump_img.c libgraph.h ../../byterun/caml/mlvalues.h \
|
||||||
../../byterun/caml/alloc.h ../../byterun/caml/mlvalues.h \
|
../../byterun/caml/alloc.h ../../byterun/caml/mlvalues.h \
|
||||||
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
||||||
../../byterun/caml/major_gc.h ../../byterun/caml/freelist.h \
|
../../byterun/caml/major_gc.h ../../byterun/caml/freelist.h \
|
||||||
../../byterun/caml/minor_gc.h
|
../../byterun/caml/minor_gc.h ../../byterun/caml/address_class.h
|
||||||
events.o: events.c libgraph.h ../../byterun/caml/mlvalues.h \
|
events.o: events.c libgraph.h ../../byterun/caml/mlvalues.h \
|
||||||
../../byterun/caml/compatibility.h ../../byterun/caml/config.h \
|
../../byterun/caml/compatibility.h ../../byterun/caml/config.h \
|
||||||
../../byterun/caml/../../config/m.h ../../byterun/caml/../../config/s.h \
|
../../byterun/caml/../../config/m.h ../../byterun/caml/../../config/s.h \
|
||||||
|
@ -27,7 +27,8 @@ fill.o: fill.c libgraph.h ../../byterun/caml/mlvalues.h \
|
||||||
../../byterun/caml/misc.h ../../byterun/caml/misc.h \
|
../../byterun/caml/misc.h ../../byterun/caml/misc.h \
|
||||||
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
||||||
../../byterun/caml/mlvalues.h ../../byterun/caml/major_gc.h \
|
../../byterun/caml/mlvalues.h ../../byterun/caml/major_gc.h \
|
||||||
../../byterun/caml/freelist.h ../../byterun/caml/minor_gc.h
|
../../byterun/caml/freelist.h ../../byterun/caml/minor_gc.h \
|
||||||
|
../../byterun/caml/address_class.h
|
||||||
image.o: image.c libgraph.h ../../byterun/caml/mlvalues.h \
|
image.o: image.c libgraph.h ../../byterun/caml/mlvalues.h \
|
||||||
../../byterun/caml/compatibility.h ../../byterun/caml/config.h \
|
../../byterun/caml/compatibility.h ../../byterun/caml/config.h \
|
||||||
../../byterun/caml/../../config/m.h ../../byterun/caml/../../config/s.h \
|
../../byterun/caml/../../config/m.h ../../byterun/caml/../../config/s.h \
|
||||||
|
@ -40,7 +41,8 @@ make_img.o: make_img.c libgraph.h ../../byterun/caml/mlvalues.h \
|
||||||
../../byterun/caml/misc.h ../../byterun/caml/misc.h image.h \
|
../../byterun/caml/misc.h ../../byterun/caml/misc.h image.h \
|
||||||
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
||||||
../../byterun/caml/mlvalues.h ../../byterun/caml/major_gc.h \
|
../../byterun/caml/mlvalues.h ../../byterun/caml/major_gc.h \
|
||||||
../../byterun/caml/freelist.h ../../byterun/caml/minor_gc.h
|
../../byterun/caml/freelist.h ../../byterun/caml/minor_gc.h \
|
||||||
|
../../byterun/caml/address_class.h
|
||||||
open.o: open.c libgraph.h ../../byterun/caml/mlvalues.h \
|
open.o: open.c libgraph.h ../../byterun/caml/mlvalues.h \
|
||||||
../../byterun/caml/compatibility.h ../../byterun/caml/config.h \
|
../../byterun/caml/compatibility.h ../../byterun/caml/config.h \
|
||||||
../../byterun/caml/../../config/m.h ../../byterun/caml/../../config/s.h \
|
../../byterun/caml/../../config/m.h ../../byterun/caml/../../config/s.h \
|
||||||
|
@ -49,7 +51,7 @@ open.o: open.c libgraph.h ../../byterun/caml/mlvalues.h \
|
||||||
../../byterun/caml/callback.h ../../byterun/caml/fail.h \
|
../../byterun/caml/callback.h ../../byterun/caml/fail.h \
|
||||||
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
||||||
../../byterun/caml/major_gc.h ../../byterun/caml/freelist.h \
|
../../byterun/caml/major_gc.h ../../byterun/caml/freelist.h \
|
||||||
../../byterun/caml/minor_gc.h
|
../../byterun/caml/minor_gc.h ../../byterun/caml/address_class.h
|
||||||
point_col.o: point_col.c libgraph.h ../../byterun/caml/mlvalues.h \
|
point_col.o: point_col.c libgraph.h ../../byterun/caml/mlvalues.h \
|
||||||
../../byterun/caml/compatibility.h ../../byterun/caml/config.h \
|
../../byterun/caml/compatibility.h ../../byterun/caml/config.h \
|
||||||
../../byterun/caml/../../config/m.h ../../byterun/caml/../../config/s.h \
|
../../byterun/caml/../../config/m.h ../../byterun/caml/../../config/s.h \
|
||||||
|
|
|
@ -27,6 +27,6 @@ include ../Makefile
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
$(CC) -MM $(CFLAGS) *.c | sed -e 's, /[^ ]*\.h,,g' > .depend
|
$(CC) -MM $(CFLAGS) *.c | sed -e 's, /[^ ]*\.h,,g' > .depend
|
||||||
../../boot/ocamlrun ../../tools/ocamldep *.mli *.ml >> .depend
|
$(CAMLRUN) ../../tools/ocamldep *.mli *.ml >> .depend
|
||||||
|
|
||||||
include .depend
|
include .depend
|
||||||
|
|
|
@ -32,6 +32,6 @@ bng.$(O): bng.h bng_digit.c \
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
$(CC) -MM $(CFLAGS) *.c > .depend
|
$(CC) -MM $(CFLAGS) *.c > .depend
|
||||||
../../boot/ocamlrun ../../tools/ocamldep *.mli *.ml >> .depend
|
$(CAMLRUN) ../../tools/ocamldep *.mli *.ml >> .depend
|
||||||
|
|
||||||
include .depend
|
include .depend
|
||||||
|
|
|
@ -318,6 +318,12 @@ let digits = "0123456789ABCDEF"
|
||||||
A la fin de la boucle i-1 est la plus grande puissance de la base qui tient
|
A la fin de la boucle i-1 est la plus grande puissance de la base qui tient
|
||||||
sur un seul digit et j est la plus grande puissance de la base qui tient
|
sur un seul digit et j est la plus grande puissance de la base qui tient
|
||||||
sur un int.
|
sur un int.
|
||||||
|
|
||||||
|
This function returns [(pmax, pint)] where:
|
||||||
|
[pmax] is the index of the digit of [power_base] that contains the
|
||||||
|
the maximum power of [base] that fits in a digit. This is also one
|
||||||
|
less than the exponent of that power.
|
||||||
|
[pint] is the exponent of the maximum power of [base] that fits in an [int].
|
||||||
*)
|
*)
|
||||||
let make_power_base base power_base =
|
let make_power_base base power_base =
|
||||||
let i = ref 0
|
let i = ref 0
|
||||||
|
@ -329,7 +335,7 @@ let make_power_base base power_base =
|
||||||
power_base (pred !i) 1
|
power_base (pred !i) 1
|
||||||
power_base 0)
|
power_base 0)
|
||||||
done;
|
done;
|
||||||
while !j <= !i && is_digit_int power_base !j do incr j done;
|
while !j < !i - 1 && is_digit_int power_base !j do incr j done;
|
||||||
(!i - 2, !j)
|
(!i - 2, !j)
|
||||||
|
|
||||||
(*
|
(*
|
||||||
|
|
|
@ -160,57 +160,71 @@ let floor_num = function
|
||||||
| Big_int bi as n -> n
|
| Big_int bi as n -> n
|
||||||
| Ratio r -> num_of_big_int (floor_ratio r)
|
| Ratio r -> num_of_big_int (floor_ratio r)
|
||||||
|
|
||||||
(* The function [quo_num] is equivalent to
|
(* Coercion with ratio type *)
|
||||||
|
let ratio_of_num = function
|
||||||
|
Int i -> ratio_of_int i
|
||||||
|
| Big_int bi -> ratio_of_big_int bi
|
||||||
|
| Ratio r -> r
|
||||||
|
;;
|
||||||
|
|
||||||
let quo_num x y = floor_num (div_num x y);;
|
(* Euclidean division and remainder. The specification is:
|
||||||
|
|
||||||
|
a = b * quo_num a b + mod_num a b
|
||||||
|
quo_num a b is an integer (Z)
|
||||||
|
0 <= mod_num a b < |b|
|
||||||
|
|
||||||
|
A correct but slow implementation is:
|
||||||
|
|
||||||
|
quo_num a b =
|
||||||
|
if b >= 0 then floor_num (div_num a b)
|
||||||
|
else minus_num (floor_num (div_num a (minus_num b)))
|
||||||
|
|
||||||
|
mod_num a b =
|
||||||
|
sub_num a (mult_num b (quo_num a b))
|
||||||
|
|
||||||
However, this definition is vastly inefficient (cf PR #3473):
|
However, this definition is vastly inefficient (cf PR #3473):
|
||||||
we define here a better way of computing the same thing.
|
we define here a better way of computing the same thing.
|
||||||
*)
|
|
||||||
|
PR#6753: the previous implementation was based on
|
||||||
|
quo_num a b = floor_num (div_num a b)
|
||||||
|
which is incorrect for negative b.
|
||||||
|
*)
|
||||||
|
|
||||||
let quo_num n1 n2 =
|
let quo_num n1 n2 =
|
||||||
match n1 with
|
match n1, n2 with
|
||||||
| Int i1 ->
|
| Int i1, Int i2 ->
|
||||||
begin match n2 with
|
let q = i1 / i2 and r = i1 mod i2 in
|
||||||
| Int i2 -> Int (i1 / i2)
|
Int (if r >= 0 then q else if i2 > 0 then q - 1 else q + 1)
|
||||||
| Big_int bi2 -> num_of_big_int (div_big_int (big_int_of_int i1) bi2)
|
| Int i1, Big_int bi2 ->
|
||||||
| Ratio r2 -> num_of_big_int (floor_ratio (div_int_ratio i1 r2)) end
|
num_of_big_int (div_big_int (big_int_of_int i1) bi2)
|
||||||
|
| Int i1, Ratio r2 ->
|
||||||
|
num_of_big_int (report_sign_ratio r2
|
||||||
|
(floor_ratio (div_int_ratio i1 (abs_ratio r2))))
|
||||||
|
| Big_int bi1, Int i2 ->
|
||||||
|
num_of_big_int (div_big_int bi1 (big_int_of_int i2))
|
||||||
|
| Big_int bi1, Big_int bi2 ->
|
||||||
|
num_of_big_int (div_big_int bi1 bi2)
|
||||||
|
| Big_int bi1, Ratio r2 ->
|
||||||
|
num_of_big_int (report_sign_ratio r2
|
||||||
|
(floor_ratio (div_big_int_ratio bi1 (abs_ratio r2))))
|
||||||
|
| Ratio r1, _ ->
|
||||||
|
let r2 = ratio_of_num n2 in
|
||||||
|
num_of_big_int (report_sign_ratio r2
|
||||||
|
(floor_ratio (div_ratio r1 (abs_ratio r2))))
|
||||||
|
|
||||||
| Big_int bi1 ->
|
|
||||||
begin match n2 with
|
|
||||||
| Int i2 -> num_of_big_int (div_big_int bi1 (big_int_of_int i2))
|
|
||||||
| Big_int bi2 -> num_of_big_int (div_big_int bi1 bi2)
|
|
||||||
| Ratio r2 -> num_of_big_int (floor_ratio (div_big_int_ratio bi1 r2)) end
|
|
||||||
|
|
||||||
| Ratio r1 ->
|
|
||||||
begin match n2 with
|
|
||||||
| Int i2 -> num_of_big_int (floor_ratio (div_ratio_int r1 i2))
|
|
||||||
| Big_int bi2 -> num_of_big_int (floor_ratio (div_ratio_big_int r1 bi2))
|
|
||||||
| Ratio r2 -> num_of_big_int (floor_ratio (div_ratio r1 r2)) end
|
|
||||||
;;
|
|
||||||
|
|
||||||
(* The function [mod_num] is equivalent to:
|
|
||||||
|
|
||||||
let mod_num x y = sub_num x (mult_num y (quo_num x y));;
|
|
||||||
|
|
||||||
However, as for [quo_num] above, this definition is inefficient:
|
|
||||||
we define here a better way of computing the same thing.
|
|
||||||
*)
|
|
||||||
let mod_num n1 n2 =
|
let mod_num n1 n2 =
|
||||||
match n1 with
|
match n1, n2 with
|
||||||
| Int i1 ->
|
| Int i1, Int i2 ->
|
||||||
begin match n2 with
|
let r = i1 mod i2 in
|
||||||
| Int i2 -> Int (i1 mod i2)
|
Int (if r >= 0 then r else if i2 > 0 then r + i2 else r - i2)
|
||||||
| Big_int bi2 -> num_of_big_int (mod_big_int (big_int_of_int i1) bi2)
|
| Int i1, Big_int bi2 ->
|
||||||
| Ratio _r2 -> sub_num n1 (mult_num n2 (quo_num n1 n2)) end
|
num_of_big_int (mod_big_int (big_int_of_int i1) bi2)
|
||||||
|
| Big_int bi1, Int i2 ->
|
||||||
| Big_int bi1 ->
|
num_of_big_int (mod_big_int bi1 (big_int_of_int i2))
|
||||||
begin match n2 with
|
| Big_int bi1, Big_int bi2 ->
|
||||||
| Int i2 -> num_of_big_int (mod_big_int bi1 (big_int_of_int i2))
|
num_of_big_int (mod_big_int bi1 bi2)
|
||||||
| Big_int bi2 -> num_of_big_int (mod_big_int bi1 bi2)
|
| _, _ ->
|
||||||
| Ratio _r2 -> sub_num n1 (mult_num n2 (quo_num n1 n2)) end
|
sub_num n1 (mult_num n2 (quo_num n1 n2))
|
||||||
|
|
||||||
| Ratio _r1 -> sub_num n1 (mult_num n2 (quo_num n1 n2))
|
|
||||||
;;
|
|
||||||
|
|
||||||
let power_num_int a b = match (a,b) with
|
let power_num_int a b = match (a,b) with
|
||||||
((Int i), n) ->
|
((Int i), n) ->
|
||||||
|
@ -368,13 +382,6 @@ let big_int_of_num = function
|
||||||
| Big_int bi -> bi
|
| Big_int bi -> bi
|
||||||
| Ratio r -> big_int_of_ratio r
|
| Ratio r -> big_int_of_ratio r
|
||||||
|
|
||||||
(* Coercion with ratio type *)
|
|
||||||
let ratio_of_num = function
|
|
||||||
Int i -> ratio_of_int i
|
|
||||||
| Big_int bi -> ratio_of_big_int bi
|
|
||||||
| Ratio r -> r
|
|
||||||
;;
|
|
||||||
|
|
||||||
let string_of_big_int_for_num bi =
|
let string_of_big_int_for_num bi =
|
||||||
if !approx_printing_flag
|
if !approx_printing_flag
|
||||||
then approx_big_int !floating_precision bi
|
then approx_big_int !floating_precision bi
|
||||||
|
|
|
@ -28,6 +28,6 @@ str.cmx: str.cmi
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
$(CC) -MM $(CFLAGS) *.c > .depend
|
$(CC) -MM $(CFLAGS) *.c > .depend
|
||||||
../../boot/ocamlrun ../../tools/ocamldep *.mli *.ml >> .depend
|
$(CAMLRUN) ../../tools/ocamldep *.mli *.ml >> .depend
|
||||||
|
|
||||||
include .depend
|
include .depend
|
||||||
|
|
|
@ -12,13 +12,15 @@
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
include ../../config/Makefile
|
include ../../config/Makefile
|
||||||
|
CAMLRUN ?= ../../boot/ocamlrun
|
||||||
|
CAMLYACC ?= ../../boot/ocamlyacc
|
||||||
|
|
||||||
ROOTDIR=../..
|
ROOTDIR=../..
|
||||||
CAMLC=$(ROOTDIR)/boot/ocamlrun $(ROOTDIR)/ocamlc -nostdlib \
|
CAMLC=$(CAMLRUN) $(ROOTDIR)/ocamlc -nostdlib \
|
||||||
-I $(ROOTDIR)/stdlib -I $(ROOTDIR)/otherlibs/unix
|
-I $(ROOTDIR)/stdlib -I $(ROOTDIR)/otherlibs/unix
|
||||||
CAMLOPT=$(ROOTDIR)/boot/ocamlrun $(ROOTDIR)/ocamlopt -nostdlib \
|
CAMLOPT=$(CAMLRUN) $(ROOTDIR)/ocamlopt -nostdlib \
|
||||||
-I $(ROOTDIR)/stdlib -I $(ROOTDIR)/otherlibs/unix
|
-I $(ROOTDIR)/stdlib -I $(ROOTDIR)/otherlibs/unix
|
||||||
MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
|
MKLIB=$(CAMLRUN) ../../tools/ocamlmklib
|
||||||
COMPFLAGS=-w +33..39 -warn-error A -g -bin-annot -safe-string
|
COMPFLAGS=-w +33..39 -warn-error A -g -bin-annot -safe-string
|
||||||
|
|
||||||
BYTECODE_C_OBJS=st_stubs_b.o
|
BYTECODE_C_OBJS=st_stubs_b.o
|
||||||
|
@ -34,7 +36,7 @@ libthreads.a: $(BYTECODE_C_OBJS)
|
||||||
$(MKLIB) -o threads $(BYTECODE_C_OBJS) $(PTHREAD_LINK)
|
$(MKLIB) -o threads $(BYTECODE_C_OBJS) $(PTHREAD_LINK)
|
||||||
|
|
||||||
st_stubs_b.o: st_stubs.c st_posix.h
|
st_stubs_b.o: st_stubs.c st_posix.h
|
||||||
$(BYTECC) -O -I../../byterun $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) \
|
$(BYTECC) -I../../byterun $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) \
|
||||||
-c st_stubs.c
|
-c st_stubs.c
|
||||||
mv st_stubs.o st_stubs_b.o
|
mv st_stubs.o st_stubs_b.o
|
||||||
|
|
||||||
|
@ -44,7 +46,7 @@ libthreadsnat.a: $(NATIVECODE_C_OBJS)
|
||||||
$(AR) rc libthreadsnat.a $(NATIVECODE_C_OBJS)
|
$(AR) rc libthreadsnat.a $(NATIVECODE_C_OBJS)
|
||||||
|
|
||||||
st_stubs_n.o: st_stubs.c st_posix.h
|
st_stubs_n.o: st_stubs.c st_posix.h
|
||||||
$(NATIVECC) -O -I../../asmrun -I../../byterun $(NATIVECCCOMPOPTS) \
|
$(NATIVECC) -I../../asmrun -I../../byterun $(NATIVECCCOMPOPTS) \
|
||||||
$(SHAREDCCCOMPOPTS) -DNATIVE_CODE -DTARGET_$(ARCH) \
|
$(SHAREDCCCOMPOPTS) -DNATIVE_CODE -DTARGET_$(ARCH) \
|
||||||
-DSYS_$(SYSTEM) -c st_stubs.c
|
-DSYS_$(SYSTEM) -c st_stubs.c
|
||||||
mv st_stubs.o st_stubs_n.o
|
mv st_stubs.o st_stubs_n.o
|
||||||
|
@ -107,6 +109,6 @@ installopt:
|
||||||
|
|
||||||
depend: $(GENFILES)
|
depend: $(GENFILES)
|
||||||
-$(CC) -MM -I../../byterun *.c > .depend
|
-$(CC) -MM -I../../byterun *.c > .depend
|
||||||
../../boot/ocamlrun ../../tools/ocamldep *.mli *.ml >> .depend
|
$(CAMLRUN) ../../tools/ocamldep *.mli *.ml >> .depend
|
||||||
|
|
||||||
include .depend
|
include .depend
|
||||||
|
|
|
@ -12,12 +12,14 @@
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
include ../../config/Makefile
|
include ../../config/Makefile
|
||||||
|
CAMLRUN ?= ../../boot/ocamlrun
|
||||||
|
CAMLYACC ?= ../../boot/ocamlyacc
|
||||||
|
|
||||||
# Compilation options
|
# Compilation options
|
||||||
CAMLC=../../boot/ocamlrun ../../ocamlc -I ../../stdlib -I ../win32unix
|
CAMLC=$(CAMLRUN) ../../ocamlc -I ../../stdlib -I ../win32unix
|
||||||
CAMLOPT=../../boot/ocamlrun ../../ocamlopt -I ../../stdlib -I ../win32unix
|
CAMLOPT=$(CAMLRUN) ../../ocamlopt -I ../../stdlib -I ../win32unix
|
||||||
COMPFLAGS=-w +33 -warn-error A -g
|
COMPFLAGS=-w +33 -warn-error A -g
|
||||||
MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
|
MKLIB=$(CAMLRUN) ../../tools/ocamlmklib
|
||||||
CFLAGS=-I../../byterun $(EXTRACFLAGS)
|
CFLAGS=-I../../byterun $(EXTRACFLAGS)
|
||||||
|
|
||||||
CAMLOBJS=thread.cmo mutex.cmo condition.cmo event.cmo threadUnix.cmo
|
CAMLOBJS=thread.cmo mutex.cmo condition.cmo event.cmo threadUnix.cmo
|
||||||
|
@ -32,7 +34,7 @@ all: lib$(LIBNAME).$(A) $(LIBNAME).cma $(CMIFILES)
|
||||||
allopt: lib$(LIBNAME).$(A) $(LIBNAME).cmxa $(LIBNAME).cmxs $(CMIFILES)
|
allopt: lib$(LIBNAME).$(A) $(LIBNAME).cmxa $(LIBNAME).cmxs $(CMIFILES)
|
||||||
|
|
||||||
$(LIBNAME).cma: $(CAMLOBJS)
|
$(LIBNAME).cma: $(CAMLOBJS)
|
||||||
$(MKLIB) -o $(LIBNAME) -ocamlc "../../boot/ocamlrun ../../ocamlc" \
|
$(MKLIB) -o $(LIBNAME) -ocamlc "$(CAMLRUN) ../../ocamlc" \
|
||||||
-linkall $(CAMLOBJS) $(LINKOPTS)
|
-linkall $(CAMLOBJS) $(LINKOPTS)
|
||||||
|
|
||||||
lib$(LIBNAME).$(A): $(COBJS)
|
lib$(LIBNAME).$(A): $(COBJS)
|
||||||
|
@ -46,7 +48,7 @@ st_stubs_b.$(O): st_stubs.c st_win32.h
|
||||||
|
|
||||||
$(LIBNAME).cmxa: $(CAMLOBJS:.cmo=.cmx)
|
$(LIBNAME).cmxa: $(CAMLOBJS:.cmo=.cmx)
|
||||||
$(MKLIB) -o $(LIBNAME)nat \
|
$(MKLIB) -o $(LIBNAME)nat \
|
||||||
-ocamlopt "../../boot/ocamlrun ../../ocamlopt" -linkall \
|
-ocamlopt "$(CAMLRUN) ../../ocamlopt" -linkall \
|
||||||
$(CAMLOBJS:.cmo=.cmx) $(LINKOPTS)
|
$(CAMLOBJS:.cmo=.cmx) $(LINKOPTS)
|
||||||
mv $(LIBNAME)nat.cmxa $(LIBNAME).cmxa
|
mv $(LIBNAME)nat.cmxa $(LIBNAME).cmxa
|
||||||
mv $(LIBNAME)nat.$(A) $(LIBNAME).$(A)
|
mv $(LIBNAME)nat.$(A) $(LIBNAME).$(A)
|
||||||
|
|
|
@ -8,18 +8,16 @@ scheduler.o: scheduler.c ../../byterun/caml/alloc.h \
|
||||||
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
../../byterun/caml/memory.h ../../byterun/caml/gc.h \
|
||||||
../../byterun/caml/major_gc.h ../../byterun/caml/freelist.h \
|
../../byterun/caml/major_gc.h ../../byterun/caml/freelist.h \
|
||||||
../../byterun/caml/minor_gc.h ../../byterun/caml/misc.h \
|
../../byterun/caml/minor_gc.h ../../byterun/caml/misc.h \
|
||||||
|
../../byterun/caml/address_class.h \
|
||||||
../../byterun/caml/mlvalues.h ../../byterun/caml/printexc.h \
|
../../byterun/caml/mlvalues.h ../../byterun/caml/printexc.h \
|
||||||
../../byterun/caml/roots.h ../../byterun/caml/memory.h \
|
../../byterun/caml/roots.h ../../byterun/caml/memory.h \
|
||||||
../../byterun/caml/signals.h ../../byterun/caml/stacks.h \
|
../../byterun/caml/signals.h ../../byterun/caml/stacks.h \
|
||||||
../../byterun/caml/sys.h
|
../../byterun/caml/sys.h
|
||||||
condition.cmi : mutex.cmi
|
condition.cmi : mutex.cmi
|
||||||
event.cmi :
|
event.cmi :
|
||||||
marshal.cmi :
|
|
||||||
mutex.cmi :
|
mutex.cmi :
|
||||||
pervasives.cmi :
|
thread.cmi : unix.cmo
|
||||||
thread.cmi : unix.cmi
|
threadUnix.cmi : unix.cmo
|
||||||
threadUnix.cmi : unix.cmi
|
|
||||||
unix.cmi :
|
|
||||||
condition.cmo : thread.cmi mutex.cmi condition.cmi
|
condition.cmo : thread.cmi mutex.cmi condition.cmi
|
||||||
condition.cmx : thread.cmx mutex.cmx condition.cmi
|
condition.cmx : thread.cmx mutex.cmx condition.cmi
|
||||||
event.cmo : mutex.cmi condition.cmi event.cmi
|
event.cmo : mutex.cmi condition.cmi event.cmi
|
||||||
|
@ -28,11 +26,11 @@ marshal.cmo :
|
||||||
marshal.cmx :
|
marshal.cmx :
|
||||||
mutex.cmo : thread.cmi mutex.cmi
|
mutex.cmo : thread.cmi mutex.cmi
|
||||||
mutex.cmx : thread.cmx mutex.cmi
|
mutex.cmx : thread.cmx mutex.cmi
|
||||||
pervasives.cmo : unix.cmi pervasives.cmi
|
pervasives.cmo : unix.cmo
|
||||||
pervasives.cmx : unix.cmx pervasives.cmi
|
pervasives.cmx : unix.cmx
|
||||||
thread.cmo : unix.cmi thread.cmi
|
thread.cmo : unix.cmo thread.cmi
|
||||||
thread.cmx : unix.cmx thread.cmi
|
thread.cmx : unix.cmx thread.cmi
|
||||||
threadUnix.cmo : unix.cmi thread.cmi threadUnix.cmi
|
threadUnix.cmo : unix.cmo thread.cmi threadUnix.cmi
|
||||||
threadUnix.cmx : unix.cmx thread.cmx threadUnix.cmi
|
threadUnix.cmx : unix.cmx thread.cmx threadUnix.cmi
|
||||||
unix.cmo : unix.cmi
|
unix.cmo :
|
||||||
unix.cmx : unix.cmi
|
unix.cmx :
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue