Compare commits

..

440 Commits

Author SHA1 Message Date
Jarred Sumner
ab04e82f55 good enough for now 2022-06-05 04:44:05 -07:00
Jarred Sumner
5aa196b361 take two 2022-06-04 20:01:33 -07:00
Jarred Sumner
9f640ffb51 impl #1 2022-06-03 18:49:12 -07:00
Jarred Sumner
af6859acc2 temp 2022-06-03 04:45:50 -07:00
Jarred Sumner
e5322eb63b Move streams to it's own file 2022-06-03 04:44:11 -07:00
Jarred Sumner
102553dca6 Update streams.test.js 2022-06-03 04:43:38 -07:00
Jarred Sumner
549e5bbbcd Handle empty files/blobs 2022-06-02 18:36:10 -07:00
Jarred Sumner
57ad68a4b0 Fix off by one & exceptions 2022-06-02 17:55:03 -07:00
Jarred Sumner
e5eabc0658 Faster ReadableStream 2022-06-02 03:00:45 -07:00
Jarred Sumner
121c2960de Create bun-jsc.test.js 2022-06-01 07:31:14 -07:00
Jarred Sumner
a96a2a8b12 Update WebKit 2022-06-01 07:29:11 -07:00
Jarred Sumner
6e8a30e999 Update mimalloc 2022-06-01 07:29:05 -07:00
Jarred Sumner
7b455492d3 Update Makefile 2022-06-01 07:29:00 -07:00
Jarred Sumner
f9710e270a Update streams.test.js 2022-06-01 07:28:56 -07:00
Jarred Sumner
515da14621 More streams 2022-06-01 07:28:53 -07:00
Jarred Sumner
b735de0d3f bun:jsc 2022-06-01 07:28:35 -07:00
Jarred Sumner
bf28afad1d Add releaseWEakrefs binding 2022-06-01 07:28:19 -07:00
Jarred Sumner
73ad5c4f67 More WebKit updates 2022-06-01 07:27:59 -07:00
Jarred Sumner
73ec79fa8e WebKit updates 2022-06-01 07:27:39 -07:00
Jarred Sumner
3083718e3f faster async/await + readablestream optimizations 2022-05-30 17:11:39 -07:00
Jarred Sumner
17cdc0fee6 fix segfault 2022-05-30 17:11:39 -07:00
Jarred Sumner
26c890d3a1 make jsc bindings a little easier to work with 2022-05-30 17:11:39 -07:00
Jarred Sumner
564b6d12f0 [fs.readFile] Improve performance 2022-05-30 17:11:39 -07:00
Jarred Sumner
f4aa3a8c34 Add an extra function 2022-05-30 17:11:39 -07:00
Jarred Sumner
ed63b22f7a Implement Bun.file(pathOrFd).stream() 2022-05-30 17:11:39 -07:00
Jarred Sumner
b18b0efb8b Implement Blob.stream() 2022-05-30 17:11:39 -07:00
Jarred Sumner
7f3bc2b9e6 start to implement native streams 2022-05-30 17:11:36 -07:00
Jarred Sumner
c362729186 reading almost works 2022-05-30 17:11:14 -07:00
Jarred Sumner
f0e58fec49 [TextEncoder] 3x faster in hot loops 2022-05-30 17:11:14 -07:00
Jarred Sumner
9fcc5f27e8 Fix sourcemaps crash 2022-05-30 17:11:14 -07:00
Jarred Sumner
ab2d25bfec Update streams.test.js 2022-05-30 17:11:14 -07:00
Jarred Sumner
3e55023819 Implement Blob.stream() 2022-05-30 17:11:12 -07:00
Jarred Sumner
4fb9354439 [bun.js] WritableStream, ReadableStream, TransformStream, WritableStreamDefaultController, ReadableStreamDefaultController & more 2022-05-30 17:10:47 -07:00
Jarred Sumner
958fc3d4f5 Update .gitignore 2022-05-30 03:50:35 -07:00
Jarred Sumner
aecc849692 Improve error messages when you mistype commands/files/scripts 2022-05-30 03:50:24 -07:00
Jarred Sumner
882559f0b9 Load bunfig.toml by default if bun or bun {file}\.[cjt]sx?
Fixes https://github.com/Jarred-Sumner/bun/issues/183
2022-05-30 03:50:24 -07:00
Alexander Kuznetsov
ca21c00f86 Remove generated files from git index (#182) 2022-05-30 01:13:12 -07:00
M Javad
960cb1a8d5 docs: fix typo in readme (#179) 2022-05-20 12:26:15 -07:00
Jarred Sumner
8a3a5c3b74 Update string_mutable.zig 2022-05-20 00:59:50 -07:00
Jarred Sumner
99d61877d6 [solid] more progress, no fragments, but still not right 2022-05-20 00:45:51 -07:00
Jarred Sumner
224cfa91fb [TSConfig] Propagate runtime from tsconfig.json 2022-05-19 21:10:11 -07:00
Jarred Sumner
1af67dbe15 woops 2022-05-19 19:44:19 -07:00
Jarred Sumner
55bfa6cd02 Update cache.zig 2022-05-19 19:27:25 -07:00
Jarred Sumner
1d0124093c [solid] Move the post-process JSX step 2022-05-19 19:27:23 -07:00
Jarred Sumner
70078f48c0 [bun de] Fix crash when printing source maps 2022-05-19 19:26:45 -07:00
Jarred Sumner
44d1b217ac move js_parser to src/ 2022-05-19 17:52:40 -07:00
Jarred Sumner
3672bb85eb [solid] wip make nested components work 2022-05-19 17:52:07 -07:00
Jarred Sumner
6f741e8c10 Symbols 2022-05-19 05:37:30 -07:00
Jarred Sumner
d4767ca763 [wip] Solid.js support for Bun! 2022-05-19 05:37:18 -07:00
Jarred Sumner
07e695da03 add a test 2022-05-16 23:05:21 -07:00
Jarred Sumner
4f72021007 Update README.md 2022-05-16 21:14:34 -07:00
Jarred Sumner
bc73d21917 Update types.d.ts 2022-05-16 20:54:01 -07:00
Jarred Sumner
7ca297a5cc Update download-northwind.sh 2022-05-16 19:51:30 -07:00
Jarred Sumner
e114fca5ee Still not correct! 2022-05-16 19:33:19 -07:00
Jarred Sumner
d0ca9f2499 Update README.md 2022-05-16 19:28:29 -07:00
Jarred Sumner
95daafee0f Update serve.test.ts 2022-05-16 19:26:57 -07:00
Jarred Sumner
37e4848c6f work around test failure 2022-05-16 19:25:49 -07:00
Jarred Sumner
78cd9e89f3 Update sqlite3.c 2022-05-16 19:15:10 -07:00
Jarred Sumner
15c40f5ea3 Fix build error on linux 2022-05-16 19:12:22 -07:00
Jarred Sumner
5f3256d939 Update Makefile 2022-05-16 19:06:01 -07:00
Jarred Sumner
a2b22c339e Update sqlite.d.ts 2022-05-16 19:03:30 -07:00
Jarred Sumner
aed5e39f4d remove bad examples 2022-05-16 19:02:38 -07:00
Jarred Sumner
bd1e64b9b1 Fix type errors 2022-05-16 18:58:11 -07:00
Jarred Sumner
31f3050356 Bump 2022-05-16 18:53:33 -07:00
Jarred Sumner
ba36f5db7e prepare for release 2022-05-16 18:45:46 -07:00
Jarred Sumner
a372a0dd6d Update JSSQLStatement.cpp 2022-05-16 18:24:55 -07:00
Jarred Sumner
aba032e176 Copy strings when binding to sqlite 2022-05-16 18:19:08 -07:00
Jarred Sumner
e31f44c3d1 Update README.md 2022-05-16 17:40:33 -07:00
Jarred Sumner
0d12a1f9ee reset on stmt on error 2022-05-16 17:18:50 -07:00
Jarred Sumner
036eb2a9ed Update README.md 2022-05-16 16:34:05 -07:00
Jarred Sumner
2eb889be89 Update README.md 2022-05-16 16:33:13 -07:00
Jarred Sumner
dd07717b80 Update README.md 2022-05-16 16:28:48 -07:00
Jarred Sumner
36a82cfb93 Update README.md 2022-05-16 16:26:32 -07:00
Jarred Sumner
6fce02bd85 Update sqlite.d.ts 2022-05-16 16:25:54 -07:00
Jarred Sumner
93767bf78f Update .gitattributes 2022-05-16 16:24:42 -07:00
Jarred Sumner
a779fc180f Update README.md 2022-05-16 16:07:59 -07:00
Jarred Sumner
223ce6b22d Update README.md 2022-05-16 16:00:30 -07:00
Jarred Sumner
5d4673742e Update README.md 2022-05-16 15:59:57 -07:00
Jarred Sumner
05eb1e5684 Update README.md 2022-05-16 15:57:45 -07:00
Jarred Sumner
b4ac7697ac Update README.md 2022-05-16 15:55:35 -07:00
Jarred Sumner
2cfc1d42a3 Update README.md 2022-05-16 15:52:05 -07:00
Jarred Sumner
be1f469ec5 Update README.md 2022-05-16 15:48:56 -07:00
Jarred Sumner
a37f86e89d bun:sqlite (#167)
* ✂️

* Add the slow version

* draw the rest of the owl

* Fix crash when allocating lots of memory

* [Bun.Transipiler] Support passing objects

* [JS Parser] Support passing objects to macros via Bun.Transpiler

* Update JSSQLStatement.cpp

* Embed SQLite

* Add SQLite to Dockerfile

* [sqlite] Add quick one-off queries without creating a whole object

* [sqlite] Add `columnsCount`, rename raw() to `values()`, remove `rebind`

* Implement `bun:sqlite`

* return null

* Fix updating query

* Update bun.d.ts

* more tests

* Support variadic arguments, write tests and add types

* Update sqlite.d.ts

* Update sqlite.d.ts

* latest

* Implement `Database.loadExtension` and `Database.setCustomSQLite`

* Support `require.resolve`

* [napi] Improve string performance

* [bun.js] Support some of `node:module`

* another test

* [sqlite] Support serialize & deserialize

* [`bun:ffi`] Implement `CFunction` and `linkSymbols`

* [bun.js] Fix crash in `Buffer.from`

* Update sqlite.test.js

* Document linkSymbols

* docs

* Update README.md
2022-05-16 15:46:20 -07:00
Divy Srivastava
2bd0dcfdfa Add go and esbuild to build instructions (#169) 2022-05-16 13:55:14 -07:00
Hugo Romano
e75535d14c wrangler 2 released (#166) 2022-05-12 14:43:44 -07:00
Jarred Sumner
1d6923bead Update README.md 2022-05-11 19:12:00 -07:00
Jarred Sumner
732124e3dd Update README.md 2022-05-11 19:11:17 -07:00
Jarred Sumner
a15e66cc7b Add section about napi 2022-05-11 19:08:46 -07:00
Jarred Sumner
3eacfe2314 Update README.md 2022-05-11 18:29:05 -07:00
Jarred Sumner
89c0d9dd56 Update build-id 2022-05-11 17:57:55 -07:00
Jarred Sumner
b21d0f0b22 Fix several bugs in napi
Closes https://github.com/Jarred-Sumner/bun/issues/163
Closes https://github.com/Jarred-Sumner/bun/issues/162
Closes https://github.com/Jarred-Sumner/bun/issues/161
2022-05-11 17:49:18 -07:00
Jarred Sumner
61b2821472 Make the napi mjs file runnable in both bun & node 2022-05-11 15:12:17 -07:00
Jarred Sumner
1f86e0c87e Update build-id 2022-05-11 04:47:34 -07:00
Jarred Sumner
d1ea51e9f2 disable the new target allowed error 2022-05-11 04:45:47 -07:00
Jarred Sumner
5de2e2c71e Update Makefile 2022-05-11 04:05:08 -07:00
Jarred Sumner
2c1051f539 Update Makefile 2022-05-11 03:46:00 -07:00
Jarred Sumner
247f4810c5 Fix export symbols on Linux 2022-05-11 03:45:00 -07:00
Jarred Sumner
47b6dc9eea Add test for import.meta.require 2022-05-11 03:19:29 -07:00
Jarred Sumner
aea3b4e280 [napi] Add a couple more symbols 2022-05-11 02:59:46 -07:00
Jarred Sumner
12e0496a79 [napi] Fix panic inside napi_fatal_error 2022-05-11 02:59:38 -07:00
Jarred Sumner
aa87d40f4b [napi] Stub a couple more 2022-05-11 02:59:22 -07:00
Jarred Sumner
7d1eced8c6 [bun.js] eagerly convert to import.meta.require 2022-05-11 02:57:51 -07:00
Jarred Sumner
123267685f [json] Fix bug with negative integers in json parser 2022-05-11 02:56:46 -07:00
Jarred Sumner
0bec7001ba [bun.js] Implement a polyfill for the detect-libc npm package 2022-05-11 00:57:06 -07:00
Jarred Sumner
3c87fbfd37 [bun.js] Implement import.meta.require
This allows synchronous dynamic loading of `.node`, `.json`, and `.toml` files.

It is not a CommonJS require, but it can be used that way so long as the content is not JavaScript.
2022-05-11 00:56:35 -07:00
Jarred Sumner
fd00950852 [bun.js] Implement import.meta.resolveSync 2022-05-11 00:54:42 -07:00
Jarred Sumner
eb2a6aee4d Include napi in plus100 2022-05-10 20:50:38 -07:00
Jarred Sumner
84e8d08ec6 Add test for Buffer.byteLength 2022-05-10 20:47:51 -07:00
Jarred Sumner
92e8eaf581 [napi] Error on import .node 2022-05-10 20:47:38 -07:00
Jarred Sumner
e8e58a511f Update napi.cpp 2022-05-10 20:44:25 -07:00
Jarred Sumner
08e40efe11 [napi] Fix string bug 2022-05-10 20:24:07 -07:00
Jarred Sumner
01a0aee1e8 [napi] transpile require(*.node) into process.dlopen 2022-05-10 19:12:15 -07:00
Jarred Sumner
8def37c14e [bun.js] Implement Buffer.byteLength 2022-05-10 19:09:28 -07:00
Jarred Sumner
b3760cd723 Fix extra quote in bundled require errors 2022-05-09 23:01:05 -07:00
Jarred Sumner
1cb870be16 few more napi functions 2022-05-09 22:39:22 -07:00
Jarred Sumner
35232fa422 Update Makefile 2022-05-09 22:07:47 -07:00
Jarred Sumner
77342a2268 Update Dockerfile.base 2022-05-09 22:01:56 -07:00
Jarred Sumner
b834e21192 [napi] getters & setters work 2022-05-09 21:58:41 -07:00
Jarred Sumner
f4188b3ddc Add test for __dirname 2022-05-09 21:54:08 -07:00
Jarred Sumner
963c08d472 Update symbols.txt 2022-05-09 21:54:00 -07:00
Jarred Sumner
29b9ced11a Update bindings.cpp 2022-05-09 21:53:44 -07:00
Jarred Sumner
8ac108ba06 [napi] Move some code to C++ for perf 2022-05-09 04:11:48 -07:00
Jarred Sumner
8014a0b8d8 [napi] Support import and require of .node modules 2022-05-09 00:24:25 -07:00
Jarred Sumner
3bd83eb134 [napi] Fix strings 2022-05-09 00:23:51 -07:00
Jarred Sumner
a5ebcefeeb fixup 2022-05-09 00:23:35 -07:00
Jarred Sumner
c806e778d6 [JS Parser] Support __dirname and __filename 2022-05-09 00:00:01 -07:00
Jarred Sumner
3850fc5b0b Make a lot more stuff work 2022-05-08 17:37:58 -07:00
Jarred Sumner
6bac11f066 Create change-array-by-copy.js 2022-05-08 17:37:36 -07:00
Jarred Sumner
bc2ca8afbd Update WebKit 2022-05-08 01:34:53 -07:00
Jarred Sumner
e403b6111f more napi 2022-05-08 01:32:20 -07:00
Jarred Sumner
d613ba5fcd Update serve.test.ts 2022-05-08 01:14:21 -07:00
Jarred Sumner
4dee9be3eb Update http-file.ts 2022-05-08 01:13:03 -07:00
Jarred Sumner
61afb8955c Update build-id 2022-05-08 01:12:56 -07:00
Jarred Sumner
61d548c7bf [bun.js] Fix bug with headers not being sent in fetch 2022-05-08 01:12:46 -07:00
Jarred Sumner
c1efeefb8a Ugprade webkit 2022-05-08 01:12:27 -07:00
Jarred Sumner
3b6c3d8196 Update wtf-bindings.cpp 2022-05-08 01:12:20 -07:00
Jarred Sumner
97cceb47b9 Upgrade WebKit 2022-05-08 01:12:13 -07:00
Jarred Sumner
94637711b9 Update zlib.test.js 2022-05-07 13:27:23 -07:00
Jarred Sumner
bdf28e42f6 [bun.js] Support gzipSync, gunzipSync, inflateSync, deflateSync 2022-05-07 01:38:26 -07:00
Jarred Sumner
1687455a3f [napi] Fix function arguments 2022-05-06 06:43:49 -07:00
Jarred Sumner
84e40a4f74 symbols list 2022-05-06 00:37:23 -07:00
Jarred Sumner
bce60a5a86 more napi 2022-05-06 00:05:31 -07:00
Jarred Sumner
a7b0bc8790 it can call functions 2022-05-05 21:35:08 -07:00
Jarred Sumner
30ca112260 napi_threadsafe_function 2022-05-05 21:35:08 -07:00
Jarred Sumner
b487eb7e13 Update napi.zig 2022-05-05 21:35:08 -07:00
Jarred Sumner
5d24f45ac1 Update napi.zig 2022-05-05 21:35:08 -07:00
Jarred Sumner
c1f65ef975 napi_get_dataview_info? 2022-05-05 21:35:08 -07:00
Jarred Sumner
d6ce585ef3 cleanup hook 2022-05-05 21:35:08 -07:00
Jarred Sumner
c80e048ab3 implement napi_async_work 2022-05-05 21:35:08 -07:00
Jarred Sumner
b6a8675658 typeof 2022-05-05 21:35:08 -07:00
Jarred Sumner
2c0c91e2d0 more 2022-05-05 21:35:08 -07:00
Jarred Sumner
6b97680224 Update napi.zig 2022-05-05 21:35:08 -07:00
Jarred Sumner
c76bebca0b more 2022-05-05 21:35:08 -07:00
Jarred Sumner
b534c4d661 More 2022-05-05 21:35:08 -07:00
Jarred Sumner
170d09b6bd More 2022-05-05 21:35:08 -07:00
Jarred Sumner
b4fc584d18 Even More NAPI 2022-05-05 21:35:08 -07:00
Jarred Sumner
5b2d9f8128 Begin napi 2022-05-05 21:35:08 -07:00
Jarred Sumner
d629cfafd6 E.String gets a Rope 2022-05-05 21:32:19 -07:00
Jarred Sumner
7b125c9731 Update README.md 2022-05-04 09:02:25 -07:00
Jarred Sumner
0e3df25526 specifically check utf8 2022-05-04 07:03:55 -07:00
Jarred Sumner
66e8d7346f make our http test run more 2022-05-04 07:03:46 -07:00
Jarred Sumner
d29dcf3680 Document FFIType.i64_fast 2022-05-04 07:03:38 -07:00
Jarred Sumner
164483c137 Update buffer.js 2022-05-04 07:03:22 -07:00
Jarred Sumner
6ab5ae8a7a Fix type errors 2022-05-04 00:33:42 -07:00
Jarred Sumner
5b760fe7c4 Safer i64/u64 2022-05-04 00:16:36 -07:00
Jarred Sumner
162e8911db Fix x64 build 2022-05-03 22:36:44 -07:00
Jarred Sumner
bea2cc9cbc Update Makefile 2022-05-03 21:36:22 -07:00
Jarred Sumner
ce2261dffa don't automatically run clang-format because it ignores the disable flag 2022-05-03 21:34:45 -07:00
Jarred Sumner
fa562fa56d Handle missing x64 symbols 2022-05-03 21:30:29 -07:00
Jarred Sumner
5bfd241167 Update tinycc 2022-05-03 20:49:57 -07:00
Jarred Sumner
5a85cc4386 [bun:ffi] fix panic in lib.close() 2022-05-03 20:19:33 -07:00
Jarred Sumner
ed4a021f85 Bump WebKit 2022-05-03 19:50:05 -07:00
Jarred Sumner
83c1d7c9ef Update add.rs 2022-05-03 08:03:06 -07:00
Jarred Sumner
de6aed65fb Forgot about base64 2022-05-03 04:42:17 -07:00
Jarred Sumner
57ce49654c wrong dir 2022-05-03 04:35:49 -07:00
Jarred Sumner
00bc2638ce Fix tinycc build on linux 2022-05-03 04:10:06 -07:00
Jarred Sumner
4605aff04a Fix webkit linux build 2022-05-03 04:09:23 -07:00
Jarred Sumner
d104c286c8 Update README.md 2022-05-03 03:41:43 -07:00
Jarred Sumner
16d5325874 Add tinycc dependency 2022-05-03 03:38:59 -07:00
Jarred Sumner
e3362a0fda clarify 2022-05-03 02:35:05 -07:00
Jarred Sumner
f0fdda5678 Update README.md 2022-05-03 02:28:26 -07:00
Jarred Sumner
bb2d67e361 Update README.md 2022-05-03 02:21:45 -07:00
Jarred Sumner
91e96a8da8 ffi overhead bench 2022-05-03 02:11:59 -07:00
Jarred Sumner
8b1924f6c2 Add docs for FFI 2022-05-03 01:25:46 -07:00
Jarred Sumner
c6d732eee2 [bun:ffi] Improve uint64_t and int64_t performance 2022-05-02 20:26:18 -07:00
Jarred Sumner
21ab47d9fe [bun:ffi] Support i64 and u64 2022-05-02 06:26:03 -07:00
Jarred Sumner
d70e92e79f [bun:ffi] Support double and float 2022-05-02 04:37:24 -07:00
Jarred Sumner
15466865e0 add a comment 2022-05-02 03:46:57 -07:00
Jarred Sumner
125a4c747b [bun:ffi] cleanup 2022-05-02 03:40:14 -07:00
Jarred Sumner
69668d49e5 [bun.js] Add Bun.nanoseconds() to report time in nanos 2022-05-02 03:36:26 -07:00
Jarred Sumner
5cee316d8c [bun:ffi] ~20% faster FFI bindings for functions with arguments 2022-05-02 03:23:42 -07:00
Jarred Sumner
98393ca849 Automatic CString support 2022-05-02 03:11:43 -07:00
Jarred Sumner
012564d738 [bun:ffi] Add wrapper for type coercion 2022-05-01 07:41:51 -07:00
Jarred Sumner
3403621fc2 wip Buffer.fill 2022-05-01 07:41:26 -07:00
Jarred Sumner
de23f2f8aa Buffer.compare & Buffer.equal 2022-05-01 04:36:17 -07:00
Jarred Sumner
b6aa988716 [bun.js] Improve Buffer creation perf a little 2022-05-01 03:43:52 -07:00
Jarred Sumner
a3b48b3229 [bun.js] Implement Buffer.concat 2022-05-01 02:22:13 -07:00
Jarred Sumner
d7ef268e18 Bump WebKit 2022-04-30 23:58:56 -07:00
Jarred Sumner
ba999c9ac3 cleanup 2022-04-30 23:58:46 -07:00
Jarred Sumner
92b27b338d [bun.js] Implement Buffer.from and Buffer.copy 2022-04-30 23:58:27 -07:00
Jarred Sumner
eb129d9f90 [bun ffi] Fix missing "void" 2022-04-30 23:56:41 -07:00
Jarred Sumner
5e270f9d77 [bun ffi] Remove dependency on libtcc1.a and improve error messages 2022-04-30 23:56:31 -07:00
Jarred Sumner
7e13d6cbfe wip 2022-04-30 08:35:48 -07:00
Jarred Sumner
7e6fe52c46 Update ffi-test.c 2022-04-30 05:57:25 -07:00
Jarred Sumner
893d245dca a 2022-04-30 05:56:46 -07:00
Jarred Sumner
516b54578d [bun:ffi] it works 2022-04-29 23:21:14 -07:00
Jarred Sumner
d49ba50289 [bun.js] Implement unsafe.{arrayBufferToPtr, arrayBufferFromPtr, bufferFromPtr} 2022-04-29 07:49:48 -07:00
Jarred Sumner
22f74756b4 [bun ffi] Support pointers 2022-04-29 06:08:36 -07:00
Jarred Sumner
f07463bdfd [bun ffi] support i32, i8, u8, u16, i16, u32, bool 2022-04-29 05:02:01 -07:00
Jarred Sumner
75374fdc32 more tests for buffer 2022-04-29 00:47:26 -07:00
Jarred Sumner
0332d47424 add more to buffer implementation 2022-04-29 00:47:26 -07:00
Jarred Sumner
d531d0851f ffi test code 2022-04-29 00:47:26 -07:00
Jarred Sumner
e26f96b748 wip 2022-04-29 00:47:26 -07:00
Jarred Sumner
8fa1c5ebf1 commit more 2022-04-29 00:47:26 -07:00
Jarred Sumner
ef18443b6e some tests but need more 2022-04-29 00:47:26 -07:00
Jarred Sumner
d066c7de30 Add JIT FFI 2022-04-29 00:47:26 -07:00
Jarred Sumner
fd56d0f116 more work on buffer 2022-04-28 06:56:28 -07:00
Jarred Sumner
77fbfb3fbb Most of Buffer.toString 2022-04-26 01:12:28 -07:00
Jarred Sumner
6590d1f8bf 2x - 10x faster TextEncoder & TextDecoder 2022-04-25 19:58:57 -07:00
Jarred Sumner
2d39e44520 Update .gitignore 2022-04-25 16:47:33 -07:00
Jarred Sumner
2c6e5c3fc4 some of buffer 2022-04-25 07:09:18 -07:00
Jarred Sumner
4b4df5095e Update Makefile 2022-04-23 04:12:39 -07:00
Jarred Sumner
1c11dc6630 Update Dockerfile.base 2022-04-23 03:33:21 -07:00
Jarred Sumner
2eb3319351 Bump build 2022-04-23 03:15:35 -07:00
Jarred Sumner
683b171c3f 📷 2022-04-23 03:15:27 -07:00
Jarred Sumner
ea241fcec7 [JS Parser] Fix overly-eager CJS -> ESM transform 2022-04-23 03:15:13 -07:00
Lawrence Chen
ab1d83fe8d Add bun run ${script-name} clarification (#151) 2022-04-21 00:55:15 -07:00
Jarred Sumner
5e739acfbb [misc] Fix broken build on macOS 2022-04-20 23:46:11 -07:00
Jarred Sumner
a4b8fccfa7 [misc] explain why wasm isn't released yet 2022-04-18 21:56:20 -07:00
Jarred Sumner
9822ea96b8 [misc] Recommend VSCode extensions 2022-04-18 21:44:31 -07:00
Jarred Sumner
94db83040e [misc] Set editor.formatOnSave 2022-04-18 21:44:31 -07:00
wangao
12f97f1364 [node] Remove constants definition in (#146)
... fs.exports.js

Bug: #130
2022-04-18 21:26:06 -07:00
wangao
0aacddb971 [timer] Remove timer.zig and use system_timer.zig (#149) 2022-04-18 21:25:53 -07:00
wangao
7e866bb441 [build] Fix Dockerfile COPY slash (#147) 2022-04-18 21:19:03 -07:00
Jarred Sumner
c2cf1d6493 not sure yet 2022-04-18 21:18:37 -07:00
Jarred Sumner
612fad706f fix wasm build take 2 (one more thing is broken) 2022-04-18 20:51:10 -07:00
Jarred Sumner
6728551dc4 Fix wasm build 2022-04-18 17:41:58 -07:00
wangao
64a2dda02f [node] Add more fs constants (#144)
Move fs constants to node_fs_constants.zig,
and we static append the constants definition
to fs.export.js.

Issue: #130
2022-04-18 06:14:21 -07:00
Jarred Sumner
8d28e72e8a Move some code around + delete dead code 2022-04-16 17:33:16 -07:00
Jarred Sumner
0137e5cf94 [JS Parser] Support explicit removing 2022-04-16 09:29:10 -07:00
Jarred Sumner
89ca887ea0 Workaround C ABI bug 2022-04-16 05:32:57 -07:00
Jarred Sumner
42414d5667 [JS Parser] API for removing & replacing exports 2022-04-16 04:36:00 -07:00
Jarred Sumner
8bb283e616 Update README.md 2022-04-15 16:54:58 -07:00
Jarred Sumner
32e2345e53 Document how tests work 2022-04-15 16:50:38 -07:00
Jarred Sumner
9e31602a20 Update css_scanner.zig 2022-04-14 00:39:55 -07:00
Jarred Sumner
5d0be616b7 add some more assertions 2022-04-13 21:58:28 -07:00
Jarred Sumner
e7251c0d55 [css] Fix crash on empty files in some cases 2022-04-13 21:55:42 -07:00
Jarred Sumner
1871bbc6a4 Add sha hashing example 2022-04-13 21:46:02 -07:00
Jarred Sumner
add1c91425 Warn about moduleSuffixes 2022-04-13 21:46:02 -07:00
Jarred Sumner
1788503892 [bun dev] Fix CSS HMR bug 2022-04-13 21:46:02 -07:00
evan
95aa76b9fa expose mmap size and offset option (#141)
* expose mmap size and offset option

* fix panics
2022-04-13 19:08:56 -07:00
Jarred Sumner
95101870e4 better to fix it there 2022-04-13 18:53:53 -07:00
Jarred Sumner
f2c21b7733 [bun.js] Fix bug with readdirSync on folders with less than 32 files
Closes https://github.com/Jarred-Sumner/bun/issues/143
2022-04-13 18:48:09 -07:00
Jarred Sumner
d273948f16 Update bun.d.ts 2022-04-13 05:07:33 -07:00
Jarred Sumner
bb79687f8e Even More Comments 2022-04-13 04:44:05 -07:00
Jarred Sumner
3db3057d42 Support digest("base64" | "hex") in the hashings 2022-04-13 04:20:05 -07:00
Jarred Sumner
f6d73cb06e [bun.js] Implement Bun.sha1, Bun.sha256, Bun.sha384, Bun.sha512, Bun.sha512_384 2022-04-12 22:59:52 -07:00
evan
b3522b2feb add depth limit to .gitmodules (#142)
fixes situations where git client automatically downloads all submodules without depth limit
2022-04-12 18:30:03 -07:00
Jarred Sumner
710edd34d2 maybe this fixes it? 2022-04-12 04:53:47 -07:00
Jarred Sumner
743ad44c0a Make sendfile more reliable 2022-04-12 03:46:21 -07:00
Jarred Sumner
9db701ab41 wip fixes to sendfile() blocking 2022-04-12 00:43:23 -07:00
Jarred Sumner
a0f9a6ed60 Add a very simple http server test 2022-04-11 19:10:06 -07:00
Jarred Sumner
1d79703d24 slight perf improvement to concurrently queueing tasks 2022-04-11 19:09:14 -07:00
Jarred Sumner
f357377de9 always tick the event loop 2022-04-11 19:08:51 -07:00
Jarred Sumner
87adeb61c5 isize is a little faster normally 2022-04-11 19:05:09 -07:00
Jarred Sumner
e6a5cab1d2 Fix readme link 2022-04-11 16:53:30 -07:00
Jarred Sumner
9884a5fe14 Update http-stop.ts 2022-04-11 05:59:39 -07:00
Jarred Sumner
55ff561429 Add example for stopping HTTP server 2022-04-11 05:20:44 -07:00
Jarred Sumner
4708dd26ca work around fetch("localhost") bug 2022-04-11 05:17:02 -07:00
Jarred Sumner
3e969244ac [bun.js] Add a Server.stop function 2022-04-11 04:58:29 -07:00
Jarred Sumner
ac3835227e Update comptime_string_map.zig 2022-04-11 01:44:25 -07:00
Jarred Sumner
c6393bcd27 ✂️ dead code 2022-04-11 01:44:22 -07:00
Jarred Sumner
7d164ad8c7 Update globals.d.ts 2022-04-10 19:48:44 -07:00
Jarred Sumner
3abb72037b [bun-types] Document JavaScriptCore's ES Module loader 2022-04-10 19:46:05 -07:00
Jarred Sumner
34c478a4c4 make checking for bun modules a compile time step 2022-04-10 19:45:43 -07:00
Jarred Sumner
98592fb85d [TOML] Fix toml parsing with multiple keys in object literal
Fixes https://github.com/Jarred-Sumner/bun/issues/140
2022-04-10 17:41:48 -07:00
Jarred Sumner
6edf0289ed Fix type errors 2022-04-10 05:23:02 -07:00
Jarred Sumner
faedbf0a61 Update bun.d.ts 2022-04-10 05:16:06 -07:00
Jarred Sumner
b08d3b2cd6 Update linker.zig 2022-04-10 05:02:14 -07:00
Jarred Sumner
1e810d229e Fix tests 2022-04-10 04:57:51 -07:00
Jarred Sumner
a82c486878 fix linux build 2022-04-10 04:35:40 -07:00
Jarred Sumner
d42ae4824b Update Makefile 2022-04-10 04:34:06 -07:00
Jarred Sumner
b1ebe54456 [bun.js] Support a "bun" import 2022-04-10 04:30:31 -07:00
Jarred Sumner
ac76e3b004 Move some types around 2022-04-10 04:30:09 -07:00
Jarred Sumner
43b18663fd [bun] fix bun bun --platform=bun 2022-04-10 04:24:53 -07:00
Jarred Sumner
45e1fc946d [bun-types] Make it bundle the types 2022-04-10 04:24:24 -07:00
Jarred Sumner
65eb232028 Bump 2022-04-09 22:18:32 -07:00
Jarred Sumner
7cd3d13011 [fs] Add missing isFile and isDirectory functions to stat() 2022-04-09 21:45:46 -07:00
Jarred Sumner
764fb63617 Update transpiler.test.js 2022-04-09 20:26:02 -07:00
Jarred Sumner
4de7978b27 [JS Parser] Fix code simplification bug with ! and unary expressions 2022-04-09 20:23:36 -07:00
Jarred Sumner
696bb3b026 stricter boolean check 2022-04-09 20:06:58 -07:00
Jarred Sumner
fb82e2bf86 Update build-id 2022-04-08 23:47:10 -07:00
Jarred Sumner
403a916bd5 [bun-framework-next] Fix missing scripts 2022-04-08 23:43:41 -07:00
Jarred Sumner
20cdb197e2 Fix Next.js stylesheet bug 2022-04-08 23:16:13 -07:00
Jarred Sumner
1f68b8ada0 remove some code bloat 2022-04-08 16:55:58 -07:00
Jarred Sumner
fdfbf16940 Update watcher.zig 2022-04-08 16:54:20 -07:00
Jarred Sumner
12c2659765 [bun dev] Fix race condition in file watcher 2022-04-08 16:45:24 -07:00
Jarred Sumner
8561dcdee4 Immediately inject fast refresh once 2022-04-08 16:44:08 -07:00
Jarred Sumner
ded2bcfda5 Update README.md 2022-04-08 06:32:34 -07:00
Jarred Sumner
d5173f71d4 Update README.md 2022-04-08 06:32:29 -07:00
Jarred Sumner
61ca99cfd9 Update README.md 2022-04-08 06:32:24 -07:00
Jarred Sumner
862155fa5e I think fix hmr regression? 2022-04-08 06:32:12 -07:00
Jarred Sumner
74309a1f9e Fix hardlink fallback 2022-04-08 06:32:03 -07:00
Jarred Sumner
8cdb55d94f partial fix for the sendfile() bug 2022-04-08 06:31:14 -07:00
Jarred Sumner
489299cdcc Update README.md 2022-04-08 04:36:51 -07:00
Jarred Sumner
b744634141 Update README.md 2022-04-08 04:35:20 -07:00
Jarred Sumner
a8789fc858 Update README.md 2022-04-08 04:25:52 -07:00
Jarred Sumner
14def643f7 Outdated 2022-04-07 22:39:46 -07:00
Jarred Sumner
a3398650b5 Update README.md 2022-04-07 22:14:15 -07:00
Jarred Sumner
65daaf332d Update README.md 2022-04-07 22:09:17 -07:00
Jarred Sumner
63995da2c2 example 2022-04-07 22:07:24 -07:00
Jarred Sumner
f3b118d0ad Update README.md 2022-04-07 21:48:00 -07:00
Jarred Sumner
f01a2a3360 Fix some mime types to match expectations 2022-04-07 21:47:27 -07:00
Jarred Sumner
a0566f0fbe Update README.md 2022-04-07 21:44:40 -07:00
Jarred Sumner
4b8425938a Update README.md 2022-04-07 21:37:44 -07:00
Jarred Sumner
8fa3536aba Update README.md 2022-04-07 21:34:02 -07:00
Jarred Sumner
10712a790a Update README.md 2022-04-07 21:18:26 -07:00
Jarred Sumner
9cd148de7d Update README.md 2022-04-07 20:35:05 -07:00
Jarred Sumner
9b1d4e1a45 Update README.md 2022-04-07 20:34:35 -07:00
Jarred Sumner
b089f1adae Update README.md 2022-04-07 20:32:44 -07:00
Jarred Sumner
76d54c572a Update README.md 2022-04-07 20:25:57 -07:00
Jarred Sumner
7d25dae75e Update package.json 2022-04-07 20:24:05 -07:00
Jarred Sumner
282eaef435 Update README.md 2022-04-07 20:24:02 -07:00
Jarred Sumner
80dcd30b48 Update README.md 2022-04-07 20:04:35 -07:00
Jarred Sumner
76e04ad82b Update README.md 2022-04-07 20:04:20 -07:00
Jarred Sumner
afa0d4f3a3 Update README.md 2022-04-07 20:00:51 -07:00
Jarred Sumner
e21a65fd05 Update README.md 2022-04-07 19:31:59 -07:00
Jarred Sumner
295249cf08 📷 2022-04-07 19:29:18 -07:00
Jarred Sumner
91fb170c4a Update html-rewriter.ts 2022-04-07 19:29:01 -07:00
Jarred Sumner
0878659513 Update runtime.version 2022-04-07 06:27:50 -07:00
Jarred Sumner
69cebbfca2 Update http-file.ts 2022-04-07 06:26:28 -07:00
Jarred Sumner
3c4510573e Update build-id 2022-04-07 06:26:15 -07:00
Jarred Sumner
4285d8ec0b Update ZigGlobalObject.cpp 2022-04-07 06:25:58 -07:00
Jarred Sumner
c2a8c10834 Update mimalloc 2022-04-07 06:22:51 -07:00
Jarred Sumner
4e05fd0541 [bun.js] Add baseURI support to HTTP server 2022-04-07 06:22:42 -07:00
Jarred Sumner
b97e81b27f More types 2022-04-07 06:08:48 -07:00
Jarred Sumner
e08cc968cb add GC output constraints
I don't fully understand what this does

but it sounds good!
2022-04-07 01:57:45 -07:00
Jarred Sumner
9bee40813f Update Makefile 2022-04-06 23:38:41 -07:00
Jarred Sumner
5ac6920591 7 hrs 2022-04-06 23:38:37 -07:00
Jarred Sumner
70b1beb18b Update hmr.ts 2022-04-06 23:38:32 -07:00
Jarred Sumner
964aa40612 Update runtime.zig 2022-04-06 23:36:30 -07:00
Jarred Sumner
7e58c7e89a Make Bun.activate run earlier so we catch errors sooner 2022-04-06 23:36:26 -07:00
Jarred Sumner
3db549fdb5 Update build-id 2022-04-06 06:17:24 -07:00
Jarred Sumner
87401392ba Update client.development.tsx 2022-04-06 06:15:21 -07:00
Jarred Sumner
795c172d9e Support newer next 2022-04-06 06:15:18 -07:00
Jarred Sumner
cfe60996c2 [bun.js] Support React Refresh 0.12.0 2022-04-06 06:14:49 -07:00
Jarred Sumner
da3f131185 Update javascript.zig 2022-04-06 06:14:36 -07:00
Jarred Sumner
ac06ce2160 [bun.js][breaking] import.meta.url is now a file:// url 2022-04-06 06:14:29 -07:00
Jarred Sumner
69653729f0 tweak examples 2022-04-06 06:14:04 -07:00
Jarred SUmner
81eb47de0e [bun.js] Add stdout, stderr, stdin to Bun and support sendfile() + splice() 2022-04-06 01:53:05 -07:00
Jarred Sumner
57cf035a73 Fix ssl example 2022-04-05 19:32:52 -07:00
Jarred Sumner
ddaab5a836 fix example 2022-04-05 19:15:58 -07:00
Jarred Sumner
f97e6d04a7 wip 2022-04-05 06:51:45 -07:00
Jarred Sumner
daeede28db [bun dev] Fix segfaults 2022-04-05 06:38:36 -07:00
Jarred Sumner
70f9294e15 [bun:error] Fix exception 2022-04-05 06:36:19 -07:00
Jarred Sumner
2c0e8e0a99 Add update message 2022-04-05 03:51:24 -07:00
Jarred Sumner
7f4b1a5797 cmake does not like emit-llvm 2022-04-05 03:39:52 -07:00
Jarred Sumner
138ee2803d Update Makefile 2022-04-05 03:37:38 -07:00
Jarred Sumner
c9fee3bd04 tweak some flags 2022-04-05 03:35:59 -07:00
Jarred Sumner
db5951337e Fix stat() on x64 2022-04-05 01:52:48 -07:00
Jarred Sumner
d652e87473 fix binary size regression on linux 2022-04-05 00:40:49 -07:00
Zakiego
57eac42a91 docs: fix wrong #bun-create reference in readme (#136) 2022-04-05 00:24:14 -07:00
Jarred Sumner
d61f877a94 Update response.zig 2022-04-05 00:20:43 -07:00
Jarred Sumner
7eb575d7f8 Update response.zig 2022-04-05 00:19:54 -07:00
Jarred Sumner
8e5eda79de Update Makefile 2022-04-05 00:18:58 -07:00
Jarred Sumner
82051a5f22 Update http-file.ts 2022-04-05 00:17:57 -07:00
Jarred SUmner
17b9167e52 Fix linking bug? 2022-04-05 00:01:54 -07:00
Jarred SUmner
30542225c6 fix bug with io sometimes sleeping permanetly 2022-04-04 23:25:54 -07:00
Jarred Sumner
759b6c18fd Update Makefile 2022-04-04 08:45:49 -07:00
Jarred Sumner
0e1941ce21 ughh 2022-04-04 08:44:44 -07:00
Jarred Sumner
039fb0732c Update syscall.zig 2022-04-04 08:31:02 -07:00
Jarred Sumner
6c91aa6e51 Update syscall.zig 2022-04-04 08:22:51 -07:00
Jarred Sumner
2eed081b50 hm 2022-04-04 08:14:52 -07:00
Jarred Sumner
7551041fa1 Update Dockerfile.base 2022-04-04 07:57:58 -07:00
Jarred Sumner
41a97c5bf9 fixup 2022-04-04 07:39:39 -07:00
Jarred Sumner
20ed1c32d3 Update Makefile 2022-04-04 07:33:38 -07:00
Jarred Sumner
969cf9fd48 Update Makefile 2022-04-04 07:28:49 -07:00
Jarred Sumner
d29930db3a Update Makefile 2022-04-04 07:24:20 -07:00
Jarred Sumner
015333de8c Update Makefile 2022-04-04 07:22:29 -07:00
Jarred Sumner
89b9d167d1 Update Makefile 2022-04-04 07:17:40 -07:00
Jarred Sumner
2693a3beff Remove unused function 2022-04-04 07:15:03 -07:00
Jarred Sumner
feb315cf9c Update Dockerfile 2022-04-04 07:10:39 -07:00
Jarred Sumner
779e5ccc16 Add zlib for uws 2022-04-04 07:07:39 -07:00
Jarred Sumner
7b19de97d4 Update Dockerfile 2022-04-04 07:05:33 -07:00
Jarred Sumner
5d71d0a0b4 Update Makefile 2022-04-04 07:02:43 -07:00
Jarred Sumner
42b47fe4d9 Update Dockerfile 2022-04-04 07:01:26 -07:00
Jarred Sumner
5a9e381d84 Fix missing 2022-04-04 06:59:34 -07:00
Jarred Sumner
f4e118e40a Update response.zig 2022-04-04 06:54:10 -07:00
Jarred Sumner
071d4c155b Update Dockerfile 2022-04-04 06:51:53 -07:00
Jarred Sumner
044f23739c Update tsconfig.json 2022-04-04 06:38:12 -07:00
Jarred Sumner
05a4991a5f Update launch.json 2022-04-04 06:38:09 -07:00
Jarred Sumner
078ceb7168 Update http-file.ts 2022-04-04 06:37:46 -07:00
Jarred Sumner
9554dd1c33 fix https 2022-04-04 06:37:39 -07:00
Jarred Sumner
7fd12ca3ae Update bun.d.ts 2022-04-04 06:29:46 -07:00
Jarred Sumner
e84494b0e0 Fix error in bun:error 2022-04-04 06:22:48 -07:00
Jarred Sumner
afc7da33c9 Add a couple more tests 2022-04-04 01:07:38 -07:00
Jarred Sumner
d820a9890f Make Bun.file() -> HTMLRewriter -> HTTP response work 2022-04-04 01:04:14 -07:00
Jarred Sumner
a9f0d334bb [bun] Don't allow Transfer-Encoding header 2022-04-04 00:58:26 -07:00
Jarred Sumner
cee3783e58 [bun.js] Improve error message for HTTP server 2022-04-04 00:58:12 -07:00
Jarred Sumner
fceb88005d [bun.js] Support truncating file length up to u52 2022-04-04 00:34:57 -07:00
Jarred Sumner
e3c888a7cc Add HTMLRewriter proxy example 2022-04-03 22:24:59 -07:00
Jarred Sumner
25267397f6 pico headers are now mutable 2022-04-03 22:24:09 -07:00
Jarred Sumner
931e461c87 deref after null 2022-04-03 22:24:02 -07:00
Jarred Sumner
409758dd11 [bun.js] If no Content-Type is available and the content is all ascii text, assume it is text/plain 2022-04-03 22:23:22 -07:00
Jarred Sumner
cd28c3ca83 Omit the Content-Encoding header when it was auto decompressed 2022-04-03 22:22:22 -07:00
Jarred Sumner
25533b9e08 Don't track gzip timing unless verbose mode 2022-04-03 22:21:34 -07:00
Jarred Sumner
be70e08671 [bun error] Handle error messages with missing name/message better 2022-04-03 21:28:45 -07:00
Jarred Sumner
480d4b98c7 Update server.zig 2022-04-03 21:26:07 -07:00
Jarred Sumner
3b7e421eaf Support HTMLRewriter in http server 2022-04-03 21:25:16 -07:00
Jarred Sumner
b069ff253e Handle when unable to use sendfile() with Bun.file 2022-04-03 21:23:10 -07:00
Jarred Sumner
abc15f4d30 Add ShadowRealm and Bun.hash 2022-04-03 17:40:24 -07:00
Jarred Sumner
70bb8bda23 Fix the types 2022-04-03 17:24:26 -07:00
Jarred Sumner
665acdb170 Update runtime.version 2022-04-03 16:35:12 -07:00
Jarred Sumner
27ad502119 cleanup a few things 2022-04-03 16:35:09 -07:00
Jarred Sumner
e8b2af1eae doesn't fix the bug but helps a little 2022-04-03 16:34:38 -07:00
Jarred Sumner
4d718931be More types 2022-04-02 21:56:21 -07:00
Jarred Sumner
290166adb0 Add more typings 2022-04-02 18:54:31 -07:00
Jarred Sumner
c2ed8d0240 Add more tests for Node FS 2022-04-02 05:14:13 -07:00
Jarred Sumner
51e5d3ea70 [bun.js] fs.readSync & fs.writeSync should return just the number 2022-04-02 05:13:42 -07:00
Jarred Sumner
c73fcb0731 [bun.js] Support mode and flags as integer args in fs.openSync (instead of only object) 2022-04-02 05:12:43 -07:00
Jarred Sumner
e6b70c3e01 Update base.zig 2022-04-02 05:12:01 -07:00
Jarred Sumner
614f64ba82 Fix GC bug when reading TypedArray from user input 2022-04-02 05:11:57 -07:00
Jarred Sumner
b8263d0975 s/Buffer/TypedArray 2022-04-02 05:11:16 -07:00
Jarred Sumner
95d68b26a6 Fix mmap on macOS x64 2022-04-02 02:17:22 -07:00
Jarred Sumner
db39c8e109 Create gc.js 2022-04-02 00:49:27 -07:00
Jarred Sumner
449c248f08 Fix test failures 2022-04-02 00:29:48 -07:00
Jarred Sumner
66c5a941b3 More aggressive GC 2022-04-02 00:29:26 -07:00
Jarred Sumner
4592b1ccb5 [bun.js] Bring back file resolution 2022-04-01 23:39:05 -07:00
Jarred Sumner
9bfd1801aa [bun.js] slightly more careful write() 2022-04-01 23:38:35 -07:00
Jarred Sumner
b099e7232f Decrement task counter 2022-04-01 23:36:48 -07:00
Jarred Sumner
c657c7b846 Add helper for checking if value is an exception 2022-04-01 23:36:14 -07:00
Jarred Sumner
eaf09310cd deinit 2022-04-01 23:35:57 -07:00
Jarred Sumner
fffb69ce61 [bun.js] Fix double free in Blob 2022-04-01 22:54:22 -07:00
Jarred Sumner
5c989c957a Add abstraction for protecting values we're iterating on 2022-04-01 19:54:02 -07:00
Jarred Sumner
8af0764b3b Update response.zig 2022-04-01 19:53:41 -07:00
Jarred Sumner
c7727b136b [bun.js] Fix use-after-free in Bun.write 2022-04-01 19:53:37 -07:00
Jarred Sumner
7a6b6639bc Test written length 2022-04-01 19:53:17 -07:00
Jarred Sumner
08bf4694ca http file example 2022-04-01 19:53:02 -07:00
Jarred Sumner
60cc51379d Fix sendfile() after changes to blob 2022-04-01 19:52:53 -07:00
Jarred Sumner
e035084e49 Fix mimetype value 2022-04-01 19:50:38 -07:00
644 changed files with 354402 additions and 28075 deletions

3
.gitattributes vendored
View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -0,0 +1,8 @@
{
"recommendations": [
"AugusteRame.zls-vscode",
"esbenp.prettier-vscode",
"xaver.clang-format",
"vadimcn.vscode-lldb"
]
}

55
.vscode/launch.json generated vendored
View File

@@ -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
View File

@@ -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,

View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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

1585
README.md

File diff suppressed because it is too large Load Diff

419
bench/ffi/ffi-overhead.js Normal file
View 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
View 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

Binary file not shown.

15
bench/ffi/noop.js Normal file
View 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
View File

@@ -0,0 +1 @@
./napi-plus100

View 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

View 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

Binary file not shown.

View 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"
}
}

Submodule bench/ffi/plus100/plus100-napi added at 485de94d06

View 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");
}

View 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) {}

View 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

Binary file not shown.

View 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");
}

View 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
View 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);

View 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));

View File

@@ -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);

View 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);

View 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));

View 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 = "&quot;";
break;
case 38: // &
escape = "&amp;";
break;
case 39: // '
escape = "&#x27;"; // modified from escape-html; used to be '&#39'
break;
case 60: // <
escape = "&lt;";
break;
case 62: // >
escape = "&gt;";
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
View 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 });

View 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
View 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();

View 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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
{
"name": "bench",
"dependencies": {
"better-sqlite3": "^7.5.1",
"mitata": "^0.0.14"
}
}

View 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 });

View 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
View 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 });

View File

@@ -1 +1 @@
74
83

View File

@@ -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");

BIN
bun.lockb

Binary file not shown.

57
docs/upgrading-webkit.md Normal file
View 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
View 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
View 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
View 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

View File

@@ -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;

View File

@@ -1,6 +0,0 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"types": ["../../types/bun"]
}
}

6
examples/cat.ts Normal file
View 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));

View 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
View 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
View 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
View 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
View 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;

View File

@@ -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
View 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));
}

View File

@@ -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
View File

@@ -0,0 +1,8 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"module": "esnext",
"target": "esnext",
"typeRoots": ["../types"]
}
}

138
integration/README.md Normal file
View 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.

View 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();
});

View 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();
});
});

View 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);
});
});
}
}
});

View 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);
});

View 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(
"&lt;script&gt;alert(1)&lt;/script&gt;"
);
expect(escapeHTML("<")).toBe("&lt;");
expect(escapeHTML(">")).toBe("&gt;");
expect(escapeHTML("&")).toBe("&amp;");
expect(escapeHTML("'")).toBe("&#x27;");
expect(escapeHTML('"')).toBe("&quot;");
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("&lt;script&gt;ab");
expect(escapeHTML("<script>")).toBe("&lt;script&gt;");
expect(escapeHTML("<script><script>")).toBe("&lt;script&gt;&lt;script&gt;");
expect(escapeHTML("lalala" + "<script>alert(1)</script>" + "lalala")).toBe(
"lalala&lt;script&gt;alert(1)&lt;/script&gt;lalala"
);
expect(escapeHTML("<script>alert(1)</script>" + "lalala")).toBe(
"&lt;script&gt;alert(1)&lt;/script&gt;lalala"
);
expect(escapeHTML("lalala" + "<script>alert(1)</script>")).toBe(
"lalala" + "&lt;script&gt;alert(1)&lt;/script&gt;"
);
expect(escapeHTML("What does 😊 mean?")).toBe("What does 😊 mean?");
const output = escapeHTML("<What does 😊");
expect(output).toBe("&lt;What does 😊");
expect(escapeHTML("<div>What does 😊 mean in text?")).toBe(
"&lt;div&gt;What does 😊 mean in text?"
);
expect(
escapeHTML(
("lalala" + "<script>alert(1)</script>" + "lalala").repeat(900)
)
).toBe("lalala&lt;script&gt;alert(1)&lt;/script&gt;lalala".repeat(900));
expect(
escapeHTML(("<script>alert(1)</script>" + "lalala").repeat(900))
).toBe("&lt;script&gt;alert(1)&lt;/script&gt;lalala".repeat(900));
expect(
escapeHTML(("lalala" + "<script>alert(1)</script>").repeat(900))
).toBe(("lalala" + "&lt;script&gt;alert(1)&lt;/script&gt;").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&lt;script&gt;alert(1)&lt;/script&gt;lalala");
expect(escapeHTML("<script>😊alert(1)</script>" + "lalala")).toBe(
"&lt;script&gt;😊alert(1)&lt;/script&gt;lalala"
);
expect(escapeHTML("<script>alert(1)😊</script>" + "lalala")).toBe(
"&lt;script&gt;alert(1)😊&lt;/script&gt;lalala"
);
expect(escapeHTML("<script>alert(1)</script>" + "😊lalala")).toBe(
"&lt;script&gt;alert(1)&lt;/script&gt;😊lalala"
);
expect(escapeHTML("<script>alert(1)</script>" + "lal😊ala")).toBe(
"&lt;script&gt;alert(1)&lt;/script&gt;lal😊ala"
);
expect(
escapeHTML("<script>alert(1)</script>" + "lal😊ala".repeat(10))
).toBe("&lt;script&gt;alert(1)&lt;/script&gt;" + "lal😊ala".repeat(10));
for (let i = 1; i < 10; i++)
expect(escapeHTML("<script>alert(1)</script>" + "la😊".repeat(i))).toBe(
"&lt;script&gt;alert(1)&lt;/script&gt;" + "la😊".repeat(i)
);
expect(escapeHTML("la😊" + "<script>alert(1)</script>")).toBe(
"la😊" + "&lt;script&gt;alert(1)&lt;/script&gt;"
);
expect(
escapeHTML(("lalala" + "<script>alert(1)</script>😊").repeat(1))
).toBe(("lalala" + "&lt;script&gt;alert(1)&lt;/script&gt;😊").repeat(1));
expect(escapeHTML("😊".repeat(100))).toBe("😊".repeat(100));
expect(escapeHTML("😊<".repeat(100))).toBe("😊&lt;".repeat(100));
expect(escapeHTML("<😊>".repeat(100))).toBe("&lt;😊&gt;".repeat(100));
});
});

View 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(); }

View 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);
}

View 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;
}

View 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));
});

View File

@@ -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");

View 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);
});
}

View File

@@ -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 () => {

View File

@@ -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);
});

View File

@@ -0,0 +1,3 @@
export function whatDidIPass(expr, ctx) {
return ctx;
}

View File

@@ -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(

View File

@@ -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();
});
});

View 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);
});

View File

@@ -0,0 +1,3 @@
{
"hello": -123
}

View File

@@ -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
);
});

View File

@@ -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>"
);
});

View 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();
});

View File

@@ -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>
);

View File

@@ -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;
};

View 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;
})();

View File

@@ -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;
},
}}
/>
);

View File

@@ -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="&lt;div/&gt;"/></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);

View File

@@ -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"]);

View File

@@ -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;
},
}}
/>
);

View File

@@ -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, {});

View File

@@ -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;
},
}))
);

View File

@@ -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()} />
);

View File

@@ -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()
});

View File

@@ -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