mirror of
https://github.com/oven-sh/bun
synced 2026-02-06 08:58:52 +00:00
Compare commits
440 Commits
jarred/fet
...
jarred/esc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab04e82f55 | ||
|
|
5aa196b361 | ||
|
|
9f640ffb51 | ||
|
|
af6859acc2 | ||
|
|
e5322eb63b | ||
|
|
102553dca6 | ||
|
|
549e5bbbcd | ||
|
|
57ad68a4b0 | ||
|
|
e5eabc0658 | ||
|
|
121c2960de | ||
|
|
a96a2a8b12 | ||
|
|
6e8a30e999 | ||
|
|
7b455492d3 | ||
|
|
f9710e270a | ||
|
|
515da14621 | ||
|
|
b735de0d3f | ||
|
|
bf28afad1d | ||
|
|
73ad5c4f67 | ||
|
|
73ec79fa8e | ||
|
|
3083718e3f | ||
|
|
17cdc0fee6 | ||
|
|
26c890d3a1 | ||
|
|
564b6d12f0 | ||
|
|
f4aa3a8c34 | ||
|
|
ed63b22f7a | ||
|
|
b18b0efb8b | ||
|
|
7f3bc2b9e6 | ||
|
|
c362729186 | ||
|
|
f0e58fec49 | ||
|
|
9fcc5f27e8 | ||
|
|
ab2d25bfec | ||
|
|
3e55023819 | ||
|
|
4fb9354439 | ||
|
|
958fc3d4f5 | ||
|
|
aecc849692 | ||
|
|
882559f0b9 | ||
|
|
ca21c00f86 | ||
|
|
960cb1a8d5 | ||
|
|
8a3a5c3b74 | ||
|
|
99d61877d6 | ||
|
|
224cfa91fb | ||
|
|
1af67dbe15 | ||
|
|
55bfa6cd02 | ||
|
|
1d0124093c | ||
|
|
70078f48c0 | ||
|
|
44d1b217ac | ||
|
|
3672bb85eb | ||
|
|
6f741e8c10 | ||
|
|
d4767ca763 | ||
|
|
07e695da03 | ||
|
|
4f72021007 | ||
|
|
bc73d21917 | ||
|
|
7ca297a5cc | ||
|
|
e114fca5ee | ||
|
|
d0ca9f2499 | ||
|
|
95daafee0f | ||
|
|
37e4848c6f | ||
|
|
78cd9e89f3 | ||
|
|
15c40f5ea3 | ||
|
|
5f3256d939 | ||
|
|
a2b22c339e | ||
|
|
aed5e39f4d | ||
|
|
bd1e64b9b1 | ||
|
|
31f3050356 | ||
|
|
ba36f5db7e | ||
|
|
a372a0dd6d | ||
|
|
aba032e176 | ||
|
|
e31f44c3d1 | ||
|
|
0d12a1f9ee | ||
|
|
036eb2a9ed | ||
|
|
2eb889be89 | ||
|
|
dd07717b80 | ||
|
|
36a82cfb93 | ||
|
|
6fce02bd85 | ||
|
|
93767bf78f | ||
|
|
a779fc180f | ||
|
|
223ce6b22d | ||
|
|
5d4673742e | ||
|
|
05eb1e5684 | ||
|
|
b4ac7697ac | ||
|
|
2cfc1d42a3 | ||
|
|
be1f469ec5 | ||
|
|
a37f86e89d | ||
|
|
2bd0dcfdfa | ||
|
|
e75535d14c | ||
|
|
1d6923bead | ||
|
|
732124e3dd | ||
|
|
a15e66cc7b | ||
|
|
3eacfe2314 | ||
|
|
89c0d9dd56 | ||
|
|
b21d0f0b22 | ||
|
|
61b2821472 | ||
|
|
1f86e0c87e | ||
|
|
d1ea51e9f2 | ||
|
|
5de2e2c71e | ||
|
|
2c1051f539 | ||
|
|
247f4810c5 | ||
|
|
47b6dc9eea | ||
|
|
aea3b4e280 | ||
|
|
12e0496a79 | ||
|
|
aa87d40f4b | ||
|
|
7d1eced8c6 | ||
|
|
123267685f | ||
|
|
0bec7001ba | ||
|
|
3c87fbfd37 | ||
|
|
fd00950852 | ||
|
|
eb2a6aee4d | ||
|
|
84e8d08ec6 | ||
|
|
92e8eaf581 | ||
|
|
e8e58a511f | ||
|
|
08e40efe11 | ||
|
|
01a0aee1e8 | ||
|
|
8def37c14e | ||
|
|
b3760cd723 | ||
|
|
1cb870be16 | ||
|
|
35232fa422 | ||
|
|
77342a2268 | ||
|
|
b834e21192 | ||
|
|
f4188b3ddc | ||
|
|
963c08d472 | ||
|
|
29b9ced11a | ||
|
|
8ac108ba06 | ||
|
|
8014a0b8d8 | ||
|
|
3bd83eb134 | ||
|
|
a5ebcefeeb | ||
|
|
c806e778d6 | ||
|
|
3850fc5b0b | ||
|
|
6bac11f066 | ||
|
|
bc2ca8afbd | ||
|
|
e403b6111f | ||
|
|
d613ba5fcd | ||
|
|
4dee9be3eb | ||
|
|
61afb8955c | ||
|
|
61d548c7bf | ||
|
|
c1efeefb8a | ||
|
|
3b6c3d8196 | ||
|
|
97cceb47b9 | ||
|
|
94637711b9 | ||
|
|
bdf28e42f6 | ||
|
|
1687455a3f | ||
|
|
84e40a4f74 | ||
|
|
bce60a5a86 | ||
|
|
a7b0bc8790 | ||
|
|
30ca112260 | ||
|
|
b487eb7e13 | ||
|
|
5d24f45ac1 | ||
|
|
c1f65ef975 | ||
|
|
d6ce585ef3 | ||
|
|
c80e048ab3 | ||
|
|
b6a8675658 | ||
|
|
2c0c91e2d0 | ||
|
|
6b97680224 | ||
|
|
c76bebca0b | ||
|
|
b534c4d661 | ||
|
|
170d09b6bd | ||
|
|
b4fc584d18 | ||
|
|
5b2d9f8128 | ||
|
|
d629cfafd6 | ||
|
|
7b125c9731 | ||
|
|
0e3df25526 | ||
|
|
66e8d7346f | ||
|
|
d29dcf3680 | ||
|
|
164483c137 | ||
|
|
6ab5ae8a7a | ||
|
|
5b760fe7c4 | ||
|
|
162e8911db | ||
|
|
bea2cc9cbc | ||
|
|
ce2261dffa | ||
|
|
fa562fa56d | ||
|
|
5bfd241167 | ||
|
|
5a85cc4386 | ||
|
|
ed4a021f85 | ||
|
|
83c1d7c9ef | ||
|
|
de6aed65fb | ||
|
|
57ce49654c | ||
|
|
00bc2638ce | ||
|
|
4605aff04a | ||
|
|
d104c286c8 | ||
|
|
16d5325874 | ||
|
|
e3362a0fda | ||
|
|
f0fdda5678 | ||
|
|
bb2d67e361 | ||
|
|
91e96a8da8 | ||
|
|
8b1924f6c2 | ||
|
|
c6d732eee2 | ||
|
|
21ab47d9fe | ||
|
|
d70e92e79f | ||
|
|
15466865e0 | ||
|
|
125a4c747b | ||
|
|
69668d49e5 | ||
|
|
5cee316d8c | ||
|
|
98393ca849 | ||
|
|
012564d738 | ||
|
|
3403621fc2 | ||
|
|
de23f2f8aa | ||
|
|
b6aa988716 | ||
|
|
a3b48b3229 | ||
|
|
d7ef268e18 | ||
|
|
ba999c9ac3 | ||
|
|
92b27b338d | ||
|
|
eb129d9f90 | ||
|
|
5e270f9d77 | ||
|
|
7e13d6cbfe | ||
|
|
7e6fe52c46 | ||
|
|
893d245dca | ||
|
|
516b54578d | ||
|
|
d49ba50289 | ||
|
|
22f74756b4 | ||
|
|
f07463bdfd | ||
|
|
75374fdc32 | ||
|
|
0332d47424 | ||
|
|
d531d0851f | ||
|
|
e26f96b748 | ||
|
|
8fa1c5ebf1 | ||
|
|
ef18443b6e | ||
|
|
d066c7de30 | ||
|
|
fd56d0f116 | ||
|
|
77fbfb3fbb | ||
|
|
6590d1f8bf | ||
|
|
2d39e44520 | ||
|
|
2c6e5c3fc4 | ||
|
|
4b4df5095e | ||
|
|
1c11dc6630 | ||
|
|
2eb3319351 | ||
|
|
683b171c3f | ||
|
|
ea241fcec7 | ||
|
|
ab1d83fe8d | ||
|
|
5e739acfbb | ||
|
|
a4b8fccfa7 | ||
|
|
9822ea96b8 | ||
|
|
94db83040e | ||
|
|
12f97f1364 | ||
|
|
0aacddb971 | ||
|
|
7e866bb441 | ||
|
|
c2cf1d6493 | ||
|
|
612fad706f | ||
|
|
6728551dc4 | ||
|
|
64a2dda02f | ||
|
|
8d28e72e8a | ||
|
|
0137e5cf94 | ||
|
|
89ca887ea0 | ||
|
|
42414d5667 | ||
|
|
8bb283e616 | ||
|
|
32e2345e53 | ||
|
|
9e31602a20 | ||
|
|
5d0be616b7 | ||
|
|
e7251c0d55 | ||
|
|
1871bbc6a4 | ||
|
|
add1c91425 | ||
|
|
1788503892 | ||
|
|
95aa76b9fa | ||
|
|
95101870e4 | ||
|
|
f2c21b7733 | ||
|
|
d273948f16 | ||
|
|
bb79687f8e | ||
|
|
3db3057d42 | ||
|
|
f6d73cb06e | ||
|
|
b3522b2feb | ||
|
|
710edd34d2 | ||
|
|
743ad44c0a | ||
|
|
9db701ab41 | ||
|
|
a0f9a6ed60 | ||
|
|
1d79703d24 | ||
|
|
f357377de9 | ||
|
|
87adeb61c5 | ||
|
|
e6a5cab1d2 | ||
|
|
9884a5fe14 | ||
|
|
55ff561429 | ||
|
|
4708dd26ca | ||
|
|
3e969244ac | ||
|
|
ac3835227e | ||
|
|
c6393bcd27 | ||
|
|
7d164ad8c7 | ||
|
|
3abb72037b | ||
|
|
34c478a4c4 | ||
|
|
98592fb85d | ||
|
|
6edf0289ed | ||
|
|
faedbf0a61 | ||
|
|
b08d3b2cd6 | ||
|
|
1e810d229e | ||
|
|
a82c486878 | ||
|
|
d42ae4824b | ||
|
|
b1ebe54456 | ||
|
|
ac76e3b004 | ||
|
|
43b18663fd | ||
|
|
45e1fc946d | ||
|
|
65eb232028 | ||
|
|
7cd3d13011 | ||
|
|
764fb63617 | ||
|
|
4de7978b27 | ||
|
|
696bb3b026 | ||
|
|
fb82e2bf86 | ||
|
|
403a916bd5 | ||
|
|
20cdb197e2 | ||
|
|
1f68b8ada0 | ||
|
|
fdfbf16940 | ||
|
|
12c2659765 | ||
|
|
8561dcdee4 | ||
|
|
ded2bcfda5 | ||
|
|
d5173f71d4 | ||
|
|
61ca99cfd9 | ||
|
|
862155fa5e | ||
|
|
74309a1f9e | ||
|
|
8cdb55d94f | ||
|
|
489299cdcc | ||
|
|
b744634141 | ||
|
|
a8789fc858 | ||
|
|
14def643f7 | ||
|
|
a3398650b5 | ||
|
|
65daaf332d | ||
|
|
63995da2c2 | ||
|
|
f3b118d0ad | ||
|
|
f01a2a3360 | ||
|
|
a0566f0fbe | ||
|
|
4b8425938a | ||
|
|
8fa3536aba | ||
|
|
10712a790a | ||
|
|
9cd148de7d | ||
|
|
9b1d4e1a45 | ||
|
|
b089f1adae | ||
|
|
76d54c572a | ||
|
|
7d25dae75e | ||
|
|
282eaef435 | ||
|
|
80dcd30b48 | ||
|
|
76e04ad82b | ||
|
|
afa0d4f3a3 | ||
|
|
e21a65fd05 | ||
|
|
295249cf08 | ||
|
|
91fb170c4a | ||
|
|
0878659513 | ||
|
|
69cebbfca2 | ||
|
|
3c4510573e | ||
|
|
4285d8ec0b | ||
|
|
c2a8c10834 | ||
|
|
4e05fd0541 | ||
|
|
b97e81b27f | ||
|
|
e08cc968cb | ||
|
|
9bee40813f | ||
|
|
5ac6920591 | ||
|
|
70b1beb18b | ||
|
|
964aa40612 | ||
|
|
7e58c7e89a | ||
|
|
3db549fdb5 | ||
|
|
87401392ba | ||
|
|
795c172d9e | ||
|
|
cfe60996c2 | ||
|
|
da3f131185 | ||
|
|
ac06ce2160 | ||
|
|
69653729f0 | ||
|
|
81eb47de0e | ||
|
|
57cf035a73 | ||
|
|
ddaab5a836 | ||
|
|
f97e6d04a7 | ||
|
|
daeede28db | ||
|
|
70f9294e15 | ||
|
|
2c0e8e0a99 | ||
|
|
7f4b1a5797 | ||
|
|
138ee2803d | ||
|
|
c9fee3bd04 | ||
|
|
db5951337e | ||
|
|
d652e87473 | ||
|
|
57eac42a91 | ||
|
|
d61f877a94 | ||
|
|
7eb575d7f8 | ||
|
|
8e5eda79de | ||
|
|
82051a5f22 | ||
|
|
17b9167e52 | ||
|
|
30542225c6 | ||
|
|
759b6c18fd | ||
|
|
0e1941ce21 | ||
|
|
039fb0732c | ||
|
|
6c91aa6e51 | ||
|
|
2eed081b50 | ||
|
|
7551041fa1 | ||
|
|
41a97c5bf9 | ||
|
|
20ed1c32d3 | ||
|
|
969cf9fd48 | ||
|
|
d29930db3a | ||
|
|
015333de8c | ||
|
|
89b9d167d1 | ||
|
|
2693a3beff | ||
|
|
feb315cf9c | ||
|
|
779e5ccc16 | ||
|
|
7b19de97d4 | ||
|
|
5d71d0a0b4 | ||
|
|
42b47fe4d9 | ||
|
|
5a9e381d84 | ||
|
|
f4e118e40a | ||
|
|
071d4c155b | ||
|
|
044f23739c | ||
|
|
05a4991a5f | ||
|
|
078ceb7168 | ||
|
|
9554dd1c33 | ||
|
|
7fd12ca3ae | ||
|
|
e84494b0e0 | ||
|
|
afc7da33c9 | ||
|
|
d820a9890f | ||
|
|
a9f0d334bb | ||
|
|
cee3783e58 | ||
|
|
fceb88005d | ||
|
|
e3c888a7cc | ||
|
|
25267397f6 | ||
|
|
931e461c87 | ||
|
|
409758dd11 | ||
|
|
cd28c3ca83 | ||
|
|
25533b9e08 | ||
|
|
be70e08671 | ||
|
|
480d4b98c7 | ||
|
|
3b7e421eaf | ||
|
|
b069ff253e | ||
|
|
abc15f4d30 | ||
|
|
70bb8bda23 | ||
|
|
665acdb170 | ||
|
|
27ad502119 | ||
|
|
e8b2af1eae | ||
|
|
4d718931be | ||
|
|
290166adb0 | ||
|
|
c2ed8d0240 | ||
|
|
51e5d3ea70 | ||
|
|
c73fcb0731 | ||
|
|
e6b70c3e01 | ||
|
|
614f64ba82 | ||
|
|
b8263d0975 | ||
|
|
95d68b26a6 | ||
|
|
db39c8e109 | ||
|
|
449c248f08 | ||
|
|
66c5a941b3 | ||
|
|
4592b1ccb5 | ||
|
|
9bfd1801aa | ||
|
|
b099e7232f | ||
|
|
c657c7b846 | ||
|
|
eaf09310cd | ||
|
|
fffb69ce61 | ||
|
|
5c989c957a | ||
|
|
8af0764b3b | ||
|
|
c7727b136b | ||
|
|
7a6b6639bc | ||
|
|
08bf4694ca | ||
|
|
60cc51379d | ||
|
|
e035084e49 |
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -1,4 +1,7 @@
|
||||
.vscode/launch.json linguist-generated
|
||||
src/api/schema.d.ts linguist-generated
|
||||
src/api/schema.js linguist-generated
|
||||
src/javascript/jsc/bindings/sqlite/sqlite3.c linguist-vendored
|
||||
src/javascript/jsc/bindings/sqlite/sqlite3_local.h linguist-vendored
|
||||
*.lockb binary diff=lockb
|
||||
*.zig text eol=lf
|
||||
|
||||
13
.gitignore
vendored
13
.gitignore
vendored
@@ -89,3 +89,16 @@ src/deps/PLCrashReporter/
|
||||
|
||||
*.dSYM
|
||||
*.crash
|
||||
misctools/sha
|
||||
packages/bun-wasm/*.mjs
|
||||
packages/bun-wasm/*.cjs
|
||||
packages/bun-wasm/*.map
|
||||
packages/bun-wasm/*.js
|
||||
packages/bun-wasm/*.d.ts
|
||||
*.bc
|
||||
|
||||
src/fallback.version
|
||||
src/runtime.version
|
||||
*.sqlite
|
||||
*.database
|
||||
*.db
|
||||
|
||||
14
.gitmodules
vendored
14
.gitmodules
vendored
@@ -5,35 +5,49 @@
|
||||
path = src/deps/picohttpparser
|
||||
url = https://github.com/h2o/picohttpparser.git
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
[submodule "src/javascript/jsc/WebKit"]
|
||||
path = src/javascript/jsc/WebKit
|
||||
url = https://github.com/Jarred-Sumner/WebKit.git
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
[submodule "src/deps/mimalloc"]
|
||||
path = src/deps/mimalloc
|
||||
url = https://github.com/Jarred-Sumner/mimalloc.git
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
[submodule "src/deps/zlib"]
|
||||
path = src/deps/zlib
|
||||
url = https://github.com/cloudflare/zlib.git
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
[submodule "src/deps/libarchive"]
|
||||
path = src/deps/libarchive
|
||||
url = https://github.com/libarchive/libarchive.git
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
[submodule "src/deps/boringssl"]
|
||||
path = src/deps/boringssl
|
||||
url = https://github.com/google/boringssl.git
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
[submodule "src/deps/libbacktrace"]
|
||||
path = src/deps/libbacktrace
|
||||
url = https://github.com/ianlancetaylor/libbacktrace
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
[submodule "src/deps/lol-html"]
|
||||
path = src/deps/lol-html
|
||||
url = https://github.com/cloudflare/lol-html
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
[submodule "src/deps/uws"]
|
||||
path = src/deps/uws
|
||||
url = https://github.com/Jarred-Sumner/uWebSockets
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
[submodule "src/deps/tinycc"]
|
||||
path = src/deps/tinycc
|
||||
url = https://github.com/Jarred-Sumner/tinycc.git
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
|
||||
8
.vscode/extensions.json
vendored
Normal file
8
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"AugusteRame.zls-vscode",
|
||||
"esbenp.prettier-vscode",
|
||||
"xaver.clang-format",
|
||||
"vadimcn.vscode-lldb"
|
||||
]
|
||||
}
|
||||
55
.vscode/launch.json
generated
vendored
55
.vscode/launch.json
generated
vendored
@@ -292,25 +292,74 @@
|
||||
"request": "launch",
|
||||
"name": "bun test",
|
||||
"program": "bun-debug",
|
||||
"args": ["wiptest", "transpiler"],
|
||||
"args": ["wiptest"],
|
||||
"cwd": "${workspaceFolder}/integration",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1"
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "bun test current",
|
||||
"program": "bun-debug",
|
||||
"args": ["wiptest", "mmap"],
|
||||
"cwd": "${workspaceFolder}/integration",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1"
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "bun http example",
|
||||
"program": "bun-debug",
|
||||
"args": ["run", "examples/bun/http.ts"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1"
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "bun http file example",
|
||||
"program": "bun-debug",
|
||||
"args": ["run", "examples/bun/http-file.ts"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1"
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "bun html-rewriter example",
|
||||
"program": "bun-debug",
|
||||
"args": ["run", "examples/bun/html-rewriter.ts"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1"
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "bun tes2t",
|
||||
"program": "bun-debug",
|
||||
"args": ["build", "hello.jsx", "--platform=bun"],
|
||||
"cwd": "/Users/jarred/Desktop/",
|
||||
"args": ["add", "imagemin-webpack-plugin"],
|
||||
"cwd": "/tmp/testfoo",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1"
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
|
||||
18
.vscode/settings.json
vendored
18
.vscode/settings.json
vendored
@@ -8,13 +8,24 @@
|
||||
"search.useIgnoreFiles": true,
|
||||
"zig.buildOnSave": false,
|
||||
"[zig]": {
|
||||
"editor.defaultFormatter": "AugusteRame.zls-vscode"
|
||||
"editor.defaultFormatter": "AugusteRame.zls-vscode",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[ts]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[js]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[jsx]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[tsx]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"zig.beforeDebugCmd": "make build-unit ${file} ${filter} ${bin}",
|
||||
"zig.testCmd": "make test ${file} ${filter} ${bin}",
|
||||
@@ -31,6 +42,7 @@
|
||||
"**/*.xcscheme": true,
|
||||
"**/*.pem": true,
|
||||
"**/*.xcodeproj": true,
|
||||
"packages/bun-types/*.d.ts": true,
|
||||
|
||||
"integration/snapshots": true,
|
||||
"integration/snapshots-no-hmr": true,
|
||||
|
||||
78
Dockerfile
78
Dockerfile
@@ -71,6 +71,26 @@ WORKDIR $BUN_DIR
|
||||
RUN cd $BUN_DIR && \
|
||||
make libarchive && rm -rf src/deps/libarchive Makefile
|
||||
|
||||
FROM bunbunbunbun/bun-base:latest as tinycc
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG GITHUB_WORKSPACE=/build
|
||||
ARG ZIG_PATH=${GITHUB_WORKSPACE}/zig
|
||||
# Directory extracts to "bun-webkit"
|
||||
ARG WEBKIT_DIR=${GITHUB_WORKSPACE}/bun-webkit
|
||||
ARG BUN_RELEASE_DIR=${GITHUB_WORKSPACE}/bun-release
|
||||
ARG BUN_DEPS_OUT_DIR=${GITHUB_WORKSPACE}/bun-deps
|
||||
ARG BUN_DIR=${GITHUB_WORKSPACE}/bun
|
||||
|
||||
COPY Makefile ${BUN_DIR}/Makefile
|
||||
COPY src/deps/tinycc ${BUN_DIR}/src/deps/tinycc
|
||||
|
||||
WORKDIR $BUN_DIR
|
||||
|
||||
RUN cd $BUN_DIR && \
|
||||
make tinycc && rm -rf src/deps/tinycc Makefile
|
||||
|
||||
|
||||
FROM bunbunbunbun/bun-base:latest as libbacktrace
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
@@ -106,8 +126,48 @@ COPY src/deps/boringssl ${BUN_DIR}/src/deps/boringssl
|
||||
|
||||
WORKDIR $BUN_DIR
|
||||
|
||||
RUN make boringssl && rm -rf src/deps/boringssl Makefile
|
||||
|
||||
FROM bunbunbunbun/bun-base:latest as base64
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG GITHUB_WORKSPACE=/build
|
||||
ARG ZIG_PATH=${GITHUB_WORKSPACE}/zig
|
||||
# Directory extracts to "bun-webkit"
|
||||
ARG WEBKIT_DIR=${GITHUB_WORKSPACE}/bun-webkit
|
||||
ARG BUN_RELEASE_DIR=${GITHUB_WORKSPACE}/bun-release
|
||||
ARG BUN_DEPS_OUT_DIR=${GITHUB_WORKSPACE}/bun-deps
|
||||
ARG BUN_DIR=${GITHUB_WORKSPACE}/bun
|
||||
|
||||
COPY Makefile ${BUN_DIR}/Makefile
|
||||
COPY src/base64 ${BUN_DIR}/src/base64
|
||||
|
||||
WORKDIR $BUN_DIR
|
||||
|
||||
RUN make base64 && rm -rf src/base64 Makefile
|
||||
|
||||
FROM bunbunbunbun/bun-base:latest as uws
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG GITHUB_WORKSPACE=/build
|
||||
ARG ZIG_PATH=${GITHUB_WORKSPACE}/zig
|
||||
# Directory extracts to "bun-webkit"
|
||||
ARG WEBKIT_DIR=${GITHUB_WORKSPACE}/bun-webkit
|
||||
ARG BUN_RELEASE_DIR=${GITHUB_WORKSPACE}/bun-release
|
||||
ARG BUN_DEPS_OUT_DIR=${GITHUB_WORKSPACE}/bun-deps
|
||||
ARG BUN_DIR=${GITHUB_WORKSPACE}/bun
|
||||
|
||||
COPY Makefile ${BUN_DIR}/Makefile
|
||||
COPY src/deps/uws ${BUN_DIR}/src/deps/uws
|
||||
COPY src/deps/zlib ${BUN_DIR}/src/deps/zlib
|
||||
COPY src/deps/boringssl/include ${BUN_DIR}/src/deps/boringssl/include
|
||||
COPY src/deps/libuwsockets.cpp ${BUN_DIR}/src/deps/libuwsockets.cpp
|
||||
COPY src/deps/_libusockets.h ${BUN_DIR}/src/deps/_libusockets.h
|
||||
|
||||
WORKDIR $BUN_DIR
|
||||
|
||||
RUN cd $BUN_DIR && \
|
||||
make boringssl && rm -rf src/deps/boringssl Makefile
|
||||
make uws && rm -rf src/deps/uws Makefile
|
||||
|
||||
FROM bunbunbunbun/bun-base:latest as picohttp
|
||||
|
||||
@@ -122,14 +182,15 @@ ARG BUN_DIR=${GITHUB_WORKSPACE}/bun
|
||||
|
||||
COPY Makefile ${BUN_DIR}/Makefile
|
||||
COPY src/deps/picohttpparser ${BUN_DIR}/src/deps/picohttpparser
|
||||
COPY src/deps/*.c ${BUN_DIR}/src/deps
|
||||
COPY src/deps/*.h ${BUN_DIR}/src/deps
|
||||
COPY src/deps/*.c ${BUN_DIR}/src/deps/
|
||||
COPY src/deps/*.h ${BUN_DIR}/src/deps/
|
||||
|
||||
WORKDIR $BUN_DIR
|
||||
|
||||
RUN cd $BUN_DIR && \
|
||||
make picohttp
|
||||
|
||||
|
||||
FROM bunbunbunbun/bun-base-with-zig-and-webkit:latest as identifier_cache
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
@@ -197,9 +258,13 @@ COPY --from=mimalloc ${BUN_DEPS_OUT_DIR}/*.o ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=libarchive ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=picohttp ${BUN_DEPS_OUT_DIR}/*.o ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=boringssl ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=uws ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=uws ${BUN_DEPS_OUT_DIR}/*.o ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=libbacktrace ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=zlib ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=identifier_cache ${BUN_DIR}/src/js_lexer/*.blob ${BUN_DIR}/src/js_lexer
|
||||
COPY --from=tinycc ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=base64 ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=identifier_cache ${BUN_DIR}/src/js_lexer/*.blob ${BUN_DIR}/src/js_lexer/
|
||||
COPY --from=node_fallbacks ${BUN_DIR}/src/node-fallbacks/out ${BUN_DIR}/src/node-fallbacks/out
|
||||
|
||||
WORKDIR ${BUN_DIR}
|
||||
@@ -227,7 +292,8 @@ RUN cd $BUN_DIR && rm -rf $HOME/.cache zig-cache && make \
|
||||
bun_error \
|
||||
fallback_decoder && rm -rf $HOME/.cache zig-cache && \
|
||||
mkdir -p $BUN_RELEASE_DIR && \
|
||||
make release copy-to-bun-release-dir && \
|
||||
make jsc-bindings-mac -j10 && \
|
||||
make sqlite release copy-to-bun-release-dir && \
|
||||
rm -rf $HOME/.cache zig-cache misctools package.json build-id completions build.zig $(BUN_DIR)/packages
|
||||
|
||||
FROM prepare_release as build_unit
|
||||
@@ -250,7 +316,7 @@ CMD make jsc-bindings-headers \
|
||||
analytics \
|
||||
bun_error \
|
||||
fallback_decoder \
|
||||
jsc-bindings-mac && \
|
||||
jsc-bindings-mac -j10 && \
|
||||
make \
|
||||
run-all-unit-tests
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ RUN cd $GITHUB_WORKSPACE && \
|
||||
rm zig-linux-$BUILDARCH.zip;
|
||||
|
||||
RUN cd $GITHUB_WORKSPACE && \
|
||||
curl -o bun-webkit-linux-$BUILDARCH.tar.gz -L https://github.com/Jarred-Sumner/WebKit/releases/download/Mar15/bun-webkit-linux-$BUILDARCH.tar.gz && \
|
||||
curl -o bun-webkit-linux-$BUILDARCH.tar.gz -L https://github.com/Jarred-Sumner/WebKit/releases/download/May8/bun-webkit-linux-$BUILDARCH.tar.gz && \
|
||||
tar -xzf bun-webkit-linux-$BUILDARCH.tar.gz && \
|
||||
rm bun-webkit-linux-$BUILDARCH.tar.gz && \
|
||||
cat $WEBKIT_OUT_DIR/include/cmakeconfig.h > /dev/null
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
# FROM bun_base as picohttp
|
||||
|
||||
# COPY src/deps/picohttpparser /bun/src/deps/picohttpparser
|
||||
# COPY src/deps/*.c /bun/src/deps
|
||||
# COPY src/deps/*.h /bun/src/deps
|
||||
# COPY src/deps/*.c /bun/src/deps/
|
||||
# COPY src/deps/*.h /bun/src/deps/
|
||||
|
||||
# RUN make picohttp
|
||||
|
||||
|
||||
356
Makefile
356
Makefile
@@ -12,7 +12,7 @@ endif
|
||||
MIN_MACOS_VERSION = 10.14
|
||||
|
||||
|
||||
MARCH_NATIVE =
|
||||
MARCH_NATIVE = -mtune=native
|
||||
|
||||
ARCH_NAME :=
|
||||
DOCKER_BUILDARCH =
|
||||
@@ -21,17 +21,18 @@ ifeq ($(ARCH_NAME_RAW),arm64)
|
||||
DOCKER_BUILDARCH = arm64
|
||||
BREW_PREFIX_PATH = /opt/homebrew
|
||||
MIN_MACOS_VERSION = 11.0
|
||||
MARCH_NATIVE = -mtune=native
|
||||
else
|
||||
ARCH_NAME = x64
|
||||
DOCKER_BUILDARCH = amd64
|
||||
BREW_PREFIX_PATH = /usr/local
|
||||
MARCH_NATIVE = -march=native
|
||||
MARCH_NATIVE = -march=native -mtune=native
|
||||
endif
|
||||
|
||||
AR=
|
||||
|
||||
|
||||
|
||||
CXX_VERSION=c++2a
|
||||
TRIPLET = $(OS_NAME)-$(ARCH_NAME)
|
||||
PACKAGE_NAME = bun-$(TRIPLET)
|
||||
PACKAGES_REALPATH = $(realpath packages)
|
||||
@@ -48,6 +49,7 @@ PRETTIER ?= $(shell which prettier || echo "./node_modules/.bin/prettier")
|
||||
DSYMUTIL ?= $(shell which dsymutil || which dsymutil-13)
|
||||
WEBKIT_DIR ?= $(realpath src/javascript/jsc/WebKit)
|
||||
WEBKIT_RELEASE_DIR ?= $(WEBKIT_DIR)/WebKitBuild/Release
|
||||
WEBKIT_RELEASE_DIR_LTO ?= $(WEBKIT_DIR)/WebKitBuild/ReleaseLTO
|
||||
|
||||
NPM_CLIENT ?= $(shell which bun || which npm)
|
||||
ZIG ?= $(shell which zig || echo -e "error: Missing zig. Please make sure zig is in PATH. Or set ZIG=/path/to-zig-executable")
|
||||
@@ -88,23 +90,29 @@ OPENSSL_LINUX_DIR = $(BUN_DEPS_DIR)/openssl/openssl-OpenSSL_1_1_1l
|
||||
CMAKE_FLAGS_WITHOUT_RELEASE = -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) -DCMAKE_OSX_DEPLOYMENT_TARGET=$(MIN_MACOS_VERSION)
|
||||
CMAKE_FLAGS = $(CMAKE_FLAGS_WITHOUT_RELEASE) -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
# Sqlite3 is lazily loaded on macOS
|
||||
SQLITE_OBJECT =
|
||||
|
||||
BITCODE_OR_SECTIONS=-fdata-sections -ffunction-sections
|
||||
LIBTOOL=libtoolize
|
||||
ifeq ($(OS_NAME),darwin)
|
||||
LIBTOOL=glibtoolize
|
||||
AR=llvm-ar
|
||||
AR=$(LLVM_PREFIX)/bin/llvm-ar
|
||||
BITCODE_OR_SECTIONS=-fembed-bitcode
|
||||
endif
|
||||
|
||||
ifeq ($(OS_NAME),linux)
|
||||
LIBICONV_PATH =
|
||||
AR=llvm-ar-13
|
||||
SQLITE_OBJECT = $(realpath $(OBJ_DIR))/sqlite3.o
|
||||
endif
|
||||
|
||||
OPTIMIZATION_LEVEL=-O3
|
||||
CFLAGS = $(MACOS_MIN_FLAG) $(MARCH_NATIVE) -ffunction-sections -fdata-sections -g $(OPTIMIZATION_LEVEL)
|
||||
OPTIMIZATION_LEVEL=-O3 $(MARCH_NATIVE)
|
||||
CFLAGS = $(MACOS_MIN_FLAG) $(MARCH_NATIVE) $(BITCODE_OR_SECTIONS) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden
|
||||
BUN_TMP_DIR := /tmp/make-bun
|
||||
BUN_DEPLOY_DIR = /tmp/bun-v$(PACKAGE_JSON_VERSION)/$(PACKAGE_NAME)
|
||||
|
||||
|
||||
DEFAULT_USE_BMALLOC := 1
|
||||
|
||||
|
||||
@@ -113,22 +121,28 @@ USE_BMALLOC ?= DEFAULT_USE_BMALLOC
|
||||
JSC_BASE_DIR ?= ${HOME}/webkit-build
|
||||
|
||||
DEFAULT_JSC_LIB :=
|
||||
DEFAULT_JSC_LIB_DEBUG :=
|
||||
|
||||
ifeq ($(OS_NAME),linux)
|
||||
DEFAULT_JSC_LIB = $(JSC_BASE_DIR)/lib
|
||||
DEFAULT_JSC_LIB_DEBUG = $(DEFAULT_JSC_LIB)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_NAME),darwin)
|
||||
DEFAULT_JSC_LIB = $(BUN_DEPS_DIR)
|
||||
DEFAULT_JSC_LIB = $(WEBKIT_RELEASE_DIR_LTO)/lib
|
||||
DEFAULT_JSC_LIB_DEBUG = $(WEBKIT_RELEASE_DIR)/lib
|
||||
endif
|
||||
|
||||
JSC_LIB ?= $(DEFAULT_JSC_LIB)
|
||||
JSC_LIB_DEBUG ?= $(DEFAULT_JSC_LIB_DEBUG)
|
||||
|
||||
JSC_INCLUDE_DIR ?= $(JSC_BASE_DIR)/include
|
||||
ZLIB_INCLUDE_DIR ?= $(BUN_DEPS_DIR)/zlib
|
||||
ZLIB_LIB_DIR ?= $(BUN_DEPS_DIR)/zlib
|
||||
|
||||
JSC_FILES := $(JSC_LIB)/libJavaScriptCore.a $(JSC_LIB)/libWTF.a $(JSC_LIB)/libbmalloc.a
|
||||
JSC_FILES := $(JSC_LIB)/libJavaScriptCore.a $(JSC_LIB)/libWTF.a $(JSC_LIB)/libbmalloc.a $(JSC_LIB)/libLowLevelInterpreterLib.a
|
||||
JSC_FILES_DEBUG := $(JSC_LIB_DEBUG)/libJavaScriptCore.a $(JSC_LIB_DEBUG)/libWTF.a $(JSC_LIB_DEBUG)/libbmalloc.a $(JSC_LIB_DEBUG)/libLowLevelInterpreterLib.a
|
||||
|
||||
|
||||
ENABLE_MIMALLOC ?= 1
|
||||
|
||||
@@ -181,29 +195,38 @@ endif
|
||||
|
||||
HOMEBREW_PREFIX ?= $(BREW_PREFIX_PATH)
|
||||
|
||||
|
||||
SRC_DIR := src/javascript/jsc/bindings
|
||||
OBJ_DIR := src/javascript/jsc/bindings-obj
|
||||
SRC_PATH := $(realpath $(SRC_DIR))
|
||||
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
|
||||
SRC_WEBCORE_FILES := $(wildcard $(SRC_DIR)/webcore/*.cpp)
|
||||
SRC_SQLITE_FILES := $(wildcard $(SRC_DIR)/sqlite/*.cpp)
|
||||
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
|
||||
WEBCORE_OBJ_FILES := $(patsubst $(SRC_DIR)/webcore/%.cpp,$(OBJ_DIR)/%.o,$(SRC_WEBCORE_FILES))
|
||||
BINDINGS_OBJ := $(OBJ_FILES) $(WEBCORE_OBJ_FILES)
|
||||
SQLITE_OBJ_FILES := $(patsubst $(SRC_DIR)/sqlite/%.cpp,$(OBJ_DIR)/%.o,$(SRC_SQLITE_FILES))
|
||||
BINDINGS_OBJ := $(OBJ_FILES) $(WEBCORE_OBJ_FILES) $(SQLITE_OBJ_FILES)
|
||||
MAC_INCLUDE_DIRS := -I$(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders \
|
||||
-I$(WEBKIT_RELEASE_DIR)/WTF/Headers \
|
||||
-I$(WEBKIT_RELEASE_DIR)/ICU/Headers \
|
||||
-I$(WEBKIT_RELEASE_DIR)/ \
|
||||
-Isrc/javascript/jsc/bindings/ \
|
||||
-Isrc/javascript/jsc/bindings/webcore \
|
||||
-Isrc/javascript/jsc/bindings/sqlite \
|
||||
-I$(WEBKIT_DIR)/Source/bmalloc \
|
||||
-I$(WEBKIT_DIR)/Source
|
||||
|
||||
LINUX_INCLUDE_DIRS := -I$(JSC_INCLUDE_DIR) \
|
||||
-Isrc/javascript/jsc/bindings/
|
||||
-Isrc/javascript/jsc/bindings/ \
|
||||
-Isrc/javascript/jsc/bindings/webcore \
|
||||
-Isrc/javascript/jsc/bindings/sqlite \
|
||||
-I$(ZLIB_INCLUDE_DIR)
|
||||
|
||||
|
||||
UWS_INCLUDE_DIR := -I$(BUN_DEPS_DIR)/uws/uSockets/src -I$(BUN_DEPS_DIR)/uws/src -I$(BUN_DEPS_DIR)
|
||||
|
||||
|
||||
INCLUDE_DIRS := $(UWS_INCLUDE_DIR)
|
||||
INCLUDE_DIRS := $(UWS_INCLUDE_DIR) -I$(BUN_DEPS_DIR)/mimalloc/include -Isrc/napi
|
||||
|
||||
|
||||
ifeq ($(OS_NAME),linux)
|
||||
@@ -244,11 +267,12 @@ endif
|
||||
BORINGSSL_PACKAGE = --pkg-begin boringssl $(BUN_DEPS_DIR)/boringssl.zig --pkg-end
|
||||
|
||||
CLANG_FLAGS = $(INCLUDE_DIRS) \
|
||||
-std=gnu++17 \
|
||||
-std=$(CXX_VERSION) \
|
||||
-DSTATICALLY_LINKED_WITH_JavaScriptCore=1 \
|
||||
-DSTATICALLY_LINKED_WITH_WTF=1 \
|
||||
-DSTATICALLY_LINKED_WITH_BMALLOC=1 \
|
||||
-DBUILDING_WITH_CMAKE=1 \
|
||||
-DBUN_SINGLE_THREADED_PER_VM_ENTRY_SCOPE=1 \
|
||||
-DNDEBUG=1 \
|
||||
-DNOMINMAX \
|
||||
-DIS_BUILD \
|
||||
@@ -259,21 +283,26 @@ CLANG_FLAGS = $(INCLUDE_DIRS) \
|
||||
-fvisibility-inlines-hidden
|
||||
|
||||
PLATFORM_LINKER_FLAGS =
|
||||
|
||||
|
||||
SYMBOLS=
|
||||
|
||||
# This flag is only added to webkit builds on Apple platforms
|
||||
# It has something to do with ICU
|
||||
ifeq ($(OS_NAME), darwin)
|
||||
SYMBOLS=-exported_symbols_list $(realpath src/symbols.txt)
|
||||
PLATFORM_LINKER_FLAGS += -DDU_DISABLE_RENAMING=1 \
|
||||
-lstdc++ \
|
||||
-fno-keep-static-consts \
|
||||
-ffunction-sections \
|
||||
-fdata-sections
|
||||
-fno-keep-static-consts
|
||||
endif
|
||||
|
||||
ifeq ($(OS_NAME),linux)
|
||||
SYMBOLS=-Wl,--dynamic-list $(realpath src/symbols.dyn)
|
||||
endif
|
||||
|
||||
SHARED_LIB_EXTENSION = .so
|
||||
|
||||
|
||||
JSC_BINDINGS = $(JSC_FILES) $(BINDINGS_OBJ)
|
||||
JSC_BINDINGS = $(BINDINGS_OBJ) $(JSC_FILES)
|
||||
JSC_BINDINGS_DEBUG = $(BINDINGS_OBJ) $(JSC_FILES_DEBUG)
|
||||
|
||||
RELEASE_FLAGS=
|
||||
DEBUG_FLAGS=
|
||||
@@ -281,45 +310,46 @@ DEBUG_FLAGS=
|
||||
ifeq ($(OS_NAME), darwin)
|
||||
RELEASE_FLAGS += -Wl,-dead_strip -Wl,-dead_strip_dylibs
|
||||
DEBUG_FLAGS += -Wl,-dead_strip -Wl,-dead_strip_dylibs
|
||||
SHARED_LIB_EXTENSION = .dylib
|
||||
endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ARCHIVE_FILES_WITHOUT_LIBCRYPTO = $(MIMALLOC_FILE_PATH) \
|
||||
$(BUN_DEPS_OUT_DIR)/libz.a \
|
||||
$(BUN_DEPS_OUT_DIR)/libarchive.a \
|
||||
$(BUN_DEPS_OUT_DIR)/libssl.a \
|
||||
$(BUN_DEPS_OUT_DIR)/picohttpparser.o \
|
||||
$(BUN_DEPS_OUT_DIR)/liblolhtml.a \
|
||||
$(BUN_DEPS_OUT_DIR)/uSockets.a \
|
||||
$(BUN_DEPS_OUT_DIR)/libuwsockets.o
|
||||
-L$(BUN_DEPS_OUT_DIR) \
|
||||
-llolhtml \
|
||||
-lz \
|
||||
-larchive \
|
||||
-lssl \
|
||||
-lbase64 \
|
||||
-ltcc
|
||||
|
||||
ARCHIVE_FILES = $(ARCHIVE_FILES_WITHOUT_LIBCRYPTO) $(BUN_DEPS_OUT_DIR)/libcrypto.boring.a
|
||||
ARCHIVE_FILES = $(ARCHIVE_FILES_WITHOUT_LIBCRYPTO) -lcrypto
|
||||
|
||||
ifeq ($(OS_NAME), darwin)
|
||||
ARCHIVE_FILES += $(wildcard $(BUN_DEPS_DIR)/uws/uSockets/*.bc) $(BUN_DEPS_OUT_DIR)/libuwsockets.o
|
||||
else
|
||||
ARCHIVE_FILES += -lusockets $(BUN_DEPS_OUT_DIR)/libuwsockets.o
|
||||
endif
|
||||
|
||||
STATIC_MUSL_FLAG ?=
|
||||
|
||||
ifeq ($(OS_NAME), linux)
|
||||
PLATFORM_LINKER_FLAGS = \
|
||||
-fuse-ld=lld \
|
||||
-lc \
|
||||
PLATFORM_LINKER_FLAGS = $(CFLAGS) \
|
||||
-fuse-ld=lld \
|
||||
-Wl,-z,now \
|
||||
-Wl,--as-needed \
|
||||
-Wl,--gc-sections \
|
||||
-Wl,-z,stack-size=12800000 \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-static-libstdc++ \
|
||||
-static-libgcc \
|
||||
-fno-omit-frame-pointer $(CFLAGS) \
|
||||
-fno-omit-frame-pointer \
|
||||
-Wl,--compress-debug-sections,zlib \
|
||||
${STATIC_MUSL_FLAG} \
|
||||
-Wl,-Bsymbolic-functions \
|
||||
-fno-semantic-interposition \
|
||||
--allow-multiple-definition
|
||||
-flto \
|
||||
-Wl,--allow-multiple-definition \
|
||||
-rdynamic
|
||||
|
||||
ARCHIVE_FILES_WITHOUT_LIBCRYPTO += $(BUN_DEPS_OUT_DIR)/libbacktrace.a
|
||||
endif
|
||||
@@ -329,20 +359,68 @@ BUN_LLD_FLAGS_WITHOUT_JSC = $(ARCHIVE_FILES) \
|
||||
$(LIBICONV_PATH) \
|
||||
$(CLANG_FLAGS) \
|
||||
$(DEFAULT_LINKER_FLAGS) \
|
||||
$(PLATFORM_LINKER_FLAGS)
|
||||
$(PLATFORM_LINKER_FLAGS) \
|
||||
$(SQLITE_OBJECT) ${ICU_FLAGS}
|
||||
|
||||
|
||||
|
||||
BUN_LLD_FLAGS = $(JSC_BINDINGS) ${ICU_FLAGS} $(BUN_LLD_FLAGS_WITHOUT_JSC)
|
||||
BUN_LLD_FLAGS = $(BUN_LLD_FLAGS_WITHOUT_JSC) $(JSC_FILES) $(BINDINGS_OBJ)
|
||||
|
||||
BUN_LLD_FLAGS_DEBUG = $(BUN_LLD_FLAGS_WITHOUT_JSC) $(JSC_FILES_DEBUG) $(BINDINGS_OBJ)
|
||||
|
||||
CLANG_VERSION = $(shell $(CC) --version | awk '/version/ {for(i=1; i<=NF; i++){if($$i=="version"){split($$(i+1),v,".");print v[1]}}}')
|
||||
|
||||
|
||||
bun:
|
||||
|
||||
base64:
|
||||
cd src/base64 && \
|
||||
rm -rf src/base64/*.{o,ll,bc} && \
|
||||
$(CC) $(CFLAGS) $(OPTIMIZATION_LEVEL) -g -fPIC -c *.c -I$(SRC_DIR)/base64 $(BITCODE_OR_SECTIONS) && \
|
||||
$(CXX) $(CXXFLAGS) $(CFLAGS) -c neonbase64.cc -g -fPIC $(BITCODE_OR_SECTIONS) && \
|
||||
$(AR) rcvs $(BUN_DEPS_OUT_DIR)/libbase64.a ./*.bc
|
||||
|
||||
vendor-without-check: api analytics node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib boringssl libarchive libbacktrace lolhtml usockets uws
|
||||
# Prevent dependency on libtcc1 so it doesn't do filesystem lookups
|
||||
TINYCC_CFLAGS= -DTCC_LIBTCC1=\"\0\"
|
||||
|
||||
tinycc:
|
||||
cd $(TINYCC_DIR) && \
|
||||
make clean && \
|
||||
AR=$(AR) CC=$(CC) CFLAGS='$(CFLAGS) $(TINYCC_CFLAGS)' ./configure --enable-static --cc=$(CC) --ar=$(AR) --config-predefs=yes && \
|
||||
make -j10 && \
|
||||
cp $(TINYCC_DIR)/*.a $(BUN_DEPS_OUT_DIR)
|
||||
|
||||
generate-builtins:
|
||||
rm -f src/javascript/jsc/bindings/WebCoreBuiltins.cpp src/javascript/jsc/bindings/WebCoreBuiltins.h src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.cpp src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.cpp src/javascript/jsc/bindings/*Strategy*Builtins* src/javascript/jsc/bindings/*Stream*Builtins* src/javascript/jsc/bindings/WebCore*Builtins* || echo ""
|
||||
$(shell which python || which python2) $(realpath $(WEBKIT_DIR)/Source/JavaScriptCore/Scripts/generate-js-builtins.py) -i $(realpath src/javascript/jsc/bindings/builtins/js) -o $(realpath src/javascript/jsc/bindings) --framework WebCore --force
|
||||
$(shell which python || which python2) $(realpath $(WEBKIT_DIR)/Source/JavaScriptCore/Scripts/generate-js-builtins.py) -i $(realpath src/javascript/jsc/bindings/builtins/js) -o $(realpath src/javascript/jsc/bindings) --framework WebCore --wrappers-only
|
||||
echo '//clang-format off' > /tmp/1.h
|
||||
cat src/javascript/jsc/bindings/JSBufferPrototypeBuiltins.h >> /tmp/1.h
|
||||
cat /tmp/1.h > src/javascript/jsc/bindings/JSBufferPrototypeBuiltins.h
|
||||
echo '//clang-format off' > /tmp/1.h
|
||||
cat src/javascript/jsc/bindings/JSBufferConstructorBuiltins.h >> /tmp/1.h
|
||||
cat /tmp/1.h > src/javascript/jsc/bindings/JSBufferConstructorBuiltins.h
|
||||
echo '//clang-format off' > /tmp/1.h
|
||||
echo 'namespace Zig { class GlobalObject; }' >> /tmp/1.h
|
||||
cat /tmp/1.h src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h > src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h.1
|
||||
mv src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h.1 src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h
|
||||
$(SED) -i -e 's/class JSDOMGlobalObject/using JSDOMGlobalObject = Zig::GlobalObject/' src/javascript/jsc/bindings/WebCoreJSBuiltinInternals.h
|
||||
# We delete this file because our script already builds all .cpp files
|
||||
# We will get duplicate symbols if we don't delete it
|
||||
rm src/javascript/jsc/bindings/WebCoreJSBuiltins.cpp
|
||||
|
||||
vendor-without-check: api analytics node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib boringssl libarchive libbacktrace lolhtml usockets uws base64 tinycc
|
||||
|
||||
prepare-types:
|
||||
BUN_VERSION=$(PACKAGE_JSON_VERSION) $(BUN_RELEASE_BIN) types/bun/bundle.ts packages/bun-types
|
||||
echo "Generated types for $(PACKAGE_JSON_VERSION) in packages/bun-types"
|
||||
|
||||
release-types:
|
||||
cd packages/bun-types && npm publish
|
||||
|
||||
format:
|
||||
$(PRETTIER) --write integration/bunjs-only-snippets/*.js
|
||||
$(PRETTIER) --write integration/bunjs-only-snippets/solid-dom-fixtures/**/*.js
|
||||
|
||||
lolhtml:
|
||||
cd $(BUN_DEPS_DIR)/lol-html/ && cd $(BUN_DEPS_DIR)/lol-html/c-api && cargo build --release && cp target/release/liblolhtml.a $(BUN_DEPS_OUT_DIR)
|
||||
@@ -355,17 +433,24 @@ boringssl-build-debug:
|
||||
|
||||
boringssl-copy:
|
||||
cp $(BUN_DEPS_DIR)/boringssl/build/ssl/libssl.a $(BUN_DEPS_OUT_DIR)/libssl.a
|
||||
cp $(BUN_DEPS_DIR)/boringssl/build/crypto/libcrypto.a $(BUN_DEPS_OUT_DIR)/libcrypto.boring.a
|
||||
cp $(BUN_DEPS_DIR)/boringssl/build/crypto/libcrypto.a $(BUN_DEPS_OUT_DIR)/libcrypto.a
|
||||
|
||||
boringssl: boringssl-build boringssl-copy
|
||||
boringssl-debug: boringssl-build-debug boringssl-copy
|
||||
|
||||
compile-ffi-test:
|
||||
clang $(OPTIMIZATION_LEVEL) -shared -undefined dynamic_lookup -o /tmp/bun-ffi-test.dylib -fPIC ./integration/bunjs-only-snippets/ffi-test.c
|
||||
|
||||
libbacktrace:
|
||||
cd $(BUN_DEPS_DIR)/libbacktrace && \
|
||||
CFLAGS="$(CFLAGS)" CC=$(CC) ./configure --disable-shared --enable-static --with-pic && \
|
||||
make -j$(CPUS) && \
|
||||
cp ./.libs/libbacktrace.a $(BUN_DEPS_OUT_DIR)/libbacktrace.a
|
||||
|
||||
|
||||
sqlite:
|
||||
|
||||
|
||||
libarchive:
|
||||
cd $(BUN_DEPS_DIR)/libarchive; \
|
||||
(make clean || echo ""); \
|
||||
@@ -414,6 +499,7 @@ require:
|
||||
@cmake --version >/dev/null 2>&1 || (echo -e "ERROR: cmake is required."; exit 1)
|
||||
@esbuild --version >/dev/null 2>&1 || (echo -e "ERROR: esbuild is required."; exit 1)
|
||||
@npm --version >/dev/null 2>&1 || (echo -e "ERROR: npm is required."; exit 1)
|
||||
@go version >/dev/null 2>&1 || (echo -e "ERROR: go is required."; exit 1)
|
||||
@which aclocal > /dev/null || (echo -e "ERROR: automake is required. Install with:\n\n $(POSIX_PKG_MANAGER) install automake"; exit 1)
|
||||
@which $(LIBTOOL) > /dev/null || (echo -e "ERROR: libtool is required. Install with:\n\n $(POSIX_PKG_MANAGER) install libtool"; exit 1)
|
||||
@which ninja > /dev/null || (echo -e "ERROR: Ninja is required. Install with:\n\n $(POSIX_PKG_MANAGER) install ninja"; exit 1)
|
||||
@@ -454,23 +540,38 @@ build-obj-wasm-small:
|
||||
-o packages/bun-freestanding-wasm32/bun-wasm.wasm
|
||||
cp packages/bun-freestanding-wasm32/bun-wasm.wasm src/api/demo/public/bun-wasm.wasm
|
||||
|
||||
wasm: api build-obj-wasm-small
|
||||
@rm -rf packages/bun-wasm/*.{d.ts,js,wasm,cjs,mjs,tsbuildinfo}
|
||||
@cp packages/bun-freestanding-wasm32/bun-wasm.wasm packages/bun-wasm/bun.wasm
|
||||
@cp src/api/schema.d.ts packages/bun-wasm/schema.d.ts
|
||||
@cp src/api/schema.js packages/bun-wasm/schema.js
|
||||
@cd packages/bun-wasm && $(NPM_CLIENT) run tsc -- -p .
|
||||
@esbuild --sourcemap=external --external:fs --define:process.env.NODE_ENV='"production"' --outdir=packages/bun-wasm --target=esnext --bundle packages/bun-wasm/index.ts --format=esm --minify 2> /dev/null
|
||||
@mv packages/bun-wasm/index.js packages/bun-wasm/index.mjs
|
||||
@mv packages/bun-wasm/index.js.map packages/bun-wasm/index.mjs.map
|
||||
@esbuild --sourcemap=external --external:fs --define:process.env.NODE_ENV='"production"' --outdir=packages/bun-wasm --target=esnext --bundle packages/bun-wasm/index.ts --format=cjs --minify --platform=node 2> /dev/null
|
||||
@mv packages/bun-wasm/index.js packages/bun-wasm/index.cjs
|
||||
@mv packages/bun-wasm/index.js.map packages/bun-wasm/index.cjs.map
|
||||
@rm -rf packages/bun-wasm/*.tsbuildinfo
|
||||
@wasm-opt -O4 --enable-mutable-globals packages/bun-wasm/bun.wasm -o /tmp/bun.wasm
|
||||
@mv /tmp/bun.wasm packages/bun-wasm/bun.wasm
|
||||
|
||||
build-obj-safe:
|
||||
$(ZIG) build obj -Drelease-safe
|
||||
|
||||
UWS_CC_FLAGS = -pthread -DLIBUS_USE_OPENSSL=1 -DUWS_HTTPRESPONSE_NO_WRITEMARK=1 -DLIBUS_USE_BORINGSSL=1 -DWITH_BORINGSSL=1 -Wpedantic -Wall -Wextra -Wsign-conversion -Wconversion $(UWS_INCLUDE) -DUWS_WITH_PROXY
|
||||
UWS_CXX_FLAGS = $(UWS_CC_FLAGS) -std=gnu++17
|
||||
UWS_LDFLAGS = -I$(BUN_DEPS_DIR)/boringssl/include
|
||||
|
||||
UWS_CXX_FLAGS = $(UWS_CC_FLAGS) -std=$(CXX_VERSION) -fno-exceptions
|
||||
UWS_LDFLAGS = -I$(BUN_DEPS_DIR)/boringssl/include -I$(ZLIB_INCLUDE_DIR)
|
||||
USOCKETS_DIR = $(BUN_DEPS_DIR)/uws/uSockets/
|
||||
USOCKETS_SRC_DIR = $(BUN_DEPS_DIR)/uws/uSockets/src/
|
||||
|
||||
usockets:
|
||||
rm -rf $(BUN_DEPS_DIR)/uws/uSockets/*.o $(BUN_DEPS_DIR)/uws/uSockets/*.a
|
||||
cd $(BUN_DEPS_DIR)/uws/uSockets && \
|
||||
$(CC) $(CFLAGS) $(UWS_CC_FLAGS) $(UWS_LDFLAGS) $(DEFAULT_LINKER_FLAGS) $(PLATFORM_LINKER_FLAGS) $(OPTIMIZATION_LEVEL) -g -c -c src/*.c src/eventing/*.c src/crypto/*.c -flto && \
|
||||
$(CXX) $(CXXFLAGS) $(UWS_CXX_FLAGS) $(UWS_LDFLAGS) $(DEFAULT_LINKER_FLAGS) $(PLATFORM_LINKER_FLAGS) $(OPTIMIZATION_LEVEL) -g -c src/crypto/*.cpp && \
|
||||
$(AR) rvs $(BUN_DEPS_OUT_DIR)/uSockets.a *.o
|
||||
|
||||
rm -rf $(BUN_DEPS_DIR)/uws/uSockets/*.o $(BUN_DEPS_DIR)/uws/uSockets/**/*.o $(BUN_DEPS_DIR)/uws/uSockets/*.a
|
||||
cd $(USOCKETS_DIR) && $(CC) $(MACOS_MIN_FLAG) -fPIC $(CFLAGS) $(UWS_CC_FLAGS) -save-temps -flto -I$(BUN_DEPS_DIR)/uws/uSockets/src $(UWS_LDFLAGS) -g $(DEFAULT_LINKER_FLAGS) $(PLATFORM_LINKER_FLAGS) $(OPTIMIZATION_LEVEL) -g -c $(wildcard $(USOCKETS_SRC_DIR)/*.c) $(wildcard $(USOCKETS_SRC_DIR)/**/*.c)
|
||||
cd $(USOCKETS_DIR) && $(CXX) $(MACOS_MIN_FLAG) -fPIC $(CXXFLAGS) $(UWS_CXX_FLAGS) -save-temps -flto -I$(BUN_DEPS_DIR)/uws/uSockets/src $(UWS_LDFLAGS) -g $(DEFAULT_LINKER_FLAGS) $(PLATFORM_LINKER_FLAGS) $(OPTIMIZATION_LEVEL) -g -c $(wildcard $(USOCKETS_SRC_DIR)/*.cpp) $(wildcard $(USOCKETS_SRC_DIR)/**/*.cpp)
|
||||
cd $(USOCKETS_DIR) && $(AR) rcvs $(BUN_DEPS_OUT_DIR)/libusockets.a *.o *.ii *.bc *.i
|
||||
uws: usockets
|
||||
$(CXX) -I$(BUN_DEPS_DIR)/uws/uSockets/src $(CLANG_FLAGS) $(UWS_CXX_FLAGS) $(UWS_LDFLAGS) $(PLATFORM_LINKER_FLAGS) -c -flto -I$(BUN_DEPS_DIR) $(BUN_DEPS_OUT_DIR)/uSockets.a $(BUN_DEPS_DIR)/libuwsockets.cpp -o $(BUN_DEPS_OUT_DIR)/libuwsockets.o
|
||||
$(CXX) $(BITCODE_OR_SECTIONS) -fPIC -I$(BUN_DEPS_DIR)/uws/uSockets/src $(CLANG_FLAGS) $(CFLAGS) $(UWS_CXX_FLAGS) $(UWS_LDFLAGS) $(PLATFORM_LINKER_FLAGS) -c -I$(BUN_DEPS_DIR) $(BUN_DEPS_OUT_DIR)/libusockets.a $(BUN_DEPS_DIR)/libuwsockets.cpp -o $(BUN_DEPS_OUT_DIR)/libuwsockets.o
|
||||
|
||||
|
||||
|
||||
@@ -522,6 +623,9 @@ runtime_js:
|
||||
|
||||
runtime_js_dev:
|
||||
@NODE_ENV=development esbuild --define:process.env.NODE_ENV="development" --target=esnext --bundle src/runtime/index.ts --format=iife --platform=browser --global-name=BUN_RUNTIME --external:/bun:* > src/runtime.out.js; cat src/runtime.footer.js >> src/runtime.out.js
|
||||
@NODE_ENV=development esbuild --define:process.env.NODE_ENV="development" --target=esnext --bundle src/runtime/index-with-refresh.ts --format=iife --platform=browser --global-name=BUN_RUNTIME --external:/bun:* > src/runtime.out.refresh.js; cat src/runtime.footer.with-refresh.js >> src/runtime.out.refresh.js
|
||||
@NODE_ENV=development esbuild --define:process.env.NODE_ENV="development" --target=esnext --bundle src/runtime/index-without-hmr.ts --format=iife --platform=node --global-name=BUN_RUNTIME --external:/bun:* > src/runtime.node.pre.out.js; cat src/runtime.node.pre.out.js src/runtime.footer.node.js > src/runtime.node.out.js
|
||||
@NODE_ENV=development esbuild --define:process.env.NODE_ENV="development" --target=esnext --bundle src/runtime/index-without-hmr.ts --format=iife --platform=node --global-name=BUN_RUNTIME --external:/bun:* > src/runtime.bun.pre.out.js; cat src/runtime.bun.pre.out.js src/runtime.footer.bun.js > src/runtime.bun.out.js
|
||||
|
||||
bun_error:
|
||||
@cd packages/bun-error; $(NPM_CLIENT) install; $(NPM_CLIENT) run --silent build
|
||||
@@ -534,7 +638,12 @@ fetch:
|
||||
$(ZIG) build -Drelease-fast fetch-obj
|
||||
$(CXX) $(PACKAGE_DIR)/fetch.o -g $(OPTIMIZATION_LEVEL) -o ./misctools/fetch $(DEFAULT_LINKER_FLAGS) -lc $(ARCHIVE_FILES)
|
||||
rm -rf $(PACKAGE_DIR)/fetch.o
|
||||
|
||||
|
||||
sha:
|
||||
$(ZIG) build -Drelease-fast sha-bench-obj
|
||||
$(CXX) $(PACKAGE_DIR)/sha.o -g $(OPTIMIZATION_LEVEL) -o ./misctools/sha $(DEFAULT_LINKER_FLAGS) -lc $(ARCHIVE_FILES)
|
||||
rm -rf $(PACKAGE_DIR)/sha.o
|
||||
|
||||
fetch-debug:
|
||||
$(ZIG) build fetch-obj
|
||||
$(CXX) $(DEBUG_PACKAGE_DIR)/fetch.o -g $(OPTIMIZATION_LEVEL) -o ./misctools/fetch $(DEFAULT_LINKER_FLAGS) -lc $(ARCHIVE_FILES)
|
||||
@@ -590,12 +699,15 @@ clone-submodules:
|
||||
|
||||
devcontainer: clone-submodules mimalloc zlib libarchive boringssl picohttp identifier-cache node-fallbacks jsc-bindings-headers api analytics bun_error fallback_decoder jsc-bindings-mac dev runtime_js_dev
|
||||
|
||||
jsc-bindings-headers:
|
||||
CLANG_FORMAT := $(shell command -v clang-format 2> /dev/null)
|
||||
|
||||
|
||||
jsc-bindings-headers:
|
||||
rm -f /tmp/build-jsc-headers src/javascript/jsc/bindings/headers.zig
|
||||
touch src/javascript/jsc/bindings/headers.zig
|
||||
mkdir -p src/javascript/jsc/bindings-obj/
|
||||
$(ZIG) build headers-obj
|
||||
$(CXX) $(PLATFORM_LINKER_FLAGS) $(JSC_FILES) ${ICU_FLAGS} $(BUN_LLD_FLAGS_WITHOUT_JSC) -g $(DEBUG_BIN)/headers.o -W -o /tmp/build-jsc-headers -lc;
|
||||
$(CXX) $(PLATFORM_LINKER_FLAGS) $(JSC_FILES_DEBUG) ${ICU_FLAGS} $(BUN_LLD_FLAGS_WITHOUT_JSC) -g $(DEBUG_BIN)/headers.o -W -o /tmp/build-jsc-headers -lc;
|
||||
/tmp/build-jsc-headers
|
||||
$(ZIG) translate-c src/javascript/jsc/bindings/headers.h > src/javascript/jsc/bindings/headers.zig
|
||||
$(ZIG) run misctools/headers-cleaner.zig -lc
|
||||
@@ -611,8 +723,7 @@ jsc-bindings-headers:
|
||||
cat src/javascript/jsc/bindings/headers.zig > /tmp/headers.zig
|
||||
cat src/javascript/jsc/bindings/headers-replacements.zig /tmp/headers.zig > src/javascript/jsc/bindings/headers.zig
|
||||
$(ZIG) fmt src/javascript/jsc/bindings/headers.zig
|
||||
clang-format -i src/javascript/jsc/bindings/*.{cpp,h}
|
||||
|
||||
|
||||
|
||||
MIMALLOC_OVERRIDE_FLAG ?=
|
||||
|
||||
@@ -723,11 +834,16 @@ ifeq ($(OS_NAME),linux)
|
||||
release-bin-push-dsym:
|
||||
endif
|
||||
|
||||
TINYCC_DIR ?= $(realpath $(BUN_DEPS_DIR)/tinycc)
|
||||
|
||||
release-bin-push: release-bin-push-bin release-bin-push-dsym
|
||||
release-bin-without-push: test-all release-bin-check release-bin-generate release-bin-codesign
|
||||
generate-release-bin-as-zip: release-bin-generate release-bin-codesign
|
||||
release-bin-without-push: test-all release-bin-check generate-release-bin-as-zip
|
||||
|
||||
release-bin: release-bin-without-push release-bin-push
|
||||
|
||||
|
||||
|
||||
release-bin-dir:
|
||||
echo $(PACKAGE_DIR)
|
||||
|
||||
@@ -815,6 +931,40 @@ test-dev: test-dev-with-hmr
|
||||
|
||||
jsc-copy-headers:
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/heap/WeakHandleOwner.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/WeakHandleOwner.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/LazyClassStructureInlines.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/LazyClassStructureInlines.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/LazyPropertyInlines.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/LazyPropertyInlines.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSTypedArrayViewPrototype.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSTypedArrayPrototypes.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSTypedArrayPrototypes.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JIT.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JIT.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/StructureStubInfo.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/StructureStubInfo.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/PolymorphicAccess.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/PolymorphicAccess.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/AccessCase.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/AccessCase.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/ObjectPropertyConditionSet.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/PolyProtoAccessChain.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/PutKind.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/PutKind.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/StructureStubClearingWatchpoint.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/AdaptiveInferredPropertyValueWatchpointBase.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/StubInfoSummary.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/StubInfoSummary.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/CommonSlowPaths.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/CommonSlowPaths.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/DirectArguments.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/DirectArguments.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/GenericArguments.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/GenericArguments.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/ScopedArguments.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/ScopedArguments.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSLexicalEnvironment.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITDisassembler.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITDisassembler.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITInlineCacheGenerator.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITMathIC.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITMathIC.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITAddGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITAddGenerator.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITMathICInlineResult.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITMathICInlineResult.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/SnippetOperand.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/SnippetOperand.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITMulGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITMulGenerator.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITNegGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITNegGenerator.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITSubGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITSubGenerator.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/Repatch.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/Repatch.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITRightShiftGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITRightShiftGenerator.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITBitBinaryOpGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITBitBinaryOpGenerator.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JSInterfaceJIT.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSInterfaceJIT.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/llint/LLIntData.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/LLIntData.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/FunctionCodeBlock.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/FunctionCodeBlock.h
|
||||
find $(WEBKIT_RELEASE_DIR)/JavaScriptCore/Headers/JavaScriptCore/ -name "*.h" -exec cp {} $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/ \;
|
||||
|
||||
# This is a workaround for a JSC bug that impacts aarch64
|
||||
@@ -823,7 +973,6 @@ jsc-force-fastjit:
|
||||
$(SED) -i "s/USE(PTHREAD_JIT_PERMISSIONS_API)/CPU(ARM64)/g" $(WEBKIT_DIR)/Source/JavaScriptCore/jit/ExecutableAllocator.h
|
||||
$(SED) -i "s/USE(PTHREAD_JIT_PERMISSIONS_API)/CPU(ARM64)/g" $(WEBKIT_DIR)/Source/JavaScriptCore/assembler/FastJITPermissions.h
|
||||
$(SED) -i "s/USE(PTHREAD_JIT_PERMISSIONS_API)/CPU(ARM64)/g" $(WEBKIT_DIR)/Source/JavaScriptCore/jit/ExecutableAllocator.cpp
|
||||
$(SED) -i "s/GIGACAGE_ENABLED/0/g" $(WEBKIT_DIR)/Source/WTF/wtf/Gigacage.h
|
||||
|
||||
jsc-build-mac-compile:
|
||||
mkdir -p $(WEBKIT_RELEASE_DIR) $(WEBKIT_DIR);
|
||||
@@ -832,22 +981,43 @@ jsc-build-mac-compile:
|
||||
cmake \
|
||||
-DPORT="JSCOnly" \
|
||||
-DENABLE_STATIC_JSC=ON \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DENABLE_SINGLE_THREADED_VM_ENTRY_SCOPE=ON \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DUSE_THIN_ARCHIVES=OFF \
|
||||
-DENABLE_FTL_JIT=ON \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
||||
-G Ninja \
|
||||
$(CMAKE_FLAGS_WITHOUT_RELEASE) \
|
||||
-DPTHREAD_JIT_PERMISSIONS_API=1 \
|
||||
-DUSE_PTHREAD_JIT_PERMISSIONS_API=ON \
|
||||
-DENABLE_REMOTE_INSPECTOR=ON \
|
||||
-DUSE_VISIBILITY_ATTRIBUTE=1 \
|
||||
$(WEBKIT_DIR) \
|
||||
$(WEBKIT_RELEASE_DIR) && \
|
||||
CFLAGS="$(CFLAGS) -Wl,--whole-archive -ffat-lto-objects" CXXFLAGS="$(CXXFLAGS) -ffat-lto-objects" \
|
||||
CFLAGS="$(CFLAGS) $(BITCODE_OR_SECTIONS) -ffat-lto-objects" CXXFLAGS="$(CXXFLAGS) $(BITCODE_OR_SECTIONS) -ffat-lto-objects" \
|
||||
cmake --build $(WEBKIT_RELEASE_DIR) --config Release --target jsc
|
||||
|
||||
jsc-build-mac-compile-lto:
|
||||
mkdir -p $(WEBKIT_RELEASE_DIR_LTO) $(WEBKIT_DIR);
|
||||
cd $(WEBKIT_RELEASE_DIR_LTO) && \
|
||||
ICU_INCLUDE_DIRS="$(HOMEBREW_PREFIX)opt/icu4c/include" \
|
||||
cmake \
|
||||
-DPORT="JSCOnly" \
|
||||
-DENABLE_STATIC_JSC=ON \
|
||||
-DENABLE_SINGLE_THREADED_VM_ENTRY_SCOPE=ON \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DUSE_THIN_ARCHIVES=OFF \
|
||||
-DCMAKE_C_FLAGS="-flto=full" \
|
||||
-DCMAKE_CXX_FLAGS="-flto=full" \
|
||||
-DENABLE_FTL_JIT=ON \
|
||||
-G Ninja \
|
||||
$(CMAKE_FLAGS_WITHOUT_RELEASE) \
|
||||
-DPTHREAD_JIT_PERMISSIONS_API=1 \
|
||||
-DUSE_PTHREAD_JIT_PERMISSIONS_API=ON \
|
||||
-DENABLE_REMOTE_INSPECTOR=ON \
|
||||
$(WEBKIT_DIR) \
|
||||
$(WEBKIT_RELEASE_DIR_LTO) && \
|
||||
CFLAGS="$(CFLAGS) -ffat-lto-objects" CXXFLAGS="$(CXXFLAGS) -ffat-lto-objects" \
|
||||
cmake --build $(WEBKIT_RELEASE_DIR_LTO) --config Release --target jsc
|
||||
|
||||
jsc-build-mac-compile-debug:
|
||||
mkdir -p $(WEBKIT_RELEASE_DIR) $(WEBKIT_DIR);
|
||||
cd $(WEBKIT_RELEASE_DIR) && \
|
||||
@@ -904,6 +1074,7 @@ jsc-build-linux: jsc-build-linux-compile-config jsc-build-linux-compile-build js
|
||||
|
||||
jsc-build-mac-copy:
|
||||
cp $(WEBKIT_RELEASE_DIR)/lib/libJavaScriptCore.a $(BUN_DEPS_OUT_DIR)/libJavaScriptCore.a
|
||||
cp $(WEBKIT_RELEASE_DIR)/lib/libLowLevelInterpreterLib.a $(BUN_DEPS_OUT_DIR)/libLowLevelInterpreterLib.a
|
||||
cp $(WEBKIT_RELEASE_DIR)/lib/libWTF.a $(BUN_DEPS_OUT_DIR)/libWTF.a
|
||||
cp $(WEBKIT_RELEASE_DIR)/lib/libbmalloc.a $(BUN_DEPS_OUT_DIR)/libbmalloc.a
|
||||
|
||||
@@ -922,24 +1093,26 @@ clean: clean-bindings
|
||||
(cd $(BUN_DEPS_DIR)/picohttp && make clean) || echo "";
|
||||
(cd $(BUN_DEPS_DIR)/zlib && make clean) || echo "";
|
||||
|
||||
jsc-bindings-mac: $(OBJ_FILES) $(WEBCORE_OBJ_FILES)
|
||||
jsc-bindings-mac: $(OBJ_FILES) $(WEBCORE_OBJ_FILES) $(SQLITE_OBJ_FILES)
|
||||
|
||||
mimalloc-debug:
|
||||
rm -rf $(BUN_DEPS_DIR)/mimalloc/CMakeCache* $(BUN_DEPS_DIR)/mimalloc/CMakeFiles
|
||||
cd $(BUN_DEPS_DIR)/mimalloc; make clean || echo ""; \
|
||||
CFLAGS="$(CFLAGS)" cmake $(CMAKE_FLAGS_WITHOUT_RELEASE) \
|
||||
CFLAGS="$(CFLAGS)" cmake $(CMAKE_FLAGS_WITHOUT_RELEASE) ${MIMALLOC_OVERRIDE_FLAG} \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DMI_DEBUG_FULL=1 \
|
||||
-DMI_SKIP_COLLECT_ON_EXIT=1 \
|
||||
-DMI_BUILD_SHARED=OFF \
|
||||
-DMI_BUILD_STATIC=ON \
|
||||
-DMI_BUILD_TESTS=OFF \
|
||||
-DMI_BUILD_OBJECT=ON \
|
||||
-DMI_BUILD_OBJECT=ON \
|
||||
-DMI_OSX_ZONE=OFF \
|
||||
-DMI_OSX_INTERPOSE=OFF \
|
||||
${MIMALLOC_OVERRIDE_FLAG} \
|
||||
-DMI_USE_CXX=OFF .\
|
||||
-DMI_BUILD_OBJECT=ON \
|
||||
-DMI_USE_CXX=ON \
|
||||
-DMI_OVERRIDE=OFF \
|
||||
-DCMAKE_C_FLAGS="$(CFLAGS)" \
|
||||
-DCMAKE_CXX_FLAGS="$(CFLAGS)" \
|
||||
. \
|
||||
&& make -j $(CPUS);
|
||||
cp $(BUN_DEPS_DIR)/mimalloc/$(_MIMALLOC_DEBUG_FILE) $(BUN_DEPS_OUT_DIR)/$(MIMALLOC_FILE)
|
||||
|
||||
@@ -958,8 +1131,12 @@ mimalloc:
|
||||
-DMI_OSX_ZONE=OFF \
|
||||
-DMI_OSX_INTERPOSE=OFF \
|
||||
-DMI_BUILD_OBJECT=ON \
|
||||
-DMI_USE_CXX=ON \
|
||||
-DMI_OVERRIDE=ON \
|
||||
-DCMAKE_C_FLAGS="$(CFLAGS)" \
|
||||
-DCMAKE_CXX_FLAGS="$(CFLAGS) -fno-exceptions -fno-rtti" \
|
||||
${MIMALLOC_OVERRIDE_FLAG} \
|
||||
-DMI_USE_CXX=OFF .\
|
||||
.\
|
||||
&& make -j $(CPUS);
|
||||
cp $(BUN_DEPS_DIR)/mimalloc/$(MIMALLOC_INPUT_PATH) $(BUN_DEPS_OUT_DIR)/$(MIMALLOC_FILE)
|
||||
|
||||
@@ -969,14 +1146,14 @@ mimalloc-wasm:
|
||||
cp $(BUN_DEPS_DIR)/mimalloc/$(MIMALLOC_INPUT_PATH) $(BUN_DEPS_OUT_DIR)/$(MIMALLOC_FILE).wasm
|
||||
|
||||
bun-link-lld-debug:
|
||||
$(CXX) $(BUN_LLD_FLAGS) $(DEBUG_FLAGS) \
|
||||
$(CXX) $(BUN_LLD_FLAGS_DEBUG) $(DEBUG_FLAGS) $(SYMBOLS) \
|
||||
-g \
|
||||
$(DEBUG_BIN)/bun-debug.o \
|
||||
-W \
|
||||
-o $(DEBUG_BIN)/bun-debug
|
||||
|
||||
bun-link-lld-debug-no-jsc:
|
||||
$(CXX) $(BUN_LLD_FLAGS_WITHOUT_JSC) \
|
||||
$(CXX) $(BUN_LLD_FLAGS_WITHOUT_JSC) $(SYMBOLS) \
|
||||
-g \
|
||||
$(DEBUG_BIN)/bun-debug.o \
|
||||
-W \
|
||||
@@ -984,7 +1161,7 @@ bun-link-lld-debug-no-jsc:
|
||||
|
||||
|
||||
bun-link-lld-release-no-jsc:
|
||||
$(CXX) $(BUN_LLD_FLAGS_WITHOUT_JSC) \
|
||||
$(CXX) $(BUN_LLD_FLAGS_WITHOUT_JSC) $(SYMBOLS) \
|
||||
-g \
|
||||
$(BUN_RELEASE_BIN).o \
|
||||
-W \
|
||||
@@ -996,11 +1173,10 @@ bun-relink-copy:
|
||||
|
||||
|
||||
bun-link-lld-release:
|
||||
$(CXX) $(BUN_LLD_FLAGS) \
|
||||
$(CXX) $(BUN_LLD_FLAGS) $(SYMBOLS) \
|
||||
$(BUN_RELEASE_BIN).o \
|
||||
-o $(BUN_RELEASE_BIN) \
|
||||
-W \
|
||||
-flto \
|
||||
$(OPTIMIZATION_LEVEL) $(RELEASE_FLAGS)
|
||||
rm -rf $(BUN_RELEASE_BIN).dSYM
|
||||
cp $(BUN_RELEASE_BIN) $(BUN_RELEASE_BIN)-profile
|
||||
@@ -1009,7 +1185,7 @@ ifeq ($(OS_NAME),darwin)
|
||||
bun-link-lld-release-dsym:
|
||||
$(DSYMUTIL) -o $(BUN_RELEASE_BIN).dSYM $(BUN_RELEASE_BIN)
|
||||
-$(STRIP) $(BUN_RELEASE_BIN)
|
||||
mv $(BUN_RELEASE_BIN).o /tmp/bun-$(PACKAGE_JSON_VERSION).o
|
||||
cp $(BUN_RELEASE_BIN).o /tmp/bun-$(PACKAGE_JSON_VERSION).o
|
||||
|
||||
copy-to-bun-release-dir-dsym:
|
||||
gzip --keep -c $(PACKAGE_DIR)/bun.dSYM > $(BUN_RELEASE_DIR)/bun.dSYM.gz
|
||||
@@ -1030,6 +1206,9 @@ wasm-return1:
|
||||
|
||||
|
||||
|
||||
EMIT_LLVM_FOR_RELEASE=-emit-llvm -flto="full"
|
||||
EMIT_LLVM_FOR_DEBUG=
|
||||
EMIT_LLVM=$(EMIT_LLVM_FOR_RELEASE)
|
||||
|
||||
# We do this outside of build.zig for performance reasons
|
||||
# The C compilation stuff with build.zig is really slow and we don't need to run this as often as the rest
|
||||
@@ -1038,7 +1217,9 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
|
||||
$(MACOS_MIN_FLAG) \
|
||||
$(OPTIMIZATION_LEVEL) \
|
||||
-fno-exceptions \
|
||||
-fno-rtti \
|
||||
-ferror-limit=1000 \
|
||||
$(EMIT_LLVM) \
|
||||
-g3 -c -o $@ $<
|
||||
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/webcore/%.cpp
|
||||
@@ -1046,13 +1227,32 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/webcore/%.cpp
|
||||
$(MACOS_MIN_FLAG) \
|
||||
$(OPTIMIZATION_LEVEL) \
|
||||
-fno-exceptions \
|
||||
-fno-rtti \
|
||||
-ferror-limit=1000 \
|
||||
$(EMIT_LLVM) \
|
||||
-g3 -c -o $@ $<
|
||||
|
||||
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/sqlite/%.cpp
|
||||
$(CXX) $(CLANG_FLAGS) \
|
||||
$(MACOS_MIN_FLAG) \
|
||||
$(OPTIMIZATION_LEVEL) \
|
||||
-fno-exceptions \
|
||||
-fno-rtti \
|
||||
-ferror-limit=1000 \
|
||||
$(EMIT_LLVM) \
|
||||
-g3 -c -o $@ $<
|
||||
|
||||
sizegen:
|
||||
$(CXX) src/javascript/jsc/headergen/sizegen.cpp -o $(BUN_TMP_DIR)/sizegen $(CLANG_FLAGS) -O1
|
||||
$(BUN_TMP_DIR)/sizegen > src/javascript/jsc/bindings/sizes.zig
|
||||
|
||||
|
||||
# Linux uses bundled SQLite3
|
||||
ifeq ($(OS_NAME),linux)
|
||||
sqlite:
|
||||
$(CC) $(CFLAGS) $(INCLUDE_DIRS) $(EMIT_LLVM_FOR_RELEASE) -DSQLITE_ENABLE_COLUMN_METADATA= -DSQLITE_MAX_VARIABLE_NUMBER=250000 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_JSON1=1 -c $(SRC_DIR)/sqlite/sqlite3.c -o $(SQLITE_OBJECT)
|
||||
endif
|
||||
|
||||
picohttp:
|
||||
$(CC) $(CFLAGS) $(OPTIMIZATION_LEVEL) -g -fPIC -c $(BUN_DEPS_DIR)/picohttpparser/picohttpparser.c -I$(BUN_DEPS_DIR) -o $(BUN_DEPS_OUT_DIR)/picohttpparser.o; cd ../../
|
||||
|
||||
@@ -1148,7 +1348,7 @@ endif
|
||||
build-unit:
|
||||
@rm -rf zig-out/bin/$(testname)
|
||||
@mkdir -p zig-out/bin
|
||||
zig test $(realpath $(testpath)) \
|
||||
zig test $(realpath $(testpath)) \
|
||||
$(testfilterflag) \
|
||||
$(PACKAGE_MAP) \
|
||||
--main-pkg-path $(BUN_DIR) \
|
||||
@@ -1200,7 +1400,7 @@ copy-to-bun-release-dir-bin:
|
||||
cp -r $(PACKAGE_DIR)/bun-profile $(BUN_RELEASE_DIR)/bun-profile
|
||||
|
||||
|
||||
PACKAGE_MAP = --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-begin io $(BUN_DIR)/src/io/io_$(OS_NAME).zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/deps/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/deps/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-end --pkg-end --pkg-end --pkg-end --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin clap $(BUN_DIR)/src/deps/zig-clap/clap.zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/deps/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/deps/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-end --pkg-end --pkg-end --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/deps/boringssl.zig --pkg-end --pkg-begin javascript_core $(BUN_DIR)/src/jsc.zig --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-end --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-end
|
||||
PACKAGE_MAP = --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-begin io $(BUN_DIR)/src/io/io_$(OS_NAME).zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-end --pkg-end --pkg-end --pkg-end --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin clap $(BUN_DIR)/src/deps/zig-clap/clap.zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-end --pkg-end --pkg-end --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/boringssl.zig --pkg-end --pkg-begin javascript_core $(BUN_DIR)/src/jsc.zig --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-end --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-end
|
||||
|
||||
|
||||
bun: vendor identifier-cache build-obj bun-link-lld-release bun-codesign-release-local
|
||||
|
||||
419
bench/ffi/ffi-overhead.js
Normal file
419
bench/ffi/ffi-overhead.js
Normal file
@@ -0,0 +1,419 @@
|
||||
import {
|
||||
viewSource,
|
||||
dlopen,
|
||||
CString,
|
||||
ptr,
|
||||
toBuffer,
|
||||
toArrayBuffer,
|
||||
FFIType,
|
||||
callback,
|
||||
} from "bun:ffi";
|
||||
import { bench, group, run } from "mitata";
|
||||
|
||||
const types = {
|
||||
returns_true: {
|
||||
returns: "bool",
|
||||
args: [],
|
||||
},
|
||||
returns_false: {
|
||||
returns: "bool",
|
||||
args: [],
|
||||
},
|
||||
returns_42_char: {
|
||||
returns: "char",
|
||||
args: [],
|
||||
},
|
||||
// returns_42_float: {
|
||||
// returns: "float",
|
||||
// args: [],
|
||||
// },
|
||||
// returns_42_double: {
|
||||
// returns: "double",
|
||||
// args: [],
|
||||
// },
|
||||
returns_42_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
args: [],
|
||||
},
|
||||
returns_neg_42_int8_t: {
|
||||
returns: "int8_t",
|
||||
args: [],
|
||||
},
|
||||
returns_42_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
args: [],
|
||||
},
|
||||
returns_42_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
args: [],
|
||||
},
|
||||
// // returns_42_uint64_t: {
|
||||
// // returns: "uint64_t",
|
||||
// // args: [],
|
||||
// // },
|
||||
returns_neg_42_int16_t: {
|
||||
returns: "int16_t",
|
||||
args: [],
|
||||
},
|
||||
returns_neg_42_int32_t: {
|
||||
returns: "int32_t",
|
||||
args: [],
|
||||
},
|
||||
// returns_neg_42_int64_t: {
|
||||
// returns: "int64_t",
|
||||
// args: [],
|
||||
// },
|
||||
|
||||
identity_char: {
|
||||
returns: "char",
|
||||
args: ["char"],
|
||||
},
|
||||
// identity_float: {
|
||||
// returns: "float",
|
||||
// args: ["float"],
|
||||
// },
|
||||
identity_bool: {
|
||||
returns: "bool",
|
||||
args: ["bool"],
|
||||
},
|
||||
// identity_double: {
|
||||
// returns: "double",
|
||||
// args: ["double"],
|
||||
// },
|
||||
identity_int8_t: {
|
||||
returns: "int8_t",
|
||||
args: ["int8_t"],
|
||||
},
|
||||
identity_int16_t: {
|
||||
returns: "int16_t",
|
||||
args: ["int16_t"],
|
||||
},
|
||||
identity_int32_t: {
|
||||
returns: "int32_t",
|
||||
args: ["int32_t"],
|
||||
},
|
||||
// identity_int64_t: {
|
||||
// returns: "int64_t",
|
||||
// args: ["int64_t"],
|
||||
// },
|
||||
identity_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
args: ["uint8_t"],
|
||||
},
|
||||
identity_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
args: ["uint16_t"],
|
||||
},
|
||||
identity_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
args: ["uint32_t"],
|
||||
},
|
||||
// identity_uint64_t: {
|
||||
// returns: "uint64_t",
|
||||
// args: ["uint64_t"],
|
||||
// },
|
||||
|
||||
add_char: {
|
||||
returns: "char",
|
||||
args: ["char", "char"],
|
||||
},
|
||||
add_float: {
|
||||
returns: "float",
|
||||
args: ["float", "float"],
|
||||
},
|
||||
add_double: {
|
||||
returns: "double",
|
||||
args: ["double", "double"],
|
||||
},
|
||||
add_int8_t: {
|
||||
returns: "int8_t",
|
||||
args: ["int8_t", "int8_t"],
|
||||
},
|
||||
add_int16_t: {
|
||||
returns: "int16_t",
|
||||
args: ["int16_t", "int16_t"],
|
||||
},
|
||||
add_int32_t: {
|
||||
returns: "int32_t",
|
||||
args: ["int32_t", "int32_t"],
|
||||
},
|
||||
// add_int64_t: {
|
||||
// returns: "int64_t",
|
||||
// args: ["int64_t", "int64_t"],
|
||||
// },
|
||||
add_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
args: ["uint8_t", "uint8_t"],
|
||||
},
|
||||
add_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
args: ["uint16_t", "uint16_t"],
|
||||
},
|
||||
add_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
args: ["uint32_t", "uint32_t"],
|
||||
},
|
||||
|
||||
does_pointer_equal_42_as_int32_t: {
|
||||
returns: "bool",
|
||||
args: ["ptr"],
|
||||
},
|
||||
|
||||
ptr_should_point_to_42_as_int32_t: {
|
||||
returns: "ptr",
|
||||
args: [],
|
||||
},
|
||||
identity_ptr: {
|
||||
returns: "ptr",
|
||||
args: ["ptr"],
|
||||
},
|
||||
// add_uint64_t: {
|
||||
// returns: "uint64_t",
|
||||
// args: ["uint64_t", "uint64_t"],
|
||||
// },
|
||||
|
||||
cb_identity_true: {
|
||||
returns: "bool",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_false: {
|
||||
returns: "bool",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_42_char: {
|
||||
returns: "char",
|
||||
args: ["ptr"],
|
||||
},
|
||||
// cb_identity_42_float: {
|
||||
// returns: "float",
|
||||
// args: ["ptr"],
|
||||
// },
|
||||
// cb_identity_42_double: {
|
||||
// returns: "double",
|
||||
// args: ["ptr"],
|
||||
// },
|
||||
cb_identity_42_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_neg_42_int8_t: {
|
||||
returns: "int8_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_42_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_42_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
// cb_identity_42_uint64_t: {
|
||||
// returns: "uint64_t",
|
||||
// args: ["ptr"],
|
||||
// },
|
||||
cb_identity_neg_42_int16_t: {
|
||||
returns: "int16_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_neg_42_int32_t: {
|
||||
returns: "int32_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
// cb_identity_neg_42_int64_t: {
|
||||
// returns: "int64_t",
|
||||
// args: ["ptr"],
|
||||
// },
|
||||
|
||||
return_a_function_ptr_to_function_that_returns_true: {
|
||||
returns: "ptr",
|
||||
args: [],
|
||||
},
|
||||
};
|
||||
|
||||
const {
|
||||
symbols: {
|
||||
returns_true,
|
||||
returns_false,
|
||||
return_a_function_ptr_to_function_that_returns_true,
|
||||
returns_42_char,
|
||||
returns_42_float,
|
||||
returns_42_double,
|
||||
returns_42_uint8_t,
|
||||
returns_neg_42_int8_t,
|
||||
returns_42_uint16_t,
|
||||
returns_42_uint32_t,
|
||||
returns_42_uint64_t,
|
||||
returns_neg_42_int16_t,
|
||||
returns_neg_42_int32_t,
|
||||
returns_neg_42_int64_t,
|
||||
identity_char,
|
||||
identity_float,
|
||||
identity_bool,
|
||||
identity_double,
|
||||
identity_int8_t,
|
||||
identity_int16_t,
|
||||
identity_int32_t,
|
||||
identity_int64_t,
|
||||
identity_uint8_t,
|
||||
identity_uint16_t,
|
||||
identity_uint32_t,
|
||||
identity_uint64_t,
|
||||
add_char,
|
||||
add_float,
|
||||
add_double,
|
||||
add_int8_t,
|
||||
add_int16_t,
|
||||
add_int32_t,
|
||||
add_int64_t,
|
||||
add_uint8_t,
|
||||
add_uint16_t,
|
||||
identity_ptr,
|
||||
add_uint32_t,
|
||||
add_uint64_t,
|
||||
does_pointer_equal_42_as_int32_t,
|
||||
ptr_should_point_to_42_as_int32_t,
|
||||
cb_identity_true,
|
||||
cb_identity_false,
|
||||
cb_identity_42_char,
|
||||
cb_identity_42_float,
|
||||
cb_identity_42_double,
|
||||
cb_identity_42_uint8_t,
|
||||
cb_identity_neg_42_int8_t,
|
||||
cb_identity_42_uint16_t,
|
||||
cb_identity_42_uint32_t,
|
||||
cb_identity_42_uint64_t,
|
||||
cb_identity_neg_42_int16_t,
|
||||
cb_identity_neg_42_int32_t,
|
||||
cb_identity_neg_42_int64_t,
|
||||
},
|
||||
close,
|
||||
} = dlopen("/tmp/bun-ffi-test.dylib", types);
|
||||
|
||||
group("add_char", () => {
|
||||
bench("add_char (raw)", () => raw_add_char(1, 1));
|
||||
bench("add_char", () => add_char(1, 1));
|
||||
});
|
||||
group("add_int16_t", () => {
|
||||
bench("add_int16_t (raw)", () => raw_add_int16_t(1, 1));
|
||||
bench("add_int16_t", () => add_int16_t(1, 1));
|
||||
});
|
||||
group("add_int32_t", () => {
|
||||
bench("add_int32_t (raw)", () => raw_add_int32_t(1, 1));
|
||||
bench("add_int32_t", () => add_int32_t(1, 1));
|
||||
});
|
||||
group("add_int8_t", () => {
|
||||
bench("add_int8_t (raw)", () => raw_add_int8_t(1, 1));
|
||||
bench("add_int8_t", () => add_int8_t(1, 1));
|
||||
});
|
||||
group("add_uint16_t", () => {
|
||||
bench("add_uint16_t (raw)", () => raw_add_uint16_t(1, 1));
|
||||
bench("add_uint16_t", () => add_uint16_t(1, 1));
|
||||
});
|
||||
group("add_uint32_t", () => {
|
||||
bench("add_uint32_t (raw)", () => raw_add_uint32_t(1, 1));
|
||||
bench("add_uint32_t", () => add_uint32_t(1, 1));
|
||||
});
|
||||
group("add_uint8_t", () => {
|
||||
bench("add_uint8_t (raw)", () => raw_add_uint8_t(1, 1));
|
||||
bench("add_uint8_t", () => add_uint8_t(1, 1));
|
||||
});
|
||||
group("identity_bool", () => {
|
||||
bench("identity_bool (raw)", () => raw_identity_bool(false));
|
||||
bench("identity_bool", () => identity_bool(true));
|
||||
});
|
||||
group("identity_char", () => {
|
||||
bench("identity_char (raw)", () => raw_identity_char(10));
|
||||
bench("identity_char", () => identity_char(10));
|
||||
});
|
||||
group("identity_int16_t", () => {
|
||||
bench("identity_int16_t (raw)", () => raw_identity_int16_t(10));
|
||||
bench("identity_int16_t", () => identity_int16_t(10));
|
||||
});
|
||||
group("identity_int32_t", () => {
|
||||
bench("identity_int32_t (raw)", () => raw_identity_int32_t(10));
|
||||
bench("identity_int32_t", () => identity_int32_t(10));
|
||||
});
|
||||
group("identity_int8_t", () => {
|
||||
bench("identity_int8_t (raw)", () => raw_identity_int8_t(10));
|
||||
bench("identity_int8_t", () => identity_int8_t(10));
|
||||
});
|
||||
group("identity_uint16_t", () => {
|
||||
bench("identity_uint16_t (raw)", () => raw_identity_uint16_t(10));
|
||||
bench("identity_uint16_t", () => identity_uint16_t(10));
|
||||
});
|
||||
group("identity_uint32_t", () => {
|
||||
bench("identity_uint32_t (raw)", () => raw_identity_uint32_t(10));
|
||||
bench("identity_uint32_t", () => identity_uint32_t(10));
|
||||
});
|
||||
group("identity_uint8_t", () => {
|
||||
bench("identity_uint8_t (raw)", () => raw_identity_uint8_t(10));
|
||||
bench("identity_uint8_t", () => identity_uint8_t(10));
|
||||
});
|
||||
group("returns_42_char", () => {
|
||||
bench("returns_42_char (raw)", () => raw_returns_42_char());
|
||||
bench("returns_42_char", () => returns_42_char());
|
||||
});
|
||||
group("returns_42_uint16_t", () => {
|
||||
bench("returns_42_uint16_t (raw)", () => raw_returns_42_uint16_t());
|
||||
bench("returns_42_uint16_t", () => returns_42_uint16_t());
|
||||
});
|
||||
group("returns_42_uint32_t", () => {
|
||||
bench("returns_42_uint32_t (raw)", () => raw_returns_42_uint32_t());
|
||||
bench("returns_42_uint32_t", () => returns_42_uint32_t());
|
||||
});
|
||||
group("returns_42_uint8_t", () => {
|
||||
bench("returns_42_uint8_t (raw)", () => raw_returns_42_uint8_t());
|
||||
bench("returns_42_uint8_t", () => returns_42_uint8_t());
|
||||
});
|
||||
group("returns_false", () => {
|
||||
bench("returns_false (raw)", () => raw_returns_false());
|
||||
bench("returns_false", () => returns_false());
|
||||
});
|
||||
group("returns_neg_42_int16_t", () => {
|
||||
bench("returns_neg_42_int16_t (raw)", () => raw_returns_neg_42_int16_t());
|
||||
bench("returns_neg_42_int16_t", () => returns_neg_42_int16_t());
|
||||
});
|
||||
group("returns_neg_42_int32_t", () => {
|
||||
bench("returns_neg_42_int32_t (raw)", () => raw_returns_neg_42_int32_t());
|
||||
bench("returns_neg_42_int32_t", () => returns_neg_42_int32_t());
|
||||
});
|
||||
group("returns_neg_42_int8_t", () => {
|
||||
bench("returns_neg_42_int8_t (raw)", () => raw_returns_neg_42_int8_t());
|
||||
bench("returns_neg_42_int8_t", () => returns_neg_42_int8_t());
|
||||
});
|
||||
group("returns_true", () => {
|
||||
bench("returns_true (raw)", () => raw_returns_true());
|
||||
bench("returns_true", () => returns_true());
|
||||
});
|
||||
|
||||
var raw_returns_true = returns_true.native ?? returns_true;
|
||||
var raw_returns_false = returns_false.native ?? returns_false;
|
||||
var raw_returns_42_char = returns_42_char.native ?? returns_42_char;
|
||||
var raw_returns_42_uint8_t = returns_42_uint8_t.native ?? returns_42_uint8_t;
|
||||
var raw_returns_neg_42_int8_t =
|
||||
returns_neg_42_int8_t.native ?? returns_neg_42_int8_t;
|
||||
var raw_returns_42_uint16_t = returns_42_uint16_t.native ?? returns_42_uint16_t;
|
||||
var raw_returns_42_uint32_t = returns_42_uint32_t.native ?? returns_42_uint32_t;
|
||||
var raw_returns_neg_42_int16_t =
|
||||
returns_neg_42_int16_t.native ?? returns_neg_42_int16_t;
|
||||
var raw_returns_neg_42_int32_t =
|
||||
returns_neg_42_int32_t.native ?? returns_neg_42_int32_t;
|
||||
var raw_identity_char = identity_char.native ?? identity_char;
|
||||
var raw_identity_bool = identity_bool.native ?? identity_bool;
|
||||
var raw_identity_bool = identity_bool.native ?? identity_bool;
|
||||
var raw_identity_int8_t = identity_int8_t.native ?? identity_int8_t;
|
||||
var raw_identity_int16_t = identity_int16_t.native ?? identity_int16_t;
|
||||
var raw_identity_int32_t = identity_int32_t.native ?? identity_int32_t;
|
||||
var raw_identity_uint8_t = identity_uint8_t.native ?? identity_uint8_t;
|
||||
var raw_identity_uint16_t = identity_uint16_t.native ?? identity_uint16_t;
|
||||
var raw_identity_uint32_t = identity_uint32_t.native ?? identity_uint32_t;
|
||||
var raw_add_char = add_char.native ?? add_char;
|
||||
var raw_add_int8_t = add_int8_t.native ?? add_int8_t;
|
||||
var raw_add_int16_t = add_int16_t.native ?? add_int16_t;
|
||||
var raw_add_int32_t = add_int32_t.native ?? add_int32_t;
|
||||
var raw_add_uint8_t = add_uint8_t.native ?? add_uint8_t;
|
||||
var raw_add_uint16_t = add_uint16_t.native ?? add_uint16_t;
|
||||
var raw_add_uint32_t = add_uint32_t.native ?? add_uint32_t;
|
||||
|
||||
run({ collect: false, percentiles: true });
|
||||
5
bench/ffi/noop.c
Normal file
5
bench/ffi/noop.c
Normal file
@@ -0,0 +1,5 @@
|
||||
// clang -O3 -shared -mtune=native ./noop.c -o noop.dylib
|
||||
|
||||
void noop();
|
||||
|
||||
void noop() {}
|
||||
BIN
bench/ffi/noop.dylib
Executable file
BIN
bench/ffi/noop.dylib
Executable file
Binary file not shown.
15
bench/ffi/noop.js
Normal file
15
bench/ffi/noop.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import { dlopen } from "bun:ffi";
|
||||
import { bench, run } from "mitata";
|
||||
|
||||
const {
|
||||
symbols: { noop },
|
||||
} = dlopen("./noop.dylib", {
|
||||
noop: {
|
||||
args: [],
|
||||
returns: "void",
|
||||
},
|
||||
});
|
||||
bench("noop", () => {
|
||||
noop();
|
||||
});
|
||||
run({ collect: false, percentiles: true });
|
||||
1
bench/ffi/plus100/.gitignore
vendored
Normal file
1
bench/ffi/plus100/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
./napi-plus100
|
||||
37
bench/ffi/plus100/README.md
Normal file
37
bench/ffi/plus100/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
## FFI overhead comparison
|
||||
|
||||
This compares the cost of simple function calls going from JavaScript to native code and back in:
|
||||
|
||||
- Bun v0.0.79
|
||||
- napi.rs (Node v17.7.1)
|
||||
- Deno v1.21.1
|
||||
|
||||
To set up:
|
||||
|
||||
```bash
|
||||
bun setup
|
||||
```
|
||||
|
||||
To run the benchmark:
|
||||
|
||||
```bash
|
||||
bun bench
|
||||
```
|
||||
|
||||
**add 100 to a number**:
|
||||
|
||||
| Overhead | Using | Version | Platform |
|
||||
| -------- | ------- | ------- | --------------- |
|
||||
| 7ns | bun:ffi | 0.0.79 | macOS (aarch64) |
|
||||
| 18ns | napi.rs | 17.7.1 | macOS (aarch64) |
|
||||
| 580ns | Deno | 1.21.1 | macOS (aarch64) |
|
||||
|
||||
**function that does nothing**:
|
||||
|
||||
| Overhead | Using | Version | Platform |
|
||||
| -------- | ------- | ------- | --------------- |
|
||||
| 3ns | bun:ffi | 0.0.79 | macOS (aarch64) |
|
||||
| 15ns | napi.rs | 17.7.1 | macOS (aarch64) |
|
||||
| 431ns | Deno | 1.21.1 | macOS (aarch64) |
|
||||
|
||||
The native [functions](./plus100.c) called in Deno & Bun are the same. The function called with napi.rs is based on napi's official [package-template](https://github.com/napi-rs/package-template) in https://github.com/Jarred-Sumner/napi-plus100
|
||||
7
bench/ffi/plus100/download-napi-plus100.sh
Normal file
7
bench/ffi/plus100/download-napi-plus100.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm -rf plus100-napi
|
||||
git clone https://github.com/Jarred-Sumner/napi-plus100 plus100-napi --depth=1
|
||||
cd plus100-napi
|
||||
npm install
|
||||
npm run build
|
||||
BIN
bench/ffi/plus100/libadd.dylib
Executable file
BIN
bench/ffi/plus100/libadd.dylib
Executable file
Binary file not shown.
12
bench/ffi/plus100/package.json
Normal file
12
bench/ffi/plus100/package.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "plus100",
|
||||
"scripts": {
|
||||
"setup": "bun run napi-setup && bun run compile",
|
||||
"bench-deno": "deno run --allow-ffi --unstable -A plus100.deno.js",
|
||||
"napi-setup": "bash download-napi-plus100.sh",
|
||||
"bench-napi": "node plus100.napi.mjs",
|
||||
"bench-bun": "bun ./plus100.bun.js",
|
||||
"compile": "clang -mtune=native -O3 -shared ./plus100.c -o plus100.dylib",
|
||||
"bench": "bun run bench-bun && bun run bench-napi && bun run bench-deno"
|
||||
}
|
||||
}
|
||||
1
bench/ffi/plus100/plus100-napi
Submodule
1
bench/ffi/plus100/plus100-napi
Submodule
Submodule bench/ffi/plus100/plus100-napi added at 485de94d06
52
bench/ffi/plus100/plus100.bun.js
Normal file
52
bench/ffi/plus100/plus100.bun.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import { run, bench, group, baseline } from "mitata";
|
||||
import { dlopen, suffix } from "bun:ffi";
|
||||
import { readdirSync } from "fs";
|
||||
|
||||
const {
|
||||
symbols: {
|
||||
plus100: { native: plus100 },
|
||||
noop,
|
||||
},
|
||||
close,
|
||||
} = dlopen(`./plus100.dylib`, {
|
||||
plus100: {
|
||||
args: ["int32_t"],
|
||||
returns: "int32_t",
|
||||
},
|
||||
noop: {
|
||||
args: [],
|
||||
},
|
||||
});
|
||||
const {
|
||||
plus100: plus100napi,
|
||||
noop: noopNapi,
|
||||
} = require("./plus100-napi/index.js");
|
||||
|
||||
group("plus100", () => {
|
||||
bench("plus100(1) ffi", () => {
|
||||
plus100(1);
|
||||
});
|
||||
|
||||
bench("plus100(1) napi", () => {
|
||||
plus100napi(1);
|
||||
});
|
||||
});
|
||||
|
||||
group("noop", () => {
|
||||
bench("noop() ffi", () => {
|
||||
noop();
|
||||
});
|
||||
|
||||
bench("noop() napi", () => {
|
||||
noopNapi();
|
||||
});
|
||||
});
|
||||
|
||||
// collect option collects benchmark returned values into array
|
||||
// prevents gc and can help with jit optimizing out functions
|
||||
await run({ collect: false, percentiles: true });
|
||||
console.log("\n");
|
||||
|
||||
if (plus100(1) !== 101) {
|
||||
throw new Error("plus100(1) !== 101");
|
||||
}
|
||||
8
bench/ffi/plus100/plus100.c
Normal file
8
bench/ffi/plus100/plus100.c
Normal file
@@ -0,0 +1,8 @@
|
||||
// clang -mtune=native -O3 -shared ./plus100.c -o plus100.dylib
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t plus100(int32_t a);
|
||||
int32_t plus100(int32_t a) { return a + 100; }
|
||||
|
||||
void noop(void);
|
||||
void noop(void) {}
|
||||
30
bench/ffi/plus100/plus100.deno.js
Normal file
30
bench/ffi/plus100/plus100.deno.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { run, bench, group, baseline } from "https://esm.sh/mitata";
|
||||
|
||||
const {
|
||||
symbols: { plus100: plus100, noop },
|
||||
close,
|
||||
} = Deno.dlopen("./plus100.dylib", {
|
||||
plus100: {
|
||||
parameters: ["i32"],
|
||||
result: "i32",
|
||||
},
|
||||
noop: {
|
||||
parameters: [],
|
||||
result: "void",
|
||||
},
|
||||
});
|
||||
bench("plus100(1) ", () => {
|
||||
plus100(1);
|
||||
});
|
||||
|
||||
bench("noop() ", () => {
|
||||
noop();
|
||||
});
|
||||
|
||||
// collect option collects benchmark returned values into array
|
||||
// prevents gc and can help with jit optimizing out functions
|
||||
await run({ collect: false, percentiles: true });
|
||||
|
||||
if (plus100(1) !== 101) {
|
||||
throw new Error("plus100(1) !== 101");
|
||||
}
|
||||
BIN
bench/ffi/plus100/plus100.dylib
Executable file
BIN
bench/ffi/plus100/plus100.dylib
Executable file
Binary file not shown.
19
bench/ffi/plus100/plus100.napi.mjs
Normal file
19
bench/ffi/plus100/plus100.napi.mjs
Normal file
@@ -0,0 +1,19 @@
|
||||
import { bench, run } from "mitata";
|
||||
|
||||
const { plus100, noop } =
|
||||
"Bun" in globalThis
|
||||
? require("./plus100-napi")
|
||||
: (await import("module")).createRequire(import.meta.url)("./plus100-napi");
|
||||
|
||||
bench("plus100(1) napi", () => {
|
||||
plus100(1);
|
||||
});
|
||||
bench("noop() napi", () => {
|
||||
noop();
|
||||
});
|
||||
await run({ collect: false, percentiles: true });
|
||||
console.log("\n");
|
||||
|
||||
if (plus100(1) !== 101) {
|
||||
throw new Error("plus100(1) !== 101");
|
||||
}
|
||||
77
bench/snippets/buffer-read.js
Normal file
77
bench/snippets/buffer-read.js
Normal file
@@ -0,0 +1,77 @@
|
||||
// import { Buffer } from "buffer";
|
||||
var buf = new Buffer(1024);
|
||||
// var buf = new Uint8Array(1024);
|
||||
var view = new DataView(buf.buffer);
|
||||
var INTERVAL = 9999999;
|
||||
var time = (name, fn) => {
|
||||
for (let i = 0; i < INTERVAL; i++) fn();
|
||||
|
||||
console.time(name.padEnd("DataView.readBigUInt64 (LE)".length));
|
||||
for (let i = 0; i < INTERVAL; i++) fn();
|
||||
console.timeEnd(name.padEnd("DataView.readBigUInt64 (LE)".length));
|
||||
};
|
||||
|
||||
console.log(
|
||||
`Run ${new Intl.NumberFormat().format(INTERVAL)} times with a warmup:`,
|
||||
"\n"
|
||||
);
|
||||
var array = new Uint8Array(1024);
|
||||
time("Buffer[] ", () => buf[0]);
|
||||
time("Uint8Array[]", () => array[0]);
|
||||
console.log("");
|
||||
|
||||
time("Buffer.getBigInt64BE ", () => buf.readBigInt64BE(0));
|
||||
time("DataView.getBigInt64 (BE)", () => view.getBigInt64(0, false));
|
||||
console.log("");
|
||||
|
||||
time("Buffer.readBigInt64LE ", () => buf.readBigInt64LE(0));
|
||||
time("DataView.readBigInt64 (LE)", () => view.getBigInt64(0, true));
|
||||
console.log("");
|
||||
time("Buffer.getBigUInt64BE ", () => buf.readBigUInt64BE(0));
|
||||
time("DataView.getBigUInt64 (BE)", () => view.getBigUint64(0, false));
|
||||
console.log("");
|
||||
time("Buffer.readBigUInt64LE ", () => buf.readBigUInt64LE(0));
|
||||
time("DataView.readBigUInt64 (LE)", () => view.getBigUint64(0, true));
|
||||
console.log("");
|
||||
time("Buffer.getDoubleBE ", () => buf.readDoubleBE(0));
|
||||
time("DataView.getDouble (BE)", () => view.getFloat64(0, false));
|
||||
console.log("");
|
||||
time("Buffer.readDoubleLE ", () => buf.readDoubleLE(0));
|
||||
time("DataView.readDouble (LE)", () => view.getFloat64(0, true));
|
||||
console.log("");
|
||||
time("Buffer.getFloatBE ", () => buf.readFloatBE(0));
|
||||
time("DataView.getFloat (BE)", () => view.getFloat32(0, false));
|
||||
console.log("");
|
||||
time("Buffer.readFloatLE ", () => buf.readFloatLE(0));
|
||||
time("DataView.readFloat (LE)", () => view.getFloat32(0, true));
|
||||
console.log("");
|
||||
time("Buffer.getInt16BE ", () => buf.readInt16BE(0));
|
||||
time("DataView.getInt16 (BE)", () => view.getInt16(0, false));
|
||||
console.log("");
|
||||
time("Buffer.readInt16LE ", () => buf.readInt16LE(0));
|
||||
time("DataView.readInt16 (LE)", () => view.getInt16(0, true));
|
||||
console.log("");
|
||||
time("Buffer.getInt32BE ", () => buf.readInt32BE(0));
|
||||
time("DataView.getInt32 (BE)", () => view.getInt32(0, false));
|
||||
console.log("");
|
||||
time("Buffer.readInt32LE ", () => buf.readInt32LE(0));
|
||||
time("DataView.readInt32 (LE)", () => view.getInt32(0, true));
|
||||
console.log("");
|
||||
time("Buffer.readInt8 ", () => buf.readInt8(0));
|
||||
time("DataView.readInt (t8)", () => view.getInt8(0));
|
||||
console.log("");
|
||||
time("Buffer.getUInt16BE ", () => buf.readUInt16BE(0));
|
||||
time("DataView.getUInt16 (BE)", () => view.getUint16(0, false));
|
||||
console.log("");
|
||||
time("Buffer.readUInt16LE ", () => buf.readUInt16LE(0));
|
||||
time("DataView.readUInt16 (LE)", () => view.getUint16(0, true));
|
||||
console.log("");
|
||||
time("Buffer.getUInt32BE ", () => buf.readUInt32BE(0));
|
||||
time("DataView.getUInt32 (BE)", () => view.getUint32(0, false));
|
||||
console.log("");
|
||||
time("Buffer.readUInt32LE ", () => buf.readUInt32LE(0));
|
||||
time("DataView.getUInt32 (LE)", () => view.getUint32(0, true));
|
||||
console.log("");
|
||||
time("Buffer.readUInt8 ", () => buf.readUInt8(0));
|
||||
time("DataView.getUInt (t8)", () => view.getUint8(0));
|
||||
console.log("");
|
||||
136
bench/snippets/buffer.js
Normal file
136
bench/snippets/buffer.js
Normal file
@@ -0,0 +1,136 @@
|
||||
// import { Buffer } from "buffer";
|
||||
var buf = new Buffer(1024);
|
||||
var view = new DataView(buf.buffer);
|
||||
var INTERVAL = 9999999;
|
||||
var time = (name, fn) => {
|
||||
for (let i = 0; i < INTERVAL; i++) fn();
|
||||
|
||||
console.time(name.padEnd('Buffer.write(string, "latin1")'.length));
|
||||
for (let i = 0; i < INTERVAL; i++) fn();
|
||||
console.timeEnd(name.padEnd('Buffer.write(string, "latin1")'.length));
|
||||
};
|
||||
|
||||
console.log(
|
||||
`Run ${new Intl.NumberFormat().format(INTERVAL)} times with a warmup:`,
|
||||
"\n"
|
||||
);
|
||||
|
||||
const stringToWrite = "hellooooohellooooo";
|
||||
|
||||
time('Buffer.write(string, "utf8")', () => buf.write(stringToWrite, "utf8"));
|
||||
time('Buffer.write(string, "ascii")', () => buf.write(stringToWrite, "ascii"));
|
||||
time('Buffer.write(string, "latin1")', () =>
|
||||
buf.write(stringToWrite, "latin1")
|
||||
);
|
||||
time("Buffer.readBigInt64BE ", () => buf.readBigInt64BE(0));
|
||||
// time("DataView.getBigInt64 (BE)", () => view.getBigInt64(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.readBigInt64LE ", () => buf.readBigInt64LE(0));
|
||||
// time("DataView.readBigInt64 (LE)", () => view.getBigInt64(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.readBigUInt64BE ", () => buf.readBigUInt64BE(0));
|
||||
// time("DataView.getBigUInt64 (BE)", () => view.getBigUint64(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.readBigUInt64LE ", () => buf.readBigUInt64LE(0));
|
||||
// time("DataView.readBigUInt64 (LE)", () => view.getBigUint64(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.readDoubleBE ", () => buf.readDoubleBE(0));
|
||||
// time("DataView.getDouble (BE)", () => view.getFloat64(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.readDoubleLE ", () => buf.readDoubleLE(0));
|
||||
// time("DataView.readDouble (LE)", () => view.getFloat64(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.readFloatBE ", () => buf.readFloatBE(0));
|
||||
// time("DataView.getFloat (BE)", () => view.getFloat32(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.readFloatLE ", () => buf.readFloatLE(0));
|
||||
// time("DataView.readFloat (LE)", () => view.getFloat32(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.readInt16BE ", () => buf.readInt16BE(0));
|
||||
// time("DataView.getInt16 (BE)", () => view.getInt16(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.readInt16LE ", () => buf.readInt16LE(0));
|
||||
// time("DataView.readInt16 (LE)", () => view.getInt16(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.readInt32BE ", () => buf.readInt32BE(0));
|
||||
// time("DataView.getInt32 (BE)", () => view.getInt32(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.readInt32LE ", () => buf.readInt32LE(0));
|
||||
// time("DataView.readInt32 (LE)", () => view.getInt32(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.readInt8 ", () => buf.readInt8(0));
|
||||
// time("DataView.readInt (t8)", () => view.getInt8(0));
|
||||
// console.log("");
|
||||
time("Buffer.readUInt16BE ", () => buf.readUInt16BE(0));
|
||||
// time("DataView.getUInt16 (BE)", () => view.getUint16(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.readUInt16LE ", () => buf.readUInt16LE(0));
|
||||
// time("DataView.readUInt16 (LE)", () => view.getUint16(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.readUInt32BE ", () => buf.readUInt32BE(0));
|
||||
// time("DataView.getUInt32 (BE)", () => view.getUint32(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.readUInt32LE ", () => buf.readUInt32LE(0));
|
||||
// time("DataView.getUInt32 (LE)", () => view.getUint32(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.readUInt8 ", () => buf.readUInt8(0));
|
||||
// time("DataView.getUInt (t8)", () => view.getUint8(0));
|
||||
// console.log("");
|
||||
|
||||
time("Buffer.writeBigInt64BE", () => buf.writeBigInt64BE(BigInt(0), 0));
|
||||
// time("DataView.getBigInt64 (BE)", () => view.getBigInt64(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.writeBigInt64LE", () => buf.writeBigInt64LE(BigInt(0), 0));
|
||||
// time("DataView.readBigInt64 (LE)", () => view.getBigInt64(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.writeBigUInt64BE", () => buf.writeBigUInt64BE(BigInt(0), 0));
|
||||
// time("DataView.getBigUInt64 (BE)", () => view.getBigUint64(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.writeBigUInt64LE", () => buf.writeBigUInt64LE(BigInt(0), 0));
|
||||
// time("DataView.readBigUInt64 (LE)", () => view.getBigUint64(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.writeDoubleBE ", () => buf.writeDoubleBE(0, 0));
|
||||
// time("DataView.getDouble (BE)", () => view.getFloat64(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.writeDoubleLE ", () => buf.writeDoubleLE(0, 0));
|
||||
// time("DataView.readDouble (LE)", () => view.getFloat64(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.writeFloatBE ", () => buf.writeFloatBE(0, 0));
|
||||
// time("DataView.getFloat (BE)", () => view.getFloat32(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.writeFloatLE ", () => buf.writeFloatLE(0, 0));
|
||||
// time("DataView.readFloat (LE)", () => view.getFloat32(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.writeInt16BE ", () => buf.writeInt16BE(0, 0));
|
||||
// time("DataView.getInt16 (BE)", () => view.getInt16(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.writeInt16LE ", () => buf.writeInt16LE(0, 0));
|
||||
// time("DataView.readInt16 (LE)", () => view.getInt16(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.writeInt32BE ", () => buf.writeInt32BE(0, 0));
|
||||
// time("DataView.getInt32 (BE)", () => view.getInt32(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.writeInt32LE ", () => buf.writeInt32LE(0, 0));
|
||||
// time("DataView.readInt32 (LE)", () => view.getInt32(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.writeInt8 ", () => buf.writeInt8(0, 0));
|
||||
// time("DataView.readInt (t8)", () => view.getInt8(0));
|
||||
// console.log("");
|
||||
time("Buffer.writeUInt16BE ", () => buf.writeUInt16BE(0, 0));
|
||||
// time("DataView.getUInt16 (BE)", () => view.getUint16(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.writeUInt16LE ", () => buf.writeUInt16LE(0, 0));
|
||||
// time("DataView.readUInt16 (LE)", () => view.getUint16(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.writeUInt32BE ", () => buf.writeUInt32BE(0, 0));
|
||||
// time("DataView.getUInt32 (BE)", () => view.getUint32(0, false));
|
||||
// console.log("");
|
||||
time("Buffer.writeUInt32LE ", () => buf.writeUInt32LE(0, 0));
|
||||
// time("DataView.getUInt32 (LE)", () => view.getUint32(0, true));
|
||||
// console.log("");
|
||||
time("Buffer.writeUInt8 ", () => buf.writeUInt8(0, 0));
|
||||
// time("DataView.getUInt (t8)", () => view.getUint8(0));
|
||||
// console.log("");
|
||||
|
||||
buf.writeUInt8(10, 10);
|
||||
console.assert(buf.readUInt8(10, 10) === 10);
|
||||
5
bench/snippets/cat.bun.js
Normal file
5
bench/snippets/cat.bun.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import { resolve } from "path";
|
||||
const { write, stdout, file } = Bun;
|
||||
const input = resolve(process.argv[process.argv.length - 1]);
|
||||
|
||||
await write(stdout, file(input));
|
||||
@@ -1,3 +1,4 @@
|
||||
// works in both bun & node
|
||||
import { readFileSync } from "node:fs";
|
||||
const count = parseInt(process.env.ITERATIONS || "1", 10) || 1;
|
||||
const arg = process.argv.slice(1);
|
||||
|
||||
4
bench/snippets/cat.node.js
Normal file
4
bench/snippets/cat.node.js
Normal file
@@ -0,0 +1,4 @@
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const input = path.resolve(process.argv[process.argv.length - 1]);
|
||||
fs.createReadStream(input).pipe(process.stdout);
|
||||
4
bench/snippets/copy.bun.js
Normal file
4
bench/snippets/copy.bun.js
Normal file
@@ -0,0 +1,4 @@
|
||||
import path from "path";
|
||||
const input = path.resolve(process.argv[process.argv.length - 2]);
|
||||
const output = path.resolve(process.argv[process.argv.length - 1]);
|
||||
await Bun.write(Bun.file(output), Bun.file(input));
|
||||
108
bench/snippets/escapeHTML.js
Normal file
108
bench/snippets/escapeHTML.js
Normal file
@@ -0,0 +1,108 @@
|
||||
import { group } from "mitata";
|
||||
import { bench, run } from "mitata";
|
||||
import { encode as htmlEntityEncode } from "html-entities";
|
||||
import { escape as heEscape } from "he";
|
||||
|
||||
var bunEscapeHTML_ = globalThis.escapeHTML || Bun.escapeHTML;
|
||||
var bunEscapeHTML = bunEscapeHTML_;
|
||||
|
||||
const matchHtmlRegExp = /["'&<>]/;
|
||||
|
||||
/**
|
||||
* Escapes special characters and HTML entities in a given html string.
|
||||
*
|
||||
* @param {string} string HTML string to escape for later insertion
|
||||
* @return {string}
|
||||
* @public
|
||||
*/
|
||||
|
||||
const FIXTURE = require("fs")
|
||||
.readFileSync(import.meta.dir + "/_fixture.txt", "utf8")
|
||||
.split("")
|
||||
.map((a) => {
|
||||
if (a.charCodeAt(0) > 127) {
|
||||
return "a";
|
||||
}
|
||||
return a;
|
||||
})
|
||||
.join("");
|
||||
|
||||
const FIXTURE_WITH_UNICODE = require("fs").readFileSync(
|
||||
import.meta.dir + "/_fixture.txt",
|
||||
"utf8"
|
||||
);
|
||||
|
||||
function reactEscapeHtml(string) {
|
||||
const str = "" + string;
|
||||
const match = matchHtmlRegExp.exec(str);
|
||||
|
||||
if (!match) {
|
||||
return str;
|
||||
}
|
||||
|
||||
let escape;
|
||||
let html = "";
|
||||
let index;
|
||||
let lastIndex = 0;
|
||||
|
||||
for (index = match.index; index < str.length; index++) {
|
||||
switch (str.charCodeAt(index)) {
|
||||
case 34: // "
|
||||
escape = """;
|
||||
break;
|
||||
case 38: // &
|
||||
escape = "&";
|
||||
break;
|
||||
case 39: // '
|
||||
escape = "'"; // modified from escape-html; used to be '''
|
||||
break;
|
||||
case 60: // <
|
||||
escape = "<";
|
||||
break;
|
||||
case 62: // >
|
||||
escape = ">";
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lastIndex !== index) {
|
||||
html += str.substring(lastIndex, index);
|
||||
}
|
||||
|
||||
lastIndex = index + 1;
|
||||
html += escape;
|
||||
}
|
||||
|
||||
return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
|
||||
}
|
||||
|
||||
for (let input of [
|
||||
"<script>alert('xss')</script>",
|
||||
`long string, nothing to escape... `.repeat(9999),
|
||||
`long utf16 string, no esc 🤔🤔🤔🤔🤔` + "tex".repeat(4000),
|
||||
`smol`,
|
||||
// `medium string with <script>alert('xss')</script>`,
|
||||
|
||||
FIXTURE,
|
||||
// "[unicode]" + FIXTURE_WITH_UNICODE,
|
||||
]) {
|
||||
group(
|
||||
{
|
||||
summary: true,
|
||||
name:
|
||||
`"` +
|
||||
input.substring(0, Math.min(input.length, 32)) +
|
||||
`"` +
|
||||
` (${input.length} chars)`,
|
||||
},
|
||||
() => {
|
||||
bench(`ReactDOM.escapeHTML`, () => reactEscapeHtml(input));
|
||||
bench(`html-entities.encode`, () => htmlEntityEncode(input));
|
||||
bench(`he.escape`, () => heEscape(input));
|
||||
bench(`Bun.escapeHTML`, () => bunEscapeHTML(input));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
await run();
|
||||
20
bench/snippets/gzip.js
Normal file
20
bench/snippets/gzip.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import { bench, group, run } from "mitata";
|
||||
import { gzipSync, gunzipSync } from "bun";
|
||||
|
||||
const data = new TextEncoder().encode("Hello World!".repeat(9999));
|
||||
|
||||
const compressed = gzipSync(data);
|
||||
|
||||
bench(`roundtrip - "Hello World!".repeat(9999))`, () => {
|
||||
gunzipSync(gzipSync(data));
|
||||
});
|
||||
|
||||
bench(`gzipSync("Hello World!".repeat(9999)))`, () => {
|
||||
gzipSync(data);
|
||||
});
|
||||
|
||||
bench(`gunzipSync("Hello World!".repeat(9999)))`, () => {
|
||||
gunzipSync(compressed);
|
||||
});
|
||||
|
||||
run({ collect: false, percentiles: true });
|
||||
20
bench/snippets/gzip.node.mjs
Normal file
20
bench/snippets/gzip.node.mjs
Normal file
@@ -0,0 +1,20 @@
|
||||
import { bench, group, run } from "mitata";
|
||||
import { gzipSync, gunzipSync } from "zlib";
|
||||
|
||||
const data = new TextEncoder().encode("Hello World!".repeat(9999));
|
||||
|
||||
const compressed = gzipSync(data);
|
||||
|
||||
bench(`roundtrip - "Hello World!".repeat(9999))`, () => {
|
||||
gunzipSync(gzipSync(data));
|
||||
});
|
||||
|
||||
bench(`gzipSync("Hello World!".repeat(9999)))`, () => {
|
||||
gzipSync(data);
|
||||
});
|
||||
|
||||
bench(`gunzipSync("Hello World!".repeat(9999)))`, () => {
|
||||
gunzipSync(compressed);
|
||||
});
|
||||
|
||||
run({ collect: false, percentiles: true });
|
||||
17
bench/snippets/noop.js
Normal file
17
bench/snippets/noop.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import { bench, run } from "mitata";
|
||||
|
||||
var noop = globalThis[Symbol.for("Bun.lazy")]("noop");
|
||||
|
||||
bench("function", function () {
|
||||
noop.function();
|
||||
});
|
||||
|
||||
bench("setter", function () {
|
||||
noop.getterSetter = 1;
|
||||
});
|
||||
|
||||
bench("getter", function () {
|
||||
noop.getterSetter;
|
||||
});
|
||||
|
||||
run();
|
||||
10
bench/sqlite/download-northwind.sh
Normal file
10
bench/sqlite/download-northwind.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
rm -rf Northwind_large.sqlite.zip
|
||||
wget https://github.com/jpwhite3/northwind-SQLite3/blob/master/Northwind_large.sqlite.zip?raw=true
|
||||
unzip Northwind_large.sqlite.zip
|
||||
rm Northwind_large.sqlite.zip
|
||||
mv Northwind_large.sqlite /tmp/northwind.sqlite
|
||||
rm -rf Northwind* || echo ""
|
||||
rm -rf __MACOSX
|
||||
1071
bench/sqlite/package-lock.json
generated
Normal file
1071
bench/sqlite/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
7
bench/sqlite/package.json
Normal file
7
bench/sqlite/package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "bench",
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^7.5.1",
|
||||
"mitata": "^0.0.14"
|
||||
}
|
||||
}
|
||||
31
bench/sqlite/query.better-sqlite3.mjs
Normal file
31
bench/sqlite/query.better-sqlite3.mjs
Normal file
@@ -0,0 +1,31 @@
|
||||
import { bench, run } from "mitata";
|
||||
import { createRequire } from "module";
|
||||
const db = createRequire(import.meta.url)("better-sqlite3")(
|
||||
"/tmp/northwind.sqlite"
|
||||
);
|
||||
|
||||
{
|
||||
const sql = db.prepare(`SELECT * FROM "Order"`);
|
||||
|
||||
bench('SELECT * FROM "Order"', () => {
|
||||
sql.all();
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const sql = db.prepare(`SELECT * FROM "Product"`);
|
||||
|
||||
bench('SELECT * FROM "Product"', () => {
|
||||
sql.all();
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const sql = db.prepare(`SELECT * FROM "OrderDetail"`);
|
||||
|
||||
bench('SELECT * FROM "OrderDetail"', () => {
|
||||
sql.all();
|
||||
});
|
||||
}
|
||||
|
||||
run({ json: false });
|
||||
26
bench/sqlite/query.deno.js
Normal file
26
bench/sqlite/query.deno.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { DB } from "https://deno.land/x/sqlite/mod.ts";
|
||||
import { bench, run } from "https://esm.run/mitata";
|
||||
const db = new DB("/tmp/northwind.sqlite");
|
||||
|
||||
{
|
||||
const sql = db.prepareQuery(`SELECT * FROM "Order"`);
|
||||
bench('SELECT * FROM "Order"', () => {
|
||||
sql.allEntries();
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const sql = db.prepareQuery(`SELECT * FROM "Product"`);
|
||||
bench('SELECT * FROM "Product"', () => {
|
||||
sql.allEntries();
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const sql = db.prepareQuery(`SELECT * FROM "OrderDetail"`);
|
||||
bench('SELECT * FROM "OrderDetail"', () => {
|
||||
sql.allEntries();
|
||||
});
|
||||
}
|
||||
|
||||
run({ json: false });
|
||||
26
bench/sqlite/query.js
Normal file
26
bench/sqlite/query.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { bench, run } from "mitata";
|
||||
import { Database } from "bun:sqlite";
|
||||
const db = Database.open("/tmp/northwind.sqlite");
|
||||
|
||||
{
|
||||
const sql = db.prepare(`SELECT * FROM "Order"`);
|
||||
bench('SELECT * FROM "Order"', () => {
|
||||
sql.all();
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const sql = db.prepare(`SELECT * FROM "Product"`);
|
||||
bench('SELECT * FROM "Product"', () => {
|
||||
sql.all();
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const sql = db.prepare(`SELECT * FROM "OrderDetail"`);
|
||||
bench('SELECT * FROM "OrderDetail"', () => {
|
||||
sql.all();
|
||||
});
|
||||
}
|
||||
|
||||
run({ json: false });
|
||||
@@ -43,7 +43,7 @@ const color_map = std.ComptimeStringMap([]const u8, .{
|
||||
fn addInternalPackages(step: *std.build.LibExeObjStep, _: std.mem.Allocator, target: anytype) !void {
|
||||
var boringssl: std.build.Pkg = .{
|
||||
.name = "boringssl",
|
||||
.path = pkgPath("src/deps/boringssl.zig"),
|
||||
.path = pkgPath("src/boringssl.zig"),
|
||||
};
|
||||
|
||||
var datetime: std.build.Pkg = .{
|
||||
@@ -404,6 +404,13 @@ pub fn build(b: *std.build.Builder) !void {
|
||||
try configureObjectStep(b, headers_obj, target, obj.main_pkg_path.?);
|
||||
}
|
||||
|
||||
{
|
||||
const headers_step = b.step("sha-bench-obj", "Build sha bench");
|
||||
var headers_obj: *std.build.LibExeObjStep = b.addObject("sha", "src/sha.zig");
|
||||
defer headers_step.dependOn(&headers_obj.step);
|
||||
try configureObjectStep(b, headers_obj, target, obj.main_pkg_path.?);
|
||||
}
|
||||
|
||||
{
|
||||
const headers_step = b.step("vlq-bench", "Build vlq bench");
|
||||
var headers_obj: *std.build.LibExeObjStep = b.addExecutable("vlq-bench", "src/sourcemap/vlq_bench.zig");
|
||||
|
||||
57
docs/upgrading-webkit.md
Normal file
57
docs/upgrading-webkit.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Upgrading WebKit
|
||||
|
||||
Bun uses [a fork](https://github.com/Jarred-Sumner/WebKit) of WebKit with a small number of changes.
|
||||
|
||||
It's important to periodically update WebKit for many reasons:
|
||||
|
||||
- Security
|
||||
- Performance
|
||||
- Compatibility
|
||||
- …and many more.
|
||||
|
||||
To upgrade, first find the commit in **bun's WebKit fork** (not bun!) between when we last upgraded and now.
|
||||
|
||||
```bash
|
||||
cd src/javascript/jsc/WebKit # In the WebKit directory! not bun
|
||||
git checkout $COMMIT
|
||||
```
|
||||
|
||||
This is the main command to run:
|
||||
|
||||
```bash
|
||||
git pull https://github.com/WebKit/WebKit.git main --no-rebase --allow-unrelated-histories -X theirs
|
||||
```
|
||||
|
||||
Then, you will likely see some silly merge conflicts. Fix them and then run:
|
||||
|
||||
```bash
|
||||
# You might have to run this multiple times.
|
||||
rm -rf WebKitBuild
|
||||
|
||||
# Go to Bun's directory! Not WebKit.
|
||||
cd ../../../../
|
||||
make jsc-build-mac-compile
|
||||
```
|
||||
|
||||
Make sure that JSC's CLI is able to load successfully. This verifies that the build is working.
|
||||
|
||||
You know this worked when it printed help options. If it complains about symbols, crashes, or anything else that looks wrong, something is wrong.
|
||||
|
||||
```bash
|
||||
src/javascript/jsc/WebKit/WebKitBuild/Release/bin/jsc --help
|
||||
```
|
||||
|
||||
Then, clear out our bindings and regenerate the C++<>Zig headers:
|
||||
|
||||
```bash
|
||||
make clean-bindings jsc-bindings-headers generate-builtins
|
||||
```
|
||||
|
||||
Now update Bun's bindings wherever there are compiler errors:
|
||||
|
||||
```bash
|
||||
# It will take awhile if you don't pass -j here
|
||||
make jsc-bindings-mac -j10
|
||||
```
|
||||
|
||||
This is the hard part. It might involve digging through WebKit's commit history to figure out what changed and why. Fortunately, WebKit contributors write great commit messages.
|
||||
7
examples/add.rs
Normal file
7
examples/add.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
#[no_mangle]
|
||||
pub extern "C" fn add(a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
}
|
||||
|
||||
// to compile:
|
||||
// rustc --crate-type cdylib add.rs
|
||||
12
examples/add.ts
Normal file
12
examples/add.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { dlopen, suffix } from "bun:ffi";
|
||||
|
||||
const {
|
||||
symbols: { add },
|
||||
} = dlopen(`./libadd.${suffix}`, {
|
||||
add: {
|
||||
args: ["i32", "i32"],
|
||||
returns: "i32",
|
||||
},
|
||||
});
|
||||
|
||||
console.log(add(1, 2));
|
||||
6
examples/add.zig
Normal file
6
examples/add.zig
Normal file
@@ -0,0 +1,6 @@
|
||||
pub export fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// to compile:
|
||||
// zig build-lib -OReleaseFast ./add.zig -dynamic --name add
|
||||
@@ -1,35 +0,0 @@
|
||||
// Start a fast HTTP server from a function
|
||||
Bun.serve({
|
||||
fetch(req) {
|
||||
return new Response("Hello World!");
|
||||
},
|
||||
|
||||
// this is called when fetch() throws or rejects
|
||||
error(err: Error) {
|
||||
return new Response("uh oh! :(" + err.toString(), { status: 500 });
|
||||
},
|
||||
|
||||
// this boolean enables the bun's default error handler
|
||||
// sometime after the initial release, it will auto reload as well
|
||||
development: process.env.NODE_ENV !== "production",
|
||||
// note: this isn't node, but for compatibility bun supports process.env + more stuff in process
|
||||
|
||||
// SSL is enabled if these two are set
|
||||
// certFile: './cert.pem',
|
||||
// keyFile: './key.pem',
|
||||
|
||||
port: 8080, // number or string
|
||||
hostname: "localhost", // defaults to 0.0.0.0
|
||||
});
|
||||
|
||||
// Start a fast HTTP server from the main file's export
|
||||
export default {
|
||||
fetch(req) {
|
||||
return new Response(
|
||||
`This is another way to start a server!
|
||||
if the main file export default's an object
|
||||
with 'fetch'. Bun automatically calls Bun.serve`
|
||||
);
|
||||
},
|
||||
// so autocomplete & type checking works
|
||||
} as Bun.Serve;
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"types": ["../../types/bun"]
|
||||
}
|
||||
}
|
||||
6
examples/cat.ts
Normal file
6
examples/cat.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { resolve } from "path";
|
||||
const { write, stdout, file } = Bun;
|
||||
const { argv } = process;
|
||||
|
||||
const path = resolve(argv.at(-1));
|
||||
await write(stdout, file(path));
|
||||
11
examples/change-array-by-copy.js
Normal file
11
examples/change-array-by-copy.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const sequence = [1, 2, 3];
|
||||
sequence.toReversed(); // => [3, 2, 1]
|
||||
sequence; // => [1, 2, 3]
|
||||
|
||||
const outOfOrder = new Uint8Array([3, 1, 2]);
|
||||
outOfOrder.toSorted(); // => Uint8Array [1, 2, 3]
|
||||
outOfOrder; // => Uint8Array [3, 1, 2]
|
||||
|
||||
const correctionNeeded = [1, 1, 3];
|
||||
correctionNeeded.with(1, 2); // => [1, 2, 3]
|
||||
correctionNeeded; // => [1, 1, 3]
|
||||
47
examples/html-rewriter.ts
Normal file
47
examples/html-rewriter.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
// Start a fast HTTP server from a function
|
||||
Bun.serve({
|
||||
async fetch(req) {
|
||||
const { pathname } = new URL(req.url);
|
||||
if (
|
||||
!(pathname.startsWith("/https://") || pathname.startsWith("/http://"))
|
||||
) {
|
||||
return new Response(
|
||||
"Enter a path that starts with https:// or http://\n",
|
||||
{
|
||||
status: 400,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
req.url.substring("http://localhost:3000/".length),
|
||||
req.clone()
|
||||
);
|
||||
|
||||
return new HTMLRewriter()
|
||||
.on("a[href]", {
|
||||
element(element: Element) {
|
||||
element.setAttribute(
|
||||
"href",
|
||||
"https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
||||
);
|
||||
},
|
||||
})
|
||||
.transform(response);
|
||||
},
|
||||
|
||||
// this is called when fetch() throws or rejects
|
||||
// error(err: Error) {
|
||||
// },
|
||||
|
||||
// this boolean enables the bun's default error handler
|
||||
// sometime after the initial release, it will auto reload as well
|
||||
development: process.env.NODE_ENV !== "production",
|
||||
// note: this isn't node, but for compatibility bun supports process.env + more stuff in process
|
||||
|
||||
// SSL is enabled if these two are set
|
||||
// certFile: './cert.pem',
|
||||
// keyFile: './key.pem',
|
||||
|
||||
port: 3000, // number or string
|
||||
});
|
||||
24
examples/http-file.ts
Normal file
24
examples/http-file.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
const { serve, file, resolveSync } = Bun;
|
||||
const { path } = import.meta;
|
||||
serve({
|
||||
fetch(req: Request) {
|
||||
return new Response(file(new URL(req.url).pathname.substring(1)));
|
||||
},
|
||||
|
||||
// this is called when fetch() throws or rejects
|
||||
// error(err: Error) {
|
||||
// return new Response("uh oh! :(" + String(err.toString()), { status: 500 });
|
||||
// },
|
||||
|
||||
// this boolean enables the bun's default error handler
|
||||
// sometime after the initial release, it will auto reload as well
|
||||
development: process.env.NODE_ENV !== "production",
|
||||
// note: this isn't node, but for compatibility bun supports process.env + more stuff in process
|
||||
|
||||
// SSL is enabled if these two are set
|
||||
// certFile: './cert.pem',
|
||||
// keyFile: './key.pem',
|
||||
|
||||
port: 3000, // number or string
|
||||
hostname: "localhost", // defaults to 0.0.0.0
|
||||
});
|
||||
12
examples/http-stop.ts
Normal file
12
examples/http-stop.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { serve } from "bun";
|
||||
|
||||
const server = serve({
|
||||
fetch(req) {
|
||||
return new Response(`Pending requests count: ${this.pendingRequests}`);
|
||||
},
|
||||
});
|
||||
|
||||
// Stop the server after 5 seconds
|
||||
setTimeout(() => {
|
||||
server.stop();
|
||||
}, 5000);
|
||||
34
examples/http.ts
Normal file
34
examples/http.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
// Start a fast HTTP server from a function
|
||||
Bun.serve({
|
||||
fetch(req: Request) {
|
||||
return new Response(`Echo: ${req.url}`);
|
||||
},
|
||||
|
||||
// baseURI: "http://localhost:3000",
|
||||
|
||||
// this is called when fetch() throws or rejects
|
||||
// error(err: Error) {
|
||||
// return new Response("uh oh! :(\n" + err.toString(), { status: 500 });
|
||||
// },
|
||||
|
||||
// this boolean enables bun's default error handler
|
||||
development: process.env.NODE_ENV !== "production",
|
||||
// note: this isn't node, but for compatibility bun supports process.env + more stuff in process
|
||||
|
||||
// SSL is enabled if these two are set
|
||||
// certFile: './cert.pem',
|
||||
// keyFile: './key.pem',
|
||||
|
||||
port: 3000, // number or string
|
||||
});
|
||||
// Start a fast HTTP server from the main file's export
|
||||
// export default {
|
||||
// fetch(req) {
|
||||
// return new Response(
|
||||
// `This is another way to start a server!
|
||||
// if the main file export default's an object
|
||||
// with 'fetch'. Bun automatically calls Bun.serve`
|
||||
// );
|
||||
// },
|
||||
// // so autocomplete & type checking works
|
||||
// } as Bun.Serve;
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "@bun-examples/next",
|
||||
"version": "0.0.48",
|
||||
"version": "0.0.51",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"next": "^12.1.0",
|
||||
"react": "beta",
|
||||
"react-dom": "beta",
|
||||
"react": "^17",
|
||||
"react-dom": "^17",
|
||||
"react-is": "^17.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
68
examples/sha.js
Normal file
68
examples/sha.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import { SHA1, SHA256, SHA512, SHA384, SHA512_256, MD5, MD4, sha } from "bun";
|
||||
|
||||
const input = "Hello World";
|
||||
const [first, second] = input.split(" ");
|
||||
|
||||
const log = (name, ...args) =>
|
||||
console.log(`${name}:`.padStart("SHA512_256: ".length), ...args);
|
||||
|
||||
console.log("");
|
||||
// This is SHA512-256:
|
||||
// This function is shorthand for SHA512_256.hash(input)
|
||||
log("Bun.sha()", sha(input, "base64"));
|
||||
|
||||
log("SHA1", SHA1.hash(input, "hex"));
|
||||
log("SHA256", SHA256.hash(input, "hex"));
|
||||
log("SHA384", SHA384.hash(input, "hex"));
|
||||
log("SHA512", SHA512.hash(input, "hex"));
|
||||
log("SHA512_256", SHA512_256.hash(input, "hex"));
|
||||
|
||||
console.log("");
|
||||
console.log("---- Chunked ----");
|
||||
console.log("");
|
||||
|
||||
// You can also do updates in chunks:
|
||||
// const hash = new Hash();
|
||||
for (let Hash of [SHA1, SHA256, SHA384, SHA512, SHA512_256]) {
|
||||
const hash = new Hash();
|
||||
hash.update(first);
|
||||
hash.update(" " + second);
|
||||
log(Hash.name, hash.digest("hex"));
|
||||
}
|
||||
|
||||
console.log("");
|
||||
console.log("---- Base64 ----");
|
||||
console.log("");
|
||||
|
||||
// base64 or hex
|
||||
for (let Hash of [SHA1, SHA256, SHA384, SHA512, SHA512_256]) {
|
||||
const hash = new Hash();
|
||||
hash.update(first);
|
||||
hash.update(" " + second);
|
||||
log(Hash.name, hash.digest("base64"));
|
||||
}
|
||||
|
||||
console.log("");
|
||||
console.log("---- Uint8Array ----");
|
||||
console.log("");
|
||||
|
||||
// Uint8Array by default
|
||||
for (let Hash of [SHA1, SHA256, SHA384, SHA512, SHA512_256]) {
|
||||
const hash = new Hash();
|
||||
hash.update(first);
|
||||
hash.update(" " + second);
|
||||
log(Hash.name, hash.digest());
|
||||
}
|
||||
|
||||
console.log("");
|
||||
console.log("---- Uint8Array can be updated in-place ----");
|
||||
console.log("");
|
||||
|
||||
var oneBuf = new Uint8Array(1024);
|
||||
// Update Uint8Array in-place instead of allocating a new one
|
||||
for (let Hash of [SHA1, SHA256, SHA384, SHA512, SHA512_256]) {
|
||||
const hash = new Hash();
|
||||
hash.update(first);
|
||||
hash.update(" " + second);
|
||||
log(Hash.name, hash.digest(oneBuf).subarray(0, Hash.byteLength));
|
||||
}
|
||||
@@ -3,13 +3,12 @@ import { resolve } from "path";
|
||||
const development = process.env.NODE_ENV !== "production";
|
||||
export default {
|
||||
fetch(req: Request) {
|
||||
Bun.file;
|
||||
return new Response(Bun.file(resolve(req.url.substring(1))));
|
||||
},
|
||||
|
||||
// hostname: "0.0.0.0",
|
||||
// port: parseInt(process.env.PORT || "443", 10),
|
||||
// keyFile: process.env.SSL_KEY_FILE || "./key.pem",
|
||||
// certFile: process.env.SSL_CERTIFICATE_FILE || "./cert.pem",
|
||||
// hostname: "0.0.0.0",
|
||||
port: process.env.PORT || "443",
|
||||
keyFile: process.env.SSL_KEY_FILE || "./key.pem",
|
||||
certFile: process.env.SSL_CERTIFICATE_FILE || "./cert.pem",
|
||||
development,
|
||||
} as Bun.Serve;
|
||||
8
examples/tsconfig.json
Normal file
8
examples/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"module": "esnext",
|
||||
"target": "esnext",
|
||||
"typeRoots": ["../types"]
|
||||
}
|
||||
}
|
||||
138
integration/README.md
Normal file
138
integration/README.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# Tests in Bun
|
||||
|
||||
Bun currently has four different kinds of tests
|
||||
|
||||
To run the tests:
|
||||
|
||||
```bash
|
||||
make test-all
|
||||
bun wiptest
|
||||
```
|
||||
|
||||
### Browser tests
|
||||
|
||||
Browser tests run end-to-end inside of Puppeteer and execute code transpiled by `bun dev`. These tests are in [./snippets](./snippets).
|
||||
|
||||
The interface is:
|
||||
|
||||
```js
|
||||
// this function is called after import()
|
||||
// if testDone() is never called, the test fails
|
||||
export function test() {
|
||||
return testDone(import.meta.url);
|
||||
}
|
||||
```
|
||||
|
||||
On success, it saves a snapshot to [./snapshots](./snapshots) which is checked into git.
|
||||
|
||||
#### Adding a new test
|
||||
|
||||
1. Create a new file in the `snippets` directory.
|
||||
2. Append the filename to [./scripts/snippets.json](./scripts/snippets.json)
|
||||
3. Run `bun dev` inside this folder in one terminal window
|
||||
4. Run `make integration-test-dev`
|
||||
|
||||
These tests are run twice. Once with HMR enabled and once with HMR disabled. HMR changes the output enough to warrant it's own special treatment.
|
||||
|
||||
#### Running the tests
|
||||
|
||||
To run the browser tests with HMR on a production build:
|
||||
|
||||
```bash
|
||||
make test-with-hmr
|
||||
```
|
||||
|
||||
To run the browser tests without HMR on a production build:
|
||||
|
||||
```bash
|
||||
make test-with-no-hmr
|
||||
```
|
||||
|
||||
To run the browser tests with HMR on a debug build:
|
||||
|
||||
```bash
|
||||
make test-dev-with-hmr
|
||||
```
|
||||
|
||||
To run the browser tests without HMR on a debug build:
|
||||
|
||||
```bash
|
||||
make test-dev-no-hmr
|
||||
```
|
||||
|
||||
To run the browser tests on whatever version of bun is running on port 3000:
|
||||
|
||||
```bash
|
||||
make integration-test-dev
|
||||
```
|
||||
|
||||
These were the first tests bun started with
|
||||
|
||||
### Runtime tests
|
||||
|
||||
These tests are in [./bunjs-only-snippets](./bunjs-only-snippets) and are files which are either `.test.js` or `.test.ts` files.
|
||||
|
||||
These test that the runtime behaves as expected. These also test the transpiler, both because test files are transpiled and directly by running the transpiler via `Bun.Transpiler`.
|
||||
|
||||
#### Adding a new test
|
||||
|
||||
1. Create a new file in [./bunjs-only-snippets](./bunjs-only-snippets/) with `.test` in the name.
|
||||
|
||||
These test use `bun:test` as the import (though you can also import from `vitest` or jest and it will work).
|
||||
|
||||
This will eventually be a public test runner for bun, but the reporter isn't very good yet and it doesn't run in parallel.
|
||||
|
||||
The syntax intends for Jest compatibility.
|
||||
|
||||
```ts
|
||||
import { describe, expect, it } from "bun:test";
|
||||
|
||||
describe("Example", () => {
|
||||
it("should work", () => {
|
||||
expect(1).toBe(1);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
#### Running the tests
|
||||
|
||||
Run `bun wiptest ${part-of-file-name}`
|
||||
|
||||
If you run the test in the top-level bun repo directory, it will take an extra couple seconds because `bun wiptest` will scan through all of WebKit recursively. Consider running it in the `bunjs-only-snippets` directory instead.
|
||||
|
||||
### CLI tests
|
||||
|
||||
These run the bash files in the `apps` directory.
|
||||
|
||||
They check end-to-end that the CLI works as expected.
|
||||
|
||||
```bash
|
||||
# Install dependencies for running tests
|
||||
# Does not run tests
|
||||
make test-install
|
||||
|
||||
# Check a Create React App created via `bun create react ./foo` returns HTML
|
||||
make test-create-react
|
||||
|
||||
# Check a Next.js app created via `bun create next ./foo` SSRs successfully
|
||||
make test-create-next
|
||||
|
||||
# Check that bun run works for the same CLI args passed to npm run
|
||||
make test-bun-run
|
||||
|
||||
# Check that "react" installed via bun install loads successfully
|
||||
# and that deleting/adding updates the lockfile as expected
|
||||
make test-bun-install
|
||||
|
||||
# Check that serving public paths works correctly
|
||||
# and that files which should be transpiled are transpiled and files which shouldn't be aren't
|
||||
make test-bun-dev
|
||||
```
|
||||
|
||||
### Zig tests
|
||||
|
||||
These tests live in various `.zig` files throughout Bun's codebase, leveraging Zig's builtin `test` keyword.
|
||||
|
||||
Currently, they're not run automatically nor is there a simple way to run all of them.
|
||||
|
||||
This is an area bun needs to improve in.
|
||||
301
integration/bunjs-only-snippets/buffer.test.js
Normal file
301
integration/bunjs-only-snippets/buffer.test.js
Normal file
@@ -0,0 +1,301 @@
|
||||
import { gc } from "bun";
|
||||
import { describe, it, expect } from "bun:test";
|
||||
|
||||
it("buffer", () => {
|
||||
var buf = new Buffer(20);
|
||||
gc();
|
||||
// if this fails or infinitely loops, it means there is a memory issue with the JSC::Structure object
|
||||
expect(Object.keys(buf).length > 0).toBe(true);
|
||||
gc();
|
||||
expect(buf.write("hello world ")).toBe(12);
|
||||
expect(buf.write("hello world ", "utf8")).toBe(12);
|
||||
|
||||
gc();
|
||||
expect(buf.toString("utf8", 0, "hello world ".length)).toBe("hello world ");
|
||||
gc();
|
||||
expect(buf.toString("base64url", 0, "hello world ".length)).toBe(
|
||||
btoa("hello world ")
|
||||
);
|
||||
gc();
|
||||
expect(buf instanceof Uint8Array).toBe(true);
|
||||
gc();
|
||||
expect(buf instanceof Buffer).toBe(true);
|
||||
gc();
|
||||
expect(buf.slice() instanceof Uint8Array).toBe(true);
|
||||
gc();
|
||||
expect(buf.slice(0, 1) instanceof Buffer).toBe(true);
|
||||
gc();
|
||||
expect(buf.slice(0, 1) instanceof Uint8Array).toBe(true);
|
||||
gc();
|
||||
expect(buf.slice(0, 1) instanceof Buffer).toBe(true);
|
||||
gc();
|
||||
});
|
||||
|
||||
it("Buffer", () => {
|
||||
var inputs = [
|
||||
"hello world",
|
||||
"hello world".repeat(100),
|
||||
`😋 Get Emoji — All Emojis to ✂️ Copy and 📋 Paste 👌`,
|
||||
];
|
||||
var good = inputs.map((a) => new TextEncoder().encode(a));
|
||||
for (let i = 0; i < inputs.length; i++) {
|
||||
var input = inputs[i];
|
||||
expect(new Buffer(input).toString("utf8")).toBe(inputs[i]);
|
||||
gc();
|
||||
expect(Array.from(new Buffer(input)).join(",")).toBe(good[i].join(","));
|
||||
gc();
|
||||
expect(Buffer.byteLength(input)).toBe(good[i].length);
|
||||
gc();
|
||||
expect(Buffer.from(input).byteLength).toBe(Buffer.byteLength(input));
|
||||
}
|
||||
});
|
||||
|
||||
it("Buffer.byteLength", () => {
|
||||
expect(Buffer.byteLength("😀😃😄😁😆😅😂🤣☺️😊😊😇")).toBe(
|
||||
new TextEncoder().encode("😀😃😄😁😆😅😂🤣☺️😊😊😇").byteLength
|
||||
);
|
||||
});
|
||||
|
||||
it("Buffer.isBuffer", () => {
|
||||
expect(Buffer.isBuffer(new Buffer(1))).toBe(true);
|
||||
gc();
|
||||
expect(Buffer.isBuffer(new Buffer(0))).toBe(true);
|
||||
gc();
|
||||
expect(Buffer.isBuffer(new Uint8Array(0))).toBe(false);
|
||||
gc();
|
||||
expect(Buffer.isBuffer(new Uint8Array(1))).toBe(false);
|
||||
gc();
|
||||
var a = new Uint8Array(1);
|
||||
gc();
|
||||
expect(Buffer.isBuffer(a)).toBe(false);
|
||||
gc();
|
||||
Buffer.toBuffer(a);
|
||||
gc();
|
||||
expect(Buffer.isBuffer(a)).toBe(true);
|
||||
gc();
|
||||
});
|
||||
|
||||
it("Buffer.toBuffer throws", () => {
|
||||
const checks = [
|
||||
[],
|
||||
{},
|
||||
"foo",
|
||||
new Uint16Array(),
|
||||
new DataView(new Uint8Array(14).buffer),
|
||||
];
|
||||
for (let i = 0; i < checks.length; i++) {
|
||||
try {
|
||||
Buffer.toBuffer(checks[i]);
|
||||
expect(false).toBe(true);
|
||||
} catch (exception) {
|
||||
expect(exception.message).toBe("Expected Uint8Array");
|
||||
}
|
||||
}
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
|
||||
it("Buffer.toBuffer works", () => {
|
||||
var array = new Uint8Array(20);
|
||||
expect(array instanceof Buffer).toBe(false);
|
||||
var buf = Buffer.toBuffer(array);
|
||||
expect(array instanceof Buffer).toBe(true);
|
||||
// if this fails or infinitely loops, it means there is a memory issue with the JSC::Structure object
|
||||
expect(Object.keys(buf).length > 0).toBe(true);
|
||||
|
||||
expect(buf.write("hello world ")).toBe(12);
|
||||
gc();
|
||||
expect(buf.toString("utf8", 0, "hello world ".length)).toBe("hello world ");
|
||||
gc();
|
||||
expect(buf.toString("base64url", 0, "hello world ".length)).toBe(
|
||||
btoa("hello world ")
|
||||
);
|
||||
gc();
|
||||
|
||||
expect(buf instanceof Uint8Array).toBe(true);
|
||||
expect(buf instanceof Buffer).toBe(true);
|
||||
expect(buf.slice() instanceof Uint8Array).toBe(true);
|
||||
expect(buf.slice(0, 1) instanceof Buffer).toBe(true);
|
||||
expect(buf.slice(0, 1) instanceof Uint8Array).toBe(true);
|
||||
expect(buf.slice(0, 1) instanceof Buffer).toBe(true);
|
||||
expect(new Buffer(buf) instanceof Buffer).toBe(true);
|
||||
expect(new Buffer(buf.buffer) instanceof Buffer).toBe(true);
|
||||
});
|
||||
|
||||
it("writeInt", () => {
|
||||
var buf = new Buffer(1024);
|
||||
var data = new DataView(buf.buffer);
|
||||
buf.writeInt32BE(100);
|
||||
expect(data.getInt32(0, false)).toBe(100);
|
||||
buf.writeInt32BE(100);
|
||||
expect(data.getInt32(0, false)).toBe(100);
|
||||
var childBuf = buf.subarray(0, 4);
|
||||
expect(data.getInt32(0, false)).toBe(100);
|
||||
expect(childBuf.readInt32BE(0, false)).toBe(100);
|
||||
});
|
||||
|
||||
it("Buffer.from", () => {
|
||||
expect(Buffer.from("hello world").toString("utf8")).toBe("hello world");
|
||||
expect(Buffer.from("hello world", "ascii").toString("utf8")).toBe(
|
||||
"hello world"
|
||||
);
|
||||
expect(Buffer.from("hello world", "latin1").toString("utf8")).toBe(
|
||||
"hello world"
|
||||
);
|
||||
gc();
|
||||
expect(Buffer.from([254]).join(",")).toBe("254");
|
||||
expect(Buffer.from(123).join(",")).toBe(Uint8Array.from(123).join(","));
|
||||
expect(Buffer.from({ length: 124 }).join(",")).toBe(
|
||||
Uint8Array.from({ length: 124 }).join(",")
|
||||
);
|
||||
|
||||
expect(Buffer.from(new ArrayBuffer(1024), 0, 512).join(",")).toBe(
|
||||
new Uint8Array(512).join(",")
|
||||
);
|
||||
|
||||
expect(Buffer.from(new Buffer(new ArrayBuffer(1024), 0, 512)).join(",")).toBe(
|
||||
new Uint8Array(512).join(",")
|
||||
);
|
||||
gc();
|
||||
});
|
||||
|
||||
it("Buffer.equals", () => {
|
||||
var a = new Uint8Array(10);
|
||||
a[2] = 1;
|
||||
var b = new Uint8Array(10);
|
||||
b[2] = 1;
|
||||
Buffer.toBuffer(a);
|
||||
Buffer.toBuffer(b);
|
||||
expect(a.equals(b)).toBe(true);
|
||||
b[2] = 0;
|
||||
expect(a.equals(b)).toBe(false);
|
||||
});
|
||||
|
||||
it("Buffer.compare", () => {
|
||||
var a = new Uint8Array(10);
|
||||
a[2] = 1;
|
||||
var b = new Uint8Array(10);
|
||||
b[2] = 1;
|
||||
Buffer.toBuffer(a);
|
||||
Buffer.toBuffer(b);
|
||||
expect(a.compare(b)).toBe(0);
|
||||
b[2] = 0;
|
||||
expect(a.compare(b)).toBe(1);
|
||||
expect(b.compare(a)).toBe(-1);
|
||||
});
|
||||
|
||||
it("Buffer.copy", () => {
|
||||
var array1 = new Uint8Array(128);
|
||||
array1.fill(100);
|
||||
Buffer.toBuffer(array1);
|
||||
var array2 = new Uint8Array(128);
|
||||
array2.fill(200);
|
||||
Buffer.toBuffer(array2);
|
||||
var array3 = new Uint8Array(128);
|
||||
Buffer.toBuffer(array3);
|
||||
gc();
|
||||
expect(array1.copy(array2)).toBe(128);
|
||||
expect(array1.join("")).toBe(array2.join(""));
|
||||
});
|
||||
|
||||
it("Buffer.concat", () => {
|
||||
var array1 = new Uint8Array(128);
|
||||
array1.fill(100);
|
||||
var array2 = new Uint8Array(128);
|
||||
array2.fill(200);
|
||||
var array3 = new Uint8Array(128);
|
||||
array3.fill(300);
|
||||
gc();
|
||||
expect(Buffer.concat([array1, array2, array3]).join("")).toBe(
|
||||
array1.join("") + array2.join("") + array3.join("")
|
||||
);
|
||||
expect(Buffer.concat([array1, array2, array3], 222).length).toBe(222);
|
||||
expect(
|
||||
Buffer.concat([array1, array2, array3], 222).subarray(0, 128).join("")
|
||||
).toBe("100".repeat(128));
|
||||
expect(
|
||||
Buffer.concat([array1, array2, array3], 222).subarray(129, 222).join("")
|
||||
).toBe("200".repeat(222 - 129));
|
||||
});
|
||||
|
||||
it("read", () => {
|
||||
var buf = new Buffer(1024);
|
||||
var data = new DataView(buf.buffer);
|
||||
function reset() {
|
||||
new Uint8Array(buf.buffer).fill(0);
|
||||
}
|
||||
data.setBigInt64(0, BigInt(1000), false);
|
||||
expect(buf.readBigInt64BE(0)).toBe(BigInt(1000));
|
||||
reset();
|
||||
|
||||
data.setBigInt64(0, BigInt(1000), false);
|
||||
expect(buf.readBigInt64LE(0)).toBe(BigInt(1000));
|
||||
reset();
|
||||
|
||||
data.setBigUint64(0, BigInt(1000), false);
|
||||
expect(buf.readBigUInt64BE(0)).toBe(BigInt(1000));
|
||||
reset();
|
||||
|
||||
data.setBigUint64(0, BigInt(1000), false);
|
||||
expect(buf.readBigUInt64LE(0)).toBe(BigInt(1000));
|
||||
reset();
|
||||
|
||||
data.setFloat64(0, 1000, false);
|
||||
expect(buf.readDoubleBE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setFloat64(0, 1000, true);
|
||||
expect(buf.readDoubleLE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setFloat32(0, 1000, false);
|
||||
expect(buf.readFloatBE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setFloat32(0, 1000, true);
|
||||
expect(buf.readFloatLE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setInt16(0, 1000, false);
|
||||
expect(buf.readInt16BE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setInt16(0, 1000, true);
|
||||
expect(buf.readInt16LE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setInt32(0, 1000, false);
|
||||
expect(buf.readInt32BE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setInt32(0, 1000, true);
|
||||
expect(buf.readInt32LE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setInt8(0, 100, false);
|
||||
expect(buf.readInt8(0)).toBe(100);
|
||||
reset();
|
||||
|
||||
data.setUint16(0, 1000, false);
|
||||
expect(buf.readUInt16BE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setUint16(0, 1000, true);
|
||||
expect(buf.readUInt16LE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setUint32(0, 1000, false);
|
||||
expect(buf.readUInt32BE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setUint32(0, 1000, true);
|
||||
expect(buf.readUInt32LE(0)).toBe(1000);
|
||||
reset();
|
||||
|
||||
data.setUint8(0, 255, false);
|
||||
expect(buf.readUInt8(0)).toBe(255);
|
||||
reset();
|
||||
|
||||
data.setUint8(0, 255, false);
|
||||
expect(buf.readUInt8(0)).toBe(255);
|
||||
reset();
|
||||
});
|
||||
94
integration/bunjs-only-snippets/bun-jsc.test.js
Normal file
94
integration/bunjs-only-snippets/bun-jsc.test.js
Normal file
@@ -0,0 +1,94 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import {
|
||||
describe as jscDescribe,
|
||||
describeArray,
|
||||
gcAndSweep,
|
||||
fullGC,
|
||||
edenGC,
|
||||
heapSize,
|
||||
heapStats,
|
||||
memoryUsage,
|
||||
getRandomSeed,
|
||||
setRandomSeed,
|
||||
isRope,
|
||||
callerSourceOrigin,
|
||||
noFTL,
|
||||
noOSRExitFuzzing,
|
||||
optimizeNextInvocation,
|
||||
numberOfDFGCompiles,
|
||||
releaseWeakRefs,
|
||||
totalCompileTime,
|
||||
reoptimizationRetryCount,
|
||||
drainMicrotasks,
|
||||
} from "bun:jsc";
|
||||
|
||||
describe("bun:jsc", () => {
|
||||
function count() {
|
||||
var j = 0;
|
||||
for (var i = 0; i < 999999; i++) {
|
||||
j += i + 2;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
it("describe", () => {
|
||||
jscDescribe([]);
|
||||
});
|
||||
it("describeArray", () => {
|
||||
describeArray([1, 2, 3]);
|
||||
});
|
||||
it("gcAndSweep", () => {
|
||||
gcAndSweep();
|
||||
});
|
||||
it("fullGC", () => {
|
||||
fullGC();
|
||||
});
|
||||
it("edenGC", () => {
|
||||
edenGC();
|
||||
});
|
||||
it("heapSize", () => {
|
||||
expect(heapSize() > 0).toBe(true);
|
||||
});
|
||||
it("heapStats", () => {
|
||||
heapStats();
|
||||
});
|
||||
it("memoryUsage", () => {
|
||||
memoryUsage();
|
||||
});
|
||||
it("getRandomSeed", () => {
|
||||
getRandomSeed(2);
|
||||
});
|
||||
it("setRandomSeed", () => {
|
||||
setRandomSeed(2);
|
||||
});
|
||||
it("isRope", () => {
|
||||
expect(isRope("a" + 123 + "b")).toBe(true);
|
||||
expect(isRope("abcdefgh")).toBe(false);
|
||||
});
|
||||
it("callerSourceOrigin", () => {
|
||||
expect(callerSourceOrigin()).toBe(import.meta.url);
|
||||
});
|
||||
it("noFTL", () => {});
|
||||
it("noOSRExitFuzzing", () => {});
|
||||
it("optimizeNextInvocation", () => {
|
||||
count();
|
||||
optimizeNextInvocation(count);
|
||||
count();
|
||||
});
|
||||
it("numberOfDFGCompiles", () => {
|
||||
expect(numberOfDFGCompiles(count)).toBe(3);
|
||||
});
|
||||
it("releaseWeakRefs", () => {
|
||||
releaseWeakRefs();
|
||||
});
|
||||
it("totalCompileTime", () => {
|
||||
totalCompileTime(count);
|
||||
});
|
||||
it("reoptimizationRetryCount", () => {
|
||||
reoptimizationRetryCount(count);
|
||||
});
|
||||
it("drainMicrotasks", () => {
|
||||
drainMicrotasks();
|
||||
});
|
||||
});
|
||||
70
integration/bunjs-only-snippets/crypto.test.js
Normal file
70
integration/bunjs-only-snippets/crypto.test.js
Normal file
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
sha,
|
||||
MD5,
|
||||
MD4,
|
||||
SHA1,
|
||||
SHA256,
|
||||
SHA384,
|
||||
SHA512,
|
||||
SHA512_256,
|
||||
gc,
|
||||
} from "bun";
|
||||
import { it, expect, describe } from "bun:test";
|
||||
import { readFileSync } from "fs";
|
||||
|
||||
describe("crypto", () => {
|
||||
for (let Hash of [MD5, MD4, SHA1, SHA256, SHA384, SHA512, SHA512_256]) {
|
||||
for (let input of [
|
||||
"hello world",
|
||||
"hello world".repeat(20).slice(),
|
||||
"",
|
||||
"a",
|
||||
]) {
|
||||
describe(input, () => {
|
||||
gc(true);
|
||||
|
||||
it(`${Hash.name} base64`, () => {
|
||||
gc(true);
|
||||
const result = new Hash();
|
||||
result.update(input);
|
||||
expect(typeof result.digest("base64")).toBe("string");
|
||||
gc(true);
|
||||
});
|
||||
|
||||
it(`${Hash.name} hash base64`, () => {
|
||||
Hash.hash(input, "base64");
|
||||
gc(true);
|
||||
});
|
||||
|
||||
it(`${Hash.name} hex`, () => {
|
||||
const result = new Hash();
|
||||
result.update(input);
|
||||
expect(typeof result.digest("hex")).toBe("string");
|
||||
gc(true);
|
||||
});
|
||||
|
||||
it(`${Hash.name} hash hex`, () => {
|
||||
expect(typeof Hash.hash(input, "hex")).toBe("string");
|
||||
gc(true);
|
||||
});
|
||||
|
||||
it(`${Hash.name} buffer`, () => {
|
||||
var buf = new Uint8Array(256);
|
||||
const result = new Hash();
|
||||
|
||||
result.update(input);
|
||||
expect(result.digest(buf)).toBe(buf);
|
||||
expect(buf[0] != 0).toBe(true);
|
||||
gc(true);
|
||||
});
|
||||
|
||||
it(`${Hash.name} buffer`, () => {
|
||||
var buf = new Uint8Array(256);
|
||||
|
||||
expect(Hash.hash(input, buf) instanceof Uint8Array).toBe(true);
|
||||
gc(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
9
integration/bunjs-only-snippets/dirname.test.js
Normal file
9
integration/bunjs-only-snippets/dirname.test.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { expect, it } from "bun:test";
|
||||
|
||||
it("__dirname should work", () => {
|
||||
expect(import.meta.dir).toBe(__dirname);
|
||||
});
|
||||
|
||||
it("__filename should work", () => {
|
||||
expect(import.meta.path).toBe(__filename);
|
||||
});
|
||||
104
integration/bunjs-only-snippets/escapeHTML.test.js
Normal file
104
integration/bunjs-only-snippets/escapeHTML.test.js
Normal file
@@ -0,0 +1,104 @@
|
||||
import { describe, it, expect } from "bun:test";
|
||||
import { gcTick } from "./gc";
|
||||
|
||||
describe("escapeHTML", () => {
|
||||
// The matrix of cases we need to test for:
|
||||
// 1. Works with short strings
|
||||
// 2. Works with long strings
|
||||
// 3. Works with latin1 strings
|
||||
// 4. Works with utf16 strings
|
||||
// 5. Works when the text to escape is somewhere in the middle
|
||||
// 6. Works when the text to escape is in the beginning
|
||||
// 7. Works when the text to escape is in the end
|
||||
// 8. Returns the same string when there's no need to escape
|
||||
it("works", () => {
|
||||
expect(escapeHTML("absolutely nothing to do here")).toBe(
|
||||
"absolutely nothing to do here"
|
||||
);
|
||||
expect(escapeHTML("<script>alert(1)</script>")).toBe(
|
||||
"<script>alert(1)</script>"
|
||||
);
|
||||
expect(escapeHTML("<")).toBe("<");
|
||||
expect(escapeHTML(">")).toBe(">");
|
||||
expect(escapeHTML("&")).toBe("&");
|
||||
expect(escapeHTML("'")).toBe("'");
|
||||
expect(escapeHTML('"')).toBe(""");
|
||||
expect(escapeHTML("\n")).toBe("\n");
|
||||
expect(escapeHTML("\r")).toBe("\r");
|
||||
expect(escapeHTML("\t")).toBe("\t");
|
||||
expect(escapeHTML("\f")).toBe("\f");
|
||||
expect(escapeHTML("\v")).toBe("\v");
|
||||
expect(escapeHTML("\b")).toBe("\b");
|
||||
expect(escapeHTML("\u00A0")).toBe("\u00A0");
|
||||
expect(escapeHTML("<script>ab")).toBe("<script>ab");
|
||||
expect(escapeHTML("<script>")).toBe("<script>");
|
||||
expect(escapeHTML("<script><script>")).toBe("<script><script>");
|
||||
|
||||
expect(escapeHTML("lalala" + "<script>alert(1)</script>" + "lalala")).toBe(
|
||||
"lalala<script>alert(1)</script>lalala"
|
||||
);
|
||||
|
||||
expect(escapeHTML("<script>alert(1)</script>" + "lalala")).toBe(
|
||||
"<script>alert(1)</script>lalala"
|
||||
);
|
||||
expect(escapeHTML("lalala" + "<script>alert(1)</script>")).toBe(
|
||||
"lalala" + "<script>alert(1)</script>"
|
||||
);
|
||||
|
||||
expect(escapeHTML("What does 😊 mean?")).toBe("What does 😊 mean?");
|
||||
const output = escapeHTML("<What does 😊");
|
||||
expect(output).toBe("<What does 😊");
|
||||
expect(escapeHTML("<div>What does 😊 mean in text?")).toBe(
|
||||
"<div>What does 😊 mean in text?"
|
||||
);
|
||||
|
||||
expect(
|
||||
escapeHTML(
|
||||
("lalala" + "<script>alert(1)</script>" + "lalala").repeat(900)
|
||||
)
|
||||
).toBe("lalala<script>alert(1)</script>lalala".repeat(900));
|
||||
expect(
|
||||
escapeHTML(("<script>alert(1)</script>" + "lalala").repeat(900))
|
||||
).toBe("<script>alert(1)</script>lalala".repeat(900));
|
||||
expect(
|
||||
escapeHTML(("lalala" + "<script>alert(1)</script>").repeat(900))
|
||||
).toBe(("lalala" + "<script>alert(1)</script>").repeat(900));
|
||||
|
||||
// the positions of the unicode codepoint are important
|
||||
// our simd code for U16 is at 8 bytes, so we need to especially check the boundaries
|
||||
expect(
|
||||
escapeHTML("😊lalala" + "<script>alert(1)</script>" + "lalala")
|
||||
).toBe("😊lalala<script>alert(1)</script>lalala");
|
||||
expect(escapeHTML("<script>😊alert(1)</script>" + "lalala")).toBe(
|
||||
"<script>😊alert(1)</script>lalala"
|
||||
);
|
||||
expect(escapeHTML("<script>alert(1)😊</script>" + "lalala")).toBe(
|
||||
"<script>alert(1)😊</script>lalala"
|
||||
);
|
||||
expect(escapeHTML("<script>alert(1)</script>" + "😊lalala")).toBe(
|
||||
"<script>alert(1)</script>😊lalala"
|
||||
);
|
||||
expect(escapeHTML("<script>alert(1)</script>" + "lal😊ala")).toBe(
|
||||
"<script>alert(1)</script>lal😊ala"
|
||||
);
|
||||
expect(
|
||||
escapeHTML("<script>alert(1)</script>" + "lal😊ala".repeat(10))
|
||||
).toBe("<script>alert(1)</script>" + "lal😊ala".repeat(10));
|
||||
|
||||
for (let i = 1; i < 10; i++)
|
||||
expect(escapeHTML("<script>alert(1)</script>" + "la😊".repeat(i))).toBe(
|
||||
"<script>alert(1)</script>" + "la😊".repeat(i)
|
||||
);
|
||||
|
||||
expect(escapeHTML("la😊" + "<script>alert(1)</script>")).toBe(
|
||||
"la😊" + "<script>alert(1)</script>"
|
||||
);
|
||||
expect(
|
||||
escapeHTML(("lalala" + "<script>alert(1)</script>😊").repeat(1))
|
||||
).toBe(("lalala" + "<script>alert(1)</script>😊").repeat(1));
|
||||
|
||||
expect(escapeHTML("😊".repeat(100))).toBe("😊".repeat(100));
|
||||
expect(escapeHTML("😊<".repeat(100))).toBe("😊<".repeat(100));
|
||||
expect(escapeHTML("<😊>".repeat(100))).toBe("<😊>".repeat(100));
|
||||
});
|
||||
});
|
||||
129
integration/bunjs-only-snippets/ffi-test.c
Normal file
129
integration/bunjs-only-snippets/ffi-test.c
Normal file
@@ -0,0 +1,129 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
bool returns_true();
|
||||
bool returns_false();
|
||||
char returns_42_char();
|
||||
float returns_42_float();
|
||||
double returns_42_double();
|
||||
uint8_t returns_42_uint8_t();
|
||||
int8_t returns_neg_42_int8_t();
|
||||
uint16_t returns_42_uint16_t();
|
||||
uint32_t returns_42_uint32_t();
|
||||
uint64_t returns_42_uint64_t();
|
||||
int16_t returns_neg_42_int16_t();
|
||||
int32_t returns_neg_42_int32_t();
|
||||
int64_t returns_neg_42_int64_t();
|
||||
|
||||
bool cb_identity_true(bool (*cb)());
|
||||
bool cb_identity_false(bool (*cb)());
|
||||
char cb_identity_42_char(char (*cb)());
|
||||
float cb_identity_42_float(float (*cb)());
|
||||
double cb_identity_42_double(double (*cb)());
|
||||
uint8_t cb_identity_42_uint8_t(uint8_t (*cb)());
|
||||
int8_t cb_identity_neg_42_int8_t(int8_t (*cb)());
|
||||
uint16_t cb_identity_42_uint16_t(uint16_t (*cb)());
|
||||
uint32_t cb_identity_42_uint32_t(uint32_t (*cb)());
|
||||
uint64_t cb_identity_42_uint64_t(uint64_t (*cb)());
|
||||
int16_t cb_identity_neg_42_int16_t(int16_t (*cb)());
|
||||
int32_t cb_identity_neg_42_int32_t(int32_t (*cb)());
|
||||
int64_t cb_identity_neg_42_int64_t(int64_t (*cb)());
|
||||
|
||||
bool identity_bool_true();
|
||||
bool identity_bool_false();
|
||||
char identity_char(char a);
|
||||
float identity_float(float a);
|
||||
bool identity_bool(bool ident);
|
||||
double identity_double(double a);
|
||||
int8_t identity_int8_t(int8_t a);
|
||||
int16_t identity_int16_t(int16_t a);
|
||||
int32_t identity_int32_t(int32_t a);
|
||||
int64_t identity_int64_t(int64_t a);
|
||||
uint8_t identity_uint8_t(uint8_t a);
|
||||
uint16_t identity_uint16_t(uint16_t a);
|
||||
uint32_t identity_uint32_t(uint32_t a);
|
||||
uint64_t identity_uint64_t(uint64_t a);
|
||||
|
||||
char add_char(char a, char b);
|
||||
float add_float(float a, float b);
|
||||
double add_double(double a, double b);
|
||||
int8_t add_int8_t(int8_t a, int8_t b);
|
||||
int16_t add_int16_t(int16_t a, int16_t b);
|
||||
int32_t add_int32_t(int32_t a, int32_t b);
|
||||
int64_t add_int64_t(int64_t a, int64_t b);
|
||||
uint8_t add_uint8_t(uint8_t a, uint8_t b);
|
||||
uint16_t add_uint16_t(uint16_t a, uint16_t b);
|
||||
uint32_t add_uint32_t(uint32_t a, uint32_t b);
|
||||
uint64_t add_uint64_t(uint64_t a, uint64_t b);
|
||||
|
||||
bool returns_false() { return false; }
|
||||
bool returns_true() { return true; }
|
||||
char returns_42_char() { return '*'; }
|
||||
double returns_42_double() { return (double)42.42; }
|
||||
float returns_42_float() { return 42.42f; }
|
||||
int16_t returns_neg_42_int16_t() { return -42; }
|
||||
int32_t returns_neg_42_int32_t() { return -42; }
|
||||
int64_t returns_neg_42_int64_t() { return -42; }
|
||||
int8_t returns_neg_42_int8_t() { return -42; }
|
||||
uint16_t returns_42_uint16_t() { return 42; }
|
||||
uint32_t returns_42_uint32_t() { return 42; }
|
||||
uint64_t returns_42_uint64_t() { return 42; }
|
||||
uint8_t returns_42_uint8_t() { return (uint8_t)42; }
|
||||
|
||||
char identity_char(char a) { return a; }
|
||||
float identity_float(float a) { return a; }
|
||||
double identity_double(double a) { return a; }
|
||||
int8_t identity_int8_t(int8_t a) { return a; }
|
||||
int16_t identity_int16_t(int16_t a) { return a; }
|
||||
int32_t identity_int32_t(int32_t a) { return a; }
|
||||
int64_t identity_int64_t(int64_t a) { return a; }
|
||||
uint8_t identity_uint8_t(uint8_t a) { return a; }
|
||||
uint16_t identity_uint16_t(uint16_t a) { return a; }
|
||||
uint32_t identity_uint32_t(uint32_t a) { return a; }
|
||||
uint64_t identity_uint64_t(uint64_t a) { return a; }
|
||||
bool identity_bool(bool ident) { return ident; }
|
||||
void *identity_ptr(void *ident) { return ident; }
|
||||
|
||||
char add_char(char a, char b) { return a + b; }
|
||||
float add_float(float a, float b) { return a + b; }
|
||||
double add_double(double a, double b) { return a + b; }
|
||||
int8_t add_int8_t(int8_t a, int8_t b) { return a + b; }
|
||||
int16_t add_int16_t(int16_t a, int16_t b) { return a + b; }
|
||||
int32_t add_int32_t(int32_t a, int32_t b) { return a + b; }
|
||||
int64_t add_int64_t(int64_t a, int64_t b) { return a + b; }
|
||||
uint8_t add_uint8_t(uint8_t a, uint8_t b) { return a + b; }
|
||||
uint16_t add_uint16_t(uint16_t a, uint16_t b) { return a + b; }
|
||||
uint32_t add_uint32_t(uint32_t a, uint32_t b) { return a + b; }
|
||||
uint64_t add_uint64_t(uint64_t a, uint64_t b) { return a + b; }
|
||||
|
||||
void *ptr_should_point_to_42_as_int32_t();
|
||||
void *ptr_should_point_to_42_as_int32_t() {
|
||||
int32_t *ptr = malloc(sizeof(int32_t));
|
||||
*ptr = 42;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool does_pointer_equal_42_as_int32_t(int32_t *ptr);
|
||||
bool does_pointer_equal_42_as_int32_t(int32_t *ptr) { return *ptr == 42; }
|
||||
|
||||
void *return_a_function_ptr_to_function_that_returns_true();
|
||||
void *return_a_function_ptr_to_function_that_returns_true() {
|
||||
return (void *)&returns_true;
|
||||
}
|
||||
|
||||
bool cb_identity_true(bool (*cb)()) { return cb(); }
|
||||
|
||||
bool cb_identity_false(bool (*cb)()) { return cb(); }
|
||||
char cb_identity_42_char(char (*cb)()) { return cb(); }
|
||||
float cb_identity_42_float(float (*cb)()) { return cb(); }
|
||||
double cb_identity_42_double(double (*cb)()) { return cb(); }
|
||||
uint8_t cb_identity_42_uint8_t(uint8_t (*cb)()) { return cb(); }
|
||||
int8_t cb_identity_neg_42_int8_t(int8_t (*cb)()) { return cb(); }
|
||||
uint16_t cb_identity_42_uint16_t(uint16_t (*cb)()) { return cb(); }
|
||||
uint32_t cb_identity_42_uint32_t(uint32_t (*cb)()) { return cb(); }
|
||||
uint64_t cb_identity_42_uint64_t(uint64_t (*cb)()) { return cb(); }
|
||||
int16_t cb_identity_neg_42_int16_t(int16_t (*cb)()) { return cb(); }
|
||||
int32_t cb_identity_neg_42_int32_t(int32_t (*cb)()) { return cb(); }
|
||||
int64_t cb_identity_neg_42_int64_t(int64_t (*cb)()) { return cb(); }
|
||||
270
integration/bunjs-only-snippets/ffi.test.fixture.callback.c
Normal file
270
integration/bunjs-only-snippets/ffi.test.fixture.callback.c
Normal file
@@ -0,0 +1,270 @@
|
||||
#define IS_CALLBACK 1
|
||||
// This file is part of Bun!
|
||||
// You can find the original source:
|
||||
// https://github.com/Jarred-Sumner/bun/blob/main/src/javascript/jsc/api/FFI.h#L2
|
||||
//
|
||||
// clang-format off
|
||||
// This file is only compatible with 64 bit CPUs
|
||||
// It must be kept in sync with JSCJSValue.h
|
||||
// https://github.com/Jarred-Sumner/WebKit/blob/72c2052b781cbfd4af867ae79ac9de460e392fba/Source/JavaScriptCore/runtime/JSCJSValue.h#L455-L458
|
||||
#ifdef IS_CALLBACK
|
||||
#define INJECT_BEFORE int c = 500; // This is a callback, so we need to inject code before the call
|
||||
#endif
|
||||
#define IS_BIG_ENDIAN 0
|
||||
#define USE_JSVALUE64 1
|
||||
#define USE_JSVALUE32_64 0
|
||||
|
||||
|
||||
// /* 7.18.1.1 Exact-width integer types */
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed char int8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned long long size_t;
|
||||
typedef long intptr_t;
|
||||
typedef uint64_t uintptr_t;
|
||||
typedef _Bool bool;
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
|
||||
#ifdef INJECT_BEFORE
|
||||
// #include <stdint.h>
|
||||
#endif
|
||||
// #include <tcclib.h>
|
||||
|
||||
// This value is 2^49, used to encode doubles such that the encoded value will
|
||||
// begin with a 15-bit pattern within the range 0x0002..0xFFFC.
|
||||
#define DoubleEncodeOffsetBit 49
|
||||
#define DoubleEncodeOffset (1ll << DoubleEncodeOffsetBit)
|
||||
#define OtherTag 0x2
|
||||
#define BoolTag 0x4
|
||||
#define UndefinedTag 0x8
|
||||
#define TagValueFalse (OtherTag | BoolTag | false)
|
||||
#define TagValueTrue (OtherTag | BoolTag | true)
|
||||
#define TagValueUndefined (OtherTag | UndefinedTag)
|
||||
#define TagValueNull (OtherTag)
|
||||
#define NotCellMask NumberTag | OtherTag
|
||||
|
||||
#define MAX_INT32 2147483648
|
||||
#define MAX_INT52 9007199254740991
|
||||
|
||||
// If all bits in the mask are set, this indicates an integer number,
|
||||
// if any but not all are set this value is a double precision number.
|
||||
#define NumberTag 0xfffe000000000000ll
|
||||
|
||||
typedef void* JSCell;
|
||||
|
||||
typedef union EncodedJSValue {
|
||||
int64_t asInt64;
|
||||
|
||||
#if USE_JSVALUE64
|
||||
JSCell *ptr;
|
||||
#endif
|
||||
|
||||
#if IS_BIG_ENDIAN
|
||||
struct {
|
||||
int32_t tag;
|
||||
int32_t payload;
|
||||
} asBits;
|
||||
#else
|
||||
struct {
|
||||
int32_t payload;
|
||||
int32_t tag;
|
||||
} asBits;
|
||||
#endif
|
||||
|
||||
void* asPtr;
|
||||
double asDouble;
|
||||
} EncodedJSValue;
|
||||
|
||||
EncodedJSValue ValueUndefined = { TagValueUndefined };
|
||||
EncodedJSValue ValueTrue = { TagValueTrue };
|
||||
|
||||
typedef void* JSContext;
|
||||
|
||||
// Bun_FFI_PointerOffsetToArgumentsList is injected into the build
|
||||
// The value is generated in `make sizegen`
|
||||
// The value is 6.
|
||||
// On ARM64_32, the value is something else but it really doesn't matter for our case
|
||||
// However, I don't want this to subtly break amidst future upgrades to JavaScriptCore
|
||||
#define LOAD_ARGUMENTS_FROM_CALL_FRAME \
|
||||
int64_t *argsPtr = (int64_t*)((size_t*)callFrame + Bun_FFI_PointerOffsetToArgumentsList)
|
||||
|
||||
|
||||
#ifdef IS_CALLBACK
|
||||
extern int64_t bun_call(JSContext, void* func, void* thisValue, size_t len, const EncodedJSValue args[], void* exception);
|
||||
JSContext cachedJSContext;
|
||||
void* cachedCallbackFunction;
|
||||
#endif
|
||||
|
||||
static bool JSVALUE_IS_CELL(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static bool JSVALUE_IS_INT32(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static bool JSVALUE_IS_NUMBER(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
|
||||
static uint64_t JSVALUE_TO_UINT64(void* globalObject, EncodedJSValue value) __attribute__((__always_inline__));
|
||||
static int64_t JSVALUE_TO_INT64(EncodedJSValue value) __attribute__((__always_inline__));
|
||||
uint64_t JSVALUE_TO_UINT64_SLOW(void* globalObject, EncodedJSValue value);
|
||||
int64_t JSVALUE_TO_INT64_SLOW(EncodedJSValue value);
|
||||
|
||||
EncodedJSValue UINT64_TO_JSVALUE_SLOW(void* globalObject, uint64_t val);
|
||||
EncodedJSValue INT64_TO_JSVALUE_SLOW(void* globalObject, int64_t val);
|
||||
static EncodedJSValue UINT64_TO_JSVALUE(void* globalObject, uint64_t val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue INT64_TO_JSVALUE(void* globalObject, int64_t val) __attribute__((__always_inline__));
|
||||
|
||||
|
||||
static EncodedJSValue INT32_TO_JSVALUE(int32_t val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue DOUBLE_TO_JSVALUE(double val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue FLOAT_TO_JSVALUE(float val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue BOOLEAN_TO_JSVALUE(bool val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue PTR_TO_JSVALUE(void* ptr) __attribute__((__always_inline__));
|
||||
|
||||
static void* JSVALUE_TO_PTR(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static int32_t JSVALUE_TO_INT32(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static float JSVALUE_TO_FLOAT(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static double JSVALUE_TO_DOUBLE(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static bool JSVALUE_TO_BOOL(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
|
||||
static bool JSVALUE_IS_CELL(EncodedJSValue val) {
|
||||
return !(val.asInt64 & NotCellMask);
|
||||
}
|
||||
|
||||
static bool JSVALUE_IS_INT32(EncodedJSValue val) {
|
||||
return (val.asInt64 & NumberTag) == NumberTag;
|
||||
}
|
||||
|
||||
static bool JSVALUE_IS_NUMBER(EncodedJSValue val) {
|
||||
return val.asInt64 & NumberTag;
|
||||
}
|
||||
|
||||
|
||||
static void* JSVALUE_TO_PTR(EncodedJSValue val) {
|
||||
// must be a double
|
||||
return (void*)(val.asInt64 - DoubleEncodeOffset);
|
||||
}
|
||||
|
||||
static EncodedJSValue PTR_TO_JSVALUE(void* ptr) {
|
||||
EncodedJSValue val;
|
||||
val.asInt64 = (int64_t)ptr + DoubleEncodeOffset;
|
||||
return val;
|
||||
}
|
||||
|
||||
static int32_t JSVALUE_TO_INT32(EncodedJSValue val) {
|
||||
return val.asInt64;
|
||||
}
|
||||
|
||||
static EncodedJSValue INT32_TO_JSVALUE(int32_t val) {
|
||||
EncodedJSValue res;
|
||||
res.asInt64 = NumberTag | (uint32_t)val;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static EncodedJSValue DOUBLE_TO_JSVALUE(double val) {
|
||||
EncodedJSValue res;
|
||||
res.asDouble = val;
|
||||
res.asInt64 += DoubleEncodeOffset;
|
||||
return res;
|
||||
}
|
||||
|
||||
static EncodedJSValue FLOAT_TO_JSVALUE(float val) {
|
||||
return DOUBLE_TO_JSVALUE((double)val);
|
||||
}
|
||||
|
||||
static EncodedJSValue BOOLEAN_TO_JSVALUE(bool val) {
|
||||
EncodedJSValue res;
|
||||
res.asInt64 = val ? TagValueTrue : TagValueFalse;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static double JSVALUE_TO_DOUBLE(EncodedJSValue val) {
|
||||
val.asInt64 -= DoubleEncodeOffset;
|
||||
return val.asDouble;
|
||||
}
|
||||
|
||||
static float JSVALUE_TO_FLOAT(EncodedJSValue val) {
|
||||
return (float)JSVALUE_TO_DOUBLE(val);
|
||||
}
|
||||
|
||||
static bool JSVALUE_TO_BOOL(EncodedJSValue val) {
|
||||
return val.asInt64 == TagValueTrue;
|
||||
}
|
||||
|
||||
|
||||
static uint64_t JSVALUE_TO_UINT64(void* globalObject, EncodedJSValue value) {
|
||||
if (JSVALUE_IS_INT32(value)) {
|
||||
return (uint64_t)JSVALUE_TO_INT32(value);
|
||||
}
|
||||
|
||||
if (JSVALUE_IS_NUMBER(value)) {
|
||||
return (uint64_t)JSVALUE_TO_DOUBLE(value);
|
||||
}
|
||||
|
||||
return JSVALUE_TO_UINT64_SLOW(globalObject, value);
|
||||
}
|
||||
static int64_t JSVALUE_TO_INT64(EncodedJSValue value) {
|
||||
if (JSVALUE_IS_INT32(value)) {
|
||||
return (int64_t)JSVALUE_TO_INT32(value);
|
||||
}
|
||||
|
||||
if (JSVALUE_IS_NUMBER(value)) {
|
||||
return (int64_t)JSVALUE_TO_DOUBLE(value);
|
||||
}
|
||||
|
||||
return JSVALUE_TO_INT64_SLOW(value);
|
||||
}
|
||||
|
||||
static EncodedJSValue UINT64_TO_JSVALUE(void* globalObject, uint64_t val) {
|
||||
if (val < MAX_INT32) {
|
||||
return INT32_TO_JSVALUE((int32_t)val);
|
||||
}
|
||||
|
||||
if (val < MAX_INT52) {
|
||||
return DOUBLE_TO_JSVALUE((double)val);
|
||||
}
|
||||
|
||||
return UINT64_TO_JSVALUE_SLOW(globalObject, val);
|
||||
}
|
||||
|
||||
static EncodedJSValue INT64_TO_JSVALUE(void* globalObject, int64_t val) {
|
||||
if (val >= -MAX_INT32 && val <= MAX_INT32) {
|
||||
return INT32_TO_JSVALUE((int32_t)val);
|
||||
}
|
||||
|
||||
if (val >= -MAX_INT52 && val <= MAX_INT52) {
|
||||
return DOUBLE_TO_JSVALUE((double)val);
|
||||
}
|
||||
|
||||
return INT64_TO_JSVALUE_SLOW(globalObject, val);
|
||||
}
|
||||
|
||||
#ifndef IS_CALLBACK
|
||||
void* JSFunctionCall(void* globalObject, void* callFrame);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// --- Generated Code ---
|
||||
|
||||
|
||||
/* --- The Callback Function */
|
||||
/* --- The Callback Function */
|
||||
bool my_callback_function(void* arg0);
|
||||
|
||||
bool my_callback_function(void* arg0) {
|
||||
#ifdef INJECT_BEFORE
|
||||
INJECT_BEFORE;
|
||||
#endif
|
||||
EncodedJSValue arguments[1] = {
|
||||
PTR_TO_JSVALUE(arg0)
|
||||
};
|
||||
EncodedJSValue return_value = {bun_call(cachedJSContext, cachedCallbackFunction, (void*)0, 1, &arguments[0], (void*)0)};
|
||||
return JSVALUE_TO_BOOL(return_value);
|
||||
}
|
||||
|
||||
268
integration/bunjs-only-snippets/ffi.test.fixture.receiver.c
Normal file
268
integration/bunjs-only-snippets/ffi.test.fixture.receiver.c
Normal file
@@ -0,0 +1,268 @@
|
||||
#define HAS_ARGUMENTS
|
||||
#define USES_FLOAT 1
|
||||
// This file is part of Bun!
|
||||
// You can find the original source:
|
||||
// https://github.com/Jarred-Sumner/bun/blob/main/src/javascript/jsc/api/FFI.h#L2
|
||||
//
|
||||
// clang-format off
|
||||
// This file is only compatible with 64 bit CPUs
|
||||
// It must be kept in sync with JSCJSValue.h
|
||||
// https://github.com/Jarred-Sumner/WebKit/blob/72c2052b781cbfd4af867ae79ac9de460e392fba/Source/JavaScriptCore/runtime/JSCJSValue.h#L455-L458
|
||||
#ifdef IS_CALLBACK
|
||||
#define INJECT_BEFORE int c = 500; // This is a callback, so we need to inject code before the call
|
||||
#endif
|
||||
#define IS_BIG_ENDIAN 0
|
||||
#define USE_JSVALUE64 1
|
||||
#define USE_JSVALUE32_64 0
|
||||
|
||||
|
||||
// /* 7.18.1.1 Exact-width integer types */
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed char int8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned long long size_t;
|
||||
typedef long intptr_t;
|
||||
typedef uint64_t uintptr_t;
|
||||
typedef _Bool bool;
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
|
||||
#ifdef INJECT_BEFORE
|
||||
// #include <stdint.h>
|
||||
#endif
|
||||
// #include <tcclib.h>
|
||||
|
||||
// This value is 2^49, used to encode doubles such that the encoded value will
|
||||
// begin with a 15-bit pattern within the range 0x0002..0xFFFC.
|
||||
#define DoubleEncodeOffsetBit 49
|
||||
#define DoubleEncodeOffset (1ll << DoubleEncodeOffsetBit)
|
||||
#define OtherTag 0x2
|
||||
#define BoolTag 0x4
|
||||
#define UndefinedTag 0x8
|
||||
#define TagValueFalse (OtherTag | BoolTag | false)
|
||||
#define TagValueTrue (OtherTag | BoolTag | true)
|
||||
#define TagValueUndefined (OtherTag | UndefinedTag)
|
||||
#define TagValueNull (OtherTag)
|
||||
#define NotCellMask NumberTag | OtherTag
|
||||
|
||||
#define MAX_INT32 2147483648
|
||||
#define MAX_INT52 9007199254740991
|
||||
|
||||
// If all bits in the mask are set, this indicates an integer number,
|
||||
// if any but not all are set this value is a double precision number.
|
||||
#define NumberTag 0xfffe000000000000ll
|
||||
|
||||
typedef void* JSCell;
|
||||
|
||||
typedef union EncodedJSValue {
|
||||
int64_t asInt64;
|
||||
|
||||
#if USE_JSVALUE64
|
||||
JSCell *ptr;
|
||||
#endif
|
||||
|
||||
#if IS_BIG_ENDIAN
|
||||
struct {
|
||||
int32_t tag;
|
||||
int32_t payload;
|
||||
} asBits;
|
||||
#else
|
||||
struct {
|
||||
int32_t payload;
|
||||
int32_t tag;
|
||||
} asBits;
|
||||
#endif
|
||||
|
||||
void* asPtr;
|
||||
double asDouble;
|
||||
} EncodedJSValue;
|
||||
|
||||
EncodedJSValue ValueUndefined = { TagValueUndefined };
|
||||
EncodedJSValue ValueTrue = { TagValueTrue };
|
||||
|
||||
typedef void* JSContext;
|
||||
|
||||
// Bun_FFI_PointerOffsetToArgumentsList is injected into the build
|
||||
// The value is generated in `make sizegen`
|
||||
// The value is 6.
|
||||
// On ARM64_32, the value is something else but it really doesn't matter for our case
|
||||
// However, I don't want this to subtly break amidst future upgrades to JavaScriptCore
|
||||
#define LOAD_ARGUMENTS_FROM_CALL_FRAME \
|
||||
int64_t *argsPtr = (int64_t*)((size_t*)callFrame + Bun_FFI_PointerOffsetToArgumentsList)
|
||||
|
||||
|
||||
#ifdef IS_CALLBACK
|
||||
extern int64_t bun_call(JSContext, void* func, void* thisValue, size_t len, const EncodedJSValue args[], void* exception);
|
||||
JSContext cachedJSContext;
|
||||
void* cachedCallbackFunction;
|
||||
#endif
|
||||
|
||||
static bool JSVALUE_IS_CELL(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static bool JSVALUE_IS_INT32(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static bool JSVALUE_IS_NUMBER(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
|
||||
static uint64_t JSVALUE_TO_UINT64(void* globalObject, EncodedJSValue value) __attribute__((__always_inline__));
|
||||
static int64_t JSVALUE_TO_INT64(EncodedJSValue value) __attribute__((__always_inline__));
|
||||
uint64_t JSVALUE_TO_UINT64_SLOW(void* globalObject, EncodedJSValue value);
|
||||
int64_t JSVALUE_TO_INT64_SLOW(EncodedJSValue value);
|
||||
|
||||
EncodedJSValue UINT64_TO_JSVALUE_SLOW(void* globalObject, uint64_t val);
|
||||
EncodedJSValue INT64_TO_JSVALUE_SLOW(void* globalObject, int64_t val);
|
||||
static EncodedJSValue UINT64_TO_JSVALUE(void* globalObject, uint64_t val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue INT64_TO_JSVALUE(void* globalObject, int64_t val) __attribute__((__always_inline__));
|
||||
|
||||
|
||||
static EncodedJSValue INT32_TO_JSVALUE(int32_t val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue DOUBLE_TO_JSVALUE(double val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue FLOAT_TO_JSVALUE(float val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue BOOLEAN_TO_JSVALUE(bool val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue PTR_TO_JSVALUE(void* ptr) __attribute__((__always_inline__));
|
||||
|
||||
static void* JSVALUE_TO_PTR(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static int32_t JSVALUE_TO_INT32(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static float JSVALUE_TO_FLOAT(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static double JSVALUE_TO_DOUBLE(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static bool JSVALUE_TO_BOOL(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
|
||||
static bool JSVALUE_IS_CELL(EncodedJSValue val) {
|
||||
return !(val.asInt64 & NotCellMask);
|
||||
}
|
||||
|
||||
static bool JSVALUE_IS_INT32(EncodedJSValue val) {
|
||||
return (val.asInt64 & NumberTag) == NumberTag;
|
||||
}
|
||||
|
||||
static bool JSVALUE_IS_NUMBER(EncodedJSValue val) {
|
||||
return val.asInt64 & NumberTag;
|
||||
}
|
||||
|
||||
|
||||
static void* JSVALUE_TO_PTR(EncodedJSValue val) {
|
||||
// must be a double
|
||||
return (void*)(val.asInt64 - DoubleEncodeOffset);
|
||||
}
|
||||
|
||||
static EncodedJSValue PTR_TO_JSVALUE(void* ptr) {
|
||||
EncodedJSValue val;
|
||||
val.asInt64 = (int64_t)ptr + DoubleEncodeOffset;
|
||||
return val;
|
||||
}
|
||||
|
||||
static int32_t JSVALUE_TO_INT32(EncodedJSValue val) {
|
||||
return val.asInt64;
|
||||
}
|
||||
|
||||
static EncodedJSValue INT32_TO_JSVALUE(int32_t val) {
|
||||
EncodedJSValue res;
|
||||
res.asInt64 = NumberTag | (uint32_t)val;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static EncodedJSValue DOUBLE_TO_JSVALUE(double val) {
|
||||
EncodedJSValue res;
|
||||
res.asDouble = val;
|
||||
res.asInt64 += DoubleEncodeOffset;
|
||||
return res;
|
||||
}
|
||||
|
||||
static EncodedJSValue FLOAT_TO_JSVALUE(float val) {
|
||||
return DOUBLE_TO_JSVALUE((double)val);
|
||||
}
|
||||
|
||||
static EncodedJSValue BOOLEAN_TO_JSVALUE(bool val) {
|
||||
EncodedJSValue res;
|
||||
res.asInt64 = val ? TagValueTrue : TagValueFalse;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static double JSVALUE_TO_DOUBLE(EncodedJSValue val) {
|
||||
val.asInt64 -= DoubleEncodeOffset;
|
||||
return val.asDouble;
|
||||
}
|
||||
|
||||
static float JSVALUE_TO_FLOAT(EncodedJSValue val) {
|
||||
return (float)JSVALUE_TO_DOUBLE(val);
|
||||
}
|
||||
|
||||
static bool JSVALUE_TO_BOOL(EncodedJSValue val) {
|
||||
return val.asInt64 == TagValueTrue;
|
||||
}
|
||||
|
||||
|
||||
static uint64_t JSVALUE_TO_UINT64(void* globalObject, EncodedJSValue value) {
|
||||
if (JSVALUE_IS_INT32(value)) {
|
||||
return (uint64_t)JSVALUE_TO_INT32(value);
|
||||
}
|
||||
|
||||
if (JSVALUE_IS_NUMBER(value)) {
|
||||
return (uint64_t)JSVALUE_TO_DOUBLE(value);
|
||||
}
|
||||
|
||||
return JSVALUE_TO_UINT64_SLOW(globalObject, value);
|
||||
}
|
||||
static int64_t JSVALUE_TO_INT64(EncodedJSValue value) {
|
||||
if (JSVALUE_IS_INT32(value)) {
|
||||
return (int64_t)JSVALUE_TO_INT32(value);
|
||||
}
|
||||
|
||||
if (JSVALUE_IS_NUMBER(value)) {
|
||||
return (int64_t)JSVALUE_TO_DOUBLE(value);
|
||||
}
|
||||
|
||||
return JSVALUE_TO_INT64_SLOW(value);
|
||||
}
|
||||
|
||||
static EncodedJSValue UINT64_TO_JSVALUE(void* globalObject, uint64_t val) {
|
||||
if (val < MAX_INT32) {
|
||||
return INT32_TO_JSVALUE((int32_t)val);
|
||||
}
|
||||
|
||||
if (val < MAX_INT52) {
|
||||
return DOUBLE_TO_JSVALUE((double)val);
|
||||
}
|
||||
|
||||
return UINT64_TO_JSVALUE_SLOW(globalObject, val);
|
||||
}
|
||||
|
||||
static EncodedJSValue INT64_TO_JSVALUE(void* globalObject, int64_t val) {
|
||||
if (val >= -MAX_INT32 && val <= MAX_INT32) {
|
||||
return INT32_TO_JSVALUE((int32_t)val);
|
||||
}
|
||||
|
||||
if (val >= -MAX_INT52 && val <= MAX_INT52) {
|
||||
return DOUBLE_TO_JSVALUE((double)val);
|
||||
}
|
||||
|
||||
return INT64_TO_JSVALUE_SLOW(globalObject, val);
|
||||
}
|
||||
|
||||
#ifndef IS_CALLBACK
|
||||
void* JSFunctionCall(void* globalObject, void* callFrame);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// --- Generated Code ---
|
||||
/* --- The Function To Call */
|
||||
float not_a_callback(float arg0);
|
||||
|
||||
|
||||
/* ---- Your Wrapper Function ---- */
|
||||
void* JSFunctionCall(void* globalObject, void* callFrame) {
|
||||
LOAD_ARGUMENTS_FROM_CALL_FRAME;
|
||||
EncodedJSValue arg0;
|
||||
arg0.asInt64 = *argsPtr;
|
||||
float return_value = not_a_callback( JSVALUE_TO_FLOAT(arg0));
|
||||
|
||||
return FLOAT_TO_JSVALUE(return_value).asPtr;
|
||||
}
|
||||
|
||||
538
integration/bunjs-only-snippets/ffi.test.js
Normal file
538
integration/bunjs-only-snippets/ffi.test.js
Normal file
@@ -0,0 +1,538 @@
|
||||
import { describe, it, expect } from "bun:test";
|
||||
import { unsafe } from "bun";
|
||||
//
|
||||
import {
|
||||
native,
|
||||
viewSource,
|
||||
dlopen,
|
||||
CString,
|
||||
ptr,
|
||||
toBuffer,
|
||||
toArrayBuffer,
|
||||
FFIType,
|
||||
callback,
|
||||
CFunction,
|
||||
} from "bun:ffi";
|
||||
|
||||
it("ffi print", async () => {
|
||||
await Bun.write(
|
||||
import.meta.dir + "/ffi.test.fixture.callback.c",
|
||||
viewSource(
|
||||
{
|
||||
returns: "bool",
|
||||
args: ["ptr"],
|
||||
},
|
||||
true
|
||||
)
|
||||
);
|
||||
await Bun.write(
|
||||
import.meta.dir + "/ffi.test.fixture.receiver.c",
|
||||
viewSource(
|
||||
{
|
||||
not_a_callback: {
|
||||
returns: "float",
|
||||
args: ["float"],
|
||||
},
|
||||
},
|
||||
false
|
||||
)[0]
|
||||
);
|
||||
expect(
|
||||
viewSource(
|
||||
{
|
||||
returns: "int8_t",
|
||||
args: [],
|
||||
},
|
||||
true
|
||||
).length > 0
|
||||
).toBe(true);
|
||||
expect(
|
||||
viewSource(
|
||||
{
|
||||
a: {
|
||||
returns: "int8_t",
|
||||
args: [],
|
||||
},
|
||||
},
|
||||
false
|
||||
).length > 0
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
function getTypes(fast) {
|
||||
const int64_t = fast ? "i64_fast" : "int64_t";
|
||||
const uint64_t = fast ? "u64_fast" : "uint64_t";
|
||||
return {
|
||||
returns_true: {
|
||||
returns: "bool",
|
||||
args: [],
|
||||
},
|
||||
returns_false: {
|
||||
returns: "bool",
|
||||
args: [],
|
||||
},
|
||||
returns_42_char: {
|
||||
returns: "char",
|
||||
args: [],
|
||||
},
|
||||
returns_42_float: {
|
||||
returns: "float",
|
||||
args: [],
|
||||
},
|
||||
returns_42_double: {
|
||||
returns: "double",
|
||||
args: [],
|
||||
},
|
||||
returns_42_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
args: [],
|
||||
},
|
||||
returns_neg_42_int8_t: {
|
||||
returns: "int8_t",
|
||||
args: [],
|
||||
},
|
||||
returns_42_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
args: [],
|
||||
},
|
||||
returns_42_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
args: [],
|
||||
},
|
||||
returns_42_uint64_t: {
|
||||
returns: uint64_t,
|
||||
args: [],
|
||||
},
|
||||
returns_neg_42_int16_t: {
|
||||
returns: "int16_t",
|
||||
args: [],
|
||||
},
|
||||
returns_neg_42_int32_t: {
|
||||
returns: "int32_t",
|
||||
args: [],
|
||||
},
|
||||
returns_neg_42_int64_t: {
|
||||
returns: int64_t,
|
||||
args: [],
|
||||
},
|
||||
|
||||
identity_char: {
|
||||
returns: "char",
|
||||
args: ["char"],
|
||||
},
|
||||
identity_float: {
|
||||
returns: "float",
|
||||
args: ["float"],
|
||||
},
|
||||
identity_bool: {
|
||||
returns: "bool",
|
||||
args: ["bool"],
|
||||
},
|
||||
identity_double: {
|
||||
returns: "double",
|
||||
args: ["double"],
|
||||
},
|
||||
identity_int8_t: {
|
||||
returns: "int8_t",
|
||||
args: ["int8_t"],
|
||||
},
|
||||
identity_int16_t: {
|
||||
returns: "int16_t",
|
||||
args: ["int16_t"],
|
||||
},
|
||||
identity_int32_t: {
|
||||
returns: "int32_t",
|
||||
args: ["int32_t"],
|
||||
},
|
||||
identity_int64_t: {
|
||||
returns: int64_t,
|
||||
args: [int64_t],
|
||||
},
|
||||
identity_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
args: ["uint8_t"],
|
||||
},
|
||||
identity_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
args: ["uint16_t"],
|
||||
},
|
||||
identity_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
args: ["uint32_t"],
|
||||
},
|
||||
identity_uint64_t: {
|
||||
returns: uint64_t,
|
||||
args: [uint64_t],
|
||||
},
|
||||
|
||||
add_char: {
|
||||
returns: "char",
|
||||
args: ["char", "char"],
|
||||
},
|
||||
add_float: {
|
||||
returns: "float",
|
||||
args: ["float", "float"],
|
||||
},
|
||||
add_double: {
|
||||
returns: "double",
|
||||
args: ["double", "double"],
|
||||
},
|
||||
add_int8_t: {
|
||||
returns: "int8_t",
|
||||
args: ["int8_t", "int8_t"],
|
||||
},
|
||||
add_int16_t: {
|
||||
returns: "int16_t",
|
||||
args: ["int16_t", "int16_t"],
|
||||
},
|
||||
add_int32_t: {
|
||||
returns: "int32_t",
|
||||
args: ["int32_t", "int32_t"],
|
||||
},
|
||||
add_int64_t: {
|
||||
returns: int64_t,
|
||||
args: [int64_t, int64_t],
|
||||
},
|
||||
add_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
args: ["uint8_t", "uint8_t"],
|
||||
},
|
||||
add_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
args: ["uint16_t", "uint16_t"],
|
||||
},
|
||||
add_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
args: ["uint32_t", "uint32_t"],
|
||||
},
|
||||
|
||||
does_pointer_equal_42_as_int32_t: {
|
||||
returns: "bool",
|
||||
args: ["ptr"],
|
||||
},
|
||||
|
||||
ptr_should_point_to_42_as_int32_t: {
|
||||
returns: "ptr",
|
||||
args: [],
|
||||
},
|
||||
identity_ptr: {
|
||||
returns: "ptr",
|
||||
args: ["ptr"],
|
||||
},
|
||||
add_uint64_t: {
|
||||
returns: uint64_t,
|
||||
args: [uint64_t, uint64_t],
|
||||
},
|
||||
|
||||
cb_identity_true: {
|
||||
returns: "bool",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_false: {
|
||||
returns: "bool",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_42_char: {
|
||||
returns: "char",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_42_float: {
|
||||
returns: "float",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_42_double: {
|
||||
returns: "double",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_42_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_neg_42_int8_t: {
|
||||
returns: "int8_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_42_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_42_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_42_uint64_t: {
|
||||
returns: uint64_t,
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_neg_42_int16_t: {
|
||||
returns: "int16_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_neg_42_int32_t: {
|
||||
returns: "int32_t",
|
||||
args: ["ptr"],
|
||||
},
|
||||
cb_identity_neg_42_int64_t: {
|
||||
returns: int64_t,
|
||||
args: ["ptr"],
|
||||
},
|
||||
|
||||
return_a_function_ptr_to_function_that_returns_true: {
|
||||
returns: "ptr",
|
||||
args: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function ffiRunner(types) {
|
||||
const {
|
||||
symbols: {
|
||||
returns_true,
|
||||
returns_false,
|
||||
return_a_function_ptr_to_function_that_returns_true,
|
||||
returns_42_char,
|
||||
returns_42_float,
|
||||
returns_42_double,
|
||||
returns_42_uint8_t,
|
||||
returns_neg_42_int8_t,
|
||||
returns_42_uint16_t,
|
||||
returns_42_uint32_t,
|
||||
returns_42_uint64_t,
|
||||
returns_neg_42_int16_t,
|
||||
returns_neg_42_int32_t,
|
||||
returns_neg_42_int64_t,
|
||||
identity_char,
|
||||
identity_float,
|
||||
identity_bool,
|
||||
identity_double,
|
||||
identity_int8_t,
|
||||
identity_int16_t,
|
||||
identity_int32_t,
|
||||
identity_int64_t,
|
||||
identity_uint8_t,
|
||||
identity_uint16_t,
|
||||
identity_uint32_t,
|
||||
identity_uint64_t,
|
||||
add_char,
|
||||
add_float,
|
||||
add_double,
|
||||
add_int8_t,
|
||||
add_int16_t,
|
||||
add_int32_t,
|
||||
add_int64_t,
|
||||
add_uint8_t,
|
||||
add_uint16_t,
|
||||
identity_ptr,
|
||||
add_uint32_t,
|
||||
add_uint64_t,
|
||||
does_pointer_equal_42_as_int32_t,
|
||||
ptr_should_point_to_42_as_int32_t,
|
||||
cb_identity_true,
|
||||
cb_identity_false,
|
||||
cb_identity_42_char,
|
||||
cb_identity_42_float,
|
||||
cb_identity_42_double,
|
||||
cb_identity_42_uint8_t,
|
||||
cb_identity_neg_42_int8_t,
|
||||
cb_identity_42_uint16_t,
|
||||
cb_identity_42_uint32_t,
|
||||
cb_identity_42_uint64_t,
|
||||
cb_identity_neg_42_int16_t,
|
||||
cb_identity_neg_42_int32_t,
|
||||
cb_identity_neg_42_int64_t,
|
||||
},
|
||||
close,
|
||||
} = dlopen("/tmp/bun-ffi-test.dylib", types);
|
||||
|
||||
expect(returns_true()).toBe(true);
|
||||
|
||||
expect(returns_false()).toBe(false);
|
||||
|
||||
expect(returns_42_char()).toBe(42);
|
||||
expect(returns_42_uint64_t().valueOf()).toBe(42);
|
||||
|
||||
expect(Math.fround(returns_42_float())).toBe(Math.fround(42.41999804973602));
|
||||
expect(returns_42_double()).toBe(42.42);
|
||||
expect(returns_42_uint8_t()).toBe(42);
|
||||
expect(returns_neg_42_int8_t()).toBe(-42);
|
||||
expect(returns_42_uint16_t()).toBe(42);
|
||||
expect(returns_42_uint32_t()).toBe(42);
|
||||
expect(returns_42_uint64_t()).toBe(42);
|
||||
expect(returns_neg_42_int16_t()).toBe(-42);
|
||||
expect(returns_neg_42_int32_t()).toBe(-42);
|
||||
expect(identity_int32_t(10)).toBe(10);
|
||||
expect(returns_neg_42_int64_t()).toBe(-42);
|
||||
|
||||
expect(identity_char(10)).toBe(10);
|
||||
|
||||
expect(identity_float(10.199999809265137)).toBe(10.199999809265137);
|
||||
|
||||
expect(identity_bool(true)).toBe(true);
|
||||
|
||||
expect(identity_bool(false)).toBe(false);
|
||||
expect(identity_double(10.100000000000364)).toBe(10.100000000000364);
|
||||
|
||||
expect(identity_int8_t(10)).toBe(10);
|
||||
expect(identity_int16_t(10)).toBe(10);
|
||||
expect(identity_int64_t(10)).toBe(10);
|
||||
expect(identity_uint8_t(10)).toBe(10);
|
||||
expect(identity_uint16_t(10)).toBe(10);
|
||||
expect(identity_uint32_t(10)).toBe(10);
|
||||
expect(identity_uint64_t(10)).toBe(10);
|
||||
|
||||
var bigArray = new BigUint64Array(8);
|
||||
new Uint8Array(bigArray.buffer).fill(255);
|
||||
var bigIntArray = new BigInt64Array(bigArray.buffer);
|
||||
|
||||
expect(identity_uint64_t(bigArray[0])).toBe(bigArray[0]);
|
||||
expect(identity_uint64_t(bigArray[0] - BigInt(1))).toBe(
|
||||
bigArray[0] - BigInt(1)
|
||||
);
|
||||
expect(add_uint64_t(BigInt(-1) * bigArray[0], bigArray[0])).toBe(0);
|
||||
expect(add_uint64_t(BigInt(-1) * bigArray[0] + BigInt(10), bigArray[0])).toBe(
|
||||
10
|
||||
);
|
||||
expect(identity_uint64_t(0)).toBe(0);
|
||||
expect(identity_uint64_t(100)).toBe(100);
|
||||
expect(identity_uint64_t(BigInt(100))).toBe(100);
|
||||
expect(identity_int64_t(bigIntArray[0])).toBe(bigIntArray[0]);
|
||||
expect(identity_int64_t(bigIntArray[0] - BigInt(1))).toBe(
|
||||
bigIntArray[0] - BigInt(1)
|
||||
);
|
||||
|
||||
expect(add_char(1, 1)).toBe(2);
|
||||
expect(add_float(2.4, 2.8)).toBe(Math.fround(5.2));
|
||||
expect(add_double(4.2, 0.1)).toBe(4.3);
|
||||
expect(add_int8_t(1, 1)).toBe(2);
|
||||
expect(add_int16_t(1, 1)).toBe(2);
|
||||
expect(add_int32_t(1, 1)).toBe(2);
|
||||
expect(add_int64_t(1, 1)).toBe(2);
|
||||
expect(add_uint8_t(1, 1)).toBe(2);
|
||||
expect(add_uint16_t(1, 1)).toBe(2);
|
||||
expect(add_uint32_t(1, 1)).toBe(2);
|
||||
|
||||
const cptr = ptr_should_point_to_42_as_int32_t();
|
||||
expect(cptr != 0).toBe(true);
|
||||
expect(typeof cptr === "number").toBe(true);
|
||||
expect(does_pointer_equal_42_as_int32_t(cptr)).toBe(true);
|
||||
const buffer = toBuffer(cptr, 0, 4);
|
||||
expect(buffer.readInt32(0)).toBe(42);
|
||||
expect(new DataView(toArrayBuffer(cptr, 0, 4), 0, 4).getInt32(0, true)).toBe(
|
||||
42
|
||||
);
|
||||
expect(ptr(buffer)).toBe(cptr);
|
||||
expect(new CString(cptr, 0, 1).toString()).toBe("*");
|
||||
expect(identity_ptr(cptr)).toBe(cptr);
|
||||
const second_ptr = ptr(new Buffer(8));
|
||||
expect(identity_ptr(second_ptr)).toBe(second_ptr);
|
||||
|
||||
var myCFunction = new CFunction({
|
||||
ptr: return_a_function_ptr_to_function_that_returns_true(),
|
||||
returns: "bool",
|
||||
});
|
||||
expect(myCFunction()).toBe(true);
|
||||
|
||||
// function identityBool() {
|
||||
// return true;
|
||||
// }
|
||||
// globalThis.identityBool = identityBool;
|
||||
|
||||
// const first = native.callback(
|
||||
// {
|
||||
// returns: "bool",
|
||||
// },
|
||||
// identityBool
|
||||
// );
|
||||
// expect(
|
||||
// cb_identity_true()
|
||||
// ).toBe(true);
|
||||
|
||||
// expect(cb_identity_true(first)).toBe(true);
|
||||
|
||||
// expect(
|
||||
// cb_identity_false(
|
||||
// callback(
|
||||
// {
|
||||
// returns: "bool",
|
||||
// },
|
||||
// () => false
|
||||
// )
|
||||
// )
|
||||
// ).toBe(false);
|
||||
|
||||
// expect(
|
||||
// cb_identity_42_char(
|
||||
// callback(
|
||||
// {
|
||||
// returns: "char",
|
||||
// },
|
||||
// () => 42
|
||||
// )
|
||||
// )
|
||||
// ).toBe(42);
|
||||
// expect(
|
||||
// cb_identity_42_uint8_t(
|
||||
// callback(
|
||||
// {
|
||||
// returns: "uint8_t",
|
||||
// },
|
||||
// () => 42
|
||||
// )
|
||||
// )
|
||||
// ).toBe(42);
|
||||
|
||||
// cb_identity_neg_42_int8_t(
|
||||
// callback(
|
||||
// {
|
||||
// returns: "int8_t",
|
||||
// },
|
||||
// () => -42
|
||||
// )
|
||||
// ).toBe(-42);
|
||||
|
||||
// cb_identity_42_uint16_t(
|
||||
// callback(
|
||||
// {
|
||||
// returns: "uint16_t",
|
||||
// },
|
||||
// () => 42
|
||||
// )
|
||||
// ).toBe(42);
|
||||
|
||||
// cb_identity_42_uint32_t(
|
||||
// callback(
|
||||
// {
|
||||
// returns: "uint32_t",
|
||||
// },
|
||||
// () => 42
|
||||
// )
|
||||
// ).toBe(42);
|
||||
|
||||
// cb_identity_neg_42_int16_t(
|
||||
// callback(
|
||||
// {
|
||||
// returns: "int16_t",
|
||||
// },
|
||||
// () => -42
|
||||
// )
|
||||
// ).toBe(-42);
|
||||
|
||||
// cb_identity_neg_42_int32_t(
|
||||
// callback(
|
||||
// {
|
||||
// returns: "int32_t",
|
||||
// },
|
||||
// () => -42
|
||||
// )
|
||||
// ).toBe(-42);
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
it("run ffi fast", () => {
|
||||
ffiRunner(getTypes(true));
|
||||
});
|
||||
|
||||
it("run ffi", () => {
|
||||
ffiRunner(getTypes(false));
|
||||
});
|
||||
@@ -1,10 +1,16 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { gc } from "bun";
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import {
|
||||
mkdirSync,
|
||||
closeSync,
|
||||
existsSync,
|
||||
readFileSync,
|
||||
writeFileSync,
|
||||
mkdirSync,
|
||||
openSync,
|
||||
readdirSync,
|
||||
readFile,
|
||||
readFileSync,
|
||||
readSync,
|
||||
writeFileSync,
|
||||
writeSync,
|
||||
} from "node:fs";
|
||||
|
||||
const Buffer = globalThis.Buffer || Uint8Array;
|
||||
@@ -24,6 +30,131 @@ describe("mkdirSync", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("readdirSync on import.meta.dir", () => {
|
||||
const dirs = readdirSync(import.meta.dir);
|
||||
expect(dirs.length > 0).toBe(true);
|
||||
var match = false;
|
||||
gc(true);
|
||||
for (let i = 0; i < dirs.length; i++) {
|
||||
if (dirs[i] === import.meta.file) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
gc(true);
|
||||
expect(match).toBe(true);
|
||||
});
|
||||
|
||||
it("readdirSync on import.meta.dir with trailing slash", () => {
|
||||
const dirs = readdirSync(import.meta.dir + "/");
|
||||
expect(dirs.length > 0).toBe(true);
|
||||
// this file should exist in it
|
||||
var match = false;
|
||||
for (let i = 0; i < dirs.length; i++) {
|
||||
if (dirs[i] === import.meta.file) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
expect(match).toBe(true);
|
||||
});
|
||||
|
||||
it("readdirSync works on empty directories", () => {
|
||||
const path = `/tmp/fs-test-empty-dir-${(
|
||||
Math.random() * 100000 +
|
||||
100
|
||||
).toString(32)}`;
|
||||
mkdirSync(path, { recursive: true });
|
||||
expect(readdirSync(path).length).toBe(0);
|
||||
});
|
||||
|
||||
it("readdirSync works on directories with under 32 files", () => {
|
||||
const path = `/tmp/fs-test-one-dir-${(Math.random() * 100000 + 100).toString(
|
||||
32
|
||||
)}`;
|
||||
mkdirSync(path, { recursive: true });
|
||||
writeFileSync(`${path}/a`, "a");
|
||||
const results = readdirSync(path);
|
||||
expect(results.length).toBe(1);
|
||||
expect(results[0]).toBe("a");
|
||||
});
|
||||
|
||||
it("readdirSync throws when given a file path", () => {
|
||||
try {
|
||||
readdirSync(import.meta.path);
|
||||
throw new Error("should not get here");
|
||||
} catch (exception) {
|
||||
expect(exception.name).toBe("ENOTDIR");
|
||||
}
|
||||
});
|
||||
|
||||
it("readdirSync throws when given a path that doesn't exist", () => {
|
||||
try {
|
||||
readdirSync(import.meta.path + "/does-not-exist/really");
|
||||
throw new Error("should not get here");
|
||||
} catch (exception) {
|
||||
expect(exception.name).toBe("ENOTDIR");
|
||||
}
|
||||
});
|
||||
|
||||
it("readdirSync throws when given a file path with trailing slash", () => {
|
||||
try {
|
||||
readdirSync(import.meta.path + "/");
|
||||
throw new Error("should not get here");
|
||||
} catch (exception) {
|
||||
expect(exception.name).toBe("ENOTDIR");
|
||||
}
|
||||
});
|
||||
|
||||
describe("readSync", () => {
|
||||
const firstFourBytes = new Uint32Array(
|
||||
new TextEncoder().encode("File").buffer
|
||||
)[0];
|
||||
it("works with a position set to 0", () => {
|
||||
const fd = openSync(import.meta.dir + "/readFileSync.txt", "r");
|
||||
const four = new Uint8Array(4);
|
||||
|
||||
{
|
||||
const count = readSync(fd, four, 0, 4, 0);
|
||||
const u32 = new Uint32Array(four.buffer)[0];
|
||||
expect(u32).toBe(firstFourBytes);
|
||||
expect(count).toBe(4);
|
||||
}
|
||||
closeSync(fd);
|
||||
});
|
||||
it("works without position set", () => {
|
||||
const fd = openSync(import.meta.dir + "/readFileSync.txt", "r");
|
||||
const four = new Uint8Array(4);
|
||||
{
|
||||
const count = readSync(fd, four);
|
||||
const u32 = new Uint32Array(four.buffer)[0];
|
||||
expect(u32).toBe(firstFourBytes);
|
||||
expect(count).toBe(4);
|
||||
}
|
||||
closeSync(fd);
|
||||
});
|
||||
});
|
||||
|
||||
describe("writeSync", () => {
|
||||
it("works with a position set to 0", () => {
|
||||
const fd = openSync(import.meta.dir + "/writeFileSync.txt", "w+");
|
||||
const four = new Uint8Array(4);
|
||||
|
||||
{
|
||||
const count = writeSync(fd, new TextEncoder().encode("File"), 0, 4, 0);
|
||||
expect(count).toBe(4);
|
||||
}
|
||||
closeSync(fd);
|
||||
});
|
||||
it("works without position set", () => {
|
||||
const fd = openSync(import.meta.dir + "/writeFileSync.txt", "w+");
|
||||
const four = new Uint8Array(4);
|
||||
{
|
||||
const count = writeSync(fd, new TextEncoder().encode("File"));
|
||||
expect(count).toBe(4);
|
||||
}
|
||||
closeSync(fd);
|
||||
});
|
||||
});
|
||||
|
||||
describe("readFileSync", () => {
|
||||
it("works", () => {
|
||||
const text = readFileSync(import.meta.dir + "/readFileSync.txt", "utf8");
|
||||
|
||||
14
integration/bunjs-only-snippets/gc.js
Normal file
14
integration/bunjs-only-snippets/gc.js
Normal file
@@ -0,0 +1,14 @@
|
||||
export function gc() {
|
||||
Bun.gc(true);
|
||||
}
|
||||
|
||||
// we must ensure that finalizers are run
|
||||
// so that the reference-counting logic is exercised
|
||||
export function gcTick(trace = false) {
|
||||
trace && console.trace("");
|
||||
|
||||
gc();
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, 0);
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { describe, it, expect } from "bun:test";
|
||||
import { gcTick } from "./gc";
|
||||
|
||||
var setTimeoutAsync = (fn, delay) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -14,6 +15,7 @@ var setTimeoutAsync = (fn, delay) => {
|
||||
|
||||
describe("HTMLRewriter", () => {
|
||||
it("HTMLRewriter: async replacement", async () => {
|
||||
await gcTick();
|
||||
const res = new HTMLRewriter()
|
||||
.on("div", {
|
||||
async element(element) {
|
||||
@@ -23,7 +25,9 @@ describe("HTMLRewriter", () => {
|
||||
},
|
||||
})
|
||||
.transform(new Response("<div>example.com</div>"));
|
||||
await gcTick();
|
||||
expect(await res.text()).toBe("<div><span>replace</span></div>");
|
||||
await gcTick();
|
||||
});
|
||||
|
||||
it("supports element handlers", async () => {
|
||||
|
||||
@@ -1,7 +1,29 @@
|
||||
import { it, expect } from "bun:test";
|
||||
import * as Module from "node:module";
|
||||
import sync from "./require-json.json";
|
||||
|
||||
const { path, dir } = import.meta;
|
||||
|
||||
it("import.meta.resolveSync", () => {
|
||||
expect(
|
||||
import.meta.resolveSync("./" + import.meta.file, import.meta.path)
|
||||
).toBe(path);
|
||||
const require = Module.createRequire(import.meta.path);
|
||||
expect(require.resolve(import.meta.path)).toBe(path);
|
||||
expect(require.resolve("./" + import.meta.file)).toBe(path);
|
||||
|
||||
// check it works with URL objects
|
||||
expect(
|
||||
Module.createRequire(new URL(import.meta.url)).resolve(import.meta.path)
|
||||
).toBe(import.meta.path);
|
||||
});
|
||||
|
||||
it("import.meta.require", () => {
|
||||
expect(import.meta.require("./require-json.json").hello).toBe(sync.hello);
|
||||
const require = Module.createRequire(import.meta.path);
|
||||
expect(require("./require-json.json").hello).toBe(sync.hello);
|
||||
});
|
||||
|
||||
it("import.meta.dir", () => {
|
||||
expect(dir.endsWith("/bun/integration/bunjs-only-snippets")).toBe(true);
|
||||
});
|
||||
|
||||
3
integration/bunjs-only-snippets/inline.macro.js
Normal file
3
integration/bunjs-only-snippets/inline.macro.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export function whatDidIPass(expr, ctx) {
|
||||
return ctx;
|
||||
}
|
||||
@@ -57,16 +57,16 @@ it("inspect", () => {
|
||||
str += "123";
|
||||
}
|
||||
expect(Bun.inspect(str)).toBe(str);
|
||||
expect(Bun.inspect(new Headers())).toBe("Headers (0 KB) {}");
|
||||
// expect(Bun.inspect(new Headers())).toBe("Headers (0 KB) {}");
|
||||
expect(Bun.inspect(new Response()).length > 0).toBe(true);
|
||||
|
||||
expect(
|
||||
JSON.stringify(
|
||||
new Headers({
|
||||
hi: "ok",
|
||||
})
|
||||
)
|
||||
).toBe('{"hi":"ok"}');
|
||||
// expect(
|
||||
// JSON.stringify(
|
||||
// new Headers({
|
||||
// hi: "ok",
|
||||
// })
|
||||
// )
|
||||
// ).toBe('{"hi":"ok"}');
|
||||
expect(Bun.inspect(new Set())).toBe("Set {}");
|
||||
expect(Bun.inspect(new Map())).toBe("Map {}");
|
||||
expect(Bun.inspect(new Map([["foo", "bar"]]))).toBe(
|
||||
|
||||
@@ -1,49 +1,69 @@
|
||||
import { describe, it, expect } from "bun:test";
|
||||
import { gcTick } from "./gc";
|
||||
|
||||
const path = `/tmp/bun-mmap-test_${Math.random()}.txt`;
|
||||
describe("Bun.mmap", async () => {
|
||||
await gcTick();
|
||||
const path = `/tmp/bun-mmap-test_${Math.random()}.txt`;
|
||||
await gcTick();
|
||||
await Bun.write(path, "hello");
|
||||
await gcTick();
|
||||
|
||||
await Bun.write(path, "hello");
|
||||
it("mmap finalizer", async () => {
|
||||
let map = Bun.mmap(path);
|
||||
await gcTick();
|
||||
const map2 = Bun.mmap(path);
|
||||
|
||||
it("mmap finalizer", async () => {
|
||||
let map = Bun.mmap(path);
|
||||
const map2 = Bun.mmap(path);
|
||||
map = null;
|
||||
await gcTick();
|
||||
});
|
||||
|
||||
map = null;
|
||||
Bun.gc(true);
|
||||
await new Promise((resolve) => setTimeout(resolve, 1));
|
||||
});
|
||||
|
||||
it("mmap passed to other syscalls", async () => {
|
||||
const map = Bun.mmap(path);
|
||||
await Bun.write(path + "1", map);
|
||||
const text = await (await Bun.file(path + "1")).text();
|
||||
|
||||
expect(text).toBe(new TextDecoder().decode(map));
|
||||
});
|
||||
|
||||
it("mmap sync", async () => {
|
||||
const map = Bun.mmap(path);
|
||||
const map2 = Bun.mmap(path);
|
||||
|
||||
const old = map[0];
|
||||
|
||||
map[0] = 0;
|
||||
expect(map2[0]).toBe(0);
|
||||
|
||||
map2[0] = old;
|
||||
expect(map[0]).toBe(old);
|
||||
|
||||
await Bun.write(path, "olleh");
|
||||
expect(new TextDecoder().decode(map)).toBe("olleh");
|
||||
});
|
||||
|
||||
it("mmap private", () => {
|
||||
const map = Bun.mmap(path, { shared: true });
|
||||
const map2 = Bun.mmap(path, { shared: false });
|
||||
|
||||
const old = map[0];
|
||||
|
||||
map2[0] = 0;
|
||||
expect(map2[0]).toBe(0);
|
||||
expect(map[0]).toBe(old);
|
||||
it("mmap passed to other syscalls", async () => {
|
||||
const map = Bun.mmap(path);
|
||||
await gcTick();
|
||||
await Bun.write(path + "1", map);
|
||||
await gcTick();
|
||||
const text = await (await Bun.file(path + "1")).text();
|
||||
await gcTick();
|
||||
|
||||
expect(text).toBe(new TextDecoder().decode(map));
|
||||
});
|
||||
|
||||
it("mmap sync", async () => {
|
||||
const map = Bun.mmap(path);
|
||||
await gcTick();
|
||||
const map2 = Bun.mmap(path);
|
||||
await gcTick();
|
||||
|
||||
const old = map[0];
|
||||
await gcTick();
|
||||
map[0] = 0;
|
||||
await gcTick();
|
||||
expect(map2[0]).toBe(0);
|
||||
|
||||
map2[0] = old;
|
||||
await gcTick();
|
||||
expect(map[0]).toBe(old);
|
||||
await gcTick();
|
||||
await Bun.write(path, "olleh");
|
||||
await gcTick();
|
||||
expect(new TextDecoder().decode(map)).toBe("olleh");
|
||||
await gcTick();
|
||||
});
|
||||
|
||||
it("mmap private", async () => {
|
||||
await gcTick();
|
||||
const map = Bun.mmap(path, { shared: true });
|
||||
await gcTick();
|
||||
const map2 = Bun.mmap(path, { shared: false });
|
||||
await gcTick();
|
||||
const old = map[0];
|
||||
|
||||
await gcTick();
|
||||
map2[0] = 0;
|
||||
await gcTick();
|
||||
expect(map2[0]).toBe(0);
|
||||
await gcTick();
|
||||
expect(map[0]).toBe(old);
|
||||
await gcTick();
|
||||
});
|
||||
});
|
||||
|
||||
18
integration/bunjs-only-snippets/performance.test.js
Normal file
18
integration/bunjs-only-snippets/performance.test.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { expect, it } from "bun:test";
|
||||
|
||||
it("performance.now() should be monotonic", () => {
|
||||
const first = performance.now();
|
||||
const second = performance.now();
|
||||
const third = performance.now();
|
||||
const fourth = performance.now();
|
||||
const fifth = performance.now();
|
||||
const sixth = performance.now();
|
||||
expect(first < second).toBe(true);
|
||||
expect(second < third).toBe(true);
|
||||
expect(third < fourth).toBe(true);
|
||||
expect(fourth < fifth).toBe(true);
|
||||
expect(fifth < sixth).toBe(true);
|
||||
expect(Bun.nanoseconds() > 0).toBe(true);
|
||||
expect(Bun.nanoseconds() > sixth).toBe(true);
|
||||
expect(typeof Bun.nanoseconds() === "number").toBe(true);
|
||||
});
|
||||
3
integration/bunjs-only-snippets/require-json.json
Normal file
3
integration/bunjs-only-snippets/require-json.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"hello": -123
|
||||
}
|
||||
@@ -3,46 +3,46 @@ import { mkdirSync, writeFileSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
it("import.meta.resolve", async () => {
|
||||
expect(await import.meta.resolve("./resolve.test.js")).toBe(import.meta.url);
|
||||
expect(await import.meta.resolve("./resolve.test.js")).toBe(import.meta.path);
|
||||
|
||||
expect(await import.meta.resolve("./resolve.test.js", import.meta.url)).toBe(
|
||||
import.meta.url
|
||||
expect(await import.meta.resolve("./resolve.test.js", import.meta.path)).toBe(
|
||||
import.meta.path
|
||||
);
|
||||
|
||||
expect(
|
||||
// optional second param can be any path, including a dir
|
||||
await import.meta.resolve(
|
||||
"./bunjs-only-snippets/resolve.test.js",
|
||||
join(import.meta.url, "../")
|
||||
join(import.meta.path, "../")
|
||||
)
|
||||
).toBe(import.meta.url);
|
||||
).toBe(import.meta.path);
|
||||
|
||||
// can be a package path
|
||||
expect((await import.meta.resolve("react", import.meta.url)).length > 0).toBe(
|
||||
true
|
||||
);
|
||||
expect(
|
||||
(await import.meta.resolve("react", import.meta.path)).length > 0
|
||||
).toBe(true);
|
||||
|
||||
// file extensions are optional
|
||||
expect(await import.meta.resolve("./resolve.test")).toBe(import.meta.url);
|
||||
expect(await import.meta.resolve("./resolve.test")).toBe(import.meta.path);
|
||||
|
||||
// works with tsconfig.json "paths"
|
||||
expect(await import.meta.resolve("foo/bar")).toBe(
|
||||
join(import.meta.url, "../baz.js")
|
||||
join(import.meta.path, "../baz.js")
|
||||
);
|
||||
|
||||
// works with package.json "exports"
|
||||
writePackageJSONExportsFixture();
|
||||
expect(await import.meta.resolve("package-json-exports/baz")).toBe(
|
||||
join(import.meta.url, "../node_modules/package-json-exports/foo/bar.js")
|
||||
join(import.meta.path, "../node_modules/package-json-exports/foo/bar.js")
|
||||
);
|
||||
|
||||
// works with TypeScript compiler edgecases like:
|
||||
// - If the file ends with .js and it doesn't exist, try again with .ts and .tsx
|
||||
expect(await import.meta.resolve("./resolve-typescript-file.js")).toBe(
|
||||
join(import.meta.url, "../resolve-typescript-file.tsx")
|
||||
join(import.meta.path, "../resolve-typescript-file.tsx")
|
||||
);
|
||||
expect(await import.meta.resolve("./resolve-typescript-file.tsx")).toBe(
|
||||
join(import.meta.url, "../resolve-typescript-file.tsx")
|
||||
join(import.meta.path, "../resolve-typescript-file.tsx")
|
||||
);
|
||||
|
||||
// throws a ResolveError on failure
|
||||
@@ -51,7 +51,7 @@ it("import.meta.resolve", async () => {
|
||||
throw new Error("Test failed");
|
||||
} catch (exception) {
|
||||
expect(exception instanceof ResolveError).toBe(true);
|
||||
expect(exception.referrer).toBe(import.meta.url);
|
||||
expect(exception.referrer).toBe(import.meta.path);
|
||||
expect(exception.name).toBe("ResolveError");
|
||||
}
|
||||
});
|
||||
@@ -60,14 +60,14 @@ it("import.meta.resolve", async () => {
|
||||
// and expects a directory instead of a filepath
|
||||
it("Bun.resolve", async () => {
|
||||
expect(await Bun.resolve("./resolve.test.js", import.meta.dir)).toBe(
|
||||
import.meta.url
|
||||
import.meta.path
|
||||
);
|
||||
});
|
||||
|
||||
// synchronous
|
||||
it("Bun.resolveSync", () => {
|
||||
expect(Bun.resolveSync("./resolve.test.js", import.meta.dir)).toBe(
|
||||
import.meta.url
|
||||
import.meta.path
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
import fs from "fs";
|
||||
import { it, expect } from "bun:test";
|
||||
import path from "path";
|
||||
|
||||
function gc() {
|
||||
Bun.gc(true);
|
||||
}
|
||||
|
||||
// we must ensure that finalizers are run
|
||||
// so that the reference-counting logic is exercised
|
||||
function gcTick() {
|
||||
gc();
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, 0);
|
||||
});
|
||||
}
|
||||
import { gcTick } from "./gc";
|
||||
|
||||
it("Bun.file not found returns ENOENT", async () => {
|
||||
try {
|
||||
@@ -34,7 +22,7 @@ it("Bun.write('out.txt', 'string')", async () => {
|
||||
} catch (e) {}
|
||||
}
|
||||
await gcTick();
|
||||
await Bun.write("/tmp/out.txt", "string");
|
||||
expect(await Bun.write("/tmp/out.txt", "string")).toBe("string".length);
|
||||
await gcTick();
|
||||
const out = Bun.file("/tmp/out.txt");
|
||||
await gcTick();
|
||||
@@ -81,7 +69,7 @@ it("Bun.file -> Bun.file", async () => {
|
||||
const file = path.join(import.meta.dir, "fetch.js.txt");
|
||||
await gcTick();
|
||||
const text = fs.readFileSync(file, "utf8");
|
||||
fs.writeFileSync("/tmp/fetch.js.in", text, { mode: 0644 });
|
||||
fs.writeFileSync("/tmp/fetch.js.in", text);
|
||||
await gcTick();
|
||||
{
|
||||
const result = await Bun.write(
|
||||
@@ -119,7 +107,7 @@ it("Bun.file", async () => {
|
||||
});
|
||||
|
||||
it("Bun.file as a Blob", async () => {
|
||||
const filePath = path.join(import.meta.url, "../fetch.js.txt");
|
||||
const filePath = path.join(import.meta.path, "../fetch.js.txt");
|
||||
const fixture = fs.readFileSync(filePath, "utf8");
|
||||
// this is a Blob object with the same interface as the one returned by fetch
|
||||
// internally, instead of a byte array, it stores the file path!
|
||||
@@ -182,6 +170,7 @@ it("Bun.file -> Response", async () => {
|
||||
await gcTick();
|
||||
const resp = await fetch("https://example.com");
|
||||
await gcTick();
|
||||
|
||||
expect(await Bun.write("/tmp/fetch.js.out", resp)).toBe(text.length);
|
||||
await gcTick();
|
||||
expect(await Bun.file("/tmp/fetch.js.out").text()).toBe(text);
|
||||
@@ -201,3 +190,29 @@ it("Response -> Bun.file -> Response -> text", async () => {
|
||||
expect(await response2.text()).toBe(text);
|
||||
await gcTick();
|
||||
});
|
||||
|
||||
// If you write nothing to a file, it shouldn't modify it
|
||||
// If you want to truncate a file, it should be more explicit
|
||||
it("Bun.write('output.html', '')", async () => {
|
||||
await Bun.write("/tmp/output.html", "lalalala");
|
||||
expect(await Bun.write("/tmp/output.html", "")).toBe(0);
|
||||
expect(await Bun.file("/tmp/output.html").text()).toBe("lalalala");
|
||||
});
|
||||
|
||||
// Since Bun.file is resolved lazily, this needs to specifically be checked
|
||||
it("Bun.write('output.html', HTMLRewriter.transform(Bun.file)))", async () => {
|
||||
var rewriter = new HTMLRewriter();
|
||||
rewriter.on("div", {
|
||||
element(element) {
|
||||
element.setInnerContent("<blink>it worked!</blink>", { html: true });
|
||||
},
|
||||
});
|
||||
await Bun.write("/tmp/html-rewriter.txt.js", "<div>hello</div>");
|
||||
var input = new Response(Bun.file("/tmp/html-rewriter.txt.js"));
|
||||
var output = rewriter.transform(input);
|
||||
const outpath = `/tmp/html-rewriter.${Date.now()}.html`;
|
||||
await Bun.write(outpath, output);
|
||||
expect(await Bun.file(outpath).text()).toBe(
|
||||
"<div><blink>it worked!</blink></div>"
|
||||
);
|
||||
});
|
||||
|
||||
82
integration/bunjs-only-snippets/serve.test.ts
Normal file
82
integration/bunjs-only-snippets/serve.test.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { file, serve } from "bun";
|
||||
import { expect, it } from "bun:test";
|
||||
import { readFileSync } from "fs";
|
||||
import { resolve } from "path";
|
||||
|
||||
var port = 40000;
|
||||
|
||||
it("should work for a hello world", async () => {
|
||||
const server = serve({
|
||||
port: port++,
|
||||
fetch(req) {
|
||||
return new Response(`Hello, world!`);
|
||||
},
|
||||
});
|
||||
const response = await fetch(`http://localhost:${server.port}`);
|
||||
expect(await response.text()).toBe("Hello, world!");
|
||||
server.stop();
|
||||
});
|
||||
|
||||
it("should work for a file", async () => {
|
||||
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
|
||||
const textToExpect = readFileSync(fixture, "utf-8");
|
||||
|
||||
const server = serve({
|
||||
port: port++,
|
||||
fetch(req) {
|
||||
return new Response(file(fixture));
|
||||
},
|
||||
});
|
||||
const response = await fetch(`http://localhost:${server.port}`);
|
||||
expect(await response.text()).toBe(textToExpect);
|
||||
server.stop();
|
||||
});
|
||||
|
||||
it("fetch should work with headers", async () => {
|
||||
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
|
||||
|
||||
const server = serve({
|
||||
port: port++,
|
||||
fetch(req) {
|
||||
if (req.headers.get("X-Foo") !== "bar") {
|
||||
return new Response("X-Foo header not set", { status: 500 });
|
||||
}
|
||||
return new Response(file(fixture), {
|
||||
headers: { "X-Both-Ways": "1" },
|
||||
});
|
||||
},
|
||||
});
|
||||
const response = await fetch(`http://localhost:${server.port}`, {
|
||||
headers: {
|
||||
"X-Foo": "bar",
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers.get("X-Both-Ways")).toBe("1");
|
||||
server.stop();
|
||||
});
|
||||
|
||||
var count = 200;
|
||||
it(`should work for a file ${count} times`, async () => {
|
||||
const fixture = resolve(import.meta.dir, "./fetch.js.txt");
|
||||
const textToExpect = readFileSync(fixture, "utf-8");
|
||||
var ran = 0;
|
||||
const server = serve({
|
||||
port: port++,
|
||||
async fetch(req) {
|
||||
return new Response(file(fixture));
|
||||
},
|
||||
});
|
||||
|
||||
// this gets stuck if run about 200 times awaiting all the promises
|
||||
// when the promises are run altogether, instead of one at a time
|
||||
// it's hard to say if this only happens here due to some weird stuff with the test runner
|
||||
// or if it's "real" issue
|
||||
for (let i = 0; i < count; i++) {
|
||||
const response = await fetch(`http://localhost:${server.port}`);
|
||||
expect(await response.text()).toBe(textToExpect);
|
||||
}
|
||||
|
||||
server.stop();
|
||||
});
|
||||
@@ -0,0 +1,74 @@
|
||||
const template = (
|
||||
<svg width="400" height="180">
|
||||
<rect
|
||||
stroke-width="2"
|
||||
x="50"
|
||||
y="20"
|
||||
rx="20"
|
||||
ry="20"
|
||||
width="150"
|
||||
height="150"
|
||||
style="fill:red;stroke:black;stroke-width:5;opacity:0.5"
|
||||
/>
|
||||
<linearGradient gradientTransform="rotate(25)">
|
||||
<stop offset="0%"></stop>
|
||||
</linearGradient>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const template2 = (
|
||||
<svg width="400" height="180">
|
||||
<rect
|
||||
className={state.name}
|
||||
stroke-width={state.width}
|
||||
x={state.x}
|
||||
y={state.y}
|
||||
rx="20"
|
||||
ry="20"
|
||||
width="150"
|
||||
height="150"
|
||||
style={{
|
||||
fill: "red",
|
||||
stroke: "black",
|
||||
"stroke-width": props.stroke,
|
||||
opacity: 0.5,
|
||||
}}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const template3 = (
|
||||
<svg width="400" height="180">
|
||||
<rect {...props} />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const template4 = <rect x="50" y="20" width="150" height="150" />;
|
||||
|
||||
const template5 = (
|
||||
<>
|
||||
<rect x="50" y="20" width="150" height="150" />
|
||||
</>
|
||||
);
|
||||
|
||||
const template6 = (
|
||||
<Component>
|
||||
<rect x="50" y="20" width="150" height="150" />
|
||||
</Component>
|
||||
);
|
||||
|
||||
const template7 = (
|
||||
<svg viewBox={"0 0 160 40"} xmlns="http://www.w3.org/2000/svg">
|
||||
<a xlink:href={url}>
|
||||
<text x="10" y="25">
|
||||
MDN Web Docs
|
||||
</text>
|
||||
</a>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const template8 = (
|
||||
<svg viewBox={"0 0 160 40"} xmlns="http://www.w3.org/2000/svg">
|
||||
<text x="10" y="25" textContent={text} />
|
||||
</svg>
|
||||
);
|
||||
@@ -0,0 +1,33 @@
|
||||
var _tmpl$1 = _template$('<svg width="400" height="180"><rect stroke-width="2" x="50" y="20" rx="20" ry="20" width="150" height="150"/><linearGradient gradientTransform="rotate(25)"><stop offset="0%"/></linearGradient></svg>', 4), _tmpl$2 = _template$('<svg width="400" height="180"><rect rx="20" ry="20" width="150" height="150"/></svg>', 2), _tmpl$3 = _template$('<svg width="400" height="180"><rect/></svg>', 2), _tmpl$4 = _template$('<rect x="50" y="20" width="150" height="150"/>', 0), _tmpl$5 = _template$('<svg viewBox="0 0 160 40" xmlns="http://www.w3.org/2000/svg"><a><text x="10" y="25">MDN Web Docs</text></a></svg>', 6), _tmpl$6 = _template$('<svg viewBox="0 0 160 40" xmlns="http://www.w3.org/2000/svg"><text x="10" y="25"/></svg>', 2);
|
||||
const template = _tmpl$1.cloneNode(true);
|
||||
const template2 = () => {
|
||||
var _el = _tmpl$1.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "className", state.name);
|
||||
});
|
||||
effect(() => {
|
||||
return setAttribute(_el, "stroke-width", state.width);
|
||||
});
|
||||
effect(() => {
|
||||
return setAttribute(_el, "x", state.x);
|
||||
});
|
||||
effect(() => {
|
||||
return setAttribute(_el, "y", state.y);
|
||||
});
|
||||
;
|
||||
return _el;
|
||||
};
|
||||
const template3 = _tmpl$3.cloneNode(true);
|
||||
const template4 = _tmpl$4.cloneNode(true);
|
||||
const template5 = ;
|
||||
const template6 = createComponent(Component, {});
|
||||
const template7 = () => {
|
||||
var _el = _tmpl$4.cloneNode(true);
|
||||
setAttribute(_el, "xlink:href", url);
|
||||
return _el;
|
||||
};
|
||||
const template8 = () => {
|
||||
var _el = _tmpl$5.cloneNode(true);
|
||||
setAttribute(_el, "textContent", text);
|
||||
return _el;
|
||||
};
|
||||
108
integration/bunjs-only-snippets/solid-dom-fixtures/SVG/output.js
Normal file
108
integration/bunjs-only-snippets/solid-dom-fixtures/SVG/output.js
Normal file
@@ -0,0 +1,108 @@
|
||||
import { template as _$template } from "r-dom";
|
||||
import { setAttributeNS as _$setAttributeNS } from "r-dom";
|
||||
import { createComponent as _$createComponent } from "r-dom";
|
||||
import { spread as _$spread } from "r-dom";
|
||||
import { setAttribute as _$setAttribute } from "r-dom";
|
||||
import { effect as _$effect } from "r-dom";
|
||||
|
||||
const _tmpl$ = /*#__PURE__*/ _$template(
|
||||
`<svg width="400" height="180"><rect stroke-width="2" x="50" y="20" rx="20" ry="20" width="150" height="150" style="fill:red;stroke:black;stroke-width:5;opacity:0.5"></rect><linearGradient gradientTransform="rotate(25)"><stop offset="0%"></stop></linearGradient></svg>`,
|
||||
8
|
||||
),
|
||||
_tmpl$2 = /*#__PURE__*/ _$template(
|
||||
`<svg width="400" height="180"><rect rx="20" ry="20" width="150" height="150"></rect></svg>`,
|
||||
4
|
||||
),
|
||||
_tmpl$3 = /*#__PURE__*/ _$template(
|
||||
`<svg width="400" height="180"><rect></rect></svg>`,
|
||||
4
|
||||
),
|
||||
_tmpl$4 = /*#__PURE__*/ _$template(
|
||||
`<svg><rect x="50" y="20" width="150" height="150"></rect></svg>`,
|
||||
4,
|
||||
true
|
||||
),
|
||||
_tmpl$5 = /*#__PURE__*/ _$template(
|
||||
`<svg viewBox="0 0 160 40" xmlns="http://www.w3.org/2000/svg"><a><text x="10" y="25">MDN Web Docs</text></a></svg>`,
|
||||
6
|
||||
),
|
||||
_tmpl$6 = /*#__PURE__*/ _$template(
|
||||
`<svg viewBox="0 0 160 40" xmlns="http://www.w3.org/2000/svg"><text x="10" y="25"></text></svg>`,
|
||||
4
|
||||
);
|
||||
|
||||
const template = _tmpl$.cloneNode(true);
|
||||
|
||||
const template2 = (() => {
|
||||
const _el$2 = _tmpl$2.cloneNode(true),
|
||||
_el$3 = _el$2.firstChild;
|
||||
|
||||
_el$3.style.setProperty("fill", "red");
|
||||
|
||||
_el$3.style.setProperty("stroke", "black");
|
||||
|
||||
_el$3.style.setProperty("opacity", "0.5");
|
||||
|
||||
_$effect(
|
||||
(_p$) => {
|
||||
const _v$ = state.name,
|
||||
_v$2 = state.width,
|
||||
_v$3 = state.x,
|
||||
_v$4 = state.y,
|
||||
_v$5 = props.stroke;
|
||||
_v$ !== _p$._v$ && _$setAttribute(_el$3, "class", (_p$._v$ = _v$));
|
||||
_v$2 !== _p$._v$2 &&
|
||||
_$setAttribute(_el$3, "stroke-width", (_p$._v$2 = _v$2));
|
||||
_v$3 !== _p$._v$3 && _$setAttribute(_el$3, "x", (_p$._v$3 = _v$3));
|
||||
_v$4 !== _p$._v$4 && _$setAttribute(_el$3, "y", (_p$._v$4 = _v$4));
|
||||
_v$5 !== _p$._v$5 &&
|
||||
_el$3.style.setProperty("stroke-width", (_p$._v$5 = _v$5));
|
||||
return _p$;
|
||||
},
|
||||
{
|
||||
_v$: undefined,
|
||||
_v$2: undefined,
|
||||
_v$3: undefined,
|
||||
_v$4: undefined,
|
||||
_v$5: undefined,
|
||||
}
|
||||
);
|
||||
|
||||
return _el$2;
|
||||
})();
|
||||
|
||||
const template3 = (() => {
|
||||
const _el$4 = _tmpl$3.cloneNode(true),
|
||||
_el$5 = _el$4.firstChild;
|
||||
|
||||
_$spread(_el$5, props, true, false);
|
||||
|
||||
return _el$4;
|
||||
})();
|
||||
|
||||
const template4 = _tmpl$4.cloneNode(true);
|
||||
|
||||
const template5 = _tmpl$4.cloneNode(true);
|
||||
|
||||
const template6 = _$createComponent(Component, {
|
||||
get children() {
|
||||
return _tmpl$4.cloneNode(true);
|
||||
},
|
||||
});
|
||||
|
||||
const template7 = (() => {
|
||||
const _el$9 = _tmpl$5.cloneNode(true),
|
||||
_el$10 = _el$9.firstChild;
|
||||
|
||||
_$setAttributeNS(_el$10, "http://www.w3.org/1999/xlink", "xlink:href", url);
|
||||
|
||||
return _el$9;
|
||||
})();
|
||||
|
||||
const template8 = (() => {
|
||||
const _el$11 = _tmpl$6.cloneNode(true),
|
||||
_el$12 = _el$11.firstChild;
|
||||
|
||||
_el$12.textContent = text;
|
||||
return _el$11;
|
||||
})();
|
||||
@@ -0,0 +1,115 @@
|
||||
const selected = true;
|
||||
let id = "my-h1";
|
||||
let link;
|
||||
const template = (
|
||||
<div
|
||||
id="main"
|
||||
{...results}
|
||||
classList={{ selected: unknown }}
|
||||
style={{ color }}
|
||||
>
|
||||
<h1
|
||||
class="base"
|
||||
id={id}
|
||||
{...results()}
|
||||
disabled
|
||||
readonly=""
|
||||
title={welcoming()}
|
||||
style={{ "background-color": color(), "margin-right": "40px" }}
|
||||
classList={{ dynamic: dynamic(), selected }}
|
||||
>
|
||||
<a href={"/"} ref={link} classList={{ "ccc ddd": true }} readonly={value}>
|
||||
Welcome
|
||||
</a>
|
||||
</h1>
|
||||
</div>
|
||||
);
|
||||
|
||||
const template2 = (
|
||||
<div {...getProps("test")}>
|
||||
<div textContent={rowId} />
|
||||
<div textContent={row.label} />
|
||||
<div innerHTML={"<div/>"} />
|
||||
</div>
|
||||
);
|
||||
|
||||
const template3 = (
|
||||
<div
|
||||
id={/*@once*/ state.id}
|
||||
style={/*@once*/ { "background-color": state.color }}
|
||||
name={state.name}
|
||||
textContent={/*@once*/ state.content}
|
||||
/>
|
||||
);
|
||||
|
||||
const template4 = (
|
||||
<div class="hi" className={state.class} classList={{ "ccc:ddd": true }} />
|
||||
);
|
||||
|
||||
const template5 = <div class="a" className="b"></div>;
|
||||
|
||||
const template6 = <div style={someStyle()} textContent="Hi" />;
|
||||
|
||||
const template7 = (
|
||||
<div
|
||||
style={{
|
||||
"background-color": color(),
|
||||
"margin-right": "40px",
|
||||
...props.style,
|
||||
}}
|
||||
style:padding-top={props.top}
|
||||
class:my-class={props.active}
|
||||
/>
|
||||
);
|
||||
|
||||
let refTarget;
|
||||
const template8 = <div ref={refTarget} />;
|
||||
|
||||
const template9 = <div ref={(e) => console.log(e)} />;
|
||||
|
||||
const template10 = <div ref={refFactory()} />;
|
||||
|
||||
const template11 = <div use:something use:another={thing} use:zero={0} />;
|
||||
|
||||
const template12 = <div prop:htmlFor={thing} />;
|
||||
|
||||
const template13 = <input type="checkbox" checked={true} />;
|
||||
|
||||
const template14 = <input type="checkbox" checked={state.visible} />;
|
||||
|
||||
const template15 = <div class="`a">`$`</div>;
|
||||
|
||||
const template16 = (
|
||||
<button
|
||||
class="static"
|
||||
classList={{
|
||||
hi: "k",
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
Write
|
||||
</button>
|
||||
);
|
||||
|
||||
const template17 = (
|
||||
<button
|
||||
classList={{
|
||||
a: true,
|
||||
b: true,
|
||||
c: true,
|
||||
}}
|
||||
onClick={increment}
|
||||
>
|
||||
Hi
|
||||
</button>
|
||||
);
|
||||
|
||||
const template18 = (
|
||||
<div
|
||||
{...{
|
||||
get [key()]() {
|
||||
return props.value;
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -0,0 +1,155 @@
|
||||
var _tmpl = _template$(
|
||||
'<div id="main"><h1 class="base" disabled readonly><a href="/">Welcome</a></h1></div>',
|
||||
6
|
||||
),
|
||||
_tmpl$2 = _template$(
|
||||
'<div><div/><div/><div innerHTML="<div/>"/></div>',
|
||||
2
|
||||
),
|
||||
_tmpl$2 = _template$("<div/>", 0),
|
||||
_tmpl$3 = _template$('<div class="hi"/>', 0),
|
||||
_tmpl$5 = _template$('<div class="a" class="b"/>', 0),
|
||||
_tmpl$5 = _template$('<div textContent="Hi"/>', 0),
|
||||
_tmpl$6 = _template$("<div use:something use:zero=0/>", 0),
|
||||
_tmpl$8 = _template$('<input type="checkbox" checked/>', 0),
|
||||
_tmpl$8 = _template$('<input type="checkbox"/>', 0),
|
||||
_tmpl$10 = _template$('<div class="`a">`$`</div>', 2),
|
||||
_tmpl$10 = _template$(
|
||||
'<button class="static" type="button">Write</button>',
|
||||
2
|
||||
),
|
||||
_tmpl$11 = _template$("<button>Hi</button>", 2);
|
||||
const selected = true;
|
||||
let id = "my-h1";
|
||||
let link;
|
||||
const template = () => {
|
||||
var _el = _tmpl.cloneNode(true),
|
||||
_el$1 = _el.firstChild,
|
||||
_el$2 = _el$1.nextSibling;
|
||||
effect(() => {
|
||||
return setAttribute(_el, "classList", { selected: unknown });
|
||||
});
|
||||
setAttribute(_el$1, "id", id);
|
||||
effect(() => {
|
||||
return setAttribute(_el$1, "title", welcoming());
|
||||
});
|
||||
effect(() => {
|
||||
return setAttribute(_el$1, "classList", { dynamic: dynamic(), selected });
|
||||
});
|
||||
setAttribute(_el$2, "ref", link);
|
||||
effect(() => {
|
||||
return setAttribute(_el$2, "classList", { "ccc ddd": true });
|
||||
});
|
||||
setAttribute(_el$2, "readonly", value);
|
||||
return _el;
|
||||
};
|
||||
const template2 = () => {
|
||||
var _el = _tmpl$1.cloneNode(true),
|
||||
_el$1 = _el.firstChild;
|
||||
setAttribute(_el, "textContent", rowId);
|
||||
effect(() => {
|
||||
return setAttribute(_el$1, "textContent", row.label);
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template3 = () => {
|
||||
var _el = _tmpl$2.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "id", state.id);
|
||||
});
|
||||
effect(() => {
|
||||
return setAttribute(_el, "name", state.name);
|
||||
});
|
||||
effect(() => {
|
||||
return setAttribute(_el, "textContent", state.content);
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template4 = () => {
|
||||
var _el = _tmpl$3.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "className", state.class);
|
||||
});
|
||||
effect(() => {
|
||||
return setAttribute(_el, "classList", { "ccc:ddd": true });
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template5 = _tmpl$5.cloneNode(true);
|
||||
const template6 = () => {
|
||||
var _el = _tmpl$5.cloneNode(true);
|
||||
return _el;
|
||||
};
|
||||
const template7 = () => {
|
||||
var _el = _tmpl$2.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "style:padding-top", props.top);
|
||||
});
|
||||
effect(() => {
|
||||
return setAttribute(_el, "class:my-class", props.active);
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
let refTarget;
|
||||
const template8 = () => {
|
||||
var _el = _tmpl$2.cloneNode(true);
|
||||
setAttribute(_el, "ref", refTarget);
|
||||
return _el;
|
||||
};
|
||||
const template9 = () => {
|
||||
var _el = _tmpl$2.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "ref", (e) => console.log(e));
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template10 = () => {
|
||||
var _el = _tmpl$2.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "ref", refFactory());
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template11 = () => {
|
||||
var _el = _tmpl$6.cloneNode(true);
|
||||
setAttribute(_el, "use:another", thing);
|
||||
return _el;
|
||||
};
|
||||
const template12 = () => {
|
||||
var _el = _tmpl$2.cloneNode(true);
|
||||
setAttribute(_el, "prop:htmlFor", thing);
|
||||
return _el;
|
||||
};
|
||||
const template13 = _tmpl$8.cloneNode(true);
|
||||
const template14 = () => {
|
||||
var _el = _tmpl$8.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "checked", state.visible);
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template15 = _tmpl$10.cloneNode(true);
|
||||
const template16 = () => {
|
||||
var _el = _tmpl$10.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "classList", {
|
||||
hi: "k",
|
||||
});
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template17 = () => {
|
||||
var _el = _tmpl$11.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "classList", {
|
||||
a: true,
|
||||
b: true,
|
||||
c: true,
|
||||
});
|
||||
});
|
||||
effect(() => {
|
||||
return (_el.$$click = increment);
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template18 = _tmpl$2.cloneNode(true);
|
||||
@@ -0,0 +1,241 @@
|
||||
const _tmpl$ = /*#__PURE__*/ _$template(
|
||||
`<div id="main"><h1 class="base selected" id="my-h1" disabled readonly=""><a href="/">Welcome</a></h1></div>`,
|
||||
6
|
||||
),
|
||||
_tmpl$2 = /*#__PURE__*/ _$template(
|
||||
`<div><div></div><div> </div><div></div></div>`,
|
||||
8
|
||||
),
|
||||
_tmpl$3 = /*#__PURE__*/ _$template(`<div></div>`, 2),
|
||||
_tmpl$4 = /*#__PURE__*/ _$template(`<div class="a b"></div>`, 2),
|
||||
_tmpl$5 = /*#__PURE__*/ _$template(`<input type="checkbox">`, 1),
|
||||
_tmpl$6 = /*#__PURE__*/ _$template(`<div class="\`a">\`$\`</div>`, 2),
|
||||
_tmpl$7 = /*#__PURE__*/ _$template(
|
||||
`<button class="static hi" type="button">Write</button>`,
|
||||
2
|
||||
),
|
||||
_tmpl$8 = /*#__PURE__*/ _$template(`<button class="a b c">Hi</button>`, 2);
|
||||
|
||||
const selected = true;
|
||||
let id = "my-h1";
|
||||
let link;
|
||||
|
||||
const template = (() => {
|
||||
const _el$ = _tmpl$.cloneNode(true),
|
||||
_el$2 = _el$.firstChild,
|
||||
_el$3 = _el$2.firstChild;
|
||||
|
||||
_$spread(_el$, results, false, true);
|
||||
|
||||
_el$.classList.toggle("selected", unknown);
|
||||
|
||||
_el$.style.setProperty("color", color);
|
||||
|
||||
_$spread(_el$2, results, false, true);
|
||||
|
||||
_el$2.style.setProperty("margin-right", "40px");
|
||||
|
||||
const _ref$ = link;
|
||||
typeof _ref$ === "function" ? _ref$(_el$3) : (link = _el$3);
|
||||
|
||||
_$classList(_el$3, {
|
||||
"ccc ddd": true,
|
||||
});
|
||||
|
||||
_el$3.readOnly = value;
|
||||
|
||||
_$effect(
|
||||
(_p$) => {
|
||||
const _v$ = welcoming(),
|
||||
_v$2 = color(),
|
||||
_v$3 = !!dynamic();
|
||||
|
||||
_v$ !== _p$._v$ && _$setAttribute(_el$2, "title", (_p$._v$ = _v$));
|
||||
_v$2 !== _p$._v$2 &&
|
||||
_el$2.style.setProperty("background-color", (_p$._v$2 = _v$2));
|
||||
_v$3 !== _p$._v$3 && _el$2.classList.toggle("dynamic", (_p$._v$3 = _v$3));
|
||||
return _p$;
|
||||
},
|
||||
{
|
||||
_v$: undefined,
|
||||
_v$2: undefined,
|
||||
_v$3: undefined,
|
||||
}
|
||||
);
|
||||
|
||||
return _el$;
|
||||
})();
|
||||
|
||||
const template2 = (() => {
|
||||
const _el$4 = _tmpl$2.cloneNode(true),
|
||||
_el$5 = _el$4.firstChild,
|
||||
_el$6 = _el$5.nextSibling,
|
||||
_el$7 = _el$6.firstChild,
|
||||
_el$8 = _el$6.nextSibling;
|
||||
|
||||
_$spread(_el$4, () => getProps("test"), false, true);
|
||||
|
||||
_el$5.textContent = rowId;
|
||||
_el$8.innerHTML = "<div/>";
|
||||
|
||||
_$effect(() => (_el$7.data = row.label));
|
||||
|
||||
return _el$4;
|
||||
})();
|
||||
|
||||
const template3 = (() => {
|
||||
const _el$9 = _tmpl$3.cloneNode(true);
|
||||
|
||||
_$setAttribute(_el$9, "id", state.id);
|
||||
|
||||
_el$9.style.setProperty("background-color", state.color);
|
||||
|
||||
_el$9.textContent = state.content;
|
||||
|
||||
_$effect(() => _$setAttribute(_el$9, "name", state.name));
|
||||
|
||||
return _el$9;
|
||||
})();
|
||||
|
||||
const template4 = (() => {
|
||||
const _el$10 = _tmpl$3.cloneNode(true);
|
||||
|
||||
_$classList(_el$10, {
|
||||
"ccc:ddd": true,
|
||||
});
|
||||
|
||||
_$effect(() => _$className(_el$10, `hi ${state.class || ""}`));
|
||||
|
||||
return _el$10;
|
||||
})();
|
||||
|
||||
const template5 = _tmpl$4.cloneNode(true);
|
||||
|
||||
const template6 = (() => {
|
||||
const _el$12 = _tmpl$3.cloneNode(true);
|
||||
|
||||
_el$12.textContent = "Hi";
|
||||
|
||||
_$effect((_$p) => _$style(_el$12, someStyle(), _$p));
|
||||
|
||||
return _el$12;
|
||||
})();
|
||||
|
||||
const template7 = (() => {
|
||||
const _el$13 = _tmpl$3.cloneNode(true);
|
||||
|
||||
_$effect(
|
||||
(_p$) => {
|
||||
const _v$4 = {
|
||||
"background-color": color(),
|
||||
"margin-right": "40px",
|
||||
...props.style,
|
||||
},
|
||||
_v$5 = props.top,
|
||||
_v$6 = !!props.active;
|
||||
|
||||
_p$._v$4 = _$style(_el$13, _v$4, _p$._v$4);
|
||||
_v$5 !== _p$._v$5 &&
|
||||
_el$13.style.setProperty("padding-top", (_p$._v$5 = _v$5));
|
||||
_v$6 !== _p$._v$6 &&
|
||||
_el$13.classList.toggle("my-class", (_p$._v$6 = _v$6));
|
||||
return _p$;
|
||||
},
|
||||
{
|
||||
_v$4: undefined,
|
||||
_v$5: undefined,
|
||||
_v$6: undefined,
|
||||
}
|
||||
);
|
||||
|
||||
return _el$13;
|
||||
})();
|
||||
|
||||
let refTarget;
|
||||
|
||||
const template8 = (() => {
|
||||
const _el$14 = _tmpl$3.cloneNode(true);
|
||||
|
||||
const _ref$2 = refTarget;
|
||||
typeof _ref$2 === "function" ? _ref$2(_el$14) : (refTarget = _el$14);
|
||||
return _el$14;
|
||||
})();
|
||||
|
||||
const template9 = (() => {
|
||||
const _el$15 = _tmpl$3.cloneNode(true);
|
||||
|
||||
((e) => console.log(e))(_el$15);
|
||||
|
||||
return _el$15;
|
||||
})();
|
||||
|
||||
const template10 = (() => {
|
||||
const _el$16 = _tmpl$3.cloneNode(true);
|
||||
|
||||
const _ref$3 = refFactory();
|
||||
|
||||
typeof _ref$3 === "function" && _ref$3(_el$16);
|
||||
return _el$16;
|
||||
})();
|
||||
|
||||
const template11 = (() => {
|
||||
const _el$17 = _tmpl$3.cloneNode(true);
|
||||
|
||||
zero(_el$17, () => 0);
|
||||
another(_el$17, () => thing);
|
||||
something(_el$17, () => true);
|
||||
return _el$17;
|
||||
})();
|
||||
|
||||
const template12 = (() => {
|
||||
const _el$18 = _tmpl$3.cloneNode(true);
|
||||
|
||||
_el$18.htmlFor = thing;
|
||||
return _el$18;
|
||||
})();
|
||||
|
||||
const template13 = (() => {
|
||||
const _el$19 = _tmpl$5.cloneNode(true);
|
||||
|
||||
_el$19.checked = true;
|
||||
return _el$19;
|
||||
})();
|
||||
|
||||
const template14 = (() => {
|
||||
const _el$20 = _tmpl$5.cloneNode(true);
|
||||
|
||||
_$effect(() => (_el$20.checked = state.visible));
|
||||
|
||||
return _el$20;
|
||||
})();
|
||||
|
||||
const template15 = _tmpl$6.cloneNode(true);
|
||||
|
||||
const template16 = _tmpl$7.cloneNode(true);
|
||||
|
||||
const template17 = (() => {
|
||||
const _el$23 = _tmpl$8.cloneNode(true);
|
||||
|
||||
_$addEventListener(_el$23, "click", increment, true);
|
||||
|
||||
return _el$23;
|
||||
})();
|
||||
|
||||
const template18 = (() => {
|
||||
const _el$24 = _tmpl$3.cloneNode(true);
|
||||
|
||||
_$spread(
|
||||
_el$24,
|
||||
() => ({
|
||||
get [key()]() {
|
||||
return props.value;
|
||||
},
|
||||
}),
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
return _el$24;
|
||||
})();
|
||||
|
||||
_$delegateEvents(["click"]);
|
||||
@@ -0,0 +1,161 @@
|
||||
import { Show } from "somewhere";
|
||||
|
||||
const Child = (props) => {
|
||||
const [s, set] = createSignal();
|
||||
return (
|
||||
<>
|
||||
<div ref={props.ref}>Hello {props.name}</div>
|
||||
<div ref={set}>{props.children}</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const template = (props) => {
|
||||
let childRef;
|
||||
const { content } = props;
|
||||
return (
|
||||
<div>
|
||||
<Child name="John" {...props} ref={childRef} booleanProperty>
|
||||
<div>From Parent</div>
|
||||
</Child>
|
||||
<Child name="Jason" {...dynamicSpread()} ref={props.ref}>
|
||||
{/* Comment Node */}
|
||||
<div>{content}</div>
|
||||
</Child>
|
||||
<Context.Consumer ref={props.consumerRef()}>
|
||||
{(context) => context}
|
||||
</Context.Consumer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const template2 = (
|
||||
<Child
|
||||
name="Jake"
|
||||
dynamic={state.data}
|
||||
stale={/*@once*/ state.data}
|
||||
handleClick={clickHandler}
|
||||
hyphen-ated={state.data}
|
||||
ref={(el) => (e = el)}
|
||||
/>
|
||||
);
|
||||
|
||||
const template3 = (
|
||||
<Child>
|
||||
<div />
|
||||
<div />
|
||||
<div />
|
||||
After
|
||||
</Child>
|
||||
);
|
||||
|
||||
const [s, set] = createSignal();
|
||||
const template4 = <Child ref={set}>{<div />}</Child>;
|
||||
|
||||
const template5 = <Child dynamic={state.dynamic}>{state.dynamic}</Child>;
|
||||
|
||||
// builtIns
|
||||
const template6 = (
|
||||
<For each={state.list} fallback={<Loading />}>
|
||||
{(item) => <Show when={state.condition}>{item}</Show>}
|
||||
</For>
|
||||
);
|
||||
|
||||
const template7 = (
|
||||
<Child>
|
||||
<div />
|
||||
{state.dynamic}
|
||||
</Child>
|
||||
);
|
||||
|
||||
const template8 = (
|
||||
<Child>
|
||||
{(item) => item}
|
||||
{(item) => item}
|
||||
</Child>
|
||||
);
|
||||
|
||||
const template9 = <_garbage>Hi</_garbage>;
|
||||
|
||||
const template10 = (
|
||||
<div>
|
||||
<Link>new</Link>
|
||||
{" | "}
|
||||
<Link>comments</Link>
|
||||
{" | "}
|
||||
<Link>show</Link>
|
||||
{" | "}
|
||||
<Link>ask</Link>
|
||||
{" | "}
|
||||
<Link>jobs</Link>
|
||||
{" | "}
|
||||
<Link>submit</Link>
|
||||
</div>
|
||||
);
|
||||
|
||||
const template11 = (
|
||||
<div>
|
||||
<Link>new</Link>
|
||||
{" | "}
|
||||
<Link>comments</Link>
|
||||
<Link>show</Link>
|
||||
{" | "}
|
||||
<Link>ask</Link>
|
||||
<Link>jobs</Link>
|
||||
{" | "}
|
||||
<Link>submit</Link>
|
||||
</div>
|
||||
);
|
||||
|
||||
const template12 = (
|
||||
<div>
|
||||
{" | "}
|
||||
<Link>comments</Link>
|
||||
{" | "}
|
||||
{" | "}
|
||||
{" | "}
|
||||
<Link>show</Link>
|
||||
{" | "}
|
||||
</div>
|
||||
);
|
||||
|
||||
class Template13 {
|
||||
render() {
|
||||
<Component prop={this.something} onClick={() => this.shouldStay}>
|
||||
<Nested prop={this.data}>{this.content}</Nested>
|
||||
</Component>;
|
||||
}
|
||||
}
|
||||
|
||||
const Template14 = <Component>{data()}</Component>;
|
||||
|
||||
const Template15 = <Component {...props} />;
|
||||
|
||||
const Template16 = <Component something={something} {...props} />;
|
||||
|
||||
const Template17 = (
|
||||
<Pre>
|
||||
<span>1</span> <span>2</span> <span>3</span>
|
||||
</Pre>
|
||||
);
|
||||
const Template18 = (
|
||||
<Pre>
|
||||
<span>1</span>
|
||||
<span>2</span>
|
||||
<span>3</span>
|
||||
</Pre>
|
||||
);
|
||||
|
||||
const Template19 = <Component {...s.dynamic()} />;
|
||||
|
||||
const Template20 = <Component class={prop.red ? "red" : "green"} />;
|
||||
|
||||
const template21 = (
|
||||
<Component
|
||||
{...{
|
||||
get [key()]() {
|
||||
return props.value;
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -0,0 +1,205 @@
|
||||
var _tmpl = _template$("<div><div>From Parent</div><div</div></div>", 9), _tmpl$1 = _template$("<div> | | | | | </div>", 8), _tmpl$2 = _template$("<div> | | | </div>", 8);
|
||||
import {Show} from "somewhere";
|
||||
const Child = (props) => {
|
||||
const [s, set] = createSignal();
|
||||
return ;
|
||||
};
|
||||
const template = (props) => {
|
||||
let childRef;
|
||||
const { content } = props;
|
||||
return () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, createComponent(Child, {
|
||||
name: "John",
|
||||
ref: childRef,
|
||||
booleanProperty: true
|
||||
}), null);
|
||||
insert(_tmpl, content, null);
|
||||
insert(_tmpl, createComponent(Child, {
|
||||
name: "Jason",
|
||||
ref: props.ref
|
||||
}), null);
|
||||
insert(_tmpl, createComponent(Context.Consumer, {
|
||||
ref: props.consumerRef(),
|
||||
get children: [
|
||||
(context) => context
|
||||
]
|
||||
}), null);
|
||||
return _tmpl;
|
||||
};
|
||||
};
|
||||
const template2 = createComponent(Child, {
|
||||
name: "Jake",
|
||||
dynamic: state.data,
|
||||
stale: state.data,
|
||||
handleClick: clickHandler,
|
||||
"hyphen-ated": state.data,
|
||||
get ref: () => {
|
||||
return (el) => e = el;
|
||||
}
|
||||
});
|
||||
const template3 = createComponent(Child, {
|
||||
get children: [
|
||||
"After"
|
||||
]
|
||||
});
|
||||
const [s, set] = createSignal();
|
||||
const template4 = createComponent(Child, {
|
||||
ref: set
|
||||
});
|
||||
const template5 = createComponent(Child, {
|
||||
dynamic: state.dynamic,
|
||||
get children: [
|
||||
state.dynamic
|
||||
]
|
||||
});
|
||||
const template6 = createComponent(For, {
|
||||
each: state.list,
|
||||
fallback: ,
|
||||
get children: [
|
||||
(item) => createComponent(Show, {
|
||||
when: state.condition,
|
||||
get children: [
|
||||
item
|
||||
]
|
||||
})
|
||||
]
|
||||
});
|
||||
const template7 = createComponent(Child, {
|
||||
get children: [
|
||||
state.dynamic
|
||||
]
|
||||
});
|
||||
const template8 = createComponent(Child, {
|
||||
get children: [
|
||||
(item) => item,
|
||||
(item) => item
|
||||
]
|
||||
});
|
||||
const template9 = createComponent(_garbage, {
|
||||
get children: [
|
||||
"Hi"
|
||||
]
|
||||
});
|
||||
const template10 = () => {
|
||||
var _tmpl$1 = _tmpl$1.cloneNode(true);
|
||||
insert(_tmpl$1, createComponent(Link, {
|
||||
get children: [
|
||||
"new"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$1, createComponent(Link, {
|
||||
get children: [
|
||||
"comments"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$1, createComponent(Link, {
|
||||
get children: [
|
||||
"show"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$1, createComponent(Link, {
|
||||
get children: [
|
||||
"ask"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$1, createComponent(Link, {
|
||||
get children: [
|
||||
"jobs"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$1, createComponent(Link, {
|
||||
get children: [
|
||||
"submit"
|
||||
]
|
||||
}), null);
|
||||
return _tmpl$1;
|
||||
};
|
||||
const template11 = () => {
|
||||
var _tmpl$2 = _tmpl$2.cloneNode(true);
|
||||
insert(_tmpl$2, createComponent(Link, {
|
||||
get children: [
|
||||
"new"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$2, createComponent(Link, {
|
||||
get children: [
|
||||
"comments"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$2, createComponent(Link, {
|
||||
get children: [
|
||||
"show"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$2, createComponent(Link, {
|
||||
get children: [
|
||||
"ask"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$2, createComponent(Link, {
|
||||
get children: [
|
||||
"jobs"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$2, createComponent(Link, {
|
||||
get children: [
|
||||
"submit"
|
||||
]
|
||||
}), null);
|
||||
return _tmpl$2;
|
||||
};
|
||||
const template12 = () => {
|
||||
var _tmpl$1 = _tmpl$1.cloneNode(true);
|
||||
insert(_tmpl$1, createComponent(Link, {
|
||||
get children: [
|
||||
"comments"
|
||||
]
|
||||
}), null);
|
||||
insert(_tmpl$1, createComponent(Link, {
|
||||
get children: [
|
||||
"show"
|
||||
]
|
||||
}), null);
|
||||
return _tmpl$1;
|
||||
};
|
||||
|
||||
class Template13 {
|
||||
render() {
|
||||
createComponent(Component, {
|
||||
prop: this.something,
|
||||
get onClick: () => {
|
||||
return () => this.shouldStay;
|
||||
},
|
||||
get children: [
|
||||
createComponent(Nested, {
|
||||
prop: this.data,
|
||||
get children: [
|
||||
this.content
|
||||
]
|
||||
})
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
const Template14 = createComponent(Component, {
|
||||
get children: [
|
||||
data()
|
||||
]
|
||||
});
|
||||
const Template15 = createComponent(Component, {});
|
||||
const Template16 = createComponent(Component, {
|
||||
something
|
||||
});
|
||||
const Template17 = createComponent(Pre, {
|
||||
get children: [
|
||||
" ",
|
||||
" "
|
||||
]
|
||||
});
|
||||
const Template18 = createComponent(Pre, {});
|
||||
const Template19 = createComponent(Component, {});
|
||||
const Template20 = createComponent(Component, {
|
||||
class: prop.red ? "red" : "green"
|
||||
});
|
||||
const template21 = createComponent(Component, {});
|
||||
@@ -0,0 +1,443 @@
|
||||
import { template as _$template } from "r-dom";
|
||||
import { memo as _$memo } from "r-dom";
|
||||
import { For as _$For } from "r-dom";
|
||||
import { createComponent as _$createComponent } from "r-dom";
|
||||
import { mergeProps as _$mergeProps } from "r-dom";
|
||||
import { insert as _$insert } from "r-dom";
|
||||
|
||||
const _tmpl$ = /*#__PURE__*/ _$template(`<div>Hello </div>`, 2),
|
||||
_tmpl$2 = /*#__PURE__*/ _$template(`<div></div>`, 2),
|
||||
_tmpl$3 = /*#__PURE__*/ _$template(`<div>From Parent</div>`, 2),
|
||||
_tmpl$4 = /*#__PURE__*/ _$template(
|
||||
`<div> | <!> | <!> | <!> | <!> | </div>`,
|
||||
6
|
||||
),
|
||||
_tmpl$5 = /*#__PURE__*/ _$template(`<div> | <!> | <!> | </div>`, 4),
|
||||
_tmpl$6 = /*#__PURE__*/ _$template(`<div> | <!> | | | <!> | </div>`, 4),
|
||||
_tmpl$7 = /*#__PURE__*/ _$template(`<span>1</span>`, 2),
|
||||
_tmpl$8 = /*#__PURE__*/ _$template(`<span>2</span>`, 2),
|
||||
_tmpl$9 = /*#__PURE__*/ _$template(`<span>3</span>`, 2);
|
||||
|
||||
import { Show } from "somewhere";
|
||||
|
||||
const Child = (props) => {
|
||||
const [s, set] = createSignal();
|
||||
return [
|
||||
(() => {
|
||||
const _el$ = _tmpl$.cloneNode(true),
|
||||
_el$2 = _el$.firstChild;
|
||||
|
||||
const _ref$ = props.ref;
|
||||
typeof _ref$ === "function" ? _ref$(_el$) : (props.ref = _el$);
|
||||
|
||||
_$insert(_el$, () => props.name, null);
|
||||
|
||||
return _el$;
|
||||
})(),
|
||||
(() => {
|
||||
const _el$3 = _tmpl$2.cloneNode(true);
|
||||
|
||||
set(_el$3);
|
||||
|
||||
_$insert(_el$3, () => props.children);
|
||||
|
||||
return _el$3;
|
||||
})(),
|
||||
];
|
||||
};
|
||||
|
||||
const template = (props) => {
|
||||
let childRef;
|
||||
const { content } = props;
|
||||
return (() => {
|
||||
const _el$4 = _tmpl$2.cloneNode(true);
|
||||
|
||||
_$insert(
|
||||
_el$4,
|
||||
_$createComponent(
|
||||
Child,
|
||||
_$mergeProps(
|
||||
{
|
||||
name: "John",
|
||||
},
|
||||
props,
|
||||
{
|
||||
ref(r$) {
|
||||
const _ref$2 = childRef;
|
||||
typeof _ref$2 === "function" ? _ref$2(r$) : (childRef = r$);
|
||||
},
|
||||
|
||||
booleanProperty: true,
|
||||
|
||||
get children() {
|
||||
return _tmpl$3.cloneNode(true);
|
||||
},
|
||||
}
|
||||
)
|
||||
),
|
||||
null
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$4,
|
||||
_$createComponent(
|
||||
Child,
|
||||
_$mergeProps(
|
||||
{
|
||||
name: "Jason",
|
||||
},
|
||||
dynamicSpread,
|
||||
{
|
||||
ref(r$) {
|
||||
const _ref$3 = props.ref;
|
||||
typeof _ref$3 === "function" ? _ref$3(r$) : (props.ref = r$);
|
||||
},
|
||||
|
||||
get children() {
|
||||
const _el$6 = _tmpl$2.cloneNode(true);
|
||||
|
||||
_$insert(_el$6, content);
|
||||
|
||||
return _el$6;
|
||||
},
|
||||
}
|
||||
)
|
||||
),
|
||||
null
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$4,
|
||||
_$createComponent(Context.Consumer, {
|
||||
ref(r$) {
|
||||
const _ref$4 = props.consumerRef();
|
||||
|
||||
typeof _ref$4 === "function" && _ref$4(r$);
|
||||
},
|
||||
|
||||
children: (context) => context,
|
||||
}),
|
||||
null
|
||||
);
|
||||
|
||||
return _el$4;
|
||||
})();
|
||||
};
|
||||
|
||||
const template2 = _$createComponent(Child, {
|
||||
name: "Jake",
|
||||
|
||||
get dynamic() {
|
||||
return state.data;
|
||||
},
|
||||
|
||||
stale: state.data,
|
||||
handleClick: clickHandler,
|
||||
|
||||
get ["hyphen-ated"]() {
|
||||
return state.data;
|
||||
},
|
||||
|
||||
ref: (el) => (e = el),
|
||||
});
|
||||
|
||||
const template3 = _$createComponent(Child, {
|
||||
get children() {
|
||||
return [
|
||||
_tmpl$2.cloneNode(true),
|
||||
_tmpl$2.cloneNode(true),
|
||||
_tmpl$2.cloneNode(true),
|
||||
"After",
|
||||
];
|
||||
},
|
||||
});
|
||||
|
||||
const [s, set] = createSignal();
|
||||
|
||||
const template4 = _$createComponent(Child, {
|
||||
ref: set,
|
||||
|
||||
get children() {
|
||||
return _tmpl$2.cloneNode(true);
|
||||
},
|
||||
});
|
||||
|
||||
const template5 = _$createComponent(Child, {
|
||||
get dynamic() {
|
||||
return state.dynamic;
|
||||
},
|
||||
|
||||
get children() {
|
||||
return state.dynamic;
|
||||
},
|
||||
}); // builtIns
|
||||
|
||||
const template6 = _$createComponent(_$For, {
|
||||
get each() {
|
||||
return state.list;
|
||||
},
|
||||
|
||||
get fallback() {
|
||||
return _$createComponent(Loading, {});
|
||||
},
|
||||
|
||||
children: (item) =>
|
||||
_$createComponent(Show, {
|
||||
get when() {
|
||||
return state.condition;
|
||||
},
|
||||
|
||||
children: item,
|
||||
}),
|
||||
});
|
||||
|
||||
const template7 = _$createComponent(Child, {
|
||||
get children() {
|
||||
return [_tmpl$2.cloneNode(true), _$memo(() => state.dynamic)];
|
||||
},
|
||||
});
|
||||
|
||||
const template8 = _$createComponent(Child, {
|
||||
get children() {
|
||||
return [(item) => item, (item) => item];
|
||||
},
|
||||
});
|
||||
|
||||
const template9 = _$createComponent(_garbage, {
|
||||
children: "Hi",
|
||||
});
|
||||
|
||||
const template10 = (() => {
|
||||
const _el$12 = _tmpl$4.cloneNode(true),
|
||||
_el$13 = _el$12.firstChild,
|
||||
_el$18 = _el$13.nextSibling,
|
||||
_el$14 = _el$18.nextSibling,
|
||||
_el$19 = _el$14.nextSibling,
|
||||
_el$15 = _el$19.nextSibling,
|
||||
_el$20 = _el$15.nextSibling,
|
||||
_el$16 = _el$20.nextSibling,
|
||||
_el$21 = _el$16.nextSibling,
|
||||
_el$17 = _el$21.nextSibling;
|
||||
|
||||
_$insert(
|
||||
_el$12,
|
||||
_$createComponent(Link, {
|
||||
children: "new",
|
||||
}),
|
||||
_el$13
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$12,
|
||||
_$createComponent(Link, {
|
||||
children: "comments",
|
||||
}),
|
||||
_el$18
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$12,
|
||||
_$createComponent(Link, {
|
||||
children: "show",
|
||||
}),
|
||||
_el$19
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$12,
|
||||
_$createComponent(Link, {
|
||||
children: "ask",
|
||||
}),
|
||||
_el$20
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$12,
|
||||
_$createComponent(Link, {
|
||||
children: "jobs",
|
||||
}),
|
||||
_el$21
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$12,
|
||||
_$createComponent(Link, {
|
||||
children: "submit",
|
||||
}),
|
||||
null
|
||||
);
|
||||
|
||||
return _el$12;
|
||||
})();
|
||||
|
||||
const template11 = (() => {
|
||||
const _el$22 = _tmpl$5.cloneNode(true),
|
||||
_el$23 = _el$22.firstChild,
|
||||
_el$26 = _el$23.nextSibling,
|
||||
_el$24 = _el$26.nextSibling,
|
||||
_el$27 = _el$24.nextSibling,
|
||||
_el$25 = _el$27.nextSibling;
|
||||
|
||||
_$insert(
|
||||
_el$22,
|
||||
_$createComponent(Link, {
|
||||
children: "new",
|
||||
}),
|
||||
_el$23
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$22,
|
||||
_$createComponent(Link, {
|
||||
children: "comments",
|
||||
}),
|
||||
_el$26
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$22,
|
||||
_$createComponent(Link, {
|
||||
children: "show",
|
||||
}),
|
||||
_el$26
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$22,
|
||||
_$createComponent(Link, {
|
||||
children: "ask",
|
||||
}),
|
||||
_el$27
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$22,
|
||||
_$createComponent(Link, {
|
||||
children: "jobs",
|
||||
}),
|
||||
_el$27
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$22,
|
||||
_$createComponent(Link, {
|
||||
children: "submit",
|
||||
}),
|
||||
null
|
||||
);
|
||||
|
||||
return _el$22;
|
||||
})();
|
||||
|
||||
const template12 = (() => {
|
||||
const _el$28 = _tmpl$6.cloneNode(true),
|
||||
_el$29 = _el$28.firstChild,
|
||||
_el$34 = _el$29.nextSibling,
|
||||
_el$30 = _el$34.nextSibling,
|
||||
_el$35 = _el$30.nextSibling,
|
||||
_el$33 = _el$35.nextSibling;
|
||||
|
||||
_$insert(
|
||||
_el$28,
|
||||
_$createComponent(Link, {
|
||||
children: "comments",
|
||||
}),
|
||||
_el$34
|
||||
);
|
||||
|
||||
_$insert(
|
||||
_el$28,
|
||||
_$createComponent(Link, {
|
||||
children: "show",
|
||||
}),
|
||||
_el$35
|
||||
);
|
||||
|
||||
return _el$28;
|
||||
})();
|
||||
|
||||
class Template13 {
|
||||
render() {
|
||||
const _self$ = this;
|
||||
|
||||
_$createComponent(Component, {
|
||||
get prop() {
|
||||
return _self$.something;
|
||||
},
|
||||
|
||||
onClick: () => _self$.shouldStay,
|
||||
|
||||
get children() {
|
||||
return _$createComponent(Nested, {
|
||||
get prop() {
|
||||
return _self$.data;
|
||||
},
|
||||
|
||||
get children() {
|
||||
return _self$.content;
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const Template14 = _$createComponent(Component, {
|
||||
get children() {
|
||||
return data();
|
||||
},
|
||||
});
|
||||
|
||||
const Template15 = _$createComponent(Component, props);
|
||||
|
||||
const Template16 = _$createComponent(
|
||||
Component,
|
||||
_$mergeProps(
|
||||
{
|
||||
something: something,
|
||||
},
|
||||
props
|
||||
)
|
||||
);
|
||||
|
||||
const Template17 = _$createComponent(Pre, {
|
||||
get children() {
|
||||
return [
|
||||
_tmpl$7.cloneNode(true),
|
||||
" ",
|
||||
_tmpl$8.cloneNode(true),
|
||||
" ",
|
||||
_tmpl$9.cloneNode(true),
|
||||
];
|
||||
},
|
||||
});
|
||||
|
||||
const Template18 = _$createComponent(Pre, {
|
||||
get children() {
|
||||
return [
|
||||
_tmpl$7.cloneNode(true),
|
||||
_tmpl$8.cloneNode(true),
|
||||
_tmpl$9.cloneNode(true),
|
||||
];
|
||||
},
|
||||
});
|
||||
|
||||
const Template19 = _$createComponent(
|
||||
Component,
|
||||
_$mergeProps(() => s.dynamic())
|
||||
);
|
||||
|
||||
const Template20 = _$createComponent(Component, {
|
||||
get ["class"]() {
|
||||
return prop.red ? "red" : "green";
|
||||
},
|
||||
});
|
||||
|
||||
const template21 = _$createComponent(
|
||||
Component,
|
||||
_$mergeProps(() => ({
|
||||
get [key()]() {
|
||||
return props.value;
|
||||
},
|
||||
}))
|
||||
);
|
||||
@@ -0,0 +1,71 @@
|
||||
const template1 = <div>{simple}</div>;
|
||||
|
||||
const template2 = <div>{state.dynamic}</div>;
|
||||
|
||||
const template3 = <div>{simple ? good : bad}</div>;
|
||||
|
||||
const template4 = <div>{simple ? good() : bad}</div>;
|
||||
|
||||
const template5 = <div>{state.dynamic ? good() : bad}</div>;
|
||||
|
||||
const template6 = <div>{state.dynamic && good()}</div>;
|
||||
|
||||
const template7 = (
|
||||
<div>{state.count > 5 ? (state.dynamic ? best : good()) : bad}</div>
|
||||
);
|
||||
|
||||
const template8 = <div>{state.dynamic && state.something && good()}</div>;
|
||||
|
||||
const template9 = <div>{(state.dynamic && good()) || bad}</div>;
|
||||
|
||||
const template10 = (
|
||||
<div>{state.a ? "a" : state.b ? "b" : state.c ? "c" : "fallback"}</div>
|
||||
);
|
||||
|
||||
const template11 = (
|
||||
<div>{state.a ? a() : state.b ? b() : state.c ? "c" : "fallback"}</div>
|
||||
);
|
||||
|
||||
const template12 = <Comp render={state.dynamic ? good() : bad} />;
|
||||
|
||||
// no dynamic predicate
|
||||
const template13 = <Comp render={state.dynamic ? good : bad} />;
|
||||
|
||||
const template14 = <Comp render={state.dynamic && good()} />;
|
||||
|
||||
// no dynamic predicate
|
||||
const template15 = <Comp render={state.dynamic && good} />;
|
||||
|
||||
const template16 = <Comp render={state.dynamic || good()} />;
|
||||
|
||||
const template17 = <Comp render={state.dynamic ? <Comp /> : <Comp />} />;
|
||||
|
||||
const template18 = <Comp>{state.dynamic ? <Comp /> : <Comp />}</Comp>;
|
||||
|
||||
const template19 = <div innerHTML={state.dynamic ? <Comp /> : <Comp />} />;
|
||||
|
||||
const template20 = <div>{state.dynamic ? <Comp /> : <Comp />}</div>;
|
||||
|
||||
const template21 = <Comp render={state?.dynamic ? "a" : "b"} />;
|
||||
|
||||
const template22 = <Comp>{state?.dynamic ? "a" : "b"}</Comp>;
|
||||
|
||||
const template23 = <div innerHTML={state?.dynamic ? "a" : "b"} />;
|
||||
|
||||
const template24 = <div>{state?.dynamic ? "a" : "b"}</div>;
|
||||
|
||||
const template25 = <Comp render={state.dynamic ?? <Comp />} />;
|
||||
|
||||
const template26 = <Comp>{state.dynamic ?? <Comp />}</Comp>;
|
||||
|
||||
const template27 = <div innerHTML={state.dynamic ?? <Comp />} />;
|
||||
|
||||
const template28 = <div>{state.dynamic ?? <Comp />}</div>;
|
||||
|
||||
const template29 = <div>{(thing() && thing1()) ?? thing2() ?? thing3()}</div>;
|
||||
|
||||
const template30 = <div>{thing() || thing1() || thing2()}</div>;
|
||||
|
||||
const template31 = (
|
||||
<Comp value={count() ? (count() ? count() : count()) : count()} />
|
||||
);
|
||||
@@ -0,0 +1,144 @@
|
||||
var _tmpl = template("<div</div>", 2), _tmpl$1 = template("<div/>", 0);
|
||||
const template1 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, simple, null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template2 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state.dynamic, null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template3 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, simple ? good : bad, null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template4 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, simple ? good() : bad, null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template5 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state.dynamic ? good() : bad, null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template6 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state.dynamic && good(), null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template7 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state.count > 5 ? state.dynamic ? best : good() : bad, null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template8 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state.dynamic && state.something && good(), null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template9 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state.dynamic && good() || bad, null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template10 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state.a ? "a" : state.b ? "b" : state.c ? "c" : "fallback", null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template11 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state.a ? a() : state.b ? b() : state.c ? "c" : "fallback", null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template12 = createComponent(Comp, {
|
||||
render: state.dynamic ? good() : bad
|
||||
});
|
||||
const template13 = createComponent(Comp, {
|
||||
render: state.dynamic ? good : bad
|
||||
});
|
||||
const template14 = createComponent(Comp, {
|
||||
render: state.dynamic && good()
|
||||
});
|
||||
const template15 = createComponent(Comp, {
|
||||
render: state.dynamic && good
|
||||
});
|
||||
const template16 = createComponent(Comp, {
|
||||
render: state.dynamic || good()
|
||||
});
|
||||
const template17 = createComponent(Comp, {
|
||||
render: state.dynamic ? createComponent(Comp, {}) : createComponent(Comp, {})
|
||||
});
|
||||
const template18 = createComponent(Comp, {
|
||||
get children: [
|
||||
state.dynamic ? createComponent(Comp, {}) : createComponent(Comp, {})
|
||||
]
|
||||
});
|
||||
const template19 = () => {
|
||||
var _el = _tmpl$1.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "innerHTML", state.dynamic ? createComponent(Comp, {}) : createComponent(Comp, {}));
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template20 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state.dynamic ? createComponent(Comp, {}) : createComponent(Comp, {}), null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template21 = createComponent(Comp, {
|
||||
render: state?.dynamic ? "a" : "b"
|
||||
});
|
||||
const template22 = createComponent(Comp, {
|
||||
get children: [
|
||||
state?.dynamic ? "a" : "b"
|
||||
]
|
||||
});
|
||||
const template23 = () => {
|
||||
var _el = _tmpl$1.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "innerHTML", state?.dynamic ? "a" : "b");
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template24 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state?.dynamic ? "a" : "b", null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template25 = createComponent(Comp, {
|
||||
render: state.dynamic ?? createComponent(Comp, {})
|
||||
});
|
||||
const template26 = createComponent(Comp, {
|
||||
get children: [
|
||||
state.dynamic ?? createComponent(Comp, {})
|
||||
]
|
||||
});
|
||||
const template27 = () => {
|
||||
var _el = _tmpl$1.cloneNode(true);
|
||||
effect(() => {
|
||||
return setAttribute(_el, "innerHTML", state.dynamic ?? createComponent(Comp, {}));
|
||||
});
|
||||
return _el;
|
||||
};
|
||||
const template28 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, state.dynamic ?? createComponent(Comp, {}), null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template29 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, (thing() && thing1()) ?? thing2() ?? thing3(), null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template30 = () => {
|
||||
var _tmpl = _tmpl.cloneNode(true);
|
||||
insert(_tmpl, thing() || thing1() || thing2(), null);
|
||||
return _tmpl;
|
||||
};
|
||||
const template31 = createComponent(Comp, {
|
||||
value: count() ? count() ? count() : count() : count()
|
||||
});
|
||||
@@ -0,0 +1,319 @@
|
||||
import { template as _$template } from "r-dom";
|
||||
import { effect as _$effect } from "r-dom";
|
||||
import { createComponent as _$createComponent } from "r-dom";
|
||||
import { memo as _$memo } from "r-dom";
|
||||
import { insert as _$insert } from "r-dom";
|
||||
|
||||
const _tmpl$ = /*#__PURE__*/ _$template(`<div></div>`, 2);
|
||||
|
||||
const template1 = (() => {
|
||||
const _el$ = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(_el$, simple);
|
||||
|
||||
return _el$;
|
||||
})();
|
||||
|
||||
const template2 = (() => {
|
||||
const _el$2 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(_el$2, () => state.dynamic);
|
||||
|
||||
return _el$2;
|
||||
})();
|
||||
|
||||
const template3 = (() => {
|
||||
const _el$3 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(_el$3, simple ? good : bad);
|
||||
|
||||
return _el$3;
|
||||
})();
|
||||
|
||||
const template4 = (() => {
|
||||
const _el$4 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(_el$4, () => (simple ? good() : bad));
|
||||
|
||||
return _el$4;
|
||||
})();
|
||||
|
||||
const template5 = (() => {
|
||||
const _el$5 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(
|
||||
_el$5,
|
||||
(() => {
|
||||
const _c$ = _$memo(() => !!state.dynamic, true);
|
||||
|
||||
return () => (_c$() ? good() : bad);
|
||||
})()
|
||||
);
|
||||
|
||||
return _el$5;
|
||||
})();
|
||||
|
||||
const template6 = (() => {
|
||||
const _el$6 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(
|
||||
_el$6,
|
||||
(() => {
|
||||
const _c$2 = _$memo(() => !!state.dynamic, true);
|
||||
|
||||
return () => _c$2() && good();
|
||||
})()
|
||||
);
|
||||
|
||||
return _el$6;
|
||||
})();
|
||||
|
||||
const template7 = (() => {
|
||||
const _el$7 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(
|
||||
_el$7,
|
||||
(() => {
|
||||
const _c$3 = _$memo(() => state.count > 5, true);
|
||||
|
||||
return () =>
|
||||
_c$3()
|
||||
? (() => {
|
||||
const _c$4 = _$memo(() => !!state.dynamic, true);
|
||||
|
||||
return () => (_c$4() ? best : good());
|
||||
})()
|
||||
: bad;
|
||||
})()
|
||||
);
|
||||
|
||||
return _el$7;
|
||||
})();
|
||||
|
||||
const template8 = (() => {
|
||||
const _el$8 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(
|
||||
_el$8,
|
||||
(() => {
|
||||
const _c$5 = _$memo(() => !!(state.dynamic && state.something), true);
|
||||
|
||||
return () => _c$5() && good();
|
||||
})()
|
||||
);
|
||||
|
||||
return _el$8;
|
||||
})();
|
||||
|
||||
const template9 = (() => {
|
||||
const _el$9 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(
|
||||
_el$9,
|
||||
(() => {
|
||||
const _c$6 = _$memo(() => !!state.dynamic, true);
|
||||
|
||||
return () => (_c$6() && good()) || bad;
|
||||
})()
|
||||
);
|
||||
|
||||
return _el$9;
|
||||
})();
|
||||
|
||||
const template10 = (() => {
|
||||
const _el$10 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(_el$10, () =>
|
||||
state.a ? "a" : state.b ? "b" : state.c ? "c" : "fallback"
|
||||
);
|
||||
|
||||
return _el$10;
|
||||
})();
|
||||
|
||||
const template11 = (() => {
|
||||
const _el$11 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(
|
||||
_el$11,
|
||||
(() => {
|
||||
const _c$7 = _$memo(() => !!state.a, true);
|
||||
|
||||
return () =>
|
||||
_c$7()
|
||||
? a()
|
||||
: (() => {
|
||||
const _c$8 = _$memo(() => !!state.b, true);
|
||||
|
||||
return () => (_c$8() ? b() : state.c ? "c" : "fallback");
|
||||
})();
|
||||
})()
|
||||
);
|
||||
|
||||
return _el$11;
|
||||
})();
|
||||
|
||||
const template12 = _$createComponent(Comp, {
|
||||
get render() {
|
||||
return _$memo(() => !!state.dynamic, true)() ? good() : bad;
|
||||
},
|
||||
}); // no dynamic predicate
|
||||
|
||||
const template13 = _$createComponent(Comp, {
|
||||
get render() {
|
||||
return state.dynamic ? good : bad;
|
||||
},
|
||||
});
|
||||
|
||||
const template14 = _$createComponent(Comp, {
|
||||
get render() {
|
||||
return _$memo(() => !!state.dynamic, true)() && good();
|
||||
},
|
||||
}); // no dynamic predicate
|
||||
|
||||
const template15 = _$createComponent(Comp, {
|
||||
get render() {
|
||||
return state.dynamic && good;
|
||||
},
|
||||
});
|
||||
|
||||
const template16 = _$createComponent(Comp, {
|
||||
get render() {
|
||||
return state.dynamic || good();
|
||||
},
|
||||
});
|
||||
|
||||
const template17 = _$createComponent(Comp, {
|
||||
get render() {
|
||||
return _$memo(() => !!state.dynamic, true)()
|
||||
? _$createComponent(Comp, {})
|
||||
: _$createComponent(Comp, {});
|
||||
},
|
||||
});
|
||||
|
||||
const template18 = _$createComponent(Comp, {
|
||||
get children() {
|
||||
return _$memo(() => !!state.dynamic, true)()
|
||||
? _$createComponent(Comp, {})
|
||||
: _$createComponent(Comp, {});
|
||||
},
|
||||
});
|
||||
|
||||
const template19 = (() => {
|
||||
const _el$12 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$effect(
|
||||
() =>
|
||||
(_el$12.innerHTML = state.dynamic
|
||||
? _$createComponent(Comp, {})
|
||||
: _$createComponent(Comp, {}))
|
||||
);
|
||||
|
||||
return _el$12;
|
||||
})();
|
||||
|
||||
const template20 = (() => {
|
||||
const _el$13 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(
|
||||
_el$13,
|
||||
(() => {
|
||||
const _c$9 = _$memo(() => !!state.dynamic, true);
|
||||
|
||||
return () =>
|
||||
_c$9() ? _$createComponent(Comp, {}) : _$createComponent(Comp, {});
|
||||
})()
|
||||
);
|
||||
|
||||
return _el$13;
|
||||
})();
|
||||
|
||||
const template21 = _$createComponent(Comp, {
|
||||
get render() {
|
||||
return state?.dynamic ? "a" : "b";
|
||||
},
|
||||
});
|
||||
|
||||
const template22 = _$createComponent(Comp, {
|
||||
get children() {
|
||||
return state?.dynamic ? "a" : "b";
|
||||
},
|
||||
});
|
||||
|
||||
const template23 = (() => {
|
||||
const _el$14 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$effect(() => (_el$14.innerHTML = state?.dynamic ? "a" : "b"));
|
||||
|
||||
return _el$14;
|
||||
})();
|
||||
|
||||
const template24 = (() => {
|
||||
const _el$15 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(_el$15, () => (state?.dynamic ? "a" : "b"));
|
||||
|
||||
return _el$15;
|
||||
})();
|
||||
|
||||
const template25 = _$createComponent(Comp, {
|
||||
get render() {
|
||||
return state.dynamic ?? _$createComponent(Comp, {});
|
||||
},
|
||||
});
|
||||
|
||||
const template26 = _$createComponent(Comp, {
|
||||
get children() {
|
||||
return state.dynamic ?? _$createComponent(Comp, {});
|
||||
},
|
||||
});
|
||||
|
||||
const template27 = (() => {
|
||||
const _el$16 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$effect(
|
||||
() => (_el$16.innerHTML = state.dynamic ?? _$createComponent(Comp, {}))
|
||||
);
|
||||
|
||||
return _el$16;
|
||||
})();
|
||||
|
||||
const template28 = (() => {
|
||||
const _el$17 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(_el$17, () => state.dynamic ?? _$createComponent(Comp, {}));
|
||||
|
||||
return _el$17;
|
||||
})();
|
||||
|
||||
const template29 = (() => {
|
||||
const _el$18 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(
|
||||
_el$18,
|
||||
(() => {
|
||||
const _c$10 = _$memo(() => !!thing(), true);
|
||||
|
||||
return () => (_c$10() && thing1()) ?? thing2() ?? thing3();
|
||||
})()
|
||||
);
|
||||
|
||||
return _el$18;
|
||||
})();
|
||||
|
||||
const template30 = (() => {
|
||||
const _el$19 = _tmpl$.cloneNode(true);
|
||||
|
||||
_$insert(_el$19, () => thing() || thing1() || thing2());
|
||||
|
||||
return _el$19;
|
||||
})();
|
||||
|
||||
const template31 = _$createComponent(Comp, {
|
||||
get value() {
|
||||
return _$memo(() => !!count(), true)()
|
||||
? _$memo(() => !!count(), true)()
|
||||
? count()
|
||||
: count()
|
||||
: count();
|
||||
},
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user