Created
June 20, 2014 13:06
-
-
Save emillon/6f1a866fd44c046e066f to your computer and use it in GitHub Desktop.
zamcov 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary files ocaml-3.12.0/.DS_Store and ocaml-diff/.DS_Store differ | |
diff -urN ocaml-3.12.0/.depend ocaml-diff/.depend | |
--- ocaml-3.12.0/.depend 2010-07-23 17:30:37.000000000 +0200 | |
+++ ocaml-diff/.depend 2012-03-14 14:42:30.000000000 +0100 | |
@@ -291,12 +291,17 @@ | |
bytecomp/bytepackager.cmi: typing/ident.cmi | |
bytecomp/bytesections.cmi: | |
bytecomp/cmo_format.cmi: bytecomp/lambda.cmi typing/ident.cmi | |
+bytecomp/covevent.cmi: typing/types.cmi parsing/location.cmi | |
+bytecomp/covutils.cmi: typing/typedtree.cmi typing/primitive.cmi \ | |
+ bytecomp/lambda.cmi bytecomp/instruct.cmi bytecomp/covevent.cmi \ | |
+ bytecomp/cmo_format.cmi | |
bytecomp/dll.cmi: | |
bytecomp/emitcode.cmi: bytecomp/instruct.cmi bytecomp/cmo_format.cmi | |
bytecomp/instruct.cmi: typing/types.cmi typing/subst.cmi parsing/location.cmi \ | |
- bytecomp/lambda.cmi typing/ident.cmi typing/env.cmi | |
+ bytecomp/lambda.cmi typing/ident.cmi typing/env.cmi bytecomp/covevent.cmi | |
bytecomp/lambda.cmi: typing/types.cmi typing/primitive.cmi typing/path.cmi \ | |
- parsing/location.cmi typing/ident.cmi typing/env.cmi parsing/asttypes.cmi | |
+ parsing/location.cmi typing/ident.cmi typing/env.cmi \ | |
+ bytecomp/covevent.cmi parsing/asttypes.cmi | |
bytecomp/matching.cmi: typing/typedtree.cmi parsing/location.cmi \ | |
bytecomp/lambda.cmi typing/ident.cmi parsing/asttypes.cmi | |
bytecomp/meta.cmi: | |
@@ -318,12 +323,14 @@ | |
bytecomp/lambda.cmi | |
bytecomp/bytegen.cmo: typing/types.cmi bytecomp/switch.cmi typing/subst.cmi \ | |
typing/stypes.cmi typing/primitive.cmi utils/misc.cmi bytecomp/lambda.cmi \ | |
- bytecomp/instruct.cmi typing/ident.cmi utils/config.cmi \ | |
- parsing/asttypes.cmi typing/annot.cmi bytecomp/bytegen.cmi | |
+ bytecomp/instruct.cmi typing/ident.cmi bytecomp/covutils.cmi \ | |
+ utils/config.cmi parsing/asttypes.cmi typing/annot.cmi \ | |
+ bytecomp/bytegen.cmi | |
bytecomp/bytegen.cmx: typing/types.cmx bytecomp/switch.cmx typing/subst.cmx \ | |
typing/stypes.cmx typing/primitive.cmx utils/misc.cmx bytecomp/lambda.cmx \ | |
- bytecomp/instruct.cmx typing/ident.cmx utils/config.cmx \ | |
- parsing/asttypes.cmi typing/annot.cmi bytecomp/bytegen.cmi | |
+ bytecomp/instruct.cmx typing/ident.cmx bytecomp/covutils.cmx \ | |
+ utils/config.cmx parsing/asttypes.cmi typing/annot.cmi \ | |
+ bytecomp/bytegen.cmi | |
bytecomp/bytelibrarian.cmo: utils/misc.cmi utils/config.cmi \ | |
bytecomp/cmo_format.cmi utils/clflags.cmi bytecomp/bytelink.cmi \ | |
bytecomp/bytelibrarian.cmi | |
@@ -332,14 +339,14 @@ | |
bytecomp/bytelibrarian.cmi | |
bytecomp/bytelink.cmo: bytecomp/symtable.cmi bytecomp/opcodes.cmo \ | |
utils/misc.cmi bytecomp/instruct.cmi typing/ident.cmi bytecomp/dll.cmi \ | |
- utils/consistbl.cmi utils/config.cmi bytecomp/cmo_format.cmi \ | |
- utils/clflags.cmi utils/ccomp.cmi bytecomp/bytesections.cmi \ | |
- bytecomp/bytelink.cmi | |
+ bytecomp/covutils.cmi utils/consistbl.cmi utils/config.cmi \ | |
+ bytecomp/cmo_format.cmi utils/clflags.cmi utils/ccomp.cmi \ | |
+ bytecomp/bytesections.cmi bytecomp/bytelink.cmi | |
bytecomp/bytelink.cmx: bytecomp/symtable.cmx bytecomp/opcodes.cmx \ | |
utils/misc.cmx bytecomp/instruct.cmx typing/ident.cmx bytecomp/dll.cmx \ | |
- utils/consistbl.cmx utils/config.cmx bytecomp/cmo_format.cmi \ | |
- utils/clflags.cmx utils/ccomp.cmx bytecomp/bytesections.cmx \ | |
- bytecomp/bytelink.cmi | |
+ bytecomp/covutils.cmx utils/consistbl.cmx utils/config.cmx \ | |
+ bytecomp/cmo_format.cmi utils/clflags.cmx utils/ccomp.cmx \ | |
+ bytecomp/bytesections.cmx bytecomp/bytelink.cmi | |
bytecomp/bytepackager.cmo: typing/typemod.cmi bytecomp/translmod.cmi \ | |
typing/subst.cmi typing/path.cmi utils/misc.cmi bytecomp/instruct.cmi \ | |
typing/ident.cmi typing/env.cmi bytecomp/emitcode.cmi utils/config.cmi \ | |
@@ -352,28 +359,42 @@ | |
bytecomp/bytegen.cmx bytecomp/bytepackager.cmi | |
bytecomp/bytesections.cmo: utils/config.cmi bytecomp/bytesections.cmi | |
bytecomp/bytesections.cmx: utils/config.cmx bytecomp/bytesections.cmi | |
+bytecomp/covutils.cmo: typing/types.cmi bytecomp/typeopt.cmi \ | |
+ typing/typedtree.cmi typing/primitive.cmi typing/predef.cmi \ | |
+ typing/path.cmi utils/misc.cmi parsing/location.cmi bytecomp/lambda.cmi \ | |
+ bytecomp/instruct.cmi typing/ident.cmi bytecomp/covevent.cmi \ | |
+ bytecomp/cmo_format.cmi parsing/asttypes.cmi bytecomp/covutils.cmi | |
+bytecomp/covutils.cmx: typing/types.cmx bytecomp/typeopt.cmx \ | |
+ typing/typedtree.cmx typing/primitive.cmx typing/predef.cmx \ | |
+ typing/path.cmx utils/misc.cmx parsing/location.cmx bytecomp/lambda.cmx \ | |
+ bytecomp/instruct.cmx typing/ident.cmx bytecomp/covevent.cmi \ | |
+ bytecomp/cmo_format.cmi parsing/asttypes.cmi bytecomp/covutils.cmi | |
bytecomp/dll.cmo: utils/misc.cmi utils/config.cmi bytecomp/dll.cmi | |
bytecomp/dll.cmx: utils/misc.cmx utils/config.cmx bytecomp/dll.cmi | |
bytecomp/emitcode.cmo: bytecomp/translmod.cmi typing/primitive.cmi \ | |
bytecomp/opcodes.cmo utils/misc.cmi bytecomp/meta.cmi bytecomp/lambda.cmi \ | |
- bytecomp/instruct.cmi typing/env.cmi utils/config.cmi \ | |
- bytecomp/cmo_format.cmi utils/clflags.cmi typing/btype.cmi \ | |
- parsing/asttypes.cmi bytecomp/emitcode.cmi | |
+ bytecomp/instruct.cmi typing/env.cmi bytecomp/covutils.cmi \ | |
+ bytecomp/covevent.cmi utils/config.cmi bytecomp/cmo_format.cmi \ | |
+ utils/clflags.cmi typing/btype.cmi parsing/asttypes.cmi \ | |
+ bytecomp/emitcode.cmi | |
bytecomp/emitcode.cmx: bytecomp/translmod.cmx typing/primitive.cmx \ | |
bytecomp/opcodes.cmx utils/misc.cmx bytecomp/meta.cmx bytecomp/lambda.cmx \ | |
- bytecomp/instruct.cmx typing/env.cmx utils/config.cmx \ | |
- bytecomp/cmo_format.cmi utils/clflags.cmx typing/btype.cmx \ | |
- parsing/asttypes.cmi bytecomp/emitcode.cmi | |
+ bytecomp/instruct.cmx typing/env.cmx bytecomp/covutils.cmx \ | |
+ bytecomp/covevent.cmi utils/config.cmx bytecomp/cmo_format.cmi \ | |
+ utils/clflags.cmx typing/btype.cmx parsing/asttypes.cmi \ | |
+ bytecomp/emitcode.cmi | |
bytecomp/instruct.cmo: typing/types.cmi typing/subst.cmi parsing/location.cmi \ | |
- bytecomp/lambda.cmi typing/ident.cmi typing/env.cmi bytecomp/instruct.cmi | |
+ bytecomp/lambda.cmi typing/ident.cmi typing/env.cmi bytecomp/covevent.cmi \ | |
+ bytecomp/instruct.cmi | |
bytecomp/instruct.cmx: typing/types.cmx typing/subst.cmx parsing/location.cmx \ | |
- bytecomp/lambda.cmx typing/ident.cmx typing/env.cmx bytecomp/instruct.cmi | |
+ bytecomp/lambda.cmx typing/ident.cmx typing/env.cmx bytecomp/covevent.cmi \ | |
+ bytecomp/instruct.cmi | |
bytecomp/lambda.cmo: typing/types.cmi typing/primitive.cmi typing/path.cmi \ | |
utils/misc.cmi parsing/location.cmi typing/ident.cmi typing/env.cmi \ | |
- parsing/asttypes.cmi bytecomp/lambda.cmi | |
+ bytecomp/covevent.cmi parsing/asttypes.cmi bytecomp/lambda.cmi | |
bytecomp/lambda.cmx: typing/types.cmx typing/primitive.cmx typing/path.cmx \ | |
utils/misc.cmx parsing/location.cmx typing/ident.cmx typing/env.cmx \ | |
- parsing/asttypes.cmi bytecomp/lambda.cmi | |
+ bytecomp/covevent.cmi parsing/asttypes.cmi bytecomp/lambda.cmi | |
bytecomp/matching.cmo: typing/types.cmi bytecomp/typeopt.cmi \ | |
typing/typedtree.cmi bytecomp/switch.cmi bytecomp/printlambda.cmi \ | |
typing/primitive.cmi typing/predef.cmi typing/path.cmi \ | |
@@ -394,16 +415,16 @@ | |
bytecomp/opcodes.cmx: | |
bytecomp/printinstr.cmo: bytecomp/printlambda.cmi parsing/location.cmi \ | |
bytecomp/lambda.cmi bytecomp/instruct.cmi typing/ident.cmi \ | |
- bytecomp/printinstr.cmi | |
+ bytecomp/covutils.cmi bytecomp/printinstr.cmi | |
bytecomp/printinstr.cmx: bytecomp/printlambda.cmx parsing/location.cmx \ | |
bytecomp/lambda.cmx bytecomp/instruct.cmx typing/ident.cmx \ | |
- bytecomp/printinstr.cmi | |
+ bytecomp/covutils.cmx bytecomp/printinstr.cmi | |
bytecomp/printlambda.cmo: typing/types.cmi typing/primitive.cmi \ | |
parsing/location.cmi bytecomp/lambda.cmi typing/ident.cmi \ | |
- parsing/asttypes.cmi bytecomp/printlambda.cmi | |
+ bytecomp/covutils.cmi parsing/asttypes.cmi bytecomp/printlambda.cmi | |
bytecomp/printlambda.cmx: typing/types.cmx typing/primitive.cmx \ | |
parsing/location.cmx bytecomp/lambda.cmx typing/ident.cmx \ | |
- parsing/asttypes.cmi bytecomp/printlambda.cmi | |
+ bytecomp/covutils.cmx parsing/asttypes.cmi bytecomp/printlambda.cmi | |
bytecomp/runtimedef.cmo: bytecomp/runtimedef.cmi | |
bytecomp/runtimedef.cmx: bytecomp/runtimedef.cmi | |
bytecomp/simplif.cmo: bytecomp/lambda.cmi typing/ident.cmi utils/clflags.cmi \ | |
@@ -436,14 +457,16 @@ | |
typing/typedtree.cmi bytecomp/translobj.cmi typing/primitive.cmi \ | |
typing/predef.cmi typing/path.cmi typing/parmatch.cmi utils/misc.cmi \ | |
bytecomp/matching.cmi parsing/location.cmi bytecomp/lambda.cmi \ | |
- typing/ident.cmi typing/env.cmi utils/config.cmi utils/clflags.cmi \ | |
- typing/btype.cmi parsing/asttypes.cmi bytecomp/translcore.cmi | |
+ typing/ident.cmi typing/env.cmi bytecomp/covutils.cmi \ | |
+ bytecomp/covevent.cmi utils/config.cmi utils/clflags.cmi typing/btype.cmi \ | |
+ parsing/asttypes.cmi bytecomp/translcore.cmi | |
bytecomp/translcore.cmx: typing/types.cmx bytecomp/typeopt.cmx \ | |
typing/typedtree.cmx bytecomp/translobj.cmx typing/primitive.cmx \ | |
typing/predef.cmx typing/path.cmx typing/parmatch.cmx utils/misc.cmx \ | |
bytecomp/matching.cmx parsing/location.cmx bytecomp/lambda.cmx \ | |
- typing/ident.cmx typing/env.cmx utils/config.cmx utils/clflags.cmx \ | |
- typing/btype.cmx parsing/asttypes.cmi bytecomp/translcore.cmi | |
+ typing/ident.cmx typing/env.cmx bytecomp/covutils.cmx \ | |
+ bytecomp/covevent.cmi utils/config.cmx utils/clflags.cmx typing/btype.cmx \ | |
+ parsing/asttypes.cmi bytecomp/translcore.cmi | |
bytecomp/translmod.cmo: typing/types.cmi typing/typedtree.cmi \ | |
bytecomp/translobj.cmi bytecomp/translcore.cmi bytecomp/translclass.cmi \ | |
typing/printtyp.cmi typing/primitive.cmi typing/predef.cmi \ | |
@@ -479,9 +502,9 @@ | |
asmcomp/clambda.cmi: bytecomp/lambda.cmi typing/ident.cmi \ | |
asmcomp/debuginfo.cmi parsing/asttypes.cmi | |
asmcomp/closure.cmi: bytecomp/lambda.cmi asmcomp/clambda.cmi | |
-asmcomp/cmm.cmi: typing/ident.cmi asmcomp/debuginfo.cmi | |
asmcomp/cmmgen.cmi: asmcomp/cmx_format.cmi asmcomp/cmm.cmi \ | |
asmcomp/clambda.cmi | |
+asmcomp/cmm.cmi: typing/ident.cmi asmcomp/debuginfo.cmi | |
asmcomp/cmx_format.cmi: asmcomp/clambda.cmi | |
asmcomp/codegen.cmi: asmcomp/cmm.cmi | |
asmcomp/coloring.cmi: | |
@@ -489,8 +512,8 @@ | |
asmcomp/compilenv.cmi: typing/ident.cmi asmcomp/cmx_format.cmi \ | |
asmcomp/clambda.cmi | |
asmcomp/debuginfo.cmi: parsing/location.cmi bytecomp/lambda.cmi | |
-asmcomp/emit.cmi: asmcomp/linearize.cmi asmcomp/cmm.cmi | |
asmcomp/emitaux.cmi: asmcomp/debuginfo.cmi | |
+asmcomp/emit.cmi: asmcomp/linearize.cmi asmcomp/cmm.cmi | |
asmcomp/interf.cmi: asmcomp/mach.cmi | |
asmcomp/linearize.cmi: asmcomp/reg.cmi asmcomp/mach.cmi asmcomp/debuginfo.cmi | |
asmcomp/liveness.cmi: asmcomp/mach.cmi | |
@@ -501,8 +524,8 @@ | |
asmcomp/printmach.cmi: asmcomp/reg.cmi asmcomp/mach.cmi | |
asmcomp/proc.cmi: asmcomp/reg.cmi asmcomp/mach.cmi | |
asmcomp/reg.cmi: asmcomp/cmm.cmi | |
-asmcomp/reload.cmi: asmcomp/mach.cmi | |
asmcomp/reloadgen.cmi: asmcomp/reg.cmi asmcomp/mach.cmi | |
+asmcomp/reload.cmi: asmcomp/mach.cmi | |
asmcomp/schedgen.cmi: asmcomp/mach.cmi asmcomp/linearize.cmi | |
asmcomp/scheduling.cmi: asmcomp/linearize.cmi | |
asmcomp/selectgen.cmi: utils/tbl.cmi asmcomp/reg.cmi asmcomp/mach.cmi \ | |
@@ -572,10 +595,6 @@ | |
utils/misc.cmx bytecomp/lambda.cmx typing/ident.cmx asmcomp/debuginfo.cmx \ | |
asmcomp/compilenv.cmx utils/clflags.cmx asmcomp/clambda.cmx \ | |
parsing/asttypes.cmi asmcomp/closure.cmi | |
-asmcomp/cmm.cmo: typing/ident.cmi asmcomp/debuginfo.cmi asmcomp/arch.cmo \ | |
- asmcomp/cmm.cmi | |
-asmcomp/cmm.cmx: typing/ident.cmx asmcomp/debuginfo.cmx asmcomp/arch.cmx \ | |
- asmcomp/cmm.cmi | |
asmcomp/cmmgen.cmo: typing/types.cmi bytecomp/switch.cmi asmcomp/proc.cmi \ | |
typing/primitive.cmi utils/misc.cmi bytecomp/lambda.cmi typing/ident.cmi \ | |
asmcomp/debuginfo.cmi utils/config.cmi asmcomp/compilenv.cmi \ | |
@@ -588,6 +607,10 @@ | |
asmcomp/cmx_format.cmi asmcomp/cmm.cmx utils/clflags.cmx \ | |
asmcomp/clambda.cmx parsing/asttypes.cmi asmcomp/arch.cmx \ | |
asmcomp/cmmgen.cmi | |
+asmcomp/cmm.cmo: typing/ident.cmi asmcomp/debuginfo.cmi asmcomp/arch.cmo \ | |
+ asmcomp/cmm.cmi | |
+asmcomp/cmm.cmx: typing/ident.cmx asmcomp/debuginfo.cmx asmcomp/arch.cmx \ | |
+ asmcomp/cmm.cmi | |
asmcomp/codegen.cmo: asmcomp/split.cmi asmcomp/spill.cmi asmcomp/reload.cmi \ | |
asmcomp/reg.cmi asmcomp/printmach.cmi asmcomp/printlinear.cmi \ | |
asmcomp/printcmm.cmi asmcomp/liveness.cmi asmcomp/linearize.cmi \ | |
@@ -614,6 +637,12 @@ | |
asmcomp/debuginfo.cmi | |
asmcomp/debuginfo.cmx: parsing/location.cmx bytecomp/lambda.cmx \ | |
asmcomp/debuginfo.cmi | |
+asmcomp/emitaux.cmo: asmcomp/reg.cmi asmcomp/linearize.cmi \ | |
+ asmcomp/debuginfo.cmi asmcomp/cmm.cmi asmcomp/arch.cmo \ | |
+ asmcomp/emitaux.cmi | |
+asmcomp/emitaux.cmx: asmcomp/reg.cmx asmcomp/linearize.cmx \ | |
+ asmcomp/debuginfo.cmx asmcomp/cmm.cmx asmcomp/arch.cmx \ | |
+ asmcomp/emitaux.cmi | |
asmcomp/emit.cmo: asmcomp/reg.cmi asmcomp/proc.cmi utils/misc.cmi \ | |
asmcomp/mach.cmi asmcomp/linearize.cmi asmcomp/emitaux.cmi \ | |
asmcomp/debuginfo.cmi utils/config.cmi asmcomp/compilenv.cmi \ | |
@@ -622,12 +651,6 @@ | |
asmcomp/mach.cmx asmcomp/linearize.cmx asmcomp/emitaux.cmx \ | |
asmcomp/debuginfo.cmx utils/config.cmx asmcomp/compilenv.cmx \ | |
asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx asmcomp/emit.cmi | |
-asmcomp/emitaux.cmo: asmcomp/reg.cmi asmcomp/linearize.cmi \ | |
- asmcomp/debuginfo.cmi asmcomp/cmm.cmi asmcomp/arch.cmo \ | |
- asmcomp/emitaux.cmi | |
-asmcomp/emitaux.cmx: asmcomp/reg.cmx asmcomp/linearize.cmx \ | |
- asmcomp/debuginfo.cmx asmcomp/cmm.cmx asmcomp/arch.cmx \ | |
- asmcomp/emitaux.cmi | |
asmcomp/interf.cmo: asmcomp/reg.cmi asmcomp/proc.cmi utils/misc.cmi \ | |
asmcomp/mach.cmi asmcomp/interf.cmi | |
asmcomp/interf.cmx: asmcomp/reg.cmx asmcomp/proc.cmx utils/misc.cmx \ | |
@@ -668,14 +691,14 @@ | |
asmcomp/proc.cmi | |
asmcomp/reg.cmo: asmcomp/cmm.cmi asmcomp/reg.cmi | |
asmcomp/reg.cmx: asmcomp/cmm.cmx asmcomp/reg.cmi | |
-asmcomp/reload.cmo: asmcomp/reloadgen.cmi asmcomp/reg.cmi asmcomp/mach.cmi \ | |
- asmcomp/cmm.cmi utils/clflags.cmi asmcomp/arch.cmo asmcomp/reload.cmi | |
-asmcomp/reload.cmx: asmcomp/reloadgen.cmx asmcomp/reg.cmx asmcomp/mach.cmx \ | |
- asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx asmcomp/reload.cmi | |
asmcomp/reloadgen.cmo: asmcomp/reg.cmi utils/misc.cmi asmcomp/mach.cmi \ | |
asmcomp/reloadgen.cmi | |
asmcomp/reloadgen.cmx: asmcomp/reg.cmx utils/misc.cmx asmcomp/mach.cmx \ | |
asmcomp/reloadgen.cmi | |
+asmcomp/reload.cmo: asmcomp/reloadgen.cmi asmcomp/reg.cmi asmcomp/mach.cmi \ | |
+ asmcomp/cmm.cmi utils/clflags.cmi asmcomp/arch.cmo asmcomp/reload.cmi | |
+asmcomp/reload.cmx: asmcomp/reloadgen.cmx asmcomp/reg.cmx asmcomp/mach.cmx \ | |
+ asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx asmcomp/reload.cmi | |
asmcomp/schedgen.cmo: asmcomp/reg.cmi utils/misc.cmi asmcomp/mach.cmi \ | |
asmcomp/linearize.cmi asmcomp/cmm.cmi asmcomp/arch.cmo \ | |
asmcomp/schedgen.cmi | |
@@ -706,8 +729,8 @@ | |
asmcomp/split.cmi | |
driver/compile.cmi: typing/env.cmi | |
driver/errors.cmi: | |
-driver/main.cmi: | |
driver/main_args.cmi: | |
+driver/main.cmi: | |
driver/optcompile.cmi: typing/env.cmi | |
driver/opterrors.cmi: | |
driver/optmain.cmi: | |
@@ -740,6 +763,8 @@ | |
parsing/location.cmx parsing/lexer.cmx typing/includemod.cmx \ | |
typing/env.cmx typing/ctype.cmx bytecomp/bytepackager.cmx \ | |
bytecomp/bytelink.cmx bytecomp/bytelibrarian.cmx driver/errors.cmi | |
+driver/main_args.cmo: utils/warnings.cmi driver/main_args.cmi | |
+driver/main_args.cmx: utils/warnings.cmx driver/main_args.cmi | |
driver/main.cmo: utils/warnings.cmi utils/misc.cmi driver/main_args.cmi \ | |
driver/errors.cmi utils/config.cmi driver/compile.cmi utils/clflags.cmi \ | |
bytecomp/bytepackager.cmi bytecomp/bytelink.cmi \ | |
@@ -748,8 +773,6 @@ | |
driver/errors.cmx utils/config.cmx driver/compile.cmx utils/clflags.cmx \ | |
bytecomp/bytepackager.cmx bytecomp/bytelink.cmx \ | |
bytecomp/bytelibrarian.cmx driver/main.cmi | |
-driver/main_args.cmo: utils/warnings.cmi driver/main_args.cmi | |
-driver/main_args.cmx: utils/warnings.cmx driver/main_args.cmi | |
driver/optcompile.cmo: utils/warnings.cmi typing/unused_var.cmi \ | |
typing/typemod.cmi typing/typedtree.cmi bytecomp/translmod.cmi \ | |
typing/stypes.cmi bytecomp/simplif.cmi typing/printtyp.cmi \ | |
diff -urN ocaml-3.12.0/Makefile ocaml-diff/Makefile | |
--- ocaml-3.12.0/Makefile 2010-06-16 03:32:26.000000000 +0200 | |
+++ ocaml-diff/Makefile 2012-03-14 14:42:30.000000000 +0100 | |
@@ -17,15 +17,15 @@ | |
include config/Makefile | |
include stdlib/StdlibModules | |
-CAMLC=boot/ocamlrun boot/ocamlc -nostdlib -I boot | |
+CAMLC=@OCAMLPREFIX@/bin/ocamlc | |
CAMLOPT=boot/ocamlrun ./ocamlopt -nostdlib -I stdlib -I otherlibs/dynlink | |
COMPFLAGS=-strict-sequence -warn-error A $(INCLUDES) | |
LINKFLAGS= | |
-CAMLYACC=boot/ocamlyacc | |
+CAMLYACC=@OCAMLPREFIX@/bin/ocamlyacc | |
YACCFLAGS=-v | |
-CAMLLEX=boot/ocamlrun boot/ocamllex | |
-CAMLDEP=boot/ocamlrun tools/ocamldep | |
+CAMLLEX=@OCAMLPREFIX@/bin/ocamllex | |
+CAMLDEP=@OCAMLPREFIX@/bin/ocamldep | |
DEPFLAGS=$(INCLUDES) | |
CAMLRUN=byterun/ocamlrun | |
SHELL=/bin/sh | |
@@ -57,7 +57,7 @@ | |
typing/typedecl.cmo typing/typeclass.cmo \ | |
typing/typemod.cmo | |
-COMP=bytecomp/lambda.cmo bytecomp/printlambda.cmo \ | |
+COMP=bytecomp/lambda.cmo bytecomp/covutils.cmo bytecomp/printlambda.cmo \ | |
bytecomp/typeopt.cmo bytecomp/switch.cmo bytecomp/matching.cmo \ | |
bytecomp/translobj.cmo bytecomp/translcore.cmo \ | |
bytecomp/translclass.cmo bytecomp/translmod.cmo \ | |
Binary files ocaml-3.12.0/bytecomp/.DS_Store and ocaml-diff/bytecomp/.DS_Store differ | |
diff -urN ocaml-3.12.0/bytecomp/bytegen.ml ocaml-diff/bytecomp/bytegen.ml | |
--- ocaml-3.12.0/bytecomp/bytegen.ml 2009-05-20 13:52:42.000000000 +0200 | |
+++ ocaml-diff/bytecomp/bytegen.ml 2012-03-14 14:42:30.000000000 +0100 | |
@@ -159,6 +159,7 @@ | |
| Lprim (Pduprecord (Record_regular, size), args) -> RHS_block size | |
| Lprim (Pduprecord (Record_float, size), args) -> RHS_floatblock size | |
| Levent (lam, _) -> size_of_lambda lam | |
+ | Lcovevent (lam, _) -> size_of_lambda lam | |
| Lsequence (lam, lam') -> size_of_lambda lam' | |
| _ -> RHS_nonrec | |
@@ -754,6 +755,8 @@ | |
let cont1 = add_event ev cont in | |
comp_expr env lam sz cont1 | |
end | |
+ | Lcovevent (lam, lco) -> | |
+ Covutils.comp_expr comp_expr env lam sz cont !compunit_name lco | |
| Lifused (_, exp) -> | |
comp_expr env exp sz cont | |
diff -urN ocaml-3.12.0/bytecomp/bytelink.ml ocaml-diff/bytecomp/bytelink.ml | |
--- ocaml-3.12.0/bytecomp/bytelink.ml 2010-01-20 17:26:46.000000000 +0100 | |
+++ ocaml-diff/bytecomp/bytelink.ml 2012-03-14 14:42:30.000000000 +0100 | |
@@ -194,6 +194,7 @@ | |
really_input inchan buffer 0 compunit.cu_debugsize; | |
debug_info := (currpos_fun(), buffer) :: !debug_info | |
end; | |
+ Covutils.link_compunit currpos_fun compunit; | |
output_fun code_block; | |
if !Clflags.link_everything then | |
List.iter Symtable.require_primitive compunit.cu_primitives | |
@@ -303,7 +304,9 @@ | |
end; | |
let output_fun = output_string outchan | |
and currpos_fun () = pos_out outchan - start_code in | |
+ Covutils.cov_info_output := open_out "cover.info"; | |
List.iter (link_file output_fun currpos_fun) tolink; | |
+ close_out !Covutils.cov_info_output; | |
if standalone then Dll.close_all_dlls(); | |
(* The final STOP instruction *) | |
output_byte outchan Opcodes.opSTOP; | |
@@ -424,7 +427,9 @@ | |
output_code_string outchan code; | |
currpos := !currpos + String.length code | |
and currpos_fun () = !currpos in | |
+ Covutils.cov_info_output := open_out "cover.info"; | |
List.iter (link_file output_fun currpos_fun) tolink; | |
+ close_out !Covutils.cov_info_output; | |
(* The final STOP instruction *) | |
Printf.fprintf outchan "\n0x%x};\n\n" Opcodes.opSTOP; | |
(* The table of global data *) | |
diff -urN ocaml-3.12.0/bytecomp/covevent.mli ocaml-diff/bytecomp/covevent.mli | |
--- ocaml-3.12.0/bytecomp/covevent.mli 1970-01-01 01:00:00.000000000 +0100 | |
+++ ocaml-diff/bytecomp/covevent.mli 2012-08-29 19:43:16.000000000 +0200 | |
@@ -0,0 +1,28 @@ | |
+(***********************************************************************) | |
+(* Project Couverture *) | |
+(* *) | |
+(* file: covevent.mli *) | |
+(* authors: Adrien Jonquet, Mathias Bourgoin *) | |
+(* licence: CeCILL-B *) | |
+(***********************************************************************) | |
+ | |
+type coverage_event = | |
+ { mutable covev_pos: int; | |
+ covev_module: string; | |
+ covev_loc: Location.t; | |
+ covev_status: coverage_event_status } | |
+ | |
+and coverage_event_status = | |
+ Coverage_event_statement | |
+ | Coverage_event_decision | |
+ | Coverage_event_condition of coverage_event | |
+ (* [coverage_event] refers to the decision the condition belongs to. *) | |
+ | |
+type lambda = | |
+ { lcovev_loc: Location.t; | |
+ lcovev_status: lambda_status } | |
+ | |
+and lambda_status = | |
+ Lcovev_statement | |
+ | Lcovev_decision | |
+ | Lcovev_condition of lambda (* [lambda] refers to the decision the condition belongs to. *) | |
diff -urN ocaml-3.12.0/bytecomp/covutils.ml ocaml-diff/bytecomp/covutils.ml | |
--- ocaml-3.12.0/bytecomp/covutils.ml 1970-01-01 01:00:00.000000000 +0100 | |
+++ ocaml-diff/bytecomp/covutils.ml 2012-09-06 18:05:26.000000000 +0200 | |
@@ -0,0 +1,196 @@ | |
+(***********************************************************************) | |
+(* Project Couverture *) | |
+(* *) | |
+(* file: covutils.ml *) | |
+(* authors: Adrien Jonquet, Mathias Bourgoin, Philippe Wang *) | |
+(* licence: CeCILL-B *) | |
+(***********************************************************************) | |
+ | |
+open Misc | |
+open Asttypes | |
+open Primitive | |
+open Path | |
+open Types | |
+open Typedtree | |
+open Typeopt | |
+open Lambda | |
+(* open Covevent *) | |
+ | |
+let rec is_bool = function | |
+ Tconstr ((Pident i) as path, _, _) -> path = Predef.path_bool | |
+ | Tconstr (_, _, _) -> false | |
+ | Tpoly (_, _) -> false | |
+ | Tvariant _ -> false | |
+ | Tsubst te -> is_bool te.desc | |
+ | Tlink te -> is_bool te.desc | |
+ | Tfield (_, _, _, _) -> false | |
+ | Tobject (_, _) -> false | |
+ | Ttuple _ -> false | |
+ | Tarrow (_, _, _, _) -> false | |
+ | Tunivar -> false | |
+ | Tnil -> false | |
+ | Tvar -> false | |
+ | Tpackage _ -> false | |
+ | |
+(* Insertion of coverage events *) | |
+let put exp status lam = | |
+ Lcovevent(lam, { Covevent.lcovev_loc = exp.exp_loc; | |
+ lcovev_status = status }) | |
+ | |
+let build_lambda_covev exp status = | |
+ { Covevent.lcovev_loc = exp.exp_loc; | |
+ lcovev_status = status } | |
+ | |
+let add_coverage_event event cont = Instruct.Kcovevent event :: cont | |
+ | |
+(* Bytegen *) | |
+ | |
+let comp_expr | |
+ (continuation:('a -> 'b -> 'c -> Instruct.instruction list -> Instruct.instruction list)) | |
+ (env:'a) | |
+ (lam:'b) | |
+ (sz:'c) | |
+ (cont:Instruct.instruction list) | |
+ (compunit_name:string) | |
+ (lco:Covevent.lambda) | |
+ : Instruct.instruction list | |
+ = | |
+ let event status = { | |
+ Covevent.covev_pos = 0; (* patched in emitcode *) | |
+ Covevent.covev_module = compunit_name; | |
+ Covevent.covev_loc = lco.Covevent.lcovev_loc; | |
+ Covevent.covev_status = status | |
+ } in | |
+ let s = match lco.Covevent.lcovev_status with | |
+ Covevent.Lcovev_statement -> Covevent.Coverage_event_statement | |
+ | Covevent.Lcovev_decision -> Covevent.Coverage_event_decision | |
+ | Covevent.Lcovev_condition lcovev -> | |
+ let rec covev_of_lcovev lcov = | |
+ let status = match lcov.Covevent.lcovev_status with | |
+ Covevent.Lcovev_statement -> Covevent.Coverage_event_statement | |
+ | Covevent.Lcovev_decision -> Covevent.Coverage_event_decision | |
+ | Covevent.Lcovev_condition lcov2 -> Covevent.Coverage_event_condition (covev_of_lcovev lcov2) in | |
+ { Covevent.covev_pos = (-1); | |
+ Covevent.covev_module = compunit_name; | |
+ Covevent.covev_loc = lcov.Covevent.lcovev_loc; | |
+ Covevent.covev_status = status } in | |
+ Covevent.Coverage_event_condition (covev_of_lcovev lcovev) in | |
+ let ev = event s in | |
+ let cont1 = add_coverage_event ev cont in | |
+ continuation env lam sz cont1 | |
+ | |
+(* Bytelink *) | |
+ | |
+let cov_info_output = ref stdout | |
+ | |
+let link_compunit currpos_fun compunit = | |
+ if Sys.file_exists (compunit.Cmo_format.cu_name ^ ".cmo.covermo") then begin | |
+ let ci = open_in (compunit.Cmo_format.cu_name ^ ".cmo.covermo") in | |
+ let ev_list = Marshal.from_channel ci in | |
+ Sys.remove (compunit.Cmo_format.cu_name ^ ".cmo.covermo"); | |
+ let co = open_out (compunit.Cmo_format.cu_name ^ ".cmo.cover") in | |
+ output_value co (currpos_fun(), ev_list); | |
+ output_string !cov_info_output compunit.Cmo_format.cu_name; | |
+ output_string !cov_info_output "\n"; | |
+ close_out co; | |
+ close_in ci | |
+ end | |
+ | |
+(* Emitcode *) | |
+ | |
+let coverage_events = ref ([] : Covevent.coverage_event list) | |
+ | |
+let record_covevent covevent out_position = | |
+ covevent.Covevent.covev_pos <- !out_position; | |
+ coverage_events := covevent :: !coverage_events | |
+ | |
+let to_file unit_name = | |
+ let coverage_chan = open_out (unit_name ^ ".cmo.covermo") in | |
+ output_value coverage_chan !coverage_events; | |
+ close_out coverage_chan | |
+ | |
+(* Translcore *) | |
+ | |
+let with_from_dec dec f arg = | |
+ f dec arg | |
+ | |
+let with_new_dec f arg = with_from_dec None f arg | |
+ | |
+let covevent_of_exp dec e = | |
+ (* >semantics< *) | |
+ if is_bool e.exp_type.desc then | |
+ match dec with | |
+ Some d -> Covevent.Lcovev_condition d | |
+ | None -> Covevent.Lcovev_decision | |
+ else Covevent.Lcovev_statement | |
+ | |
+let is_bool_prim p = | |
+ (p.prim_name = "%sequor") || (p.prim_name = "%sequand") || (p.prim_name = "%boolnot") | |
+ | |
+(* let apply_prim_put_dec (dec:'a option) e p f arg = *) | |
+(* (\* >semantics< *\) *) | |
+(* if is_bool_prim p then *) | |
+(* if dec = None then *) | |
+(* let dec = Some (build_lambda_covev e Covevent.Lcovev_decision) in *) | |
+(* with_from_dec dec f arg *) | |
+(* else f dec arg *) | |
+(* else *) | |
+(* begin *) | |
+(* if is_bool e.exp_type.desc && dec <> None then *) | |
+(* with_new_dec f arg *) | |
+(* else f dec arg *) | |
+(* end *) | |
+ | |
+let apply_prim_put_dec (dec:'a option) e p f (args:Typedtree.expression list) = | |
+ (* >semantics< *) | |
+ if is_bool e.exp_type.desc && dec = None then | |
+ with_new_dec f args | |
+ else | |
+ with_from_dec dec f args | |
+ | |
+(* (\* *) | |
+(* let _old_apply_prim_covev p e = *) | |
+(* (\* >semantics< *\) *) | |
+(* if is_bool e.exp_type.desc then (\* a Boolean *\) *) | |
+(* if is_bool_prim p then *) | |
+(* begin *) | |
+(* if !from_dec = None then Covevent.Lcovev_decision *) | |
+(* else Covevent.Lcovev_statement *) | |
+(* end *) | |
+(* else *) | |
+(* begin *) | |
+(* match !from_dec with *) | |
+(* | None -> Covevent.Lcovev_decision *) | |
+(* | Some dec -> Covevent.Lcovev_condition dec *) | |
+(* end *) | |
+(* else (\* not a Boolean *\) *) | |
+(* Covevent.Lcovev_statement *) | |
+(* *\) *) | |
+ | |
+let apply_prim_covev dec p e = | |
+ (* >semantics< *) | |
+ if is_bool e.exp_type.desc then (* a Boolean *) | |
+ begin | |
+ match dec with | |
+ | None -> Covevent.Lcovev_decision | |
+ | Some dec -> Covevent.Lcovev_condition dec | |
+ end | |
+ else (* not a Boolean *) | |
+ Covevent.Lcovev_statement | |
+ | |
+ | |
+(* Printinstr *) | |
+ | |
+let print_instruction ppf event = | |
+ Format.fprintf ppf "\tcovevent_event \"%s\" %i-%i" | |
+ event.Covevent.covev_loc.Location.loc_start.Lexing.pos_fname | |
+ event.Covevent.covev_loc.Location.loc_start.Lexing.pos_cnum | |
+ event.Covevent.covev_loc.Location.loc_end.Lexing.pos_cnum | |
+ | |
+(* Printlambda *) | |
+ | |
+let print_lambda ppf lam expr ev = | |
+ Format.fprintf ppf "@[<2>(%i-%i@ %a)@]" | |
+ ev.Covevent.lcovev_loc.Location.loc_start.Lexing.pos_cnum | |
+ ev.Covevent.lcovev_loc.Location.loc_end.Lexing.pos_cnum | |
+ lam expr | |
diff -urN ocaml-3.12.0/bytecomp/covutils.mli ocaml-diff/bytecomp/covutils.mli | |
--- ocaml-3.12.0/bytecomp/covutils.mli 1970-01-01 01:00:00.000000000 +0100 | |
+++ ocaml-diff/bytecomp/covutils.mli 2012-09-03 02:31:07.000000000 +0200 | |
@@ -0,0 +1,53 @@ | |
+(***********************************************************************) | |
+(* Project Couverture *) | |
+(* *) | |
+(* file: covutils.mli *) | |
+(* authors: Adrien Jonquet, Mathias Bourgoin *) | |
+(* licence: CeCILL-B *) | |
+(***********************************************************************) | |
+ | |
+val is_bool : Types.type_desc -> bool | |
+ | |
+val put : (Typedtree.expression -> Covevent.lambda_status -> Lambda.lambda -> Lambda.lambda) | |
+ | |
+val build_lambda_covev : Typedtree.expression -> Covevent.lambda_status -> Covevent.lambda | |
+ | |
+val comp_expr : | |
+ ('a -> 'b -> 'c -> Instruct.instruction list -> Instruct.instruction list) -> | |
+ 'a -> | |
+ 'b -> | |
+ 'c -> | |
+ Instruct.instruction list -> | |
+ string -> Covevent.lambda -> Instruct.instruction list | |
+ | |
+val cov_info_output : out_channel ref | |
+ | |
+val link_compunit : (unit -> 'a) -> Cmo_format.compilation_unit -> unit | |
+ | |
+val coverage_events : Covevent.coverage_event list ref | |
+ | |
+val record_covevent : Covevent.coverage_event -> int ref -> unit | |
+ | |
+val to_file : string -> unit | |
+ | |
+val with_new_dec : ('dec option -> 'a -> 'b) -> 'a -> 'b | |
+ | |
+val covevent_of_exp : Covevent.lambda option -> Typedtree.expression -> Covevent.lambda_status | |
+ | |
+val apply_prim_put_dec : | |
+ 'a option -> | |
+ Typedtree.expression -> | |
+ 'b -> | |
+ ('a option -> Typedtree.expression list -> 'c) -> | |
+ Typedtree.expression list -> 'c | |
+ (* Typedtree.expression -> Primitive.description -> ('a -> 'b) -> 'a -> 'b *) | |
+ | |
+val apply_prim_covev : | |
+ Covevent.lambda option -> 'a -> Typedtree.expression -> Covevent.lambda_status | |
+ | |
+(* 'dec option -> Primitive.description -> Typedtree.expression -> Covevent.lambda_status *) | |
+ | |
+val print_instruction : Format.formatter -> Covevent.coverage_event -> unit | |
+ | |
+val print_lambda : | |
+ Format.formatter -> (Format.formatter -> 'a -> unit) -> 'a -> Covevent.lambda -> unit | |
diff -urN ocaml-3.12.0/bytecomp/emitcode.ml ocaml-diff/bytecomp/emitcode.ml | |
--- ocaml-3.12.0/bytecomp/emitcode.ml 2010-01-22 13:48:24.000000000 +0100 | |
+++ ocaml-diff/bytecomp/emitcode.ml 2012-03-14 14:42:30.000000000 +0100 | |
@@ -148,6 +148,7 @@ | |
out_position := 0; | |
label_table := Array.create 16 (Label_undefined []); | |
reloc_info := []; | |
+ Covutils.coverage_events := []; | |
events := [] | |
(* Emission of one instruction *) | |
@@ -266,6 +267,7 @@ | |
| Kgetpubmet tag -> out opGETPUBMET; out_int tag; out_int 0 | |
| Kgetdynmet -> out opGETDYNMET | |
| Kevent ev -> record_event ev | |
+ | Kcovevent covev -> Covutils.record_covevent covev out_position | |
| Kstop -> out opSTOP | |
(* Emission of a list of instructions. Include some peephole optimization. *) | |
@@ -344,6 +346,12 @@ | |
| Kpush :: (Kevent {ev_kind = Event_before} as ev) :: | |
(Kacc _ | Kenvacc _ | Koffsetclosure _ | Kgetglobal _ | Kconst _ as instr) :: c -> | |
emit (Kpush :: instr :: ev :: c) | |
+ | Kpush :: (Kcovevent _ as ev) :: | |
+ (Kgetglobal _ as instr1) :: (Kgetfield _ as instr2) :: c -> | |
+ emit (Kpush :: instr1 :: instr2 :: ev :: c) | |
+ | Kpush :: (Kcovevent _ as ev) :: | |
+ (Kacc _ | Kenvacc _ | Koffsetclosure _ | Kgetglobal _ | Kconst _ as instr) :: c -> | |
+ emit (Kpush :: instr :: ev :: c) | |
| Kgetglobal id :: Kgetfield n :: c -> | |
out opGETGLOBALFIELD; slot_for_getglobal id; out_int n; emit c | |
(* Default case *) | |
@@ -367,6 +375,7 @@ | |
(p, pos_out outchan - p) | |
end else | |
(0, 0) in | |
+ Covutils.to_file unit_name; | |
let compunit = | |
{ cu_name = unit_name; | |
cu_pos = pos_code; | |
diff -urN ocaml-3.12.0/bytecomp/instruct.ml ocaml-diff/bytecomp/instruct.ml | |
--- ocaml-3.12.0/bytecomp/instruct.ml 2009-05-20 13:52:42.000000000 +0200 | |
+++ ocaml-diff/bytecomp/instruct.ml 2012-03-14 14:42:30.000000000 +0100 | |
@@ -101,6 +101,7 @@ | |
| Kgetpubmet of int | |
| Kgetdynmet | |
| Kevent of debug_event | |
+ | Kcovevent of Covevent.coverage_event | |
| Kstop | |
let immed_min = -0x40000000 | |
diff -urN ocaml-3.12.0/bytecomp/instruct.mli ocaml-diff/bytecomp/instruct.mli | |
--- ocaml-3.12.0/bytecomp/instruct.mli 2009-05-20 13:52:42.000000000 +0200 | |
+++ ocaml-diff/bytecomp/instruct.mli 2012-03-14 14:42:30.000000000 +0100 | |
@@ -121,6 +121,7 @@ | |
| Kgetpubmet of int | |
| Kgetdynmet | |
| Kevent of debug_event | |
+ | Kcovevent of Covevent.coverage_event | |
| Kstop | |
val immed_min: int | |
diff -urN ocaml-3.12.0/bytecomp/lambda.ml ocaml-diff/bytecomp/lambda.ml | |
--- ocaml-3.12.0/bytecomp/lambda.ml 2010-01-22 13:48:24.000000000 +0100 | |
+++ ocaml-diff/bytecomp/lambda.ml 2012-03-14 14:42:30.000000000 +0100 | |
@@ -142,6 +142,7 @@ | |
| Lassign of Ident.t * lambda | |
| Lsend of meth_kind * lambda * lambda * lambda list | |
| Levent of lambda * lambda_event | |
+ | Lcovevent of lambda * Covevent.lambda | |
| Lifused of Ident.t * lambda | |
and lambda_switch = | |
@@ -205,6 +206,8 @@ | |
k1 = k2 && same a1 a2 && same b1 b2 && samelist same cl1 cl2 | |
| Levent(a1, ev1), Levent(a2, ev2) -> | |
same a1 a2 && ev1.lev_loc = ev2.lev_loc | |
+ | Lcovevent(a1, ev1), Lcovevent(a2, ev2) -> | |
+ same a1 a2 && ev1.Covevent.lcovev_loc = ev2.Covevent.lcovev_loc | |
| Lifused(id1, a1), Lifused(id2, a2) -> | |
Ident.same id1 id2 && same a1 a2 | |
| _, _ -> | |
@@ -281,6 +284,8 @@ | |
List.iter f (met::obj::args) | |
| Levent (lam, evt) -> | |
f lam | |
+ | Lcovevent (lam, evt) -> | |
+ f lam | |
| Lifused (v, e) -> | |
f e | |
@@ -313,7 +318,7 @@ | |
| Lvar _ | Lconst _ | Lapply _ | |
| Lprim _ | Lswitch _ | Lstaticraise _ | |
| Lifthenelse _ | Lsequence _ | Lwhile _ | |
- | Lsend _ | Levent _ | Lifused _ -> () | |
+ | Lsend _ | Levent _ | Lcovevent _ | Lifused _ -> () | |
in free l; !fv | |
let free_variables l = | |
@@ -336,6 +341,7 @@ | |
| Lifthenelse( cond, body, Lstaticraise (0,[])) -> true | |
| Llet(str, id, lam, body) -> is_guarded body | |
| Levent(lam, ev) -> is_guarded lam | |
+ | Lcovevent(lam, ev) -> is_guarded lam | |
| _ -> false | |
let rec patch_guarded patch = function | |
@@ -345,6 +351,8 @@ | |
Llet (str, id, lam, patch_guarded patch body) | |
| Levent(lam, ev) -> | |
Levent (patch_guarded patch lam, ev) | |
+ | Lcovevent(lam, ev) -> | |
+ Lcovevent (patch_guarded patch lam, ev) | |
| _ -> fatal_error "Lambda.patch_guarded" | |
(* Translate an access path *) | |
@@ -401,6 +409,7 @@ | |
| Lsend (k, met, obj, args) -> | |
Lsend (k, subst met, subst obj, List.map subst args) | |
| Levent (lam, evt) -> Levent (subst lam, evt) | |
+ | Lcovevent (lam, evt) -> Lcovevent (subst lam, evt) | |
| Lifused (v, e) -> Lifused (v, subst e) | |
and subst_decl (id, exp) = (id, subst exp) | |
and subst_case (key, case) = (key, subst case) | |
diff -urN ocaml-3.12.0/bytecomp/lambda.mli ocaml-diff/bytecomp/lambda.mli | |
--- ocaml-3.12.0/bytecomp/lambda.mli 2010-04-18 11:02:40.000000000 +0200 | |
+++ ocaml-diff/bytecomp/lambda.mli 2012-03-14 14:42:30.000000000 +0100 | |
@@ -151,6 +151,7 @@ | |
| Lassign of Ident.t * lambda | |
| Lsend of meth_kind * lambda * lambda * lambda list | |
| Levent of lambda * lambda_event | |
+ | Lcovevent of lambda * Covevent.lambda | |
| Lifused of Ident.t * lambda | |
and lambda_switch = | |
diff -urN ocaml-3.12.0/bytecomp/printinstr.ml ocaml-diff/bytecomp/printinstr.ml | |
--- ocaml-3.12.0/bytecomp/printinstr.ml 2005-08-25 17:35:16.000000000 +0200 | |
+++ ocaml-diff/bytecomp/printinstr.ml 2012-03-14 14:42:30.000000000 +0100 | |
@@ -103,6 +103,7 @@ | |
ev.ev_loc.Location.loc_start.Lexing.pos_fname | |
ev.ev_loc.Location.loc_start.Lexing.pos_cnum | |
ev.ev_loc.Location.loc_end.Lexing.pos_cnum | |
+ | Kcovevent ev -> Covutils.print_instruction ppf ev | |
let rec instruction_list ppf = function | |
[] -> () | |
diff -urN ocaml-3.12.0/bytecomp/printlambda.ml ocaml-diff/bytecomp/printlambda.ml | |
--- ocaml-3.12.0/bytecomp/printlambda.ml 2008-08-01 18:57:10.000000000 +0200 | |
+++ ocaml-diff/bytecomp/printlambda.ml 2012-03-14 14:42:30.000000000 +0100 | |
@@ -301,6 +301,8 @@ | |
ev.lev_loc.Location.loc_start.Lexing.pos_cnum | |
ev.lev_loc.Location.loc_end.Lexing.pos_cnum | |
lam expr | |
+ | Lcovevent(expr, ev) -> | |
+ Covutils.print_lambda ppf lam expr ev | |
| Lifused(id, expr) -> | |
fprintf ppf "@[<2>(ifused@ %a@ %a)@]" Ident.print id lam expr | |
diff -urN ocaml-3.12.0/bytecomp/simplif.ml ocaml-diff/bytecomp/simplif.ml | |
--- ocaml-3.12.0/bytecomp/simplif.ml 2010-01-22 13:48:24.000000000 +0100 | |
+++ ocaml-diff/bytecomp/simplif.ml 2012-03-14 14:42:30.000000000 +0100 | |
@@ -80,6 +80,8 @@ | |
List.map (eliminate_ref id) el) | |
| Levent(l, ev) -> | |
Levent(eliminate_ref id l, ev) | |
+ | Lcovevent(l, ev) -> | |
+ Lcovevent(eliminate_ref id l, ev) | |
| Lifused(v, e) -> | |
Lifused(v, eliminate_ref id e) | |
@@ -146,6 +148,7 @@ | |
count l | |
| Lsend(k, m, o, ll) -> List.iter count (m::o::ll) | |
| Levent(l, _) -> count l | |
+ | Lcovevent(l, _) -> count l | |
| Lifused(v, l) -> count l | |
and count_default sw = match sw.sw_failaction with | |
@@ -252,6 +255,7 @@ | |
| Lassign(v, l) -> Lassign(v, simplif l) | |
| Lsend(k, m, o, ll) -> Lsend(k, simplif m, simplif o, List.map simplif ll) | |
| Levent(l, ev) -> Levent(simplif l, ev) | |
+ | Lcovevent(l, ev) -> Lcovevent(simplif l, ev) | |
| Lifused(v, l) -> Lifused (v,simplif l) | |
in | |
simplif lam | |
@@ -315,6 +319,7 @@ | |
count l | |
| Lsend(_, m, o, ll) -> List.iter count (m::o::ll) | |
| Levent(l, _) -> count l | |
+ | Lcovevent(l, _) -> count l | |
| Lifused(v, l) -> | |
if count_var v > 0 then count l | |
@@ -404,6 +409,7 @@ | |
| Lassign(v, l) -> Lassign(v, simplif l) | |
| Lsend(k, m, o, ll) -> Lsend(k, simplif m, simplif o, List.map simplif ll) | |
| Levent(l, ev) -> Levent(simplif l, ev) | |
+ | Lcovevent(l, ev) -> Lcovevent(simplif l, ev) | |
| Lifused(v, l) -> | |
if count_var v > 0 then simplif l else lambda_unit | |
in | |
diff -urN ocaml-3.12.0/bytecomp/translcore.ml ocaml-diff/bytecomp/translcore.ml | |
--- ocaml-3.12.0/bytecomp/translcore.ml 2010-05-20 16:57:42.000000000 +0200 | |
+++ ocaml-diff/bytecomp/translcore.ml 2012-09-07 02:24:03.000000000 +0200 | |
@@ -384,6 +384,7 @@ | |
| Lprim (Pmakearray (Pgenarray), args) -> false | |
| Lsequence (lam1, lam2) -> check idlist lam1 && check_top idlist lam2 | |
| Levent (lam, _) -> check_top idlist lam | |
+ | Lcovevent (lam, _) -> check_top idlist lam | |
| lam -> check idlist lam | |
and check idlist = function | |
@@ -403,6 +404,7 @@ | |
List.for_all (check idlist) args | |
| Lsequence (lam1, lam2) -> check idlist lam1 && check idlist lam2 | |
| Levent (lam, _) -> check idlist lam | |
+ | Lcovevent (lam, _) -> check idlist lam | |
| lam -> | |
let fv = free_variables lam in | |
not (List.exists (fun id -> IdentSet.mem id fv) idlist) | |
@@ -554,311 +556,399 @@ | |
(* Translation of expressions *) | |
-let rec transl_exp e = | |
+let rec transl_exp (dec:'a option) (e:Typedtree.expression) : Lambda.lambda = | |
let eval_once = | |
(* Whether classes for immediate objects must be cached *) | |
match e.exp_desc with | |
- Texp_function _ | Texp_for _ | Texp_while _ -> false | |
- | _ -> true | |
+ Texp_function _ | Texp_for _ | Texp_while _ -> false | |
+ | _ -> true | |
in | |
- if eval_once then transl_exp0 e else | |
- Translobj.oo_wrap e.exp_env true transl_exp0 e | |
+ if eval_once then transl_exp0 dec e else | |
+ Translobj.oo_wrap e.exp_env true (transl_exp0 dec) e | |
-and transl_exp0 e = | |
+and transl_exp0 (dec:'a option) (e:Typedtree.expression) : Lambda.lambda = | |
match e.exp_desc with | |
- Texp_ident(path, {val_kind = Val_prim p}) -> | |
- let public_send = p.prim_name = "%send" in | |
- if public_send || p.prim_name = "%sendself" then | |
- let kind = if public_send then Public else Self in | |
- let obj = Ident.create "obj" and meth = Ident.create "meth" in | |
- Lfunction(Curried, [obj; meth], Lsend(kind, Lvar meth, Lvar obj, [])) | |
- else if p.prim_name = "%sendcache" then | |
- let obj = Ident.create "obj" and meth = Ident.create "meth" in | |
- let cache = Ident.create "cache" and pos = Ident.create "pos" in | |
- Lfunction(Curried, [obj; meth; cache; pos], | |
- Lsend(Cached, Lvar meth, Lvar obj, [Lvar cache; Lvar pos])) | |
- else | |
- transl_primitive p | |
- | Texp_ident(path, {val_kind = Val_anc _}) -> | |
- raise(Error(e.exp_loc, Free_super_var)) | |
- | Texp_ident(path, {val_kind = Val_reg | Val_self _}) -> | |
- transl_path path | |
- | Texp_ident _ -> fatal_error "Translcore.transl_exp: bad Texp_ident" | |
- | Texp_constant cst -> | |
- Lconst(Const_base cst) | |
- | Texp_let(rec_flag, pat_expr_list, body) -> | |
- transl_let rec_flag pat_expr_list (event_before body (transl_exp body)) | |
- | Texp_function (pat_expr_list, partial) -> | |
- let ((kind, params), body) = | |
- event_function e | |
- (function repr -> | |
- let pl = push_defaults e.exp_loc [] pat_expr_list partial in | |
- transl_function e.exp_loc !Clflags.native_code repr partial pl) | |
- in | |
- Lfunction(kind, params, body) | |
- | Texp_apply({exp_desc = Texp_ident(path, {val_kind = Val_prim p})}, oargs) | |
- when List.length oargs >= p.prim_arity | |
- && List.for_all (fun (arg,_) -> arg <> None) oargs -> | |
- let args, args' = cut p.prim_arity oargs in | |
- let wrap f = | |
- if args' = [] | |
- then event_after e f | |
- else event_after e (transl_apply f args' e.exp_loc) | |
- in | |
- let wrap0 f = | |
- if args' = [] then f else wrap f in | |
- let args = List.map (function Some x, _ -> x | _ -> assert false) args in | |
- let argl = transl_list args in | |
- let public_send = p.prim_name = "%send" | |
- || not !Clflags.native_code && p.prim_name = "%sendcache"in | |
- if public_send || p.prim_name = "%sendself" then | |
- let kind = if public_send then Public else Self in | |
- let obj = List.hd argl in | |
- wrap (Lsend (kind, List.nth argl 1, obj, [])) | |
- else if p.prim_name = "%sendcache" then | |
- match argl with [obj; meth; cache; pos] -> | |
- wrap (Lsend(Cached, meth, obj, [cache; pos])) | |
- | _ -> assert false | |
- else begin | |
- let prim = transl_prim p args in | |
- match (prim, args) with | |
- (Praise, [arg1]) -> | |
- wrap0 (Lprim(Praise, [event_after arg1 (List.hd argl)])) | |
- | (_, _) -> | |
- begin match (prim, argl) with | |
- | (Plazyforce, [a]) -> | |
- wrap (Matching.inline_lazy_force a e.exp_loc) | |
- | (Plazyforce, _) -> assert false | |
- |_ -> let p = Lprim(prim, argl) in | |
- if primitive_is_ccall prim then wrap p else wrap0 p | |
+ Texp_ident(path, {val_kind = Val_prim p}) -> | |
+ let public_send = p.prim_name = "%send" in | |
+ if public_send || p.prim_name = "%sendself" then | |
+ let kind = if public_send then Public else Self in | |
+ let obj = Ident.create "obj" and meth = Ident.create "meth" in | |
+ Lfunction(Curried, [obj; meth], Lsend(kind, Lvar meth, Lvar obj, [])) | |
+ else if p.prim_name = "%sendcache" then | |
+ let obj = Ident.create "obj" and meth = Ident.create "meth" in | |
+ let cache = Ident.create "cache" and pos = Ident.create "pos" in | |
+ (Lfunction(Curried, [obj; meth; cache; pos], | |
+ Lsend(Cached, Lvar meth, Lvar obj, [Lvar cache; Lvar pos]))) | |
+ else | |
+ transl_primitive p | |
+ | Texp_ident(path, {val_kind = Val_anc _}) -> | |
+ raise(Error(e.exp_loc, Free_super_var)) | |
+ | Texp_ident(path, {val_kind = Val_reg | Val_self _}) -> | |
+ Covutils.put e (Covutils.covevent_of_exp dec e) (transl_path path) | |
+ | Texp_ident _ -> fatal_error "Translcore.transl_exp: bad Texp_ident" | |
+ | Texp_constant cst -> | |
+ Covutils.put e Covevent.Lcovev_statement (Lconst(Const_base cst)) | |
+ | Texp_let(rec_flag, pat_expr_list, body) -> | |
+ (* dec transmission for let bodies except for functions *) | |
+ if pat_expr_list = [] then | |
+ transl_let dec rec_flag pat_expr_list (event_before body (transl_exp dec body)) | |
+ else | |
+ transl_let None rec_flag pat_expr_list (event_before body (transl_exp None body)) | |
+ | Texp_function (pat_expr_list, partial) -> | |
+ (* no dec transmission to functions *) | |
+ let ((kind, params), body) = | |
+ event_function e | |
+ (function repr -> | |
+ let pl = push_defaults e.exp_loc [] pat_expr_list partial in | |
+ transl_function None e.exp_loc !Clflags.native_code repr partial pl) | |
+ in | |
+ Lfunction(kind, params, body) | |
+ | |
+ (* ****************************** APPLY (PRIMITIVE) *******************************) | |
+ | Texp_apply({exp_desc = Texp_ident(path, {val_kind = Val_prim p})}, oargs) | |
+ when List.length oargs >= p.prim_arity | |
+ && List.for_all (fun (arg,_) -> arg <> None) oargs | |
+ -> | |
+ let args, args' = cut p.prim_arity oargs in | |
+ let wrap f = | |
+ if args' = [] | |
+ then event_after e f | |
+ else event_after e (transl_apply dec f args' e.exp_loc) | |
+ in | |
+ let wrap0 f = | |
+ if args' = [] then f else wrap f in | |
+ let args : Typedtree.expression list = | |
+ List.map (function Some x, _ -> x | _ -> assert false) args in | |
+ let argl : Lambda.lambda list = | |
+ Covutils.apply_prim_put_dec | |
+ (dec:Covevent.lambda option) | |
+ (e:Typedtree.expression) | |
+ (p:Primitive.description) | |
+ (transl_list:(Covevent.lambda option -> Typedtree.expression list -> Lambda.lambda list)) | |
+ (args:Typedtree.expression list) | |
+ in | |
+ let public_send = p.prim_name = "%send" | |
+ || not !Clflags.native_code && p.prim_name = "%sendcache"in | |
+ if public_send || p.prim_name = "%sendself" then | |
+ let kind = if public_send then Public else Self in | |
+ let obj = List.hd argl in | |
+ wrap (Lsend (kind, List.nth argl 1, obj, [])) | |
+ else if p.prim_name = "%sendcache" then | |
+ match argl with [obj; meth; cache; pos] -> | |
+ wrap (Lsend(Cached, meth, obj, [cache; pos])) | |
+ | _ -> assert false | |
+ else | |
+ begin | |
+ let prim = transl_prim p args in | |
+ match (prim, args) with | |
+ (Praise, [arg1]) -> | |
+ wrap0 (Lprim(Praise, [event_after arg1 (List.hd argl)])) | |
+ | (_, _) -> | |
+ begin match (prim, argl) with | |
+ | (Plazyforce, [a]) -> | |
+ wrap (Matching.inline_lazy_force a e.exp_loc) | |
+ | (Plazyforce, _) -> assert false | |
+ |_ -> | |
+ begin | |
+ match (Covutils.apply_prim_covev dec p e) with | |
+ | Covevent.Lcovev_statement | |
+ | Covevent.Lcovev_condition _ -> | |
+ Covutils.put e | |
+ (* (Covutils.apply_prim_covev dec p e) *) | |
+ Covevent.Lcovev_statement | |
+ (let p = Lprim(prim, argl) in | |
+ if primitive_is_ccall prim then wrap p else wrap0 p) | |
+ | Covevent.Lcovev_decision -> | |
+ let gdec = Some (Covutils.build_lambda_covev e Covevent.Lcovev_decision) in | |
+ let argl : Lambda.lambda list = | |
+ Covutils.apply_prim_put_dec | |
+ (gdec:Covevent.lambda option) | |
+ (e:Typedtree.expression) | |
+ (p:Primitive.description) | |
+ (transl_list:(Covevent.lambda option -> Typedtree.expression list -> Lambda.lambda list)) | |
+ (args:Typedtree.expression list) | |
+ in | |
+ Covutils.put e (Covutils.apply_prim_covev dec p e) | |
+ (let p = Lprim(prim, argl) in | |
+ if primitive_is_ccall prim then wrap p else wrap0 p) | |
+ end | |
+ end | |
end | |
- end | |
- | Texp_apply(funct, oargs) -> | |
- event_after e (transl_apply (transl_exp funct) oargs e.exp_loc) | |
- | Texp_match({exp_desc = Texp_tuple argl}, pat_expr_list, partial) -> | |
- Matching.for_multiple_match e.exp_loc | |
- (transl_list argl) (transl_cases pat_expr_list) partial | |
- | Texp_match(arg, pat_expr_list, partial) -> | |
- Matching.for_function e.exp_loc None | |
- (transl_exp arg) (transl_cases pat_expr_list) partial | |
- | Texp_try(body, pat_expr_list) -> | |
- let id = name_pattern "exn" pat_expr_list in | |
- Ltrywith(transl_exp body, id, | |
- Matching.for_trywith (Lvar id) (transl_cases pat_expr_list)) | |
- | Texp_tuple el -> | |
- let ll = transl_list el in | |
- begin try | |
- Lconst(Const_block(0, List.map extract_constant ll)) | |
- with Not_constant -> | |
- Lprim(Pmakeblock(0, Immutable), ll) | |
- end | |
- | Texp_construct(cstr, args) -> | |
- let ll = transl_list args in | |
- begin match cstr.cstr_tag with | |
- Cstr_constant n -> | |
- Lconst(Const_pointer n) | |
- | Cstr_block n -> | |
+ | |
+ (* ****************************** APPLY (GENERAL) *******************************) | |
+ | Texp_apply(funct, oargs) -> | |
+ begin | |
+ match (Covutils.covevent_of_exp dec e) with | |
+ | Covevent.Lcovev_condition d -> (* dec is Some _ *) | |
+ begin | |
+ let gdec = Some (Covutils.build_lambda_covev e Covevent.Lcovev_decision) in | |
+ Covutils.put e (Covutils.covevent_of_exp dec e) | |
+ (event_after e (transl_apply gdec (transl_exp gdec funct) oargs e.exp_loc)) | |
+ end | |
+ | Covevent.Lcovev_decision -> (* dec is None *) | |
+ let gdec = Some (Covutils.build_lambda_covev e Covevent.Lcovev_decision) in | |
+ Covutils.put e (Covutils.covevent_of_exp (dec) e) | |
+ (* something not right below vvvv vvvv*) | |
+ (event_after e (transl_apply gdec (transl_exp gdec funct) oargs e.exp_loc)) | |
+ | Covevent.Lcovev_statement -> (* expr is not Boolean *) | |
+ Covutils.put e (Covutils.covevent_of_exp dec e) | |
+ (event_after e (transl_apply dec (transl_exp dec funct) oargs e.exp_loc)) | |
+ end | |
+ | |
+ | |
+ | Texp_match({exp_desc = Texp_tuple argl}, pat_expr_list, partial) -> | |
+ Matching.for_multiple_match e.exp_loc | |
+ (transl_list dec argl) | |
+ (transl_cases dec pat_expr_list) | |
+ partial | |
+ | Texp_match(arg, pat_expr_list, partial) -> | |
+ Matching.for_function e.exp_loc None | |
+ (transl_exp dec arg) (transl_cases dec pat_expr_list) partial | |
+ | Texp_try(body, pat_expr_list) -> | |
+ let id = name_pattern "exn" pat_expr_list in | |
+ Ltrywith(transl_exp dec body, id, | |
+ Matching.for_trywith (Lvar id) (transl_cases dec pat_expr_list)) | |
+ | Texp_tuple el -> | |
+ let ll = transl_list dec el in | |
begin try | |
- Lconst(Const_block(n, List.map extract_constant ll)) | |
- with Not_constant -> | |
- Lprim(Pmakeblock(n, Immutable), ll) | |
+ Lconst(Const_block(0, List.map extract_constant ll)) | |
+ with Not_constant -> | |
+ Lprim(Pmakeblock(0, Immutable), ll) | |
end | |
- | Cstr_exception path -> | |
- Lprim(Pmakeblock(0, Immutable), transl_path path :: ll) | |
- end | |
- | Texp_variant(l, arg) -> | |
- let tag = Btype.hash_variant l in | |
- begin match arg with | |
- None -> Lconst(Const_pointer tag) | |
- | Some arg -> | |
- let lam = transl_exp arg in | |
- try | |
- Lconst(Const_block(0, [Const_base(Const_int tag); | |
- extract_constant lam])) | |
- with Not_constant -> | |
- Lprim(Pmakeblock(0, Immutable), | |
- [Lconst(Const_base(Const_int tag)); lam]) | |
- end | |
- | Texp_record ((lbl1, _) :: _ as lbl_expr_list, opt_init_expr) -> | |
- transl_record lbl1.lbl_all lbl1.lbl_repres lbl_expr_list opt_init_expr | |
- | Texp_record ([], _) -> | |
- fatal_error "Translcore.transl_exp: bad Texp_record" | |
- | Texp_field(arg, lbl) -> | |
- let access = | |
- match lbl.lbl_repres with | |
- Record_regular -> Pfield lbl.lbl_pos | |
- | Record_float -> Pfloatfield lbl.lbl_pos in | |
- Lprim(access, [transl_exp arg]) | |
- | Texp_setfield(arg, lbl, newval) -> | |
- let access = | |
- match lbl.lbl_repres with | |
- Record_regular -> Psetfield(lbl.lbl_pos, maybe_pointer newval) | |
- | Record_float -> Psetfloatfield lbl.lbl_pos in | |
- Lprim(access, [transl_exp arg; transl_exp newval]) | |
- | Texp_array expr_list -> | |
- let kind = array_kind e in | |
- let ll = transl_list expr_list in | |
- begin try | |
- (* Deactivate constant optimization if array is small enough *) | |
- if List.length ll <= 4 then raise Not_constant; | |
- let cl = List.map extract_constant ll in | |
- let master = | |
- match kind with | |
- | Paddrarray | Pintarray -> | |
- Lconst(Const_block(0, cl)) | |
- | Pfloatarray -> | |
- Lconst(Const_float_array(List.map extract_float cl)) | |
- | Pgenarray -> | |
- raise Not_constant in (* can this really happen? *) | |
- Lprim(Pccall prim_obj_dup, [master]) | |
- with Not_constant -> | |
- Lprim(Pmakearray kind, ll) | |
- end | |
- | Texp_ifthenelse(cond, ifso, Some ifnot) -> | |
- Lifthenelse(transl_exp cond, | |
- event_before ifso (transl_exp ifso), | |
- event_before ifnot (transl_exp ifnot)) | |
- | Texp_ifthenelse(cond, ifso, None) -> | |
- Lifthenelse(transl_exp cond, | |
- event_before ifso (transl_exp ifso), | |
- lambda_unit) | |
- | Texp_sequence(expr1, expr2) -> | |
- Lsequence(transl_exp expr1, event_before expr2 (transl_exp expr2)) | |
- | Texp_while(cond, body) -> | |
- Lwhile(transl_exp cond, event_before body (transl_exp body)) | |
- | Texp_for(param, low, high, dir, body) -> | |
- Lfor(param, transl_exp low, transl_exp high, dir, | |
- event_before body (transl_exp body)) | |
- | Texp_when(cond, body) -> | |
- event_before cond | |
- (Lifthenelse(transl_exp cond, event_before body (transl_exp body), | |
- staticfail)) | |
- | Texp_send(expr, met) -> | |
- let obj = transl_exp expr in | |
- let lam = | |
- match met with | |
- Tmeth_val id -> Lsend (Self, Lvar id, obj, []) | |
- | Tmeth_name nm -> | |
- let (tag, cache) = Translobj.meth obj nm in | |
- let kind = if cache = [] then Public else Cached in | |
- Lsend (kind, tag, obj, cache) | |
- in | |
- event_after e lam | |
- | Texp_new (cl, _) -> | |
- Lapply(Lprim(Pfield 0, [transl_path cl]), [lambda_unit], Location.none) | |
- | Texp_instvar(path_self, path) -> | |
- Lprim(Parrayrefu Paddrarray, [transl_path path_self; transl_path path]) | |
- | Texp_setinstvar(path_self, path, expr) -> | |
- transl_setinstvar (transl_path path_self) path expr | |
- | Texp_override(path_self, modifs) -> | |
- let cpy = Ident.create "copy" in | |
- Llet(Strict, cpy, | |
- Lapply(Translobj.oo_prim "copy", [transl_path path_self], | |
- Location.none), | |
- List.fold_right | |
- (fun (path, expr) rem -> | |
- Lsequence(transl_setinstvar (Lvar cpy) path expr, rem)) | |
- modifs | |
- (Lvar cpy)) | |
- | Texp_letmodule(id, modl, body) -> | |
- Llet(Strict, id, !transl_module Tcoerce_none None modl, transl_exp body) | |
- | Texp_pack modl -> | |
- !transl_module Tcoerce_none None modl | |
- | Texp_assert (cond) -> | |
- if !Clflags.noassert | |
- then lambda_unit | |
- else Lifthenelse (transl_exp cond, lambda_unit, assert_failed e.exp_loc) | |
- | Texp_assertfalse -> assert_failed e.exp_loc | |
- | Texp_lazy e -> | |
- (* when e needs no computation (constants, identifiers, ...), we | |
- optimize the translation just as Lazy.lazy_from_val would | |
- do *) | |
- begin match e.exp_desc with | |
- (* a constant expr of type <> float gets compiled as itself *) | |
- | Texp_constant | |
- ( Const_int _ | Const_char _ | Const_string _ | |
- | Const_int32 _ | Const_int64 _ | Const_nativeint _ ) | |
- | Texp_function(_, _) | |
- | Texp_construct ({cstr_arity = 0}, _) | |
- -> transl_exp e | |
- | Texp_constant(Const_float _) -> | |
- Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp e]) | |
- | Texp_ident(_, _) -> (* according to the type *) | |
- begin match e.exp_type.desc with | |
- (* the following may represent a float/forward/lazy: need a | |
- forward_tag *) | |
- | Tvar | Tlink _ | Tsubst _ | Tunivar | |
- | Tpoly(_,_) | Tfield(_,_,_,_) -> | |
- Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp e]) | |
- (* the following cannot be represented as float/forward/lazy: | |
- optimize *) | |
- | Tarrow(_,_,_,_) | Ttuple _ | Tpackage _ | Tobject(_,_) | Tnil | Tvariant _ | |
- -> transl_exp e | |
- (* optimize predefined types (excepted float) *) | |
- | Tconstr(_,_,_) -> | |
- if has_base_type e Predef.path_int | |
- || has_base_type e Predef.path_char | |
- || has_base_type e Predef.path_string | |
- || has_base_type e Predef.path_bool | |
- || has_base_type e Predef.path_unit | |
- || has_base_type e Predef.path_exn | |
- || has_base_type e Predef.path_array | |
- || has_base_type e Predef.path_list | |
- || has_base_type e Predef.path_format6 | |
- || has_base_type e Predef.path_option | |
- || has_base_type e Predef.path_nativeint | |
- || has_base_type e Predef.path_int32 | |
- || has_base_type e Predef.path_int64 | |
- then transl_exp e | |
- else | |
- Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp e]) | |
+ | Texp_construct(cstr, args) -> | |
+ let ll = transl_list dec args in | |
+ begin match cstr.cstr_tag with | |
+ Cstr_constant n -> | |
+ Covutils.put e Covevent.Lcovev_statement (Lconst(Const_pointer n)) | |
+ | Cstr_block n -> | |
+ begin try | |
+ Covutils.put e Covevent.Lcovev_statement | |
+ (Lconst(Const_block(n, List.map extract_constant ll))) | |
+ with Not_constant -> | |
+ Covutils.put e Covevent.Lcovev_statement | |
+ (Lprim(Pmakeblock(n, Immutable), ll)) | |
+ end | |
+ | Cstr_exception path -> | |
+ Covutils.put e Covevent.Lcovev_statement | |
+ (Lprim(Pmakeblock(0, Immutable), transl_path path :: ll)) | |
+ end | |
+ | Texp_variant(l, arg) -> | |
+ let tag = Btype.hash_variant l in | |
+ begin match arg with | |
+ None -> Lconst(Const_pointer tag) | |
+ | Some arg -> | |
+ let lam = transl_exp dec arg in | |
+ try | |
+ Lconst(Const_block(0, [Const_base(Const_int tag); | |
+ extract_constant lam])) | |
+ with Not_constant -> | |
+ Lprim(Pmakeblock(0, Immutable), | |
+ [Lconst(Const_base(Const_int tag)); lam]) | |
end | |
- (* other cases compile to a lazy block holding a function *) | |
- | _ -> | |
- let fn = Lfunction (Curried, [Ident.create "param"], transl_exp e) in | |
- Lprim(Pmakeblock(Config.lazy_tag, Immutable), [fn]) | |
- end | |
- | Texp_object (cs, cty, meths) -> | |
- let cl = Ident.create "class" in | |
- !transl_object cl meths | |
- { cl_desc = Tclass_structure cs; | |
- cl_loc = e.exp_loc; | |
- cl_type = Tcty_signature cty; | |
- cl_env = e.exp_env } | |
+ | Texp_record ((lbl1, _) :: _ as lbl_expr_list, opt_init_expr) -> | |
+ transl_record dec lbl1.lbl_all lbl1.lbl_repres lbl_expr_list opt_init_expr | |
+ | Texp_record ([], _) -> | |
+ fatal_error "Translcore.transl_exp: bad Texp_record" | |
+ | Texp_field(arg, lbl) -> | |
+ begin | |
+ let gdec = | |
+ if Covutils.is_bool e.exp_type.desc && dec = None then | |
+ Some (Covutils.build_lambda_covev e Covevent.Lcovev_decision) | |
+ else | |
+ dec | |
+ in | |
+ let access = | |
+ match lbl.lbl_repres with | |
+ Record_regular -> Pfield lbl.lbl_pos | |
+ | Record_float -> Pfloatfield lbl.lbl_pos in | |
+ Covutils.put e (Covutils.covevent_of_exp dec e) | |
+ (Lprim(access, [transl_exp gdec arg])) | |
+ end | |
+ | Texp_setfield(arg, lbl, newval) -> | |
+ let access = | |
+ match lbl.lbl_repres with | |
+ Record_regular -> Psetfield(lbl.lbl_pos, maybe_pointer newval) | |
+ | Record_float -> Psetfloatfield lbl.lbl_pos in | |
+ Covutils.put e (Covutils.covevent_of_exp dec e) | |
+ (Lprim(access, [transl_exp dec arg; transl_exp dec newval])) | |
+ | Texp_array expr_list -> | |
+ let kind = array_kind e in | |
+ let ll = transl_list dec expr_list in | |
+ begin try | |
+ (* Deactivate constant optimization if array is small enough *) | |
+ if List.length ll <= 4 then raise Not_constant; | |
+ let cl = List.map extract_constant ll in | |
+ let master = | |
+ match kind with | |
+ | Paddrarray | Pintarray -> | |
+ Lconst(Const_block(0, cl)) | |
+ | Pfloatarray -> | |
+ Lconst(Const_float_array(List.map extract_float cl)) | |
+ | Pgenarray -> | |
+ raise Not_constant in (* can this really happen? *) | |
+ Lprim(Pccall prim_obj_dup, [master]) | |
+ with Not_constant -> | |
+ Lprim(Pmakearray kind, ll) | |
+ end | |
+ | Texp_ifthenelse(cond, ifso, Some ifnot) -> | |
+ begin | |
+ if Covutils.is_bool e.exp_type.desc && dec = None then | |
+ let gdec = | |
+ Some (Covutils.build_lambda_covev e Covevent.Lcovev_decision) | |
+ in | |
+ Covutils.put e (Covutils.covevent_of_exp dec e) | |
+ (Lifthenelse(transl_exp gdec cond, | |
+ event_before ifso (transl_exp gdec ifso), | |
+ event_before ifnot (transl_exp gdec ifnot))) | |
+ else | |
+ Covutils.put e (Covutils.covevent_of_exp dec e) | |
+ (Lifthenelse(transl_exp dec cond, | |
+ event_before ifso (transl_exp dec ifso), | |
+ event_before ifnot (transl_exp dec ifnot))) | |
+ end | |
+ | Texp_ifthenelse(cond, ifso, None) -> | |
+ Lifthenelse(transl_exp dec cond, | |
+ event_before ifso (transl_exp dec ifso), | |
+ lambda_unit) | |
+ | Texp_sequence(expr1, expr2) -> | |
+ Lsequence(transl_exp dec expr1, event_before expr2 (transl_exp dec expr2)) | |
+ | Texp_while(cond, body) -> | |
+ (* no dec transmission to loops *) | |
+ Lwhile(transl_exp None cond, event_before body (transl_exp None body)) | |
+ | Texp_for(param, low, high, dir, body) -> | |
+ (* no dec transmission to loops *) | |
+ Lfor(param, transl_exp None low, transl_exp dec high, dir, | |
+ event_before body (transl_exp None body)) | |
+ | Texp_when(cond, body) -> | |
+ event_before cond | |
+ (Lifthenelse(transl_exp dec cond, event_before body (transl_exp dec body), | |
+ staticfail)) | |
+ | Texp_send(expr, met) -> | |
+ let obj = transl_exp dec expr in | |
+ let lam = | |
+ match met with | |
+ Tmeth_val id -> Lsend (Self, Lvar id, obj, []) | |
+ | Tmeth_name nm -> | |
+ let (tag, cache) = Translobj.meth obj nm in | |
+ let kind = if cache = [] then Public else Cached in | |
+ Lsend (kind, tag, obj, cache) | |
+ in | |
+ event_after e lam | |
+ | Texp_new (cl, _) -> | |
+ Lapply(Lprim(Pfield 0, [transl_path cl]), [lambda_unit], Location.none) | |
+ | Texp_instvar(path_self, path) -> | |
+ Lprim(Parrayrefu Paddrarray, [transl_path path_self; transl_path path]) | |
+ | Texp_setinstvar(path_self, path, expr) -> | |
+ transl_setinstvar dec (transl_path path_self) path expr | |
+ | Texp_override(path_self, modifs) -> | |
+ let cpy = Ident.create "copy" in | |
+ Llet(Strict, cpy, | |
+ Lapply(Translobj.oo_prim "copy", [transl_path path_self], | |
+ Location.none), | |
+ List.fold_right | |
+ (fun (path, expr) rem -> | |
+ Lsequence(transl_setinstvar dec (Lvar cpy) path expr, rem)) | |
+ modifs | |
+ (Lvar cpy)) | |
+ | Texp_letmodule(id, modl, body) -> | |
+ Llet(Strict, id, !transl_module Tcoerce_none None modl, transl_exp dec body) | |
+ | Texp_pack modl -> | |
+ !transl_module Tcoerce_none None modl | |
+ | Texp_assert (cond) -> | |
+ if !Clflags.noassert | |
+ then lambda_unit | |
+ else Lifthenelse (transl_exp dec cond, lambda_unit, assert_failed e.exp_loc) | |
+ | Texp_assertfalse -> assert_failed e.exp_loc | |
+ | Texp_lazy e -> | |
+ (* when e needs no computation (constants, identifiers, ...), we | |
+ optimize the translation just as Lazy.lazy_from_val would | |
+ do *) | |
+ begin match e.exp_desc with | |
+ (* a constant expr of type <> float gets compiled as itself *) | |
+ | Texp_constant | |
+ ( Const_int _ | Const_char _ | Const_string _ | |
+ | Const_int32 _ | Const_int64 _ | Const_nativeint _ ) | |
+ | Texp_function(_, _) | |
+ | Texp_construct ({cstr_arity = 0}, _) | |
+ -> transl_exp dec e | |
+ | Texp_constant(Const_float _) -> | |
+ Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp dec e]) | |
+ | Texp_ident(_, _) -> (* according to the type *) | |
+ begin match e.exp_type.desc with | |
+ (* the following may represent a float/forward/lazy: need a | |
+ forward_tag *) | |
+ | Tvar | Tlink _ | Tsubst _ | Tunivar | |
+ | Tpoly(_,_) | Tfield(_,_,_,_) -> | |
+ Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp dec e]) | |
+ (* the following cannot be represented as float/forward/lazy: | |
+ optimize *) | |
+ | Tarrow(_,_,_,_) | Ttuple _ | Tpackage _ | Tobject(_,_) | Tnil | Tvariant _ | |
+ -> transl_exp dec e | |
+ (* optimize predefined types (excepted float) *) | |
+ | Tconstr(_,_,_) -> | |
+ if has_base_type e Predef.path_int | |
+ || has_base_type e Predef.path_char | |
+ || has_base_type e Predef.path_string | |
+ || has_base_type e Predef.path_bool | |
+ || has_base_type e Predef.path_unit | |
+ || has_base_type e Predef.path_exn | |
+ || has_base_type e Predef.path_array | |
+ || has_base_type e Predef.path_list | |
+ || has_base_type e Predef.path_format6 | |
+ || has_base_type e Predef.path_option | |
+ || has_base_type e Predef.path_nativeint | |
+ || has_base_type e Predef.path_int32 | |
+ || has_base_type e Predef.path_int64 | |
+ then transl_exp dec e | |
+ else | |
+ Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp dec e]) | |
+ end | |
+ (* other cases compile to a lazy block holding a function *) | |
+ | _ -> | |
+ let fn = Lfunction (Curried, [Ident.create "param"], transl_exp dec e) in | |
+ Lprim(Pmakeblock(Config.lazy_tag, Immutable), [fn]) | |
+ end | |
+ | Texp_object (cs, cty, meths) -> | |
+ let cl = Ident.create "class" in | |
+ !transl_object cl meths | |
+ { cl_desc = Tclass_structure cs; | |
+ cl_loc = e.exp_loc; | |
+ cl_type = Tcty_signature cty; | |
+ cl_env = e.exp_env } | |
-and transl_list expr_list = | |
- List.map transl_exp expr_list | |
+and transl_list (dec:Covevent.lambda option) expr_list = | |
+ List.map (transl_exp dec) expr_list | |
-and transl_cases pat_expr_list = | |
+and transl_cases dec pat_expr_list = | |
List.map | |
- (fun (pat, expr) -> (pat, event_before expr (transl_exp expr))) | |
+ (fun (pat, expr) -> (pat, event_before expr (transl_exp dec expr))) | |
pat_expr_list | |
-and transl_tupled_cases patl_expr_list = | |
- List.map (fun (patl, expr) -> (patl, transl_exp expr)) patl_expr_list | |
+and transl_tupled_cases dec patl_expr_list = | |
+ List.map (fun (patl, expr) -> (patl, transl_exp dec expr)) patl_expr_list | |
-and transl_apply lam sargs loc = | |
+and transl_apply dec lam sargs loc = | |
let lapply funct args = | |
match funct with | |
- Lsend(k, lmet, lobj, largs) -> | |
- Lsend(k, lmet, lobj, largs @ args) | |
- | Levent(Lsend(k, lmet, lobj, largs), _) -> | |
- Lsend(k, lmet, lobj, largs @ args) | |
- | Lapply(lexp, largs, _) -> | |
- Lapply(lexp, largs @ args, loc) | |
- | lexp -> | |
- Lapply(lexp, args, loc) | |
+ Lsend(k, lmet, lobj, largs) -> | |
+ Lsend(k, lmet, lobj, largs @ args) | |
+ | Levent(Lsend(k, lmet, lobj, largs), _) -> | |
+ Lsend(k, lmet, lobj, largs @ args) | |
+ | Lapply(lexp, largs, _) -> | |
+ Lapply(lexp, largs @ args, loc) | |
+ | lexp -> | |
+ Lapply(lexp, args, loc) | |
in | |
let rec build_apply lam args = function | |
(None, optional) :: l -> | |
let defs = ref [] in | |
let protect name lam = | |
match lam with | |
- Lvar _ | Lconst _ -> lam | |
- | _ -> | |
- let id = Ident.create name in | |
- defs := (id, lam) :: !defs; | |
- Lvar id | |
+ Lvar _ | Lconst _ -> lam | |
+ | _ -> | |
+ let id = Ident.create name in | |
+ defs := (id, lam) :: !defs; | |
+ Lvar id | |
in | |
let args, args' = | |
if List.for_all (fun (_,opt) -> opt = Optional) args then [], args | |
@@ -870,147 +960,152 @@ | |
and id_arg = Ident.create "param" in | |
let body = | |
match build_apply handle ((Lvar id_arg, optional)::args') l with | |
- Lfunction(Curried, ids, lam) -> | |
- Lfunction(Curried, id_arg::ids, lam) | |
- | Levent(Lfunction(Curried, ids, lam), _) -> | |
- Lfunction(Curried, id_arg::ids, lam) | |
- | lam -> | |
- Lfunction(Curried, [id_arg], lam) | |
+ Lfunction(Curried, ids, lam) -> | |
+ Lfunction(Curried, id_arg::ids, lam) | |
+ | Levent(Lfunction(Curried, ids, lam), _) -> | |
+ Lfunction(Curried, id_arg::ids, lam) | |
+ | lam -> | |
+ Lfunction(Curried, [id_arg], lam) | |
in | |
- List.fold_left | |
- (fun body (id, lam) -> Llet(Strict, id, lam, body)) | |
- body !defs | |
+ List.fold_left | |
+ (fun body (id, lam) -> Llet(Strict, id, lam, body)) | |
+ body !defs | |
| (Some arg, optional) :: l -> | |
build_apply lam ((arg, optional) :: args) l | |
| [] -> | |
lapply lam (List.rev_map fst args) | |
in | |
- build_apply lam [] (List.map (fun (x,o) -> may_map transl_exp x, o) sargs) | |
+ build_apply lam [] (List.map (fun (x,o) -> may_map (transl_exp dec) x, o) sargs) | |
-and transl_function loc untuplify_fn repr partial pat_expr_list = | |
+and transl_function dec loc untuplify_fn repr partial pat_expr_list = | |
match pat_expr_list with | |
- [pat, ({exp_desc = Texp_function(pl,partial')} as exp)] | |
- when Parmatch.fluid pat -> | |
- let param = name_pattern "param" pat_expr_list in | |
- let ((_, params), body) = | |
- transl_function exp.exp_loc false repr partial' pl in | |
- ((Curried, param :: params), | |
- Matching.for_function loc None (Lvar param) [pat, body] partial) | |
- | ({pat_desc = Tpat_tuple pl}, _) :: _ when untuplify_fn -> | |
- begin try | |
- let size = List.length pl in | |
- let pats_expr_list = | |
- List.map | |
- (fun (pat, expr) -> (Matching.flatten_pattern size pat, expr)) | |
- pat_expr_list in | |
- let params = List.map (fun p -> Ident.create "param") pl in | |
- ((Tupled, params), | |
- Matching.for_tupled_function loc params | |
- (transl_tupled_cases pats_expr_list) partial) | |
- with Matching.Cannot_flatten -> | |
+ [pat, ({exp_desc = Texp_function(pl,partial')} as exp)] | |
+ when Parmatch.fluid pat -> | |
+ let param = name_pattern "param" pat_expr_list in | |
+ let ((_, params), body) = | |
+ transl_function dec exp.exp_loc false repr partial' pl in | |
+ ((Curried, param :: params), | |
+ Matching.for_function loc None (Lvar param) [pat, body] partial) | |
+ | ({pat_desc = Tpat_tuple pl}, _) :: _ when untuplify_fn -> | |
+ begin try | |
+ let size = List.length pl in | |
+ let pats_expr_list = | |
+ List.map | |
+ (fun (pat, expr) -> (Matching.flatten_pattern size pat, expr)) | |
+ pat_expr_list in | |
+ let params = List.map (fun p -> Ident.create "param") pl in | |
+ ((Tupled, params), | |
+ Matching.for_tupled_function loc params | |
+ (transl_tupled_cases dec pats_expr_list) partial) | |
+ with Matching.Cannot_flatten -> | |
+ let param = name_pattern "param" pat_expr_list in | |
+ ((Curried, [param]), | |
+ Matching.for_function loc repr (Lvar param) | |
+ (transl_cases dec pat_expr_list) partial) | |
+ end | |
+ | _ -> | |
let param = name_pattern "param" pat_expr_list in | |
- ((Curried, [param]), | |
- Matching.for_function loc repr (Lvar param) | |
- (transl_cases pat_expr_list) partial) | |
- end | |
- | _ -> | |
- let param = name_pattern "param" pat_expr_list in | |
- ((Curried, [param]), | |
- Matching.for_function loc repr (Lvar param) | |
- (transl_cases pat_expr_list) partial) | |
+ ((Curried, [param]), | |
+ Matching.for_function loc repr (Lvar param) | |
+ (transl_cases dec pat_expr_list) partial) | |
-and transl_let rec_flag pat_expr_list body = | |
+and transl_let dec rec_flag pat_expr_list body = | |
match rec_flag with | |
- Nonrecursive | Default -> | |
- let rec transl = function | |
- [] -> | |
- body | |
- | (pat, expr) :: rem -> | |
- Matching.for_let pat.pat_loc (transl_exp expr) pat (transl rem) | |
- in transl pat_expr_list | |
- | Recursive -> | |
- let idlist = | |
- List.map | |
- (fun (pat, expr) -> | |
- match pat.pat_desc with | |
- Tpat_var id -> id | |
- | _ -> raise(Error(pat.pat_loc, Illegal_letrec_pat))) | |
- pat_expr_list in | |
- let transl_case (pat, expr) id = | |
- let lam = transl_exp expr in | |
- if not (check_recursive_lambda idlist lam) then | |
- raise(Error(expr.exp_loc, Illegal_letrec_expr)); | |
- (id, lam) in | |
- Lletrec(List.map2 transl_case pat_expr_list idlist, body) | |
+ Nonrecursive | Default -> | |
+ let rec transl = function | |
+ [] -> | |
+ body | |
+ | (pat, expr) :: rem -> | |
+ Matching.for_let pat.pat_loc (transl_exp dec expr) pat (transl rem) | |
+ in transl pat_expr_list | |
+ | Recursive -> | |
+ let idlist = | |
+ List.map | |
+ (fun (pat, expr) -> | |
+ match pat.pat_desc with | |
+ Tpat_var id -> id | |
+ | _ -> raise(Error(pat.pat_loc, Illegal_letrec_pat))) | |
+ pat_expr_list in | |
+ let transl_case (pat, expr) id = | |
+ let lam = transl_exp dec expr in | |
+ if not (check_recursive_lambda idlist lam) then | |
+ raise(Error(expr.exp_loc, Illegal_letrec_expr)); | |
+ (id, lam) in | |
+ Lletrec(List.map2 transl_case pat_expr_list idlist, body) | |
-and transl_setinstvar self var expr = | |
+and transl_setinstvar dec self var expr = | |
Lprim(Parraysetu (if maybe_pointer expr then Paddrarray else Pintarray), | |
- [self; transl_path var; transl_exp expr]) | |
+ [self; transl_path var; transl_exp dec expr]) | |
-and transl_record all_labels repres lbl_expr_list opt_init_expr = | |
+and transl_record dec all_labels repres lbl_expr_list opt_init_expr = | |
let size = Array.length all_labels in | |
- (* Determine if there are "enough" new fields *) | |
- if 3 + 2 * List.length lbl_expr_list >= size | |
- then begin | |
- (* Allocate new record with given fields (and remaining fields | |
- taken from init_expr if any *) | |
- let lv = Array.create (Array.length all_labels) staticfail in | |
- let init_id = Ident.create "init" in | |
- begin match opt_init_expr with | |
- None -> () | |
- | Some init_expr -> | |
- for i = 0 to Array.length all_labels - 1 do | |
- let access = | |
- match all_labels.(i).lbl_repres with | |
- Record_regular -> Pfield i | |
- | Record_float -> Pfloatfield i in | |
- lv.(i) <- Lprim(access, [Lvar init_id]) | |
- done | |
- end; | |
- List.iter | |
- (fun (lbl, expr) -> lv.(lbl.lbl_pos) <- transl_exp expr) | |
- lbl_expr_list; | |
- let ll = Array.to_list lv in | |
- let mut = | |
- if List.exists (fun (lbl, expr) -> lbl.lbl_mut = Mutable) lbl_expr_list | |
- then Mutable | |
- else Immutable in | |
- let lam = | |
- try | |
- if mut = Mutable then raise Not_constant; | |
- let cl = List.map extract_constant ll in | |
- match repres with | |
- Record_regular -> Lconst(Const_block(0, cl)) | |
- | Record_float -> | |
- Lconst(Const_float_array(List.map extract_float cl)) | |
- with Not_constant -> | |
- match repres with | |
- Record_regular -> Lprim(Pmakeblock(0, mut), ll) | |
- | Record_float -> Lprim(Pmakearray Pfloatarray, ll) in | |
- begin match opt_init_expr with | |
- None -> lam | |
- | Some init_expr -> Llet(Strict, init_id, transl_exp init_expr, lam) | |
- end | |
- end else begin | |
- (* Take a shallow copy of the init record, then mutate the fields | |
- of the copy *) | |
- (* If you change anything here, you will likely have to change | |
- [check_recursive_recordwith] in this file. *) | |
- let copy_id = Ident.create "newrecord" in | |
- let rec update_field (lbl, expr) cont = | |
- let upd = | |
- match lbl.lbl_repres with | |
- Record_regular -> Psetfield(lbl.lbl_pos, maybe_pointer expr) | |
- | Record_float -> Psetfloatfield lbl.lbl_pos in | |
- Lsequence(Lprim(upd, [Lvar copy_id; transl_exp expr]), cont) in | |
- begin match opt_init_expr with | |
- None -> assert false | |
- | Some init_expr -> | |
- Llet(Strict, copy_id, | |
- Lprim(Pduprecord (repres, size), [transl_exp init_expr]), | |
- List.fold_right update_field lbl_expr_list (Lvar copy_id)) | |
+ (* Determine if there are "enough" new fields *) | |
+ if 3 + 2 * List.length lbl_expr_list >= size | |
+ then begin | |
+ (* Allocate new record with given fields (and remaining fields | |
+ taken from init_expr if any *) | |
+ let lv = Array.create (Array.length all_labels) staticfail in | |
+ let init_id = Ident.create "init" in | |
+ begin match opt_init_expr with | |
+ None -> () | |
+ | Some init_expr -> | |
+ for i = 0 to Array.length all_labels - 1 do | |
+ let access = | |
+ match all_labels.(i).lbl_repres with | |
+ Record_regular -> Pfield i | |
+ | Record_float -> Pfloatfield i in | |
+ lv.(i) <- Lprim(access, [Lvar init_id]) | |
+ done | |
+ end; | |
+ List.iter | |
+ (fun (lbl, expr) -> lv.(lbl.lbl_pos) <- transl_exp dec expr) | |
+ lbl_expr_list; | |
+ let ll = Array.to_list lv in | |
+ let mut = | |
+ if List.exists (fun (lbl, expr) -> lbl.lbl_mut = Mutable) lbl_expr_list | |
+ then Mutable | |
+ else Immutable in | |
+ let lam = | |
+ try | |
+ if mut = Mutable then raise Not_constant; | |
+ let cl = List.map extract_constant ll in | |
+ match repres with | |
+ Record_regular -> Lconst(Const_block(0, cl)) | |
+ | Record_float -> | |
+ Lconst(Const_float_array(List.map extract_float cl)) | |
+ with Not_constant -> | |
+ match repres with | |
+ Record_regular -> Lprim(Pmakeblock(0, mut), ll) | |
+ | Record_float -> Lprim(Pmakearray Pfloatarray, ll) in | |
+ begin match opt_init_expr with | |
+ None -> lam | |
+ | Some init_expr -> Llet(Strict, init_id, transl_exp dec init_expr, lam) | |
+ end | |
+ end else begin | |
+ (* Take a shallow copy of the init record, then mutate the fields | |
+ of the copy *) | |
+ (* If you change anything here, you will likely have to change | |
+ [check_recursive_recordwith] in this file. *) | |
+ let copy_id = Ident.create "newrecord" in | |
+ let rec update_field (lbl, expr) cont = | |
+ let upd = | |
+ match lbl.lbl_repres with | |
+ Record_regular -> Psetfield(lbl.lbl_pos, maybe_pointer expr) | |
+ | Record_float -> Psetfloatfield lbl.lbl_pos in | |
+ Lsequence(Lprim(upd, [Lvar copy_id; transl_exp dec expr]), cont) in | |
+ begin match opt_init_expr with | |
+ None -> assert false | |
+ | Some init_expr -> | |
+ Llet(Strict, copy_id, | |
+ Lprim(Pduprecord (repres, size), [transl_exp dec init_expr]), | |
+ List.fold_right update_field lbl_expr_list (Lvar copy_id)) | |
+ end | |
end | |
- end | |
+ | |
+ | |
+let transl_exp = transl_exp None | |
+let transl_apply = transl_apply None | |
+let transl_let = transl_let None | |
(* Wrapper for class compilation *) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment