Skip to content

Commit 85eb864

Browse files
zthcknittcristianoc
authored
Specialize uses of new dict literal to direct JS object creation (#6538)
* specialize Js.Dict.fromArray to compile to a direct JS object creation when possible * second approach to inlining dicts * change matching approach * remove experiment * changelog * move changelog to correct place * spelling * Fix format * change approach to use builtin primitive for creating dicts * remove old js fromArray way of specializing dict * cleanup * cleanup * cleanup * cleanup * snapshor * move creator fn to new runtime dict module * ocaml format * artifact list * ignore editor tooling file * remove redundant tests from syntax, and add more tests to dict test file --------- Co-authored-by: Christoph Knittel <ck@cca.io> Co-authored-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
1 parent 62095e6 commit 85eb864

File tree

18 files changed

+74
-77
lines changed

18 files changed

+74
-77
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
- Allow coercing polyvariants to variants when we can guarantee that the runtime representation matches. https://github.com/rescript-lang/rescript-compiler/pull/6981
1818
- Add new dict literal syntax (`dict{"foo": "bar"}`). https://github.com/rescript-lang/rescript-compiler/pull/6774
19+
- Optimize usage of the new dict literal syntax to emit an actual JS object literal. https://github.com/rescript-lang/rescript-compiler/pull/6538
1920

2021
#### :nail_care: Polish
2122

@@ -2618,4 +2619,4 @@ Features:
26182619
26192620
# 1.0.0
26202621
2621-
Initial release
2622+
Initial release

jscomp/core/lam_dispatch_primitive.ml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,17 @@ let translate loc (prim_name : string) (args : J.expression list) : J.expression
264264
match args with
265265
| [e] -> {e with expression_desc = Await e}
266266
| _ -> assert false)
267+
| "?create_dict" -> (
268+
match args with
269+
| [{expression_desc = Array (items, _)}] ->
270+
E.obj
271+
(items
272+
|> List.filter_map (fun (exp : J.expression) ->
273+
match exp.expression_desc with
274+
| Caml_block ([{expression_desc = Str {txt}}; expr], _, _, _) ->
275+
Some (Js_op.Lit txt, expr)
276+
| _ -> None))
277+
| _ -> assert false)
267278
| missing_impl ->
268279
let msg = Warnings.message (Bs_unimplemented_primitive missing_impl) in
269280
Location.raise_errorf ~loc "%s" msg

jscomp/runtime/caml_dict.res

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
external unsafe_create: array<(string, 'a)> => dict<'a> = "?create_dict"

jscomp/runtime/caml_dict.resi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
external unsafe_create: array<(string, 'a)> => dict<'a> = "?create_dict"

jscomp/runtime/release.ninja

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ o runtime/caml_bigint.cmj : cc_cmi runtime/caml_bigint.res | runtime/caml_bigint
2121
o runtime/caml_bigint.cmi : cc runtime/caml_bigint.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
2222
o runtime/caml_bytes.cmj : cc_cmi runtime/caml_bytes.res | runtime/caml_bytes.cmi
2323
o runtime/caml_bytes.cmi : cc runtime/caml_bytes.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
24+
o runtime/caml_dict.cmj : cc_cmi runtime/caml_dict.res | runtime/caml_dict.cmi
25+
o runtime/caml_dict.cmi : cc runtime/caml_dict.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
2426
o runtime/caml_exceptions.cmj : cc_cmi runtime/caml_exceptions.res | runtime/caml_exceptions.cmi
2527
o runtime/caml_exceptions.cmi : cc runtime/caml_exceptions.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj
2628
o runtime/caml_float.cmj : cc_cmi runtime/caml_float.res | runtime/caml_float.cmi runtime/caml_float_extern.cmj
@@ -62,4 +64,4 @@ o runtime/caml_nativeint_extern.cmi runtime/caml_nativeint_extern.cmj : cc runti
6264
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
6365
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
6466
o runtime/curry.cmi runtime/curry.cmj : cc runtime/curry.res | runtime/bs_stdlib_mini.cmi runtime/caml_array.cmj runtime/caml_array_extern.cmj runtime/js.cmi runtime/js.cmj
65-
o runtime : phony runtime/bs_stdlib_mini.cmi runtime/js.cmj runtime/js.cmi runtime/caml.cmi runtime/caml.cmj runtime/caml_array.cmi runtime/caml_array.cmj runtime/caml_bigint.cmi runtime/caml_bigint.cmj runtime/caml_bytes.cmi runtime/caml_bytes.cmj runtime/caml_exceptions.cmi runtime/caml_exceptions.cmj runtime/caml_float.cmi runtime/caml_float.cmj runtime/caml_format.cmi runtime/caml_format.cmj runtime/caml_hash.cmi runtime/caml_hash.cmj runtime/caml_hash_primitive.cmi runtime/caml_hash_primitive.cmj runtime/caml_int32.cmi runtime/caml_int32.cmj runtime/caml_int64.cmi runtime/caml_int64.cmj runtime/caml_lexer.cmi runtime/caml_lexer.cmj runtime/caml_md5.cmi runtime/caml_md5.cmj runtime/caml_module.cmi runtime/caml_module.cmj runtime/caml_obj.cmi runtime/caml_obj.cmj runtime/caml_option.cmi runtime/caml_option.cmj runtime/caml_parser.cmi runtime/caml_parser.cmj runtime/caml_splice_call.cmi runtime/caml_splice_call.cmj runtime/caml_string.cmi runtime/caml_string.cmj runtime/caml_sys.cmi runtime/caml_sys.cmj runtime/caml_array_extern.cmi runtime/caml_array_extern.cmj runtime/caml_bigint_extern.cmi runtime/caml_bigint_extern.cmj runtime/caml_float_extern.cmi runtime/caml_float_extern.cmj runtime/caml_int64_extern.cmi runtime/caml_int64_extern.cmj runtime/caml_js_exceptions.cmi runtime/caml_js_exceptions.cmj runtime/caml_nativeint_extern.cmi runtime/caml_nativeint_extern.cmj runtime/caml_string_extern.cmi runtime/caml_string_extern.cmj runtime/caml_undefined_extern.cmi runtime/caml_undefined_extern.cmj runtime/curry.cmi runtime/curry.cmj
67+
o runtime : phony runtime/bs_stdlib_mini.cmi runtime/js.cmj runtime/js.cmi runtime/caml.cmi runtime/caml.cmj runtime/caml_array.cmi runtime/caml_array.cmj runtime/caml_bigint.cmi runtime/caml_bigint.cmj runtime/caml_bytes.cmi runtime/caml_bytes.cmj runtime/caml_dict.cmi runtime/caml_dict.cmj runtime/caml_exceptions.cmi runtime/caml_exceptions.cmj runtime/caml_float.cmi runtime/caml_float.cmj runtime/caml_format.cmi runtime/caml_format.cmj runtime/caml_hash.cmi runtime/caml_hash.cmj runtime/caml_hash_primitive.cmi runtime/caml_hash_primitive.cmj runtime/caml_int32.cmi runtime/caml_int32.cmj runtime/caml_int64.cmi runtime/caml_int64.cmj runtime/caml_lexer.cmi runtime/caml_lexer.cmj runtime/caml_md5.cmi runtime/caml_md5.cmj runtime/caml_module.cmi runtime/caml_module.cmj runtime/caml_obj.cmi runtime/caml_obj.cmj runtime/caml_option.cmi runtime/caml_option.cmj runtime/caml_parser.cmi runtime/caml_parser.cmj runtime/caml_splice_call.cmi runtime/caml_splice_call.cmj runtime/caml_string.cmi runtime/caml_string.cmj runtime/caml_sys.cmi runtime/caml_sys.cmj runtime/caml_array_extern.cmi runtime/caml_array_extern.cmj runtime/caml_bigint_extern.cmi runtime/caml_bigint_extern.cmj runtime/caml_float_extern.cmi runtime/caml_float_extern.cmj runtime/caml_int64_extern.cmi runtime/caml_int64_extern.cmj runtime/caml_js_exceptions.cmi runtime/caml_js_exceptions.cmj runtime/caml_nativeint_extern.cmi runtime/caml_nativeint_extern.cmj runtime/caml_string_extern.cmi runtime/caml_string_extern.cmj runtime/caml_undefined_extern.cmi runtime/caml_undefined_extern.cmj runtime/curry.cmi runtime/curry.cmj

jscomp/syntax/src/res_comments_table.ml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,11 +1349,7 @@ and walk_expression expr t comments =
13491349
( {
13501350
pexp_desc =
13511351
Pexp_ident
1352-
{
1353-
txt =
1354-
Longident.Ldot
1355-
(Longident.Ldot (Lident "Js", "Dict"), "fromArray");
1356-
};
1352+
{txt = Longident.Ldot (Lident "Caml_dict", "unsafe_create")};
13571353
},
13581354
[(Nolabel, key_values)] )
13591355
when Res_parsetree_viewer.is_tuple_array key_values ->

jscomp/syntax/src/res_core.ml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3946,8 +3946,7 @@ and parse_dict_expr ~start_pos p =
39463946
Ast_helper.Exp.apply ~loc
39473947
(Ast_helper.Exp.ident ~loc
39483948
(Location.mkloc
3949-
(Longident.Ldot
3950-
(Longident.Ldot (Longident.Lident "Js", "Dict"), "fromArray"))
3949+
(Longident.Ldot (Longident.Lident "Caml_dict", "unsafe_create"))
39513950
loc))
39523951
[(Asttypes.Nolabel, Ast_helper.Exp.array ~loc key_value_pairs)]
39533952

jscomp/syntax/src/res_printer.ml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4078,11 +4078,7 @@ and print_pexp_apply ~state expr cmt_tbl =
40784078
( {
40794079
pexp_desc =
40804080
Pexp_ident
4081-
{
4082-
txt =
4083-
Longident.Ldot
4084-
(Longident.Ldot (Lident "Js", "Dict"), "fromArray");
4085-
};
4081+
{txt = Longident.Ldot (Lident "Caml_dict", "unsafe_create")};
40864082
},
40874083
[(Nolabel, key_values)] )
40884084
when Res_parsetree_viewer.is_tuple_array key_values ->
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
let x = Js.Dict.fromArray [||]
2-
let x = Js.Dict.fromArray [|("foo", {js|bar|js})|]
3-
let x = Js.Dict.fromArray [|("foo", {js|bar|js});("bar", {js|baz|js})|]
1+
let x = Caml_dict.unsafe_create [||]
2+
let x = Caml_dict.unsafe_create [|("foo", {js|bar|js})|]
3+
let x = Caml_dict.unsafe_create [|("foo", {js|bar|js});("bar", {js|baz|js})|]
44
let baz = {js|foo|js}
55
let x =
6-
Js.Dict.fromArray
6+
Caml_dict.unsafe_create
77
[|("foo", {js|bar|js});("bar", {js|baz|js});("baz", baz)|]

jscomp/syntax/tests/printer/expr/dict.res

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,6 @@ let x = dict{
1717
"baz": baz
1818
}
1919

20-
let x = Js.Dict.fromArray([("foo", "bar"), ("bar", "baz")])
21-
let x = Js.Dict.fromArray([("foo", "bar"), ("bar", "baz"), ("baz", baz)])
22-
23-
let x = Js.Dict.fromArray([
24-
("foo", "bar"),
25-
("bar", "baz"),
26-
("baz", baz)
27-
])
28-
2920
// comments
3021
let x = dict{/* foo */ "foo": "bar"}
3122
let x = dict{"foo": /* foo */ "bar"}
@@ -63,23 +54,3 @@ let x = dict{
6354
"bar": "baz" /* bar */,
6455
"baz": baz /* bar */
6556
}
66-
67-
let x = Js.Dict.fromArray([/* foo */ ("foo", "bar"), /* bar */ ("bar", "baz")])
68-
let x = Js.Dict.fromArray([(/* foo */ "foo", "bar"), (/* bar */"bar", "baz"), (/* baz */ "baz", baz)])
69-
let x = Js.Dict.fromArray([("foo", /* foo */"bar"), ("bar", /* bar */"baz"), ("baz", /* baz */baz)])
70-
let x = Js.Dict.fromArray([("foo", "bar" /* foo */), ("bar", "baz" /* bar */), ("baz", baz /* baz */)])
71-
72-
let x = Js.Dict.fromArray([
73-
// foo
74-
("foo", "bar"),
75-
// bar
76-
("bar", "baz"),
77-
// baz
78-
("baz", baz)
79-
])
80-
81-
let x = Js.Dict.fromArray([
82-
("foo", "bar"), // foo
83-
("bar", "baz"), // bar
84-
("baz", baz) // baz
85-
])

jscomp/syntax/tests/printer/expr/expected/dict.res.txt

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,6 @@ let x = dict{
1717
"baz": baz,
1818
}
1919

20-
let x = dict{"foo": "bar", "bar": "baz"}
21-
let x = dict{"foo": "bar", "bar": "baz", "baz": baz}
22-
23-
let x = dict{
24-
"foo": "bar",
25-
"bar": "baz",
26-
"baz": baz,
27-
}
28-
2920
// comments
3021
let x = dict{/* foo */ "foo": "bar"}
3122
let x = dict{"foo": /* foo */ "bar"}
@@ -63,23 +54,3 @@ let x = dict{
6354
"bar": "baz" /* bar */,
6455
"baz": baz /* bar */,
6556
}
66-
67-
let x = dict{/* foo */ "foo": "bar", /* bar */ "bar": "baz"}
68-
let x = dict{/* foo */ "foo": "bar", /* bar */ "bar": "baz", /* baz */ "baz": baz}
69-
let x = dict{"foo": /* foo */ "bar", "bar": /* bar */ "baz", "baz": /* baz */ baz}
70-
let x = dict{"foo": "bar" /* foo */, "bar": "baz" /* bar */, "baz": baz /* baz */}
71-
72-
let x = dict{
73-
// foo
74-
"foo": "bar",
75-
// bar
76-
"bar": "baz",
77-
// baz
78-
"baz": baz,
79-
}
80-
81-
let x = dict{
82-
"foo": "bar", // foo
83-
"bar": "baz", // bar
84-
"baz": baz, // baz
85-
}

jscomp/test/DictTests.js

Lines changed: 26 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: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
let someString = "hello"
2+
3+
let createdDict = dict{
4+
"name": "hello",
5+
"age": "what",
6+
"more": "stuff",
7+
"otherStr": someString,
8+
}
9+
10+
let three = 3
11+
12+
let intDict = dict{
13+
"one": 1,
14+
"two": 2,
15+
"three": three,
16+
}

jscomp/test/build.ninja

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

lib/.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
*.log
33
*.ninja
44
.ninja_log
5+
bs/.project-files-cache

lib/es6/caml_dict.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */

lib/js/caml_dict.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */

packages/artifacts.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ lib/es6/caml_array_extern.js
8080
lib/es6/caml_bigint.js
8181
lib/es6/caml_bigint_extern.js
8282
lib/es6/caml_bytes.js
83+
lib/es6/caml_dict.js
8384
lib/es6/caml_exceptions.js
8485
lib/es6/caml_float.js
8586
lib/es6/caml_float_extern.js
@@ -238,6 +239,7 @@ lib/js/caml_array_extern.js
238239
lib/js/caml_bigint.js
239240
lib/js/caml_bigint_extern.js
240241
lib/js/caml_bytes.js
242+
lib/js/caml_dict.js
241243
lib/js/caml_exceptions.js
242244
lib/js/caml_float.js
243245
lib/js/caml_float_extern.js

0 commit comments

Comments
 (0)