From 07aba840b163081b1b913b491fe1e8224fb9c1e1 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Tue, 25 Oct 2022 17:01:52 +0200 Subject: [PATCH 1/4] Prevent inlining of async functions Fixes https://github.com/rescript-lang/rescript-compiler/issues/5754 --- CHANGELOG.md | 4 ++++ jscomp/core/lam_analysis.ml | 1 + jscomp/core/lam_pass_lets_dce.ml | 4 ++-- jscomp/core/lam_pass_lets_dce.pp.ml | 4 ++-- jscomp/core/lam_pass_remove_alias.ml | 4 ++-- jscomp/test/async_inline.js | 20 +++++++++++++++++++ jscomp/test/async_inline.res | 12 +++++++++++ jscomp/test/build.ninja | 3 ++- lib/4.06.1/unstable/js_compiler.ml | 9 +++++---- lib/4.06.1/unstable/js_playground_compiler.ml | 9 +++++---- lib/4.06.1/whole_compiler.ml | 9 +++++---- 11 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 jscomp/test/async_inline.js create mode 100644 jscomp/test/async_inline.res diff --git a/CHANGELOG.md b/CHANGELOG.md index eb4e0cd223..fe4933c788 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,12 @@ # 10.1.0-rc.3 +#### :bug: Bug Fix + - Fix issue where the JSX key type is not an optional string https://github.com/rescript-lang/syntax/pull/693 +- Prevent inlining of async functions + # 10.1.0-rc.2 #### :bug: Bug Fix diff --git a/jscomp/core/lam_analysis.ml b/jscomp/core/lam_analysis.ml index 565d45838b..681ecf68aa 100644 --- a/jscomp/core/lam_analysis.ml +++ b/jscomp/core/lam_analysis.ml @@ -247,6 +247,7 @@ let destruct_pattern (body : Lam.t) params args = (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with + | _ when m.attr.async -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( diff --git a/jscomp/core/lam_pass_lets_dce.ml b/jscomp/core/lam_pass_lets_dce.ml index 11c35d10da..7174842262 100644 --- a/jscomp/core/lam_pass_lets_dce.ml +++ b/jscomp/core/lam_pass_lets_dce.ml @@ -147,8 +147,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = end | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) - | Lapply{ap_func = Lfunction{params; body}; ap_args = args; _} - when Ext_list.same_length params args -> + | Lapply{ap_func = Lfunction{params; body; attr}; ap_args = args; _} + when Ext_list.same_length params args && not attr.async -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/jscomp/core/lam_pass_lets_dce.pp.ml b/jscomp/core/lam_pass_lets_dce.pp.ml index b8bd3e4d31..8a77de83be 100644 --- a/jscomp/core/lam_pass_lets_dce.pp.ml +++ b/jscomp/core/lam_pass_lets_dce.pp.ml @@ -146,8 +146,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = end | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) - | Lapply{ap_func = Lfunction{params; body}; ap_args = args; _} - when Ext_list.same_length params args -> + | Lapply{ap_func = Lfunction{params; body; attr}; ap_args = args; _} + when Ext_list.same_length params args && not attr.async -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/jscomp/core/lam_pass_remove_alias.ml b/jscomp/core/lam_pass_remove_alias.ml index 118ecd9be4..185b7759bb 100644 --- a/jscomp/core/lam_pass_remove_alias.ml +++ b/jscomp/core/lam_pass_remove_alias.ml @@ -211,8 +211,8 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = else normal () else normal () | Some _ | None -> normal ()) - | Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ } - when Ext_list.same_length params args -> + | Lapply { ap_func = Lfunction { params; body; attr }; ap_args = args; _ } + when Ext_list.same_length params args && not attr.async -> simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/jscomp/test/async_inline.js b/jscomp/test/async_inline.js new file mode 100644 index 0000000000..80db73efcd --- /dev/null +++ b/jscomp/test/async_inline.js @@ -0,0 +1,20 @@ +'use strict'; + + +async function willBeInlined(param) { + return 3; +} + +var inlined = willBeInlined(undefined); + +function wrapSomethingAsync(param) { + ((async function (param) { + var test = await Promise.resolve("Test"); + console.log(test); + })(777)); +} + +exports.willBeInlined = willBeInlined; +exports.inlined = inlined; +exports.wrapSomethingAsync = wrapSomethingAsync; +/* inlined Not a pure module */ diff --git a/jscomp/test/async_inline.res b/jscomp/test/async_inline.res new file mode 100644 index 0000000000..7ea557bbc1 --- /dev/null +++ b/jscomp/test/async_inline.res @@ -0,0 +1,12 @@ +let willBeInlined = async () => 3 + +let inlined = willBeInlined () + +let wrapSomethingAsync: unit => unit = () => { + let _ = ( + async (_) => { + let test = await Js.Promise.resolve("Test") + Js.log(test) + } + )(777) +} \ No newline at end of file diff --git a/jscomp/test/build.ninja b/jscomp/test/build.ninja index 4d540ff1cf..0940c846b6 100644 --- a/jscomp/test/build.ninja +++ b/jscomp/test/build.ninja @@ -57,6 +57,7 @@ o test/ast_js_mapper_test.cmi : cc test/ast_js_mapper_test.mli | $bsc $stdlib ru o test/ast_mapper_defensive_test.cmi test/ast_mapper_defensive_test.cmj : cc test/ast_mapper_defensive_test.ml | test/mt.cmj $bsc $stdlib runtime o test/ast_mapper_unused_warning_test.cmi test/ast_mapper_unused_warning_test.cmj : cc test/ast_mapper_unused_warning_test.ml | $bsc $stdlib runtime o test/async_ideas.cmi test/async_ideas.cmj : cc test/async_ideas.ml | $bsc $stdlib runtime +o test/async_inline.cmi test/async_inline.cmj : cc test/async_inline.res | $bsc $stdlib runtime o test/attr_test.cmi test/attr_test.cmj : cc test/attr_test.ml | $bsc $stdlib runtime o test/b.cmi test/b.cmj : cc test/b.ml | $bsc $stdlib runtime o test/bal_set_mini.cmi test/bal_set_mini.cmj : cc test/bal_set_mini.ml | $bsc $stdlib runtime @@ -734,4 +735,4 @@ o test/utf8_decode_test.cmi test/utf8_decode_test.cmj : cc test/utf8_decode_test o test/variant.cmi test/variant.cmj : cc test/variant.ml | $bsc $stdlib runtime o test/watch_test.cmi test/watch_test.cmj : cc test/watch_test.ml | $bsc $stdlib runtime o test/webpack_config.cmi test/webpack_config.cmj : cc test/webpack_config.ml | $bsc $stdlib runtime -o test : phony test/406_primitive_test.cmi test/406_primitive_test.cmj test/EmptyRecord.cmi test/EmptyRecord.cmj test/SafePromises.cmi test/SafePromises.cmj test/a.cmi test/a.cmj test/a_filename_test.cmi test/a_filename_test.cmj test/a_list_test.cmi test/a_list_test.cmj test/a_recursive_type.cmi test/a_recursive_type.cmj test/a_scope_bug.cmi test/a_scope_bug.cmj test/a_string_test.cmi test/a_string_test.cmj test/abstract_type.cmi test/abstract_type.cmj test/adt_optimize_test.cmi test/adt_optimize_test.cmj test/alias_test.cmi test/alias_test.cmj test/and_or_tailcall_test.cmi test/and_or_tailcall_test.cmj test/app_root_finder.cmi test/app_root_finder.cmj test/argv_test.cmi test/argv_test.cmj test/ari_regress_test.cmi test/ari_regress_test.cmj test/arith_lexer.cmi test/arith_lexer.cmj test/arith_parser.cmi test/arith_parser.cmj test/arith_syntax.cmi test/arith_syntax.cmj test/arity.cmi test/arity.cmj test/arity_deopt.cmi test/arity_deopt.cmj test/arity_infer.cmi test/arity_infer.cmj test/arity_ml.cmi test/arity_ml.cmj test/array_data_util.cmi test/array_data_util.cmj test/array_safe_get.cmi test/array_safe_get.cmj test/array_subtle_test.cmi test/array_subtle_test.cmj test/array_test.cmi test/array_test.cmj test/ast_abstract_test.cmi test/ast_abstract_test.cmj test/ast_js_mapper_poly_test.cmi test/ast_js_mapper_poly_test.cmj test/ast_js_mapper_test.cmi test/ast_js_mapper_test.cmj test/ast_mapper_defensive_test.cmi test/ast_mapper_defensive_test.cmj test/ast_mapper_unused_warning_test.cmi test/ast_mapper_unused_warning_test.cmj test/async_ideas.cmi test/async_ideas.cmj test/attr_test.cmi test/attr_test.cmj test/b.cmi test/b.cmj test/bal_set_mini.cmi test/bal_set_mini.cmj test/bang_primitive.cmi test/bang_primitive.cmj test/basic_module_test.cmi test/basic_module_test.cmj test/bb.cmi test/bb.cmj test/bdd.cmi test/bdd.cmj test/belt_internal_test.cmi test/belt_internal_test.cmj test/belt_result_alias_test.cmi test/belt_result_alias_test.cmj test/bench.cmi test/bench.cmj test/big_enum.cmi test/big_enum.cmj test/big_polyvar_test.cmi test/big_polyvar_test.cmj test/block_alias_test.cmi test/block_alias_test.cmj test/boolean_test.cmi test/boolean_test.cmj test/bs_MapInt_test.cmi test/bs_MapInt_test.cmj test/bs_abstract_test.cmi test/bs_abstract_test.cmj test/bs_array_test.cmi test/bs_array_test.cmj test/bs_auto_uncurry.cmi test/bs_auto_uncurry.cmj test/bs_auto_uncurry_test.cmi test/bs_auto_uncurry_test.cmj test/bs_float_test.cmi test/bs_float_test.cmj test/bs_hashmap_test.cmi test/bs_hashmap_test.cmj test/bs_hashset_int_test.cmi test/bs_hashset_int_test.cmj test/bs_hashtbl_string_test.cmi test/bs_hashtbl_string_test.cmj test/bs_ignore_effect.cmi test/bs_ignore_effect.cmj test/bs_ignore_test.cmi test/bs_ignore_test.cmj test/bs_int_test.cmi test/bs_int_test.cmj test/bs_list_test.cmi test/bs_list_test.cmj test/bs_map_set_dict_test.cmi test/bs_map_set_dict_test.cmj test/bs_map_test.cmi test/bs_map_test.cmj test/bs_min_max_test.cmi test/bs_min_max_test.cmj test/bs_mutable_set_test.cmi test/bs_mutable_set_test.cmj test/bs_node_string_buffer_test.cmi test/bs_node_string_buffer_test.cmj test/bs_poly_map_test.cmi test/bs_poly_map_test.cmj test/bs_poly_mutable_map_test.cmi test/bs_poly_mutable_map_test.cmj test/bs_poly_mutable_set_test.cmi test/bs_poly_mutable_set_test.cmj test/bs_poly_set_test.cmi test/bs_poly_set_test.cmj test/bs_qualified.cmi test/bs_qualified.cmj test/bs_queue_test.cmi test/bs_queue_test.cmj test/bs_rbset_int_bench.cmi test/bs_rbset_int_bench.cmj test/bs_rest_test.cmi test/bs_rest_test.cmj test/bs_set_bench.cmi test/bs_set_bench.cmj test/bs_set_int_test.cmi test/bs_set_int_test.cmj test/bs_sort_test.cmi test/bs_sort_test.cmj test/bs_splice_partial.cmi test/bs_splice_partial.cmj test/bs_stack_test.cmi test/bs_stack_test.cmj test/bs_string_test.cmi test/bs_string_test.cmj test/bs_unwrap_test.cmi test/bs_unwrap_test.cmj test/buffer_test.cmi test/buffer_test.cmj test/bytes_split_gpr_743_test.cmi test/bytes_split_gpr_743_test.cmj test/caml_compare_test.cmi test/caml_compare_test.cmj test/caml_format_test.cmi test/caml_format_test.cmj test/caml_sys_poly_fill_test.cmi test/caml_sys_poly_fill_test.cmj test/chain_code_test.cmi test/chain_code_test.cmj test/chn_test.cmi test/chn_test.cmj test/class_setter_getter.cmi test/class_setter_getter.cmj test/class_type_ffi_test.cmi test/class_type_ffi_test.cmj test/coercion_module_alias_test.cmi test/coercion_module_alias_test.cmj test/compare_test.cmi test/compare_test.cmj test/complete_parmatch_test.cmi test/complete_parmatch_test.cmj test/complex_if_test.cmi test/complex_if_test.cmj test/complex_test.cmi test/complex_test.cmj test/complex_while_loop.cmi test/complex_while_loop.cmj test/condition_compilation_test.cmi test/condition_compilation_test.cmj test/config1_test.cmi test/config1_test.cmj test/config2_test.cmi test/config2_test.cmj test/console_log_test.cmi test/console_log_test.cmj test/const_block_test.cmi test/const_block_test.cmj test/const_defs.cmi test/const_defs.cmj test/const_defs_test.cmi test/const_defs_test.cmj test/const_test.cmi test/const_test.cmj test/cont_int_fold_test.cmi test/cont_int_fold_test.cmj test/cps_test.cmi test/cps_test.cmj test/cross_module_inline_test.cmi test/cross_module_inline_test.cmj test/custom_error_test.cmi test/custom_error_test.cmj test/debug_keep_test.cmi test/debug_keep_test.cmj test/debug_mode_value.cmi test/debug_mode_value.cmj test/debug_tmp.cmi test/debug_tmp.cmj test/debugger_test.cmi test/debugger_test.cmj test/default_export_test.cmi test/default_export_test.cmj test/defunctor_make_test.cmi test/defunctor_make_test.cmj test/demo.cmi test/demo.cmj test/demo_binding.cmi test/demo_binding.cmj test/demo_int_map.cmi test/demo_int_map.cmj test/demo_page.cmi test/demo_page.cmj test/demo_pipe.cmi test/demo_pipe.cmj test/derive_dyntype.cmi test/derive_dyntype.cmj test/derive_projector_test.cmi test/derive_projector_test.cmj test/derive_type_test.cmi test/derive_type_test.cmj test/digest_test.cmi test/digest_test.cmj test/div_by_zero_test.cmi test/div_by_zero_test.cmj test/dollar_escape_test.cmi test/dollar_escape_test.cmj test/earger_curry_test.cmi test/earger_curry_test.cmj test/effect.cmi test/effect.cmj test/epsilon_test.cmi test/epsilon_test.cmj test/equal_box_test.cmi test/equal_box_test.cmj test/equal_exception_test.cmi test/equal_exception_test.cmj test/equal_test.cmi test/equal_test.cmj test/es6_export.cmi test/es6_export.cmj test/es6_import.cmi test/es6_import.cmj test/es6_module_test.cmi test/es6_module_test.cmj test/escape_esmodule.cmi test/escape_esmodule.cmj test/esmodule_ref.cmi test/esmodule_ref.cmj test/event_ffi.cmi test/event_ffi.cmj test/exception_alias.cmi test/exception_alias.cmj test/exception_def.cmi test/exception_def.cmj test/exception_raise_test.cmi test/exception_raise_test.cmj test/exception_rebind_test.cmi test/exception_rebind_test.cmj test/exception_rebound_err_test.cmi test/exception_rebound_err_test.cmj test/exception_repr_test.cmi test/exception_repr_test.cmj test/exception_value_test.cmi test/exception_value_test.cmj test/exn_error_pattern.cmi test/exn_error_pattern.cmj test/export_keyword.cmi test/export_keyword.cmj test/ext_array_test.cmi test/ext_array_test.cmj test/ext_bytes_test.cmi test/ext_bytes_test.cmj test/ext_filename_test.cmi test/ext_filename_test.cmj test/ext_list_test.cmi test/ext_list_test.cmj test/ext_pervasives_test.cmi test/ext_pervasives_test.cmj test/ext_string_test.cmi test/ext_string_test.cmj test/ext_sys_test.cmi test/ext_sys_test.cmj test/extensible_variant_test.cmi test/extensible_variant_test.cmj test/external_polyfill_test.cmi test/external_polyfill_test.cmj test/external_ppx.cmi test/external_ppx.cmj test/external_ppx2.cmi test/external_ppx2.cmj test/fail_comp.cmi test/fail_comp.cmj test/ffi_arity_test.cmi test/ffi_arity_test.cmj test/ffi_array_test.cmi test/ffi_array_test.cmj test/ffi_js_test.cmi test/ffi_js_test.cmj test/ffi_splice_test.cmi test/ffi_splice_test.cmj test/ffi_test.cmi test/ffi_test.cmj test/fib.cmi test/fib.cmj test/flattern_order_test.cmi test/flattern_order_test.cmj test/flexible_array_test.cmi test/flexible_array_test.cmj test/float_array.cmi test/float_array.cmj test/float_of_bits_test.cmi test/float_of_bits_test.cmj test/float_record.cmi test/float_record.cmj test/float_test.cmi test/float_test.cmj test/floatarray_test.cmi test/floatarray_test.cmj test/flow_parser_reg_test.cmi test/flow_parser_reg_test.cmj test/for_loop_test.cmi test/for_loop_test.cmj test/for_side_effect_test.cmi test/for_side_effect_test.cmj test/format_regression.cmi test/format_regression.cmj test/format_test.cmi test/format_test.cmj test/fs_test.cmi test/fs_test.cmj test/fun_pattern_match.cmi test/fun_pattern_match.cmj test/functor_app_test.cmi test/functor_app_test.cmj test/functor_def.cmi test/functor_def.cmj test/functor_ffi.cmi test/functor_ffi.cmj test/functor_inst.cmi test/functor_inst.cmj test/functors.cmi test/functors.cmj test/gbk.cmi test/gbk.cmj test/genlex_test.cmi test/genlex_test.cmj test/gentTypeReTest.cmi test/gentTypeReTest.cmj test/global_exception_regression_test.cmi test/global_exception_regression_test.cmj test/global_mangles.cmi test/global_mangles.cmj test/global_module_alias_test.cmi test/global_module_alias_test.cmj test/google_closure_test.cmi test/google_closure_test.cmj test/gpr496_test.cmi test/gpr496_test.cmj test/gpr_1063_test.cmi test/gpr_1063_test.cmj test/gpr_1072.cmi test/gpr_1072.cmj test/gpr_1072_reg.cmi test/gpr_1072_reg.cmj test/gpr_1150.cmi test/gpr_1150.cmj test/gpr_1154_test.cmi test/gpr_1154_test.cmj test/gpr_1170.cmi test/gpr_1170.cmj test/gpr_1240_missing_unbox.cmi test/gpr_1240_missing_unbox.cmj test/gpr_1245_test.cmi test/gpr_1245_test.cmj test/gpr_1268.cmi test/gpr_1268.cmj test/gpr_1409_test.cmi test/gpr_1409_test.cmj test/gpr_1423_app_test.cmi test/gpr_1423_app_test.cmj test/gpr_1423_nav.cmi test/gpr_1423_nav.cmj test/gpr_1438.cmi test/gpr_1438.cmj test/gpr_1481.cmi test/gpr_1481.cmj test/gpr_1484.cmi test/gpr_1484.cmj test/gpr_1501_test.cmi test/gpr_1501_test.cmj test/gpr_1503_test.cmi test/gpr_1503_test.cmj test/gpr_1539_test.cmi test/gpr_1539_test.cmj test/gpr_1600_test.cmi test/gpr_1600_test.cmj test/gpr_1658_test.cmi test/gpr_1658_test.cmj test/gpr_1667_test.cmi test/gpr_1667_test.cmj test/gpr_1692_test.cmi test/gpr_1692_test.cmj test/gpr_1698_test.cmi test/gpr_1698_test.cmj test/gpr_1701_test.cmi test/gpr_1701_test.cmj test/gpr_1716_test.cmi test/gpr_1716_test.cmj test/gpr_1717_test.cmi test/gpr_1717_test.cmj test/gpr_1728_test.cmi test/gpr_1728_test.cmj test/gpr_1749_test.cmi test/gpr_1749_test.cmj test/gpr_1759_test.cmi test/gpr_1759_test.cmj test/gpr_1760_test.cmi test/gpr_1760_test.cmj test/gpr_1762_test.cmi test/gpr_1762_test.cmj test/gpr_1817_test.cmi test/gpr_1817_test.cmj test/gpr_1822_test.cmi test/gpr_1822_test.cmj test/gpr_1891_test.cmi test/gpr_1891_test.cmj test/gpr_1943_test.cmi test/gpr_1943_test.cmj test/gpr_1946_test.cmi test/gpr_1946_test.cmj test/gpr_2316_test.cmi test/gpr_2316_test.cmj test/gpr_2352_test.cmi test/gpr_2352_test.cmj test/gpr_2413_test.cmi test/gpr_2413_test.cmj test/gpr_2474.cmi test/gpr_2474.cmj test/gpr_2487.cmi test/gpr_2487.cmj test/gpr_2503_test.cmi test/gpr_2503_test.cmj test/gpr_2608_test.cmi test/gpr_2608_test.cmj test/gpr_2614_test.cmi test/gpr_2614_test.cmj test/gpr_2633_test.cmi test/gpr_2633_test.cmj test/gpr_2642_test.cmi test/gpr_2642_test.cmj test/gpr_2652_test.cmi test/gpr_2652_test.cmj test/gpr_2682_test.cmi test/gpr_2682_test.cmj test/gpr_2700_test.cmi test/gpr_2700_test.cmj test/gpr_2731_test.cmi test/gpr_2731_test.cmj test/gpr_2789_test.cmi test/gpr_2789_test.cmj test/gpr_2931_test.cmi test/gpr_2931_test.cmj test/gpr_3142_test.cmi test/gpr_3142_test.cmj test/gpr_3154_test.cmi test/gpr_3154_test.cmj test/gpr_3209_test.cmi test/gpr_3209_test.cmj test/gpr_3492_test.cmi test/gpr_3492_test.cmj test/gpr_3519_jsx_test.cmi test/gpr_3519_jsx_test.cmj test/gpr_3519_test.cmi test/gpr_3519_test.cmj test/gpr_3536_test.cmi test/gpr_3536_test.cmj test/gpr_3546_test.cmi test/gpr_3546_test.cmj test/gpr_3548_test.cmi test/gpr_3548_test.cmj test/gpr_3549_test.cmi test/gpr_3549_test.cmj test/gpr_3566_drive_test.cmi test/gpr_3566_drive_test.cmj test/gpr_3566_test.cmi test/gpr_3566_test.cmj test/gpr_3595_test.cmi test/gpr_3595_test.cmj test/gpr_3609_test.cmi test/gpr_3609_test.cmj test/gpr_3697_test.cmi test/gpr_3697_test.cmj test/gpr_373_test.cmi test/gpr_373_test.cmj test/gpr_3770_test.cmi test/gpr_3770_test.cmj test/gpr_3852_alias.cmi test/gpr_3852_alias.cmj test/gpr_3852_alias_reify.cmi test/gpr_3852_alias_reify.cmj test/gpr_3852_effect.cmi test/gpr_3852_effect.cmj test/gpr_3865.cmi test/gpr_3865.cmj test/gpr_3865_bar.cmi test/gpr_3865_bar.cmj test/gpr_3865_foo.cmi test/gpr_3865_foo.cmj test/gpr_3875_test.cmi test/gpr_3875_test.cmj test/gpr_3877_test.cmi test/gpr_3877_test.cmj test/gpr_3895_test.cmi test/gpr_3895_test.cmj test/gpr_3897_test.cmi test/gpr_3897_test.cmj test/gpr_3931_test.cmi test/gpr_3931_test.cmj test/gpr_3980_test.cmi test/gpr_3980_test.cmj test/gpr_4025_test.cmi test/gpr_4025_test.cmj test/gpr_405_test.cmi test/gpr_405_test.cmj test/gpr_4069_test.cmi test/gpr_4069_test.cmj test/gpr_4265_test.cmi test/gpr_4265_test.cmj test/gpr_4274_test.cmi test/gpr_4274_test.cmj test/gpr_4280_test.cmi test/gpr_4280_test.cmj test/gpr_4407_test.cmi test/gpr_4407_test.cmj test/gpr_441.cmi test/gpr_441.cmj test/gpr_4442_test.cmi test/gpr_4442_test.cmj test/gpr_4491_test.cmi test/gpr_4491_test.cmj test/gpr_4494_test.cmi test/gpr_4494_test.cmj test/gpr_4519_test.cmi test/gpr_4519_test.cmj test/gpr_459_test.cmi test/gpr_459_test.cmj test/gpr_4632.cmi test/gpr_4632.cmj test/gpr_4639_test.cmi test/gpr_4639_test.cmj test/gpr_4900_test.cmi test/gpr_4900_test.cmj test/gpr_4924_test.cmi test/gpr_4924_test.cmj test/gpr_4931.cmi test/gpr_4931.cmj test/gpr_4931_allow.cmi test/gpr_4931_allow.cmj test/gpr_5071_test.cmi test/gpr_5071_test.cmj test/gpr_5169_test.cmi test/gpr_5169_test.cmj test/gpr_5218_test.cmi test/gpr_5218_test.cmj test/gpr_5280_optimize_test.cmi test/gpr_5280_optimize_test.cmj test/gpr_5312.cmi test/gpr_5312.cmj test/gpr_627_test.cmi test/gpr_627_test.cmj test/gpr_658.cmi test/gpr_658.cmj test/gpr_858_test.cmi test/gpr_858_test.cmj test/gpr_858_unit2_test.cmi test/gpr_858_unit2_test.cmj test/gpr_904_test.cmi test/gpr_904_test.cmj test/gpr_974_test.cmi test/gpr_974_test.cmj test/gpr_977_test.cmi test/gpr_977_test.cmj test/gpr_return_type_unused_attribute.cmi test/gpr_return_type_unused_attribute.cmj test/gray_code_test.cmi test/gray_code_test.cmj test/guide_for_ext.cmi test/guide_for_ext.cmj test/hamming_test.cmi test/hamming_test.cmj test/hash_collision_test.cmi test/hash_collision_test.cmj test/hash_sugar_desugar.cmi test/hash_sugar_desugar.cmj test/hash_test.cmi test/hash_test.cmj test/hashtbl_test.cmi test/hashtbl_test.cmj test/hello.foo.cmi test/hello.foo.cmj test/hello_res.cmi test/hello_res.cmj test/http_types.cmi test/http_types.cmj test/ignore_test.cmi test/ignore_test.cmj test/imm_map_bench.cmi test/imm_map_bench.cmj test/include_side_effect.cmi test/include_side_effect.cmj test/include_side_effect_free.cmi test/include_side_effect_free.cmj test/incomplete_toplevel_test.cmi test/incomplete_toplevel_test.cmj test/infer_type_test.cmi test/infer_type_test.cmj test/inline_const.cmi test/inline_const.cmj test/inline_const_test.cmi test/inline_const_test.cmj test/inline_edge_cases.cmi test/inline_edge_cases.cmj test/inline_map2_test.cmi test/inline_map2_test.cmj test/inline_map_demo.cmi test/inline_map_demo.cmj test/inline_map_test.cmi test/inline_map_test.cmj test/inline_record_test.cmi test/inline_record_test.cmj test/inline_regression_test.cmi test/inline_regression_test.cmj test/inline_string_test.cmi test/inline_string_test.cmj test/inner_call.cmi test/inner_call.cmj test/inner_define.cmi test/inner_define.cmj test/inner_unused.cmi test/inner_unused.cmj test/installation_test.cmi test/installation_test.cmj test/int32_test.cmi test/int32_test.cmj test/int64_mul_div_test.cmi test/int64_mul_div_test.cmj test/int64_string_bench.cmi test/int64_string_bench.cmj test/int64_string_test.cmi test/int64_string_test.cmj test/int64_test.cmi test/int64_test.cmj test/int_hashtbl_test.cmi test/int_hashtbl_test.cmj test/int_map.cmi test/int_map.cmj test/int_overflow_test.cmi test/int_overflow_test.cmj test/int_poly_var.cmi test/int_poly_var.cmj test/int_switch_test.cmi test/int_switch_test.cmj test/internal_unused_test.cmi test/internal_unused_test.cmj test/io_test.cmi test/io_test.cmj test/js_array_test.cmi test/js_array_test.cmj test/js_bool_test.cmi test/js_bool_test.cmj test/js_cast_test.cmi test/js_cast_test.cmj test/js_date_test.cmi test/js_date_test.cmj test/js_dict_test.cmi test/js_dict_test.cmj test/js_exception_catch_test.cmi test/js_exception_catch_test.cmj test/js_float_test.cmi test/js_float_test.cmj test/js_global_test.cmi test/js_global_test.cmj test/js_int_test.cmi test/js_int_test.cmj test/js_json_test.cmi test/js_json_test.cmj test/js_list_test.cmi test/js_list_test.cmj test/js_math_test.cmi test/js_math_test.cmj test/js_null_test.cmi test/js_null_test.cmj test/js_null_undefined_test.cmi test/js_null_undefined_test.cmj test/js_nullable_test.cmi test/js_nullable_test.cmj test/js_obj_test.cmi test/js_obj_test.cmj test/js_option_test.cmi test/js_option_test.cmj test/js_promise_basic_test.cmi test/js_promise_basic_test.cmj test/js_re_test.cmi test/js_re_test.cmj test/js_string_test.cmi test/js_string_test.cmj test/js_typed_array_test.cmi test/js_typed_array_test.cmj test/js_undefined_test.cmi test/js_undefined_test.cmj test/js_val.cmi test/js_val.cmj test/jsoo_400_test.cmi test/jsoo_400_test.cmj test/jsoo_485_test.cmi test/jsoo_485_test.cmj test/key_word_property.cmi test/key_word_property.cmj test/key_word_property2.cmi test/key_word_property2.cmj test/key_word_property_plus_test.cmi test/key_word_property_plus_test.cmj test/label_uncurry.cmi test/label_uncurry.cmj test/large_integer_pat.cmi test/large_integer_pat.cmj test/large_record_duplication_test.cmi test/large_record_duplication_test.cmj test/largest_int_flow.cmi test/largest_int_flow.cmj test/lazy_demo.cmi test/lazy_demo.cmj test/lazy_test.cmi test/lazy_test.cmj test/lexer_test.cmi test/lexer_test.cmj test/lib_js_test.cmi test/lib_js_test.cmj test/libarg_test.cmi test/libarg_test.cmj test/libqueue_test.cmi test/libqueue_test.cmj test/limits_test.cmi test/limits_test.cmj test/list_stack.cmi test/list_stack.cmj test/list_test.cmi test/list_test.cmj test/local_class_type.cmi test/local_class_type.cmj test/local_exception_test.cmi test/local_exception_test.cmj test/loop_regression_test.cmi test/loop_regression_test.cmj test/loop_suites_test.cmi test/loop_suites_test.cmj test/map_find_test.cmi test/map_find_test.cmj test/map_test.cmi test/map_test.cmj test/mario_game.cmi test/mario_game.cmj test/marshal.cmi test/marshal.cmj test/method_chain.cmi test/method_chain.cmj test/method_name_test.cmi test/method_name_test.cmj test/method_string_name.cmi test/method_string_name.cmj test/minimal_test.cmi test/minimal_test.cmj test/miss_colon_test.cmi test/miss_colon_test.cmj test/mock_mt.cmi test/mock_mt.cmj test/module_alias_test.cmi test/module_alias_test.cmj test/module_as_class_ffi.cmi test/module_as_class_ffi.cmj test/module_as_function.cmi test/module_as_function.cmj test/module_missing_conversion.cmi test/module_missing_conversion.cmj test/module_parameter_test.cmi test/module_parameter_test.cmj test/module_splice_test.cmi test/module_splice_test.cmj test/more_poly_variant_test.cmi test/more_poly_variant_test.cmj test/more_uncurry.cmi test/more_uncurry.cmj test/mpr_6033_test.cmi test/mpr_6033_test.cmj test/mt.cmi test/mt.cmj test/mt_global.cmi test/mt_global.cmj test/mutable_obj_test.cmi test/mutable_obj_test.cmj test/mutable_uncurry_test.cmi test/mutable_uncurry_test.cmj test/mutual_non_recursive_type.cmi test/mutual_non_recursive_type.cmj test/name_mangle_test.cmi test/name_mangle_test.cmj test/nested_include.cmi test/nested_include.cmj test/nested_module_alias.cmi test/nested_module_alias.cmj test/nested_obj_literal.cmi test/nested_obj_literal.cmj test/nested_obj_test.cmi test/nested_obj_test.cmj test/nested_pattern_match_test.cmi test/nested_pattern_match_test.cmj test/noassert.cmi test/noassert.cmj test/node_fs_test.cmi test/node_fs_test.cmj test/node_path_test.cmi test/node_path_test.cmj test/null_list_test.cmi test/null_list_test.cmj test/number_lexer.cmi test/number_lexer.cmj test/obj_literal_ppx.cmi test/obj_literal_ppx.cmj test/obj_literal_ppx_test.cmi test/obj_literal_ppx_test.cmj test/obj_magic_test.cmi test/obj_magic_test.cmj test/obj_type_test.cmi test/obj_type_test.cmj test/ocaml_re_test.cmi test/ocaml_re_test.cmj test/of_string_test.cmi test/of_string_test.cmj test/offset.cmi test/offset.cmj test/oo_js_test_date.cmi test/oo_js_test_date.cmj test/option_encoding_test.cmi test/option_encoding_test.cmj test/option_record_none_test.cmi test/option_record_none_test.cmj test/option_repr_test.cmi test/option_repr_test.cmj test/optional_ffi_test.cmi test/optional_ffi_test.cmj test/optional_regression_test.cmi test/optional_regression_test.cmj test/pipe_send_readline.cmi test/pipe_send_readline.cmj test/pipe_syntax.cmi test/pipe_syntax.cmj test/poly_empty_array.cmi test/poly_empty_array.cmj test/poly_type.cmi test/poly_type.cmj test/poly_variant_test.cmi test/poly_variant_test.cmj test/polymorphic_raw_test.cmi test/polymorphic_raw_test.cmj test/polymorphism_test.cmi test/polymorphism_test.cmj test/polyvar_convert.cmi test/polyvar_convert.cmj test/polyvar_test.cmi test/polyvar_test.cmj test/ppx_apply_test.cmi test/ppx_apply_test.cmj test/ppx_this_obj_field.cmi test/ppx_this_obj_field.cmj test/ppx_this_obj_test.cmi test/ppx_this_obj_test.cmj test/pq_test.cmi test/pq_test.cmj test/pr6726.cmi test/pr6726.cmj test/pr_regression_test.cmi test/pr_regression_test.cmj test/prepend_data_ffi.cmi test/prepend_data_ffi.cmj test/primitive_reg_test.cmi test/primitive_reg_test.cmj test/print_alpha_test.cmi test/print_alpha_test.cmj test/promise.cmi test/promise.cmj test/promise_catch_test.cmi test/promise_catch_test.cmj test/queue_402.cmi test/queue_402.cmj test/queue_test.cmi test/queue_test.cmj test/random_test.cmi test/random_test.cmj test/raw_hash_tbl_bench.cmi test/raw_hash_tbl_bench.cmj test/raw_output_test.cmi test/raw_output_test.cmj test/raw_pure_test.cmi test/raw_pure_test.cmj test/rbset.cmi test/rbset.cmj test/react.cmi test/react.cmj test/reactDOMRe.cmi test/reactDOMRe.cmj test/reactDOMServerRe.cmi test/reactDOMServerRe.cmj test/reactEvent.cmi test/reactEvent.cmj test/reactTestUtils.cmi test/reactTestUtils.cmj test/reasonReact.cmi test/reasonReact.cmj test/reasonReactCompat.cmi test/reasonReactCompat.cmj test/reasonReactOptimizedCreateClass.cmi test/reasonReactOptimizedCreateClass.cmj test/reasonReactRouter.cmi test/reasonReactRouter.cmj test/rebind_module.cmi test/rebind_module.cmj test/rebind_module_test.cmi test/rebind_module_test.cmj test/rec_array_test.cmi test/rec_array_test.cmj test/rec_fun_test.cmi test/rec_fun_test.cmj test/rec_module_opt.cmi test/rec_module_opt.cmj test/rec_module_test.cmi test/rec_module_test.cmj test/rec_value_test.cmi test/rec_value_test.cmj test/record_debug_test.cmi test/record_debug_test.cmj test/record_extension_test.cmi test/record_extension_test.cmj test/record_name_test.cmi test/record_name_test.cmj test/record_regression.cmi test/record_regression.cmj test/record_with_test.cmi test/record_with_test.cmj test/recursive_module.cmi test/recursive_module.cmj test/recursive_module_test.cmi test/recursive_module_test.cmj test/recursive_react_component.cmi test/recursive_react_component.cmj test/recursive_records_test.cmi test/recursive_records_test.cmj test/recursive_unbound_module_test.cmi test/recursive_unbound_module_test.cmj test/regression_print.cmi test/regression_print.cmj test/relative_path.cmi test/relative_path.cmj test/res_debug.cmi test/res_debug.cmj test/return_check.cmi test/return_check.cmj test/runtime_encoding_test.cmi test/runtime_encoding_test.cmj test/set_gen.cmi test/set_gen.cmj test/sexp.cmi test/sexp.cmj test/sexpm.cmi test/sexpm.cmj test/sexpm_test.cmi test/sexpm_test.cmj test/side_effect.cmi test/side_effect.cmj test/side_effect_free.cmi test/side_effect_free.cmj test/simple_derive_test.cmi test/simple_derive_test.cmj test/simple_derive_use.cmi test/simple_derive_use.cmj test/simple_lexer_test.cmi test/simple_lexer_test.cmj test/simplify_lambda_632o.cmi test/simplify_lambda_632o.cmj test/single_module_alias.cmi test/single_module_alias.cmj test/singular_unit_test.cmi test/singular_unit_test.cmj test/small_inline_test.cmi test/small_inline_test.cmj test/splice_test.cmi test/splice_test.cmj test/stack_comp_test.cmi test/stack_comp_test.cmj test/stack_test.cmi test/stack_test.cmj test/stream_parser_test.cmi test/stream_parser_test.cmj test/string_bound_get_test.cmi test/string_bound_get_test.cmj test/string_get_set_test.cmi test/string_get_set_test.cmj test/string_interp_test.cmi test/string_interp_test.cmj test/string_literal_print_test.cmi test/string_literal_print_test.cmj test/string_runtime_test.cmi test/string_runtime_test.cmj test/string_set.cmi test/string_set.cmj test/string_set_test.cmi test/string_set_test.cmj test/string_test.cmi test/string_test.cmj test/string_unicode_test.cmi test/string_unicode_test.cmj test/stringmatch_test.cmi test/stringmatch_test.cmj test/submodule.cmi test/submodule.cmj test/submodule_call.cmi test/submodule_call.cmj test/switch_case_test.cmi test/switch_case_test.cmj test/tailcall_inline_test.cmi test/tailcall_inline_test.cmj test/template.cmi test/template.cmj test/test.cmi test/test.cmj test/test2.cmi test/test2.cmj test/test_alias.cmi test/test_alias.cmj test/test_ari.cmi test/test_ari.cmj test/test_array.cmi test/test_array.cmj test/test_array_append.cmi test/test_array_append.cmj test/test_array_primitive.cmi test/test_array_primitive.cmj test/test_bool_equal.cmi test/test_bool_equal.cmj test/test_bs_this.cmi test/test_bs_this.cmj test/test_bug.cmi test/test_bug.cmj test/test_bytes.cmi test/test_bytes.cmj test/test_case_opt_collision.cmi test/test_case_opt_collision.cmj test/test_case_set.cmi test/test_case_set.cmj test/test_char.cmi test/test_char.cmj test/test_closure.cmi test/test_closure.cmj test/test_common.cmi test/test_common.cmj test/test_const_elim.cmi test/test_const_elim.cmj test/test_const_propogate.cmi test/test_const_propogate.cmj test/test_cpp.cmi test/test_cpp.cmj test/test_cps.cmi test/test_cps.cmj test/test_demo.cmi test/test_demo.cmj test/test_dup_param.cmi test/test_dup_param.cmj test/test_eq.cmi test/test_eq.cmj test/test_exception.cmi test/test_exception.cmj test/test_exception_escape.cmi test/test_exception_escape.cmj test/test_export2.cmi test/test_export2.cmj test/test_external.cmi test/test_external.cmj test/test_external_unit.cmi test/test_external_unit.cmj test/test_ffi.cmi test/test_ffi.cmj test/test_fib.cmi test/test_fib.cmj test/test_filename.cmi test/test_filename.cmj test/test_for_loop.cmi test/test_for_loop.cmj test/test_for_map.cmi test/test_for_map.cmj test/test_for_map2.cmi test/test_for_map2.cmj test/test_format.cmi test/test_format.cmj test/test_formatter.cmi test/test_formatter.cmj test/test_functor_dead_code.cmi test/test_functor_dead_code.cmj test/test_generative_module.cmi test/test_generative_module.cmj test/test_global_print.cmi test/test_global_print.cmj test/test_google_closure.cmi test/test_google_closure.cmj test/test_http_server.cmi test/test_http_server.cmj test/test_include.cmi test/test_include.cmj test/test_incomplete.cmi test/test_incomplete.cmj test/test_incr_ref.cmi test/test_incr_ref.cmj test/test_index.cmi test/test_index.cmj test/test_int_map_find.cmi test/test_int_map_find.cmj test/test_internalOO.cmi test/test_internalOO.cmj test/test_is_js.cmi test/test_is_js.cmj test/test_js_ffi.cmi test/test_js_ffi.cmj test/test_let.cmi test/test_let.cmj test/test_list.cmi test/test_list.cmj test/test_literal.cmi test/test_literal.cmj test/test_literals.cmi test/test_literals.cmj test/test_match_exception.cmi test/test_match_exception.cmj test/test_mutliple.cmi test/test_mutliple.cmj test/test_nat64.cmi test/test_nat64.cmj test/test_nested_let.cmi test/test_nested_let.cmj test/test_nested_print.cmi test/test_nested_print.cmj test/test_non_export.cmi test/test_non_export.cmj test/test_nullary.cmi test/test_nullary.cmj test/test_obj.cmi test/test_obj.cmj test/test_obj_simple_ffi.cmi test/test_obj_simple_ffi.cmj test/test_order.cmi test/test_order.cmj test/test_order_tailcall.cmi test/test_order_tailcall.cmj test/test_other_exn.cmi test/test_other_exn.cmj test/test_pack.cmi test/test_pack.cmj test/test_per.cmi test/test_per.cmj test/test_pervasive.cmi test/test_pervasive.cmj test/test_pervasives2.cmi test/test_pervasives2.cmj test/test_pervasives3.cmi test/test_pervasives3.cmj test/test_primitive.cmi test/test_primitive.cmj test/test_promise_bind.cmi test/test_promise_bind.cmj test/test_ramification.cmi test/test_ramification.cmj test/test_react.cmi test/test_react.cmj test/test_react_case.cmi test/test_react_case.cmj test/test_regex.cmi test/test_regex.cmj test/test_require.cmi test/test_require.cmj test/test_runtime_encoding.cmi test/test_runtime_encoding.cmj test/test_scope.cmi test/test_scope.cmj test/test_seq.cmi test/test_seq.cmj test/test_set.cmi test/test_set.cmj test/test_side_effect_functor.cmi test/test_side_effect_functor.cmj test/test_simple_include.cmi test/test_simple_include.cmj test/test_simple_pattern_match.cmi test/test_simple_pattern_match.cmj test/test_simple_ref.cmi test/test_simple_ref.cmj test/test_simple_tailcall.cmi test/test_simple_tailcall.cmj test/test_small.cmi test/test_small.cmj test/test_sprintf.cmi test/test_sprintf.cmj test/test_stack.cmi test/test_stack.cmj test/test_static_catch_ident.cmi test/test_static_catch_ident.cmj test/test_string.cmi test/test_string.cmj test/test_string_case.cmi test/test_string_case.cmj test/test_string_const.cmi test/test_string_const.cmj test/test_string_map.cmi test/test_string_map.cmj test/test_string_switch.cmi test/test_string_switch.cmj test/test_switch.cmi test/test_switch.cmj test/test_trywith.cmi test/test_trywith.cmj test/test_tuple.cmi test/test_tuple.cmj test/test_tuple_destructring.cmi test/test_tuple_destructring.cmj test/test_type_based_arity.cmi test/test_type_based_arity.cmj test/test_u.cmi test/test_u.cmj test/test_unknown.cmi test/test_unknown.cmj test/test_unsafe_cmp.cmi test/test_unsafe_cmp.cmj test/test_unsafe_obj_ffi.cmi test/test_unsafe_obj_ffi.cmj test/test_unsafe_obj_ffi_ppx.cmi test/test_unsafe_obj_ffi_ppx.cmj test/test_unsupported_primitive.cmi test/test_unsupported_primitive.cmj test/test_while_closure.cmi test/test_while_closure.cmj test/test_while_side_effect.cmi test/test_while_side_effect.cmj test/test_zero_nullable.cmi test/test_zero_nullable.cmj test/then_mangle_test.cmi test/then_mangle_test.cmj test/ticker.cmi test/ticker.cmj test/to_string_test.cmi test/to_string_test.cmj test/topsort_test.cmi test/topsort_test.cmj test/tramp_fib.cmi test/tramp_fib.cmj test/tuple_alloc.cmi test/tuple_alloc.cmj test/type_disambiguate.cmi test/type_disambiguate.cmj test/typeof_test.cmi test/typeof_test.cmj test/ui_defs.cmi test/unboxed_attribute.cmi test/unboxed_attribute.cmj test/unboxed_attribute_test.cmi test/unboxed_attribute_test.cmj test/unboxed_crash.cmi test/unboxed_crash.cmj test/unboxed_use_case.cmi test/unboxed_use_case.cmj test/uncurry_external_test.cmi test/uncurry_external_test.cmj test/uncurry_glob_test.cmi test/uncurry_glob_test.cmj test/uncurry_method.cmi test/uncurry_method.cmj test/uncurry_test.cmi test/uncurry_test.cmj test/undef_regression2_test.cmi test/undef_regression2_test.cmj test/undef_regression_test.cmi test/undef_regression_test.cmj test/undefine_conditional.cmi test/undefine_conditional.cmj test/unicode_type_error.cmi test/unicode_type_error.cmj test/unit_undefined_test.cmi test/unit_undefined_test.cmj test/unitest_string.cmi test/unitest_string.cmj test/unsafe_full_apply_primitive.cmi test/unsafe_full_apply_primitive.cmj test/unsafe_obj_external.cmi test/unsafe_obj_external.cmj test/unsafe_ppx_test.cmi test/unsafe_ppx_test.cmj test/unsafe_this.cmi test/unsafe_this.cmj test/update_record_test.cmi test/update_record_test.cmj test/utf8_decode_test.cmi test/utf8_decode_test.cmj test/variant.cmi test/variant.cmj test/watch_test.cmi test/watch_test.cmj test/webpack_config.cmi test/webpack_config.cmj +o test : phony test/406_primitive_test.cmi test/406_primitive_test.cmj test/EmptyRecord.cmi test/EmptyRecord.cmj test/SafePromises.cmi test/SafePromises.cmj test/a.cmi test/a.cmj test/a_filename_test.cmi test/a_filename_test.cmj test/a_list_test.cmi test/a_list_test.cmj test/a_recursive_type.cmi test/a_recursive_type.cmj test/a_scope_bug.cmi test/a_scope_bug.cmj test/a_string_test.cmi test/a_string_test.cmj test/abstract_type.cmi test/abstract_type.cmj test/adt_optimize_test.cmi test/adt_optimize_test.cmj test/alias_test.cmi test/alias_test.cmj test/and_or_tailcall_test.cmi test/and_or_tailcall_test.cmj test/app_root_finder.cmi test/app_root_finder.cmj test/argv_test.cmi test/argv_test.cmj test/ari_regress_test.cmi test/ari_regress_test.cmj test/arith_lexer.cmi test/arith_lexer.cmj test/arith_parser.cmi test/arith_parser.cmj test/arith_syntax.cmi test/arith_syntax.cmj test/arity.cmi test/arity.cmj test/arity_deopt.cmi test/arity_deopt.cmj test/arity_infer.cmi test/arity_infer.cmj test/arity_ml.cmi test/arity_ml.cmj test/array_data_util.cmi test/array_data_util.cmj test/array_safe_get.cmi test/array_safe_get.cmj test/array_subtle_test.cmi test/array_subtle_test.cmj test/array_test.cmi test/array_test.cmj test/ast_abstract_test.cmi test/ast_abstract_test.cmj test/ast_js_mapper_poly_test.cmi test/ast_js_mapper_poly_test.cmj test/ast_js_mapper_test.cmi test/ast_js_mapper_test.cmj test/ast_mapper_defensive_test.cmi test/ast_mapper_defensive_test.cmj test/ast_mapper_unused_warning_test.cmi test/ast_mapper_unused_warning_test.cmj test/async_ideas.cmi test/async_ideas.cmj test/async_inline.cmi test/async_inline.cmj test/attr_test.cmi test/attr_test.cmj test/b.cmi test/b.cmj test/bal_set_mini.cmi test/bal_set_mini.cmj test/bang_primitive.cmi test/bang_primitive.cmj test/basic_module_test.cmi test/basic_module_test.cmj test/bb.cmi test/bb.cmj test/bdd.cmi test/bdd.cmj test/belt_internal_test.cmi test/belt_internal_test.cmj test/belt_result_alias_test.cmi test/belt_result_alias_test.cmj test/bench.cmi test/bench.cmj test/big_enum.cmi test/big_enum.cmj test/big_polyvar_test.cmi test/big_polyvar_test.cmj test/block_alias_test.cmi test/block_alias_test.cmj test/boolean_test.cmi test/boolean_test.cmj test/bs_MapInt_test.cmi test/bs_MapInt_test.cmj test/bs_abstract_test.cmi test/bs_abstract_test.cmj test/bs_array_test.cmi test/bs_array_test.cmj test/bs_auto_uncurry.cmi test/bs_auto_uncurry.cmj test/bs_auto_uncurry_test.cmi test/bs_auto_uncurry_test.cmj test/bs_float_test.cmi test/bs_float_test.cmj test/bs_hashmap_test.cmi test/bs_hashmap_test.cmj test/bs_hashset_int_test.cmi test/bs_hashset_int_test.cmj test/bs_hashtbl_string_test.cmi test/bs_hashtbl_string_test.cmj test/bs_ignore_effect.cmi test/bs_ignore_effect.cmj test/bs_ignore_test.cmi test/bs_ignore_test.cmj test/bs_int_test.cmi test/bs_int_test.cmj test/bs_list_test.cmi test/bs_list_test.cmj test/bs_map_set_dict_test.cmi test/bs_map_set_dict_test.cmj test/bs_map_test.cmi test/bs_map_test.cmj test/bs_min_max_test.cmi test/bs_min_max_test.cmj test/bs_mutable_set_test.cmi test/bs_mutable_set_test.cmj test/bs_node_string_buffer_test.cmi test/bs_node_string_buffer_test.cmj test/bs_poly_map_test.cmi test/bs_poly_map_test.cmj test/bs_poly_mutable_map_test.cmi test/bs_poly_mutable_map_test.cmj test/bs_poly_mutable_set_test.cmi test/bs_poly_mutable_set_test.cmj test/bs_poly_set_test.cmi test/bs_poly_set_test.cmj test/bs_qualified.cmi test/bs_qualified.cmj test/bs_queue_test.cmi test/bs_queue_test.cmj test/bs_rbset_int_bench.cmi test/bs_rbset_int_bench.cmj test/bs_rest_test.cmi test/bs_rest_test.cmj test/bs_set_bench.cmi test/bs_set_bench.cmj test/bs_set_int_test.cmi test/bs_set_int_test.cmj test/bs_sort_test.cmi test/bs_sort_test.cmj test/bs_splice_partial.cmi test/bs_splice_partial.cmj test/bs_stack_test.cmi test/bs_stack_test.cmj test/bs_string_test.cmi test/bs_string_test.cmj test/bs_unwrap_test.cmi test/bs_unwrap_test.cmj test/buffer_test.cmi test/buffer_test.cmj test/bytes_split_gpr_743_test.cmi test/bytes_split_gpr_743_test.cmj test/caml_compare_test.cmi test/caml_compare_test.cmj test/caml_format_test.cmi test/caml_format_test.cmj test/caml_sys_poly_fill_test.cmi test/caml_sys_poly_fill_test.cmj test/chain_code_test.cmi test/chain_code_test.cmj test/chn_test.cmi test/chn_test.cmj test/class_setter_getter.cmi test/class_setter_getter.cmj test/class_type_ffi_test.cmi test/class_type_ffi_test.cmj test/coercion_module_alias_test.cmi test/coercion_module_alias_test.cmj test/compare_test.cmi test/compare_test.cmj test/complete_parmatch_test.cmi test/complete_parmatch_test.cmj test/complex_if_test.cmi test/complex_if_test.cmj test/complex_test.cmi test/complex_test.cmj test/complex_while_loop.cmi test/complex_while_loop.cmj test/condition_compilation_test.cmi test/condition_compilation_test.cmj test/config1_test.cmi test/config1_test.cmj test/config2_test.cmi test/config2_test.cmj test/console_log_test.cmi test/console_log_test.cmj test/const_block_test.cmi test/const_block_test.cmj test/const_defs.cmi test/const_defs.cmj test/const_defs_test.cmi test/const_defs_test.cmj test/const_test.cmi test/const_test.cmj test/cont_int_fold_test.cmi test/cont_int_fold_test.cmj test/cps_test.cmi test/cps_test.cmj test/cross_module_inline_test.cmi test/cross_module_inline_test.cmj test/custom_error_test.cmi test/custom_error_test.cmj test/debug_keep_test.cmi test/debug_keep_test.cmj test/debug_mode_value.cmi test/debug_mode_value.cmj test/debug_tmp.cmi test/debug_tmp.cmj test/debugger_test.cmi test/debugger_test.cmj test/default_export_test.cmi test/default_export_test.cmj test/defunctor_make_test.cmi test/defunctor_make_test.cmj test/demo.cmi test/demo.cmj test/demo_binding.cmi test/demo_binding.cmj test/demo_int_map.cmi test/demo_int_map.cmj test/demo_page.cmi test/demo_page.cmj test/demo_pipe.cmi test/demo_pipe.cmj test/derive_dyntype.cmi test/derive_dyntype.cmj test/derive_projector_test.cmi test/derive_projector_test.cmj test/derive_type_test.cmi test/derive_type_test.cmj test/digest_test.cmi test/digest_test.cmj test/div_by_zero_test.cmi test/div_by_zero_test.cmj test/dollar_escape_test.cmi test/dollar_escape_test.cmj test/earger_curry_test.cmi test/earger_curry_test.cmj test/effect.cmi test/effect.cmj test/epsilon_test.cmi test/epsilon_test.cmj test/equal_box_test.cmi test/equal_box_test.cmj test/equal_exception_test.cmi test/equal_exception_test.cmj test/equal_test.cmi test/equal_test.cmj test/es6_export.cmi test/es6_export.cmj test/es6_import.cmi test/es6_import.cmj test/es6_module_test.cmi test/es6_module_test.cmj test/escape_esmodule.cmi test/escape_esmodule.cmj test/esmodule_ref.cmi test/esmodule_ref.cmj test/event_ffi.cmi test/event_ffi.cmj test/exception_alias.cmi test/exception_alias.cmj test/exception_def.cmi test/exception_def.cmj test/exception_raise_test.cmi test/exception_raise_test.cmj test/exception_rebind_test.cmi test/exception_rebind_test.cmj test/exception_rebound_err_test.cmi test/exception_rebound_err_test.cmj test/exception_repr_test.cmi test/exception_repr_test.cmj test/exception_value_test.cmi test/exception_value_test.cmj test/exn_error_pattern.cmi test/exn_error_pattern.cmj test/export_keyword.cmi test/export_keyword.cmj test/ext_array_test.cmi test/ext_array_test.cmj test/ext_bytes_test.cmi test/ext_bytes_test.cmj test/ext_filename_test.cmi test/ext_filename_test.cmj test/ext_list_test.cmi test/ext_list_test.cmj test/ext_pervasives_test.cmi test/ext_pervasives_test.cmj test/ext_string_test.cmi test/ext_string_test.cmj test/ext_sys_test.cmi test/ext_sys_test.cmj test/extensible_variant_test.cmi test/extensible_variant_test.cmj test/external_polyfill_test.cmi test/external_polyfill_test.cmj test/external_ppx.cmi test/external_ppx.cmj test/external_ppx2.cmi test/external_ppx2.cmj test/fail_comp.cmi test/fail_comp.cmj test/ffi_arity_test.cmi test/ffi_arity_test.cmj test/ffi_array_test.cmi test/ffi_array_test.cmj test/ffi_js_test.cmi test/ffi_js_test.cmj test/ffi_splice_test.cmi test/ffi_splice_test.cmj test/ffi_test.cmi test/ffi_test.cmj test/fib.cmi test/fib.cmj test/flattern_order_test.cmi test/flattern_order_test.cmj test/flexible_array_test.cmi test/flexible_array_test.cmj test/float_array.cmi test/float_array.cmj test/float_of_bits_test.cmi test/float_of_bits_test.cmj test/float_record.cmi test/float_record.cmj test/float_test.cmi test/float_test.cmj test/floatarray_test.cmi test/floatarray_test.cmj test/flow_parser_reg_test.cmi test/flow_parser_reg_test.cmj test/for_loop_test.cmi test/for_loop_test.cmj test/for_side_effect_test.cmi test/for_side_effect_test.cmj test/format_regression.cmi test/format_regression.cmj test/format_test.cmi test/format_test.cmj test/fs_test.cmi test/fs_test.cmj test/fun_pattern_match.cmi test/fun_pattern_match.cmj test/functor_app_test.cmi test/functor_app_test.cmj test/functor_def.cmi test/functor_def.cmj test/functor_ffi.cmi test/functor_ffi.cmj test/functor_inst.cmi test/functor_inst.cmj test/functors.cmi test/functors.cmj test/gbk.cmi test/gbk.cmj test/genlex_test.cmi test/genlex_test.cmj test/gentTypeReTest.cmi test/gentTypeReTest.cmj test/global_exception_regression_test.cmi test/global_exception_regression_test.cmj test/global_mangles.cmi test/global_mangles.cmj test/global_module_alias_test.cmi test/global_module_alias_test.cmj test/google_closure_test.cmi test/google_closure_test.cmj test/gpr496_test.cmi test/gpr496_test.cmj test/gpr_1063_test.cmi test/gpr_1063_test.cmj test/gpr_1072.cmi test/gpr_1072.cmj test/gpr_1072_reg.cmi test/gpr_1072_reg.cmj test/gpr_1150.cmi test/gpr_1150.cmj test/gpr_1154_test.cmi test/gpr_1154_test.cmj test/gpr_1170.cmi test/gpr_1170.cmj test/gpr_1240_missing_unbox.cmi test/gpr_1240_missing_unbox.cmj test/gpr_1245_test.cmi test/gpr_1245_test.cmj test/gpr_1268.cmi test/gpr_1268.cmj test/gpr_1409_test.cmi test/gpr_1409_test.cmj test/gpr_1423_app_test.cmi test/gpr_1423_app_test.cmj test/gpr_1423_nav.cmi test/gpr_1423_nav.cmj test/gpr_1438.cmi test/gpr_1438.cmj test/gpr_1481.cmi test/gpr_1481.cmj test/gpr_1484.cmi test/gpr_1484.cmj test/gpr_1501_test.cmi test/gpr_1501_test.cmj test/gpr_1503_test.cmi test/gpr_1503_test.cmj test/gpr_1539_test.cmi test/gpr_1539_test.cmj test/gpr_1600_test.cmi test/gpr_1600_test.cmj test/gpr_1658_test.cmi test/gpr_1658_test.cmj test/gpr_1667_test.cmi test/gpr_1667_test.cmj test/gpr_1692_test.cmi test/gpr_1692_test.cmj test/gpr_1698_test.cmi test/gpr_1698_test.cmj test/gpr_1701_test.cmi test/gpr_1701_test.cmj test/gpr_1716_test.cmi test/gpr_1716_test.cmj test/gpr_1717_test.cmi test/gpr_1717_test.cmj test/gpr_1728_test.cmi test/gpr_1728_test.cmj test/gpr_1749_test.cmi test/gpr_1749_test.cmj test/gpr_1759_test.cmi test/gpr_1759_test.cmj test/gpr_1760_test.cmi test/gpr_1760_test.cmj test/gpr_1762_test.cmi test/gpr_1762_test.cmj test/gpr_1817_test.cmi test/gpr_1817_test.cmj test/gpr_1822_test.cmi test/gpr_1822_test.cmj test/gpr_1891_test.cmi test/gpr_1891_test.cmj test/gpr_1943_test.cmi test/gpr_1943_test.cmj test/gpr_1946_test.cmi test/gpr_1946_test.cmj test/gpr_2316_test.cmi test/gpr_2316_test.cmj test/gpr_2352_test.cmi test/gpr_2352_test.cmj test/gpr_2413_test.cmi test/gpr_2413_test.cmj test/gpr_2474.cmi test/gpr_2474.cmj test/gpr_2487.cmi test/gpr_2487.cmj test/gpr_2503_test.cmi test/gpr_2503_test.cmj test/gpr_2608_test.cmi test/gpr_2608_test.cmj test/gpr_2614_test.cmi test/gpr_2614_test.cmj test/gpr_2633_test.cmi test/gpr_2633_test.cmj test/gpr_2642_test.cmi test/gpr_2642_test.cmj test/gpr_2652_test.cmi test/gpr_2652_test.cmj test/gpr_2682_test.cmi test/gpr_2682_test.cmj test/gpr_2700_test.cmi test/gpr_2700_test.cmj test/gpr_2731_test.cmi test/gpr_2731_test.cmj test/gpr_2789_test.cmi test/gpr_2789_test.cmj test/gpr_2931_test.cmi test/gpr_2931_test.cmj test/gpr_3142_test.cmi test/gpr_3142_test.cmj test/gpr_3154_test.cmi test/gpr_3154_test.cmj test/gpr_3209_test.cmi test/gpr_3209_test.cmj test/gpr_3492_test.cmi test/gpr_3492_test.cmj test/gpr_3519_jsx_test.cmi test/gpr_3519_jsx_test.cmj test/gpr_3519_test.cmi test/gpr_3519_test.cmj test/gpr_3536_test.cmi test/gpr_3536_test.cmj test/gpr_3546_test.cmi test/gpr_3546_test.cmj test/gpr_3548_test.cmi test/gpr_3548_test.cmj test/gpr_3549_test.cmi test/gpr_3549_test.cmj test/gpr_3566_drive_test.cmi test/gpr_3566_drive_test.cmj test/gpr_3566_test.cmi test/gpr_3566_test.cmj test/gpr_3595_test.cmi test/gpr_3595_test.cmj test/gpr_3609_test.cmi test/gpr_3609_test.cmj test/gpr_3697_test.cmi test/gpr_3697_test.cmj test/gpr_373_test.cmi test/gpr_373_test.cmj test/gpr_3770_test.cmi test/gpr_3770_test.cmj test/gpr_3852_alias.cmi test/gpr_3852_alias.cmj test/gpr_3852_alias_reify.cmi test/gpr_3852_alias_reify.cmj test/gpr_3852_effect.cmi test/gpr_3852_effect.cmj test/gpr_3865.cmi test/gpr_3865.cmj test/gpr_3865_bar.cmi test/gpr_3865_bar.cmj test/gpr_3865_foo.cmi test/gpr_3865_foo.cmj test/gpr_3875_test.cmi test/gpr_3875_test.cmj test/gpr_3877_test.cmi test/gpr_3877_test.cmj test/gpr_3895_test.cmi test/gpr_3895_test.cmj test/gpr_3897_test.cmi test/gpr_3897_test.cmj test/gpr_3931_test.cmi test/gpr_3931_test.cmj test/gpr_3980_test.cmi test/gpr_3980_test.cmj test/gpr_4025_test.cmi test/gpr_4025_test.cmj test/gpr_405_test.cmi test/gpr_405_test.cmj test/gpr_4069_test.cmi test/gpr_4069_test.cmj test/gpr_4265_test.cmi test/gpr_4265_test.cmj test/gpr_4274_test.cmi test/gpr_4274_test.cmj test/gpr_4280_test.cmi test/gpr_4280_test.cmj test/gpr_4407_test.cmi test/gpr_4407_test.cmj test/gpr_441.cmi test/gpr_441.cmj test/gpr_4442_test.cmi test/gpr_4442_test.cmj test/gpr_4491_test.cmi test/gpr_4491_test.cmj test/gpr_4494_test.cmi test/gpr_4494_test.cmj test/gpr_4519_test.cmi test/gpr_4519_test.cmj test/gpr_459_test.cmi test/gpr_459_test.cmj test/gpr_4632.cmi test/gpr_4632.cmj test/gpr_4639_test.cmi test/gpr_4639_test.cmj test/gpr_4900_test.cmi test/gpr_4900_test.cmj test/gpr_4924_test.cmi test/gpr_4924_test.cmj test/gpr_4931.cmi test/gpr_4931.cmj test/gpr_4931_allow.cmi test/gpr_4931_allow.cmj test/gpr_5071_test.cmi test/gpr_5071_test.cmj test/gpr_5169_test.cmi test/gpr_5169_test.cmj test/gpr_5218_test.cmi test/gpr_5218_test.cmj test/gpr_5280_optimize_test.cmi test/gpr_5280_optimize_test.cmj test/gpr_5312.cmi test/gpr_5312.cmj test/gpr_627_test.cmi test/gpr_627_test.cmj test/gpr_658.cmi test/gpr_658.cmj test/gpr_858_test.cmi test/gpr_858_test.cmj test/gpr_858_unit2_test.cmi test/gpr_858_unit2_test.cmj test/gpr_904_test.cmi test/gpr_904_test.cmj test/gpr_974_test.cmi test/gpr_974_test.cmj test/gpr_977_test.cmi test/gpr_977_test.cmj test/gpr_return_type_unused_attribute.cmi test/gpr_return_type_unused_attribute.cmj test/gray_code_test.cmi test/gray_code_test.cmj test/guide_for_ext.cmi test/guide_for_ext.cmj test/hamming_test.cmi test/hamming_test.cmj test/hash_collision_test.cmi test/hash_collision_test.cmj test/hash_sugar_desugar.cmi test/hash_sugar_desugar.cmj test/hash_test.cmi test/hash_test.cmj test/hashtbl_test.cmi test/hashtbl_test.cmj test/hello.foo.cmi test/hello.foo.cmj test/hello_res.cmi test/hello_res.cmj test/http_types.cmi test/http_types.cmj test/ignore_test.cmi test/ignore_test.cmj test/imm_map_bench.cmi test/imm_map_bench.cmj test/include_side_effect.cmi test/include_side_effect.cmj test/include_side_effect_free.cmi test/include_side_effect_free.cmj test/incomplete_toplevel_test.cmi test/incomplete_toplevel_test.cmj test/infer_type_test.cmi test/infer_type_test.cmj test/inline_const.cmi test/inline_const.cmj test/inline_const_test.cmi test/inline_const_test.cmj test/inline_edge_cases.cmi test/inline_edge_cases.cmj test/inline_map2_test.cmi test/inline_map2_test.cmj test/inline_map_demo.cmi test/inline_map_demo.cmj test/inline_map_test.cmi test/inline_map_test.cmj test/inline_record_test.cmi test/inline_record_test.cmj test/inline_regression_test.cmi test/inline_regression_test.cmj test/inline_string_test.cmi test/inline_string_test.cmj test/inner_call.cmi test/inner_call.cmj test/inner_define.cmi test/inner_define.cmj test/inner_unused.cmi test/inner_unused.cmj test/installation_test.cmi test/installation_test.cmj test/int32_test.cmi test/int32_test.cmj test/int64_mul_div_test.cmi test/int64_mul_div_test.cmj test/int64_string_bench.cmi test/int64_string_bench.cmj test/int64_string_test.cmi test/int64_string_test.cmj test/int64_test.cmi test/int64_test.cmj test/int_hashtbl_test.cmi test/int_hashtbl_test.cmj test/int_map.cmi test/int_map.cmj test/int_overflow_test.cmi test/int_overflow_test.cmj test/int_poly_var.cmi test/int_poly_var.cmj test/int_switch_test.cmi test/int_switch_test.cmj test/internal_unused_test.cmi test/internal_unused_test.cmj test/io_test.cmi test/io_test.cmj test/js_array_test.cmi test/js_array_test.cmj test/js_bool_test.cmi test/js_bool_test.cmj test/js_cast_test.cmi test/js_cast_test.cmj test/js_date_test.cmi test/js_date_test.cmj test/js_dict_test.cmi test/js_dict_test.cmj test/js_exception_catch_test.cmi test/js_exception_catch_test.cmj test/js_float_test.cmi test/js_float_test.cmj test/js_global_test.cmi test/js_global_test.cmj test/js_int_test.cmi test/js_int_test.cmj test/js_json_test.cmi test/js_json_test.cmj test/js_list_test.cmi test/js_list_test.cmj test/js_math_test.cmi test/js_math_test.cmj test/js_null_test.cmi test/js_null_test.cmj test/js_null_undefined_test.cmi test/js_null_undefined_test.cmj test/js_nullable_test.cmi test/js_nullable_test.cmj test/js_obj_test.cmi test/js_obj_test.cmj test/js_option_test.cmi test/js_option_test.cmj test/js_promise_basic_test.cmi test/js_promise_basic_test.cmj test/js_re_test.cmi test/js_re_test.cmj test/js_string_test.cmi test/js_string_test.cmj test/js_typed_array_test.cmi test/js_typed_array_test.cmj test/js_undefined_test.cmi test/js_undefined_test.cmj test/js_val.cmi test/js_val.cmj test/jsoo_400_test.cmi test/jsoo_400_test.cmj test/jsoo_485_test.cmi test/jsoo_485_test.cmj test/key_word_property.cmi test/key_word_property.cmj test/key_word_property2.cmi test/key_word_property2.cmj test/key_word_property_plus_test.cmi test/key_word_property_plus_test.cmj test/label_uncurry.cmi test/label_uncurry.cmj test/large_integer_pat.cmi test/large_integer_pat.cmj test/large_record_duplication_test.cmi test/large_record_duplication_test.cmj test/largest_int_flow.cmi test/largest_int_flow.cmj test/lazy_demo.cmi test/lazy_demo.cmj test/lazy_test.cmi test/lazy_test.cmj test/lexer_test.cmi test/lexer_test.cmj test/lib_js_test.cmi test/lib_js_test.cmj test/libarg_test.cmi test/libarg_test.cmj test/libqueue_test.cmi test/libqueue_test.cmj test/limits_test.cmi test/limits_test.cmj test/list_stack.cmi test/list_stack.cmj test/list_test.cmi test/list_test.cmj test/local_class_type.cmi test/local_class_type.cmj test/local_exception_test.cmi test/local_exception_test.cmj test/loop_regression_test.cmi test/loop_regression_test.cmj test/loop_suites_test.cmi test/loop_suites_test.cmj test/map_find_test.cmi test/map_find_test.cmj test/map_test.cmi test/map_test.cmj test/mario_game.cmi test/mario_game.cmj test/marshal.cmi test/marshal.cmj test/method_chain.cmi test/method_chain.cmj test/method_name_test.cmi test/method_name_test.cmj test/method_string_name.cmi test/method_string_name.cmj test/minimal_test.cmi test/minimal_test.cmj test/miss_colon_test.cmi test/miss_colon_test.cmj test/mock_mt.cmi test/mock_mt.cmj test/module_alias_test.cmi test/module_alias_test.cmj test/module_as_class_ffi.cmi test/module_as_class_ffi.cmj test/module_as_function.cmi test/module_as_function.cmj test/module_missing_conversion.cmi test/module_missing_conversion.cmj test/module_parameter_test.cmi test/module_parameter_test.cmj test/module_splice_test.cmi test/module_splice_test.cmj test/more_poly_variant_test.cmi test/more_poly_variant_test.cmj test/more_uncurry.cmi test/more_uncurry.cmj test/mpr_6033_test.cmi test/mpr_6033_test.cmj test/mt.cmi test/mt.cmj test/mt_global.cmi test/mt_global.cmj test/mutable_obj_test.cmi test/mutable_obj_test.cmj test/mutable_uncurry_test.cmi test/mutable_uncurry_test.cmj test/mutual_non_recursive_type.cmi test/mutual_non_recursive_type.cmj test/name_mangle_test.cmi test/name_mangle_test.cmj test/nested_include.cmi test/nested_include.cmj test/nested_module_alias.cmi test/nested_module_alias.cmj test/nested_obj_literal.cmi test/nested_obj_literal.cmj test/nested_obj_test.cmi test/nested_obj_test.cmj test/nested_pattern_match_test.cmi test/nested_pattern_match_test.cmj test/noassert.cmi test/noassert.cmj test/node_fs_test.cmi test/node_fs_test.cmj test/node_path_test.cmi test/node_path_test.cmj test/null_list_test.cmi test/null_list_test.cmj test/number_lexer.cmi test/number_lexer.cmj test/obj_literal_ppx.cmi test/obj_literal_ppx.cmj test/obj_literal_ppx_test.cmi test/obj_literal_ppx_test.cmj test/obj_magic_test.cmi test/obj_magic_test.cmj test/obj_type_test.cmi test/obj_type_test.cmj test/ocaml_re_test.cmi test/ocaml_re_test.cmj test/of_string_test.cmi test/of_string_test.cmj test/offset.cmi test/offset.cmj test/oo_js_test_date.cmi test/oo_js_test_date.cmj test/option_encoding_test.cmi test/option_encoding_test.cmj test/option_record_none_test.cmi test/option_record_none_test.cmj test/option_repr_test.cmi test/option_repr_test.cmj test/optional_ffi_test.cmi test/optional_ffi_test.cmj test/optional_regression_test.cmi test/optional_regression_test.cmj test/pipe_send_readline.cmi test/pipe_send_readline.cmj test/pipe_syntax.cmi test/pipe_syntax.cmj test/poly_empty_array.cmi test/poly_empty_array.cmj test/poly_type.cmi test/poly_type.cmj test/poly_variant_test.cmi test/poly_variant_test.cmj test/polymorphic_raw_test.cmi test/polymorphic_raw_test.cmj test/polymorphism_test.cmi test/polymorphism_test.cmj test/polyvar_convert.cmi test/polyvar_convert.cmj test/polyvar_test.cmi test/polyvar_test.cmj test/ppx_apply_test.cmi test/ppx_apply_test.cmj test/ppx_this_obj_field.cmi test/ppx_this_obj_field.cmj test/ppx_this_obj_test.cmi test/ppx_this_obj_test.cmj test/pq_test.cmi test/pq_test.cmj test/pr6726.cmi test/pr6726.cmj test/pr_regression_test.cmi test/pr_regression_test.cmj test/prepend_data_ffi.cmi test/prepend_data_ffi.cmj test/primitive_reg_test.cmi test/primitive_reg_test.cmj test/print_alpha_test.cmi test/print_alpha_test.cmj test/promise.cmi test/promise.cmj test/promise_catch_test.cmi test/promise_catch_test.cmj test/queue_402.cmi test/queue_402.cmj test/queue_test.cmi test/queue_test.cmj test/random_test.cmi test/random_test.cmj test/raw_hash_tbl_bench.cmi test/raw_hash_tbl_bench.cmj test/raw_output_test.cmi test/raw_output_test.cmj test/raw_pure_test.cmi test/raw_pure_test.cmj test/rbset.cmi test/rbset.cmj test/react.cmi test/react.cmj test/reactDOMRe.cmi test/reactDOMRe.cmj test/reactDOMServerRe.cmi test/reactDOMServerRe.cmj test/reactEvent.cmi test/reactEvent.cmj test/reactTestUtils.cmi test/reactTestUtils.cmj test/reasonReact.cmi test/reasonReact.cmj test/reasonReactCompat.cmi test/reasonReactCompat.cmj test/reasonReactOptimizedCreateClass.cmi test/reasonReactOptimizedCreateClass.cmj test/reasonReactRouter.cmi test/reasonReactRouter.cmj test/rebind_module.cmi test/rebind_module.cmj test/rebind_module_test.cmi test/rebind_module_test.cmj test/rec_array_test.cmi test/rec_array_test.cmj test/rec_fun_test.cmi test/rec_fun_test.cmj test/rec_module_opt.cmi test/rec_module_opt.cmj test/rec_module_test.cmi test/rec_module_test.cmj test/rec_value_test.cmi test/rec_value_test.cmj test/record_debug_test.cmi test/record_debug_test.cmj test/record_extension_test.cmi test/record_extension_test.cmj test/record_name_test.cmi test/record_name_test.cmj test/record_regression.cmi test/record_regression.cmj test/record_with_test.cmi test/record_with_test.cmj test/recursive_module.cmi test/recursive_module.cmj test/recursive_module_test.cmi test/recursive_module_test.cmj test/recursive_react_component.cmi test/recursive_react_component.cmj test/recursive_records_test.cmi test/recursive_records_test.cmj test/recursive_unbound_module_test.cmi test/recursive_unbound_module_test.cmj test/regression_print.cmi test/regression_print.cmj test/relative_path.cmi test/relative_path.cmj test/res_debug.cmi test/res_debug.cmj test/return_check.cmi test/return_check.cmj test/runtime_encoding_test.cmi test/runtime_encoding_test.cmj test/set_gen.cmi test/set_gen.cmj test/sexp.cmi test/sexp.cmj test/sexpm.cmi test/sexpm.cmj test/sexpm_test.cmi test/sexpm_test.cmj test/side_effect.cmi test/side_effect.cmj test/side_effect_free.cmi test/side_effect_free.cmj test/simple_derive_test.cmi test/simple_derive_test.cmj test/simple_derive_use.cmi test/simple_derive_use.cmj test/simple_lexer_test.cmi test/simple_lexer_test.cmj test/simplify_lambda_632o.cmi test/simplify_lambda_632o.cmj test/single_module_alias.cmi test/single_module_alias.cmj test/singular_unit_test.cmi test/singular_unit_test.cmj test/small_inline_test.cmi test/small_inline_test.cmj test/splice_test.cmi test/splice_test.cmj test/stack_comp_test.cmi test/stack_comp_test.cmj test/stack_test.cmi test/stack_test.cmj test/stream_parser_test.cmi test/stream_parser_test.cmj test/string_bound_get_test.cmi test/string_bound_get_test.cmj test/string_get_set_test.cmi test/string_get_set_test.cmj test/string_interp_test.cmi test/string_interp_test.cmj test/string_literal_print_test.cmi test/string_literal_print_test.cmj test/string_runtime_test.cmi test/string_runtime_test.cmj test/string_set.cmi test/string_set.cmj test/string_set_test.cmi test/string_set_test.cmj test/string_test.cmi test/string_test.cmj test/string_unicode_test.cmi test/string_unicode_test.cmj test/stringmatch_test.cmi test/stringmatch_test.cmj test/submodule.cmi test/submodule.cmj test/submodule_call.cmi test/submodule_call.cmj test/switch_case_test.cmi test/switch_case_test.cmj test/tailcall_inline_test.cmi test/tailcall_inline_test.cmj test/template.cmi test/template.cmj test/test.cmi test/test.cmj test/test2.cmi test/test2.cmj test/test_alias.cmi test/test_alias.cmj test/test_ari.cmi test/test_ari.cmj test/test_array.cmi test/test_array.cmj test/test_array_append.cmi test/test_array_append.cmj test/test_array_primitive.cmi test/test_array_primitive.cmj test/test_bool_equal.cmi test/test_bool_equal.cmj test/test_bs_this.cmi test/test_bs_this.cmj test/test_bug.cmi test/test_bug.cmj test/test_bytes.cmi test/test_bytes.cmj test/test_case_opt_collision.cmi test/test_case_opt_collision.cmj test/test_case_set.cmi test/test_case_set.cmj test/test_char.cmi test/test_char.cmj test/test_closure.cmi test/test_closure.cmj test/test_common.cmi test/test_common.cmj test/test_const_elim.cmi test/test_const_elim.cmj test/test_const_propogate.cmi test/test_const_propogate.cmj test/test_cpp.cmi test/test_cpp.cmj test/test_cps.cmi test/test_cps.cmj test/test_demo.cmi test/test_demo.cmj test/test_dup_param.cmi test/test_dup_param.cmj test/test_eq.cmi test/test_eq.cmj test/test_exception.cmi test/test_exception.cmj test/test_exception_escape.cmi test/test_exception_escape.cmj test/test_export2.cmi test/test_export2.cmj test/test_external.cmi test/test_external.cmj test/test_external_unit.cmi test/test_external_unit.cmj test/test_ffi.cmi test/test_ffi.cmj test/test_fib.cmi test/test_fib.cmj test/test_filename.cmi test/test_filename.cmj test/test_for_loop.cmi test/test_for_loop.cmj test/test_for_map.cmi test/test_for_map.cmj test/test_for_map2.cmi test/test_for_map2.cmj test/test_format.cmi test/test_format.cmj test/test_formatter.cmi test/test_formatter.cmj test/test_functor_dead_code.cmi test/test_functor_dead_code.cmj test/test_generative_module.cmi test/test_generative_module.cmj test/test_global_print.cmi test/test_global_print.cmj test/test_google_closure.cmi test/test_google_closure.cmj test/test_http_server.cmi test/test_http_server.cmj test/test_include.cmi test/test_include.cmj test/test_incomplete.cmi test/test_incomplete.cmj test/test_incr_ref.cmi test/test_incr_ref.cmj test/test_index.cmi test/test_index.cmj test/test_int_map_find.cmi test/test_int_map_find.cmj test/test_internalOO.cmi test/test_internalOO.cmj test/test_is_js.cmi test/test_is_js.cmj test/test_js_ffi.cmi test/test_js_ffi.cmj test/test_let.cmi test/test_let.cmj test/test_list.cmi test/test_list.cmj test/test_literal.cmi test/test_literal.cmj test/test_literals.cmi test/test_literals.cmj test/test_match_exception.cmi test/test_match_exception.cmj test/test_mutliple.cmi test/test_mutliple.cmj test/test_nat64.cmi test/test_nat64.cmj test/test_nested_let.cmi test/test_nested_let.cmj test/test_nested_print.cmi test/test_nested_print.cmj test/test_non_export.cmi test/test_non_export.cmj test/test_nullary.cmi test/test_nullary.cmj test/test_obj.cmi test/test_obj.cmj test/test_obj_simple_ffi.cmi test/test_obj_simple_ffi.cmj test/test_order.cmi test/test_order.cmj test/test_order_tailcall.cmi test/test_order_tailcall.cmj test/test_other_exn.cmi test/test_other_exn.cmj test/test_pack.cmi test/test_pack.cmj test/test_per.cmi test/test_per.cmj test/test_pervasive.cmi test/test_pervasive.cmj test/test_pervasives2.cmi test/test_pervasives2.cmj test/test_pervasives3.cmi test/test_pervasives3.cmj test/test_primitive.cmi test/test_primitive.cmj test/test_promise_bind.cmi test/test_promise_bind.cmj test/test_ramification.cmi test/test_ramification.cmj test/test_react.cmi test/test_react.cmj test/test_react_case.cmi test/test_react_case.cmj test/test_regex.cmi test/test_regex.cmj test/test_require.cmi test/test_require.cmj test/test_runtime_encoding.cmi test/test_runtime_encoding.cmj test/test_scope.cmi test/test_scope.cmj test/test_seq.cmi test/test_seq.cmj test/test_set.cmi test/test_set.cmj test/test_side_effect_functor.cmi test/test_side_effect_functor.cmj test/test_simple_include.cmi test/test_simple_include.cmj test/test_simple_pattern_match.cmi test/test_simple_pattern_match.cmj test/test_simple_ref.cmi test/test_simple_ref.cmj test/test_simple_tailcall.cmi test/test_simple_tailcall.cmj test/test_small.cmi test/test_small.cmj test/test_sprintf.cmi test/test_sprintf.cmj test/test_stack.cmi test/test_stack.cmj test/test_static_catch_ident.cmi test/test_static_catch_ident.cmj test/test_string.cmi test/test_string.cmj test/test_string_case.cmi test/test_string_case.cmj test/test_string_const.cmi test/test_string_const.cmj test/test_string_map.cmi test/test_string_map.cmj test/test_string_switch.cmi test/test_string_switch.cmj test/test_switch.cmi test/test_switch.cmj test/test_trywith.cmi test/test_trywith.cmj test/test_tuple.cmi test/test_tuple.cmj test/test_tuple_destructring.cmi test/test_tuple_destructring.cmj test/test_type_based_arity.cmi test/test_type_based_arity.cmj test/test_u.cmi test/test_u.cmj test/test_unknown.cmi test/test_unknown.cmj test/test_unsafe_cmp.cmi test/test_unsafe_cmp.cmj test/test_unsafe_obj_ffi.cmi test/test_unsafe_obj_ffi.cmj test/test_unsafe_obj_ffi_ppx.cmi test/test_unsafe_obj_ffi_ppx.cmj test/test_unsupported_primitive.cmi test/test_unsupported_primitive.cmj test/test_while_closure.cmi test/test_while_closure.cmj test/test_while_side_effect.cmi test/test_while_side_effect.cmj test/test_zero_nullable.cmi test/test_zero_nullable.cmj test/then_mangle_test.cmi test/then_mangle_test.cmj test/ticker.cmi test/ticker.cmj test/to_string_test.cmi test/to_string_test.cmj test/topsort_test.cmi test/topsort_test.cmj test/tramp_fib.cmi test/tramp_fib.cmj test/tuple_alloc.cmi test/tuple_alloc.cmj test/type_disambiguate.cmi test/type_disambiguate.cmj test/typeof_test.cmi test/typeof_test.cmj test/ui_defs.cmi test/unboxed_attribute.cmi test/unboxed_attribute.cmj test/unboxed_attribute_test.cmi test/unboxed_attribute_test.cmj test/unboxed_crash.cmi test/unboxed_crash.cmj test/unboxed_use_case.cmi test/unboxed_use_case.cmj test/uncurry_external_test.cmi test/uncurry_external_test.cmj test/uncurry_glob_test.cmi test/uncurry_glob_test.cmj test/uncurry_method.cmi test/uncurry_method.cmj test/uncurry_test.cmi test/uncurry_test.cmj test/undef_regression2_test.cmi test/undef_regression2_test.cmj test/undef_regression_test.cmi test/undef_regression_test.cmj test/undefine_conditional.cmi test/undefine_conditional.cmj test/unicode_type_error.cmi test/unicode_type_error.cmj test/unit_undefined_test.cmi test/unit_undefined_test.cmj test/unitest_string.cmi test/unitest_string.cmj test/unsafe_full_apply_primitive.cmi test/unsafe_full_apply_primitive.cmj test/unsafe_obj_external.cmi test/unsafe_obj_external.cmj test/unsafe_ppx_test.cmi test/unsafe_ppx_test.cmj test/unsafe_this.cmi test/unsafe_this.cmj test/update_record_test.cmi test/update_record_test.cmj test/utf8_decode_test.cmi test/utf8_decode_test.cmj test/variant.cmi test/variant.cmj test/watch_test.cmi test/watch_test.cmj test/webpack_config.cmi test/webpack_config.cmj diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index eab64f524c..53e3e6504a 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -91581,6 +91581,7 @@ let destruct_pattern (body : Lam.t) params args = (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with + | _ when m.attr.async -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( @@ -258306,8 +258307,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = end | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) - | Lapply{ap_func = Lfunction{params; body}; ap_args = args; _} - when Ext_list.same_length params args -> + | Lapply{ap_func = Lfunction{params; body; attr}; ap_args = args; _} + when Ext_list.same_length params args && not attr.async -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) @@ -258679,8 +258680,8 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = else normal () else normal () | Some _ | None -> normal ()) - | Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ } - when Ext_list.same_length params args -> + | Lapply { ap_func = Lfunction { params; body; attr }; ap_args = args; _ } + when Ext_list.same_length params args && not attr.async -> simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/lib/4.06.1/unstable/js_playground_compiler.ml b/lib/4.06.1/unstable/js_playground_compiler.ml index 559685bd4b..5d1c783a8e 100644 --- a/lib/4.06.1/unstable/js_playground_compiler.ml +++ b/lib/4.06.1/unstable/js_playground_compiler.ml @@ -91581,6 +91581,7 @@ let destruct_pattern (body : Lam.t) params args = (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with + | _ when m.attr.async -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( @@ -258306,8 +258307,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = end | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) - | Lapply{ap_func = Lfunction{params; body}; ap_args = args; _} - when Ext_list.same_length params args -> + | Lapply{ap_func = Lfunction{params; body; attr}; ap_args = args; _} + when Ext_list.same_length params args && not attr.async -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) @@ -258679,8 +258680,8 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = else normal () else normal () | Some _ | None -> normal ()) - | Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ } - when Ext_list.same_length params args -> + | Lapply { ap_func = Lfunction { params; body; attr }; ap_args = args; _ } + when Ext_list.same_length params args && not attr.async -> simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index 3bf85a12a6..c19af844b5 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -260942,6 +260942,7 @@ let destruct_pattern (body : Lam.t) params args = (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with + | _ when m.attr.async -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( @@ -273576,8 +273577,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = end | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) - | Lapply{ap_func = Lfunction{params; body}; ap_args = args; _} - when Ext_list.same_length params args -> + | Lapply{ap_func = Lfunction{params; body; attr}; ap_args = args; _} + when Ext_list.same_length params args && not attr.async -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) @@ -273949,8 +273950,8 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = else normal () else normal () | Some _ | None -> normal ()) - | Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ } - when Ext_list.same_length params args -> + | Lapply { ap_func = Lfunction { params; body; attr }; ap_args = args; _ } + when Ext_list.same_length params args && not attr.async -> simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) From a9f7a03f699fa50226e45d06028c08dee93e5d84 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Tue, 25 Oct 2022 17:06:23 +0200 Subject: [PATCH 2/4] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe4933c788..882b902e48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ - Fix issue where the JSX key type is not an optional string https://github.com/rescript-lang/syntax/pull/693 -- Prevent inlining of async functions +- Prevent inlining of async functions https://github.com/rescript-lang/rescript-compiler/issues/5754 # 10.1.0-rc.2 From a16d6c4aabfc702ba815bcfa03886272ea207338 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Wed, 26 Oct 2022 06:48:23 +0200 Subject: [PATCH 3/4] Refactor logic to disable inlining of async functions. --- jscomp/core/lam_analysis.ml | 6 +++++- jscomp/core/lam_analysis.mli | 2 ++ jscomp/core/lam_pass_lets_dce.ml | 4 ++-- jscomp/core/lam_pass_remove_alias.ml | 4 ++-- lib/4.06.1/unstable/js_compiler.ml | 12 +++++++++--- lib/4.06.1/unstable/js_playground_compiler.ml | 12 +++++++++--- lib/4.06.1/whole_compiler.ml | 12 +++++++++--- 7 files changed, 38 insertions(+), 14 deletions(-) diff --git a/jscomp/core/lam_analysis.ml b/jscomp/core/lam_analysis.ml index 681ecf68aa..43b3b8b725 100644 --- a/jscomp/core/lam_analysis.ml +++ b/jscomp/core/lam_analysis.ml @@ -244,10 +244,14 @@ let destruct_pattern (body : Lam.t) params args = | Some _ | None -> false) | _ -> false +(* Async functions cannot be inlined *) +let lfunction_can_be_inlined (lfunction : Lam.lfunction) = + not lfunction.attr.async + (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with - | _ when m.attr.async -> false + | _ when not (lfunction_can_be_inlined m) -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( diff --git a/jscomp/core/lam_analysis.mli b/jscomp/core/lam_analysis.mli index 1ab7087b9c..0451182da4 100644 --- a/jscomp/core/lam_analysis.mli +++ b/jscomp/core/lam_analysis.mli @@ -29,6 +29,8 @@ val no_side_effects : Lam.t -> bool val size : Lam.t -> int +val lfunction_can_be_inlined : Lam.lfunction -> bool + val ok_to_inline_fun_when_app : Lam.lfunction -> Lam.t list -> bool val small_inline_size : int diff --git a/jscomp/core/lam_pass_lets_dce.ml b/jscomp/core/lam_pass_lets_dce.ml index 7174842262..43d62730aa 100644 --- a/jscomp/core/lam_pass_lets_dce.ml +++ b/jscomp/core/lam_pass_lets_dce.ml @@ -147,8 +147,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = end | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) - | Lapply{ap_func = Lfunction{params; body; attr}; ap_args = args; _} - when Ext_list.same_length params args && not attr.async -> + | Lapply{ap_func = Lfunction ({params; body} as lfunction); ap_args = args; _} + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_inlined lfunction -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/jscomp/core/lam_pass_remove_alias.ml b/jscomp/core/lam_pass_remove_alias.ml index 185b7759bb..718868fb97 100644 --- a/jscomp/core/lam_pass_remove_alias.ml +++ b/jscomp/core/lam_pass_remove_alias.ml @@ -211,8 +211,8 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = else normal () else normal () | Some _ | None -> normal ()) - | Lapply { ap_func = Lfunction { params; body; attr }; ap_args = args; _ } - when Ext_list.same_length params args && not attr.async -> + | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_inlined lfunction -> simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 53e3e6504a..22375971bb 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -91322,6 +91322,8 @@ val no_side_effects : Lam.t -> bool val size : Lam.t -> int +val lfunction_can_be_inlined : Lam.lfunction -> bool + val ok_to_inline_fun_when_app : Lam.lfunction -> Lam.t list -> bool val small_inline_size : int @@ -91578,10 +91580,14 @@ let destruct_pattern (body : Lam.t) params args = | Some _ | None -> false) | _ -> false +(* Async functions cannot be inlined *) +let lfunction_can_be_inlined (lfunction : Lam.lfunction) = + not lfunction.attr.async + (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with - | _ when m.attr.async -> false + | _ when not (lfunction_can_be_inlined m) -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( @@ -258680,8 +258686,8 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = else normal () else normal () | Some _ | None -> normal ()) - | Lapply { ap_func = Lfunction { params; body; attr }; ap_args = args; _ } - when Ext_list.same_length params args && not attr.async -> + | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_inlined lfunction -> simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/lib/4.06.1/unstable/js_playground_compiler.ml b/lib/4.06.1/unstable/js_playground_compiler.ml index 5d1c783a8e..9d2f8880c5 100644 --- a/lib/4.06.1/unstable/js_playground_compiler.ml +++ b/lib/4.06.1/unstable/js_playground_compiler.ml @@ -91322,6 +91322,8 @@ val no_side_effects : Lam.t -> bool val size : Lam.t -> int +val lfunction_can_be_inlined : Lam.lfunction -> bool + val ok_to_inline_fun_when_app : Lam.lfunction -> Lam.t list -> bool val small_inline_size : int @@ -91578,10 +91580,14 @@ let destruct_pattern (body : Lam.t) params args = | Some _ | None -> false) | _ -> false +(* Async functions cannot be inlined *) +let lfunction_can_be_inlined (lfunction : Lam.lfunction) = + not lfunction.attr.async + (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with - | _ when m.attr.async -> false + | _ when not (lfunction_can_be_inlined m) -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( @@ -258680,8 +258686,8 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = else normal () else normal () | Some _ | None -> normal ()) - | Lapply { ap_func = Lfunction { params; body; attr }; ap_args = args; _ } - when Ext_list.same_length params args && not attr.async -> + | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_inlined lfunction -> simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index c19af844b5..ef21fd688c 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -260683,6 +260683,8 @@ val no_side_effects : Lam.t -> bool val size : Lam.t -> int +val lfunction_can_be_inlined : Lam.lfunction -> bool + val ok_to_inline_fun_when_app : Lam.lfunction -> Lam.t list -> bool val small_inline_size : int @@ -260939,10 +260941,14 @@ let destruct_pattern (body : Lam.t) params args = | Some _ | None -> false) | _ -> false +(* Async functions cannot be inlined *) +let lfunction_can_be_inlined (lfunction : Lam.lfunction) = + not lfunction.attr.async + (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with - | _ when m.attr.async -> false + | _ when not (lfunction_can_be_inlined m) -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( @@ -273950,8 +273956,8 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = else normal () else normal () | Some _ | None -> normal ()) - | Lapply { ap_func = Lfunction { params; body; attr }; ap_args = args; _ } - when Ext_list.same_length params args && not attr.async -> + | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_inlined lfunction -> simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) From 88ab999b469cd2dc0c977c06fe6839c13c6de843 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Wed, 26 Oct 2022 07:16:36 +0200 Subject: [PATCH 4/4] Prevent all async function beta reductions. --- jscomp/core/lam_analysis.ml | 5 +-- jscomp/core/lam_analysis.mli | 2 +- jscomp/core/lam_beta_reduce.ml | 4 +- jscomp/core/lam_beta_reduce.mli | 4 +- jscomp/core/lam_compile.ml | 6 +-- jscomp/core/lam_pass_count.ml | 4 +- jscomp/core/lam_pass_lets_dce.ml | 2 +- jscomp/core/lam_pass_lets_dce.pp.ml | 4 +- jscomp/core/lam_pass_remove_alias.ml | 14 +++--- lib/4.06.1/unstable/js_compiler.ml | 43 +++++++++---------- lib/4.06.1/unstable/js_playground_compiler.ml | 43 +++++++++---------- lib/4.06.1/whole_compiler.ml | 43 +++++++++---------- 12 files changed, 85 insertions(+), 89 deletions(-) diff --git a/jscomp/core/lam_analysis.ml b/jscomp/core/lam_analysis.ml index 43b3b8b725..1280a17dc8 100644 --- a/jscomp/core/lam_analysis.ml +++ b/jscomp/core/lam_analysis.ml @@ -244,14 +244,13 @@ let destruct_pattern (body : Lam.t) params args = | Some _ | None -> false) | _ -> false -(* Async functions cannot be inlined *) -let lfunction_can_be_inlined (lfunction : Lam.lfunction) = +(* Async functions cannot be beta reduced *) +let lfunction_can_be_beta_reduced (lfunction : Lam.lfunction) = not lfunction.attr.async (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with - | _ when not (lfunction_can_be_inlined m) -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( diff --git a/jscomp/core/lam_analysis.mli b/jscomp/core/lam_analysis.mli index 0451182da4..a6105b8b9b 100644 --- a/jscomp/core/lam_analysis.mli +++ b/jscomp/core/lam_analysis.mli @@ -29,7 +29,7 @@ val no_side_effects : Lam.t -> bool val size : Lam.t -> int -val lfunction_can_be_inlined : Lam.lfunction -> bool +val lfunction_can_be_beta_reduced : Lam.lfunction -> bool val ok_to_inline_fun_when_app : Lam.lfunction -> Lam.t list -> bool diff --git a/jscomp/core/lam_beta_reduce.ml b/jscomp/core/lam_beta_reduce.ml index d5ce5fef18..30d3977901 100644 --- a/jscomp/core/lam_beta_reduce.ml +++ b/jscomp/core/lam_beta_reduce.ml @@ -44,7 +44,7 @@ ]} we can bound [x] to [100] in a single step *) -let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) +let propagate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) (body : Lam.t) (args : Lam.t list) = match Lam_beta_reduce_util.simple_beta_reduce params body args with | Some x -> x @@ -73,7 +73,7 @@ let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) | _ -> ()); Lam_util.refine_let ~kind:Strict param arg l) -let propogate_beta_reduce_with_map (meta : Lam_stats.t) +let propagate_beta_reduce_with_map (meta : Lam_stats.t) (map : Lam_var_stats.stats Map_ident.t) params body args = match Lam_beta_reduce_util.simple_beta_reduce params body args with | Some x -> x diff --git a/jscomp/core/lam_beta_reduce.mli b/jscomp/core/lam_beta_reduce.mli index 77e819537c..8be5e2d49e 100644 --- a/jscomp/core/lam_beta_reduce.mli +++ b/jscomp/core/lam_beta_reduce.mli @@ -42,10 +42,10 @@ val no_names_beta_reduce : Ident.t list -> Lam.t -> Lam.t list -> Lam.t the obvious example is parameter *) -val propogate_beta_reduce : +val propagate_beta_reduce : Lam_stats.t -> Ident.t list -> Lam.t -> Lam.t list -> Lam.t -val propogate_beta_reduce_with_map : +val propagate_beta_reduce_with_map : Lam_stats.t -> Lam_var_stats.stats Map_ident.t -> Ident.t list -> diff --git a/jscomp/core/lam_compile.ml b/jscomp/core/lam_compile.ml index 29a40757fa..a4e925e63b 100644 --- a/jscomp/core/lam_compile.ml +++ b/jscomp/core/lam_compile.ml @@ -221,14 +221,14 @@ and compile_external_field_apply (appinfo : Lam.apply) (module_id : Ident.t) in let ap_args = appinfo.ap_args in match ident_info.persistent_closed_lambda with - | Some (Lfunction { params; body; _ }) - when Ext_list.same_length params ap_args -> + | Some (Lfunction ({ params; body; _ } as lfunction)) + when Ext_list.same_length params ap_args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> (* TODO: serialize it when exporting to save compile time *) let _, param_map = Lam_closure.is_closed_with_map Set_ident.empty params body in compile_lambda lambda_cxt - (Lam_beta_reduce.propogate_beta_reduce_with_map lambda_cxt.meta + (Lam_beta_reduce.propagate_beta_reduce_with_map lambda_cxt.meta param_map params body ap_args) | _ -> let args_code, args = diff --git a/jscomp/core/lam_pass_count.ml b/jscomp/core/lam_pass_count.ml index 6159e40fb7..b7ee7a8195 100644 --- a/jscomp/core/lam_pass_count.ml +++ b/jscomp/core/lam_pass_count.ml @@ -143,8 +143,8 @@ let collect_occurs lam : occ_tbl = List.iter (fun (_v, l) -> count bv l) bindings; count bv body (* Note there is a difference here when do beta reduction for *) - | Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ } - when Ext_list.same_length params args -> + | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> count bv (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/jscomp/core/lam_pass_lets_dce.ml b/jscomp/core/lam_pass_lets_dce.ml index 43d62730aa..6220be37e3 100644 --- a/jscomp/core/lam_pass_lets_dce.ml +++ b/jscomp/core/lam_pass_lets_dce.ml @@ -148,7 +148,7 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) | Lapply{ap_func = Lfunction ({params; body} as lfunction); ap_args = args; _} - when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_inlined lfunction -> + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/jscomp/core/lam_pass_lets_dce.pp.ml b/jscomp/core/lam_pass_lets_dce.pp.ml index 8a77de83be..7005041ee3 100644 --- a/jscomp/core/lam_pass_lets_dce.pp.ml +++ b/jscomp/core/lam_pass_lets_dce.pp.ml @@ -146,8 +146,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = end | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) - | Lapply{ap_func = Lfunction{params; body; attr}; ap_args = args; _} - when Ext_list.same_length params args && not attr.async -> + | Lapply{ap_func = Lfunction ({params; body} as lfunction); ap_args = args; _} + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) diff --git a/jscomp/core/lam_pass_remove_alias.ml b/jscomp/core/lam_pass_remove_alias.ml index 718868fb97..f7e4253932 100644 --- a/jscomp/core/lam_pass_remove_alias.ml +++ b/jscomp/core/lam_pass_remove_alias.ml @@ -138,7 +138,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = | Some v -> v <> Parameter | None -> true) | _ -> true) -> - simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) + simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args) | _ -> Lam.apply (simpl l1) (Ext_list.map args simpl) ap_info) (* Function inlining interact with other optimizations... @@ -160,7 +160,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = Some ( Lfunction ({ params; body; attr = { is_a_functor } } as m), rec_flag ); - }) -> + }) when Lam_analysis.lfunction_can_be_beta_reduced m -> if Ext_list.same_length ap_args params (* && false *) then if is_a_functor @@ -174,7 +174,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = (* Check: recursive applying may result in non-termination *) (* Ext_log.dwarn __LOC__ "beta .. %s/%d" v.name v.stamp ; *) simpl - (Lam_beta_reduce.propogate_beta_reduce meta params body + (Lam_beta_reduce.propagate_beta_reduce meta params body ap_args) else if (* Lam_analysis.size body < Lam_analysis.small_inline_size *) @@ -194,7 +194,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = | false, (_, param_map) | true, (true, param_map) -> ( match rec_flag with | Lam_rec -> - Lam_beta_reduce.propogate_beta_reduce_with_map meta + Lam_beta_reduce.propagate_beta_reduce_with_map meta param_map params body ap_args | Lam_self_rec -> normal () | Lam_non_rec -> @@ -205,15 +205,15 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = then normal () else simpl - (Lam_beta_reduce.propogate_beta_reduce_with_map meta + (Lam_beta_reduce.propagate_beta_reduce_with_map meta param_map params body ap_args)) | _ -> normal () else normal () else normal () | Some _ | None -> normal ()) | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } - when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_inlined lfunction -> - simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> + simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) (* (\** TODO: keep track of this parameter in ocaml trunk, *) diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 22375971bb..e418bffbd4 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -91322,7 +91322,7 @@ val no_side_effects : Lam.t -> bool val size : Lam.t -> int -val lfunction_can_be_inlined : Lam.lfunction -> bool +val lfunction_can_be_beta_reduced : Lam.lfunction -> bool val ok_to_inline_fun_when_app : Lam.lfunction -> Lam.t list -> bool @@ -91580,14 +91580,13 @@ let destruct_pattern (body : Lam.t) params args = | Some _ | None -> false) | _ -> false -(* Async functions cannot be inlined *) -let lfunction_can_be_inlined (lfunction : Lam.lfunction) = +(* Async functions cannot be beta reduced *) +let lfunction_can_be_beta_reduced (lfunction : Lam.lfunction) = not lfunction.attr.async (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with - | _ when not (lfunction_can_be_inlined m) -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( @@ -94295,10 +94294,10 @@ val no_names_beta_reduce : Ident.t list -> Lam.t -> Lam.t list -> Lam.t the obvious example is parameter *) -val propogate_beta_reduce : +val propagate_beta_reduce : Lam_stats.t -> Ident.t list -> Lam.t -> Lam.t list -> Lam.t -val propogate_beta_reduce_with_map : +val propagate_beta_reduce_with_map : Lam_stats.t -> Lam_var_stats.stats Map_ident.t -> Ident.t list -> @@ -94374,7 +94373,7 @@ end = struct ]} we can bound [x] to [100] in a single step *) -let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) +let propagate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) (body : Lam.t) (args : Lam.t list) = match Lam_beta_reduce_util.simple_beta_reduce params body args with | Some x -> x @@ -94403,7 +94402,7 @@ let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) | _ -> ()); Lam_util.refine_let ~kind:Strict param arg l) -let propogate_beta_reduce_with_map (meta : Lam_stats.t) +let propagate_beta_reduce_with_map (meta : Lam_stats.t) (map : Lam_var_stats.stats Map_ident.t) params body args = match Lam_beta_reduce_util.simple_beta_reduce params body args with | Some x -> x @@ -99772,14 +99771,14 @@ and compile_external_field_apply (appinfo : Lam.apply) (module_id : Ident.t) in let ap_args = appinfo.ap_args in match ident_info.persistent_closed_lambda with - | Some (Lfunction { params; body; _ }) - when Ext_list.same_length params ap_args -> + | Some (Lfunction ({ params; body; _ } as lfunction)) + when Ext_list.same_length params ap_args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> (* TODO: serialize it when exporting to save compile time *) let _, param_map = Lam_closure.is_closed_with_map Set_ident.empty params body in compile_lambda lambda_cxt - (Lam_beta_reduce.propogate_beta_reduce_with_map lambda_cxt.meta + (Lam_beta_reduce.propagate_beta_reduce_with_map lambda_cxt.meta param_map params body ap_args) | _ -> let args_code, args = @@ -257932,8 +257931,8 @@ let collect_occurs lam : occ_tbl = List.iter (fun (_v, l) -> count bv l) bindings; count bv body (* Note there is a difference here when do beta reduction for *) - | Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ } - when Ext_list.same_length params args -> + | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> count bv (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) @@ -258313,8 +258312,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = end | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) - | Lapply{ap_func = Lfunction{params; body; attr}; ap_args = args; _} - when Ext_list.same_length params args && not attr.async -> + | Lapply{ap_func = Lfunction ({params; body} as lfunction); ap_args = args; _} + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) @@ -258613,7 +258612,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = | Some v -> v <> Parameter | None -> true) | _ -> true) -> - simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) + simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args) | _ -> Lam.apply (simpl l1) (Ext_list.map args simpl) ap_info) (* Function inlining interact with other optimizations... @@ -258635,7 +258634,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = Some ( Lfunction ({ params; body; attr = { is_a_functor } } as m), rec_flag ); - }) -> + }) when Lam_analysis.lfunction_can_be_beta_reduced m -> if Ext_list.same_length ap_args params (* && false *) then if is_a_functor @@ -258649,7 +258648,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = (* Check: recursive applying may result in non-termination *) (* Ext_log.dwarn __LOC__ "beta .. %s/%d" v.name v.stamp ; *) simpl - (Lam_beta_reduce.propogate_beta_reduce meta params body + (Lam_beta_reduce.propagate_beta_reduce meta params body ap_args) else if (* Lam_analysis.size body < Lam_analysis.small_inline_size *) @@ -258669,7 +258668,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = | false, (_, param_map) | true, (true, param_map) -> ( match rec_flag with | Lam_rec -> - Lam_beta_reduce.propogate_beta_reduce_with_map meta + Lam_beta_reduce.propagate_beta_reduce_with_map meta param_map params body ap_args | Lam_self_rec -> normal () | Lam_non_rec -> @@ -258680,15 +258679,15 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = then normal () else simpl - (Lam_beta_reduce.propogate_beta_reduce_with_map meta + (Lam_beta_reduce.propagate_beta_reduce_with_map meta param_map params body ap_args)) | _ -> normal () else normal () else normal () | Some _ | None -> normal ()) | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } - when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_inlined lfunction -> - simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> + simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) (* (\** TODO: keep track of this parameter in ocaml trunk, *) diff --git a/lib/4.06.1/unstable/js_playground_compiler.ml b/lib/4.06.1/unstable/js_playground_compiler.ml index 9d2f8880c5..d3ec2fd33d 100644 --- a/lib/4.06.1/unstable/js_playground_compiler.ml +++ b/lib/4.06.1/unstable/js_playground_compiler.ml @@ -91322,7 +91322,7 @@ val no_side_effects : Lam.t -> bool val size : Lam.t -> int -val lfunction_can_be_inlined : Lam.lfunction -> bool +val lfunction_can_be_beta_reduced : Lam.lfunction -> bool val ok_to_inline_fun_when_app : Lam.lfunction -> Lam.t list -> bool @@ -91580,14 +91580,13 @@ let destruct_pattern (body : Lam.t) params args = | Some _ | None -> false) | _ -> false -(* Async functions cannot be inlined *) -let lfunction_can_be_inlined (lfunction : Lam.lfunction) = +(* Async functions cannot be beta reduced *) +let lfunction_can_be_beta_reduced (lfunction : Lam.lfunction) = not lfunction.attr.async (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with - | _ when not (lfunction_can_be_inlined m) -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( @@ -94295,10 +94294,10 @@ val no_names_beta_reduce : Ident.t list -> Lam.t -> Lam.t list -> Lam.t the obvious example is parameter *) -val propogate_beta_reduce : +val propagate_beta_reduce : Lam_stats.t -> Ident.t list -> Lam.t -> Lam.t list -> Lam.t -val propogate_beta_reduce_with_map : +val propagate_beta_reduce_with_map : Lam_stats.t -> Lam_var_stats.stats Map_ident.t -> Ident.t list -> @@ -94374,7 +94373,7 @@ end = struct ]} we can bound [x] to [100] in a single step *) -let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) +let propagate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) (body : Lam.t) (args : Lam.t list) = match Lam_beta_reduce_util.simple_beta_reduce params body args with | Some x -> x @@ -94403,7 +94402,7 @@ let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) | _ -> ()); Lam_util.refine_let ~kind:Strict param arg l) -let propogate_beta_reduce_with_map (meta : Lam_stats.t) +let propagate_beta_reduce_with_map (meta : Lam_stats.t) (map : Lam_var_stats.stats Map_ident.t) params body args = match Lam_beta_reduce_util.simple_beta_reduce params body args with | Some x -> x @@ -99772,14 +99771,14 @@ and compile_external_field_apply (appinfo : Lam.apply) (module_id : Ident.t) in let ap_args = appinfo.ap_args in match ident_info.persistent_closed_lambda with - | Some (Lfunction { params; body; _ }) - when Ext_list.same_length params ap_args -> + | Some (Lfunction ({ params; body; _ } as lfunction)) + when Ext_list.same_length params ap_args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> (* TODO: serialize it when exporting to save compile time *) let _, param_map = Lam_closure.is_closed_with_map Set_ident.empty params body in compile_lambda lambda_cxt - (Lam_beta_reduce.propogate_beta_reduce_with_map lambda_cxt.meta + (Lam_beta_reduce.propagate_beta_reduce_with_map lambda_cxt.meta param_map params body ap_args) | _ -> let args_code, args = @@ -257932,8 +257931,8 @@ let collect_occurs lam : occ_tbl = List.iter (fun (_v, l) -> count bv l) bindings; count bv body (* Note there is a difference here when do beta reduction for *) - | Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ } - when Ext_list.same_length params args -> + | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> count bv (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) @@ -258313,8 +258312,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = end | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) - | Lapply{ap_func = Lfunction{params; body; attr}; ap_args = args; _} - when Ext_list.same_length params args && not attr.async -> + | Lapply{ap_func = Lfunction ({params; body} as lfunction); ap_args = args; _} + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) @@ -258613,7 +258612,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = | Some v -> v <> Parameter | None -> true) | _ -> true) -> - simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) + simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args) | _ -> Lam.apply (simpl l1) (Ext_list.map args simpl) ap_info) (* Function inlining interact with other optimizations... @@ -258635,7 +258634,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = Some ( Lfunction ({ params; body; attr = { is_a_functor } } as m), rec_flag ); - }) -> + }) when Lam_analysis.lfunction_can_be_beta_reduced m -> if Ext_list.same_length ap_args params (* && false *) then if is_a_functor @@ -258649,7 +258648,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = (* Check: recursive applying may result in non-termination *) (* Ext_log.dwarn __LOC__ "beta .. %s/%d" v.name v.stamp ; *) simpl - (Lam_beta_reduce.propogate_beta_reduce meta params body + (Lam_beta_reduce.propagate_beta_reduce meta params body ap_args) else if (* Lam_analysis.size body < Lam_analysis.small_inline_size *) @@ -258669,7 +258668,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = | false, (_, param_map) | true, (true, param_map) -> ( match rec_flag with | Lam_rec -> - Lam_beta_reduce.propogate_beta_reduce_with_map meta + Lam_beta_reduce.propagate_beta_reduce_with_map meta param_map params body ap_args | Lam_self_rec -> normal () | Lam_non_rec -> @@ -258680,15 +258679,15 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = then normal () else simpl - (Lam_beta_reduce.propogate_beta_reduce_with_map meta + (Lam_beta_reduce.propagate_beta_reduce_with_map meta param_map params body ap_args)) | _ -> normal () else normal () else normal () | Some _ | None -> normal ()) | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } - when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_inlined lfunction -> - simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> + simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) (* (\** TODO: keep track of this parameter in ocaml trunk, *) diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index ef21fd688c..b6ea9c98d0 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -260683,7 +260683,7 @@ val no_side_effects : Lam.t -> bool val size : Lam.t -> int -val lfunction_can_be_inlined : Lam.lfunction -> bool +val lfunction_can_be_beta_reduced : Lam.lfunction -> bool val ok_to_inline_fun_when_app : Lam.lfunction -> Lam.t list -> bool @@ -260941,14 +260941,13 @@ let destruct_pattern (body : Lam.t) params args = | Some _ | None -> false) | _ -> false -(* Async functions cannot be inlined *) -let lfunction_can_be_inlined (lfunction : Lam.lfunction) = +(* Async functions cannot be beta reduced *) +let lfunction_can_be_beta_reduced (lfunction : Lam.lfunction) = not lfunction.attr.async (** Hints to inlining *) let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) = match m.attr.inline with - | _ when not (lfunction_can_be_inlined m) -> false | Always_inline -> true | Never_inline -> false | Default_inline -> ( @@ -263656,10 +263655,10 @@ val no_names_beta_reduce : Ident.t list -> Lam.t -> Lam.t list -> Lam.t the obvious example is parameter *) -val propogate_beta_reduce : +val propagate_beta_reduce : Lam_stats.t -> Ident.t list -> Lam.t -> Lam.t list -> Lam.t -val propogate_beta_reduce_with_map : +val propagate_beta_reduce_with_map : Lam_stats.t -> Lam_var_stats.stats Map_ident.t -> Ident.t list -> @@ -263735,7 +263734,7 @@ end = struct ]} we can bound [x] to [100] in a single step *) -let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) +let propagate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) (body : Lam.t) (args : Lam.t list) = match Lam_beta_reduce_util.simple_beta_reduce params body args with | Some x -> x @@ -263764,7 +263763,7 @@ let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list) | _ -> ()); Lam_util.refine_let ~kind:Strict param arg l) -let propogate_beta_reduce_with_map (meta : Lam_stats.t) +let propagate_beta_reduce_with_map (meta : Lam_stats.t) (map : Lam_var_stats.stats Map_ident.t) params body args = match Lam_beta_reduce_util.simple_beta_reduce params body args with | Some x -> x @@ -269065,14 +269064,14 @@ and compile_external_field_apply (appinfo : Lam.apply) (module_id : Ident.t) in let ap_args = appinfo.ap_args in match ident_info.persistent_closed_lambda with - | Some (Lfunction { params; body; _ }) - when Ext_list.same_length params ap_args -> + | Some (Lfunction ({ params; body; _ } as lfunction)) + when Ext_list.same_length params ap_args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> (* TODO: serialize it when exporting to save compile time *) let _, param_map = Lam_closure.is_closed_with_map Set_ident.empty params body in compile_lambda lambda_cxt - (Lam_beta_reduce.propogate_beta_reduce_with_map lambda_cxt.meta + (Lam_beta_reduce.propagate_beta_reduce_with_map lambda_cxt.meta param_map params body ap_args) | _ -> let args_code, args = @@ -273202,8 +273201,8 @@ let collect_occurs lam : occ_tbl = List.iter (fun (_v, l) -> count bv l) bindings; count bv body (* Note there is a difference here when do beta reduction for *) - | Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ } - when Ext_list.same_length params args -> + | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> count bv (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) @@ -273583,8 +273582,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = end | Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2) - | Lapply{ap_func = Lfunction{params; body; attr}; ap_args = args; _} - when Ext_list.same_length params args && not attr.async -> + | Lapply{ap_func = Lfunction ({params; body} as lfunction); ap_args = args; _} + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> simplif (Lam_beta_reduce.no_names_beta_reduce params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) @@ -273883,7 +273882,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = | Some v -> v <> Parameter | None -> true) | _ -> true) -> - simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) + simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args) | _ -> Lam.apply (simpl l1) (Ext_list.map args simpl) ap_info) (* Function inlining interact with other optimizations... @@ -273905,7 +273904,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = Some ( Lfunction ({ params; body; attr = { is_a_functor } } as m), rec_flag ); - }) -> + }) when Lam_analysis.lfunction_can_be_beta_reduced m -> if Ext_list.same_length ap_args params (* && false *) then if is_a_functor @@ -273919,7 +273918,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = (* Check: recursive applying may result in non-termination *) (* Ext_log.dwarn __LOC__ "beta .. %s/%d" v.name v.stamp ; *) simpl - (Lam_beta_reduce.propogate_beta_reduce meta params body + (Lam_beta_reduce.propagate_beta_reduce meta params body ap_args) else if (* Lam_analysis.size body < Lam_analysis.small_inline_size *) @@ -273939,7 +273938,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = | false, (_, param_map) | true, (true, param_map) -> ( match rec_flag with | Lam_rec -> - Lam_beta_reduce.propogate_beta_reduce_with_map meta + Lam_beta_reduce.propagate_beta_reduce_with_map meta param_map params body ap_args | Lam_self_rec -> normal () | Lam_non_rec -> @@ -273950,15 +273949,15 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t = then normal () else simpl - (Lam_beta_reduce.propogate_beta_reduce_with_map meta + (Lam_beta_reduce.propagate_beta_reduce_with_map meta param_map params body ap_args)) | _ -> normal () else normal () else normal () | Some _ | None -> normal ()) | Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ } - when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_inlined lfunction -> - simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) + when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction -> + simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args) (* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *) (* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *) (* (\** TODO: keep track of this parameter in ocaml trunk, *)