Skip to content

Commit 45b4d6a

Browse files
committed
specialize Js.Dict.fromArray to compile to a direct JS object creation when possible
1 parent dbe3a58 commit 45b4d6a

File tree

5 files changed

+60
-4
lines changed

5 files changed

+60
-4
lines changed

jscomp/ml/translcore.ml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,14 @@ let try_ids = Hashtbl.create 8
683683

684684
let has_async_attribute exp = exp.exp_attributes |> List.exists (fun ({txt}, _payload) -> txt = "res.async")
685685

686+
let args_elgible_for_dict_inlining (args : expression list) =
687+
args
688+
|> List.find_opt (fun (arg : expression) ->
689+
match arg.exp_desc with
690+
| Texp_tuple [{exp_desc = Texp_constant (Const_string _)}; _] -> false
691+
| _ -> true)
692+
|> Option.is_none
693+
686694
let rec transl_exp e =
687695
List.iter (Translattribute.check_attribute e) e.exp_attributes;
688696
transl_exp0 e
@@ -758,6 +766,28 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
758766
| _ ->
759767
wrap (Lprim (prim, argl, e.exp_loc))
760768
))
769+
| Texp_apply
770+
( {exp_desc = Texp_ident (p, _, _)},
771+
[(_lbl, Some {exp_desc = Texp_array args})] )
772+
when Path.name p = "Js.Dict.fromArray"
773+
&& args_elgible_for_dict_inlining args ->
774+
let fields = Array.make (List.length args) "" in
775+
let args =
776+
args
777+
|> List.mapi (fun index (arg : expression) ->
778+
match arg.exp_desc with
779+
| Texp_tuple
780+
[{exp_desc = Texp_constant (Const_string (fieldName, _))}; exp]
781+
->
782+
Array.set fields index fieldName;
783+
exp |> transl_exp |> extract_constant
784+
| _ -> assert false)
785+
in
786+
Lconst
787+
(Const_block
788+
( Blk_record
789+
{fields; mutable_flag = Mutable; record_repr = Record_regular},
790+
args ))
761791
| Texp_apply (funct, oargs) ->
762792
let inlined, funct =
763793
Translattribute.get_and_remove_inlined_attribute funct

jscomp/runtime/release.ninja

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ o runtime/caml_bytes.cmj : cc_cmi runtime/caml_bytes.res | runtime/caml_bytes.cm
2121
o runtime/caml_bytes.cmi : cc runtime/caml_bytes.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
2222
o runtime/caml_float.cmj : cc_cmi runtime/caml_float.res | runtime/caml_float.cmi runtime/caml_float_extern.cmj
2323
o runtime/caml_float.cmi : cc runtime/caml_float.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
24-
o runtime/caml_format.cmj : cc_cmi runtime/caml_format.ml | runtime/caml_float.cmj runtime/caml_float_extern.cmj runtime/caml_format.cmi runtime/caml_int64.cmj runtime/caml_int64_extern.cmj runtime/caml_nativeint_extern.cmj runtime/caml_string_extern.cmj
24+
o runtime/caml_format.cmj : cc_cmi runtime/caml_format.ml | runtime/caml.cmj runtime/caml_float.cmj runtime/caml_float_extern.cmj runtime/caml_format.cmi runtime/caml_int64.cmj runtime/caml_int64_extern.cmj runtime/caml_nativeint_extern.cmj runtime/caml_string_extern.cmj
2525
o runtime/caml_format.cmi : cc runtime/caml_format.mli | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
2626
o runtime/caml_hash.cmj : cc_cmi runtime/caml_hash.res | runtime/caml_hash.cmi runtime/caml_hash_primitive.cmj runtime/caml_nativeint_extern.cmj runtime/js.cmj
2727
o runtime/caml_hash.cmi : cc runtime/caml_hash.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
@@ -37,7 +37,7 @@ o runtime/caml_md5.cmj : cc_cmi runtime/caml_md5.res | runtime/caml_array_extern
3737
o runtime/caml_md5.cmi : cc runtime/caml_md5.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
3838
o runtime/caml_module.cmj : cc_cmi runtime/caml_module.res | runtime/caml_array_extern.cmj runtime/caml_module.cmi runtime/caml_obj.cmj
3939
o runtime/caml_module.cmi : cc runtime/caml_module.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
40-
o runtime/caml_obj.cmj : cc_cmi runtime/caml_obj.res | runtime/caml_array_extern.cmj runtime/caml_obj.cmi runtime/caml_option.cmj runtime/js.cmj
40+
o runtime/caml_obj.cmj : cc_cmi runtime/caml_obj.res | runtime/caml.cmj runtime/caml_array_extern.cmj runtime/caml_obj.cmi runtime/caml_option.cmj runtime/js.cmj
4141
o runtime/caml_obj.cmi : cc runtime/caml_obj.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
4242
o runtime/caml_option.cmj : cc_cmi runtime/caml_option.res | runtime/caml_option.cmi runtime/caml_undefined_extern.cmj runtime/js.cmj
4343
o runtime/caml_option.cmi : cc runtime/caml_option.resi | runtime/bs_stdlib_mini.cmi runtime/caml_undefined_extern.cmj runtime/js.cmi runtime/js.cmj
@@ -54,7 +54,7 @@ o runtime/caml_exceptions.cmi runtime/caml_exceptions.cmj : cc runtime/caml_exce
5454
o runtime/caml_external_polyfill.cmi runtime/caml_external_polyfill.cmj : cc runtime/caml_external_polyfill.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
5555
o runtime/caml_float_extern.cmi runtime/caml_float_extern.cmj : cc runtime/caml_float_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
5656
o runtime/caml_int64_extern.cmi runtime/caml_int64_extern.cmj : cc runtime/caml_int64_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
57-
o runtime/caml_js_exceptions.cmi runtime/caml_js_exceptions.cmj : cc runtime/caml_js_exceptions.res | runtime/bs_stdlib_mini.cmi runtime/caml_exceptions.cmj runtime/js.cmi runtime/js.cmj
57+
o runtime/caml_js_exceptions.cmi runtime/caml_js_exceptions.cmj : cc runtime/caml_js_exceptions.res | runtime/bs_stdlib_mini.cmi runtime/caml_exceptions.cmj runtime/caml_option.cmj runtime/js.cmi runtime/js.cmj
5858
o runtime/caml_nativeint_extern.cmi runtime/caml_nativeint_extern.cmj : cc runtime/caml_nativeint_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
5959
o runtime/caml_string_extern.cmi runtime/caml_string_extern.cmj : cc runtime/caml_string_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
6060
o runtime/caml_undefined_extern.cmi runtime/caml_undefined_extern.cmj : cc runtime/caml_undefined_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj

jscomp/test/DictTests.js

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/test/DictTests.res

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
let dictCreationCanBeInlined = Js.Dict.fromArray([
2+
("name", "hello"),
3+
("age", "what"),
4+
("more", "stuff"),
5+
])
6+
7+
external imaginaryExternalArgs: array<(string, string)> = "imaginary"
8+
9+
let dictCreationCanNotBeInlined = Js.Dict.fromArray(imaginaryExternalArgs)

jscomp/test/build.ninja

Lines changed: 2 additions & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)