Compare commits

...

58 Commits

Author SHA1 Message Date
Don Isaac
ba62af9e98 feat(node:net): node:net compatability 2025-02-05 20:10:43 -05: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
697 changed files with 28200 additions and 10777 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

View File

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

2
LATEST
View File

@@ -1 +1 @@
1.2.0
1.2.2

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)) {
@@ -154,8 +154,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 +207,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;
};
@@ -331,11 +329,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 +375,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),
});
@@ -429,7 +441,6 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile {
.strip = false, // stripped at the end
});
obj.bundle_compiler_rt = false;
obj.formatted_panics = true;
obj.root_module.omit_frame_pointer = false;
// Link libc
@@ -614,7 +625,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

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

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 e32c6356625cfacebff0c61d182f759abf6f508a)
endif()
string(SUBSTRING ${WEBKIT_VERSION} 0 16 WEBKIT_VERSION_PREFIX)

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 "568a19ea4b811a5580bbf869cdaf6071244b9bb2")
optionx(ZIG_TARGET STRING "The zig target to use" DEFAULT ${DEFAULT_ZIG_TARGET})
if(CMAKE_BUILD_TYPE STREQUAL "Release")

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

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

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

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

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

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

View File

@@ -18,7 +18,7 @@ pub const LOLHTMLContext = struct {
document_handlers: std.ArrayListUnmanaged(*DocumentHandler) = .{},
ref_count: u32 = 1,
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
fn deinit(this: *LOLHTMLContext) void {
for (this.selectors.items) |selector| {
@@ -189,7 +189,7 @@ pub const HTMLRewriter = struct {
const kind: ResponseKind = brk: {
if (response_value.isString())
break :brk .string
else if (response_value.jsType().isTypedArray())
else if (response_value.jsType().isTypedArrayOrArrayBuffer())
break :brk .array_buffer
else
break :brk .other;
@@ -395,7 +395,7 @@ pub const HTMLRewriter = struct {
bodyValueBufferer: ?JSC.WebCore.BodyValueBufferer = null,
tmp_sync_error: ?*JSC.JSValue = null,
ref_count: u32 = 1,
pub usingnamespace bun.NewRefCounted(BufferOutputSink, deinit);
pub usingnamespace bun.NewRefCounted(BufferOutputSink, deinit, null);
// const log = bun.Output.scoped(.BufferOutputSink, false);
pub fn init(context: *LOLHTMLContext, global: *JSGlobalObject, original: *Response, builder: *LOLHTML.HTMLRewriter.Builder) JSC.JSValue {
@@ -1066,7 +1066,7 @@ pub const TextChunk = struct {
ref_count: u32 = 1,
pub usingnamespace JSC.Codegen.JSTextChunk;
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
pub fn init(text_chunk: *LOLHTML.TextChunk) *TextChunk {
return TextChunk.new(.{ .text_chunk = text_chunk, .ref_count = 2 });
}
@@ -1175,7 +1175,7 @@ pub const DocType = struct {
return DocType.new(.{ .doctype = doctype, .ref_count = 2 });
}
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
pub usingnamespace JSC.Codegen.JSDocType;
/// The doctype name.
@@ -1242,7 +1242,7 @@ pub const DocEnd = struct {
doc_end: ?*LOLHTML.DocEnd,
ref_count: u32 = 1,
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
pub usingnamespace JSC.Codegen.JSDocEnd;
pub fn init(doc_end: *LOLHTML.DocEnd) *DocEnd {
@@ -1291,7 +1291,7 @@ pub const Comment = struct {
comment: ?*LOLHTML.Comment = null,
ref_count: u32 = 1,
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
pub usingnamespace JSC.Codegen.JSComment;
pub fn init(comment: *LOLHTML.Comment) *Comment {
@@ -1436,7 +1436,7 @@ pub const EndTag = struct {
};
pub usingnamespace JSC.Codegen.JSEndTag;
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
fn contentHandler(this: *EndTag, comptime Callback: (fn (*LOLHTML.EndTag, []const u8, bool) LOLHTML.Error!void), thisObject: JSValue, globalObject: *JSGlobalObject, content: ZigString, contentOptions: ?ContentOptions) JSValue {
if (this.end_tag == null)
@@ -1554,7 +1554,7 @@ pub const AttributeIterator = struct {
}
pub usingnamespace JSC.Codegen.JSAttributeIterator;
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
pub fn next(this: *AttributeIterator, globalObject: *JSGlobalObject, _: *JSC.CallFrame) bun.JSError!JSValue {
const done_label = JSC.ZigString.static("done");
@@ -1591,7 +1591,7 @@ pub const Element = struct {
ref_count: u32 = 1,
pub usingnamespace JSC.Codegen.JSElement;
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
pub fn init(element: *LOLHTML.Element) *Element {
return Element.new(.{ .element = element, .ref_count = 2 });

View File

@@ -69,7 +69,6 @@ const Config = @import("../config.zig");
const URL = @import("../../url.zig").URL;
const VirtualMachine = JSC.VirtualMachine;
const IOTask = JSC.IOTask;
const is_bindgen = JSC.is_bindgen;
const uws = bun.uws;
const Fallback = Runtime.Fallback;
const MimeType = HTTP.MimeType;
@@ -1111,7 +1110,7 @@ pub const ServerConfig = struct {
var port = args.address.tcp.port;
if (arguments.vm.transpiler.options.transform_options.origin) |origin| {
args.base_uri = origin;
args.base_uri = try bun.default_allocator.dupeZ(u8, origin);
}
defer {
@@ -1151,16 +1150,15 @@ pub const ServerConfig = struct {
while (try iter.next()) |key| {
const path, const is_ascii = key.toOwnedSliceReturningAllASCII(bun.default_allocator) catch bun.outOfMemory();
errdefer bun.default_allocator.free(path);
const value = iter.value;
if (path.len == 0 or path[0] != '/') {
bun.default_allocator.free(path);
if (path.len == 0 or (path[0] != '/' and path[0] != '*')) {
return global.throwInvalidArguments("Invalid static route \"{s}\". path must start with '/'", .{path});
}
if (!is_ascii) {
bun.default_allocator.free(path);
return global.throwInvalidArguments("Invalid static route \"{s}\". Please encode all non-ASCII characters in the path.", .{path});
}
@@ -1220,6 +1218,9 @@ pub const ServerConfig = struct {
if (sliced.len > 0) {
defer sliced.deinit();
if (args.base_uri.len > 0) {
bun.default_allocator.free(@constCast(args.base_uri));
}
args.base_uri = bun.default_allocator.dupe(u8, sliced.slice()) catch unreachable;
}
}
@@ -1414,6 +1415,8 @@ pub const ServerConfig = struct {
const protocol: string = if (args.ssl_config != null) "https" else "http";
const hostname = args.base_url.hostname;
const needsBrackets: bool = strings.isIPV6Address(hostname) and hostname[0] != '[';
const original_base_uri = args.base_uri;
defer bun.default_allocator.free(@constCast(original_base_uri));
if (needsBrackets) {
args.base_uri = (if ((port == 80 and args.ssl_config == null) or (port == 443 and args.ssl_config != null))
std.fmt.allocPrint(bun.default_allocator, "{s}://[{s}]/{s}", .{
@@ -1608,7 +1611,7 @@ pub const AnyRequestContext = struct {
tagged_pointer: Pointer,
pub const Null = .{ .tagged_pointer = Pointer.Null };
pub const Null: @This() = .{ .tagged_pointer = Pointer.Null };
pub fn init(request_ctx: anytype) AnyRequestContext {
return .{ .tagged_pointer = Pointer.init(request_ctx) };
@@ -2752,7 +2755,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
}
}
pub fn onReadFile(this: *RequestContext, result: Blob.ReadFile.ResultType) void {
pub fn onReadFile(this: *RequestContext, result: Blob.ReadFileResultType) void {
defer this.deref();
if (this.isAbortedOrEnded()) {
@@ -4127,7 +4130,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
var body = this.request_body.?;
var old = body.value;
old.Locked.onReceiveValue = null;
var new_body = .{ .Null = {} };
var new_body: WebCore.Body.Value = .{ .Null = {} };
old.resolve(&new_body, server.globalThis, null);
body.value = new_body;
}
@@ -4183,13 +4186,13 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
comptime {
const jsonResolve = JSC.toJSHostFunction(onResolve);
@export(jsonResolve, .{ .name = Export[0].symbol_name });
@export(&jsonResolve, .{ .name = Export[0].symbol_name });
const jsonReject = JSC.toJSHostFunction(onReject);
@export(jsonReject, .{ .name = Export[1].symbol_name });
@export(&jsonReject, .{ .name = Export[1].symbol_name });
const jsonResolveStream = JSC.toJSHostFunction(onResolveStream);
@export(jsonResolveStream, .{ .name = Export[2].symbol_name });
@export(&jsonResolveStream, .{ .name = Export[2].symbol_name });
const jsonRejectStream = JSC.toJSHostFunction(onRejectStream);
@export(jsonRejectStream, .{ .name = Export[3].symbol_name });
@export(&jsonRejectStream, .{ .name = Export[3].symbol_name });
}
};
}
@@ -5792,7 +5795,7 @@ const ServePlugins = struct {
value: Value,
ref_count: u32 = 1,
pub usingnamespace bun.NewRefCounted(ServePlugins, deinit);
pub usingnamespace bun.NewRefCounted(ServePlugins, deinit, null);
pub const Value = union(enum) {
pending: struct {
@@ -5950,8 +5953,8 @@ const ServePlugins = struct {
}
comptime {
@export(onResolve, .{ .name = "BunServe__onResolvePlugins" });
@export(onReject, .{ .name = "BunServe__onRejectPlugins" });
@export(&onResolve, .{ .name = "BunServe__onResolvePlugins" });
@export(&onReject, .{ .name = "BunServe__onRejectPlugins" });
}
};
@@ -7450,8 +7453,30 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
if (this.dev_server) |dev| {
dev.attachRoutes(this) catch bun.outOfMemory();
} else {
bun.assert(this.config.onRequest != .zero);
app.any("/*", *ThisServer, this, onRequest);
const @"has /*" = brk: {
for (this.config.static_routes.items) |route| {
if (strings.eqlComptime(route.path, "/*")) {
break :brk true;
}
}
break :brk false;
};
// "/*" routes are added backwards, so if they have a static route, it will never be matched
// so we need to check for that first
if (!@"has /*") {
bun.assert(this.config.onRequest != .zero);
app.any("/*", *ThisServer, this, onRequest);
} else if (this.config.onRequest != .zero) {
app.post("/*", *ThisServer, this, onRequest);
app.put("/*", *ThisServer, this, onRequest);
app.patch("/*", *ThisServer, this, onRequest);
app.delete("/*", *ThisServer, this, onRequest);
app.options("/*", *ThisServer, this, onRequest);
app.trace("/*", *ThisServer, this, onRequest);
app.connect("/*", *ThisServer, this, onRequest);
}
}
}
@@ -7785,9 +7810,7 @@ pub fn Server__setIdleTimeout_(server: JSC.JSValue, seconds: JSC.JSValue, global
}
comptime {
if (!JSC.is_bindgen) {
_ = Server__setIdleTimeout;
}
_ = Server__setIdleTimeout;
}
fn throwSSLErrorIfNecessary(globalThis: *JSC.JSGlobalObject) bool {

View File

@@ -68,6 +68,7 @@ pub const HTMLBundleRoute = struct {
}
pub fn init(html_bundle: *HTMLBundle) *HTMLBundleRoute {
html_bundle.ref();
return HTMLBundleRoute.new(.{
.html_bundle = html_bundle,
.pending_responses = .{},
@@ -77,7 +78,7 @@ pub const HTMLBundleRoute = struct {
});
}
pub usingnamespace bun.NewRefCounted(@This(), @This().deinit);
pub usingnamespace bun.NewRefCounted(@This(), _deinit, null);
pub const Value = union(enum) {
pending_plugins,
@@ -114,7 +115,7 @@ pub const HTMLBundleRoute = struct {
}
};
pub fn deinit(this: *HTMLBundleRoute) void {
fn _deinit(this: *HTMLBundleRoute) void {
for (this.pending_responses.items) |pending_response| {
pending_response.deref();
}
@@ -287,6 +288,10 @@ pub const HTMLBundleRoute = struct {
if (!server.config().development) {
config.define.put("process.env.NODE_ENV", "\"production\"") catch bun.outOfMemory();
config.jsx.development = false;
} else {
config.force_node_env = .development;
config.jsx.development = true;
}
config.source_map = .linked;
@@ -512,9 +517,9 @@ pub const HTMLBundleRoute = struct {
server: ?AnyServer = null,
route: *HTMLBundleRoute,
pub usingnamespace bun.NewRefCounted(@This(), @This().deinit);
pub usingnamespace bun.NewRefCounted(@This(), __deinit, null);
pub fn deinit(this: *PendingResponse) void {
fn __deinit(this: *PendingResponse) void {
if (this.is_response_pending) {
this.resp.clearAborted();
this.resp.clearOnWritable();
@@ -544,7 +549,7 @@ pub const HTMLBundleRoute = struct {
};
pub usingnamespace JSC.Codegen.JSHTMLBundle;
pub usingnamespace bun.NewRefCounted(HTMLBundle, deinit);
pub usingnamespace bun.NewRefCounted(HTMLBundle, deinit, null);
const bun = @import("root").bun;
const std = @import("std");
const JSC = bun.JSC;

View File

@@ -10,7 +10,7 @@ headers: Headers = .{
},
ref_count: u32 = 1,
pub usingnamespace bun.NewRefCounted(@This(), deinit);
pub usingnamespace bun.NewRefCounted(@This(), deinit, null);
fn deinit(this: *StaticRoute) void {
this.blob.detach();

View File

@@ -9,18 +9,11 @@ const strings = bun.strings;
const MutableString = bun.MutableString;
const stringZ = bun.stringZ;
const default_allocator = bun.default_allocator;
const C = bun.C;
const JavaScript = @import("./javascript.zig");
const JSC = bun.JSC;
const WebCore = @import("./webcore.zig");
const Test = @import("./test/jest.zig");
const Fetch = WebCore.Fetch;
const Response = WebCore.Response;
const Request = WebCore.Request;
const Router = @import("./api/filesystem_router.zig");
const IdentityContext = @import("../identity_context.zig").IdentityContext;
const uws = bun.uws;
const Body = WebCore.Body;
const TaggedPointerTypes = @import("../tagged_pointer.zig");
const TaggedPointerUnion = TaggedPointerTypes.TaggedPointerUnion;
@@ -41,11 +34,11 @@ pub const Lifetime = enum {
pub fn toJS(globalObject: *JSC.JSGlobalObject, comptime ValueType: type, value: ValueType, comptime lifetime: Lifetime) JSC.JSValue {
const Type = comptime brk: {
var CurrentType = ValueType;
if (@typeInfo(ValueType) == .Optional) {
CurrentType = @typeInfo(ValueType).Optional.child;
if (@typeInfo(ValueType) == .optional) {
CurrentType = @typeInfo(ValueType).optional.child;
}
break :brk if (@typeInfo(CurrentType) == .Pointer and @typeInfo(CurrentType).Pointer.size == .One)
@typeInfo(CurrentType).Pointer.child
break :brk if (@typeInfo(CurrentType) == .pointer and @typeInfo(CurrentType).pointer.size == .one)
@typeInfo(CurrentType).pointer.child
else
CurrentType;
};
@@ -72,6 +65,18 @@ pub fn toJS(globalObject: *JSC.JSGlobalObject, comptime ValueType: type, value:
},
JSC.JSValue => return if (Type != ValueType) value.* else value,
inline []const u16, []const u32, []const i16, []const i8, []const i32, []const f32 => {
var array = JSC.JSValue.createEmptyArray(globalObject, value.len);
for (value, 0..) |item, i| {
array.putIndex(
globalObject,
@truncate(i),
JSC.jsNumber(item),
);
}
return array;
},
else => {
// Recursion can stack overflow here
@@ -80,7 +85,7 @@ pub fn toJS(globalObject: *JSC.JSGlobalObject, comptime ValueType: type, value:
var array = JSC.JSValue.createEmptyArray(globalObject, value.len);
for (value, 0..) |*item, i| {
const res = toJS(globalObject, *const Child, item, lifetime);
const res = toJS(globalObject, *Child, item, lifetime);
if (res == .zero) return .zero;
array.putIndex(
globalObject,
@@ -91,16 +96,16 @@ pub fn toJS(globalObject: *JSC.JSGlobalObject, comptime ValueType: type, value:
return array;
}
if (comptime @hasDecl(Type, "toJSNewlyCreated") and @typeInfo(@TypeOf(@field(Type, "toJSNewlyCreated"))).Fn.params.len == 2) {
if (comptime @hasDecl(Type, "toJSNewlyCreated") and @typeInfo(@TypeOf(@field(Type, "toJSNewlyCreated"))).@"fn".params.len == 2) {
return value.toJSNewlyCreated(globalObject);
}
if (comptime @hasDecl(Type, "toJS") and @typeInfo(@TypeOf(@field(Type, "toJS"))).Fn.params.len == 2) {
if (comptime @hasDecl(Type, "toJS") and @typeInfo(@TypeOf(@field(Type, "toJS"))).@"fn".params.len == 2) {
return value.toJS(globalObject);
}
// must come after toJS check in case this enum implements its own serializer.
if (@typeInfo(Type) == .Enum) {
if (@typeInfo(Type) == .@"enum") {
// FIXME: creates non-normalized integers (e.g. u2), which
// aren't handled by `jsNumberWithType` rn
return JSC.JSValue.jsNumberWithType(u32, @as(u32, @intFromEnum(value)));
@@ -156,9 +161,6 @@ pub const Properties = struct {
}
};
const JSValue = JSC.JSValue;
const ZigString = JSC.ZigString;
pub const PathString = bun.PathString;
pub fn createError(
@@ -193,7 +195,7 @@ fn toTypeErrorWithCode(
args: anytype,
ctx: js.JSContextRef,
) JSC.JSValue {
@setCold(true);
@branchHint(.cold);
var zig_str: JSC.ZigString = undefined;
if (comptime std.meta.fields(@TypeOf(args)).len == 0) {
zig_str = JSC.ZigString.init(fmt);
@@ -204,7 +206,7 @@ fn toTypeErrorWithCode(
zig_str.detectEncoding();
zig_str.mark();
}
const code_str = ZigString.init(code);
const code_str = JSC.ZigString.init(code);
return JSC.JSValue.createTypeError(&zig_str, &code_str, ctx);
}
@@ -223,7 +225,7 @@ pub fn throwInvalidArguments(
ctx: js.JSContextRef,
exception: ExceptionValueRef,
) void {
@setCold(true);
@branchHint(.cold);
exception.* = JSC.Error.ERR_INVALID_ARG_TYPE.fmt(ctx, fmt, args).asObjectRef();
}
@@ -232,7 +234,7 @@ pub fn toInvalidArguments(
args: anytype,
ctx: js.JSContextRef,
) JSC.JSValue {
@setCold(true);
@branchHint(.cold);
return JSC.Error.ERR_INVALID_ARG_TYPE.fmt(ctx, fmt, args);
}
@@ -241,7 +243,7 @@ pub fn getAllocator(_: js.JSContextRef) std.mem.Allocator {
}
/// Print a JSValue to stdout; this is only meant for debugging purposes
pub fn dump(value: JSValue, globalObject: *JSC.JSGlobalObject) !void {
pub fn dump(value: JSC.WebCore.JSValue, globalObject: *JSC.JSGlobalObject) !void {
var formatter = JSC.ConsoleObject.Formatter{ .globalThis = globalObject };
try Output.errorWriter().print("{}\n", .{value.toFmt(globalObject, &formatter)});
Output.flush();
@@ -377,7 +379,7 @@ pub const ArrayBuffer = extern struct {
return Stream{ .pos = 0, .buf = this.slice() };
}
pub fn create(globalThis: *JSC.JSGlobalObject, bytes: []const u8, comptime kind: JSValue.JSType) JSValue {
pub fn create(globalThis: *JSC.JSGlobalObject, bytes: []const u8, comptime kind: JSC.JSValue.JSType) JSC.JSValue {
JSC.markBinding(@src());
return switch (comptime kind) {
.Uint8Array => Bun__createUint8ArrayForCopy(globalThis, bytes.ptr, bytes.len, false),
@@ -386,7 +388,7 @@ pub const ArrayBuffer = extern struct {
};
}
pub fn createEmpty(globalThis: *JSC.JSGlobalObject, comptime kind: JSC.JSValue.JSType) JSValue {
pub fn createEmpty(globalThis: *JSC.JSGlobalObject, comptime kind: JSC.JSValue.JSType) JSC.JSValue {
JSC.markBinding(@src());
return switch (comptime kind) {
@@ -396,18 +398,18 @@ pub const ArrayBuffer = extern struct {
};
}
pub fn createBuffer(globalThis: *JSC.JSGlobalObject, bytes: []const u8) JSValue {
pub fn createBuffer(globalThis: *JSC.JSGlobalObject, bytes: []const u8) JSC.JSValue {
JSC.markBinding(@src());
return Bun__createUint8ArrayForCopy(globalThis, bytes.ptr, bytes.len, true);
}
pub fn createUint8Array(globalThis: *JSC.JSGlobalObject, bytes: []const u8) JSValue {
pub fn createUint8Array(globalThis: *JSC.JSGlobalObject, bytes: []const u8) JSC.JSValue {
JSC.markBinding(@src());
return Bun__createUint8ArrayForCopy(globalThis, bytes.ptr, bytes.len, false);
}
extern "C" fn Bun__allocUint8ArrayForCopy(*JSC.JSGlobalObject, usize, **anyopaque) JSValue;
pub fn allocBuffer(globalThis: *JSC.JSGlobalObject, len: usize) struct { JSValue, []u8 } {
extern "c" fn Bun__allocUint8ArrayForCopy(*JSC.JSGlobalObject, usize, **anyopaque) JSC.JSValue;
pub fn allocBuffer(globalThis: *JSC.JSGlobalObject, len: usize) struct { JSC.JSValue, []u8 } {
var ptr: [*]u8 = undefined;
const buffer = Bun__allocUint8ArrayForCopy(globalThis, len, @ptrCast(&ptr));
if (buffer.isEmpty()) {
@@ -416,8 +418,8 @@ pub const ArrayBuffer = extern struct {
return .{ buffer, ptr[0..len] };
}
extern "C" fn Bun__createUint8ArrayForCopy(*JSC.JSGlobalObject, ptr: ?*const anyopaque, len: usize, buffer: bool) JSValue;
extern "C" fn Bun__createArrayBufferForCopy(*JSC.JSGlobalObject, ptr: ?*const anyopaque, len: usize) JSValue;
extern "c" fn Bun__createUint8ArrayForCopy(*JSC.JSGlobalObject, ptr: ?*const anyopaque, len: usize, buffer: bool) JSC.JSValue;
extern "c" fn Bun__createArrayBufferForCopy(*JSC.JSGlobalObject, ptr: ?*const anyopaque, len: usize) JSC.JSValue;
pub fn fromTypedArray(ctx: JSC.C.JSContextRef, value: JSC.JSValue) ArrayBuffer {
var out = std.mem.zeroes(ArrayBuffer);
@@ -427,7 +429,7 @@ pub const ArrayBuffer = extern struct {
return out;
}
extern "C" fn JSArrayBuffer__fromDefaultAllocator(*JSC.JSGlobalObject, ptr: [*]u8, len: usize) JSC.JSValue;
extern "c" fn JSArrayBuffer__fromDefaultAllocator(*JSC.JSGlobalObject, ptr: [*]u8, len: usize) JSC.JSValue;
pub fn toJSFromDefaultAllocator(globalThis: *JSC.JSGlobalObject, bytes: []u8) JSC.JSValue {
return JSArrayBuffer__fromDefaultAllocator(globalThis, bytes.ptr, bytes.len);
}
@@ -652,7 +654,7 @@ pub const MarkedArrayBuffer = struct {
}
pub fn toNodeBuffer(this: *const MarkedArrayBuffer, ctx: js.JSContextRef) JSC.JSValue {
return JSValue.createBufferWithCtx(ctx, this.buffer.byteSlice(), this.buffer.ptr, MarkedArrayBuffer_deallocator);
return JSC.JSValue.createBufferWithCtx(ctx, this.buffer.byteSlice(), this.buffer.ptr, MarkedArrayBuffer_deallocator);
}
pub fn toJSObjectRef(this: *const MarkedArrayBuffer, ctx: js.JSContextRef, exception: js.ExceptionRef) js.JSObjectRef {
@@ -711,7 +713,7 @@ pub const RefString = struct {
pub const Hash = u32;
pub const Map = std.HashMap(Hash, *JSC.RefString, IdentityContext(Hash), 80);
pub fn toJS(this: *RefString, global: *JSC.JSGlobalObject) JSValue {
pub fn toJS(this: *RefString, global: *JSC.JSGlobalObject) JSC.JSValue {
return bun.String.init(this.impl).toJS(global);
}
@@ -783,9 +785,9 @@ const Expect = Test.Expect;
const DescribeScope = Test.DescribeScope;
const TestScope = Test.TestScope;
const NodeFS = JSC.Node.NodeFS;
const TextEncoder = WebCore.TextEncoder;
const TextDecoder = WebCore.TextDecoder;
const TextEncoderStreamEncoder = WebCore.TextEncoderStreamEncoder;
const TextEncoder = JSC.WebCore.TextEncoder;
const TextDecoder = JSC.WebCore.TextDecoder;
const TextEncoderStreamEncoder = JSC.WebCore.TextEncoderStreamEncoder;
const HTMLRewriter = JSC.Cloudflare.HTMLRewriter;
const Element = JSC.Cloudflare.Element;
const Comment = JSC.Cloudflare.Comment;
@@ -902,7 +904,7 @@ pub const DOMEffect = struct {
};
fn DOMCallArgumentType(comptime Type: type) []const u8 {
const ChildType = if (@typeInfo(Type) == .Pointer) std.meta.Child(Type) else Type;
const ChildType = if (@typeInfo(Type) == .pointer) std.meta.Child(Type) else Type;
return switch (ChildType) {
i8, u8, i16, u16, i32 => "JSC::SpecInt32Only",
u32, i64, u64 => "JSC::SpecInt52Any",
@@ -915,7 +917,7 @@ fn DOMCallArgumentType(comptime Type: type) []const u8 {
}
fn DOMCallArgumentTypeWrapper(comptime Type: type) []const u8 {
const ChildType = if (@typeInfo(Type) == .Pointer) std.meta.Child(Type) else Type;
const ChildType = if (@typeInfo(Type) == .pointer) std.meta.Child(Type) else Type;
return switch (ChildType) {
i32 => "int32_t",
f64 => "double",
@@ -929,7 +931,7 @@ fn DOMCallArgumentTypeWrapper(comptime Type: type) []const u8 {
}
fn DOMCallResultType(comptime Type: type) []const u8 {
const ChildType = if (@typeInfo(Type) == .Pointer) std.meta.Child(Type) else Type;
const ChildType = if (@typeInfo(Type) == .pointer) std.meta.Child(Type) else Type;
return switch (ChildType) {
i32 => "JSC::SpecInt32Only",
bool => "JSC::SpecBoolean",
@@ -963,7 +965,7 @@ pub fn DOMCall(
thisValue: JSC.JSValue,
arguments_ptr: [*]const JSC.JSValue,
arguments_len: usize,
) callconv(JSC.conv) JSValue {
) callconv(JSC.conv) JSC.JSValue {
return JSC.toJSHostValue(globalObject, @field(Container, functionName)(globalObject, thisValue, arguments_ptr[0..arguments_len]));
}
@@ -971,7 +973,7 @@ pub fn DOMCall(
pub const Fastpath = @TypeOf(fastpath);
pub const Arguments = std.meta.ArgsTuple(Fastpath);
pub fn put(globalObject: *JSC.JSGlobalObject, value: JSValue) void {
pub fn put(globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void {
shim.cppFn("put", .{ globalObject, value });
}
@@ -980,10 +982,8 @@ pub fn DOMCall(
pub const Extern = [_][]const u8{"put"};
comptime {
if (!JSC.is_bindgen) {
@export(slowpath, .{ .name = shim.symbolName("slowpath") });
@export(fastpath, .{ .name = shim.symbolName("fastpath") });
}
@export(&slowpath, .{ .name = shim.symbolName("slowpath") });
@export(&fastpath, .{ .name = shim.symbolName("fastpath") });
}
};
}
@@ -999,7 +999,7 @@ pub fn wrapInstanceMethod(
) InstanceMethodType(Container) {
return struct {
const FunctionType = @TypeOf(@field(Container, name));
const FunctionTypeInfo: std.builtin.Type.Fn = @typeInfo(FunctionType).Fn;
const FunctionTypeInfo: std.builtin.Type.Fn = @typeInfo(FunctionType).@"fn";
const Args = std.meta.ArgsTuple(FunctionType);
const eater = if (auto_protect) JSC.Node.ArgumentsSlice.protectEatNext else JSC.Node.ArgumentsSlice.nextEat;
@@ -1081,7 +1081,7 @@ pub fn wrapInstanceMethod(
args[i] = null;
}
},
ZigString => {
JSC.ZigString => {
var string_value = eater(&iter) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Missing argument", .{});
@@ -1103,32 +1103,32 @@ pub fn wrapInstanceMethod(
args[i] = null;
}
},
*Response => {
*JSC.WebCore.Response => {
args[i] = (eater(&iter) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Missing Response object", .{});
}).as(Response) orelse {
}).as(JSC.WebCore.Response) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Expected Response object", .{});
};
},
*Request => {
*JSC.WebCore.Request => {
args[i] = (eater(&iter) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Missing Request object", .{});
}).as(Request) orelse {
}).as(JSC.WebCore.Request) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Expected Request object", .{});
};
},
JSValue => {
JSC.JSValue => {
const val = eater(&iter) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Missing argument", .{});
};
args[i] = val;
},
?JSValue => {
?JSC.JSValue => {
args[i] = eater(&iter);
},
JSC.C.ExceptionRef => {
@@ -1160,7 +1160,7 @@ pub fn wrapStaticMethod(
) JSC.JSHostZigFunction {
return struct {
const FunctionType = @TypeOf(@field(Container, name));
const FunctionTypeInfo: std.builtin.Type.Fn = @typeInfo(FunctionType).Fn;
const FunctionTypeInfo: std.builtin.Type.Fn = @typeInfo(FunctionType).@"fn";
const Args = std.meta.ArgsTuple(FunctionType);
const eater = if (auto_protect) JSC.Node.ArgumentsSlice.protectEatNext else JSC.Node.ArgumentsSlice.nextEat;
@@ -1234,7 +1234,7 @@ pub fn wrapStaticMethod(
args[i] = null;
}
},
ZigString => {
JSC.ZigString => {
var string_value = eater(&iter) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Missing argument", .{});
@@ -1256,32 +1256,32 @@ pub fn wrapStaticMethod(
args[i] = null;
}
},
*Response => {
*JSC.WebCore.Response => {
args[i] = (eater(&iter) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Missing Response object", .{});
}).as(Response) orelse {
}).as(JSC.WebCore.Response) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Expected Response object", .{});
};
},
*Request => {
*JSC.WebCore.Request => {
args[i] = (eater(&iter) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Missing Request object", .{});
}).as(Request) orelse {
}).as(JSC.WebCore.Request) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Expected Request object", .{});
};
},
JSValue => {
JSC.WebCore.JSValue => {
const val = eater(&iter) orelse {
iter.deinit();
return globalThis.throwInvalidArguments("Missing argument", .{});
};
args[i] = val;
},
?JSValue => {
?JSC.WebCore.JSValue => {
args[i] = eater(&iter);
},
else => @compileError(std.fmt.comptimePrint("Unexpected Type " ++ @typeName(ArgType) ++ " at argument {d} in {s}#{s}", .{ i, @typeName(Container), name })),
@@ -1392,7 +1392,7 @@ pub const BinaryType = enum(u4) {
return Map.get(input);
}
pub fn fromJSValue(globalThis: *JSC.JSGlobalObject, input: JSValue) bun.JSError!?BinaryType {
pub fn fromJSValue(globalThis: *JSC.JSGlobalObject, input: JSC.JSValue) bun.JSError!?BinaryType {
if (input.isString()) {
return Map.getWithEql(try input.toBunString2(globalThis), bun.String.eqlComptime);
}
@@ -1401,7 +1401,7 @@ pub const BinaryType = enum(u4) {
}
/// This clones bytes
pub fn toJS(this: BinaryType, bytes: []const u8, globalThis: *JSC.JSGlobalObject) JSValue {
pub fn toJS(this: BinaryType, bytes: []const u8, globalThis: *JSC.JSGlobalObject) JSC.JSValue {
switch (this) {
.Buffer => return JSC.ArrayBuffer.createBuffer(globalThis, bytes),
.ArrayBuffer => return JSC.ArrayBuffer.create(globalThis, bytes, .ArrayBuffer),

View File

@@ -44,7 +44,7 @@ JSValue AsyncContextFrame::withAsyncContextIfNeeded(JSGlobalObject* globalObject
}
// Construct a low-overhead wrapper
auto& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
return AsyncContextFrame::create(
vm,
jsCast<Zig::GlobalObject*>(globalObject)->AsyncContextFrameStructure(),

View File

@@ -550,7 +550,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionCreateConnection, (JSGlobalObject * globalObj
if (!targetContext || !onMessageFn)
return JSValue::encode(jsUndefined());
auto& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
auto connection = BunInspectorConnection::create(
*targetContext,
targetContext->jsGlobalObject(), shouldRef);

View File

@@ -1,20 +1,33 @@
#include "root.h"
#include "BunClientData.h"
#include <JavaScriptCore/VM.h>
#include <JavaScriptCore/Heap.h>
extern "C" int Bun__JSC_onBeforeWait(JSC::VM* vm)
// It would be nicer to construct a DropAllLocks in us_loop_run_bun_tick (the only function that
// uses onBeforeWait and onAfterWait), but that code is in C. We use an optional as that lets us
// check whether it's initialized.
static thread_local std::optional<JSC::JSLock::DropAllLocks> drop_all_locks { std::nullopt };
extern "C" void WTFTimer__runIfImminent(void* bun_vm);
// Safe if VM is nullptr
extern "C" void Bun__JSC_onBeforeWait(JSC::VM* vm)
{
(void)vm;
// if (vm->heap.hasAccess()) {
// vm->heap.releaseAccess();
// return 1;
// }
return 0;
ASSERT(!drop_all_locks.has_value());
if (vm) {
bool previouslyHadAccess = vm->heap.hasHeapAccess();
drop_all_locks.emplace(*vm);
if (previouslyHadAccess) {
vm->heap.releaseAccess();
}
}
}
extern "C" void Bun__JSC_onAfterWait(JSC::VM* vm)
{
(void)vm;
// vm->heap.acquireAccess();
if (vm) {
vm->heap.acquireAccess();
drop_all_locks.reset();
}
}

View File

@@ -1,3 +1,4 @@
#include "root.h"
#include "JavaScriptCore/HeapProfiler.h"
@@ -37,6 +38,7 @@
#include "ErrorCode.h"
#include "GeneratedBunObject.h"
#include "JavaScriptCore/BunV8HeapSnapshotBuilder.h"
#include "BunObjectModule.h"
#ifdef WIN32
#include <ws2def.h>
@@ -67,11 +69,12 @@ BUN_DECLARE_HOST_FUNCTION(Bun__DNSResolver__cancel);
BUN_DECLARE_HOST_FUNCTION(Bun__fetch);
BUN_DECLARE_HOST_FUNCTION(Bun__fetchPreconnect);
BUN_DECLARE_HOST_FUNCTION(Bun__randomUUIDv7);
namespace Bun {
using namespace JSC;
using namespace WebCore;
namespace Bun {
extern "C" bool has_bun_garbage_collector_flag_enabled;
static JSValue BunObject_getter_wrap_ArrayBufferSink(VM& vm, JSObject* bunObject)
@@ -86,7 +89,7 @@ static JSValue constructEnvObject(VM& vm, JSObject* object)
static inline JSC::EncodedJSValue flattenArrayOfBuffersIntoArrayBufferOrUint8Array(JSGlobalObject* lexicalGlobalObject, JSValue arrayValue, size_t maxLength, bool asUint8Array)
{
auto& vm = lexicalGlobalObject->vm();
auto& vm = JSC::getVM(lexicalGlobalObject);
if (arrayValue.isUndefinedOrNull() || !arrayValue) {
return JSC::JSValue::encode(JSC::JSArrayBuffer::create(vm, lexicalGlobalObject->arrayBufferStructure(), JSC::ArrayBuffer::create(static_cast<size_t>(0), 1)));
@@ -228,7 +231,7 @@ static inline JSC::EncodedJSValue flattenArrayOfBuffersIntoArrayBufferOrUint8Arr
JSC_DEFINE_HOST_FUNCTION(functionConcatTypedArrays, (JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
auto& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
if (UNLIKELY(callFrame->argumentCount() < 1)) {
@@ -422,7 +425,7 @@ static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(functionBunEscapeHTMLWitho
JSC_DEFINE_HOST_FUNCTION(functionBunSleep,
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
JSC::VM& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
JSC::JSValue millisecondsValue = callFrame->argument(0);
@@ -448,7 +451,7 @@ extern "C" JSC::EncodedJSValue Bun__escapeHTML16(JSGlobalObject* globalObject, J
JSC_DEFINE_HOST_FUNCTION(functionBunEscapeHTML, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
{
JSC::VM& vm = JSC::getVM(lexicalGlobalObject);
auto& vm = JSC::getVM(lexicalGlobalObject);
JSC::JSValue argument = callFrame->argument(0);
if (argument.isEmpty())
return JSValue::encode(jsEmptyString(vm));
@@ -477,7 +480,7 @@ JSC_DEFINE_HOST_FUNCTION(functionBunEscapeHTML, (JSC::JSGlobalObject * lexicalGl
JSC_DEFINE_HOST_FUNCTION(functionBunDeepEquals, (JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
auto* global = reinterpret_cast<GlobalObject*>(globalObject);
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -509,7 +512,7 @@ JSC_DEFINE_HOST_FUNCTION(functionBunDeepEquals, (JSGlobalObject * globalObject,
JSC_DEFINE_HOST_FUNCTION(functionBunDeepMatch, (JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
auto* global = reinterpret_cast<GlobalObject*>(globalObject);
JSC::VM& vm = global->vm();
auto& vm = JSC::getVM(global);
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -569,7 +572,7 @@ JSC_DEFINE_HOST_FUNCTION(functionPathToFileURL, (JSC::JSGlobalObject * lexicalGl
JSC_DEFINE_HOST_FUNCTION(functionGenerateHeapSnapshot, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
auto& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
vm.ensureHeapProfiler();
auto& heapProfiler = *vm.heapProfiler();
heapProfiler.clearSnapshots();
@@ -608,7 +611,7 @@ JSC_DEFINE_HOST_FUNCTION(functionGenerateHeapSnapshot, (JSC::JSGlobalObject * gl
JSC_DEFINE_HOST_FUNCTION(functionFileURLToPath, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
auto& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
JSValue arg0 = callFrame->argument(0);
WTF::URL url;
@@ -728,13 +731,13 @@ JSC_DEFINE_HOST_FUNCTION(functionFileURLToPath, (JSC::JSGlobalObject * globalObj
isMainThread constructIsMainThread ReadOnly|DontDelete|PropertyCallback
jest BunObject_callback_jest DontEnum|DontDelete|Function 1
listen BunObject_callback_listen DontDelete|Function 1
udpSocket BunObject_callback_udpSocket DontDelete|Function 1
udpSocket BunObject_callback_udpSocket DontDelete|Function 1
main BunObject_getter_wrap_main DontDelete|PropertyCallback
mmap BunObject_callback_mmap DontDelete|Function 1
nanoseconds functionBunNanoseconds DontDelete|Function 0
openInEditor BunObject_callback_openInEditor DontDelete|Function 1
origin BunObject_getter_wrap_origin DontDelete|PropertyCallback
version_with_sha constructBunVersionWithSha ReadOnly|DontDelete|PropertyCallback
origin BunObject_getter_wrap_origin DontEnum|ReadOnly|DontDelete|PropertyCallback
version_with_sha constructBunVersionWithSha DontEnum|ReadOnly|DontDelete|PropertyCallback
password constructPasswordObject DontDelete|PropertyCallback
pathToFileURL functionPathToFileURL DontDelete|Function 1
peek constructBunPeekObject DontDelete|PropertyCallback
@@ -838,4 +841,54 @@ JSC::JSObject* createBunObject(VM& vm, JSObject* globalObject)
return JSBunObject::create(vm, jsCast<Zig::GlobalObject*>(globalObject));
}
static void exportBunObject(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSObject* object, Vector<JSC::Identifier, 4>& exportNames, JSC::MarkedArgumentBuffer& exportValues)
{
exportNames.reserveCapacity(std::size(bunObjectTableValues) + 1);
exportValues.ensureCapacity(std::size(bunObjectTableValues) + 1);
PropertyNameArray propertyNames(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
auto scope = DECLARE_THROW_SCOPE(vm);
object->getOwnNonIndexPropertyNames(globalObject, propertyNames, DontEnumPropertiesMode::Exclude);
RETURN_IF_EXCEPTION(scope, void());
for (const auto& propertyName : propertyNames) {
exportNames.append(propertyName);
auto catchScope = DECLARE_CATCH_SCOPE(vm);
// Yes, we have to call getters :(
JSValue value = object->get(globalObject, propertyName);
if (catchScope.exception()) {
catchScope.clearException();
value = jsUndefined();
}
exportValues.append(value);
}
exportNames.append(vm.propertyNames->defaultKeyword);
exportValues.append(object);
}
}
namespace Zig {
void generateNativeModule_BunObject(JSC::JSGlobalObject* lexicalGlobalObject,
JSC::Identifier moduleKey,
Vector<JSC::Identifier, 4>& exportNames,
JSC::MarkedArgumentBuffer& exportValues)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
Zig::GlobalObject* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
auto* object = globalObject->bunObject();
// :'(
object->reifyAllStaticProperties(lexicalGlobalObject);
RETURN_IF_EXCEPTION(scope, void());
Bun::exportBunObject(vm, globalObject, object, exportNames, exportValues);
}
}

View File

@@ -47,7 +47,7 @@ static bool isValidNamespaceString(String& namespaceString)
static JSC::EncodedJSValue jsFunctionAppendOnLoadPluginBody(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callframe, BunPluginTarget target, BunPlugin::Base& plugin, void* ctx, OnAppendPluginCallback callback)
{
JSC::VM& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
if (callframe->argumentCount() < 2) {
@@ -99,7 +99,7 @@ static JSC::EncodedJSValue jsFunctionAppendOnLoadPluginBody(JSC::JSGlobalObject*
static EncodedJSValue jsFunctionAppendVirtualModulePluginBody(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callframe)
{
JSC::VM& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
if (callframe->argumentCount() < 2) {
@@ -155,7 +155,7 @@ static EncodedJSValue jsFunctionAppendVirtualModulePluginBody(JSC::JSGlobalObjec
static JSC::EncodedJSValue jsFunctionAppendOnResolvePluginBody(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callframe, BunPluginTarget target, BunPlugin::Base& plugin, void* ctx, OnAppendPluginCallback callback)
{
JSC::VM& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
if (callframe->argumentCount() < 2) {
@@ -262,7 +262,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionAppendOnResolvePluginBrowser, (JSC::JSGlobalO
static inline JSC::EncodedJSValue setupBunPlugin(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callframe, BunPluginTarget target)
{
JSC::VM& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
if (callframe->argumentCount() < 1) {
JSC::throwTypeError(globalObject, throwScope, "plugin needs at least one argument (an object)"_s);
@@ -445,7 +445,7 @@ Structure* JSModuleMock::createStructure(JSC::VM& vm, JSC::JSGlobalObject* globa
JSObject* JSModuleMock::executeOnce(JSC::JSGlobalObject* lexicalGlobalObject)
{
auto& vm = lexicalGlobalObject->vm();
auto& vm = JSC::getVM(lexicalGlobalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
if (hasCalledModuleMock) {
@@ -484,7 +484,7 @@ extern "C" JSC::EncodedJSValue Bun__resolveSyncWithSource(JSC::JSGlobalObject* g
BUN_DECLARE_HOST_FUNCTION(JSMock__jsModuleMock);
extern "C" JSC_DEFINE_HOST_FUNCTION(JSMock__jsModuleMock, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callframe))
{
JSC::VM& vm = lexicalGlobalObject->vm();
auto& vm = JSC::getVM(lexicalGlobalObject);
Zig::GlobalObject* globalObject = defaultGlobalObject(lexicalGlobalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
if (UNLIKELY(!globalObject)) {
@@ -704,7 +704,7 @@ EncodedJSValue BunPlugin::OnLoad::run(JSC::JSGlobalObject* globalObject, BunStri
}
JSC::MarkedArgumentBuffer arguments;
JSC::VM& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
JSC::JSObject* paramsObject = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 1);
const auto& builtinNames = WebCore::builtinNames(vm);
@@ -790,7 +790,7 @@ EncodedJSValue BunPlugin::OnResolve::run(JSC::JSGlobalObject* globalObject, BunS
}
JSC::MarkedArgumentBuffer arguments;
JSC::VM& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
JSC::JSObject* paramsObject = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 2);
const auto& builtinNames = WebCore::builtinNames(vm);
@@ -880,7 +880,7 @@ JSC::JSValue runVirtualModule(Zig::GlobalObject* globalObject, BunString* specif
WTF::String specifierString = specifier->toWTFString(BunString::ZeroCopy);
if (auto virtualModuleFn = virtualModules.get(specifierString)) {
auto& vm = globalObject->vm();
auto& vm = JSC::getVM(globalObject);
JSC::JSObject* function = virtualModuleFn.get();
auto throwScope = DECLARE_THROW_SCOPE(vm);

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