Compare commits

...

71 Commits

Author SHA1 Message Date
Jarred Sumner
4787487b31 not-yet-working code for --experimental-vm-modules 2025-02-07 05:04:29 -08:00
Ciro Spaciari
c970922456 fix(sql) expose alias in SQLOption type (#17122) 2025-02-06 19:14:34 -08:00
Jarred Sumner
93af28751f Update CMakeLists.txt 2025-02-06 18:07:55 -08:00
190n
4d2a8650e5 test: bump pglite version (#17117) 2025-02-06 14:33:44 -08:00
Don Isaac
146ec7791b fix(node/assert): port more test cases from node (#16895)
Co-authored-by: DonIsaac <22823424+DonIsaac@users.noreply.github.com>
Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com>
2025-02-06 14:29:59 -08:00
Ciro Spaciari
253faed1cf fix(sql) types (#17118) 2025-02-06 13:37:58 -08:00
Ciro Spaciari
1fe2c3b426 feat(sql) support retrieving array values (#17094) 2025-02-06 02:45:05 -08:00
Jarred Sumner
fad856c03c Support fs.stat, fs.existsSync, fs.readFile, fs.promises.stat, fs.promises.readFile in bun build --compile (#17102)
Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com>
2025-02-06 00:06:52 -08:00
Jarred Sumner
2770ecad5c Fixes #16995 (#17101) 2025-02-05 22:35:53 -08:00
Michael H
1684c6246d fix bunx on windows with postinstall scripts (#17076) 2025-02-05 22:31:42 -08:00
Jarred Sumner
d2cdb5031d Fix potential crash when printing errors in bun install (#17027) 2025-02-05 22:17:02 -08:00
pfg
0c8658b350 Fix test-fs-promises-writefile.js on windows (#17053) 2025-02-05 22:12:52 -08:00
pfg
fc7bd569f5 Fix UAF in throwCommandNotFound (#17097) 2025-02-05 21:22:52 -08:00
pfg
5620a7dfac Enable asan on debug macos aarch64 builds (#17058) 2025-02-05 17:24:32 -08:00
Bartłomiej Kalemba
1ccc13ecf7 docs(bunfig): update test runner options (#17040) 2025-02-04 23:56:12 -08:00
Dylan Conway
4d004b90ca Fix bun.lock formatting of bin (#17041) 2025-02-04 23:55:57 -08:00
Zack Radisic
dcf0b719a5 CSS Fixes: light dark, color down-leveling bugs, implement minify for box-shadow (#17055) 2025-02-04 22:50:41 -08:00
Meghan Denny
8634ee3065 fix test-buffer-copy.js (#16640) 2025-02-04 20:19:22 -08:00
Meghan Denny
1819b01932 node: fix test-buffer-fill.js (#16738) 2025-02-04 19:52:11 -08:00
Meghan Denny
b39d84690c implement process.binding('buffer') (#16741)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-02-04 17:59:48 -08:00
Kai Tamkun
d63fe71a6d Fix node:dgram addMembership/dropMembership segfault (#17049) 2025-02-04 15:22:44 -08:00
Dylan Conway
fa55ca31e1 Fix occasional crash on FilePoll deinit (#17050) 2025-02-04 15:22:28 -08:00
190n
a8d159da22 Fix napi_is_buffer/napi_is_typedarray to match Node.js (#17034) 2025-02-03 21:49:27 -08:00
Jarred Sumner
0861c03b37 Fix memory leak in the SQL query string (#17026)
Co-authored-by: Ciro Spaciari <ciro.spaciari@gmail.com>
2025-02-03 17:38:17 -08:00
Jarred Sumner
7a918d24a7 Fix loading react-jsxdev instead of react-jsx (#17013)
Co-authored-by: chloe caruso <git@paperclover.net>
2025-02-03 14:10:09 -08:00
Bkh
7bef462257 Fix typo in html.ts (#17023) 2025-02-03 12:28:19 -08:00
Jarred Sumner
9cfa3a558b Bump 2025-02-03 07:15:33 -08:00
Jarred Sumner
97ae35dfde Update html.md 2025-02-03 04:08:46 -08:00
Jarred Sumner
1ea14f483c Introduce bun ./index.html (#16993) 2025-02-03 04:06:12 -08:00
Jarred Sumner
ec751159c6 Update typescript.md 2025-02-03 02:40:20 -08:00
Minsoo Choo
fa502506e5 Fix formatting for extern "c" (#16983) 2025-02-02 21:34:58 -08:00
Dylan Conway
06b16fc11e fix 16939 (#16991) 2025-02-02 21:31:40 -08:00
Ciro Spaciari
00a5c4af5a fix(sql) disable idle timeout when still processing data (#16984) 2025-02-02 21:27:22 -08:00
Dylan Conway
cc68f4f025 Fix occasional crash starting debugger thread (#16989) 2025-02-02 05:11:15 -08:00
Jarred Sumner
aac951bd47 Move semver-related structs into their own files (#16987) 2025-02-02 00:20:45 -08:00
Meghan Denny
34419c5f0d zig: only call strlen/wcslen in indexOfSentinel if libc is linked (#16986) 2025-02-01 23:59:45 -08:00
Jarred Sumner
1595b1cc2b Disable stop if necessary timer (#16962) 2025-02-01 22:56:34 -08:00
Michael H
5366c9db33 hopefully auto pr to DT (#16956) 2025-02-01 22:55:19 -08:00
Okinea Dev
87281b6d48 fix: add file association for *.mdc files (#16963) 2025-02-01 22:18:17 -08:00
Jarred Sumner
43fd9326ba Use a more reliable zig download url 2025-02-01 22:12:22 -08:00
Meghan Denny
26d3688e53 zig: update to 0.14.0-dev (#16862)
Co-authored-by: nektro <5464072+nektro@users.noreply.github.com>
2025-02-01 01:11:02 -08:00
pfg
1ddf3fc097 Fix fetch with formdata on some servers (#16947) 2025-01-31 22:39:43 -08:00
Dylan Conway
73bcff9d01 fix 16842 (#16952) 2025-01-31 22:39:30 -08:00
Jarred Sumner
c1708ea6ab Try bringing release/acquire heap access back (#16865)
Co-authored-by: Ben Grant <ben@bun.sh>
2025-01-31 16:13:03 -08:00
Meghan Denny
447121235c node:vm: this error was super confusing without the period 2025-01-31 15:54:06 -08:00
Jarred Sumner
1fa42d81af Bump 2025-01-31 07:08:40 -08:00
Jarred Sumner
22a23add8d Fix import("bun") in Vite (#16938) 2025-01-31 06:34:14 -08:00
Dylan Conway
d4ce421982 Fix node:fs memory leak with AbortSignal (#16788)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-01-31 05:25:53 -08:00
chloe caruso
322098fa54 allow resolution to work when the source file does not exist (#16851)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-01-31 05:24:57 -08:00
Jarred Sumner
9acb72d2ad Correctly handle __esModule for loader: "object" (#16885)
Co-authored-by: Jarred-Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2025-01-31 05:24:33 -08:00
Ciro Spaciari
25f6cbd471 fix(s3) fix queue and multipart flow (#16890)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-01-31 05:19:23 -08:00
Dylan Conway
b098c9ed89 fix(fs): WriteStream pending write fastpath (#16856)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-01-31 05:14:41 -08:00
Jarred Sumner
212944a5b6 Reduce memory usage of fs.readdir withFileTypes (#16897) 2025-01-31 04:25:58 -08:00
Jarred Sumner
61bf221510 Get pnpm to run inside bun (#16934) 2025-01-31 04:22:03 -08:00
Michael H
891057cd20 fix bun init -h (#16896) 2025-01-31 04:15:44 -08:00
Don Isaac
c51196a8dc fix(install): crash from invalid SemVer with extra wildcard (#16489) 2025-01-31 04:14:53 -08:00
Zack Radisic
f6ec0da125 Various CSS fixing and stability stuff (#16889) 2025-01-31 03:47:49 -08:00
Jarred Sumner
b59b793a32 Fix lifetime issue in BunString (#16930) 2025-01-30 20:46:19 -08:00
Matt Sutkowski
3a4df79a64 chore(docs): remove await from migrate cmd in drizzle.md (#16919) 2025-01-30 17:09:16 -08:00
190n
91f2be57b5 fix(node:os): loadavg() return values on Darwin (#16922) 2025-01-30 17:08:44 -08:00
Don Isaac
b612bc4f47 feat(node/fs): add fs.glob, fs.globSync, and fs.promises.glob (#16676) 2025-01-30 13:20:19 -08:00
Don Isaac
f454c27365 fix: Bun.deepEquals on empty objects with the same prototype (#16894)
Co-authored-by: DonIsaac <22823424+DonIsaac@users.noreply.github.com>
2025-01-30 12:12:51 -08:00
Ciro Spaciari
892764ec43 fix(sql) fix execution queue (#16854) 2025-01-29 23:52:19 -08:00
190n
574a41b03f chore: bump to v1.2.1 (#16891) 2025-01-29 20:19:12 -08:00
Don Isaac
c8f8d2c0bb fix(node/http): re-export WebSocket, CloseEvent, and MessageEvent (#16888) 2025-01-29 18:52:02 -08:00
Meghan Denny
29839737df cpp: synchronize on JSC::getVM since its more likely to be forward compatible (#16688) 2025-01-29 15:50:57 -08:00
Jarred Sumner
4d5ece3f63 Run stopIfNecessary GC timer more (#16871) 2025-01-29 14:40:51 -08:00
Meghan Denny
93a89e5866 meta: update bun.locks with bun 1.2 (#16867)
Co-authored-by: nektro <5464072+nektro@users.noreply.github.com>
2025-01-29 01:47:43 -08:00
Meghan Denny
676e8d1632 zig: delete is_bindgen (#16858) 2025-01-28 23:51:24 -08:00
Meghan Denny
5633ec4334 docker: fix distroless build (#16820) 2025-01-28 18:08:40 -08:00
Meghan Denny
160bf9d563 zig: make install.Resolution.init() not use anytype (#16852) 2025-01-28 18:08:10 -08:00
731 changed files with 38214 additions and 11016 deletions

View File

@@ -0,0 +1,378 @@
---
description: JavaScript class implemented in C++
globs: *.cpp
---
# Implementing JavaScript classes in C++
If there is a publicly accessible Constructor and Prototype, then there are 3 classes:
- IF there are C++ class members we need a destructor, so `class Foo : public JSC::DestructibleObject`, if no C++ class fields (only JS properties) then we don't need a class at all usually. We can instead use JSC::constructEmptyObject(vm, structure) and `putDirectOffset` like in [NodeFSBinding.cpp](mdc:src/bun.js/bindings/NodeFSBinding.cpp).
- class FooPrototype : public JSC::JSNonFinalObject
- class FooConstructor : public JSC::InternalFunction
If there is no publicly accessible Constructor, just the Prototype and the class is necessary. In some cases, we can avoid the prototype entirely (but that's rare).
If there are C++ fields on the Foo class, the Foo class will need an iso subspace added to [DOMClientIsoSubspaces.h](mdc:src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h) and [DOMIsoSubspaces.h](mdc:src/bun.js/bindings/webcore/DOMIsoSubspaces.h). Prototype and Constructor do not need subspaces.
Usually you'll need to #include "root.h" at the top of C++ files or you'll get lint errors.
Generally, defining the subspace looks like this:
```c++
class Foo : public JSC::DestructibleObject {
// ...
template<typename MyClassT, JSC::SubspaceAccess mode>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return WebCore::subspaceForImpl<MyClassT, WebCore::UseCustomHeapCellType::No>(
vm,
[](auto& spaces) { return spaces.m_clientSubspaceFor${MyClassT}.get(); },
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceFor${MyClassT} = std::forward<decltype(space)>(space); },
[](auto& spaces) { return spaces.m_subspaceFo${MyClassT}.get(); },
[](auto& spaces, auto&& space) { spaces.m_subspaceFor${MyClassT} = std::forward<decltype(space)>(space); });
}
```
It's better to put it in the .cpp file instead of the .h file, when possible.
## Defining properties
Define properties on the prototype. Use a const HashTableValues like this:
```C++
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckEmail);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckHost);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckIP);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckIssued);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckPrivateKey);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncToJSON);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncToLegacyObject);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncToString);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncVerify);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_ca);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_fingerprint);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_fingerprint256);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_fingerprint512);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_subject);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_subjectAltName);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_infoAccess);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_keyUsage);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_issuer);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_issuerCertificate);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_publicKey);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_raw);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_serialNumber);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_validFrom);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_validTo);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_validFromDate);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_validToDate);
static const HashTableValue JSX509CertificatePrototypeTableValues[] = {
{ "ca"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_ca, 0 } },
{ "checkEmail"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncCheckEmail, 2 } },
{ "checkHost"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncCheckHost, 2 } },
{ "checkIP"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncCheckIP, 1 } },
{ "checkIssued"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncCheckIssued, 1 } },
{ "checkPrivateKey"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncCheckPrivateKey, 1 } },
{ "fingerprint"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_fingerprint, 0 } },
{ "fingerprint256"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_fingerprint256, 0 } },
{ "fingerprint512"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_fingerprint512, 0 } },
{ "infoAccess"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_infoAccess, 0 } },
{ "issuer"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_issuer, 0 } },
{ "issuerCertificate"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_issuerCertificate, 0 } },
{ "keyUsage"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_keyUsage, 0 } },
{ "publicKey"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_publicKey, 0 } },
{ "raw"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_raw, 0 } },
{ "serialNumber"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_serialNumber, 0 } },
{ "subject"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_subject, 0 } },
{ "subjectAltName"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_subjectAltName, 0 } },
{ "toJSON"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncToJSON, 0 } },
{ "toLegacyObject"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncToLegacyObject, 0 } },
{ "toString"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncToString, 0 } },
{ "validFrom"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_validFrom, 0 } },
{ "validFromDate"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessorOrValue), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_validFromDate, 0 } },
{ "validTo"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_validTo, 0 } },
{ "validToDate"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessorOrValue), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_validToDate, 0 } },
{ "verify"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncVerify, 1 } },
};
```
### Creating a prototype class
Follow a pattern like this:
```c++
class JSX509CertificatePrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static constexpr unsigned StructureFlags = Base::StructureFlags;
static JSX509CertificatePrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
{
JSX509CertificatePrototype* prototype = new (NotNull, allocateCell<JSX509CertificatePrototype>(vm)) JSX509CertificatePrototype(vm, structure);
prototype->finishCreation(vm);
return prototype;
}
template<typename, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
return &vm.plainObjectSpace();
}
DECLARE_INFO;
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
auto* structure = JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
structure->setMayBePrototype(true);
return structure;
}
private:
JSX509CertificatePrototype(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure)
{
}
void finishCreation(JSC::VM& vm);
};
const ClassInfo JSX509CertificatePrototype::s_info = { "X509Certificate"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSX509CertificatePrototype) };
void JSX509CertificatePrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSX509Certificate::info(), JSX509CertificatePrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
} // namespace Bun
```
### Getter definition:
```C++
JSC_DEFINE_CUSTOM_GETTER(jsX509CertificateGetter_ca, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSX509Certificate* thisObject = jsDynamicCast<JSX509Certificate*>(JSValue::decode(thisValue));
if (UNLIKELY(!thisObject)) {
Bun::throwThisTypeError(*globalObject, scope, "JSX509Certificate"_s, "ca"_s);
return {};
}
return JSValue::encode(jsBoolean(thisObject->view().isCA()));
}
```
### Setter definition
```C++
JSC_DEFINE_CUSTOM_SETTER(jsImportMetaObjectSetter_require, (JSGlobalObject * jsGlobalObject, JSC::EncodedJSValue thisValue, JSC::EncodedJSValue encodedValue, PropertyName propertyName))
{
ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
if (UNLIKELY(!thisObject))
return false;
JSValue value = JSValue::decode(encodedValue);
if (!value.isCell()) {
// TODO:
return true;
}
thisObject->requireProperty.set(thisObject->vm(), thisObject, value.asCell());
return true;
}
```
### Function definition
```C++
JSC_DEFINE_HOST_FUNCTION(jsX509CertificateProtoFuncToJSON, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
auto *thisObject = jsDynamicCast<MyClassT*>(callFrame->thisValue());
if (UNLIKELY(!thisObject)) {
Bun::throwThisTypeError(*globalObject, scope, "MyClass"_s, "myFunctionName"_s);
return {};
}
return JSValue::encode(functionThatReturnsJSValue(vm, globalObject, thisObject));
}
```
### Constructor definition
```C++
JSC_DECLARE_HOST_FUNCTION(callStats);
JSC_DECLARE_HOST_FUNCTION(constructStats);
class JSStatsConstructor final : public JSC::InternalFunction {
public:
using Base = JSC::InternalFunction;
static constexpr unsigned StructureFlags = Base::StructureFlags;
static JSStatsConstructor* create(JSC::VM& vm, JSC::Structure* structure, JSC::JSObject* prototype)
{
JSStatsConstructor* constructor = new (NotNull, JSC::allocateCell<JSStatsConstructor>(vm)) JSStatsConstructor(vm, structure);
constructor->finishCreation(vm, prototype);
return constructor;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
return &vm.internalFunctionSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
}
private:
JSStatsConstructor(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure, callStats, constructStats)
{
}
void finishCreation(JSC::VM& vm, JSC::JSObject* prototype)
{
Base::finishCreation(vm, 0, "Stats"_s);
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
}
};
```
### Structure caching
If there's a class, prototype, and constructor:
1. Add the `JSC::LazyClassStructure` to [ZigGlobalObject.h](mdc:src/bun.js/bindings/ZigGlobalObject.h)
2. Initialize the class structure in [ZigGlobalObject.cpp](mdc:src/bun.js/bindings/ZigGlobalObject.cpp) in `void GlobalObject::finishCreation(VM& vm)`
3. Visit the class structure in visitChildren in [ZigGlobalObject.cpp](mdc:src/bun.js/bindings/ZigGlobalObject.cpp) in `void GlobalObject::visitChildrenImpl`
```c++
m_JSStatsBigIntClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
Bun::initJSBigIntStatsClassStructure(init);
});
```
If there's only a class, use `JSC::LazyProperty<JSGlobalObject, Structure>` instead of `JSC::LazyClassStructure`.
Then, implement the function that creates the structure:
```c++
void setupX509CertificateClassStructure(LazyClassStructure::Initializer& init)
{
auto* prototypeStructure = JSX509CertificatePrototype::createStructure(init.vm, init.global, init.global->objectPrototype());
auto* prototype = JSX509CertificatePrototype::create(init.vm, init.global, prototypeStructure);
auto* constructorStructure = JSX509CertificateConstructor::createStructure(init.vm, init.global, init.global->functionPrototype());
auto* constructor = JSX509CertificateConstructor::create(init.vm, init.global, constructorStructure, prototype);
auto* structure = JSX509Certificate::createStructure(init.vm, init.global, prototype);
init.setPrototype(prototype);
init.setStructure(structure);
init.setConstructor(constructor);
}
```
Then, use the structure by calling `globalObject.m_myStructureName.get(globalObject)`
```C++
JSC_DEFINE_HOST_FUNCTION(x509CertificateConstructorConstruct, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
if (!callFrame->argumentCount()) {
Bun::throwError(globalObject, scope, ErrorCode::ERR_MISSING_ARGS, "X509Certificate constructor requires at least one argument"_s);
return {};
}
JSValue arg = callFrame->uncheckedArgument(0);
if (!arg.isCell()) {
Bun::throwError(globalObject, scope, ErrorCode::ERR_INVALID_ARG_TYPE, "X509Certificate constructor argument must be a Buffer, TypedArray, or string"_s);
return {};
}
auto* zigGlobalObject = defaultGlobalObject(globalObject);
Structure* structure = zigGlobalObject->m_JSX509CertificateClassStructure.get(zigGlobalObject);
JSValue newTarget = callFrame->newTarget();
if (UNLIKELY(zigGlobalObject->m_JSX509CertificateClassStructure.constructor(zigGlobalObject) != newTarget)) {
auto scope = DECLARE_THROW_SCOPE(vm);
if (!newTarget) {
throwTypeError(globalObject, scope, "Class constructor X509Certificate cannot be invoked without 'new'"_s);
return {};
}
auto* functionGlobalObject = defaultGlobalObject(getFunctionRealm(globalObject, newTarget.getObject()));
RETURN_IF_EXCEPTION(scope, {});
structure = InternalFunction::createSubclassStructure(
globalObject, newTarget.getObject(), functionGlobalObject->NodeVMScriptStructure());
scope.release();
}
return JSValue::encode(createX509Certificate(vm, globalObject, structure, arg));
}
```
### Expose to Zig
To expose the constructor to zig:
```c++
extern "C" JSC::EncodedJSValue Bun__JSBigIntStatsObjectConstructor(Zig::GlobalObject* globalobject)
{
return JSValue::encode(globalobject->m_JSStatsBigIntClassStructure.constructor(globalobject));
}
```
Zig:
```zig
extern "c" fn Bun__JSBigIntStatsObjectConstructor(*JSC.JSGlobalObject) JSC.JSValue;
pub const getBigIntStatsConstructor = Bun__JSBigIntStatsObjectConstructor;
```
To create an object (instance) of a JS class defined in C++ from Zig, follow the __toJS convention like this:
```c++
// X509* is whatever we need to create the object
extern "C" EncodedJSValue Bun__X509__toJS(Zig::GlobalObject* globalObject, X509* cert)
{
// ... implementation details
auto* structure = globalObject->m_JSX509CertificateClassStructure.get(globalObject);
return JSValue::encode(JSX509Certificate::create(globalObject->vm(), structure, globalObject, WTFMove(cert)));
}
```
And from Zig:
```zig
const X509 = opaque {
// ... class
extern fn Bun__X509__toJS(*JSC.JSGlobalObject, *X509) JSC.JSValue;
pub fn toJS(this: *X509, globalObject: *JSC.JSGlobalObject) JSC.JSValue {
return Bun__X509__toJS(globalObject, this);
}
};
```

1
.gitattributes vendored
View File

@@ -15,6 +15,7 @@
*.lock text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.map text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.md text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.mdc text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.mjs text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.mts text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2

View File

@@ -4,7 +4,7 @@ description: An internal version of the 'oven-sh/setup-bun' action.
inputs:
bun-version:
type: string
description: "The version of bun to install: 'latest', 'canary', 'bun-v1.0.0', etc."
description: "The version of bun to install: 'latest', 'canary', 'bun-v1.2.0', etc."
default: latest
required: false
baseline:

View File

@@ -10,7 +10,7 @@ on:
merge_group:
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
LLVM_VERSION: "18.1.8"
LLVM_VERSION_MAJOR: "18"

View File

@@ -10,7 +10,7 @@ on:
merge_group:
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
LLVM_VERSION: "18.1.8"
LLVM_VERSION_MAJOR: "18"

View File

@@ -5,7 +5,7 @@ on:
workflow_dispatch:
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
OXLINT_VERSION: "0.15.0"
jobs:

View File

@@ -10,7 +10,7 @@ on:
merge_group:
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
jobs:
prettier-format:

View File

@@ -44,6 +44,10 @@ on:
description: Should types be released to npm?
type: boolean
default: false
use-definitelytyped:
description: "Should types be PR'd to DefinitelyTyped?"
type: boolean
default: false
jobs:
sign:
@@ -66,7 +70,7 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.44"
bun-version: "1.2.0"
- name: Install Dependencies
run: bun install
- name: Sign Release
@@ -94,7 +98,7 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.44"
bun-version: "1.2.0"
- name: Install Dependencies
run: bun install
- name: Release
@@ -123,7 +127,7 @@ jobs:
if: ${{ env.BUN_VERSION != 'canary' }}
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.44"
bun-version: "1.2.0"
- name: Setup Bun
if: ${{ env.BUN_VERSION == 'canary' }}
uses: ./.github/actions/setup-bun
@@ -155,6 +159,48 @@ jobs:
with:
package: packages/bun-types/package.json
token: ${{ secrets.NPM_TOKEN }}
definitelytyped:
name: Make pr to DefinitelyTyped to update `bun-types` version
runs-on: ubuntu-latest
needs: npm-types
if: ${{ github.event_name == 'release' || github.event.inputs.use-definitelytyped == 'true' }}
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
with:
repository: DefinitelyTyped/DefinitelyTyped
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.2.0"
- id: bun-version
run: echo "BUN_VERSION=${BUN_VERSION#bun-v}" >> "$GITHUB_OUTPUT"
- name: Update bun-types version in package.json
run: |
bun -e '
const file = Bun.file("./types/bun/package.json");
const json = await file.json();
const version = "${{ steps.bun-version.outputs.BUN_VERSION }}";
json.dependencies["bun-types"] = version;
json.version = version.slice(0, version.lastIndexOf(".")) + ".9999";
await file.write(JSON.stringify(json, null, 4) + "\n");
'
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
if: ${{ env.BUN_LATEST == 'true' && env.BUN_VERSION != 'canary'}}
with:
token: ${{ secrets.ROBOBUN_TOKEN }}
add-paths: ./types/bun/package.json
title: "[bun] update to ${{ steps.bun-version.outputs.BUN_VERSION }}"
commit-message: "[bun] update to ${{ steps.bun-version.outputs.BUN_VERSION }}"
body: |
Update `bun-types` version to ${{ steps.bun-version.outputs.BUN_VERSION }}
https://bun.sh/blog/${{ env.BUN_VERSION }}
push-to-fork: oven-sh/DefinitelyTyped
branch: ${{env.BUN_VERSION}}
docker:
name: Release to Dockerhub
runs-on: ubuntu-latest
@@ -265,7 +311,7 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.44"
bun-version: "1.2.0"
- name: Install Dependencies
run: bun install
- name: Release
@@ -309,7 +355,7 @@ jobs:
uses: ./.github/actions/setup-bun
if: ${{ env.BUN_LATEST == 'true' }}
with:
bun-version: "1.1.44"
bun-version: "1.2.0"
- name: Bump version
uses: ./.github/actions/bump
if: ${{ env.BUN_LATEST == 'true' }}

View File

@@ -4,7 +4,7 @@ permissions:
contents: read
env:
LLVM_VERSION: 16
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
on:
workflow_call:

View File

@@ -9,7 +9,7 @@ on:
required: true
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
jobs:
bump:

View File

@@ -10,7 +10,7 @@ on:
merge_group:
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
jobs:
zig-format:

3
.gitignore vendored
View File

@@ -151,6 +151,7 @@ src/bake/generated.ts
test/cli/install/registry/packages/publish-pkg-*
test/cli/install/registry/packages/@secret/publish-pkg-8
test/js/third_party/prisma/prisma/sqlite/dev.db-journal
tmp
# Dependencies
/vendor
@@ -178,4 +179,4 @@ test/js/third_party/prisma/prisma/sqlite/dev.db-journal
.buildkite/ci.yml
*.sock
scratch*.{js,ts,tsx,cjs,mjs}
scratch*.{js,ts,tsx,cjs,mjs}

View File

@@ -7,3 +7,4 @@ src/react-refresh.js
*.min.js
test/snippets
test/js/node/test
bun.lock

13
.vscode/launch.json generated vendored
View File

@@ -7,6 +7,19 @@
// - "cppvsdbg" is used instead of "lldb" on Windows, because "lldb" is too slow
"version": "0.2.0",
"configurations": [
{
"type": "bun",
"request": "launch",
"name": "[js] bun test [file]",
"runtime": "${workspaceFolder}/build/debug/bun-debug",
"args": ["test", "${file}"],
"cwd": "${workspaceFolder}",
"env": {
"BUN_DEBUG_QUIET_LOGS": "1",
"BUN_DEBUG_jest": "1",
"BUN_GARBAGE_COLLECTOR_LEVEL": "1",
},
},
// bun test [file]
{
"type": "lldb",

View File

@@ -140,6 +140,7 @@
},
"files.associations": {
"*.idl": "cpp",
"*.mdc": "markdown",
"array": "cpp",
},
"C_Cpp.files.exclude": {

View File

@@ -12,6 +12,12 @@ list(APPEND CMAKE_MODULE_PATH
include(Policies)
include(Globals)
if (CMAKE_HOST_WIN32)
# Workaround for TLS certificate verification issue on Windows when downloading from GitHub
# Remove this once we've bumped the CI machines build image
set(CMAKE_TLS_VERIFY 0)
endif()
# --- Compilers ---
if(CMAKE_HOST_APPLE)

2
LATEST
View File

@@ -1 +1 @@
1.2.0
1.2.2

View File

@@ -1301,6 +1301,7 @@ jsc-build-mac-compile-lto:
.PHONY: jsc-build-mac-compile-debug
jsc-build-mac-compile-debug:
mkdir -p $(WEBKIT_DEBUG_DIR) $(WEBKIT_DIR);
# to disable asan, remove -DENABLE_SANITIZERS=address and add -DENABLE_MALLOC_HEAP_BREAKDOWN=ON
cd $(WEBKIT_DEBUG_DIR) && \
ICU_INCLUDE_DIRS="$(HOMEBREW_PREFIX)opt/icu4c/include" \
cmake \
@@ -1309,7 +1310,6 @@ jsc-build-mac-compile-debug:
-DCMAKE_BUILD_TYPE=Debug \
-DUSE_THIN_ARCHIVES=OFF \
-DENABLE_FTL_JIT=ON \
-DENABLE_MALLOC_HEAP_BREAKDOWN=ON \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DUSE_BUN_JSC_ADDITIONS=ON \
-DUSE_BUN_EVENT_LOOP=ON \
@@ -1321,6 +1321,7 @@ jsc-build-mac-compile-debug:
-DUSE_PTHREAD_JIT_PERMISSIONS_API=ON \
-DENABLE_REMOTE_INSPECTOR=ON \
-DUSE_VISIBILITY_ATTRIBUTE=1 \
-DENABLE_SANITIZERS=address \
$(WEBKIT_DIR) \
$(WEBKIT_DEBUG_DIR) && \
CFLAGS="$(CFLAGS) -ffat-lto-objects" CXXFLAGS="$(CXXFLAGS) -ffat-lto-objects" \

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bench",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "expect-to-equal",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bench",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bench",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "simple-react",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "react-hello-world",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "scan",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bench",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "websocket-server",

View File

@@ -19,7 +19,7 @@ const OperatingSystem = @import("src/env.zig").OperatingSystem;
const pathRel = fs.path.relative;
/// Do not rename this constant. It is scanned by some scripts to determine which zig version to install.
const recommended_zig_version = "0.13.0";
const recommended_zig_version = "0.14.0-dev.2987+183bb8b08";
comptime {
if (!std.mem.eql(u8, builtin.zig_version_string, recommended_zig_version)) {
@@ -46,6 +46,7 @@ const BunBuildOptions = struct {
sha: []const u8,
/// enable debug logs in release builds
enable_logs: bool = false,
enable_asan: bool,
tracy_callstack_depth: u16,
reported_nodejs_version: Version,
/// To make iterating on some '@embedFile's faster, we load them at runtime
@@ -154,8 +155,6 @@ pub fn build(b: *Build) !void {
std.log.info("zig compiler v{s}", .{builtin.zig_version_string});
checked_file_exists = std.AutoHashMap(u64, void).init(b.allocator);
b.zig_lib_dir = b.zig_lib_dir orelse b.path("vendor/zig/lib");
// TODO: Upgrade path for 0.14.0
// b.graph.zig_lib_directory = brk: {
// const sub_path = "vendor/zig/lib";
@@ -209,7 +208,7 @@ pub fn build(b: *Build) !void {
const bun_version = b.option([]const u8, "version", "Value of `Bun.version`") orelse "0.0.0";
b.reference_trace = ref_trace: {
const trace = b.option(u32, "reference-trace", "Set the reference trace") orelse 16;
const trace = b.option(u32, "reference-trace", "Set the reference trace") orelse 24;
break :ref_trace if (trace == 0) null else trace;
};
@@ -277,6 +276,7 @@ pub fn build(b: *Build) !void {
.tracy_callstack_depth = b.option(u16, "tracy_callstack_depth", "") orelse 10,
.enable_logs = b.option(bool, "enable_logs", "Enable logs in release") orelse false,
.enable_asan = b.option(bool, "enable_asan", "Enable asan") orelse false,
};
// zig build obj
@@ -331,11 +331,25 @@ pub fn build(b: *Build) !void {
.{ .os = .windows, .arch = .x86_64 },
});
}
{
const step = b.step("check-macos", "Check for semantic analysis errors on Windows");
addMultiCheck(b, step, build_options, &.{
.{ .os = .mac, .arch = .x86_64 },
.{ .os = .mac, .arch = .aarch64 },
});
}
{
const step = b.step("check-linux", "Check for semantic analysis errors on Windows");
addMultiCheck(b, step, build_options, &.{
.{ .os = .linux, .arch = .x86_64 },
.{ .os = .linux, .arch = .aarch64 },
});
}
// zig build translate-c-headers
{
const step = b.step("translate-c", "Copy generated translated-c-headers.zig to zig-out");
step.dependOn(&b.addInstallFile(getTranslateC(b, b.host, .Debug).getOutput(), "translated-c-headers.zig").step);
step.dependOn(&b.addInstallFile(getTranslateC(b, b.graph.host, .Debug).getOutput(), "translated-c-headers.zig").step);
}
// zig build enum-extractor
@@ -363,7 +377,7 @@ pub fn addMultiCheck(
const check_target = b.resolveTargetQuery(.{
.os_tag = OperatingSystem.stdOSTag(check.os),
.cpu_arch = check.arch,
.cpu_model = getCpuModel(check.os, check.arch) orelse .determined_by_cpu_arch,
.cpu_model = getCpuModel(check.os, check.arch) orelse .determined_by_arch_os,
.os_version_min = getOSVersionMin(check.os),
.glibc_version = if (check.musl) null else getOSGlibCVersion(check.os),
});
@@ -381,6 +395,7 @@ pub fn addMultiCheck(
.reported_nodejs_version = root_build_options.reported_nodejs_version,
.codegen_path = root_build_options.codegen_path,
.no_llvm = root_build_options.no_llvm,
.enable_asan = root_build_options.enable_asan,
};
var obj = addBunObject(b, &options);
@@ -428,8 +443,15 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile {
.omit_frame_pointer = false,
.strip = false, // stripped at the end
});
if (opts.enable_asan) {
if (@hasField(Build.Module, "sanitize_address")) {
obj.root_module.sanitize_address = true;
} else {
const fail_step = b.addFail("asan is not supported on this platform");
obj.step.dependOn(&fail_step.step);
}
}
obj.bundle_compiler_rt = false;
obj.formatted_panics = true;
obj.root_module.omit_frame_pointer = false;
// Link libc
@@ -614,7 +636,7 @@ const WindowsShim = struct {
.optimize = .ReleaseFast,
.use_llvm = true,
.use_lld = true,
.unwind_tables = false,
.unwind_tables = .none,
.omit_frame_pointer = true,
.strip = true,
.linkage = .static,

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun",
@@ -10,8 +10,8 @@
"@typescript-eslint/eslint-plugin": "^7.11.0",
"@typescript-eslint/parser": "^7.11.0",
"@vscode/debugadapter": "^1.65.0",
"autoprefixer": "^10.4.19",
"caniuse-lite": "^1.0.30001620",
"autoprefixer": "^10.4.20",
"caniuse-lite": "^1.0.30001660",
"esbuild": "^0.21.4",
"eslint": "^9.4.0",
"eslint-config-prettier": "^9.1.0",
@@ -257,7 +257,7 @@
"builtins": ["builtins@1.0.3", "", {}, "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ=="],
"bun-types": ["bun-types@workspace:packages/bun-types", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" }, "devDependencies": { "@biomejs/biome": "^1.5.3", "@definitelytyped/dtslint": "^0.0.199", "@definitelytyped/eslint-plugin": "^0.0.197", "typescript": "^5.0.2" } }],
"bun-types": ["bun-types@workspace:packages/bun-types"],
"call-bind": ["call-bind@1.0.7", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.1" } }, "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w=="],
@@ -265,7 +265,7 @@
"camel-case": ["camel-case@4.1.2", "", { "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" } }, "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw=="],
"caniuse-lite": ["caniuse-lite@1.0.30001653", "", {}, "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw=="],
"caniuse-lite": ["caniuse-lite@1.0.30001695", "", {}, "sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw=="],
"capital-case": ["capital-case@1.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A=="],
@@ -923,10 +923,14 @@
"are-we-there-yet/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
"autoprefixer/caniuse-lite": ["caniuse-lite@1.0.30001653", "", {}, "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw=="],
"babel-code-frame/chalk": ["chalk@1.1.3", "", { "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A=="],
"babel-code-frame/js-tokens": ["js-tokens@3.0.2", "", {}, "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg=="],
"browserslist/caniuse-lite": ["caniuse-lite@1.0.30001653", "", {}, "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw=="],
"eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
"eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],

View File

@@ -44,6 +44,13 @@ if(WIN32)
)
endif()
if(ENABLE_ASAN)
register_compiler_flags(
DESCRIPTION "Enable AddressSanitizer"
-fsanitize=address
)
endif()
# --- Optimization level ---
if(DEBUG)
register_compiler_flags(

View File

@@ -86,6 +86,11 @@ optionx(ENABLE_LTO BOOL "If LTO (link-time optimization) should be used" DEFAULT
if(LINUX)
optionx(ENABLE_VALGRIND BOOL "If Valgrind support should be enabled" DEFAULT OFF)
endif()
if(DEBUG AND APPLE AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64")
optionx(ENABLE_ASAN BOOL "If ASAN support should be enabled" DEFAULT ON)
else()
optionx(ENABLE_ASAN BOOL "If ASAN support should be enabled" DEFAULT OFF)
endif()
optionx(ENABLE_PRETTIER BOOL "If prettier should be ran" DEFAULT OFF)

View File

@@ -28,7 +28,12 @@ else()
message(FATAL_ERROR "Unsupported architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
endif()
set(ZIG_NAME zig-${ZIG_OS}-${ZIG_ARCH}-${ZIG_VERSION})
set(ZIG_ASAN "")
if(ENABLE_ASAN)
set(ZIG_ASAN "+asan")
endif()
set(ZIG_NAME zig-${ZIG_OS}-${ZIG_ARCH}-${ZIG_VERSION}${ZIG_ASAN})
if(CMAKE_HOST_WIN32)
set(ZIG_EXE "zig.exe")
@@ -38,7 +43,7 @@ else()
set(ZIG_FILENAME ${ZIG_NAME}.tar.xz)
endif()
set(ZIG_DOWNLOAD_URL https://ziglang.org/download/${ZIG_VERSION}/${ZIG_FILENAME})
set(ZIG_DOWNLOAD_URL https://bun-ci-assets.bun.sh/${ZIG_FILENAME})
execute_process(
COMMAND

View File

@@ -404,6 +404,7 @@ set(BUN_OBJECT_LUT_SOURCES
${CWD}/src/bun.js/bindings/ZigGlobalObject.lut.txt
${CWD}/src/bun.js/bindings/JSBuffer.cpp
${CWD}/src/bun.js/bindings/BunProcess.cpp
${CWD}/src/bun.js/bindings/ProcessBindingBuffer.cpp
${CWD}/src/bun.js/bindings/ProcessBindingConstants.cpp
${CWD}/src/bun.js/bindings/ProcessBindingNatives.cpp
${CWD}/src/bun.js/modules/NodeModuleModule.cpp
@@ -415,6 +416,7 @@ set(BUN_OBJECT_LUT_OUTPUTS
${CODEGEN_PATH}/ZigGlobalObject.lut.h
${CODEGEN_PATH}/JSBuffer.lut.h
${CODEGEN_PATH}/BunProcess.lut.h
${CODEGEN_PATH}/ProcessBindingBuffer.lut.h
${CODEGEN_PATH}/ProcessBindingConstants.lut.h
${CODEGEN_PATH}/ProcessBindingNatives.lut.h
${CODEGEN_PATH}/NodeModuleModule.lut.h
@@ -565,6 +567,7 @@ register_command(
-Dcanary=${CANARY_REVISION}
-Dcodegen_path=${CODEGEN_PATH}
-Dcodegen_embed=$<IF:$<BOOL:${CODEGEN_EMBED}>,true,false>
-Denable_asan=$<IF:$<BOOL:${ENABLE_ASAN}>,true,false>
--prominent-compile-errors
${ZIG_FLAGS_BUN}
ARTIFACTS
@@ -827,6 +830,15 @@ if(NOT WIN32)
)
endif()
if (ENABLE_ASAN)
target_compile_options(${bun} PUBLIC
-fsanitize=address
)
target_link_libraries(${bun} PUBLIC
-fsanitize=address
)
endif()
target_compile_options(${bun} PUBLIC
-Werror=return-type
-Werror=return-stack-address

View File

@@ -4,7 +4,7 @@ register_repository(
REPOSITORY
oven-sh/mimalloc
COMMIT
82b2c2277a4d570187c07b376557dc5bde81d848
1beadf9651a7bfdec6b5367c380ecc3fe1c40d1a
)
set(MIMALLOC_CMAKE_ARGS
@@ -19,6 +19,10 @@ set(MIMALLOC_CMAKE_ARGS
-DMI_SKIP_COLLECT_ON_EXIT=ON
)
if(ENABLE_ASAN)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_TRACK_ASAN=ON)
endif()
if(DEBUG)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_DEBUG_FULL=ON)
endif()

View File

@@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use")
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")
if(NOT WEBKIT_VERSION)
set(WEBKIT_VERSION e6cb36cabed465c28c7bcbb28d86e8466ea36e8d)
set(WEBKIT_VERSION 851aabf42b06ba583cc0485ff9088e3f84c22f3d)
endif()
string(SUBSTRING ${WEBKIT_VERSION} 0 16 WEBKIT_VERSION_PREFIX)
@@ -79,6 +79,10 @@ else()
set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}")
endif()
if(ENABLE_ASAN)
set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}-asan")
endif()
set(WEBKIT_NAME bun-webkit-${WEBKIT_OS}-${WEBKIT_ARCH}${WEBKIT_SUFFIX})
set(WEBKIT_FILENAME ${WEBKIT_NAME}.tar.gz)
setx(WEBKIT_DOWNLOAD_URL https://github.com/oven-sh/WebKit/releases/download/autobuild-${WEBKIT_VERSION}/${WEBKIT_FILENAME})

View File

@@ -20,8 +20,8 @@ else()
unsupported(CMAKE_SYSTEM_NAME)
endif()
optionx(ZIG_VERSION STRING "The zig version of the compiler to download" DEFAULT "0.13.0")
optionx(ZIG_COMMIT STRING "The zig commit to use in oven-sh/zig" DEFAULT "131a009ba2eb127a3447d05b9e12f710429aa5ee")
optionx(ZIG_VERSION STRING "The zig version of the compiler to download" DEFAULT "0.14.0-dev.2987+183bb8b08")
optionx(ZIG_COMMIT STRING "The zig commit to use in oven-sh/zig" DEFAULT "63f8ed52c011beafde83216efba766492491ef4b")
optionx(ZIG_TARGET STRING "The zig target to use" DEFAULT ${DEFAULT_ZIG_TARGET})
if(CMAKE_BUILD_TYPE STREQUAL "Release")
@@ -79,6 +79,7 @@ register_command(
-DZIG_PATH=${ZIG_PATH}
-DZIG_VERSION=${ZIG_VERSION}
-DZIG_COMMIT=${ZIG_COMMIT}
-DENABLE_ASAN=${ENABLE_ASAN}
-P ${CWD}/cmake/scripts/DownloadZig.cmake
SOURCES
${CWD}/cmake/scripts/DownloadZig.cmake

View File

@@ -67,14 +67,18 @@ ARG BUN_INSTALL_BIN=/usr/local/bin
ENV BUN_INSTALL_BIN=${BUN_INSTALL_BIN}
COPY --from=build /usr/local/bin/bun /usr/local/bin/
RUN mkdir -p /usr/local/bun-node-fallback-bin && ln -s /usr/local/bin/bun /usr/local/bun-node-fallback-bin/node
ENV PATH "${PATH}:/usr/local/bun-node-fallback-bin"
# Temporarily use the `build`-stage image binaries to create a symlink:
RUN --mount=type=bind,from=build,source=/usr/bin,target=/usr/bin \
--mount=type=bind,from=build,source=/bin,target=/bin <<EOF
--mount=type=bind,from=build,source=/bin,target=/bin \
--mount=type=bind,from=build,source=/usr/lib,target=/usr/lib \
--mount=type=bind,from=build,source=/lib,target=/lib \
<<EOF
ln -s /usr/local/bin/bun /usr/local/bin/bunx
which bunx
mkdir -p /usr/local/bun-node-fallback-bin
ln -s /usr/local/bin/bun /usr/local/bun-node-fallback-bin/nodebun
EOF
ENTRYPOINT ["/usr/local/bin/bun"]

View File

@@ -1,6 +1,6 @@
As of Bun v1.1.44, we've added initial support for bundling frontend apps directly in Bun's HTTP server: `Bun.serve()`. Run your frontend and backend in the same app with no extra steps.
Using `Bun.serve()`'s `static` option, you can run your frontend and backend in the same app with no extra steps.
To get started, import your HTML files and pass them to the `static` option in `Bun.serve()`.
To get started, import HTML files and pass them to the `static` option in `Bun.serve()`.
```ts
import dashboard from "./dashboard.html";
@@ -33,7 +33,7 @@ const server = Bun.serve({
},
});
console.log(`Listening on ${server.url}`)
console.log(`Listening on ${server.url}`);
```
```bash
@@ -211,6 +211,7 @@ For example, enable TailwindCSS on your routes by installing and adding the `bun
```sh
$ bun add bun-plugin-tailwind
```
```toml#bunfig.toml
[serve.static]
plugins = ["bun-plugin-tailwind"]

View File

@@ -1,4 +1,4 @@
As of Bun v1.1.43, Bun's bundler now has first-class support for HTML. Build static sites, landing pages, and web applications with zero configuration. Just point Bun at your HTML file and it handles everything else.
Bun's bundler has first-class support for HTML. Build static sites, landing pages, and web applications with zero configuration. Just point Bun at your HTML file and it handles everything else.
```html#index.html
<!doctype html>
@@ -13,45 +13,228 @@ As of Bun v1.1.43, Bun's bundler now has first-class support for HTML. Build sta
</html>
```
One command is all you need (won't be experimental after Bun v1.2):
To get started, pass HTML files to `bun`.
{% bunDevServerTerminal alt="bun ./index.html" path="./index.html" routes="" /%}
Bun's development server provides powerful features with zero configuration:
- **Automatic Bundling** - Bundles and serves your HTML, JavaScript, and CSS
- **Multi-Entry Support** - Handles multiple HTML entry points and glob entry points
- **Modern JavaScript** - TypeScript & JSX support out of the box
- **Smart Configuration** - Reads `tsconfig.json` for paths, JSX options, experimental decorators, and more
- **Plugins** - Plugins for TailwindCSS and more
- **ESM & CommonJS** - Use ESM and CommonJS in your JavaScript, TypeScript, and JSX files
- **CSS Bundling & Minification** - Bundles CSS from `<link>` tags and `@import` statements
- **Asset Management**
- Automatic copying & hashing of images and assets
- Rewrites asset paths in JavaScript, CSS, and HTML
## Single Page Apps (SPA)
When you pass a single .html file to Bun, Bun will use it as a fallback route for all paths. This makes it perfect for single page apps that use client-side routing:
{% bunDevServerTerminal alt="bun index.html" path="index.html" routes="" /%}
Your React or other SPA will work out of the box — no configuration needed. All routes like `/about`, `/users/123`, etc. will serve the same HTML file, letting your client-side router handle the navigation.
```html#index.html
<!doctype html>
<html>
<head>
<title>My SPA</title>
<script src="./app.tsx" type="module"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
```
## Multi-page apps (MPA)
Some projects have several separate routes or HTML files as entry points. To support multiple entry points, pass them all to `bun`
{% bunDevServerTerminal alt="bun ./index.html ./about.html" path="./index.html ./about.html" routes="[{\"path\": \"/\", \"file\": \"./index.html\"}, {\"path\": \"/about\", \"file\": \"./about.html\"}]" /%}
This will serve:
- `index.html` at `/`
- `about.html` at `/about`
### Glob patterns
To specify multiple files, you can use glob patterns that end in `.html`:
{% bunDevServerTerminal alt="bun ./**/*.html" path="./**/*.html" routes="[{\"path\": \"/\", \"file\": \"./index.html\"}, {\"path\": \"/about\", \"file\": \"./about.html\"}]" /%}
### Path normalization
The base path is chosen from the longest common prefix among all the files.
{% bunDevServerTerminal alt="bun ./index.html ./about/index.html ./about/foo/index.html" path="./index.html ./about/index.html ./about/foo/index.html" routes="[{\"path\": \"/\", \"file\": \"./index.html\"}, {\"path\": \"/about\", \"file\": \"./about/index.html\"}, {\"path\": \"/about/foo\", \"file\": \"./about/foo/index.html\"}]" /%}
## JavaScript, TypeScript, and JSX
Bun's transpiler natively implements JavaScript, TypeScript, and JSX support. [Learn more about loaders in Bun](/docs/bundler/loaders).
Bun's transpiler is also used at runtime.
### ES Modules & CommonJS
You can use ESM and CJS in your JavaScript, TypeScript, and JSX files. Bun will handle the transpilation and bundling automatically.
There is no pre-build or separate optimization step. It's all done at the same time.
Learn more about [module resolution in Bun](/docs/runtime/modules).
## CSS
Bun's CSS parser is also natively implemented (clocking in around 58,000 lines of Zig).
It's also a CSS bundler. You can use `@import` in your CSS files to import other CSS files.
For example:
```css#styles.css
@import "./abc.css";
.container {
background-color: blue;
}
```
```css#abc.css
body {
background-color: red;
}
```
This outputs:
```css#styles.css
body {
background-color: red;
}
.container {
background-color: blue;
}
```
### Referencing local assets in CSS
You can reference local assets in your CSS files.
```css#styles.css
body {
background-image: url("./logo.png");
}
```
This will copy `./logo.png` to the output directory and rewrite the path in the CSS file to include a content hash.
```css#styles.css
body {
background-image: url("./logo-[ABC123].png");
}
```
### Importing CSS in JavaScript
To associate a CSS file with a JavaScript file, you can import it in your JavaScript file.
```ts#app.ts
import "./styles.css";
import "./more-styles.css";
```
This generates `./app.css` and `./app.js` in the output directory. All CSS files imported from JavaScript will be bundled into a single CSS file per entry point. If you import the same CSS file from multiple JavaScript files, it will only be included once in the output CSS file.
## Plugins
The dev server supports plugins.
### Tailwind CSS
To use TailwindCSS, install the `bun-plugin-tailwind` plugin:
```bash
# Or any npm client
$ bun install --dev bun-plugin-tailwind
```
Then, add the plugin to your `bunfig.toml`:
```toml
[serve.static]
plugins = ["bun-plugin-tailwind"]
```
Then, reference TailwindCSS in your HTML via `<link>` tag, `@import` in CSS, or `import` in JavaScript.
{% codetabs %}
```html#index.html
<!-- Reference TailwindCSS in your HTML -->
<link rel="stylesheet" href="tailwindcss" />
```
```css#styles.css
/* Import TailwindCSS in your CSS */
@import "tailwindcss";
```
```ts#app.ts
/* Import TailwindCSS in your JavaScript */
import "tailwindcss";
```
{% /codetabs %}
Only one of those are necessary, not all three.
## Keyboard Shortcuts
While the server is running:
- `o + Enter` - Open in browser
- `c + Enter` - Clear console
- `q + Enter` (or Ctrl+C) - Quit server
## Build for Production
When you're ready to deploy, use `bun build` to create optimized production bundles:
{% codetabs %}
```bash#CLI
$ bun build ./index.html --outdir=dist
$ bun build ./index.html --minify --outdir=dist
```
```ts#API
Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
minify: {
whitespace: true,
identifiers: true,
syntax: true,
}
});
```
{% /codetabs %}
Bun automatically:
Currently, plugins are only supported through `Bun.build`'s API or through `bunfig.toml` with the frontend dev server - not yet supported in `bun build`'s CLI.
- Bundles, tree-shakes, and optimizes your JavaScript, JSX and TypeScript
- Bundles and optimizes your CSS
- Copies & hashes images and other assets
- Updates all references to local files or packages in your HTML
### Watch Mode
## Zero Config, Maximum Performance
The HTML bundler is enabled by default after Bun v1.2+. Drop in your existing HTML files and Bun will handle:
- **TypeScript & JSX** - Write modern JavaScript for browsers without the setup
- **CSS** - Bundle CSS stylesheets directly from `<link rel="stylesheet">` or `@import`
- **Images & Assets** - Automatic copying & hashing & rewriting of assets in JavaScript, CSS, and HTML
## Watch mode
You can run `bun build --watch` to watch for changes and rebuild automatically.
You can run `bun build --watch` to watch for changes and rebuild automatically. This works nicely for library development.
You've never seen a watch mode this fast.
## Plugin API
### Plugin API
Need more control? Configure the bundler through the JavaScript API and use Bun's builtin `HTMLRewriter` to preprocess HTML.
@@ -102,3 +285,22 @@ Bun automatically handles all common web assets:
- Any `<link>` tag with an `href` attribute pointing to a local file is rewritten to the new path, and hashed
All paths are resolved relative to your HTML file, making it easy to organize your project however you want.
## This is a work in progress
- No HMR support yet
- Need more plugins
- Need more configuration options for things like asset handling
- Need a way to configure CORS, headers, etc.
If you want to submit a PR, most of the [code is here](https://github.com/oven-sh/bun/blob/main/src/js/internal/html.ts). You could even copy paste that file into your project and use it as a starting point.
## How this works
This is a small wrapper around Bun's support for HTML imports in JavaScript.
### Adding a backend to your frontend
To add a backend to your frontend, you can use the `"static"` option in `Bun.serve`.
Learn more in [the full-stack docs](/docs/bundler/fullstack).

View File

@@ -98,7 +98,7 @@ import { Database } from "bun:sqlite";
const sqlite = new Database("sqlite.db");
const db = drizzle(sqlite);
await migrate(db, { migrationsFolder: "./drizzle" });
migrate(db, { migrationsFolder: "./drizzle" });
```
---

View File

@@ -35,7 +35,7 @@ jobs:
# ...
- uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: 1.0.11 # or "latest", "canary", <sha>
+ bun-version: 1.2.0 # or "latest", "canary", <sha>
```
---

View File

@@ -214,7 +214,7 @@ export default {
page("bundler", "`Bun.build`", {
description: "Bundle code for consumption in the browser with Bun's native bundler.",
}),
page("bundler/html", "HTML", {
page("bundler/html", "Frontend & static sites", {
description: `Bundle html files with Bun's native bundler.`,
}),
page("bundler/fullstack", "Fullstack Dev Server", {

View File

@@ -180,6 +180,25 @@ Whether to skip test files when computing coverage statistics. Default `false`.
coverageSkipTestFiles = false
```
### `test.coverageReporter`
By default, coverage reports will be printed to the console. For persistent code coverage reports in CI environments and for other tools use `lcov`.
```toml
[test]
coverageReporter = ["text", "lcov"] # default ["text"]
```
### `test.coverageDir`
Set path where coverage reports will be saved. Please notice, that it works only for persistent `coverageReporter` like `lcov`.
```toml
[test]
coverageDir = "path/to/somewhere" # default "coverage"
```
## Package manager
Package management is a complex issue; to support a range of use cases, the behavior of `bun install` can be configured under the `[install]` section.

View File

@@ -58,3 +58,82 @@ export const foo = "Hello world!"
```
{% /codetabs %}
## Experimental Decorators
Bun supports the pre-TypeScript 5.0 experimental decorators syntax.
```ts#hello.ts
// Simple logging decorator
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey} with:`, args);
return originalMethod.apply(this, args);
};
}
class Example {
@log
greet(name: string) {
return `Hello ${name}!`;
}
}
// Usage
const example = new Example();
example.greet("world"); // Logs: "Calling greet with: ['world']"
```
To enable it, add `"experimentalDecorators": true` to your `tsconfig.json`:
```jsonc#tsconfig.json
{
"compilerOptions": {
// ... rest of your config
"experimentalDecorators": true,
},
}
```
We generally don't recommend using this in new codebases, but plenty of existing codebases have come to rely on it.
### emitDecoratorMetadata
Bun supports `emitDecoratorMetadata` in your `tsconfig.json`. This enables emitting design-time type metadata for decorated declarations in source files.
```ts#emit-decorator-metadata.ts
import "reflect-metadata";
class User {
id: number;
name: string;
}
function Injectable(target: Function) {
// Get metadata about constructor parameters
const params = Reflect.getMetadata("design:paramtypes", target);
console.log("Dependencies:", params); // [User]
}
@Injectable
class UserService {
constructor(private user: User) {}
}
// Creates new UserService instance with dependencies
const container = new UserService(new User());
```
To enable it, add `"emitDecoratorMetadata": true` to your `tsconfig.json`:
```jsonc#tsconfig.json
{
"compilerOptions": {
// ... rest of your config
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
},
}
```

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "macros",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "simple-react",
@@ -1659,7 +1659,7 @@
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
"ws": ["ws@7.5.9", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q=="],
"ws": ["ws@7.5.9", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q=="],
"xml-name-validator": ["xml-name-validator@3.0.0", "", {}, "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="],

View File

@@ -20,6 +20,7 @@
"build",
"test/snapshots/**",
"bench/react-hello-world/*.js",
"bun.lock",
"test/js/node/**/parallel/**",
"test/js/node/test/fixtures", // full of JS with intentional syntax errors

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "bun",
"version": "1.2.1",
"version": "1.2.3",
"workspaces": [
"./packages/bun-types"
],
@@ -22,8 +22,8 @@
"react-dom": "^18.3.1",
"source-map-js": "^1.2.0",
"typescript": "^5.7.2",
"caniuse-lite": "^1.0.30001620",
"autoprefixer": "^10.4.19",
"caniuse-lite": "^1.0.30001660",
"autoprefixer": "^10.4.20",
"@mdn/browser-compat-data": "~5.5.28"
},
"resolutions": {

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-debug-adapter-protocol",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "web-inspector-bun",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-inspector-protocol",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {
@@ -26,7 +26,7 @@
"@types/p-queue": ["@types/p-queue@3.2.1", "", { "dependencies": { "p-queue": "*" } }, "sha512-tgAdn5zEs05NuHzOyRM34cMO0rczStphR/kLo/ZJwwwJ5S2+QVxwA6gST3vDHWPB1oDfUuT6wOouhJvJkBCA0w=="],
"bun": ["bun@workspace:runners/bun", {}],
"bun": ["bun@workspace:runners/bun"],
"bun-types": ["bun-types@1.0.4-canary.20230929T233451", "", {}, "sha512-Ke/y3GX0T2ZYKx0UKKCnFRRP9bXzVRcRZCrIlF5/aRNEpgbfrMBw+s5imPqrV2CqJ7q6kIbMikCahzMr4N9PTg=="],
@@ -38,7 +38,7 @@
"prettier": ["prettier@2.8.8", "", { "bin": { "prettier": "bin-prettier.js" } }, "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="],
"qunit": ["qunit@workspace:runners/qunit", {}],
"qunit": ["qunit@workspace:runners/qunit"],
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {

View File

@@ -2,16 +2,12 @@
name = "bun-native-plugin"
description = "Rustified wrapper for writing native plugins for Bun."
license = "MIT"
version = "0.1.2"
version = "0.2.0"
edition = "2021"
[dependencies]
anyhow = "1.0.94"
# use local path in dev and publish to crates.io in prod
bun-macro = { path = "./bun-macro", version = "0.1.0" }
napi = { version = "2.14.1", default-features = false, features = ["napi4"] }
[features]
default = ["napi"]
napi = []

View File

@@ -473,6 +473,10 @@ impl<'a> OnBeforeParse<'a> {
}
}
/// # Safety
/// This is unsafe as you must ensure that no other invocation of the plugin (or JS!)
/// simultaneously holds a mutable reference to the external.
///
/// Get the external object from the `OnBeforeParse` arguments.
///
/// The external object is set by the plugin definition inside of JS:
@@ -521,42 +525,35 @@ impl<'a> OnBeforeParse<'a> {
/// },
/// };
/// ```
pub unsafe fn external<T: 'static + Sync>(&self) -> PluginResult<Option<&'static T>> {
pub unsafe fn external<'b, T: 'static + Sync>(
&self,
from_raw: unsafe fn(*mut c_void) -> Option<&'b T>,
) -> PluginResult<Option<&'b T>> {
if unsafe { (*self.args_raw).external.is_null() } {
return Ok(None);
}
let external: *mut TaggedObject<T> =
unsafe { (*self.args_raw).external as *mut TaggedObject<T> };
let external = unsafe { from_raw((*self.args_raw).external as *mut _) };
unsafe {
if (*external).type_id != TypeId::of::<T>() {
return Err(Error::ExternalTypeMismatch);
}
Ok((*external).object.as_ref())
}
Ok(external)
}
/// The same as [`crate::bun_native_plugin::OnBeforeParse::external`], but returns a mutable reference.
///
/// This is unsafe as you must ensure that no other invocation of the plugin
/// # Safety
/// This is unsafe as you must ensure that no other invocation of the plugin (or JS!)
/// simultaneously holds a mutable reference to the external.
pub unsafe fn external_mut<T: 'static + Sync>(&mut self) -> PluginResult<Option<&mut T>> {
pub unsafe fn external_mut<'b, T: 'static + Sync>(
&mut self,
from_raw: unsafe fn(*mut c_void) -> Option<&'b mut T>,
) -> PluginResult<Option<&'b mut T>> {
if unsafe { (*self.args_raw).external.is_null() } {
return Ok(None);
}
let external: *mut TaggedObject<T> =
unsafe { (*self.args_raw).external as *mut TaggedObject<T> };
let external = unsafe { from_raw((*self.args_raw).external as *mut _) };
unsafe {
if (*external).type_id != TypeId::of::<T>() {
return Err(Error::ExternalTypeMismatch);
}
Ok((*external).object.as_mut())
}
Ok(external)
}
/// Get the input source code for the current file.

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-plugin",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-polyfills",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {

View File

@@ -2009,35 +2009,51 @@ declare module "bun" {
*/
type SQLOptions = {
/** Connection URL (can be string or URL object) */
url: URL | string;
url?: URL | string;
/** Database server hostname */
host: string;
host?: string;
/** Database server hostname (alias for host) */
hostname?: string;
/** Database server port number */
port: number | string;
port?: number | string;
/** Database user for authentication */
username: string;
username?: string;
/** Database user for authentication (alias for username) */
user?: string;
/** Database password for authentication */
password: string;
password?: string;
/** Database password for authentication (alias for password) */
pass?: string;
/** Name of the database to connect to */
database: string;
database?: string;
/** Name of the database to connect to (alias for database) */
db?: string;
/** Database adapter/driver to use */
adapter: string;
/** Maximum time in milliseconds to wait for connection to become available */
idleTimeout: number;
/** Maximum time in milliseconds to wait when establishing a connection */
connectionTimeout: number;
/** Maximum lifetime in milliseconds of a connection */
maxLifetime: number;
adapter?: string;
/** Maximum time in seconds to wait for connection to become available */
idleTimeout?: number;
/** Maximum time in seconds to wait for connection to become available (alias for idleTimeout) */
idle_timeout?: number;
/** Maximum time in seconds to wait when establishing a connection */
connectionTimeout?: number;
/** Maximum time in seconds to wait when establishing a connection (alias for connectionTimeout) */
connection_timeout?: number;
/** Maximum lifetime in seconds of a connection */
maxLifetime?: number;
/** Maximum lifetime in seconds of a connection (alias for maxLifetime) */
max_lifetime?: number;
/** Whether to use TLS/SSL for the connection */
tls: boolean;
tls?: TLSOptions | boolean;
/** Whether to use TLS/SSL for the connection (alias for tls) */
ssl?: TLSOptions | boolean;
/** Callback function executed when a connection is established */
onconnect: (client: SQL) => void;
onconnect?: (client: SQL) => void;
/** Callback function executed when a connection is closed */
onclose: (client: SQL) => void;
onclose?: (client: SQL) => void;
/** Maximum number of connections in the pool */
max: number;
max?: number;
/** By default values outside i32 range are returned as strings. If this is true, values outside i32 range are returned as BigInts. */
bigint: boolean;
bigint?: boolean;
};
/**

View File

@@ -27,7 +27,7 @@
},
"scripts": {
"prebuild": "echo $(pwd)",
"copy-docs": "rm -rf docs && cp -rL ../../docs/ ./docs && sed -i 's/\\$BUN_LATEST_VERSION/'\"${BUN_VERSION:-1.0.0}\"'/g' ./docs/**/*.md",
"copy-docs": "rm -rf docs && cp -rL ../../docs/ ./docs && find ./docs -type f -name '*.md' -exec sed -i 's/\\$BUN_LATEST_VERSION/'\"${BUN_VERSION#bun-v:-1.0.0}\"'/g' {} +",
"build": "bun run copy-docs && bun scripts/build.ts && bun run fmt",
"test": "tsc",
"fmt": "echo $(which biome) && biome format --write ."

View File

@@ -387,8 +387,15 @@ int bsd_socket_multicast_interface(LIBUS_SOCKET_DESCRIPTOR fd, const struct sock
static int bsd_socket_set_membership4(LIBUS_SOCKET_DESCRIPTOR fd, const struct sockaddr_in *addr, const struct sockaddr_in *iface, int drop) {
struct ip_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
mreq.imr_interface.s_addr = iface->sin_addr.s_addr;
if (iface != NULL) {
mreq.imr_interface.s_addr = iface->sin_addr.s_addr;
} else {
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
}
int option = drop ? IP_DROP_MEMBERSHIP : IP_ADD_MEMBERSHIP;
return setsockopt(fd, IPPROTO_IP, option, &mreq, sizeof(mreq));
}
@@ -397,13 +404,15 @@ static int bsd_socket_set_membership6(LIBUS_SOCKET_DESCRIPTOR fd, const struct s
struct ipv6_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.ipv6mr_multiaddr = addr->sin6_addr;
mreq.ipv6mr_interface = iface->sin6_scope_id;
if (iface != NULL) {
mreq.ipv6mr_interface = iface->sin6_scope_id;
}
int option = drop ? IPV6_LEAVE_GROUP : IPV6_JOIN_GROUP;
return setsockopt(fd, IPPROTO_IP, option, &mreq, sizeof(mreq));
}
int bsd_socket_set_membership(LIBUS_SOCKET_DESCRIPTOR fd, const struct sockaddr_storage *addr, const struct sockaddr_storage *iface, int drop) {
if (addr->ss_family != iface->ss_family) {
if (iface != NULL && addr->ss_family != iface->ss_family) {
errno = EINVAL;
return -1;
}

View File

@@ -1589,22 +1589,40 @@ struct us_listen_socket_t *us_internal_ssl_socket_context_listen_unix(
socket_ext_size, error);
}
// https://github.com/oven-sh/bun/issues/16995
static void us_internal_zero_ssl_data_for_connected_socket_before_onopen(struct us_internal_ssl_socket_t *s) {
s->ssl = NULL;
s->ssl_write_wants_read = 0;
s->ssl_read_wants_write = 0;
s->fatal_error = 0;
s->handshake_state = HANDSHAKE_PENDING;
}
// TODO does this need more changes?
struct us_connecting_socket_t *us_internal_ssl_socket_context_connect(
struct us_socket_t *us_internal_ssl_socket_context_connect(
struct us_internal_ssl_socket_context_t *context, const char *host,
int port, int options, int socket_ext_size, int* is_connected) {
return us_socket_context_connect(
int port, int options, int socket_ext_size, int* is_connecting) {
struct us_internal_ssl_socket_t *s = (struct us_internal_ssl_socket_t *)us_socket_context_connect(
2, &context->sc, host, port, options,
sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) +
socket_ext_size, is_connected);
socket_ext_size, is_connecting);
if (*is_connecting) {
us_internal_zero_ssl_data_for_connected_socket_before_onopen(s);
}
return (struct us_socket_t*)s;
}
struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_connect_unix(
struct us_socket_t *us_internal_ssl_socket_context_connect_unix(
struct us_internal_ssl_socket_context_t *context, const char *server_path,
size_t pathlen, int options, int socket_ext_size) {
return (struct us_internal_ssl_socket_t *)us_socket_context_connect_unix(
struct us_socket_t *s = (struct us_socket_t *)us_socket_context_connect_unix(
0, &context->sc, server_path, pathlen, options,
sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) +
socket_ext_size);
if (s) {
us_internal_zero_ssl_data_for_connected_socket_before_onopen((struct us_internal_ssl_socket_t*) s);
}
return s;
}
static void ssl_on_open_without_sni(struct us_internal_ssl_socket_t *s, int is_client, char *ip, int ip_length) {

View File

@@ -247,7 +247,7 @@ void us_loop_run(struct us_loop_t *loop) {
}
}
extern int Bun__JSC_onBeforeWait(void*);
extern void Bun__JSC_onBeforeWait(void*);
extern void Bun__JSC_onAfterWait(void*);
void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout) {
@@ -265,10 +265,8 @@ void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout
/* Emit pre callback */
us_internal_loop_pre(loop);
int needs_after_wait = 0;
if (loop->data.jsc_vm) {
needs_after_wait = Bun__JSC_onBeforeWait(loop->data.jsc_vm);
}
/* Safe if jsc_vm is NULL */
Bun__JSC_onBeforeWait(loop->data.jsc_vm);
/* Fetch ready polls */
#ifdef LIBUS_USE_EPOLL
@@ -280,9 +278,7 @@ void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout
} while (IS_EINTR(loop->num_ready_polls));
#endif
if (needs_after_wait) {
Bun__JSC_onAfterWait(loop->data.jsc_vm);
}
Bun__JSC_onAfterWait(loop->data.jsc_vm);
/* Iterate ready polls, dispatching them by type */
for (loop->current_ready_poll = 0; loop->current_ready_poll < loop->num_ready_polls; loop->current_ready_poll++) {

View File

@@ -400,11 +400,11 @@ struct us_listen_socket_t *us_internal_ssl_socket_context_listen_unix(
us_internal_ssl_socket_context_r context, const char *path,
size_t pathlen, int options, int socket_ext_size, int* error);
struct us_connecting_socket_t *us_internal_ssl_socket_context_connect(
struct us_socket_t *us_internal_ssl_socket_context_connect(
us_internal_ssl_socket_context_r context, const char *host,
int port, int options, int socket_ext_size, int* is_resolved);
struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_connect_unix(
struct us_socket_t *us_internal_ssl_socket_context_connect_unix(
us_internal_ssl_socket_context_r context, const char *server_path,
size_t pathlen, int options, int socket_ext_size);

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "mock-debug",
@@ -148,9 +148,9 @@
"buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
"bun-debug-adapter-protocol": ["bun-debug-adapter-protocol@workspace:../bun-debug-adapter-protocol", { "dependencies": { "semver": "^7.5.4", "source-map-js": "^1.0.2" } }],
"bun-debug-adapter-protocol": ["bun-debug-adapter-protocol@workspace:../bun-debug-adapter-protocol"],
"bun-inspector-protocol": ["bun-inspector-protocol@workspace:../bun-inspector-protocol", { "dependencies": { "ws": "^8.13.0" } }],
"bun-inspector-protocol": ["bun-inspector-protocol@workspace:../bun-inspector-protocol"],
"bun-types": ["bun-types@1.1.29", "", { "dependencies": { "@types/node": "~20.12.8", "@types/ws": "~8.5.10" } }, "sha512-En3/TzSPMPyl5UlUB1MHzHpcrZDakTm7mS203eLoX1fBoEa3PW+aSS8GAqVJ7Is/m34Z5ogL+ECniLY0uDaCPw=="],

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-wasm",

View File

@@ -3,7 +3,6 @@ pub usingnamespace @import("src/main_wasm.zig");
pub const bun = @import("src/bun.zig");
pub const completions = struct {};
pub const is_bindgen = true;
pub const JavaScriptCore = struct {
pub fn markBinding(_: @import("std").builtin.SourceLocation) void {
unreachable;

View File

@@ -765,7 +765,7 @@ install_nodejs_headers() {
}
bun_version_exact() {
print "1.1.38"
print "1.2.0"
}
install_bun() {

View File

@@ -170,13 +170,13 @@ pub inline fn configureAllocator(_: AllocatorConfiguration) void {
}
pub fn notimpl() noreturn {
@setCold(true);
@branchHint(.cold);
Output.panic("Not implemented yet!!!!!", .{});
}
// Make sure we always print any leftover
pub fn crash() noreturn {
@setCold(true);
@branchHint(.cold);
Global.exit(1);
}

View File

@@ -164,7 +164,7 @@ const FutexImpl = struct {
}
fn lockSlow(self: *@This()) void {
@setCold(true);
@branchHint(.cold);
// Avoid doing an atomic swap below if we already know the state is contended.
// An atomic swap unconditionally stores which marks the cache-line as modified unnecessarily.

View File

@@ -36,6 +36,17 @@ pub const StandaloneModuleGraph = struct {
pub const base_public_path = targetBasePublicPath(Environment.os, "");
pub const base_public_path_with_default_suffix = targetBasePublicPath(Environment.os, "root/");
const Instance = struct {
pub var instance: ?*StandaloneModuleGraph = null;
};
pub fn get() ?*StandaloneModuleGraph {
return Instance.instance;
}
pub fn set(instance: *StandaloneModuleGraph) void {
Instance.instance = instance;
}
pub fn targetBasePublicPath(target: Environment.OperatingSystem, comptime suffix: [:0]const u8) [:0]const u8 {
return switch (target) {
@@ -62,10 +73,16 @@ pub const StandaloneModuleGraph = struct {
return this.findAssumeStandalonePath(name);
}
pub fn stat(this: *const StandaloneModuleGraph, name: []const u8) ?bun.Stat {
const file = this.find(name) orelse return null;
return file.stat();
}
pub fn findAssumeStandalonePath(this: *const StandaloneModuleGraph, name: []const u8) ?*File {
if (Environment.isWindows) {
var normalized_buf: bun.PathBuffer = undefined;
const normalized = bun.path.platformToPosixBuf(u8, name, &normalized_buf);
const input = strings.withoutNTPrefix(u8, name);
const normalized = bun.path.platformToPosixBuf(u8, input, &normalized_buf);
return this.files.getPtr(normalized);
}
return this.files.getPtr(name);
@@ -107,6 +124,13 @@ pub const StandaloneModuleGraph = struct {
bytecode: []u8 = "",
module_format: ModuleFormat = .none,
pub fn stat(this: *const File) bun.Stat {
var result = std.mem.zeroes(bun.Stat);
result.size = @intCast(this.contents.len);
result.mode = bun.S.IFREG | 0o644;
return result;
}
pub fn lessThanByIndex(ctx: []const File, lhs_i: u32, rhs_i: u32) bool {
const lhs = ctx[lhs_i];
const rhs = ctx[rhs_i];

View File

@@ -333,11 +333,11 @@ fn appendFileAssumeCapacity(
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kqueue.2.html
var event = std.mem.zeroes(KEvent);
event.flags = std.c.EV_ADD | std.c.EV_CLEAR | std.c.EV_ENABLE;
event.flags = std.c.EV.ADD | std.c.EV.CLEAR | std.c.EV.ENABLE;
// we want to know about the vnode
event.filter = std.c.EVFILT_VNODE;
event.filter = std.c.EVFILT.VNODE;
event.fflags = std.c.NOTE_WRITE | std.c.NOTE_RENAME | std.c.NOTE_DELETE;
event.fflags = std.c.NOTE.WRITE | std.c.NOTE.RENAME | std.c.NOTE.DELETE;
// id
event.ident = @intCast(fd.int());
@@ -425,15 +425,15 @@ fn appendDirectoryAssumeCapacity(
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kqueue.2.html
var event = std.mem.zeroes(KEvent);
event.flags = std.c.EV_ADD | std.c.EV_CLEAR | std.c.EV_ENABLE;
event.flags = std.c.EV.ADD | std.c.EV.CLEAR | std.c.EV.ENABLE;
// we want to know about the vnode
event.filter = std.c.EVFILT_VNODE;
event.filter = std.c.EVFILT.VNODE;
// monitor:
// - Write
// - Rename
// - Delete
event.fflags = std.c.NOTE_WRITE | std.c.NOTE_RENAME | std.c.NOTE_DELETE;
event.fflags = std.c.NOTE.WRITE | std.c.NOTE.RENAME | std.c.NOTE.DELETE;
// id
event.ident = @intCast(fd.int());

View File

@@ -20,7 +20,7 @@ const Analytics = @import("./analytics_schema.zig").analytics;
const Writer = @import("./analytics_schema.zig").Writer;
const Headers = bun.http.Headers;
const Futex = @import("../futex.zig");
const Semver = @import("../install/semver.zig");
const Semver = bun.Semver;
/// Enables analytics. This is used by:
/// - crash_handler.zig's `report` function to anonymously report crashes
@@ -126,8 +126,8 @@ pub const Features = struct {
pub var s3: usize = 0;
comptime {
@export(napi_module_register, .{ .name = "Bun__napi_module_register_count" });
@export(process_dlopen, .{ .name = "Bun__process_dlopen_count" });
@export(&napi_module_register, .{ .name = "Bun__napi_module_register_count" });
@export(&process_dlopen, .{ .name = "Bun__process_dlopen_count" });
}
pub fn formatter() Formatter {
@@ -138,14 +138,14 @@ pub const Features = struct {
pub fn format(_: Formatter, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
const fields = comptime brk: {
const info: std.builtin.Type = @typeInfo(Features);
var buffer: [info.Struct.decls.len][]const u8 = .{""} ** info.Struct.decls.len;
var buffer: [info.@"struct".decls.len][]const u8 = .{""} ** info.@"struct".decls.len;
var count: usize = 0;
for (info.Struct.decls) |decl| {
for (info.@"struct".decls) |decl| {
var f = &@field(Features, decl.name);
_ = &f;
const Field = @TypeOf(f);
const FieldT: std.builtin.Type = @typeInfo(Field);
if (FieldT.Pointer.child != usize) continue;
if (FieldT.pointer.child != usize) continue;
buffer[count] = decl.name;
count += 1;
}
@@ -216,7 +216,7 @@ pub const packed_features_list = brk: {
};
pub const PackedFeatures = @Type(.{
.Struct = .{
.@"struct" = .{
.layout = .@"packed",
.backing_integer = u64,
.fields = brk: {
@@ -226,7 +226,7 @@ pub const PackedFeatures = @Type(.{
fields[i] = .{
.name = name,
.type = bool,
.default_value = &false,
.default_value_ptr = &false,
.is_comptime = false,
.alignment = 0,
};
@@ -236,7 +236,7 @@ pub const PackedFeatures = @Type(.{
fields[i] = .{
.name = std.fmt.comptimePrint("_{d}", .{i}),
.type = bool,
.default_value = &false,
.default_value_ptr = &false,
.is_comptime = false,
.alignment = 0,
};

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-api",

View File

@@ -62,7 +62,7 @@ pub const Index = packed struct(u32) {
pub fn init(num: anytype) Index {
const NumType = @TypeOf(num);
if (comptime @typeInfo(NumType) == .Pointer) {
if (comptime @typeInfo(NumType) == .pointer) {
return init(num.*);
}

View File

@@ -366,42 +366,42 @@ pub const FilePoll = struct {
// var loader = ptr.as(ShellSubprocessCapturedBufferedWriterMini);
// loader.onPoll(size_or_offset, 0);
// },
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(ShellBufferedWriter))) => {
@field(Owner.Tag, @typeName(ShellBufferedWriter)) => {
var handler: *ShellBufferedWriter = ptr.as(ShellBufferedWriter);
handler.onPoll(size_or_offset, poll.flags.contains(.hup));
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(ShellStaticPipeWriter))) => {
@field(Owner.Tag, @typeName(ShellStaticPipeWriter)) => {
var handler: *ShellStaticPipeWriter = ptr.as(ShellStaticPipeWriter);
handler.onPoll(size_or_offset, poll.flags.contains(.hup));
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(StaticPipeWriter))) => {
@field(Owner.Tag, @typeName(StaticPipeWriter)) => {
var handler: *StaticPipeWriter = ptr.as(StaticPipeWriter);
handler.onPoll(size_or_offset, poll.flags.contains(.hup));
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(FileSink))) => {
@field(Owner.Tag, @typeName(FileSink)) => {
var handler: *FileSink = ptr.as(FileSink);
handler.onPoll(size_or_offset, poll.flags.contains(.hup));
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(BufferedReader))) => {
@field(Owner.Tag, @typeName(BufferedReader)) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) Reader", .{poll.fd});
var handler: *BufferedReader = ptr.as(BufferedReader);
handler.onPoll(size_or_offset, poll.flags.contains(.hup));
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(Process))) => {
@field(Owner.Tag, @typeName(Process)) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) Process", .{poll.fd});
var loader = ptr.as(Process);
loader.onWaitPidFromEventLoopTask();
},
@field(Owner.Tag, "DNSResolver") => {
@field(Owner.Tag, @typeName(DNSResolver)) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) DNSResolver", .{poll.fd});
var loader: *DNSResolver = ptr.as(DNSResolver);
loader.onDNSPoll(poll);
},
@field(Owner.Tag, "GetAddrInfoRequest") => {
@field(Owner.Tag, @typeName(GetAddrInfoRequest)) => {
if (comptime !Environment.isMac) {
unreachable;
}
@@ -411,7 +411,7 @@ pub const FilePoll = struct {
loader.onMachportChange();
},
@field(Owner.Tag, "Request") => {
@field(Owner.Tag, @typeName(Request)) => {
if (comptime !Environment.isMac) {
unreachable;
}
@@ -503,19 +503,19 @@ pub const FilePoll = struct {
pub fn fromKQueueEvent(kqueue_event: std.posix.system.kevent64_s) Flags.Set {
var flags = Flags.Set{};
if (kqueue_event.filter == std.posix.system.EVFILT_READ) {
if (kqueue_event.filter == std.posix.system.EVFILT.READ) {
flags.insert(Flags.readable);
if (kqueue_event.flags & std.posix.system.EV_EOF != 0) {
if (kqueue_event.flags & std.posix.system.EV.EOF != 0) {
flags.insert(Flags.hup);
}
} else if (kqueue_event.filter == std.posix.system.EVFILT_WRITE) {
} else if (kqueue_event.filter == std.posix.system.EVFILT.WRITE) {
flags.insert(Flags.writable);
if (kqueue_event.flags & std.posix.system.EV_EOF != 0) {
if (kqueue_event.flags & std.posix.system.EV.EOF != 0) {
flags.insert(Flags.hup);
}
} else if (kqueue_event.filter == std.posix.system.EVFILT_PROC) {
} else if (kqueue_event.filter == std.posix.system.EVFILT.PROC) {
flags.insert(Flags.process);
} else if (kqueue_event.filter == std.posix.system.EVFILT_MACHPORT) {
} else if (kqueue_event.filter == std.posix.system.EVFILT.MACHPORT) {
flags.insert(Flags.machport);
}
return flags;
@@ -592,8 +592,10 @@ pub const FilePoll = struct {
poll.flags.insert(.ignore_updates);
this.pending_free_tail = poll;
bun.assert(vm.after_event_loop_callback == null or vm.after_event_loop_callback == @as(?JSC.OpaqueCallback, @ptrCast(&processDeferredFrees)));
vm.after_event_loop_callback = @ptrCast(&processDeferredFrees);
const callback = JSC.OpaqueWrap(Store, processDeferredFrees);
bun.assert(vm.after_event_loop_callback == null or vm.after_event_loop_callback == @as(?JSC.OpaqueCallback, callback));
vm.after_event_loop_callback = callback;
vm.after_event_loop_callback_ctx = this;
}
};
@@ -763,7 +765,7 @@ pub const FilePoll = struct {
pub fn onTick(loop: *Loop, tagged_pointer: ?*anyopaque) callconv(.C) void {
var tag = Pollable.from(tagged_pointer);
if (tag.tag() != @field(Pollable.Tag, "FilePoll"))
if (tag.tag() != @field(Pollable.Tag, @typeName(FilePoll)))
return;
var file_poll: *FilePoll = tag.as(FilePoll);
@@ -782,7 +784,7 @@ pub const FilePoll = struct {
});
comptime {
@export(onTick, .{ .name = "Bun__internal_dispatch_ready_poll" });
@export(&onTick, .{ .name = "Bun__internal_dispatch_ready_poll" });
}
const timeout = std.mem.zeroes(std.posix.timespec);
@@ -837,45 +839,45 @@ pub const FilePoll = struct {
const one_shot_flag: u16 = if (!this.flags.contains(.one_shot))
0
else if (one_shot == .dispatch)
std.c.EV_DISPATCH | std.c.EV_ENABLE
std.c.EV.DISPATCH | std.c.EV.ENABLE
else
std.c.EV_ONESHOT;
std.c.EV.ONESHOT;
changelist[0] = switch (flag) {
.readable => .{
.ident = @intCast(fd.cast()),
.filter = std.posix.system.EVFILT_READ,
.filter = std.posix.system.EVFILT.READ,
.data = 0,
.fflags = 0,
.udata = @intFromPtr(Pollable.init(this).ptr()),
.flags = std.c.EV_ADD | one_shot_flag,
.flags = std.c.EV.ADD | one_shot_flag,
.ext = .{ this.generation_number, 0 },
},
.writable => .{
.ident = @intCast(fd.cast()),
.filter = std.posix.system.EVFILT_WRITE,
.filter = std.posix.system.EVFILT.WRITE,
.data = 0,
.fflags = 0,
.udata = @intFromPtr(Pollable.init(this).ptr()),
.flags = std.c.EV_ADD | one_shot_flag,
.flags = std.c.EV.ADD | one_shot_flag,
.ext = .{ this.generation_number, 0 },
},
.process => .{
.ident = @intCast(fd.cast()),
.filter = std.posix.system.EVFILT_PROC,
.filter = std.posix.system.EVFILT.PROC,
.data = 0,
.fflags = std.c.NOTE_EXIT,
.fflags = std.c.NOTE.EXIT,
.udata = @intFromPtr(Pollable.init(this).ptr()),
.flags = std.c.EV_ADD | one_shot_flag,
.flags = std.c.EV.ADD | one_shot_flag,
.ext = .{ this.generation_number, 0 },
},
.machport => .{
.ident = @intCast(fd.cast()),
.filter = std.posix.system.EVFILT_MACHPORT,
.filter = std.posix.system.EVFILT.MACHPORT,
.data = 0,
.fflags = 0,
.udata = @intFromPtr(Pollable.init(this).ptr()),
.flags = std.c.EV_ADD | one_shot_flag,
.flags = std.c.EV.ADD | one_shot_flag,
.ext = .{ this.generation_number, 0 },
},
else => unreachable,
@@ -913,7 +915,7 @@ pub const FilePoll = struct {
// processing an element of the changelist and there is enough room
// in the eventlist, then the event will be placed in the eventlist
// with EV_ERROR set in flags and the system error in data.
if (changelist[0].flags == std.c.EV_ERROR and changelist[0].data != 0) {
if (changelist[0].flags == std.c.EV.ERROR and changelist[0].data != 0) {
return JSC.Maybe(void).errnoSys(changelist[0].data, .kevent).?;
// Otherwise, -1 will be returned, and errno will be set to
// indicate the error condition.
@@ -1008,38 +1010,38 @@ pub const FilePoll = struct {
changelist[0] = switch (flag) {
.readable => .{
.ident = @intCast(fd.cast()),
.filter = std.posix.system.EVFILT_READ,
.filter = std.posix.system.EVFILT.READ,
.data = 0,
.fflags = 0,
.udata = @intFromPtr(Pollable.init(this).ptr()),
.flags = std.c.EV_DELETE,
.flags = std.c.EV.DELETE,
.ext = .{ 0, 0 },
},
.machport => .{
.ident = @intCast(fd.cast()),
.filter = std.posix.system.EVFILT_MACHPORT,
.filter = std.posix.system.EVFILT.MACHPORT,
.data = 0,
.fflags = 0,
.udata = @intFromPtr(Pollable.init(this).ptr()),
.flags = std.c.EV_DELETE,
.flags = std.c.EV.DELETE,
.ext = .{ 0, 0 },
},
.writable => .{
.ident = @intCast(fd.cast()),
.filter = std.posix.system.EVFILT_WRITE,
.filter = std.posix.system.EVFILT.WRITE,
.data = 0,
.fflags = 0,
.udata = @intFromPtr(Pollable.init(this).ptr()),
.flags = std.c.EV_DELETE,
.flags = std.c.EV.DELETE,
.ext = .{ 0, 0 },
},
.process => .{
.ident = @intCast(fd.cast()),
.filter = std.posix.system.EVFILT_PROC,
.filter = std.posix.system.EVFILT.PROC,
.data = 0,
.fflags = std.c.NOTE_EXIT,
.fflags = std.c.NOTE.EXIT,
.udata = @intFromPtr(Pollable.init(this).ptr()),
.flags = std.c.EV_DELETE,
.flags = std.c.EV.DELETE,
.ext = .{ 0, 0 },
},
else => unreachable,
@@ -1065,7 +1067,7 @@ pub const FilePoll = struct {
// processing an element of the changelist and there is enough room
// in the eventlist, then the event will be placed in the eventlist
// with EV_ERROR set in flags and the system error in data.
if (changelist[0].flags == std.c.EV_ERROR) {
if (changelist[0].flags == std.c.EV.ERROR) {
return JSC.Maybe(void).errnoSys(changelist[0].data, .kevent).?;
// Otherwise, -1 will be returned, and errno will be set to
// indicate the error condition.

View File

@@ -358,8 +358,10 @@ pub const FilePoll = struct {
poll.flags.insert(.ignore_updates);
this.pending_free_tail = poll;
bun.assert(vm.after_event_loop_callback == null or vm.after_event_loop_callback == @as(?JSC.OpaqueCallback, @ptrCast(&processDeferredFrees)));
vm.after_event_loop_callback = @ptrCast(&processDeferredFrees);
const callback = JSC.OpaqueWrap(Store, processDeferredFrees);
bun.assert(vm.after_event_loop_callback == null or vm.after_event_loop_callback == @as(?JSC.OpaqueCallback, callback));
vm.after_event_loop_callback = callback;
vm.after_event_loop_callback_ctx = this;
}
};

View File

@@ -342,7 +342,7 @@ pub fn BabyList(comptime Type: type) type {
return this.len - initial;
}
pub fn writeLatin1(this: *@This(), allocator: std.mem.Allocator, str: []const u8) !u32 {
pub fn writeLatin1(this: *@This(), allocator: std.mem.Allocator, str: []const u8) OOM!u32 {
if (comptime Type != u8)
@compileError("Unsupported for type " ++ @typeName(Type));
const initial = this.len;
@@ -352,7 +352,7 @@ pub fn BabyList(comptime Type: type) type {
return this.len - initial;
}
pub fn writeUTF16(this: *@This(), allocator: std.mem.Allocator, str: []const u16) !u32 {
pub fn writeUTF16(this: *@This(), allocator: std.mem.Allocator, str: []const u16) OOM!u32 {
if (comptime Type != u8)
@compileError("Unsupported for type " ++ @typeName(Type));

View File

@@ -21,13 +21,13 @@ bakeModuleLoaderImportModule(JSC::JSGlobalObject* global,
{
WTF::String keyString = moduleNameValue->getString(global);
if (keyString.startsWith("bake:/"_s)) {
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
return JSC::importModule(global, JSC::Identifier::fromString(vm, keyString),
JSC::jsUndefined(), parameters, JSC::jsUndefined());
}
if (!sourceOrigin.isNull() && sourceOrigin.string().startsWith("bake:/"_s)) {
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
auto scope = DECLARE_THROW_SCOPE(vm);
WTF::String refererString = sourceOrigin.string();
@@ -55,7 +55,7 @@ JSC::Identifier bakeModuleLoaderResolve(JSC::JSGlobalObject* jsGlobal,
JSC::JSValue referrer, JSC::JSValue origin)
{
Bake::GlobalObject* global = jsCast<Bake::GlobalObject*>(jsGlobal);
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
auto scope = DECLARE_THROW_SCOPE(vm);
ASSERT(referrer.isString());
@@ -77,7 +77,7 @@ JSC::Identifier bakeModuleLoaderResolve(JSC::JSGlobalObject* jsGlobal,
static JSC::JSInternalPromise* rejectedInternalPromise(JSC::JSGlobalObject* globalObject, JSC::JSValue value)
{
JSC::VM& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
JSC::JSInternalPromise* promise = JSC::JSInternalPromise::create(vm, globalObject->internalPromiseStructure());
promise->internalField(JSC::JSPromise::Field::ReactionsOrResult).set(vm, promise, value);
promise->internalField(JSC::JSPromise::Field::Flags).set(vm, promise, JSC::jsNumber(promise->internalField(JSC::JSPromise::Field::Flags).get().asUInt32AsAnyInt() | JSC::JSPromise::isFirstResolvingFunctionCalledFlag | static_cast<unsigned>(JSC::JSPromise::Status::Rejected)));
@@ -86,7 +86,7 @@ static JSC::JSInternalPromise* rejectedInternalPromise(JSC::JSGlobalObject* glob
static JSC::JSInternalPromise* resolvedInternalPromise(JSC::JSGlobalObject* globalObject, JSC::JSValue value)
{
JSC::VM& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
JSC::JSInternalPromise* promise = JSC::JSInternalPromise::create(vm, globalObject->internalPromiseStructure());
promise->internalField(JSC::JSPromise::Field::ReactionsOrResult).set(vm, promise, value);
promise->internalField(JSC::JSPromise::Field::Flags).set(vm, promise, JSC::jsNumber(promise->internalField(JSC::JSPromise::Field::Flags).get().asUInt32AsAnyInt() | JSC::JSPromise::isFirstResolvingFunctionCalledFlag | static_cast<unsigned>(JSC::JSPromise::Status::Fulfilled)));
@@ -100,7 +100,7 @@ JSC::JSInternalPromise* bakeModuleLoaderFetch(JSC::JSGlobalObject* globalObject,
JSC::JSValue parameters, JSC::JSValue script)
{
Bake::GlobalObject* global = jsCast<Bake::GlobalObject*>(globalObject);
JSC::VM& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
auto moduleKey = key.toWTFString(globalObject);
if (UNLIKELY(scope.exception()))

View File

@@ -21,7 +21,7 @@ extern "C" JSC::JSPromise* BakeRenderRoutesForProdStatic(
JSC::JSValue paramInformation,
JSC::JSValue styles)
{
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
JSC::JSFunction* cb = JSC::JSFunction::create(vm, global, WebCore::bakeRenderRoutesForProdStaticCodeGenerator(vm), global);
JSC::CallData callData = JSC::getCallData(cb);

View File

@@ -17,7 +17,7 @@
namespace Bake {
extern "C" JSC::EncodedJSValue BakeLoadInitialServerCode(GlobalObject* global, BunString source, bool separateSSRGraph) {
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
auto scope = DECLARE_THROW_SCOPE(vm);
String string = "bake://server-runtime.js"_s;
@@ -75,7 +75,7 @@ extern "C" JSC::EncodedJSValue BakeGetModuleNamespace(
JSC::JSValue keyValue
) {
JSC::JSString* key = JSC::jsCast<JSC::JSString*>(keyValue);
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
JSC::JSMap* map = JSC::jsCast<JSC::JSMap*>(
global->moduleLoader()->getDirect(
vm, JSC::Identifier::fromString(global->vm(), "registry"_s)
@@ -93,7 +93,7 @@ extern "C" JSC::EncodedJSValue BakeGetDefaultExportFromModule(
JSC::JSGlobalObject* global,
JSC::JSValue keyValue
) {
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
return JSC::JSValue::encode(jsCast<JSC::JSModuleNamespaceObject*>(JSC::JSValue::decode(BakeGetModuleNamespace(global, keyValue)))->get(global, vm.propertyNames->defaultKeyword));
}
@@ -104,7 +104,7 @@ extern "C" JSC::EncodedJSValue BakeGetOnModuleNamespace(
const unsigned char* key,
size_t keyLength
) {
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
const auto propertyString = String(StringImpl::createWithoutCopying({ key, keyLength }));
const auto identifier = JSC::Identifier::fromString(vm, propertyString);
const auto property = JSC::PropertyName(identifier);
@@ -112,7 +112,7 @@ extern "C" JSC::EncodedJSValue BakeGetOnModuleNamespace(
}
extern "C" JSC::EncodedJSValue BakeRegisterProductionChunk(JSC::JSGlobalObject* global, BunString virtualPathName, BunString source) {
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
auto scope = DECLARE_THROW_SCOPE(vm);
String string = virtualPathName.toWTFString();

View File

@@ -865,7 +865,7 @@ const DeferredRequest = struct {
server_handler: bun.JSC.API.SavedRequest,
js_payload: *Response,
const Tag = @typeInfo(Data).Union.tag_type.?;
const Tag = @typeInfo(Data).@"union".tag_type.?;
};
};
@@ -3715,20 +3715,20 @@ const HmrTopic = enum(u8) {
/// Invalid data
_,
pub const max_count = @typeInfo(HmrTopic).Enum.fields.len;
pub const Bits = @Type(.{ .Struct = .{
.backing_integer = @Type(.{ .Int = .{
pub const max_count = @typeInfo(HmrTopic).@"enum".fields.len;
pub const Bits = @Type(.{ .@"struct" = .{
.backing_integer = @Type(.{ .int = .{
.bits = max_count,
.signedness = .unsigned,
} }),
.fields = &brk: {
const enum_fields = @typeInfo(HmrTopic).Enum.fields;
const enum_fields = @typeInfo(HmrTopic).@"enum".fields;
var fields: [enum_fields.len]std.builtin.Type.StructField = undefined;
for (enum_fields, &fields) |e, *s| {
s.* = .{
.name = e.name,
.type = bool,
.default_value = &false,
.default_value_ptr = &false,
.is_comptime = false,
.alignment = 0,
};
@@ -3768,7 +3768,7 @@ const HmrSocket = struct {
const topics = msg[1..];
if (topics.len > HmrTopic.max_count) return;
outer: for (topics) |char| {
inline for (@typeInfo(HmrTopic).Enum.fields) |field| {
inline for (@typeInfo(HmrTopic).@"enum".fields) |field| {
if (char == field.value) {
@field(new_bits, field.name) = true;
continue :outer;
@@ -4063,7 +4063,7 @@ const WatcherAtomics = struct {
ev.timer = std.time.Timer.start() catch unreachable;
},
1 => {
// @branchHint(.unlikely);
@branchHint(.unlikely);
// DevServer stole this event. Unlikely but possible when
// the user is saving very heavily (10-30 times per second)
state.current +%= 1;
@@ -4087,12 +4087,12 @@ const WatcherAtomics = struct {
ev.owner.bun_watcher.thread_lock.assertLocked();
if (ev.files.count() > 0) {
// @branchHint(.likely);
@branchHint(.likely);
// There are files to be processed, increment this count first.
const prev_count = state.watcher_events_emitted.fetchAdd(1, .seq_cst);
if (prev_count == 0) {
// @branchHint(.likely);
@branchHint(.likely);
// Submit a task to the DevServer, notifying it that there is
// work to do. The watcher will move to the other event.
ev.concurrent_task = .{
@@ -4434,7 +4434,7 @@ pub const EntryPointList = struct {
pub fn append(entry_points: *EntryPointList, allocator: std.mem.Allocator, abs_path: []const u8, flags: Flags) !void {
const gop = try entry_points.set.getOrPut(allocator, abs_path);
if (gop.found_existing) {
const T = @typeInfo(Flags).Struct.backing_integer.?;
const T = @typeInfo(Flags).@"struct".backing_integer.?;
gop.value_ptr.* = @bitCast(@as(T, @bitCast(gop.value_ptr.*)) | @as(T, @bitCast(flags)));
} else {
gop.value_ptr.* = flags;

View File

@@ -331,7 +331,7 @@ pub const Part = union(enum(u3)) {
group: []const u8,
const SerializedHeader = packed struct(u32) {
tag: @typeInfo(Part).Union.tag_type.?,
tag: @typeInfo(Part).@"union".tag_type.?,
len: u29,
};

View File

@@ -325,10 +325,10 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type {
const mask_info: std.builtin.Type = @typeInfo(MaskIntType);
// Make sure the mask int is indeed an int
if (mask_info != .Int) @compileError("ArrayBitSet can only operate on integer masks, but was passed " ++ @typeName(MaskIntType));
if (mask_info != .int) @compileError("ArrayBitSet can only operate on integer masks, but was passed " ++ @typeName(MaskIntType));
// It must also be unsigned.
if (mask_info.Int.signedness != .unsigned) @compileError("ArrayBitSet requires an unsigned integer mask type, but was passed " ++ @typeName(MaskIntType));
if (mask_info.int.signedness != .unsigned) @compileError("ArrayBitSet requires an unsigned integer mask type, but was passed " ++ @typeName(MaskIntType));
// And it must not be empty.
if (MaskIntType == u0)
@@ -1620,7 +1620,7 @@ fn testSupersetOf(empty: anytype, full: anytype, even: anytype, odd: anytype, le
fn testBitSet(a: anytype, b: anytype, len: usize) !void {
try testing.expectEqual(len, a.capacity());
try testing.expectEqual(len, b.capacity());
const needs_ptr = @hasField(std.meta.Child(@TypeOf(a)), "masks") and @typeInfo(@TypeOf(@field(a, "masks"))) != .Pointer;
const needs_ptr = @hasField(std.meta.Child(@TypeOf(a)), "masks") and @typeInfo(@TypeOf(@field(a, "masks"))) != .pointer;
{
for (0..len) |i| {
@@ -1844,7 +1844,7 @@ fn fillOdd(set: anytype, len: usize) void {
fn testPureBitSet(comptime Set: type) !void {
var empty_ = Set.initEmpty();
var full_ = Set.initFull();
const needs_ptr = @hasField(Set, "masks") and @typeInfo(@TypeOf(empty_.masks)) != .Pointer;
const needs_ptr = @hasField(Set, "masks") and @typeInfo(@TypeOf(empty_.masks)) != .pointer;
var even_ = even: {
var bit_set = Set.initEmpty();
@@ -1900,7 +1900,7 @@ fn testPureBitSet(comptime Set: type) !void {
try testing.expect(full.differenceWith(even).eql(odd));
}
fn testStaticBitSet(comptime Set: type, comptime Container: @Type(.EnumLiteral)) !void {
fn testStaticBitSet(comptime Set: type, comptime Container: @Type(.enum_literal)) !void {
var a = Set.initEmpty();
var b = Set.initFull();
try testing.expectEqual(@as(usize, 0), a.count());

View File

@@ -2,11 +2,13 @@ const std = @import("std");
pub fn Bitflags(comptime T: type) type {
const tyinfo = @typeInfo(T);
const IntType = tyinfo.Struct.backing_integer.?;
const IntType = tyinfo.@"struct".backing_integer.?;
const IntTypeInfo = @typeInfo(IntType);
const IntRepresentingNumOfBits = std.math.IntFittingRange(0, IntTypeInfo.Int.bits);
const IntRepresentingNumOfBits = std.math.IntFittingRange(0, IntTypeInfo.int.bits);
return struct {
pub const IMPL_BITFLAGS: u0 = 0;
pub inline fn empty() T {
return @bitCast(@as(IntType, 0));
}

View File

@@ -8,7 +8,6 @@ const String = bun.String;
const JSGlobalObject = JSC.JSGlobalObject;
const JSValue = JSC.JSValue;
const strings = bun.strings;
const is_bindgen = JSC.is_bindgen;
const ZigException = JSC.ZigException;
const ZigString = JSC.ZigString;
const VirtualMachine = JSC.VirtualMachine;
@@ -104,10 +103,6 @@ fn messageWithTypeAndLevel_(
vals: [*]const JSValue,
len: usize,
) bun.JSError!void {
if (comptime is_bindgen) {
return;
}
var console = global.bunVM().console;
defer console.default_indent +|= @as(u16, @intFromBool(message_type == .StartGroup));
@@ -3438,7 +3433,7 @@ pub const Formatter = struct {
"<r><d>, ... {d} more<r>";
writer.print(comptime Output.prettyFmt(fmt_, enable_ansi_colors), .{
if (@typeInfo(Number) == .Float) bun.fmt.double(@floatCast(slice[0])) else slice[0],
if (@typeInfo(Number) == .float) bun.fmt.double(@floatCast(slice[0])) else slice[0],
});
var leftover = slice[1..];
const max = 512;
@@ -3448,7 +3443,7 @@ pub const Formatter = struct {
writer.space();
writer.print(comptime Output.prettyFmt(fmt_, enable_ansi_colors), .{
if (@typeInfo(Number) == .Float) bun.fmt.double(@floatCast(el)) else el,
if (@typeInfo(Number) == .float) bun.fmt.double(@floatCast(el)) else el,
});
}
@@ -3691,17 +3686,17 @@ pub fn screenshot(
) callconv(JSC.conv) void {}
comptime {
@export(messageWithTypeAndLevel, .{ .name = shim.symbolName("messageWithTypeAndLevel") });
@export(count, .{ .name = shim.symbolName("count") });
@export(countReset, .{ .name = shim.symbolName("countReset") });
@export(time, .{ .name = shim.symbolName("time") });
@export(timeLog, .{ .name = shim.symbolName("timeLog") });
@export(timeEnd, .{ .name = shim.symbolName("timeEnd") });
@export(profile, .{ .name = shim.symbolName("profile") });
@export(profileEnd, .{ .name = shim.symbolName("profileEnd") });
@export(takeHeapSnapshot, .{ .name = shim.symbolName("takeHeapSnapshot") });
@export(timeStamp, .{ .name = shim.symbolName("timeStamp") });
@export(record, .{ .name = shim.symbolName("record") });
@export(recordEnd, .{ .name = shim.symbolName("recordEnd") });
@export(screenshot, .{ .name = shim.symbolName("screenshot") });
@export(&messageWithTypeAndLevel, .{ .name = shim.symbolName("messageWithTypeAndLevel") });
@export(&count, .{ .name = shim.symbolName("count") });
@export(&countReset, .{ .name = shim.symbolName("countReset") });
@export(&time, .{ .name = shim.symbolName("time") });
@export(&timeLog, .{ .name = shim.symbolName("timeLog") });
@export(&timeEnd, .{ .name = shim.symbolName("timeEnd") });
@export(&profile, .{ .name = shim.symbolName("profile") });
@export(&profileEnd, .{ .name = shim.symbolName("profileEnd") });
@export(&takeHeapSnapshot, .{ .name = shim.symbolName("takeHeapSnapshot") });
@export(&timeStamp, .{ .name = shim.symbolName("timeStamp") });
@export(&record, .{ .name = shim.symbolName("record") });
@export(&recordEnd, .{ .name = shim.symbolName("recordEnd") });
@export(&screenshot, .{ .name = shim.symbolName("screenshot") });
}

View File

@@ -99,75 +99,71 @@ pub const BunObject = struct {
@compileError("Must be comptime");
}
if (JSC.is_bindgen) {
return;
}
// --- Getters ---
@export(BunObject.CryptoHasher, .{ .name = getterName("CryptoHasher") });
@export(BunObject.FFI, .{ .name = getterName("FFI") });
@export(BunObject.FileSystemRouter, .{ .name = getterName("FileSystemRouter") });
@export(BunObject.MD4, .{ .name = getterName("MD4") });
@export(BunObject.MD5, .{ .name = getterName("MD5") });
@export(BunObject.SHA1, .{ .name = getterName("SHA1") });
@export(BunObject.SHA224, .{ .name = getterName("SHA224") });
@export(BunObject.SHA256, .{ .name = getterName("SHA256") });
@export(BunObject.SHA384, .{ .name = getterName("SHA384") });
@export(BunObject.SHA512, .{ .name = getterName("SHA512") });
@export(BunObject.SHA512_256, .{ .name = getterName("SHA512_256") });
@export(&BunObject.CryptoHasher, .{ .name = getterName("CryptoHasher") });
@export(&BunObject.FFI, .{ .name = getterName("FFI") });
@export(&BunObject.FileSystemRouter, .{ .name = getterName("FileSystemRouter") });
@export(&BunObject.MD4, .{ .name = getterName("MD4") });
@export(&BunObject.MD5, .{ .name = getterName("MD5") });
@export(&BunObject.SHA1, .{ .name = getterName("SHA1") });
@export(&BunObject.SHA224, .{ .name = getterName("SHA224") });
@export(&BunObject.SHA256, .{ .name = getterName("SHA256") });
@export(&BunObject.SHA384, .{ .name = getterName("SHA384") });
@export(&BunObject.SHA512, .{ .name = getterName("SHA512") });
@export(&BunObject.SHA512_256, .{ .name = getterName("SHA512_256") });
@export(BunObject.TOML, .{ .name = getterName("TOML") });
@export(BunObject.Glob, .{ .name = getterName("Glob") });
@export(BunObject.Transpiler, .{ .name = getterName("Transpiler") });
@export(BunObject.argv, .{ .name = getterName("argv") });
@export(BunObject.cwd, .{ .name = getterName("cwd") });
@export(BunObject.enableANSIColors, .{ .name = getterName("enableANSIColors") });
@export(BunObject.hash, .{ .name = getterName("hash") });
@export(BunObject.inspect, .{ .name = getterName("inspect") });
@export(BunObject.main, .{ .name = getterName("main") });
@export(BunObject.origin, .{ .name = getterName("origin") });
@export(BunObject.stderr, .{ .name = getterName("stderr") });
@export(BunObject.stdin, .{ .name = getterName("stdin") });
@export(BunObject.stdout, .{ .name = getterName("stdout") });
@export(BunObject.unsafe, .{ .name = getterName("unsafe") });
@export(BunObject.semver, .{ .name = getterName("semver") });
@export(BunObject.embeddedFiles, .{ .name = getterName("embeddedFiles") });
@export(BunObject.S3Client, .{ .name = getterName("S3Client") });
@export(BunObject.s3, .{ .name = getterName("s3") });
@export(&BunObject.TOML, .{ .name = getterName("TOML") });
@export(&BunObject.Glob, .{ .name = getterName("Glob") });
@export(&BunObject.Transpiler, .{ .name = getterName("Transpiler") });
@export(&BunObject.argv, .{ .name = getterName("argv") });
@export(&BunObject.cwd, .{ .name = getterName("cwd") });
@export(&BunObject.enableANSIColors, .{ .name = getterName("enableANSIColors") });
@export(&BunObject.hash, .{ .name = getterName("hash") });
@export(&BunObject.inspect, .{ .name = getterName("inspect") });
@export(&BunObject.main, .{ .name = getterName("main") });
@export(&BunObject.origin, .{ .name = getterName("origin") });
@export(&BunObject.stderr, .{ .name = getterName("stderr") });
@export(&BunObject.stdin, .{ .name = getterName("stdin") });
@export(&BunObject.stdout, .{ .name = getterName("stdout") });
@export(&BunObject.unsafe, .{ .name = getterName("unsafe") });
@export(&BunObject.semver, .{ .name = getterName("semver") });
@export(&BunObject.embeddedFiles, .{ .name = getterName("embeddedFiles") });
@export(&BunObject.S3Client, .{ .name = getterName("S3Client") });
@export(&BunObject.s3, .{ .name = getterName("s3") });
// --- Getters --
// -- Callbacks --
@export(BunObject.allocUnsafe, .{ .name = callbackName("allocUnsafe") });
@export(BunObject.build, .{ .name = callbackName("build") });
@export(BunObject.color, .{ .name = callbackName("color") });
@export(BunObject.connect, .{ .name = callbackName("connect") });
@export(BunObject.createParsedShellScript, .{ .name = callbackName("createParsedShellScript") });
@export(BunObject.createShellInterpreter, .{ .name = callbackName("createShellInterpreter") });
@export(BunObject.deflateSync, .{ .name = callbackName("deflateSync") });
@export(BunObject.file, .{ .name = callbackName("file") });
@export(BunObject.gunzipSync, .{ .name = callbackName("gunzipSync") });
@export(BunObject.gzipSync, .{ .name = callbackName("gzipSync") });
@export(BunObject.indexOfLine, .{ .name = callbackName("indexOfLine") });
@export(BunObject.inflateSync, .{ .name = callbackName("inflateSync") });
@export(BunObject.jest, .{ .name = callbackName("jest") });
@export(BunObject.listen, .{ .name = callbackName("listen") });
@export(BunObject.mmap, .{ .name = callbackName("mmap") });
@export(BunObject.nanoseconds, .{ .name = callbackName("nanoseconds") });
@export(BunObject.openInEditor, .{ .name = callbackName("openInEditor") });
@export(BunObject.registerMacro, .{ .name = callbackName("registerMacro") });
@export(BunObject.resolve, .{ .name = callbackName("resolve") });
@export(BunObject.resolveSync, .{ .name = callbackName("resolveSync") });
@export(BunObject.serve, .{ .name = callbackName("serve") });
@export(BunObject.sha, .{ .name = callbackName("sha") });
@export(BunObject.shellEscape, .{ .name = callbackName("shellEscape") });
@export(BunObject.shrink, .{ .name = callbackName("shrink") });
@export(BunObject.sleepSync, .{ .name = callbackName("sleepSync") });
@export(BunObject.spawn, .{ .name = callbackName("spawn") });
@export(BunObject.spawnSync, .{ .name = callbackName("spawnSync") });
@export(BunObject.udpSocket, .{ .name = callbackName("udpSocket") });
@export(BunObject.which, .{ .name = callbackName("which") });
@export(BunObject.write, .{ .name = callbackName("write") });
@export(&BunObject.allocUnsafe, .{ .name = callbackName("allocUnsafe") });
@export(&BunObject.build, .{ .name = callbackName("build") });
@export(&BunObject.color, .{ .name = callbackName("color") });
@export(&BunObject.connect, .{ .name = callbackName("connect") });
@export(&BunObject.createParsedShellScript, .{ .name = callbackName("createParsedShellScript") });
@export(&BunObject.createShellInterpreter, .{ .name = callbackName("createShellInterpreter") });
@export(&BunObject.deflateSync, .{ .name = callbackName("deflateSync") });
@export(&BunObject.file, .{ .name = callbackName("file") });
@export(&BunObject.gunzipSync, .{ .name = callbackName("gunzipSync") });
@export(&BunObject.gzipSync, .{ .name = callbackName("gzipSync") });
@export(&BunObject.indexOfLine, .{ .name = callbackName("indexOfLine") });
@export(&BunObject.inflateSync, .{ .name = callbackName("inflateSync") });
@export(&BunObject.jest, .{ .name = callbackName("jest") });
@export(&BunObject.listen, .{ .name = callbackName("listen") });
@export(&BunObject.mmap, .{ .name = callbackName("mmap") });
@export(&BunObject.nanoseconds, .{ .name = callbackName("nanoseconds") });
@export(&BunObject.openInEditor, .{ .name = callbackName("openInEditor") });
@export(&BunObject.registerMacro, .{ .name = callbackName("registerMacro") });
@export(&BunObject.resolve, .{ .name = callbackName("resolve") });
@export(&BunObject.resolveSync, .{ .name = callbackName("resolveSync") });
@export(&BunObject.serve, .{ .name = callbackName("serve") });
@export(&BunObject.sha, .{ .name = callbackName("sha") });
@export(&BunObject.shellEscape, .{ .name = callbackName("shellEscape") });
@export(&BunObject.shrink, .{ .name = callbackName("shrink") });
@export(&BunObject.sleepSync, .{ .name = callbackName("sleepSync") });
@export(&BunObject.spawn, .{ .name = callbackName("spawn") });
@export(&BunObject.spawnSync, .{ .name = callbackName("spawnSync") });
@export(&BunObject.udpSocket, .{ .name = callbackName("udpSocket") });
@export(&BunObject.which, .{ .name = callbackName("which") });
@export(&BunObject.write, .{ .name = callbackName("write") });
// -- Callbacks --
}
};
@@ -248,11 +244,10 @@ const IOTask = JSC.IOTask;
const zlib = @import("../../zlib.zig");
const Which = @import("../../which.zig");
const ErrorableString = JSC.ErrorableString;
const is_bindgen = JSC.is_bindgen;
const max_addressable_memory = std.math.maxInt(u56);
const glob = @import("../../glob.zig");
const Async = bun.Async;
const SemverObject = @import("../../install/semver.zig").SemverObject;
const SemverObject = bun.Semver.SemverObject;
const Braces = @import("../../shell/braces.zig");
const Shell = @import("../../shell/shell.zig");
@@ -1925,7 +1920,7 @@ pub const Crypto = struct {
hash: []const u8,
pub fn toErrorInstance(this: Value, globalObject: *JSC.JSGlobalObject) JSC.JSValue {
const error_code = std.fmt.allocPrint(bun.default_allocator, "PASSWORD_{}", .{PascalToUpperUnderscoreCaseFormatter{ .input = @errorName(this.err) }}) catch bun.outOfMemory();
const error_code = std.fmt.allocPrint(bun.default_allocator, "PASSWORD{}", .{PascalToUpperUnderscoreCaseFormatter{ .input = @errorName(this.err) }}) catch bun.outOfMemory();
defer bun.default_allocator.free(error_code);
const instance = globalObject.createErrorInstance("Password hashing failed with error \"{s}\"", .{@errorName(this.err)});
instance.put(globalObject, ZigString.static("code"), JSC.ZigString.init(error_code).toJS(globalObject));
@@ -2862,7 +2857,7 @@ pub const Crypto = struct {
return globalThis.throw("Bun.file() is not supported here yet (it needs an async version)", .{});
}
if (comptime @typeInfo(@TypeOf(Hasher.hash)).Fn.params.len == 3) {
if (comptime @typeInfo(@TypeOf(Hasher.hash)).@"fn".params.len == 3) {
Hasher.hash(input.slice(), &output_digest_buf, JSC.VirtualMachine.get().rareData().boringEngine());
} else {
Hasher.hash(input.slice(), &output_digest_buf);
@@ -2882,7 +2877,7 @@ pub const Crypto = struct {
output_digest_slice = bytes[0..Hasher.digest];
}
if (comptime @typeInfo(@TypeOf(Hasher.hash)).Fn.params.len == 3) {
if (comptime @typeInfo(@TypeOf(Hasher.hash)).@"fn".params.len == 3) {
Hasher.hash(input.slice(), output_digest_slice, JSC.VirtualMachine.get().rareData().boringEngine());
} else {
Hasher.hash(input.slice(), output_digest_slice);
@@ -3204,10 +3199,8 @@ pub export fn Bun__escapeHTML8(globalObject: *JSC.JSGlobalObject, input_value: J
}
comptime {
if (!JSC.is_bindgen) {
_ = Bun__escapeHTML8;
_ = Bun__escapeHTML16;
}
_ = Bun__escapeHTML8;
_ = Bun__escapeHTML16;
}
pub fn allocUnsafe(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
@@ -3273,7 +3266,7 @@ pub fn mmapFile(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.
if (try opts.get(globalThis, "offset")) |value| {
offset = @as(usize, @intCast(value.toInt64()));
offset = std.mem.alignBackwardAnyAlign(offset, std.mem.page_size);
offset = std.mem.alignBackwardAnyAlign(usize, offset, std.mem.page_size);
}
}
@@ -3536,7 +3529,7 @@ const UnsafeObject = struct {
callframe: *JSC.CallFrame,
) bun.JSError!JSC.JSValue {
const args = callframe.arguments_old(2).slice();
if (args.len < 1 or !args[0].isCell() or !args[0].jsType().isTypedArray()) {
if (args.len < 1 or !args[0].isCell() or !args[0].jsType().isTypedArrayOrArrayBuffer()) {
return globalThis.throwInvalidArguments("Expected an ArrayBuffer", .{});
}
@@ -4302,12 +4295,10 @@ export fn Bun__reportError(globalObject: *JSGlobalObject, err: JSC.JSValue) void
}
comptime {
if (!is_bindgen) {
_ = Bun__reportError;
_ = EnvironmentVariables.Bun__getEnvCount;
_ = EnvironmentVariables.Bun__getEnvKey;
_ = EnvironmentVariables.Bun__getEnvValue;
}
_ = Bun__reportError;
_ = EnvironmentVariables.Bun__getEnvCount;
_ = EnvironmentVariables.Bun__getEnvKey;
_ = EnvironmentVariables.Bun__getEnvValue;
}
pub const JSZlib = struct {

View File

@@ -1,6 +1,5 @@
const std = @import("std");
const Api = @import("../../api/schema.zig").Api;
const JavaScript = @import("../javascript.zig");
const QueryStringMap = @import("../../url.zig").QueryStringMap;
const CombinedScanner = @import("../../url.zig").CombinedScanner;
const bun = @import("root").bun;
@@ -11,7 +10,6 @@ const WebCore = @import("../webcore/response.zig");
const Transpiler = bun.transpiler;
const options = @import("../../options.zig");
const resolve_path = @import("../../resolver/resolve_path.zig");
const VirtualMachine = JavaScript.VirtualMachine;
const ScriptSrcStream = std.io.FixedBufferStream([]u8);
const ZigString = JSC.ZigString;
const Fs = @import("../../fs.zig");
@@ -60,6 +58,7 @@ pub const JSBundler = struct {
rootdir: OwnedString = OwnedString.initEmpty(bun.default_allocator),
serve: Serve = .{},
jsx: options.JSX.Pragma = .{},
force_node_env: options.BundleOptions.ForceNodeEnv = .unspecified,
code_splitting: bool = false,
minify: Minify = .{},
no_macros: bool = false,

View File

@@ -1,6 +1,5 @@
const std = @import("std");
const Api = @import("../../api/schema.zig").Api;
const JavaScript = @import("../javascript.zig");
const QueryStringMap = @import("../../url.zig").QueryStringMap;
const CombinedScanner = @import("../../url.zig").CombinedScanner;
const bun = @import("root").bun;
@@ -10,7 +9,6 @@ const js = JSC.C;
const WebCore = @import("../webcore/response.zig");
const Transpiler = bun.transpiler;
const options = @import("../../options.zig");
const VirtualMachine = JavaScript.VirtualMachine;
const ScriptSrcStream = std.io.FixedBufferStream([]u8);
const ZigString = JSC.ZigString;
const Fs = @import("../../fs.zig");
@@ -454,7 +452,7 @@ fn transformOptionsFromJSC(globalObject: JSC.C.JSContextRef, temp_allocator: std
allocator,
&transpiler.log,
logger.Source.initPathString("tsconfig.json", transpiler.tsconfig_buf),
&VirtualMachine.get().transpiler.resolver.caches.json,
&JSC.VirtualMachine.get().transpiler.resolver.caches.json,
) catch null) |parsed_tsconfig| {
transpiler.tsconfig = parsed_tsconfig;
}
@@ -488,7 +486,7 @@ fn transformOptionsFromJSC(globalObject: JSC.C.JSContextRef, temp_allocator: std
if (out.isEmpty()) break :macros;
transpiler.macros_buf = out.toOwnedSlice(allocator) catch bun.outOfMemory();
const source = logger.Source.initPathString("macros.json", transpiler.macros_buf);
const json = (VirtualMachine.get().transpiler.resolver.caches.json.parseJSON(
const json = (JSC.VirtualMachine.get().transpiler.resolver.caches.json.parseJSON(
&transpiler.log,
source,
allocator,
@@ -731,7 +729,7 @@ pub fn constructor(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) b
allocator,
log,
transpiler_options.transform,
JavaScript.VirtualMachine.get().transpiler.env,
JSC.VirtualMachine.get().transpiler.env,
) catch |err| {
if ((log.warnings + log.errors) > 0) {
return globalThis.throwValue(log.toJS(globalThis, allocator, "Failed to create transpiler"));
@@ -1022,7 +1020,7 @@ pub fn transformSync(
arena.allocator(),
code,
loader,
if (comptime JSC.is_bindgen) Transpiler.MacroJSValueType.zero else js_ctx_value,
js_ctx_value,
) orelse {
if ((this.transpiler.log.warnings + this.transpiler.log.errors) > 0) {
return globalThis.throwValue(this.transpiler.log.toJS(globalThis, globalThis.allocator(), "Parse error"));

View File

@@ -302,9 +302,7 @@ pub const All = struct {
}
comptime {
if (!JSC.is_bindgen) {
@export(setImmediate, .{ .name = "Bun__Timer__setImmediate" });
}
@export(&setImmediate, .{ .name = "Bun__Timer__setImmediate" });
}
pub fn setTimeout(
@@ -414,13 +412,11 @@ pub const All = struct {
});
comptime {
if (!JSC.is_bindgen) {
@export(setTimeout, .{ .name = Export[0].symbol_name });
@export(setInterval, .{ .name = Export[1].symbol_name });
@export(clearTimeout, .{ .name = Export[2].symbol_name });
@export(clearInterval, .{ .name = Export[3].symbol_name });
@export(getNextID, .{ .name = Export[4].symbol_name });
}
@export(&setTimeout, .{ .name = Export[0].symbol_name });
@export(&setInterval, .{ .name = Export[1].symbol_name });
@export(&clearTimeout, .{ .name = Export[2].symbol_name });
@export(&clearInterval, .{ .name = Export[3].symbol_name });
@export(&getNextID, .{ .name = Export[4].symbol_name });
}
};
@@ -448,9 +444,9 @@ pub const TimerObject = struct {
},
pub usingnamespace JSC.Codegen.JSTimeout;
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
extern "C" fn Bun__JSTimeout__call(encodedTimeoutValue: JSValue, globalObject: *JSC.JSGlobalObject) void;
extern "c" fn Bun__JSTimeout__call(encodedTimeoutValue: JSValue, globalObject: *JSC.JSGlobalObject) void;
pub fn runImmediateTask(this: *TimerObject, vm: *VirtualMachine) void {
if (this.has_cleared_timer) {
@@ -962,6 +958,10 @@ pub const WTFTimer = struct {
return this;
}
pub export fn WTFTimer__runIfImminent(vm: *VirtualMachine) void {
vm.eventLoop().runImminentGCTimer();
}
pub fn run(this: *WTFTimer, vm: *VirtualMachine) void {
if (this.event_loop_timer.state == .ACTIVE) {
vm.timer.remove(&this.event_loop_timer);

View File

@@ -41,10 +41,7 @@ const LibInfo = struct {
if (loaded)
return handle;
loaded = true;
const RTLD_LAZY = 1;
const RTLD_LOCAL = 4;
handle = bun.C.dlopen("libinfo.dylib", RTLD_LAZY | RTLD_LOCAL);
handle = bun.C.dlopen("libinfo.dylib", .{ .LAZY = true, .LOCAL = true });
if (handle == null)
Output.debug("libinfo.dylib not found", .{});
return handle;
@@ -1395,7 +1392,7 @@ pub const InternalDNS = struct {
// https://github.com/nodejs/node/issues/33816
// https://github.com/aio-libs/aiohttp/issues/5357
// https://github.com/libuv/libuv/issues/2225
.flags = if (Environment.isPosix) bun.C.translated.AI_ADDRCONFIG else 0,
.flags = if (Environment.isPosix) .{ .ADDRCONFIG = true } else .{},
.next = null,
.protocol = 0,
.socktype = std.c.SOCK.STREAM,
@@ -1527,7 +1524,7 @@ pub const InternalDNS = struct {
if (Environment.isWindows) {
const wsa = std.os.windows.ws2_32;
const wsa_hints = wsa.addrinfo{
.flags = 0,
.flags = .{},
.family = wsa.AF.UNSPEC,
.socktype = wsa.SOCK.STREAM,
.protocol = 0,
@@ -1756,16 +1753,16 @@ pub const InternalDNS = struct {
pub const InternalDNSRequest = InternalDNS.Request;
comptime {
@export(InternalDNS.us_getaddrinfo_set, .{
@export(&InternalDNS.us_getaddrinfo_set, .{
.name = "Bun__addrinfo_set",
});
@export(InternalDNS.us_getaddrinfo, .{
@export(&InternalDNS.us_getaddrinfo, .{
.name = "Bun__addrinfo_get",
});
@export(InternalDNS.freeaddrinfo, .{
@export(&InternalDNS.freeaddrinfo, .{
.name = "Bun__addrinfo_freeRequest",
});
@export(InternalDNS.getRequestResult, .{
@export(&InternalDNS.getRequestResult, .{
.name = "Bun__addrinfo_getRequestResult",
});
}
@@ -1802,7 +1799,7 @@ pub const DNSResolver = struct {
pending_nameinfo_cache_cares: NameInfoPendingCache = NameInfoPendingCache.init(),
pub usingnamespace JSC.Codegen.JSDNSResolver;
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
const PollsMap = std.AutoArrayHashMap(c_ares.ares_socket_t, *PollType);
@@ -1912,7 +1909,7 @@ pub const DNSResolver = struct {
}
fn anyRequestsPending(this: *DNSResolver) bool {
inline for (@typeInfo(DNSResolver).Struct.fields) |field| {
inline for (@typeInfo(DNSResolver).@"struct".fields) |field| {
if (comptime std.mem.startsWith(u8, field.name, "pending_")) {
const set = &@field(this, field.name).available;
if (set.count() < set.capacity()) {
@@ -2522,7 +2519,7 @@ pub const DNSResolver = struct {
return globalThis.throwInvalidArgumentType("resolve", "name", "non-empty string");
}
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
switch (record_type) {
RecordType.A => {
@@ -2585,7 +2582,7 @@ pub const DNSResolver = struct {
return globalThis.throwInvalidArgumentType("reverse", "ip", "non-empty string");
}
const ip_slice = ip_str.toSliceClone(globalThis, bun.default_allocator);
const ip_slice = try ip_str.toSliceClone(globalThis, bun.default_allocator);
const ip = ip_slice.slice();
const channel: *c_ares.Channel = switch (this.getChannel()) {
.result => |res| res,
@@ -2721,7 +2718,7 @@ pub const DNSResolver = struct {
return globalThis.throwInvalidArgumentType("resolveSrv", "hostname", "non-empty string");
}
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
return this.doResolveCAres(c_ares.struct_ares_srv_reply, "srv", name.slice(), globalThis);
}
@@ -2747,7 +2744,7 @@ pub const DNSResolver = struct {
return .zero;
};
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
return this.doResolveCAres(c_ares.struct_ares_soa_reply, "soa", name.slice(), globalThis);
}
@@ -2777,7 +2774,7 @@ pub const DNSResolver = struct {
return globalThis.throwInvalidArgumentType("resolveCaa", "hostname", "non-empty string");
}
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
return this.doResolveCAres(c_ares.struct_ares_caa_reply, "caa", name.slice(), globalThis);
}
@@ -2803,7 +2800,7 @@ pub const DNSResolver = struct {
return .zero;
};
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
return this.doResolveCAres(c_ares.struct_hostent, "ns", name.slice(), globalThis);
}
@@ -2833,7 +2830,7 @@ pub const DNSResolver = struct {
return globalThis.throwInvalidArgumentType("resolvePtr", "hostname", "non-empty string");
}
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
return this.doResolveCAres(c_ares.struct_hostent, "ptr", name.slice(), globalThis);
}
@@ -2863,7 +2860,7 @@ pub const DNSResolver = struct {
return globalThis.throwInvalidArgumentType("resolveCname", "hostname", "non-empty string");
}
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
return this.doResolveCAres(c_ares.struct_hostent, "cname", name.slice(), globalThis);
}
@@ -2893,7 +2890,7 @@ pub const DNSResolver = struct {
return globalThis.throwInvalidArgumentType("resolveMx", "hostname", "non-empty string");
}
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
return this.doResolveCAres(c_ares.struct_ares_mx_reply, "mx", name.slice(), globalThis);
}
@@ -2923,7 +2920,7 @@ pub const DNSResolver = struct {
return globalThis.throwInvalidArgumentType("resolveNaptr", "hostname", "non-empty string");
}
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
return this.doResolveCAres(c_ares.struct_ares_naptr_reply, "naptr", name.slice(), globalThis);
}
@@ -2953,7 +2950,7 @@ pub const DNSResolver = struct {
return globalThis.throwInvalidArgumentType("resolveTxt", "hostname", "non-empty string");
}
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
return this.doResolveCAres(c_ares.struct_ares_txt_reply, "txt", name.slice(), globalThis);
}
@@ -2983,7 +2980,7 @@ pub const DNSResolver = struct {
return globalThis.throwInvalidArgumentType("resolveAny", "hostname", "non-empty string");
}
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
const name = try name_str.toSliceClone(globalThis, bun.default_allocator);
return this.doResolveCAres(c_ares.struct_any_reply, "any", name.slice(), globalThis);
}
@@ -3396,40 +3393,40 @@ pub const DNSResolver = struct {
comptime {
const js_resolve = JSC.toJSHostFunction(globalResolve);
@export(js_resolve, .{ .name = "Bun__DNS__resolve" });
@export(&js_resolve, .{ .name = "Bun__DNS__resolve" });
const js_lookup = JSC.toJSHostFunction(globalLookup);
@export(js_lookup, .{ .name = "Bun__DNS__lookup" });
@export(&js_lookup, .{ .name = "Bun__DNS__lookup" });
const js_resolveTxt = JSC.toJSHostFunction(globalResolveTxt);
@export(js_resolveTxt, .{ .name = "Bun__DNS__resolveTxt" });
@export(&js_resolveTxt, .{ .name = "Bun__DNS__resolveTxt" });
const js_resolveSoa = JSC.toJSHostFunction(globalResolveSoa);
@export(js_resolveSoa, .{ .name = "Bun__DNS__resolveSoa" });
@export(&js_resolveSoa, .{ .name = "Bun__DNS__resolveSoa" });
const js_resolveMx = JSC.toJSHostFunction(globalResolveMx);
@export(js_resolveMx, .{ .name = "Bun__DNS__resolveMx" });
@export(&js_resolveMx, .{ .name = "Bun__DNS__resolveMx" });
const js_resolveNaptr = JSC.toJSHostFunction(globalResolveNaptr);
@export(js_resolveNaptr, .{ .name = "Bun__DNS__resolveNaptr" });
@export(&js_resolveNaptr, .{ .name = "Bun__DNS__resolveNaptr" });
const js_resolveSrv = JSC.toJSHostFunction(globalResolveSrv);
@export(js_resolveSrv, .{ .name = "Bun__DNS__resolveSrv" });
@export(&js_resolveSrv, .{ .name = "Bun__DNS__resolveSrv" });
const js_resolveCaa = JSC.toJSHostFunction(globalResolveCaa);
@export(js_resolveCaa, .{ .name = "Bun__DNS__resolveCaa" });
@export(&js_resolveCaa, .{ .name = "Bun__DNS__resolveCaa" });
const js_resolveNs = JSC.toJSHostFunction(globalResolveNs);
@export(js_resolveNs, .{ .name = "Bun__DNS__resolveNs" });
@export(&js_resolveNs, .{ .name = "Bun__DNS__resolveNs" });
const js_resolvePtr = JSC.toJSHostFunction(globalResolvePtr);
@export(js_resolvePtr, .{ .name = "Bun__DNS__resolvePtr" });
@export(&js_resolvePtr, .{ .name = "Bun__DNS__resolvePtr" });
const js_resolveCname = JSC.toJSHostFunction(globalResolveCname);
@export(js_resolveCname, .{ .name = "Bun__DNS__resolveCname" });
@export(&js_resolveCname, .{ .name = "Bun__DNS__resolveCname" });
const js_resolveAny = JSC.toJSHostFunction(globalResolveAny);
@export(js_resolveAny, .{ .name = "Bun__DNS__resolveAny" });
@export(&js_resolveAny, .{ .name = "Bun__DNS__resolveAny" });
const js_getGlobalServers = JSC.toJSHostFunction(getGlobalServers);
@export(js_getGlobalServers, .{ .name = "Bun__DNS__getServers" });
@export(&js_getGlobalServers, .{ .name = "Bun__DNS__getServers" });
const js_setGlobalServers = JSC.toJSHostFunction(setGlobalServers);
@export(js_setGlobalServers, .{ .name = "Bun__DNS__setServers" });
@export(&js_setGlobalServers, .{ .name = "Bun__DNS__setServers" });
const js_reverse = JSC.toJSHostFunction(globalReverse);
@export(js_reverse, .{ .name = "Bun__DNS__reverse" });
@export(&js_reverse, .{ .name = "Bun__DNS__reverse" });
const js_lookupService = JSC.toJSHostFunction(globalLookupService);
@export(js_lookupService, .{ .name = "Bun__DNS__lookupService" });
@export(&js_lookupService, .{ .name = "Bun__DNS__lookupService" });
const js_prefetchFromJS = JSC.toJSHostFunction(InternalDNS.prefetchFromJS);
@export(js_prefetchFromJS, .{ .name = "Bun__DNS__prefetch" });
@export(&js_prefetchFromJS, .{ .name = "Bun__DNS__prefetch" });
const js_getDNSCacheStats = JSC.toJSHostFunction(InternalDNS.getDNSCacheStats);
@export(js_getDNSCacheStats, .{ .name = "Bun__DNS__getCacheStats" });
@export(&js_getDNSCacheStats, .{ .name = "Bun__DNS__getCacheStats" });
}
};

View File

@@ -530,7 +530,7 @@ const Handlers = struct {
globalObject: *JSC.JSGlobalObject,
strong_ctx: JSC.Strong = .{},
pub fn callEventHandler(this: *Handlers, comptime event: @Type(.EnumLiteral), thisValue: JSValue, data: []const JSValue) bool {
pub fn callEventHandler(this: *Handlers, comptime event: @Type(.enum_literal), thisValue: JSValue, data: []const JSValue) bool {
const callback = @field(this, @tagName(event));
if (callback == .zero) {
return false;
@@ -546,7 +546,7 @@ const Handlers = struct {
return true;
}
pub fn callEventHandlerWithResult(this: *Handlers, comptime event: @Type(.EnumLiteral), thisValue: JSValue, data: []const JSValue) JSValue {
pub fn callEventHandlerWithResult(this: *Handlers, comptime event: @Type(.enum_literal), thisValue: JSValue, data: []const JSValue) JSValue {
const callback = @field(this, @tagName(event));
if (callback == .zero) {
return JSC.JSValue.zero;
@@ -643,8 +643,7 @@ const Handlers = struct {
pub const H2FrameParser = struct {
pub const log = Output.scoped(.H2FrameParser, false);
pub usingnamespace JSC.Codegen.JSH2FrameParser;
pub usingnamespace bun.NewRefCounted(@This(), @This().deinit);
pub const DEBUG_REFCOUNT_NAME = "H2";
pub usingnamespace bun.NewRefCounted(@This(), deinit, "H2");
const ENABLE_AUTO_CORK = true; // ENABLE CORK OPTIMIZATION
const ENABLE_ALLOCATOR_POOL = true; // ENABLE HIVE ALLOCATOR OPTIMIZATION
@@ -1356,7 +1355,7 @@ pub const H2FrameParser = struct {
_ = this.write(&buffer);
}
pub fn dispatch(this: *H2FrameParser, comptime event: @Type(.EnumLiteral), value: JSC.JSValue) void {
pub fn dispatch(this: *H2FrameParser, comptime event: @Type(.enum_literal), value: JSC.JSValue) void {
JSC.markBinding(@src());
const ctx_value = this.strong_ctx.get() orelse return;
@@ -1364,7 +1363,7 @@ pub const H2FrameParser = struct {
_ = this.handlers.callEventHandler(event, ctx_value, &[_]JSC.JSValue{ ctx_value, value });
}
pub fn call(this: *H2FrameParser, comptime event: @Type(.EnumLiteral), value: JSC.JSValue) JSValue {
pub fn call(this: *H2FrameParser, comptime event: @Type(.enum_literal), value: JSC.JSValue) JSValue {
JSC.markBinding(@src());
const ctx_value = this.strong_ctx.get() orelse return .zero;
@@ -1376,7 +1375,7 @@ pub const H2FrameParser = struct {
_ = this.handlers.callWriteCallback(callback, &[_]JSC.JSValue{});
}
pub fn dispatchWithExtra(this: *H2FrameParser, comptime event: @Type(.EnumLiteral), value: JSC.JSValue, extra: JSC.JSValue) void {
pub fn dispatchWithExtra(this: *H2FrameParser, comptime event: @Type(.enum_literal), value: JSC.JSValue, extra: JSC.JSValue) void {
JSC.markBinding(@src());
const ctx_value = this.strong_ctx.get() orelse return;
@@ -1385,7 +1384,7 @@ pub const H2FrameParser = struct {
_ = this.handlers.callEventHandler(event, ctx_value, &[_]JSC.JSValue{ ctx_value, value, extra });
}
pub fn dispatchWith2Extra(this: *H2FrameParser, comptime event: @Type(.EnumLiteral), value: JSC.JSValue, extra: JSC.JSValue, extra2: JSC.JSValue) void {
pub fn dispatchWith2Extra(this: *H2FrameParser, comptime event: @Type(.enum_literal), value: JSC.JSValue, extra: JSC.JSValue, extra2: JSC.JSValue) void {
JSC.markBinding(@src());
const ctx_value = this.strong_ctx.get() orelse return;
@@ -1394,7 +1393,7 @@ pub const H2FrameParser = struct {
extra2.ensureStillAlive();
_ = this.handlers.callEventHandler(event, ctx_value, &[_]JSC.JSValue{ ctx_value, value, extra, extra2 });
}
pub fn dispatchWith3Extra(this: *H2FrameParser, comptime event: @Type(.EnumLiteral), value: JSC.JSValue, extra: JSC.JSValue, extra2: JSC.JSValue, extra3: JSC.JSValue) void {
pub fn dispatchWith3Extra(this: *H2FrameParser, comptime event: @Type(.enum_literal), value: JSC.JSValue, extra: JSC.JSValue, extra2: JSC.JSValue, extra3: JSC.JSValue) void {
JSC.markBinding(@src());
const ctx_value = this.strong_ctx.get() orelse return;

View File

@@ -11,12 +11,12 @@ const Maybe = JSC.Maybe;
const win_rusage = struct {
utime: struct {
tv_sec: i64 = 0,
tv_usec: i64 = 0,
sec: i64 = 0,
usec: i64 = 0,
},
stime: struct {
tv_sec: i64 = 0,
tv_usec: i64 = 0,
sec: i64 = 0,
usec: i64 = 0,
},
maxrss: u64 = 0,
ixrss: u0 = 0,
@@ -54,16 +54,16 @@ pub fn uv_getrusage(process: *uv.uv_process_t) win_rusage {
var kerneltime: WinTime = undefined;
var usertime: WinTime = undefined;
// We at least get process times
if (std.os.windows.kernel32.GetProcessTimes(process_pid, &starttime, &exittime, &kerneltime, &usertime) == 1) {
if (bun.windows.GetProcessTimes(process_pid, &starttime, &exittime, &kerneltime, &usertime) == 1) {
var temp: u64 = (@as(u64, kerneltime.dwHighDateTime) << 32) | kerneltime.dwLowDateTime;
if (temp > 0) {
usage_info.stime.tv_sec = @intCast(temp / 10000000);
usage_info.stime.tv_usec = @intCast(temp % 1000000);
usage_info.stime.sec = @intCast(temp / 10000000);
usage_info.stime.usec = @intCast(temp % 1000000);
}
temp = (@as(u64, usertime.dwHighDateTime) << 32) | usertime.dwLowDateTime;
if (temp > 0) {
usage_info.utime.tv_sec = @intCast(temp / 10000000);
usage_info.utime.tv_usec = @intCast(temp % 1000000);
usage_info.utime.sec = @intCast(temp / 10000000);
usage_info.utime.usec = @intCast(temp % 1000000);
}
}
var counters: IO_COUNTERS = .{};
@@ -110,23 +110,23 @@ pub const ProcessExitHandler = struct {
}
switch (this.ptr.tag()) {
.Subprocess => {
@field(TaggedPointer.Tag, @typeName(Subprocess)) => {
const subprocess = this.ptr.as(Subprocess);
subprocess.onProcessExit(process, status, rusage);
},
.LifecycleScriptSubprocess => {
@field(TaggedPointer.Tag, @typeName(LifecycleScriptSubprocess)) => {
const subprocess = this.ptr.as(LifecycleScriptSubprocess);
subprocess.onProcessExit(process, status, rusage);
},
.ProcessHandle => {
@field(TaggedPointer.Tag, @typeName(ProcessHandle)) => {
const subprocess = this.ptr.as(ProcessHandle);
subprocess.onProcessExit(process, status, rusage);
},
@field(TaggedPointer.Tag, bun.meta.typeBaseName(@typeName(ShellSubprocess))) => {
@field(TaggedPointer.Tag, @typeName(ShellSubprocess)) => {
const subprocess = this.ptr.as(ShellSubprocess);
subprocess.onProcessExit(process, status, rusage);
},
@field(TaggedPointer.Tag, bun.meta.typeBaseName(@typeName(SyncProcess))) => {
@field(TaggedPointer.Tag, @typeName(SyncProcess)) => {
const subprocess = this.ptr.as(SyncProcess);
if (comptime Environment.isPosix) {
@panic("This code should not reached");
@@ -157,7 +157,7 @@ pub const Process = struct {
return @sizeOf(@This());
}
pub usingnamespace bun.NewRefCounted(Process, deinit);
pub usingnamespace bun.NewRefCounted(Process, deinit, null);
pub fn setExitHandler(this: *Process, handler: anytype) void {
this.exit_handler.init(handler);
@@ -924,7 +924,7 @@ const WaiterThreadPosix = struct {
.mask = current_mask,
.flags = std.posix.SA.NOCLDSTOP,
};
std.posix.sigaction(std.posix.SIG.CHLD, &act, null) catch {};
std.posix.sigaction(std.posix.SIG.CHLD, &act, null);
}
}
@@ -2018,7 +2018,9 @@ pub const sync = struct {
pub fn spawn(
options: *const Options,
) !Maybe(Result) {
const envp = options.envp orelse std.c.environ;
// [*:null]?[*:0]const u8
// [*:null]?[*:0]u8
const envp = options.envp orelse @as([*:null]?[*:0]const u8, @ptrCast(std.c.environ));
const argv = options.argv;
var string_builder = bun.StringBuilder{};
defer string_builder.deinit(bun.default_allocator);
@@ -2040,16 +2042,16 @@ pub const sync = struct {
}
// Forward signals from parent to the child process.
extern "C" fn Bun__registerSignalsForForwarding() void;
extern "C" fn Bun__unregisterSignalsForForwarding() void;
extern "c" fn Bun__registerSignalsForForwarding() void;
extern "c" fn Bun__unregisterSignalsForForwarding() void;
// The PID to forward signals to.
// Set to 0 when unregistering.
extern "C" var Bun__currentSyncPID: i64;
extern "c" var Bun__currentSyncPID: i64;
// Race condition: a signal could be sent before spawnProcessPosix returns.
// We need to make sure to send it after the process is spawned.
extern "C" fn Bun__sendPendingSignalIfNecessary() void;
extern "c" fn Bun__sendPendingSignalIfNecessary() void;
fn spawnPosix(
options: *const Options,

View File

@@ -1342,9 +1342,7 @@ fn NewSocket(comptime ssl: bool) type {
// This is wasteful because it means we are keeping a JSC::Weak for every single open socket
has_pending_activity: std.atomic.Value(bool) = std.atomic.Value(bool).init(true),
native_callback: NativeCallbacks = .none,
pub usingnamespace bun.NewRefCounted(@This(), @This().deinit);
pub const DEBUG_REFCOUNT_NAME = "Socket";
pub usingnamespace bun.NewRefCounted(@This(), deinit, "Socket");
// We use this direct callbacks on HTTP2 when available
pub const NativeCallbacks = union(enum) {
@@ -1395,8 +1393,6 @@ fn NewSocket(comptime ssl: bool) type {
JSC.Codegen.JSTLSSocket;
pub fn hasPendingActivity(this: *This) callconv(.C) bool {
@fence(.acquire);
return this.has_pending_activity.load(.acquire);
}
@@ -4378,6 +4374,9 @@ pub fn jsCreateSocketPair(global: *JSC.JSGlobalObject, _: *JSC.CallFrame) bun.JS
return global.throwValue(err.toJSC(global));
}
_ = bun.sys.setNonblocking(bun.toFD(fds_[0]));
_ = bun.sys.setNonblocking(bun.toFD(fds_[1]));
const array = JSC.JSValue.createEmptyArray(global, 2);
array.putIndex(global, 0, JSC.jsNumber(fds_[0]));
array.putIndex(global, 1, JSC.jsNumber(fds_[1]));

View File

@@ -48,8 +48,8 @@ pub const ResourceUsage = struct {
var cpu = JSC.JSValue.createEmptyObjectWithNullPrototype(globalObject);
const rusage = this.rusage;
const usrTime = JSValue.fromTimevalNoTruncate(globalObject, rusage.utime.tv_usec, rusage.utime.tv_sec);
const sysTime = JSValue.fromTimevalNoTruncate(globalObject, rusage.stime.tv_usec, rusage.stime.tv_sec);
const usrTime = JSValue.fromTimevalNoTruncate(globalObject, rusage.utime.usec, rusage.utime.sec);
const sysTime = JSValue.fromTimevalNoTruncate(globalObject, rusage.stime.usec, rusage.stime.sec);
cpu.put(globalObject, JSC.ZigString.static("user"), usrTime);
cpu.put(globalObject, JSC.ZigString.static("system"), sysTime);
@@ -199,7 +199,7 @@ pub const Subprocess = struct {
ref_count: u32 = 1,
abort_signal: ?*JSC.AbortSignal = null,
usingnamespace bun.NewRefCounted(@This(), Subprocess.deinit);
usingnamespace bun.NewRefCounted(@This(), deinit, null);
pub const Flags = packed struct {
is_sync: bool = false,
@@ -279,7 +279,6 @@ pub const Subprocess = struct {
}
pub fn updateHasPendingActivity(this: *Subprocess) void {
@fence(.seq_cst);
if (comptime Environment.isDebug) {
log("updateHasPendingActivity() {any} -> {any}", .{
this.has_pending_activity.raw,
@@ -342,7 +341,6 @@ pub const Subprocess = struct {
}
pub fn hasPendingActivity(this: *Subprocess) callconv(.C) bool {
@fence(.acquire);
return this.has_pending_activity.load(.acquire);
}
@@ -684,7 +682,7 @@ pub const Subprocess = struct {
return this.process.kill(@intCast(sig));
}
fn hasCalledGetter(this: *Subprocess, comptime getter: @Type(.EnumLiteral)) bool {
fn hasCalledGetter(this: *Subprocess, comptime getter: @Type(.enum_literal)) bool {
return this.observable_getters.contains(getter);
}
@@ -853,7 +851,7 @@ pub const Subprocess = struct {
ref_count: u32 = 1,
buffer: []const u8 = "",
pub usingnamespace bun.NewRefCounted(@This(), @This().deinit);
pub usingnamespace bun.NewRefCounted(@This(), _deinit, null);
const This = @This();
const print = bun.Output.scoped(.StaticPipeWriter, false);
@@ -940,7 +938,7 @@ pub const Subprocess = struct {
this.process.onCloseIO(.stdin);
}
pub fn deinit(this: *This) void {
fn _deinit(this: *This) void {
this.writer.end();
this.source.detach();
this.destroy();
@@ -981,7 +979,7 @@ pub const Subprocess = struct {
pub const IOReader = bun.io.BufferedReader;
pub const Poll = IOReader;
pub usingnamespace bun.NewRefCounted(PipeReader, PipeReader.deinit);
pub usingnamespace bun.NewRefCounted(PipeReader, _deinit, null);
pub fn memoryCost(this: *const PipeReader) usize {
return this.reader.memoryCost();
@@ -1148,7 +1146,7 @@ pub const Subprocess = struct {
return this.event_loop.virtual_machine.uwsLoop();
}
fn deinit(this: *PipeReader) void {
fn _deinit(this: *PipeReader) void {
if (comptime Environment.isPosix) {
bun.assert(this.reader.isDone());
}
@@ -1570,7 +1568,7 @@ pub const Subprocess = struct {
}
}
fn closeIO(this: *Subprocess, comptime io: @Type(.EnumLiteral)) void {
fn closeIO(this: *Subprocess, comptime io: @Type(.enum_literal)) void {
if (this.closed.contains(io)) return;
this.closed.insert(io);
@@ -2441,12 +2439,12 @@ pub const Subprocess = struct {
}
fn throwCommandNotFound(globalThis: *JSC.JSGlobalObject, command: []const u8) bun.JSError {
const message = bun.String.createFormat("Executable not found in $PATH: \"{s}\"", .{command}) catch bun.outOfMemory();
defer message.deref();
const err = message.toZigString().toErrorInstance(globalThis);
err.putZigString(globalThis, JSC.ZigString.static("code"), JSC.ZigString.init("ENOENT").toJS(globalThis));
err.putZigString(globalThis, JSC.ZigString.static("path"), JSC.ZigString.init(command).toJS(globalThis));
return globalThis.throwValue(err);
const err = JSC.SystemError{
.message = bun.String.createFormat("Executable not found in $PATH: \"{s}\"", .{command}) catch bun.outOfMemory(),
.code = bun.String.static("ENOENT"),
.path = bun.String.createUTF8(command),
};
return globalThis.throwValue(err.toErrorInstance(globalThis));
}
const node_cluster_binding = @import("./../../node/node_cluster_binding.zig");

View File

@@ -282,7 +282,7 @@ pub const UDPSocket = struct {
globalThis: *JSGlobalObject,
thisValue: JSValue = .zero,
ref: JSC.Ref = JSC.Ref.init(),
jsc_ref: JSC.Ref = JSC.Ref.init(),
poll_ref: Async.KeepAlive = Async.KeepAlive.init(),
// if marked as closed the socket pointer may be stale
closed: bool = false,

View File

@@ -81,8 +81,8 @@ const Offsets = extern struct {
JSArrayBufferView__offsetOfVector: u32,
JSCell__offsetOfType: u32,
extern "C" var Bun__FFI__offsets: Offsets;
extern "C" fn Bun__FFI__ensureOffsetsAreLoaded() void;
extern "c" var Bun__FFI__offsets: Offsets;
extern "c" fn Bun__FFI__ensureOffsetsAreLoaded() void;
fn loadOnce() void {
Bun__FFI__ensureOffsetsAreLoaded();
}
@@ -165,27 +165,27 @@ pub const FFI = struct {
};
const stdarg = struct {
extern "C" fn ffi_vfprintf(*anyopaque, [*:0]const u8, ...) callconv(.C) c_int;
extern "C" fn ffi_vprintf([*:0]const u8, ...) callconv(.C) c_int;
extern "C" fn ffi_fprintf(*anyopaque, [*:0]const u8, ...) callconv(.C) c_int;
extern "C" fn ffi_printf([*:0]const u8, ...) callconv(.C) c_int;
extern "C" fn ffi_fscanf(*anyopaque, [*:0]const u8, ...) callconv(.C) c_int;
extern "C" fn ffi_scanf([*:0]const u8, ...) callconv(.C) c_int;
extern "C" fn ffi_sscanf([*:0]const u8, [*:0]const u8, ...) callconv(.C) c_int;
extern "C" fn ffi_vsscanf([*:0]const u8, [*:0]const u8, ...) callconv(.C) c_int;
extern "C" fn ffi_fopen([*:0]const u8, [*:0]const u8) callconv(.C) *anyopaque;
extern "C" fn ffi_fclose(*anyopaque) callconv(.C) c_int;
extern "C" fn ffi_fgetc(*anyopaque) callconv(.C) c_int;
extern "C" fn ffi_fputc(c: c_int, *anyopaque) callconv(.C) c_int;
extern "C" fn ffi_feof(*anyopaque) callconv(.C) c_int;
extern "C" fn ffi_fileno(*anyopaque) callconv(.C) c_int;
extern "C" fn ffi_ungetc(c: c_int, *anyopaque) callconv(.C) c_int;
extern "C" fn ffi_ftell(*anyopaque) callconv(.C) c_long;
extern "C" fn ffi_fseek(*anyopaque, c_long, c_int) callconv(.C) c_int;
extern "C" fn ffi_fflush(*anyopaque) callconv(.C) c_int;
extern "c" fn ffi_vfprintf(*anyopaque, [*:0]const u8, ...) callconv(.C) c_int;
extern "c" fn ffi_vprintf([*:0]const u8, ...) callconv(.C) c_int;
extern "c" fn ffi_fprintf(*anyopaque, [*:0]const u8, ...) callconv(.C) c_int;
extern "c" fn ffi_printf([*:0]const u8, ...) callconv(.C) c_int;
extern "c" fn ffi_fscanf(*anyopaque, [*:0]const u8, ...) callconv(.C) c_int;
extern "c" fn ffi_scanf([*:0]const u8, ...) callconv(.C) c_int;
extern "c" fn ffi_sscanf([*:0]const u8, [*:0]const u8, ...) callconv(.C) c_int;
extern "c" fn ffi_vsscanf([*:0]const u8, [*:0]const u8, ...) callconv(.C) c_int;
extern "c" fn ffi_fopen([*:0]const u8, [*:0]const u8) callconv(.C) *anyopaque;
extern "c" fn ffi_fclose(*anyopaque) callconv(.C) c_int;
extern "c" fn ffi_fgetc(*anyopaque) callconv(.C) c_int;
extern "c" fn ffi_fputc(c: c_int, *anyopaque) callconv(.C) c_int;
extern "c" fn ffi_feof(*anyopaque) callconv(.C) c_int;
extern "c" fn ffi_fileno(*anyopaque) callconv(.C) c_int;
extern "c" fn ffi_ungetc(c: c_int, *anyopaque) callconv(.C) c_int;
extern "c" fn ffi_ftell(*anyopaque) callconv(.C) c_long;
extern "c" fn ffi_fseek(*anyopaque, c_long, c_int) callconv(.C) c_int;
extern "c" fn ffi_fflush(*anyopaque) callconv(.C) c_int;
extern "C" fn calloc(nmemb: usize, size: usize) callconv(.C) ?*anyopaque;
extern "C" fn perror([*:0]const u8) callconv(.C) void;
extern "c" fn calloc(nmemb: usize, size: usize) callconv(.C) ?*anyopaque;
extern "c" fn perror([*:0]const u8) callconv(.C) void;
const mac = if (Environment.isMac) struct {
var ffi_stdinp: *anyopaque = @extern(*anyopaque, .{ .name = "__stdinp" });
@@ -275,7 +275,9 @@ pub const FFI = struct {
"macosx",
"-show-sdk-path",
},
.envp = std.c.environ,
// ?[*:null]?[*:0]const u8
// [*:null]?[*:0]u8
.envp = @ptrCast(std.c.environ),
}) catch return;
if (process == .result) {
defer process.result.deinit();
@@ -1469,7 +1471,7 @@ pub const FFI = struct {
return val.return_type == ABIType.napi_value;
}
extern "C" fn FFICallbackFunctionWrapper_destroy(*anyopaque) void;
extern "c" fn FFICallbackFunctionWrapper_destroy(*anyopaque) void;
pub fn deinit(val: *Function, globalThis: *JSC.JSGlobalObject, allocator: std.mem.Allocator) void {
JSC.markBinding(@src());
@@ -2438,13 +2440,13 @@ const CompilerRT = struct {
bun_call: *const @TypeOf(JSC.C.JSObjectCallAsFunction),
};
const headers = @import("../bindings/headers.zig");
var workaround: MyFunctionSStructWorkAround = if (!JSC.is_bindgen) .{
var workaround: MyFunctionSStructWorkAround = .{
.JSVALUE_TO_INT64 = headers.JSC__JSValue__toInt64,
.JSVALUE_TO_UINT64 = headers.JSC__JSValue__toUInt64NoTruncate,
.INT64_TO_JSVALUE = headers.JSC__JSValue__fromInt64NoTruncate,
.UINT64_TO_JSVALUE = headers.JSC__JSValue__fromUInt64NoTruncate,
.bun_call = &JSC.C.JSObjectCallAsFunction,
} else undefined;
};
noinline fn memset(
dest: [*]u8,
@@ -2520,12 +2522,10 @@ const CompilerRT = struct {
"JSVALUE_TO_UINT64_SLOW",
workaround.JSVALUE_TO_UINT64,
);
if (!comptime JSC.is_bindgen) {
std.mem.doNotOptimizeAway(headers.JSC__JSValue__toUInt64NoTruncate);
std.mem.doNotOptimizeAway(headers.JSC__JSValue__toInt64);
std.mem.doNotOptimizeAway(headers.JSC__JSValue__fromInt64NoTruncate);
std.mem.doNotOptimizeAway(headers.JSC__JSValue__fromUInt64NoTruncate);
}
std.mem.doNotOptimizeAway(headers.JSC__JSValue__toUInt64NoTruncate);
std.mem.doNotOptimizeAway(headers.JSC__JSValue__toInt64);
std.mem.doNotOptimizeAway(headers.JSC__JSValue__fromInt64NoTruncate);
std.mem.doNotOptimizeAway(headers.JSC__JSValue__fromUInt64NoTruncate);
_ = TCC.tcc_add_symbol(
state,
"INT64_TO_JSVALUE_SLOW",

View File

@@ -1,6 +1,5 @@
const std = @import("std");
const Api = @import("../../api/schema.zig").Api;
const JavaScript = @import("../javascript.zig");
const QueryStringMap = @import("../../url.zig").QueryStringMap;
const CombinedScanner = @import("../../url.zig").CombinedScanner;
const bun = @import("root").bun;
@@ -9,7 +8,6 @@ const JSC = bun.JSC;
const js = JSC.C;
const WebCore = JSC.WebCore;
const Transpiler = bun.transpiler;
const VirtualMachine = JavaScript.VirtualMachine;
const ScriptSrcStream = std.io.FixedBufferStream([]u8);
const ZigString = JSC.ZigString;
const Fs = @import("../../fs.zig");
@@ -605,7 +603,7 @@ pub const MatchedRoute = struct {
var writer = stream.writer();
JSC.API.Bun.getPublicPathWithAssetPrefix(
this.route.file_path,
if (this.base_dir) |base_dir| base_dir.slice() else VirtualMachine.get().transpiler.fs.top_level_dir,
if (this.base_dir) |base_dir| base_dir.slice() else JSC.VirtualMachine.get().transpiler.fs.top_level_dir,
if (this.origin) |origin| URL.parse(origin.slice()) else URL{},
if (this.asset_prefix) |prefix| prefix.slice() else "",
@TypeOf(&writer),

View File

@@ -324,17 +324,14 @@ pub fn finalize(
}
pub fn hasPendingActivity(this: *Glob) callconv(.C) bool {
@fence(.seq_cst);
return this.has_pending_activity.load(.seq_cst) > 0;
}
fn incrPendingActivityFlag(has_pending_activity: *std.atomic.Value(usize)) void {
@fence(.seq_cst);
_ = has_pending_activity.fetchAdd(1, .seq_cst);
}
fn decrPendingActivityFlag(has_pending_activity: *std.atomic.Value(usize)) void {
@fence(.seq_cst);
_ = has_pending_activity.fetchSub(1, .seq_cst);
}

Some files were not shown because too many files have changed in this diff Show More