aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
authorGravatar Dylan Conway <dylan.conway567@gmail.com> 2023-10-17 14:10:25 -0700
committerGravatar Dylan Conway <dylan.conway567@gmail.com> 2023-10-17 14:10:25 -0700
commit7458b969c5d9971e89d187b687e1924e78da427e (patch)
treeee3dbf95c728cf407bf49a27826b541e9264a8bd /src/bun.js
parentd4a2c29131ec154f5e4db897d4deedab2002cbc4 (diff)
parente91436e5248d947b50f90b4a7402690be8a41f39 (diff)
downloadbun-7458b969c5d9971e89d187b687e1924e78da427e.tar.gz
bun-7458b969c5d9971e89d187b687e1924e78da427e.tar.zst
bun-7458b969c5d9971e89d187b687e1924e78da427e.zip
Merge branch 'main' into postinstall_3
Diffstat (limited to 'src/bun.js')
m---------src/bun.js/WebKit0
-rw-r--r--src/bun.js/api/JSTranspiler.zig6
-rw-r--r--src/bun.js/api/bun.zig18
-rw-r--r--src/bun.js/api/bun/dns_resolver.zig335
-rw-r--r--src/bun.js/api/bun/socket.zig37
-rw-r--r--src/bun.js/api/bun/subprocess.zig62
-rw-r--r--src/bun.js/api/bun/x509.zig6
-rw-r--r--src/bun.js/api/ffi.zig6
-rw-r--r--src/bun.js/api/html_rewriter.zig28
-rw-r--r--src/bun.js/api/server.classes.ts8
-rw-r--r--src/bun.js/api/server.zig272
-rw-r--r--src/bun.js/base.zig34
-rw-r--r--src/bun.js/bindings/AsyncContextFrame.cpp4
-rw-r--r--src/bun.js/bindings/BunDebugger.cpp5
-rw-r--r--src/bun.js/bindings/BunObject.cpp47
-rw-r--r--src/bun.js/bindings/BunObject.h2
-rw-r--r--src/bun.js/bindings/BunObject.lut.h2
-rw-r--r--src/bun.js/bindings/BunPlugin.cpp255
-rw-r--r--src/bun.js/bindings/BunPlugin.h22
-rw-r--r--src/bun.js/bindings/BunString.cpp40
-rw-r--r--src/bun.js/bindings/CallSite.cpp2
-rw-r--r--src/bun.js/bindings/CallSitePrototype.h1
-rw-r--r--src/bun.js/bindings/CommonJSModuleRecord.cpp297
-rw-r--r--src/bun.js/bindings/CommonJSModuleRecord.h44
-rw-r--r--src/bun.js/bindings/DOMURL.cpp33
-rw-r--r--src/bun.js/bindings/DOMURL.h1
-rw-r--r--src/bun.js/bindings/ErrorStackTrace.cpp92
-rw-r--r--src/bun.js/bindings/ErrorStackTrace.h12
-rw-r--r--src/bun.js/bindings/FFI.zig3
-rw-r--r--src/bun.js/bindings/ImportMetaObject.cpp47
-rw-r--r--src/bun.js/bindings/InternalModuleRegistry.cpp21
-rw-r--r--src/bun.js/bindings/InternalModuleRegistry.h17
-rw-r--r--src/bun.js/bindings/JSBuffer.cpp111
-rw-r--r--src/bun.js/bindings/JSBuffer.lut.h52
-rw-r--r--src/bun.js/bindings/JSBufferList.cpp28
-rw-r--r--src/bun.js/bindings/JSBufferList.h3
-rw-r--r--src/bun.js/bindings/JSBundlerPlugin.cpp2
-rw-r--r--src/bun.js/bindings/JSCUSocketsLoopIntegration.cpp30
-rw-r--r--src/bun.js/bindings/JSDOMFile.cpp11
-rw-r--r--src/bun.js/bindings/JSDOMWrapperCache.h4
-rw-r--r--src/bun.js/bindings/JSMockFunction.cpp4
-rw-r--r--src/bun.js/bindings/JSNextTickQueue.cpp6
-rw-r--r--src/bun.js/bindings/JSNextTickQueue.h1
-rw-r--r--src/bun.js/bindings/JSReadableState.cpp12
-rw-r--r--src/bun.js/bindings/JSReadableState.h1
-rw-r--r--src/bun.js/bindings/JSSink.cpp64
-rw-r--r--src/bun.js/bindings/JSSocketAddress.cpp63
-rw-r--r--src/bun.js/bindings/JSSocketAddress.h16
-rw-r--r--src/bun.js/bindings/JSStringDecoder.h1
-rw-r--r--src/bun.js/bindings/KeyObject.cpp2389
-rw-r--r--src/bun.js/bindings/KeyObject.h18
-rw-r--r--src/bun.js/bindings/ModuleLoader.cpp20
-rw-r--r--src/bun.js/bindings/ModuleLoader.h3
-rw-r--r--src/bun.js/bindings/NodeVMScript.cpp8
-rw-r--r--src/bun.js/bindings/Path.cpp2
-rw-r--r--src/bun.js/bindings/Process.cpp162
-rw-r--r--src/bun.js/bindings/Process.h17
-rw-r--r--src/bun.js/bindings/Process.lut.h118
-rw-r--r--src/bun.js/bindings/ProcessBindingConstants.cpp25
-rw-r--r--src/bun.js/bindings/ProcessBindingConstants.h4
-rw-r--r--src/bun.js/bindings/ProcessBindingConstants.lut.h31
-rw-r--r--src/bun.js/bindings/ProcessBindingNatives.cpp131
-rw-r--r--src/bun.js/bindings/ProcessBindingNatives.h36
-rw-r--r--src/bun.js/bindings/ProcessBindingNatives.lut.h339
-rw-r--r--src/bun.js/bindings/ProcessBindingUV.cpp158
-rw-r--r--src/bun.js/bindings/ProcessBindingUV.h13
-rw-r--r--src/bun.js/bindings/RegularExpression.cpp4
-rw-r--r--src/bun.js/bindings/ScriptExecutionContext.cpp4
-rw-r--r--src/bun.js/bindings/Serialization.cpp32
-rw-r--r--src/bun.js/bindings/URLDecomposition.cpp9
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h1
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h1
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h306
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h109
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses.cpp563
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses.h60
-rw-r--r--src/bun.js/bindings/ZigGeneratedCode.cpp39
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp1631
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h164
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.lut.h341
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.lut.txt82
-rw-r--r--src/bun.js/bindings/ZigLazyStaticFunctions-inlines.h2
-rw-r--r--src/bun.js/bindings/ZigSourceProvider.cpp1
-rw-r--r--src/bun.js/bindings/ZigSourceProvider.h3
-rw-r--r--src/bun.js/bindings/bindings.cpp200
-rw-r--r--src/bun.js/bindings/bindings.zig54
-rw-r--r--src/bun.js/bindings/c-bindings.cpp29
-rw-r--r--src/bun.js/bindings/exports.zig58
-rw-r--r--src/bun.js/bindings/generated_classes.zig205
-rw-r--r--src/bun.js/bindings/generated_classes_list.zig1
-rw-r--r--src/bun.js/bindings/headers-handwritten.h24
-rw-r--r--src/bun.js/bindings/isBuiltinModule.cpp98
-rw-r--r--src/bun.js/bindings/isBuiltinModule.h5
-rw-r--r--src/bun.js/bindings/napi.cpp124
-rw-r--r--src/bun.js/bindings/process.d.ts8
-rw-r--r--src/bun.js/bindings/sqlite/JSSQLStatement.cpp38
-rw-r--r--src/bun.js/bindings/sqlite/JSSQLStatement.h17
-rw-r--r--src/bun.js/bindings/sqlite/lazy_sqlite3.h4
-rw-r--r--src/bun.js/bindings/webcore/AbortSignal.h7
-rw-r--r--src/bun.js/bindings/webcore/JSDOMURL.cpp29
-rw-r--r--src/bun.js/bindings/webcore/JSEventEmitter.cpp7
-rw-r--r--src/bun.js/bindings/webcore/JSFetchHeaders.cpp30
-rw-r--r--src/bun.js/bindings/webcore/JSFetchHeaders.h2
-rw-r--r--src/bun.js/bindings/webcore/JSMessageEvent.cpp2
-rw-r--r--src/bun.js/bindings/webcore/JSReadableStream.cpp2
-rw-r--r--src/bun.js/bindings/webcore/JSReadableStreamDefaultController.cpp2
-rw-r--r--src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.cpp2
-rw-r--r--src/bun.js/bindings/webcore/JSURLSearchParams.cpp1
-rw-r--r--src/bun.js/bindings/webcore/MessagePort.cpp12
-rw-r--r--src/bun.js/bindings/webcore/MessagePortChannel.cpp12
-rw-r--r--src/bun.js/bindings/webcore/MessagePortChannelProvider.cpp3
-rw-r--r--src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp41
-rw-r--r--src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp12
-rw-r--r--src/bun.js/bindings/webcore/WebSocket.cpp21
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyAES.cpp4
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyEC.h4
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyECOpenSSL.cpp7
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyHMAC.cpp14
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyHMAC.h2
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyOKP.cpp29
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyOKP.h2
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyOKPOpenSSL.cpp12
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyRSA.cpp23
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKey.cpp2
-rw-r--r--src/bun.js/bindings/webcrypto/JSJsonWebKey.cpp6
-rw-r--r--src/bun.js/bindings/webcrypto/JSJsonWebKey.h2
-rw-r--r--src/bun.js/bindings/wtf-bindings.cpp22
-rw-r--r--src/bun.js/bindings/wtf-bindings.h4
-rw-r--r--src/bun.js/event_loop.zig303
-rw-r--r--src/bun.js/ipc.zig144
-rw-r--r--src/bun.js/javascript.zig189
-rw-r--r--src/bun.js/module_loader.zig112
-rw-r--r--src/bun.js/modules/BunJSCModule.h4
-rw-r--r--src/bun.js/modules/NodeConstantsModule.h759
-rw-r--r--src/bun.js/modules/NodeModuleModule.h72
-rw-r--r--src/bun.js/modules/NodeUtilTypesModule.h5
-rw-r--r--src/bun.js/modules/_NativeModule.h9
-rw-r--r--src/bun.js/node/node_fs.zig2190
-rw-r--r--src/bun.js/node/node_fs_binding.zig62
-rw-r--r--src/bun.js/node/node_fs_constant.zig71
-rw-r--r--src/bun.js/node/node_fs_stat_watcher.zig4
-rw-r--r--src/bun.js/node/node_os.zig3
-rw-r--r--src/bun.js/node/path_watcher.zig13
-rw-r--r--src/bun.js/node/types.zig132
-rw-r--r--src/bun.js/rare_data.zig26
-rwxr-xr-xsrc/bun.js/scripts/create_hash_table461
-rw-r--r--src/bun.js/scripts/generate-classes.ts52
-rw-r--r--src/bun.js/scripts/generate-jssink.js18
-rw-r--r--src/bun.js/test/expect.zig131
-rw-r--r--src/bun.js/test/jest.classes.ts16
-rw-r--r--src/bun.js/test/jest.zig43
-rw-r--r--src/bun.js/webcore.zig9
-rw-r--r--src/bun.js/webcore/blob.zig58
-rw-r--r--src/bun.js/webcore/body.zig171
-rw-r--r--src/bun.js/webcore/encoding.classes.ts3
-rw-r--r--src/bun.js/webcore/encoding.zig38
-rw-r--r--src/bun.js/webcore/request.zig49
-rw-r--r--src/bun.js/webcore/response.zig292
-rw-r--r--src/bun.js/webcore/streams.zig61
159 files changed, 10910 insertions, 4767 deletions
diff --git a/src/bun.js/WebKit b/src/bun.js/WebKit
-Subproject a780bdf0255ae1a7ed15e4b3f31c14af705faca
+Subproject 1a49a1f94bf42ab4f8c6b11d7bbbb21e491d2d6
diff --git a/src/bun.js/api/JSTranspiler.zig b/src/bun.js/api/JSTranspiler.zig
index 8cec025eb..d41458acb 100644
--- a/src/bun.js/api/JSTranspiler.zig
+++ b/src/bun.js/api/JSTranspiler.zig
@@ -72,6 +72,7 @@ const TranspilerOptions = struct {
trim_unused_imports: ?bool = null,
inlining: bool = false,
+ dead_code_elimination: bool = true,
minify_whitespace: bool = false,
minify_identifiers: bool = false,
minify_syntax: bool = false,
@@ -541,6 +542,10 @@ fn transformOptionsFromJSC(globalObject: JSC.C.JSContextRef, temp_allocator: std
transpiler.minify_whitespace = flag.toBoolean();
}
+ if (object.get(globalThis, "deadCodeElimination")) |flag| {
+ transpiler.dead_code_elimination = flag.toBoolean();
+ }
+
if (object.getTruthy(globalThis, "minify")) |hot| {
if (hot.isBoolean()) {
transpiler.minify_whitespace = hot.coerce(bool, globalThis);
@@ -800,6 +805,7 @@ pub fn constructor(
bundler.options.macro_remap = transpiler_options.macro_map;
}
+ bundler.options.dead_code_elimination = transpiler_options.dead_code_elimination;
bundler.options.minify_whitespace = transpiler_options.minify_whitespace;
// Keep defaults for these
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig
index 966c82d38..21c2ecd0e 100644
--- a/src/bun.js/api/bun.zig
+++ b/src/bun.js/api/bun.zig
@@ -782,11 +782,17 @@ fn doResolveWithArgs(
var errorable: ErrorableString = undefined;
var query_string = ZigString.Empty;
+ const specifier_decoded = if (specifier.hasPrefixComptime("file://"))
+ bun.JSC.URL.pathFromFileURL(specifier)
+ else
+ specifier.dupeRef();
+ defer specifier_decoded.deref();
+
if (comptime is_file_path) {
VirtualMachine.resolveFilePathForAPI(
&errorable,
ctx.ptr(),
- specifier,
+ specifier_decoded,
from,
&query_string,
is_esm,
@@ -795,7 +801,7 @@ fn doResolveWithArgs(
VirtualMachine.resolveForAPI(
&errorable,
ctx.ptr(),
- specifier,
+ specifier_decoded,
from,
&query_string,
is_esm,
@@ -1098,10 +1104,12 @@ pub const Crypto = struct {
}
pub fn reset(this: *EVP, engine: *BoringSSL.ENGINE) void {
+ BoringSSL.ERR_clear_error();
_ = BoringSSL.EVP_DigestInit_ex(&this.ctx, this.md, engine);
}
pub fn hash(this: *EVP, engine: *BoringSSL.ENGINE, input: []const u8, output: []u8) ?u32 {
+ BoringSSL.ERR_clear_error();
var outsize: c_uint = @min(@as(u16, @truncate(output.len)), this.size());
if (BoringSSL.EVP_Digest(input.ptr, input.len, output.ptr, &outsize, this.md, engine) != 1) {
return null;
@@ -1111,6 +1119,7 @@ pub const Crypto = struct {
}
pub fn final(this: *EVP, engine: *BoringSSL.ENGINE, output: []u8) []const u8 {
+ BoringSSL.ERR_clear_error();
var outsize: u32 = @min(@as(u16, @truncate(output.len)), this.size());
if (BoringSSL.EVP_DigestFinal_ex(
&this.ctx,
@@ -1126,6 +1135,7 @@ pub const Crypto = struct {
}
pub fn update(this: *EVP, input: []const u8) void {
+ BoringSSL.ERR_clear_error();
_ = BoringSSL.EVP_DigestUpdate(&this.ctx, input.ptr, input.len);
}
@@ -1134,6 +1144,7 @@ pub const Crypto = struct {
}
pub fn copy(this: *const EVP, engine: *BoringSSL.ENGINE) error{OutOfMemory}!EVP {
+ BoringSSL.ERR_clear_error();
var new = init(this.algorithm, this.md, engine);
if (BoringSSL.EVP_MD_CTX_copy_ex(&new.ctx, &this.ctx) == 0) {
return error.OutOfMemory;
@@ -2004,7 +2015,6 @@ pub const Crypto = struct {
pub const digest = JSC.wrapInstanceMethod(CryptoHasher, "digest_", false);
pub const hash = JSC.wrapStaticMethod(CryptoHasher, "hash_", false);
-
pub fn getByteLength(
this: *CryptoHasher,
_: *JSC.JSGlobalObject,
@@ -3594,7 +3604,7 @@ pub const Timer = struct {
this.poll_ref.unref(vm);
- this.timer.deinit();
+ this.timer.deinit(false);
// balance double unreffing in doUnref
vm.event_loop_handle.?.num_polls += @as(i32, @intFromBool(this.did_unref_timer));
diff --git a/src/bun.js/api/bun/dns_resolver.zig b/src/bun.js/api/bun/dns_resolver.zig
index 8232318a2..3c20f4df7 100644
--- a/src/bun.js/api/bun/dns_resolver.zig
+++ b/src/bun.js/api/bun/dns_resolver.zig
@@ -102,11 +102,12 @@ const LibInfo = struct {
) catch unreachable;
const promise_value = request.head.promise.value();
+ const hints = query.options.toLibC();
const errno = getaddrinfo_async_start_(
&request.backend.libinfo.machport,
name_z.ptr,
null,
- null,
+ if (hints != null) &hints.? else null,
GetAddrInfoRequest.getAddrInfoAsyncCallback,
request,
);
@@ -812,6 +813,170 @@ pub const GetHostByAddrInfoRequest = struct {
}
};
+pub const CAresNameInfo = struct {
+ const log = Output.scoped(@This(), true);
+
+ globalThis: *JSC.JSGlobalObject = undefined,
+ promise: JSC.JSPromise.Strong,
+ poll_ref: JSC.PollRef,
+ allocated: bool = false,
+ next: ?*@This() = null,
+ name: []const u8,
+
+ pub fn init(globalThis: *JSC.JSGlobalObject, allocator: std.mem.Allocator, name: []const u8) !*@This() {
+ var this = try allocator.create(@This());
+ var poll_ref = JSC.PollRef.init();
+ poll_ref.ref(globalThis.bunVM());
+ this.* = .{ .globalThis = globalThis, .promise = JSC.JSPromise.Strong.init(globalThis), .poll_ref = poll_ref, .allocated = true, .name = name };
+ return this;
+ }
+
+ pub fn processResolve(this: *@This(), err_: ?c_ares.Error, _: i32, result: ?c_ares.struct_nameinfo) void {
+ if (err_) |err| {
+ var promise = this.promise;
+ var globalThis = this.globalThis;
+ const error_value = globalThis.createErrorInstance("lookupService failed: {s}", .{err.label()});
+ error_value.put(
+ globalThis,
+ JSC.ZigString.static("code"),
+ JSC.ZigString.init(err.code()).toValueGC(globalThis),
+ );
+
+ promise.reject(globalThis, error_value);
+ this.deinit();
+ return;
+ }
+ if (result == null) {
+ var promise = this.promise;
+ var globalThis = this.globalThis;
+ const error_value = globalThis.createErrorInstance("lookupService failed: No results", .{});
+ error_value.put(
+ globalThis,
+ JSC.ZigString.static("code"),
+ JSC.ZigString.init("EUNREACHABLE").toValueGC(globalThis),
+ );
+
+ promise.reject(globalThis, error_value);
+ this.deinit();
+ return;
+ }
+ var name_info = result.?;
+ const array = name_info.toJSResponse(this.globalThis.allocator(), this.globalThis);
+ this.onComplete(array);
+ return;
+ }
+
+ pub fn onComplete(this: *@This(), result: JSC.JSValue) void {
+ var promise = this.promise;
+ var globalThis = this.globalThis;
+ this.promise = .{};
+ promise.resolve(globalThis, result);
+ this.deinit();
+ }
+
+ pub fn deinit(this: *@This()) void {
+ this.poll_ref.unrefOnNextTick(this.globalThis.bunVM());
+ // freed
+ bun.default_allocator.free(this.name);
+
+ if (this.allocated)
+ this.globalThis.allocator().destroy(this);
+ }
+};
+
+pub const GetNameInfoRequest = struct {
+ const request_type = @This();
+
+ const log = Output.scoped(@This(), false);
+
+ resolver_for_caching: ?*DNSResolver = null,
+ hash: u64 = 0,
+ cache: @This().CacheConfig = @This().CacheConfig{},
+ head: CAresNameInfo,
+ tail: *CAresNameInfo = undefined,
+
+ pub fn init(
+ cache: DNSResolver.LookupCacheHit(@This()),
+ resolver: ?*DNSResolver,
+ name: []const u8,
+ globalThis: *JSC.JSGlobalObject,
+ comptime cache_field: []const u8,
+ ) !*@This() {
+ var request = try globalThis.allocator().create(@This());
+ var hasher = std.hash.Wyhash.init(0);
+ hasher.update(name);
+ const hash = hasher.final();
+ var poll_ref = JSC.PollRef.init();
+ poll_ref.ref(globalThis.bunVM());
+ request.* = .{
+ .resolver_for_caching = resolver,
+ .hash = hash,
+ .head = .{ .poll_ref = poll_ref, .globalThis = globalThis, .promise = JSC.JSPromise.Strong.init(globalThis), .allocated = false, .name = name },
+ };
+ request.tail = &request.head;
+ if (cache == .new) {
+ request.resolver_for_caching = resolver;
+ request.cache = @This().CacheConfig{
+ .pending_cache = true,
+ .entry_cache = false,
+ .pos_in_pending = @as(u5, @truncate(@field(resolver.?, cache_field).indexOf(cache.new).?)),
+ .name_len = @as(u9, @truncate(name.len)),
+ };
+ cache.new.lookup = request;
+ }
+ return request;
+ }
+
+ pub const CacheConfig = packed struct(u16) {
+ pending_cache: bool = false,
+ entry_cache: bool = false,
+ pos_in_pending: u5 = 0,
+ name_len: u9 = 0,
+ };
+
+ pub const PendingCacheKey = struct {
+ hash: u64,
+ len: u16,
+ lookup: *request_type = undefined,
+
+ pub fn append(this: *PendingCacheKey, cares_lookup: *CAresNameInfo) void {
+ var tail = this.lookup.tail;
+ tail.next = cares_lookup;
+ this.lookup.tail = cares_lookup;
+ }
+
+ pub fn init(name: []const u8) PendingCacheKey {
+ var hasher = std.hash.Wyhash.init(0);
+ hasher.update(name);
+ const hash = hasher.final();
+ return PendingCacheKey{
+ .hash = hash,
+ .len = @as(u16, @truncate(name.len)),
+ .lookup = undefined,
+ };
+ }
+ };
+
+ pub fn onCaresComplete(this: *@This(), err_: ?c_ares.Error, timeout: i32, result: ?c_ares.struct_nameinfo) void {
+ if (this.resolver_for_caching) |resolver| {
+ if (this.cache.pending_cache) {
+ resolver.drainPendingNameInfoCares(
+ this.cache.pos_in_pending,
+ err_,
+ timeout,
+ result,
+ );
+ return;
+ }
+ }
+
+ var head = this.head;
+ bun.default_allocator.destroy(this);
+
+ head.processResolve(err_, timeout, result);
+ }
+};
+
pub const GetAddrInfoRequest = struct {
const log = Output.scoped(.GetAddrInfoRequest, false);
@@ -1086,7 +1251,7 @@ pub const CAresReverse = struct {
return;
}
var node = result.?;
- const array = node.toJSReponse(this.globalThis.allocator(), this.globalThis, "");
+ const array = node.toJSResponse(this.globalThis.allocator(), this.globalThis, "");
this.onComplete(array);
return;
}
@@ -1157,7 +1322,7 @@ pub fn CAresLookup(comptime cares_type: type, comptime type_name: []const u8) ty
return;
}
var node = result.?;
- const array = node.toJSReponse(this.globalThis.allocator(), this.globalThis, type_name);
+ const array = node.toJSResponse(this.globalThis.allocator(), this.globalThis, type_name);
this.onComplete(array);
return;
}
@@ -1325,6 +1490,7 @@ pub const DNSResolver = struct {
pending_ptr_cache_cares: PtrPendingCache = PtrPendingCache.init(),
pending_cname_cache_cares: CnamePendingCache = CnamePendingCache.init(),
pending_addr_cache_crares: AddrPendingCache = AddrPendingCache.init(),
+ pending_nameinfo_cache_cares: NameInfoPendingCache = NameInfoPendingCache.init(),
const PendingCache = bun.HiveArray(GetAddrInfoRequest.PendingCacheKey, 32);
const SrvPendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_ares_srv_reply, "srv").PendingCacheKey, 32);
@@ -1337,6 +1503,7 @@ pub const DNSResolver = struct {
const PtrPendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_hostent, "ptr").PendingCacheKey, 32);
const CnamePendingCache = bun.HiveArray(ResolveInfoRequest(c_ares.struct_hostent, "cname").PendingCacheKey, 32);
const AddrPendingCache = bun.HiveArray(GetHostByAddrInfoRequest.PendingCacheKey, 32);
+ const NameInfoPendingCache = bun.HiveArray(GetNameInfoRequest.PendingCacheKey, 32);
fn getKey(this: *DNSResolver, index: u8, comptime cache_name: []const u8, comptime request_type: type) request_type.PendingCacheKey {
var cache = &@field(this, cache_name);
@@ -1370,7 +1537,7 @@ pub const DNSResolver = struct {
var pending: ?*CAresLookup(cares_type, lookup_name) = key.lookup.head.next;
var prev_global = key.lookup.head.globalThis;
- var array = addr.toJSReponse(this.vm.allocator, prev_global, lookup_name);
+ var array = addr.toJSResponse(this.vm.allocator, prev_global, lookup_name);
defer addr.deinit();
array.ensureStillAlive();
key.lookup.head.onComplete(array);
@@ -1381,7 +1548,7 @@ pub const DNSResolver = struct {
while (pending) |value| {
var new_global = value.globalThis;
if (prev_global != new_global) {
- array = addr.toJSReponse(this.vm.allocator, new_global, lookup_name);
+ array = addr.toJSResponse(this.vm.allocator, new_global, lookup_name);
prev_global = new_global;
}
pending = value.next;
@@ -1500,7 +1667,48 @@ pub const DNSResolver = struct {
// The callback need not and should not attempt to free the memory
// pointed to by hostent; the ares library will free it when the
// callback returns.
- var array = addr.toJSReponse(this.vm.allocator, prev_global, "");
+ var array = addr.toJSResponse(this.vm.allocator, prev_global, "");
+ array.ensureStillAlive();
+ key.lookup.head.onComplete(array);
+ bun.default_allocator.destroy(key.lookup);
+
+ array.ensureStillAlive();
+
+ while (pending) |value| {
+ var new_global = value.globalThis;
+ if (prev_global != new_global) {
+ array = addr.toJSResponse(this.vm.allocator, new_global, "");
+ prev_global = new_global;
+ }
+ pending = value.next;
+
+ {
+ array.ensureStillAlive();
+ value.onComplete(array);
+ array.ensureStillAlive();
+ }
+ }
+ }
+
+ pub fn drainPendingNameInfoCares(this: *DNSResolver, index: u8, err: ?c_ares.Error, timeout: i32, result: ?c_ares.struct_nameinfo) void {
+ const key = this.getKey(index, "pending_nameinfo_cache_cares", GetNameInfoRequest);
+
+ var name_info = result orelse {
+ var pending: ?*CAresNameInfo = key.lookup.head.next;
+ key.lookup.head.processResolve(err, timeout, null);
+ bun.default_allocator.destroy(key.lookup);
+
+ while (pending) |value| {
+ pending = value.next;
+ value.processResolve(err, timeout, null);
+ }
+ return;
+ };
+
+ var pending: ?*CAresNameInfo = key.lookup.head.next;
+ var prev_global = key.lookup.head.globalThis;
+
+ var array = name_info.toJSResponse(this.vm.allocator, prev_global);
array.ensureStillAlive();
key.lookup.head.onComplete(array);
bun.default_allocator.destroy(key.lookup);
@@ -1510,7 +1718,7 @@ pub const DNSResolver = struct {
while (pending) |value| {
var new_global = value.globalThis;
if (prev_global != new_global) {
- array = addr.toJSReponse(this.vm.allocator, new_global, "");
+ array = name_info.toJSResponse(this.vm.allocator, new_global);
prev_global = new_global;
}
pending = value.next;
@@ -1977,11 +2185,6 @@ pub const DNSResolver = struct {
return .zero;
};
- if (name_str.length() == 0) {
- globalThis.throwInvalidArgumentType("resolveSoa", "hostname", "non-empty string");
- return .zero;
- }
-
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
var vm = globalThis.bunVM();
@@ -2039,11 +2242,6 @@ pub const DNSResolver = struct {
return .zero;
};
- if (name_str.length() == 0) {
- globalThis.throwInvalidArgumentType("resolveNs", "hostname", "non-empty string");
- return .zero;
- }
-
const name = name_str.toSliceClone(globalThis, bun.default_allocator);
var vm = globalThis.bunVM();
@@ -2278,7 +2476,7 @@ pub const DNSResolver = struct {
return dns_lookup.promise.value();
}
- // var hints_buf = &[_]c_ares.AddrInfo_hints{query.toCAres()};
+ var hints_buf = &[_]c_ares.AddrInfo_hints{query.toCAres()};
var request = GetAddrInfoRequest.init(
cache,
.{
@@ -2294,7 +2492,7 @@ pub const DNSResolver = struct {
channel.getAddrInfo(
query.name,
query.port,
- &.{},
+ hints_buf,
GetAddrInfoRequest,
request,
GetAddrInfoRequest.onCaresComplete,
@@ -2386,6 +2584,95 @@ pub const DNSResolver = struct {
return values;
}
+ // Resolves the given address and port into a host name and service using the operating system's underlying getnameinfo implementation.
+ // If address is not a valid IP address, a TypeError will be thrown. The port will be coerced to a number.
+ // If it is not a legal port, a TypeError will be thrown.
+ pub fn lookupService(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(3);
+ if (arguments.len < 2) {
+ globalThis.throwNotEnoughArguments("lookupService", 3, arguments.len);
+ return .zero;
+ }
+
+ const addr_value = arguments.ptr[0];
+ const port_value = arguments.ptr[1];
+ if (addr_value.isEmptyOrUndefinedOrNull() or !addr_value.isString()) {
+ globalThis.throwInvalidArgumentType("lookupService", "address", "string");
+ return .zero;
+ }
+ const addr_str = addr_value.toStringOrNull(globalThis) orelse {
+ return .zero;
+ };
+ if (addr_str.length() == 0) {
+ globalThis.throwInvalidArgumentType("lookupService", "address", "non-empty string");
+ return .zero;
+ }
+
+ const addr_s = addr_str.getZigString(globalThis).slice();
+ const port: u16 = if (port_value.isNumber()) blk: {
+ break :blk port_value.to(u16);
+ } else {
+ globalThis.throwInvalidArgumentType("lookupService", "port", "invalid port");
+ return .zero;
+ };
+
+ var sa: std.os.sockaddr.storage = std.mem.zeroes(std.os.sockaddr.storage);
+ if (c_ares.getSockaddr(addr_s, port, @as(*std.os.sockaddr, @ptrCast(&sa))) != 0) {
+ globalThis.throwInvalidArgumentType("lookupService", "address", "invalid address");
+ return .zero;
+ }
+
+ var vm = globalThis.bunVM();
+ var resolver = vm.rareData().globalDNSResolver(vm);
+ var channel: *c_ares.Channel = switch (resolver.getChannel()) {
+ .result => |res| res,
+ .err => |err| {
+ const system_error = JSC.SystemError{
+ .errno = -1,
+ .code = bun.String.static(err.code()),
+ .message = bun.String.static(err.label()),
+ };
+
+ globalThis.throwValue(system_error.toErrorInstance(globalThis));
+ return .zero;
+ },
+ };
+
+ // This string will be freed in `CAresNameInfo.deinit`
+ const cache_name = std.fmt.allocPrint(bun.default_allocator, "{s}|{d}", .{ addr_s, port }) catch unreachable;
+
+ const key = GetNameInfoRequest.PendingCacheKey.init(cache_name);
+ var cache = resolver.getOrPutIntoResolvePendingCache(
+ GetNameInfoRequest,
+ key,
+ "pending_nameinfo_cache_cares",
+ );
+
+ if (cache == .inflight) {
+ var info = CAresNameInfo.init(globalThis, globalThis.allocator(), cache_name) catch unreachable;
+ cache.inflight.append(info);
+ return info.promise.value();
+ }
+
+ var request = GetNameInfoRequest.init(
+ cache,
+ resolver,
+ cache_name, // transfer ownership here
+ globalThis,
+ "pending_nameinfo_cache_cares",
+ ) catch unreachable;
+
+ const promise = request.tail.promise.value();
+ channel.getNameInfo(
+ @as(*std.os.sockaddr, @ptrCast(&sa)),
+ GetNameInfoRequest,
+ request,
+ GetNameInfoRequest.onCaresComplete,
+ );
+
+ return promise;
+ }
+
comptime {
@export(
resolve,
@@ -2465,11 +2752,13 @@ pub const DNSResolver = struct {
.name = "Bun__DNSResolver__reverse",
},
);
+ @export(
+ lookupService,
+ .{
+ .name = "Bun__DNSResolver__lookupService",
+ },
+ );
}
- // pub fn lookupService(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
- // const arguments = callframe.arguments(3);
-
- // }
// pub fn cancel(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
// const arguments = callframe.arguments(3);
diff --git a/src/bun.js/api/bun/socket.zig b/src/bun.js/api/bun/socket.zig
index 2ad44ffb0..e89ee5aa1 100644
--- a/src/bun.js/api/bun/socket.zig
+++ b/src/bun.js/api/bun/socket.zig
@@ -771,7 +771,7 @@ pub const Listener = struct {
Socket.dataSetCached(this_socket.getThisValue(globalObject), globalObject, default_data);
}
socket.ext(**anyopaque).?.* = bun.cast(**anyopaque, this_socket);
- socket.timeout(120000);
+ socket.setTimeout(120000);
}
// pub fn addServerName(this: *Listener, _: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSValue {
@@ -996,7 +996,12 @@ pub const Listener = struct {
handlers.vm.allocator.destroy(handlers_ptr);
handlers.promise.deinit();
bun.default_allocator.destroy(tls);
- exception.* = ZigString.static("Failed to connect").toErrorInstance(globalObject).asObjectRef();
+ const err = JSC.SystemError{
+ .message = bun.String.static("Failed to connect"),
+ .syscall = bun.String.static("connect"),
+ .code = if (port == null) bun.String.static("ENOENT") else bun.String.static("ECONNREFUSED"),
+ };
+ exception.* = err.toErrorInstance(globalObject).asObjectRef();
return .zero;
};
tls.poll_ref.ref(handlers.vm);
@@ -1022,7 +1027,12 @@ pub const Listener = struct {
handlers.vm.allocator.destroy(handlers_ptr);
handlers.promise.deinit();
bun.default_allocator.destroy(tcp);
- exception.* = ZigString.static("Failed to connect").toErrorInstance(globalObject).asObjectRef();
+ const err = JSC.SystemError{
+ .message = bun.String.static("Failed to connect"),
+ .syscall = bun.String.static("connect"),
+ .code = if (port == null) bun.String.static("ENOENT") else bun.String.static("ECONNREFUSED"),
+ };
+ exception.* = err.toErrorInstance(globalObject).asObjectRef();
return .zero;
};
tcp.poll_ref.ref(handlers.vm);
@@ -1205,6 +1215,12 @@ fn NewSocket(comptime ssl: bool) type {
.errno = errno,
.message = bun.String.static("Failed to connect"),
.syscall = bun.String.static("connect"),
+
+ // For some reason errno is 0 which causes this to be success.
+ // Unix socket case wont hit this callback because it instantly errors.
+ .code = bun.String.static("ECONNREFUSED"),
+ // .code = bun.String.static(@tagName(bun.sys.getErrno(errno))),
+ // .code = bun.String.static(@tagName(@as(bun.C.E, @enumFromInt(errno)))),
};
if (callback == .zero) {
@@ -1583,7 +1599,7 @@ fn NewSocket(comptime ssl: bool) type {
return .zero;
}
- this.socket.timeout(@as(c_uint, @intCast(t)));
+ this.socket.setTimeout(@as(c_uint, @intCast(t)));
return JSValue.jsUndefined();
}
@@ -1913,7 +1929,7 @@ fn NewSocket(comptime ssl: bool) type {
}
pub fn finalize(this: *This) callconv(.C) void {
- log("finalize()", .{});
+ log("finalize() {d}", .{@intFromPtr(this)});
if (!this.detached) {
this.detached = true;
if (!this.socket.isClosed()) {
@@ -2946,6 +2962,17 @@ pub fn NewWrappedHandler(comptime tls: bool) type {
}
}
+ pub fn onLongTimeout(
+ this: WrappedSocket,
+ socket: Socket,
+ ) void {
+ if (comptime tls) {
+ TLSSocket.onTimeout(this.tls, socket);
+ } else {
+ TLSSocket.onTimeout(this.tcp, socket);
+ }
+ }
+
pub fn onConnectError(
this: WrappedSocket,
socket: Socket,
diff --git a/src/bun.js/api/bun/subprocess.zig b/src/bun.js/api/bun/subprocess.zig
index 5695c15ad..f6d86d91a 100644
--- a/src/bun.js/api/bun/subprocess.zig
+++ b/src/bun.js/api/bun/subprocess.zig
@@ -62,12 +62,11 @@ pub const Subprocess = struct {
is_sync: bool = false,
this_jsvalue: JSC.JSValue = .zero,
- ipc: IPCMode,
- // this is only ever accessed when `ipc` is not `none`
- ipc_socket: IPC.Socket = undefined,
+ ipc_mode: IPCMode,
ipc_callback: JSC.Strong = .{},
- ipc_buffer: bun.ByteList,
+ ipc: IPC.IPCData,
+ has_pending_unref: bool = false,
pub const SignalCode = bun.SignalCode;
pub const IPCMode = enum {
@@ -82,7 +81,7 @@ pub const Subprocess = struct {
pub fn updateHasPendingActivityFlag(this: *Subprocess) void {
@fence(.SeqCst);
- this.has_pending_activity.store(this.waitpid_err == null and this.exit_code == null and this.ipc == .none, .SeqCst);
+ this.has_pending_activity.store(this.waitpid_err == null and this.exit_code == null and this.ipc_mode == .none and this.has_pending_unref, .SeqCst);
}
pub fn hasPendingActivity(this: *Subprocess) callconv(.C) bool {
@@ -92,7 +91,7 @@ pub const Subprocess = struct {
pub fn updateHasPendingActivity(this: *Subprocess) void {
@fence(.Release);
- this.has_pending_activity.store(this.waitpid_err == null and this.exit_code == null and this.ipc == .none, .Release);
+ this.has_pending_activity.store(this.waitpid_err == null and this.exit_code == null and this.ipc_mode == .none and this.has_pending_unref, .Release);
}
pub fn ref(this: *Subprocess) void {
@@ -111,8 +110,10 @@ pub const Subprocess = struct {
}
}
+ /// This disables the keeping process alive flag on the poll and also in the stdin, stdout, and stderr
pub fn unref(this: *Subprocess) void {
var vm = this.globalThis.bunVM();
+
if (this.poll_ref) |poll| poll.disableKeepingProcessAlive(vm);
if (!this.hasCalledGetter(.stdin)) {
this.stdin.unref();
@@ -425,7 +426,7 @@ pub const Subprocess = struct {
}
pub fn doSend(this: *Subprocess, global: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSValue {
- if (this.ipc == .none) {
+ if (this.ipc_mode == .none) {
global.throw("Subprocess.send() can only be used if an IPC channel is open.", .{});
return .zero;
}
@@ -437,20 +438,16 @@ pub const Subprocess = struct {
const value = callFrame.argument(0);
- const success = IPC.serializeJSValueForSubprocess(
- global,
- value,
- this.ipc_socket.fd(),
- );
+ const success = this.ipc.serializeAndSend(global, value);
if (!success) return .zero;
return JSC.JSValue.jsUndefined();
}
pub fn disconnect(this: *Subprocess) void {
- if (this.ipc == .none) return;
- this.ipc_socket.close(0, null);
- this.ipc = .none;
+ if (this.ipc_mode == .none) return;
+ this.ipc.socket.close(0, null);
+ this.ipc_mode = .none;
}
pub fn getPid(
@@ -1538,15 +1535,15 @@ pub const Subprocess = struct {
.stderr = Readable.init(stdio[bun.STDERR_FD], stderr_pipe[0], jsc_vm.allocator, default_max_buffer_size),
.on_exit_callback = if (on_exit_callback != .zero) JSC.Strong.create(on_exit_callback, globalThis) else .{},
.is_sync = is_sync,
- .ipc = ipc_mode,
+ .ipc_mode = ipc_mode,
// will be assigned in the block below
- .ipc_socket = socket,
- .ipc_buffer = bun.ByteList{},
+ .ipc = .{ .socket = socket },
.ipc_callback = if (ipc_callback != .zero) JSC.Strong.create(ipc_callback, globalThis) else undefined,
};
if (ipc_mode != .none) {
var ptr = socket.ext(*Subprocess);
ptr.?.* = subprocess;
+ subprocess.ipc.writeVersionPacket();
}
if (subprocess.stdin == .pipe) {
@@ -1805,8 +1802,29 @@ pub const Subprocess = struct {
}
}
- if (this.hasExited())
- this.unref();
+ if (this.hasExited()) {
+ const Holder = struct {
+ process: *Subprocess,
+ task: JSC.AnyTask,
+
+ pub fn unref(self: *@This()) void {
+ // this calls disableKeepingProcessAlive on pool_ref and stdin, stdout, stderr
+ self.process.unref();
+ self.process.has_pending_unref = false;
+ self.process.updateHasPendingActivity();
+ bun.default_allocator.destroy(self);
+ }
+ };
+
+ var holder = bun.default_allocator.create(Holder) catch @panic("OOM");
+ this.has_pending_unref = true;
+ holder.* = .{
+ .process = this,
+ .task = JSC.AnyTask.New(Holder, Holder.unref).init(holder),
+ };
+
+ this.globalThis.bunVM().enqueueTask(JSC.Task.init(&holder.task));
+ }
}
const os = std.os;
@@ -2036,7 +2054,7 @@ pub const Subprocess = struct {
const result = cb.callWithThis(
this.globalThis,
this.this_jsvalue,
- &[_]JSValue{data},
+ &[_]JSValue{ data, this.this_jsvalue },
);
data.ensureStillAlive();
if (result.isAnyError()) {
@@ -2049,7 +2067,7 @@ pub const Subprocess = struct {
pub fn handleIPCClose(this: *Subprocess, _: IPC.Socket) void {
// uSocket is already freed so calling .close() on the socket can segfault
- this.ipc = .none;
+ this.ipc_mode = .none;
this.updateHasPendingActivity();
}
diff --git a/src/bun.js/api/bun/x509.zig b/src/bun.js/api/bun/x509.zig
index 9c902b39c..a94d47c45 100644
--- a/src/bun.js/api/bun/x509.zig
+++ b/src/bun.js/api/bun/x509.zig
@@ -273,7 +273,8 @@ fn x509PrintGeneralName(out: *BoringSSL.BIO, name: *BoringSSL.GENERAL_NAME) bool
// instead always print its numeric representation.
var oline: [256]u8 = undefined;
_ = BoringSSL.OBJ_obj2txt(&oline, @sizeOf(@TypeOf(oline)), name.d.rid, 1);
- _ = BoringSSL.BIO_printf(out, "Registered ID:%s", &oline);
+ // Workaround for https://github.com/ziglang/zig/issues/16197
+ _ = BoringSSL.BIO_printf(out, "Registered ID:%s", @as([*]const u8, &oline));
} else if (name.name_type == .GEN_X400) {
_ = BoringSSL.BIO_printf(out, "X400Name:<unsupported>");
} else if (name.name_type == .GEN_EDIPARTY) {
@@ -301,7 +302,8 @@ fn x509InfoAccessPrint(out: *BoringSSL.BIO, ext: *BoringSSL.X509_EXTENSION) bool
}
var tmp: [80]u8 = undefined;
_ = BoringSSL.i2t_ASN1_OBJECT(&tmp, @sizeOf(@TypeOf(tmp)), desc.method);
- _ = BoringSSL.BIO_printf(out, "%s - ", &tmp);
+ // Workaround for https://github.com/ziglang/zig/issues/16197
+ _ = BoringSSL.BIO_printf(out, "%s - ", @as([*]const u8, &tmp));
if (!x509PrintGeneralName(out, desc.location)) {
return false;
diff --git a/src/bun.js/api/ffi.zig b/src/bun.js/api/ffi.zig
index 097b66d35..a7a03e784 100644
--- a/src/bun.js/api/ffi.zig
+++ b/src/bun.js/api/ffi.zig
@@ -318,7 +318,11 @@ pub const FFI = struct {
};
};
- var obj = JSC.JSValue.createEmptyObject(global, symbols.values().len);
+ var size = symbols.values().len;
+ if (size >= 63) {
+ size = 0;
+ }
+ var obj = JSC.JSValue.createEmptyObject(global, size);
obj.protect();
defer obj.unprotect();
for (symbols.values()) |*function| {
diff --git a/src/bun.js/api/html_rewriter.zig b/src/bun.js/api/html_rewriter.zig
index 1bda47512..1f2366ad9 100644
--- a/src/bun.js/api/html_rewriter.zig
+++ b/src/bun.js/api/html_rewriter.zig
@@ -384,10 +384,10 @@ pub const HTMLRewriter = struct {
result.* = Response{
.allocator = bun.default_allocator,
+ .init = .{
+ .status_code = 200,
+ },
.body = .{
- .init = .{
- .status_code = 200,
- },
.value = .{
.Locked = .{
.global = global,
@@ -397,16 +397,16 @@ pub const HTMLRewriter = struct {
},
};
- result.body.init.method = original.body.init.method;
- result.body.init.status_code = original.body.init.status_code;
+ result.init.method = original.init.method;
+ result.init.status_code = original.init.status_code;
+ result.init.status_text = original.init.status_text.clone();
// https://github.com/oven-sh/bun/issues/3334
- if (original.body.init.headers) |headers| {
- result.body.init.headers = headers.cloneThis(global);
+ if (original.init.headers) |headers| {
+ result.init.headers = headers.cloneThis(global);
}
result.url = original.url.clone();
- result.status_text = original.status_text.clone();
var value = original.getBodyValue();
sink.bodyValueBufferer = JSC.WebCore.BodyValueBufferer.init(sink, onFinishedBuffering, sink.global, bun.default_allocator);
sink.bodyValueBufferer.?.run(value) catch |buffering_error| {
@@ -606,10 +606,10 @@ pub const HTMLRewriter = struct {
// result.* = Response{
// .allocator = bun.default_allocator,
+ // .init = .{
+ // .status_code = 200,
+ // },
// .body = .{
- // .init = .{
- // .status_code = 200,
- // },
// .value = .{
// .Locked = .{
// .global = global,
@@ -619,9 +619,9 @@ pub const HTMLRewriter = struct {
// },
// };
- // result.body.init.headers = original.body.init.headers;
- // result.body.init.method = original.body.init.method;
- // result.body.init.status_code = original.body.init.status_code;
+ // result.init.headers = original.init.headers;
+ // result.init.method = original.init.method;
+ // result.init.status_code = original.init.status_code;
// result.url = bun.default_allocator.dupe(u8, original.url) catch unreachable;
// result.status_text = bun.default_allocator.dupe(u8, original.status_text) catch unreachable;
diff --git a/src/bun.js/api/server.classes.ts b/src/bun.js/api/server.classes.ts
index 544f37ce6..81ec30988 100644
--- a/src/bun.js/api/server.classes.ts
+++ b/src/bun.js/api/server.classes.ts
@@ -24,6 +24,10 @@ function generate(name) {
fn: "doStop",
length: 1,
},
+ requestIP: {
+ fn: "doRequestIP",
+ length: 1,
+ },
port: {
getter: "getPort",
},
@@ -41,6 +45,10 @@ function generate(name) {
getter: "getHostname",
cache: true,
},
+ address: {
+ getter: "getAddress",
+ cache: true,
+ },
protocol: {
getter: "getProtocol",
},
diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig
index 85d4dadb5..edf1d6d69 100644
--- a/src/bun.js/api/server.zig
+++ b/src/bun.js/api/server.zig
@@ -1125,6 +1125,92 @@ fn NewFlags(comptime debug_mode: bool) type {
};
}
+/// A generic wrapper for the HTTP(s) Server`RequestContext`s.
+/// Only really exists because of `NewServer()` and `NewRequestContext()` generics.
+pub const AnyRequestContext = struct {
+ pub const Pointer = bun.TaggedPointerUnion(.{
+ HTTPServer.RequestContext,
+ HTTPSServer.RequestContext,
+ DebugHTTPServer.RequestContext,
+ DebugHTTPSServer.RequestContext,
+ });
+
+ tagged_pointer: Pointer,
+
+ pub const Null = .{ .tagged_pointer = Pointer.Null };
+
+ pub fn init(request_ctx: anytype) AnyRequestContext {
+ return .{ .tagged_pointer = Pointer.init(request_ctx) };
+ }
+
+ pub fn getRemoteSocketInfo(self: AnyRequestContext) ?uws.SocketAddress {
+ if (self.tagged_pointer.isNull()) {
+ return null;
+ }
+
+ switch (self.tagged_pointer.tag()) {
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(HTTPServer.RequestContext))) => {
+ return self.tagged_pointer.as(HTTPServer.RequestContext).getRemoteSocketInfo();
+ },
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(HTTPSServer.RequestContext))) => {
+ return self.tagged_pointer.as(HTTPSServer.RequestContext).getRemoteSocketInfo();
+ },
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(DebugHTTPServer.RequestContext))) => {
+ return self.tagged_pointer.as(DebugHTTPServer.RequestContext).getRemoteSocketInfo();
+ },
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(DebugHTTPSServer.RequestContext))) => {
+ return self.tagged_pointer.as(DebugHTTPSServer.RequestContext).getRemoteSocketInfo();
+ },
+ else => @panic("Unexpected AnyRequestContext tag"),
+ }
+ }
+
+ /// Wont actually set anything if `self` is `.none`
+ pub fn setRequest(self: AnyRequestContext, req: *uws.Request) void {
+ if (self.tagged_pointer.isNull()) {
+ return;
+ }
+
+ switch (self.tagged_pointer.tag()) {
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(HTTPServer.RequestContext))) => {
+ self.tagged_pointer.as(HTTPServer.RequestContext).req = req;
+ },
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(HTTPSServer.RequestContext))) => {
+ self.tagged_pointer.as(HTTPSServer.RequestContext).req = req;
+ },
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(DebugHTTPServer.RequestContext))) => {
+ self.tagged_pointer.as(DebugHTTPServer.RequestContext).req = req;
+ },
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(DebugHTTPSServer.RequestContext))) => {
+ self.tagged_pointer.as(DebugHTTPSServer.RequestContext).req = req;
+ },
+ else => @panic("Unexpected AnyRequestContext tag"),
+ }
+ }
+
+ pub fn getRequest(self: AnyRequestContext) ?*uws.Request {
+ if (self.tagged_pointer.isNull()) {
+ return null;
+ }
+
+ switch (self.tagged_pointer.tag()) {
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(HTTPServer.RequestContext))) => {
+ return self.tagged_pointer.as(HTTPServer.RequestContext).req;
+ },
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(HTTPSServer.RequestContext))) => {
+ return self.tagged_pointer.as(HTTPSServer.RequestContext).req;
+ },
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(DebugHTTPServer.RequestContext))) => {
+ return self.tagged_pointer.as(DebugHTTPServer.RequestContext).req;
+ },
+ @field(Pointer.Tag, bun.meta.typeBaseName(@typeName(DebugHTTPSServer.RequestContext))) => {
+ return self.tagged_pointer.as(DebugHTTPSServer.RequestContext).req;
+ },
+ else => @panic("Unexpected AnyRequestContext tag"),
+ }
+ }
+};
+
// This is defined separately partially to work-around an LLVM debugger bug.
fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comptime ThisServer: type) type {
return struct {
@@ -1443,6 +1529,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
}
pub fn endStream(this: *RequestContext, closeConnection: bool) void {
+ ctxLog("endStream", .{});
if (this.resp) |resp| {
if (this.flags.is_waiting_for_request_body) {
this.flags.is_waiting_for_request_body = false;
@@ -1537,8 +1624,17 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
pub fn onAbort(this: *RequestContext, resp: *App.Response) void {
std.debug.assert(this.resp == resp);
std.debug.assert(!this.flags.aborted);
- //mark request as aborted
+ // mark request as aborted
this.flags.aborted = true;
+ var any_js_calls = false;
+ var vm = this.server.vm;
+ defer {
+ // This is a task in the event loop.
+ // If we called into JavaScript, we must drain the microtask queue
+ if (any_js_calls) {
+ vm.drainMicrotasks();
+ }
+ }
// if signal is not aborted, abort the signal
if (this.signal) |signal| {
@@ -1547,6 +1643,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
const reason = JSC.WebCore.AbortSignal.createAbortError(JSC.ZigString.static("The user aborted a request"), &JSC.ZigString.Empty, this.server.globalThis);
reason.ensureStillAlive();
_ = signal.signal(reason);
+ any_js_calls = true;
}
_ = signal.unref();
}
@@ -1578,6 +1675,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
} else if (body.value.Locked.readable != null) {
body.value.Locked.readable.?.abort(this.server.globalThis);
body.value.Locked.readable = null;
+ any_js_calls = true;
}
body.value.toErrorInstance(JSC.toTypeError(.ABORT_ERR, "Request aborted", .{}, this.server.globalThis), this.server.globalThis);
}
@@ -1588,6 +1686,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
if (response.body.value.Locked.readable) |*readable| {
response.body.value.Locked.readable = null;
readable.abort(this.server.globalThis);
+ any_js_calls = true;
}
}
}
@@ -1597,10 +1696,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
this.pending_promises_for_abort += 1;
this.promise = null;
promise.asAnyPromise().?.reject(this.server.globalThis, JSC.toTypeError(.ABORT_ERR, "Request aborted", .{}, this.server.globalThis));
- }
-
- if (this.pending_promises_for_abort > 0) {
- this.server.vm.tick();
+ any_js_calls = true;
}
}
}
@@ -1720,6 +1816,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
this: *RequestContext,
headers: *JSC.FetchHeaders,
) void {
+ ctxLog("writeHeaders", .{});
headers.fastRemove(.ContentLength);
headers.fastRemove(.TransferEncoding);
if (!ssl_enabled) headers.fastRemove(.StrictTransportSecurity);
@@ -2091,6 +2188,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
}
fn doRenderStream(pair: *StreamPair) void {
+ ctxLog("doRenderStream", .{});
var this = pair.this;
var stream = pair.stream;
if (this.resp == null or this.flags.aborted) {
@@ -2214,6 +2312,14 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
},
}
return;
+ } else {
+ // if is not a promise we treat it as Error
+ streamLog("returned an error", .{});
+ if (!this.flags.aborted) resp.clearAborted();
+ response_stream.detach();
+ this.sink = null;
+ response_stream.sink.destroy();
+ return this.handleReject(assignment_result);
}
}
@@ -2223,6 +2329,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
defer stream.value.unprotect();
response_stream.sink.markDone();
this.finalizeForAbort();
+ response_stream.sink.onFirstWrite = null;
response_stream.sink.finalize();
return;
@@ -2246,7 +2353,12 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
this.setAbortHandler();
streamLog("is in progress, but did not return a Promise. Finalizing request context", .{});
- this.finalize();
+ response_stream.sink.onFirstWrite = null;
+ response_stream.sink.ctx = null;
+ response_stream.detach();
+ stream.cancel(globalThis);
+ response_stream.sink.markDone();
+ this.renderMissing();
}
const streamLog = Output.scoped(.ReadableStream, false);
@@ -2256,7 +2368,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
}
fn toAsyncWithoutAbortHandler(ctx: *RequestContext, req: *uws.Request, request_object: *Request) void {
- request_object.uws_request = req;
+ request_object.request_context.setRequest(req);
request_object.ensureURL() catch {
request_object.url = bun.String.empty;
@@ -2269,7 +2381,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
// This object dies after the stack frame is popped
// so we have to clear it in here too
- request_object.uws_request = null;
+ request_object.request_context = JSC.API.AnyRequestContext.Null;
}
fn toAsync(
@@ -2446,7 +2558,6 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
}
streamLog("onResolve({any})", .{wrote_anything});
-
//aborted so call finalizeForAbort
if (req.flags.aborted or req.resp == null) {
req.finalizeForAbort();
@@ -2723,7 +2834,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
}
pub fn doRender(this: *RequestContext) void {
- ctxLog("render", .{});
+ ctxLog("doRender", .{});
if (this.flags.aborted) {
this.finalizeForAbort();
@@ -2877,7 +2988,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
var needs_content_type = true;
const content_type: MimeType = brk: {
- if (response.body.init.headers) |headers_| {
+ if (response.init.headers) |headers_| {
if (headers_.fastGet(.ContentType)) |content| {
needs_content_type = false;
break :brk MimeType.byName(content.slice());
@@ -2897,7 +3008,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
};
var has_content_disposition = false;
- if (response.body.init.headers) |headers_| {
+ if (response.init.headers) |headers_| {
has_content_disposition = headers_.fastHas(.ContentDisposition);
needs_content_range = needs_content_range and headers_.fastHas(.ContentRange);
if (needs_content_range) {
@@ -2907,7 +3018,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
this.writeStatus(status);
this.writeHeaders(headers_);
- response.body.init.headers = null;
+ response.init.headers = null;
headers_.deref();
} else if (needs_content_range) {
status = 206;
@@ -3039,7 +3150,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
if (last) {
var bytes = this.request_body_buf;
- defer this.request_body_buf = .{};
+
var old = body.value;
const total = bytes.items.len + chunk.len;
@@ -3070,6 +3181,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
};
// }
}
+ this.request_body_buf = .{};
if (old == .Locked) {
var vm = this.server.vm;
@@ -3142,6 +3254,10 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
return onStartStreamingRequestBody(bun.cast(*RequestContext, this));
}
+ pub fn getRemoteSocketInfo(this: *RequestContext) ?uws.SocketAddress {
+ return (this.resp orelse return null).getRemoteSocketInfo();
+ }
+
pub const Export = shim.exportFunctions(.{
.onResolve = onResolve,
.onReject = onReject,
@@ -4667,17 +4783,6 @@ pub const ServerWebSocket = struct {
return JSValue.jsBoolean(this.websocket.isSubscribed(topic.slice()));
}
- // pub fn getTopics(
- // this: *ServerWebSocket,
- // globalThis: *JSC.JSGlobalObject,
- // ) callconv(.C) JSValue {
- // if (this.closed) {
- // return JSValue.createStringArray(globalThis, bun.default_allocator, null, 0, false);
- // }
-
- // this
- // }
-
pub fn getRemoteAddress(
this: *ServerWebSocket,
globalThis: *JSC.JSGlobalObject,
@@ -4704,7 +4809,7 @@ pub const ServerWebSocket = struct {
pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
return struct {
pub const ssl_enabled = ssl_enabled_;
- const debug_mode = debug_mode_;
+ pub const debug_mode = debug_mode_;
const ThisServer = @This();
pub const RequestContext = NewRequestContext(ssl_enabled, debug_mode, @This());
@@ -4742,6 +4847,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
pub const doPublish = JSC.wrapInstanceMethod(ThisServer, "publish", false);
pub const doReload = onReload;
pub const doFetch = onFetch;
+ pub const doRequestIP = JSC.wrapInstanceMethod(ThisServer, "requestIP", false);
pub usingnamespace NamespaceType;
@@ -4749,6 +4855,24 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
globalThis.throw("Server() is not a constructor", .{});
return null;
}
+
+ extern fn JSSocketAddress__create(global: *JSC.JSGlobalObject, ip: JSValue, port: i32, is_ipv6: bool) JSValue;
+
+ pub fn requestIP(this: *ThisServer, request: *JSC.WebCore.Request) JSC.JSValue {
+ if (this.config.address == .unix) {
+ return JSValue.jsNull();
+ }
+ return if (request.request_context.getRemoteSocketInfo()) |info|
+ JSSocketAddress__create(
+ this.globalThis,
+ bun.String.static(info.ip).toJSConst(this.globalThis),
+ info.port,
+ info.is_ipv6,
+ )
+ else
+ JSValue.jsNull();
+ }
+
pub fn publish(this: *ThisServer, globalThis: *JSC.JSGlobalObject, topic: ZigString, message_value: JSValue, compress_value: ?JSValue, exception: JSC.C.ExceptionRef) JSValue {
if (this.config.websocket == null)
return JSValue.jsNumber(0);
@@ -5092,7 +5216,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
return JSPromise.rejectedPromiseValue(ctx, err);
}
- var request = ctx.bunVM().allocator.create(Request) catch unreachable;
+ var request = bun.default_allocator.create(Request) catch unreachable;
request.* = existing_request;
const response_value = this.config.onRequest.callWithThis(
@@ -5173,6 +5297,37 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
return JSC.JSValue.jsNumber(@as(i32, @intCast(@as(u31, @truncate(this.activeSocketsCount())))));
}
+ pub fn getAddress(this: *ThisServer, globalThis: *JSGlobalObject) callconv(.C) JSC.JSValue {
+ switch (this.config.address) {
+ .unix => |unix| {
+ var value = bun.String.create(bun.sliceTo(@constCast(unix), 0));
+ defer value.deref();
+ return value.toJS(globalThis);
+ },
+ .tcp => {
+ var port: u16 = this.config.address.tcp.port;
+
+ if (this.listener) |listener| {
+ port = @intCast(listener.getLocalPort());
+
+ var buf: [64]u8 = [_]u8{0} ** 64;
+ var is_ipv6: bool = false;
+
+ if (listener.socket().localAddressText(&buf, &is_ipv6)) |slice| {
+ var ip = bun.String.create(slice);
+ return JSSocketAddress__create(
+ this.globalThis,
+ ip.toJS(this.globalThis),
+ port,
+ is_ipv6,
+ );
+ }
+ }
+ return JSValue.jsNull();
+ },
+ }
+ }
+
pub fn getHostname(this: *ThisServer, globalThis: *JSGlobalObject) callconv(.C) JSC.JSValue {
if (this.cached_hostname.isEmpty()) {
if (this.listener) |listener| {
@@ -5254,6 +5409,10 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
var listener = this.listener orelse return;
this.listener = null;
this.unref();
+
+ if (!ssl_enabled_)
+ this.vm.removeListeningSocketForWatchMode(@intCast(listener.socket().fd()));
+
if (!abrupt) {
listener.close();
} else if (!this.flags.terminated) {
@@ -5388,24 +5547,18 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
if (error_instance == .zero) {
switch (this.config.address) {
.tcp => |tcp| {
- error_instance = ZigString.init(
- std.fmt.bufPrint(&output_buf, "Failed to start server. Is port {d} in use?", .{tcp.port}) catch "Failed to start server",
- ).toErrorInstance(
- this.globalThis,
- );
+ error_instance = (JSC.SystemError{
+ .message = bun.String.init(std.fmt.bufPrint(&output_buf, "Failed to start server. Is port {d} in use?", .{tcp.port}) catch "Failed to start server"),
+ .code = bun.String.static("EADDRINUSE"),
+ .syscall = bun.String.static("listen"),
+ }).toErrorInstance(this.globalThis);
},
.unix => |unix| {
- error_instance = ZigString.init(
- std.fmt.bufPrint(
- &output_buf,
- "Failed to listen on unix socket {}",
- .{
- strings.QuotedFormatter{ .text = bun.sliceTo(unix, 0) },
- },
- ) catch "Failed to start server",
- ).toErrorInstance(
- this.globalThis,
- );
+ error_instance = (JSC.SystemError{
+ .message = bun.String.init(std.fmt.bufPrint(&output_buf, "Failed to listen on unix socket {}", .{strings.QuotedFormatter{ .text = bun.sliceTo(unix, 0) }}) catch "Failed to start server"),
+ .code = bun.String.static("EADDRINUSE"),
+ .syscall = bun.String.static("listen"),
+ }).toErrorInstance(this.globalThis);
},
}
}
@@ -5428,6 +5581,8 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
this.listener = socket;
this.vm.event_loop_handle = uws.Loop.get();
+ if (!ssl_enabled_)
+ this.vm.addListeningSocketForWatchMode(@intCast(socket.?.socket().fd()));
}
pub fn ref(this: *ThisServer) void {
@@ -5512,21 +5667,19 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
req.setYield(false);
var ctx = this.request_pool_allocator.tryGet() catch @panic("ran out of memory");
ctx.create(this, req, resp);
+ this.vm.jsc.reportExtraMemory(@sizeOf(RequestContext));
var request_object = this.allocator.create(JSC.WebCore.Request) catch unreachable;
var body = JSC.WebCore.InitRequestBodyValue(.{ .Null = {} }) catch unreachable;
ctx.request_body = body;
- const js_signal = JSC.WebCore.AbortSignal.create(this.globalThis);
- js_signal.ensureStillAlive();
- if (JSC.WebCore.AbortSignal.fromJS(js_signal)) |signal| {
- ctx.signal = signal.ref().ref(); // +2 refs 1 for the request and 1 for the request context
- }
+ var signal = JSC.WebCore.AbortSignal.new(this.globalThis);
+ ctx.signal = signal;
request_object.* = .{
.method = ctx.method,
- .uws_request = req,
+ .request_context = AnyRequestContext.init(ctx),
.https = ssl_enabled,
- .signal = ctx.signal,
+ .signal = signal.ref(),
.body = body.ref(),
};
@@ -5593,7 +5746,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
const response_value = this.config.onRequest.callWithThis(this.globalThis, this.thisObject, &args);
defer {
// uWS request will not live longer than this function
- request_object.uws_request = null;
+ request_object.request_context = JSC.API.AnyRequestContext.Null;
}
var should_deinit_context = false;
@@ -5608,7 +5761,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
ctx.defer_deinit_until_callback_completes = null;
if (should_deinit_context) {
- request_object.uws_request = null;
+ request_object.request_context = JSC.API.AnyRequestContext.Null;
ctx.deinit();
return;
}
@@ -5637,18 +5790,15 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
var body = JSC.WebCore.InitRequestBodyValue(.{ .Null = {} }) catch unreachable;
ctx.request_body = body;
- const js_signal = JSC.WebCore.AbortSignal.create(this.globalThis);
- js_signal.ensureStillAlive();
- if (JSC.WebCore.AbortSignal.fromJS(js_signal)) |signal| {
- ctx.signal = signal.ref().ref(); // +2 refs 1 for the request and 1 for the request context
- }
+ var signal = JSC.WebCore.AbortSignal.new(this.globalThis);
+ ctx.signal = signal;
request_object.* = .{
.method = ctx.method,
- .uws_request = req,
+ .request_context = AnyRequestContext.init(ctx),
.upgrader = ctx,
.https = ssl_enabled,
- .signal = ctx.signal,
+ .signal = signal.ref(),
.body = body.ref(),
};
ctx.upgrade_context = upgrade_ctx;
@@ -5663,7 +5813,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
const response_value = this.config.onRequest.callWithThis(this.globalThis, this.thisObject, &args);
defer {
// uWS request will not live longer than this function
- request_object.uws_request = null;
+ request_object.request_context = JSC.API.AnyRequestContext.Null;
}
var should_deinit_context = false;
@@ -5678,7 +5828,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
ctx.defer_deinit_until_callback_completes = null;
if (should_deinit_context) {
- request_object.uws_request = null;
+ request_object.request_context = JSC.API.AnyRequestContext.Null;
ctx.deinit();
return;
}
diff --git a/src/bun.js/base.zig b/src/bun.js/base.zig
index d050804e3..70e5351cc 100644
--- a/src/bun.js/base.zig
+++ b/src/bun.js/base.zig
@@ -1179,8 +1179,7 @@ pub fn DOMCall(
\\ thisObject->putDirect(
\\ globalObject->vm(),
\\ Identifier::fromString(globalObject->vm(), "{[name]s}"_s),
- \\ function,
- \\ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0
+ \\ function
\\ );
\\}}
;
@@ -1794,12 +1793,19 @@ pub const FilePoll = struct {
pub fn deinit(this: *FilePoll) void {
var vm = JSC.VirtualMachine.get();
- this.deinitWithVM(vm);
+ var loop = vm.event_loop_handle.?;
+ this.deinitPossiblyDefer(vm, loop, vm.rareData().filePolls(vm), false);
+ }
+
+ pub fn deinitForceUnregister(this: *FilePoll) void {
+ var vm = JSC.VirtualMachine.get();
+ var loop = vm.event_loop_handle.?;
+ this.deinitPossiblyDefer(vm, loop, vm.rareData().filePolls(vm), true);
}
- fn deinitPossiblyDefer(this: *FilePoll, vm: *JSC.VirtualMachine, loop: *uws.Loop, polls: *JSC.FilePoll.Store) void {
+ fn deinitPossiblyDefer(this: *FilePoll, vm: *JSC.VirtualMachine, loop: *uws.Loop, polls: *JSC.FilePoll.Store, force_unregister: bool) void {
if (this.isRegistered()) {
- _ = this.unregister(loop);
+ _ = this.unregister(loop, force_unregister);
}
this.owner = Deactivated.owner;
@@ -1811,7 +1817,7 @@ pub const FilePoll = struct {
pub fn deinitWithVM(this: *FilePoll, vm: *JSC.VirtualMachine) void {
var loop = vm.event_loop_handle.?;
- this.deinitPossiblyDefer(vm, loop, vm.rareData().filePolls(vm));
+ this.deinitPossiblyDefer(vm, loop, vm.rareData().filePolls(vm), false);
}
pub fn isRegistered(this: *const FilePoll) bool {
@@ -2204,10 +2210,12 @@ pub const FilePoll = struct {
var event = linux.epoll_event{ .events = flags, .data = .{ .u64 = @intFromPtr(Pollable.init(this).ptr()) } };
+ var op: u32 = if (this.isRegistered() or this.flags.contains(.needs_rearm)) linux.EPOLL.CTL_MOD else linux.EPOLL.CTL_ADD;
+
const ctl = linux.epoll_ctl(
watcher_fd,
- if (this.isRegistered() or this.flags.contains(.needs_rearm)) linux.EPOLL.CTL_MOD else linux.EPOLL.CTL_ADD,
- @as(std.os.fd_t, @intCast(fd)),
+ op,
+ @intCast(fd),
&event,
);
this.flags.insert(.was_ever_registered);
@@ -2321,11 +2329,11 @@ pub const FilePoll = struct {
const invalid_fd = bun.invalid_fd;
- pub fn unregister(this: *FilePoll, loop: *uws.Loop) JSC.Maybe(void) {
- return this.unregisterWithFd(loop, this.fd);
+ pub fn unregister(this: *FilePoll, loop: *uws.Loop, force_unregister: bool) JSC.Maybe(void) {
+ return this.unregisterWithFd(loop, this.fd, force_unregister);
}
- pub fn unregisterWithFd(this: *FilePoll, loop: *uws.Loop, fd: bun.UFileDescriptor) JSC.Maybe(void) {
+ pub fn unregisterWithFd(this: *FilePoll, loop: *uws.Loop, fd: bun.UFileDescriptor, force_unregister: bool) JSC.Maybe(void) {
if (!(this.flags.contains(.poll_readable) or this.flags.contains(.poll_writable) or this.flags.contains(.poll_process) or this.flags.contains(.poll_machport))) {
// no-op
return JSC.Maybe(void).success;
@@ -2346,7 +2354,7 @@ pub const FilePoll = struct {
return JSC.Maybe(void).success;
};
- if (this.flags.contains(.needs_rearm)) {
+ if (this.flags.contains(.needs_rearm) and !force_unregister) {
log("unregister: {s} ({d}) skipped due to needs_rearm", .{ @tagName(flag), fd });
this.flags.remove(.poll_process);
this.flags.remove(.poll_readable);
@@ -2361,7 +2369,7 @@ pub const FilePoll = struct {
const ctl = linux.epoll_ctl(
watcher_fd,
linux.EPOLL.CTL_DEL,
- @as(std.os.fd_t, @intCast(fd)),
+ @intCast(fd),
null,
);
diff --git a/src/bun.js/bindings/AsyncContextFrame.cpp b/src/bun.js/bindings/AsyncContextFrame.cpp
index 1c541b2a8..7b715d3d7 100644
--- a/src/bun.js/bindings/AsyncContextFrame.cpp
+++ b/src/bun.js/bindings/AsyncContextFrame.cpp
@@ -22,7 +22,7 @@ AsyncContextFrame* AsyncContextFrame::create(VM& vm, JSC::Structure* structure,
AsyncContextFrame* AsyncContextFrame::create(JSGlobalObject* global, JSValue callback, JSValue context)
{
auto& vm = global->vm();
- AsyncContextFrame* asyncContextData = new (NotNull, allocateCell<AsyncContextFrame>(vm)) AsyncContextFrame(vm, static_cast<Zig::GlobalObject*>(global)->AsyncContextFrameStructure());
+ AsyncContextFrame* asyncContextData = new (NotNull, allocateCell<AsyncContextFrame>(vm)) AsyncContextFrame(vm, jsCast<Zig::GlobalObject*>(global)->AsyncContextFrameStructure());
asyncContextData->finishCreation(vm);
asyncContextData->callback.set(vm, asyncContextData, callback);
asyncContextData->context.set(vm, asyncContextData, context);
@@ -47,7 +47,7 @@ JSValue AsyncContextFrame::withAsyncContextIfNeeded(JSGlobalObject* globalObject
auto& vm = globalObject->vm();
return AsyncContextFrame::create(
vm,
- static_cast<Zig::GlobalObject*>(globalObject)->AsyncContextFrameStructure(),
+ jsCast<Zig::GlobalObject*>(globalObject)->AsyncContextFrameStructure(),
callback,
context);
}
diff --git a/src/bun.js/bindings/BunDebugger.cpp b/src/bun.js/bindings/BunDebugger.cpp
index 046739923..55942d2f6 100644
--- a/src/bun.js/bindings/BunDebugger.cpp
+++ b/src/bun.js/bindings/BunDebugger.cpp
@@ -452,12 +452,13 @@ extern "C" void Bun__ensureDebugger(ScriptExecutionContextIdentifier scriptId, b
}
}
-extern "C" void BunDebugger__willHotReload() {
+extern "C" void BunDebugger__willHotReload()
+{
if (debuggerScriptExecutionContext == nullptr) {
return;
}
- debuggerScriptExecutionContext->postTaskConcurrently([](ScriptExecutionContext &context){
+ debuggerScriptExecutionContext->postTaskConcurrently([](ScriptExecutionContext& context) {
WTF::LockHolder locker(inspectorConnectionsLock);
for (auto& connections : *inspectorConnections) {
for (auto* connection : connections.value) {
diff --git a/src/bun.js/bindings/BunObject.cpp b/src/bun.js/bindings/BunObject.cpp
index 0b78d1367..498b83b45 100644
--- a/src/bun.js/bindings/BunObject.cpp
+++ b/src/bun.js/bindings/BunObject.cpp
@@ -190,7 +190,7 @@ static JSValue constructPluginObject(VM& vm, JSObject* bunObject)
auto* globalObject = bunObject->globalObject();
JSFunction* pluginFunction = JSFunction::create(vm, globalObject, 1, String("plugin"_s), jsFunctionBunPlugin, ImplementationVisibility::Public, NoIntrinsic);
pluginFunction->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "clearAll"_s), 1, jsFunctionBunPluginClear, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
return pluginFunction;
}
@@ -215,37 +215,40 @@ extern "C" EncodedJSValue Bun__DNSResolver__resolvePtr(JSGlobalObject*, JSC::Cal
extern "C" EncodedJSValue Bun__DNSResolver__resolveCname(JSGlobalObject*, JSC::CallFrame*);
extern "C" EncodedJSValue Bun__DNSResolver__getServers(JSGlobalObject*, JSC::CallFrame*);
extern "C" EncodedJSValue Bun__DNSResolver__reverse(JSGlobalObject*, JSC::CallFrame*);
+extern "C" EncodedJSValue Bun__DNSResolver__lookupService(JSGlobalObject*, JSC::CallFrame*);
static JSValue constructDNSObject(VM& vm, JSObject* bunObject)
{
JSGlobalObject* globalObject = bunObject->globalObject();
JSC::JSObject* dnsObject = JSC::constructEmptyObject(globalObject);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "lookup"_s), 2, Bun__DNSResolver__lookup, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "resolve"_s), 2, Bun__DNSResolver__resolve, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "resolveSrv"_s), 2, Bun__DNSResolver__resolveSrv, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "resolveTxt"_s), 2, Bun__DNSResolver__resolveTxt, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "resolveSoa"_s), 2, Bun__DNSResolver__resolveSoa, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "resolveNaptr"_s), 2, Bun__DNSResolver__resolveNaptr, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "resolveMx"_s), 2, Bun__DNSResolver__resolveMx, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "resolveCaa"_s), 2, Bun__DNSResolver__resolveCaa, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "resolveNs"_s), 2, Bun__DNSResolver__resolveNs, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "resolvePtr"_s), 2, Bun__DNSResolver__resolvePtr, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "resolveCname"_s), 2, Bun__DNSResolver__resolveCname, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "getServers"_s), 2, Bun__DNSResolver__getServers, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "reverse"_s), 2, Bun__DNSResolver__reverse, ImplementationVisibility::Public, NoIntrinsic,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::PropertyAttribute::DontDelete | 0);
+ dnsObject->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "lookupService"_s), 2, Bun__DNSResolver__lookupService, ImplementationVisibility::Public, NoIntrinsic,
+ JSC::PropertyAttribute::DontDelete | 0);
return dnsObject;
}
@@ -255,7 +258,7 @@ static JSValue constructBunPeekObject(VM& vm, JSObject* bunObject)
JSC::Identifier identifier = JSC::Identifier::fromString(vm, "peek"_s);
JSFunction* peekFunction = JSFunction::create(vm, globalObject, 2, WTF::String("peek"_s), functionBunPeek, ImplementationVisibility::Public, NoIntrinsic);
JSFunction* peekStatus = JSFunction::create(vm, globalObject, 1, WTF::String("status"_s), functionBunPeekStatus, ImplementationVisibility::Public, NoIntrinsic);
- peekFunction->putDirect(vm, PropertyName(JSC::Identifier::fromString(vm, "status"_s)), peekStatus, JSC::PropertyAttribute::Function | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
+ peekFunction->putDirect(vm, PropertyName(JSC::Identifier::fromString(vm, "status"_s)), peekStatus, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
return peekFunction;
}
@@ -602,7 +605,7 @@ JSC_DEFINE_HOST_FUNCTION(functionHashCode,
hash BunObject_getter_wrap_hash DontDelete|PropertyCallback
indexOfLine BunObject_callback_indexOfLine DontDelete|Function 1
inflateSync BunObject_callback_inflateSync DontDelete|Function 1
- inspect BunObject_getter_wrap_inspect DontDelete|PropertyCallback
+ inspect BunObject_getter_wrap_inspect DontDelete|PropertyCallback
isMainThread constructIsMainThread ReadOnly|DontDelete|PropertyCallback
jest BunObject_callback_jest DontEnum|DontDelete|Function 1
listen BunObject_callback_listen DontDelete|Function 1
@@ -660,6 +663,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSBunObject, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -670,15 +674,14 @@ public:
void finishCreation(JSC::VM& vm)
{
Base::finishCreation(vm);
-
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
static JSBunObject* create(JSC::VM& vm, JSGlobalObject* globalObject)
{
- auto* object = new (NotNull, JSC::allocateCell<JSBunObject>(vm)) JSBunObject(vm, createStructure(vm, globalObject, globalObject->objectPrototype()));
+ auto structure = createStructure(vm, globalObject, globalObject->objectPrototype());
+ auto* object = new (NotNull, JSC::allocateCell<JSBunObject>(vm)) JSBunObject(vm, structure);
object->finishCreation(vm);
-
return object;
}
};
@@ -699,11 +702,11 @@ public:
#undef bunObjectReadableStreamToJSONCodeGenerator
#undef bunObjectReadableStreamToTextCodeGenerator
-const JSC::ClassInfo JSBunObject::s_info = { "Bun"_s, &JSNonFinalObject::s_info, &bunObjectTable, nullptr, CREATE_METHOD_TABLE(JSBunObject) };
+const JSC::ClassInfo JSBunObject::s_info = { "Bun"_s, &Base::s_info, &bunObjectTable, nullptr, CREATE_METHOD_TABLE(JSBunObject) };
-JSValue createBunObject(Zig::GlobalObject* globalObject)
+JSC::JSObject* createBunObject(VM& vm, JSObject* globalObject)
{
- return JSBunObject::create(globalObject->vm(), globalObject);
+ return JSBunObject::create(vm, jsCast<Zig::GlobalObject*>(globalObject));
}
}
diff --git a/src/bun.js/bindings/BunObject.h b/src/bun.js/bindings/BunObject.h
index c2abfe06f..f527f5729 100644
--- a/src/bun.js/bindings/BunObject.h
+++ b/src/bun.js/bindings/BunObject.h
@@ -13,5 +13,5 @@ JSC_DECLARE_HOST_FUNCTION(functionBunNanoseconds);
JSC_DECLARE_HOST_FUNCTION(functionPathToFileURL);
JSC_DECLARE_HOST_FUNCTION(functionFileURLToPath);
-JSC::JSValue createBunObject(Zig::GlobalObject* globalObject);
+JSC::JSObject* createBunObject(VM& vm, JSObject* globalObject);
}
diff --git a/src/bun.js/bindings/BunObject.lut.h b/src/bun.js/bindings/BunObject.lut.h
index 1971cb8da..a2aa95fda 100644
--- a/src/bun.js/bindings/BunObject.lut.h
+++ b/src/bun.js/bindings/BunObject.lut.h
@@ -1,4 +1,4 @@
-// File generated via `make generate-builtins`
+// File generated via `make static-hash-table` / `make cpp`
static const struct CompactHashIndex bunObjectTableIndex[269] = {
{ 75, -1 },
{ -1, -1 },
diff --git a/src/bun.js/bindings/BunPlugin.cpp b/src/bun.js/bindings/BunPlugin.cpp
index 129d7816b..e0527c724 100644
--- a/src/bun.js/bindings/BunPlugin.cpp
+++ b/src/bun.js/bindings/BunPlugin.cpp
@@ -11,14 +11,17 @@
#include "JavaScriptCore/JSObjectInlines.h"
#include "wtf/text/WTFString.h"
#include "JavaScriptCore/JSCInlines.h"
+#include "JavaScriptCore/StrongInlines.h"
#include "JavaScriptCore/ObjectConstructor.h"
#include "JavaScriptCore/SubspaceInlines.h"
#include "JavaScriptCore/RegExpObject.h"
#include "JavaScriptCore/JSPromise.h"
#include "BunClientData.h"
-
+#include "isBuiltinModule.h"
#include "JavaScriptCore/RegularExpression.h"
+#include "JavaScriptCore/JSMap.h"
+#include "JavaScriptCore/JSMapInlines.h"
namespace Zig {
@@ -86,6 +89,76 @@ static EncodedJSValue jsFunctionAppendOnLoadPluginBody(JSC::JSGlobalObject* glob
return JSValue::encode(jsUndefined());
}
+static EncodedJSValue jsFunctionAppendVirtualModulePluginBody(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callframe)
+{
+ JSC::VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (callframe->argumentCount() < 2) {
+ throwException(globalObject, scope, createError(globalObject, "module() needs 2 arguments: a module ID and a function to call"_s));
+ return JSValue::encode(jsUndefined());
+ }
+
+ JSValue moduleIdValue = callframe->uncheckedArgument(0);
+ JSValue functionValue = callframe->uncheckedArgument(1);
+
+ if (!moduleIdValue.isString()) {
+ throwException(globalObject, scope, createError(globalObject, "module() expects first argument to be a string for the module ID"_s));
+ return JSValue::encode(jsUndefined());
+ }
+
+ if (!functionValue.isCallable()) {
+ throwException(globalObject, scope, createError(globalObject, "module() expects second argument to be a function"_s));
+ return JSValue::encode(jsUndefined());
+ }
+
+ String moduleId = moduleIdValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+ if (moduleId.isEmpty()) {
+ throwException(globalObject, scope, createError(globalObject, "virtual module cannot be blank"_s));
+ return JSValue::encode(jsUndefined());
+ }
+
+ if (Bun::isBuiltinModule(moduleId)) {
+ throwException(globalObject, scope, createError(globalObject, makeString("module() cannot be used to override builtin module \""_s, moduleId, "\""_s)));
+ return JSValue::encode(jsUndefined());
+ }
+
+ if (moduleId.startsWith("."_s)) {
+ throwException(globalObject, scope, createError(globalObject, "virtual module cannot start with \".\""_s));
+ return JSValue::encode(jsUndefined());
+ }
+
+ Zig::GlobalObject* global = Zig::jsCast<Zig::GlobalObject*>(globalObject);
+ if (global->onLoadPlugins.virtualModules == nullptr) {
+ global->onLoadPlugins.virtualModules = new BunPlugin::VirtualModuleMap;
+ }
+ auto* virtualModules = global->onLoadPlugins.virtualModules;
+
+ virtualModules->set(moduleId, JSC::Strong<JSC::JSObject> { vm, jsCast<JSC::JSObject*>(functionValue) });
+
+ JSMap* esmRegistry;
+
+ if (auto loaderValue = global->getIfPropertyExists(global, JSC::Identifier::fromString(vm, "Loader"_s))) {
+ if (auto registryValue = loaderValue.getObject()->getIfPropertyExists(global, JSC::Identifier::fromString(vm, "registry"_s))) {
+ esmRegistry = jsCast<JSC::JSMap*>(registryValue);
+ }
+ }
+
+ global->requireMap()->remove(globalObject, moduleIdValue);
+ esmRegistry && esmRegistry->remove(globalObject, moduleIdValue);
+
+ // bool hasBeenRequired = global->requireMap()->has(globalObject, moduleIdValue);
+ // bool hasBeenImported = esmRegistry && esmRegistry->has(globalObject, moduleIdValue);
+ // if (hasBeenRequired || hasBeenImported) {
+ // // callAndReplaceModule(global, moduleIdValue, functionValue, global->requireMap(), esmRegistry, hasBeenRequired, hasBeenImported);
+ // // RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ // }
+
+ return JSValue::encode(jsUndefined());
+}
+
static EncodedJSValue jsFunctionAppendOnResolvePluginBody(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callframe, BunPluginTarget target, BunPlugin::Base& plugin, void* ctx, OnAppendPluginCallback callback)
{
JSC::VM& vm = globalObject->vm();
@@ -143,7 +216,7 @@ static EncodedJSValue jsFunctionAppendOnResolvePluginGlobal(JSC::JSGlobalObject*
{
Zig::GlobalObject* global = Zig::jsCast<Zig::GlobalObject*>(globalObject);
- auto& plugins = global->onResolvePlugins[target];
+ auto& plugins = global->onResolvePlugins;
auto callback = Bun__onDidAppendPlugin;
return jsFunctionAppendOnResolvePluginBody(globalObject, callframe, target, plugins, global->bunVM(), callback);
}
@@ -152,7 +225,7 @@ static EncodedJSValue jsFunctionAppendOnLoadPluginGlobal(JSC::JSGlobalObject* gl
{
Zig::GlobalObject* global = Zig::jsCast<Zig::GlobalObject*>(globalObject);
- auto& plugins = global->onLoadPlugins[target];
+ auto& plugins = global->onLoadPlugins;
auto callback = Bun__onDidAppendPlugin;
return jsFunctionAppendOnLoadPluginBody(globalObject, callframe, target, plugins, global->bunVM(), callback);
}
@@ -182,6 +255,11 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionAppendOnResolvePluginBun, (JSC::JSGlobalObjec
return jsFunctionAppendOnResolvePluginGlobal(globalObject, callframe, BunPluginTargetBun);
}
+JSC_DEFINE_HOST_FUNCTION(jsFunctionAppendVirtualModule, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe))
+{
+ return jsFunctionAppendVirtualModulePluginBody(globalObject, callframe);
+}
+
JSC_DEFINE_HOST_FUNCTION(jsFunctionAppendOnResolvePluginBrowser, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe))
{
return jsFunctionAppendOnResolvePluginGlobal(globalObject, callframe, BunPluginTargetBrowser);
@@ -190,12 +268,12 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionAppendOnResolvePluginBrowser, (JSC::JSGlobalO
extern "C" EncodedJSValue jsFunctionBunPluginClear(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callframe)
{
Zig::GlobalObject* global = reinterpret_cast<Zig::GlobalObject*>(globalObject);
- for (uint8_t i = 0; i < BunPluginTargetMax + 1; i++) {
- global->onLoadPlugins[i].fileNamespace.clear();
- global->onResolvePlugins[i].fileNamespace.clear();
- global->onLoadPlugins[i].groups.clear();
- global->onResolvePlugins[i].namespaces.clear();
- }
+ global->onLoadPlugins.fileNamespace.clear();
+ global->onResolvePlugins.fileNamespace.clear();
+ global->onLoadPlugins.groups.clear();
+ global->onResolvePlugins.namespaces.clear();
+
+ delete global->onLoadPlugins.virtualModules;
return JSValue::encode(jsUndefined());
}
@@ -239,76 +317,37 @@ extern "C" EncodedJSValue setupBunPlugin(JSC::JSGlobalObject* globalObject, JSC:
}
JSFunction* setupFunction = jsCast<JSFunction*>(setupFunctionValue);
- JSObject* builderObject = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 3);
-
- switch (target) {
- case BunPluginTargetNode: {
- builderObject->putDirect(vm, Identifier::fromString(vm, "target"_s), jsString(vm, String("node"_s)), 0);
- builderObject->putDirectNativeFunction(
- vm,
- globalObject,
- JSC::Identifier::fromString(vm, "onLoad"_s),
- 1,
- jsFunctionAppendOnLoadPluginNode,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::DontDelete | 0);
- builderObject->putDirectNativeFunction(
- vm,
- globalObject,
- JSC::Identifier::fromString(vm, "onResolve"_s),
- 1,
- jsFunctionAppendOnResolvePluginNode,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::DontDelete | 0);
- break;
- }
- case BunPluginTargetBun: {
- builderObject->putDirect(vm, Identifier::fromString(vm, "target"_s), jsString(vm, String("bun"_s)), 0);
- builderObject->putDirectNativeFunction(
- vm,
- globalObject,
- JSC::Identifier::fromString(vm, "onLoad"_s),
- 1,
- jsFunctionAppendOnLoadPluginBun,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::DontDelete | 0);
- builderObject->putDirectNativeFunction(
- vm,
- globalObject,
- JSC::Identifier::fromString(vm, "onResolve"_s),
- 1,
- jsFunctionAppendOnResolvePluginBun,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::DontDelete | 0);
- break;
- }
- case BunPluginTargetBrowser: {
- builderObject->putDirect(vm, Identifier::fromString(vm, "target"_s), jsString(vm, String("browser"_s)), 0);
- builderObject->putDirectNativeFunction(
- vm,
- globalObject,
- JSC::Identifier::fromString(vm, "onLoad"_s),
- 1,
- jsFunctionAppendOnLoadPluginBrowser,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::DontDelete | 0);
- builderObject->putDirectNativeFunction(
- vm,
- globalObject,
- JSC::Identifier::fromString(vm, "onResolve"_s),
- 1,
- jsFunctionAppendOnResolvePluginBrowser,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::DontDelete | 0);
- break;
- }
- }
+ JSObject* builderObject = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 4);
+
+ builderObject->putDirect(vm, Identifier::fromString(vm, "target"_s), jsString(vm, String("bun"_s)), 0);
+ builderObject->putDirectNativeFunction(
+ vm,
+ globalObject,
+ JSC::Identifier::fromString(vm, "onLoad"_s),
+ 1,
+ jsFunctionAppendOnLoadPluginBun,
+ ImplementationVisibility::Public,
+ NoIntrinsic,
+ JSC::PropertyAttribute::DontDelete | 0);
+ builderObject->putDirectNativeFunction(
+ vm,
+ globalObject,
+ JSC::Identifier::fromString(vm, "onResolve"_s),
+ 1,
+ jsFunctionAppendOnResolvePluginBun,
+ ImplementationVisibility::Public,
+ NoIntrinsic,
+ JSC::PropertyAttribute::DontDelete | 0);
+
+ builderObject->putDirectNativeFunction(
+ vm,
+ globalObject,
+ JSC::Identifier::fromString(vm, "module"_s),
+ 1,
+ jsFunctionAppendVirtualModule,
+ ImplementationVisibility::Public,
+ NoIntrinsic,
+ JSC::PropertyAttribute::DontDelete | 0);
JSC::MarkedArgumentBuffer args;
args.append(builderObject);
@@ -329,9 +368,7 @@ extern "C" EncodedJSValue setupBunPlugin(JSC::JSGlobalObject* globalObject, JSC:
extern "C" EncodedJSValue jsFunctionBunPlugin(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callframe)
{
Zig::GlobalObject* global = reinterpret_cast<Zig::GlobalObject*>(globalObject);
- BunPluginTarget target = global->defaultBunPluginTarget;
-
- return setupBunPlugin(globalObject, callframe, target);
+ return setupBunPlugin(globalObject, callframe, BunPluginTargetBun);
}
void BunPlugin::Group::append(JSC::VM& vm, JSC::RegExp* filter, JSC::JSFunction* func)
@@ -513,10 +550,60 @@ EncodedJSValue BunPlugin::OnResolve::run(JSC::JSGlobalObject* globalObject, BunS
extern "C" JSC::EncodedJSValue Bun__runOnResolvePlugins(Zig::GlobalObject* globalObject, BunString* namespaceString, BunString* path, BunString* from, BunPluginTarget target)
{
- return globalObject->onResolvePlugins[target].run(globalObject, namespaceString, path, from);
+ return globalObject->onResolvePlugins.run(globalObject, namespaceString, path, from);
}
extern "C" JSC::EncodedJSValue Bun__runOnLoadPlugins(Zig::GlobalObject* globalObject, BunString* namespaceString, BunString* path, BunPluginTarget target)
{
- return globalObject->onLoadPlugins[target].run(globalObject, namespaceString, path);
+ return globalObject->onLoadPlugins.run(globalObject, namespaceString, path);
+}
+
+namespace Bun {
+JSC::JSValue runVirtualModule(Zig::GlobalObject* globalObject, BunString* specifier)
+{
+ auto fallback = [&]() -> JSC::JSValue {
+ return JSValue::decode(Bun__runVirtualModule(globalObject, specifier));
+ };
+
+ if (!globalObject->onLoadPlugins.virtualModules) {
+ return fallback();
+ }
+ auto& virtualModules = *globalObject->onLoadPlugins.virtualModules;
+ WTF::String specifierString = Bun::toWTFString(*specifier);
+ if (auto virtualModuleFn = virtualModules.get(specifierString)) {
+ auto& vm = globalObject->vm();
+ JSC::JSObject* function = virtualModuleFn.get();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ JSC::MarkedArgumentBuffer arguments;
+ JSC::CallData callData = JSC::getCallData(function);
+ RELEASE_ASSERT(callData.type != JSC::CallData::Type::None);
+
+ auto result = call(globalObject, function, callData, JSC::jsUndefined(), arguments);
+ RETURN_IF_EXCEPTION(throwScope, JSC::jsUndefined());
+
+ if (auto* promise = JSC::jsDynamicCast<JSPromise*>(result)) {
+ switch (promise->status(vm)) {
+ case JSPromise::Status::Rejected:
+ case JSPromise::Status::Pending: {
+ return promise;
+ }
+ case JSPromise::Status::Fulfilled: {
+ result = promise->result(vm);
+ break;
+ }
+ }
+ }
+
+ if (!result.isObject()) {
+ JSC::throwTypeError(globalObject, throwScope, "virtual module expects an object returned"_s);
+ return JSC::jsUndefined();
+ }
+
+ return result;
+ }
+
+ return fallback();
}
+
+} \ No newline at end of file
diff --git a/src/bun.js/bindings/BunPlugin.h b/src/bun.js/bindings/BunPlugin.h
index cf37b739b..f4d09883d 100644
--- a/src/bun.js/bindings/BunPlugin.h
+++ b/src/bun.js/bindings/BunPlugin.h
@@ -15,6 +15,8 @@ using namespace JSC;
class BunPlugin {
public:
+ using VirtualModuleMap = WTF::HashMap<String, JSC::Strong<JSC::JSObject>>;
+
// This is a list of pairs of regexps and functions to match against
class Group {
@@ -67,7 +69,15 @@ public:
{
}
- EncodedJSValue run(JSC::JSGlobalObject* globalObject, BunString* namespaceString, BunString* path);
+ VirtualModuleMap* virtualModules = nullptr;
+ JSC::EncodedJSValue run(JSC::JSGlobalObject* globalObject, BunString* namespaceString, BunString* path);
+
+ ~OnLoad()
+ {
+ if (virtualModules) {
+ delete virtualModules;
+ }
+ }
};
class OnResolve final : public Base {
@@ -78,8 +88,14 @@ public:
{
}
- EncodedJSValue run(JSC::JSGlobalObject* globalObject, BunString* namespaceString, BunString* path, BunString* importer);
+ JSC::EncodedJSValue run(JSC::JSGlobalObject* globalObject, BunString* namespaceString, BunString* path, BunString* importer);
};
};
-} // namespace Zig \ No newline at end of file
+class GlobalObject;
+
+} // namespace Zig
+
+namespace Bun {
+JSC::JSValue runVirtualModule(Zig::GlobalObject*, BunString* specifier);
+} \ No newline at end of file
diff --git a/src/bun.js/bindings/BunString.cpp b/src/bun.js/bindings/BunString.cpp
index 416d5d334..99fd02175 100644
--- a/src/bun.js/bindings/BunString.cpp
+++ b/src/bun.js/bindings/BunString.cpp
@@ -3,12 +3,13 @@
#include "JavaScriptCore/JSCJSValueInlines.h"
#include "helpers.h"
#include "simdutf.h"
-#include "wtf/text/ExternalStringImpl.h"
+#include "wtf/Seconds.h"
#include "GCDefferalContext.h"
#include <JavaScriptCore/JSONObject.h>
#include <wtf/text/AtomString.h>
using namespace JSC;
+extern "C" BunString BunString__fromBytes(const char* bytes, size_t length);
extern "C" bool Bun__WTFStringImpl__hasPrefix(const WTF::StringImpl* impl, const char* bytes, size_t length)
{
@@ -74,7 +75,10 @@ JSC::JSValue toJS(JSC::JSGlobalObject* globalObject, BunString bunString, size_t
#endif
return jsSubstring(globalObject, jsUndefined(), Bun::toWTFString(bunString), 0, length);
}
-
+BunString toString(const char* bytes, size_t length)
+{
+ return BunString__fromBytes(bytes, length);
+}
WTF::String toWTFString(const BunString& bunString)
{
if (bunString.tag == BunStringTag::ZigString) {
@@ -190,22 +194,6 @@ BunString toStringRef(WTF::StringImpl* wtfString)
return { BunStringTag::WTFStringImpl, { .wtf = wtfString } };
}
-BunString fromString(WTF::String& wtfString)
-{
- if (wtfString.isEmpty())
- return { BunStringTag::Empty };
-
- return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
-}
-
-BunString fromString(WTF::StringImpl* wtfString)
-{
- if (wtfString->isEmpty())
- return { BunStringTag::Empty };
-
- return { BunStringTag::WTFStringImpl, { .wtf = wtfString } };
-}
-
}
extern "C" JSC::EncodedJSValue BunString__toJS(JSC::JSGlobalObject* globalObject, BunString* bunString)
@@ -252,7 +240,7 @@ extern "C" BunString BunString__fromUTF8(const char* bytes, size_t length)
auto str = WTF::String::fromUTF8ReplacingInvalidSequences(reinterpret_cast<const LChar*>(bytes), length);
str.impl()->ref();
- return Bun::fromString(str);
+ return Bun::toString(str);
}
extern "C" BunString BunString__fromLatin1(const char* bytes, size_t length)
@@ -381,7 +369,17 @@ extern "C" BunString URL__getHref(BunString* input)
return Bun::toStringRef(url.string());
}
-extern "C" BunString URL__getHrefJoin(BunString* baseStr, BunString *relativeStr)
+extern "C" BunString URL__pathFromFileURL(BunString* input)
+{
+ auto&& str = Bun::toWTFString(*input);
+ auto url = WTF::URL(str);
+ if (!url.isValid() || url.isEmpty())
+ return { BunStringTag::Dead };
+
+ return Bun::toStringRef(url.fileSystemPath());
+}
+
+extern "C" BunString URL__getHrefJoin(BunString* baseStr, BunString* relativeStr)
{
auto base = Bun::toWTFString(*baseStr);
auto relative = Bun::toWTFString(*relativeStr);
@@ -455,4 +453,4 @@ extern "C" uint32_t URL__port(WTF::URL* url)
extern "C" BunString URL__pathname(WTF::URL* url)
{
return Bun::toStringRef(url->path().toStringWithoutCopying());
-} \ No newline at end of file
+}
diff --git a/src/bun.js/bindings/CallSite.cpp b/src/bun.js/bindings/CallSite.cpp
index 48fe82275..7667d9606 100644
--- a/src/bun.js/bindings/CallSite.cpp
+++ b/src/bun.js/bindings/CallSite.cpp
@@ -45,7 +45,7 @@ void CallSite::finishCreation(VM& vm, JSC::JSGlobalObject* globalObject, JSCStac
m_function.set(vm, this, JSC::jsUndefined());
m_flags |= static_cast<unsigned int>(Flags::IsStrict);
} else {
- if (callFrame) {
+ if (callFrame && callFrame->thisValue()) {
// We know that we're not in strict mode
m_thisValue.set(vm, this, callFrame->thisValue().toThis(globalObject, JSC::ECMAMode::sloppy()));
} else {
diff --git a/src/bun.js/bindings/CallSitePrototype.h b/src/bun.js/bindings/CallSitePrototype.h
index 000bce2de..8aa543fd3 100644
--- a/src/bun.js/bindings/CallSitePrototype.h
+++ b/src/bun.js/bindings/CallSitePrototype.h
@@ -26,6 +26,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(CallSitePrototype, Base);
return &vm.plainObjectSpace();
}
diff --git a/src/bun.js/bindings/CommonJSModuleRecord.cpp b/src/bun.js/bindings/CommonJSModuleRecord.cpp
index b94386ab3..f47c57559 100644
--- a/src/bun.js/bindings/CommonJSModuleRecord.cpp
+++ b/src/bun.js/bindings/CommonJSModuleRecord.cpp
@@ -8,7 +8,7 @@
* Then, at runtime, we create a JSCommonJSModule object.
*
* On this special object, we override the setter for the "exports" property in
- * a non-observable way (`static bool put ...`)
+ * a non-observable way using a CustomGetterSetter.
*
* When the setter is called, we set the internal "exports" property to the
* value passed in and we also update the requireMap with the new value.
@@ -20,17 +20,13 @@
*
* If an exception occurs, we remove the entry from the requireMap.
*
- * We tried using a CustomGetterSetter instead of overriding `put`, but it led
- * to returning the getter itself
- *
- * How cyclical dependencies are handled
+ * How cyclical dependencies are handled:
*
* Before executing the CommonJS module, we set the exports object in the
* requireMap to an empty object. When the CommonJS module is required again, we
* return the exports object from the requireMap. The values should be in sync
* while the module is being executed, unless module.exports is re-assigned to a
* different value. In that case, it will have a stale value.
- *
*/
#include "root.h"
@@ -71,6 +67,8 @@
#include <JavaScriptCore/JSSourceCode.h>
#include <JavaScriptCore/LazyPropertyInlines.h>
+extern "C" bool Bun__isBunMain(JSC::JSGlobalObject* global, const char* input_ptr, uint64_t input_len);
+
namespace Bun {
using namespace JSC;
@@ -96,28 +94,36 @@ static bool canPerformFastEnumeration(Structure* s)
static bool evaluateCommonJSModuleOnce(JSC::VM& vm, Zig::GlobalObject* globalObject, JSCommonJSModule* moduleObject, JSString* dirname, JSValue filename, WTF::NakedPtr<Exception>& exception)
{
JSC::Structure* thisObjectStructure = globalObject->commonJSFunctionArgumentsStructure();
- JSC::JSObject* thisObject = JSC::constructEmptyObject(
- vm,
- thisObjectStructure);
- thisObject->putDirectOffset(
- vm,
- 0,
- moduleObject);
- thisObject->putDirectOffset(
- vm,
- 1,
- dirname);
+ JSFunction* resolveFunction = JSC::JSBoundFunction::create(vm,
+ globalObject,
+ globalObject->requireResolveFunctionUnbound(),
+ moduleObject->id(),
+ ArgList(), 1, jsString(vm, String("resolve"_s)));
+ JSFunction* requireFunction = JSC::JSBoundFunction::create(vm,
+ globalObject,
+ globalObject->requireFunctionUnbound(),
+ moduleObject,
+ ArgList(), 1, jsString(vm, String("require"_s)));
+ requireFunction->putDirect(vm, vm.propertyNames->resolve, resolveFunction, 0);
+ moduleObject->putDirect(vm, WebCore::clientData(vm)->builtinNames().requirePublicName(), requireFunction, 0);
- thisObject->putDirectOffset(
- vm,
- 2,
- filename);
+ JSC::JSObject* thisObject = JSC::constructEmptyObject(vm, thisObjectStructure);
+ thisObject->putDirectOffset(vm, 0, moduleObject);
+ thisObject->putDirectOffset(vm, 1, requireFunction);
+ thisObject->putDirectOffset(vm, 2, resolveFunction);
+ thisObject->putDirectOffset(vm, 3, dirname);
+ thisObject->putDirectOffset(vm, 4, filename);
moduleObject->hasEvaluated = true;
+ // TODO: try to not use this write barrier. it needs some extensive testing.
+ // there is some possible GC issue where `thisObject` is gc'd before it should be
globalObject->m_BunCommonJSModuleValue.set(vm, globalObject, thisObject);
JSValue empty = JSC::evaluate(globalObject, moduleObject->sourceCode.get()->sourceCode(), thisObject, exception);
+
+ ensureStillAliveHere(thisObject);
+ globalObject->m_BunCommonJSModuleValue.clear();
moduleObject->sourceCode.clear();
return exception.get() == nullptr;
@@ -190,11 +196,25 @@ static const HashTableValue RequireFunctionPrototypeValues[] = {
{ "cache"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsRequireCacheGetter, jsRequireCacheSetter } },
};
+Structure* RequireFunctionPrototype::createStructure(
+ JSC::VM& vm,
+ JSC::JSGlobalObject* globalObject)
+{
+ return Structure::create(vm, globalObject, globalObject->functionPrototype(), TypeInfo(JSFunctionType, StructureFlags), info());
+}
+
+Structure* RequireResolveFunctionPrototype::createStructure(
+ JSC::VM& vm,
+ JSC::JSGlobalObject* globalObject)
+{
+ return Structure::create(vm, globalObject, globalObject->functionPrototype(), TypeInfo(JSFunctionType, StructureFlags), info());
+}
+
RequireResolveFunctionPrototype* RequireResolveFunctionPrototype::create(JSC::JSGlobalObject* globalObject)
{
auto& vm = globalObject->vm();
- auto* structure = RequireResolveFunctionPrototype::createStructure(vm, globalObject, globalObject->functionPrototype());
+ auto* structure = RequireResolveFunctionPrototype::createStructure(vm, globalObject);
RequireResolveFunctionPrototype* prototype = new (NotNull, JSC::allocateCell<RequireResolveFunctionPrototype>(vm)) RequireResolveFunctionPrototype(vm, structure);
prototype->finishCreation(vm);
return prototype;
@@ -205,11 +225,11 @@ RequireFunctionPrototype* RequireFunctionPrototype::create(
{
auto& vm = globalObject->vm();
- auto* structure = RequireFunctionPrototype::createStructure(vm, globalObject, globalObject->functionPrototype());
+ auto* structure = RequireFunctionPrototype::createStructure(vm, globalObject);
RequireFunctionPrototype* prototype = new (NotNull, JSC::allocateCell<RequireFunctionPrototype>(vm)) RequireFunctionPrototype(vm, structure);
prototype->finishCreation(vm);
- prototype->putDirect(vm, JSC::Identifier::fromString(vm, "resolve"_s), static_cast<Zig::GlobalObject*>(globalObject)->requireResolveFunctionUnbound(), PropertyAttribute::Function | 0);
+ prototype->putDirect(vm, JSC::Identifier::fromString(vm, "resolve"_s), jsCast<Zig::GlobalObject*>(globalObject)->requireResolveFunctionUnbound(), 0);
return prototype;
}
@@ -217,7 +237,7 @@ RequireFunctionPrototype* RequireFunctionPrototype::create(
void RequireFunctionPrototype::finishCreation(JSC::VM& vm)
{
Base::finishCreation(vm);
- ASSERT(inherits(vm, info()));
+ ASSERT(inherits(info()));
reifyStaticProperties(vm, info(), RequireFunctionPrototypeValues, *this);
JSC::JSFunction* requireDotMainFunction = JSFunction::create(
@@ -225,11 +245,11 @@ void RequireFunctionPrototype::finishCreation(JSC::VM& vm)
moduleMainCodeGenerator(vm),
globalObject()->globalScope());
- this->putDirect(
- vm,
+ this->putDirectAccessor(
+ globalObject(),
JSC::Identifier::fromString(vm, "main"_s),
- JSC::GetterSetter::create(vm, globalObject(), requireDotMainFunction, JSValue()),
- PropertyAttribute::Builtin | PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | 0);
+ JSC::GetterSetter::create(vm, globalObject(), requireDotMainFunction, requireDotMainFunction),
+ PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | 0);
auto extensions = constructEmptyObject(globalObject());
extensions->putDirect(vm, JSC::Identifier::fromString(vm, ".js"_s), jsBoolean(true), 0);
@@ -265,6 +285,31 @@ JSC_DEFINE_CUSTOM_GETTER(getterPath, (JSC::JSGlobalObject * globalObject, JSC::E
return JSValue::encode(thisObject->m_id.get());
}
+JSC_DEFINE_CUSTOM_GETTER(getterParent, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
+{
+ JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
+ if (UNLIKELY(!thisObject)) {
+ return JSValue::encode(jsUndefined());
+ }
+ auto v = thisObject->m_parent.get();
+ if (v)
+ return JSValue::encode(thisObject->m_parent.get());
+
+ // initialize parent by checking if it is the main module. we do this lazily because most people
+ // dont need `module.parent` and creating commonjs module records is done a ton.
+ auto idValue = thisObject->m_id.get();
+ if (idValue) {
+ auto id = idValue->value(globalObject).utf8();
+ if (Bun__isBunMain(globalObject, id.data(), id.length())) {
+ thisObject->m_parent.set(globalObject->vm(), thisObject, jsNull());
+ return JSValue::encode(jsNull());
+ }
+ }
+
+ thisObject->m_parent.set(globalObject->vm(), thisObject, jsUndefined());
+ return JSValue::encode(jsUndefined());
+}
+
JSC_DEFINE_CUSTOM_SETTER(setterPath,
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
@@ -294,6 +339,16 @@ JSC_DEFINE_CUSTOM_GETTER(getterPaths, (JSC::JSGlobalObject * globalObject, JSC::
return JSValue::encode(thisObject->m_paths.get());
}
+JSC_DEFINE_CUSTOM_GETTER(getterLoaded, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
+{
+ JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
+ if (UNLIKELY(!thisObject)) {
+ return JSValue::encode(jsUndefined());
+ }
+
+ return JSValue::encode(jsBoolean(thisObject->hasEvaluated));
+}
+
JSC_DEFINE_CUSTOM_SETTER(setterPaths,
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
@@ -329,27 +384,100 @@ JSC_DEFINE_CUSTOM_SETTER(setterId,
thisObject->m_id.set(globalObject->vm(), thisObject, JSValue::decode(value).toString(globalObject));
return true;
}
-
-static JSValue createLoaded(VM& vm, JSObject* object)
+JSC_DEFINE_CUSTOM_SETTER(setterParent,
+ (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
+ JSC::EncodedJSValue value, JSC::PropertyName propertyName))
{
- JSCommonJSModule* cjs = jsCast<JSCommonJSModule*>(object);
- return jsBoolean(cjs->hasEvaluated);
+ JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
+ if (!thisObject)
+ return false;
+
+ thisObject->m_parent.set(globalObject->vm(), thisObject, JSValue::decode(value));
+
+ return true;
}
-static JSValue createParent(VM& vm, JSObject* object)
+JSC_DEFINE_CUSTOM_SETTER(setterLoaded,
+ (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
+ JSC::EncodedJSValue value, JSC::PropertyName propertyName))
{
- return jsUndefined();
+ JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
+ if (!thisObject)
+ return false;
+
+ thisObject->hasEvaluated = JSValue::decode(value).toBoolean(globalObject);
+
+ return true;
}
+
static JSValue createChildren(VM& vm, JSObject* object)
{
return constructEmptyArray(object->globalObject(), nullptr, 0);
}
+JSC_DEFINE_HOST_FUNCTION(functionCommonJSModuleRecord_compile, (JSGlobalObject * globalObject, CallFrame* callframe))
+{
+ auto* moduleObject = jsDynamicCast<JSCommonJSModule*>(callframe->thisValue());
+ if (!moduleObject) {
+ return JSValue::encode(jsUndefined());
+ }
+
+ auto& vm = globalObject->vm();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ String sourceString = callframe->argument(0).toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(throwScope, JSValue::encode({}));
+
+ String filenameString = callframe->argument(1).toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(throwScope, JSValue::encode({}));
+
+ String wrappedString = makeString(
+ "(function(exports,require,module,__filename,__dirname){"_s,
+ sourceString,
+ "\n}).call(this.module.exports,this.module.exports,this.require,this.module,this.__filename,this.__dirname)"_s);
+
+ SourceCode sourceCode = makeSource(
+ WTFMove(wrappedString),
+ SourceOrigin(URL::fileURLWithFileSystemPath(filenameString)),
+ JSC::SourceTaintedOrigin::Untainted,
+ filenameString,
+ WTF::TextPosition(),
+ JSC::SourceProviderSourceType::Program);
+ JSSourceCode* jsSourceCode = JSSourceCode::create(vm, WTFMove(sourceCode));
+ moduleObject->sourceCode.set(vm, moduleObject, jsSourceCode);
+
+ auto index = filenameString.reverseFind('/', filenameString.length());
+ String dirnameString;
+ if (index != WTF::notFound) {
+ dirnameString = filenameString.substring(0, index);
+ } else {
+ dirnameString = "/"_s;
+ }
+
+ WTF::NakedPtr<JSC::Exception> exception;
+ evaluateCommonJSModuleOnce(
+ vm,
+ jsCast<Zig::GlobalObject*>(globalObject),
+ moduleObject,
+ jsString(vm, dirnameString),
+ jsString(vm, filenameString),
+ exception);
+
+ if (exception) {
+ throwException(globalObject, throwScope, exception.get());
+ exception.clear();
+ return JSValue::encode({});
+ }
+
+ return JSValue::encode(jsUndefined());
+}
+
static const struct HashTableValue JSCommonJSModulePrototypeTableValues[] = {
- { "children"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createChildren } },
+ { "_compile"_s, static_cast<unsigned>(PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, functionCommonJSModuleRecord_compile, 2 } },
+ { "children"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, createChildren } },
{ "filename"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterFilename, setterFilename } },
{ "id"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterId, setterId } },
- { "loaded"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createLoaded } },
- { "parent"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createParent } },
+ { "loaded"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterLoaded, setterLoaded } },
+ { "parent"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, getterParent, setterParent } },
{ "path"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterPath, setterPath } },
{ "paths"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterPaths, setterPaths } },
};
@@ -367,6 +495,14 @@ public:
return prototype;
}
+ static JSC::Structure* createStructure(
+ JSC::VM& vm,
+ JSC::JSGlobalObject* globalObject,
+ JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
DECLARE_INFO;
JSCommonJSModulePrototype(
@@ -379,36 +515,36 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCommonJSModulePrototype, Base);
return &vm.plainObjectSpace();
}
void finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
Base::finishCreation(vm);
- ASSERT(inherits(vm, info()));
- reifyStaticProperties(vm, JSCommonJSModule::info(), JSCommonJSModulePrototypeTableValues, *this);
-
- this->putDirect(vm, clientData(vm)->builtinNames().requirePublicName(), (static_cast<Zig::GlobalObject*>(globalObject))->requireFunctionUnbound(), PropertyAttribute::Builtin | PropertyAttribute::Function | 0);
+ ASSERT(inherits(info()));
+ reifyStaticProperties(vm, info(), JSCommonJSModulePrototypeTableValues, *this);
this->putDirectNativeFunction(
vm,
globalObject,
clientData(vm)->builtinNames().requirePrivateName(),
2,
- jsFunctionRequireCommonJS, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
+ jsFunctionRequireCommonJS, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete);
}
};
-const JSC::ClassInfo JSCommonJSModulePrototype::s_info = { "Module"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCommonJSModulePrototype) };
+const JSC::ClassInfo JSCommonJSModulePrototype::s_info = { "ModulePrototype"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCommonJSModulePrototype) };
void JSCommonJSModule::finishCreation(JSC::VM& vm, JSC::JSString* id, JSValue filename, JSC::JSString* dirname, JSC::JSSourceCode* sourceCode)
{
Base::finishCreation(vm);
- ASSERT(inherits(vm, info()));
+ ASSERT(inherits(info()));
m_id.set(vm, this, id);
m_filename.set(vm, this, filename);
m_dirname.set(vm, this, dirname);
- this->sourceCode.set(vm, this, sourceCode);
+ if (sourceCode)
+ this->sourceCode.set(vm, this, sourceCode);
}
JSC::Structure* JSCommonJSModule::createStructure(
@@ -439,23 +575,23 @@ JSCommonJSModule* JSCommonJSModule::create(
JSC_DEFINE_HOST_FUNCTION(jsFunctionCreateCommonJSModule, (JSGlobalObject * globalObject, CallFrame* callframe))
{
auto& vm = globalObject->vm();
+ RELEASE_ASSERT(callframe->argumentCount() == 4);
- auto id = callframe->argument(0).toWTFString(globalObject);
+ auto id = callframe->uncheckedArgument(0).toWTFString(globalObject);
+ JSValue object = callframe->uncheckedArgument(1);
+ JSValue hasEvaluated = callframe->uncheckedArgument(2);
+ ASSERT(hasEvaluated.isBoolean());
+ JSValue parent = callframe->uncheckedArgument(3);
- JSValue object = callframe->argument(1);
-
- return JSValue::encode(
- JSCommonJSModule::create(
- jsCast<Zig::GlobalObject*>(globalObject),
- id,
- object, callframe->argument(2).isBoolean() && callframe->argument(2).asBoolean()));
+ return JSValue::encode(JSCommonJSModule::create(jsCast<Zig::GlobalObject*>(globalObject), id, object, hasEvaluated.isTrue(), parent));
}
JSCommonJSModule* JSCommonJSModule::create(
Zig::GlobalObject* globalObject,
const WTF::String& key,
JSValue exportsObject,
- bool hasEvaluated)
+ bool hasEvaluated,
+ JSValue parent)
{
auto& vm = globalObject->vm();
JSString* requireMapKey = JSC::jsStringWithCache(vm, key);
@@ -470,8 +606,14 @@ JSCommonJSModule* JSCommonJSModule::create(
globalObject->CommonJSModuleObjectStructure(),
requireMapKey, requireMapKey, dirname, nullptr);
- out->putDirect(vm, WebCore::clientData(vm)->builtinNames().exportsPublicName(), exportsObject, exportsObject.isCell() && exportsObject.isCallable() ? JSC::PropertyAttribute::Function | 0 : 0);
+ out->putDirect(
+ vm,
+ WebCore::clientData(vm)->builtinNames().exportsPublicName(),
+ exportsObject,
+ 0);
out->hasEvaluated = hasEvaluated;
+ out->m_parent.set(vm, out, parent);
+
return out;
}
@@ -543,7 +685,7 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject,
bool needsToAssignDefault = true;
if (result.isObject()) {
- auto* exports = asObject(result);
+ auto* exports = result.getObject();
auto* structure = exports->structure();
uint32_t size = structure->inlineSize() + structure->outOfLineSize();
@@ -673,33 +815,6 @@ JSValue JSCommonJSModule::id()
return m_id.get();
}
-bool JSCommonJSModule::put(
- JSC::JSCell* cell,
- JSC::JSGlobalObject* globalObject,
- JSC::PropertyName propertyName,
- JSC::JSValue value,
- JSC::PutPropertySlot& slot)
-{
-
- auto& vm = globalObject->vm();
- auto* clientData = WebCore::clientData(vm);
- auto throwScope = DECLARE_THROW_SCOPE(vm);
-
- RELEASE_AND_RETURN(throwScope, Base::put(cell, globalObject, propertyName, value, slot));
-}
-
-template<typename, SubspaceAccess mode> JSC::GCClient::IsoSubspace* JSCommonJSModule::subspaceFor(JSC::VM& vm)
-{
- if constexpr (mode == JSC::SubspaceAccess::Concurrently)
- return nullptr;
- return WebCore::subspaceForImpl<JSCommonJSModule, WebCore::UseCustomHeapCellType::No>(
- vm,
- [](auto& spaces) { return spaces.m_clientSubspaceForCommonJSModuleRecord.get(); },
- [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForCommonJSModuleRecord = std::forward<decltype(space)>(space); },
- [](auto& spaces) { return spaces.m_subspaceForCommonJSModuleRecord.get(); },
- [](auto& spaces, auto&& space) { spaces.m_subspaceForCommonJSModuleRecord = std::forward<decltype(space)>(space); });
-}
-
Structure* createCommonJSModuleStructure(
Zig::GlobalObject* globalObject)
{
@@ -740,7 +855,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo
// Special-case for "process" to just return the process object directly.
if (UNLIKELY(specifier == "process"_s || specifier == "node:process"_s)) {
- jsDynamicCast<JSCommonJSModule*>(callframe->argument(1))->putDirect(vm, builtinNames(vm).exportsPublicName(), globalObject->processObject(), 0);
+ jsCast<JSCommonJSModule*>(callframe->argument(1))->putDirect(vm, builtinNames(vm).exportsPublicName(), globalObject->processObject(), 0);
return JSValue::encode(globalObject->processObject());
}
@@ -752,7 +867,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo
JSValue fetchResult = Bun::fetchCommonJSModule(
globalObject,
- jsDynamicCast<JSCommonJSModule*>(callframe->argument(1)),
+ jsCast<JSCommonJSModule*>(callframe->argument(1)),
specifierValue,
&specifierStr,
&referrerStr);
@@ -763,9 +878,9 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo
void RequireResolveFunctionPrototype::finishCreation(JSC::VM& vm)
{
Base::finishCreation(vm);
- ASSERT(inherits(vm, info()));
+ ASSERT(inherits(info()));
- reifyStaticProperties(vm, RequireResolveFunctionPrototype::info(), RequireResolveFunctionPrototypeValues, *this);
+ reifyStaticProperties(vm, info(), RequireResolveFunctionPrototypeValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
@@ -909,8 +1024,6 @@ JSObject* JSCommonJSModule::createBoundRequireFunction(VM& vm, JSGlobalObject* l
globalObject->CommonJSModuleObjectStructure(),
filename, filename, dirname, nullptr);
- auto& builtinNames = WebCore::builtinNames(vm);
-
JSFunction* requireFunction = JSC::JSBoundFunction::create(vm,
globalObject,
globalObject->requireFunctionUnbound(),
@@ -921,9 +1034,9 @@ JSObject* JSCommonJSModule::createBoundRequireFunction(VM& vm, JSGlobalObject* l
globalObject,
globalObject->requireResolveFunctionUnbound(),
moduleObject,
- ArgList(), 1, jsString(vm, String("require"_s)));
+ ArgList(), 1, jsString(vm, String("resolve"_s)));
- requireFunction->putDirect(vm, builtinNames.resolvePublicName(), resolveFunction, PropertyAttribute::Function | 0);
+ requireFunction->putDirect(vm, vm.propertyNames->resolve, resolveFunction, 0);
return requireFunction;
}
diff --git a/src/bun.js/bindings/CommonJSModuleRecord.h b/src/bun.js/bindings/CommonJSModuleRecord.h
index e38d2e083..37353978e 100644
--- a/src/bun.js/bindings/CommonJSModuleRecord.h
+++ b/src/bun.js/bindings/CommonJSModuleRecord.h
@@ -20,13 +20,14 @@ JSC_DECLARE_HOST_FUNCTION(jsFunctionLoadModule);
class JSCommonJSModule final : public JSC::JSDestructibleObject {
public:
using Base = JSC::JSDestructibleObject;
- static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::OverridesPut;
+ static constexpr unsigned StructureFlags = Base::StructureFlags;
- mutable JSC::WriteBarrier<JSC::JSString> m_id;
- mutable JSC::WriteBarrier<JSC::Unknown> m_filename;
- mutable JSC::WriteBarrier<JSC::JSString> m_dirname;
+ mutable JSC::WriteBarrier<JSString> m_id;
+ mutable JSC::WriteBarrier<Unknown> m_filename;
+ mutable JSC::WriteBarrier<JSString> m_dirname;
mutable JSC::WriteBarrier<Unknown> m_paths;
- mutable JSC::WriteBarrier<JSC::JSSourceCode> sourceCode;
+ mutable JSC::WriteBarrier<Unknown> m_parent;
+ mutable JSC::WriteBarrier<JSSourceCode> sourceCode;
bool ignoreESModuleAnnotation { false };
static void destroy(JSC::JSCell*);
@@ -54,8 +55,7 @@ public:
static JSCommonJSModule* create(
Zig::GlobalObject* globalObject,
const WTF::String& key,
- JSValue exportsObject,
- bool hasEvaluated = false);
+ JSValue exportsObject, bool hasEvaluated, JSValue parent);
static JSCommonJSModule* create(
Zig::GlobalObject* globalObject,
@@ -72,15 +72,21 @@ public:
JSValue exportsObject();
JSValue id();
+ DECLARE_INFO;
DECLARE_VISIT_CHILDREN;
- static bool put(JSC::JSCell* cell, JSC::JSGlobalObject* globalObject,
- JSC::PropertyName propertyName, JSC::JSValue value,
- JSC::PutPropertySlot& slot);
-
- DECLARE_INFO;
template<typename, SubspaceAccess mode>
- static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm);
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return WebCore::subspaceForImpl<JSCommonJSModule, WebCore::UseCustomHeapCellType::No>(
+ vm,
+ [](auto& spaces) { return spaces.m_clientSubspaceForCommonJSModuleRecord.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForCommonJSModuleRecord = std::forward<decltype(space)>(space); },
+ [](auto& spaces) { return spaces.m_subspaceForCommonJSModuleRecord.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_subspaceForCommonJSModuleRecord = std::forward<decltype(space)>(space); });
+ }
bool hasEvaluated = false;
@@ -114,7 +120,9 @@ inline std::optional<JSC::SourceCode> createCommonJSModule(
class RequireResolveFunctionPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
+
static RequireResolveFunctionPrototype* create(JSC::JSGlobalObject* globalObject);
+ static Structure* createStructure(VM& vm, JSC::JSGlobalObject* globalObject);
DECLARE_INFO;
@@ -128,6 +136,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(RequireResolveFunctionPrototype, Base);
return &vm.plainObjectSpace();
}
@@ -137,7 +146,11 @@ public:
class RequireFunctionPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
+
static RequireFunctionPrototype* create(JSC::JSGlobalObject* globalObject);
+ static Structure* createStructure(VM& vm, JSC::JSGlobalObject* globalObject);
+
+ DECLARE_INFO;
RequireFunctionPrototype(
JSC::VM& vm,
@@ -149,12 +162,11 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(RequireFunctionPrototype, Base);
return &vm.plainObjectSpace();
}
- DECLARE_INFO;
-
- void finishCreation(JSC::VM& vm);
+ void finishCreation(JSC::VM&);
};
} // namespace Bun
diff --git a/src/bun.js/bindings/DOMURL.cpp b/src/bun.js/bindings/DOMURL.cpp
index 31381b867..b88161a4d 100644
--- a/src/bun.js/bindings/DOMURL.cpp
+++ b/src/bun.js/bindings/DOMURL.cpp
@@ -36,26 +36,45 @@
namespace WebCore {
+static inline String redact(const String& input)
+{
+ if (input.contains("@"_s))
+ return "<redacted>"_s;
+
+ return makeString('"', input, '"');
+}
+
inline DOMURL::DOMURL(URL&& completeURL, const URL& baseURL)
: m_baseURL(baseURL)
, m_url(WTFMove(completeURL))
{
}
+DOMURL::~DOMURL() = default;
+
+bool DOMURL::canParse(const String& url, const String& base)
+{
+ URL baseURL { base };
+ if (!base.isNull() && !baseURL.isValid())
+ return false;
+ URL completeURL { baseURL, url };
+ return completeURL.isValid();
+}
+
ExceptionOr<Ref<DOMURL>> DOMURL::create(const String& url, const URL& base)
{
ASSERT(base.isValid() || base.isNull());
URL completeURL { base, url };
if (!completeURL.isValid())
- return Exception { TypeError };
+ return Exception { TypeError, makeString(redact(url), " cannot be parsed as a URL.") };
return adoptRef(*new DOMURL(WTFMove(completeURL), base));
}
ExceptionOr<Ref<DOMURL>> DOMURL::create(const String& url, const String& base)
{
- URL baseURL { URL {}, base };
+ URL baseURL { base };
if (!base.isNull() && !baseURL.isValid())
- return Exception { TypeError };
+ return Exception { TypeError, makeString(redact(url), " cannot be parsed as a URL against "_s, redact(base)) };
return create(url, baseURL);
}
@@ -64,13 +83,13 @@ ExceptionOr<Ref<DOMURL>> DOMURL::create(const String& url, const DOMURL& base)
return create(url, base.href());
}
-DOMURL::~DOMURL() = default;
-
ExceptionOr<void> DOMURL::setHref(const String& url)
{
URL completeURL { URL {}, url };
- if (!completeURL.isValid())
- return Exception { TypeError };
+ if (!completeURL.isValid()) {
+
+ return Exception { TypeError, makeString(redact(url), " cannot be parsed as a URL.") };
+ }
m_url = WTFMove(completeURL);
if (m_searchParams)
m_searchParams->updateFromAssociatedURL();
diff --git a/src/bun.js/bindings/DOMURL.h b/src/bun.js/bindings/DOMURL.h
index 0a6210690..0f19510b6 100644
--- a/src/bun.js/bindings/DOMURL.h
+++ b/src/bun.js/bindings/DOMURL.h
@@ -43,6 +43,7 @@ public:
static ExceptionOr<Ref<DOMURL>> create(const String& url, const DOMURL& base);
~DOMURL();
+ static bool canParse(const String& url, const String& base);
const URL& href() const { return m_url; }
ExceptionOr<void> setHref(const String&);
void setQuery(const String&);
diff --git a/src/bun.js/bindings/ErrorStackTrace.cpp b/src/bun.js/bindings/ErrorStackTrace.cpp
index a8c5b65d8..f7013c9c4 100644
--- a/src/bun.js/bindings/ErrorStackTrace.cpp
+++ b/src/bun.js/bindings/ErrorStackTrace.cpp
@@ -12,6 +12,7 @@
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/ErrorInstance.h>
#include <JavaScriptCore/StackVisitor.h>
+#include <JavaScriptCore/NativeCallee.h>
#include <wtf/IterationStatus.h>
using namespace JSC;
@@ -130,8 +131,8 @@ JSCStackFrame::JSCStackFrame(JSC::VM& vm, JSC::StackVisitor& visitor)
: m_vm(vm)
, m_codeBlock(nullptr)
, m_bytecodeIndex(JSC::BytecodeIndex())
- , m_sourceURL(nullptr)
- , m_functionName(nullptr)
+ , m_sourceURL()
+ , m_functionName()
, m_isWasmFrame(false)
, m_sourcePositionsState(SourcePositionsState::NotCalculated)
{
@@ -139,9 +140,18 @@ JSCStackFrame::JSCStackFrame(JSC::VM& vm, JSC::StackVisitor& visitor)
m_callFrame = visitor->callFrame();
// Based on JSC's GetStackTraceFunctor (Interpreter.cpp)
- if (visitor->isWasmFrame()) {
- m_wasmFunctionIndexOrName = visitor->wasmFunctionIndexOrName();
- m_isWasmFrame = true;
+ if (visitor->isNativeCalleeFrame()) {
+ auto* nativeCallee = visitor->callee().asNativeCallee();
+ switch (nativeCallee->category()) {
+ case NativeCallee::Category::Wasm: {
+ m_wasmFunctionIndexOrName = visitor->wasmFunctionIndexOrName();
+ m_isWasmFrame = true;
+ break;
+ }
+ case NativeCallee::Category::InlineCache: {
+ break;
+ }
+ }
} else if (!!visitor->codeBlock() && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) {
m_codeBlock = visitor->codeBlock();
m_bytecodeIndex = visitor->bytecodeIndex();
@@ -153,8 +163,8 @@ JSCStackFrame::JSCStackFrame(JSC::VM& vm, const JSC::StackFrame& frame)
, m_callFrame(nullptr)
, m_codeBlock(nullptr)
, m_bytecodeIndex(JSC::BytecodeIndex())
- , m_sourceURL(nullptr)
- , m_functionName(nullptr)
+ , m_sourceURL()
+ , m_functionName()
, m_isWasmFrame(false)
, m_sourcePositionsState(SourcePositionsState::NotCalculated)
{
@@ -183,7 +193,7 @@ JSC::JSString* JSCStackFrame::sourceURL()
m_sourceURL = retrieveSourceURL();
}
- return m_sourceURL;
+ return jsString(this->m_vm, m_sourceURL);
}
JSC::JSString* JSCStackFrame::functionName()
@@ -192,7 +202,7 @@ JSC::JSString* JSCStackFrame::functionName()
m_functionName = retrieveFunctionName();
}
- return m_functionName;
+ return jsString(this->m_vm, m_functionName);
}
JSC::JSString* JSCStackFrame::typeName()
@@ -201,7 +211,7 @@ JSC::JSString* JSCStackFrame::typeName()
m_typeName = retrieveTypeName();
}
- return m_typeName;
+ return jsString(this->m_vm, m_typeName);
}
JSCStackFrame::SourcePositions* JSCStackFrame::getSourcePositions()
@@ -213,91 +223,61 @@ JSCStackFrame::SourcePositions* JSCStackFrame::getSourcePositions()
return (SourcePositionsState::Calculated == m_sourcePositionsState) ? &m_sourcePositions : nullptr;
}
-ALWAYS_INLINE JSC::JSString* JSCStackFrame::retrieveSourceURL()
+ALWAYS_INLINE String JSCStackFrame::retrieveSourceURL()
{
static auto sourceURLWasmString = MAKE_STATIC_STRING_IMPL("[wasm code]");
static auto sourceURLNativeString = MAKE_STATIC_STRING_IMPL("[native code]");
if (m_isWasmFrame) {
- return jsOwnedString(m_vm, sourceURLWasmString);
+ return String(sourceURLWasmString);
}
if (!m_codeBlock) {
- return jsOwnedString(m_vm, sourceURLNativeString);
+ return String(sourceURLNativeString);
}
- String sourceURL = m_codeBlock->ownerExecutable()->sourceURL();
- return sourceURL.isNull() ? m_vm.smallStrings.emptyString() : JSC::jsString(m_vm, sourceURL);
+ return m_codeBlock->ownerExecutable()->sourceURL();
}
-ALWAYS_INLINE JSC::JSString* JSCStackFrame::retrieveFunctionName()
+ALWAYS_INLINE String JSCStackFrame::retrieveFunctionName()
{
static auto functionNameEvalCodeString = MAKE_STATIC_STRING_IMPL("eval code");
static auto functionNameModuleCodeString = MAKE_STATIC_STRING_IMPL("module code");
static auto functionNameGlobalCodeString = MAKE_STATIC_STRING_IMPL("global code");
if (m_isWasmFrame) {
- return jsString(m_vm, JSC::Wasm::makeString(m_wasmFunctionIndexOrName));
+ return JSC::Wasm::makeString(m_wasmFunctionIndexOrName);
}
if (m_codeBlock) {
switch (m_codeBlock->codeType()) {
case JSC::EvalCode:
- return JSC::jsOwnedString(m_vm, functionNameEvalCodeString);
+ return String(functionNameEvalCodeString);
case JSC::ModuleCode:
- return JSC::jsOwnedString(m_vm, functionNameModuleCodeString);
+ return String(functionNameModuleCodeString);
case JSC::FunctionCode:
break;
case JSC::GlobalCode:
- return JSC::jsOwnedString(m_vm, functionNameGlobalCodeString);
+ return String(functionNameGlobalCodeString);
default:
ASSERT_NOT_REACHED();
}
}
- if (!m_callee || !m_callee->isObject()) {
- return m_vm.smallStrings.emptyString();
- }
-
- JSC::JSObject* calleeAsObject = JSC::jsCast<JSC::JSObject*>(m_callee);
-
- // First, try the "displayName" property
- JSC::JSValue displayName = calleeAsObject->getDirect(m_vm, m_vm.propertyNames->displayName);
- if (displayName && isJSString(displayName)) {
- return JSC::asString(displayName);
- }
-
- // Our addition - if there's no "dispalyName" property, try the "name" property
- JSC::JSValue name = calleeAsObject->getDirect(m_vm, m_vm.propertyNames->name);
- if (name && isJSString(name)) {
- return JSC::asString(name);
- }
-
- /* For functions (either JSFunction or InternalFunction), fallback to their "native" name property.
- * Based on JSC::getCalculatedDisplayName, "inlining" the
- * JSFunction::calculatedDisplayName\InternalFunction::calculatedDisplayName calls */
- if (JSC::JSFunction* function = JSC::jsDynamicCast<JSC::JSFunction*>(calleeAsObject)) {
- // Based on JSC::JSFunction::calculatedDisplayName, skipping the "displayName" property check
- WTF::String actualName = function->name(m_vm);
- if (!actualName.isEmpty() || function->isHostOrBuiltinFunction()) {
- return JSC::jsString(m_vm, actualName);
- }
-
- return JSC::jsString(m_vm, function->jsExecutable()->name().string());
- }
- if (JSC::InternalFunction* function = JSC::jsDynamicCast<JSC::InternalFunction*>(calleeAsObject)) {
- // Based on JSC::InternalFunction::calculatedDisplayName, skipping the "displayName" property check
- return JSC::jsString(m_vm, function->name());
+ String name;
+ if (m_callee) {
+ if (m_callee->isObject())
+ name = getCalculatedDisplayName(m_vm, jsCast<JSObject*>(m_callee)).impl();
}
- return m_vm.smallStrings.emptyString();
+ return name.isNull() ? emptyString() : name;
}
-ALWAYS_INLINE JSC::JSString* JSCStackFrame::retrieveTypeName()
+ALWAYS_INLINE String JSCStackFrame::retrieveTypeName()
{
JSC::JSObject* calleeObject = JSC::jsCast<JSC::JSObject*>(m_callee);
// return JSC::jsTypeStringForValue(m_globalObjectcalleeObject->toThis()
- return jsString(m_vm, makeString(calleeObject->className()));
+ return calleeObject->className();
}
// General flow here is based on JSC's appendSourceToError (ErrorInstance.cpp)
diff --git a/src/bun.js/bindings/ErrorStackTrace.h b/src/bun.js/bindings/ErrorStackTrace.h
index 1284376a4..ac40eaf4b 100644
--- a/src/bun.js/bindings/ErrorStackTrace.h
+++ b/src/bun.js/bindings/ErrorStackTrace.h
@@ -61,9 +61,9 @@ private:
JSC::BytecodeIndex m_bytecodeIndex;
// Lazy-initialized
- JSC::JSString* m_sourceURL;
- JSC::JSString* m_functionName;
- JSC::JSString* m_typeName;
+ WTF::String m_sourceURL;
+ WTF::String m_functionName;
+ WTF::String m_typeName;
// m_wasmFunctionIndexOrName has meaning only when m_isWasmFrame is set
JSC::Wasm::IndexOrName m_wasmFunctionIndexOrName;
@@ -105,7 +105,7 @@ public:
bool isConstructor() const { return m_codeBlock && (JSC::CodeForConstruct == m_codeBlock->specializationKind()); }
private:
- ALWAYS_INLINE JSC::JSString* retrieveSourceURL();
+ ALWAYS_INLINE String retrieveSourceURL();
/* Regarding real functions (not eval\module\global code), both v8 and JSC seem to follow
* the same logic, which is to first try the function's "display name", and if it's not defined,
@@ -119,9 +119,9 @@ private:
* and just try to use the "name" property when needed, so our lookup will be:
* "display name" property -> "name" property -> JSFunction\InternalFunction "name" methods.
*/
- ALWAYS_INLINE JSC::JSString* retrieveFunctionName();
+ ALWAYS_INLINE String retrieveFunctionName();
- ALWAYS_INLINE JSC::JSString* retrieveTypeName();
+ ALWAYS_INLINE String retrieveTypeName();
bool calculateSourcePositions();
};
diff --git a/src/bun.js/bindings/FFI.zig b/src/bun.js/bindings/FFI.zig
index 9d16bd78e..da98438ba 100644
--- a/src/bun.js/bindings/FFI.zig
+++ b/src/bun.js/bindings/FFI.zig
@@ -20,8 +20,9 @@ pub const EncodedJSValue = union_EncodedJSValue;
pub export var ValueUndefined: EncodedJSValue = EncodedJSValue{
.asInt64 = @as(i64, @bitCast(@as(c_longlong, @as(c_int, 2) | @as(c_int, 8)))),
};
+pub const TrueI64 = @as(i64, @bitCast(@as(c_longlong, (@as(c_int, 2) | @as(c_int, 4)) | @as(c_int, 1))));
pub export var ValueTrue: EncodedJSValue = EncodedJSValue{
- .asInt64 = @as(i64, @bitCast(@as(c_longlong, (@as(c_int, 2) | @as(c_int, 4)) | @as(c_int, 1)))),
+ .asInt64 = TrueI64,
};
pub const JSContext = ?*anyopaque;
pub inline fn JSVALUE_IS_CELL(arg_val: EncodedJSValue) bool {
diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp
index 4160102a5..199a13392 100644
--- a/src/bun.js/bindings/ImportMetaObject.cpp
+++ b/src/bun.js/bindings/ImportMetaObject.cpp
@@ -64,6 +64,12 @@ static EncodedJSValue functionRequireResolve(JSC::JSGlobalObject* globalObject,
JSC::JSValue moduleName = callFrame->argument(0);
auto doIt = [&](const WTF::String& fromStr) -> JSC::EncodedJSValue {
+ if (auto* virtualModules = jsCast<Zig::GlobalObject*>(globalObject)->onLoadPlugins.virtualModules) {
+ if (virtualModules->contains(fromStr)) {
+ return JSC::JSValue::encode(jsString(vm, fromStr));
+ }
+ }
+
BunString from = Bun::toString(fromStr);
auto result = Bun__resolveSyncWithSource(globalObject, JSC::JSValue::encode(moduleName), &from, false);
@@ -160,6 +166,14 @@ extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* g
JSC__JSValue from;
bool isESM = true;
+ if (auto* virtualModules = jsCast<Zig::GlobalObject*>(globalObject)->onLoadPlugins.virtualModules) {
+ if (moduleName.isString()) {
+ if (virtualModules->contains(moduleName.toWTFString(globalObject))) {
+ return JSC::JSValue::encode(moduleName);
+ }
+ }
+ }
+
if (callFrame->argumentCount() > 1) {
if (callFrame->argumentCount() > 2) {
@@ -226,6 +240,7 @@ extern "C" EncodedJSValue functionImportMeta__resolveSyncPrivate(JSC::JSGlobalOb
{
JSC::VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ auto* global = jsDynamicCast<Zig::GlobalObject*>(globalObject);
JSC::JSValue moduleName = callFrame->argument(0);
JSValue from = callFrame->argument(1);
@@ -239,12 +254,19 @@ extern "C" EncodedJSValue functionImportMeta__resolveSyncPrivate(JSC::JSGlobalOb
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
+ if (auto* virtualModules = global->onLoadPlugins.virtualModules) {
+ if (moduleName.isString()) {
+ if (virtualModules->contains(moduleName.toWTFString(globalObject))) {
+ return JSC::JSValue::encode(moduleName);
+ }
+ }
+ }
+
if (!isESM) {
- auto* global = jsDynamicCast<Zig::GlobalObject*>(globalObject);
if (LIKELY(global)) {
auto overrideHandler = global->m_nodeModuleOverriddenResolveFilename.get();
if (UNLIKELY(overrideHandler)) {
- ASSERT(overrideHandler.isCallable(globalObject));
+ ASSERT(overrideHandler->isCallable());
MarkedArgumentBuffer args;
args.append(moduleName);
args.append(from);
@@ -289,6 +311,14 @@ JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve,
JSC__JSValue from;
+ if (auto* virtualModules = jsCast<Zig::GlobalObject*>(globalObject)->onLoadPlugins.virtualModules) {
+ if (moduleName.isString()) {
+ if (virtualModules->contains(moduleName.toWTFString(globalObject))) {
+ return JSC::JSValue::encode(moduleName);
+ }
+ }
+ }
+
if (callFrame->argumentCount() > 1 && callFrame->argument(1).isString()) {
from = JSC::JSValue::encode(callFrame->argument(1));
} else {
@@ -404,6 +434,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(ImportMetaObjectPrototype, Base);
return &vm.plainObjectSpace();
}
@@ -417,11 +448,13 @@ public:
reifyStaticProperties(vm, ImportMetaObject::info(), ImportMetaObjectPrototypeValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
- this->putDirect(
- vm,
+ auto mainGetter = JSFunction::create(vm, importMetaObjectMainCodeGenerator(vm), globalObject);
+
+ this->putDirectAccessor(
+ this->globalObject(),
builtinNames.mainPublicName(),
- GetterSetter::create(vm, globalObject, JSFunction::create(vm, importMetaObjectMainCodeGenerator(vm), globalObject), nullptr),
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin | 0);
+ GetterSetter::create(vm, globalObject, mainGetter, mainGetter),
+ JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | 0);
}
ImportMetaObjectPrototype(JSC::VM& vm, JSC::Structure* structure)
@@ -433,7 +466,7 @@ public:
const ClassInfo ImportMetaObjectPrototype::s_info = {
"ImportMeta"_s,
- Base::info(), nullptr, nullptr, CREATE_METHOD_TABLE(ImportMetaObjectPrototype)
+ &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ImportMetaObjectPrototype)
};
JSC::Structure* ImportMetaObject::createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
diff --git a/src/bun.js/bindings/InternalModuleRegistry.cpp b/src/bun.js/bindings/InternalModuleRegistry.cpp
index 8dbf42a02..03f946192 100644
--- a/src/bun.js/bindings/InternalModuleRegistry.cpp
+++ b/src/bun.js/bindings/InternalModuleRegistry.cpp
@@ -33,7 +33,9 @@ static void maybeAddCodeCoverage(JSC::VM& vm, const JSC::SourceCode& code)
#define INTERNAL_MODULE_REGISTRY_GENERATE_(globalObject, vm, SOURCE, moduleName, urlString) \
auto throwScope = DECLARE_THROW_SCOPE(vm); \
auto&& origin = SourceOrigin(WTF::URL(urlString)); \
- SourceCode source = JSC::makeSource(SOURCE, origin, moduleName); \
+ SourceCode source = JSC::makeSource(SOURCE, origin, \
+ JSC::SourceTaintedOrigin::Untainted, \
+ moduleName); \
maybeAddCodeCoverage(vm, source); \
JSFunction* func \
= JSFunction::create( \
@@ -118,16 +120,23 @@ DEFINE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE, InternalModuleRegistry);
InternalModuleRegistry* InternalModuleRegistry::create(VM& vm, Structure* structure)
{
InternalModuleRegistry* registry = new (NotNull, allocateCell<InternalModuleRegistry>(vm)) InternalModuleRegistry(vm, structure);
+ registry->finishCreation(vm);
+ return registry;
+}
+
+void InternalModuleRegistry::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+
for (uint8_t i = 0; i < BUN_INTERNAL_MODULE_COUNT; i++) {
- registry->internalField(static_cast<Field>(i))
- .set(vm, registry, jsUndefined());
+ this->internalField(static_cast<Field>(i)).set(vm, this, jsUndefined());
}
- return registry;
}
Structure* InternalModuleRegistry::createStructure(VM& vm, JSGlobalObject* globalObject)
{
- return Structure::create(vm, globalObject, jsNull(), TypeInfo(InternalFieldTupleType, StructureFlags), info(), 0, 48);
+ return Structure::create(vm, globalObject, jsNull(), TypeInfo(InternalFieldTupleType, StructureFlags), info(), 0, 0);
}
JSValue InternalModuleRegistry::requireId(JSGlobalObject* globalObject, VM& vm, Field id)
@@ -150,7 +159,7 @@ JSC_DEFINE_HOST_FUNCTION(InternalModuleRegistry::jsCreateInternalModuleById, (JS
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto id = callframe->argument(0).toUInt32(lexicalGlobalObject);
- auto registry = static_cast<Zig::GlobalObject*>(lexicalGlobalObject)->internalModuleRegistry();
+ auto registry = jsCast<Zig::GlobalObject*>(lexicalGlobalObject)->internalModuleRegistry();
auto mod = registry->createInternalModuleById(lexicalGlobalObject, vm, static_cast<Field>(id));
RETURN_IF_EXCEPTION(throwScope, {});
registry->internalField(static_cast<Field>(id)).set(vm, registry, mod);
diff --git a/src/bun.js/bindings/InternalModuleRegistry.h b/src/bun.js/bindings/InternalModuleRegistry.h
index d14625e00..0944a382a 100644
--- a/src/bun.js/bindings/InternalModuleRegistry.h
+++ b/src/bun.js/bindings/InternalModuleRegistry.h
@@ -16,19 +16,21 @@ using namespace JSC;
// - some are written in JS (src/js, there is a readme file that explain those files more.
// - others are native code (src/bun.js/modules), see _NativeModule.h in there.
class InternalModuleRegistry : public JSInternalFieldObjectImpl<BUN_INTERNAL_MODULE_COUNT> {
-protected:
- JS_EXPORT_PRIVATE InternalModuleRegistry(VM&, Structure*);
- DECLARE_DEFAULT_FINISH_CREATION;
- DECLARE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE);
-
public:
using Base = JSInternalFieldObjectImpl<BUN_INTERNAL_MODULE_COUNT>;
DECLARE_EXPORT_INFO;
+ static size_t allocationSize(Checked<size_t> inlineCapacity)
+ {
+ ASSERT_UNUSED(inlineCapacity, inlineCapacity == 0U);
+ return sizeof(InternalModuleRegistry);
+ }
+
enum Field : uint8_t {
#include "../../../src/js/out/InternalModuleRegistry+enum.h"
};
+
const WriteBarrier<Unknown>& internalField(Field field) const { return Base::internalField(static_cast<uint32_t>(field)); }
WriteBarrier<Unknown>& internalField(Field field) { return Base::internalField(static_cast<uint32_t>(field)); }
@@ -52,8 +54,11 @@ public:
static JSC_DECLARE_HOST_FUNCTION(jsCreateInternalModuleById);
-protected:
+private:
+ JS_EXPORT_PRIVATE InternalModuleRegistry(VM&, Structure*);
+ DECLARE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE);
JSValue createInternalModuleById(JSGlobalObject* globalObject, VM& vm, Field id);
+ void finishCreation(VM&);
};
} // namespace Bun
diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp
index 9227e47b3..524007f86 100644
--- a/src/bun.js/bindings/JSBuffer.cpp
+++ b/src/bun.js/bindings/JSBuffer.cpp
@@ -819,6 +819,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSBufferPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -865,28 +866,49 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_compareBody(JSC::JSG
size_t sourceEndInit = castedThis->byteLength();
size_t sourceEnd = sourceEndInit;
+ JSValue targetStartValue = jsUndefined();
+ JSValue targetEndValue = jsUndefined();
+ JSValue sourceStartValue = jsUndefined();
+ JSValue sourceEndValue = jsUndefined();
+
switch (callFrame->argumentCount()) {
default:
- sourceEnd = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(4));
- RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ sourceEndValue = callFrame->uncheckedArgument(4);
FALLTHROUGH;
case 4:
- sourceStart = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(3));
- RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ sourceStartValue = callFrame->uncheckedArgument(3);
FALLTHROUGH;
case 3:
- targetEnd = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(2));
- RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ targetEndValue = callFrame->uncheckedArgument(2);
FALLTHROUGH;
case 2:
- targetStart = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(1));
- RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ targetStartValue = callFrame->uncheckedArgument(1);
break;
case 1:
case 0:
break;
}
+ if (!targetStartValue.isUndefined()) {
+ targetStart = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(1));
+ RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ }
+
+ if (!targetEndValue.isUndefined()) {
+ targetEnd = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(2));
+ RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ }
+
+ if (!sourceStartValue.isUndefined()) {
+ sourceStart = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(3));
+ RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ }
+
+ if (!sourceEndValue.isUndefined()) {
+ sourceEnd = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(4));
+ RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ }
+
targetStart = std::min(targetStart, std::min(targetEnd, targetEndInit));
sourceStart = std::min(sourceStart, std::min(sourceEnd, sourceEndInit));
@@ -931,24 +953,40 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_copyBody(JSC::JSGlob
size_t sourceEndInit = castedThis->byteLength();
size_t sourceEnd = sourceEndInit;
+ JSValue targetStartValue = jsUndefined();
+ JSValue sourceStartValue = jsUndefined();
+ JSValue sourceEndValue = jsUndefined();
+
switch (callFrame->argumentCount()) {
default:
- sourceEnd = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(3));
- RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ sourceEndValue = callFrame->uncheckedArgument(3);
FALLTHROUGH;
case 3:
- sourceStart = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(2));
- RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ sourceStartValue = callFrame->uncheckedArgument(2);
FALLTHROUGH;
case 2:
- targetStart = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(1));
- RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ targetStartValue = callFrame->uncheckedArgument(1);
break;
case 1:
case 0:
break;
}
+ if (!targetStartValue.isUndefined()) {
+ targetStart = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(1));
+ RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ }
+
+ if (!sourceStartValue.isUndefined()) {
+ sourceStart = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(2));
+ RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ }
+
+ if (!sourceEndValue.isUndefined()) {
+ sourceEnd = parseIndex(lexicalGlobalObject, throwScope, callFrame->uncheckedArgument(3));
+ RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined()));
+ }
+
targetStart = std::min(targetStart, targetEnd);
sourceEnd = std::min(sourceEnd, sourceEndInit);
sourceStart = std::min(sourceStart, sourceEnd);
@@ -1614,7 +1652,7 @@ JSC_DEFINE_HOST_FUNCTION(jsBufferConstructorFunction_toBuffer, (JSGlobalObject *
class JSBufferConstructor final : public JSC::InternalFunction {
public:
using Base = JSC::InternalFunction;
- static constexpr unsigned StructureFlags = Base::StructureFlags;
+ static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
~JSBufferConstructor() = default;
@@ -1700,8 +1738,6 @@ JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeSlowWithoutTypeChecks, JS
JSC_ANNOTATE_HOST_FUNCTION(JSBufferConstructorConstruct, JSBufferConstructor::construct);
-const ClassInfo JSBufferConstructor::s_info = { "Buffer"_s, nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSBufferConstructor) };
-
class JSBuffer : public JSC::JSNonFinalObject {
DECLARE_INFO;
@@ -1790,8 +1826,8 @@ static const HashTableValue JSBufferPrototypeTableValues[]
{ "lastIndexOf"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferPrototypeFunction_lastIndexOf, 3 } },
{ "latin1Slice"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferPrototypeLatin1SliceCodeGenerator, 2 } },
{ "latin1Write"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferPrototypeLatin1WriteCodeGenerator, 1 } },
- { "offset"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferPrototypeOffsetCodeGenerator, 0 } },
- { "parent"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferPrototypeParentCodeGenerator, 0 } },
+ { "offset"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinAccessorType, jsBufferPrototypeOffsetCodeGenerator, 0 } },
+ { "parent"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinAccessorType, jsBufferPrototypeParentCodeGenerator, 0 } },
{ "readBigInt64"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferPrototypeReadBigInt64LECodeGenerator, 1 } },
{ "readBigInt64BE"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferPrototypeReadBigInt64BECodeGenerator, 1 } },
{ "readBigInt64LE"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferPrototypeReadBigInt64LECodeGenerator, 1 } },
@@ -1899,8 +1935,7 @@ const ClassInfo JSBufferPrototype::s_info = {
// We must use the same naming convention to match Node
// Some packages (like MongoDB's official Node.js client) rely on this behavior.
"Uint8Array"_s,
-
- nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSBufferPrototype)
+ &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBufferPrototype)
};
static const JSC::DOMJIT::Signature DOMJITSignaturejsBufferConstructorAlloc(jsBufferConstructorAllocWithoutTypeChecks,
@@ -1917,27 +1952,27 @@ static const JSC::DOMJIT::Signature DOMJITSignaturejsBufferConstructorAllocUnsaf
JSC::DOMJIT::Effect::forWriteKinds(JSC::DFG::AbstractHeapKind::Heap),
JSC::SpecUint8Array, JSC::SpecInt32Only);
-/* Hash table for constructor */
-static const HashTableValue JSBufferConstructorTableValues[] = {
- // { "alloc"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction), NoIntrinsic, { HashTableValue::DOMJITFunctionType, jsBufferConstructorFunction_alloc, &DOMJITSignaturejsBufferConstructorAlloc } },
- { "alloc"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_alloc, 1 } },
- // { "allocUnsafe"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction), NoIntrinsic, { HashTableValue::DOMJITFunctionType, jsBufferConstructorFunction_allocUnsafe, &DOMJITSignaturejsBufferConstructorAllocUnsafe } },
- { "allocUnsafe"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafe, 1 } },
- // { "allocUnsafeSlow"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction), NoIntrinsic, { HashTableValue::DOMJITFunctionType, jsBufferConstructorFunction_allocUnsafeSlow, &DOMJITSignaturejsBufferConstructorAllocUnsafeSlow } },
- { "allocUnsafeSlow"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafeSlow, 1 } },
- { "byteLength"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_byteLength, 2 } },
- { "compare"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_compare, 2 } },
- { "concat"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_concat, 2 } },
- { "from"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferConstructorFromCodeGenerator, 1 } },
- { "isBuffer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferConstructorIsBufferCodeGenerator, 1 } },
- { "toBuffer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_toBuffer, 1 } },
- { "isEncoding"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_isEncoding, 1 } },
-};
+/* Source for JSBuffer.lut.h
+@begin jsBufferConstructorTable
+ alloc jsBufferConstructorFunction_alloc Constructable|Function 1
+ allocUnsafe jsBufferConstructorFunction_allocUnsafe Constructable|Function 1
+ allocUnsafeSlow jsBufferConstructorFunction_allocUnsafeSlow Constructable|Function 1
+ byteLength jsBufferConstructorFunction_byteLength Function 2
+ compare jsBufferConstructorFunction_compare Function 2
+ concat jsBufferConstructorFunction_concat Function 2
+ from JSBuiltin Builtin|Function 1
+ isBuffer JSBuiltin Builtin|Function 1
+ toBuffer jsBufferConstructorFunction_toBuffer Function 1
+ isEncoding jsBufferConstructorFunction_isEncoding Function 1
+@end
+*/
+#include "JSBuffer.lut.h"
+
+const ClassInfo JSBufferConstructor::s_info = { "Buffer"_s, &Base::s_info, &jsBufferConstructorTable, nullptr, CREATE_METHOD_TABLE(JSBufferConstructor) };
void JSBufferConstructor::finishCreation(VM& vm, JSGlobalObject* globalObject, JSC::JSObject* prototype)
{
Base::finishCreation(vm, 3, "Buffer"_s, PropertyAdditionMode::WithoutStructureTransition);
- reifyStaticProperties(vm, JSBufferConstructor::info(), JSBufferConstructorTableValues, *this);
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
prototype->putDirect(vm, vm.propertyNames->speciesSymbol, this, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
}
diff --git a/src/bun.js/bindings/JSBuffer.lut.h b/src/bun.js/bindings/JSBuffer.lut.h
new file mode 100644
index 000000000..35a3acea9
--- /dev/null
+++ b/src/bun.js/bindings/JSBuffer.lut.h
@@ -0,0 +1,52 @@
+// File generated via `make static-hash-table` / `make cpp`
+static const struct CompactHashIndex jsBufferConstructorTableIndex[33] = {
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 1, 32 },
+ { 0, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 8, -1 },
+ { 3, -1 },
+ { -1, -1 },
+ { 5, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 9, -1 },
+ { -1, -1 },
+ { 4, -1 },
+ { -1, -1 },
+ { 6, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 2, -1 },
+ { -1, -1 },
+ { 7, -1 },
+};
+
+static const struct HashTableValue jsBufferConstructorTableValues[10] = {
+ { "alloc"_s, static_cast<unsigned>(PropertyAttribute::Constructable|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_alloc, 1 } },
+ { "allocUnsafe"_s, static_cast<unsigned>(PropertyAttribute::Constructable|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafe, 1 } },
+ { "allocUnsafeSlow"_s, static_cast<unsigned>(PropertyAttribute::Constructable|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafeSlow, 1 } },
+ { "byteLength"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_byteLength, 2 } },
+ { "compare"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_compare, 2 } },
+ { "concat"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_concat, 2 } },
+ { "from"_s, ((static_cast<unsigned>(PropertyAttribute::Builtin|PropertyAttribute::Function)) & ~PropertyAttribute::Function) | PropertyAttribute::Builtin, NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferConstructorFromCodeGenerator, 1 } },
+ { "isBuffer"_s, ((static_cast<unsigned>(PropertyAttribute::Builtin|PropertyAttribute::Function)) & ~PropertyAttribute::Function) | PropertyAttribute::Builtin, NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferConstructorIsBufferCodeGenerator, 1 } },
+ { "toBuffer"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_toBuffer, 1 } },
+ { "isEncoding"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_isEncoding, 1 } },
+};
+
+static const struct HashTable jsBufferConstructorTable =
+ { 10, 31, false, nullptr, jsBufferConstructorTableValues, jsBufferConstructorTableIndex };
diff --git a/src/bun.js/bindings/JSBufferList.cpp b/src/bun.js/bindings/JSBufferList.cpp
index a8cefa710..0db5527d7 100644
--- a/src/bun.js/bindings/JSBufferList.cpp
+++ b/src/bun.js/bindings/JSBufferList.cpp
@@ -118,8 +118,7 @@ JSC::JSValue JSBufferList::_getString(JSC::VM& vm, JSC::JSGlobalObject* lexicalG
RELEASE_AND_RETURN(throwScope, JSC::jsEmptyString(vm));
}
- auto iter = m_deque.begin();
- JSC::JSString* str = JSC::jsDynamicCast<JSC::JSString*>(iter->get());
+ JSC::JSString* str = JSC::jsDynamicCast<JSC::JSString*>(m_deque.first().get());
if (UNLIKELY(!str)) {
return throwTypeError(lexicalGlobalObject, throwScope, "_getString can only be called when all buffers are string"_s);
}
@@ -132,13 +131,14 @@ JSC::JSValue JSBufferList::_getString(JSC::VM& vm, JSC::JSGlobalObject* lexicalG
}
if (n < len) {
JSString* firstHalf = JSC::jsSubstring(lexicalGlobalObject, str, 0, n);
- iter->set(vm, this, JSC::jsSubstring(lexicalGlobalObject, str, n, len - n));
+ m_deque.first().set(vm, this, JSC::jsSubstring(lexicalGlobalObject, str, n, len - n));
RELEASE_AND_RETURN(throwScope, firstHalf);
}
JSRopeString::RopeBuilder<RecordOverflow> ropeBuilder(vm);
- for (const auto end = m_deque.end(); iter != end; ++iter) {
- JSC::JSString* str = JSC::jsDynamicCast<JSC::JSString*>(iter->get());
+ while (m_deque.size() > 0) {
+ auto& element = m_deque.first();
+ JSC::JSString* str = JSC::jsDynamicCast<JSC::JSString*>(element.get());
if (UNLIKELY(!str)) {
return throwTypeError(lexicalGlobalObject, throwScope, "_getString can only be called when all buffers are string"_s);
}
@@ -147,7 +147,7 @@ JSC::JSValue JSBufferList::_getString(JSC::VM& vm, JSC::JSGlobalObject* lexicalG
JSString* firstHalf = JSC::jsSubstring(lexicalGlobalObject, str, 0, n);
if (!ropeBuilder.append(firstHalf))
return throwOutOfMemoryError(lexicalGlobalObject, throwScope);
- iter->set(vm, this, JSC::jsSubstring(lexicalGlobalObject, str, n, len - n));
+ element.set(vm, this, JSC::jsSubstring(lexicalGlobalObject, str, n, len - n));
break;
}
if (!ropeBuilder.append(str))
@@ -169,8 +169,7 @@ JSC::JSValue JSBufferList::_getBuffer(JSC::VM& vm, JSC::JSGlobalObject* lexicalG
RELEASE_AND_RETURN(throwScope, JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, 0));
}
- auto iter = m_deque.begin();
- JSC::JSUint8Array* array = JSC::jsDynamicCast<JSC::JSUint8Array*>(iter->get());
+ JSC::JSUint8Array* array = JSC::jsDynamicCast<JSC::JSUint8Array*>(m_deque.first().get());
if (UNLIKELY(!array)) {
return throwTypeError(lexicalGlobalObject, throwScope, "_getBuffer can only be called when all buffers are Uint8Array"_s);
}
@@ -185,7 +184,7 @@ JSC::JSValue JSBufferList::_getBuffer(JSC::VM& vm, JSC::JSGlobalObject* lexicalG
auto buffer = array->possiblySharedBuffer();
JSC::JSUint8Array* retArray = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, buffer, 0, n);
JSC::JSUint8Array* newArray = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, buffer, n, len - n);
- iter->set(vm, this, newArray);
+ m_deque.first().set(vm, this, newArray);
RELEASE_AND_RETURN(throwScope, retArray);
}
@@ -196,8 +195,9 @@ JSC::JSValue JSBufferList::_getBuffer(JSC::VM& vm, JSC::JSGlobalObject* lexicalG
}
JSC::JSUint8Array* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(arrayBuffer), 0, n);
size_t offset = 0;
- for (const auto end = m_deque.end(); iter != end; ++iter) {
- JSC::JSUint8Array* array = JSC::jsDynamicCast<JSC::JSUint8Array*>(iter->get());
+ while (m_deque.size() > 0) {
+ auto& element = m_deque.first();
+ JSC::JSUint8Array* array = JSC::jsDynamicCast<JSC::JSUint8Array*>(element.get());
if (UNLIKELY(!array)) {
return throwTypeError(lexicalGlobalObject, throwScope, "_getBuffer can only be called when all buffers are Uint8Array"_s);
}
@@ -208,7 +208,7 @@ JSC::JSValue JSBufferList::_getBuffer(JSC::VM& vm, JSC::JSGlobalObject* lexicalG
}
auto buffer = array->possiblySharedBuffer();
JSC::JSUint8Array* newArray = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, buffer, n, len - n);
- iter->set(vm, this, newArray);
+ element.set(vm, this, newArray);
offset += n;
break;
}
@@ -411,11 +411,11 @@ static const HashTableValue JSBufferListPrototypeTableValues[]
void JSBufferListPrototype::finishCreation(VM& vm, JSC::JSGlobalObject* globalThis)
{
Base::finishCreation(vm);
- this->setPrototypeDirect(vm, globalThis->objectPrototype());
reifyStaticProperties(vm, JSBufferList::info(), JSBufferListPrototypeTableValues, *this);
+ ASSERT(inherits(info()));
}
-const ClassInfo JSBufferListPrototype::s_info = { "BufferList"_s, nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSBufferListPrototype) };
+const ClassInfo JSBufferListPrototype::s_info = { "BufferList"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBufferListPrototype) };
void JSBufferListConstructor::finishCreation(VM& vm, JSC::JSGlobalObject* globalObject, JSBufferListPrototype* prototype)
{
diff --git a/src/bun.js/bindings/JSBufferList.h b/src/bun.js/bindings/JSBufferList.h
index 94a69c8d1..ebbc1781e 100644
--- a/src/bun.js/bindings/JSBufferList.h
+++ b/src/bun.js/bindings/JSBufferList.h
@@ -46,7 +46,7 @@ public:
void finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject);
static void destroy(JSCell*) {}
- size_t length() { return m_deque.size(); }
+ inline size_t length() { return m_deque.size(); }
void push(JSC::VM& vm, JSC::JSValue v)
{
m_deque.append(WriteBarrier<Unknown>());
@@ -100,6 +100,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSBufferListPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
diff --git a/src/bun.js/bindings/JSBundlerPlugin.cpp b/src/bun.js/bindings/JSBundlerPlugin.cpp
index 6ae266df7..d896d5b3d 100644
--- a/src/bun.js/bindings/JSBundlerPlugin.cpp
+++ b/src/bun.js/bindings/JSBundlerPlugin.cpp
@@ -31,6 +31,7 @@ namespace Bun {
extern "C" void JSBundlerPlugin__addError(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue);
extern "C" void JSBundlerPlugin__onLoadAsync(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue);
extern "C" void JSBundlerPlugin__onResolveAsync(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::EncodedJSValue);
+extern "C" void JSBundlerPlugin__onVirtualModulePlugin(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC_DECLARE_HOST_FUNCTION(jsBundlerPluginFunction_addFilter);
JSC_DECLARE_HOST_FUNCTION(jsBundlerPluginFunction_addError);
@@ -154,6 +155,7 @@ public:
Bun::BundlerPlugin plugin;
JSC::LazyProperty<JSBundlerPlugin, JSC::JSFunction> onLoadFunction;
JSC::LazyProperty<JSBundlerPlugin, JSC::JSFunction> onResolveFunction;
+ JSC::LazyProperty<JSBundlerPlugin, JSC::JSFunction> moduleFunction;
JSC::LazyProperty<JSBundlerPlugin, JSC::JSFunction> setupFunction;
private:
diff --git a/src/bun.js/bindings/JSCUSocketsLoopIntegration.cpp b/src/bun.js/bindings/JSCUSocketsLoopIntegration.cpp
new file mode 100644
index 000000000..0e3fcf47d
--- /dev/null
+++ b/src/bun.js/bindings/JSCUSocketsLoopIntegration.cpp
@@ -0,0 +1,30 @@
+#include "root.h"
+#include "JavaScriptCore/VM.h"
+
+// On Linux, signals are used to suspend/resume threads in JavaScriptCore
+// When `.acquireAccess` is called, the signal might be raised.
+// This causes issues with LLDB which might catch the signal.
+// So we want to avoid that, we really only want this code to be executed when the debugger is attached
+// But it's pretty hard to tell if LLDB is attached or not, so we just disable this code on Linux when in debug mode
+#ifndef ACQUIRE_RELEASE_HEAP_ACCESS
+#if OS(DARWIN)
+#define ACQUIRE_RELEASE_HEAP_ACCESS 1
+#else
+#ifndef BUN_DEBUG
+#define ACQUIRE_RELEASE_HEAP_ACCESS 1
+#endif
+#endif
+#endif
+
+extern "C" void bun_on_tick_before(JSC::VM* vm)
+{
+#if ACQUIRE_RELEASE_HEAP_ACCESS
+ // vm->heap.releaseAccess();
+#endif
+}
+extern "C" void bun_on_tick_after(JSC::VM* vm)
+{
+#if ACQUIRE_RELEASE_HEAP_ACCESS
+ // vm->heap.acquireAccess();
+#endif
+} \ No newline at end of file
diff --git a/src/bun.js/bindings/JSDOMFile.cpp b/src/bun.js/bindings/JSDOMFile.cpp
index 1d7770ac1..1e1f9f2bc 100644
--- a/src/bun.js/bindings/JSDOMFile.cpp
+++ b/src/bun.js/bindings/JSDOMFile.cpp
@@ -17,7 +17,7 @@ class JSDOMFile : public JSC::InternalFunction {
public:
JSDOMFile(JSC::VM& vm, JSC::Structure* structure)
- : Base(vm, structure, nullptr, construct)
+ : Base(vm, structure, call, construct)
{
}
@@ -43,7 +43,8 @@ public:
static JSDOMFile* create(JSC::VM& vm, JSGlobalObject* globalObject)
{
auto* zigGlobal = reinterpret_cast<Zig::GlobalObject*>(globalObject);
- auto* object = new (NotNull, JSC::allocateCell<JSDOMFile>(vm)) JSDOMFile(vm, createStructure(vm, globalObject, zigGlobal->functionPrototype()));
+ auto structure = createStructure(vm, globalObject, zigGlobal->functionPrototype());
+ auto* object = new (NotNull, JSC::allocateCell<JSDOMFile>(vm)) JSDOMFile(vm, structure);
object->finishCreation(vm);
// This is not quite right. But we'll fix it if someone files an issue about it.
@@ -91,6 +92,12 @@ public:
return JSValue::encode(
WebCore::JSBlob::create(vm, globalObject, structure, ptr));
}
+
+ static EncodedJSValue call(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
+ {
+ auto scope = DECLARE_THROW_SCOPE(lexicalGlobalObject->vm());
+ throwTypeError(lexicalGlobalObject, scope, "Class constructor File cannot be invoked without 'new"_s);
+ }
};
const JSC::ClassInfo JSDOMFile::s_info = { "File"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMFile) };
diff --git a/src/bun.js/bindings/JSDOMWrapperCache.h b/src/bun.js/bindings/JSDOMWrapperCache.h
index 7656c7c17..e06f2607d 100644
--- a/src/bun.js/bindings/JSDOMWrapperCache.h
+++ b/src/bun.js/bindings/JSDOMWrapperCache.h
@@ -215,6 +215,10 @@ template<typename DOMClass> inline void setSubclassStructureIfNeeded(JSC::JSGlob
JSC::VM& vm = lexicalGlobalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
+ // If the new target isn't actually callable
+ if (UNLIKELY(!newTarget->isCallable()))
+ newTarget = constructor;
+
auto* functionGlobalObject = JSC::getFunctionRealm(lexicalGlobalObject, newTarget);
RETURN_IF_EXCEPTION(scope, void());
auto* newTargetGlobalObject = JSC::jsCast<JSDOMGlobalObject*>(functionGlobalObject);
diff --git a/src/bun.js/bindings/JSMockFunction.cpp b/src/bun.js/bindings/JSMockFunction.cpp
index a8bac7c56..498864dfc 100644
--- a/src/bun.js/bindings/JSMockFunction.cpp
+++ b/src/bun.js/bindings/JSMockFunction.cpp
@@ -486,6 +486,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMockFunctionPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -623,7 +624,6 @@ extern "C" EncodedJSValue JSMock__jsSpyOn(JSC::JSGlobalObject* lexicalGlobalObje
mock->copyNameAndLength(vm, globalObject, value);
- attributes |= PropertyAttribute::Function;
object->putDirect(vm, propertyKey, mock, attributes);
RETURN_IF_EXCEPTION(scope, {});
@@ -1320,7 +1320,7 @@ MockWithImplementationCleanupData* MockWithImplementationCleanupData::create(VM&
}
Structure* MockWithImplementationCleanupData::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
}
MockWithImplementationCleanupData::MockWithImplementationCleanupData(VM& vm, Structure* structure)
diff --git a/src/bun.js/bindings/JSNextTickQueue.cpp b/src/bun.js/bindings/JSNextTickQueue.cpp
index 8916ef6c8..18963645c 100644
--- a/src/bun.js/bindings/JSNextTickQueue.cpp
+++ b/src/bun.js/bindings/JSNextTickQueue.cpp
@@ -18,7 +18,7 @@ namespace Bun {
using namespace JSC;
-const JSC::ClassInfo JSNextTickQueue::s_info = { "JSNextTickQueue"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSNextTickQueue) };
+const JSC::ClassInfo JSNextTickQueue::s_info = { "NextTickQueue"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSNextTickQueue) };
template<typename, JSC::SubspaceAccess mode>
JSC::GCClient::IsoSubspace* JSNextTickQueue::subspaceFor(JSC::VM& vm)
@@ -34,11 +34,12 @@ JSC::GCClient::IsoSubspace* JSNextTickQueue::subspaceFor(JSC::VM& vm)
JSNextTickQueue* JSNextTickQueue::create(VM& vm, Structure* structure)
{
JSNextTickQueue* mod = new (NotNull, allocateCell<JSNextTickQueue>(vm)) JSNextTickQueue(vm, structure);
+ mod->finishCreation(vm);
return mod;
}
Structure* JSNextTickQueue::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
}
JSNextTickQueue::JSNextTickQueue(VM& vm, Structure* structure)
@@ -65,7 +66,6 @@ JSNextTickQueue* JSNextTickQueue::create(JSC::JSGlobalObject* globalObject)
{
auto& vm = globalObject->vm();
auto* obj = create(vm, createStructure(vm, globalObject, jsNull()));
- obj->finishCreation(vm);
return obj;
}
diff --git a/src/bun.js/bindings/JSNextTickQueue.h b/src/bun.js/bindings/JSNextTickQueue.h
index c3bd228cc..3a499345d 100644
--- a/src/bun.js/bindings/JSNextTickQueue.h
+++ b/src/bun.js/bindings/JSNextTickQueue.h
@@ -10,7 +10,6 @@ using namespace JSC;
class JSNextTickQueue : public JSC::JSInternalFieldObjectImpl<3> {
public:
- static constexpr unsigned numberOfInternalFields = 3;
using Base = JSC::JSInternalFieldObjectImpl<3>;
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm);
diff --git a/src/bun.js/bindings/JSReadableState.cpp b/src/bun.js/bindings/JSReadableState.cpp
index 1f3a36def..22b1ec357 100644
--- a/src/bun.js/bindings/JSReadableState.cpp
+++ b/src/bun.js/bindings/JSReadableState.cpp
@@ -314,12 +314,12 @@ JSReadableState_NULLABLE_BOOLEAN_GETTER_SETTER(paused)
#undef JSReadableState_JSVALUE_GETTER_SETTER
-#define JSReadableState_GETTER_SETTER_HASH_TABLE_VALUE(NAME) \
- { \
-#NAME ""_s, static_cast < unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, \
- { \
- HashTableValue::GetterSetterType, jsReadableState_##NAME, setJSReadableState_##NAME \
- } \
+#define JSReadableState_GETTER_SETTER_HASH_TABLE_VALUE(NAME) \
+ { \
+ #NAME ""_s, static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, \
+ { \
+ HashTableValue::GetterSetterType, jsReadableState_##NAME, setJSReadableState_##NAME \
+ } \
}
/* Hash table for prototype */
diff --git a/src/bun.js/bindings/JSReadableState.h b/src/bun.js/bindings/JSReadableState.h
index c67baebad..78a716910 100644
--- a/src/bun.js/bindings/JSReadableState.h
+++ b/src/bun.js/bindings/JSReadableState.h
@@ -107,6 +107,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStatePrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
diff --git a/src/bun.js/bindings/JSSink.cpp b/src/bun.js/bindings/JSSink.cpp
index d986ae590..ef6343849 100644
--- a/src/bun.js/bindings/JSSink.cpp
+++ b/src/bun.js/bindings/JSSink.cpp
@@ -711,6 +711,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSArrayBufferSinkPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -743,6 +744,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableArrayBufferSinkControllerPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -798,17 +800,19 @@ void JSReadableArrayBufferSinkController::detach()
auto readableStream = m_weakReadableStream.get();
auto onClose = m_onClose.get();
- m_onClose.clear();
if (readableStream && onClose) {
- JSC::JSGlobalObject* globalObject = this->globalObject();
auto callData = JSC::getCallData(onClose);
- JSC::MarkedArgumentBuffer arguments;
- arguments.append(readableStream);
- arguments.append(jsUndefined());
- call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ if (callData.type != JSC::CallData::Type::None) {
+ JSC::JSGlobalObject* globalObject = this->globalObject();
+ JSC::MarkedArgumentBuffer arguments;
+ arguments.append(readableStream);
+ arguments.append(jsUndefined());
+ call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ }
}
+ m_onClose.clear();
m_weakReadableStream.clear();
}
@@ -965,6 +969,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSFileSinkPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -997,6 +1002,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableFileSinkControllerPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -1052,17 +1058,19 @@ void JSReadableFileSinkController::detach()
auto readableStream = m_weakReadableStream.get();
auto onClose = m_onClose.get();
- m_onClose.clear();
if (readableStream && onClose) {
- JSC::JSGlobalObject* globalObject = this->globalObject();
auto callData = JSC::getCallData(onClose);
- JSC::MarkedArgumentBuffer arguments;
- arguments.append(readableStream);
- arguments.append(jsUndefined());
- call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ if (callData.type != JSC::CallData::Type::None) {
+ JSC::JSGlobalObject* globalObject = this->globalObject();
+ JSC::MarkedArgumentBuffer arguments;
+ arguments.append(readableStream);
+ arguments.append(jsUndefined());
+ call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ }
}
+ m_onClose.clear();
m_weakReadableStream.clear();
}
@@ -1219,6 +1227,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSHTTPResponseSinkPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -1251,6 +1260,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableHTTPResponseSinkControllerPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -1306,17 +1316,19 @@ void JSReadableHTTPResponseSinkController::detach()
auto readableStream = m_weakReadableStream.get();
auto onClose = m_onClose.get();
- m_onClose.clear();
if (readableStream && onClose) {
- JSC::JSGlobalObject* globalObject = this->globalObject();
auto callData = JSC::getCallData(onClose);
- JSC::MarkedArgumentBuffer arguments;
- arguments.append(readableStream);
- arguments.append(jsUndefined());
- call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ if (callData.type != JSC::CallData::Type::None) {
+ JSC::JSGlobalObject* globalObject = this->globalObject();
+ JSC::MarkedArgumentBuffer arguments;
+ arguments.append(readableStream);
+ arguments.append(jsUndefined());
+ call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ }
}
+ m_onClose.clear();
m_weakReadableStream.clear();
}
@@ -1473,6 +1485,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSHTTPSResponseSinkPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -1505,6 +1518,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableHTTPSResponseSinkControllerPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -1560,17 +1574,19 @@ void JSReadableHTTPSResponseSinkController::detach()
auto readableStream = m_weakReadableStream.get();
auto onClose = m_onClose.get();
- m_onClose.clear();
if (readableStream && onClose) {
- JSC::JSGlobalObject* globalObject = this->globalObject();
auto callData = JSC::getCallData(onClose);
- JSC::MarkedArgumentBuffer arguments;
- arguments.append(readableStream);
- arguments.append(jsUndefined());
- call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ if (callData.type != JSC::CallData::Type::None) {
+ JSC::JSGlobalObject* globalObject = this->globalObject();
+ JSC::MarkedArgumentBuffer arguments;
+ arguments.append(readableStream);
+ arguments.append(jsUndefined());
+ call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ }
}
+ m_onClose.clear();
m_weakReadableStream.clear();
}
diff --git a/src/bun.js/bindings/JSSocketAddress.cpp b/src/bun.js/bindings/JSSocketAddress.cpp
new file mode 100644
index 000000000..181507339
--- /dev/null
+++ b/src/bun.js/bindings/JSSocketAddress.cpp
@@ -0,0 +1,63 @@
+#include "JSSocketAddress.h"
+#include "ZigGlobalObject.h"
+#include "JavaScriptCore/JSObjectInlines.h"
+#include "JavaScriptCore/ObjectConstructor.h"
+#include "JavaScriptCore/JSCast.h"
+
+using namespace JSC;
+
+namespace Bun {
+namespace JSSocketAddress {
+
+// Using a structure with inlined offsets should be more lightweight than a class.
+Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
+{
+ JSC::Structure* structure = globalObject->structureCache().emptyObjectStructureForPrototype(
+ globalObject,
+ globalObject->objectPrototype(),
+ 3);
+
+ JSC::PropertyOffset offset;
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "address"_s),
+ 0,
+ offset);
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "family"_s),
+ 0,
+ offset);
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "port"_s),
+ 0,
+ offset);
+
+ return structure;
+}
+
+} // namespace JSSocketAddress
+} // namespace Bun
+
+extern "C" JSObject* JSSocketAddress__create(JSGlobalObject* globalObject, JSString* value, int32_t port, bool isIPv6)
+{
+ static const NeverDestroyed<String> IPv4 = MAKE_STATIC_STRING_IMPL("IPv4");
+ static const NeverDestroyed<String> IPv6 = MAKE_STATIC_STRING_IMPL("IPv6");
+
+ VM& vm = globalObject->vm();
+
+ auto* global = jsCast<Zig::GlobalObject*>(globalObject);
+
+ JSObject* thisObject = constructEmptyObject(vm, global->JSSocketAddressStructure());
+ thisObject->putDirectOffset(vm, 0, value);
+ thisObject->putDirectOffset(vm, 1, isIPv6 ? jsString(vm, IPv6) : jsString(vm, IPv4));
+ thisObject->putDirectOffset(vm, 2, jsNumber(port));
+
+ return thisObject;
+}
diff --git a/src/bun.js/bindings/JSSocketAddress.h b/src/bun.js/bindings/JSSocketAddress.h
new file mode 100644
index 000000000..77bdca5d4
--- /dev/null
+++ b/src/bun.js/bindings/JSSocketAddress.h
@@ -0,0 +1,16 @@
+// The object returned by Bun.serve's .requestIP()
+#pragma once
+#include "root.h"
+#include "JavaScriptCore/JSObjectInlines.h"
+
+using namespace JSC;
+
+namespace Bun {
+namespace JSSocketAddress {
+
+Structure* createStructure(VM& vm, JSGlobalObject* globalObject);
+
+} // namespace JSSocketAddress
+} // namespace Bun
+
+extern "C" JSObject* JSSocketAddress__create(JSGlobalObject* globalObject, JSString* value, int port, bool isIPv6);
diff --git a/src/bun.js/bindings/JSStringDecoder.h b/src/bun.js/bindings/JSStringDecoder.h
index bce1ae05d..cd2e017d6 100644
--- a/src/bun.js/bindings/JSStringDecoder.h
+++ b/src/bun.js/bindings/JSStringDecoder.h
@@ -77,6 +77,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSStringDecoderPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
diff --git a/src/bun.js/bindings/KeyObject.cpp b/src/bun.js/bindings/KeyObject.cpp
new file mode 100644
index 000000000..d5782779d
--- /dev/null
+++ b/src/bun.js/bindings/KeyObject.cpp
@@ -0,0 +1,2389 @@
+// Attribution: Some parts of of this module are derived from code originating from the Node.js
+// crypto module which is licensed under an MIT license:
+//
+// Copyright Node.js contributors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "KeyObject.h"
+#include "webcrypto/JSCryptoKey.h"
+#include "webcrypto/JSSubtleCrypto.h"
+#include "webcrypto/CryptoKeyOKP.h"
+#include "webcrypto/CryptoKeyEC.h"
+#include "webcrypto/CryptoKeyRSA.h"
+#include "webcrypto/CryptoKeyAES.h"
+#include "webcrypto/CryptoKeyHMAC.h"
+#include "webcrypto/CryptoKeyRaw.h"
+#include "webcrypto/CryptoKeyUsage.h"
+#include "webcrypto/JsonWebKey.h"
+#include "webcrypto/JSJsonWebKey.h"
+#include "JavaScriptCore/JSObject.h"
+#include "JavaScriptCore/ObjectConstructor.h"
+#include "headers-handwritten.h"
+#include <openssl/evp.h>
+#include <openssl/mem.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/curve25519.h>
+#include "JSBuffer.h"
+
+using namespace JSC;
+using namespace Bun;
+using JSGlobalObject
+ = JSC::JSGlobalObject;
+using Exception = JSC::Exception;
+using JSValue = JSC::JSValue;
+using JSString = JSC::JSString;
+using JSModuleLoader = JSC::JSModuleLoader;
+using JSModuleRecord = JSC::JSModuleRecord;
+using Identifier = JSC::Identifier;
+using SourceOrigin = JSC::SourceOrigin;
+using JSObject = JSC::JSObject;
+using JSNonFinalObject = JSC::JSNonFinalObject;
+
+namespace WebCore {
+
+static bool KeyObject__IsASN1Sequence(const unsigned char* data, size_t size,
+ size_t* data_offset, size_t* data_size)
+{
+ if (size < 2 || data[0] != 0x30)
+ return false;
+
+ if (data[1] & 0x80) {
+ // Long form.
+ size_t n_bytes = data[1] & ~0x80;
+ if (n_bytes + 2 > size || n_bytes > sizeof(size_t))
+ return false;
+ size_t length = 0;
+ for (size_t i = 0; i < n_bytes; i++)
+ length = (length << 8) | data[i + 2];
+ *data_offset = 2 + n_bytes;
+ *data_size = std::min(size - 2 - n_bytes, length);
+ } else {
+ // Short form.
+ *data_offset = 2;
+ *data_size = std::min<size_t>(size - 2, data[1]);
+ }
+
+ return true;
+}
+static bool KeyObject__IsRSAPrivateKey(const unsigned char* data, size_t size)
+{
+ // Both RSAPrivateKey and RSAPublicKey structures start with a SEQUENCE.
+ size_t offset, len;
+ if (!KeyObject__IsASN1Sequence(data, size, &offset, &len))
+ return false;
+
+ // An RSAPrivateKey sequence always starts with a single-byte integer whose
+ // value is either 0 or 1, whereas an RSAPublicKey starts with the modulus
+ // (which is the product of two primes and therefore at least 4), so we can
+ // decide the type of the structure based on the first three bytes of the
+ // sequence.
+ return len >= 3 && data[offset] == 2 && data[offset + 1] == 1 && !(data[offset + 2] & 0xfe);
+}
+
+static bool KeyObject__IsEncryptedPrivateKeyInfo(const unsigned char* data, size_t size)
+{
+ // Both PrivateKeyInfo and EncryptedPrivateKeyInfo start with a SEQUENCE.
+ size_t offset, len;
+ if (!KeyObject__IsASN1Sequence(data, size, &offset, &len))
+ return false;
+
+ // A PrivateKeyInfo sequence always starts with an integer whereas an
+ // EncryptedPrivateKeyInfo starts with an AlgorithmIdentifier.
+ return len >= 1 && data[offset] != 2;
+}
+
+struct AsymmetricKeyValue {
+ EVP_PKEY* key;
+ bool owned;
+};
+
+struct AsymmetricKeyValueWithDER {
+ EVP_PKEY* key;
+ unsigned char* der_data;
+ long der_len;
+};
+
+struct PrivateKeyPassphrase {
+ char* passphrase;
+ size_t passphrase_len;
+};
+
+int PasswordCallback(char* buf, int size, int rwflag, void* u)
+{
+ auto result = static_cast<PrivateKeyPassphrase*>(u);
+ if (result != nullptr && size > 0 && result->passphrase != nullptr) {
+ size_t buflen = static_cast<size_t>(size);
+ size_t len = result->passphrase_len;
+ if (buflen < len)
+ return -1;
+ memcpy(buf, result->passphrase, buflen);
+ return len;
+ }
+
+ return -1;
+}
+
+AsymmetricKeyValueWithDER KeyObject__ParsePublicKeyPEM(const char* key_pem,
+ size_t key_pem_len)
+{
+ auto bp = BIOPtr(BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len));
+ auto result = (AsymmetricKeyValueWithDER) { .key = nullptr, .der_data = nullptr, .der_len = 0 };
+
+ if (!bp) {
+ ERR_clear_error();
+ return result;
+ }
+
+ // Try parsing as a SubjectPublicKeyInfo first.
+ if (PEM_bytes_read_bio(&result.der_data, &result.der_len, nullptr, "PUBLIC KEY", bp.get(), nullptr, nullptr) == 1) {
+ // OpenSSL might modify the pointer, so we need to make a copy before parsing.
+ const unsigned char* p = result.der_data;
+ result.key = d2i_PUBKEY(nullptr, &p, result.der_len);
+ if (result.key) {
+ return result;
+ }
+ }
+
+ ERR_clear_error();
+ BIO_reset(bp.get());
+
+ // Maybe it is PKCS#1.
+ if (PEM_bytes_read_bio(&result.der_data, &result.der_len, nullptr, "RSA PUBLIC KEY", bp.get(), nullptr, nullptr) == 1) {
+ const unsigned char* p = result.der_data;
+ result.key = d2i_PublicKey(EVP_PKEY_RSA, nullptr, &p, result.der_len);
+ if (result.key) {
+ return result;
+ }
+ }
+ ERR_clear_error();
+ BIO_reset(bp.get());
+
+ // X.509 fallback.
+ if (PEM_bytes_read_bio(&result.der_data, &result.der_len, nullptr, "CERTIFICATE", bp.get(), nullptr, nullptr) == 1) {
+ const unsigned char* p = result.der_data;
+ X509Ptr x509(d2i_X509(nullptr, &p, result.der_len));
+ result.key = x509 ? X509_get_pubkey(x509.get()) : nullptr;
+ if (result.key) {
+ return result;
+ }
+ OPENSSL_clear_free(result.der_data, result.der_len);
+ ERR_clear_error();
+ result.der_data = nullptr;
+ result.der_len = 0;
+ } else {
+ OPENSSL_clear_free(result.der_data, result.der_len);
+ ERR_clear_error();
+ result.der_data = nullptr;
+ result.der_len = 0;
+ }
+ return result;
+}
+
+JSC::EncodedJSValue KeyObject__createPrivateKey(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
+{
+
+ auto count = callFrame->argumentCount();
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (count < 1) {
+ JSC::throwTypeError(globalObject, scope, "createPrivateKey requires 1 arguments"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ auto* options = jsDynamicCast<JSC::JSObject*>(callFrame->argument(0));
+ if (!options) {
+ JSC::throwTypeError(globalObject, scope, "expected options to be a object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ JSValue keyJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "key"_s)));
+ if (keyJSValue.isUndefinedOrNull() || keyJSValue.isEmpty()) {
+ JSC::throwTypeError(globalObject, scope, "key is required"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ if (!keyJSValue.isCell()) {
+ JSC::throwTypeError(globalObject, scope, "key must be a Buffer, Array-like or object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ JSValue formatJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "format"_s)));
+ if (formatJSValue.isUndefinedOrNull() || formatJSValue.isEmpty()) {
+ JSC::throwTypeError(globalObject, scope, "format is required"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ if (!formatJSValue.isString()) {
+ JSC::throwTypeError(globalObject, scope, "format must be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto format = formatJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+ Zig::GlobalObject* zigGlobalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject);
+ auto* structure = zigGlobalObject->JSCryptoKeyStructure();
+
+ void* data;
+ size_t byteLength;
+
+ auto keyJSValueCell = keyJSValue.asCell();
+ auto type = keyJSValueCell->type();
+
+ switch (type) {
+
+ case DataViewType:
+ case Uint8ArrayType:
+ case Uint8ClampedArrayType:
+ case Uint16ArrayType:
+ case Uint32ArrayType:
+ case Int8ArrayType:
+ case Int16ArrayType:
+ case Int32ArrayType:
+ case Float32ArrayType:
+ case Float64ArrayType:
+ case BigInt64ArrayType:
+ case BigUint64ArrayType: {
+ JSC::JSArrayBufferView* view = jsCast<JSC::JSArrayBufferView*>(keyJSValueCell);
+
+ data = view->vector();
+ byteLength = view->length();
+ break;
+ }
+ case ArrayBufferType: {
+ auto* jsBuffer = jsDynamicCast<JSC::JSArrayBuffer*>(keyJSValueCell);
+ if (UNLIKELY(!jsBuffer)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "ERR_INVALID_ARG_TYPE: expected key to be Buffer or array-like object"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto* buffer = jsBuffer->impl();
+ data = buffer->data();
+ byteLength = buffer->byteLength();
+ break;
+ }
+ default: {
+ if (auto* keyObj = jsDynamicCast<JSC::JSObject*>(keyJSValue)) {
+ if (format != "jwk"_s) {
+ JSC::throwTypeError(globalObject, scope, "format should be 'jwk' when key type is 'object'"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto jwk = WebCore::convertDictionary<JsonWebKey>(*globalObject, keyJSValue);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (jwk.kty == "OKP"_s) {
+ if (jwk.crv == "Ed25519"_s) {
+ auto result = CryptoKeyOKP::importJwk(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::Ed25519, WTFMove(jwk), true, CryptoKeyUsageSign);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ if (impl->type() != CryptoKeyType::Private) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (jwk.crv == "X25519"_s) {
+ auto result = CryptoKeyOKP::importJwk(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::X25519, WTFMove(jwk), true, CryptoKeyUsageSign);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid X25519 private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ if (impl->type() != CryptoKeyType::Private) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else {
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported OKP curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ } else if (jwk.kty == "EC"_s) {
+ auto result = CryptoKeyEC::importJwk(CryptoAlgorithmIdentifier::ECDSA, jwk.crv, WTFMove(jwk), true, jwk.usages);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ if (impl->type() != CryptoKeyType::Private) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (jwk.kty == "RSA"_s) {
+ auto result = CryptoKeyRSA::importJwk(CryptoAlgorithmIdentifier::RSA_OAEP, std::nullopt, WTFMove(jwk), true, jwk.usages);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid RSA private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ if (impl->type() != CryptoKeyType::Private) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else {
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ }
+ JSC::throwTypeError(globalObject, scope, "The \"key\" property must be of type object"_s);
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ }
+
+ if (format == "jwk"_s) {
+ JSC::throwTypeError(globalObject, scope, "The \"key\" property must be of type object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ if (UNLIKELY(!data) || UNLIKELY(!byteLength)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "ERR_INVALID_ARG_TYPE: expected key to be Buffer or array-like object"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+
+ JSValue passphraseJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "passphrase"_s)));
+ PrivateKeyPassphrase passphrase = { nullptr, 0 };
+
+ auto hasPassphrase = !passphraseJSValue.isUndefinedOrNull() && !passphraseJSValue.isEmpty();
+
+ if (hasPassphrase) {
+ if (passphraseJSValue.isString()) {
+ auto passphrase_wtfstr = passphraseJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (!passphrase_wtfstr.isNull()) {
+ if (auto pass = passphrase_wtfstr.tryGetUTF8()) {
+ if (pass.has_value()) {
+ auto value = pass.value();
+ passphrase.passphrase = const_cast<char*>(value.data());
+ passphrase.passphrase_len = value.length();
+ }
+ }
+ }
+ } else if (auto* passphraseBuffer = jsDynamicCast<JSUint8Array*>(passphraseJSValue)) {
+ passphrase.passphrase = (char*)passphraseBuffer->vector();
+ passphrase.passphrase_len = passphraseBuffer->byteLength();
+ } else {
+ JSC::throwTypeError(globalObject, scope, "passphrase must be a Buffer or String"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ }
+
+ if (format == "pem"_s) {
+ auto bio = BIOPtr(BIO_new_mem_buf(const_cast<char*>((char*)data), byteLength));
+ auto pkey = EvpPKeyPtr(PEM_read_bio_PrivateKey(bio.get(), nullptr, PasswordCallback, &passphrase));
+
+ if (!pkey) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key pem file"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto pKeyID = EVP_PKEY_id(pkey.get());
+
+ if (pKeyID == EVP_PKEY_RSA || pKeyID == EVP_PKEY_RSA_PSS) {
+ auto impl = CryptoKeyRSA::create(pKeyID == EVP_PKEY_RSA_PSS ? CryptoAlgorithmIdentifier::RSA_PSS : CryptoAlgorithmIdentifier::RSA_OAEP, CryptoAlgorithmIdentifier::SHA_1, false, CryptoKeyType::Private, WTFMove(pkey), true, CryptoKeyUsageDecrypt);
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_ED25519 || pKeyID == EVP_PKEY_X25519) {
+ size_t out_len = 0;
+ if (!EVP_PKEY_get_raw_private_key(pkey.get(), nullptr, &out_len)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ Vector<uint8_t> out(out_len);
+ if (!EVP_PKEY_get_raw_private_key(pkey.get(), out.data(), &out_len) || out_len != out.size()) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto result = CryptoKeyOKP::create(CryptoAlgorithmIdentifier::Ed25519, pKeyID == EVP_PKEY_ED25519 ? CryptoKeyOKP::NamedCurve::Ed25519 : CryptoKeyOKP::NamedCurve::X25519, CryptoKeyType::Private, WTFMove(out), true, CryptoKeyUsageSign);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_EC) {
+ EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(pkey.get());
+ if (UNLIKELY(ec_key == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
+ // Get the curve name
+ int curve_name = EC_GROUP_get_curve_name(ec_group);
+ if (curve_name == NID_undef) {
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unable to identify EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ CryptoKeyEC::NamedCurve curve;
+ if (curve_name == NID_X9_62_prime256v1)
+ curve = CryptoKeyEC::NamedCurve::P256;
+ else if (curve_name == NID_secp384r1)
+ curve = CryptoKeyEC::NamedCurve::P384;
+ else if (curve_name == NID_secp521r1)
+ curve = CryptoKeyEC::NamedCurve::P521;
+ else {
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ EC_KEY_free(ec_key);
+ auto impl = CryptoKeyEC::create(CryptoAlgorithmIdentifier::ECDH, curve, CryptoKeyType::Private, WTFMove(pkey), true, CryptoKeyUsageSign);
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else {
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ }
+ if (format == "der"_s) {
+ JSValue typeJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "type"_s)));
+ WTF::String type = "pkcs8"_s;
+ if (!typeJSValue.isUndefinedOrNull() && !typeJSValue.isEmpty()) {
+ if (!typeJSValue.isString()) {
+ JSC::throwTypeError(globalObject, scope, "type must be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ type = typeJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ }
+
+ if (type == "pkcs1"_s) {
+ // must be RSA
+ const unsigned char* p = reinterpret_cast<const unsigned char*>(data);
+ auto pkey = EvpPKeyPtr(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &p, byteLength));
+ if (!pkey) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid use of PKCS#1 as private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto pKeyID = EVP_PKEY_id(pkey.get());
+ auto impl = CryptoKeyRSA::create(pKeyID == EVP_PKEY_RSA_PSS ? CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5 : CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5, CryptoAlgorithmIdentifier::SHA_1, false, CryptoKeyType::Private, WTFMove(pkey), true, CryptoKeyUsageDecrypt);
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (type == "pkcs8"_s) {
+
+ auto bio = BIOPtr(BIO_new_mem_buf(const_cast<char*>((char*)data), byteLength));
+ WebCore::EvpPKeyPtr pkey;
+ if (KeyObject__IsEncryptedPrivateKeyInfo(const_cast<unsigned char*>((unsigned char*)data), byteLength)) {
+ pkey = EvpPKeyPtr(d2i_PKCS8PrivateKey_bio(bio.get(),
+ nullptr,
+ PasswordCallback,
+ &passphrase));
+ } else {
+ auto* p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), nullptr);
+ if (!p8inf) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid PKCS8 data"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ pkey = EvpPKeyPtr(EVP_PKCS82PKEY(p8inf));
+ }
+ if (!pkey) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto pKeyID = EVP_PKEY_id(pkey.get());
+
+ if (pKeyID == EVP_PKEY_RSA || pKeyID == EVP_PKEY_RSA_PSS) {
+ auto impl = CryptoKeyRSA::create(pKeyID == EVP_PKEY_RSA_PSS ? CryptoAlgorithmIdentifier::RSA_PSS : CryptoAlgorithmIdentifier::RSA_OAEP, CryptoAlgorithmIdentifier::SHA_1, false, CryptoKeyType::Private, WTFMove(pkey), true, CryptoKeyUsageDecrypt);
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_ED25519) {
+ auto result = CryptoKeyOKP::importPkcs8(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::Ed25519, Vector<uint8_t>((uint8_t*)data, byteLength), true, CryptoKeyUsageSign);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_X25519) {
+ auto result = CryptoKeyOKP::importPkcs8(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::X25519, Vector<uint8_t>((uint8_t*)data, byteLength), true, CryptoKeyUsageSign);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_EC) {
+ EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(pkey.get());
+ if (UNLIKELY(ec_key == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
+ // Get the curve name
+ int curve_name = EC_GROUP_get_curve_name(ec_group);
+ if (curve_name == NID_undef) {
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unable to identify EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ CryptoKeyEC::NamedCurve curve;
+ if (curve_name == NID_X9_62_prime256v1)
+ curve = CryptoKeyEC::NamedCurve::P256;
+ else if (curve_name == NID_secp384r1)
+ curve = CryptoKeyEC::NamedCurve::P384;
+ else if (curve_name == NID_secp521r1)
+ curve = CryptoKeyEC::NamedCurve::P521;
+ else {
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto result = CryptoKeyEC::platformImportPkcs8(CryptoAlgorithmIdentifier::ECDH, curve, Vector<uint8_t>((uint8_t*)data, byteLength), true, CryptoKeyUsageSign);
+ if (UNLIKELY(result == nullptr)) {
+ result = CryptoKeyEC::platformImportPkcs8(CryptoAlgorithmIdentifier::ECDSA, curve, Vector<uint8_t>((uint8_t*)data, byteLength), true, CryptoKeyUsageSign);
+ }
+ EC_KEY_free(ec_key);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else {
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ } else if (type == "sec1"_s) {
+ const unsigned char* p = reinterpret_cast<const unsigned char*>(data);
+ auto pkey = EvpPKeyPtr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, byteLength));
+ auto pKeyID = EVP_PKEY_id(pkey.get());
+
+ if (pKeyID == EVP_PKEY_EC) {
+ EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(pkey.get());
+ if (UNLIKELY(ec_key == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
+ // Get the curve name
+ int curve_name = EC_GROUP_get_curve_name(ec_group);
+ if (curve_name == NID_undef) {
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unable to identify EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ CryptoKeyEC::NamedCurve curve;
+ if (curve_name == NID_X9_62_prime256v1)
+ curve = CryptoKeyEC::NamedCurve::P256;
+ else if (curve_name == NID_secp384r1)
+ curve = CryptoKeyEC::NamedCurve::P384;
+ else if (curve_name == NID_secp521r1)
+ curve = CryptoKeyEC::NamedCurve::P521;
+ else {
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ EC_KEY_free(ec_key);
+ auto impl = CryptoKeyEC::create(CryptoAlgorithmIdentifier::ECDH, curve, CryptoKeyType::Private, WTFMove(pkey), true, CryptoKeyUsageSign);
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ }
+
+ JSC::throwTypeError(globalObject, scope, "type should be 'pkcs1', 'pkcs8' or 'sec1'"_s);
+ return JSValue::encode(JSC::jsUndefined());
+ }
+
+ JSC::throwTypeError(globalObject, scope, "format should be 'pem' or 'der'"_s);
+ return JSValue::encode(JSC::jsUndefined());
+}
+
+static JSC::EncodedJSValue KeyObject__createRSAFromPrivate(JSC::JSGlobalObject* globalObject, EVP_PKEY* pkey, WebCore::CryptoAlgorithmIdentifier alg)
+{
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ const RSA* rsa_key = EVP_PKEY_get0_RSA(pkey);
+
+ auto publicRSA = RSAPtr(RSAPublicKey_dup(rsa_key));
+ if (!publicRSA) {
+ JSC::throwTypeError(globalObject, scope, "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE: Failed to create a public key from private"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto publicPKey = EvpPKeyPtr(EVP_PKEY_new());
+ if (EVP_PKEY_set1_RSA(publicPKey.get(), publicRSA.get()) <= 0) {
+ JSC::throwTypeError(globalObject, scope, "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE: Failed to create a public key from private"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto impl = CryptoKeyRSA::create(alg, CryptoAlgorithmIdentifier::SHA_1, false, CryptoKeyType::Public, WTFMove(publicPKey), true, CryptoKeyUsageVerify);
+ Zig::GlobalObject* zigGlobalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject);
+ auto* structure = zigGlobalObject->JSCryptoKeyStructure();
+
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+}
+
+static JSC::EncodedJSValue KeyObject__createECFromPrivate(JSC::JSGlobalObject* globalObject, EVP_PKEY* pkey, CryptoKeyEC::NamedCurve namedCurve, WebCore::CryptoAlgorithmIdentifier alg)
+{
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey);
+ auto point = ECPointPtr(EC_POINT_dup(EC_KEY_get0_public_key(ec_key), EC_KEY_get0_group(ec_key)));
+ if (!point) {
+ JSC::throwTypeError(globalObject, scope, "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE: Failed to create a public key from private 1"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto curve = NID_undef;
+
+ switch (namedCurve) {
+ case CryptoKeyEC::NamedCurve::P256:
+ curve = NID_X9_62_prime256v1;
+ break;
+ case CryptoKeyEC::NamedCurve::P384:
+ curve = NID_secp384r1;
+ break;
+ case CryptoKeyEC::NamedCurve::P521:
+ curve = NID_secp521r1;
+ break;
+ }
+ auto publicECKey = ECKeyPtr(EC_KEY_new_by_curve_name(curve));
+ if (!publicECKey) {
+ JSC::throwTypeError(globalObject, scope, "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE: Failed to create a public key from private 2"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ // OPENSSL_EC_NAMED_CURVE needs to be set to export the key with the curve name, not with the curve parameters.
+ EC_KEY_set_asn1_flag(publicECKey.get(), OPENSSL_EC_NAMED_CURVE);
+ if (EC_KEY_set_public_key(publicECKey.get(), point.get()) <= 0) {
+ JSC::throwTypeError(globalObject, scope, "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE: Failed to create a public key from private 3"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto publicPKey = EvpPKeyPtr(EVP_PKEY_new());
+ if (EVP_PKEY_set1_EC_KEY(publicPKey.get(), publicECKey.get()) <= 0) {
+ JSC::throwTypeError(globalObject, scope, "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE: Failed to create a public key from private 4"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto impl = CryptoKeyEC::create(alg, namedCurve, CryptoKeyType::Public, WTFMove(publicPKey), true, CryptoKeyUsageVerify);
+
+ Zig::GlobalObject* zigGlobalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject);
+ auto* structure = zigGlobalObject->JSCryptoKeyStructure();
+
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+}
+
+static JSC::EncodedJSValue KeyObject__createOKPFromPrivate(JSC::JSGlobalObject* globalObject, const WebCore::CryptoKeyOKP::KeyMaterial keyData, CryptoKeyOKP::NamedCurve namedCurve, WebCore::CryptoAlgorithmIdentifier alg)
+{
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ uint8_t public_key[ED25519_PUBLIC_KEY_LEN];
+
+ if (namedCurve == CryptoKeyOKP::NamedCurve::Ed25519) {
+ memcpy(public_key, keyData.data() + ED25519_PRIVATE_KEY_LEN, ED25519_PUBLIC_KEY_LEN);
+ } else {
+ X25519_public_from_private(public_key, keyData.data());
+ }
+ auto result = CryptoKeyOKP::create(alg, namedCurve, CryptoKeyType::Public, Vector<uint8_t>(public_key), true, CryptoKeyUsageVerify);
+ if (UNLIKELY(result == nullptr)) {
+ JSC::throwTypeError(globalObject, scope, "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE: Failed to create a public key from private"_s);
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+
+ Zig::GlobalObject* zigGlobalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject);
+ auto* structure = zigGlobalObject->JSCryptoKeyStructure();
+
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+}
+
+static JSC::EncodedJSValue KeyObject__createPublicFromPrivate(JSC::JSGlobalObject* globalObject, EVP_PKEY* pkey)
+{
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto pKeyID = EVP_PKEY_id(pkey);
+ if (pKeyID == EVP_PKEY_RSA || pKeyID == EVP_PKEY_RSA_PSS) {
+ return KeyObject__createRSAFromPrivate(globalObject, pkey, pKeyID == EVP_PKEY_RSA_PSS ? CryptoAlgorithmIdentifier::RSA_PSS : CryptoAlgorithmIdentifier::RSA_OAEP);
+ } else if (pKeyID == EVP_PKEY_EC) {
+
+ EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(pkey);
+ if (UNLIKELY(ec_key == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
+ // Get the curve name
+ int curve_name = EC_GROUP_get_curve_name(ec_group);
+ if (curve_name == NID_undef) {
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unable to identify EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ CryptoKeyEC::NamedCurve curve;
+ if (curve_name == NID_X9_62_prime256v1)
+ curve = CryptoKeyEC::NamedCurve::P256;
+ else if (curve_name == NID_secp384r1)
+ curve = CryptoKeyEC::NamedCurve::P384;
+ else if (curve_name == NID_secp521r1)
+ curve = CryptoKeyEC::NamedCurve::P521;
+ else {
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ EC_KEY_free(ec_key);
+ return KeyObject__createECFromPrivate(globalObject, pkey, curve, CryptoAlgorithmIdentifier::ECDSA);
+ } else if (pKeyID == EVP_PKEY_ED25519 || pKeyID == EVP_PKEY_X25519) {
+ size_t out_len = 0;
+ auto& vm = globalObject->vm();
+ if (!EVP_PKEY_get_raw_private_key(pkey, nullptr, &out_len)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ Vector<uint8_t> out(out_len);
+ if (!EVP_PKEY_get_raw_private_key(pkey, out.data(), &out_len) || out_len != out.size()) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ return KeyObject__createOKPFromPrivate(globalObject, out, pKeyID == EVP_PKEY_ED25519 ? CryptoKeyOKP::NamedCurve::Ed25519 : CryptoKeyOKP::NamedCurve::X25519, CryptoAlgorithmIdentifier::Ed25519);
+ } else {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid private key type"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+}
+
+JSC::EncodedJSValue KeyObject__createPublicKey(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
+{
+
+ auto count = callFrame->argumentCount();
+ auto& vm = globalObject->vm();
+
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (count < 1) {
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ JSC::throwTypeError(globalObject, scope, "createPublicKey requires 1 arguments"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto* options = jsDynamicCast<JSC::JSObject*>(callFrame->argument(0));
+ if (!options) {
+ JSC::throwTypeError(globalObject, scope, "expected options to be a object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ JSValue keyJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "key"_s)));
+ if (keyJSValue.isUndefinedOrNull() || keyJSValue.isEmpty()) {
+ JSC::throwTypeError(globalObject, scope, "key is required"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ Zig::GlobalObject* zigGlobalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject);
+ auto* structure = zigGlobalObject->JSCryptoKeyStructure();
+
+ void* data;
+ size_t byteLength;
+ if (auto* key = jsDynamicCast<JSCryptoKey*>(keyJSValue)) {
+ auto& wrapped = key->wrapped();
+ auto key_type = wrapped.type();
+ if (key_type != CryptoKeyType::Private) {
+ JSC::throwTypeError(globalObject, scope, "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE: Invalid key object type, expected private"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto id = wrapped.keyClass();
+
+ switch (id) {
+ case CryptoKeyClass::RSA: {
+ return KeyObject__createRSAFromPrivate(globalObject, downcast<WebCore::CryptoKeyRSA>(wrapped).platformKey(), wrapped.algorithmIdentifier());
+ }
+ case CryptoKeyClass::EC: {
+ auto& impl = downcast<WebCore::CryptoKeyEC>(wrapped);
+ return KeyObject__createECFromPrivate(globalObject, impl.platformKey(), impl.namedCurve(), wrapped.algorithmIdentifier());
+ }
+ case CryptoKeyClass::OKP: {
+ auto& impl = downcast<WebCore::CryptoKeyOKP>(wrapped);
+ return KeyObject__createOKPFromPrivate(globalObject, impl.exportKey(), impl.namedCurve(), wrapped.algorithmIdentifier());
+ }
+ default: {
+ JSC::throwTypeError(globalObject, scope, "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE: Invalid key object type, expected private"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ }
+ }
+ if (!keyJSValue.isCell()) {
+ JSC::throwTypeError(globalObject, scope, "expected options to be a object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ JSValue formatJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "format"_s)));
+ if (formatJSValue.isUndefinedOrNull() || formatJSValue.isEmpty()) {
+ JSC::throwTypeError(globalObject, scope, "format is required"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ if (!formatJSValue.isString()) {
+ JSC::throwTypeError(globalObject, scope, "format must be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto format = formatJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+ auto keyJSValueCell = keyJSValue.asCell();
+ auto type = keyJSValueCell->type();
+
+ switch (type) {
+
+ case DataViewType:
+ case Uint8ArrayType:
+ case Uint8ClampedArrayType:
+ case Uint16ArrayType:
+ case Uint32ArrayType:
+ case Int8ArrayType:
+ case Int16ArrayType:
+ case Int32ArrayType:
+ case Float32ArrayType:
+ case Float64ArrayType:
+ case BigInt64ArrayType:
+ case BigUint64ArrayType: {
+ JSC::JSArrayBufferView* view = jsCast<JSC::JSArrayBufferView*>(keyJSValueCell);
+
+ data = view->vector();
+ byteLength = view->length();
+ break;
+ }
+ case ArrayBufferType: {
+ auto* jsBuffer = jsDynamicCast<JSC::JSArrayBuffer*>(keyJSValueCell);
+ if (UNLIKELY(!jsBuffer)) {
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ throwException(globalObject, scope, createTypeError(globalObject, "ERR_INVALID_ARG_TYPE: expected key to be Buffer or array-like object"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto* buffer = jsBuffer->impl();
+ data = buffer->data();
+ byteLength = buffer->byteLength();
+ break;
+ }
+ default: {
+ if (auto* keyObj = jsDynamicCast<JSC::JSObject*>(keyJSValue)) {
+ if (format != "jwk"_s) {
+ JSC::throwTypeError(globalObject, scope, "format should be 'jwk' when key type is 'object'"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto jwk = WebCore::convertDictionary<JsonWebKey>(*globalObject, keyJSValue);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (jwk.kty == "OKP"_s) {
+ if (jwk.crv == "Ed25519"_s) {
+ auto result = CryptoKeyOKP::importPublicJwk(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::Ed25519, WTFMove(jwk), true, CryptoKeyUsageVerify);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ if (impl->type() == CryptoKeyType::Private) {
+ return KeyObject__createOKPFromPrivate(globalObject, impl.get().exportKey(), CryptoKeyOKP::NamedCurve::Ed25519, CryptoAlgorithmIdentifier::Ed25519);
+ }
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (jwk.crv == "X25519"_s) {
+ auto result = CryptoKeyOKP::importPublicJwk(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::X25519, WTFMove(jwk), true, CryptoKeyUsageVerify);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid X25519 public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ if (impl->type() == CryptoKeyType::Private) {
+ return KeyObject__createOKPFromPrivate(globalObject, impl.get().exportKey(), CryptoKeyOKP::NamedCurve::X25519, CryptoAlgorithmIdentifier::Ed25519);
+ }
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else {
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported OKP curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ } else if (jwk.kty == "EC"_s) {
+ auto result = CryptoKeyEC::importJwk(CryptoAlgorithmIdentifier::ECDSA, jwk.crv, WTFMove(jwk), true, jwk.usages);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ if (impl->type() == CryptoKeyType::Private) {
+ return KeyObject__createECFromPrivate(globalObject, impl.get().platformKey(), impl.get().namedCurve(), CryptoAlgorithmIdentifier::ECDSA);
+ }
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (jwk.kty == "RSA"_s) {
+ auto result = CryptoKeyRSA::importJwk(CryptoAlgorithmIdentifier::RSA_OAEP, std::nullopt, WTFMove(jwk), true, jwk.usages);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid RSA public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ if (impl->type() == CryptoKeyType::Private) {
+ return KeyObject__createRSAFromPrivate(globalObject, impl.get().platformKey(), CryptoAlgorithmIdentifier::RSA_OAEP);
+ }
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else {
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ }
+ }
+ }
+
+ if (format == "jwk"_s) {
+ JSC::throwTypeError(globalObject, scope, "The \"key\" property must be of type object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ if (UNLIKELY(!data) || UNLIKELY(!byteLength)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "ERR_INVALID_ARG_TYPE: expected key to be Buffer or array-like object"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+
+ if (format == "pem"_s) {
+ auto pem = KeyObject__ParsePublicKeyPEM((const char*)data, byteLength);
+ if (!pem.key) {
+ // maybe is a private pem
+ auto bio = BIOPtr(BIO_new_mem_buf(const_cast<char*>((char*)data), byteLength));
+ JSValue passphraseJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "passphrase"_s)));
+ PrivateKeyPassphrase passphrase = { nullptr, 0 };
+
+ auto hasPassphrase = !passphraseJSValue.isUndefinedOrNull() && !passphraseJSValue.isEmpty();
+
+ if (hasPassphrase) {
+ if (passphraseJSValue.isString()) {
+ auto passphrase_wtfstr = passphraseJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (!passphrase_wtfstr.isNull()) {
+ if (auto pass = passphrase_wtfstr.tryGetUTF8()) {
+ if (pass.has_value()) {
+ auto value = pass.value();
+ passphrase.passphrase = const_cast<char*>(value.data());
+ passphrase.passphrase_len = value.length();
+ }
+ }
+ }
+ } else if (auto* passphraseBuffer = jsDynamicCast<JSUint8Array*>(passphraseJSValue)) {
+ passphrase.passphrase = (char*)passphraseBuffer->vector();
+ passphrase.passphrase_len = passphraseBuffer->byteLength();
+ } else {
+ JSC::throwTypeError(globalObject, scope, "passphrase must be a Buffer or String"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ }
+
+ auto pkey = EvpPKeyPtr(PEM_read_bio_PrivateKey(bio.get(), nullptr, PasswordCallback, &passphrase));
+ if (!pkey) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid PEM data"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ return KeyObject__createPublicFromPrivate(globalObject, pkey.get());
+ }
+ auto pkey = EvpPKeyPtr(pem.key);
+ auto pKeyID = EVP_PKEY_id(pem.key);
+ if (pKeyID == EVP_PKEY_RSA || pKeyID == EVP_PKEY_RSA_PSS) {
+ if (pem.der_data) {
+ OPENSSL_clear_free(pem.der_data, pem.der_len);
+ }
+ auto impl = CryptoKeyRSA::create(pKeyID == EVP_PKEY_RSA_PSS ? CryptoAlgorithmIdentifier::RSA_PSS : CryptoAlgorithmIdentifier::RSA_OAEP, CryptoAlgorithmIdentifier::SHA_1, false, CryptoKeyType::Public, WTFMove(pkey), true, CryptoKeyUsageEncrypt);
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_ED25519) {
+ auto result = CryptoKeyOKP::importSpki(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::Ed25519, Vector<uint8_t>((uint8_t*)pem.der_data, (size_t)pem.der_len), true, CryptoKeyUsageVerify);
+ if (pem.der_data) {
+ OPENSSL_clear_free(pem.der_data, pem.der_len);
+ }
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_X25519) {
+ auto result = CryptoKeyOKP::importSpki(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::X25519, Vector<uint8_t>((uint8_t*)pem.der_data, (size_t)pem.der_len), true, CryptoKeyUsageVerify);
+ if (pem.der_data) {
+ OPENSSL_clear_free(pem.der_data, pem.der_len);
+ }
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_EC) {
+ EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(pkey.get());
+ if (UNLIKELY(ec_key == nullptr)) {
+ if (pem.der_data) {
+ OPENSSL_clear_free(pem.der_data, pem.der_len);
+ }
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
+ // Get the curve name
+ int curve_name = EC_GROUP_get_curve_name(ec_group);
+ if (curve_name == NID_undef) {
+ if (pem.der_data) {
+ OPENSSL_clear_free(pem.der_data, pem.der_len);
+ }
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unable to identify EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ CryptoKeyEC::NamedCurve curve;
+ if (curve_name == NID_X9_62_prime256v1)
+ curve = CryptoKeyEC::NamedCurve::P256;
+ else if (curve_name == NID_secp384r1)
+ curve = CryptoKeyEC::NamedCurve::P384;
+ else if (curve_name == NID_secp521r1)
+ curve = CryptoKeyEC::NamedCurve::P521;
+ else {
+ if (pem.der_data) {
+ OPENSSL_clear_free(pem.der_data, pem.der_len);
+ }
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto result = CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier::ECDH, curve, Vector<uint8_t>((uint8_t*)pem.der_data, (size_t)pem.der_len), true, CryptoKeyUsageVerify);
+ if (UNLIKELY(result == nullptr)) {
+ result = CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier::ECDSA, curve, Vector<uint8_t>((uint8_t*)pem.der_data, (size_t)pem.der_len), true, CryptoKeyUsageVerify);
+ }
+ if (pem.der_data) {
+ OPENSSL_clear_free(pem.der_data, pem.der_len);
+ }
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else {
+ if (pem.der_data) {
+ OPENSSL_clear_free(pem.der_data, pem.der_len);
+ }
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ }
+ if (format == "der"_s) {
+ JSValue typeJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "type"_s)));
+ WTF::String type = "spki"_s;
+ if (!typeJSValue.isUndefinedOrNull() && !typeJSValue.isEmpty()) {
+ if (!typeJSValue.isString()) {
+ JSC::throwTypeError(globalObject, scope, "type must be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ type = typeJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ }
+
+ if (type == "pkcs1"_s) {
+ // must be RSA
+ const unsigned char* p = reinterpret_cast<const unsigned char*>(data);
+ auto pkey = EvpPKeyPtr(d2i_PublicKey(EVP_PKEY_RSA, nullptr, &p, byteLength));
+ if (!pkey) {
+ // maybe is a private RSA key
+ const unsigned char* p = reinterpret_cast<const unsigned char*>(data);
+ pkey = EvpPKeyPtr(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &p, byteLength));
+ if (!pkey) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid PKCS#1"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto pKeyID = EVP_PKEY_id(pkey.get());
+ return KeyObject__createRSAFromPrivate(globalObject, pkey.get(), pKeyID == EVP_PKEY_RSA_PSS ? CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5 : CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5);
+ }
+
+ auto pKeyID = EVP_PKEY_id(pkey.get());
+ auto impl = CryptoKeyRSA::create(pKeyID == EVP_PKEY_RSA_PSS ? CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5 : CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5, CryptoAlgorithmIdentifier::SHA_1, false, CryptoKeyType::Public, WTFMove(pkey), true, CryptoKeyUsageEncrypt);
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (type == "spki"_s) {
+ // We use d2i_PUBKEY() to import a public key.
+ const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
+ auto pkey = EvpPKeyPtr(d2i_PUBKEY(nullptr, &ptr, byteLength));
+ if (!pkey) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto pKeyID = EVP_PKEY_id(pkey.get());
+
+ if (pKeyID == EVP_PKEY_RSA || pKeyID == EVP_PKEY_RSA_PSS) {
+ auto impl = CryptoKeyRSA::create(pKeyID == EVP_PKEY_RSA_PSS ? CryptoAlgorithmIdentifier::RSA_PSS : CryptoAlgorithmIdentifier::RSA_OAEP, CryptoAlgorithmIdentifier::SHA_1, false, CryptoKeyType::Public, WTFMove(pkey), true, CryptoKeyUsageEncrypt);
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_ED25519) {
+ auto result = CryptoKeyOKP::importSpki(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::Ed25519, Vector<uint8_t>((uint8_t*)data, byteLength), true, CryptoKeyUsageVerify);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_X25519) {
+ auto result = CryptoKeyOKP::importSpki(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::X25519, Vector<uint8_t>((uint8_t*)data, byteLength), true, CryptoKeyUsageVerify);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else if (pKeyID == EVP_PKEY_EC) {
+ EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(pkey.get());
+ if (UNLIKELY(ec_key == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
+ // Get the curve name
+ int curve_name = EC_GROUP_get_curve_name(ec_group);
+ if (curve_name == NID_undef) {
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unable to identify EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ CryptoKeyEC::NamedCurve curve;
+ if (curve_name == NID_X9_62_prime256v1)
+ curve = CryptoKeyEC::NamedCurve::P256;
+ else if (curve_name == NID_secp384r1)
+ curve = CryptoKeyEC::NamedCurve::P384;
+ else if (curve_name == NID_secp521r1)
+ curve = CryptoKeyEC::NamedCurve::P521;
+ else {
+ EC_KEY_free(ec_key);
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported EC curve"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto alg = CryptoAlgorithmIdentifier::ECDH;
+ auto result = CryptoKeyEC::platformImportSpki(alg, curve, Vector<uint8_t>((uint8_t*)data, byteLength), true, CryptoKeyUsageVerify);
+ if (UNLIKELY(result == nullptr)) {
+ alg = CryptoAlgorithmIdentifier::ECDSA;
+ result = CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier::ECDSA, curve, Vector<uint8_t>((uint8_t*)data, byteLength), true, CryptoKeyUsageVerify);
+ }
+ if (UNLIKELY(result == nullptr)) {
+ throwException(globalObject, scope, createTypeError(globalObject, "Invalid EC public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ auto impl = result.releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
+ } else {
+ throwException(globalObject, scope, createTypeError(globalObject, "Unsupported public key"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ }
+
+ JSC::throwTypeError(globalObject, scope, "type should be 'pkcs1' or 'spki'"_s);
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ JSC::throwTypeError(globalObject, scope, "format should be 'pem' or 'der'"_s);
+ return JSValue::encode(JSC::jsUndefined());
+}
+
+JSC::EncodedJSValue KeyObject__createSecretKey(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
+{
+
+ JSValue bufferArg = callFrame->uncheckedArgument(0);
+ auto& vm = lexicalGlobalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto* structure = globalObject->JSCryptoKeyStructure();
+
+ if (!bufferArg.isCell()) {
+ throwException(lexicalGlobalObject, scope, createTypeError(lexicalGlobalObject, "ERR_INVALID_ARG_TYPE: expected Buffer or array-like object"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto bufferArgCell = bufferArg.asCell();
+ auto type = bufferArgCell->type();
+
+ switch (type) {
+
+ case DataViewType:
+ case Uint8ArrayType:
+ case Uint8ClampedArrayType:
+ case Uint16ArrayType:
+ case Uint32ArrayType:
+ case Int8ArrayType:
+ case Int16ArrayType:
+ case Int32ArrayType:
+ case Float32ArrayType:
+ case Float64ArrayType:
+ case BigInt64ArrayType:
+ case BigUint64ArrayType: {
+ JSC::JSArrayBufferView* view = jsCast<JSC::JSArrayBufferView*>(bufferArgCell);
+
+ void* data = view->vector();
+ size_t byteLength = view->length();
+ if (UNLIKELY(!data)) {
+ break;
+ }
+ auto impl = CryptoKeyHMAC::generateFromBytes(data, byteLength, CryptoAlgorithmIdentifier::HMAC, true, CryptoKeyUsageSign | CryptoKeyUsageVerify).releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, globalObject, WTFMove(impl)));
+ }
+ case ArrayBufferType: {
+ auto* jsBuffer = jsDynamicCast<JSC::JSArrayBuffer*>(bufferArgCell);
+ if (UNLIKELY(!jsBuffer)) {
+ break;
+ }
+ auto* buffer = jsBuffer->impl();
+ void* data = buffer->data();
+ size_t byteLength = buffer->byteLength();
+ if (UNLIKELY(!data)) {
+ break;
+ }
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto impl = CryptoKeyHMAC::generateFromBytes(data, byteLength, CryptoAlgorithmIdentifier::HMAC, true, CryptoKeyUsageSign | CryptoKeyUsageVerify).releaseNonNull();
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, globalObject, WTFMove(impl)));
+ }
+ default:
+ throwException(lexicalGlobalObject, scope, createTypeError(lexicalGlobalObject, "ERR_INVALID_ARG_TYPE: expected Buffer or array-like object"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+}
+
+JSC::EncodedJSValue KeyObject__Exports(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
+{
+
+ auto count = callFrame->argumentCount();
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (count < 2) {
+ JSC::throwTypeError(globalObject, scope, "exports requires 2 arguments"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ auto* key = jsDynamicCast<JSCryptoKey*>(callFrame->argument(0));
+ if (!key) {
+ // No JSCryptoKey instance
+ JSC::throwTypeError(globalObject, scope, "expected CryptoKey as first argument"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ auto& wrapped = key->wrapped();
+ auto key_type = wrapped.type();
+ auto id = wrapped.keyClass();
+ if (auto* options = jsDynamicCast<JSC::JSObject*>(callFrame->argument(1))) {
+ JSValue formatJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "format"_s)));
+ JSValue typeJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "type"_s)));
+ JSValue passphraseJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "passphrase"_s)));
+ auto hasPassphrase = !passphraseJSValue.isUndefinedOrNull() && !passphraseJSValue.isEmpty();
+ if (formatJSValue.isUndefinedOrNull() || formatJSValue.isEmpty()) {
+ JSC::throwTypeError(globalObject, scope, "format is expected to be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ auto string = formatJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (string == "jwk"_s && hasPassphrase) {
+ JSC::throwTypeError(globalObject, scope, "encryption is not supported for jwk format"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ switch (id) {
+ case CryptoKeyClass::HMAC: {
+ const auto& hmac = downcast<WebCore::CryptoKeyHMAC>(wrapped);
+ if (string == "buffer"_s) {
+ auto keyData = hmac.key();
+ auto size = keyData.size();
+ auto* buffer = jsCast<JSUint8Array*>(JSValue::decode(JSBuffer__bufferFromLength(globalObject, size)));
+ if (size > 0)
+ memcpy(buffer->vector(), keyData.data(), size);
+
+ return JSC::JSValue::encode(buffer);
+ } else if (string == "jwk"_s) {
+ const JsonWebKey& jwkValue = hmac.exportJwk();
+ Zig::GlobalObject* domGlobalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject);
+ return JSC::JSValue::encode(WebCore::convertDictionaryToJS(*globalObject, *domGlobalObject, jwkValue, true));
+ }
+ break;
+ }
+ case CryptoKeyClass::AES: {
+ const auto& aes = downcast<WebCore::CryptoKeyAES>(wrapped);
+ if (string == "buffer"_s) {
+ auto keyData = aes.key();
+ auto size = keyData.size();
+ auto* buffer = jsCast<JSUint8Array*>(JSValue::decode(JSBuffer__bufferFromLength(globalObject, size)));
+ if (size > 0)
+ memcpy(buffer->vector(), keyData.data(), size);
+
+ return JSC::JSValue::encode(buffer);
+ } else if (string == "jwk"_s) {
+ const JsonWebKey& jwkValue = aes.exportJwk();
+ Zig::GlobalObject* domGlobalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject);
+ return JSC::JSValue::encode(WebCore::convertDictionaryToJS(*globalObject, *domGlobalObject, jwkValue, true));
+ }
+ break;
+ }
+ case CryptoKeyClass::RSA: {
+ const auto& rsa = downcast<WebCore::CryptoKeyRSA>(wrapped);
+ if (string == "jwk"_s) {
+ const JsonWebKey& jwkValue = rsa.exportJwk();
+ Zig::GlobalObject* domGlobalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject);
+ return JSC::JSValue::encode(WebCore::convertDictionaryToJS(*globalObject, *domGlobalObject, jwkValue, true));
+ } else {
+ WTF::String type = "pkcs1"_s;
+ if (!typeJSValue.isUndefinedOrNull() && !typeJSValue.isEmpty()) {
+ if (!typeJSValue.isString()) {
+ JSC::throwTypeError(globalObject, scope, "type must be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ type = typeJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ }
+
+ auto* bio = BIO_new(BIO_s_mem());
+ auto* rsaKey = rsa.platformKey();
+ auto* rsa_ptr = EVP_PKEY_get0_RSA(rsaKey);
+
+ if (key_type == CryptoKeyType::Public) {
+ if (string == "pem"_s) {
+ if (type == "pkcs1"_s) {
+ if (PEM_write_bio_RSAPublicKey(bio, rsa_ptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write public key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else if (type == "spki"_s) {
+ if (PEM_write_bio_PUBKEY(bio, rsaKey) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write public key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'pkcs1' or 'spki'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ } else if (string == "der"_s) {
+ if (type == "pkcs1"_s) {
+ if (i2d_RSAPublicKey_bio(bio, rsa_ptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write public key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else if (type == "spki"_s) {
+ if (i2d_PUBKEY_bio(bio, rsaKey) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write public key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'pkcs1' or 'spki'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "format expected to be 'der', 'pem' or 'jwk'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSValue cipherJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "cipher"_s)));
+
+ const EVP_CIPHER* cipher = nullptr;
+ if (!cipherJSValue.isUndefinedOrNull() && !cipherJSValue.isEmpty() && cipherJSValue.isString()) {
+ auto cipher_wtfstr = cipherJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (!cipher_wtfstr.isNull()) {
+ auto cipherOrError = cipher_wtfstr.tryGetUTF8();
+ if (!cipherOrError.has_value()) {
+ JSC::throwTypeError(globalObject, scope, "invalid cipher name"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ } else {
+ auto value = cipherOrError.value();
+ auto cipher_str = value.data();
+ if (cipher_str != nullptr) {
+ cipher = EVP_get_cipherbyname(cipher_str);
+ }
+ }
+ }
+ }
+ void* passphrase = nullptr;
+ size_t passphrase_len = 0;
+ if (hasPassphrase) {
+ if (!cipher) {
+ JSC::throwTypeError(globalObject, scope, "cipher is required when passphrase is specified"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ if (passphraseJSValue.isString()) {
+ auto passphrase_wtfstr = passphraseJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (!passphrase_wtfstr.isNull()) {
+ if (auto pass = passphrase_wtfstr.tryGetUTF8()) {
+ if (pass.has_value()) {
+ auto value = pass.value();
+ passphrase = const_cast<char*>(value.data());
+ passphrase_len = value.length();
+ }
+ }
+ }
+ } else if (auto* passphraseBuffer = jsDynamicCast<JSUint8Array*>(passphraseJSValue)) {
+ passphrase = passphraseBuffer->vector();
+ passphrase_len = passphraseBuffer->byteLength();
+ } else {
+ JSC::throwTypeError(globalObject, scope, "passphrase must be a Buffer or String"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ }
+
+ if (string == "pem"_s) {
+ if (type == "pkcs1"_s) {
+ if (PEM_write_bio_RSAPrivateKey(bio, rsa_ptr, cipher, (unsigned char*)passphrase, passphrase_len, nullptr, nullptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write private key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else if (type == "pkcs8"_s) {
+ if (PEM_write_bio_PKCS8PrivateKey(bio, rsaKey, cipher, (char*)passphrase, passphrase_len, nullptr, nullptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write private key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'pkcs1' or 'pkcs8'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else if (string == "der"_s) {
+ if (type == "pkcs1"_s) {
+ if (i2d_RSAPrivateKey_bio(bio, rsa_ptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write private key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else if (type == "pkcs8"_s) {
+ if (i2d_PKCS8PrivateKey_bio(bio, rsaKey, cipher, (char*)passphrase, passphrase_len, nullptr, nullptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write private key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'pkcs1' or 'pkcs8'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "format expected to be 'der', 'pem' or 'jwk'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ }
+
+ BUF_MEM* bptr;
+ BIO_get_mem_ptr(bio, &bptr);
+ auto length = bptr->length;
+ if (string == "pem"_s) {
+ auto str = WTF::String::fromUTF8(bptr->data, length);
+ return JSValue::encode(JSC::jsString(vm, str));
+ }
+
+ auto* buffer = jsCast<JSUint8Array*>(JSValue::decode(JSBuffer__bufferFromLength(globalObject, length)));
+ if (length > 0)
+ memcpy(buffer->vector(), bptr->data, length);
+
+ BIO_free(bio);
+ return JSC::JSValue::encode(buffer);
+ }
+ }
+ case CryptoKeyClass::EC: {
+ const auto& ec = downcast<WebCore::CryptoKeyEC>(wrapped);
+ if (string == "jwk"_s) {
+ auto result = ec.exportJwk();
+ if (result.hasException()) {
+ WebCore::propagateException(*globalObject, scope, result.releaseException());
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ const JsonWebKey& jwkValue = result.releaseReturnValue();
+ Zig::GlobalObject* domGlobalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject);
+ return JSC::JSValue::encode(WebCore::convertDictionaryToJS(*globalObject, *domGlobalObject, jwkValue, true));
+ } else {
+ WTF::String type = "spki"_s;
+ if (!typeJSValue.isUndefinedOrNull() && !typeJSValue.isEmpty()) {
+ if (!typeJSValue.isString()) {
+ JSC::throwTypeError(globalObject, scope, "type must be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ type = typeJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ }
+
+ auto* bio = BIO_new(BIO_s_mem());
+ auto* ecKey = ec.platformKey();
+ auto* ec_ptr = EVP_PKEY_get1_EC_KEY(ecKey);
+
+ if (key_type == CryptoKeyType::Public) {
+ if (string == "pem"_s) {
+ if (type == "spki"_s) {
+ if (PEM_write_bio_PUBKEY(bio, ecKey) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write public key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'spki'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ } else if (string == "der"_s) {
+ if (type == "spki"_s) {
+ if (i2d_PUBKEY_bio(bio, ecKey) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write public key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'spki'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "format expected to be 'der', 'pem' or 'jwk'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSValue passphraseJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "passphrase"_s)));
+ JSValue cipherJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "cipher"_s)));
+
+ const EVP_CIPHER* cipher = nullptr;
+ if (!cipherJSValue.isUndefinedOrNull() && !cipherJSValue.isEmpty()) {
+ auto cipher_wtfstr = cipherJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (!cipher_wtfstr.isNull()) {
+ auto cipherOrError = cipher_wtfstr.tryGetUTF8();
+ if (!cipherOrError.has_value()) {
+ JSC::throwTypeError(globalObject, scope, "invalid cipher name"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ } else {
+ auto value = cipherOrError.value();
+ auto cipher_str = value.data();
+ if (cipher_str != nullptr) {
+ cipher = EVP_get_cipherbyname(cipher_str);
+ }
+ }
+ }
+ }
+ void* passphrase = nullptr;
+ size_t passphrase_len = 0;
+ auto hasPassphrase = !passphraseJSValue.isUndefinedOrNull() && !passphraseJSValue.isEmpty();
+
+ if (hasPassphrase) {
+ if (!cipher) {
+ JSC::throwTypeError(globalObject, scope, "cipher is required when passphrase is specified"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ if (passphraseJSValue.isString()) {
+ auto passphrase_wtfstr = passphraseJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (!passphrase_wtfstr.isNull()) {
+ if (auto pass = passphrase_wtfstr.tryGetUTF8()) {
+ if (pass.has_value()) {
+ auto value = pass.value();
+ passphrase = const_cast<char*>(value.data());
+ passphrase_len = value.length();
+ }
+ }
+ }
+ } else if (auto* passphraseBuffer = jsDynamicCast<JSUint8Array*>(passphraseJSValue)) {
+ passphrase = passphraseBuffer->vector();
+ passphrase_len = passphraseBuffer->byteLength();
+ } else {
+ JSC::throwTypeError(globalObject, scope, "passphrase must be a Buffer or String"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ }
+
+ if (string == "pem"_s) {
+ if (type == "sec1"_s) {
+ if (PEM_write_bio_ECPrivateKey(bio, ec_ptr, cipher, (unsigned char*)passphrase, passphrase_len, nullptr, nullptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write private key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else if (type == "pkcs8"_s) {
+ if (PEM_write_bio_PKCS8PrivateKey(bio, ecKey, cipher, (char*)passphrase, passphrase_len, nullptr, nullptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write private key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'sec1' or 'pkcs8'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else if (string == "der"_s) {
+ if (type == "sec1"_s) {
+ if (i2d_ECPrivateKey_bio(bio, ec_ptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write private key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else if (type == "pkcs8"_s) {
+ if (i2d_PKCS8PrivateKey_bio(bio, ecKey, cipher, (char*)passphrase, passphrase_len, nullptr, nullptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write private key"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'sec1' or 'pkcs8'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "format expected to be 'der', 'pem' or 'jwk'"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ }
+
+ BUF_MEM* bptr;
+ BIO_get_mem_ptr(bio, &bptr);
+ auto length = bptr->length;
+ if (string == "pem"_s) {
+ auto str = WTF::String::fromUTF8(bptr->data, length);
+ return JSValue::encode(JSC::jsString(vm, str));
+ }
+
+ auto* buffer = jsCast<JSUint8Array*>(JSValue::decode(JSBuffer__bufferFromLength(globalObject, length)));
+ if (length > 0)
+ memcpy(buffer->vector(), bptr->data, length);
+
+ BIO_free(bio);
+ return JSC::JSValue::encode(buffer);
+ }
+ }
+ case CryptoKeyClass::OKP: {
+ const auto& okpKey = downcast<WebCore::CryptoKeyOKP>(wrapped);
+ if (string == "jwk"_s) {
+ auto result = okpKey.exportJwk();
+ if (result.hasException()) {
+ WebCore::propagateException(*globalObject, scope, result.releaseException());
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ const JsonWebKey& jwkValue = result.releaseReturnValue();
+ Zig::GlobalObject* domGlobalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject);
+ return JSC::JSValue::encode(WebCore::convertDictionaryToJS(*globalObject, *domGlobalObject, jwkValue, true));
+ } else {
+ WTF::String type = "pkcs8"_s;
+ if (!typeJSValue.isUndefinedOrNull() && !typeJSValue.isEmpty()) {
+ if (!typeJSValue.isString()) {
+ JSC::throwTypeError(globalObject, scope, "type must be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ type = typeJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ }
+
+ auto keyData = okpKey.exportKey();
+ auto* bio = BIO_new(BIO_s_mem());
+
+ EVP_PKEY* evpKey;
+ // TODO: CHECK THIS WHEN X488 AND ED448 ARE ADDED
+ if (okpKey.type() == CryptoKeyType::Private) {
+ evpKey = EVP_PKEY_new_raw_private_key(okpKey.namedCurve() == CryptoKeyOKP::NamedCurve::X25519 ? EVP_PKEY_X25519 : EVP_PKEY_ED25519, nullptr, keyData.data(), keyData.size());
+ JSValue passphraseJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "passphrase"_s)));
+ JSValue cipherJSValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "cipher"_s)));
+
+ const EVP_CIPHER* cipher = nullptr;
+ if (!cipherJSValue.isUndefinedOrNull() && !cipherJSValue.isEmpty() && cipherJSValue.isString()) {
+ auto cipher_wtfstr = cipherJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (!cipher_wtfstr.isNull()) {
+ auto cipherOrError = cipher_wtfstr.tryGetUTF8();
+ if (!cipherOrError.has_value()) {
+ JSC::throwTypeError(globalObject, scope, "invalid cipher name"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ } else {
+ auto value = cipherOrError.value();
+ auto cipher_str = value.data();
+ if (cipher_str != nullptr) {
+ cipher = EVP_get_cipherbyname(cipher_str);
+ }
+ }
+ }
+ }
+ void* passphrase = nullptr;
+ size_t passphrase_len = 0;
+ auto hasPassphrase = !passphraseJSValue.isUndefinedOrNull() && !passphraseJSValue.isEmpty();
+
+ if (hasPassphrase) {
+ if (!cipher) {
+ JSC::throwTypeError(globalObject, scope, "cipher is required when passphrase is specified"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ if (passphraseJSValue.isString()) {
+ auto passphrase_wtfstr = passphraseJSValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (!passphrase_wtfstr.isNull()) {
+ if (auto pass = passphrase_wtfstr.tryGetUTF8()) {
+ if (pass.has_value()) {
+ auto value = pass.value();
+ passphrase = const_cast<char*>(value.data());
+ passphrase_len = value.length();
+ }
+ }
+ }
+ } else if (auto* passphraseBuffer = jsDynamicCast<JSUint8Array*>(passphraseJSValue)) {
+ passphrase = passphraseBuffer->vector();
+ passphrase_len = passphraseBuffer->byteLength();
+ } else {
+ JSC::throwTypeError(globalObject, scope, "passphrase must be a Buffer or String"_s);
+ BIO_free(bio);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ }
+
+ if (string == "pem"_s) {
+ if (type == "pkcs8"_s) {
+ if (PEM_write_bio_PKCS8PrivateKey(bio, evpKey, cipher, (char*)passphrase, passphrase_len, nullptr, nullptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write private key"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'pkcs8'"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else if (string == "der"_s) {
+ if (type == "pkcs8"_s) {
+ if (i2d_PKCS8PrivateKey_bio(bio, evpKey, cipher, (char*)passphrase, passphrase_len, nullptr, nullptr) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write private key"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'pkcs8'"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "format expected to be 'der', 'pem' or 'jwk'"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ evpKey = EVP_PKEY_new_raw_public_key(okpKey.namedCurve() == CryptoKeyOKP::NamedCurve::X25519 ? EVP_PKEY_X25519 : EVP_PKEY_ED25519, nullptr, keyData.data(), keyData.size());
+ if (string == "pem"_s) {
+ if (type == "spki"_s) {
+ if (PEM_write_bio_PUBKEY(bio, evpKey) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write public key"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'spki'"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ } else if (string == "der"_s) {
+ if (type == "spki"_s) {
+ if (i2d_PUBKEY_bio(bio, evpKey) != 1) {
+ JSC::throwTypeError(globalObject, scope, "Failed to write public key"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "type should be 'spki'"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ } else {
+ JSC::throwTypeError(globalObject, scope, "format expected to be 'der', 'pem' or 'jwk'"_s);
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ }
+
+ BUF_MEM* bptr;
+ BIO_get_mem_ptr(bio, &bptr);
+ auto length = bptr->length;
+ if (string == "pem"_s) {
+ auto str = WTF::String::fromUTF8(bptr->data, length);
+ EVP_PKEY_free(evpKey);
+ return JSValue::encode(JSC::jsString(vm, str));
+ }
+
+ auto* buffer = jsCast<JSUint8Array*>(JSValue::decode(JSBuffer__bufferFromLength(globalObject, length)));
+ if (length > 0)
+ memcpy(buffer->vector(), bptr->data, length);
+
+ BIO_free(bio);
+ EVP_PKEY_free(evpKey);
+ return JSC::JSValue::encode(buffer);
+ }
+ }
+ case CryptoKeyClass::Raw: {
+ const auto& raw = downcast<WebCore::CryptoKeyRaw>(wrapped);
+ if (string == "buffer"_s) {
+ auto keyData = raw.key();
+ auto size = keyData.size();
+ auto* buffer = jsCast<JSUint8Array*>(JSValue::decode(JSBuffer__bufferFromLength(globalObject, size)));
+ if (size > 0)
+ memcpy(buffer->vector(), keyData.data(), size);
+
+ return JSC::JSValue::encode(buffer);
+ }
+
+ JSC::throwTypeError(globalObject, scope, "format is expected to be 'buffer'"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ default: {
+ JSC::throwTypeError(globalObject, scope, "Invalid Operation"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ }
+ JSC::throwTypeError(globalObject, scope, "format is expected to be 'buffer' or 'jwk'"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ } else {
+ JSC::throwTypeError(globalObject, scope, "expected options to be a object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+}
+
+static char* bignum_to_string(const BIGNUM* bn)
+{
+ char *tmp, *ret;
+ size_t len;
+
+ // Display large numbers in hex and small numbers in decimal. Converting to
+ // decimal takes quadratic time and is no more useful than hex for large
+ // numbers.
+ if (BN_num_bits(bn) < 32) {
+ return BN_bn2dec(bn);
+ }
+
+ tmp = BN_bn2hex(bn);
+ if (tmp == NULL) {
+ return NULL;
+ }
+
+ len = strlen(tmp) + 3;
+ ret = (char*)OPENSSL_malloc(len);
+ if (ret == NULL) {
+ OPENSSL_free(tmp);
+ return NULL;
+ }
+
+ // Prepend "0x", but place it after the "-" if negative.
+ if (tmp[0] == '-') {
+ OPENSSL_strlcpy(ret, "-0x", len);
+ OPENSSL_strlcat(ret, tmp + 1, len);
+ } else {
+ OPENSSL_strlcpy(ret, "0x", len);
+ OPENSSL_strlcat(ret, tmp, len);
+ }
+ OPENSSL_free(tmp);
+ return ret;
+}
+
+JSC::EncodedJSValue KeyObject_AsymmetricKeyDetails(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
+{
+
+ if (auto* key = jsDynamicCast<JSCryptoKey*>(callFrame->argument(0))) {
+ auto id = key->wrapped().algorithmIdentifier();
+ auto& vm = lexicalGlobalObject->vm();
+ switch (id) {
+ case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::RSA_OAEP:
+ case CryptoAlgorithmIdentifier::RSA_PSS: {
+ auto* obj = JSC::constructEmptyObject(lexicalGlobalObject);
+
+ auto& wrapped = key->wrapped();
+ const auto& rsa = downcast<WebCore::CryptoKeyRSA>(wrapped);
+ auto* platformKey = rsa.platformKey();
+ const BIGNUM* e; // Public Exponent
+ const BIGNUM* n; // Modulus
+ const RSA* rsa_key = EVP_PKEY_get0_RSA(platformKey);
+ if (rsa_key == nullptr) {
+ return JSValue::encode(JSC::jsUndefined());
+ }
+
+ RSA_get0_key(rsa_key, &n, &e, nullptr);
+
+ auto modulus_length = BN_num_bits(n);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "modulusLength"_s)), jsNumber(modulus_length), 0);
+
+ auto str = bignum_to_string(e);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "publicExponent"_s)), JSC::JSBigInt::stringToBigInt(lexicalGlobalObject, StringView::fromLatin1(str)), 0);
+ OPENSSL_free(str);
+
+ if (id == CryptoAlgorithmIdentifier::RSA_PSS) {
+ // Due to the way ASN.1 encoding works, default values are omitted when
+ // encoding the data structure. However, there are also RSA-PSS keys for
+ // which no parameters are set. In that case, the ASN.1 RSASSA-PSS-params
+ // sequence will be missing entirely and RSA_get0_pss_params will return
+ // nullptr. If parameters are present but all parameters are set to their
+ // default values, an empty sequence will be stored in the ASN.1 structure.
+ // In that case, RSA_get0_pss_params does not return nullptr but all fields
+ // of the returned RSA_PSS_PARAMS will be set to nullptr.
+
+ auto* params = RSA_get0_pss_params(rsa_key);
+ if (params != nullptr) {
+ int hash_nid = NID_sha1;
+ int mgf_nid = NID_mgf1;
+ int mgf1_hash_nid = NID_sha1;
+ int64_t salt_length = 20;
+
+ if (params->hashAlgorithm != nullptr) {
+ hash_nid = OBJ_obj2nid(params->hashAlgorithm->algorithm);
+ }
+ auto* hash_srt = OBJ_nid2ln(hash_nid);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "hashAlgorithm"_s)), Bun::toJS(lexicalGlobalObject, Bun::toString(hash_srt, strlen(hash_srt))), 0);
+ if (params->maskGenAlgorithm != nullptr) {
+ mgf_nid = OBJ_obj2nid(params->maskGenAlgorithm->algorithm);
+ if (mgf_nid == NID_mgf1) {
+ mgf1_hash_nid = OBJ_obj2nid(params->maskHash->algorithm);
+ }
+ }
+
+ // If, for some reason, the MGF is not MGF1, then the MGF1 hash function
+ // is intentionally not added to the object.
+ if (mgf_nid == NID_mgf1) {
+ auto* mgf1_hash_srt = OBJ_nid2ln(mgf1_hash_nid);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "mgf1HashAlgorithm"_s)), Bun::toJS(lexicalGlobalObject, Bun::toString(mgf1_hash_srt, strlen(mgf1_hash_srt))), 0);
+ }
+
+ if (params->saltLength != nullptr) {
+ if (ASN1_INTEGER_get_int64(&salt_length, params->saltLength) != 1) {
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ throwException(lexicalGlobalObject, scope, createTypeError(lexicalGlobalObject, "Failed to get saltLenght"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ }
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "saltLength"_s)), jsNumber(salt_length), 0);
+ }
+ }
+ return JSC::JSValue::encode(obj);
+ }
+ case CryptoAlgorithmIdentifier::ECDSA:
+ case CryptoAlgorithmIdentifier::ECDH: {
+ auto* obj = JSC::constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), 1);
+
+ auto& wrapped = key->wrapped();
+ const auto& ec = downcast<WebCore::CryptoKeyEC>(wrapped);
+ static const NeverDestroyed<String> values[] = {
+ MAKE_STATIC_STRING_IMPL("prime256v1"),
+ MAKE_STATIC_STRING_IMPL("secp384r1"),
+ MAKE_STATIC_STRING_IMPL("secp521r1"),
+ };
+
+ WTF::String named_curve;
+ switch (ec.namedCurve()) {
+ case CryptoKeyEC::NamedCurve::P256:
+ named_curve = values[0];
+ break;
+ case CryptoKeyEC::NamedCurve::P384:
+ named_curve = values[1];
+ break;
+ case CryptoKeyEC::NamedCurve::P521:
+ named_curve = values[2];
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ named_curve = WTF::emptyString();
+ }
+
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "namedCurve"_s)), JSC::jsString(vm, named_curve), 0);
+ return JSC::JSValue::encode(obj);
+ }
+ case CryptoAlgorithmIdentifier::Ed25519: {
+ auto* obj = JSC::constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), 1);
+ auto& wrapped = key->wrapped();
+ const auto& okp = downcast<WebCore::CryptoKeyOKP>(wrapped);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "namedCurve"_s)), JSC::jsString(vm, okp.namedCurveString()), 0);
+ return JSC::JSValue::encode(obj);
+ }
+ default:
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+ }
+ return JSC::JSValue::encode(JSC::jsUndefined());
+}
+
+JSC::EncodedJSValue KeyObject__generateKeyPairSync(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
+{
+ auto count = callFrame->argumentCount();
+ auto& vm = lexicalGlobalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (count < 1) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "generateKeyPairSync requires 1 arguments"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ auto type = callFrame->argument(0);
+ if (type.isUndefinedOrNull() || type.isEmpty() || !type.isString()) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "type is expected to be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto type_str = type.toWTFString(lexicalGlobalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+ Zig::GlobalObject* zigGlobalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto* structure = zigGlobalObject->JSCryptoKeyStructure();
+ // TODO: rsa-pss
+ if (type_str == "rsa"_s) {
+ if (count == 1) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "options.modulusLength are required for rsa"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto* options = jsDynamicCast<JSC::JSObject*>(callFrame->argument(1));
+ if (options == nullptr) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "options is expected to be a object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto modulusLengthJS = options->getIfPropertyExists(lexicalGlobalObject, PropertyName(Identifier::fromString(vm, "modulusLength"_s)));
+ if (!modulusLengthJS.isNumber()) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "options.modulusLength is expected to be a number"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto publicExponentJS = options->getIfPropertyExists(lexicalGlobalObject, PropertyName(Identifier::fromString(vm, "publicExponent"_s)));
+ uint32_t publicExponent = 0x10001;
+ if (publicExponentJS.isNumber()) {
+ publicExponent = publicExponentJS.toUInt32(lexicalGlobalObject);
+ } else if (!publicExponentJS.isUndefinedOrNull() && !publicExponentJS.isEmpty()) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "options.publicExponent is expected to be a number"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ uint8_t publicExponentArray[4];
+ publicExponentArray[0] = (uint8_t)(publicExponent >> 24);
+ publicExponentArray[1] = (uint8_t)(publicExponent >> 16);
+ publicExponentArray[2] = (uint8_t)(publicExponent >> 8);
+ publicExponentArray[3] = (uint8_t)publicExponent;
+
+ int modulusLength = modulusLengthJS.toUInt32(lexicalGlobalObject);
+ auto returnValue = JSC::JSValue {};
+ auto keyPairCallback = [&](CryptoKeyPair&& pair) {
+ pair.publicKey->setUsagesBitmap(pair.publicKey->usagesBitmap() & CryptoKeyUsageVerify);
+ pair.privateKey->setUsagesBitmap(pair.privateKey->usagesBitmap() & CryptoKeyUsageSign);
+
+ auto obj = JSC::constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), 2);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "publicKey"_s)), JSCryptoKey::create(structure, zigGlobalObject, pair.publicKey.releaseNonNull()), 0);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "privateKey"_s)), JSCryptoKey::create(structure, zigGlobalObject, pair.privateKey.releaseNonNull()), 0);
+ returnValue = obj;
+ };
+ auto failureCallback = [&]() {
+ throwException(lexicalGlobalObject, scope, createTypeError(lexicalGlobalObject, "Failed to generate key pair"_s));
+ };
+ // this is actually sync
+ CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSA_OAEP, CryptoAlgorithmIdentifier::SHA_1, false, modulusLength, Vector<uint8_t>((uint8_t*)&publicExponentArray, 4), true, CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt, WTFMove(keyPairCallback), WTFMove(failureCallback), zigGlobalObject->scriptExecutionContext());
+ return JSValue::encode(returnValue);
+ } else if (type_str == "ec"_s) {
+ if (count == 1) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "options.namedCurve is required for ec"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto* options = jsDynamicCast<JSC::JSObject*>(callFrame->argument(1));
+ if (options == nullptr) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "options is expected to be a object"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto namedCurveJS = options->getIfPropertyExists(lexicalGlobalObject, PropertyName(Identifier::fromString(vm, "namedCurve"_s)));
+ if (namedCurveJS.isUndefinedOrNull() || namedCurveJS.isEmpty() || !namedCurveJS.isString()) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "namedCurve is expected to be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto namedCurve = namedCurveJS.toWTFString(lexicalGlobalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if(namedCurve == "P-384"_s || namedCurve == "p384"_s || namedCurve == "secp384r1"_s) {
+ namedCurve = "P-384"_s;
+ } else if(namedCurve == "P-256"_s || namedCurve == "p256"_s || namedCurve == "prime256v1"_s) {
+ namedCurve = "P-256"_s;
+ } else if(namedCurve == "P-521"_s || namedCurve == "p521"_s || namedCurve == "secp521r1"_s) {
+ namedCurve = "P-521"_s;
+ }else {
+ throwException(lexicalGlobalObject, scope, createTypeError(lexicalGlobalObject, "curve not supported"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+
+ auto result = CryptoKeyEC::generatePair(CryptoAlgorithmIdentifier::ECDSA, namedCurve, true, CryptoKeyUsageSign | CryptoKeyUsageVerify);
+ if (result.hasException()) {
+ WebCore::propagateException(*lexicalGlobalObject, scope, result.releaseException());
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto pair = result.releaseReturnValue();
+ auto obj = JSC::constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), 2);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "publicKey"_s)), JSCryptoKey::create(structure, zigGlobalObject, pair.publicKey.releaseNonNull()), 0);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "privateKey"_s)), JSCryptoKey::create(structure, zigGlobalObject, pair.privateKey.releaseNonNull()), 0);
+ return JSValue::encode(obj);
+ } else if (type_str == "ed25519"_s) {
+ auto result = CryptoKeyOKP::generatePair(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::Ed25519, true, CryptoKeyUsageSign | CryptoKeyUsageVerify);
+ if (result.hasException()) {
+ WebCore::propagateException(*lexicalGlobalObject, scope, result.releaseException());
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto pair = result.releaseReturnValue();
+ auto obj = JSC::constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), 2);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "publicKey"_s)), JSCryptoKey::create(structure, zigGlobalObject, pair.publicKey.releaseNonNull()), 0);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "privateKey"_s)), JSCryptoKey::create(structure, zigGlobalObject, pair.privateKey.releaseNonNull()), 0);
+ return JSValue::encode(obj);
+ } else if (type_str == "x25519"_s) {
+ auto result = CryptoKeyOKP::generatePair(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::X25519, true, CryptoKeyUsageSign | CryptoKeyUsageVerify);
+ if (result.hasException()) {
+ WebCore::propagateException(*lexicalGlobalObject, scope, result.releaseException());
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ auto pair = result.releaseReturnValue();
+ auto obj = JSC::constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), 2);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "publicKey"_s)), JSCryptoKey::create(structure, zigGlobalObject, pair.publicKey.releaseNonNull()), 0);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "privateKey"_s)), JSCryptoKey::create(structure, zigGlobalObject, pair.privateKey.releaseNonNull()), 0);
+ return JSValue::encode(obj);
+ } else {
+ throwException(lexicalGlobalObject, scope, createTypeError(lexicalGlobalObject, "algorithm should be 'rsa', 'ec', 'x25519' or 'ed25519'"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ return JSValue::encode(JSC::jsUndefined());
+}
+JSC::EncodedJSValue KeyObject__generateKeySync(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
+{
+ auto count = callFrame->argumentCount();
+ auto& vm = lexicalGlobalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ if (count < 2) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "generateKeySync requires 2 arguments"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ auto type = callFrame->argument(0);
+ if (type.isUndefinedOrNull() || type.isEmpty() || !type.isString()) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "type is expected to be a string"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ auto type_str = type.toWTFString(lexicalGlobalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+ if (type_str == "hmac"_s) {
+ Zig::GlobalObject* zigGlobalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto* structure = zigGlobalObject->JSCryptoKeyStructure();
+ size_t lengthBits = 0;
+ auto length = callFrame->argument(1);
+ if (!length.isNumber()) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "length is expected to be a number"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ lengthBits = length.toUInt32(lexicalGlobalObject);
+ auto result = CryptoKeyHMAC::generate(lengthBits, WebCore::CryptoAlgorithmIdentifier::HMAC, true, CryptoKeyUsageSign | CryptoKeyUsageVerify);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(lexicalGlobalObject, scope, createTypeError(lexicalGlobalObject, "Invalid length"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(result.releaseNonNull())));
+ } else if (type_str == "aes"_s) {
+ Zig::GlobalObject* zigGlobalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto* structure = zigGlobalObject->JSCryptoKeyStructure();
+ size_t lengthBits = 0;
+ if (count > 1) {
+ auto length = callFrame->argument(1);
+ if (!length.isNumber()) {
+ JSC::throwTypeError(lexicalGlobalObject, scope, "length is expected to be a number"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+ lengthBits = length.toUInt32(lexicalGlobalObject);
+ }
+
+ auto result = CryptoKeyAES::generate(WebCore::CryptoAlgorithmIdentifier::AES_CBC, lengthBits, true, CryptoKeyUsageSign | CryptoKeyUsageVerify);
+ if (UNLIKELY(result == nullptr)) {
+ throwException(lexicalGlobalObject, scope, createTypeError(lexicalGlobalObject, "Invalid length"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(result.releaseNonNull())));
+ } else {
+ throwException(lexicalGlobalObject, scope, createTypeError(lexicalGlobalObject, "algorithm should be 'aes' or 'hmac'"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+}
+
+JSC::EncodedJSValue KeyObject__AsymmetricKeyType(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
+{
+ static const NeverDestroyed<String> values[] = {
+ MAKE_STATIC_STRING_IMPL("rsa"),
+ MAKE_STATIC_STRING_IMPL("rsa-pss"),
+ MAKE_STATIC_STRING_IMPL("ec"),
+ MAKE_STATIC_STRING_IMPL("x25519"),
+ MAKE_STATIC_STRING_IMPL("ed25519"),
+ };
+
+ // TODO: Look into DSA and DH
+ if (auto* key = jsDynamicCast<JSCryptoKey*>(callFrame->argument(0))) {
+ auto id = key->wrapped().algorithmIdentifier();
+ switch (id) {
+ case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::RSA_OAEP:
+ return JSC::JSValue::encode(JSC::jsStringWithCache(lexicalGlobalObject->vm(), values[0]));
+ case CryptoAlgorithmIdentifier::RSA_PSS:
+ return JSC::JSValue::encode(JSC::jsStringWithCache(lexicalGlobalObject->vm(), values[1]));
+ case CryptoAlgorithmIdentifier::ECDSA:
+ case CryptoAlgorithmIdentifier::ECDH:
+ return JSC::JSValue::encode(JSC::jsStringWithCache(lexicalGlobalObject->vm(), values[2]));
+ case CryptoAlgorithmIdentifier::Ed25519: {
+ const auto& okpKey = downcast<WebCore::CryptoKeyOKP>(key->wrapped());
+ // TODO: CHECK THIS WHEN X488 AND ED448 ARE ADDED
+ return JSC::JSValue::encode(JSC::jsStringWithCache(lexicalGlobalObject->vm(), String(okpKey.namedCurve() == CryptoKeyOKP::NamedCurve::X25519 ? values[3] : values[4])));
+ }
+ default:
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+ }
+ return JSC::JSValue::encode(JSC::jsUndefined());
+}
+
+static Vector<uint8_t> GetRawKeyFromSecret(WebCore::CryptoKey& key)
+{
+ auto id = key.keyClass();
+ switch (id) {
+ case CryptoKeyClass::HMAC: {
+ const auto& hmac = downcast<WebCore::CryptoKeyHMAC>(key);
+ return hmac.key();
+ }
+ case CryptoKeyClass::AES: {
+ const auto& aes = downcast<WebCore::CryptoKeyAES>(key);
+ return aes.key();
+ }
+ case CryptoKeyClass::Raw: {
+ const auto& raw = downcast<WebCore::CryptoKeyRaw>(key);
+ return raw.key();
+ }
+ default: {
+ Vector<uint8_t> empty;
+ return empty;
+ }
+ }
+}
+static AsymmetricKeyValue GetInternalAsymmetricKey(WebCore::CryptoKey& key)
+{
+ auto id = key.algorithmIdentifier();
+ switch (id) {
+ case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::RSA_OAEP:
+ case CryptoAlgorithmIdentifier::RSA_PSS:
+ return (AsymmetricKeyValue) { .key = downcast<WebCore::CryptoKeyRSA>(key).platformKey(), .owned = false };
+ case CryptoAlgorithmIdentifier::ECDSA:
+ case CryptoAlgorithmIdentifier::ECDH:
+ return (AsymmetricKeyValue) { .key = downcast<WebCore::CryptoKeyEC>(key).platformKey(), .owned = false };
+ case CryptoAlgorithmIdentifier::Ed25519: {
+ const auto& okpKey = downcast<WebCore::CryptoKeyOKP>(key);
+ auto keyData = okpKey.exportKey();
+ if (okpKey.type() == CryptoKeyType::Private) {
+ auto* evp_key = EVP_PKEY_new_raw_private_key(okpKey.namedCurve() == CryptoKeyOKP::NamedCurve::X25519 ? EVP_PKEY_X25519 : EVP_PKEY_ED25519, nullptr, keyData.data(), keyData.size());
+ return (AsymmetricKeyValue) { .key = evp_key, .owned = true };
+ } else {
+ auto* evp_key = EVP_PKEY_new_raw_public_key(okpKey.namedCurve() == CryptoKeyOKP::NamedCurve::X25519 ? EVP_PKEY_X25519 : EVP_PKEY_ED25519, nullptr, keyData.data(), keyData.size());
+ return (AsymmetricKeyValue) { .key = evp_key, .owned = true };
+ }
+ }
+ default:
+ return (AsymmetricKeyValue) { .key = NULL, .owned = false };
+ }
+}
+
+JSC::EncodedJSValue KeyObject__Equals(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
+{
+ if (auto* key = jsDynamicCast<JSCryptoKey*>(callFrame->argument(0))) {
+ if (auto* key2 = jsDynamicCast<JSCryptoKey*>(callFrame->argument(1))) {
+ auto& wrapped = key->wrapped();
+ auto& wrapped2 = key2->wrapped();
+ auto key_type = wrapped.type();
+ auto key_class = wrapped.keyClass();
+ if (key_type != wrapped2.type()) {
+ return JSC::JSValue::encode(jsBoolean(false));
+ }
+
+ if (key_type == CryptoKeyType::Secret) {
+ auto keyData = GetRawKeyFromSecret(wrapped);
+ auto keyData2 = GetRawKeyFromSecret(wrapped2);
+ auto size = keyData.size();
+
+ if (size != keyData2.size()) {
+ return JSC::JSValue::encode(jsBoolean(false));
+ }
+ return JSC::JSValue::encode(jsBoolean(CRYPTO_memcmp(keyData.data(), keyData2.data(), size) == 0));
+ }
+ auto evp_key = GetInternalAsymmetricKey(wrapped);
+ auto evp_key2 = GetInternalAsymmetricKey(wrapped2);
+
+ int ok = !evp_key.key || !evp_key2.key ? -2 : EVP_PKEY_cmp(evp_key.key, evp_key2.key);
+
+ if (evp_key.key && evp_key.owned) {
+ EVP_PKEY_free(evp_key.key);
+ }
+ if (evp_key2.key && evp_key2.owned) {
+ EVP_PKEY_free(evp_key2.key);
+ }
+ if (ok == -2) {
+ auto& vm = lexicalGlobalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ throwException(lexicalGlobalObject, scope, createTypeError(lexicalGlobalObject, "ERR_CRYPTO_UNSUPPORTED_OPERATION"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+ return JSC::JSValue::encode(jsBoolean(ok == 1));
+ }
+ }
+ return JSC::JSValue::encode(jsBoolean(false));
+}
+
+JSC::EncodedJSValue KeyObject__SymmetricKeySize(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
+{
+ if (auto* key = jsDynamicCast<JSCryptoKey*>(callFrame->argument(0))) {
+ auto& wrapped = key->wrapped();
+ auto id = wrapped.keyClass();
+ size_t size = 0;
+ switch (id) {
+ case CryptoKeyClass::HMAC: {
+ const auto& hmac = downcast<WebCore::CryptoKeyHMAC>(wrapped);
+ auto keyData = hmac.key();
+ size = keyData.size();
+ break;
+ }
+ case CryptoKeyClass::AES: {
+ const auto& aes = downcast<WebCore::CryptoKeyAES>(wrapped);
+ auto keyData = aes.key();
+ size = keyData.size();
+ break;
+ }
+ case CryptoKeyClass::Raw: {
+ const auto& raw = downcast<WebCore::CryptoKeyRaw>(wrapped);
+ auto keyData = raw.key();
+ size = keyData.size();
+ break;
+ }
+ default: {
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+ }
+
+ if (!size) {
+ return JSC::JSValue::encode(JSC::jsUndefined());
+ }
+
+ return JSC::JSValue::encode(JSC::jsNumber(size));
+ }
+
+ return JSC::JSValue::encode(JSC::jsUndefined());
+}
+
+} \ No newline at end of file
diff --git a/src/bun.js/bindings/KeyObject.h b/src/bun.js/bindings/KeyObject.h
new file mode 100644
index 000000000..c9b172e3b
--- /dev/null
+++ b/src/bun.js/bindings/KeyObject.h
@@ -0,0 +1,18 @@
+
+#pragma once
+
+#include "root.h"
+#include "helpers.h"
+namespace WebCore {
+
+JSC::EncodedJSValue KeyObject__AsymmetricKeyType(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC::EncodedJSValue KeyObject_AsymmetricKeyDetails(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC::EncodedJSValue KeyObject__SymmetricKeySize(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame);
+JSC::EncodedJSValue KeyObject__Equals(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC::EncodedJSValue KeyObject__Exports(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame);
+JSC::EncodedJSValue KeyObject__createSecretKey(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC::EncodedJSValue KeyObject__createPublicKey(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC::EncodedJSValue KeyObject__createPrivateKey(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC::EncodedJSValue KeyObject__generateKeySync(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC::EncodedJSValue KeyObject__generateKeyPairSync(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+} \ No newline at end of file
diff --git a/src/bun.js/bindings/ModuleLoader.cpp b/src/bun.js/bindings/ModuleLoader.cpp
index 252c446b1..ac980d062 100644
--- a/src/bun.js/bindings/ModuleLoader.cpp
+++ b/src/bun.js/bindings/ModuleLoader.cpp
@@ -27,7 +27,6 @@
#include "EventEmitter.h"
#include "JSEventEmitter.h"
-#include "CommonJSModuleRecord.h"
#include <JavaScriptCore/JSModuleLoader.h>
#include <JavaScriptCore/Completion.h>
#include <JavaScriptCore/JSModuleNamespaceObject.h>
@@ -93,13 +92,20 @@ generateInternalModuleSourceCode(JSC::JSGlobalObject* globalObject, InternalModu
exportNames.reserveCapacity(len);
exportValues.ensureCapacity(len);
- exportNames.append(vm.propertyNames->defaultKeyword);
- exportValues.append(object);
+ bool hasDefault = false;
for (auto& entry : properties) {
+ if (UNLIKELY(entry == vm.propertyNames->defaultKeyword)) {
+ hasDefault = true;
+ }
exportNames.append(entry);
exportValues.append(object->get(globalObject, entry));
}
+
+ if (!hasDefault) {
+ exportNames.append(vm.propertyNames->defaultKeyword);
+ exportValues.append(object);
+ }
};
}
@@ -139,7 +145,7 @@ PendingVirtualModuleResult* PendingVirtualModuleResult::create(VM& vm, Structure
}
Structure* PendingVirtualModuleResult::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
}
PendingVirtualModuleResult::PendingVirtualModuleResult(VM& vm, Structure* structure)
@@ -459,7 +465,7 @@ JSValue fetchCommonJSModule(
}
}
- if (JSC::JSValue virtualModuleResult = JSValue::decode(Bun__runVirtualModule(globalObject, specifier))) {
+ if (JSC::JSValue virtualModuleResult = Bun::runVirtualModule(globalObject, specifier)) {
JSPromise* promise = jsCast<JSPromise*>(handleVirtualModuleResult<true>(globalObject, virtualModuleResult, res, specifier, referrer));
switch (promise->status(vm)) {
case JSPromise::Status::Rejected: {
@@ -534,7 +540,7 @@ JSValue fetchCommonJSModule(
RELEASE_AND_RETURN(scope, {});
}
- target->putDirect(vm, WebCore::clientData(vm)->builtinNames().exportsPublicName(), value, value.isCell() && value.isCallable() ? JSC::PropertyAttribute::Function | 0 : 0);
+ target->putDirect(vm, WebCore::clientData(vm)->builtinNames().exportsPublicName(), value, 0);
target->hasEvaluated = true;
RELEASE_AND_RETURN(scope, target);
}
@@ -634,7 +640,7 @@ static JSValue fetchESMSourceCode(
}
}
- if (JSC::JSValue virtualModuleResult = JSValue::decode(Bun__runVirtualModule(globalObject, specifier))) {
+ if (JSC::JSValue virtualModuleResult = Bun::runVirtualModule(globalObject, specifier)) {
return handleVirtualModuleResult<allowPromise>(globalObject, virtualModuleResult, res, specifier, referrer);
}
diff --git a/src/bun.js/bindings/ModuleLoader.h b/src/bun.js/bindings/ModuleLoader.h
index ee726ebcf..72dd8b49a 100644
--- a/src/bun.js/bindings/ModuleLoader.h
+++ b/src/bun.js/bindings/ModuleLoader.h
@@ -4,6 +4,9 @@
#include "JavaScriptCore/JSCInlines.h"
#include "BunClientData.h"
+extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultResolve(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame);
+extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultReject(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame);
+
namespace Zig {
class GlobalObject;
}
diff --git a/src/bun.js/bindings/NodeVMScript.cpp b/src/bun.js/bindings/NodeVMScript.cpp
index 05921dd8d..e0e0dc93a 100644
--- a/src/bun.js/bindings/NodeVMScript.cpp
+++ b/src/bun.js/bindings/NodeVMScript.cpp
@@ -19,6 +19,7 @@
#include "JavaScriptCore/JSWeakMap.h"
#include "JavaScriptCore/JSWeakMapInlines.h"
#include "JavaScriptCore/JSWithScope.h"
+#include "JavaScriptCore/JSGlobalProxyInlines.h"
#include "Buffer.h"
#include "GCDefferalContext.h"
#include "Buffer.h"
@@ -120,7 +121,7 @@ constructScript(JSGlobalObject* globalObject, CallFrame* callFrame, JSValue newT
auto scope = DECLARE_THROW_SCOPE(vm);
SourceCode source(
- JSC::StringSourceProvider::create(sourceString, JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(options.filename)), options.filename, TextPosition(options.lineOffset, options.columnOffset)),
+ JSC::StringSourceProvider::create(sourceString, JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(options.filename)), options.filename, JSC::SourceTaintedOrigin::Untainted, TextPosition(options.lineOffset, options.columnOffset)),
options.lineOffset.zeroBasedInt(), options.columnOffset.zeroBasedInt());
RETURN_IF_EXCEPTION(scope, {});
NodeVMScript* script = NodeVMScript::create(vm, globalObject, structure, source);
@@ -263,7 +264,7 @@ JSC_DEFINE_HOST_FUNCTION(vmModuleRunInNewContext, (JSGlobalObject * globalObject
}
}
SourceCode source(
- JSC::StringSourceProvider::create(sourceString, JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(options.filename)), options.filename, TextPosition(options.lineOffset, options.columnOffset)),
+ JSC::StringSourceProvider::create(sourceString, JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(options.filename)), options.filename, JSC::SourceTaintedOrigin::Untainted, TextPosition(options.lineOffset, options.columnOffset)),
options.lineOffset.zeroBasedInt(), options.columnOffset.zeroBasedInt());
auto* zigGlobal = reinterpret_cast<Zig::GlobalObject*>(globalObject);
@@ -332,7 +333,7 @@ JSC_DEFINE_HOST_FUNCTION(vmModuleRunInThisContext, (JSGlobalObject * globalObjec
}
}
SourceCode source(
- JSC::StringSourceProvider::create(sourceString, JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(options.filename)), options.filename, TextPosition(options.lineOffset, options.columnOffset)),
+ JSC::StringSourceProvider::create(sourceString, JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(options.filename)), options.filename, JSC::SourceTaintedOrigin::Untainted, TextPosition(options.lineOffset, options.columnOffset)),
options.lineOffset.zeroBasedInt(), options.columnOffset.zeroBasedInt());
auto* zigGlobal = reinterpret_cast<Zig::GlobalObject*>(globalObject);
JSObject* context = asObject(contextObjectValue);
@@ -501,6 +502,7 @@ public:
template<typename CellType, SubspaceAccess>
static GCClient::IsoSubspace* subspaceFor(VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(NodeVMScriptPrototype, Base);
return &vm.plainObjectSpace();
}
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
diff --git a/src/bun.js/bindings/Path.cpp b/src/bun.js/bindings/Path.cpp
index 808613b0c..6507b7122 100644
--- a/src/bun.js/bindings/Path.cpp
+++ b/src/bun.js/bindings/Path.cpp
@@ -173,7 +173,7 @@ static JSC::JSObject* createPath(JSGlobalObject* globalThis, bool isWindows)
JSC::JSFunction::create(vm, JSC::jsCast<JSC::JSGlobalObject*>(globalThis), 0,
"relative"_s, Path_functionRelative, ImplementationVisibility::Public),
0);
- path->putDirect(vm, clientData->builtinNames().resolvePublicName(),
+ path->putDirect(vm, vm.propertyNames->resolve,
JSC::JSFunction::create(vm, JSC::jsCast<JSC::JSGlobalObject*>(globalThis), 0,
"resolve"_s, Path_functionResolve, ImplementationVisibility::Public),
0);
diff --git a/src/bun.js/bindings/Process.cpp b/src/bun.js/bindings/Process.cpp
index 282cf6460..6fbc797cd 100644
--- a/src/bun.js/bindings/Process.cpp
+++ b/src/bun.js/bindings/Process.cpp
@@ -20,6 +20,8 @@
#include <errno.h>
#include <sys/ioctl.h>
#include "JSNextTickQueue.h"
+#include "ProcessBindingUV.h"
+#include "ProcessBindingNatives.h"
#pragma mark - Node.js Process
@@ -39,11 +41,11 @@
#include <unistd.h> // setuid, getuid
#endif
-namespace Zig {
+namespace Bun {
using namespace JSC;
-#define REPORTED_NODE_VERSION "18.15.0"
+#define REPORTED_NODE_VERSION "20.8.0"
#define processObjectBindingCodeGenerator processObjectInternalsBindingCodeGenerator
#define processObjectMainModuleCodeGenerator moduleMainCodeGenerator
@@ -226,7 +228,7 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
}
}
- JSC::EncodedJSValue (*napi_register_module_v1)(JSC::JSGlobalObject * globalObject,
+ JSC::EncodedJSValue (*napi_register_module_v1)(JSC::JSGlobalObject* globalObject,
JSC::EncodedJSValue exports);
napi_register_module_v1 = reinterpret_cast<JSC::EncodedJSValue (*)(JSC::JSGlobalObject*,
@@ -618,7 +620,7 @@ static void onDidChangeListeners(EventEmitter& eventEmitter, const Identifier& e
continue;
JSGlobalObject* lexicalGlobalObject = context->jsGlobalObject();
- Zig::GlobalObject* globalObject = static_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ Zig::GlobalObject* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
Process* process = jsCast<Process*>(globalObject->processObject());
@@ -677,7 +679,7 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionAbort, (JSGlobalObject * globalObject,
JSC_DEFINE_HOST_FUNCTION(Process_emitWarning, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
- Zig::GlobalObject* globalObject = static_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ Zig::GlobalObject* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -747,8 +749,8 @@ JSC_DEFINE_CUSTOM_SETTER(setProcessExitCode, (JSC::JSGlobalObject * lexicalGloba
int exitCodeInt = exitCode.toInt32(lexicalGlobalObject);
RETURN_IF_EXCEPTION(throwScope, false);
- if (exitCodeInt < 0 || exitCodeInt > 127) {
- throwRangeError(lexicalGlobalObject, throwScope, "exitCode must be between 0 and 127"_s);
+ if (exitCodeInt < 0 || exitCodeInt > 255) {
+ throwRangeError(lexicalGlobalObject, throwScope, "exitCode must be between 0 and 255"_s);
return false;
}
@@ -808,12 +810,12 @@ static JSValue constructVersions(VM& vm, JSObject* processObject)
object->putDirect(vm, JSC::Identifier::fromString(vm, "usockets"_s),
JSC::JSValue(JSC::jsString(vm, makeString(Bun__versions_usockets))), 0);
- object->putDirect(vm, JSC::Identifier::fromString(vm, "v8"_s), JSValue(JSC::jsString(vm, makeString("10.8.168.20-node.8"_s))), 0);
- object->putDirect(vm, JSC::Identifier::fromString(vm, "uv"_s), JSValue(JSC::jsString(vm, makeString("1.44.2"_s))), 0);
- object->putDirect(vm, JSC::Identifier::fromString(vm, "napi"_s), JSValue(JSC::jsString(vm, makeString("8"_s))), 0);
+ object->putDirect(vm, JSC::Identifier::fromString(vm, "v8"_s), JSValue(JSC::jsString(vm, makeString("11.3.244.8-node.15"_s))), 0);
+ object->putDirect(vm, JSC::Identifier::fromString(vm, "uv"_s), JSValue(JSC::jsString(vm, makeString("1.46.0"_s))), 0);
+ object->putDirect(vm, JSC::Identifier::fromString(vm, "napi"_s), JSValue(JSC::jsString(vm, makeString("9"_s))), 0);
object->putDirect(vm, JSC::Identifier::fromString(vm, "modules"_s),
- JSC::JSValue(JSC::jsString(vm, makeAtomString("108"))));
+ JSC::JSValue(JSC::jsString(vm, makeAtomString("115"))));
return object;
}
@@ -950,7 +952,7 @@ static JSValue constructProcessSend(VM& vm, JSObject* processObject)
if (Bun__GlobalObject__hasIPC(globalObject)) {
return JSC::JSFunction::create(vm, globalObject, 1, String("send"_s), Bun__Process__send, ImplementationVisibility::Public);
} else {
- return jsNumber(4);
+ return jsUndefined();
}
}
@@ -1121,6 +1123,91 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionAssert, (JSGlobalObject * globalObject,
return JSValue::encode(jsUndefined());
}
+#define PROCESS_BINDING_NOT_IMPLEMENTED_ISSUE(str, issue) \
+ { \
+ throwScope.throwException(globalObject, createError(globalObject, String("process.binding(\"" str "\") is not implemented in Bun. Track the status & thumbs up the issue: https://github.com/oven-sh/bun/issues/" issue ""_s))); \
+ return JSValue::encode(JSValue {}); \
+ }
+
+#define PROCESS_BINDING_NOT_IMPLEMENTED(str) \
+ { \
+ throwScope.throwException(globalObject, createError(globalObject, String("process.binding(\"" str "\") is not implemented in Bun. If that breaks something, please file an issue and include a reproducible code sample."_s))); \
+ return JSValue::encode(JSValue {}); \
+ }
+
+inline JSValue processBindingUtil(Zig::GlobalObject* globalObject, JSC::VM& vm)
+{
+ auto& builtinNames = WebCore::builtinNames(vm);
+ auto fn = globalObject->getDirect(vm, builtinNames.requireNativeModulePrivateName());
+ auto callData = JSC::getCallData(fn);
+ JSC::MarkedArgumentBuffer args;
+ args.append(jsString(vm, String("util/types"_s)));
+ return JSC::call(globalObject, fn, callData, globalObject, args);
+}
+
+inline JSValue processBindingConfig(Zig::GlobalObject* globalObject, JSC::VM& vm)
+{
+ auto config = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 9);
+#ifdef BUN_DEBUG
+ config->putDirect(vm, Identifier::fromString(vm, "isDebugBuild"_s), jsBoolean(true), 0);
+#else
+ config->putDirect(vm, Identifier::fromString(vm, "isDebugBuild"_s), jsBoolean(false), 0);
+#endif
+ config->putDirect(vm, Identifier::fromString(vm, "hasOpenSSL"_s), jsBoolean(true), 0);
+ config->putDirect(vm, Identifier::fromString(vm, "fipsMode"_s), jsBoolean(true), 0);
+ config->putDirect(vm, Identifier::fromString(vm, "hasIntl"_s), jsBoolean(true), 0);
+ config->putDirect(vm, Identifier::fromString(vm, "hasTracing"_s), jsBoolean(true), 0);
+ config->putDirect(vm, Identifier::fromString(vm, "hasNodeOptions"_s), jsBoolean(true), 0);
+ config->putDirect(vm, Identifier::fromString(vm, "hasInspector"_s), jsBoolean(true), 0);
+ config->putDirect(vm, Identifier::fromString(vm, "noBrowserGlobals"_s), jsBoolean(false), 0);
+ config->putDirect(vm, Identifier::fromString(vm, "bits"_s), jsNumber(64), 0);
+ return config;
+}
+
+JSC_DEFINE_HOST_FUNCTION(Process_functionBinding, (JSGlobalObject * jsGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = jsGlobalObject->vm();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto globalObject = jsCast<Zig::GlobalObject*>(jsGlobalObject);
+ auto process = jsCast<Process*>(globalObject->processObject());
+ auto moduleName = callFrame->argument(0).toWTFString(globalObject);
+
+ // clang-format off
+ if (moduleName == "async_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("async_wrap");
+ if (moduleName == "buffer"_s) PROCESS_BINDING_NOT_IMPLEMENTED_ISSUE("buffer", "2020");
+ if (moduleName == "cares_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("cares_wrap");
+ if (moduleName == "config"_s) return JSValue::encode(processBindingConfig(globalObject, vm));
+ if (moduleName == "constants"_s) return JSValue::encode(globalObject->processBindingConstants());
+ if (moduleName == "contextify"_s) PROCESS_BINDING_NOT_IMPLEMENTED("contextify");
+ if (moduleName == "crypto"_s) PROCESS_BINDING_NOT_IMPLEMENTED("crypto");
+ if (moduleName == "fs"_s) PROCESS_BINDING_NOT_IMPLEMENTED_ISSUE("fs", "3546");
+ if (moduleName == "fs_event_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("fs_event_wrap");
+ if (moduleName == "http_parser"_s) PROCESS_BINDING_NOT_IMPLEMENTED("http_parser");
+ if (moduleName == "icu"_s) PROCESS_BINDING_NOT_IMPLEMENTED("icu");
+ if (moduleName == "inspector"_s) PROCESS_BINDING_NOT_IMPLEMENTED("inspector");
+ if (moduleName == "js_stream"_s) PROCESS_BINDING_NOT_IMPLEMENTED("js_stream");
+ if (moduleName == "natives"_s) return JSValue::encode(process->bindingNatives());
+ if (moduleName == "os"_s) PROCESS_BINDING_NOT_IMPLEMENTED("os");
+ if (moduleName == "pipe_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("pipe_wrap");
+ if (moduleName == "process_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("process_wrap");
+ if (moduleName == "signal_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("signal_wrap");
+ if (moduleName == "spawn_sync"_s) PROCESS_BINDING_NOT_IMPLEMENTED("spawn_sync");
+ if (moduleName == "stream_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED_ISSUE("stream_wrap", "4957");
+ if (moduleName == "tcp_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("tcp_wrap");
+ if (moduleName == "tls_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("tls_wrap");
+ if (moduleName == "tty_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED_ISSUE("tty_wrap", "4694");
+ if (moduleName == "udp_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("udp_wrap");
+ if (moduleName == "url"_s) PROCESS_BINDING_NOT_IMPLEMENTED("url");
+ if (moduleName == "util"_s) return JSValue::encode(processBindingUtil(globalObject, vm));
+ if (moduleName == "uv"_s) return JSValue::encode(process->bindingUV());
+ if (moduleName == "v8"_s) PROCESS_BINDING_NOT_IMPLEMENTED("v8");
+ if (moduleName == "zlib"_s) PROCESS_BINDING_NOT_IMPLEMENTED("zlib");
+ // clang-format on
+
+ throwScope.throwException(globalObject, createError(globalObject, makeString("No such module: "_s, moduleName)));
+ return JSValue::encode(jsUndefined());
+}
+
JSC_DEFINE_HOST_FUNCTION(Process_functionReallyExit, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
auto& vm = globalObject->vm();
@@ -1158,8 +1245,10 @@ void Process::visitChildrenImpl(JSCell* cell, Visitor& visitor)
Process* thisObject = jsCast<Process*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitChildren(thisObject, visitor);
- thisObject->cpuUsageStructure.visit(visitor);
- thisObject->memoryUsageStructure.visit(visitor);
+ thisObject->m_cpuUsageStructure.visit(visitor);
+ thisObject->m_memoryUsageStructure.visit(visitor);
+ thisObject->m_bindingUV.visit(visitor);
+ thisObject->m_bindingNatives.visit(visitor);
}
DEFINE_VISIT_CHILDREN(Process);
@@ -1239,6 +1328,16 @@ static Process* getProcessObject(JSC::JSGlobalObject* lexicalGlobalObject, JSVal
return process;
}
+JSC_DEFINE_HOST_FUNCTION(Process_functionConstrainedMemory,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+#if OS(LINUX) || OS(FREEBSD)
+ return JSValue::encode(jsDoubleNumber(static_cast<double>(WTF::ramSize())));
+#else
+ return JSValue::encode(jsUndefined());
+#endif
+}
+
JSC_DEFINE_HOST_FUNCTION(Process_functionCpuUsage,
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
@@ -1252,7 +1351,7 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionCpuUsage,
auto* process = getProcessObject(globalObject, callFrame->thisValue());
- Structure* cpuUsageStructure = process->cpuUsageStructure.getInitializedOnMainThread(process);
+ Structure* cpuUsageStructure = process->cpuUsageStructure();
constexpr double MICROS_PER_SEC = 1000000.0;
@@ -1405,7 +1504,7 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionMemoryUsage,
return JSC::JSValue::encode(JSC::JSValue {});
}
- JSC::JSObject* result = JSC::constructEmptyObject(vm, process->memoryUsageStructure.getInitializedOnMainThread(process));
+ JSC::JSObject* result = JSC::constructEmptyObject(vm, process->memoryUsageStructure());
if (UNLIKELY(throwScope.exception())) {
return JSC::JSValue::encode(JSC::JSValue {});
}
@@ -1525,7 +1624,7 @@ static JSValue constructMemoryUsage(VM& vm, JSObject* processObject)
JSC::JSFunction* rss = JSC::JSFunction::create(vm, globalObject, 0,
String("rss"_s), Process_functionMemoryUsageRSS, ImplementationVisibility::Public);
- memoryUsage->putDirect(vm, JSC::Identifier::fromString(vm, "rss"_s), rss, JSC::PropertyAttribute::Function | 0);
+ memoryUsage->putDirect(vm, JSC::Identifier::fromString(vm, "rss"_s), rss, 0);
return memoryUsage;
}
@@ -1548,14 +1647,14 @@ static JSValue constructProcessNextTickFn(VM& vm, JSObject* processObject)
Zig::GlobalObject* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
JSValue nextTickQueueObject;
if (!globalObject->m_nextTickQueue) {
- Bun::JSNextTickQueue* queue = Bun::JSNextTickQueue::create(globalObject);
- globalObject->m_nextTickQueue.set(vm, globalObject, queue);
- nextTickQueueObject = queue;
+ nextTickQueueObject = Bun::JSNextTickQueue::create(globalObject);
+ globalObject->m_nextTickQueue.set(vm, globalObject, nextTickQueueObject);
} else {
nextTickQueueObject = jsCast<Bun::JSNextTickQueue*>(globalObject->m_nextTickQueue.get());
}
JSC::JSFunction* initializer = JSC::JSFunction::create(vm, processObjectInternalsInitializeNextTickQueueCodeGenerator(vm), lexicalGlobalObject);
+
JSC::MarkedArgumentBuffer args;
args.append(processObject);
args.append(nextTickQueueObject);
@@ -1736,7 +1835,7 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionKill,
return JSValue::encode(jsUndefined());
}
- return JSValue::encode(jsUndefined());
+ return JSValue::encode(jsBoolean(true));
}
extern "C" void Process__emitMessageEvent(Zig::GlobalObject* global, EncodedJSValue value)
@@ -1770,11 +1869,12 @@ extern "C" void Process__emitDisconnectEvent(Zig::GlobalObject* global)
argv constructArgv PropertyCallback
argv0 constructArgv0 PropertyCallback
assert Process_functionAssert Function 1
- binding JSBuiltin Function 1
+ binding Process_functionBinding Function 1
browser constructBrowser PropertyCallback
chdir Process_functionChdir Function 1
config constructProcessConfigObject PropertyCallback
connected processConnected CustomAccessor
+ constrainedMemory Process_functionConstrainedMemory Function 0
cpuUsage Process_functionCpuUsage Function 1
cwd Process_functionCwd Function 1
debugPort processDebugPort CustomAccessor
@@ -1831,7 +1931,6 @@ extern "C" void Process__emitDisconnectEvent(Zig::GlobalObject* global)
_kill Process_functionReallyKill Function 2
@end
*/
-
#include "Process.lut.h"
const JSC::ClassInfo Process::s_info = { "Process"_s, &Base::s_info, &processObjectTable, nullptr,
CREATE_METHOD_TABLE(Process) };
@@ -1840,17 +1939,24 @@ void Process::finishCreation(JSC::VM& vm)
{
Base::finishCreation(vm);
- this->wrapped().onDidChangeListener = &onDidChangeListeners;
+ wrapped().onDidChangeListener = &onDidChangeListeners;
- this->cpuUsageStructure.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::Structure>::Initializer& init) {
+ m_cpuUsageStructure.initLater([](const JSC::LazyProperty<Process, JSC::Structure>::Initializer& init) {
init.set(constructCPUUsageStructure(init.vm, init.owner->globalObject()));
});
- this->memoryUsageStructure.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::Structure>::Initializer& init) {
+ m_memoryUsageStructure.initLater([](const JSC::LazyProperty<Process, JSC::Structure>::Initializer& init) {
init.set(constructMemoryUsageStructure(init.vm, init.owner->globalObject()));
});
- this->putDirect(vm, vm.propertyNames->toStringTagSymbol, jsString(vm, String("process"_s)), 0);
+ m_bindingUV.initLater([](const JSC::LazyProperty<Process, JSC::JSObject>::Initializer& init) {
+ init.set(Bun::ProcessBindingUV::create(init.vm, init.owner->globalObject()));
+ });
+ m_bindingNatives.initLater([](const JSC::LazyProperty<Process, JSC::JSObject>::Initializer& init) {
+ init.set(Bun::ProcessBindingNatives::create(init.vm, ProcessBindingNatives::createStructure(init.vm, init.owner->globalObject())));
+ });
+
+ putDirect(vm, vm.propertyNames->toStringTagSymbol, jsString(vm, String("process"_s)), 0);
}
-} // namespace Zig
+} // namespace Bun
diff --git a/src/bun.js/bindings/Process.h b/src/bun.js/bindings/Process.h
index ab344c7fe..1615aabdd 100644
--- a/src/bun.js/bindings/Process.h
+++ b/src/bun.js/bindings/Process.h
@@ -6,7 +6,7 @@
#include "BunClientData.h"
#include "JSEventEmitter.h"
-namespace Zig {
+namespace Bun {
// TODO: find a better place for this
int getRSS(size_t* rss);
@@ -16,6 +16,11 @@ using namespace JSC;
class Process : public WebCore::JSEventEmitter {
using Base = WebCore::JSEventEmitter;
+ LazyProperty<Process, Structure> m_cpuUsageStructure;
+ LazyProperty<Process, Structure> m_memoryUsageStructure;
+ LazyProperty<Process, JSObject> m_bindingUV;
+ LazyProperty<Process, JSObject> m_bindingNatives;
+
public:
Process(JSC::Structure* structure, WebCore::JSDOMGlobalObject& globalObject, Ref<WebCore::EventEmitter>&& impl)
: Base(structure, globalObject, WTFMove(impl))
@@ -50,9 +55,6 @@ public:
return accessor;
}
- LazyProperty<JSObject, Structure> cpuUsageStructure;
- LazyProperty<JSObject, Structure> memoryUsageStructure;
-
DECLARE_VISIT_CHILDREN;
template<typename, SubspaceAccess mode>
@@ -69,6 +71,11 @@ public:
}
void finishCreation(JSC::VM& vm);
+
+ inline Structure* cpuUsageStructure() { return m_cpuUsageStructure.getInitializedOnMainThread(this); }
+ inline Structure* memoryUsageStructure() { return m_memoryUsageStructure.getInitializedOnMainThread(this); }
+ inline JSObject* bindingUV() { return m_bindingUV.getInitializedOnMainThread(this); }
+ inline JSObject* bindingNatives() { return m_bindingNatives.getInitializedOnMainThread(this); }
};
-} // namespace Zig \ No newline at end of file
+} // namespace Bun \ No newline at end of file
diff --git a/src/bun.js/bindings/Process.lut.h b/src/bun.js/bindings/Process.lut.h
index dda54ff01..6016466c2 100644
--- a/src/bun.js/bindings/Process.lut.h
+++ b/src/bun.js/bindings/Process.lut.h
@@ -1,6 +1,6 @@
-// File generated via `make generate-builtins`
-static const struct CompactHashIndex processObjectTableIndex[267] = {
- { 47, -1 },
+// File generated via `make static-hash-table` / `make cpp`
+static const struct CompactHashIndex processObjectTableIndex[268] = {
+ { 48, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -14,9 +14,9 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 20, -1 },
+ { 21, -1 },
{ -1, -1 },
- { 49, -1 },
+ { 50, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -41,14 +41,14 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 34, -1 },
+ { 35, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 29, -1 },
- { 13, -1 },
+ { 30, -1 },
+ { 14, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -57,11 +57,11 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 59, -1 },
+ { 60, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 55, -1 },
+ { 56, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -75,36 +75,36 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 43, -1 },
+ { 44, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 0, -1 },
- { 28, -1 },
- { 37, -1 },
- { 42, -1 },
+ { 29, -1 },
+ { 38, -1 },
+ { 43, -1 },
{ -1, -1 },
- { 25, -1 },
- { 12, -1 },
+ { 26, -1 },
+ { 13, -1 },
{ -1, -1 },
{ -1, -1 },
- { 62, -1 },
+ { 63, -1 },
{ -1, -1 },
{ -1, -1 },
- { 33, -1 },
- { 44, -1 },
+ { 34, -1 },
+ { 45, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 26, -1 },
+ { 27, -1 },
{ -1, -1 },
{ -1, -1 },
- { 22, -1 },
+ { 23, -1 },
{ -1, -1 },
{ 5, -1 },
{ -1, -1 },
- { 64, -1 },
+ { 65, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -115,19 +115,19 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 27, 261 },
+ { 28, 262 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 23, 262 },
+ { 24, 263 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 50, 265 },
+ { 51, 266 },
{ -1, -1 },
- { 19, -1 },
+ { 20, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -139,10 +139,10 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 17, 257 },
+ { 18, 257 },
{ -1, -1 },
- { 14, -1 },
- { 57, -1 },
+ { 15, -1 },
+ { 58, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -161,12 +161,12 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 3, 266 },
+ { 3, 267 },
{ 1, -1 },
{ -1, -1 },
- { 63, -1 },
+ { 64, -1 },
{ -1, -1 },
- { 11, -1 },
+ { 12, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -174,24 +174,24 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 56, -1 },
+ { 57, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 10, 256 },
{ -1, -1 },
- { 16, 263 },
+ { 17, 264 },
{ -1, -1 },
- { 39, -1 },
+ { 40, -1 },
{ -1, -1 },
- { 41, -1 },
+ { 42, -1 },
{ -1, -1 },
- { 38, -1 },
- { 6, 264 },
+ { 11, 260 },
+ { 6, 265 },
{ -1, -1 },
{ -1, -1 },
{ 4, -1 },
- { 51, -1 },
+ { 52, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -205,11 +205,11 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 31, 260 },
+ { 32, 261 },
{ -1, -1 },
{ -1, -1 },
- { 48, -1 },
- { 18, 258 },
+ { 49, -1 },
+ { 19, 258 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -219,10 +219,10 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 53, -1 },
+ { 54, -1 },
{ -1, -1 },
- { 32, -1 },
- { 24, -1 },
+ { 33, -1 },
+ { 25, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -233,12 +233,12 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 52, -1 },
+ { 53, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 15, 259 },
+ { 16, 259 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
@@ -256,31 +256,33 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
- { 21, -1 },
- { 30, -1 },
- { 35, -1 },
+ { 22, -1 },
+ { 31, -1 },
{ 36, -1 },
- { 40, -1 },
- { 45, -1 },
+ { 37, -1 },
+ { 39, -1 },
+ { 41, -1 },
{ 46, -1 },
- { 54, -1 },
- { 58, -1 },
- { 60, -1 },
+ { 47, -1 },
+ { 55, -1 },
+ { 59, -1 },
{ 61, -1 },
+ { 62, -1 },
};
-static const struct HashTableValue processObjectTableValues[65] = {
+static const struct HashTableValue processObjectTableValues[66] = {
{ "abort"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionAbort, 1 } },
{ "allowedNodeEnvironmentFlags"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, Process_stubEmptySet } },
{ "arch"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, constructArch } },
{ "argv"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, constructArgv } },
{ "argv0"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, constructArgv0 } },
{ "assert"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionAssert, 1 } },
- { "binding"_s, ((static_cast<unsigned>(PropertyAttribute::Function)) & ~PropertyAttribute::Function) | PropertyAttribute::Builtin, NoIntrinsic, { HashTableValue::BuiltinGeneratorType, processObjectBindingCodeGenerator, 1 } },
+ { "binding"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionBinding, 1 } },
{ "browser"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, constructBrowser } },
{ "chdir"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionChdir, 1 } },
{ "config"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, constructProcessConfigObject } },
{ "connected"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, processConnected, setProcessConnected } },
+ { "constrainedMemory"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionConstrainedMemory, 0 } },
{ "cpuUsage"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionCpuUsage, 1 } },
{ "cwd"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionCwd, 1 } },
{ "debugPort"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, processDebugPort, setProcessDebugPort } },
@@ -338,4 +340,4 @@ static const struct HashTableValue processObjectTableValues[65] = {
};
static const struct HashTable processObjectTable =
- { 65, 255, true, nullptr, processObjectTableValues, processObjectTableIndex };
+ { 66, 255, true, nullptr, processObjectTableValues, processObjectTableIndex };
diff --git a/src/bun.js/bindings/ProcessBindingConstants.cpp b/src/bun.js/bindings/ProcessBindingConstants.cpp
index 36a4a7f96..8544b2f20 100644
--- a/src/bun.js/bindings/ProcessBindingConstants.cpp
+++ b/src/bun.js/bindings/ProcessBindingConstants.cpp
@@ -685,9 +685,6 @@ static JSValue processBindingConstantsGetFs(VM& vm, JSObject* bindingObject)
#ifdef O_DIRECTORY
object->putDirect(vm, PropertyName(Identifier::fromString(vm, "O_DIRECTORY"_s)), jsNumber(O_DIRECTORY));
#endif
-#ifdef O_EXCL
- object->putDirect(vm, PropertyName(Identifier::fromString(vm, "O_EXCL"_s)), jsNumber(O_EXCL));
-#endif
#ifdef O_NOATIME
object->putDirect(vm, PropertyName(Identifier::fromString(vm, "O_NOATIME"_s)), jsNumber(O_NOATIME));
#endif
@@ -1082,15 +1079,18 @@ static JSValue processBindingConstantsGetZlib(VM& vm, JSObject* bindingObject)
return object;
}
-static const HashTableValue ProcessBindingConstantsValues[] = {
- { "os"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingConstantsGetOs } },
- { "fs"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingConstantsGetFs } },
- { "crypto"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingConstantsGetCrypto } },
- { "zlib"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingConstantsGetZlib } },
- { "trace"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingConstantsGetTrace } },
-};
+/* Source for ProcessBindingConstants.lut.h
+@begin processBindingConstantsTable
+ os processBindingConstantsGetOs PropertyCallback
+ fs processBindingConstantsGetFs PropertyCallback
+ crypto processBindingConstantsGetCrypto PropertyCallback
+ zlib processBindingConstantsGetZlib PropertyCallback
+ trace processBindingConstantsGetTrace PropertyCallback
+@end
+*/
+#include "ProcessBindingConstants.lut.h"
-const ClassInfo ProcessBindingConstants::s_info = { "ProcessBindingConstants"_s, Base::info(), nullptr, nullptr, CREATE_METHOD_TABLE(ProcessBindingConstants) };
+const ClassInfo ProcessBindingConstants::s_info = { "ProcessBindingConstants"_s, &Base::s_info, &processBindingConstantsTable, nullptr, CREATE_METHOD_TABLE(ProcessBindingConstants) };
ProcessBindingConstants* ProcessBindingConstants::create(VM& vm, Structure* structure)
{
@@ -1107,8 +1107,7 @@ Structure* ProcessBindingConstants::createStructure(VM& vm, JSGlobalObject* glob
void ProcessBindingConstants::finishCreation(JSC::VM& vm)
{
Base::finishCreation(vm);
- reifyStaticProperties(vm, ProcessBindingConstants::info(), ProcessBindingConstantsValues, *this);
- ASSERT(inherits(vm, info()));
+ ASSERT(inherits(info()));
}
template<typename Visitor>
diff --git a/src/bun.js/bindings/ProcessBindingConstants.h b/src/bun.js/bindings/ProcessBindingConstants.h
index 5a9be7ce7..6115534a0 100644
--- a/src/bun.js/bindings/ProcessBindingConstants.h
+++ b/src/bun.js/bindings/ProcessBindingConstants.h
@@ -1,3 +1,4 @@
+#pragma once
#include "root.h"
namespace Bun {
@@ -11,12 +12,15 @@ public:
using Base = JSC::JSNonFinalObject;
+ static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
+
static ProcessBindingConstants* create(JSC::VM& vm, JSC::Structure* structure);
static Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject);
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(ProcessBindingConstants, Base);
return &vm.plainObjectSpace();
}
diff --git a/src/bun.js/bindings/ProcessBindingConstants.lut.h b/src/bun.js/bindings/ProcessBindingConstants.lut.h
new file mode 100644
index 000000000..4ad86860d
--- /dev/null
+++ b/src/bun.js/bindings/ProcessBindingConstants.lut.h
@@ -0,0 +1,31 @@
+// File generated via `make static-hash-table` / `make cpp`
+static const struct CompactHashIndex processBindingConstantsTableIndex[17] = {
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 2, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 0, 16 },
+ { -1, -1 },
+ { -1, -1 },
+ { 4, -1 },
+ { 3, -1 },
+};
+
+static const struct HashTableValue processBindingConstantsTableValues[5] = {
+ { "os"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingConstantsGetOs } },
+ { "fs"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingConstantsGetFs } },
+ { "crypto"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingConstantsGetCrypto } },
+ { "zlib"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingConstantsGetZlib } },
+ { "trace"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingConstantsGetTrace } },
+};
+
+static const struct HashTable processBindingConstantsTable =
+ { 5, 15, false, nullptr, processBindingConstantsTableValues, processBindingConstantsTableIndex };
diff --git a/src/bun.js/bindings/ProcessBindingNatives.cpp b/src/bun.js/bindings/ProcessBindingNatives.cpp
new file mode 100644
index 000000000..2a2685524
--- /dev/null
+++ b/src/bun.js/bindings/ProcessBindingNatives.cpp
@@ -0,0 +1,131 @@
+// Modelled off of https://github.com/nodejs/node/blob/main/src/node_constants.cc
+// Note that if you change any of this code, you probably also have to change NodeConstantsModule.h
+#include "ProcessBindingNatives.h"
+#include "JavaScriptCore/ObjectConstructor.h"
+
+namespace Bun {
+using namespace JSC;
+
+static JSValue processBindingNativesGetter(VM& vm, JSObject* bindingObject)
+{
+ // Instead of actually returning our source code, we just return a dummy string.
+ // Most people just use `process.binding('natives')` to get a list of builtin modules
+ // We also don't report internal modules.
+ // If any of this breaks your package, please open an issue.
+ return jsString(vm, String("/* [native code] */"_s));
+}
+
+static JSValue processBindingNativesReturnUndefined(VM& vm, JSObject* bindingObject)
+{
+ // process.binding('natives').config === undefined
+ return jsUndefined();
+}
+
+/* Source for ProcessBindingNatives.lut.h
+@begin processBindingNativesTable
+ _http_agent processBindingNativesGetter PropertyCallback
+ _http_client processBindingNativesGetter PropertyCallback
+ _http_common processBindingNativesGetter PropertyCallback
+ _http_incoming processBindingNativesGetter PropertyCallback
+ _http_outgoing processBindingNativesGetter PropertyCallback
+ _http_server processBindingNativesGetter PropertyCallback
+ _stream_duplex processBindingNativesGetter PropertyCallback
+ _stream_passthrough processBindingNativesGetter PropertyCallback
+ _stream_readable processBindingNativesGetter PropertyCallback
+ _stream_transform processBindingNativesGetter PropertyCallback
+ _stream_wrap processBindingNativesGetter PropertyCallback
+ _stream_writable processBindingNativesGetter PropertyCallback
+ _tls_common processBindingNativesGetter PropertyCallback
+ _tls_wrap processBindingNativesGetter PropertyCallback
+ assert processBindingNativesGetter PropertyCallback
+ assert/strict processBindingNativesGetter PropertyCallback
+ async_hooks processBindingNativesGetter PropertyCallback
+ buffer processBindingNativesGetter PropertyCallback
+ child_process processBindingNativesGetter PropertyCallback
+ cluster processBindingNativesGetter PropertyCallback
+ console processBindingNativesGetter PropertyCallback
+ constants processBindingNativesGetter PropertyCallback
+ crypto processBindingNativesGetter PropertyCallback
+ dgram processBindingNativesGetter PropertyCallback
+ diagnostics_channel processBindingNativesGetter PropertyCallback
+ dns processBindingNativesGetter PropertyCallback
+ dns/promises processBindingNativesGetter PropertyCallback
+ domain processBindingNativesGetter PropertyCallback
+ events processBindingNativesGetter PropertyCallback
+ fs processBindingNativesGetter PropertyCallback
+ fs/promises processBindingNativesGetter PropertyCallback
+ http processBindingNativesGetter PropertyCallback
+ http2 processBindingNativesGetter PropertyCallback
+ https processBindingNativesGetter PropertyCallback
+ inspector processBindingNativesGetter PropertyCallback
+ inspector/promises processBindingNativesGetter PropertyCallback
+ module processBindingNativesGetter PropertyCallback
+ net processBindingNativesGetter PropertyCallback
+ os processBindingNativesGetter PropertyCallback
+ path processBindingNativesGetter PropertyCallback
+ path/posix processBindingNativesGetter PropertyCallback
+ path/win32 processBindingNativesGetter PropertyCallback
+ perf_hooks processBindingNativesGetter PropertyCallback
+ process processBindingNativesGetter PropertyCallback
+ punycode processBindingNativesGetter PropertyCallback
+ querystring processBindingNativesGetter PropertyCallback
+ readline processBindingNativesGetter PropertyCallback
+ readline/promises processBindingNativesGetter PropertyCallback
+ repl processBindingNativesGetter PropertyCallback
+ stream processBindingNativesGetter PropertyCallback
+ stream/consumers processBindingNativesGetter PropertyCallback
+ stream/promises processBindingNativesGetter PropertyCallback
+ stream/web processBindingNativesGetter PropertyCallback
+ string_decoder processBindingNativesGetter PropertyCallback
+ sys processBindingNativesGetter PropertyCallback
+ test processBindingNativesGetter PropertyCallback
+ test/reporters processBindingNativesGetter PropertyCallback
+ timers processBindingNativesGetter PropertyCallback
+ timers/promises processBindingNativesGetter PropertyCallback
+ tls processBindingNativesGetter PropertyCallback
+ trace_events processBindingNativesGetter PropertyCallback
+ tty processBindingNativesGetter PropertyCallback
+ url processBindingNativesGetter PropertyCallback
+ util processBindingNativesGetter PropertyCallback
+ util/types processBindingNativesGetter PropertyCallback
+ v8 processBindingNativesGetter PropertyCallback
+ vm processBindingNativesGetter PropertyCallback
+ wasi processBindingNativesGetter PropertyCallback
+ worker_threads processBindingNativesGetter PropertyCallback
+ zlib processBindingNativesGetter PropertyCallback
+ configs processBindingNativesReturnUndefined PropertyCallback
+@end
+*/
+#include "ProcessBindingNatives.lut.h"
+
+const ClassInfo ProcessBindingNatives::s_info = { "ProcessBindingNatives"_s, &Base::s_info, &processBindingNativesTable, nullptr, CREATE_METHOD_TABLE(ProcessBindingNatives) };
+
+ProcessBindingNatives* ProcessBindingNatives::create(VM& vm, Structure* structure)
+{
+ ProcessBindingNatives* obj = new (NotNull, allocateCell<ProcessBindingNatives>(vm)) ProcessBindingNatives(vm, structure);
+ obj->finishCreation(vm);
+ return obj;
+}
+
+Structure* ProcessBindingNatives::createStructure(VM& vm, JSGlobalObject* globalObject)
+{
+ return Structure::create(vm, globalObject, jsNull(), TypeInfo(ObjectType, StructureFlags), ProcessBindingNatives::info());
+}
+
+void ProcessBindingNatives::finishCreation(JSC::VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+}
+
+template<typename Visitor>
+void ProcessBindingNatives::visitChildrenImpl(JSCell* cell, Visitor& visitor)
+{
+ ProcessBindingNatives* thisObject = jsCast<ProcessBindingNatives*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(thisObject, visitor);
+}
+
+DEFINE_VISIT_CHILDREN(ProcessBindingNatives);
+
+} // namespace Bun
diff --git a/src/bun.js/bindings/ProcessBindingNatives.h b/src/bun.js/bindings/ProcessBindingNatives.h
new file mode 100644
index 000000000..bbeaaa524
--- /dev/null
+++ b/src/bun.js/bindings/ProcessBindingNatives.h
@@ -0,0 +1,36 @@
+#pragma once
+#include "root.h"
+
+namespace Bun {
+using namespace JSC;
+
+// The object returned from process.binding('natives')
+class ProcessBindingNatives final : public JSC::JSNonFinalObject {
+public:
+ DECLARE_INFO;
+ DECLARE_VISIT_CHILDREN;
+
+ using Base = JSC::JSNonFinalObject;
+
+ static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
+
+ static ProcessBindingNatives* create(JSC::VM& vm, JSC::Structure* structure);
+ static Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject);
+
+ template<typename CellType, JSC::SubspaceAccess>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(ProcessBindingNatives, Base);
+ return &vm.plainObjectSpace();
+ }
+
+private:
+ void finishCreation(JSC::VM& vm);
+
+ ProcessBindingNatives(JSC::VM& vm, JSC::Structure* structure)
+ : Base(vm, structure)
+ {
+ }
+};
+
+} // namespace Bun
diff --git a/src/bun.js/bindings/ProcessBindingNatives.lut.h b/src/bun.js/bindings/ProcessBindingNatives.lut.h
new file mode 100644
index 000000000..2bc7e34f5
--- /dev/null
+++ b/src/bun.js/bindings/ProcessBindingNatives.lut.h
@@ -0,0 +1,339 @@
+// File generated via `make static-hash-table` / `make cpp`
+static const struct CompactHashIndex processBindingNativesTableIndex[259] = {
+ { 11, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 16, -1 },
+ { 40, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 17, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 18, -1 },
+ { -1, -1 },
+ { 59, -1 },
+ { -1, -1 },
+ { 58, -1 },
+ { 29, -1 },
+ { -1, -1 },
+ { 12, -1 },
+ { 56, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 64, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 63, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 61, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 50, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 35, -1 },
+ { 42, -1 },
+ { 55, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 66, -1 },
+ { -1, -1 },
+ { 52, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 60, -1 },
+ { -1, -1 },
+ { 41, -1 },
+ { 21, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 47, -1 },
+ { 30, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 15, -1 },
+ { 70, -1 },
+ { 26, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 54, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 51, -1 },
+ { -1, -1 },
+ { 2, -1 },
+ { 28, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 14, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 27, -1 },
+ { -1, -1 },
+ { 37, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 36, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 1, -1 },
+ { -1, -1 },
+ { 3, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 19, -1 },
+ { -1, -1 },
+ { 10, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 8, 257 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 43, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 5, -1 },
+ { -1, -1 },
+ { 62, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 57, -1 },
+ { 38, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 6, 256 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 22, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 0, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 48, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 4, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 32, -1 },
+ { -1, -1 },
+ { 31, -1 },
+ { 49, -1 },
+ { 34, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 68, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 69, -1 },
+ { 33, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 9, -1 },
+ { 44, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 23, -1 },
+ { -1, -1 },
+ { 7, -1 },
+ { 67, -1 },
+ { -1, -1 },
+ { 24, -1 },
+ { 25, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 20, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 65, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 46, -1 },
+ { -1, -1 },
+ { 45, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 13, -1 },
+ { 39, 258 },
+ { 53, -1 },
+};
+
+static const struct HashTableValue processBindingNativesTableValues[71] = {
+ { "_http_agent"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_http_client"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_http_common"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_http_incoming"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_http_outgoing"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_http_server"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_stream_duplex"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_stream_passthrough"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_stream_readable"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_stream_transform"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_stream_wrap"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_stream_writable"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_tls_common"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "_tls_wrap"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "assert"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "assert/strict"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "async_hooks"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "buffer"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "child_process"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "cluster"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "console"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "constants"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "crypto"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "dgram"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "diagnostics_channel"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "dns"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "dns/promises"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "domain"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "events"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "fs"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "fs/promises"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "http"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "http2"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "https"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "inspector"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "inspector/promises"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "module"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "net"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "os"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "path"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "path/posix"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "path/win32"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "perf_hooks"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "process"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "punycode"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "querystring"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "readline"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "readline/promises"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "repl"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "stream"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "stream/consumers"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "stream/promises"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "stream/web"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "string_decoder"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "sys"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "test"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "test/reporters"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "timers"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "timers/promises"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "tls"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "trace_events"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "tty"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "url"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "util"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "util/types"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "v8"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "vm"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "wasi"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "worker_threads"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "zlib"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesGetter } },
+ { "configs"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, processBindingNativesReturnUndefined } },
+};
+
+static const struct HashTable processBindingNativesTable =
+ { 71, 255, false, nullptr, processBindingNativesTableValues, processBindingNativesTableIndex };
diff --git a/src/bun.js/bindings/ProcessBindingUV.cpp b/src/bun.js/bindings/ProcessBindingUV.cpp
new file mode 100644
index 000000000..8173072a9
--- /dev/null
+++ b/src/bun.js/bindings/ProcessBindingUV.cpp
@@ -0,0 +1,158 @@
+#include "ProcessBindingUV.h"
+#include "ZigGlobalObject.h"
+#include "JavaScriptCore/ObjectConstructor.h"
+#include "JavaScriptCore/JSMap.h"
+#include "JavaScriptCore/JSMapInlines.h"
+
+// clang-format off
+
+#define UV_ERRNO_MAP(macro) \
+ macro(E2BIG, -7, "argument list too long") \
+ macro(EACCES, -13, "permission denied") \
+ macro(EADDRINUSE, -48, "address already in use") \
+ macro(EADDRNOTAVAIL, -49, "address not available") \
+ macro(EAFNOSUPPORT, -47, "address family not supported") \
+ macro(EAGAIN, -35, "resource temporarily unavailable") \
+ macro(EAI_ADDRFAMILY, -3000, "address family not supported") \
+ macro(EAI_AGAIN, -3001, "temporary failure") \
+ macro(EAI_BADFLAGS, -3002, "bad ai_flags value") \
+ macro(EAI_BADHINTS, -3013, "invalid value for hints") \
+ macro(EAI_CANCELED, -3003, "request canceled") \
+ macro(EAI_FAIL, -3004, "permanent failure") \
+ macro(EAI_FAMILY, -3005, "ai_family not supported") \
+ macro(EAI_MEMORY, -3006, "out of memory") \
+ macro(EAI_NODATA, -3007, "no address") \
+ macro(EAI_NONAME, -3008, "unknown node or service") \
+ macro(EAI_OVERFLOW, -3009, "argument buffer overflow") \
+ macro(EAI_PROTOCOL, -3014, "resolved protocol is unknown") \
+ macro(EAI_SERVICE, -3010, "service not available for socket type") \
+ macro(EAI_SOCKTYPE, -3011, "socket type not supported") \
+ macro(EALREADY, -37, "connection already in progress") \
+ macro(EBADF, -9, "bad file descriptor") \
+ macro(EBUSY, -16, "resource busy or locked") \
+ macro(ECANCELED, -89, "operation canceled") \
+ macro(ECHARSET, -4080, "invalid Unicode character") \
+ macro(ECONNABORTED, -53, "software caused connection abort") \
+ macro(ECONNREFUSED, -61, "connection refused") \
+ macro(ECONNRESET, -54, "connection reset by peer") \
+ macro(EDESTADDRREQ, -39, "destination address required") \
+ macro(EEXIST, -17, "file already exists") \
+ macro(EFAULT, -14, "bad address in system call argument") \
+ macro(EFBIG, -27, "file too large") \
+ macro(EHOSTUNREACH, -65, "host is unreachable") \
+ macro(EINTR, -4, "interrupted system call") \
+ macro(EINVAL, -22, "invalid argument") \
+ macro(EIO, -5, "i/o error") \
+ macro(EISCONN, -56, "socket is already connected") \
+ macro(EISDIR, -21, "illegal operation on a directory") \
+ macro(ELOOP, -62, "too many symbolic links encountered") \
+ macro(EMFILE, -24, "too many open files") \
+ macro(EMSGSIZE, -40, "message too long") \
+ macro(ENAMETOOLONG, -63, "name too long") \
+ macro(ENETDOWN, -50, "network is down") \
+ macro(ENETUNREACH, -51, "network is unreachable") \
+ macro(ENFILE, -23, "file table overflow") \
+ macro(ENOBUFS, -55, "no buffer space available") \
+ macro(ENODEV, -19, "no such device") \
+ macro(ENOENT, -2, "no such file or directory") \
+ macro(ENOMEM, -12, "not enough memory") \
+ macro(ENONET, -4056, "machine is not on the network") \
+ macro(ENOPROTOOPT, -42, "protocol not available") \
+ macro(ENOSPC, -28, "no space left on device") \
+ macro(ENOSYS, -78, "function not implemented") \
+ macro(ENOTCONN, -57, "socket is not connected") \
+ macro(ENOTDIR, -20, "not a directory") \
+ macro(ENOTEMPTY, -66, "directory not empty") \
+ macro(ENOTSOCK, -38, "socket operation on non-socket") \
+ macro(ENOTSUP, -45, "operation not supported on socket") \
+ macro(EOVERFLOW, -84, "value too large for defined data type") \
+ macro(EPERM, -1, "operation not permitted") \
+ macro(EPIPE, -32, "broken pipe") \
+ macro(EPROTO, -100, "protocol error") \
+ macro(EPROTONOSUPPORT, -43, "protocol not supported") \
+ macro(EPROTOTYPE, -41, "protocol wrong type for socket") \
+ macro(ERANGE, -34, "result too large") \
+ macro(EROFS, -30, "read-only file system") \
+ macro(ESHUTDOWN, -58, "cannot send after transport endpoint shutdown") \
+ macro(ESPIPE, -29, "invalid seek") \
+ macro(ESRCH, -3, "no such process") \
+ macro(ETIMEDOUT, -60, "connection timed out") \
+ macro(ETXTBSY, -26, "text file is busy") \
+ macro(EXDEV, -18, "cross-device link not permitted") \
+ macro(UNKNOWN, -4094, "unknown error") \
+ macro(EOF, -4095, "end of file") \
+ macro(ENXIO, -6, "no such device or address") \
+ macro(EMLINK, -31, "too many links") \
+ macro(EHOSTDOWN, -64, "host is down") \
+ macro(EREMOTEIO, -4030, "remote I/O error") \
+ macro(ENOTTY, -25, "inappropriate ioctl for device") \
+ macro(EFTYPE, -79, "inappropriate file type or format") \
+ macro(EILSEQ, -92, "illegal byte sequence") \
+ macro(ESOCKTNOSUPPORT, -44, "socket type not supported") \
+ macro(ENODATA, -96, "no data available") \
+ macro(EUNATCH, -4023, "protocol driver not attache")
+
+// clang-format on
+namespace Bun {
+namespace ProcessBindingUV {
+
+JSC_DEFINE_HOST_FUNCTION(jsErrname, (JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ auto arg0 = callFrame->argument(0);
+ auto& vm = globalObject->vm();
+
+ // Node.js will actualy crash here, lol.
+ if (!arg0.isInt32())
+ return JSValue::encode(jsString(vm, makeString("Unknown system error "_s, arg0.toWTFString(globalObject))));
+
+ auto err = arg0.asInt32();
+ switch (err) {
+#define CASE(name, value, desc) \
+ case value: \
+ return JSValue::encode(JSC::jsString(vm, String(#name##_s)));
+
+ UV_ERRNO_MAP(CASE)
+#undef CASE
+ }
+
+ return JSValue::encode(jsString(vm, makeString("Unknown system error "_s, String::number(err))));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsGetErrorMap, (JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ auto& vm = globalObject->vm();
+ auto map = JSC::JSMap::create(vm, globalObject->mapStructure());
+
+#define PUT_PROPERTY(name, value, desc) \
+ { \
+ auto arr = JSC::constructEmptyArray(globalObject, nullptr, 2); \
+ arr->putDirectIndex(globalObject, 0, JSC::jsString(vm, String(#name##_s))); \
+ arr->putDirectIndex(globalObject, 1, JSC::jsString(vm, String(desc##_s))); \
+ map->set(globalObject, JSC::jsNumber(value), arr); \
+ }
+
+ UV_ERRNO_MAP(PUT_PROPERTY)
+#undef PUT_PROPERTY
+
+ return JSValue::encode(map);
+}
+
+JSObject* create(VM& vm, JSGlobalObject* globalObject)
+{
+ auto bindingObject = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 0);
+
+ bindingObject->putDirect(vm, JSC::Identifier::fromString(vm, "errname"_s), JSC::JSFunction::create(vm, globalObject, 1, "errname"_s, jsErrname, ImplementationVisibility::Public));
+
+#define PUT_PROPERTY(name, value, desc) \
+ bindingObject->putDirect(vm, JSC::Identifier::fromString(vm, "UV_" #name##_s), JSC::jsNumber(value));
+
+ UV_ERRNO_MAP(PUT_PROPERTY)
+#undef PUT_PROPERTY
+
+ bindingObject->putDirect(vm, JSC::Identifier::fromString(vm, "getErrorMap"_s), JSC::JSFunction::create(vm, globalObject, 0, "getErrorMap"_s, jsGetErrorMap, ImplementationVisibility::Public));
+
+ return bindingObject;
+}
+
+} // namespace ProcessBindingUV
+} // namespace Bun \ No newline at end of file
diff --git a/src/bun.js/bindings/ProcessBindingUV.h b/src/bun.js/bindings/ProcessBindingUV.h
new file mode 100644
index 000000000..4306e21f8
--- /dev/null
+++ b/src/bun.js/bindings/ProcessBindingUV.h
@@ -0,0 +1,13 @@
+#include "root.h"
+
+namespace Bun {
+namespace ProcessBindingUV {
+
+JSC_DECLARE_HOST_FUNCTION(jsErrname);
+
+JSC_DECLARE_HOST_FUNCTION(jsGetErrorMap);
+
+JSC::JSObject* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject);
+
+} // namespace ProcessBindingUV
+} // namespace Bun \ No newline at end of file
diff --git a/src/bun.js/bindings/RegularExpression.cpp b/src/bun.js/bindings/RegularExpression.cpp
index 1c8df1bc0..c59e6fa4c 100644
--- a/src/bun.js/bindings/RegularExpression.cpp
+++ b/src/bun.js/bindings/RegularExpression.cpp
@@ -1,12 +1,16 @@
#include "root.h"
#include "headers-handwritten.h"
#include "JavaScriptCore/RegularExpression.h"
+#include "JavaScriptCore/Options.h"
using namespace JSC;
using namespace JSC::Yarr;
extern "C" RegularExpression* Yarr__RegularExpression__init(BunString pattern, uint16_t flags)
{
+ // TODO: Remove this, we technically are accessing options before we finalize them.
+ // This means you cannot use BUN_JSC_dumpCompiledRegExpPatterns on the flag passed to `bun test -t`
+ Options::AllowUnfinalizedAccessScope scope;
return new RegularExpression(Bun::toWTFString(pattern), OptionSet<Flags>(static_cast<Flags>(flags)));
}
extern "C" void Yarr__RegularExpression__deinit(RegularExpression* re)
diff --git a/src/bun.js/bindings/ScriptExecutionContext.cpp b/src/bun.js/bindings/ScriptExecutionContext.cpp
index 2113c9f64..9f824dde5 100644
--- a/src/bun.js/bindings/ScriptExecutionContext.cpp
+++ b/src/bun.js/bindings/ScriptExecutionContext.cpp
@@ -105,7 +105,7 @@ bool ScriptExecutionContext::postTaskTo(ScriptExecutionContextIdentifier identif
void ScriptExecutionContext::didCreateDestructionObserver(ContextDestructionObserver& observer)
{
- ASSERT(!m_inScriptExecutionContextDestructor);
+ // ASSERT(!m_inScriptExecutionContextDestructor);
m_destructionObservers.add(&observer);
}
@@ -181,7 +181,7 @@ void ScriptExecutionContext::dispatchMessagePortEvents()
ASSERT(isContextThread());
checkConsistency();
- ASSERT(m_willprocessMessageWithMessagePortsSoon);
+ ASSERT(m_willProcessMessageWithMessagePortsSoon);
m_willProcessMessageWithMessagePortsSoon = false;
auto completionHandlers = std::exchange(m_processMessageWithMessagePortsSoonHandlers, Vector<CompletionHandler<void()>> {});
diff --git a/src/bun.js/bindings/Serialization.cpp b/src/bun.js/bindings/Serialization.cpp
index 89937ebbb..fdaf2ab75 100644
--- a/src/bun.js/bindings/Serialization.cpp
+++ b/src/bun.js/bindings/Serialization.cpp
@@ -8,9 +8,15 @@
using namespace JSC;
using namespace WebCore;
-/// This is used for Bun.spawn() IPC because otherwise we would have to copy the data once to get it to zig, then write it.
-/// Returns `true` on success, `false` on failure + throws a JS error.
-extern "C" bool Bun__serializeJSValueForSubprocess(JSGlobalObject* globalObject, EncodedJSValue encodedValue, int fd)
+// Must be synced with bindings.zig's JSValue.SerializedScriptValue.External
+struct SerializedValueSlice {
+ uint8_t* bytes;
+ size_t size;
+ WebCore::SerializedScriptValue* value;
+};
+
+/// Returns a "slice" that also contains a pointer to the SerializedScriptValue. Must be freed by the caller
+extern "C" SerializedValueSlice Bun__serializeJSValue(JSGlobalObject* globalObject, EncodedJSValue encodedValue)
{
JSValue value = JSValue::decode(encodedValue);
@@ -25,19 +31,23 @@ extern "C" bool Bun__serializeJSValueForSubprocess(JSGlobalObject* globalObject,
if (serialized.hasException()) {
WebCore::propagateException(*globalObject, scope,
serialized.releaseException());
- RELEASE_AND_RETURN(scope, false);
+ RELEASE_AND_RETURN(scope, { 0 });
}
auto serializedValue = serialized.releaseReturnValue();
- auto bytes = serializedValue.ptr()->wireBytes();
- uint8_t id = 2; // IPCMessageType.SerializedMessage
- write(fd, &id, sizeof(uint8_t));
- uint32_t size = bytes.size();
- write(fd, &size, sizeof(uint32_t));
- write(fd, bytes.data(), size);
+ auto bytes = serializedValue->wireBytes();
- RELEASE_AND_RETURN(scope, true);
+ return {
+ bytes.data(),
+ bytes.size(),
+ &serializedValue.leakRef(),
+ };
+}
+
+extern "C" void Bun__SerializedScriptSlice__free(SerializedScriptValue* value)
+{
+ delete value;
}
extern "C" EncodedJSValue Bun__JSValue__deserialize(JSGlobalObject* globalObject, const uint8_t* bytes, size_t size)
diff --git a/src/bun.js/bindings/URLDecomposition.cpp b/src/bun.js/bindings/URLDecomposition.cpp
index d3f11b27f..21168f70f 100644
--- a/src/bun.js/bindings/URLDecomposition.cpp
+++ b/src/bun.js/bindings/URLDecomposition.cpp
@@ -35,7 +35,14 @@ String URLDecomposition::origin() const
if (fullURL.protocolIsInHTTPFamily() or fullURL.protocolIsInFTPFamily() or fullURL.protocolIs("ws"_s) or fullURL.protocolIs("wss"_s))
return fullURL.protocolHostAndPort();
-
+ if (fullURL.protocolIsBlob()) {
+ const String& path = fullURL.path().toString();
+ const URL subUrl { URL {}, path };
+ if (subUrl.isValid()) {
+ if (subUrl.protocolIsInHTTPFamily() or subUrl.protocolIsInFTPFamily() or subUrl.protocolIs("ws"_s) or subUrl.protocolIs("wss"_s) or subUrl.protocolIsFile())
+ return subUrl.protocolHostAndPort();
+ }
+ }
return "null"_s;
}
diff --git a/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h b/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h
index a364c0a48..cef5c512a 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h
+++ b/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h
@@ -16,6 +16,7 @@ std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEndTag;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExpect;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExpectConstructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExpectAny;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExpectAnything;
+std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExpectArrayContaining;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExpectStringContaining;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExpectStringMatching;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFFI;
diff --git a/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h b/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h
index e98ea16c3..d06451eda 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h
+++ b/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h
@@ -16,6 +16,7 @@ std::unique_ptr<IsoSubspace> m_subspaceForEndTag;
std::unique_ptr<IsoSubspace> m_subspaceForExpect;
std::unique_ptr<IsoSubspace> m_subspaceForExpectConstructor;std::unique_ptr<IsoSubspace> m_subspaceForExpectAny;
std::unique_ptr<IsoSubspace> m_subspaceForExpectAnything;
+std::unique_ptr<IsoSubspace> m_subspaceForExpectArrayContaining;
std::unique_ptr<IsoSubspace> m_subspaceForExpectStringContaining;
std::unique_ptr<IsoSubspace> m_subspaceForExpectStringMatching;
std::unique_ptr<IsoSubspace> m_subspaceForFFI;
diff --git a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h
index 2c075a508..381378262 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h
+++ b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h
@@ -1,300 +1,204 @@
JSC::Structure* JSAttributeIteratorStructure() { return m_JSAttributeIterator.getInitializedOnMainThread(this); }
- JSC::JSObject* JSAttributeIteratorConstructor() { return m_JSAttributeIterator.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSAttributeIteratorPrototype() { return m_JSAttributeIterator.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSAttributeIteratorConstructor() { return m_JSAttributeIterator.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSAttributeIteratorPrototype() { return m_JSAttributeIterator.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSAttributeIterator;
- bool hasJSAttributeIteratorSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSAttributeIteratorSetterValue;
JSC::Structure* JSBigIntStatsStructure() { return m_JSBigIntStats.getInitializedOnMainThread(this); }
- JSC::JSObject* JSBigIntStatsConstructor() { return m_JSBigIntStats.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSBigIntStatsPrototype() { return m_JSBigIntStats.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSBigIntStatsConstructor() { return m_JSBigIntStats.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSBigIntStatsPrototype() { return m_JSBigIntStats.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSBigIntStats;
- bool hasJSBigIntStatsSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSBigIntStatsSetterValue;
JSC::Structure* JSBlobStructure() { return m_JSBlob.getInitializedOnMainThread(this); }
- JSC::JSObject* JSBlobConstructor() { return m_JSBlob.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSBlobPrototype() { return m_JSBlob.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSBlobConstructor() { return m_JSBlob.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSBlobPrototype() { return m_JSBlob.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSBlob;
- bool hasJSBlobSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSBlobSetterValue;
JSC::Structure* JSBuildArtifactStructure() { return m_JSBuildArtifact.getInitializedOnMainThread(this); }
- JSC::JSObject* JSBuildArtifactConstructor() { return m_JSBuildArtifact.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSBuildArtifactPrototype() { return m_JSBuildArtifact.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSBuildArtifactConstructor() { return m_JSBuildArtifact.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSBuildArtifactPrototype() { return m_JSBuildArtifact.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSBuildArtifact;
- bool hasJSBuildArtifactSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSBuildArtifactSetterValue;
JSC::Structure* JSBuildMessageStructure() { return m_JSBuildMessage.getInitializedOnMainThread(this); }
- JSC::JSObject* JSBuildMessageConstructor() { return m_JSBuildMessage.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSBuildMessagePrototype() { return m_JSBuildMessage.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSBuildMessageConstructor() { return m_JSBuildMessage.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSBuildMessagePrototype() { return m_JSBuildMessage.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSBuildMessage;
- bool hasJSBuildMessageSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSBuildMessageSetterValue;
JSC::Structure* JSCommentStructure() { return m_JSComment.getInitializedOnMainThread(this); }
- JSC::JSObject* JSCommentConstructor() { return m_JSComment.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSCommentPrototype() { return m_JSComment.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSCommentConstructor() { return m_JSComment.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSCommentPrototype() { return m_JSComment.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSComment;
- bool hasJSCommentSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSCommentSetterValue;
JSC::Structure* JSCryptoStructure() { return m_JSCrypto.getInitializedOnMainThread(this); }
- JSC::JSObject* JSCryptoConstructor() { return m_JSCrypto.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSCryptoPrototype() { return m_JSCrypto.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSCryptoConstructor() { return m_JSCrypto.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSCryptoPrototype() { return m_JSCrypto.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSCrypto;
- bool hasJSCryptoSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSCryptoSetterValue;
JSC::Structure* JSCryptoHasherStructure() { return m_JSCryptoHasher.getInitializedOnMainThread(this); }
- JSC::JSObject* JSCryptoHasherConstructor() { return m_JSCryptoHasher.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSCryptoHasherPrototype() { return m_JSCryptoHasher.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSCryptoHasherConstructor() { return m_JSCryptoHasher.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSCryptoHasherPrototype() { return m_JSCryptoHasher.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSCryptoHasher;
- bool hasJSCryptoHasherSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSCryptoHasherSetterValue;
JSC::Structure* JSDebugHTTPSServerStructure() { return m_JSDebugHTTPSServer.getInitializedOnMainThread(this); }
- JSC::JSObject* JSDebugHTTPSServerConstructor() { return m_JSDebugHTTPSServer.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSDebugHTTPSServerPrototype() { return m_JSDebugHTTPSServer.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSDebugHTTPSServerConstructor() { return m_JSDebugHTTPSServer.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSDebugHTTPSServerPrototype() { return m_JSDebugHTTPSServer.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSDebugHTTPSServer;
- bool hasJSDebugHTTPSServerSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSDebugHTTPSServerSetterValue;
JSC::Structure* JSDebugHTTPServerStructure() { return m_JSDebugHTTPServer.getInitializedOnMainThread(this); }
- JSC::JSObject* JSDebugHTTPServerConstructor() { return m_JSDebugHTTPServer.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSDebugHTTPServerPrototype() { return m_JSDebugHTTPServer.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSDebugHTTPServerConstructor() { return m_JSDebugHTTPServer.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSDebugHTTPServerPrototype() { return m_JSDebugHTTPServer.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSDebugHTTPServer;
- bool hasJSDebugHTTPServerSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSDebugHTTPServerSetterValue;
JSC::Structure* JSDirentStructure() { return m_JSDirent.getInitializedOnMainThread(this); }
- JSC::JSObject* JSDirentConstructor() { return m_JSDirent.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSDirentPrototype() { return m_JSDirent.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSDirentConstructor() { return m_JSDirent.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSDirentPrototype() { return m_JSDirent.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSDirent;
- bool hasJSDirentSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSDirentSetterValue;
JSC::Structure* JSDocEndStructure() { return m_JSDocEnd.getInitializedOnMainThread(this); }
- JSC::JSObject* JSDocEndConstructor() { return m_JSDocEnd.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSDocEndPrototype() { return m_JSDocEnd.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSDocEndConstructor() { return m_JSDocEnd.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSDocEndPrototype() { return m_JSDocEnd.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSDocEnd;
- bool hasJSDocEndSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSDocEndSetterValue;
JSC::Structure* JSDocTypeStructure() { return m_JSDocType.getInitializedOnMainThread(this); }
- JSC::JSObject* JSDocTypeConstructor() { return m_JSDocType.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSDocTypePrototype() { return m_JSDocType.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSDocTypeConstructor() { return m_JSDocType.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSDocTypePrototype() { return m_JSDocType.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSDocType;
- bool hasJSDocTypeSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSDocTypeSetterValue;
JSC::Structure* JSElementStructure() { return m_JSElement.getInitializedOnMainThread(this); }
- JSC::JSObject* JSElementConstructor() { return m_JSElement.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSElementPrototype() { return m_JSElement.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSElementConstructor() { return m_JSElement.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSElementPrototype() { return m_JSElement.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSElement;
- bool hasJSElementSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSElementSetterValue;
JSC::Structure* JSEndTagStructure() { return m_JSEndTag.getInitializedOnMainThread(this); }
- JSC::JSObject* JSEndTagConstructor() { return m_JSEndTag.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSEndTagPrototype() { return m_JSEndTag.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSEndTagConstructor() { return m_JSEndTag.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSEndTagPrototype() { return m_JSEndTag.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSEndTag;
- bool hasJSEndTagSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSEndTagSetterValue;
JSC::Structure* JSExpectStructure() { return m_JSExpect.getInitializedOnMainThread(this); }
- JSC::JSObject* JSExpectConstructor() { return m_JSExpect.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSExpectPrototype() { return m_JSExpect.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSExpectConstructor() { return m_JSExpect.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSExpectPrototype() { return m_JSExpect.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSExpect;
- bool hasJSExpectSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSExpectSetterValue;
JSC::Structure* JSExpectAnyStructure() { return m_JSExpectAny.getInitializedOnMainThread(this); }
- JSC::JSObject* JSExpectAnyConstructor() { return m_JSExpectAny.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSExpectAnyPrototype() { return m_JSExpectAny.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSExpectAnyConstructor() { return m_JSExpectAny.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSExpectAnyPrototype() { return m_JSExpectAny.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSExpectAny;
- bool hasJSExpectAnySetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSExpectAnySetterValue;
JSC::Structure* JSExpectAnythingStructure() { return m_JSExpectAnything.getInitializedOnMainThread(this); }
- JSC::JSObject* JSExpectAnythingConstructor() { return m_JSExpectAnything.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSExpectAnythingPrototype() { return m_JSExpectAnything.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSExpectAnythingConstructor() { return m_JSExpectAnything.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSExpectAnythingPrototype() { return m_JSExpectAnything.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSExpectAnything;
- bool hasJSExpectAnythingSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSExpectAnythingSetterValue;
+JSC::Structure* JSExpectArrayContainingStructure() { return m_JSExpectArrayContaining.getInitializedOnMainThread(this); }
+ JSC::JSObject* JSExpectArrayContainingConstructor() { return m_JSExpectArrayContaining.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSExpectArrayContainingPrototype() { return m_JSExpectArrayContaining.prototypeInitializedOnMainThread(this); }
+ JSC::LazyClassStructure m_JSExpectArrayContaining;
JSC::Structure* JSExpectStringContainingStructure() { return m_JSExpectStringContaining.getInitializedOnMainThread(this); }
- JSC::JSObject* JSExpectStringContainingConstructor() { return m_JSExpectStringContaining.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSExpectStringContainingPrototype() { return m_JSExpectStringContaining.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSExpectStringContainingConstructor() { return m_JSExpectStringContaining.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSExpectStringContainingPrototype() { return m_JSExpectStringContaining.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSExpectStringContaining;
- bool hasJSExpectStringContainingSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSExpectStringContainingSetterValue;
JSC::Structure* JSExpectStringMatchingStructure() { return m_JSExpectStringMatching.getInitializedOnMainThread(this); }
- JSC::JSObject* JSExpectStringMatchingConstructor() { return m_JSExpectStringMatching.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSExpectStringMatchingPrototype() { return m_JSExpectStringMatching.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSExpectStringMatchingConstructor() { return m_JSExpectStringMatching.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSExpectStringMatchingPrototype() { return m_JSExpectStringMatching.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSExpectStringMatching;
- bool hasJSExpectStringMatchingSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSExpectStringMatchingSetterValue;
JSC::Structure* JSFFIStructure() { return m_JSFFI.getInitializedOnMainThread(this); }
- JSC::JSObject* JSFFIConstructor() { return m_JSFFI.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSFFIPrototype() { return m_JSFFI.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSFFIConstructor() { return m_JSFFI.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSFFIPrototype() { return m_JSFFI.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSFFI;
- bool hasJSFFISetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSFFISetterValue;
JSC::Structure* JSFSWatcherStructure() { return m_JSFSWatcher.getInitializedOnMainThread(this); }
- JSC::JSObject* JSFSWatcherConstructor() { return m_JSFSWatcher.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSFSWatcherPrototype() { return m_JSFSWatcher.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSFSWatcherConstructor() { return m_JSFSWatcher.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSFSWatcherPrototype() { return m_JSFSWatcher.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSFSWatcher;
- bool hasJSFSWatcherSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSFSWatcherSetterValue;
JSC::Structure* JSFileSystemRouterStructure() { return m_JSFileSystemRouter.getInitializedOnMainThread(this); }
- JSC::JSObject* JSFileSystemRouterConstructor() { return m_JSFileSystemRouter.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSFileSystemRouterPrototype() { return m_JSFileSystemRouter.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSFileSystemRouterConstructor() { return m_JSFileSystemRouter.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSFileSystemRouterPrototype() { return m_JSFileSystemRouter.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSFileSystemRouter;
- bool hasJSFileSystemRouterSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSFileSystemRouterSetterValue;
JSC::Structure* JSHTMLRewriterStructure() { return m_JSHTMLRewriter.getInitializedOnMainThread(this); }
- JSC::JSObject* JSHTMLRewriterConstructor() { return m_JSHTMLRewriter.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSHTMLRewriterPrototype() { return m_JSHTMLRewriter.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSHTMLRewriterConstructor() { return m_JSHTMLRewriter.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSHTMLRewriterPrototype() { return m_JSHTMLRewriter.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSHTMLRewriter;
- bool hasJSHTMLRewriterSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSHTMLRewriterSetterValue;
JSC::Structure* JSHTTPSServerStructure() { return m_JSHTTPSServer.getInitializedOnMainThread(this); }
- JSC::JSObject* JSHTTPSServerConstructor() { return m_JSHTTPSServer.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSHTTPSServerPrototype() { return m_JSHTTPSServer.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSHTTPSServerConstructor() { return m_JSHTTPSServer.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSHTTPSServerPrototype() { return m_JSHTTPSServer.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSHTTPSServer;
- bool hasJSHTTPSServerSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSHTTPSServerSetterValue;
JSC::Structure* JSHTTPServerStructure() { return m_JSHTTPServer.getInitializedOnMainThread(this); }
- JSC::JSObject* JSHTTPServerConstructor() { return m_JSHTTPServer.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSHTTPServerPrototype() { return m_JSHTTPServer.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSHTTPServerConstructor() { return m_JSHTTPServer.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSHTTPServerPrototype() { return m_JSHTTPServer.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSHTTPServer;
- bool hasJSHTTPServerSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSHTTPServerSetterValue;
JSC::Structure* JSListenerStructure() { return m_JSListener.getInitializedOnMainThread(this); }
- JSC::JSObject* JSListenerConstructor() { return m_JSListener.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSListenerPrototype() { return m_JSListener.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSListenerConstructor() { return m_JSListener.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSListenerPrototype() { return m_JSListener.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSListener;
- bool hasJSListenerSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSListenerSetterValue;
JSC::Structure* JSMD4Structure() { return m_JSMD4.getInitializedOnMainThread(this); }
- JSC::JSObject* JSMD4Constructor() { return m_JSMD4.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSMD4Prototype() { return m_JSMD4.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSMD4Constructor() { return m_JSMD4.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSMD4Prototype() { return m_JSMD4.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSMD4;
- bool hasJSMD4SetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSMD4SetterValue;
JSC::Structure* JSMD5Structure() { return m_JSMD5.getInitializedOnMainThread(this); }
- JSC::JSObject* JSMD5Constructor() { return m_JSMD5.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSMD5Prototype() { return m_JSMD5.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSMD5Constructor() { return m_JSMD5.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSMD5Prototype() { return m_JSMD5.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSMD5;
- bool hasJSMD5SetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSMD5SetterValue;
JSC::Structure* JSMatchedRouteStructure() { return m_JSMatchedRoute.getInitializedOnMainThread(this); }
- JSC::JSObject* JSMatchedRouteConstructor() { return m_JSMatchedRoute.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSMatchedRoutePrototype() { return m_JSMatchedRoute.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSMatchedRouteConstructor() { return m_JSMatchedRoute.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSMatchedRoutePrototype() { return m_JSMatchedRoute.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSMatchedRoute;
- bool hasJSMatchedRouteSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSMatchedRouteSetterValue;
JSC::Structure* JSNodeJSFSStructure() { return m_JSNodeJSFS.getInitializedOnMainThread(this); }
- JSC::JSObject* JSNodeJSFSConstructor() { return m_JSNodeJSFS.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSNodeJSFSPrototype() { return m_JSNodeJSFS.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSNodeJSFSConstructor() { return m_JSNodeJSFS.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSNodeJSFSPrototype() { return m_JSNodeJSFS.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSNodeJSFS;
- bool hasJSNodeJSFSSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSNodeJSFSSetterValue;
JSC::Structure* JSRequestStructure() { return m_JSRequest.getInitializedOnMainThread(this); }
- JSC::JSObject* JSRequestConstructor() { return m_JSRequest.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSRequestPrototype() { return m_JSRequest.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSRequestConstructor() { return m_JSRequest.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSRequestPrototype() { return m_JSRequest.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSRequest;
- bool hasJSRequestSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSRequestSetterValue;
JSC::Structure* JSResolveMessageStructure() { return m_JSResolveMessage.getInitializedOnMainThread(this); }
- JSC::JSObject* JSResolveMessageConstructor() { return m_JSResolveMessage.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSResolveMessagePrototype() { return m_JSResolveMessage.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSResolveMessageConstructor() { return m_JSResolveMessage.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSResolveMessagePrototype() { return m_JSResolveMessage.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSResolveMessage;
- bool hasJSResolveMessageSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSResolveMessageSetterValue;
JSC::Structure* JSResponseStructure() { return m_JSResponse.getInitializedOnMainThread(this); }
- JSC::JSObject* JSResponseConstructor() { return m_JSResponse.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSResponsePrototype() { return m_JSResponse.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSResponseConstructor() { return m_JSResponse.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSResponsePrototype() { return m_JSResponse.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSResponse;
- bool hasJSResponseSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSResponseSetterValue;
JSC::Structure* JSSHA1Structure() { return m_JSSHA1.getInitializedOnMainThread(this); }
- JSC::JSObject* JSSHA1Constructor() { return m_JSSHA1.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSSHA1Prototype() { return m_JSSHA1.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSSHA1Constructor() { return m_JSSHA1.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSSHA1Prototype() { return m_JSSHA1.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSSHA1;
- bool hasJSSHA1SetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSSHA1SetterValue;
JSC::Structure* JSSHA224Structure() { return m_JSSHA224.getInitializedOnMainThread(this); }
- JSC::JSObject* JSSHA224Constructor() { return m_JSSHA224.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSSHA224Prototype() { return m_JSSHA224.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSSHA224Constructor() { return m_JSSHA224.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSSHA224Prototype() { return m_JSSHA224.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSSHA224;
- bool hasJSSHA224SetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSSHA224SetterValue;
JSC::Structure* JSSHA256Structure() { return m_JSSHA256.getInitializedOnMainThread(this); }
- JSC::JSObject* JSSHA256Constructor() { return m_JSSHA256.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSSHA256Prototype() { return m_JSSHA256.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSSHA256Constructor() { return m_JSSHA256.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSSHA256Prototype() { return m_JSSHA256.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSSHA256;
- bool hasJSSHA256SetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSSHA256SetterValue;
JSC::Structure* JSSHA384Structure() { return m_JSSHA384.getInitializedOnMainThread(this); }
- JSC::JSObject* JSSHA384Constructor() { return m_JSSHA384.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSSHA384Prototype() { return m_JSSHA384.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSSHA384Constructor() { return m_JSSHA384.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSSHA384Prototype() { return m_JSSHA384.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSSHA384;
- bool hasJSSHA384SetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSSHA384SetterValue;
JSC::Structure* JSSHA512Structure() { return m_JSSHA512.getInitializedOnMainThread(this); }
- JSC::JSObject* JSSHA512Constructor() { return m_JSSHA512.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSSHA512Prototype() { return m_JSSHA512.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSSHA512Constructor() { return m_JSSHA512.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSSHA512Prototype() { return m_JSSHA512.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSSHA512;
- bool hasJSSHA512SetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSSHA512SetterValue;
JSC::Structure* JSSHA512_256Structure() { return m_JSSHA512_256.getInitializedOnMainThread(this); }
- JSC::JSObject* JSSHA512_256Constructor() { return m_JSSHA512_256.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSSHA512_256Prototype() { return m_JSSHA512_256.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSSHA512_256Constructor() { return m_JSSHA512_256.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSSHA512_256Prototype() { return m_JSSHA512_256.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSSHA512_256;
- bool hasJSSHA512_256SetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSSHA512_256SetterValue;
JSC::Structure* JSServerWebSocketStructure() { return m_JSServerWebSocket.getInitializedOnMainThread(this); }
- JSC::JSObject* JSServerWebSocketConstructor() { return m_JSServerWebSocket.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSServerWebSocketPrototype() { return m_JSServerWebSocket.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSServerWebSocketConstructor() { return m_JSServerWebSocket.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSServerWebSocketPrototype() { return m_JSServerWebSocket.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSServerWebSocket;
- bool hasJSServerWebSocketSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSServerWebSocketSetterValue;
JSC::Structure* JSStatWatcherStructure() { return m_JSStatWatcher.getInitializedOnMainThread(this); }
- JSC::JSObject* JSStatWatcherConstructor() { return m_JSStatWatcher.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSStatWatcherPrototype() { return m_JSStatWatcher.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSStatWatcherConstructor() { return m_JSStatWatcher.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSStatWatcherPrototype() { return m_JSStatWatcher.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSStatWatcher;
- bool hasJSStatWatcherSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSStatWatcherSetterValue;
JSC::Structure* JSStatsStructure() { return m_JSStats.getInitializedOnMainThread(this); }
- JSC::JSObject* JSStatsConstructor() { return m_JSStats.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSStatsPrototype() { return m_JSStats.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSStatsConstructor() { return m_JSStats.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSStatsPrototype() { return m_JSStats.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSStats;
- bool hasJSStatsSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSStatsSetterValue;
JSC::Structure* JSSubprocessStructure() { return m_JSSubprocess.getInitializedOnMainThread(this); }
- JSC::JSObject* JSSubprocessConstructor() { return m_JSSubprocess.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSSubprocessPrototype() { return m_JSSubprocess.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSSubprocessConstructor() { return m_JSSubprocess.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSSubprocessPrototype() { return m_JSSubprocess.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSSubprocess;
- bool hasJSSubprocessSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSSubprocessSetterValue;
JSC::Structure* JSTCPSocketStructure() { return m_JSTCPSocket.getInitializedOnMainThread(this); }
- JSC::JSObject* JSTCPSocketConstructor() { return m_JSTCPSocket.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSTCPSocketPrototype() { return m_JSTCPSocket.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSTCPSocketConstructor() { return m_JSTCPSocket.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSTCPSocketPrototype() { return m_JSTCPSocket.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSTCPSocket;
- bool hasJSTCPSocketSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSTCPSocketSetterValue;
JSC::Structure* JSTLSSocketStructure() { return m_JSTLSSocket.getInitializedOnMainThread(this); }
- JSC::JSObject* JSTLSSocketConstructor() { return m_JSTLSSocket.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSTLSSocketPrototype() { return m_JSTLSSocket.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSTLSSocketConstructor() { return m_JSTLSSocket.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSTLSSocketPrototype() { return m_JSTLSSocket.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSTLSSocket;
- bool hasJSTLSSocketSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSTLSSocketSetterValue;
JSC::Structure* JSTextChunkStructure() { return m_JSTextChunk.getInitializedOnMainThread(this); }
- JSC::JSObject* JSTextChunkConstructor() { return m_JSTextChunk.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSTextChunkPrototype() { return m_JSTextChunk.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSTextChunkConstructor() { return m_JSTextChunk.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSTextChunkPrototype() { return m_JSTextChunk.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSTextChunk;
- bool hasJSTextChunkSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSTextChunkSetterValue;
JSC::Structure* JSTextDecoderStructure() { return m_JSTextDecoder.getInitializedOnMainThread(this); }
- JSC::JSObject* JSTextDecoderConstructor() { return m_JSTextDecoder.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSTextDecoderPrototype() { return m_JSTextDecoder.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSTextDecoderConstructor() { return m_JSTextDecoder.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSTextDecoderPrototype() { return m_JSTextDecoder.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSTextDecoder;
- bool hasJSTextDecoderSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSTextDecoderSetterValue;
JSC::Structure* JSTimeoutStructure() { return m_JSTimeout.getInitializedOnMainThread(this); }
- JSC::JSObject* JSTimeoutConstructor() { return m_JSTimeout.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSTimeoutPrototype() { return m_JSTimeout.prototypeInitializedOnMainThread(this); }
+ JSC::JSObject* JSTimeoutConstructor() { return m_JSTimeout.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSTimeoutPrototype() { return m_JSTimeout.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_JSTimeout;
- bool hasJSTimeoutSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSTimeoutSetterValue;
JSC::Structure* JSTranspilerStructure() { return m_JSTranspiler.getInitializedOnMainThread(this); }
- JSC::JSObject* JSTranspilerConstructor() { return m_JSTranspiler.constructorInitializedOnMainThread(this); }
- JSC::JSValue JSTranspilerPrototype() { return m_JSTranspiler.prototypeInitializedOnMainThread(this); }
- JSC::LazyClassStructure m_JSTranspiler;
- bool hasJSTranspilerSetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_JSTranspilerSetterValue; \ No newline at end of file
+ JSC::JSObject* JSTranspilerConstructor() { return m_JSTranspiler.constructorInitializedOnMainThread(this); }
+ JSC::JSValue JSTranspilerPrototype() { return m_JSTranspiler.prototypeInitializedOnMainThread(this); }
+ JSC::LazyClassStructure m_JSTranspiler; \ No newline at end of file
diff --git a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h
index cb4c47ccb..84d3df7a0 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h
+++ b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h
@@ -1,4 +1,4 @@
-void GlobalObject::initGeneratedLazyClasses() {
+ALWAYS_INLINE void GlobalObject::initGeneratedLazyClasses() {
m_JSAttributeIterator.initLater(
[](LazyClassStructure::Initializer& init) {
init.setPrototype(WebCore::JSAttributeIterator::createPrototype(init.vm, reinterpret_cast<Zig::GlobalObject*>(init.global)));
@@ -107,6 +107,12 @@ void GlobalObject::initGeneratedLazyClasses() {
init.setStructure(WebCore::JSExpectAnything::createStructure(init.vm, init.global, init.prototype));
});
+ m_JSExpectArrayContaining.initLater(
+ [](LazyClassStructure::Initializer& init) {
+ init.setPrototype(WebCore::JSExpectArrayContaining::createPrototype(init.vm, reinterpret_cast<Zig::GlobalObject*>(init.global)));
+ init.setStructure(WebCore::JSExpectArrayContaining::createStructure(init.vm, init.global, init.prototype));
+
+ });
m_JSExpectStringContaining.initLater(
[](LazyClassStructure::Initializer& init) {
init.setPrototype(WebCore::JSExpectStringContaining::createPrototype(init.vm, reinterpret_cast<Zig::GlobalObject*>(init.global)));
@@ -303,54 +309,55 @@ void GlobalObject::initGeneratedLazyClasses() {
template<typename Visitor>
void GlobalObject::visitGeneratedLazyClasses(GlobalObject *thisObject, Visitor& visitor)
{
- thisObject->m_JSAttributeIterator.visit(visitor); visitor.append(thisObject->m_JSAttributeIteratorSetterValue);
- thisObject->m_JSBigIntStats.visit(visitor); visitor.append(thisObject->m_JSBigIntStatsSetterValue);
- thisObject->m_JSBlob.visit(visitor); visitor.append(thisObject->m_JSBlobSetterValue);
- thisObject->m_JSBuildArtifact.visit(visitor); visitor.append(thisObject->m_JSBuildArtifactSetterValue);
- thisObject->m_JSBuildMessage.visit(visitor); visitor.append(thisObject->m_JSBuildMessageSetterValue);
- thisObject->m_JSComment.visit(visitor); visitor.append(thisObject->m_JSCommentSetterValue);
- thisObject->m_JSCrypto.visit(visitor); visitor.append(thisObject->m_JSCryptoSetterValue);
- thisObject->m_JSCryptoHasher.visit(visitor); visitor.append(thisObject->m_JSCryptoHasherSetterValue);
- thisObject->m_JSDebugHTTPSServer.visit(visitor); visitor.append(thisObject->m_JSDebugHTTPSServerSetterValue);
- thisObject->m_JSDebugHTTPServer.visit(visitor); visitor.append(thisObject->m_JSDebugHTTPServerSetterValue);
- thisObject->m_JSDirent.visit(visitor); visitor.append(thisObject->m_JSDirentSetterValue);
- thisObject->m_JSDocEnd.visit(visitor); visitor.append(thisObject->m_JSDocEndSetterValue);
- thisObject->m_JSDocType.visit(visitor); visitor.append(thisObject->m_JSDocTypeSetterValue);
- thisObject->m_JSElement.visit(visitor); visitor.append(thisObject->m_JSElementSetterValue);
- thisObject->m_JSEndTag.visit(visitor); visitor.append(thisObject->m_JSEndTagSetterValue);
- thisObject->m_JSExpect.visit(visitor); visitor.append(thisObject->m_JSExpectSetterValue);
- thisObject->m_JSExpectAny.visit(visitor); visitor.append(thisObject->m_JSExpectAnySetterValue);
- thisObject->m_JSExpectAnything.visit(visitor); visitor.append(thisObject->m_JSExpectAnythingSetterValue);
- thisObject->m_JSExpectStringContaining.visit(visitor); visitor.append(thisObject->m_JSExpectStringContainingSetterValue);
- thisObject->m_JSExpectStringMatching.visit(visitor); visitor.append(thisObject->m_JSExpectStringMatchingSetterValue);
- thisObject->m_JSFFI.visit(visitor); visitor.append(thisObject->m_JSFFISetterValue);
- thisObject->m_JSFSWatcher.visit(visitor); visitor.append(thisObject->m_JSFSWatcherSetterValue);
- thisObject->m_JSFileSystemRouter.visit(visitor); visitor.append(thisObject->m_JSFileSystemRouterSetterValue);
- thisObject->m_JSHTMLRewriter.visit(visitor); visitor.append(thisObject->m_JSHTMLRewriterSetterValue);
- thisObject->m_JSHTTPSServer.visit(visitor); visitor.append(thisObject->m_JSHTTPSServerSetterValue);
- thisObject->m_JSHTTPServer.visit(visitor); visitor.append(thisObject->m_JSHTTPServerSetterValue);
- thisObject->m_JSListener.visit(visitor); visitor.append(thisObject->m_JSListenerSetterValue);
- thisObject->m_JSMD4.visit(visitor); visitor.append(thisObject->m_JSMD4SetterValue);
- thisObject->m_JSMD5.visit(visitor); visitor.append(thisObject->m_JSMD5SetterValue);
- thisObject->m_JSMatchedRoute.visit(visitor); visitor.append(thisObject->m_JSMatchedRouteSetterValue);
- thisObject->m_JSNodeJSFS.visit(visitor); visitor.append(thisObject->m_JSNodeJSFSSetterValue);
- thisObject->m_JSRequest.visit(visitor); visitor.append(thisObject->m_JSRequestSetterValue);
- thisObject->m_JSResolveMessage.visit(visitor); visitor.append(thisObject->m_JSResolveMessageSetterValue);
- thisObject->m_JSResponse.visit(visitor); visitor.append(thisObject->m_JSResponseSetterValue);
- thisObject->m_JSSHA1.visit(visitor); visitor.append(thisObject->m_JSSHA1SetterValue);
- thisObject->m_JSSHA224.visit(visitor); visitor.append(thisObject->m_JSSHA224SetterValue);
- thisObject->m_JSSHA256.visit(visitor); visitor.append(thisObject->m_JSSHA256SetterValue);
- thisObject->m_JSSHA384.visit(visitor); visitor.append(thisObject->m_JSSHA384SetterValue);
- thisObject->m_JSSHA512.visit(visitor); visitor.append(thisObject->m_JSSHA512SetterValue);
- thisObject->m_JSSHA512_256.visit(visitor); visitor.append(thisObject->m_JSSHA512_256SetterValue);
- thisObject->m_JSServerWebSocket.visit(visitor); visitor.append(thisObject->m_JSServerWebSocketSetterValue);
- thisObject->m_JSStatWatcher.visit(visitor); visitor.append(thisObject->m_JSStatWatcherSetterValue);
- thisObject->m_JSStats.visit(visitor); visitor.append(thisObject->m_JSStatsSetterValue);
- thisObject->m_JSSubprocess.visit(visitor); visitor.append(thisObject->m_JSSubprocessSetterValue);
- thisObject->m_JSTCPSocket.visit(visitor); visitor.append(thisObject->m_JSTCPSocketSetterValue);
- thisObject->m_JSTLSSocket.visit(visitor); visitor.append(thisObject->m_JSTLSSocketSetterValue);
- thisObject->m_JSTextChunk.visit(visitor); visitor.append(thisObject->m_JSTextChunkSetterValue);
- thisObject->m_JSTextDecoder.visit(visitor); visitor.append(thisObject->m_JSTextDecoderSetterValue);
- thisObject->m_JSTimeout.visit(visitor); visitor.append(thisObject->m_JSTimeoutSetterValue);
- thisObject->m_JSTranspiler.visit(visitor); visitor.append(thisObject->m_JSTranspilerSetterValue);
+ thisObject->m_JSAttributeIterator.visit(visitor);
+ thisObject->m_JSBigIntStats.visit(visitor);
+ thisObject->m_JSBlob.visit(visitor);
+ thisObject->m_JSBuildArtifact.visit(visitor);
+ thisObject->m_JSBuildMessage.visit(visitor);
+ thisObject->m_JSComment.visit(visitor);
+ thisObject->m_JSCrypto.visit(visitor);
+ thisObject->m_JSCryptoHasher.visit(visitor);
+ thisObject->m_JSDebugHTTPSServer.visit(visitor);
+ thisObject->m_JSDebugHTTPServer.visit(visitor);
+ thisObject->m_JSDirent.visit(visitor);
+ thisObject->m_JSDocEnd.visit(visitor);
+ thisObject->m_JSDocType.visit(visitor);
+ thisObject->m_JSElement.visit(visitor);
+ thisObject->m_JSEndTag.visit(visitor);
+ thisObject->m_JSExpect.visit(visitor);
+ thisObject->m_JSExpectAny.visit(visitor);
+ thisObject->m_JSExpectAnything.visit(visitor);
+ thisObject->m_JSExpectArrayContaining.visit(visitor);
+ thisObject->m_JSExpectStringContaining.visit(visitor);
+ thisObject->m_JSExpectStringMatching.visit(visitor);
+ thisObject->m_JSFFI.visit(visitor);
+ thisObject->m_JSFSWatcher.visit(visitor);
+ thisObject->m_JSFileSystemRouter.visit(visitor);
+ thisObject->m_JSHTMLRewriter.visit(visitor);
+ thisObject->m_JSHTTPSServer.visit(visitor);
+ thisObject->m_JSHTTPServer.visit(visitor);
+ thisObject->m_JSListener.visit(visitor);
+ thisObject->m_JSMD4.visit(visitor);
+ thisObject->m_JSMD5.visit(visitor);
+ thisObject->m_JSMatchedRoute.visit(visitor);
+ thisObject->m_JSNodeJSFS.visit(visitor);
+ thisObject->m_JSRequest.visit(visitor);
+ thisObject->m_JSResolveMessage.visit(visitor);
+ thisObject->m_JSResponse.visit(visitor);
+ thisObject->m_JSSHA1.visit(visitor);
+ thisObject->m_JSSHA224.visit(visitor);
+ thisObject->m_JSSHA256.visit(visitor);
+ thisObject->m_JSSHA384.visit(visitor);
+ thisObject->m_JSSHA512.visit(visitor);
+ thisObject->m_JSSHA512_256.visit(visitor);
+ thisObject->m_JSServerWebSocket.visit(visitor);
+ thisObject->m_JSStatWatcher.visit(visitor);
+ thisObject->m_JSStats.visit(visitor);
+ thisObject->m_JSSubprocess.visit(visitor);
+ thisObject->m_JSTCPSocket.visit(visitor);
+ thisObject->m_JSTLSSocket.visit(visitor);
+ thisObject->m_JSTextChunk.visit(visitor);
+ thisObject->m_JSTextDecoder.visit(visitor);
+ thisObject->m_JSTimeout.visit(visitor);
+ thisObject->m_JSTranspiler.visit(visitor);
} \ No newline at end of file
diff --git a/src/bun.js/bindings/ZigGeneratedClasses.cpp b/src/bun.js/bindings/ZigGeneratedClasses.cpp
index ec2add296..8d8c98154 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses.cpp
+++ b/src/bun.js/bindings/ZigGeneratedClasses.cpp
@@ -43,6 +43,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSAttributeIteratorPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -150,7 +151,7 @@ void JSAttributeIteratorPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObje
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSAttributeIterator::info(), JSAttributeIteratorPrototypeTableValues, *this);
- this->putDirect(vm, vm.propertyNames->iteratorSymbol, JSFunction::create(vm, globalObject, 1, String("iterator"_s), AttributeIteratorPrototype__iteratorCallback, ImplementationVisibility::Public), PropertyAttribute::Function | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | 0);
+ this->putDirect(vm, vm.propertyNames->iteratorSymbol, JSFunction::create(vm, globalObject, 1, String("iterator"_s), AttributeIteratorPrototype__iteratorCallback, ImplementationVisibility::Public), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | 0);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
@@ -245,6 +246,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSBigIntStatsPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -1301,6 +1303,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSBlobPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -1777,7 +1780,7 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSBlobConstructor::construct(JSC::J
}
JSBlob* instance = JSBlob::create(vm, globalObject, structure, ptr);
- vm.heap.reportExtraMemoryAllocated(Blob__estimatedSize(instance->wrapped()));
+ vm.heap.reportExtraMemoryAllocated(instance, Blob__estimatedSize(instance->wrapped()));
return JSValue::encode(instance);
}
@@ -1871,7 +1874,7 @@ extern "C" EncodedJSValue Blob__create(Zig::GlobalObject* globalObject, void* pt
auto& vm = globalObject->vm();
JSC::Structure* structure = globalObject->JSBlobStructure();
JSBlob* instance = JSBlob::create(vm, globalObject, structure, ptr);
- vm.heap.reportExtraMemoryAllocated(Blob__estimatedSize(ptr));
+ vm.heap.reportExtraMemoryAllocated(instance, Blob__estimatedSize(ptr));
return JSValue::encode(instance);
}
@@ -1924,6 +1927,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSBuildArtifactPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -2471,6 +2475,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSBuildMessagePrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -2752,7 +2757,7 @@ void JSBuildMessagePrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* g
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSBuildMessage::info(), JSBuildMessagePrototypeTableValues, *this);
- this->putDirect(vm, vm.propertyNames->toPrimitiveSymbol, JSFunction::create(vm, globalObject, 1, String("toPrimitive"_s), BuildMessagePrototype__toPrimitiveCallback, ImplementationVisibility::Public), PropertyAttribute::Function | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | 0);
+ this->putDirect(vm, vm.propertyNames->toPrimitiveSymbol, JSFunction::create(vm, globalObject, 1, String("toPrimitive"_s), BuildMessagePrototype__toPrimitiveCallback, ImplementationVisibility::Public), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | 0);
this->putDirect(vm, vm.propertyNames->name, jsString(vm, String("BuildMessage"_s)), PropertyAttribute::ReadOnly | 0);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
@@ -2950,6 +2955,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCommentPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -3262,6 +3268,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCryptoPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -3715,6 +3722,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCryptoHasherPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -4146,6 +4154,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDebugHTTPSServerPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -4167,6 +4176,9 @@ JSC_DECLARE_CUSTOM_GETTER(jsDebugHTTPSServerConstructor);
extern "C" void DebugHTTPSServerClass__finalize(void*);
+extern "C" JSC::EncodedJSValue DebugHTTPSServerPrototype__getAddress(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
+JSC_DECLARE_CUSTOM_GETTER(DebugHTTPSServerPrototype__addressGetterWrap);
+
extern "C" JSC::EncodedJSValue DebugHTTPSServerPrototype__getDevelopment(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
JSC_DECLARE_CUSTOM_GETTER(DebugHTTPSServerPrototype__developmentGetterWrap);
@@ -4197,6 +4209,9 @@ JSC_DECLARE_HOST_FUNCTION(DebugHTTPSServerPrototype__publishCallback);
extern "C" EncodedJSValue DebugHTTPSServerPrototype__doReload(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
JSC_DECLARE_HOST_FUNCTION(DebugHTTPSServerPrototype__reloadCallback);
+extern "C" EncodedJSValue DebugHTTPSServerPrototype__doRequestIP(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(DebugHTTPSServerPrototype__requestIPCallback);
+
extern "C" EncodedJSValue DebugHTTPSServerPrototype__doStop(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
JSC_DECLARE_HOST_FUNCTION(DebugHTTPSServerPrototype__stopCallback);
@@ -4206,6 +4221,7 @@ JSC_DECLARE_HOST_FUNCTION(DebugHTTPSServerPrototype__upgradeCallback);
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDebugHTTPSServerPrototype, JSDebugHTTPSServerPrototype::Base);
static const HashTableValue JSDebugHTTPSServerPrototypeTableValues[] = {
+ { "address"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPSServerPrototype__addressGetterWrap, 0 } },
{ "development"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPSServerPrototype__developmentGetterWrap, 0 } },
{ "fetch"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPSServerPrototype__fetchCallback, 1 } },
{ "hostname"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPSServerPrototype__hostnameGetterWrap, 0 } },
@@ -4216,6 +4232,7 @@ static const HashTableValue JSDebugHTTPSServerPrototypeTableValues[] = {
{ "protocol"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPSServerPrototype__protocolGetterWrap, 0 } },
{ "publish"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPSServerPrototype__publishCallback, 3 } },
{ "reload"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPSServerPrototype__reloadCallback, 2 } },
+ { "requestIP"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPSServerPrototype__requestIPCallback, 1 } },
{ "stop"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPSServerPrototype__stopCallback, 1 } },
{ "upgrade"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPSServerPrototype__upgradeCallback, 1 } }
};
@@ -4234,6 +4251,37 @@ JSC_DEFINE_CUSTOM_GETTER(jsDebugHTTPSServerConstructor, (JSGlobalObject * lexica
return JSValue::encode(globalObject->JSDebugHTTPSServerConstructor());
}
+JSC_DEFINE_CUSTOM_GETTER(DebugHTTPSServerPrototype__addressGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ auto& vm = lexicalGlobalObject->vm();
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ JSDebugHTTPSServer* thisObject = jsCast<JSDebugHTTPSServer*>(JSValue::decode(thisValue));
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+ if (JSValue cachedValue = thisObject->m_address.get())
+ return JSValue::encode(cachedValue);
+
+ JSC::JSValue result = JSC::JSValue::decode(
+ DebugHTTPSServerPrototype__getAddress(thisObject->wrapped(), globalObject));
+ RETURN_IF_EXCEPTION(throwScope, {});
+ thisObject->m_address.set(vm, thisObject, result);
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(result));
+}
+
+extern "C" void DebugHTTPSServerPrototype__addressSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value)
+{
+ auto& vm = globalObject->vm();
+ auto* thisObject = jsCast<JSDebugHTTPSServer*>(JSValue::decode(thisValue));
+ thisObject->m_address.set(vm, thisObject, JSValue::decode(value));
+}
+
+extern "C" EncodedJSValue DebugHTTPSServerPrototype__addressGetCachedValue(JSC::EncodedJSValue thisValue)
+{
+ auto* thisObject = jsCast<JSDebugHTTPSServer*>(JSValue::decode(thisValue));
+ return JSValue::encode(thisObject->m_address.get());
+}
+
JSC_DEFINE_CUSTOM_GETTER(DebugHTTPSServerPrototype__developmentGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
auto& vm = lexicalGlobalObject->vm();
@@ -4440,6 +4488,34 @@ JSC_DEFINE_HOST_FUNCTION(DebugHTTPSServerPrototype__reloadCallback, (JSGlobalObj
return DebugHTTPSServerPrototype__doReload(thisObject->wrapped(), lexicalGlobalObject, callFrame);
}
+JSC_DEFINE_HOST_FUNCTION(DebugHTTPSServerPrototype__requestIPCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSDebugHTTPSServer* thisObject = jsDynamicCast<JSDebugHTTPSServer*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ throwVMTypeError(lexicalGlobalObject, throwScope, "Expected 'this' to be instanceof DebugHTTPSServer"_s);
+ return JSValue::encode({});
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+#ifdef BUN_DEBUG
+ /** View the file name of the JS file that called this function
+ * from a debugger */
+ SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm);
+ const char* fileName = sourceOrigin.string().utf8().data();
+ static const char* lastFileName = nullptr;
+ if (lastFileName != fileName) {
+ lastFileName = fileName;
+ }
+#endif
+
+ return DebugHTTPSServerPrototype__doRequestIP(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
JSC_DEFINE_HOST_FUNCTION(DebugHTTPSServerPrototype__stopCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
auto& vm = lexicalGlobalObject->vm();
@@ -4598,6 +4674,7 @@ void JSDebugHTTPSServer::visitAdditionalChildren(Visitor& visitor)
JSDebugHTTPSServer* thisObject = this;
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ visitor.append(thisObject->m_address);
visitor.append(thisObject->m_hostname);
visitor.append(thisObject->m_id);
}
@@ -4628,6 +4705,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDebugHTTPServerPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -4649,6 +4727,9 @@ JSC_DECLARE_CUSTOM_GETTER(jsDebugHTTPServerConstructor);
extern "C" void DebugHTTPServerClass__finalize(void*);
+extern "C" JSC::EncodedJSValue DebugHTTPServerPrototype__getAddress(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
+JSC_DECLARE_CUSTOM_GETTER(DebugHTTPServerPrototype__addressGetterWrap);
+
extern "C" JSC::EncodedJSValue DebugHTTPServerPrototype__getDevelopment(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
JSC_DECLARE_CUSTOM_GETTER(DebugHTTPServerPrototype__developmentGetterWrap);
@@ -4679,6 +4760,9 @@ JSC_DECLARE_HOST_FUNCTION(DebugHTTPServerPrototype__publishCallback);
extern "C" EncodedJSValue DebugHTTPServerPrototype__doReload(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
JSC_DECLARE_HOST_FUNCTION(DebugHTTPServerPrototype__reloadCallback);
+extern "C" EncodedJSValue DebugHTTPServerPrototype__doRequestIP(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(DebugHTTPServerPrototype__requestIPCallback);
+
extern "C" EncodedJSValue DebugHTTPServerPrototype__doStop(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
JSC_DECLARE_HOST_FUNCTION(DebugHTTPServerPrototype__stopCallback);
@@ -4688,6 +4772,7 @@ JSC_DECLARE_HOST_FUNCTION(DebugHTTPServerPrototype__upgradeCallback);
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDebugHTTPServerPrototype, JSDebugHTTPServerPrototype::Base);
static const HashTableValue JSDebugHTTPServerPrototypeTableValues[] = {
+ { "address"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPServerPrototype__addressGetterWrap, 0 } },
{ "development"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPServerPrototype__developmentGetterWrap, 0 } },
{ "fetch"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPServerPrototype__fetchCallback, 1 } },
{ "hostname"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPServerPrototype__hostnameGetterWrap, 0 } },
@@ -4698,6 +4783,7 @@ static const HashTableValue JSDebugHTTPServerPrototypeTableValues[] = {
{ "protocol"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPServerPrototype__protocolGetterWrap, 0 } },
{ "publish"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPServerPrototype__publishCallback, 3 } },
{ "reload"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPServerPrototype__reloadCallback, 2 } },
+ { "requestIP"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPServerPrototype__requestIPCallback, 1 } },
{ "stop"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPServerPrototype__stopCallback, 1 } },
{ "upgrade"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPServerPrototype__upgradeCallback, 1 } }
};
@@ -4716,6 +4802,37 @@ JSC_DEFINE_CUSTOM_GETTER(jsDebugHTTPServerConstructor, (JSGlobalObject * lexical
return JSValue::encode(globalObject->JSDebugHTTPServerConstructor());
}
+JSC_DEFINE_CUSTOM_GETTER(DebugHTTPServerPrototype__addressGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ auto& vm = lexicalGlobalObject->vm();
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ JSDebugHTTPServer* thisObject = jsCast<JSDebugHTTPServer*>(JSValue::decode(thisValue));
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+ if (JSValue cachedValue = thisObject->m_address.get())
+ return JSValue::encode(cachedValue);
+
+ JSC::JSValue result = JSC::JSValue::decode(
+ DebugHTTPServerPrototype__getAddress(thisObject->wrapped(), globalObject));
+ RETURN_IF_EXCEPTION(throwScope, {});
+ thisObject->m_address.set(vm, thisObject, result);
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(result));
+}
+
+extern "C" void DebugHTTPServerPrototype__addressSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value)
+{
+ auto& vm = globalObject->vm();
+ auto* thisObject = jsCast<JSDebugHTTPServer*>(JSValue::decode(thisValue));
+ thisObject->m_address.set(vm, thisObject, JSValue::decode(value));
+}
+
+extern "C" EncodedJSValue DebugHTTPServerPrototype__addressGetCachedValue(JSC::EncodedJSValue thisValue)
+{
+ auto* thisObject = jsCast<JSDebugHTTPServer*>(JSValue::decode(thisValue));
+ return JSValue::encode(thisObject->m_address.get());
+}
+
JSC_DEFINE_CUSTOM_GETTER(DebugHTTPServerPrototype__developmentGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
auto& vm = lexicalGlobalObject->vm();
@@ -4922,6 +5039,34 @@ JSC_DEFINE_HOST_FUNCTION(DebugHTTPServerPrototype__reloadCallback, (JSGlobalObje
return DebugHTTPServerPrototype__doReload(thisObject->wrapped(), lexicalGlobalObject, callFrame);
}
+JSC_DEFINE_HOST_FUNCTION(DebugHTTPServerPrototype__requestIPCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSDebugHTTPServer* thisObject = jsDynamicCast<JSDebugHTTPServer*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ throwVMTypeError(lexicalGlobalObject, throwScope, "Expected 'this' to be instanceof DebugHTTPServer"_s);
+ return JSValue::encode({});
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+#ifdef BUN_DEBUG
+ /** View the file name of the JS file that called this function
+ * from a debugger */
+ SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm);
+ const char* fileName = sourceOrigin.string().utf8().data();
+ static const char* lastFileName = nullptr;
+ if (lastFileName != fileName) {
+ lastFileName = fileName;
+ }
+#endif
+
+ return DebugHTTPServerPrototype__doRequestIP(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
JSC_DEFINE_HOST_FUNCTION(DebugHTTPServerPrototype__stopCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
auto& vm = lexicalGlobalObject->vm();
@@ -5080,6 +5225,7 @@ void JSDebugHTTPServer::visitAdditionalChildren(Visitor& visitor)
JSDebugHTTPServer* thisObject = this;
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ visitor.append(thisObject->m_address);
visitor.append(thisObject->m_hostname);
visitor.append(thisObject->m_id);
}
@@ -5110,6 +5256,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDirentPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -5644,6 +5791,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDocEndPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -5814,6 +5962,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDocTypePrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -6092,6 +6241,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSElementPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -6808,6 +6958,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSEndTagPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -7072,6 +7223,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSExpectPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -7257,6 +7409,9 @@ JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toEndWithCallback);
extern "C" EncodedJSValue ExpectPrototype__toEqual(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toEqualCallback);
+extern "C" EncodedJSValue ExpectPrototype__toEqualIgnoringWhitespace(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toEqualIgnoringWhitespaceCallback);
+
extern "C" EncodedJSValue ExpectPrototype__toHaveBeenCalled(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toHaveBeenCalledCallback);
@@ -7371,6 +7526,7 @@ static const HashTableValue JSExpectPrototypeTableValues[] = {
{ "toContainEqual"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toContainEqualCallback, 1 } },
{ "toEndWith"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toEndWithCallback, 1 } },
{ "toEqual"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toEqualCallback, 1 } },
+ { "toEqualIgnoringWhitespace"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toEqualIgnoringWhitespaceCallback, 1 } },
{ "toHaveBeenCalled"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toHaveBeenCalledCallback, 0 } },
{ "toHaveBeenCalledTimes"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toHaveBeenCalledTimesCallback, 1 } },
{ "toHaveBeenCalledWith"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toHaveBeenCalledWithCallback, 1 } },
@@ -8538,6 +8694,34 @@ JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__toEqualCallback, (JSGlobalObject * lex
return ExpectPrototype__toEqual(thisObject->wrapped(), lexicalGlobalObject, callFrame);
}
+JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__toEqualIgnoringWhitespaceCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSExpect* thisObject = jsDynamicCast<JSExpect*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ throwVMTypeError(lexicalGlobalObject, throwScope, "Expected 'this' to be instanceof Expect"_s);
+ return JSValue::encode({});
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+#ifdef BUN_DEBUG
+ /** View the file name of the JS file that called this function
+ * from a debugger */
+ SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm);
+ const char* fileName = sourceOrigin.string().utf8().data();
+ static const char* lastFileName = nullptr;
+ if (lastFileName != fileName) {
+ lastFileName = fileName;
+ }
+#endif
+
+ return ExpectPrototype__toEqualIgnoringWhitespace(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__toHaveBeenCalledCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
auto& vm = lexicalGlobalObject->vm();
@@ -9436,6 +9620,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSExpectAnyPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -9604,6 +9789,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSExpectAnythingPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -9712,6 +9898,175 @@ extern "C" EncodedJSValue ExpectAnything__create(Zig::GlobalObject* globalObject
return JSValue::encode(instance);
}
+class JSExpectArrayContainingPrototype final : public JSC::JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+
+ static JSExpectArrayContainingPrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ JSExpectArrayContainingPrototype* ptr = new (NotNull, JSC::allocateCell<JSExpectArrayContainingPrototype>(vm)) JSExpectArrayContainingPrototype(vm, globalObject, structure);
+ ptr->finishCreation(vm, globalObject);
+ return ptr;
+ }
+
+ DECLARE_INFO;
+ template<typename CellType, JSC::SubspaceAccess>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSExpectArrayContainingPrototype, Base);
+ return &vm.plainObjectSpace();
+ }
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+private:
+ JSExpectArrayContainingPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
+ : Base(vm, structure)
+ {
+ }
+
+ void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
+};
+
+extern "C" void ExpectArrayContainingClass__finalize(void*);
+extern "C" JSC_DECLARE_HOST_FUNCTION(ExpectArrayContainingClass__call);
+
+STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSExpectArrayContainingPrototype, JSExpectArrayContainingPrototype::Base);
+
+static const HashTableValue JSExpectArrayContainingPrototypeTableValues[] = {};
+
+const ClassInfo JSExpectArrayContainingPrototype::s_info = { "ExpectArrayContaining"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSExpectArrayContainingPrototype) };
+
+extern "C" void ExpectArrayContainingPrototype__arrayValueSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value)
+{
+ auto& vm = globalObject->vm();
+ auto* thisObject = jsCast<JSExpectArrayContaining*>(JSValue::decode(thisValue));
+ thisObject->m_arrayValue.set(vm, thisObject, JSValue::decode(value));
+}
+
+extern "C" EncodedJSValue ExpectArrayContainingPrototype__arrayValueGetCachedValue(JSC::EncodedJSValue thisValue)
+{
+ auto* thisObject = jsCast<JSExpectArrayContaining*>(JSValue::decode(thisValue));
+ return JSValue::encode(thisObject->m_arrayValue.get());
+}
+
+void JSExpectArrayContainingPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
+{
+ Base::finishCreation(vm);
+
+ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+}
+
+JSExpectArrayContaining::~JSExpectArrayContaining()
+{
+ if (m_ctx) {
+ ExpectArrayContainingClass__finalize(m_ctx);
+ }
+}
+void JSExpectArrayContaining::destroy(JSCell* cell)
+{
+ static_cast<JSExpectArrayContaining*>(cell)->JSExpectArrayContaining::~JSExpectArrayContaining();
+}
+
+const ClassInfo JSExpectArrayContaining::s_info = { "ExpectArrayContaining"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSExpectArrayContaining) };
+
+void JSExpectArrayContaining::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+}
+
+JSExpectArrayContaining* JSExpectArrayContaining::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* ctx)
+{
+ JSExpectArrayContaining* ptr = new (NotNull, JSC::allocateCell<JSExpectArrayContaining>(vm)) JSExpectArrayContaining(vm, structure, ctx);
+ ptr->finishCreation(vm);
+ return ptr;
+}
+
+extern "C" void* ExpectArrayContaining__fromJS(JSC::EncodedJSValue value)
+{
+ JSC::JSValue decodedValue = JSC::JSValue::decode(value);
+ if (decodedValue.isEmpty() || !decodedValue.isCell())
+ return nullptr;
+
+ JSC::JSCell* cell = decodedValue.asCell();
+ JSExpectArrayContaining* object = JSC::jsDynamicCast<JSExpectArrayContaining*>(cell);
+
+ if (!object)
+ return nullptr;
+
+ return object->wrapped();
+}
+
+extern "C" bool ExpectArrayContaining__dangerouslySetPtr(JSC::EncodedJSValue value, void* ptr)
+{
+ JSExpectArrayContaining* object = JSC::jsDynamicCast<JSExpectArrayContaining*>(JSValue::decode(value));
+ if (!object)
+ return false;
+
+ object->m_ctx = ptr;
+ return true;
+}
+
+extern "C" const size_t ExpectArrayContaining__ptrOffset = JSExpectArrayContaining::offsetOfWrapped();
+
+void JSExpectArrayContaining::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
+{
+ auto* thisObject = jsCast<JSExpectArrayContaining*>(cell);
+ if (void* wrapped = thisObject->wrapped()) {
+ // if (thisObject->scriptExecutionContext())
+ // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
+ }
+ Base::analyzeHeap(cell, analyzer);
+}
+
+JSObject* JSExpectArrayContaining::createPrototype(VM& vm, JSDOMGlobalObject* globalObject)
+{
+ return JSExpectArrayContainingPrototype::create(vm, globalObject, JSExpectArrayContainingPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
+}
+
+extern "C" EncodedJSValue ExpectArrayContaining__create(Zig::GlobalObject* globalObject, void* ptr)
+{
+ auto& vm = globalObject->vm();
+ JSC::Structure* structure = globalObject->JSExpectArrayContainingStructure();
+ JSExpectArrayContaining* instance = JSExpectArrayContaining::create(vm, globalObject, structure, ptr);
+
+ return JSValue::encode(instance);
+}
+
+template<typename Visitor>
+void JSExpectArrayContaining::visitChildrenImpl(JSCell* cell, Visitor& visitor)
+{
+ JSExpectArrayContaining* thisObject = jsCast<JSExpectArrayContaining*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(thisObject, visitor);
+
+ thisObject->visitAdditionalChildren<Visitor>(visitor);
+}
+
+DEFINE_VISIT_CHILDREN(JSExpectArrayContaining);
+
+template<typename Visitor>
+void JSExpectArrayContaining::visitAdditionalChildren(Visitor& visitor)
+{
+ JSExpectArrayContaining* thisObject = this;
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ visitor.append(thisObject->m_arrayValue);
+}
+
+DEFINE_VISIT_ADDITIONAL_CHILDREN(JSExpectArrayContaining);
+
+template<typename Visitor>
+void JSExpectArrayContaining::visitOutputConstraintsImpl(JSCell* cell, Visitor& visitor)
+{
+ JSExpectArrayContaining* thisObject = jsCast<JSExpectArrayContaining*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ thisObject->visitAdditionalChildren<Visitor>(visitor);
+}
+
+DEFINE_VISIT_OUTPUT_CONSTRAINTS(JSExpectArrayContaining);
class JSExpectStringContainingPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
@@ -9727,6 +10082,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSExpectStringContainingPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -9895,6 +10251,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSExpectStringMatchingPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -10063,6 +10420,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSFFIPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -10313,6 +10671,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSFSWatcherPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -10617,6 +10976,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSFileSystemRouterPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -11063,6 +11423,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSHTMLRewriterPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -11401,6 +11762,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSHTTPSServerPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -11422,6 +11784,9 @@ JSC_DECLARE_CUSTOM_GETTER(jsHTTPSServerConstructor);
extern "C" void HTTPSServerClass__finalize(void*);
+extern "C" JSC::EncodedJSValue HTTPSServerPrototype__getAddress(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
+JSC_DECLARE_CUSTOM_GETTER(HTTPSServerPrototype__addressGetterWrap);
+
extern "C" JSC::EncodedJSValue HTTPSServerPrototype__getDevelopment(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
JSC_DECLARE_CUSTOM_GETTER(HTTPSServerPrototype__developmentGetterWrap);
@@ -11452,6 +11817,9 @@ JSC_DECLARE_HOST_FUNCTION(HTTPSServerPrototype__publishCallback);
extern "C" EncodedJSValue HTTPSServerPrototype__doReload(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
JSC_DECLARE_HOST_FUNCTION(HTTPSServerPrototype__reloadCallback);
+extern "C" EncodedJSValue HTTPSServerPrototype__doRequestIP(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(HTTPSServerPrototype__requestIPCallback);
+
extern "C" EncodedJSValue HTTPSServerPrototype__doStop(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
JSC_DECLARE_HOST_FUNCTION(HTTPSServerPrototype__stopCallback);
@@ -11461,6 +11829,7 @@ JSC_DECLARE_HOST_FUNCTION(HTTPSServerPrototype__upgradeCallback);
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSHTTPSServerPrototype, JSHTTPSServerPrototype::Base);
static const HashTableValue JSHTTPSServerPrototypeTableValues[] = {
+ { "address"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPSServerPrototype__addressGetterWrap, 0 } },
{ "development"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPSServerPrototype__developmentGetterWrap, 0 } },
{ "fetch"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPSServerPrototype__fetchCallback, 1 } },
{ "hostname"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPSServerPrototype__hostnameGetterWrap, 0 } },
@@ -11471,6 +11840,7 @@ static const HashTableValue JSHTTPSServerPrototypeTableValues[] = {
{ "protocol"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPSServerPrototype__protocolGetterWrap, 0 } },
{ "publish"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPSServerPrototype__publishCallback, 3 } },
{ "reload"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPSServerPrototype__reloadCallback, 2 } },
+ { "requestIP"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPSServerPrototype__requestIPCallback, 1 } },
{ "stop"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPSServerPrototype__stopCallback, 1 } },
{ "upgrade"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPSServerPrototype__upgradeCallback, 1 } }
};
@@ -11489,6 +11859,37 @@ JSC_DEFINE_CUSTOM_GETTER(jsHTTPSServerConstructor, (JSGlobalObject * lexicalGlob
return JSValue::encode(globalObject->JSHTTPSServerConstructor());
}
+JSC_DEFINE_CUSTOM_GETTER(HTTPSServerPrototype__addressGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ auto& vm = lexicalGlobalObject->vm();
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ JSHTTPSServer* thisObject = jsCast<JSHTTPSServer*>(JSValue::decode(thisValue));
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+ if (JSValue cachedValue = thisObject->m_address.get())
+ return JSValue::encode(cachedValue);
+
+ JSC::JSValue result = JSC::JSValue::decode(
+ HTTPSServerPrototype__getAddress(thisObject->wrapped(), globalObject));
+ RETURN_IF_EXCEPTION(throwScope, {});
+ thisObject->m_address.set(vm, thisObject, result);
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(result));
+}
+
+extern "C" void HTTPSServerPrototype__addressSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value)
+{
+ auto& vm = globalObject->vm();
+ auto* thisObject = jsCast<JSHTTPSServer*>(JSValue::decode(thisValue));
+ thisObject->m_address.set(vm, thisObject, JSValue::decode(value));
+}
+
+extern "C" EncodedJSValue HTTPSServerPrototype__addressGetCachedValue(JSC::EncodedJSValue thisValue)
+{
+ auto* thisObject = jsCast<JSHTTPSServer*>(JSValue::decode(thisValue));
+ return JSValue::encode(thisObject->m_address.get());
+}
+
JSC_DEFINE_CUSTOM_GETTER(HTTPSServerPrototype__developmentGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
auto& vm = lexicalGlobalObject->vm();
@@ -11695,6 +12096,34 @@ JSC_DEFINE_HOST_FUNCTION(HTTPSServerPrototype__reloadCallback, (JSGlobalObject *
return HTTPSServerPrototype__doReload(thisObject->wrapped(), lexicalGlobalObject, callFrame);
}
+JSC_DEFINE_HOST_FUNCTION(HTTPSServerPrototype__requestIPCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSHTTPSServer* thisObject = jsDynamicCast<JSHTTPSServer*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ throwVMTypeError(lexicalGlobalObject, throwScope, "Expected 'this' to be instanceof HTTPSServer"_s);
+ return JSValue::encode({});
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+#ifdef BUN_DEBUG
+ /** View the file name of the JS file that called this function
+ * from a debugger */
+ SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm);
+ const char* fileName = sourceOrigin.string().utf8().data();
+ static const char* lastFileName = nullptr;
+ if (lastFileName != fileName) {
+ lastFileName = fileName;
+ }
+#endif
+
+ return HTTPSServerPrototype__doRequestIP(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
JSC_DEFINE_HOST_FUNCTION(HTTPSServerPrototype__stopCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
auto& vm = lexicalGlobalObject->vm();
@@ -11853,6 +12282,7 @@ void JSHTTPSServer::visitAdditionalChildren(Visitor& visitor)
JSHTTPSServer* thisObject = this;
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ visitor.append(thisObject->m_address);
visitor.append(thisObject->m_hostname);
visitor.append(thisObject->m_id);
}
@@ -11883,6 +12313,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSHTTPServerPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -11904,6 +12335,9 @@ JSC_DECLARE_CUSTOM_GETTER(jsHTTPServerConstructor);
extern "C" void HTTPServerClass__finalize(void*);
+extern "C" JSC::EncodedJSValue HTTPServerPrototype__getAddress(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
+JSC_DECLARE_CUSTOM_GETTER(HTTPServerPrototype__addressGetterWrap);
+
extern "C" JSC::EncodedJSValue HTTPServerPrototype__getDevelopment(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
JSC_DECLARE_CUSTOM_GETTER(HTTPServerPrototype__developmentGetterWrap);
@@ -11934,6 +12368,9 @@ JSC_DECLARE_HOST_FUNCTION(HTTPServerPrototype__publishCallback);
extern "C" EncodedJSValue HTTPServerPrototype__doReload(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
JSC_DECLARE_HOST_FUNCTION(HTTPServerPrototype__reloadCallback);
+extern "C" EncodedJSValue HTTPServerPrototype__doRequestIP(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(HTTPServerPrototype__requestIPCallback);
+
extern "C" EncodedJSValue HTTPServerPrototype__doStop(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
JSC_DECLARE_HOST_FUNCTION(HTTPServerPrototype__stopCallback);
@@ -11943,6 +12380,7 @@ JSC_DECLARE_HOST_FUNCTION(HTTPServerPrototype__upgradeCallback);
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSHTTPServerPrototype, JSHTTPServerPrototype::Base);
static const HashTableValue JSHTTPServerPrototypeTableValues[] = {
+ { "address"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPServerPrototype__addressGetterWrap, 0 } },
{ "development"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPServerPrototype__developmentGetterWrap, 0 } },
{ "fetch"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPServerPrototype__fetchCallback, 1 } },
{ "hostname"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPServerPrototype__hostnameGetterWrap, 0 } },
@@ -11953,6 +12391,7 @@ static const HashTableValue JSHTTPServerPrototypeTableValues[] = {
{ "protocol"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPServerPrototype__protocolGetterWrap, 0 } },
{ "publish"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPServerPrototype__publishCallback, 3 } },
{ "reload"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPServerPrototype__reloadCallback, 2 } },
+ { "requestIP"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPServerPrototype__requestIPCallback, 1 } },
{ "stop"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPServerPrototype__stopCallback, 1 } },
{ "upgrade"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPServerPrototype__upgradeCallback, 1 } }
};
@@ -11971,6 +12410,37 @@ JSC_DEFINE_CUSTOM_GETTER(jsHTTPServerConstructor, (JSGlobalObject * lexicalGloba
return JSValue::encode(globalObject->JSHTTPServerConstructor());
}
+JSC_DEFINE_CUSTOM_GETTER(HTTPServerPrototype__addressGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ auto& vm = lexicalGlobalObject->vm();
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ JSHTTPServer* thisObject = jsCast<JSHTTPServer*>(JSValue::decode(thisValue));
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+ if (JSValue cachedValue = thisObject->m_address.get())
+ return JSValue::encode(cachedValue);
+
+ JSC::JSValue result = JSC::JSValue::decode(
+ HTTPServerPrototype__getAddress(thisObject->wrapped(), globalObject));
+ RETURN_IF_EXCEPTION(throwScope, {});
+ thisObject->m_address.set(vm, thisObject, result);
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(result));
+}
+
+extern "C" void HTTPServerPrototype__addressSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value)
+{
+ auto& vm = globalObject->vm();
+ auto* thisObject = jsCast<JSHTTPServer*>(JSValue::decode(thisValue));
+ thisObject->m_address.set(vm, thisObject, JSValue::decode(value));
+}
+
+extern "C" EncodedJSValue HTTPServerPrototype__addressGetCachedValue(JSC::EncodedJSValue thisValue)
+{
+ auto* thisObject = jsCast<JSHTTPServer*>(JSValue::decode(thisValue));
+ return JSValue::encode(thisObject->m_address.get());
+}
+
JSC_DEFINE_CUSTOM_GETTER(HTTPServerPrototype__developmentGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
auto& vm = lexicalGlobalObject->vm();
@@ -12177,6 +12647,34 @@ JSC_DEFINE_HOST_FUNCTION(HTTPServerPrototype__reloadCallback, (JSGlobalObject *
return HTTPServerPrototype__doReload(thisObject->wrapped(), lexicalGlobalObject, callFrame);
}
+JSC_DEFINE_HOST_FUNCTION(HTTPServerPrototype__requestIPCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = lexicalGlobalObject->vm();
+
+ JSHTTPServer* thisObject = jsDynamicCast<JSHTTPServer*>(callFrame->thisValue());
+
+ if (UNLIKELY(!thisObject)) {
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ throwVMTypeError(lexicalGlobalObject, throwScope, "Expected 'this' to be instanceof HTTPServer"_s);
+ return JSValue::encode({});
+ }
+
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+
+#ifdef BUN_DEBUG
+ /** View the file name of the JS file that called this function
+ * from a debugger */
+ SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm);
+ const char* fileName = sourceOrigin.string().utf8().data();
+ static const char* lastFileName = nullptr;
+ if (lastFileName != fileName) {
+ lastFileName = fileName;
+ }
+#endif
+
+ return HTTPServerPrototype__doRequestIP(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
JSC_DEFINE_HOST_FUNCTION(HTTPServerPrototype__stopCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
auto& vm = lexicalGlobalObject->vm();
@@ -12335,6 +12833,7 @@ void JSHTTPServer::visitAdditionalChildren(Visitor& visitor)
JSHTTPServer* thisObject = this;
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ visitor.append(thisObject->m_address);
visitor.append(thisObject->m_hostname);
visitor.append(thisObject->m_id);
}
@@ -12365,6 +12864,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSListenerPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -12781,6 +13281,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMD4Prototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -13111,6 +13612,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMD5Prototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -13441,6 +13943,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMatchedRoutePrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -13898,6 +14401,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSNodeJSFSPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -16889,6 +17393,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSRequestPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -17514,7 +18019,7 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSRequestConstructor::construct(JSC
}
JSRequest* instance = JSRequest::create(vm, globalObject, structure, ptr);
- vm.heap.reportExtraMemoryAllocated(Request__estimatedSize(instance->wrapped()));
+ vm.heap.reportExtraMemoryAllocated(instance, Request__estimatedSize(instance->wrapped()));
return JSValue::encode(instance);
}
@@ -17608,7 +18113,7 @@ extern "C" EncodedJSValue Request__create(Zig::GlobalObject* globalObject, void*
auto& vm = globalObject->vm();
JSC::Structure* structure = globalObject->JSRequestStructure();
JSRequest* instance = JSRequest::create(vm, globalObject, structure, ptr);
- vm.heap.reportExtraMemoryAllocated(Request__estimatedSize(ptr));
+ vm.heap.reportExtraMemoryAllocated(instance, Request__estimatedSize(ptr));
return JSValue::encode(instance);
}
@@ -17664,6 +18169,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSResolveMessagePrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -18085,7 +18591,7 @@ void JSResolveMessagePrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject*
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSResolveMessage::info(), JSResolveMessagePrototypeTableValues, *this);
- this->putDirect(vm, vm.propertyNames->toPrimitiveSymbol, JSFunction::create(vm, globalObject, 1, String("toPrimitive"_s), ResolveMessagePrototype__toPrimitiveCallback, ImplementationVisibility::Public), PropertyAttribute::Function | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | 0);
+ this->putDirect(vm, vm.propertyNames->toPrimitiveSymbol, JSFunction::create(vm, globalObject, 1, String("toPrimitive"_s), ResolveMessagePrototype__toPrimitiveCallback, ImplementationVisibility::Public), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | 0);
this->putDirect(vm, vm.propertyNames->name, jsString(vm, String("ResolveMessage"_s)), PropertyAttribute::ReadOnly | 0);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
@@ -18287,6 +18793,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSResponsePrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -18841,7 +19348,7 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSResponseConstructor::construct(JS
}
JSResponse* instance = JSResponse::create(vm, globalObject, structure, ptr);
- vm.heap.reportExtraMemoryAllocated(Response__estimatedSize(instance->wrapped()));
+ vm.heap.reportExtraMemoryAllocated(instance, Response__estimatedSize(instance->wrapped()));
return JSValue::encode(instance);
}
@@ -18935,7 +19442,7 @@ extern "C" EncodedJSValue Response__create(Zig::GlobalObject* globalObject, void
auto& vm = globalObject->vm();
JSC::Structure* structure = globalObject->JSResponseStructure();
JSResponse* instance = JSResponse::create(vm, globalObject, structure, ptr);
- vm.heap.reportExtraMemoryAllocated(Response__estimatedSize(ptr));
+ vm.heap.reportExtraMemoryAllocated(instance, Response__estimatedSize(ptr));
return JSValue::encode(instance);
}
@@ -18991,6 +19498,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSSHA1Prototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -19321,6 +19829,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSSHA224Prototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -19651,6 +20160,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSSHA256Prototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -19981,6 +20491,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSSHA384Prototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -20311,6 +20822,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSSHA512Prototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -20641,6 +21153,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSSHA512_256Prototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -20971,6 +21484,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSServerWebSocketPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -21929,6 +22443,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSStatWatcherPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -22201,6 +22716,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSStatsPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -23173,6 +23689,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSSubprocessPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -23736,6 +24253,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTCPSocketPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -24723,8 +25241,10 @@ bool JSTCPSocket::hasPendingActivity(void* ctx)
JSTCPSocket::~JSTCPSocket()
{
+ printf("~JSTCPSocket\n");
if (m_ctx) {
TCPSocketClass__finalize(m_ctx);
+ m_ctx = nullptr;
}
}
void JSTCPSocket::destroy(JSCell* cell)
@@ -24847,6 +25367,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTLSSocketPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -25958,6 +26479,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTextChunkPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -26324,6 +26846,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTextDecoderPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -26409,12 +26932,16 @@ JSC_DECLARE_CUSTOM_GETTER(TextDecoderPrototype__encodingGetterWrap);
extern "C" JSC::EncodedJSValue TextDecoderPrototype__getFatal(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
JSC_DECLARE_CUSTOM_GETTER(TextDecoderPrototype__fatalGetterWrap);
+extern "C" JSC::EncodedJSValue TextDecoderPrototype__getIgnoreBOM(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);
+JSC_DECLARE_CUSTOM_GETTER(TextDecoderPrototype__ignoreBOMGetterWrap);
+
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTextDecoderPrototype, JSTextDecoderPrototype::Base);
static const HashTableValue JSTextDecoderPrototypeTableValues[] = {
{ "decode"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::DOMJITFunctionType, TextDecoderPrototype__decodeCallback, &DOMJITSignatureForTextDecoderPrototype__decode } },
{ "encoding"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TextDecoderPrototype__encodingGetterWrap, 0 } },
- { "fatal"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TextDecoderPrototype__fatalGetterWrap, 0 } }
+ { "fatal"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TextDecoderPrototype__fatalGetterWrap, 0 } },
+ { "ignoreBOM"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, TextDecoderPrototype__ignoreBOMGetterWrap, 0 } }
};
const ClassInfo JSTextDecoderPrototype::s_info = { "TextDecoder"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTextDecoderPrototype) };
@@ -26502,6 +27029,18 @@ JSC_DEFINE_CUSTOM_GETTER(TextDecoderPrototype__fatalGetterWrap, (JSGlobalObject
RELEASE_AND_RETURN(throwScope, result);
}
+JSC_DEFINE_CUSTOM_GETTER(TextDecoderPrototype__ignoreBOMGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ auto& vm = lexicalGlobalObject->vm();
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ JSTextDecoder* thisObject = jsCast<JSTextDecoder*>(JSValue::decode(thisValue));
+ JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
+ JSC::EncodedJSValue result = TextDecoderPrototype__getIgnoreBOM(thisObject->wrapped(), globalObject);
+ RETURN_IF_EXCEPTION(throwScope, {});
+ RELEASE_AND_RETURN(throwScope, result);
+}
+
void JSTextDecoderPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
Base::finishCreation(vm);
@@ -26700,6 +27239,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTimeoutPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -26914,7 +27454,7 @@ void JSTimeoutPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* global
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSTimeout::info(), JSTimeoutPrototypeTableValues, *this);
- this->putDirect(vm, vm.propertyNames->toPrimitiveSymbol, JSFunction::create(vm, globalObject, 1, String("toPrimitive"_s), TimeoutPrototype__toPrimitiveCallback, ImplementationVisibility::Public), PropertyAttribute::Function | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | 0);
+ this->putDirect(vm, vm.propertyNames->toPrimitiveSymbol, JSFunction::create(vm, globalObject, 1, String("toPrimitive"_s), TimeoutPrototype__toPrimitiveCallback, ImplementationVisibility::Public), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | 0);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
@@ -27042,6 +27582,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTranspilerPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
diff --git a/src/bun.js/bindings/ZigGeneratedClasses.h b/src/bun.js/bindings/ZigGeneratedClasses.h
index 142a96746..c1d7ca99e 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses.h
+++ b/src/bun.js/bindings/ZigGeneratedClasses.h
@@ -510,6 +510,7 @@ public:
template<typename Visitor> void visitAdditionalChildren(Visitor&);
DECLARE_VISIT_OUTPUT_CONSTRAINTS;
+ mutable JSC::WriteBarrier<JSC::Unknown> m_address;
mutable JSC::WriteBarrier<JSC::Unknown> m_hostname;
mutable JSC::WriteBarrier<JSC::Unknown> m_id;
};
@@ -567,6 +568,7 @@ public:
template<typename Visitor> void visitAdditionalChildren(Visitor&);
DECLARE_VISIT_OUTPUT_CONSTRAINTS;
+ mutable JSC::WriteBarrier<JSC::Unknown> m_address;
mutable JSC::WriteBarrier<JSC::Unknown> m_hostname;
mutable JSC::WriteBarrier<JSC::Unknown> m_id;
};
@@ -1004,6 +1006,62 @@ public:
void finishCreation(JSC::VM&);
};
+class JSExpectArrayContaining final : public JSC::JSDestructibleObject {
+public:
+ using Base = JSC::JSDestructibleObject;
+ static JSExpectArrayContaining* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* ctx);
+
+ DECLARE_EXPORT_INFO;
+ template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return WebCore::subspaceForImpl<JSExpectArrayContaining, WebCore::UseCustomHeapCellType::No>(
+ vm,
+ [](auto& spaces) { return spaces.m_clientSubspaceForExpectArrayContaining.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForExpectArrayContaining = std::forward<decltype(space)>(space); },
+ [](auto& spaces) { return spaces.m_subspaceForExpectArrayContaining.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_subspaceForExpectArrayContaining = std::forward<decltype(space)>(space); });
+ }
+
+ static void destroy(JSC::JSCell*);
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(static_cast<JSC::JSType>(0b11101110), StructureFlags), info());
+ }
+
+ static JSObject* createPrototype(VM& vm, JSDOMGlobalObject* globalObject);
+ ;
+
+ ~JSExpectArrayContaining();
+
+ void* wrapped() const { return m_ctx; }
+
+ void detach()
+ {
+ m_ctx = nullptr;
+ }
+
+ static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
+ static ptrdiff_t offsetOfWrapped() { return OBJECT_OFFSETOF(JSExpectArrayContaining, m_ctx); }
+
+ void* m_ctx { nullptr };
+
+ JSExpectArrayContaining(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr)
+ : Base(vm, structure)
+ {
+ m_ctx = sinkPtr;
+ }
+
+ void finishCreation(JSC::VM&);
+
+ DECLARE_VISIT_CHILDREN;
+ template<typename Visitor> void visitAdditionalChildren(Visitor&);
+ DECLARE_VISIT_OUTPUT_CONSTRAINTS;
+
+ mutable JSC::WriteBarrier<JSC::Unknown> m_arrayValue;
+};
+
class JSExpectStringContaining final : public JSC::JSDestructibleObject {
public:
using Base = JSC::JSDestructibleObject;
@@ -1416,6 +1474,7 @@ public:
template<typename Visitor> void visitAdditionalChildren(Visitor&);
DECLARE_VISIT_OUTPUT_CONSTRAINTS;
+ mutable JSC::WriteBarrier<JSC::Unknown> m_address;
mutable JSC::WriteBarrier<JSC::Unknown> m_hostname;
mutable JSC::WriteBarrier<JSC::Unknown> m_id;
};
@@ -1473,6 +1532,7 @@ public:
template<typename Visitor> void visitAdditionalChildren(Visitor&);
DECLARE_VISIT_OUTPUT_CONSTRAINTS;
+ mutable JSC::WriteBarrier<JSC::Unknown> m_address;
mutable JSC::WriteBarrier<JSC::Unknown> m_hostname;
mutable JSC::WriteBarrier<JSC::Unknown> m_id;
};
diff --git a/src/bun.js/bindings/ZigGeneratedCode.cpp b/src/bun.js/bindings/ZigGeneratedCode.cpp
index 057eaf28e..777c6455e 100644
--- a/src/bun.js/bindings/ZigGeneratedCode.cpp
+++ b/src/bun.js/bindings/ZigGeneratedCode.cpp
@@ -51,8 +51,7 @@ extern "C" void FFI__ptr__put(JSC::JSGlobalObject* globalObject, JSC::EncodedJSV
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "ptr"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__u8__slowpathWrapper);
@@ -92,8 +91,7 @@ extern "C" void Reader__u8__put(JSC::JSGlobalObject* globalObject, JSC::EncodedJ
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "u8"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__u16__slowpathWrapper);
@@ -133,8 +131,7 @@ extern "C" void Reader__u16__put(JSC::JSGlobalObject* globalObject, JSC::Encoded
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "u16"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__u32__slowpathWrapper);
@@ -174,8 +171,7 @@ extern "C" void Reader__u32__put(JSC::JSGlobalObject* globalObject, JSC::Encoded
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "u32"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__ptr__slowpathWrapper);
@@ -215,8 +211,7 @@ extern "C" void Reader__ptr__put(JSC::JSGlobalObject* globalObject, JSC::Encoded
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "ptr"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__i8__slowpathWrapper);
@@ -256,8 +251,7 @@ extern "C" void Reader__i8__put(JSC::JSGlobalObject* globalObject, JSC::EncodedJ
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "i8"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__i16__slowpathWrapper);
@@ -297,8 +291,7 @@ extern "C" void Reader__i16__put(JSC::JSGlobalObject* globalObject, JSC::Encoded
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "i16"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__i32__slowpathWrapper);
@@ -338,8 +331,7 @@ extern "C" void Reader__i32__put(JSC::JSGlobalObject* globalObject, JSC::Encoded
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "i32"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__i64__slowpathWrapper);
@@ -379,8 +371,7 @@ extern "C" void Reader__i64__put(JSC::JSGlobalObject* globalObject, JSC::Encoded
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "i64"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__u64__slowpathWrapper);
@@ -420,8 +411,7 @@ extern "C" void Reader__u64__put(JSC::JSGlobalObject* globalObject, JSC::Encoded
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "u64"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__intptr__slowpathWrapper);
@@ -461,8 +451,7 @@ extern "C" void Reader__intptr__put(JSC::JSGlobalObject* globalObject, JSC::Enco
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "intptr"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__f32__slowpathWrapper);
@@ -502,8 +491,7 @@ extern "C" void Reader__f32__put(JSC::JSGlobalObject* globalObject, JSC::Encoded
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "f32"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
extern "C" JSC_DECLARE_HOST_FUNCTION(Reader__f64__slowpathWrapper);
@@ -543,8 +531,7 @@ extern "C" void Reader__f64__put(JSC::JSGlobalObject* globalObject, JSC::Encoded
thisObject->putDirect(
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "f64"_s),
- function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ function);
}
/* -- END DOMCall DEFINITIONS-- */
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index cdc4adb1b..93f9a0fa2 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -23,6 +23,7 @@
#include "JavaScriptCore/InitializeThreading.h"
#include "JavaScriptCore/IteratorOperations.h"
#include "JavaScriptCore/JSArray.h"
+#include "JavaScriptCore/JSGlobalProxyInlines.h"
#include "JavaScriptCore/JSCallbackConstructor.h"
#include "JavaScriptCore/JSCallbackObject.h"
@@ -38,6 +39,7 @@
#include "JavaScriptCore/JSMap.h"
#include "JavaScriptCore/JSModuleLoader.h"
#include "JavaScriptCore/JSModuleNamespaceObject.h"
+#include "JavaScriptCore/JSModuleNamespaceObjectInlines.h"
#include "JavaScriptCore/JSModuleRecord.h"
#include "JavaScriptCore/JSNativeStdFunction.h"
#include "JavaScriptCore/JSObject.h"
@@ -103,6 +105,7 @@
#include "JavaScriptCore/LazyClassStructure.h"
#include "JavaScriptCore/LazyClassStructureInlines.h"
#include "JavaScriptCore/FunctionPrototype.h"
+#include "JavaScriptCore/GetterSetter.h"
#include "napi.h"
#include "JSSQLStatement.h"
#include "ModuleLoader.h"
@@ -125,6 +128,8 @@
#include "JSDOMFile.h"
+#include "ProcessBindingConstants.h"
+
#if ENABLE(REMOTE_INSPECTOR)
#include "JavaScriptCore/RemoteInspectorServer.h"
#endif
@@ -186,9 +191,6 @@ namespace JSCastingHelpers = JSC::JSCastingHelpers;
#include "DOMJITHelpers.h"
#include <JavaScriptCore/DFGAbstractHeap.h>
-#include "webcrypto/JSCryptoKey.h"
-#include "webcrypto/JSSubtleCrypto.h"
-
#include "JSDOMFormData.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
@@ -201,6 +203,7 @@ namespace JSCastingHelpers = JSC::JSCastingHelpers;
#include "JSDOMConvertStrings.h"
#include "JSDOMConvertUnion.h"
#include "AddEventListenerOptions.h"
+#include "JSSocketAddress.h"
#include "ErrorStackTrace.h"
#include "CallSite.h"
@@ -211,6 +214,9 @@ namespace JSCastingHelpers = JSC::JSCastingHelpers;
#include <wtf/text/Base64.h>
#include "simdutf.h"
#include "libusockets.h"
+#include "KeyObject.h"
+#include "webcrypto/JSCryptoKey.h"
+#include "webcrypto/JSSubtleCrypto.h"
constexpr size_t DEFAULT_ERROR_STACK_TRACE_LIMIT = 10;
@@ -226,6 +232,10 @@ static bool has_loaded_jsc = false;
Structure* createMemoryFootprintStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject);
+namespace Bun {
+extern JSC::EncodedJSValue Process_functionInternalGetWindowSize(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame);
+}
+
namespace WebCore {
class Base64Utilities {
public:
@@ -270,6 +280,7 @@ extern "C" void JSCInitialize(const char* envp[], size_t envc, void (*onCrash)(c
JSC::Options::useShadowRealm() = true;
JSC::Options::useResizableArrayBuffer() = true;
JSC::Options::usePromiseWithResolversMethod() = true;
+ JSC::Options::useV8DateParser() = true;
#ifdef BUN_DEBUG
JSC::Options::showPrivateScriptsInStackTraces() = true;
@@ -305,29 +316,16 @@ static bool skipNextComputeErrorInfo = false;
// error.stack calls this function
static String computeErrorInfoWithoutPrepareStackTrace(JSC::VM& vm, Vector<StackFrame>& stackTrace, unsigned& line, unsigned& column, String& sourceURL, JSObject* errorInstance)
{
- if (!errorInstance) {
- return String();
- }
-
- if (skipNextComputeErrorInfo) {
- return String();
- }
-
- Zig::GlobalObject* globalObject = jsDynamicCast<Zig::GlobalObject*>(errorInstance->globalObject());
- if (!globalObject) {
- // Happens in node:vm
- globalObject = jsDynamicCast<Zig::GlobalObject*>(Bun__getDefaultGlobal());
- }
+ auto* lexicalGlobalObject = errorInstance->globalObject();
+ Zig::GlobalObject* globalObject = jsDynamicCast<Zig::GlobalObject*>(lexicalGlobalObject);
WTF::String name = "Error"_s;
WTF::String message;
- if (errorInstance) {
- // Note that we are not allowed to allocate memory in here. It's called inside a finalizer.
- if (auto* instance = jsDynamicCast<ErrorInstance*>(errorInstance)) {
- name = instance->sanitizedNameString(globalObject);
- message = instance->sanitizedMessageString(globalObject);
- }
+ // Note that we are not allowed to allocate memory in here. It's called inside a finalizer.
+ if (auto* instance = jsDynamicCast<ErrorInstance*>(errorInstance)) {
+ name = instance->sanitizedNameString(lexicalGlobalObject);
+ message = instance->sanitizedMessageString(lexicalGlobalObject);
}
WTF::StringBuilder sb;
@@ -381,20 +379,23 @@ static String computeErrorInfoWithoutPrepareStackTrace(JSC::VM& vm, Vector<Stack
unsigned int thisColumn = 0;
frame.computeLineAndColumn(thisLine, thisColumn);
memset(remappedFrames + i, 0, sizeof(ZigStackFrame));
-
remappedFrames[i].position.line = thisLine;
remappedFrames[i].position.column_start = thisColumn;
+
String sourceURLForFrame = frame.sourceURL(vm);
- if (!sourceURLForFrame.isEmpty()) {
- remappedFrames[i].source_url = Bun::toString(sourceURLForFrame);
- } else {
- // https://github.com/oven-sh/bun/issues/3595
- remappedFrames[i].source_url = BunStringEmpty;
- }
+ // If it's not a Zig::GlobalObject, don't bother source-mapping it.
+ if (globalObject) {
+ if (!sourceURLForFrame.isEmpty()) {
+ remappedFrames[i].source_url = Bun::toString(sourceURLForFrame);
+ } else {
+ // https://github.com/oven-sh/bun/issues/3595
+ remappedFrames[i].source_url = BunStringEmpty;
+ }
- // This ensures the lifetime of the sourceURL is accounted for correctly
- Bun__remapStackFramePositions(globalObject, remappedFrames + i, 1);
+ // This ensures the lifetime of the sourceURL is accounted for correctly
+ Bun__remapStackFramePositions(globalObject, remappedFrames + i, 1);
+ }
if (!hasSet) {
hasSet = true;
@@ -402,11 +403,9 @@ static String computeErrorInfoWithoutPrepareStackTrace(JSC::VM& vm, Vector<Stack
column = thisColumn;
sourceURL = frame.sourceURL(vm);
- if (errorInstance) {
- if (remappedFrames[i].remapped) {
- errorInstance->putDirect(vm, Identifier::fromString(vm, "originalLine"_s), jsNumber(thisLine), 0);
- errorInstance->putDirect(vm, Identifier::fromString(vm, "originalColumn"_s), jsNumber(thisColumn), 0);
- }
+ if (remappedFrames[i].remapped) {
+ errorInstance->putDirect(vm, Identifier::fromString(vm, "originalLine"_s), jsNumber(thisLine), 0);
+ errorInstance->putDirect(vm, Identifier::fromString(vm, "originalColumn"_s), jsNumber(thisColumn), 0);
}
}
@@ -428,8 +427,95 @@ static String computeErrorInfoWithoutPrepareStackTrace(JSC::VM& vm, Vector<Stack
return sb.toString();
}
+static String computeErrorInfoWithPrepareStackTrace(JSC::VM& vm, Zig::GlobalObject* globalObject, JSC::JSGlobalObject* lexicalGlobalObject, Vector<StackFrame>& stackFrames, unsigned& line, unsigned& column, String& sourceURL, JSObject* errorObject, JSObject* prepareStackTrace)
+{
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ size_t stackTraceLimit = globalObject->stackTraceLimit().value();
+ if (stackTraceLimit == 0) {
+ stackTraceLimit = DEFAULT_ERROR_STACK_TRACE_LIMIT;
+ }
+
+ JSCStackTrace stackTrace = JSCStackTrace::fromExisting(vm, stackFrames);
+
+ // Note: we cannot use tryCreateUninitializedRestricted here because we cannot allocate memory inside initializeIndex()
+ JSC::JSArray* callSites = JSC::JSArray::create(vm,
+ globalObject->arrayStructureForIndexingTypeDuringAllocation(JSC::ArrayWithContiguous),
+ stackTrace.size());
+
+ // Create the call sites (one per frame)
+ GlobalObject::createCallSitesFromFrames(globalObject, lexicalGlobalObject, stackTrace, callSites);
+
+ // We need to sourcemap it if it's a GlobalObject.
+ if (globalObject == lexicalGlobalObject) {
+ size_t framesCount = stackTrace.size();
+ ZigStackFrame remappedFrames[framesCount];
+ for (int i = 0; i < framesCount; i++) {
+ memset(remappedFrames + i, 0, sizeof(ZigStackFrame));
+ remappedFrames[i].source_url = Bun::toString(lexicalGlobalObject, stackTrace.at(i).sourceURL());
+ if (JSCStackFrame::SourcePositions* sourcePositions = stackTrace.at(i).getSourcePositions()) {
+ remappedFrames[i].position.line = sourcePositions->line.zeroBasedInt();
+ remappedFrames[i].position.column_start = sourcePositions->startColumn.zeroBasedInt() + 1;
+ } else {
+ remappedFrames[i].position.line = -1;
+ remappedFrames[i].position.column_start = -1;
+ }
+ }
+
+ Bun__remapStackFramePositions(globalObject, remappedFrames, framesCount);
+
+ for (size_t i = 0; i < framesCount; i++) {
+ JSC::JSValue callSiteValue = callSites->getIndex(lexicalGlobalObject, i);
+ CallSite* callSite = JSC::jsDynamicCast<CallSite*>(callSiteValue);
+ if (remappedFrames[i].remapped) {
+ int32_t remappedColumnStart = remappedFrames[i].position.column_start;
+ JSC::JSValue columnNumber = JSC::jsNumber(remappedColumnStart);
+ callSite->setColumnNumber(columnNumber);
+
+ int32_t remappedLine = remappedFrames[i].position.line;
+ JSC::JSValue lineNumber = JSC::jsNumber(remappedLine);
+ callSite->setLineNumber(lineNumber);
+ }
+ }
+ }
+
+ globalObject->formatStackTrace(vm, lexicalGlobalObject, errorObject, callSites, prepareStackTrace);
+
+ RETURN_IF_EXCEPTION(scope, String());
+ return String();
+}
+
static String computeErrorInfo(JSC::VM& vm, Vector<StackFrame>& stackTrace, unsigned& line, unsigned& column, String& sourceURL, JSObject* errorInstance)
{
+ if (skipNextComputeErrorInfo) {
+ return String();
+ }
+
+ if (!errorInstance) {
+ return String();
+ }
+
+ auto* lexicalGlobalObject = errorInstance->globalObject();
+ Zig::GlobalObject* globalObject = jsDynamicCast<Zig::GlobalObject*>(lexicalGlobalObject);
+
+ // Error.prepareStackTrace - https://v8.dev/docs/stack-trace-api#customizing-stack-traces
+ if (!globalObject) {
+ // node:vm will use a different JSGlobalObject
+ globalObject = Bun__getDefaultGlobal();
+
+ auto* errorConstructor = lexicalGlobalObject->m_errorStructure.constructor(lexicalGlobalObject);
+ if (JSValue prepareStackTrace = errorConstructor->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "prepareStackTrace"_s))) {
+ if (prepareStackTrace.isCell() && prepareStackTrace.isObject() && prepareStackTrace.isCallable()) {
+ return computeErrorInfoWithPrepareStackTrace(vm, globalObject, lexicalGlobalObject, stackTrace, line, column, sourceURL, errorInstance, prepareStackTrace.getObject());
+ }
+ }
+ } else {
+ if (JSValue prepareStackTrace = globalObject->m_errorConstructorPrepareStackTraceValue.get()) {
+ if (prepareStackTrace.isCell() && prepareStackTrace.isObject() && prepareStackTrace.isCallable()) {
+ return computeErrorInfoWithPrepareStackTrace(vm, globalObject, lexicalGlobalObject, stackTrace, line, column, sourceURL, errorInstance, prepareStackTrace.getObject());
+ }
+ }
+ }
+
return computeErrorInfoWithoutPrepareStackTrace(vm, stackTrace, line, column, sourceURL, errorInstance);
}
@@ -627,69 +713,17 @@ extern "C" bool Zig__GlobalObject__resetModuleRegistryMap(JSC__JSGlobalObject* g
return true;
}
-#define BUN_LAZY_GETTER_FN_NAME(GetterName) BunLazyGetter##GetterName##_getter
-
-#define DEFINE_BUN_LAZY_GETTER(GetterName, __propertyName) \
- JSC_DEFINE_CUSTOM_GETTER(GetterName, \
- (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, \
- JSC::PropertyName)) \
- { \
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject); \
- return JSC::JSValue::encode(thisObject->__propertyName()); \
- }
-
-#define GENERATED_CONSTRUCTOR_GETTER(ConstructorName) \
- JSC_DECLARE_CUSTOM_GETTER(ConstructorName##_getter); \
- JSC_DEFINE_CUSTOM_GETTER(ConstructorName##_getter, \
- (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, \
- JSC::PropertyName)) \
- { \
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject); \
- if (JSValue override = thisObject->m_##ConstructorName##SetterValue.get()) { \
- return JSC::JSValue::encode(override); \
- } \
- return JSC::JSValue::encode( \
- thisObject->ConstructorName##Constructor()); \
- }
-
-#define GENERATED_CONSTRUCTOR_SETTER(ConstructorName) \
- JSC_DECLARE_CUSTOM_SETTER(ConstructorName##_setter); \
- JSC_DEFINE_CUSTOM_SETTER(ConstructorName##_setter, \
- (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, \
- EncodedJSValue value, JSC::PropertyName)) \
- { \
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject); \
- thisObject->m_##ConstructorName##SetterValue.set(thisObject->vm(), thisObject, JSValue::decode(value)); \
- return true; \
- }
-
-#define WEBCORE_GENERATED_CONSTRUCTOR_GETTER(ConstructorName) \
- JSC_DECLARE_CUSTOM_GETTER(ConstructorName##_getter); \
- JSC_DEFINE_CUSTOM_GETTER(ConstructorName##_getter, \
- (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, \
- JSC::PropertyName)) \
- { \
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject); \
- if (JSValue override = thisObject->m_##ConstructorName##SetterValue.get()) { \
- return JSC::JSValue::encode(override); \
- } \
- return JSC::JSValue::encode( \
- WebCore::ConstructorName::getConstructor(JSC::getVM(lexicalGlobalObject), thisObject)); \
- }
-
-#define WEBCORE_GENERATED_CONSTRUCTOR_SETTER(ConstructorName) \
- JSC_DECLARE_CUSTOM_SETTER(ConstructorName##_setter); \
- JSC_DEFINE_CUSTOM_SETTER(ConstructorName##_setter, \
- (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, \
- EncodedJSValue value, JSC::PropertyName)) \
- { \
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject); \
- thisObject->m_##ConstructorName##SetterValue.set(thisObject->vm(), thisObject, JSValue::decode(value)); \
- return true; \
- }
-
-#define PUT_WEBCORE_GENERATED_CONSTRUCTOR(name, ConstructorName) \
- putDirectCustomAccessor(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, name)), JSC::CustomGetterSetter::create(vm, ConstructorName##_getter, ConstructorName##_setter), 0)
+#define WEBCORE_GENERATED_CONSTRUCTOR_GETTER(ConstructorName) \
+ JSValue ConstructorName##ConstructorCallback(VM& vm, JSObject* lexicalGlobalObject) \
+ { \
+ return WebCore::JS##ConstructorName::getConstructor(vm, JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject)); \
+ } \
+ JSC_DEFINE_CUSTOM_GETTER(ConstructorName##_getter, \
+ (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, \
+ JSC::PropertyName)) \
+ { \
+ return JSC::JSValue::encode(WebCore::JS##ConstructorName::getConstructor(lexicalGlobalObject->vm(), JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject))); \
+ }
String GlobalObject::defaultAgentClusterID()
{
@@ -708,9 +742,6 @@ namespace Zig {
using namespace WebCore;
-const JSC::ClassInfo GlobalObject::s_info = { "GlobalObject"_s, &Base::s_info, nullptr, nullptr,
- CREATE_METHOD_TABLE(GlobalObject) };
-
static JSGlobalObject* deriveShadowRealmGlobalObject(JSGlobalObject* globalObject)
{
auto& vm = globalObject->vm();
@@ -734,9 +765,9 @@ extern "C" JSC__JSValue JSC__JSValue__makeWithNameAndPrototype(JSC__JSGlobalObje
JSC::JSObject* wrapped = JSC::JSValue::decode(reinterpret_cast<JSC__JSValue>(wrappedRef)).getObject();
object->setPrototypeDirect(vm, wrapped);
JSString* nameString = JSC::jsNontrivialString(vm, Zig::toString(*visibleInterfaceName));
- object->putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+ object->putDirect(vm, vm.propertyNames->name, nameString, PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
object->putDirect(vm, vm.propertyNames->toStringTagSymbol,
- nameString, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly);
+ nameString, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
return JSC::JSValue::encode(JSC::JSValue(object));
}
@@ -801,7 +832,7 @@ GlobalObject::~GlobalObject()
finalizer(toNapi(this), napiInstanceData, napiInstanceDataFinalizerHint);
}
- delete crypto;
+ delete m_subtleCrypto;
scriptExecutionContext()->removeFromContextsMap();
}
@@ -851,9 +882,31 @@ void GlobalObject::setConsole(void* console)
this->setConsoleClient(new Zig::ConsoleClient(console));
}
+JSC_DEFINE_CUSTOM_GETTER(errorConstructorPrepareStackTraceGetter,
+ (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
+ JSC::PropertyName))
+{
+ Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
+ JSValue value = jsUndefined();
+ if (thisObject->m_errorConstructorPrepareStackTraceValue) {
+ value = thisObject->m_errorConstructorPrepareStackTraceValue.get();
+ }
+ return JSValue::encode(value);
+}
+
+JSC_DEFINE_CUSTOM_SETTER(errorConstructorPrepareStackTraceSetter,
+ (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
+ JSC::EncodedJSValue encodedValue, JSC::PropertyName property))
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
+ thisObject->m_errorConstructorPrepareStackTraceValue.set(vm, thisObject, JSValue::decode(encodedValue));
+ return true;
+}
+
#pragma mark - Globals
-JSC_DEFINE_CUSTOM_GETTER(globalGetterOnMessage,
+JSC_DEFINE_CUSTOM_GETTER(globalOnMessage,
(JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
JSC::PropertyName))
{
@@ -861,7 +914,7 @@ JSC_DEFINE_CUSTOM_GETTER(globalGetterOnMessage,
return JSValue::encode(eventHandlerAttribute(thisObject->eventTarget(), eventNames().messageEvent, thisObject->world()));
}
-JSC_DEFINE_CUSTOM_GETTER(globalGetterOnError,
+JSC_DEFINE_CUSTOM_GETTER(globalOnError,
(JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
JSC::PropertyName))
{
@@ -869,7 +922,7 @@ JSC_DEFINE_CUSTOM_GETTER(globalGetterOnError,
return JSValue::encode(eventHandlerAttribute(thisObject->eventTarget(), eventNames().errorEvent, thisObject->world()));
}
-JSC_DEFINE_CUSTOM_SETTER(globalSetterOnMessage,
+JSC_DEFINE_CUSTOM_SETTER(setGlobalOnMessage,
(JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
JSC::EncodedJSValue encodedValue, JSC::PropertyName property))
{
@@ -882,7 +935,7 @@ JSC_DEFINE_CUSTOM_SETTER(globalSetterOnMessage,
return true;
}
-JSC_DEFINE_CUSTOM_SETTER(globalSetterOnError,
+JSC_DEFINE_CUSTOM_SETTER(setGlobalOnError,
(JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
JSC::EncodedJSValue encodedValue, JSC::PropertyName property))
{
@@ -900,8 +953,6 @@ WebCore::EventTarget& GlobalObject::eventTarget()
return globalEventScope;
}
-JSC_DECLARE_CUSTOM_GETTER(functionLazyLoadStreamPrototypeMap_getter);
-
JSC_DEFINE_CUSTOM_GETTER(functionLazyLoadStreamPrototypeMap_getter,
(JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
JSC::PropertyName))
@@ -911,165 +962,61 @@ JSC_DEFINE_CUSTOM_GETTER(functionLazyLoadStreamPrototypeMap_getter,
thisObject->readableStreamNativeMap());
}
-JSC_DECLARE_CUSTOM_GETTER(JSDOMURL_getter);
-
-JSC_DEFINE_CUSTOM_GETTER(JSDOMURL_getter,
- (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
- JSC::PropertyName))
-{
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
- return JSC::JSValue::encode(
- WebCore::JSDOMURL::getConstructor(JSC::getVM(lexicalGlobalObject), thisObject));
-}
-
-JSC_DEFINE_CUSTOM_GETTER(JSBuffer_privateGetter,
- (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
- JSC::PropertyName))
-{
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
- return JSC::JSValue::encode(
- thisObject->JSBufferConstructor());
-}
-
-GENERATED_CONSTRUCTOR_GETTER(JSBuffer);
-GENERATED_CONSTRUCTOR_SETTER(JSBuffer);
-
-GENERATED_CONSTRUCTOR_GETTER(JSTextDecoder);
-GENERATED_CONSTRUCTOR_SETTER(JSTextDecoder);
-
-GENERATED_CONSTRUCTOR_GETTER(JSResponse);
-GENERATED_CONSTRUCTOR_SETTER(JSResponse);
-
-GENERATED_CONSTRUCTOR_GETTER(JSRequest);
-GENERATED_CONSTRUCTOR_SETTER(JSRequest);
-
-GENERATED_CONSTRUCTOR_GETTER(JSBlob);
-GENERATED_CONSTRUCTOR_SETTER(JSBlob);
-
-GENERATED_CONSTRUCTOR_GETTER(JSHTMLRewriter);
-GENERATED_CONSTRUCTOR_SETTER(JSHTMLRewriter);
-
-GENERATED_CONSTRUCTOR_GETTER(JSCrypto);
-GENERATED_CONSTRUCTOR_SETTER(JSCrypto);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSMessageEvent);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSMessageEvent);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSWebSocket);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSWebSocket);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSFetchHeaders);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSFetchHeaders);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSTextEncoder);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSTextEncoder);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSURLSearchParams);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSURLSearchParams);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSDOMFormData);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSDOMFormData);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSWorker);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSWorker);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSMessageChannel);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSMessageChannel);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSMessagePort);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSMessagePort);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSBroadcastChannel);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSBroadcastChannel);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSEvent);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSEvent);
-
-JSC_DECLARE_CUSTOM_GETTER(JSEvent_getter);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSDOMException);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSDOMException);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSEventTarget);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSEventTarget);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSCustomEvent);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSCustomEvent);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSErrorEvent);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSErrorEvent);
-
-WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSCloseEvent);
-WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSCloseEvent);
-
-JSC_DECLARE_CUSTOM_GETTER(JSDOMAbortController_getter);
-
-JSC_DEFINE_CUSTOM_GETTER(JSDOMAbortController_getter,
+JSC_DEFINE_CUSTOM_GETTER(JSBuffer_getter,
(JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
JSC::PropertyName))
{
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
- return JSC::JSValue::encode(
- WebCore::JSAbortController::getConstructor(JSC::getVM(lexicalGlobalObject), thisObject));
-}
-
-JSC_DECLARE_CUSTOM_GETTER(JSDOMAbortSignal_getter);
-
-JSC_DEFINE_CUSTOM_GETTER(JSDOMAbortSignal_getter,
- (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
- JSC::PropertyName))
-{
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
- return JSC::JSValue::encode(
- WebCore::JSAbortSignal::getConstructor(JSC::getVM(lexicalGlobalObject), thisObject));
-}
-
-static JSC_DECLARE_CUSTOM_SETTER(property_lazyProcessSetter);
-static JSC_DECLARE_CUSTOM_GETTER(property_lazyProcessGetter);
-
-JSC_DEFINE_CUSTOM_SETTER(property_lazyProcessSetter,
- (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
- JSC::EncodedJSValue value, JSC::PropertyName))
-{
- return false;
-}
-
-JSC_DEFINE_CUSTOM_GETTER(property_lazyProcessGetter,
- (JSC::JSGlobalObject * _globalObject, JSC::EncodedJSValue thisValue,
- JSC::PropertyName))
-{
- Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(_globalObject);
-
- JSC::VM& vm = globalObject->vm();
- auto clientData = WebCore::clientData(vm);
- return JSC::JSValue::encode(
- globalObject->processObject());
-}
-
-JSC_DEFINE_CUSTOM_GETTER(property_lazyCryptoGetter,
- (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue,
- JSC::PropertyName property))
+ return JSC::JSValue::encode(JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject)->JSBufferConstructor());
+}
+
+// This macro defines the getter needed for ZigGlobalObject.lut.h
+// "<ClassName>ConstructorCallback" is a PropertyCallback
+// it also defines "<ClassName>_getter" which is the getter for a JSC::CustomGetterSetter
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(AbortController);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(AbortSignal);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(BroadcastChannel);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(ByteLengthQueuingStrategy)
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(CloseEvent);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(CountQueuingStrategy)
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(CryptoKey);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(CustomEvent);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(DOMException);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(DOMFormData);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(DOMURL);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(ErrorEvent);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(Event);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(EventTarget);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(FetchHeaders);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(MessageChannel);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(MessageEvent);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(MessagePort);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(ReadableByteStreamController)
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(ReadableStream)
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(ReadableStreamBYOBReader)
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(ReadableStreamBYOBRequest)
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(ReadableStreamDefaultController)
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(ReadableStreamDefaultReader)
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(SubtleCrypto);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TextEncoder);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TransformStream)
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TransformStreamDefaultController)
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(URLSearchParams);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(WebSocket);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(Worker);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(WritableStream);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(WritableStreamDefaultController);
+WEBCORE_GENERATED_CONSTRUCTOR_GETTER(WritableStreamDefaultWriter);
+
+JSC_DEFINE_HOST_FUNCTION(functionGetSelf,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(JSValue::decode(thisValue));
- JSValue cryptoObject = thisObject->cryptoObject();
- thisObject->putDirect(thisObject->vm(), property, cryptoObject, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- return JSValue::encode(cryptoObject);
+ return JSC::JSValue::encode(callFrame->thisValue());
}
-JSC_DEFINE_CUSTOM_SETTER(lazyProcessEnvSetter,
- (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
- JSC::EncodedJSValue value, JSC::PropertyName))
-{
- return false;
-}
-
-JSC_DEFINE_CUSTOM_GETTER(lazyProcessEnvGetter,
- (JSC::JSGlobalObject * _globalObject, JSC::EncodedJSValue thisValue,
- JSC::PropertyName))
+JSC_DEFINE_HOST_FUNCTION(functionSetSelf,
+ (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
- Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(_globalObject);
- return JSC::JSValue::encode(
- globalObject->processEnvObject());
+ return JSC::JSValue::encode(jsUndefined());
}
JSC_DEFINE_HOST_FUNCTION(functionQueueMicrotask,
@@ -1385,7 +1332,7 @@ JSC_DEFINE_HOST_FUNCTION(functionBTOA,
static_cast<uint8_t>(WebCore::BufferEncodingType::base64)));
}
-static JSC_DEFINE_HOST_FUNCTION(functionATOB,
+JSC_DEFINE_HOST_FUNCTION(functionATOB,
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
JSC::VM& vm = globalObject->vm();
@@ -1408,7 +1355,7 @@ static JSC_DEFINE_HOST_FUNCTION(functionATOB,
RELEASE_AND_RETURN(throwScope, JSValue::encode(jsString(vm, result.releaseReturnValue())));
}
-static JSC_DEFINE_HOST_FUNCTION(functionReportError,
+JSC_DEFINE_HOST_FUNCTION(functionReportError,
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
switch (callFrame->argumentCount()) {
@@ -1538,6 +1485,89 @@ JSC_DEFINE_HOST_FUNCTION(jsTTYSetMode, (JSC::JSGlobalObject * globalObject, Call
return JSValue::encode(jsNumber(err));
}
+JSC_DEFINE_HOST_FUNCTION(jsHTTPGetHeader, (JSGlobalObject * globalObject, CallFrame* callFrame))
+{
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ JSValue headersValue = callFrame->argument(0);
+
+ if (auto* headers = jsDynamicCast<WebCore::JSFetchHeaders*>(headersValue)) {
+ JSValue nameValue = callFrame->argument(1);
+ if (nameValue.isString()) {
+ FetchHeaders* impl = &headers->wrapped();
+ String name = nameValue.toWTFString(globalObject);
+ if (WTF::equalIgnoringASCIICase(name, "set-cookie"_s)) {
+ return fetchHeadersGetSetCookie(globalObject, vm, impl);
+ }
+
+ WebCore::ExceptionOr<String> res = impl->get(name);
+ if (res.hasException()) {
+ WebCore::propagateException(globalObject, scope, res.releaseException());
+ return JSValue::encode(jsUndefined());
+ }
+
+ String value = res.returnValue();
+ if (value.isEmpty()) {
+ return JSValue::encode(jsUndefined());
+ }
+
+ return JSC::JSValue::encode(jsString(vm, value));
+ }
+ }
+
+ return JSValue::encode(jsUndefined());
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsHTTPSetHeader, (JSGlobalObject * globalObject, CallFrame* callFrame))
+{
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ JSValue headersValue = callFrame->argument(0);
+
+ if (auto* headers = jsDynamicCast<WebCore::JSFetchHeaders*>(headersValue)) {
+ JSValue nameValue = callFrame->argument(1);
+ if (nameValue.isString()) {
+ String name = nameValue.toWTFString(globalObject);
+ FetchHeaders* impl = &headers->wrapped();
+
+ JSValue valueValue = callFrame->argument(2);
+ if (valueValue.isUndefined())
+ return JSValue::encode(jsUndefined());
+
+ if (isArray(globalObject, valueValue)) {
+ auto* array = jsCast<JSArray*>(valueValue);
+ unsigned length = array->length();
+ if (length > 0) {
+ JSValue item = array->getIndex(globalObject, 0);
+ if (UNLIKELY(scope.exception()))
+ return JSValue::encode(jsUndefined());
+ impl->set(name, item.getString(globalObject));
+ RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
+ }
+ for (unsigned i = 1; i < length; ++i) {
+ JSValue value = array->getIndex(globalObject, i);
+ if (UNLIKELY(scope.exception()))
+ return JSValue::encode(jsUndefined());
+ if (!value.isString())
+ continue;
+ impl->append(name, value.getString(globalObject));
+ RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
+ }
+ RELEASE_AND_RETURN(scope, JSValue::encode(jsUndefined()));
+ return JSValue::encode(jsUndefined());
+ }
+
+ impl->set(name, valueValue.getString(globalObject));
+ RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
+ return JSValue::encode(jsUndefined());
+ }
+ }
+
+ return JSValue::encode(jsUndefined());
+}
+
JSC_DEFINE_CUSTOM_GETTER(noop_getter, (JSGlobalObject*, EncodedJSValue, PropertyName))
{
return JSC::JSValue::encode(JSC::jsUndefined());
@@ -1577,15 +1607,6 @@ enum ReadableStreamTag : int32_t {
Bytes = 4,
};
-JSC_DEFINE_HOST_FUNCTION(functionCallNotImplemented,
- (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
-{
- auto& vm = globalObject->vm();
- auto scope = DECLARE_THROW_SCOPE(vm);
- throwTypeError(globalObject, scope, "Not implemented yet in Bun :("_s);
- return JSC::JSValue::encode(JSC::JSValue {});
-}
-
JSC_DEFINE_HOST_FUNCTION(jsReceiveMessageOnPort, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
auto& vm = lexicalGlobalObject->vm();
@@ -1614,11 +1635,9 @@ JSC_DEFINE_HOST_FUNCTION(jsReceiveMessageOnPort, (JSGlobalObject * lexicalGlobal
return JSC::JSValue::encode(jsUndefined());
}
-extern JSC::EncodedJSValue Process_functionInternalGetWindowSize(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame);
-
// we're trying out a new way to do this lazy loading
// this is $lazy() in js code
-static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
+JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
(JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
{
@@ -1628,7 +1647,7 @@ static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
switch (callFrame->argumentCount()) {
case 0: {
- JSC::throwTypeError(globalObject, scope, "lazyLoad needs 1 argument (a string)"_s);
+ JSC::throwTypeError(globalObject, scope, "$lazy needs 1 argument (a string)"_s);
scope.release();
return JSC::JSValue::encode(JSC::JSValue {});
}
@@ -1637,7 +1656,7 @@ static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
if (moduleName.isNumber()) {
switch (moduleName.toInt32(globalObject)) {
case 0: {
- JSC::throwTypeError(globalObject, scope, "lazyLoad expects a string"_s);
+ JSC::throwTypeError(globalObject, scope, "$lazy expects a string"_s);
scope.release();
return JSC::JSValue::encode(JSC::JSValue {});
}
@@ -1654,7 +1673,7 @@ static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
default: {
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
- JSC::throwTypeError(globalObject, scope, "lazyLoad expects a string"_s);
+ JSC::throwTypeError(globalObject, scope, "$lazy expects a string"_s);
scope.release();
return JSC::JSValue::encode(JSC::JSValue {});
}
@@ -1663,7 +1682,7 @@ static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
auto string = moduleName.toWTFString(globalObject);
if (string.isNull()) {
- JSC::throwTypeError(globalObject, scope, "lazyLoad expects a string"_s);
+ JSC::throwTypeError(globalObject, scope, "$lazy expects a string"_s);
scope.release();
return JSC::JSValue::encode(JSC::JSValue {});
}
@@ -1672,6 +1691,17 @@ static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
return JSC::JSValue::encode(JSSQLStatementConstructor::create(vm, globalObject, JSSQLStatementConstructor::createStructure(vm, globalObject, globalObject->m_functionPrototype.get())));
}
+ if (string == "http"_s) {
+ auto* obj = constructEmptyObject(globalObject);
+ obj->putDirect(
+ vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "setHeader"_s)),
+ JSC::JSFunction::create(vm, globalObject, 3, "setHeader"_s, jsHTTPSetHeader, ImplementationVisibility::Public), NoIntrinsic);
+ obj->putDirect(
+ vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "getHeader"_s)),
+ JSC::JSFunction::create(vm, globalObject, 2, "getHeader"_s, jsHTTPGetHeader, ImplementationVisibility::Public), NoIntrinsic);
+ return JSC::JSValue::encode(obj);
+ }
+
if (string == "worker_threads"_s) {
JSValue workerData = jsUndefined();
@@ -1729,6 +1759,41 @@ static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
if (string == "events"_s) {
return JSValue::encode(WebCore::JSEventEmitter::getConstructor(vm, globalObject));
}
+
+ if (string == "internal/crypto"_s) {
+ // auto sourceOrigin = callFrame->callerSourceOrigin(vm).url();
+ // bool isBuiltin = sourceOrigin.protocolIs("builtin"_s);
+ // if (!isBuiltin) {
+ // return JSC::JSValue::encode(JSC::jsUndefined());
+ // }
+ auto* obj = constructEmptyObject(globalObject);
+ obj->putDirect(
+ vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "symmetricKeySize"_s)), JSC::JSFunction::create(vm, globalObject, 1, "symmetricKeySize"_s, KeyObject__SymmetricKeySize, ImplementationVisibility::Public, NoIntrinsic), 0);
+ obj->putDirect(
+ vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "asymmetricKeyType"_s)), JSC::JSFunction::create(vm, globalObject, 1, "asymmetricKeyType"_s, KeyObject__AsymmetricKeyType, ImplementationVisibility::Public, NoIntrinsic), 0);
+ obj->putDirect(
+ vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "asymmetricKeyDetails"_s)), JSC::JSFunction::create(vm, globalObject, 1, "asymmetricKeyDetails"_s, KeyObject_AsymmetricKeyDetails, ImplementationVisibility::Public, NoIntrinsic), 0);
+ obj->putDirect(
+ vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "equals"_s)), JSC::JSFunction::create(vm, globalObject, 2, "equals"_s, KeyObject__Equals, ImplementationVisibility::Public, NoIntrinsic), 0);
+ obj->putDirect(
+ vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "exports"_s)), JSC::JSFunction::create(vm, globalObject, 2, "exports"_s, KeyObject__Exports, ImplementationVisibility::Public, NoIntrinsic), 0);
+
+ obj->putDirect(
+ vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "createSecretKey"_s)), JSC::JSFunction::create(vm, globalObject, 1, "createSecretKey"_s, KeyObject__createSecretKey, ImplementationVisibility::Public, NoIntrinsic), 0);
+
+ obj->putDirect(
+ vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "createPublicKey"_s)), JSC::JSFunction::create(vm, globalObject, 1, "createPublicKey"_s, KeyObject__createPublicKey, ImplementationVisibility::Public, NoIntrinsic), 0);
+
+ obj->putDirect(
+ vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "createPrivateKey"_s)), JSC::JSFunction::create(vm, globalObject, 1, "createPrivateKey"_s, KeyObject__createPrivateKey, ImplementationVisibility::Public, NoIntrinsic), 0);
+
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "generateKeySync"_s)), JSC::JSFunction::create(vm, globalObject, 2, "generateKeySync"_s, KeyObject__generateKeySync, ImplementationVisibility::Public, NoIntrinsic), 0);
+
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "generateKeyPairSync"_s)), JSC::JSFunction::create(vm, globalObject, 2, "generateKeyPairSync"_s, KeyObject__generateKeyPairSync, ImplementationVisibility::Public, NoIntrinsic), 0);
+
+ return JSValue::encode(obj);
+ }
+
if (string == "internal/tls"_s) {
auto* obj = constructEmptyObject(globalObject);
@@ -1759,10 +1824,6 @@ static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
return JSValue::encode(obj);
}
- if (string == "masqueradesAsUndefined"_s) {
- return JSValue::encode(InternalFunction::createFunctionThatMasqueradesAsUndefined(vm, globalObject, 0, String(), functionCallNotImplemented));
- }
-
if (string == "vm"_s) {
auto* obj = constructEmptyObject(globalObject);
obj->putDirect(
@@ -1803,7 +1864,7 @@ static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
obj->putDirect(vm, PropertyName(Identifier::fromString(vm, "isatty"_s)), JSFunction::create(vm, globalObject, 0, "isatty"_s, jsFunctionTty_isatty, ImplementationVisibility::Public), 1);
- obj->putDirect(vm, PropertyName(Identifier::fromString(vm, "getWindowSize"_s)), JSFunction::create(vm, globalObject, 0, "getWindowSize"_s, Process_functionInternalGetWindowSize, ImplementationVisibility::Public), 2);
+ obj->putDirect(vm, PropertyName(Identifier::fromString(vm, "getWindowSize"_s)), JSFunction::create(vm, globalObject, 0, "getWindowSize"_s, Bun::Process_functionInternalGetWindowSize, ImplementationVisibility::Public), 2);
return JSValue::encode(obj);
}
@@ -1812,9 +1873,9 @@ static JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
auto* obj = constructEmptyObject(globalObject);
obj->putDirectCustomAccessor(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "getterSetter"_s)), JSC::CustomGetterSetter::create(vm, noop_getter, noop_setter), 0);
Zig::JSFFIFunction* function = Zig::JSFFIFunction::create(vm, reinterpret_cast<Zig::GlobalObject*>(globalObject), 0, String(), functionNoop, JSC::NoIntrinsic);
- obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "function"_s)), function, JSC::PropertyAttribute::Function | 0);
- obj->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "functionRegular"_s), 1, functionNoop, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function);
- obj->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "callback"_s), 1, functionCallback, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function);
+ obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "function"_s)), function, 0);
+ obj->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "functionRegular"_s), 1, functionNoop, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
+ obj->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "callback"_s), 1, functionCallback, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
return JSC::JSValue::encode(obj);
}
@@ -1903,173 +1964,9 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionDispatchEvent, (JSGlobalObject * lexicalGloba
return jsFunctionDispatchEventBody(lexicalGlobalObject, callFrame, jsDynamicCast<Zig::GlobalObject*>(lexicalGlobalObject));
}
-static inline JSValue jsServiceWorkerGlobalScope_ByteLengthQueuingStrategyConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSByteLengthQueuingStrategy::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_ByteLengthQueuingStrategyConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_ByteLengthQueuingStrategyConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_CountQueuingStrategyConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSCountQueuingStrategy::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_CountQueuingStrategyConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_CountQueuingStrategyConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_ReadableByteStreamControllerConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSReadableByteStreamController::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_ReadableByteStreamControllerConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_ReadableByteStreamControllerConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_ReadableStreamConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSReadableStream::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_ReadableStreamConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_ReadableStreamConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_ReadableStreamBYOBReaderConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSReadableStreamBYOBReader::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_ReadableStreamBYOBReaderConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_ReadableStreamBYOBReaderConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_ReadableStreamBYOBRequestConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSReadableStreamBYOBRequest::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_ReadableStreamBYOBRequestConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_ReadableStreamBYOBRequestConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_ReadableStreamDefaultControllerConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSReadableStreamDefaultController::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_ReadableStreamDefaultControllerConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_ReadableStreamDefaultControllerConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_ReadableStreamDefaultReaderConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSReadableStreamDefaultReader::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_ReadableStreamDefaultReaderConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_ReadableStreamDefaultReaderConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_TransformStreamConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSTransformStream::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_TransformStreamConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_TransformStreamConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_TransformStreamDefaultControllerConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSTransformStreamDefaultController::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_TransformStreamDefaultControllerConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_TransformStreamDefaultControllerConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_WritableStreamConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSWritableStream::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_WritableStreamConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_WritableStreamConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_WritableStreamDefaultControllerConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSWritableStreamDefaultController::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_WritableStreamDefaultControllerConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_WritableStreamDefaultControllerConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-static inline JSValue jsServiceWorkerGlobalScope_WritableStreamDefaultWriterConstructorGetter(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return JSWritableStreamDefaultWriter::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_WritableStreamDefaultWriterConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_WritableStreamDefaultWriterConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(getterSubtleCryptoConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
- return JSValue::encode(
- JSSubtleCrypto::getConstructor(thisObject->vm(), thisObject));
-}
-
-JSC_DEFINE_CUSTOM_GETTER(getterCryptoKeyConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
-{
- Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
- return JSValue::encode(
- JSCryptoKey::getConstructor(thisObject->vm(), thisObject));
-}
-
-static inline JSValue getterSubtleCryptoBody(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
-{
- UNUSED_PARAM(lexicalGlobalObject);
- return thisObject.subtleCrypto();
-}
-
JSC_DEFINE_CUSTOM_GETTER(getterSubtleCrypto, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
- return JSValue::encode(
- getterSubtleCryptoBody(*lexicalGlobalObject, *reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject)));
+ return JSValue::encode(reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject)->subtleCrypto());
}
JSC_DECLARE_HOST_FUNCTION(makeThisTypeErrorForBuiltins);
@@ -2079,6 +1976,12 @@ JSC_DECLARE_HOST_FUNCTION(createWritableStreamFromInternal);
JSC_DECLARE_HOST_FUNCTION(getInternalWritableStream);
JSC_DECLARE_HOST_FUNCTION(whenSignalAborted);
JSC_DECLARE_HOST_FUNCTION(isAbortSignal);
+
+JSC_DEFINE_HOST_FUNCTION(jsCreateCJSImportMeta, (JSGlobalObject * globalObject, CallFrame* callFrame))
+{
+ return JSValue::encode(Zig::ImportMetaObject::create(globalObject, callFrame->argument(0).toString(globalObject)));
+}
+
JSC_DEFINE_HOST_FUNCTION(makeThisTypeErrorForBuiltins, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
ASSERT(callFrame);
@@ -2296,9 +2199,11 @@ static inline EncodedJSValue functionPerformanceNowBody(JSGlobalObject* globalOb
{
auto* global = reinterpret_cast<GlobalObject*>(globalObject);
// nanoseconds to seconds
- uint64_t time = Bun__readOriginTimer(global->bunVM());
+ double time = static_cast<double>(Bun__readOriginTimer(global->bunVM()));
double result = time / 1000000.0;
- return JSValue::encode(jsNumber(result));
+
+ // https://github.com/oven-sh/bun/issues/5604
+ return JSValue::encode(jsDoubleNumber(result));
}
extern "C" {
@@ -2337,11 +2242,12 @@ private:
void finishCreation(JSC::VM& vm)
{
+ Base::finishCreation(vm);
static const JSC::DOMJIT::Signature DOMJITSignatureForPerformanceNow(
functionPerformanceNowWithoutTypeCheck,
JSPerformanceObject::info(),
JSC::DOMJIT::Effect::forWriteKinds(DFG::AbstractHeapKind::SideState),
- SpecBytecodeDouble);
+ SpecDoubleReal);
JSFunction* now = JSFunction::create(
vm,
@@ -2350,7 +2256,7 @@ private:
String("now"_s),
functionPerformanceNow, ImplementationVisibility::Public, NoIntrinsic, functionPerformanceNow,
&DOMJITSignatureForPerformanceNow);
- this->putDirect(vm, JSC::Identifier::fromString(vm, "now"_s), now, JSC::PropertyAttribute::DOMJITFunction | JSC::PropertyAttribute::Function);
+ this->putDirect(vm, JSC::Identifier::fromString(vm, "now"_s), now, 0);
JSFunction* noopNotImplemented = JSFunction::create(
vm,
@@ -2358,16 +2264,17 @@ private:
0,
String("noopNotImplemented"_s),
functionNoop, ImplementationVisibility::Public, NoIntrinsic, functionNoop,
- &DOMJITSignatureForPerformanceNow);
- this->putDirect(vm, JSC::Identifier::fromString(vm, "mark"_s), noopNotImplemented, JSC::PropertyAttribute::DOMJITFunction | JSC::PropertyAttribute::Function);
- this->putDirect(vm, JSC::Identifier::fromString(vm, "markResourceTiming"_s), noopNotImplemented, JSC::PropertyAttribute::DOMJITFunction | JSC::PropertyAttribute::Function);
- this->putDirect(vm, JSC::Identifier::fromString(vm, "measure"_s), noopNotImplemented, JSC::PropertyAttribute::DOMJITFunction | JSC::PropertyAttribute::Function);
+ nullptr);
+
+ this->putDirect(vm, JSC::Identifier::fromString(vm, "mark"_s), noopNotImplemented, 0);
+ this->putDirect(vm, JSC::Identifier::fromString(vm, "markResourceTiming"_s), noopNotImplemented, 0);
+ this->putDirect(vm, JSC::Identifier::fromString(vm, "measure"_s), noopNotImplemented, 0);
this->putDirect(
vm,
JSC::Identifier::fromString(vm, "timeOrigin"_s),
jsNumber(Bun__readOriginTimerStart(reinterpret_cast<Zig::GlobalObject*>(this->globalObject())->bunVM())),
- JSC::PropertyAttribute::ReadOnly | 0);
+ PropertyAttribute::ReadOnly | 0);
}
};
const ClassInfo JSPerformanceObject::s_info = { "Performance"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSPerformanceObject) };
@@ -2665,7 +2572,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionPerformMicrotaskVariadic, (JSGlobalObject * g
return JSValue::encode(jsUndefined());
}
-void GlobalObject::createCallSitesFromFrames(JSC::JSGlobalObject* lexicalGlobalObject, JSCStackTrace& stackTrace, JSC::JSArray* callSites)
+void GlobalObject::createCallSitesFromFrames(Zig::GlobalObject* globalObject, JSC::JSGlobalObject* lexicalGlobalObject, JSCStackTrace& stackTrace, JSC::JSArray* callSites)
{
/* From v8's "Stack Trace API" (https://github.com/v8/v8/wiki/Stack-Trace-API):
* "To maintain restrictions imposed on strict mode functions, frames that have a
@@ -2673,10 +2580,11 @@ void GlobalObject::createCallSitesFromFrames(JSC::JSGlobalObject* lexicalGlobalO
* their receiver and function objects. For those frames, getFunction() and getThis()
* will return undefined."." */
bool encounteredStrictFrame = false;
- GlobalObject* globalObject = reinterpret_cast<GlobalObject*>(lexicalGlobalObject);
+ // TODO: is it safe to use CallSite structure from a different JSGlobalObject? This case would happen within a node:vm
JSC::Structure* callSiteStructure = globalObject->callSiteStructure();
size_t framesCount = stackTrace.size();
+
for (size_t i = 0; i < framesCount; i++) {
CallSite* callSite = CallSite::create(lexicalGlobalObject, callSiteStructure, stackTrace.at(i), encounteredStrictFrame);
callSites->putDirectIndex(lexicalGlobalObject, i, callSite);
@@ -2687,40 +2595,19 @@ void GlobalObject::createCallSitesFromFrames(JSC::JSGlobalObject* lexicalGlobalO
}
}
-JSC::JSValue GlobalObject::formatStackTrace(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSObject* errorObject, JSC::JSArray* callSites)
+void GlobalObject::formatStackTrace(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSObject* errorObject, JSC::JSArray* callSites, JSValue prepareStackTrace)
{
auto scope = DECLARE_THROW_SCOPE(vm);
- JSValue errorValue = this->get(this, JSC::Identifier::fromString(vm, "Error"_s));
- if (UNLIKELY(scope.exception())) {
- return JSValue();
- }
- if (!errorValue || errorValue.isUndefined() || !errorValue.isObject()) {
- return JSValue(jsEmptyString(vm));
- }
+ auto* errorConstructor = lexicalGlobalObject->m_errorStructure.constructor(this);
- auto* errorConstructor = jsDynamicCast<JSC::JSObject*>(errorValue);
-
- /* If the user has set a callable Error.prepareStackTrace - use it to format the stack trace. */
- JSC::JSValue prepareStackTrace = errorConstructor->getIfPropertyExists(lexicalGlobalObject, JSC::Identifier::fromString(vm, "prepareStackTrace"_s));
- if (prepareStackTrace && prepareStackTrace.isCallable()) {
- JSC::CallData prepareStackTraceCallData = JSC::getCallData(prepareStackTrace);
-
- if (prepareStackTraceCallData.type != JSC::CallData::Type::None) {
- JSC::MarkedArgumentBuffer arguments;
- arguments.append(errorObject);
- arguments.append(callSites);
- ASSERT(!arguments.hasOverflowed());
-
- JSC::JSValue result = profiledCall(
- lexicalGlobalObject,
- JSC::ProfilingReason::Other,
- prepareStackTrace,
- prepareStackTraceCallData,
- errorConstructor,
- arguments);
- RETURN_IF_EXCEPTION(scope, JSC::jsUndefined());
- return result;
+ if (!prepareStackTrace) {
+ if (lexicalGlobalObject->inherits<Zig::GlobalObject>()) {
+ if (auto prepare = this->m_errorConstructorPrepareStackTraceValue.get()) {
+ prepareStackTrace = prepare;
+ }
+ } else {
+ prepareStackTrace = errorConstructor->getIfPropertyExists(lexicalGlobalObject, JSC::Identifier::fromString(vm, "prepareStackTrace"_s));
}
}
@@ -2749,7 +2636,43 @@ JSC::JSValue GlobalObject::formatStackTrace(JSC::VM& vm, JSC::JSGlobalObject* le
}
}
- return JSC::JSValue(jsString(vm, sb.toString()));
+ bool orignialSkipNextComputeErrorInfo = skipNextComputeErrorInfo;
+ skipNextComputeErrorInfo = true;
+ if (errorObject->hasProperty(lexicalGlobalObject, vm.propertyNames->stack)) {
+ skipNextComputeErrorInfo = true;
+ errorObject->deleteProperty(lexicalGlobalObject, vm.propertyNames->stack);
+ }
+ skipNextComputeErrorInfo = orignialSkipNextComputeErrorInfo;
+
+ // In Node, if you console.log(error.stack) inside Error.prepareStackTrace
+ // it will display the stack as a formatted string, so we have to do the same.
+ errorObject->putDirect(vm, vm.propertyNames->stack, JSC::JSValue(jsString(vm, sb.toString())), 0);
+
+ if (prepareStackTrace && prepareStackTrace.isCallable()) {
+ JSC::CallData prepareStackTraceCallData = JSC::getCallData(prepareStackTrace);
+
+ if (prepareStackTraceCallData.type != JSC::CallData::Type::None) {
+ JSC::MarkedArgumentBuffer arguments;
+ arguments.append(errorObject);
+ arguments.append(callSites);
+
+ JSC::JSValue result = profiledCall(
+ lexicalGlobalObject,
+ JSC::ProfilingReason::Other,
+ prepareStackTrace,
+ prepareStackTraceCallData,
+ errorConstructor,
+ arguments);
+
+ RETURN_IF_EXCEPTION(scope, void());
+
+ if (result.isUndefinedOrNull()) {
+ result = jsUndefined();
+ }
+
+ errorObject->putDirect(vm, vm.propertyNames->stack, result, 0);
+ }
+ }
}
JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncAppendStackTrace, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
@@ -2805,9 +2728,9 @@ JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncCaptureStackTrace, (JSC::JSGlobalOb
stackTrace.size());
// Create the call sites (one per frame)
- GlobalObject::createCallSitesFromFrames(lexicalGlobalObject, stackTrace, callSites);
+ GlobalObject::createCallSitesFromFrames(globalObject, lexicalGlobalObject, stackTrace, callSites);
- /* Foramt the stack trace.
+ /* Format the stack trace.
* Note that v8 won't actually format the stack trace here, but will create a "stack" accessor
* on the error object, which will format the stack trace on the first access. For now, since
* we're not being used internally by JSC, we can assume callers of Error.captureStackTrace in
@@ -2847,23 +2770,9 @@ JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncCaptureStackTrace, (JSC::JSGlobalOb
}
}
- JSC::JSValue formattedStackTrace = globalObject->formatStackTrace(vm, lexicalGlobalObject, errorObject, callSites);
+ globalObject->formatStackTrace(vm, lexicalGlobalObject, errorObject, callSites, JSC::JSValue());
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode({}));
- bool orignialSkipNextComputeErrorInfo = skipNextComputeErrorInfo;
- skipNextComputeErrorInfo = true;
- if (errorObject->hasProperty(lexicalGlobalObject, vm.propertyNames->stack)) {
- skipNextComputeErrorInfo = true;
- errorObject->deleteProperty(lexicalGlobalObject, vm.propertyNames->stack);
- }
- skipNextComputeErrorInfo = orignialSkipNextComputeErrorInfo;
-
- if (formattedStackTrace.isUndefinedOrNull()) {
- formattedStackTrace = JSC::jsUndefined();
- }
-
- errorObject->putDirect(vm, vm.propertyNames->stack, formattedStackTrace, 0);
-
if (auto* instance = jsDynamicCast<JSC::ErrorInstance*>(errorObject)) {
// we make a separate copy of the StackTrace unfortunately so that we
// can later console.log it without losing the info
@@ -2900,7 +2809,7 @@ void GlobalObject::finishCreation(VM& vm)
init.vm,
Identifier::fromString(init.vm, "subtle"_s),
JSC::CustomGetterSetter::create(init.vm, getterSubtleCrypto, nullptr),
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
+ PropertyAttribute::ReadOnly | PropertyAttribute::DontDelete | 0);
init.set(crypto);
});
@@ -2950,11 +2859,20 @@ void GlobalObject::finishCreation(VM& vm)
m_commonJSFunctionArgumentsStructure.initLater(
[](const Initializer<Structure>& init) {
auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(init.owner);
+
+ auto prototype = JSC::constructEmptyObject(init.owner, globalObject->objectPrototype(), 1);
+ prototype->putDirect(
+ init.vm,
+ Identifier::fromString(init.vm, "createImportMeta"_s),
+ JSFunction::create(init.vm, init.owner, 2, ""_s, jsCreateCJSImportMeta, ImplementationVisibility::Public),
+ PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | 0);
+
JSC::Structure* structure = globalObject->structureCache().emptyObjectStructureForPrototype(
globalObject,
- globalObject->objectPrototype(),
- 3);
+ prototype,
+ 5);
JSC::PropertyOffset offset;
+
auto& vm = globalObject->vm();
structure = structure->addPropertyTransition(
@@ -2967,6 +2885,20 @@ void GlobalObject::finishCreation(VM& vm)
structure = structure->addPropertyTransition(
vm,
structure,
+ JSC::Identifier::fromString(vm, "require"_s),
+ 0,
+ offset);
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "resolve"_s),
+ 0,
+ offset);
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
JSC::Identifier::fromString(vm, "__dirname"_s),
0,
offset);
@@ -2981,6 +2913,11 @@ void GlobalObject::finishCreation(VM& vm)
init.set(structure);
});
+ m_JSSocketAddressStructure.initLater(
+ [](const Initializer<Structure>& init) {
+ init.set(JSSocketAddress::createStructure(init.vm, init.owner));
+ });
+
// Change prototype from null to object for synthetic modules.
m_moduleNamespaceObjectStructure.initLater(
[](const Initializer<Structure>& init) {
@@ -3022,7 +2959,7 @@ void GlobalObject::finishCreation(VM& vm)
m_utilInspectFunction.initLater(
[](const Initializer<JSFunction>& init) {
- JSValue nodeUtilValue = static_cast<Zig::GlobalObject*>(init.owner)->internalModuleRegistry()->requireId(init.owner, init.vm, Bun::InternalModuleRegistry::Field::NodeUtil);
+ JSValue nodeUtilValue = jsCast<Zig::GlobalObject*>(init.owner)->internalModuleRegistry()->requireId(init.owner, init.vm, Bun::InternalModuleRegistry::Field::NodeUtil);
RELEASE_ASSERT(nodeUtilValue.isObject());
init.set(jsCast<JSFunction*>(nodeUtilValue.getObject()->getIfPropertyExists(init.owner, Identifier::fromString(init.vm, "inspect"_s))));
});
@@ -3034,7 +2971,7 @@ void GlobalObject::finishCreation(VM& vm)
// RETURN_IF_EXCEPTION(scope, {});
JSC::MarkedArgumentBuffer args;
- args.append(static_cast<Zig::GlobalObject*>(init.owner)->utilInspectFunction());
+ args.append(jsCast<Zig::GlobalObject*>(init.owner)->utilInspectFunction());
auto clientData = WebCore::clientData(init.vm);
JSC::CallData callData = JSC::getCallData(getStylize);
@@ -3078,7 +3015,7 @@ void GlobalObject::finishCreation(VM& vm)
JSC::JSObject* obj = JSC::constructEmptyObject(init.owner, init.owner->objectPrototype(), 4);
obj->putDirect(init.vm, userAgentIdentifier, JSC::jsString(init.vm, str));
obj->putDirect(init.vm, init.vm.propertyNames->toStringTagSymbol,
- jsNontrivialString(init.vm, "Navigator"_s), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly);
+ jsNontrivialString(init.vm, "Navigator"_s), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform
// https://github.com/oven-sh/bun/issues/4588
@@ -3091,8 +3028,7 @@ void GlobalObject::finishCreation(VM& vm)
#endif
obj->putDirect(init.vm, hardwareConcurrencyIdentifier, JSC::jsNumber(cpuCount));
- init.set(
- obj);
+ init.set(obj);
});
this->m_pendingVirtualModuleResultStructure.initLater(
@@ -3100,6 +3036,11 @@ void GlobalObject::finishCreation(VM& vm)
init.set(Bun::PendingVirtualModuleResult::createStructure(init.vm, init.owner, init.owner->objectPrototype()));
});
+ m_bunObject.initLater(
+ [](const JSC::LazyProperty<JSC::JSGlobalObject, JSObject>::Initializer& init) {
+ init.set(Bun::createBunObject(init.vm, init.owner));
+ });
+
this->initGeneratedLazyClasses();
m_cachedGlobalObjectStructure.initLater(
@@ -3119,13 +3060,12 @@ void GlobalObject::finishCreation(VM& vm)
m_subtleCryptoObject.initLater(
[](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) {
auto& global = *reinterpret_cast<Zig::GlobalObject*>(init.owner);
- if (global.crypto == nullptr) {
- global.crypto = WebCore::SubtleCrypto::createPtr(global.scriptExecutionContext());
- global.crypto->ref();
+
+ if (!global.m_subtleCrypto) {
+ global.m_subtleCrypto = &WebCore::SubtleCrypto::create(global.scriptExecutionContext()).leakRef();
}
- init.set(
- toJS<IDLInterface<SubtleCrypto>>(*init.owner, global, global.crypto).getObject());
+ init.set(toJS<IDLInterface<SubtleCrypto>>(*init.owner, global, global.m_subtleCrypto).getObject());
});
m_NapiClassStructure.initLater(
@@ -3173,8 +3113,8 @@ void GlobalObject::finishCreation(VM& vm)
m_processObject.initLater(
[](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) {
Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(init.owner);
- auto* process = Zig::Process::create(
- *globalObject, Zig::Process::createStructure(init.vm, init.owner, WebCore::JSEventEmitter::prototype(init.vm, *globalObject)));
+ auto* process = Bun::Process::create(
+ *globalObject, Bun::Process::createStructure(init.vm, init.owner, WebCore::JSEventEmitter::prototype(init.vm, *globalObject)));
init.set(process);
});
@@ -3234,7 +3174,7 @@ void GlobalObject::finishCreation(VM& vm)
});
m_processBindingConstants.initLater(
- [](const JSC::LazyProperty<JSC::JSGlobalObject, Bun::ProcessBindingConstants>::Initializer& init) {
+ [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) {
init.set(
ProcessBindingConstants::create(
init.vm,
@@ -3291,6 +3231,14 @@ void GlobalObject::finishCreation(VM& vm)
init.setConstructor(constructor);
});
+ m_JSCryptoKey.initLater(
+ [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::Structure>::Initializer& init) {
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(init.owner);
+ auto* prototype = JSCryptoKey::createPrototype(init.vm, *globalObject);
+ auto* structure = JSCryptoKey::createStructure(init.vm, init.owner, JSValue(prototype));
+ init.set(structure);
+ });
+
m_JSHTTPSResponseSinkClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
auto* prototype = createJSSinkPrototype(init.vm, init.global, WebCore::SinkID::HTTPSResponseSink);
@@ -3363,22 +3311,13 @@ void GlobalObject::finishCreation(VM& vm)
init.setConstructor(constructor);
});
- addBuiltinGlobals(vm);
-
#if ENABLE(REMOTE_INSPECTOR)
setInspectable(false);
#endif
- RELEASE_ASSERT(classInfo());
+ addBuiltinGlobals(vm);
- JSC::JSObject* errorConstructor = this->errorConstructor();
- errorConstructor->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "captureStackTrace"_s), 2, errorConstructorFuncCaptureStackTrace, ImplementationVisibility::Public, JSC::NoIntrinsic, PropertyAttribute::DontEnum | 0);
- errorConstructor->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "appendStackTrace"_s), 2, errorConstructorFuncAppendStackTrace, ImplementationVisibility::Private, JSC::NoIntrinsic, PropertyAttribute::DontEnum | 0);
- JSC::JSValue console = this->get(this, JSC::Identifier::fromString(vm, "console"_s));
- JSC::JSObject* consoleObject = console.getObject();
- consoleObject->putDirectBuiltinFunction(vm, this, vm.propertyNames->asyncIteratorSymbol, consoleObjectAsyncIteratorCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete);
- auto clientData = WebCore::clientData(vm);
- consoleObject->putDirectBuiltinFunction(vm, this, clientData->builtinNames().writePublicName(), consoleObjectWriteCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::ReadOnly | PropertyAttribute::DontDelete);
+ ASSERT(classInfo());
}
JSC_DEFINE_HOST_FUNCTION(jsFunctionPostMessage,
@@ -3483,7 +3422,7 @@ JSC_DEFINE_CUSTOM_GETTER(BunCommonJSModule_getter, (JSGlobalObject * globalObjec
// This implementation works the same as setTimeout(myFunction, 0)
// TODO: make it more efficient
// https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate
-static JSC_DEFINE_HOST_FUNCTION(functionSetImmediate,
+JSC_DEFINE_HOST_FUNCTION(functionSetImmediate,
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
JSC::VM& vm = globalObject->vm();
@@ -3525,31 +3464,11 @@ static JSC_DEFINE_HOST_FUNCTION(functionSetImmediate,
return Bun__Timer__setTimeout(globalObject, JSC::JSValue::encode(job), JSC::JSValue::encode(jsNumber(0)), JSValue::encode(arguments));
}
-JSC_DEFINE_CUSTOM_GETTER(JSModuleLoader_getter, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName))
-{
- return JSValue::encode(globalObject->moduleLoader());
-}
-
-JSC_DEFINE_CUSTOM_GETTER(functionResolveMessageGetter, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName))
+JSValue getEventSourceConstructor(VM& vm, JSObject* thisObject)
{
- return JSValue::encode(reinterpret_cast<Zig::GlobalObject*>(globalObject)->JSResolveMessageConstructor());
-}
-JSC_DEFINE_CUSTOM_GETTER(functionBuildMessageGetter, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName))
-{
- return JSValue::encode(reinterpret_cast<Zig::GlobalObject*>(globalObject)->JSBuildMessageConstructor());
-}
-
-JSC_DEFINE_CUSTOM_GETTER(
- EventSource_getter, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName property))
-{
- auto& vm = globalObject->vm();
+ auto globalObject = jsCast<Zig::GlobalObject*>(thisObject);
auto scope = DECLARE_THROW_SCOPE(vm);
- // If "this" is not the Global object, just return undefined
- // you should not be able to reset the global object's EventSource if you muck around with prototypes
- if (JSValue::decode(thisValue) != globalObject)
- return JSValue::encode(JSC::jsUndefined());
-
JSC::JSFunction* getSourceEvent = JSC::JSFunction::create(vm, eventSourceGetEventSourceCodeGenerator(vm), globalObject);
RETURN_IF_EXCEPTION(scope, {});
@@ -3564,15 +3483,61 @@ JSC_DEFINE_CUSTOM_GETTER(
if (returnedException) {
throwException(globalObject, scope, returnedException.get());
+ return jsUndefined();
}
- RETURN_IF_EXCEPTION(scope, {});
+ RELEASE_AND_RETURN(scope, result);
+}
- if (LIKELY(result)) {
- globalObject->putDirect(vm, property, result, 0);
+// `console.Console` or `import { Console } from 'console';`
+JSC_DEFINE_CUSTOM_GETTER(getConsoleConstructor, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName property))
+{
+ auto& vm = globalObject->vm();
+ auto console = JSValue::decode(thisValue).getObject();
+ JSC::JSFunction* createConsoleConstructor = JSC::JSFunction::create(vm, consoleObjectCreateConsoleConstructorCodeGenerator(vm), globalObject);
+ JSC::MarkedArgumentBuffer args;
+ args.append(console);
+ JSC::CallData callData = JSC::getCallData(createConsoleConstructor);
+ NakedPtr<JSC::Exception> returnedException = nullptr;
+ auto result = JSC::call(globalObject, createConsoleConstructor, callData, console, args, returnedException);
+ if (returnedException) {
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ throwException(globalObject, scope, returnedException.get());
}
+ console->putDirect(vm, property, result, 0);
+ return JSValue::encode(result);
+}
+
+// `console._stdout` is equal to `process.stdout`
+JSC_DEFINE_CUSTOM_GETTER(getConsoleStdout, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName property))
+{
+ auto& vm = globalObject->vm();
+ auto console = JSValue::decode(thisValue).getObject();
+ auto global = jsCast<Zig::GlobalObject*>(globalObject);
- RELEASE_AND_RETURN(scope, JSValue::encode(result));
+ // instead of calling the constructor builtin, go through the process.stdout getter to ensure it's only created once.
+ auto stdout = global->processObject()->get(globalObject, Identifier::fromString(vm, "stdout"_s));
+ if (!stdout)
+ return JSValue::encode({});
+
+ console->putDirect(vm, property, stdout, PropertyAttribute::DontEnum | 0);
+ return JSValue::encode(stdout);
+}
+
+// `console._stderr` is equal to `process.stderr`
+JSC_DEFINE_CUSTOM_GETTER(getConsoleStderr, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName property))
+{
+ auto& vm = globalObject->vm();
+ auto console = JSValue::decode(thisValue).getObject();
+ auto global = jsCast<Zig::GlobalObject*>(globalObject);
+
+ // instead of calling the constructor builtin, go through the process.stdout getter to ensure it's only created once.
+ auto stdout = global->processObject()->get(globalObject, Identifier::fromString(vm, "stderr"_s));
+ if (!stdout)
+ return JSValue::encode({});
+
+ console->putDirect(vm, property, stdout, PropertyAttribute::DontEnum | 0);
+ return JSValue::encode(stdout);
}
JSC_DEFINE_CUSTOM_SETTER(EventSource_setter,
@@ -3680,6 +3645,19 @@ extern "C" EncodedJSValue WebCore__alert(JSC::JSGlobalObject*, JSC::CallFrame*);
extern "C" EncodedJSValue WebCore__prompt(JSC::JSGlobalObject*, JSC::CallFrame*);
extern "C" EncodedJSValue WebCore__confirm(JSC::JSGlobalObject*, JSC::CallFrame*);
+JSValue GlobalObject_getPerformanceObject(VM& vm, JSObject* globalObject)
+{
+ return jsCast<Zig::GlobalObject*>(globalObject)->performanceObject();
+}
+
+JSValue GlobalObject_getGlobalThis(VM& vm, JSObject* globalObject)
+{
+ return jsCast<Zig::GlobalObject*>(globalObject)->globalThis();
+}
+
+// This is like `putDirectBuiltinFunction` but for the global static list.
+#define globalBuiltinFunction(vm, globalObject, identifier, function, attributes) JSC::JSGlobalObject::GlobalPropertyInfo(identifier, JSFunction::create(vm, function, globalObject), attributes)
+
void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
{
m_builtinInternalFunctions.initialize(*this);
@@ -3687,318 +3665,63 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
auto clientData = WebCore::clientData(vm);
auto& builtinNames = WebCore::builtinNames(vm);
- WTF::Vector<GlobalPropertyInfo> extraStaticGlobals;
- extraStaticGlobals.reserveCapacity(51);
-
- JSC::Identifier queueMicrotaskIdentifier = JSC::Identifier::fromString(vm, "queueMicrotask"_s);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { JSC::Identifier::fromString(vm, "fetch"_s),
- JSC::JSFunction::create(vm, this, 2,
- "fetch"_s, Bun__fetch, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { queueMicrotaskIdentifier,
- JSC::JSFunction::create(vm, this, 2,
- "queueMicrotask"_s, functionQueueMicrotask, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { JSC::Identifier::fromString(vm, "setImmediate"_s),
- JSC::JSFunction::create(vm, this, 1,
- "setImmediate"_s, functionSetImmediate, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { JSC::Identifier::fromString(vm, "clearImmediate"_s),
- JSC::JSFunction::create(vm, this, 1,
- "clearImmediate"_s, functionClearTimeout, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
-
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { JSC::Identifier::fromString(vm, "structuredClone"_s),
- JSC::JSFunction::create(vm, this, 2,
- "structuredClone"_s, functionStructuredClone, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
-
- JSC::Identifier setTimeoutIdentifier = JSC::Identifier::fromString(vm, "setTimeout"_s);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { setTimeoutIdentifier,
- JSC::JSFunction::create(vm, this, 1,
- "setTimeout"_s, functionSetTimeout, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
+ // ----- Private/Static Properties -----
- JSC::Identifier clearTimeoutIdentifier = JSC::Identifier::fromString(vm, "clearTimeout"_s);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { clearTimeoutIdentifier,
- JSC::JSFunction::create(vm, this, 1,
- "clearTimeout"_s, functionClearTimeout, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
+ auto $lazy = JSC::JSFunction::create(vm, this, 0, "$lazy"_s, functionLazyLoad, ImplementationVisibility::Public);
- JSC::Identifier setIntervalIdentifier = JSC::Identifier::fromString(vm, "setInterval"_s);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { setIntervalIdentifier,
- JSC::JSFunction::create(vm, this, 1,
- "setInterval"_s, functionSetInterval, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
-
- JSC::Identifier clearIntervalIdentifier = JSC::Identifier::fromString(vm, "clearInterval"_s);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { clearIntervalIdentifier,
- JSC::JSFunction::create(vm, this, 1,
- "clearInterval"_s, functionClearInterval, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
-
- JSC::Identifier atobIdentifier = JSC::Identifier::fromString(vm, "atob"_s);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { atobIdentifier,
- JSC::JSFunction::create(vm, this, 1,
- "atob"_s, functionATOB, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
-
- JSC::Identifier btoaIdentifier = JSC::Identifier::fromString(vm, "btoa"_s);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { btoaIdentifier,
- JSC::JSFunction::create(vm, this, 1,
- "btoa"_s, functionBTOA, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
- JSC::Identifier reportErrorIdentifier = JSC::Identifier::fromString(vm, "reportError"_s);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { reportErrorIdentifier,
- JSC::JSFunction::create(vm, this, 1,
- "reportError"_s, functionReportError, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
-
- {
- JSC::Identifier postMessageIdentifier = JSC::Identifier::fromString(vm, "postMessage"_s);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { postMessageIdentifier,
- JSC::JSFunction::create(vm, this, 1,
- "postMessage"_s, jsFunctionPostMessage, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
- }
-
- {
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { JSC::Identifier::fromString(vm, "alert"_s),
- JSC::JSFunction::create(vm, this, 1,
- "alert"_s, WebCore__alert, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
- }
-
- {
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { JSC::Identifier::fromString(vm, "confirm"_s),
- JSC::JSFunction::create(vm, this, 1,
- "confirm"_s, WebCore__confirm, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
- }
-
- {
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { JSC::Identifier::fromString(vm, "prompt"_s),
- JSC::JSFunction::create(vm, this, 1,
- "prompt"_s, WebCore__prompt, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
- }
-
- JSValue bunObject = Bun::createBunObject(this);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { builtinNames.BunPrivateName(),
- bunObject,
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0 });
-
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { builtinNames.BunPublicName(),
- bunObject,
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0 });
-
- extraStaticGlobals.uncheckedAppend(
+ GlobalPropertyInfo staticGlobals[] = {
GlobalPropertyInfo { builtinNames.startDirectStreamPrivateName(),
JSC::JSFunction::create(vm, this, 1,
String(), functionStartDirectStream, ImplementationVisibility::Public),
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
-
- static NeverDestroyed<const String> BunLazyString(MAKE_STATIC_STRING_IMPL("Bun.lazy"));
- JSC::Identifier BunLazyIdentifier = JSC::Identifier::fromUid(vm.symbolRegistry().symbolForKey(BunLazyString));
- JSC::JSFunction* lazyLoadFunction = JSC::JSFunction::create(vm, this, 0,
- BunLazyString, functionLazyLoad, ImplementationVisibility::Public);
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { BunLazyIdentifier,
- lazyLoadFunction,
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::Function | 0 });
-
- extraStaticGlobals.uncheckedAppend(
- GlobalPropertyInfo { builtinNames.lazyLoadPrivateName(),
- lazyLoadFunction,
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::Function | 0 });
-
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.makeThisTypeErrorPrivateName(), JSFunction::create(vm, this, 2, String(), makeThisTypeErrorForBuiltins, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.makeGetterTypeErrorPrivateName(), JSFunction::create(vm, this, 2, String(), makeGetterTypeErrorForBuiltins, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.makeDOMExceptionPrivateName(), JSFunction::create(vm, this, 2, String(), makeDOMExceptionForBuiltins, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.whenSignalAbortedPrivateName(), JSFunction::create(vm, this, 2, String(), whenSignalAborted, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.cloneArrayBufferPrivateName(), JSFunction::create(vm, this, 3, String(), cloneArrayBuffer, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.structuredCloneForStreamPrivateName(), JSFunction::create(vm, this, 1, String(), structuredCloneForStream, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.streamClosedPrivateName(), jsNumber(1), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::ConstantInteger));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.streamClosingPrivateName(), jsNumber(2), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::ConstantInteger));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.streamErroredPrivateName(), jsNumber(3), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::ConstantInteger));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.streamReadablePrivateName(), jsNumber(4), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::ConstantInteger));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.streamWaitingPrivateName(), jsNumber(5), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::ConstantInteger));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.streamWritablePrivateName(), jsNumber(6), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::ConstantInteger));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.isAbortSignalPrivateName(), JSFunction::create(vm, this, 1, String(), isAbortSignal, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.getInternalWritableStreamPrivateName(), JSFunction::create(vm, this, 1, String(), getInternalWritableStream, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.createWritableStreamFromInternalPrivateName(), JSFunction::create(vm, this, 1, String(), createWritableStreamFromInternal, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.fulfillModuleSyncPrivateName(), JSFunction::create(vm, this, 1, String(), functionFulfillModuleSync, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.directPrivateName(), JSFunction::create(vm, this, 1, String(), functionGetDirectStreamDetails, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function));
- extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(vm.propertyNames->builtinNames().ArrayBufferPrivateName(), arrayBufferConstructor(), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
-
- this->addStaticGlobals(extraStaticGlobals.data(), extraStaticGlobals.size());
-
- extraStaticGlobals.releaseBuffer();
+ PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | 0 },
+
+ // TODO: Remove the "Bun.lazy" symbol
+ // The reason we cant do this easily is our tests rely on this being public to test the internals.
+ GlobalPropertyInfo { JSC::Identifier::fromUid(vm.symbolRegistry().symbolForKey(MAKE_STATIC_STRING_IMPL("Bun.lazy"))),
+ $lazy,
+ PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | 0 },
+
+ GlobalPropertyInfo { builtinNames.lazyPrivateName(),
+ $lazy,
+ PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | 0 },
+
+ GlobalPropertyInfo(builtinNames.makeThisTypeErrorPrivateName(), JSFunction::create(vm, this, 2, String(), makeThisTypeErrorForBuiltins, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.makeGetterTypeErrorPrivateName(), JSFunction::create(vm, this, 2, String(), makeGetterTypeErrorForBuiltins, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.makeDOMExceptionPrivateName(), JSFunction::create(vm, this, 2, String(), makeDOMExceptionForBuiltins, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.whenSignalAbortedPrivateName(), JSFunction::create(vm, this, 2, String(), whenSignalAborted, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.cloneArrayBufferPrivateName(), JSFunction::create(vm, this, 3, String(), cloneArrayBuffer, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.structuredCloneForStreamPrivateName(), JSFunction::create(vm, this, 1, String(), structuredCloneForStream, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.isAbortSignalPrivateName(), JSFunction::create(vm, this, 1, String(), isAbortSignal, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.getInternalWritableStreamPrivateName(), JSFunction::create(vm, this, 1, String(), getInternalWritableStream, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.createWritableStreamFromInternalPrivateName(), JSFunction::create(vm, this, 1, String(), createWritableStreamFromInternal, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.fulfillModuleSyncPrivateName(), JSFunction::create(vm, this, 1, String(), functionFulfillModuleSync, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.directPrivateName(), JSFunction::create(vm, this, 1, String(), functionGetDirectStreamDetails, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->builtinNames().ArrayBufferPrivateName(), arrayBufferConstructor(), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.LoaderPrivateName(), this->moduleLoader(), PropertyAttribute::DontDelete | 0),
+ GlobalPropertyInfo(builtinNames.internalModuleRegistryPrivateName(), this->internalModuleRegistry(), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.processBindingConstantsPrivateName(), this->processBindingConstants(), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(builtinNames.requireMapPrivateName(), this->requireMap(), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | 0),
+ };
+ addStaticGlobals(staticGlobals, std::size(staticGlobals));
+
+ // TODO: most/all of these private properties can be made as static globals.
+ // i've noticed doing it as is will work somewhat but getDirect() wont be able to find them
putDirectBuiltinFunction(vm, this, builtinNames.createFIFOPrivateName(), streamInternalsCreateFIFOCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
putDirectBuiltinFunction(vm, this, builtinNames.createEmptyReadableStreamPrivateName(), readableStreamCreateEmptyReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
+ putDirectBuiltinFunction(vm, this, builtinNames.createUsedReadableStreamPrivateName(), readableStreamCreateUsedReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
putDirectBuiltinFunction(vm, this, builtinNames.consumeReadableStreamPrivateName(), readableStreamConsumeReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
-
- putDirect(vm, builtinNames.LoaderPrivateName(), this->moduleLoader(), 0);
putDirectBuiltinFunction(vm, this, builtinNames.createNativeReadableStreamPrivateName(), readableStreamCreateNativeReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
-
putDirectBuiltinFunction(vm, this, builtinNames.requireESMPrivateName(), importMetaObjectRequireESMCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
putDirectBuiltinFunction(vm, this, builtinNames.loadCJS2ESMPrivateName(), importMetaObjectLoadCJS2ESMCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
putDirectBuiltinFunction(vm, this, builtinNames.internalRequirePrivateName(), importMetaObjectInternalRequireCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
putDirectBuiltinFunction(vm, this, builtinNames.requireNativeModulePrivateName(), moduleRequireNativeModuleCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
- putDirectNativeFunction(vm, this, builtinNames.createUninitializedArrayBufferPrivateName(), 1, functionCreateUninitializedArrayBuffer, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function);
- putDirectNativeFunction(vm, this, builtinNames.resolveSyncPrivateName(), 1, functionImportMeta__resolveSyncPrivate, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function);
- putDirectNativeFunction(vm, this, builtinNames.createInternalModuleByIdPrivateName(), 1, InternalModuleRegistry::jsCreateInternalModuleById, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function);
- putDirect(vm, builtinNames.internalModuleRegistryPrivateName(), this->internalModuleRegistry(), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
- putDirect(vm, builtinNames.processBindingConstantsPrivateName(), this->processBindingConstants(), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "process"_s), JSC::CustomGetterSetter::create(vm, property_lazyProcessGetter, property_lazyProcessSetter),
- JSC::PropertyAttribute::CustomAccessor | 0);
- putDirect(vm, JSC::Identifier::fromString(vm, "performance"_s), this->performanceObject(),
- 0);
+ putDirectBuiltinFunction(vm, this, builtinNames.overridableRequirePrivateName(), moduleOverridableRequireCodeGenerator(vm), 0);
- putDirect(vm, JSC::Identifier::fromString(vm, "self"_s), this->globalThis(), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | 0);
- putDirect(vm, JSC::Identifier::fromString(vm, "global"_s), this->globalThis(), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "URL"_s), JSC::CustomGetterSetter::create(vm, JSDOMURL_getter, nullptr),
- JSC::PropertyAttribute::DontDelete | 0);
-
- putDirectCustomAccessor(vm, builtinNames.lazyStreamPrototypeMapPrivateName(), JSC::CustomGetterSetter::create(vm, functionLazyLoadStreamPrototypeMap_getter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "navigator"_s), JSC::CustomGetterSetter::create(vm, functionLazyNavigatorGetter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "ResolveError"_s), JSC::CustomGetterSetter::create(vm, functionResolveMessageGetter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "ResolveMessage"_s), JSC::CustomGetterSetter::create(vm, functionResolveMessageGetter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "BuildError"_s), JSC::CustomGetterSetter::create(vm, functionBuildMessageGetter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "BuildMessage"_s), JSC::CustomGetterSetter::create(vm, functionBuildMessageGetter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0);
-
- putDirect(vm, builtinNames.requireMapPrivateName(), this->requireMap(),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "Request"_s), JSC::CustomGetterSetter::create(vm, JSRequest_getter, JSRequest_setter),
- JSC::PropertyAttribute::DontDelete | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "Response"_s), JSC::CustomGetterSetter::create(vm, JSResponse_getter, JSResponse_setter),
- JSC::PropertyAttribute::DontDelete | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "TextDecoder"_s), JSC::CustomGetterSetter::create(vm, JSTextDecoder_getter, JSTextDecoder_setter),
- JSC::PropertyAttribute::DontDelete | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "Blob"_s), JSC::CustomGetterSetter::create(vm, JSBlob_getter, JSBlob_setter),
- JSC::PropertyAttribute::DontDelete | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "HTMLRewriter"_s), JSC::CustomGetterSetter::create(vm, JSHTMLRewriter_getter, JSHTMLRewriter_setter),
- JSC::PropertyAttribute::DontDelete | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "Crypto"_s), JSC::CustomGetterSetter::create(vm, JSCrypto_getter, JSCrypto_setter),
- JSC::PropertyAttribute::DontDelete | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "File"_s), JSC::CustomGetterSetter::create(vm, JSDOMFileConstructor_getter, JSDOMFileConstructor_setter),
- JSC::PropertyAttribute::DontDelete | 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "DOMException"_s), JSC::CustomGetterSetter::create(vm, JSDOMException_getter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "Event"_s), JSC::CustomGetterSetter::create(vm, JSEvent_getter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "EventTarget"_s), JSC::CustomGetterSetter::create(vm, JSEventTarget_getter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "AbortController"_s), JSC::CustomGetterSetter::create(vm, JSDOMAbortController_getter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "AbortSignal"_s), JSC::CustomGetterSetter::create(vm, JSDOMAbortSignal_getter, nullptr),
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "$_BunCommonJSModule_$"_s), JSC::CustomGetterSetter::create(vm, BunCommonJSModule_getter, nullptr),
- JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "EventSource"_s), JSC::CustomGetterSetter::create(vm, EventSource_getter, EventSource_setter), 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "onmessage"_s), JSC::CustomGetterSetter::create(vm, globalGetterOnMessage, globalSetterOnMessage), 0);
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "onerror"_s), JSC::CustomGetterSetter::create(vm, globalGetterOnError, globalSetterOnError), 0);
-
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "crypto"_s), JSC::CustomGetterSetter::create(vm, property_lazyCryptoGetter, nullptr),
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
-
- auto bufferAccessor = JSC::CustomGetterSetter::create(vm, JSBuffer_getter, JSBuffer_setter);
- auto realBufferAccessor = JSC::CustomGetterSetter::create(vm, JSBuffer_privateGetter, nullptr);
-
- //
- putDirectCustomAccessor(vm, static_cast<JSVMClientData*>(vm.clientData)->builtinNames().BufferPublicName(), bufferAccessor,
- JSC::PropertyAttribute::DontDelete | 0);
- putDirectCustomAccessor(vm, static_cast<JSVMClientData*>(vm.clientData)->builtinNames().BufferPrivateName(), realBufferAccessor,
- JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
-
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("BroadcastChannel"_s, JSBroadcastChannel);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("CloseEvent"_s, JSCloseEvent);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("CustomEvent"_s, JSCustomEvent);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("DOMException"_s, JSDOMException);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("ErrorEvent"_s, JSErrorEvent);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("Event"_s, JSEvent);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("EventTarget"_s, JSEventTarget);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("FormData"_s, JSDOMFormData);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("Headers"_s, JSFetchHeaders);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("MessageChannel"_s, JSMessageChannel);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("MessageEvent"_s, JSMessageEvent);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("MessagePort"_s, JSMessagePort);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("TextEncoder"_s, JSTextEncoder);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("URLSearchParams"_s, JSURLSearchParams);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("WebSocket"_s, JSWebSocket);
- PUT_WEBCORE_GENERATED_CONSTRUCTOR("Worker"_s, JSWorker);
-
- putDirectCustomAccessor(vm, builtinNames.TransformStreamPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_TransformStreamConstructor, nullptr), attributesForStructure(static_cast<unsigned>(JSC::PropertyAttribute::DontEnum)));
- putDirectCustomAccessor(vm, builtinNames.TransformStreamPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_TransformStreamConstructor, nullptr), attributesForStructure(static_cast<unsigned>(JSC::PropertyAttribute::DontEnum)));
- putDirectCustomAccessor(vm, builtinNames.TransformStreamDefaultControllerPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_TransformStreamDefaultControllerConstructor, nullptr), attributesForStructure(static_cast<unsigned>(JSC::PropertyAttribute::DontEnum)));
- putDirectCustomAccessor(vm, builtinNames.TransformStreamDefaultControllerPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_TransformStreamDefaultControllerConstructor, nullptr), attributesForStructure(static_cast<unsigned>(JSC::PropertyAttribute::DontEnum)));
- putDirectCustomAccessor(vm, builtinNames.ReadableByteStreamControllerPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableByteStreamControllerConstructor, nullptr), attributesForStructure(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly));
- putDirectCustomAccessor(vm, builtinNames.ReadableStreamPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableStreamConstructor, nullptr), attributesForStructure(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly));
- putDirectCustomAccessor(vm, builtinNames.ReadableStreamBYOBReaderPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableStreamBYOBReaderConstructor, nullptr), attributesForStructure(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly));
- putDirectCustomAccessor(vm, builtinNames.ReadableStreamBYOBRequestPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableStreamBYOBRequestConstructor, nullptr), attributesForStructure(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly));
- putDirectCustomAccessor(vm, builtinNames.ReadableStreamDefaultControllerPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableStreamDefaultControllerConstructor, nullptr), attributesForStructure(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly));
- putDirectCustomAccessor(vm, builtinNames.ReadableStreamDefaultReaderPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableStreamDefaultReaderConstructor, nullptr), attributesForStructure(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly));
- putDirectCustomAccessor(vm, builtinNames.WritableStreamPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_WritableStreamConstructor, nullptr), attributesForStructure(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly));
- putDirectCustomAccessor(vm, builtinNames.WritableStreamDefaultControllerPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_WritableStreamDefaultControllerConstructor, nullptr), attributesForStructure(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly));
- putDirectCustomAccessor(vm, builtinNames.WritableStreamDefaultWriterPrivateName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_WritableStreamDefaultWriterConstructor, nullptr), attributesForStructure(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly));
- putDirectCustomAccessor(vm, builtinNames.AbortSignalPrivateName(), CustomGetterSetter::create(vm, JSDOMAbortSignal_getter, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, builtinNames.ReadableByteStreamControllerPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableByteStreamControllerConstructor, nullptr), JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, builtinNames.ReadableStreamPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableStreamConstructor, nullptr), JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, builtinNames.ReadableStreamBYOBReaderPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableStreamBYOBReaderConstructor, nullptr), JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, builtinNames.ReadableStreamBYOBRequestPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableStreamBYOBRequestConstructor, nullptr), JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, builtinNames.ReadableStreamDefaultControllerPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableStreamDefaultControllerConstructor, nullptr), JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, builtinNames.ReadableStreamDefaultReaderPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ReadableStreamDefaultReaderConstructor, nullptr), JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, builtinNames.WritableStreamPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_WritableStreamConstructor, nullptr), JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, builtinNames.WritableStreamDefaultControllerPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_WritableStreamDefaultControllerConstructor, nullptr), JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, builtinNames.WritableStreamDefaultWriterPublicName(), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_WritableStreamDefaultWriterConstructor, nullptr), JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
+ putDirectNativeFunction(vm, this, builtinNames.createUninitializedArrayBufferPrivateName(), 1, functionCreateUninitializedArrayBuffer, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
+ putDirectNativeFunction(vm, this, builtinNames.resolveSyncPrivateName(), 1, functionImportMeta__resolveSyncPrivate, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
+ putDirectNativeFunction(vm, this, builtinNames.createInternalModuleByIdPrivateName(), 1, InternalModuleRegistry::jsCreateInternalModuleById, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
putDirectNativeFunction(vm, this,
builtinNames.createCommonJSModulePrivateName(),
@@ -4006,42 +3729,60 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
Bun::jsFunctionCreateCommonJSModule,
ImplementationVisibility::Public,
NoIntrinsic,
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ PropertyAttribute::ReadOnly | PropertyAttribute::DontDelete | 0);
putDirectNativeFunction(vm, this,
builtinNames.evaluateCommonJSModulePrivateName(),
2,
Bun::jsFunctionLoadModule,
ImplementationVisibility::Public,
NoIntrinsic,
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "ByteLengthQueuingStrategy"_s), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_ByteLengthQueuingStrategyConstructor, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "CountQueuingStrategy"_s), CustomGetterSetter::create(vm, jsServiceWorkerGlobalScope_CountQueuingStrategyConstructor, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "SubtleCrypto"_s), JSC::CustomGetterSetter::create(vm, getterSubtleCryptoConstructor, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
- putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "CryptoKey"_s), JSC::CustomGetterSetter::create(vm, getterCryptoKeyConstructor, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
+ PropertyAttribute::ReadOnly | PropertyAttribute::DontDelete | 0);
+
+ putDirectCustomAccessor(vm, static_cast<JSVMClientData*>(vm.clientData)->builtinNames().BufferPrivateName(), JSC::CustomGetterSetter::create(vm, JSBuffer_getter, nullptr), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.lazyStreamPrototypeMapPrivateName(), JSC::CustomGetterSetter::create(vm, functionLazyLoadStreamPrototypeMap_getter, nullptr), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.TransformStreamPrivateName(), CustomGetterSetter::create(vm, TransformStream_getter, nullptr), attributesForStructure(static_cast<unsigned>(PropertyAttribute::DontEnum)) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.TransformStreamDefaultControllerPrivateName(), CustomGetterSetter::create(vm, TransformStreamDefaultController_getter, nullptr), attributesForStructure(static_cast<unsigned>(PropertyAttribute::DontEnum)) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.ReadableByteStreamControllerPrivateName(), CustomGetterSetter::create(vm, ReadableByteStreamController_getter, nullptr), attributesForStructure(PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.ReadableStreamPrivateName(), CustomGetterSetter::create(vm, ReadableStream_getter, nullptr), attributesForStructure(PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.ReadableStreamBYOBReaderPrivateName(), CustomGetterSetter::create(vm, ReadableStreamBYOBReader_getter, nullptr), attributesForStructure(PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.ReadableStreamBYOBRequestPrivateName(), CustomGetterSetter::create(vm, ReadableStreamBYOBRequest_getter, nullptr), attributesForStructure(PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.ReadableStreamDefaultControllerPrivateName(), CustomGetterSetter::create(vm, ReadableStreamDefaultController_getter, nullptr), attributesForStructure(PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.ReadableStreamDefaultReaderPrivateName(), CustomGetterSetter::create(vm, ReadableStreamDefaultReader_getter, nullptr), attributesForStructure(PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.WritableStreamPrivateName(), CustomGetterSetter::create(vm, WritableStream_getter, nullptr), attributesForStructure(PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.WritableStreamDefaultControllerPrivateName(), CustomGetterSetter::create(vm, WritableStreamDefaultController_getter, nullptr), attributesForStructure(PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.WritableStreamDefaultWriterPrivateName(), CustomGetterSetter::create(vm, WritableStreamDefaultWriter_getter, nullptr), attributesForStructure(PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly) | PropertyAttribute::CustomAccessorOrValue);
+ putDirectCustomAccessor(vm, builtinNames.AbortSignalPrivateName(), CustomGetterSetter::create(vm, AbortSignal_getter, nullptr), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessorOrValue);
+
+ // ----- Public Properties -----
+
+ // a direct accessor (uses js functions for get and set) cannot be on the lookup table. i think.
+ putDirectAccessor(
+ this,
+ builtinNames.selfPublicName(),
+ JSC::GetterSetter::create(
+ vm,
+ this,
+ JSFunction::create(vm, this, 0, "get"_s, functionGetSelf, ImplementationVisibility::Public),
+ JSFunction::create(vm, this, 0, "set"_s, functionSetSelf, ImplementationVisibility::Public)),
+ PropertyAttribute::Accessor | 0);
- putDirectNativeFunction(vm, this,
- Identifier::fromString(vm, "addEventListener"_s),
- 2,
- jsFunctionAddEventListener,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ // TODO: this should be usable on the lookup table. it crashed las time i tried it
+ putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "onmessage"_s), JSC::CustomGetterSetter::create(vm, globalOnMessage, setGlobalOnMessage), 0);
+ putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "onerror"_s), JSC::CustomGetterSetter::create(vm, globalOnError, setGlobalOnError), 0);
- putDirectNativeFunction(vm, this,
- Identifier::fromString(vm, "dispatchEvent"_s),
- 1,
- jsFunctionDispatchEvent,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ // ----- Extensions to Built-in objects -----
- putDirectNativeFunction(vm, this,
- Identifier::fromString(vm, "removeEventListener"_s),
- 2,
- jsFunctionRemoveEventListener,
- ImplementationVisibility::Public,
- NoIntrinsic,
- JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
+ JSC::JSObject* errorConstructor = this->errorConstructor();
+ errorConstructor->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "captureStackTrace"_s), 2, errorConstructorFuncCaptureStackTrace, ImplementationVisibility::Public, JSC::NoIntrinsic, PropertyAttribute::DontEnum | 0);
+ errorConstructor->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "appendStackTrace"_s), 2, errorConstructorFuncAppendStackTrace, ImplementationVisibility::Private, JSC::NoIntrinsic, PropertyAttribute::DontEnum | 0);
+ errorConstructor->putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "prepareStackTrace"_s), JSC::CustomGetterSetter::create(vm, errorConstructorPrepareStackTraceGetter, errorConstructorPrepareStackTraceSetter), PropertyAttribute::DontEnum | PropertyAttribute::CustomValue);
+
+ JSC::JSObject* consoleObject = this->get(this, JSC::Identifier::fromString(vm, "console"_s)).getObject();
+ consoleObject->putDirectBuiltinFunction(vm, this, vm.propertyNames->asyncIteratorSymbol, consoleObjectAsyncIteratorCodeGenerator(vm), PropertyAttribute::Builtin | 0);
+ consoleObject->putDirectBuiltinFunction(vm, this, clientData->builtinNames().writePublicName(), consoleObjectWriteCodeGenerator(vm), PropertyAttribute::Builtin | 0);
+ consoleObject->putDirectCustomAccessor(vm, Identifier::fromString(vm, "Console"_s), CustomGetterSetter::create(vm, getConsoleConstructor, nullptr), PropertyAttribute::CustomValue | 0);
+ consoleObject->putDirectCustomAccessor(vm, Identifier::fromString(vm, "_stdout"_s), CustomGetterSetter::create(vm, getConsoleStdout, nullptr), PropertyAttribute::DontEnum | PropertyAttribute::CustomValue | 0);
+ consoleObject->putDirectCustomAccessor(vm, Identifier::fromString(vm, "_stderr"_s), CustomGetterSetter::create(vm, getConsoleStderr, nullptr), PropertyAttribute::DontEnum | PropertyAttribute::CustomValue | 0);
}
extern "C" bool JSC__JSGlobalObject__startRemoteInspector(JSC__JSGlobalObject* globalObject, unsigned char* host, uint16_t arg1)
@@ -4104,29 +3845,8 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
visitor.append(thisObject->m_readableStreamToFormData);
visitor.append(thisObject->m_nodeModuleOverriddenResolveFilename);
- visitor.append(thisObject->m_JSBlobSetterValue);
- visitor.append(thisObject->m_JSBroadcastChannelSetterValue);
- visitor.append(thisObject->m_JSBufferSetterValue);
- visitor.append(thisObject->m_JSCloseEventSetterValue);
- visitor.append(thisObject->m_JSCustomEventSetterValue);
- visitor.append(thisObject->m_JSDOMExceptionSetterValue);
- visitor.append(thisObject->m_JSDOMFormDataSetterValue);
- visitor.append(thisObject->m_JSErrorEventSetterValue);
- visitor.append(thisObject->m_JSEventSetterValue);
- visitor.append(thisObject->m_JSEventTargetSetterValue);
- visitor.append(thisObject->m_JSFetchHeadersSetterValue);
- visitor.append(thisObject->m_JSMessageChannelSetterValue);
- visitor.append(thisObject->m_JSMessageEventSetterValue);
- visitor.append(thisObject->m_JSMessagePortSetterValue);
- visitor.append(thisObject->m_JSRequestSetterValue);
- visitor.append(thisObject->m_JSResponseSetterValue);
- visitor.append(thisObject->m_JSTextDecoderSetterValue);
- visitor.append(thisObject->m_JSTextEncoderSetterValue);
- visitor.append(thisObject->m_JSURLSearchParamsSetterValue);
- visitor.append(thisObject->m_JSWebSocketSetterValue);
- visitor.append(thisObject->m_JSWorkerSetterValue);
-
visitor.append(thisObject->m_nextTickQueue);
+ visitor.append(thisObject->m_errorConstructorPrepareStackTraceValue);
thisObject->m_JSArrayBufferSinkClassStructure.visit(visitor);
thisObject->m_JSBufferListClassStructure.visit(visitor);
@@ -4157,17 +3877,19 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_performanceObject.visit(visitor);
thisObject->m_processEnvObject.visit(visitor);
thisObject->m_processObject.visit(visitor);
+ thisObject->m_bunObject.visit(visitor);
thisObject->m_subtleCryptoObject.visit(visitor);
thisObject->m_JSHTTPResponseController.visit(visitor);
thisObject->m_callSiteStructure.visit(visitor);
thisObject->m_emitReadableNextTickFunction.visit(visitor);
thisObject->m_JSBufferSubclassStructure.visit(visitor);
+ thisObject->m_JSCryptoKey.visit(visitor);
+
thisObject->m_cryptoObject.visit(visitor);
thisObject->m_JSDOMFileConstructor.visit(visitor);
thisObject->m_requireFunctionUnbound.visit(visitor);
thisObject->m_requireResolveFunctionUnbound.visit(visitor);
- thisObject->m_processBindingConstants.visit(visitor);
thisObject->m_importMetaObjectStructure.visit(visitor);
thisObject->m_asyncBoundFunctionStructure.visit(visitor);
thisObject->m_internalModuleRegistry.visit(visitor);
@@ -4180,6 +3902,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_commonJSModuleObjectStructure.visit(visitor);
thisObject->m_memoryFootprintStructure.visit(visitor);
thisObject->m_commonJSFunctionArgumentsStructure.visit(visitor);
+ thisObject->m_JSSocketAddressStructure.visit(visitor);
thisObject->m_cachedGlobalObjectStructure.visit(visitor);
thisObject->m_cachedGlobalProxyStructure.visit(visitor);
@@ -4291,7 +4014,7 @@ template void GlobalObject::visitOutputConstraints(JSCell*, SlotVisitor&);
// void GlobalObject::destroy(JSCell* cell)
// {
-// static_cast<Zig::GlobalObject*>(cell)->Zig::GlobalObject::~Zig::GlobalObject();
+// jsCast<Zig::GlobalObject*>(cell)->Zig::GlobalObject::~Zig::GlobalObject();
// }
// template<typename Visitor>
@@ -4351,16 +4074,45 @@ extern "C" void JSC__JSGlobalObject__queueMicrotaskCallback(Zig::GlobalObject* g
globalObject->queueMicrotask(function, JSValue(bitwise_cast<double>(reinterpret_cast<uintptr_t>(ptr))), JSValue(bitwise_cast<double>(reinterpret_cast<uintptr_t>(callback))), jsUndefined(), jsUndefined());
}
-JSC::Identifier GlobalObject::moduleLoaderResolve(JSGlobalObject* globalObject,
+JSC::Identifier GlobalObject::moduleLoaderResolve(JSGlobalObject* jsGlobalObject,
JSModuleLoader* loader, JSValue key,
JSValue referrer, JSValue origin)
{
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(jsGlobalObject);
+
ErrorableString res;
res.success = false;
- BunString keyZ = Bun::toString(globalObject, key);
- BunString referrerZ = referrer && !referrer.isUndefinedOrNull() && referrer.isString() ? Bun::toString(globalObject, referrer) : BunStringEmpty;
+
+ if (key.isString()) {
+ if (auto* virtualModules = globalObject->onLoadPlugins.virtualModules) {
+ auto keyString = key.toWTFString(globalObject);
+ if (virtualModules->contains(keyString)) {
+ return JSC::Identifier::fromString(globalObject->vm(), keyString);
+ }
+ }
+ }
+
+ BunString keyZ;
+ if (key.isString()) {
+ auto moduleName = jsCast<JSString*>(key)->value(globalObject);
+ if (moduleName.startsWith("file://"_s)) {
+ auto url = WTF::URL(moduleName);
+ if (url.isValid() && !url.isEmpty()) {
+ keyZ = Bun::toStringRef(url.fileSystemPath());
+ } else {
+ keyZ = Bun::toStringRef(moduleName);
+ }
+ } else {
+ keyZ = Bun::toStringRef(moduleName);
+ }
+ } else {
+ keyZ = Bun::toStringRef(globalObject, key);
+ }
+ BunString referrerZ = referrer && !referrer.isUndefinedOrNull() && referrer.isString() ? Bun::toStringRef(globalObject, referrer) : BunStringEmpty;
ZigString queryString = { 0, 0 };
Zig__GlobalObject__resolve(&res, globalObject, &keyZ, &referrerZ, &queryString);
+ keyZ.deref();
+ referrerZ.deref();
if (res.success) {
if (queryString.len > 0) {
@@ -4375,25 +4127,60 @@ JSC::Identifier GlobalObject::moduleLoaderResolve(JSGlobalObject* globalObject,
}
}
-JSC::JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* globalObject,
+JSC::JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* jsGlobalObject,
JSModuleLoader*,
JSString* moduleNameValue,
JSValue parameters,
const SourceOrigin& sourceOrigin)
{
+ auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(jsGlobalObject);
JSC::VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
auto* promise = JSC::JSInternalPromise::create(vm, globalObject->internalPromiseStructure());
RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope));
+ if (auto* virtualModules = globalObject->onLoadPlugins.virtualModules) {
+ auto keyString = moduleNameValue->value(globalObject);
+ if (virtualModules->contains(keyString)) {
+ auto resolvedIdentifier = JSC::Identifier::fromString(vm, keyString);
+
+ auto result = JSC::importModule(globalObject, resolvedIdentifier,
+ JSC::jsUndefined(), parameters, JSC::jsUndefined());
+
+ RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope));
+ return result;
+ }
+ }
+
auto sourceURL = sourceOrigin.url();
ErrorableString resolved;
- auto moduleNameZ = Bun::toString(globalObject, moduleNameValue);
- auto sourceOriginZ = sourceURL.isEmpty() ? BunStringCwd : Bun::toString(sourceURL.fileSystemPath());
+ BunString moduleNameZ;
+
+ auto moduleName = moduleNameValue->value(globalObject);
+#if BUN_DEBUG
+ auto startRefCount = moduleName.impl()->refCount();
+#endif
+ if (moduleName.startsWith("file://"_s)) {
+ auto url = WTF::URL(moduleName);
+ if (url.isValid() && !url.isEmpty()) {
+ moduleNameZ = Bun::toStringRef(url.fileSystemPath());
+ } else {
+ moduleNameZ = Bun::toStringRef(moduleName);
+ }
+ } else {
+ moduleNameZ = Bun::toStringRef(moduleName);
+ }
+ auto sourceOriginZ = sourceURL.isEmpty() ? BunStringCwd : Bun::toStringRef(sourceURL.fileSystemPath());
ZigString queryString = { 0, 0 };
resolved.success = false;
Zig__GlobalObject__resolve(&resolved, globalObject, &moduleNameZ, &sourceOriginZ, &queryString);
+ moduleNameZ.deref();
+ sourceOriginZ.deref();
+#if BUN_DEBUG
+ // TODO: ASSERT doesnt work right now
+ RELEASE_ASSERT(startRefCount == moduleName.impl()->refCount());
+#endif
if (!resolved.success) {
throwException(scope, resolved.result.err, globalObject);
return promise->rejectWithCaughtException(globalObject, scope);
@@ -4549,5 +4336,9 @@ GlobalObject::PromiseFunctions GlobalObject::promiseHandlerID(EncodedJSValue (*h
}
#include "ZigGeneratedClasses+lazyStructureImpl.h"
+#include "ZigGlobalObject.lut.h"
+
+const JSC::ClassInfo GlobalObject::s_info = { "GlobalObject"_s, &Base::s_info, &bunGlobalObjectTable, nullptr,
+ CREATE_METHOD_TABLE(GlobalObject) };
} // namespace Zig
diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h
index 29c1cd09c..19630d4b7 100644
--- a/src/bun.js/bindings/ZigGlobalObject.h
+++ b/src/bun.js/bindings/ZigGlobalObject.h
@@ -13,21 +13,22 @@ namespace JSC {
class Structure;
class Identifier;
class LazyClassStructure;
-
-} // namespace JSC
-
-namespace JSC {
-
enum class JSPromiseRejectionOperation : unsigned;
-
-}
+} // namespace JSC
namespace WebCore {
class ScriptExecutionContext;
class DOMGuardedObject;
class EventLoopTask;
class DOMWrapperWorld;
-}
+class GlobalScope;
+class SubtleCrypto;
+class EventTarget;
+} // namespace WebCore
+
+namespace Bun {
+class InternalModuleRegistry;
+} // namespace Bun
#include "root.h"
@@ -43,37 +44,9 @@ class DOMWrapperWorld;
#include "BunPlugin.h"
#include "JSMockFunction.h"
#include "InternalModuleRegistry.h"
-#include "ProcessBindingConstants.h"
-
-namespace WebCore {
-class GlobalScope;
-class SubtleCrypto;
-class EventTarget;
-}
extern "C" void Bun__reportError(JSC__JSGlobalObject*, JSC__JSValue);
extern "C" void Bun__reportUnhandledError(JSC__JSGlobalObject*, JSC::EncodedJSValue);
-// defined in ModuleLoader.cpp
-extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultResolve(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame);
-extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultReject(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame);
-
-// #include "EventTarget.h"
-
-// namespace WebCore {
-// class GlobalEventTarget : public EventTargetWithInlineData, public ContextDestructionObserver {
-// WTF_MAKE_ISO_ALLOCATED(GlobalEventTarget);
-
-// public:
-// static Ref<GlobalEventTarget> create(ScriptExecutionContext&);
-
-// EventTargetInterface eventTargetInterface() const final { return DOMWindowEventTargetInterfaceType; }
-// ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
-// void refEventTarget() final {}
-// void derefEventTarget() final {}
-// void eventListenersDidChange() final;
-// };
-
-// }
namespace Zig {
@@ -179,27 +152,17 @@ public:
void clearDOMGuardedObjects();
- static void createCallSitesFromFrames(JSC::JSGlobalObject* lexicalGlobalObject, JSCStackTrace& stackTrace, JSC::JSArray* callSites);
- JSC::JSValue formatStackTrace(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSObject* errorObject, JSC::JSArray* callSites);
+ static void createCallSitesFromFrames(Zig::GlobalObject* globalObject, JSC::JSGlobalObject* lexicalGlobalObject, JSCStackTrace& stackTrace, JSC::JSArray* callSites);
+ void formatStackTrace(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSObject* errorObject, JSC::JSArray* callSites, JSValue prepareStack = JSC::jsUndefined());
static void reportUncaughtExceptionAtEventLoop(JSGlobalObject*, JSC::Exception*);
static JSGlobalObject* deriveShadowRealmGlobalObject(JSGlobalObject* globalObject);
- static JSC::JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, JSC::JSModuleLoader*,
- JSC::JSString* moduleNameValue,
- JSC::JSValue parameters,
- const JSC::SourceOrigin&);
- static JSC::Identifier moduleLoaderResolve(JSGlobalObject*, JSC::JSModuleLoader*,
- JSC::JSValue keyValue, JSC::JSValue referrerValue,
- JSC::JSValue);
- static JSC::JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, JSC::JSModuleLoader*,
- JSC::JSValue, JSC::JSValue, JSC::JSValue);
- static JSC::JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*,
- JSC::JSModuleLoader*, JSC::JSValue,
- JSC::JSModuleRecord*, JSC::JSValue);
- static JSC::JSValue moduleLoaderEvaluate(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue,
- JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::JSValue);
- static void promiseRejectionTracker(JSGlobalObject*, JSC::JSPromise*,
- JSC::JSPromiseRejectionOperation);
+ static JSC::JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSString* moduleNameValue, JSC::JSValue parameters, const JSC::SourceOrigin&);
+ static JSC::Identifier moduleLoaderResolve(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue keyValue, JSC::JSValue referrerValue, JSC::JSValue);
+ static JSC::JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSValue, JSC::JSValue);
+ static JSC::JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSModuleRecord*, JSC::JSValue);
+ static JSC::JSValue moduleLoaderEvaluate(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::JSValue);
+ static void promiseRejectionTracker(JSGlobalObject*, JSC::JSPromise*, JSC::JSPromiseRejectionOperation);
void setConsole(void* console);
WebCore::JSBuiltinInternalFunctions& builtinInternalFunctions() { return m_builtinInternalFunctions; }
JSC::Structure* FFIFunctionStructure() { return m_JSFFIFunctionStructure.getInitializedOnMainThread(this); }
@@ -215,6 +178,8 @@ public:
JSC::JSValue JSBufferPrototype() { return m_JSBufferClassStructure.prototypeInitializedOnMainThread(this); }
JSC::Structure* JSBufferSubclassStructure() { return m_JSBufferSubclassStructure.getInitializedOnMainThread(this); }
+ JSC::Structure* JSCryptoKeyStructure() { return m_JSCryptoKey.getInitializedOnMainThread(this); }
+
JSC::Structure* ArrayBufferSinkStructure() { return m_JSArrayBufferSinkClassStructure.getInitializedOnMainThread(this); }
JSC::JSObject* ArrayBufferSink() { return m_JSArrayBufferSinkClassStructure.constructorInitializedOnMainThread(this); }
JSC::JSValue ArrayBufferSinkPrototype() { return m_JSArrayBufferSinkClassStructure.prototypeInitializedOnMainThread(this); }
@@ -266,7 +231,8 @@ public:
JSObject* requireFunctionUnbound() { return m_requireFunctionUnbound.getInitializedOnMainThread(this); }
JSObject* requireResolveFunctionUnbound() { return m_requireResolveFunctionUnbound.getInitializedOnMainThread(this); }
Bun::InternalModuleRegistry* internalModuleRegistry() { return m_internalModuleRegistry.getInitializedOnMainThread(this); }
- Bun::ProcessBindingConstants* processBindingConstants() { return m_processBindingConstants.getInitializedOnMainThread(this); }
+
+ JSObject* processBindingConstants() { return m_processBindingConstants.getInitializedOnMainThread(this); }
JSObject* lazyRequireCacheObject() { return m_lazyRequireCacheObject.getInitializedOnMainThread(this); }
@@ -281,36 +247,28 @@ public:
Structure* AsyncContextFrameStructure() { return m_asyncBoundFunctionStructure.getInitializedOnMainThread(this); }
Structure* commonJSFunctionArgumentsStructure() { return m_commonJSFunctionArgumentsStructure.getInitializedOnMainThread(this); }
+ Structure* JSSocketAddressStructure() { return m_JSSocketAddressStructure.getInitializedOnMainThread(this); }
JSWeakMap* vmModuleContextMap() { return m_vmModuleContextMap.getInitializedOnMainThread(this); }
bool hasProcessObject() const { return m_processObject.isInitialized(); }
- JSC::JSObject* processObject()
- {
- return m_processObject.getInitializedOnMainThread(this);
- }
-
- JSC::JSObject* processEnvObject()
- {
- return m_processEnvObject.getInitializedOnMainThread(this);
- }
+ JSC::JSObject* processObject() { return m_processObject.getInitializedOnMainThread(this); }
+ JSC::JSObject* processEnvObject() { return m_processEnvObject.getInitializedOnMainThread(this); }
+ JSC::JSObject* bunObject() { return m_bunObject.getInitializedOnMainThread(this); }
void drainMicrotasks();
void handleRejectedPromises();
- void initGeneratedLazyClasses();
+ ALWAYS_INLINE void initGeneratedLazyClasses();
template<typename Visitor>
void visitGeneratedLazyClasses(GlobalObject*, Visitor&);
- void* bunVM() { return m_bunVM; }
+ ALWAYS_INLINE void* bunVM() { return m_bunVM; }
bool isThreadLocalDefaultGlobalObject = false;
- JSObject* subtleCrypto()
- {
- return m_subtleCryptoObject.getInitializedOnMainThread(this);
- }
+ JSObject* subtleCrypto() { return m_subtleCryptoObject.getInitializedOnMainThread(this); }
EncodedJSValue assignToStream(JSValue stream, JSValue controller);
@@ -377,6 +335,7 @@ public:
* For example, if you don't add the queueMicrotask functions to visitChildrenImpl(),
* those callbacks will eventually never be called anymore. But it'll work the first time!
*/
+ // TODO: these should use LazyProperty
mutable WriteBarrier<JSFunction> m_assignToStream;
mutable WriteBarrier<JSFunction> m_readableStreamToArrayBuffer;
mutable WriteBarrier<JSFunction> m_readableStreamToArrayBufferResolve;
@@ -390,28 +349,14 @@ public:
mutable WriteBarrier<JSFunction> m_nodeModuleOverriddenResolveFilename;
mutable WriteBarrier<Unknown> m_nextTickQueue;
+ // Value of $_BunCommonJSModule_$
mutable WriteBarrier<Unknown> m_BunCommonJSModuleValue;
- mutable WriteBarrier<Unknown> m_JSBroadcastChannelSetterValue;
- mutable WriteBarrier<Unknown> m_JSBufferSetterValue;
- mutable WriteBarrier<Unknown> m_JSCloseEventSetterValue;
- mutable WriteBarrier<Unknown> m_JSCustomEventSetterValue;
- mutable WriteBarrier<Unknown> m_JSDOMExceptionSetterValue;
- mutable WriteBarrier<Unknown> m_JSDOMFormDataSetterValue;
- mutable WriteBarrier<Unknown> m_JSErrorEventSetterValue;
- mutable WriteBarrier<Unknown> m_JSEventSetterValue;
- mutable WriteBarrier<Unknown> m_JSEventTargetSetterValue;
- mutable WriteBarrier<Unknown> m_JSFetchHeadersSetterValue;
- mutable WriteBarrier<Unknown> m_JSMessageChannelSetterValue;
- mutable WriteBarrier<Unknown> m_JSMessageEventSetterValue;
- mutable WriteBarrier<Unknown> m_JSMessagePortSetterValue;
- mutable WriteBarrier<Unknown> m_JSTextEncoderSetterValue;
- mutable WriteBarrier<Unknown> m_JSURLSearchParamsSetterValue;
- mutable WriteBarrier<Unknown> m_JSWebSocketSetterValue;
- mutable WriteBarrier<Unknown> m_JSWorkerSetterValue;
-
- mutable WriteBarrier<Unknown> m_JSBunDebuggerValue;
+
+ // mutable WriteBarrier<Unknown> m_JSBunDebuggerValue;
mutable WriteBarrier<JSFunction> m_thenables[promiseFunctionsSize + 1];
+ mutable WriteBarrier<JSC::Unknown> m_errorConstructorPrepareStackTraceValue;
+
Structure* memoryFootprintStructure()
{
return m_memoryFootprintStructure.getInitializedOnMainThread(this);
@@ -439,9 +384,8 @@ public:
return false;
}
- BunPlugin::OnLoad onLoadPlugins[BunPluginTargetMax + 1] {};
- BunPlugin::OnResolve onResolvePlugins[BunPluginTargetMax + 1] {};
- BunPluginTarget defaultBunPluginTarget = BunPluginTargetBun;
+ BunPlugin::OnLoad onLoadPlugins {};
+ BunPlugin::OnResolve onResolvePlugins {};
// This increases the cache hit rate for JSC::VM's SourceProvider cache
// It also avoids an extra allocation for the SourceProvider
@@ -478,6 +422,7 @@ public:
private:
void addBuiltinGlobals(JSC::VM&);
+
void finishCreation(JSC::VM&);
friend void WebCore::JSBuiltinInternalFunctions::initialize(Zig::GlobalObject&);
WebCore::JSBuiltinInternalFunctions m_builtinInternalFunctions;
@@ -490,6 +435,9 @@ private:
WebCore::ScriptExecutionContext* m_scriptExecutionContext;
Ref<WebCore::DOMWrapperWorld> m_world;
+ // JSC's hashtable code-generator tries to access these properties, so we make them public.
+ // However, we'd like it better if they could be protected.
+public:
/**
* WARNING: You must update visitChildrenImpl() if you add a new field.
*
@@ -523,7 +471,7 @@ private:
* For example, if you don't add the queueMicrotask functions to visitChildrenImpl(),
* those callbacks will eventually never be called anymore. But it'll work the first time!
*/
- LazyProperty<JSGlobalObject, JSC::Structure> m_pendingVirtualModuleResultStructure;
+ LazyProperty<JSGlobalObject, Structure> m_pendingVirtualModuleResultStructure;
LazyProperty<JSGlobalObject, JSFunction> m_performMicrotaskFunction;
LazyProperty<JSGlobalObject, JSFunction> m_nativeMicrotaskTrampoline;
LazyProperty<JSGlobalObject, JSFunction> m_performMicrotaskVariadicFunction;
@@ -537,38 +485,40 @@ private:
LazyProperty<JSGlobalObject, JSObject> m_JSArrayBufferControllerPrototype;
LazyProperty<JSGlobalObject, JSObject> m_JSFileSinkControllerPrototype;
LazyProperty<JSGlobalObject, JSObject> m_JSHTTPSResponseControllerPrototype;
- LazyProperty<JSGlobalObject, JSObject> m_navigatorObject;
- LazyProperty<JSGlobalObject, JSObject> m_performanceObject;
- LazyProperty<JSGlobalObject, JSObject> m_processObject;
LazyProperty<JSGlobalObject, JSObject> m_subtleCryptoObject;
LazyProperty<JSGlobalObject, Structure> m_JSHTTPResponseController;
- LazyProperty<JSGlobalObject, JSC::Structure> m_JSBufferSubclassStructure;
+ LazyProperty<JSGlobalObject, Structure> m_JSBufferSubclassStructure;
LazyProperty<JSGlobalObject, JSWeakMap> m_vmModuleContextMap;
LazyProperty<JSGlobalObject, JSObject> m_lazyRequireCacheObject;
LazyProperty<JSGlobalObject, JSObject> m_lazyTestModuleObject;
LazyProperty<JSGlobalObject, JSObject> m_lazyPreloadTestModuleObject;
-
LazyProperty<JSGlobalObject, JSFunction> m_bunSleepThenCallback;
LazyProperty<JSGlobalObject, Structure> m_cachedGlobalObjectStructure;
LazyProperty<JSGlobalObject, Structure> m_cachedGlobalProxyStructure;
LazyProperty<JSGlobalObject, Structure> m_commonJSModuleObjectStructure;
LazyProperty<JSGlobalObject, Structure> m_commonJSFunctionArgumentsStructure;
+ LazyProperty<JSGlobalObject, Structure> m_JSSocketAddressStructure;
LazyProperty<JSGlobalObject, Structure> m_memoryFootprintStructure;
- LazyProperty<JSGlobalObject, JSObject> m_cryptoObject;
-
- LazyProperty<JSGlobalObject, JSC::JSObject> m_requireFunctionUnbound;
- LazyProperty<JSGlobalObject, JSC::JSObject> m_requireResolveFunctionUnbound;
+ LazyProperty<JSGlobalObject, JSObject> m_requireFunctionUnbound;
+ LazyProperty<JSGlobalObject, JSObject> m_requireResolveFunctionUnbound;
LazyProperty<JSGlobalObject, Bun::InternalModuleRegistry> m_internalModuleRegistry;
- LazyProperty<JSGlobalObject, Bun::ProcessBindingConstants> m_processBindingConstants;
- LazyProperty<JSGlobalObject, JSC::Structure> m_importMetaObjectStructure;
- LazyProperty<JSGlobalObject, JSC::Structure> m_asyncBoundFunctionStructure;
-
+ LazyProperty<JSGlobalObject, JSObject> m_processBindingConstants;
+ LazyProperty<JSGlobalObject, Structure> m_importMetaObjectStructure;
+ LazyProperty<JSGlobalObject, Structure> m_asyncBoundFunctionStructure;
LazyProperty<JSGlobalObject, JSC::JSObject> m_JSDOMFileConstructor;
+ LazyProperty<JSGlobalObject, Structure> m_JSCryptoKey;
+ LazyProperty<JSGlobalObject, JSObject> m_bunObject;
+ LazyProperty<JSGlobalObject, JSObject> m_cryptoObject;
+ LazyProperty<JSGlobalObject, JSObject> m_navigatorObject;
+ LazyProperty<JSGlobalObject, JSObject> m_performanceObject;
+ LazyProperty<JSGlobalObject, JSObject> m_processObject;
+
+private:
DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock);
void* m_bunVM;
- WebCore::SubtleCrypto* crypto = nullptr;
+ WebCore::SubtleCrypto* m_subtleCrypto = nullptr;
WTF::Vector<JSC::Strong<JSC::JSPromise>> m_aboutToBeNotifiedRejectedPromises;
WTF::Vector<JSC::Strong<JSC::JSFunction>> m_ffiFunctions;
diff --git a/src/bun.js/bindings/ZigGlobalObject.lut.h b/src/bun.js/bindings/ZigGlobalObject.lut.h
new file mode 100644
index 000000000..6516648e8
--- /dev/null
+++ b/src/bun.js/bindings/ZigGlobalObject.lut.h
@@ -0,0 +1,341 @@
+// File generated via `make static-hash-table` / `make cpp`
+static const struct CompactHashIndex bunGlobalObjectTableIndex[260] = {
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 42, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 6, -1 },
+ { 3, -1 },
+ { -1, -1 },
+ { 34, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 29, 258 },
+ { -1, -1 },
+ { -1, -1 },
+ { 54, 257 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 51, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 2, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 18, -1 },
+ { 56, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 14, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 41, -1 },
+ { 47, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 69, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 39, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 38, -1 },
+ { 63, -1 },
+ { -1, -1 },
+ { 57, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 49, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 58, -1 },
+ { 11, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 0, -1 },
+ { -1, -1 },
+ { 37, -1 },
+ { 21, -1 },
+ { 66, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 70, -1 },
+ { -1, -1 },
+ { 45, -1 },
+ { -1, -1 },
+ { 48, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 24, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 33, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 50, -1 },
+ { 46, -1 },
+ { -1, -1 },
+ { 13, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 43, -1 },
+ { -1, -1 },
+ { 1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 32, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 28, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 26, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 17, -1 },
+ { -1, -1 },
+ { 31, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 35, -1 },
+ { 71, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 22, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 4, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 23, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 55, -1 },
+ { -1, -1 },
+ { 53, -1 },
+ { -1, -1 },
+ { 12, -1 },
+ { 25, -1 },
+ { 7, -1 },
+ { -1, -1 },
+ { 9, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 61, -1 },
+ { 60, -1 },
+ { -1, -1 },
+ { 5, 256 },
+ { -1, -1 },
+ { 64, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 36, -1 },
+ { -1, -1 },
+ { 15, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 40, 259 },
+ { -1, -1 },
+ { -1, -1 },
+ { 68, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 52, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 30, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 27, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 44, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 65, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 20, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 10, -1 },
+ { 16, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { -1, -1 },
+ { 19, -1 },
+ { -1, -1 },
+ { 8, -1 },
+ { 59, -1 },
+ { 62, -1 },
+ { 67, -1 },
+};
+
+static const struct HashTableValue bunGlobalObjectTableValues[72] = {
+ { "addEventListener"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsFunctionAddEventListener, 2 } },
+ { "alert"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, WebCore__alert, 1 } },
+ { "atob"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionATOB, 1 } },
+ { "btoa"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionBTOA, 1 } },
+ { "clearImmediate"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionClearTimeout, 1 } },
+ { "clearInterval"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionClearInterval, 1 } },
+ { "clearTimeout"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionClearTimeout, 1 } },
+ { "confirm"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, WebCore__confirm, 1 } },
+ { "dispatchEvent"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsFunctionDispatchEvent, 1 } },
+ { "fetch"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Bun__fetch, 2 } },
+ { "postMessage"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsFunctionPostMessage, 1 } },
+ { "prompt"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, WebCore__prompt, 1 } },
+ { "queueMicrotask"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionQueueMicrotask, 2 } },
+ { "removeEventListener"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsFunctionRemoveEventListener, 2 } },
+ { "reportError"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionReportError, 1 } },
+ { "setImmediate"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionSetImmediate, 1 } },
+ { "setInterval"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionSetInterval, 1 } },
+ { "setTimeout"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionSetTimeout, 1 } },
+ { "structuredClone"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionStructuredClone, 2 } },
+ { "global"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, GlobalObject_getGlobalThis } },
+ { "EventSource"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, getEventSourceConstructor } },
+ { "Bun"_s, static_cast<unsigned>(PropertyAttribute::CellProperty|PropertyAttribute::DontDelete|PropertyAttribute::ReadOnly), NoIntrinsic, { HashTableValue::LazyCellPropertyType, OBJECT_OFFSETOF(GlobalObject, m_bunObject) } },
+ { "File"_s, static_cast<unsigned>(PropertyAttribute::CellProperty), NoIntrinsic, { HashTableValue::LazyCellPropertyType, OBJECT_OFFSETOF(GlobalObject, m_JSDOMFileConstructor) } },
+ { "crypto"_s, static_cast<unsigned>(PropertyAttribute::CellProperty), NoIntrinsic, { HashTableValue::LazyCellPropertyType, OBJECT_OFFSETOF(GlobalObject, m_cryptoObject) } },
+ { "navigator"_s, static_cast<unsigned>(PropertyAttribute::CellProperty), NoIntrinsic, { HashTableValue::LazyCellPropertyType, OBJECT_OFFSETOF(GlobalObject, m_navigatorObject) } },
+ { "performance"_s, static_cast<unsigned>(PropertyAttribute::CellProperty), NoIntrinsic, { HashTableValue::LazyCellPropertyType, OBJECT_OFFSETOF(GlobalObject, m_performanceObject) } },
+ { "process"_s, static_cast<unsigned>(PropertyAttribute::CellProperty), NoIntrinsic, { HashTableValue::LazyCellPropertyType, OBJECT_OFFSETOF(GlobalObject, m_processObject) } },
+ { "Blob"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSBlob) } },
+ { "Buffer"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSBufferClassStructure) } },
+ { "BuildError"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSBuildMessage) } },
+ { "BuildMessage"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSBuildMessage) } },
+ { "Crypto"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSCrypto) } },
+ { "HTMLRewriter"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSHTMLRewriter) } },
+ { "Request"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSRequest) } },
+ { "ResolveError"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSResolveMessage) } },
+ { "ResolveMessage"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSResolveMessage) } },
+ { "Response"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSResponse) } },
+ { "TextDecoder"_s, static_cast<unsigned>(PropertyAttribute::ClassStructure), NoIntrinsic, { HashTableValue::LazyClassStructureType, OBJECT_OFFSETOF(GlobalObject, m_JSTextDecoder) } },
+ { "AbortController"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, AbortControllerConstructorCallback } },
+ { "AbortSignal"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, AbortSignalConstructorCallback } },
+ { "BroadcastChannel"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, BroadcastChannelConstructorCallback } },
+ { "ByteLengthQueuingStrategy"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, ByteLengthQueuingStrategyConstructorCallback } },
+ { "CloseEvent"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, CloseEventConstructorCallback } },
+ { "CountQueuingStrategy"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, CountQueuingStrategyConstructorCallback } },
+ { "CryptoKey"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, CryptoKeyConstructorCallback } },
+ { "CustomEvent"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, CustomEventConstructorCallback } },
+ { "DOMException"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, DOMExceptionConstructorCallback } },
+ { "ErrorEvent"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, ErrorEventConstructorCallback } },
+ { "Event"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, EventConstructorCallback } },
+ { "EventTarget"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, EventTargetConstructorCallback } },
+ { "FormData"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, DOMFormDataConstructorCallback } },
+ { "Headers"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, FetchHeadersConstructorCallback } },
+ { "MessageChannel"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, MessageChannelConstructorCallback } },
+ { "MessageEvent"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, MessageEventConstructorCallback } },
+ { "MessagePort"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, MessagePortConstructorCallback } },
+ { "ReadableByteStreamController"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, ReadableByteStreamControllerConstructorCallback } },
+ { "ReadableStream"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, ReadableStreamConstructorCallback } },
+ { "ReadableStreamBYOBReader"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, ReadableStreamBYOBReaderConstructorCallback } },
+ { "ReadableStreamBYOBRequest"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, ReadableStreamBYOBRequestConstructorCallback } },
+ { "ReadableStreamDefaultController"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, ReadableStreamDefaultControllerConstructorCallback } },
+ { "ReadableStreamDefaultReader"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, ReadableStreamDefaultReaderConstructorCallback } },
+ { "SubtleCrypto"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, SubtleCryptoConstructorCallback } },
+ { "TextEncoder"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, TextEncoderConstructorCallback } },
+ { "TransformStream"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, TransformStreamConstructorCallback } },
+ { "URL"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, DOMURLConstructorCallback } },
+ { "URLSearchParams"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, URLSearchParamsConstructorCallback } },
+ { "WebSocket"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, WebSocketConstructorCallback } },
+ { "Worker"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, WorkerConstructorCallback } },
+ { "WritableStream"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, WritableStreamConstructorCallback } },
+ { "WritableStreamDefaultController"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, WritableStreamDefaultControllerConstructorCallback } },
+ { "WritableStreamDefaultWriter"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, WritableStreamDefaultWriterConstructorCallback } },
+ { "TransformStreamDefaultController"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, TransformStreamDefaultControllerConstructorCallback } },
+};
+
+static const struct HashTable bunGlobalObjectTable =
+ { 72, 255, false, nullptr, bunGlobalObjectTableValues, bunGlobalObjectTableIndex };
diff --git a/src/bun.js/bindings/ZigGlobalObject.lut.txt b/src/bun.js/bindings/ZigGlobalObject.lut.txt
new file mode 100644
index 000000000..aadaee92a
--- /dev/null
+++ b/src/bun.js/bindings/ZigGlobalObject.lut.txt
@@ -0,0 +1,82 @@
+// In a separate file because processing ZigGlobalObject.cpp takes 15+ seconds
+
+/* Source for ZigGlobalObject.lut.h
+@begin bunGlobalObjectTable
+ addEventListener jsFunctionAddEventListener Function 2
+ alert WebCore__alert Function 1
+ atob functionATOB Function 1
+ btoa functionBTOA Function 1
+ clearImmediate functionClearTimeout Function 1
+ clearInterval functionClearInterval Function 1
+ clearTimeout functionClearTimeout Function 1
+ confirm WebCore__confirm Function 1
+ dispatchEvent jsFunctionDispatchEvent Function 1
+ fetch Bun__fetch Function 2
+ postMessage jsFunctionPostMessage Function 1
+ prompt WebCore__prompt Function 1
+ queueMicrotask functionQueueMicrotask Function 2
+ removeEventListener jsFunctionRemoveEventListener Function 2
+ reportError functionReportError Function 1
+ setImmediate functionSetImmediate Function 1
+ setInterval functionSetInterval Function 1
+ setTimeout functionSetTimeout Function 1
+ structuredClone functionStructuredClone Function 2
+
+ global GlobalObject_getGlobalThis PropertyCallback
+ EventSource getEventSourceConstructor PropertyCallback
+
+ Bun GlobalObject::m_bunObject CellProperty|DontDelete|ReadOnly
+ File GlobalObject::m_JSDOMFileConstructor CellProperty
+ crypto GlobalObject::m_cryptoObject CellProperty
+ navigator GlobalObject::m_navigatorObject CellProperty
+ performance GlobalObject::m_performanceObject CellProperty
+ process GlobalObject::m_processObject CellProperty
+
+ Blob GlobalObject::m_JSBlob ClassStructure
+ Buffer GlobalObject::m_JSBufferClassStructure ClassStructure
+ BuildError GlobalObject::m_JSBuildMessage ClassStructure
+ BuildMessage GlobalObject::m_JSBuildMessage ClassStructure
+ Crypto GlobalObject::m_JSCrypto ClassStructure
+ HTMLRewriter GlobalObject::m_JSHTMLRewriter ClassStructure
+ Request GlobalObject::m_JSRequest ClassStructure
+ ResolveError GlobalObject::m_JSResolveMessage ClassStructure
+ ResolveMessage GlobalObject::m_JSResolveMessage ClassStructure
+ Response GlobalObject::m_JSResponse ClassStructure
+ TextDecoder GlobalObject::m_JSTextDecoder ClassStructure
+
+ AbortController AbortControllerConstructorCallback PropertyCallback
+ AbortSignal AbortSignalConstructorCallback PropertyCallback
+ BroadcastChannel BroadcastChannelConstructorCallback PropertyCallback
+ ByteLengthQueuingStrategy ByteLengthQueuingStrategyConstructorCallback PropertyCallback
+ CloseEvent CloseEventConstructorCallback PropertyCallback
+ CountQueuingStrategy CountQueuingStrategyConstructorCallback PropertyCallback
+ CryptoKey CryptoKeyConstructorCallback PropertyCallback
+ CustomEvent CustomEventConstructorCallback PropertyCallback
+ DOMException DOMExceptionConstructorCallback PropertyCallback
+ ErrorEvent ErrorEventConstructorCallback PropertyCallback
+ Event EventConstructorCallback PropertyCallback
+ EventTarget EventTargetConstructorCallback PropertyCallback
+ FormData DOMFormDataConstructorCallback PropertyCallback
+ Headers FetchHeadersConstructorCallback PropertyCallback
+ MessageChannel MessageChannelConstructorCallback PropertyCallback
+ MessageEvent MessageEventConstructorCallback PropertyCallback
+ MessagePort MessagePortConstructorCallback PropertyCallback
+ ReadableByteStreamController ReadableByteStreamControllerConstructorCallback PropertyCallback
+ ReadableStream ReadableStreamConstructorCallback PropertyCallback
+ ReadableStreamBYOBReader ReadableStreamBYOBReaderConstructorCallback PropertyCallback
+ ReadableStreamBYOBRequest ReadableStreamBYOBRequestConstructorCallback PropertyCallback
+ ReadableStreamDefaultController ReadableStreamDefaultControllerConstructorCallback PropertyCallback
+ ReadableStreamDefaultReader ReadableStreamDefaultReaderConstructorCallback PropertyCallback
+ SubtleCrypto SubtleCryptoConstructorCallback PropertyCallback
+ TextEncoder TextEncoderConstructorCallback PropertyCallback
+ TransformStream TransformStreamConstructorCallback PropertyCallback
+ URL DOMURLConstructorCallback PropertyCallback
+ URLSearchParams URLSearchParamsConstructorCallback PropertyCallback
+ WebSocket WebSocketConstructorCallback PropertyCallback
+ Worker WorkerConstructorCallback PropertyCallback
+ WritableStream WritableStreamConstructorCallback PropertyCallback
+ WritableStreamDefaultController WritableStreamDefaultControllerConstructorCallback PropertyCallback
+ WritableStreamDefaultWriter WritableStreamDefaultWriterConstructorCallback PropertyCallback
+ TransformStreamDefaultController TransformStreamDefaultControllerConstructorCallback PropertyCallback
+@end
+*/
diff --git a/src/bun.js/bindings/ZigLazyStaticFunctions-inlines.h b/src/bun.js/bindings/ZigLazyStaticFunctions-inlines.h
index c97393723..0c13ecd58 100644
--- a/src/bun.js/bindings/ZigLazyStaticFunctions-inlines.h
+++ b/src/bun.js/bindings/ZigLazyStaticFunctions-inlines.h
@@ -25,7 +25,7 @@ static void DOMCall__FFI__ptr__put(JSC::JSGlobalObject* globalObject, JSC::Encod
globalObject->vm(),
Identifier::fromString(globalObject->vm(), "ptr"_s),
function,
- JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | 0);
+ 0);
}
/* -- END DOMCall DEFINITIONS-- */
diff --git a/src/bun.js/bindings/ZigSourceProvider.cpp b/src/bun.js/bindings/ZigSourceProvider.cpp
index d11c748da..960e577b9 100644
--- a/src/bun.js/bindings/ZigSourceProvider.cpp
+++ b/src/bun.js/bindings/ZigSourceProvider.cpp
@@ -104,6 +104,7 @@ Ref<SourceProvider> SourceProvider::create(Zig::GlobalObject* globalObject, Reso
auto provider = adoptRef(*new SourceProvider(
globalObject->isThreadLocalDefaultGlobalObject ? globalObject : nullptr,
resolvedSource, stringImpl.releaseImpl().releaseNonNull(),
+ JSC::SourceTaintedOrigin::Untainted,
toSourceOrigin(sourceURLString, isBuiltin),
sourceURLString.impl(), TextPosition(),
sourceType));
diff --git a/src/bun.js/bindings/ZigSourceProvider.h b/src/bun.js/bindings/ZigSourceProvider.h
index 364e6ee23..b7574c7a4 100644
--- a/src/bun.js/bindings/ZigSourceProvider.h
+++ b/src/bun.js/bindings/ZigSourceProvider.h
@@ -69,9 +69,10 @@ public:
private:
SourceProvider(Zig::GlobalObject* globalObject, ResolvedSource resolvedSource, Ref<WTF::StringImpl>&& sourceImpl,
+ JSC::SourceTaintedOrigin taintedness,
const SourceOrigin& sourceOrigin, WTF::String&& sourceURL,
const TextPosition& startPosition, JSC::SourceProviderSourceType sourceType)
- : Base(sourceOrigin, WTFMove(sourceURL), String(), startPosition, sourceType)
+ : Base(sourceOrigin, WTFMove(sourceURL), String(), taintedness, startPosition, sourceType)
, m_source(sourceImpl)
{
diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp
index e46982aad..117b848ef 100644
--- a/src/bun.js/bindings/bindings.cpp
+++ b/src/bun.js/bindings/bindings.cpp
@@ -19,6 +19,7 @@
#include "JavaScriptCore/JSArray.h"
#include "JavaScriptCore/JSArrayBuffer.h"
#include "JavaScriptCore/JSArrayInlines.h"
+#include "JavaScriptCore/ErrorInstanceInlines.h"
#include "JavaScriptCore/JSCallbackObject.h"
#include "JavaScriptCore/JSClassRef.h"
@@ -229,6 +230,47 @@ AsymmetricMatcherResult matchAsymmetricMatcher(JSGlobalObject* globalObject, JSC
}
return AsymmetricMatcherResult::FAIL;
+ } else if (auto* expectArrayContaining = jsDynamicCast<JSExpectArrayContaining*>(matcherPropCell)) {
+ JSValue expectedArrayValue = expectArrayContaining->m_arrayValue.get();
+
+ if (JSC::isArray(globalObject, otherProp)) {
+ if (JSC::isArray(globalObject, expectedArrayValue)) {
+ JSArray* expectedArray = jsDynamicCast<JSArray*>(expectedArrayValue);
+ JSArray* otherArray = jsDynamicCast<JSArray*>(otherProp);
+
+ unsigned expectedLength = expectedArray->length();
+ unsigned otherLength = otherArray->length();
+
+ // A empty array is all array's subset
+ if (expectedLength == 0) {
+ return AsymmetricMatcherResult::PASS;
+ }
+
+ // O(m*n) but works for now
+ for (unsigned m = 0; m < expectedLength; m++) {
+ JSValue expectedValue = expectedArray->getIndex(globalObject, m);
+ bool found = false;
+
+ for (unsigned n = 0; n < otherLength; n++) {
+ JSValue otherValue = otherArray->getIndex(globalObject, n);
+ ThrowScope scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ Vector<std::pair<JSValue, JSValue>, 16> stack;
+ if (Bun__deepEquals<false, true>(globalObject, expectedValue, otherValue, stack, &scope, true)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ return AsymmetricMatcherResult::FAIL;
+ }
+ }
+
+ return AsymmetricMatcherResult::PASS;
+ }
+ }
+
+ return AsymmetricMatcherResult::FAIL;
}
return AsymmetricMatcherResult::NOT_MATCHER;
@@ -306,10 +348,8 @@ bool Bun__deepEquals(JSC__JSGlobalObject* globalObject, JSValue v1, JSValue v2,
// need to check this before primitives, asymmetric matchers
// can match against any type of value.
if constexpr (enableAsymmetricMatchers) {
- JSCell* c1 = v1.asCell();
- JSCell* c2 = v2.asCell();
- if (v2.isCell() && !v2.isEmpty() && c2->type() == JSC::JSType(JSDOMWrapperType)) {
- switch (matchAsymmetricMatcher(globalObject, c2, v1, scope)) {
+ if (v2.isCell() && !v2.isEmpty() && v2.asCell()->type() == JSC::JSType(JSDOMWrapperType)) {
+ switch (matchAsymmetricMatcher(globalObject, v2.asCell(), v1, scope)) {
case AsymmetricMatcherResult::FAIL:
return false;
case AsymmetricMatcherResult::PASS:
@@ -318,8 +358,8 @@ bool Bun__deepEquals(JSC__JSGlobalObject* globalObject, JSValue v1, JSValue v2,
// continue comparison
break;
}
- } else if (v1.isCell() && !v1.isEmpty() && c1->type() == JSC::JSType(JSDOMWrapperType)) {
- switch (matchAsymmetricMatcher(globalObject, c1, v2, scope)) {
+ } else if (v1.isCell() && !v1.isEmpty() && v1.asCell()->type() == JSC::JSType(JSDOMWrapperType)) {
+ switch (matchAsymmetricMatcher(globalObject, v1.asCell(), v2, scope)) {
case AsymmetricMatcherResult::FAIL:
return false;
case AsymmetricMatcherResult::PASS:
@@ -576,7 +616,7 @@ bool Bun__deepEquals(JSC__JSGlobalObject* globalObject, JSValue v1, JSValue v2,
case Float64ArrayType:
case BigInt64ArrayType:
case BigUint64ArrayType: {
- if (!isTypedArrayType(static_cast<JSC::JSType>(c2Type))) {
+ if (!isTypedArrayType(static_cast<JSC::JSType>(c2Type)) || c1Type != c2Type) {
return false;
}
@@ -627,6 +667,7 @@ bool Bun__deepEquals(JSC__JSGlobalObject* globalObject, JSValue v1, JSValue v2,
case JSDOMWrapperType: {
if (c2Type == JSDOMWrapperType) {
// https://github.com/oven-sh/bun/issues/4089
+ // https://github.com/oven-sh/bun/issues/6492
auto* url2 = jsDynamicCast<JSDOMURL*>(v2);
auto* url1 = jsDynamicCast<JSDOMURL*>(v1);
@@ -635,19 +676,15 @@ bool Bun__deepEquals(JSC__JSGlobalObject* globalObject, JSValue v1, JSValue v2,
if ((url2 == nullptr) != (url1 == nullptr)) {
return false;
}
-
- if (url2 && url1) {
- return url1->wrapped().href() != url2->wrapped().href();
- }
- } else {
- if (url2 && url1) {
- // toEqual should return false when the URLs' href is not equal
- // But you could have added additional properties onto the
- // url object itself, so we must check those as well
- // But it's definitely not equal if the href() is not the same
- if (url1->wrapped().href() != url2->wrapped().href()) {
- return false;
- }
+ }
+
+ if (url2 && url1) {
+ // toEqual or toStrictEqual should return false when the URLs' href is not equal
+ // But you could have added additional properties onto the
+ // url object itself, so we must check those as well
+ // But it's definitely not equal if the href() is not the same
+ if (url1->wrapped().href() != url2->wrapped().href()) {
+ return false;
}
}
}
@@ -1045,7 +1082,9 @@ void WebCore__FetchHeaders__toUWSResponse(WebCore__FetchHeaders* arg0, bool is_s
WebCore__FetchHeaders* WebCore__FetchHeaders__createEmpty()
{
- return new WebCore::FetchHeaders({ WebCore::FetchHeaders::Guard::None, {} });
+ auto* headers = new WebCore::FetchHeaders({ WebCore::FetchHeaders::Guard::None, {} });
+ headers->relaxAdoptionRequirement();
+ return headers;
}
void WebCore__FetchHeaders__append(WebCore__FetchHeaders* headers, const ZigString* arg1, const ZigString* arg2,
JSC__JSGlobalObject* lexicalGlobalObject)
@@ -1074,6 +1113,7 @@ WebCore__FetchHeaders* WebCore__FetchHeaders__createFromJS(JSC__JSGlobalObject*
RETURN_IF_EXCEPTION(throwScope, nullptr);
auto* headers = new WebCore::FetchHeaders({ WebCore::FetchHeaders::Guard::None, {} });
+ headers->relaxAdoptionRequirement();
if (init) {
// `fill` doesn't set an exception on the VM if it fails, it returns an
// ExceptionOr<void>. So we need to check for the exception and, if set,
@@ -1112,6 +1152,7 @@ WebCore__FetchHeaders* WebCore__FetchHeaders__cloneThis(WebCore__FetchHeaders* h
{
auto throwScope = DECLARE_THROW_SCOPE(lexicalGlobalObject->vm());
auto* clone = new WebCore::FetchHeaders({ WebCore::FetchHeaders::Guard::None, {} });
+ clone->relaxAdoptionRequirement();
WebCore::propagateException(*lexicalGlobalObject, throwScope,
clone->fill(*headers));
return clone;
@@ -1181,6 +1222,7 @@ WebCore::FetchHeaders* WebCore__FetchHeaders__createFromPicoHeaders_(const void*
{
PicoHTTPHeaders pico_headers = *reinterpret_cast<const PicoHTTPHeaders*>(arg1);
auto* headers = new WebCore::FetchHeaders({ WebCore::FetchHeaders::Guard::None, {} });
+ headers->relaxAdoptionRequirement(); // This prevents an assertion later, but may not be the proper approach.
if (pico_headers.len > 0) {
HTTPHeaderMap map = HTTPHeaderMap();
@@ -1223,6 +1265,8 @@ WebCore::FetchHeaders* WebCore__FetchHeaders__createFromUWS(JSC__JSGlobalObject*
size_t i = 0;
auto* headers = new WebCore::FetchHeaders({ WebCore::FetchHeaders::Guard::None, {} });
+ headers->relaxAdoptionRequirement(); // This prevents an assertion later, but may not be the proper approach.
+
HTTPHeaderMap map = HTTPHeaderMap();
for (const auto& header : req) {
@@ -1246,7 +1290,6 @@ WebCore::FetchHeaders* WebCore__FetchHeaders__createFromUWS(JSC__JSGlobalObject*
if (i > 56)
__builtin_unreachable();
}
-
headers->setInternalHeaders(WTFMove(map));
return headers;
}
@@ -1354,15 +1397,22 @@ BunString WebCore__DOMURL__fileSystemPath(WebCore__DOMURL* arg0)
extern "C" JSC__JSValue ZigString__toJSONObject(const ZigString* strPtr, JSC::JSGlobalObject* globalObject)
{
auto str = Zig::toString(*strPtr);
- auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
- auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
- JSValue result = JSONParseWithException(globalObject, str);
- if (auto* exception = scope.exception()) {
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+
+ // JSONParseWithException does not propagate exceptions as expected. See #5859
+ JSValue result = JSONParse(globalObject, str);
+
+ if (!result && !scope.exception()) {
+ scope.throwException(globalObject, createSyntaxError(globalObject, "Failed to parse JSON"_s));
+ }
+
+ if (scope.exception()) {
+ auto* exception = scope.exception();
scope.clearException();
- RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(exception->value()));
+ return JSC::JSValue::encode(exception);
}
- RELEASE_AND_RETURN(throwScope, JSValue::encode(result));
+ return JSValue::encode(result);
}
JSC__JSValue SystemError__toErrorInstance(const SystemError* arg0,
@@ -2063,7 +2113,7 @@ JSC__JSValue JSC__JSModuleLoader__evaluate(JSC__JSGlobalObject* globalObject, co
JSC::VM& vm = globalObject->vm();
JSC::SourceCode sourceCode = JSC::makeSource(
- src, JSC::SourceOrigin { origin }, origin.fileSystemPath(),
+ src, JSC::SourceOrigin { origin }, JSC::SourceTaintedOrigin::Untainted, origin.fileSystemPath(),
WTF::TextPosition(), JSC::SourceProviderSourceType::Module);
globalObject->moduleLoader()->provideFetch(globalObject, jsString(vm, origin.fileSystemPath()), WTFMove(sourceCode));
auto* promise = JSC::importModule(globalObject, JSC::Identifier::fromString(vm, origin.fileSystemPath()), JSValue(jsString(vm, referrer.fileSystemPath())), JSValue(), JSValue());
@@ -2116,6 +2166,14 @@ JSC__JSValue ReadableStream__empty(Zig::GlobalObject* globalObject)
return JSValue::encode(JSC::call(globalObject, function, JSC::ArgList(), "ReadableStream.create"_s));
}
+JSC__JSValue ReadableStream__used(Zig::GlobalObject* globalObject)
+{
+ auto& vm = globalObject->vm();
+ auto clientData = WebCore::clientData(vm);
+ auto* function = globalObject->getDirect(vm, clientData->builtinNames().createUsedReadableStreamPrivateName()).getObject();
+ return JSValue::encode(JSC::call(globalObject, function, JSC::ArgList(), "ReadableStream.create"_s));
+}
+
JSC__JSValue JSC__JSValue__createRangeError(const ZigString* message, const ZigString* arg1,
JSC__JSGlobalObject* globalObject)
{
@@ -2303,29 +2361,31 @@ JSC__JSValue JSC__JSValue__createStringArray(JSC__JSGlobalObject* globalObject,
JSC::JSArray* array = nullptr;
{
+ JSC::GCDeferralContext deferralContext(vm);
JSC::ObjectInitializationScope initializationScope(vm);
if ((array = JSC::JSArray::tryCreateUninitializedRestricted(
- initializationScope, nullptr,
+ initializationScope, &deferralContext,
globalObject->arrayStructureForIndexingTypeDuringAllocation(JSC::ArrayWithContiguous),
arg2))) {
if (!clone) {
for (size_t i = 0; i < arg2; ++i) {
- array->putDirectIndex(globalObject, i, JSC::jsString(vm, Zig::toString(arg1[i])));
+ array->putDirectIndex(globalObject, i, JSC::jsString(vm, Zig::toString(arg1[i]), &deferralContext));
}
} else {
for (size_t i = 0; i < arg2; ++i) {
- array->putDirectIndex(globalObject, i, JSC::jsString(vm, Zig::toStringCopy(arg1[i])));
+ array->putDirectIndex(globalObject, i, JSC::jsString(vm, Zig::toStringCopy(arg1[i]), &deferralContext));
}
}
}
- }
- if (!array) {
- JSC::throwOutOfMemoryError(globalObject, scope);
- return JSC::JSValue::encode(JSC::JSValue());
- }
- RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::JSValue(array)));
+ if (!array) {
+ JSC::throwOutOfMemoryError(globalObject, scope);
+ return JSC::JSValue::encode(JSC::JSValue());
+ }
+
+ RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::JSValue(array)));
+ }
}
JSC__JSValue JSC__JSGlobalObject__createAggregateError(JSC__JSGlobalObject* globalObject,
@@ -2803,7 +2863,7 @@ JSC__VM* JSC__JSGlobalObject__vm(JSC__JSGlobalObject* arg0) { return &arg0->vm()
void JSC__JSGlobalObject__handleRejectedPromises(JSC__JSGlobalObject* arg0)
{
- return static_cast<Zig::GlobalObject*>(arg0)->handleRejectedPromises();
+ return jsCast<Zig::GlobalObject*>(arg0)->handleRejectedPromises();
}
#pragma mark - JSC::JSValue
@@ -3012,20 +3072,16 @@ JSC__JSValue JSC__JSValue__jsNumberFromUint64(uint64_t arg0)
int64_t JSC__JSValue__toInt64(JSC__JSValue val)
{
- JSC::JSValue _val = JSC::JSValue::decode(val);
-
- int64_t result = JSC::tryConvertToInt52(_val.asDouble());
- if (result != JSC::JSValue::notInt52) {
- return result;
- }
-
- if (_val.isHeapBigInt()) {
-
- if (auto* heapBigInt = _val.asHeapBigInt()) {
+ JSC::JSValue value = JSC::JSValue::decode(val);
+ ASSERT(value.isHeapBigInt() || value.isNumber());
+ if (value.isHeapBigInt()) {
+ if (auto* heapBigInt = value.asHeapBigInt()) {
return heapBigInt->toBigInt64(heapBigInt);
}
}
- return _val.asAnyInt();
+ if (value.isInt32())
+ return value.asInt32();
+ return static_cast<int64_t>(value.asDouble());
}
uint8_t JSC__JSValue__asBigIntCompare(JSC__JSValue JSValue0, JSC__JSGlobalObject* globalObject, JSC__JSValue JSValue1)
@@ -3086,28 +3142,28 @@ JSC__JSValue JSC__JSValue__fromUInt64NoTruncate(JSC__JSGlobalObject* globalObjec
uint64_t JSC__JSValue__toUInt64NoTruncate(JSC__JSValue val)
{
- JSC::JSValue _val = JSC::JSValue::decode(val);
-
- int64_t result = JSC::tryConvertToInt52(_val.asDouble());
- if (result != JSC::JSValue::notInt52) {
- if (result < 0)
- return 0;
+ JSC::JSValue value = JSC::JSValue::decode(val);
+ ASSERT(value.isHeapBigInt() || value.isNumber());
- return static_cast<uint64_t>(result);
- }
-
- if (_val.isHeapBigInt()) {
-
- if (auto* heapBigInt = _val.asHeapBigInt()) {
+ if (value.isHeapBigInt()) {
+ if (auto* heapBigInt = value.asHeapBigInt()) {
return heapBigInt->toBigUInt64(heapBigInt);
}
}
- if (!_val.isNumber()) {
- return 0;
+ if (value.isInt32()) {
+ return static_cast<uint64_t>(value.asInt32());
}
+ ASSERT(value.isDouble());
- return static_cast<uint64_t>(_val.asAnyInt());
+ int64_t result = JSC::tryConvertToInt52(value.asDouble());
+ if (result != JSC::JSValue::notInt52) {
+ if (result < 0)
+ return 0;
+
+ return static_cast<uint64_t>(result);
+ }
+ return 0;
}
JSC__JSValue JSC__JSValue__createObject2(JSC__JSGlobalObject* globalObject, const ZigString* arg1,
@@ -4046,6 +4102,7 @@ enum class BuiltinNamesMap : uint8_t {
method,
headers,
status,
+ statusText,
url,
body,
data,
@@ -4065,6 +4122,9 @@ static JSC::Identifier builtinNameMap(JSC::JSGlobalObject* globalObject, unsigne
case BuiltinNamesMap::headers: {
return clientData->builtinNames().headersPublicName();
}
+ case BuiltinNamesMap::statusText: {
+ return clientData->builtinNames().statusTextPublicName();
+ }
case BuiltinNamesMap::status: {
return clientData->builtinNames().statusPublicName();
}
@@ -4485,6 +4545,14 @@ extern "C" void JSC__JSGlobalObject__queueMicrotaskJob(JSC__JSGlobalObject* arg0
JSC::JSValue::decode(JSValue4));
}
+extern "C" WebCore::AbortSignal* WebCore__AbortSignal__new(JSC__JSGlobalObject* globalObject)
+{
+ Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(globalObject);
+ auto* context = thisObject->scriptExecutionContext();
+ RefPtr<WebCore::AbortSignal> abortSignal = WebCore::AbortSignal::create(context);
+ return abortSignal.leakRef();
+}
+
extern "C" JSC__JSValue WebCore__AbortSignal__create(JSC__JSGlobalObject* globalObject)
{
Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(globalObject);
@@ -4701,4 +4769,4 @@ CPP_DECL void JSC__VM__setControlFlowProfiler(JSC__VM* vm, bool isEnabled)
} else {
vm->disableControlFlowProfiler();
}
-} \ No newline at end of file
+}
diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig
index 1a82fc5e6..98e91c1ca 100644
--- a/src/bun.js/bindings/bindings.zig
+++ b/src/bun.js/bindings/bindings.zig
@@ -1969,6 +1969,12 @@ pub const AbortSignal = extern opaque {
return cppFn("create", .{global});
}
+ extern fn WebCore__AbortSignal__new(*JSGlobalObject) *AbortSignal;
+ pub fn new(global: *JSGlobalObject) *AbortSignal {
+ JSC.markBinding(@src());
+ return WebCore__AbortSignal__new(global);
+ }
+
pub fn createAbortError(message: *const ZigString, code: *const ZigString, global: *JSGlobalObject) JSValue {
return cppFn("createAbortError", .{ message, code, global });
}
@@ -3034,7 +3040,7 @@ pub const JSValue = enum(JSValueReprInt) {
zero = 0,
undefined = @as(JSValueReprInt, @bitCast(@as(i64, 0xa))),
null = @as(JSValueReprInt, @bitCast(@as(i64, 0x2))),
- true = @as(JSValueReprInt, @bitCast(@as(i64, 0x4))),
+ true = FFI.TrueI64,
false = @as(JSValueReprInt, @bitCast(@as(i64, 0x6))),
_,
@@ -3224,7 +3230,7 @@ pub const JSValue = enum(JSValueReprInt) {
};
}
- pub fn isObject(this: JSType) bool {
+ pub inline fn isObject(this: JSType) bool {
// inline constexpr bool isObjectType(JSType type) { return type >= ObjectType; }
return @intFromEnum(this) >= @intFromEnum(JSType.Object);
}
@@ -3527,7 +3533,7 @@ pub const JSValue = enum(JSValueReprInt) {
}
pub fn createEmptyObject(global: *JSGlobalObject, len: usize) JSValue {
- std.debug.assert(len <= 64); // max inline capacity JSC allows is 64. If you run into this, just set it to 0.
+ std.debug.assert(len <= 63); // max inline capacity JSC allows is 63. If you run into this, just set it to 0.
return cppFn("createEmptyObject", .{ global, len });
}
@@ -3903,6 +3909,10 @@ pub const JSValue = enum(JSValueReprInt) {
return jsNumberFromInt32(@as(i32, @intCast(i)));
}
+ return jsNumberFromPtrSize(i);
+ }
+
+ pub fn jsNumberFromPtrSize(i: usize) JSValue {
return jsNumberFromDouble(@as(f64, @floatFromInt(@as(i52, @intCast(@as(u51, @truncate(i)))))));
}
@@ -4255,6 +4265,7 @@ pub const JSValue = enum(JSValueReprInt) {
method,
headers,
status,
+ statusText,
url,
body,
data,
@@ -4924,6 +4935,34 @@ pub const JSValue = enum(JSValueReprInt) {
pub inline fn deserialize(bytes: []const u8, global: *JSGlobalObject) JSValue {
return Bun__JSValue__deserialize(global, bytes.ptr, @intCast(bytes.len));
}
+
+ extern fn Bun__serializeJSValue(global: *JSC.JSGlobalObject, value: JSValue) SerializedScriptValue.External;
+ extern fn Bun__SerializedScriptSlice__free(*anyopaque) void;
+
+ pub const SerializedScriptValue = struct {
+ data: []const u8,
+ handle: *anyopaque,
+
+ const External = extern struct {
+ bytes: ?[*]const u8,
+ size: isize,
+ handle: ?*anyopaque,
+ };
+
+ pub inline fn deinit(self: @This()) void {
+ Bun__SerializedScriptSlice__free(self.handle);
+ }
+ };
+
+ /// Throws a JS exception and returns null if the serialization fails, otherwise returns a SerializedScriptValue.
+ /// Must be freed when you are done with the bytes.
+ pub inline fn serialize(this: JSValue, global: *JSGlobalObject) ?SerializedScriptValue {
+ const value = Bun__serializeJSValue(global, this);
+ return if (value.bytes) |bytes|
+ .{ .data = bytes[0..@intCast(value.size)], .handle = value.handle.? }
+ else
+ null;
+ }
};
extern "c" fn AsyncContextFrame__withAsyncContextIfNeeded(global: *JSGlobalObject, callback: JSValue) JSValue;
@@ -5492,6 +5531,7 @@ pub const URL = opaque {
extern fn URL__getHref(*String) String;
extern fn URL__getFileURLString(*String) String;
extern fn URL__getHrefJoin(*String, *String) String;
+ extern fn URL__pathFromFileURL(*String) String;
pub fn hrefFromString(str: bun.String) String {
JSC.markBinding(@src());
@@ -5512,6 +5552,12 @@ pub const URL = opaque {
return URL__getFileURLString(&input);
}
+ pub fn pathFromFileURL(str: bun.String) String {
+ JSC.markBinding(@src());
+ var input = str;
+ return URL__pathFromFileURL(&input);
+ }
+
/// This percent-encodes the URL, punycode-encodes the hostname, and returns the result
/// If it fails, the tag is marked Dead
pub fn hrefFromJS(value: JSValue, globalObject: *JSC.JSGlobalObject) String {
@@ -5816,7 +5862,7 @@ pub fn initialize() void {
\\
\\ https://github.com/oven-sh/webkit/blob/main/Source/JavaScriptCore/runtime/OptionsList.h
\\
- \\Environment variables must be prefixed with "BUN_JSC_". This code runs before .env files are loaded, so those won't work here.
+ \\Environment variables must be prefixed with "BUN_JSC_". This code runs before .env files are loaded, so those won't work here.
\\
\\Warning: options change between releases of Bun and WebKit without notice. This is not a stable API, you should not rely on it beyond debugging something, and it may be removed entirely in a future version of Bun.
,
diff --git a/src/bun.js/bindings/c-bindings.cpp b/src/bun.js/bindings/c-bindings.cpp
index ff4c8c4e7..f53ff52cc 100644
--- a/src/bun.js/bindings/c-bindings.cpp
+++ b/src/bun.js/bindings/c-bindings.cpp
@@ -1,4 +1,5 @@
// when we don't want to use @cInclude, we can just stick wrapper functions here
+#include "root.h"
#include <sys/resource.h>
#include <cstdint>
#include <unistd.h>
@@ -6,6 +7,32 @@
#include <sys/stat.h>
#include <sys/signal.h>
+#if CPU(X86_64)
+#include <cstring>
+#include <cpuid.h>
+
+extern "C" void bun_warn_avx_missing(const char* url)
+{
+ __builtin_cpu_init();
+ if (__builtin_cpu_supports("avx")) {
+ return;
+ }
+
+ static constexpr const char* str = "warn: CPU lacks AVX support, strange crashes may occur. Reinstall Bun or use *-baseline build:\n ";
+ const size_t len = strlen(str);
+
+ char buf[512];
+ strcpy(buf, str);
+ strcpy(buf + len, url);
+ strcpy(buf + len + strlen(url), "\n\0");
+ write(STDERR_FILENO, buf, strlen(buf));
+}
+#else
+extern "C" void bun_warn_avx_missing(char* url)
+{
+}
+#endif
+
extern "C" int32_t get_process_priority(uint32_t pid)
{
return getpriority(PRIO_PROCESS, pid);
@@ -48,4 +75,4 @@ extern "C" ssize_t bun_sysconf__SC_CLK_TCK()
#else
return 0;
#endif
-} \ No newline at end of file
+}
diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig
index 18b7c8bce..617530ec6 100644
--- a/src/bun.js/bindings/exports.zig
+++ b/src/bun.js/bindings/exports.zig
@@ -969,7 +969,7 @@ pub const ZigConsoleClient = struct {
Output.prettyFmt("<r><red>Assertion failed<r>\n", true)
else
"Assertion failed\n";
- console.error_writer.unbuffered_writer.writeAll(text) catch unreachable;
+ console.error_writer.unbuffered_writer.writeAll(text) catch {};
return;
}
@@ -983,28 +983,48 @@ pub const ZigConsoleClient = struct {
else
console.writer;
var writer = buffered_writer.writer();
-
const Writer = @TypeOf(writer);
- if (len > 0)
+
+ var print_length = len;
+ var print_options: FormatOptions = .{
+ .enable_colors = enable_colors,
+ .add_newline = true,
+ .flush = true,
+ };
+
+ if (message_type == .Dir and len >= 2) {
+ print_length = 1;
+ var opts = vals[1];
+ if (opts.isObject()) {
+ if (opts.get(global, "depth")) |depth_prop| {
+ if (depth_prop.isNumber())
+ print_options.max_depth = depth_prop.toU16();
+ if (depth_prop.isNull() or depth_prop.toInt64() == std.math.maxInt(i64))
+ print_options.max_depth = std.math.maxInt(u16);
+ }
+ if (opts.get(global, "colors")) |colors_prop| {
+ if (colors_prop.isBoolean())
+ print_options.enable_colors = colors_prop.toBoolean();
+ }
+ }
+ }
+
+ if (print_length > 0)
format(
level,
global,
vals,
- len,
+ print_length,
@TypeOf(buffered_writer.unbuffered_writer.context),
Writer,
writer,
- .{
- .enable_colors = enable_colors,
- .add_newline = true,
- .flush = true,
- },
+ print_options,
)
else if (message_type == .Log) {
_ = console.writer.write("\n") catch 0;
console.writer.flush() catch {};
} else if (message_type != .Trace)
- writer.writeAll("undefined\n") catch unreachable;
+ writer.writeAll("undefined\n") catch {};
if (message_type == .Trace) {
writeTrace(Writer, writer, global);
@@ -1026,14 +1046,14 @@ pub const ZigConsoleClient = struct {
writer,
exception.stack,
true,
- ) catch unreachable
+ ) catch {}
else
JS.VirtualMachine.printStackTrace(
Writer,
writer,
exception.stack,
false,
- ) catch unreachable;
+ ) catch {};
}
pub const FormatOptions = struct {
@@ -1042,7 +1062,7 @@ pub const ZigConsoleClient = struct {
flush: bool,
ordered_properties: bool = false,
quote_strings: bool = false,
- max_depth: u16 = 8,
+ max_depth: u16 = 2,
};
pub fn format(
@@ -1082,7 +1102,7 @@ pub const ZigConsoleClient = struct {
if (tag.tag == .String) {
if (options.enable_colors) {
if (level == .Error) {
- unbuffered_writer.writeAll(comptime Output.prettyFmt("<r><red>", true)) catch unreachable;
+ unbuffered_writer.writeAll(comptime Output.prettyFmt("<r><red>", true)) catch {};
}
fmt.format(
tag,
@@ -1093,7 +1113,7 @@ pub const ZigConsoleClient = struct {
true,
);
if (level == .Error) {
- unbuffered_writer.writeAll(comptime Output.prettyFmt("<r>", true)) catch unreachable;
+ unbuffered_writer.writeAll(comptime Output.prettyFmt("<r>", true)) catch {};
}
} else {
fmt.format(
@@ -1155,7 +1175,7 @@ pub const ZigConsoleClient = struct {
var any = false;
if (options.enable_colors) {
if (level == .Error) {
- writer.writeAll(comptime Output.prettyFmt("<r><red>", true)) catch unreachable;
+ writer.writeAll(comptime Output.prettyFmt("<r><red>", true)) catch {};
}
while (true) {
if (any) {
@@ -1177,7 +1197,7 @@ pub const ZigConsoleClient = struct {
fmt.remaining_values = fmt.remaining_values[1..];
}
if (level == .Error) {
- writer.writeAll(comptime Output.prettyFmt("<r>", true)) catch unreachable;
+ writer.writeAll(comptime Output.prettyFmt("<r>", true)) catch {};
}
} else {
while (true) {
@@ -2119,7 +2139,7 @@ pub const ZigConsoleClient = struct {
this.globalThis,
this.custom_formatted_object.function,
this.custom_formatted_object.this,
- this.max_depth - this.depth,
+ this.max_depth -| this.depth,
this.max_depth,
enable_ansi_colors,
);
@@ -2158,7 +2178,7 @@ pub const ZigConsoleClient = struct {
this.addForNewLine(printable.len);
if (printable.len == 0) {
- writer.print(comptime Output.prettyFmt("<cyan>[class]<r>", enable_ansi_colors), .{});
+ writer.print(comptime Output.prettyFmt("<cyan>[class (anonymous)]<r>", enable_ansi_colors), .{});
} else {
writer.print(comptime Output.prettyFmt("<cyan>[class {}]<r>", enable_ansi_colors), .{printable});
}
diff --git a/src/bun.js/bindings/generated_classes.zig b/src/bun.js/bindings/generated_classes.zig
index 329506718..c4f63084b 100644
--- a/src/bun.js/bindings/generated_classes.zig
+++ b/src/bun.js/bindings/generated_classes.zig
@@ -1220,6 +1220,28 @@ pub const JSDebugHTTPSServer = struct {
return DebugHTTPSServer__fromJS(value);
}
+ extern fn DebugHTTPSServerPrototype__addressSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void;
+
+ extern fn DebugHTTPSServerPrototype__addressGetCachedValue(JSC.JSValue) JSC.JSValue;
+
+ /// `DebugHTTPSServer.address` setter
+ /// This value will be visited by the garbage collector.
+ pub fn addressSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void {
+ JSC.markBinding(@src());
+ DebugHTTPSServerPrototype__addressSetCachedValue(thisValue, globalObject, value);
+ }
+
+ /// `DebugHTTPSServer.address` getter
+ /// This value will be visited by the garbage collector.
+ pub fn addressGetCached(thisValue: JSC.JSValue) ?JSC.JSValue {
+ JSC.markBinding(@src());
+ const result = DebugHTTPSServerPrototype__addressGetCachedValue(thisValue);
+ if (result == .zero)
+ return null;
+
+ return result;
+ }
+
extern fn DebugHTTPSServerPrototype__hostnameSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void;
extern fn DebugHTTPSServerPrototype__hostnameGetCachedValue(JSC.JSValue) JSC.JSValue;
@@ -1300,6 +1322,9 @@ pub const JSDebugHTTPSServer = struct {
@compileLog("DebugHTTPSServer.finalize is not a finalizer");
}
+ if (@TypeOf(DebugHTTPSServer.getAddress) != GetterType)
+ @compileLog("Expected DebugHTTPSServer.getAddress to be a getter");
+
if (@TypeOf(DebugHTTPSServer.getDevelopment) != GetterType)
@compileLog("Expected DebugHTTPSServer.getDevelopment to be a getter");
@@ -1327,6 +1352,8 @@ pub const JSDebugHTTPSServer = struct {
@compileLog("Expected DebugHTTPSServer.doPublish to be a callback but received " ++ @typeName(@TypeOf(DebugHTTPSServer.doPublish)));
if (@TypeOf(DebugHTTPSServer.doReload) != CallbackType)
@compileLog("Expected DebugHTTPSServer.doReload to be a callback but received " ++ @typeName(@TypeOf(DebugHTTPSServer.doReload)));
+ if (@TypeOf(DebugHTTPSServer.doRequestIP) != CallbackType)
+ @compileLog("Expected DebugHTTPSServer.doRequestIP to be a callback but received " ++ @typeName(@TypeOf(DebugHTTPSServer.doRequestIP)));
if (@TypeOf(DebugHTTPSServer.doStop) != CallbackType)
@compileLog("Expected DebugHTTPSServer.doStop to be a callback but received " ++ @typeName(@TypeOf(DebugHTTPSServer.doStop)));
if (@TypeOf(DebugHTTPSServer.doUpgrade) != CallbackType)
@@ -1335,9 +1362,11 @@ pub const JSDebugHTTPSServer = struct {
@export(DebugHTTPSServer.doFetch, .{ .name = "DebugHTTPSServerPrototype__doFetch" });
@export(DebugHTTPSServer.doPublish, .{ .name = "DebugHTTPSServerPrototype__doPublish" });
@export(DebugHTTPSServer.doReload, .{ .name = "DebugHTTPSServerPrototype__doReload" });
+ @export(DebugHTTPSServer.doRequestIP, .{ .name = "DebugHTTPSServerPrototype__doRequestIP" });
@export(DebugHTTPSServer.doStop, .{ .name = "DebugHTTPSServerPrototype__doStop" });
@export(DebugHTTPSServer.doUpgrade, .{ .name = "DebugHTTPSServerPrototype__doUpgrade" });
@export(DebugHTTPSServer.finalize, .{ .name = "DebugHTTPSServerClass__finalize" });
+ @export(DebugHTTPSServer.getAddress, .{ .name = "DebugHTTPSServerPrototype__getAddress" });
@export(DebugHTTPSServer.getDevelopment, .{ .name = "DebugHTTPSServerPrototype__getDevelopment" });
@export(DebugHTTPSServer.getHostname, .{ .name = "DebugHTTPSServerPrototype__getHostname" });
@export(DebugHTTPSServer.getId, .{ .name = "DebugHTTPSServerPrototype__getId" });
@@ -1363,6 +1392,28 @@ pub const JSDebugHTTPServer = struct {
return DebugHTTPServer__fromJS(value);
}
+ extern fn DebugHTTPServerPrototype__addressSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void;
+
+ extern fn DebugHTTPServerPrototype__addressGetCachedValue(JSC.JSValue) JSC.JSValue;
+
+ /// `DebugHTTPServer.address` setter
+ /// This value will be visited by the garbage collector.
+ pub fn addressSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void {
+ JSC.markBinding(@src());
+ DebugHTTPServerPrototype__addressSetCachedValue(thisValue, globalObject, value);
+ }
+
+ /// `DebugHTTPServer.address` getter
+ /// This value will be visited by the garbage collector.
+ pub fn addressGetCached(thisValue: JSC.JSValue) ?JSC.JSValue {
+ JSC.markBinding(@src());
+ const result = DebugHTTPServerPrototype__addressGetCachedValue(thisValue);
+ if (result == .zero)
+ return null;
+
+ return result;
+ }
+
extern fn DebugHTTPServerPrototype__hostnameSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void;
extern fn DebugHTTPServerPrototype__hostnameGetCachedValue(JSC.JSValue) JSC.JSValue;
@@ -1443,6 +1494,9 @@ pub const JSDebugHTTPServer = struct {
@compileLog("DebugHTTPServer.finalize is not a finalizer");
}
+ if (@TypeOf(DebugHTTPServer.getAddress) != GetterType)
+ @compileLog("Expected DebugHTTPServer.getAddress to be a getter");
+
if (@TypeOf(DebugHTTPServer.getDevelopment) != GetterType)
@compileLog("Expected DebugHTTPServer.getDevelopment to be a getter");
@@ -1470,6 +1524,8 @@ pub const JSDebugHTTPServer = struct {
@compileLog("Expected DebugHTTPServer.doPublish to be a callback but received " ++ @typeName(@TypeOf(DebugHTTPServer.doPublish)));
if (@TypeOf(DebugHTTPServer.doReload) != CallbackType)
@compileLog("Expected DebugHTTPServer.doReload to be a callback but received " ++ @typeName(@TypeOf(DebugHTTPServer.doReload)));
+ if (@TypeOf(DebugHTTPServer.doRequestIP) != CallbackType)
+ @compileLog("Expected DebugHTTPServer.doRequestIP to be a callback but received " ++ @typeName(@TypeOf(DebugHTTPServer.doRequestIP)));
if (@TypeOf(DebugHTTPServer.doStop) != CallbackType)
@compileLog("Expected DebugHTTPServer.doStop to be a callback but received " ++ @typeName(@TypeOf(DebugHTTPServer.doStop)));
if (@TypeOf(DebugHTTPServer.doUpgrade) != CallbackType)
@@ -1478,9 +1534,11 @@ pub const JSDebugHTTPServer = struct {
@export(DebugHTTPServer.doFetch, .{ .name = "DebugHTTPServerPrototype__doFetch" });
@export(DebugHTTPServer.doPublish, .{ .name = "DebugHTTPServerPrototype__doPublish" });
@export(DebugHTTPServer.doReload, .{ .name = "DebugHTTPServerPrototype__doReload" });
+ @export(DebugHTTPServer.doRequestIP, .{ .name = "DebugHTTPServerPrototype__doRequestIP" });
@export(DebugHTTPServer.doStop, .{ .name = "DebugHTTPServerPrototype__doStop" });
@export(DebugHTTPServer.doUpgrade, .{ .name = "DebugHTTPServerPrototype__doUpgrade" });
@export(DebugHTTPServer.finalize, .{ .name = "DebugHTTPServerClass__finalize" });
+ @export(DebugHTTPServer.getAddress, .{ .name = "DebugHTTPServerPrototype__getAddress" });
@export(DebugHTTPServer.getDevelopment, .{ .name = "DebugHTTPServerPrototype__getDevelopment" });
@export(DebugHTTPServer.getHostname, .{ .name = "DebugHTTPServerPrototype__getHostname" });
@export(DebugHTTPServer.getId, .{ .name = "DebugHTTPServerPrototype__getId" });
@@ -2205,6 +2263,8 @@ pub const JSExpect = struct {
@compileLog("Expected Expect.toEndWith to be a callback but received " ++ @typeName(@TypeOf(Expect.toEndWith)));
if (@TypeOf(Expect.toEqual) != CallbackType)
@compileLog("Expected Expect.toEqual to be a callback but received " ++ @typeName(@TypeOf(Expect.toEqual)));
+ if (@TypeOf(Expect.toEqualIgnoringWhitespace) != CallbackType)
+ @compileLog("Expected Expect.toEqualIgnoringWhitespace to be a callback but received " ++ @typeName(@TypeOf(Expect.toEqualIgnoringWhitespace)));
if (@TypeOf(Expect.toHaveBeenCalled) != CallbackType)
@compileLog("Expected Expect.toHaveBeenCalled to be a callback but received " ++ @typeName(@TypeOf(Expect.toHaveBeenCalled)));
if (@TypeOf(Expect.toHaveBeenCalledTimes) != CallbackType)
@@ -2341,6 +2401,7 @@ pub const JSExpect = struct {
@export(Expect.toContainEqual, .{ .name = "ExpectPrototype__toContainEqual" });
@export(Expect.toEndWith, .{ .name = "ExpectPrototype__toEndWith" });
@export(Expect.toEqual, .{ .name = "ExpectPrototype__toEqual" });
+ @export(Expect.toEqualIgnoringWhitespace, .{ .name = "ExpectPrototype__toEqualIgnoringWhitespace" });
@export(Expect.toHaveBeenCalled, .{ .name = "ExpectPrototype__toHaveBeenCalled" });
@export(Expect.toHaveBeenCalledTimes, .{ .name = "ExpectPrototype__toHaveBeenCalledTimes" });
@export(Expect.toHaveBeenCalledWith, .{ .name = "ExpectPrototype__toHaveBeenCalledWith" });
@@ -2507,6 +2568,87 @@ pub const JSExpectAnything = struct {
}
}
};
+pub const JSExpectArrayContaining = struct {
+ const ExpectArrayContaining = Classes.ExpectArrayContaining;
+ const GetterType = fn (*ExpectArrayContaining, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue;
+ const GetterTypeWithThisValue = fn (*ExpectArrayContaining, JSC.JSValue, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue;
+ const SetterType = fn (*ExpectArrayContaining, *JSC.JSGlobalObject, JSC.JSValue) callconv(.C) bool;
+ const SetterTypeWithThisValue = fn (*ExpectArrayContaining, JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) callconv(.C) bool;
+ const CallbackType = fn (*ExpectArrayContaining, *JSC.JSGlobalObject, *JSC.CallFrame) callconv(.C) JSC.JSValue;
+
+ /// Return the pointer to the wrapped object.
+ /// If the object does not match the type, return null.
+ pub fn fromJS(value: JSC.JSValue) ?*ExpectArrayContaining {
+ JSC.markBinding(@src());
+ return ExpectArrayContaining__fromJS(value);
+ }
+
+ extern fn ExpectArrayContainingPrototype__arrayValueSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void;
+
+ extern fn ExpectArrayContainingPrototype__arrayValueGetCachedValue(JSC.JSValue) JSC.JSValue;
+
+ /// `ExpectArrayContaining.arrayValue` setter
+ /// This value will be visited by the garbage collector.
+ pub fn arrayValueSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void {
+ JSC.markBinding(@src());
+ ExpectArrayContainingPrototype__arrayValueSetCachedValue(thisValue, globalObject, value);
+ }
+
+ /// `ExpectArrayContaining.arrayValue` getter
+ /// This value will be visited by the garbage collector.
+ pub fn arrayValueGetCached(thisValue: JSC.JSValue) ?JSC.JSValue {
+ JSC.markBinding(@src());
+ const result = ExpectArrayContainingPrototype__arrayValueGetCachedValue(thisValue);
+ if (result == .zero)
+ return null;
+
+ return result;
+ }
+
+ /// Create a new instance of ExpectArrayContaining
+ pub fn toJS(this: *ExpectArrayContaining, globalObject: *JSC.JSGlobalObject) JSC.JSValue {
+ JSC.markBinding(@src());
+ if (comptime Environment.allow_assert) {
+ const value__ = ExpectArrayContaining__create(globalObject, this);
+ std.debug.assert(value__.as(ExpectArrayContaining).? == this); // If this fails, likely a C ABI issue.
+ return value__;
+ } else {
+ return ExpectArrayContaining__create(globalObject, this);
+ }
+ }
+
+ /// Modify the internal ptr to point to a new instance of ExpectArrayContaining.
+ pub fn dangerouslySetPtr(value: JSC.JSValue, ptr: ?*ExpectArrayContaining) bool {
+ JSC.markBinding(@src());
+ return ExpectArrayContaining__dangerouslySetPtr(value, ptr);
+ }
+
+ /// Detach the ptr from the thisValue
+ pub fn detachPtr(_: *ExpectArrayContaining, value: JSC.JSValue) void {
+ JSC.markBinding(@src());
+ std.debug.assert(ExpectArrayContaining__dangerouslySetPtr(value, null));
+ }
+
+ extern fn ExpectArrayContaining__fromJS(JSC.JSValue) ?*ExpectArrayContaining;
+ extern fn ExpectArrayContaining__getConstructor(*JSC.JSGlobalObject) JSC.JSValue;
+
+ extern fn ExpectArrayContaining__create(globalObject: *JSC.JSGlobalObject, ptr: ?*ExpectArrayContaining) JSC.JSValue;
+
+ extern fn ExpectArrayContaining__dangerouslySetPtr(JSC.JSValue, ?*ExpectArrayContaining) bool;
+
+ comptime {
+ if (@TypeOf(ExpectArrayContaining.finalize) != (fn (*ExpectArrayContaining) callconv(.C) void)) {
+ @compileLog("ExpectArrayContaining.finalize is not a finalizer");
+ }
+
+ if (@TypeOf(ExpectArrayContaining.call) != StaticCallbackType)
+ @compileLog("Expected ExpectArrayContaining.call to be a static callback");
+ if (!JSC.is_bindgen) {
+ @export(ExpectArrayContaining.call, .{ .name = "ExpectArrayContainingClass__call" });
+ @export(ExpectArrayContaining.finalize, .{ .name = "ExpectArrayContainingClass__finalize" });
+ }
+ }
+};
pub const JSExpectStringContaining = struct {
const ExpectStringContaining = Classes.ExpectStringContaining;
const GetterType = fn (*ExpectStringContaining, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue;
@@ -3089,6 +3231,28 @@ pub const JSHTTPSServer = struct {
return HTTPSServer__fromJS(value);
}
+ extern fn HTTPSServerPrototype__addressSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void;
+
+ extern fn HTTPSServerPrototype__addressGetCachedValue(JSC.JSValue) JSC.JSValue;
+
+ /// `HTTPSServer.address` setter
+ /// This value will be visited by the garbage collector.
+ pub fn addressSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void {
+ JSC.markBinding(@src());
+ HTTPSServerPrototype__addressSetCachedValue(thisValue, globalObject, value);
+ }
+
+ /// `HTTPSServer.address` getter
+ /// This value will be visited by the garbage collector.
+ pub fn addressGetCached(thisValue: JSC.JSValue) ?JSC.JSValue {
+ JSC.markBinding(@src());
+ const result = HTTPSServerPrototype__addressGetCachedValue(thisValue);
+ if (result == .zero)
+ return null;
+
+ return result;
+ }
+
extern fn HTTPSServerPrototype__hostnameSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void;
extern fn HTTPSServerPrototype__hostnameGetCachedValue(JSC.JSValue) JSC.JSValue;
@@ -3169,6 +3333,9 @@ pub const JSHTTPSServer = struct {
@compileLog("HTTPSServer.finalize is not a finalizer");
}
+ if (@TypeOf(HTTPSServer.getAddress) != GetterType)
+ @compileLog("Expected HTTPSServer.getAddress to be a getter");
+
if (@TypeOf(HTTPSServer.getDevelopment) != GetterType)
@compileLog("Expected HTTPSServer.getDevelopment to be a getter");
@@ -3196,6 +3363,8 @@ pub const JSHTTPSServer = struct {
@compileLog("Expected HTTPSServer.doPublish to be a callback but received " ++ @typeName(@TypeOf(HTTPSServer.doPublish)));
if (@TypeOf(HTTPSServer.doReload) != CallbackType)
@compileLog("Expected HTTPSServer.doReload to be a callback but received " ++ @typeName(@TypeOf(HTTPSServer.doReload)));
+ if (@TypeOf(HTTPSServer.doRequestIP) != CallbackType)
+ @compileLog("Expected HTTPSServer.doRequestIP to be a callback but received " ++ @typeName(@TypeOf(HTTPSServer.doRequestIP)));
if (@TypeOf(HTTPSServer.doStop) != CallbackType)
@compileLog("Expected HTTPSServer.doStop to be a callback but received " ++ @typeName(@TypeOf(HTTPSServer.doStop)));
if (@TypeOf(HTTPSServer.doUpgrade) != CallbackType)
@@ -3204,9 +3373,11 @@ pub const JSHTTPSServer = struct {
@export(HTTPSServer.doFetch, .{ .name = "HTTPSServerPrototype__doFetch" });
@export(HTTPSServer.doPublish, .{ .name = "HTTPSServerPrototype__doPublish" });
@export(HTTPSServer.doReload, .{ .name = "HTTPSServerPrototype__doReload" });
+ @export(HTTPSServer.doRequestIP, .{ .name = "HTTPSServerPrototype__doRequestIP" });
@export(HTTPSServer.doStop, .{ .name = "HTTPSServerPrototype__doStop" });
@export(HTTPSServer.doUpgrade, .{ .name = "HTTPSServerPrototype__doUpgrade" });
@export(HTTPSServer.finalize, .{ .name = "HTTPSServerClass__finalize" });
+ @export(HTTPSServer.getAddress, .{ .name = "HTTPSServerPrototype__getAddress" });
@export(HTTPSServer.getDevelopment, .{ .name = "HTTPSServerPrototype__getDevelopment" });
@export(HTTPSServer.getHostname, .{ .name = "HTTPSServerPrototype__getHostname" });
@export(HTTPSServer.getId, .{ .name = "HTTPSServerPrototype__getId" });
@@ -3232,6 +3403,28 @@ pub const JSHTTPServer = struct {
return HTTPServer__fromJS(value);
}
+ extern fn HTTPServerPrototype__addressSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void;
+
+ extern fn HTTPServerPrototype__addressGetCachedValue(JSC.JSValue) JSC.JSValue;
+
+ /// `HTTPServer.address` setter
+ /// This value will be visited by the garbage collector.
+ pub fn addressSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void {
+ JSC.markBinding(@src());
+ HTTPServerPrototype__addressSetCachedValue(thisValue, globalObject, value);
+ }
+
+ /// `HTTPServer.address` getter
+ /// This value will be visited by the garbage collector.
+ pub fn addressGetCached(thisValue: JSC.JSValue) ?JSC.JSValue {
+ JSC.markBinding(@src());
+ const result = HTTPServerPrototype__addressGetCachedValue(thisValue);
+ if (result == .zero)
+ return null;
+
+ return result;
+ }
+
extern fn HTTPServerPrototype__hostnameSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void;
extern fn HTTPServerPrototype__hostnameGetCachedValue(JSC.JSValue) JSC.JSValue;
@@ -3312,6 +3505,9 @@ pub const JSHTTPServer = struct {
@compileLog("HTTPServer.finalize is not a finalizer");
}
+ if (@TypeOf(HTTPServer.getAddress) != GetterType)
+ @compileLog("Expected HTTPServer.getAddress to be a getter");
+
if (@TypeOf(HTTPServer.getDevelopment) != GetterType)
@compileLog("Expected HTTPServer.getDevelopment to be a getter");
@@ -3339,6 +3535,8 @@ pub const JSHTTPServer = struct {
@compileLog("Expected HTTPServer.doPublish to be a callback but received " ++ @typeName(@TypeOf(HTTPServer.doPublish)));
if (@TypeOf(HTTPServer.doReload) != CallbackType)
@compileLog("Expected HTTPServer.doReload to be a callback but received " ++ @typeName(@TypeOf(HTTPServer.doReload)));
+ if (@TypeOf(HTTPServer.doRequestIP) != CallbackType)
+ @compileLog("Expected HTTPServer.doRequestIP to be a callback but received " ++ @typeName(@TypeOf(HTTPServer.doRequestIP)));
if (@TypeOf(HTTPServer.doStop) != CallbackType)
@compileLog("Expected HTTPServer.doStop to be a callback but received " ++ @typeName(@TypeOf(HTTPServer.doStop)));
if (@TypeOf(HTTPServer.doUpgrade) != CallbackType)
@@ -3347,9 +3545,11 @@ pub const JSHTTPServer = struct {
@export(HTTPServer.doFetch, .{ .name = "HTTPServerPrototype__doFetch" });
@export(HTTPServer.doPublish, .{ .name = "HTTPServerPrototype__doPublish" });
@export(HTTPServer.doReload, .{ .name = "HTTPServerPrototype__doReload" });
+ @export(HTTPServer.doRequestIP, .{ .name = "HTTPServerPrototype__doRequestIP" });
@export(HTTPServer.doStop, .{ .name = "HTTPServerPrototype__doStop" });
@export(HTTPServer.doUpgrade, .{ .name = "HTTPServerPrototype__doUpgrade" });
@export(HTTPServer.finalize, .{ .name = "HTTPServerClass__finalize" });
+ @export(HTTPServer.getAddress, .{ .name = "HTTPServerPrototype__getAddress" });
@export(HTTPServer.getDevelopment, .{ .name = "HTTPServerPrototype__getDevelopment" });
@export(HTTPServer.getHostname, .{ .name = "HTTPServerPrototype__getHostname" });
@export(HTTPServer.getId, .{ .name = "HTTPServerPrototype__getId" });
@@ -6781,6 +6981,9 @@ pub const JSTextDecoder = struct {
if (@TypeOf(TextDecoder.getFatal) != GetterType)
@compileLog("Expected TextDecoder.getFatal to be a getter");
+ if (@TypeOf(TextDecoder.getIgnoreBOM) != GetterType)
+ @compileLog("Expected TextDecoder.getIgnoreBOM to be a getter");
+
if (!JSC.is_bindgen) {
@export(TextDecoder.constructor, .{ .name = "TextDecoderClass__construct" });
@export(TextDecoder.decode, .{ .name = "TextDecoderPrototype__decode" });
@@ -6788,6 +6991,7 @@ pub const JSTextDecoder = struct {
@export(TextDecoder.finalize, .{ .name = "TextDecoderClass__finalize" });
@export(TextDecoder.getEncoding, .{ .name = "TextDecoderPrototype__getEncoding" });
@export(TextDecoder.getFatal, .{ .name = "TextDecoderPrototype__getFatal" });
+ @export(TextDecoder.getIgnoreBOM, .{ .name = "TextDecoderPrototype__getIgnoreBOM" });
}
}
};
@@ -7006,6 +7210,7 @@ comptime {
_ = JSExpect;
_ = JSExpectAny;
_ = JSExpectAnything;
+ _ = JSExpectArrayContaining;
_ = JSExpectStringContaining;
_ = JSExpectStringMatching;
_ = JSFFI;
diff --git a/src/bun.js/bindings/generated_classes_list.zig b/src/bun.js/bindings/generated_classes_list.zig
index a86f74dd3..3b45f33b8 100644
--- a/src/bun.js/bindings/generated_classes_list.zig
+++ b/src/bun.js/bindings/generated_classes_list.zig
@@ -17,6 +17,7 @@ pub const Classes = struct {
pub const ExpectAnything = JSC.Expect.ExpectAnything;
pub const ExpectStringContaining = JSC.Expect.ExpectStringContaining;
pub const ExpectStringMatching = JSC.Expect.ExpectStringMatching;
+ pub const ExpectArrayContaining = JSC.Expect.ExpectArrayContaining;
pub const FileSystemRouter = JSC.API.FileSystemRouter;
pub const Bundler = JSC.API.JSBundler;
pub const JSBundler = Bundler;
diff --git a/src/bun.js/bindings/headers-handwritten.h b/src/bun.js/bindings/headers-handwritten.h
index e19be7abe..d8cfa58ef 100644
--- a/src/bun.js/bindings/headers-handwritten.h
+++ b/src/bun.js/bindings/headers-handwritten.h
@@ -17,10 +17,6 @@ typedef union BunStringImpl {
void* wtf;
} BunStringImpl;
-typedef struct BunString {
- BunStringTag tag;
- BunStringImpl impl;
-} BunString;
#else
typedef union BunStringImpl {
ZigString zig;
@@ -34,13 +30,15 @@ enum class BunStringTag : uint8_t {
StaticZigString = 3,
Empty = 4,
};
+#endif
typedef struct BunString {
BunStringTag tag;
BunStringImpl impl;
-} BunString;
-#endif
+ inline void ref();
+ inline void deref();
+} BunString;
typedef struct ZigErrorType {
ZigErrorCode code;
@@ -241,6 +239,7 @@ extern "C" void BunString__toWTFString(BunString*);
namespace Bun {
JSC::JSValue toJS(JSC::JSGlobalObject*, BunString);
BunString toString(JSC::JSGlobalObject* globalObject, JSC::JSValue value);
+BunString toString(const char* bytes, size_t length);
WTF::String toWTFString(const BunString& bunString);
BunString toString(WTF::String& wtfString);
BunString toString(const WTF::String& wtfString);
@@ -348,3 +347,16 @@ class ScriptArguments;
using ScriptArguments = Inspector::ScriptArguments;
#endif
+
+ALWAYS_INLINE void BunString::ref()
+{
+ if (this->tag == BunStringTag::WTFStringImpl) {
+ this->impl.wtf->ref();
+ }
+}
+ALWAYS_INLINE void BunString::deref()
+{
+ if (this->tag == BunStringTag::WTFStringImpl) {
+ this->impl.wtf->deref();
+ }
+} \ No newline at end of file
diff --git a/src/bun.js/bindings/isBuiltinModule.cpp b/src/bun.js/bindings/isBuiltinModule.cpp
new file mode 100644
index 000000000..b8e69f479
--- /dev/null
+++ b/src/bun.js/bindings/isBuiltinModule.cpp
@@ -0,0 +1,98 @@
+#include "root.h"
+
+static constexpr ASCIILiteral builtinModuleNamesSortedLength[] = {
+ "fs"_s,
+ "os"_s,
+ "v8"_s,
+ "vm"_s,
+ "ws"_s,
+ "bun"_s,
+ "dns"_s,
+ "net"_s,
+ "sys"_s,
+ "tls"_s,
+ "tty"_s,
+ "url"_s,
+ "http"_s,
+ "path"_s,
+ "repl"_s,
+ "util"_s,
+ "wasi"_s,
+ "zlib"_s,
+ "dgram"_s,
+ "http2"_s,
+ "https"_s,
+ "assert"_s,
+ "buffer"_s,
+ "crypto"_s,
+ "domain"_s,
+ "events"_s,
+ "module"_s,
+ "stream"_s,
+ "timers"_s,
+ "undici"_s,
+ "bun:ffi"_s,
+ "bun:jsc"_s,
+ "cluster"_s,
+ "console"_s,
+ "process"_s,
+ "bun:wrap"_s,
+ "punycode"_s,
+ "bun:test"_s,
+ "bun:main"_s,
+ "readline"_s,
+ "_tls_wrap"_s,
+ "constants"_s,
+ "inspector"_s,
+ "bun:sqlite"_s,
+ "path/posix"_s,
+ "path/win32"_s,
+ "perf_hooks"_s,
+ "stream/web"_s,
+ "util/types"_s,
+ "_http_agent"_s,
+ "_tls_common"_s,
+ "async_hooks"_s,
+ "detect-libc"_s,
+ "fs/promises"_s,
+ "querystring"_s,
+ "_http_client"_s,
+ "_http_common"_s,
+ "_http_server"_s,
+ "_stream_wrap"_s,
+ "dns/promises"_s,
+ "trace_events"_s,
+ "assert/strict"_s,
+ "child_process"_s,
+ "_http_incoming"_s,
+ "_http_outgoing"_s,
+ "_stream_duplex"_s,
+ "string_decoder"_s,
+ "worker_threads"_s,
+ "stream/promises"_s,
+ "timers/promises"_s,
+ "_stream_readable"_s,
+ "_stream_writable"_s,
+ "stream/consumers"_s,
+ "_stream_transform"_s,
+ "readline/promises"_s,
+ "inspector/promises"_s,
+ "_stream_passthrough"_s,
+ "diagnostics_channel"_s,
+};
+
+namespace Bun {
+
+bool isBuiltinModule(const String &namePossiblyWithNodePrefix) {
+ String name = namePossiblyWithNodePrefix;
+ if (name.startsWith("node:"_s))
+ name = name.substringSharingImpl(5);
+
+ for (auto &builtinModule : builtinModuleNamesSortedLength) {
+ if (name == builtinModule)
+ return true;
+ }
+ return false;
+}
+
+} // namespace Bun \ No newline at end of file
diff --git a/src/bun.js/bindings/isBuiltinModule.h b/src/bun.js/bindings/isBuiltinModule.h
new file mode 100644
index 000000000..d66f025d1
--- /dev/null
+++ b/src/bun.js/bindings/isBuiltinModule.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace Bun {
+bool isBuiltinModule(const String &namePossiblyWithNodePrefix);
+} // namespace Bun \ No newline at end of file
diff --git a/src/bun.js/bindings/napi.cpp b/src/bun.js/bindings/napi.cpp
index 72ca50dcb..005a753d0 100644
--- a/src/bun.js/bindings/napi.cpp
+++ b/src/bun.js/bindings/napi.cpp
@@ -83,7 +83,7 @@ JSC::SourceCode generateSourceCode(WTF::String keyString, JSC::VM& vm, JSC::JSOb
sourceCodeBuilder.append(";\n"_s);
}
globalObject->putDirect(vm, ident, object, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::DontEnum);
- return JSC::makeSource(sourceCodeBuilder.toString(), JSC::SourceOrigin(), keyString, WTF::TextPosition(), JSC::SourceProviderSourceType::Module);
+ return JSC::makeSource(sourceCodeBuilder.toString(), JSC::SourceOrigin(), JSC::SourceTaintedOrigin::Untainted, keyString, WTF::TextPosition(), JSC::SourceProviderSourceType::Module);
}
}
@@ -200,10 +200,6 @@ static uint32_t getPropertyAttributes(napi_property_descriptor prop)
// result |= JSC::PropertyAttribute::ReadOnly;
// }
- if (prop.method) {
- result |= JSC::PropertyAttribute::Function;
- }
-
return result;
}
@@ -257,7 +253,7 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
value = JSC::JSValue(function);
// }
- to->putDirect(vm, propertyName, value, getPropertyAttributes(property) | JSC::PropertyAttribute::Function);
+ to->putDirect(vm, propertyName, value, getPropertyAttributes(property));
return;
}
@@ -317,6 +313,10 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
extern "C" napi_status napi_set_property(napi_env env, napi_value target,
napi_value key, napi_value value)
{
+ if (UNLIKELY(!env || !target || !key)) {
+ return napi_invalid_arg;
+ }
+
auto globalObject = toJS(env);
auto& vm = globalObject->vm();
auto* object = toJS(target).getObject();
@@ -327,7 +327,8 @@ extern "C" napi_status napi_set_property(napi_env env, napi_value target,
auto keyProp = toJS(key);
auto scope = DECLARE_CATCH_SCOPE(vm);
- object->putDirect(globalObject->vm(), keyProp.toPropertyKey(globalObject), toJS(value));
+ PutPropertySlot slot(object, true);
+ object->put(object, globalObject, keyProp.toPropertyKey(globalObject), toJS(value), slot);
RETURN_IF_EXCEPTION(scope, napi_generic_failure);
scope.clearException();
@@ -336,6 +337,10 @@ extern "C" napi_status napi_set_property(napi_env env, napi_value target,
extern "C" napi_status napi_has_property(napi_env env, napi_value object,
napi_value key, bool* result)
{
+ if (UNLIKELY(!object || !env)) {
+ return napi_invalid_arg;
+ }
+
auto globalObject = toJS(env);
auto& vm = globalObject->vm();
auto* target = toJS(object).getObject();
@@ -345,8 +350,7 @@ extern "C" napi_status napi_has_property(napi_env env, napi_value object,
auto keyProp = toJS(key);
auto scope = DECLARE_CATCH_SCOPE(vm);
- // TODO: use the slot directly?
- *result = !!target->getIfPropertyExists(globalObject, keyProp.toPropertyKey(globalObject));
+ *result = target->hasProperty(globalObject, keyProp.toPropertyKey(globalObject));
RETURN_IF_EXCEPTION(scope, napi_generic_failure);
scope.clearException();
@@ -495,6 +499,81 @@ extern "C" napi_status napi_get_named_property(napi_env env, napi_value object,
return napi_ok;
}
+#if !COMPILER(MSVC)
+__attribute__((visibility("default")))
+#endif
+extern "C" napi_status
+node_api_create_external_string_latin1(napi_env env,
+ char* str,
+ size_t length,
+ napi_finalize finalize_callback,
+ void* finalize_hint,
+ napi_value* result,
+ bool* copied)
+{
+ // https://nodejs.org/api/n-api.html#node_api_create_external_string_latin1
+ if (UNLIKELY(!str || !result)) {
+ return napi_invalid_arg;
+ }
+
+ length = length == NAPI_AUTO_LENGTH ? strlen(str) : length;
+ WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create(reinterpret_cast<LChar*>(str), static_cast<unsigned int>(length), finalize_hint, [finalize_callback](void* hint, void* str, unsigned length) {
+ if (finalize_callback) {
+ finalize_callback(reinterpret_cast<napi_env>(Bun__getDefaultGlobal()), nullptr, hint);
+ }
+ });
+ JSGlobalObject* globalObject = toJS(env);
+ // globalObject is allowed to be null here
+ if (UNLIKELY(!globalObject)) {
+ globalObject = Bun__getDefaultGlobal();
+ }
+
+ JSString* out = JSC::jsString(globalObject->vm(), WTF::String(impl));
+ ensureStillAliveHere(out);
+ *result = toNapi(out);
+ ensureStillAliveHere(out);
+
+ return napi_ok;
+}
+
+#if !COMPILER(MSVC)
+__attribute__((visibility("default")))
+#endif
+
+extern "C" napi_status
+node_api_create_external_string_utf16(napi_env env,
+ char16_t* str,
+ size_t length,
+ napi_finalize finalize_callback,
+ void* finalize_hint,
+ napi_value* result,
+ bool* copied)
+{
+ // https://nodejs.org/api/n-api.html#node_api_create_external_string_utf16
+ if (UNLIKELY(!str || !result)) {
+ return napi_invalid_arg;
+ }
+
+ length = length == NAPI_AUTO_LENGTH ? std::char_traits<char16_t>::length(str) : length;
+ WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create(reinterpret_cast<UChar*>(str), static_cast<unsigned int>(length), finalize_hint, [finalize_callback](void* hint, void* str, unsigned length) {
+ if (finalize_callback) {
+ finalize_callback(reinterpret_cast<napi_env>(Bun__getDefaultGlobal()), nullptr, hint);
+ }
+ });
+ JSGlobalObject* globalObject = toJS(env);
+ // globalObject is allowed to be null here
+ if (UNLIKELY(!globalObject)) {
+ globalObject = Bun__getDefaultGlobal();
+ }
+
+ JSString* out = JSC::jsString(globalObject->vm(), WTF::String(impl));
+ ensureStillAliveHere(out);
+ *result = toNapi(out);
+ ensureStillAliveHere(out);
+
+ return napi_ok;
+}
+
extern "C" void napi_module_register(napi_module* mod)
{
auto* globalObject = Bun__getDefaultGlobal();
@@ -1028,7 +1107,7 @@ extern "C" napi_status napi_fatal_exception(napi_env env,
napi_value err)
{
auto globalObject = toJS(env);
- JSC::JSValue value = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(err));
+ JSC::JSValue value = toJS(err);
JSC::JSObject* obj = value.getObject();
if (UNLIKELY(obj == nullptr || !obj->isErrorInstance())) {
return napi_invalid_arg;
@@ -1045,7 +1124,7 @@ extern "C" napi_status napi_throw(napi_env env, napi_value error)
JSC::VM& vm = globalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
- JSC::JSValue value = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(error));
+ JSC::JSValue value = toJS(error);
if (value) {
JSC::throwException(globalObject, throwScope, value);
} else {
@@ -1131,8 +1210,8 @@ extern "C" napi_status napi_create_type_error(napi_env env, napi_value code,
Zig::GlobalObject* globalObject = toJS(env);
JSC::VM& vm = globalObject->vm();
- JSC::JSValue codeValue = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(code));
- JSC::JSValue messageValue = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(msg));
+ JSC::JSValue codeValue = toJS(code);
+ JSC::JSValue messageValue = toJS(msg);
auto error = JSC::createTypeError(globalObject, messageValue.toWTFString(globalObject));
if (codeValue) {
@@ -1150,10 +1229,11 @@ extern "C" napi_status napi_create_error(napi_env env, napi_value code,
Zig::GlobalObject* globalObject = toJS(env);
JSC::VM& vm = globalObject->vm();
- JSC::JSValue codeValue = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(code));
- JSC::JSValue messageValue = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(msg));
+ JSC::JSValue codeValue = toJS(code);
+ JSC::JSValue messageValue = toJS(msg);
- auto error = JSC::createError(globalObject, messageValue.toWTFString(globalObject));
+ WTF::String message = messageValue.toWTFString(globalObject);
+ auto* error = JSC::createError(globalObject, message);
if (codeValue) {
error->putDirect(vm, WebCore::builtinNames(vm).codePublicName(), codeValue, 0);
}
@@ -1557,15 +1637,15 @@ extern "C" napi_status napi_define_class(napi_env env,
extern "C" napi_status napi_coerce_to_string(napi_env env, napi_value value,
napi_value* result)
{
- if (UNLIKELY(result == nullptr)) {
+ if (UNLIKELY(result == nullptr || value == nullptr || env == nullptr)) {
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
JSC::VM& vm = globalObject->vm();
- auto scope = DECLARE_CATCH_SCOPE(vm);
- JSC::JSValue jsValue = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(value));
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ JSC::JSValue jsValue = toJS(value);
JSC::EnsureStillAliveScope ensureStillAlive(jsValue);
// .toString() can throw
@@ -1588,7 +1668,7 @@ extern "C" napi_status napi_get_property_names(napi_env env, napi_value object,
Zig::GlobalObject* globalObject = toJS(env);
JSC::VM& vm = globalObject->vm();
- JSC::JSValue jsValue = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(object));
+ JSC::JSValue jsValue = toJS(object);
if (!jsValue || !jsValue.isObject()) {
return napi_invalid_arg;
}
@@ -1717,7 +1797,7 @@ extern "C" napi_status napi_get_element(napi_env env, napi_value objectValue,
uint32_t index, napi_value* result)
{
JSValue jsValue = toJS(objectValue);
- if (!jsValue || !jsValue.isObject()) {
+ if (UNLIKELY(!env || !jsValue || !jsValue.isObject())) {
return napi_invalid_arg;
}
@@ -1737,7 +1817,7 @@ extern "C" napi_status napi_get_element(napi_env env, napi_value objectValue,
extern "C" napi_status napi_create_object(napi_env env, napi_value* result)
{
- if (UNLIKELY(result == nullptr)) {
+ if (UNLIKELY(result == nullptr || env == nullptr)) {
return napi_invalid_arg;
}
diff --git a/src/bun.js/bindings/process.d.ts b/src/bun.js/bindings/process.d.ts
deleted file mode 100644
index 194ea2b6a..000000000
--- a/src/bun.js/bindings/process.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * The process object provides information about, and control over, the
- * current Bun.js process. While it is available as a global, it is
- * recommended to explicitly access it via require or import
- */
-export interface Process {
- //
-}
diff --git a/src/bun.js/bindings/sqlite/JSSQLStatement.cpp b/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
index 8519cb2e2..2ce4cc9a6 100644
--- a/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
+++ b/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
@@ -83,6 +83,11 @@ static JSC_DECLARE_CUSTOM_GETTER(jsSqlStatementGetColumnCount);
static JSC_DECLARE_HOST_FUNCTION(jsSQLStatementSerialize);
static JSC_DECLARE_HOST_FUNCTION(jsSQLStatementDeserialize);
+static inline JSC::JSValue jsNumberFromSQLite(sqlite3_stmt* stmt, unsigned int i)
+{
+ int64_t num = sqlite3_column_int64(stmt, i);
+ return num > INT_MAX || num < INT_MIN ? JSC::jsDoubleNumber(static_cast<double>(num)) : JSC::jsNumber(static_cast<int>(num));
+}
#define CHECK_THIS \
if (UNLIKELY(!castedThis)) { \
@@ -183,7 +188,7 @@ public:
JSC::JSValue rebind(JSGlobalObject* globalObject, JSC::JSValue values, bool clone);
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
- return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSFunctionType, StructureFlags), info());
}
bool need_update() { return version_db->version.load() != version; }
@@ -336,10 +341,6 @@ void JSSQLStatement::destroy(JSC::JSCell* cell)
thisObject->stmt = nullptr;
}
-void JSSQLStatementConstructor::destroy(JSC::JSCell* cell)
-{
-}
-
static inline bool rebindValue(JSC::JSGlobalObject* lexicalGlobalObject, sqlite3_stmt* stmt, int i, JSC::JSValue value, JSC::ThrowScope& scope, bool clone)
{
#define CHECK_BIND(param) \
@@ -690,6 +691,11 @@ JSC_DEFINE_HOST_FUNCTION(jsSQLStatementLoadExtensionFunction, (JSC::JSGlobalObje
return JSValue::encode(JSC::jsUndefined());
}
+ if (sqlite3_compileoption_used("SQLITE_OMIT_LOAD_EXTENSION")) {
+ throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, "This build of sqlite3 does not support dynamic extension loading"_s));
+ return JSValue::encode(JSC::jsUndefined());
+ }
+
auto entryPointStr = callFrame->argumentCount() > 2 && callFrame->argument(2).isString() ? callFrame->argument(2).toWTFString(lexicalGlobalObject) : String();
const char* entryPoint = entryPointStr.length() == 0 ? NULL : entryPointStr.utf8().data();
char* error;
@@ -1054,7 +1060,7 @@ static const HashTableValue JSSQLStatementConstructorTableValues[] = {
{ "deserialize"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSQLStatementDeserialize, 2 } },
};
-const ClassInfo JSSQLStatementConstructor::s_info = { "SQLStatement"_s, nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSSQLStatementConstructor) };
+const ClassInfo JSSQLStatementConstructor::s_info = { "SQLStatement"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSQLStatementConstructor) };
void JSSQLStatementConstructor::finishCreation(VM& vm)
{
@@ -1090,7 +1096,7 @@ static inline JSC::JSValue constructResultObject(JSC::JSGlobalObject* lexicalGlo
switch (sqlite3_column_type(stmt, i)) {
case SQLITE_INTEGER: {
// https://github.com/oven-sh/bun/issues/1536
- value = jsNumber(sqlite3_column_int64(stmt, i));
+ value = jsNumberFromSQLite(stmt, i);
break;
}
case SQLITE_FLOAT: {
@@ -1146,11 +1152,11 @@ static inline JSC::JSValue constructResultObject(JSC::JSGlobalObject* lexicalGlo
switch (sqlite3_column_type(stmt, i)) {
case SQLITE_INTEGER: {
// https://github.com/oven-sh/bun/issues/1536
- result->putDirect(vm, name, jsNumber(sqlite3_column_int64(stmt, i)), 0);
+ result->putDirect(vm, name, jsNumberFromSQLite(stmt, i), 0);
break;
}
case SQLITE_FLOAT: {
- result->putDirect(vm, name, jsNumber(sqlite3_column_double(stmt, i)), 0);
+ result->putDirect(vm, name, jsDoubleNumber(sqlite3_column_double(stmt, i)), 0);
break;
}
// > Note that the SQLITE_TEXT constant was also used in SQLite version
@@ -1205,11 +1211,11 @@ static inline JSC::JSArray* constructResultRow(JSC::JSGlobalObject* lexicalGloba
switch (sqlite3_column_type(stmt, i)) {
case SQLITE_INTEGER: {
// https://github.com/oven-sh/bun/issues/1536
- result->putDirectIndex(lexicalGlobalObject, i, jsNumber(sqlite3_column_int64(stmt, i)));
+ result->putDirectIndex(lexicalGlobalObject, i, jsNumberFromSQLite(stmt, i));
break;
}
case SQLITE_FLOAT: {
- result->putDirectIndex(lexicalGlobalObject, i, jsNumber(sqlite3_column_double(stmt, i)));
+ result->putDirectIndex(lexicalGlobalObject, i, jsDoubleNumber(sqlite3_column_double(stmt, i)));
break;
}
// > Note that the SQLITE_TEXT constant was also used in SQLite version
@@ -1251,7 +1257,6 @@ static inline JSC::JSArray* constructResultRow(JSC::JSGlobalObject* lexicalGloba
JSC_DEFINE_HOST_FUNCTION(jsSQLStatementExecuteStatementFunctionAll, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
{
-
JSC::VM& vm = lexicalGlobalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
auto castedThis = jsDynamicCast<JSSQLStatement*>(callFrame->thisValue());
@@ -1283,7 +1288,6 @@ JSC_DEFINE_HOST_FUNCTION(jsSQLStatementExecuteStatementFunctionAll, (JSC::JSGlob
size_t columnCount = castedThis->columnNames->size();
JSValue result = jsUndefined();
-
if (status == SQLITE_ROW) {
// this is a count from UPDATE or another query like that
if (columnCount == 0) {
@@ -1305,11 +1309,7 @@ JSC_DEFINE_HOST_FUNCTION(jsSQLStatementExecuteStatementFunctionAll, (JSC::JSGlob
result = resultArray;
}
} else if (status == SQLITE_DONE) {
- if (columnCount == 0) {
- result = jsNumber(sqlite3_changes(castedThis->version_db->db));
- } else {
- result = JSC::constructEmptyArray(lexicalGlobalObject, nullptr, 0);
- }
+ result = JSC::constructEmptyArray(lexicalGlobalObject, nullptr, 0);
}
if (UNLIKELY(status != SQLITE_DONE && status != SQLITE_OK)) {
@@ -1632,7 +1632,7 @@ JSC_DEFINE_HOST_FUNCTION(jsSQLStatementFunctionFinalize, (JSC::JSGlobalObject *
RELEASE_AND_RETURN(scope, JSValue::encode(jsUndefined()));
}
-const ClassInfo JSSQLStatement::s_info = { "SQLStatement"_s, nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSSQLStatement) };
+const ClassInfo JSSQLStatement::s_info = { "SQLStatement"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSQLStatement) };
/* Hash table for prototype */
static const HashTableValue JSSQLStatementTableValues[] = {
diff --git a/src/bun.js/bindings/sqlite/JSSQLStatement.h b/src/bun.js/bindings/sqlite/JSSQLStatement.h
index 8566fcdd9..b628f2a38 100644
--- a/src/bun.js/bindings/sqlite/JSSQLStatement.h
+++ b/src/bun.js/bindings/sqlite/JSSQLStatement.h
@@ -50,25 +50,15 @@ namespace WebCore {
class JSSQLStatementConstructor final : public JSC::JSFunction {
public:
using Base = JSC::JSFunction;
+ static constexpr unsigned StructureFlags = Base::StructureFlags;
+
static JSSQLStatementConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure);
DECLARE_INFO;
- template<typename, SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
- {
- if constexpr (mode == JSC::SubspaceAccess::Concurrently)
- return nullptr;
- return WebCore::subspaceForImpl<JSSQLStatementConstructor, WebCore::UseCustomHeapCellType::No>(
- vm,
- [](auto& spaces) { return spaces.m_clientSubspaceForJSSQLStatementConstructor.get(); },
- [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSSQLStatementConstructor = std::forward<decltype(space)>(space); },
- [](auto& spaces) { return spaces.m_subspaceForJSSQLStatementConstructor.get(); },
- [](auto& spaces, auto&& space) { spaces.m_subspaceForJSSQLStatementConstructor = std::forward<decltype(space)>(space); });
- }
- static void destroy(JSC::JSCell*);
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
- return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSFunctionType, StructureFlags), info());
}
private:
@@ -79,5 +69,6 @@ private:
void finishCreation(JSC::VM&);
};
+static_assert(sizeof(JSSQLStatementConstructor) == sizeof(JSFunction), "Allocate JSSQLStatementConstructor in JSFunction IsoSubspace");
} \ No newline at end of file
diff --git a/src/bun.js/bindings/sqlite/lazy_sqlite3.h b/src/bun.js/bindings/sqlite/lazy_sqlite3.h
index 8b23a7e03..a012f6ab6 100644
--- a/src/bun.js/bindings/sqlite/lazy_sqlite3.h
+++ b/src/bun.js/bindings/sqlite/lazy_sqlite3.h
@@ -71,6 +71,7 @@ typedef int (*lazy_sqlite3_deserialize_type)(
);
typedef int (*lazy_sqlite3_stmt_readonly_type)(sqlite3_stmt* pStmt);
+typedef int (*lazy_sqlite3_compileoption_used_type)(const char *zOptName);
static lazy_sqlite3_bind_blob_type lazy_sqlite3_bind_blob;
static lazy_sqlite3_bind_double_type lazy_sqlite3_bind_double;
@@ -112,6 +113,7 @@ static lazy_sqlite3_malloc64_type lazy_sqlite3_malloc64;
static lazy_sqlite3_serialize_type lazy_sqlite3_serialize;
static lazy_sqlite3_deserialize_type lazy_sqlite3_deserialize;
static lazy_sqlite3_stmt_readonly_type lazy_sqlite3_stmt_readonly;
+static lazy_sqlite3_compileoption_used_type lazy_sqlite3_compileoption_used;
#define sqlite3_bind_blob lazy_sqlite3_bind_blob
#define sqlite3_bind_double lazy_sqlite3_bind_double
@@ -152,6 +154,7 @@ static lazy_sqlite3_stmt_readonly_type lazy_sqlite3_stmt_readonly;
#define sqlite3_deserialize lazy_sqlite3_deserialize
#define sqlite3_stmt_readonly lazy_sqlite3_stmt_readonly
#define sqlite3_column_int64 lazy_sqlite3_column_int64
+#define sqlite3_compileoption_used lazy_sqlite3_compileoption_used;
static void* sqlite3_handle = nullptr;
static const char* sqlite3_lib_path = "libsqlite3.dylib";
@@ -204,6 +207,7 @@ static int lazyLoadSQLite()
lazy_sqlite3_deserialize = (lazy_sqlite3_deserialize_type)dlsym(sqlite3_handle, "sqlite3_deserialize");
lazy_sqlite3_malloc64 = (lazy_sqlite3_malloc64_type)dlsym(sqlite3_handle, "sqlite3_malloc64");
lazy_sqlite3_stmt_readonly = (lazy_sqlite3_stmt_readonly_type)dlsym(sqlite3_handle, "sqlite3_stmt_readonly");
+ lazy_sqlite3_compileoption_used = (lazy_sqlite3_compileoption_used_type)dlsym(sqlite3_handle, "sqlite3_compileoption_used");
return 0;
}
diff --git a/src/bun.js/bindings/webcore/AbortSignal.h b/src/bun.js/bindings/webcore/AbortSignal.h
index 6f4abf5ba..b60d2a6bf 100644
--- a/src/bun.js/bindings/webcore/AbortSignal.h
+++ b/src/bun.js/bindings/webcore/AbortSignal.h
@@ -45,6 +45,7 @@ class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWith
public:
static Ref<AbortSignal> create(ScriptExecutionContext*);
WEBCORE_EXPORT ~AbortSignal();
+ using NativeCallbackTuple = std::tuple<void*, void (*)(void*, JSC::EncodedJSValue)>;
static Ref<AbortSignal> abort(JSDOMGlobalObject&, ScriptExecutionContext&, JSC::JSValue reason);
static Ref<AbortSignal> timeout(ScriptExecutionContext&, uint64_t milliseconds);
@@ -66,7 +67,7 @@ public:
using Algorithm = Function<void(JSValue)>;
void addAlgorithm(Algorithm&& algorithm) { m_algorithms.append(WTFMove(algorithm)); }
void cleanNativeBindings(void* ref);
- void addNativeCallback(std::tuple<void*, void (*)(void*, JSC::EncodedJSValue)> callback) { m_native_callbacks.append(callback); }
+ void addNativeCallback(NativeCallbackTuple callback) { m_native_callbacks.append(callback); }
bool isFollowingSignal() const { return !!m_followingSignal; }
@@ -87,8 +88,8 @@ private:
void eventListenersDidChange() final;
bool m_aborted { false };
- Vector<Algorithm> m_algorithms;
- Vector<std::tuple<void*, void (*)(void*, JSC::EncodedJSValue)>> m_native_callbacks;
+ Vector<Algorithm, 2> m_algorithms;
+ Vector<NativeCallbackTuple, 2> m_native_callbacks;
WeakPtr<AbortSignal> m_followingSignal;
JSC::Strong<JSC::Unknown> m_reason;
bool m_hasActiveTimeoutTimer { false };
diff --git a/src/bun.js/bindings/webcore/JSDOMURL.cpp b/src/bun.js/bindings/webcore/JSDOMURL.cpp
index 747154bed..3f99fc2b7 100644
--- a/src/bun.js/bindings/webcore/JSDOMURL.cpp
+++ b/src/bun.js/bindings/webcore/JSDOMURL.cpp
@@ -64,6 +64,7 @@ using namespace JSC;
static JSC_DECLARE_HOST_FUNCTION(jsDOMURLPrototypeFunction_toJSON);
static JSC_DECLARE_HOST_FUNCTION(jsDOMURLConstructorFunction_createObjectURL);
static JSC_DECLARE_HOST_FUNCTION(jsDOMURLConstructorFunction_revokeObjectURL);
+static JSC_DECLARE_HOST_FUNCTION(jsDOMURLConstructorFunction_canParse);
static JSC_DECLARE_HOST_FUNCTION(jsDOMURLPrototypeFunction_toString);
// Attributes
@@ -131,6 +132,7 @@ using JSDOMURLDOMConstructor = JSDOMConstructor<JSDOMURL>;
static const HashTableValue JSDOMURLConstructorTableValues[] = {
{ "createObjectURL"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsDOMURLConstructorFunction_createObjectURL, 1 } },
{ "revokeObjectURL"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsDOMURLConstructorFunction_revokeObjectURL, 1 } },
+ { "canParse"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsDOMURLConstructorFunction_canParse, 2 } },
};
static inline EncodedJSValue constructJSDOMURL1(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
@@ -688,6 +690,33 @@ JSC_DEFINE_HOST_FUNCTION(jsDOMURLConstructorFunction_revokeObjectURL, (JSGlobalO
return IDLOperation<JSDOMURL>::callStatic<jsDOMURLConstructorFunction_revokeObjectURLBody>(*lexicalGlobalObject, *callFrame, "revokeObjectURL");
}
+static inline JSC::EncodedJSValue jsDOMURLConstructorFunction_canParseBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ if (UNLIKELY(callFrame->argumentCount() < 1))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto url = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+
+ EnsureStillAliveScope argument1 = callFrame->argument(1);
+ String base;
+ if (!argument1.value().isUndefinedOrNull()) {
+ base = convert<IDLUSVString>(*lexicalGlobalObject, argument1.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ }
+
+ return JSValue::encode(jsBoolean(DOMURL::canParse(url, base)));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsDOMURLConstructorFunction_canParse, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperation<JSDOMURL>::callStatic<jsDOMURLConstructorFunction_canParseBody>(*lexicalGlobalObject, *callFrame, "canParse");
+}
+
#if ENABLE(MEDIA_SOURCE)
static inline JSC::EncodedJSValue jsDOMURLConstructorFunction_createObjectURL2Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
{
diff --git a/src/bun.js/bindings/webcore/JSEventEmitter.cpp b/src/bun.js/bindings/webcore/JSEventEmitter.cpp
index 959cbd8d7..e81af9549 100644
--- a/src/bun.js/bindings/webcore/JSEventEmitter.cpp
+++ b/src/bun.js/bindings/webcore/JSEventEmitter.cpp
@@ -109,9 +109,10 @@ template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSEventEmitterDOMConstructor:
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, {});
- if (JSValue maxListeners = castedThis->getIfPropertyExists(lexicalGlobalObject, JSC::Identifier::fromString(vm, "defaultMaxListeners"_s))) {
- if (maxListeners.isUInt32())
- object->setMaxListeners(maxListeners.toUInt32(lexicalGlobalObject));
+ JSValue maxListeners = castedThis->getIfPropertyExists(lexicalGlobalObject, JSC::Identifier::fromString(vm, "defaultMaxListeners"_s));
+ RETURN_IF_EXCEPTION(throwScope, {});
+ if (maxListeners && maxListeners.isUInt32()) {
+ object->setMaxListeners(maxListeners.toUInt32(lexicalGlobalObject));
}
static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef);
auto jsValue = toJSNewlyCreated<IDLInterface<EventEmitter>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object));
diff --git a/src/bun.js/bindings/webcore/JSFetchHeaders.cpp b/src/bun.js/bindings/webcore/JSFetchHeaders.cpp
index 2ae8dd547..421a042e5 100644
--- a/src/bun.js/bindings/webcore/JSFetchHeaders.cpp
+++ b/src/bun.js/bindings/webcore/JSFetchHeaders.cpp
@@ -245,17 +245,11 @@ JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_getAll, (JSGlobalObject
return JSValue::encode(array);
}
-JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_getSetCookie, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+JSC_DEFINE_HOST_FUNCTION(fetchHeadersGetSetCookie, (JSC::JSGlobalObject * lexicalGlobalObject, VM& vm, WebCore::FetchHeaders* impl))
{
- auto& vm = JSC::getVM(lexicalGlobalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
- JSFetchHeaders* castedThis = jsDynamicCast<JSFetchHeaders*>(callFrame->thisValue());
- if (UNLIKELY(!castedThis)) {
- return JSValue::encode(jsUndefined());
- }
- auto& impl = castedThis->wrapped();
- auto values = impl.getSetCookieHeaders();
+ auto values = impl->getSetCookieHeaders();
unsigned count = values.size();
if (!count) {
@@ -263,20 +257,31 @@ JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_getSetCookie, (JSGlobal
}
JSC::JSArray* array = constructEmptyArray(lexicalGlobalObject, nullptr, count);
- RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
if (UNLIKELY(!array)) {
throwOutOfMemoryError(lexicalGlobalObject, scope);
- return JSValue::encode(jsUndefined());
+ return encodedJSValue();
}
for (unsigned i = 0; i < count; ++i) {
array->putDirectIndex(lexicalGlobalObject, i, jsString(vm, values[i]));
- RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
}
return JSValue::encode(array);
}
+JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_getSetCookie, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ JSFetchHeaders* castedThis = jsDynamicCast<JSFetchHeaders*>(callFrame->thisValue());
+ if (UNLIKELY(!castedThis)) {
+ return JSValue::encode(jsUndefined());
+ }
+ auto& impl = castedThis->wrapped();
+ return fetchHeadersGetSetCookie(lexicalGlobalObject, vm, &impl);
+}
+
/* Hash table for prototype */
static const HashTableValue JSFetchHeadersPrototypeTableValues[] = {
@@ -324,7 +329,7 @@ void JSFetchHeaders::finishCreation(VM& vm)
void JSFetchHeaders::computeMemoryCost()
{
m_memoryCost = wrapped().memoryCost();
- globalObject()->vm().heap.reportExtraMemoryAllocated(m_memoryCost);
+ globalObject()->vm().heap.reportExtraMemoryAllocated(this, m_memoryCost);
}
JSObject* JSFetchHeaders::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
@@ -688,7 +693,6 @@ extern void* _ZTVN7WebCore12FetchHeadersE[];
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<FetchHeaders>&& impl)
{
-
if constexpr (std::is_polymorphic_v<FetchHeaders>) {
#if ENABLE(BINDING_INTEGRITY)
const void* actualVTablePointer = getVTablePointer(impl.ptr());
diff --git a/src/bun.js/bindings/webcore/JSFetchHeaders.h b/src/bun.js/bindings/webcore/JSFetchHeaders.h
index 4efcc5f5f..58b61bbbb 100644
--- a/src/bun.js/bindings/webcore/JSFetchHeaders.h
+++ b/src/bun.js/bindings/webcore/JSFetchHeaders.h
@@ -97,4 +97,6 @@ template<> struct JSDOMWrapperConverterTraits<FetchHeaders> {
using ToWrappedReturnType = FetchHeaders*;
};
+JSC::EncodedJSValue fetchHeadersGetSetCookie(JSC::JSGlobalObject* lexicalGlobalObject, VM& vm, WebCore::FetchHeaders* impl);
+
} // namespace WebCore
diff --git a/src/bun.js/bindings/webcore/JSMessageEvent.cpp b/src/bun.js/bindings/webcore/JSMessageEvent.cpp
index 68414fe46..0a7ca6a5f 100644
--- a/src/bun.js/bindings/webcore/JSMessageEvent.cpp
+++ b/src/bun.js/bindings/webcore/JSMessageEvent.cpp
@@ -295,7 +295,7 @@ void JSMessageEvent::finishCreation(VM& vm)
// static_assert(!std::is_base_of<ActiveDOMObject, MessageEvent>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
- vm.heap.reportExtraMemoryAllocated(wrapped().memoryCost());
+ vm.heap.reportExtraMemoryAllocated(this, wrapped().memoryCost());
}
JSObject* JSMessageEvent::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
diff --git a/src/bun.js/bindings/webcore/JSReadableStream.cpp b/src/bun.js/bindings/webcore/JSReadableStream.cpp
index 3fea3d44f..0a0ef3b23 100644
--- a/src/bun.js/bindings/webcore/JSReadableStream.cpp
+++ b/src/bun.js/bindings/webcore/JSReadableStream.cpp
@@ -108,7 +108,7 @@ template<> FunctionExecutable* JSReadableStreamDOMConstructor::initializeExecuta
static const HashTableValue JSReadableStreamPrototypeTableValues[] = {
{ "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsReadableStreamConstructor, 0 } },
- { "locked"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamLockedCodeGenerator, 0 } },
+ { "locked"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinAccessorType, readableStreamLockedCodeGenerator, 0 } },
{ "cancel"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamCancelCodeGenerator, 0 } },
{ "getReader"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamGetReaderCodeGenerator, 0 } },
{ "pipeTo"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamPipeToCodeGenerator, 1 } },
diff --git a/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.cpp b/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.cpp
index fea3ffc8c..b15084041 100644
--- a/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.cpp
+++ b/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.cpp
@@ -108,7 +108,7 @@ template<> FunctionExecutable* JSReadableStreamDefaultControllerDOMConstructor::
static const HashTableValue JSReadableStreamDefaultControllerPrototypeTableValues[] = {
{ "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsReadableStreamDefaultControllerConstructor, 0 } },
- { "desiredSize"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamDefaultControllerDesiredSizeCodeGenerator, 0 } },
+ { "desiredSize"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinAccessorType, readableStreamDefaultControllerDesiredSizeCodeGenerator, 0 } },
{ "enqueue"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamDefaultControllerEnqueueCodeGenerator, 0 } },
{ "close"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamDefaultControllerCloseCodeGenerator, 0 } },
{ "error"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamDefaultControllerErrorCodeGenerator, 0 } },
diff --git a/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.cpp b/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.cpp
index 55b89ad46..68b587a92 100644
--- a/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.cpp
+++ b/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.cpp
@@ -108,7 +108,7 @@ template<> FunctionExecutable* JSReadableStreamDefaultReaderDOMConstructor::init
static const HashTableValue JSReadableStreamDefaultReaderPrototypeTableValues[] = {
{ "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsReadableStreamDefaultReaderConstructor, 0 } },
- { "closed"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamDefaultReaderClosedCodeGenerator, 0 } },
+ { "closed"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinAccessorType, readableStreamDefaultReaderClosedCodeGenerator, 0 } },
{ "read"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamDefaultReaderReadCodeGenerator, 0 } },
{ "readMany"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamDefaultReaderReadManyCodeGenerator, 0 } },
{ "cancel"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, readableStreamDefaultReaderCancelCodeGenerator, 0 } },
diff --git a/src/bun.js/bindings/webcore/JSURLSearchParams.cpp b/src/bun.js/bindings/webcore/JSURLSearchParams.cpp
index 0d401fa00..4c0f0e912 100644
--- a/src/bun.js/bindings/webcore/JSURLSearchParams.cpp
+++ b/src/bun.js/bindings/webcore/JSURLSearchParams.cpp
@@ -182,6 +182,7 @@ static const HashTableValue JSURLSearchParamsPrototypeTableValues[] = {
{ "toString"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsURLSearchParamsPrototypeFunction_toString, 0 } },
{ "toJSON"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsURLSearchParamsPrototypeFunction_toJSON, 0 } },
{ "length"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsURLSearchParamsPrototype_getLength, 0 } },
+ { "size"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsURLSearchParamsPrototype_getLength, 0 } },
};
const ClassInfo JSURLSearchParamsPrototype::s_info = { "URLSearchParams"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSURLSearchParamsPrototype) };
diff --git a/src/bun.js/bindings/webcore/MessagePort.cpp b/src/bun.js/bindings/webcore/MessagePort.cpp
index da2bd32e8..b463791df 100644
--- a/src/bun.js/bindings/webcore/MessagePort.cpp
+++ b/src/bun.js/bindings/webcore/MessagePort.cpp
@@ -141,7 +141,7 @@ MessagePort::MessagePort(ScriptExecutionContext& scriptExecutionContext, const M
, m_identifier(local)
, m_remoteIdentifier(remote)
{
- LOG(MessagePorts, "Created MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, ProcessIdent::identifier().toUInt64());
+ // LOG(MessagePorts, "Created MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, ProcessIdent::identifier().toUInt64());
Locker locker { allMessagePortsLock };
allMessagePorts().set(m_identifier, this);
@@ -157,7 +157,7 @@ MessagePort::MessagePort(ScriptExecutionContext& scriptExecutionContext, const M
MessagePort::~MessagePort()
{
- LOG(MessagePorts, "Destroyed MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, ProcessIdent::identifier().toUInt64());
+ // LOG(MessagePorts, "Destroyed MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, ProcessIdent::identifier().toUInt64());
ASSERT(allMessagePortsLock.isLocked());
@@ -175,7 +175,7 @@ void MessagePort::entangle()
ExceptionOr<void> MessagePort::postMessage(JSC::JSGlobalObject& state, JSC::JSValue messageValue, StructuredSerializeOptions&& options)
{
- LOG(MessagePorts, "Attempting to post message to port %s (to be received by port %s)", m_identifier.logString().utf8().data(), m_remoteIdentifier.logString().utf8().data());
+ // LOG(MessagePorts, "Attempting to post message to port %s (to be received by port %s)", m_identifier.logString().utf8().data(), m_remoteIdentifier.logString().utf8().data());
Vector<RefPtr<MessagePort>> ports;
auto messageData = SerializedScriptValue::create(state, messageValue, WTFMove(options.transfer), ports, SerializationForStorage::No, SerializationContext::WorkerPostMessage);
@@ -202,7 +202,7 @@ ExceptionOr<void> MessagePort::postMessage(JSC::JSGlobalObject& state, JSC::JSVa
MessageWithMessagePorts message { messageData.releaseReturnValue(), WTFMove(transferredPorts) };
- LOG(MessagePorts, "Actually posting message to port %s (to be received by port %s)", m_identifier.logString().utf8().data(), m_remoteIdentifier.logString().utf8().data());
+ // LOG(MessagePorts, "Actually posting message to port %s (to be received by port %s)", m_identifier.logString().utf8().data(), m_remoteIdentifier.logString().utf8().data());
ScriptExecutionContextIdentifier contextId = contextIdForMessagePortId(m_remoteIdentifier);
@@ -280,7 +280,7 @@ void MessagePort::dispatchMessages()
auto messagesTakenHandler = [this, protectedThis = Ref { *this }](Vector<MessageWithMessagePorts>&& messages, CompletionHandler<void()>&& completionCallback) mutable {
auto scopeExit = makeScopeExit(WTFMove(completionCallback));
- LOG(MessagePorts, "MessagePort %s (%p) dispatching %zu messages", m_identifier.logString().utf8().data(), this, messages.size());
+ // LOG(MessagePorts, "MessagePort %s (%p) dispatching %zu messages", m_identifier.logString().utf8().data(), this, messages.size());
auto* context = scriptExecutionContext();
if (!context || !context->jsGlobalObject())
@@ -382,7 +382,7 @@ ExceptionOr<Vector<TransferredMessagePort>> MessagePort::disentanglePorts(Vector
Vector<RefPtr<MessagePort>> MessagePort::entanglePorts(ScriptExecutionContext& context, Vector<TransferredMessagePort>&& transferredPorts)
{
- LOG(MessagePorts, "Entangling %zu transferred ports to ScriptExecutionContext %s (%p)", transferredPorts.size(), context.url().string().utf8().data(), &context);
+ // LOG(MessagePorts, "Entangling %zu transferred ports to ScriptExecutionContext %s (%p)", transferredPorts.size(), context.url().string().utf8().data(), &context);
if (transferredPorts.isEmpty())
return {};
diff --git a/src/bun.js/bindings/webcore/MessagePortChannel.cpp b/src/bun.js/bindings/webcore/MessagePortChannel.cpp
index 031679204..425fb8c11 100644
--- a/src/bun.js/bindings/webcore/MessagePortChannel.cpp
+++ b/src/bun.js/bindings/webcore/MessagePortChannel.cpp
@@ -75,7 +75,7 @@ void MessagePortChannel::entanglePortWithProcess(const MessagePortIdentifier& po
ASSERT(port == m_ports[0] || port == m_ports[1]);
size_t i = port == m_ports[0] ? 0 : 1;
- LOG(MessagePorts, "MessagePortChannel %s (%p) entangling port %s (that port has %zu messages available)", logString().utf8().data(), this, port.logString().utf8().data(), m_pendingMessages[i].size());
+ // LOG(MessagePorts, "MessagePortChannel %s (%p) entangling port %s (that port has %zu messages available)", logString().utf8().data(), this, port.logString().utf8().data(), m_pendingMessages[i].size());
ASSERT(!m_processes[i] || *m_processes[i] == process);
m_processes[i] = process;
@@ -85,7 +85,7 @@ void MessagePortChannel::entanglePortWithProcess(const MessagePortIdentifier& po
void MessagePortChannel::disentanglePort(const MessagePortIdentifier& port)
{
- LOG(MessagePorts, "MessagePortChannel %s (%p) disentangling port %s", logString().utf8().data(), this, port.logString().utf8().data());
+ // LOG(MessagePorts, "MessagePortChannel %s (%p) disentangling port %s", logString().utf8().data(), this, port.logString().utf8().data());
ASSERT(port == m_ports[0] || port == m_ports[1]);
size_t i = port == m_ports[0] ? 0 : 1;
@@ -123,7 +123,7 @@ bool MessagePortChannel::postMessageToRemote(MessageWithMessagePorts&& message,
size_t i = remoteTarget == m_ports[0] ? 0 : 1;
m_pendingMessages[i].append(WTFMove(message));
- LOG(MessagePorts, "MessagePortChannel %s (%p) now has %zu messages pending on port %s", logString().utf8().data(), this, m_pendingMessages[i].size(), remoteTarget.logString().utf8().data());
+ // LOG(MessagePorts, "MessagePortChannel %s (%p) now has %zu messages pending on port %s", logString().utf8().data(), this, m_pendingMessages[i].size(), remoteTarget.logString().utf8().data());
if (m_pendingMessages[i].size() == 1) {
m_pendingMessageProtectors[i] = this;
@@ -136,7 +136,7 @@ bool MessagePortChannel::postMessageToRemote(MessageWithMessagePorts&& message,
void MessagePortChannel::takeAllMessagesForPort(const MessagePortIdentifier& port, CompletionHandler<void(Vector<MessageWithMessagePorts>&&, CompletionHandler<void()>&&)>&& callback)
{
- LOG(MessagePorts, "MessagePortChannel %p taking all messages for port %s", this, port.logString().utf8().data());
+ // LOG(MessagePorts, "MessagePortChannel %p taking all messages for port %s", this, port.logString().utf8().data());
ASSERT(port == m_ports[0] || port == m_ports[1]);
size_t i = port == m_ports[0] ? 0 : 1;
@@ -153,7 +153,7 @@ void MessagePortChannel::takeAllMessagesForPort(const MessagePortIdentifier& por
++m_messageBatchesInFlight;
- LOG(MessagePorts, "There are %zu messages to take for port %s. Taking them now, messages in flight is now %" PRIu64, result.size(), port.logString().utf8().data(), m_messageBatchesInFlight);
+ // LOG(MessagePorts, "There are %zu messages to take for port %s. Taking them now, messages in flight is now %" PRIu64, result.size(), port.logString().utf8().data(), m_messageBatchesInFlight);
auto size = result.size();
callback(WTFMove(result), [size, this, port, protectedThis = WTFMove(m_pendingMessageProtectors[i])] {
@@ -162,7 +162,7 @@ void MessagePortChannel::takeAllMessagesForPort(const MessagePortIdentifier& por
UNUSED_PARAM(size);
#endif
--m_messageBatchesInFlight;
- LOG(MessagePorts, "Message port channel %s was notified that a batch of %zu message port messages targeted for port %s just completed dispatch, in flight is now %" PRIu64, logString().utf8().data(), size, port.logString().utf8().data(), m_messageBatchesInFlight);
+ // LOG(MessagePorts, "Message port channel %s was notified that a batch of %zu message port messages targeted for port %s just completed dispatch, in flight is now %" PRIu64, logString().utf8().data(), size, port.logString().utf8().data(), m_messageBatchesInFlight);
});
}
diff --git a/src/bun.js/bindings/webcore/MessagePortChannelProvider.cpp b/src/bun.js/bindings/webcore/MessagePortChannelProvider.cpp
index 7675a2e75..cde0d0dd4 100644
--- a/src/bun.js/bindings/webcore/MessagePortChannelProvider.cpp
+++ b/src/bun.js/bindings/webcore/MessagePortChannelProvider.cpp
@@ -38,7 +38,8 @@ static MessagePortChannelProviderImpl* globalProvider;
MessagePortChannelProvider& MessagePortChannelProvider::singleton()
{
- ASSERT(isMainThread());
+ // TODO: I think this assertion is relevant. Bun will call this on the Worker's thread
+ // ASSERT(isMainThread());
static std::once_flag onceFlag;
std::call_once(onceFlag, [] {
if (!globalProvider)
diff --git a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp
index 5096357f2..a92262f63 100644
--- a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp
+++ b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp
@@ -30,6 +30,9 @@
#include <wtf/CompletionHandler.h>
#include <wtf/MainThread.h>
+// ASSERT(isMainThread()) is used alot here, and I think it may be required, but i'm not 100% sure.
+// we totally are calling these off the main thread in many cases in Bun, so ........
+
namespace WebCore {
MessagePortChannelRegistry::MessagePortChannelRegistry() = default;
@@ -41,15 +44,15 @@ MessagePortChannelRegistry::~MessagePortChannelRegistry()
void MessagePortChannelRegistry::didCreateMessagePortChannel(const MessagePortIdentifier& port1, const MessagePortIdentifier& port2)
{
- LOG(MessagePorts, "Registry: Creating MessagePortChannel %p linking %s and %s", this, port1.logString().utf8().data(), port2.logString().utf8().data());
- ASSERT(isMainThread());
+ // LOG(MessagePorts, "Registry: Creating MessagePortChannel %p linking %s and %s", this, port1.logString().utf8().data(), port2.logString().utf8().data());
+ // ASSERT(isMainThread());
MessagePortChannel::create(*this, port1, port2);
}
void MessagePortChannelRegistry::messagePortChannelCreated(MessagePortChannel& channel)
{
- ASSERT(isMainThread());
+ // ASSERT(isMainThread());
auto result = m_openChannels.ensure(channel.port1(), [channel = &channel] {
return channel;
@@ -64,7 +67,7 @@ void MessagePortChannelRegistry::messagePortChannelCreated(MessagePortChannel& c
void MessagePortChannelRegistry::messagePortChannelDestroyed(MessagePortChannel& channel)
{
- ASSERT(isMainThread());
+ // ASSERT(isMainThread());
ASSERT(m_openChannels.get(channel.port1()) == &channel);
ASSERT(m_openChannels.get(channel.port2()) == &channel);
@@ -72,12 +75,12 @@ void MessagePortChannelRegistry::messagePortChannelDestroyed(MessagePortChannel&
m_openChannels.remove(channel.port1());
m_openChannels.remove(channel.port2());
- LOG(MessagePorts, "Registry: After removing channel %s there are %u channels left in the registry:", channel.logString().utf8().data(), m_openChannels.size());
+ // LOG(MessagePorts, "Registry: After removing channel %s there are %u channels left in the registry:", channel.logString().utf8().data(), m_openChannels.size());
}
void MessagePortChannelRegistry::didEntangleLocalToRemote(const MessagePortIdentifier& local, const MessagePortIdentifier& remote, ProcessIdentifier process)
{
- ASSERT(isMainThread());
+ // ASSERT(isMainThread());
// The channel might be gone if the remote side was closed.
auto* channel = m_openChannels.get(local);
@@ -91,7 +94,7 @@ void MessagePortChannelRegistry::didEntangleLocalToRemote(const MessagePortIdent
void MessagePortChannelRegistry::didDisentangleMessagePort(const MessagePortIdentifier& port)
{
- ASSERT(isMainThread());
+ // ASSERT(isMainThread());
// The channel might be gone if the remote side was closed.
auto* channel = m_openChannels.get(port);
@@ -103,17 +106,17 @@ void MessagePortChannelRegistry::didDisentangleMessagePort(const MessagePortIden
void MessagePortChannelRegistry::didCloseMessagePort(const MessagePortIdentifier& port)
{
- ASSERT(isMainThread());
+ // ASSERT(isMainThread());
- LOG(MessagePorts, "Registry: MessagePort %s closed in registry", port.logString().utf8().data());
+ // LOG(MessagePorts, "Registry: MessagePort %s closed in registry", port.logString().utf8().data());
auto* channel = m_openChannels.get(port);
if (!channel)
return;
#ifndef NDEBUG
- if (channel && channel->hasAnyMessagesPendingOrInFlight())
- LOG(MessagePorts, "Registry: (Note) The channel closed for port %s had messages pending or in flight", port.logString().utf8().data());
+ // if (channel && channel->hasAnyMessagesPendingOrInFlight())
+ // LOG(MessagePorts, "Registry: (Note) The channel closed for port %s had messages pending or in flight", port.logString().utf8().data());
#endif
channel->closePort(port);
@@ -124,14 +127,14 @@ void MessagePortChannelRegistry::didCloseMessagePort(const MessagePortIdentifier
bool MessagePortChannelRegistry::didPostMessageToRemote(MessageWithMessagePorts&& message, const MessagePortIdentifier& remoteTarget)
{
- ASSERT(isMainThread());
+ // ASSERT(isMainThread());
- LOG(MessagePorts, "Registry: Posting message to MessagePort %s in registry", remoteTarget.logString().utf8().data());
+ // LOG(MessagePorts, "Registry: Posting message to MessagePort %s in registry", remoteTarget.logString().utf8().data());
// The channel might be gone if the remote side was closed.
auto* channel = m_openChannels.get(remoteTarget);
if (!channel) {
- LOG(MessagePorts, "Registry: Could not find MessagePortChannel for port %s; It was probably closed. Message will be dropped.", remoteTarget.logString().utf8().data());
+ // LOG(MessagePorts, "Registry: Could not find MessagePortChannel for port %s; It was probably closed. Message will be dropped.", remoteTarget.logString().utf8().data());
return false;
}
@@ -140,9 +143,9 @@ bool MessagePortChannelRegistry::didPostMessageToRemote(MessageWithMessagePorts&
void MessagePortChannelRegistry::takeAllMessagesForPort(const MessagePortIdentifier& port, CompletionHandler<void(Vector<MessageWithMessagePorts>&&, CompletionHandler<void()>&&)>&& callback)
{
- ASSERT(isMainThread());
+ // ASSERT(isMainThread());
- LOG(MessagePorts, "Registry: Taking all messages for MessagePort %s", port.logString().utf8().data());
+ // LOG(MessagePorts, "Registry: Taking all messages for MessagePort %s", port.logString().utf8().data());
// The channel might be gone if the remote side was closed.
auto* channel = m_openChannels.get(port);
@@ -156,9 +159,9 @@ void MessagePortChannelRegistry::takeAllMessagesForPort(const MessagePortIdentif
std::optional<MessageWithMessagePorts> MessagePortChannelRegistry::tryTakeMessageForPort(const MessagePortIdentifier& port)
{
- ASSERT(isMainThread());
+ // ASSERT(isMainThread());
- LOG(MessagePorts, "Registry: Trying to take a message for MessagePort %s", port.logString().utf8().data());
+ // LOG(MessagePorts, "Registry: Trying to take a message for MessagePort %s", port.logString().utf8().data());
// The channel might be gone if the remote side was closed.
auto* channel = m_openChannels.get(port);
@@ -170,7 +173,7 @@ std::optional<MessageWithMessagePorts> MessagePortChannelRegistry::tryTakeMessag
MessagePortChannel* MessagePortChannelRegistry::existingChannelContainingPort(const MessagePortIdentifier& port)
{
- ASSERT(isMainThread());
+ // ASSERT(isMainThread());
return m_openChannels.get(port);
}
diff --git a/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp b/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp
index ca8c79aef..5c8f4fbea 100644
--- a/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp
+++ b/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp
@@ -35,6 +35,16 @@
#include "JavaScriptCore/JSArrayBuffer.h"
+extern "C" Zig::GlobalObject* Bun__getDefaultGlobal();
+static inline WebCore::JSDOMGlobalObject* getDefaultGlobal(JSC::JSGlobalObject* lexicalGlobalObject)
+{
+ if (auto* global = jsDynamicCast<WebCore::JSDOMGlobalObject*>(lexicalGlobalObject)) {
+ return global;
+ }
+
+ return Bun__getDefaultGlobal();
+}
+
namespace WebCore {
WebCoreTypedArrayController::WebCoreTypedArrayController(bool allowAtomicsWait)
@@ -46,7 +56,7 @@ WebCoreTypedArrayController::~WebCoreTypedArrayController() = default;
JSC::JSArrayBuffer* WebCoreTypedArrayController::toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSGlobalObject* globalObject, JSC::ArrayBuffer* buffer)
{
- return JSC::jsCast<JSC::JSArrayBuffer*>(WebCore::toJS(lexicalGlobalObject, JSC::jsCast<JSDOMGlobalObject*>(globalObject), buffer));
+ return JSC::jsCast<JSC::JSArrayBuffer*>(WebCore::toJS(lexicalGlobalObject, getDefaultGlobal(globalObject), buffer));
}
void WebCoreTypedArrayController::registerWrapper(JSC::JSGlobalObject* globalObject, JSC::ArrayBuffer* native, JSC::JSArrayBuffer* wrapper)
diff --git a/src/bun.js/bindings/webcore/WebSocket.cpp b/src/bun.js/bindings/webcore/WebSocket.cpp
index c1a4054f5..4f7f933c5 100644
--- a/src/bun.js/bindings/webcore/WebSocket.cpp
+++ b/src/bun.js/bindings/webcore/WebSocket.cpp
@@ -161,7 +161,6 @@ WebSocket::WebSocket(ScriptExecutionContext& context)
{
m_state = CONNECTING;
m_hasPendingActivity.store(true);
- ref();
}
WebSocket::~WebSocket()
@@ -650,7 +649,7 @@ ExceptionOr<void> WebSocket::close(std::optional<unsigned short> optionalCode, c
ExceptionOr<void> WebSocket::terminate()
{
- LOG(Network, "WebSocket %p terminate()", this);
+ // LOG(Network, "WebSocket %p terminate()", this);
if (m_state == CLOSING || m_state == CLOSED)
return {};
@@ -692,7 +691,7 @@ ExceptionOr<void> WebSocket::terminate()
ExceptionOr<void> WebSocket::ping()
{
auto message = WTF::String::number(WTF::jsCurrentTime());
- LOG(Network, "WebSocket %p ping() Sending Timestamp '%s'", this, message.data());
+ // LOG(Network, "WebSocket %p ping() Sending Timestamp '%s'", this, message.data());
if (m_state == CONNECTING)
return Exception { InvalidStateError };
@@ -711,7 +710,7 @@ ExceptionOr<void> WebSocket::ping()
ExceptionOr<void> WebSocket::ping(const String& message)
{
- LOG(Network, "WebSocket %p ping() Sending String '%s'", this, message.utf8().data());
+ // LOG(Network, "WebSocket %p ping() Sending String '%s'", this, message.utf8().data());
if (m_state == CONNECTING)
return Exception { InvalidStateError };
@@ -731,7 +730,7 @@ ExceptionOr<void> WebSocket::ping(const String& message)
ExceptionOr<void> WebSocket::ping(ArrayBuffer& binaryData)
{
- LOG(Network, "WebSocket %p ping() Sending ArrayBuffer %p", this, &binaryData);
+ // LOG(Network, "WebSocket %p ping() Sending ArrayBuffer %p", this, &binaryData);
if (m_state == CONNECTING)
return Exception { InvalidStateError };
@@ -751,7 +750,7 @@ ExceptionOr<void> WebSocket::ping(ArrayBuffer& binaryData)
ExceptionOr<void> WebSocket::ping(ArrayBufferView& arrayBufferView)
{
- LOG(Network, "WebSocket %p ping() Sending ArrayBufferView %p", this, &arrayBufferView);
+ // LOG(Network, "WebSocket %p ping() Sending ArrayBufferView %p", this, &arrayBufferView);
if (m_state == CONNECTING)
return Exception { InvalidStateError };
@@ -774,7 +773,7 @@ ExceptionOr<void> WebSocket::ping(ArrayBufferView& arrayBufferView)
ExceptionOr<void> WebSocket::pong()
{
auto message = WTF::String::number(WTF::jsCurrentTime());
- LOG(Network, "WebSocket %p pong() Sending Timestamp '%s'", this, message.data());
+ // LOG(Network, "WebSocket %p pong() Sending Timestamp '%s'", this, message.data());
if (m_state == CONNECTING)
return Exception { InvalidStateError };
@@ -793,7 +792,7 @@ ExceptionOr<void> WebSocket::pong()
ExceptionOr<void> WebSocket::pong(const String& message)
{
- LOG(Network, "WebSocket %p pong() Sending String '%s'", this, message.utf8().data());
+ // LOG(Network, "WebSocket %p pong() Sending String '%s'", this, message.utf8().data());
if (m_state == CONNECTING)
return Exception { InvalidStateError };
@@ -813,7 +812,7 @@ ExceptionOr<void> WebSocket::pong(const String& message)
ExceptionOr<void> WebSocket::pong(ArrayBuffer& binaryData)
{
- LOG(Network, "WebSocket %p pong() Sending ArrayBuffer %p", this, &binaryData);
+ // LOG(Network, "WebSocket %p pong() Sending ArrayBuffer %p", this, &binaryData);
if (m_state == CONNECTING)
return Exception { InvalidStateError };
@@ -833,7 +832,7 @@ ExceptionOr<void> WebSocket::pong(ArrayBuffer& binaryData)
ExceptionOr<void> WebSocket::pong(ArrayBufferView& arrayBufferView)
{
- LOG(Network, "WebSocket %p pong() Sending ArrayBufferView %p", this, &arrayBufferView);
+ // LOG(Network, "WebSocket %p pong() Sending ArrayBufferView %p", this, &arrayBufferView);
if (m_state == CONNECTING)
return Exception { InvalidStateError };
@@ -1431,7 +1430,7 @@ extern "C" void WebSocket__didAbruptClose(WebCore::WebSocket* webSocket, int32_t
{
webSocket->didFailWithErrorCode(errorCode);
}
-extern "C" void WebSocket__didClose(WebCore::WebSocket* webSocket, uint16_t errorCode, const BunString *reason)
+extern "C" void WebSocket__didClose(WebCore::WebSocket* webSocket, uint16_t errorCode, const BunString* reason)
{
WTF::String wtf_reason = Bun::toWTFString(*reason);
webSocket->didClose(0, errorCode, WTFMove(wtf_reason));
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyAES.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyAES.cpp
index 17cbf48d9..ce23ce5dd 100644
--- a/src/bun.js/bindings/webcrypto/CryptoKeyAES.cpp
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyAES.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "CryptoKeyAES.h"
-
+#include "../wtf-bindings.h"
#if ENABLE(WEB_CRYPTO)
#include "CryptoAesKeyAlgorithm.h"
@@ -107,7 +107,7 @@ JsonWebKey CryptoKeyAES::exportJwk() const
{
JsonWebKey result;
result.kty = "oct"_s;
- result.k = base64URLEncodeToString(m_key);
+ result.k = Bun::base64URLEncodeToString(m_key);
result.key_ops = usages();
result.ext = extractable();
return result;
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyEC.h b/src/bun.js/bindings/webcrypto/CryptoKeyEC.h
index f2cf7383f..8e8f5eb35 100644
--- a/src/bun.js/bindings/webcrypto/CryptoKeyEC.h
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyEC.h
@@ -91,6 +91,8 @@ public:
String namedCurveString() const;
PlatformECKey platformKey() const { return m_platformKey.get(); }
static bool isValidECAlgorithm(CryptoAlgorithmIdentifier);
+ static RefPtr<CryptoKeyEC> platformImportSpki(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyEC> platformImportPkcs8(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
private:
CryptoKeyEC(CryptoAlgorithmIdentifier, NamedCurve, CryptoKeyType, PlatformECKeyContainer&&, bool extractable, CryptoKeyUsageBitmap);
@@ -104,8 +106,6 @@ private:
static RefPtr<CryptoKeyEC> platformImportRaw(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
static RefPtr<CryptoKeyEC> platformImportJWKPublic(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, bool extractable, CryptoKeyUsageBitmap);
static RefPtr<CryptoKeyEC> platformImportJWKPrivate(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, Vector<uint8_t>&& d, bool extractable, CryptoKeyUsageBitmap);
- static RefPtr<CryptoKeyEC> platformImportSpki(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
- static RefPtr<CryptoKeyEC> platformImportPkcs8(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
Vector<uint8_t> platformExportRaw() const;
bool platformAddFieldElements(JsonWebKey&) const;
Vector<uint8_t> platformExportSpki() const;
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyECOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyECOpenSSL.cpp
index bb5dc5e62..c2b363b32 100644
--- a/src/bun.js/bindings/webcrypto/CryptoKeyECOpenSSL.cpp
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyECOpenSSL.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "CryptoKeyEC.h"
+#include "../wtf-bindings.h"
#if ENABLE(WEB_CRYPTO)
@@ -408,15 +409,15 @@ bool CryptoKeyEC::platformAddFieldElements(JsonWebKey& jwk) const
auto x = BIGNUMPtr(BN_new());
auto y = BIGNUMPtr(BN_new());
if (1 == EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key), publicKey, x.get(), y.get(), ctx.get())) {
- jwk.x = base64URLEncodeToString(convertToBytesExpand(x.get(), keySizeInBytes));
- jwk.y = base64URLEncodeToString(convertToBytesExpand(y.get(), keySizeInBytes));
+ jwk.x = Bun::base64URLEncodeToString(convertToBytesExpand(x.get(), keySizeInBytes));
+ jwk.y = Bun::base64URLEncodeToString(convertToBytesExpand(y.get(), keySizeInBytes));
}
}
if (type() == Type::Private) {
const BIGNUM* privateKey = EC_KEY_get0_private_key(key);
if (privateKey)
- jwk.d = base64URLEncodeToString(convertToBytes(privateKey));
+ jwk.d = Bun::base64URLEncodeToString(convertToBytes(privateKey));
}
return true;
}
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.cpp
index aafb3b2fe..9428998cb 100644
--- a/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.cpp
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "CryptoKeyHMAC.h"
+#include "../wtf-bindings.h"
#if ENABLE(WEB_CRYPTO)
@@ -69,6 +70,13 @@ CryptoKeyHMAC::CryptoKeyHMAC(Vector<uint8_t>&& key, CryptoAlgorithmIdentifier ha
CryptoKeyHMAC::~CryptoKeyHMAC() = default;
+
+RefPtr<CryptoKeyHMAC> CryptoKeyHMAC::generateFromBytes(void* data, size_t byteLength, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap usages) {
+
+ Vector<uint8_t> vec_data((uint8_t*)data, byteLength);
+ return adoptRef(new CryptoKeyHMAC(vec_data, hash, extractable, usages));
+}
+
RefPtr<CryptoKeyHMAC> CryptoKeyHMAC::generate(size_t lengthBits, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap usages)
{
if (!lengthBits) {
@@ -118,11 +126,13 @@ RefPtr<CryptoKeyHMAC> CryptoKeyHMAC::importJwk(size_t lengthBits, CryptoAlgorith
return CryptoKeyHMAC::importRaw(lengthBits, hash, WTFMove(*octetSequence), extractable, usages);
}
+
JsonWebKey CryptoKeyHMAC::exportJwk() const
-{
+{
+
JsonWebKey result;
result.kty = "oct"_s;
- result.k = base64URLEncodeToString(m_key);
+ result.k = Bun::base64URLEncodeToString(m_key);
result.key_ops = usages();
result.ext = extractable();
return result;
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.h b/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.h
index 0c7ba38cb..714888019 100644
--- a/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.h
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.h
@@ -43,9 +43,11 @@ public:
{
return adoptRef(*new CryptoKeyHMAC(key, hash, extractable, usage));
}
+
virtual ~CryptoKeyHMAC();
static RefPtr<CryptoKeyHMAC> generate(size_t lengthBits, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyHMAC> generateFromBytes(void* data, size_t byteLength, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap);
static RefPtr<CryptoKeyHMAC> importRaw(size_t lengthBits, CryptoAlgorithmIdentifier hash, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
using CheckAlgCallback = Function<bool(CryptoAlgorithmIdentifier, const String&)>;
static RefPtr<CryptoKeyHMAC> importJwk(size_t lengthBits, CryptoAlgorithmIdentifier hash, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap, CheckAlgCallback&&);
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyOKP.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyOKP.cpp
index b7dc55018..4b5d8d588 100644
--- a/src/bun.js/bindings/webcrypto/CryptoKeyOKP.cpp
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyOKP.cpp
@@ -119,14 +119,13 @@ RefPtr<CryptoKeyOKP> CryptoKeyOKP::importRaw(CryptoAlgorithmIdentifier identifie
return create(identifier, namedCurve, usages & CryptoKeyUsageSign ? CryptoKeyType::Private : CryptoKeyType::Public, WTFMove(keyData), extractable, usages);
}
-RefPtr<CryptoKeyOKP> CryptoKeyOKP::importJwk(CryptoAlgorithmIdentifier identifier, NamedCurve namedCurve, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
-{
+RefPtr<CryptoKeyOKP> CryptoKeyOKP::importJwkInternal(CryptoAlgorithmIdentifier identifier, NamedCurve namedCurve, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages, bool onlyPublic) {
if (!isPlatformSupportedCurve(namedCurve))
return nullptr;
switch (namedCurve) {
case NamedCurve::Ed25519:
- if (!keyData.d.isEmpty()) {
+ if (!keyData.d.isEmpty() && !onlyPublic) {
if (usages & (CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageVerify | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey))
return nullptr;
} else {
@@ -137,8 +136,6 @@ RefPtr<CryptoKeyOKP> CryptoKeyOKP::importJwk(CryptoAlgorithmIdentifier identifie
return nullptr;
if (keyData.crv != "Ed25519"_s)
return nullptr;
- if (!keyData.alg.isEmpty() && keyData.alg != "EdDSA"_s)
- return nullptr;
if (usages && !keyData.use.isEmpty() && keyData.use != "sig"_s)
return nullptr;
if (keyData.key_ops && ((keyData.usages & usages) != usages))
@@ -153,12 +150,14 @@ RefPtr<CryptoKeyOKP> CryptoKeyOKP::importJwk(CryptoAlgorithmIdentifier identifie
break;
}
- if (!keyData.d.isNull()) {
- // FIXME: Validate keyData.x is paired with keyData.d
- auto d = base64URLDecode(keyData.d);
- if (!d)
- return nullptr;
- return create(identifier, namedCurve, CryptoKeyType::Private, WTFMove(*d), extractable, usages);
+ if(!onlyPublic){
+ if (!keyData.d.isNull()) {
+ // FIXME: Validate keyData.x is paired with keyData.d
+ auto d = base64URLDecode(keyData.d);
+ if (!d)
+ return nullptr;
+ return create(identifier, namedCurve, CryptoKeyType::Private, WTFMove(*d), extractable, usages);
+ }
}
if (keyData.x.isNull())
@@ -168,6 +167,14 @@ RefPtr<CryptoKeyOKP> CryptoKeyOKP::importJwk(CryptoAlgorithmIdentifier identifie
if (!x)
return nullptr;
return create(identifier, namedCurve, CryptoKeyType::Public, WTFMove(*x), extractable, usages);
+}
+
+RefPtr<CryptoKeyOKP> CryptoKeyOKP::importPublicJwk(CryptoAlgorithmIdentifier identifier, NamedCurve namedCurve, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages) {
+ return importJwkInternal(identifier, namedCurve, WTFMove(keyData), extractable, usages, true);
+}
+RefPtr<CryptoKeyOKP> CryptoKeyOKP::importJwk(CryptoAlgorithmIdentifier identifier, NamedCurve namedCurve, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ return importJwkInternal(identifier, namedCurve, WTFMove(keyData), extractable, usages, false);
}
ExceptionOr<Vector<uint8_t>> CryptoKeyOKP::exportRaw() const
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyOKP.h b/src/bun.js/bindings/webcrypto/CryptoKeyOKP.h
index cc1fe2c73..4d521227f 100644
--- a/src/bun.js/bindings/webcrypto/CryptoKeyOKP.h
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyOKP.h
@@ -48,6 +48,7 @@ public:
WEBCORE_EXPORT static ExceptionOr<CryptoKeyPair> generatePair(CryptoAlgorithmIdentifier, NamedCurve, bool extractable, CryptoKeyUsageBitmap);
WEBCORE_EXPORT static RefPtr<CryptoKeyOKP> importRaw(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyOKP> importPublicJwk(CryptoAlgorithmIdentifier, NamedCurve, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap);
static RefPtr<CryptoKeyOKP> importJwk(CryptoAlgorithmIdentifier, NamedCurve, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap);
static RefPtr<CryptoKeyOKP> importSpki(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
static RefPtr<CryptoKeyOKP> importPkcs8(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
@@ -88,6 +89,7 @@ private:
Vector<uint8_t> platformExportRaw() const;
Vector<uint8_t> platformExportSpki() const;
Vector<uint8_t> platformExportPkcs8() const;
+ static RefPtr<CryptoKeyOKP> importJwkInternal(CryptoAlgorithmIdentifier identifier, NamedCurve namedCurve, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages, bool onlyPublic);
NamedCurve m_curve;
KeyMaterial m_data;
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyOKPOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyOKPOpenSSL.cpp
index ea3a4d498..82e352d0a 100644
--- a/src/bun.js/bindings/webcrypto/CryptoKeyOKPOpenSSL.cpp
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyOKPOpenSSL.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "CryptoKeyOKP.h"
-
+#include "../wtf-bindings.h"
#if ENABLE(WEB_CRYPTO)
#include "JsonWebKey.h"
@@ -296,9 +296,9 @@ String CryptoKeyOKP::generateJwkD() const
ASSERT(type() == CryptoKeyType::Private);
if (namedCurve() == NamedCurve::Ed25519) {
ASSERT(m_exportKey);
- return base64URLEncodeToString(*m_exportKey);
+ return Bun::base64URLEncodeToString(*m_exportKey);
}
- return base64URLEncodeToString(m_data);
+ return Bun::base64URLEncodeToString(m_data);
}
CryptoKeyOKP::KeyMaterial CryptoKeyOKP::ed25519PublicFromPrivate(const KeyMaterial& seed)
@@ -333,15 +333,15 @@ CryptoKeyOKP::KeyMaterial CryptoKeyOKP::ed25519PrivateFromSeed(KeyMaterial&& see
String CryptoKeyOKP::generateJwkX() const
{
if (type() == CryptoKeyType::Public)
- return base64URLEncodeToString(m_data);
+ return Bun::base64URLEncodeToString(m_data);
ASSERT(type() == CryptoKeyType::Private);
if (namedCurve() == NamedCurve::Ed25519)
- return base64URLEncodeToString(WTFMove(ed25519PublicFromPrivate(const_cast<KeyMaterial&>(m_data))));
+ return Bun::base64URLEncodeToString(WTFMove(ed25519PublicFromPrivate(const_cast<KeyMaterial&>(m_data))));
ASSERT(namedCurve() == NamedCurve::X25519);
- return base64URLEncodeToString(WTFMove(x25519PublicFromPrivate(const_cast<KeyMaterial&>(m_data))));
+ return Bun::base64URLEncodeToString(WTFMove(x25519PublicFromPrivate(const_cast<KeyMaterial&>(m_data))));
}
CryptoKeyOKP::KeyMaterial CryptoKeyOKP::platformExportRaw() const
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyRSA.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyRSA.cpp
index 273218721..859767107 100644
--- a/src/bun.js/bindings/webcrypto/CryptoKeyRSA.cpp
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyRSA.cpp
@@ -28,6 +28,7 @@
#include "CryptoKeyRSAComponents.h"
#include "JsonWebKey.h"
+#include "../wtf-bindings.h"
#include <wtf/text/Base64.h>
#if ENABLE(WEB_CRYPTO)
@@ -143,30 +144,30 @@ JsonWebKey CryptoKeyRSA::exportJwk() const
return result;
// public key
- result.n = base64URLEncodeToString(rsaComponents->modulus());
- result.e = base64URLEncodeToString(rsaComponents->exponent());
+ result.n = Bun::base64URLEncodeToString(rsaComponents->modulus());
+ result.e = Bun::base64URLEncodeToString(rsaComponents->exponent());
if (rsaComponents->type() == CryptoKeyRSAComponents::Type::Public)
return result;
// private key
- result.d = base64URLEncodeToString(rsaComponents->privateExponent());
+ result.d = Bun::base64URLEncodeToString(rsaComponents->privateExponent());
if (!rsaComponents->hasAdditionalPrivateKeyParameters())
return result;
- result.p = base64URLEncodeToString(rsaComponents->firstPrimeInfo().primeFactor);
- result.q = base64URLEncodeToString(rsaComponents->secondPrimeInfo().primeFactor);
- result.dp = base64URLEncodeToString(rsaComponents->firstPrimeInfo().factorCRTExponent);
- result.dq = base64URLEncodeToString(rsaComponents->secondPrimeInfo().factorCRTExponent);
- result.qi = base64URLEncodeToString(rsaComponents->secondPrimeInfo().factorCRTCoefficient);
+ result.p = Bun::base64URLEncodeToString(rsaComponents->firstPrimeInfo().primeFactor);
+ result.q = Bun::base64URLEncodeToString(rsaComponents->secondPrimeInfo().primeFactor);
+ result.dp = Bun::base64URLEncodeToString(rsaComponents->firstPrimeInfo().factorCRTExponent);
+ result.dq = Bun::base64URLEncodeToString(rsaComponents->secondPrimeInfo().factorCRTExponent);
+ result.qi = Bun::base64URLEncodeToString(rsaComponents->secondPrimeInfo().factorCRTCoefficient);
if (rsaComponents->otherPrimeInfos().isEmpty())
return result;
Vector<RsaOtherPrimesInfo> oth;
for (const auto& info : rsaComponents->otherPrimeInfos()) {
RsaOtherPrimesInfo otherInfo;
- otherInfo.r = base64URLEncodeToString(info.primeFactor);
- otherInfo.d = base64URLEncodeToString(info.factorCRTExponent);
- otherInfo.t = base64URLEncodeToString(info.factorCRTCoefficient);
+ otherInfo.r = Bun::base64URLEncodeToString(info.primeFactor);
+ otherInfo.d = Bun::base64URLEncodeToString(info.factorCRTExponent);
+ otherInfo.t = Bun::base64URLEncodeToString(info.factorCRTCoefficient);
oth.append(WTFMove(otherInfo));
}
result.oth = WTFMove(oth);
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKey.cpp b/src/bun.js/bindings/webcrypto/JSCryptoKey.cpp
index d2ec84afb..5b38d78c9 100644
--- a/src/bun.js/bindings/webcrypto/JSCryptoKey.cpp
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKey.cpp
@@ -196,6 +196,8 @@ void JSCryptoKey::finishCreation(VM& vm)
// static_assert(!std::is_base_of<ActiveDOMObject, CryptoKey>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
}
+
+
JSObject* JSCryptoKey::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return JSCryptoKeyPrototype::create(vm, &globalObject, JSCryptoKeyPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
diff --git a/src/bun.js/bindings/webcrypto/JSJsonWebKey.cpp b/src/bun.js/bindings/webcrypto/JSJsonWebKey.cpp
index 39ed1ff31..067421303 100644
--- a/src/bun.js/bindings/webcrypto/JSJsonWebKey.cpp
+++ b/src/bun.js/bindings/webcrypto/JSJsonWebKey.cpp
@@ -256,7 +256,7 @@ template<> JsonWebKey convertDictionary<JsonWebKey>(JSGlobalObject& lexicalGloba
return result;
}
-JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const JsonWebKey& dictionary)
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const JsonWebKey& dictionary, bool ignoreExtAndKeyOps)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -293,7 +293,7 @@ JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, J
RETURN_IF_EXCEPTION(throwScope, { });
result->putDirect(vm, JSC::Identifier::fromString(vm, "e"_s), eValue);
}
- if (!IDLBoolean::isNullValue(dictionary.ext)) {
+ if (!ignoreExtAndKeyOps && !IDLBoolean::isNullValue(dictionary.ext)) {
auto extValue = toJS<IDLBoolean>(lexicalGlobalObject, throwScope, IDLBoolean::extractValueFromNullable(dictionary.ext));
RETURN_IF_EXCEPTION(throwScope, { });
result->putDirect(vm, JSC::Identifier::fromString(vm, "ext"_s), extValue);
@@ -303,7 +303,7 @@ JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, J
RETURN_IF_EXCEPTION(throwScope, { });
result->putDirect(vm, JSC::Identifier::fromString(vm, "k"_s), kValue);
}
- if (!IDLSequence<IDLEnumeration<CryptoKeyUsage>>::isNullValue(dictionary.key_ops)) {
+ if (!ignoreExtAndKeyOps && !IDLSequence<IDLEnumeration<CryptoKeyUsage>>::isNullValue(dictionary.key_ops)) {
auto key_opsValue = toJS<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(lexicalGlobalObject, globalObject, throwScope, IDLSequence<IDLEnumeration<CryptoKeyUsage>>::extractValueFromNullable(dictionary.key_ops));
RETURN_IF_EXCEPTION(throwScope, { });
result->putDirect(vm, JSC::Identifier::fromString(vm, "key_ops"_s), key_opsValue);
diff --git a/src/bun.js/bindings/webcrypto/JSJsonWebKey.h b/src/bun.js/bindings/webcrypto/JSJsonWebKey.h
index 07e7960be..c1b287c4d 100644
--- a/src/bun.js/bindings/webcrypto/JSJsonWebKey.h
+++ b/src/bun.js/bindings/webcrypto/JSJsonWebKey.h
@@ -29,7 +29,7 @@ namespace WebCore {
template<> JsonWebKey convertDictionary<JsonWebKey>(JSC::JSGlobalObject&, JSC::JSValue);
-JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const JsonWebKey&);
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const JsonWebKey&, bool ignoreExtAndKeyOps = false);
} // namespace WebCore
diff --git a/src/bun.js/bindings/wtf-bindings.cpp b/src/bun.js/bindings/wtf-bindings.cpp
index d05fb255b..2ec3d7ee8 100644
--- a/src/bun.js/bindings/wtf-bindings.cpp
+++ b/src/bun.js/bindings/wtf-bindings.cpp
@@ -237,4 +237,24 @@ extern "C" size_t WTF__base64URLEncode(const unsigned char* __restrict inputData
destinationDataBuffer[didx++] = '=';
return destinationDataBufferSize;
-} \ No newline at end of file
+}
+
+namespace Bun {
+String base64URLEncodeToString(Vector<uint8_t> data)
+{
+ auto size = data.size();
+ size_t encodedLength = ((size * 4) + 2) / 3;
+ if (!encodedLength)
+ return String();
+
+ LChar* ptr;
+ auto result = String::createUninitialized(encodedLength, ptr);
+ if (UNLIKELY(!ptr)) {
+ RELEASE_ASSERT_NOT_REACHED();
+ return String();
+ }
+ encodedLength = WTF__base64URLEncode(data.data(), data.size(), ptr, encodedLength);
+ RELEASE_ASSERT(result.length() == encodedLength);
+ return result;
+}
+}
diff --git a/src/bun.js/bindings/wtf-bindings.h b/src/bun.js/bindings/wtf-bindings.h
index 1721b0e1c..3df543934 100644
--- a/src/bun.js/bindings/wtf-bindings.h
+++ b/src/bun.js/bindings/wtf-bindings.h
@@ -4,3 +4,7 @@
#include "wtf/text/ASCIIFastPath.h"
extern "C" void WTF__copyLCharsFromUCharSource(LChar* destination, const UChar* source, size_t length);
+
+namespace Bun {
+String base64URLEncodeToString(Vector<uint8_t> data);
+} \ No newline at end of file
diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig
index f22d8793a..bdee2cefb 100644
--- a/src/bun.js/event_loop.zig
+++ b/src/bun.js/event_loop.zig
@@ -118,6 +118,7 @@ pub fn WorkTask(comptime Context: type, comptime async_io: bool) type {
}
pub fn runFromThreadPool(task: *TaskType) void {
+ JSC.markBinding(@src());
var this = @fieldParentPtr(This, "task", task);
Context.run(this.ctx, this);
}
@@ -303,6 +304,48 @@ const PollPendingModulesTask = JSC.ModuleLoader.AsyncModule.Queue;
// const PromiseTask = JSInternalPromise.Completion.PromiseTask;
const GetAddrInfoRequestTask = JSC.DNS.GetAddrInfoRequest.Task;
const JSCDeferredWorkTask = JSCScheduler.JSCDeferredWorkTask;
+
+const Stat = JSC.Node.Async.stat;
+const Lstat = JSC.Node.Async.lstat;
+const Fstat = JSC.Node.Async.fstat;
+const Open = JSC.Node.Async.open;
+const ReadFile = JSC.Node.Async.readFile;
+const WriteFile = JSC.Node.Async.writeFile;
+const CopyFile = JSC.Node.Async.copyFile;
+const Read = JSC.Node.Async.read;
+const Write = JSC.Node.Async.write;
+const Truncate = JSC.Node.Async.truncate;
+const FTruncate = JSC.Node.Async.ftruncate;
+const Readdir = JSC.Node.Async.readdir;
+const Readv = JSC.Node.Async.readv;
+const Writev = JSC.Node.Async.writev;
+const Close = JSC.Node.Async.close;
+const Rm = JSC.Node.Async.rm;
+const Rmdir = JSC.Node.Async.rmdir;
+const Chown = JSC.Node.Async.chown;
+const FChown = JSC.Node.Async.fchown;
+const Utimes = JSC.Node.Async.utimes;
+const Lutimes = JSC.Node.Async.lutimes;
+const Chmod = JSC.Node.Async.chmod;
+const Fchmod = JSC.Node.Async.fchmod;
+const Link = JSC.Node.Async.link;
+const Symlink = JSC.Node.Async.symlink;
+const Readlink = JSC.Node.Async.readlink;
+const Realpath = JSC.Node.Async.realpath;
+const Mkdir = JSC.Node.Async.mkdir;
+const Fsync = JSC.Node.Async.fsync;
+const Rename = JSC.Node.Async.rename;
+const Fdatasync = JSC.Node.Async.fdatasync;
+const Access = JSC.Node.Async.access;
+const AppendFile = JSC.Node.Async.appendFile;
+const Mkdtemp = JSC.Node.Async.mkdtemp;
+const Exists = JSC.Node.Async.exists;
+const Futimes = JSC.Node.Async.futimes;
+const Lchmod = JSC.Node.Async.lchmod;
+const Lchown = JSC.Node.Async.lchown;
+const Unlink = JSC.Node.Async.unlink;
+
+// Task.get(ReadFileTask) -> ?ReadFileTask
pub const Task = TaggedPointerUnion(.{
FetchTasklet,
Microtask,
@@ -321,13 +364,49 @@ pub const Task = TaggedPointerUnion(.{
GetAddrInfoRequestTask,
FSWatchTask,
JSCDeferredWorkTask,
-
- // PromiseTask,
- // TimeoutTasklet,
+ Stat,
+ Lstat,
+ Fstat,
+ Open,
+ ReadFile,
+ WriteFile,
+ CopyFile,
+ Read,
+ Write,
+ Truncate,
+ FTruncate,
+ Readdir,
+ Close,
+ Rm,
+ Rmdir,
+ Chown,
+ FChown,
+ Utimes,
+ Lutimes,
+ Chmod,
+ Fchmod,
+ Link,
+ Symlink,
+ Readlink,
+ Realpath,
+ Mkdir,
+ Fsync,
+ Fdatasync,
+ Writev,
+ Readv,
+ Rename,
+ Access,
+ AppendFile,
+ Mkdtemp,
+ Exists,
+ Futimes,
+ Lchmod,
+ Lchown,
+ Unlink,
});
const UnboundedQueue = @import("./unbounded_queue.zig").UnboundedQueue;
pub const ConcurrentTask = struct {
- task: Task = undefined,
+ task: if (JSC.is_bindgen) void else Task = undefined,
next: ?*ConcurrentTask = null,
auto_delete: bool = false,
@@ -348,14 +427,19 @@ pub const ConcurrentTask = struct {
}
pub fn createFrom(task: anytype) *ConcurrentTask {
+ JSC.markBinding(@src());
return create(Task.init(task));
}
pub fn fromCallback(ptr: anytype, comptime callback: anytype) *ConcurrentTask {
+ JSC.markBinding(@src());
+
return create(ManagedTask.New(std.meta.Child(@TypeOf(ptr)), callback).init(ptr));
}
pub fn from(this: *ConcurrentTask, of: anytype, auto_deinit: AutoDeinit) *ConcurrentTask {
+ JSC.markBinding(@src());
+
this.* = .{
.task = Task.init(of),
.next = null,
@@ -377,6 +461,7 @@ pub const GarbageCollectionController = struct {
gc_repeating_timer: *uws.Timer = undefined,
gc_timer_interval: i32 = 0,
gc_repeating_timer_fast: bool = true,
+ disabled: bool = false,
pub fn init(this: *GarbageCollectionController, vm: *VirtualMachine) void {
var actual = vm.event_loop_handle.?;
@@ -391,8 +476,12 @@ pub const GarbageCollectionController = struct {
}
} else |_| {}
}
- this.gc_repeating_timer.set(this, onGCRepeatingTimer, gc_timer_interval, gc_timer_interval);
this.gc_timer_interval = gc_timer_interval;
+
+ this.disabled = vm.bundler.env.has("BUN_GC_TIMER_DISABLE");
+
+ if (!this.disabled)
+ this.gc_repeating_timer.set(this, onGCRepeatingTimer, gc_timer_interval, gc_timer_interval);
}
pub fn scheduleGCTimer(this: *GarbageCollectionController) void {
@@ -406,6 +495,7 @@ pub const GarbageCollectionController = struct {
pub fn onGCTimer(timer: *uws.Timer) callconv(.C) void {
var this = timer.as(*GarbageCollectionController);
+ if (this.disabled) return;
this.gc_timer_state = .run_on_next_tick;
}
@@ -450,11 +540,12 @@ pub const GarbageCollectionController = struct {
}
pub fn processGCTimer(this: *GarbageCollectionController) void {
- var vm = this.bunVM().global.vm();
+ if (this.disabled) return;
+ var vm = this.bunVM().jsc;
this.processGCTimerWithHeapSize(vm, vm.blockBytesAllocated());
}
- pub fn processGCTimerWithHeapSize(this: *GarbageCollectionController, vm: *JSC.VM, this_heap_size: usize) void {
+ fn processGCTimerWithHeapSize(this: *GarbageCollectionController, vm: *JSC.VM, this_heap_size: usize) void {
const prev = this.gc_last_heap_size;
switch (this.gc_timer_state) {
@@ -490,7 +581,8 @@ pub const GarbageCollectionController = struct {
}
pub fn performGC(this: *GarbageCollectionController) void {
- var vm = this.bunVM().global.vm();
+ if (this.disabled) return;
+ var vm = this.bunVM().jsc;
vm.collectAsync();
this.gc_last_heap_size = vm.blockBytesAllocated();
}
@@ -515,7 +607,7 @@ comptime {
pub const DeferredRepeatingTask = *const (fn (*anyopaque) bool);
pub const EventLoop = struct {
- tasks: Queue = undefined,
+ tasks: if (JSC.is_bindgen) void else Queue = undefined,
concurrent_tasks: ConcurrentTask.Queue = ConcurrentTask.Queue{},
global: *JSGlobalObject = undefined,
virtual_machine: *JSC.VirtualMachine = undefined,
@@ -530,7 +622,7 @@ pub const EventLoop = struct {
pub fn tickWhilePaused(this: *EventLoop, done: *bool) void {
while (!done.*) {
- this.virtual_machine.event_loop_handle.?.tick();
+ this.virtual_machine.event_loop_handle.?.tick(this.virtual_machine.jsc);
}
}
extern fn JSC__JSGlobalObject__drainMicrotasks(*JSC.JSGlobalObject) void;
@@ -662,6 +754,162 @@ pub const EventLoop = struct {
any.runFromJS();
any.deinit();
},
+ @field(Task.Tag, typeBaseName(@typeName(Stat))) => {
+ var any: *Stat = task.get(Stat).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Lstat))) => {
+ var any: *Lstat = task.get(Lstat).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Fstat))) => {
+ var any: *Fstat = task.get(Fstat).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Open))) => {
+ var any: *Open = task.get(Open).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(ReadFile))) => {
+ var any: *ReadFile = task.get(ReadFile).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(WriteFile))) => {
+ var any: *WriteFile = task.get(WriteFile).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(CopyFile))) => {
+ var any: *CopyFile = task.get(CopyFile).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Read))) => {
+ var any: *Read = task.get(Read).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Write))) => {
+ var any: *Write = task.get(Write).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Truncate))) => {
+ var any: *Truncate = task.get(Truncate).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Writev))) => {
+ var any: *Writev = task.get(Writev).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Readv))) => {
+ var any: *Readv = task.get(Readv).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Rename))) => {
+ var any: *Rename = task.get(Rename).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(FTruncate))) => {
+ var any: *FTruncate = task.get(FTruncate).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Readdir))) => {
+ var any: *Readdir = task.get(Readdir).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Close))) => {
+ var any: *Close = task.get(Close).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Rm))) => {
+ var any: *Rm = task.get(Rm).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Rmdir))) => {
+ var any: *Rmdir = task.get(Rmdir).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Chown))) => {
+ var any: *Chown = task.get(Chown).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(FChown))) => {
+ var any: *FChown = task.get(FChown).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Utimes))) => {
+ var any: *Utimes = task.get(Utimes).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Lutimes))) => {
+ var any: *Lutimes = task.get(Lutimes).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Chmod))) => {
+ var any: *Chmod = task.get(Chmod).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Fchmod))) => {
+ var any: *Fchmod = task.get(Fchmod).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Link))) => {
+ var any: *Link = task.get(Link).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Symlink))) => {
+ var any: *Symlink = task.get(Symlink).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Readlink))) => {
+ var any: *Readlink = task.get(Readlink).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Realpath))) => {
+ var any: *Realpath = task.get(Realpath).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Mkdir))) => {
+ var any: *Mkdir = task.get(Mkdir).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Fsync))) => {
+ var any: *Fsync = task.get(Fsync).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Fdatasync))) => {
+ var any: *Fdatasync = task.get(Fdatasync).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Access))) => {
+ var any: *Access = task.get(Access).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(AppendFile))) => {
+ var any: *AppendFile = task.get(AppendFile).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Mkdtemp))) => {
+ var any: *Mkdtemp = task.get(Mkdtemp).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Exists))) => {
+ var any: *Exists = task.get(Exists).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Futimes))) => {
+ var any: *Futimes = task.get(Futimes).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Lchmod))) => {
+ var any: *Lchmod = task.get(Lchmod).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Lchown))) => {
+ var any: *Lchown = task.get(Lchown).?;
+ any.runFromJSThread();
+ },
+ @field(Task.Tag, typeBaseName(@typeName(Unlink))) => {
+ var any: *Unlink = task.get(Unlink).?;
+ any.runFromJSThread();
+ },
else => if (Environment.allow_assert) {
bun.Output.prettyln("\nUnexpected tag: {s}\n", .{@tagName(task.tag())});
} else {
@@ -683,6 +931,7 @@ pub const EventLoop = struct {
}
pub fn tickConcurrentWithCount(this: *EventLoop) usize {
+ JSC.markBinding(@src());
var concurrent = this.concurrent_tasks.popBatch();
const count = concurrent.count;
if (count == 0)
@@ -740,8 +989,9 @@ pub const EventLoop = struct {
}
if (loop.num_polls > 0 or loop.active > 0) {
- loop.tick();
this.processGCTimer();
+ loop.tick(ctx.jsc);
+
ctx.onAfterEventLoop();
// this.afterUSocketsTick();
}
@@ -764,8 +1014,8 @@ pub const EventLoop = struct {
}
if (loop.num_polls > 0 or loop.active > 0) {
- loop.tickWithTimeout(timeoutMs);
this.processGCTimer();
+ loop.tickWithTimeout(timeoutMs, ctx.jsc);
ctx.onAfterEventLoop();
// this.afterUSocketsTick();
}
@@ -789,8 +1039,8 @@ pub const EventLoop = struct {
}
}
- loop.tick();
this.processGCTimer();
+ loop.tick(ctx.jsc);
ctx.onAfterEventLoop();
this.tickConcurrent();
this.tick();
@@ -812,8 +1062,8 @@ pub const EventLoop = struct {
}
if (loop.active > 0) {
- loop.tick();
this.processGCTimer();
+ loop.tick(ctx.jsc);
ctx.onAfterEventLoop();
// this.afterUSocketsTick();
}
@@ -824,13 +1074,15 @@ pub const EventLoop = struct {
}
pub fn tick(this: *EventLoop) void {
+ JSC.markBinding(@src());
+
var ctx = this.virtual_machine;
this.tickConcurrent();
this.processGCTimer();
var global = ctx.global;
- var global_vm = global.vm();
+ var global_vm = ctx.jsc;
while (true) {
while (this.tickWithCount() > 0) : (this.global.handleRejectedPromises()) {
this.tickConcurrent();
@@ -851,12 +1103,12 @@ pub const EventLoop = struct {
}
pub fn waitForPromise(this: *EventLoop, promise: JSC.AnyPromise) void {
- switch (promise.status(this.global.vm())) {
+ switch (promise.status(this.virtual_machine.jsc)) {
JSC.JSPromise.Status.Pending => {
- while (promise.status(this.global.vm()) == .Pending) {
+ while (promise.status(this.virtual_machine.jsc) == .Pending) {
this.tick();
- if (promise.status(this.global.vm()) == .Pending) {
+ if (promise.status(this.virtual_machine.jsc) == .Pending) {
this.autoTick();
}
}
@@ -868,16 +1120,16 @@ pub const EventLoop = struct {
// TODO: this implementation is terrible
// we should not be checking the millitimestamp every time
pub fn waitForPromiseWithTimeout(this: *EventLoop, promise: JSC.AnyPromise, timeout: u32) bool {
- return switch (promise.status(this.global.vm())) {
+ return switch (promise.status(this.virtual_machine.jsc)) {
JSC.JSPromise.Status.Pending => {
if (timeout == 0) {
return false;
}
var start_time = std.time.milliTimestamp();
- while (promise.status(this.global.vm()) == .Pending) {
+ while (promise.status(this.virtual_machine.jsc) == .Pending) {
this.tick();
- if (promise.status(this.global.vm()) == .Pending) {
+ if (promise.status(this.virtual_machine.jsc) == .Pending) {
const remaining = std.time.milliTimestamp() - start_time;
if (remaining >= timeout) {
return false;
@@ -893,6 +1145,7 @@ pub const EventLoop = struct {
}
pub fn enqueueTask(this: *EventLoop, task: Task) void {
+ JSC.markBinding(@src());
this.tasks.writeItem(task) catch unreachable;
}
@@ -905,7 +1158,7 @@ pub const EventLoop = struct {
pub fn callTask(timer: *uws.Timer) callconv(.C) void {
var task = Task.from(timer.as(*anyopaque));
- timer.deinit();
+ defer timer.deinit(true);
JSC.VirtualMachine.get().enqueueTask(task);
}
@@ -916,7 +1169,7 @@ pub const EventLoop = struct {
this.virtual_machine.event_loop_handle = uws.Loop.get();
this.virtual_machine.gc_controller.init(this.virtual_machine);
// _ = actual.addPostHandler(*JSC.EventLoop, this, JSC.EventLoop.afterUSocketsTick);
- // _ = actual.addPreHandler(*JSC.VM, this.virtual_machine.global.vm(), JSC.VM.drainMicrotasks);
+ // _ = actual.addPreHandler(*JSC.VM, this.virtual_machine.jsc, JSC.VM.drainMicrotasks);
}
}
@@ -995,7 +1248,7 @@ pub const MiniEventLoop = struct {
while (!isDone(context)) {
if (this.tickConcurrentWithCount() == 0 and this.tasks.count == 0) {
this.loop.num_polls += 1;
- this.loop.tick();
+ this.loop.tick(null);
this.loop.num_polls -= 1;
}
@@ -1086,7 +1339,7 @@ pub const AnyEventLoop = union(enum) {
// var concurrent = bun.default_allocator.create(ConcurrentTask) catch unreachable;
// _ = concurrent.from(JSC.Task.init(&@field(ctx, field)));
// concurrent.auto_delete = true;
- // this.jsc.enqueueTaskConcurrent(concurrent);
+ // this.virtual_machine.jsc.enqueueTaskConcurrent(concurrent);
},
.mini => {
this.mini.enqueueTaskConcurrent(Context, ParentContext, ctx, Callback, field);
diff --git a/src/bun.js/ipc.zig b/src/bun.js/ipc.zig
index 57fcef75f..a0742a0c4 100644
--- a/src/bun.js/ipc.zig
+++ b/src/bun.js/ipc.zig
@@ -35,6 +35,11 @@ pub const IPCMessageType = enum(u8) {
_,
};
+pub const IPCBuffer = struct {
+ list: bun.ByteList = .{},
+ cursor: u32 = 0,
+};
+
/// Given potentially unfinished buffer `data`, attempt to decode and process a message from it.
/// Returns `NotEnoughBytes` if there werent enough bytes
/// Returns `InvalidFormat` if the message was invalid, probably close the socket in this case
@@ -89,12 +94,74 @@ pub fn decodeIPCMessage(
pub const Socket = uws.NewSocketHandler(false);
+pub const IPCData = struct {
+ socket: Socket,
+ incoming: bun.ByteList = .{}, // Maybe we should use IPCBuffer here as well
+ outgoing: IPCBuffer = .{},
+
+ has_written_version: if (Environment.allow_assert) u1 else u0 = 0,
+
+ pub fn writeVersionPacket(this: *IPCData) void {
+ if (Environment.allow_assert) {
+ std.debug.assert(this.has_written_version == 0);
+ }
+ const VersionPacket = extern struct {
+ type: IPCMessageType align(1) = .Version,
+ version: u32 align(1) = ipcVersion,
+ };
+ const bytes = comptime std.mem.asBytes(&VersionPacket{});
+ const n = this.socket.write(bytes, false);
+ if (n != bytes.len) {
+ var list = this.outgoing.list.listManaged(bun.default_allocator);
+ list.appendSlice(bytes) catch @panic("OOM");
+ }
+ if (Environment.allow_assert) {
+ this.has_written_version = 1;
+ }
+ }
+
+ pub fn serializeAndSend(ipc_data: *IPCData, globalThis: *JSGlobalObject, value: JSValue) bool {
+ if (Environment.allow_assert) {
+ std.debug.assert(ipc_data.has_written_version == 1);
+ }
+
+ const serialized = value.serialize(globalThis) orelse return false;
+ defer serialized.deinit();
+
+ const size: u32 = @intCast(serialized.data.len);
+
+ const payload_length: usize = @sizeOf(IPCMessageType) + @sizeOf(u32) + size;
+
+ ipc_data.outgoing.list.ensureUnusedCapacity(bun.default_allocator, payload_length) catch @panic("OOM");
+ const start_offset = ipc_data.outgoing.list.len;
+
+ ipc_data.outgoing.list.writeTypeAsBytesAssumeCapacity(u8, @intFromEnum(IPCMessageType.SerializedMessage));
+ ipc_data.outgoing.list.writeTypeAsBytesAssumeCapacity(u32, size);
+ ipc_data.outgoing.list.appendSliceAssumeCapacity(serialized.data);
+
+ std.debug.assert(ipc_data.outgoing.list.len == start_offset + payload_length);
+
+ if (start_offset == 0) {
+ std.debug.assert(ipc_data.outgoing.cursor == 0);
+
+ const n = ipc_data.socket.write(ipc_data.outgoing.list.ptr[start_offset..payload_length], false);
+ if (n == payload_length) {
+ ipc_data.outgoing.list.len = 0;
+ } else if (n > 0) {
+ ipc_data.outgoing.cursor = @intCast(n);
+ }
+ }
+
+ return true;
+ }
+};
+
/// This type is shared between VirtualMachine and Subprocess for their respective IPC handlers
///
/// `Context` must be a struct that implements this interface:
/// struct {
/// globalThis: ?*JSGlobalObject,
-/// ipc_buffer: bun.ByteList,
+/// ipc: IPCData,
///
/// fn handleIPCMessage(*Context, DecodedIPCMessage) void
/// fn handleIPCClose(*Context, Socket) void
@@ -102,18 +169,18 @@ pub const Socket = uws.NewSocketHandler(false);
pub fn NewIPCHandler(comptime Context: type) type {
return struct {
pub fn onOpen(
- _: *Context,
- socket: Socket,
+ _: *anyopaque,
+ _: Socket,
) void {
- // Write the version message
- const Data = extern struct {
- type: IPCMessageType align(1) = .Version,
- version: u32 align(1) = ipcVersion,
- };
- const data: []const u8 = comptime @as([@sizeOf(Data)]u8, @bitCast(Data{}))[0..];
- _ = socket.write(data, false);
- socket.flush();
+ // it is NOT safe to use the first argument here because it has not been initialized yet.
+ // ideally we would call .ipc.writeVersionPacket() here, and we need that to handle the
+ // theoretical write failure, but since the .ipc.outgoing buffer isn't available, that
+ // data has nowhere to go.
+ //
+ // therefore, initializers of IPC handlers need to call .ipc.writeVersionPacket() themselves
+ // this is covered by an assertion.
}
+
pub fn onClose(
this: *Context,
socket: Socket,
@@ -124,7 +191,7 @@ pub fn NewIPCHandler(comptime Context: type) type {
log("onClose\n", .{});
this.handleIPCClose(socket);
}
- // extern fn getpid() i32;
+
pub fn onData(
this: *Context,
socket: Socket,
@@ -133,10 +200,6 @@ pub fn NewIPCHandler(comptime Context: type) type {
var data = data_;
log("onData {}", .{std.fmt.fmtSliceHexLower(data)});
- // if (comptime Context == bun.JSC.VirtualMachine.IPCInstance) {
- // logDataOnly("{d} -> '{}'", .{ getpid(), std.fmt.fmtSliceHexLower(data) });
- // }
-
// In the VirtualMachine case, `globalThis` is an optional, in case
// the vm is freed before the socket closes.
var globalThis = switch (@typeInfo(@TypeOf(this.globalThis))) {
@@ -154,11 +217,11 @@ pub fn NewIPCHandler(comptime Context: type) type {
// Decode the message with just the temporary buffer, and if that
// fails (not enough bytes) then we allocate to .ipc_buffer
- if (this.ipc_buffer.len == 0) {
+ if (this.ipc.incoming.len == 0) {
while (true) {
const result = decodeIPCMessage(data, globalThis) catch |e| switch (e) {
error.NotEnoughBytes => {
- _ = this.ipc_buffer.write(bun.default_allocator, data) catch @panic("OOM");
+ _ = this.ipc.incoming.write(bun.default_allocator, data) catch @panic("OOM");
log("hit NotEnoughBytes", .{});
return;
},
@@ -180,15 +243,15 @@ pub fn NewIPCHandler(comptime Context: type) type {
}
}
- _ = this.ipc_buffer.write(bun.default_allocator, data) catch @panic("OOM");
+ _ = this.ipc.incoming.write(bun.default_allocator, data) catch @panic("OOM");
- var slice = this.ipc_buffer.slice();
+ var slice = this.ipc.incoming.slice();
while (true) {
const result = decodeIPCMessage(slice, globalThis) catch |e| switch (e) {
error.NotEnoughBytes => {
// copy the remaining bytes to the start of the buffer
- bun.copy(u8, this.ipc_buffer.ptr[0..slice.len], slice);
- this.ipc_buffer.len = @truncate(slice.len);
+ bun.copy(u8, this.ipc.incoming.ptr[0..slice.len], slice);
+ this.ipc.incoming.len = @truncate(slice.len);
log("hit NotEnoughBytes2", .{});
return;
},
@@ -206,34 +269,47 @@ pub fn NewIPCHandler(comptime Context: type) type {
slice = slice[result.bytes_consumed..];
} else {
// clear the buffer
- this.ipc_buffer.len = 0;
+ this.ipc.incoming.len = 0;
return;
}
}
}
pub fn onWritable(
- _: *Context,
- _: Socket,
- ) void {}
+ context: *Context,
+ socket: Socket,
+ ) void {
+ const to_write = context.ipc.outgoing.list.ptr[context.ipc.outgoing.cursor..context.ipc.outgoing.list.len];
+ if (to_write.len == 0) {
+ context.ipc.outgoing.cursor = 0;
+ context.ipc.outgoing.list.len = 0;
+ return;
+ }
+ const n = socket.write(to_write, false);
+ if (n == to_write.len) {
+ context.ipc.outgoing.cursor = 0;
+ context.ipc.outgoing.list.len = 0;
+ } else if (n > 0) {
+ context.ipc.outgoing.cursor += @intCast(n);
+ }
+ }
+
pub fn onTimeout(
_: *Context,
_: Socket,
) void {}
+
pub fn onConnectError(
- _: *Context,
+ _: *anyopaque,
_: Socket,
_: c_int,
- ) void {}
+ ) void {
+ // context has not been initialized
+ }
+
pub fn onEnd(
_: *Context,
_: Socket,
) void {}
};
}
-
-/// This is used for Bun.spawn() IPC because otherwise we would have to copy the data once to get it to zig, then write it.
-/// Returns `true` on success, `false` on failure + throws a JS error.
-extern fn Bun__serializeJSValueForSubprocess(global: *JSC.JSGlobalObject, value: JSValue, fd: bun.FileDescriptor) bool;
-
-pub const serializeJSValueForSubprocess = Bun__serializeJSValueForSubprocess;
diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig
index e2e44e63a..1c996039d 100644
--- a/src/bun.js/javascript.zig
+++ b/src/bun.js/javascript.zig
@@ -294,13 +294,8 @@ pub export fn Bun__Process__send(
return .zero;
}
var vm = globalObject.bunVM();
- if (vm.ipc) |ipc| {
- const fd = ipc.socket.fd();
- const success = IPC.serializeJSValueForSubprocess(
- globalObject,
- callFrame.argument(0),
- fd,
- );
+ if (vm.ipc) |ipc_instance| {
+ const success = ipc_instance.ipc.serializeAndSend(globalObject, callFrame.argument(0));
return if (success) .undefined else .zero;
} else {
globalObject.throw("IPC Socket is no longer open.", .{});
@@ -308,10 +303,15 @@ pub export fn Bun__Process__send(
}
}
+pub export fn Bun__isBunMain(globalObject: *JSGlobalObject, input_ptr: [*]const u8, input_len: usize) bool {
+ return strings.eql(globalObject.bunVM().main, input_ptr[0..input_len]);
+}
+
pub export fn Bun__Process__disconnect(
globalObject: *JSGlobalObject,
callFrame: *JSC.CallFrame,
) JSValue {
+ JSC.markBinding(@src());
_ = callFrame;
_ = globalObject;
return .undefined;
@@ -320,14 +320,20 @@ pub export fn Bun__Process__disconnect(
/// This function is called on the main thread
/// The bunVM() call will assert this
pub export fn Bun__queueTask(global: *JSGlobalObject, task: *JSC.CppTask) void {
+ JSC.markBinding(@src());
+
global.bunVM().eventLoop().enqueueTask(Task.init(task));
}
pub export fn Bun__queueTaskWithTimeout(global: *JSGlobalObject, task: *JSC.CppTask, milliseconds: i32) void {
+ JSC.markBinding(@src());
+
global.bunVM().eventLoop().enqueueTaskWithTimeout(Task.init(task), milliseconds);
}
pub export fn Bun__reportUnhandledError(globalObject: *JSGlobalObject, value: JSValue) callconv(.C) JSValue {
+ JSC.markBinding(@src());
+
var jsc_vm = globalObject.bunVM();
jsc_vm.onUnhandledError(globalObject, value);
return JSC.JSValue.jsUndefined();
@@ -337,6 +343,8 @@ pub export fn Bun__reportUnhandledError(globalObject: *JSGlobalObject, value: JS
/// The main difference: we need to allocate the task & wakeup the thread
/// We can avoid that if we run it from the main thread.
pub export fn Bun__queueTaskConcurrently(global: *JSGlobalObject, task: *JSC.CppTask) void {
+ JSC.markBinding(@src());
+
var concurrent = bun.default_allocator.create(JSC.ConcurrentTask) catch unreachable;
concurrent.* = JSC.ConcurrentTask{
.task = Task.init(task),
@@ -346,6 +354,8 @@ pub export fn Bun__queueTaskConcurrently(global: *JSGlobalObject, task: *JSC.Cpp
}
pub export fn Bun__handleRejectedPromise(global: *JSGlobalObject, promise: *JSC.JSPromise) void {
+ JSC.markBinding(@src());
+
const result = promise.result(global.vm());
var jsc_vm = global.bunVM();
@@ -369,6 +379,14 @@ pub export fn Bun__onDidAppendPlugin(jsc_vm: *VirtualMachine, globalObject: *JSG
jsc_vm.bundler.linker.plugin_runner = &jsc_vm.plugin_runner.?;
}
+// pub fn getGlobalExitCodeForPipeFailure() u8 {
+// if (VirtualMachine.is_main_thread_vm) {
+// return VirtualMachine.get().exit_handler.exit_code;
+// }
+
+// return 0;
+// }
+
pub const ExitHandler = struct {
exit_code: u8 = 0,
@@ -401,6 +419,50 @@ pub const ExitHandler = struct {
pub const WebWorker = @import("./web_worker.zig").WebWorker;
+pub const ImportWatcher = union(enum) {
+ none: void,
+ hot: *HotReloader.Watcher,
+ watch: *WatchReloader.Watcher,
+
+ pub fn start(this: ImportWatcher) !void {
+ switch (this) {
+ inline .hot => |watcher| try watcher.start(),
+ inline .watch => |watcher| try watcher.start(),
+ else => {},
+ }
+ }
+
+ pub inline fn watchlist(this: ImportWatcher) Watcher.WatchListArray {
+ return switch (this) {
+ inline .hot, .watch => |wacher| wacher.watchlist,
+ else => .{},
+ };
+ }
+
+ pub inline fn indexOf(this: ImportWatcher, hash: Watcher.HashType) ?u32 {
+ return switch (this) {
+ inline .hot, .watch => |wacher| wacher.indexOf(hash),
+ else => null,
+ };
+ }
+
+ pub inline fn addFile(
+ this: ImportWatcher,
+ fd: StoredFileDescriptorType,
+ file_path: string,
+ hash: Watcher.HashType,
+ loader: options.Loader,
+ dir_fd: StoredFileDescriptorType,
+ package_json: ?*PackageJSON,
+ comptime copy_file_path: bool,
+ ) !void {
+ switch (this) {
+ inline .hot, .watch => |wacher| try wacher.addFile(fd, file_path, hash, loader, dir_fd, package_json, copy_file_path),
+ else => {},
+ }
+ }
+};
+
/// TODO: rename this to ScriptExecutionContext
/// This is the shared global state for a single JS instance execution
/// Today, Bun is one VM per thread, so the name "VirtualMachine" sort of makes sense
@@ -410,8 +472,7 @@ pub const VirtualMachine = struct {
allocator: std.mem.Allocator,
has_loaded_constructors: bool = false,
bundler: Bundler,
- bun_dev_watcher: ?*http.Watcher = null,
- bun_watcher: ?*JSC.Watcher = null,
+ bun_watcher: ImportWatcher = .{ .none = {} },
console: *ZigConsoleClient,
log: *logger.Log,
main: string = "",
@@ -980,6 +1041,8 @@ pub const VirtualMachine = struct {
pub const MacroMap = std.AutoArrayHashMap(i32, js.JSObjectRef);
pub fn enableMacroMode(this: *VirtualMachine) void {
+ JSC.markBinding(@src());
+
if (!this.has_enabled_macro_mode) {
this.has_enabled_macro_mode = true;
this.macro_event_loop.tasks = EventLoop.Queue.init(default_allocator);
@@ -1006,7 +1069,7 @@ pub const VirtualMachine = struct {
}
pub fn isWatcherEnabled(this: *VirtualMachine) bool {
- return this.bun_dev_watcher != null or this.bun_watcher != null;
+ return this.bun_watcher != .none;
}
/// Instead of storing timestamp as a i128, we store it as a u64.
@@ -1033,6 +1096,7 @@ pub const VirtualMachine = struct {
pub fn initWithModuleGraph(
opts: Options,
) !*VirtualMachine {
+ JSC.markBinding(@src());
const allocator = opts.allocator;
VMHolder.vm = try allocator.create(VirtualMachine);
var console = try allocator.create(ZigConsoleClient);
@@ -1129,6 +1193,7 @@ pub const VirtualMachine = struct {
};
pub fn init(opts: Options) !*VirtualMachine {
+ JSC.markBinding(@src());
const allocator = opts.allocator;
var log: *logger.Log = undefined;
if (opts.log) |__log| {
@@ -1258,6 +1323,7 @@ pub const VirtualMachine = struct {
worker: *WebWorker,
opts: Options,
) anyerror!*VirtualMachine {
+ JSC.markBinding(@src());
var log: *logger.Log = undefined;
const allocator = opts.allocator;
if (opts.log) |__log| {
@@ -1372,6 +1438,7 @@ pub const VirtualMachine = struct {
pub fn refCountedStringWithWasNew(this: *VirtualMachine, new: *bool, input_: []const u8, hash_: ?u32, comptime dupe: bool) *JSC.RefString {
JSC.markBinding(@src());
+ std.debug.assert(input_.len > 0);
const hash = hash_ orelse JSC.RefString.computeHash(input_);
this.ref_strings_mutex.lock();
defer this.ref_strings_mutex.unlock();
@@ -1400,6 +1467,7 @@ pub const VirtualMachine = struct {
}
pub fn refCountedString(this: *VirtualMachine, input_: []const u8, hash_: ?u32, comptime dupe: bool) *JSC.RefString {
+ std.debug.assert(input_.len > 0);
var _was_new = false;
return this.refCountedStringWithWasNew(&_was_new, input_, hash_, comptime dupe);
}
@@ -1476,7 +1544,6 @@ pub const VirtualMachine = struct {
fn normalizeSpecifierForResolution(specifier_: []const u8, query_string: *[]const u8) []const u8 {
var specifier = specifier_;
- if (strings.hasPrefixComptime(specifier, "file://")) specifier = specifier["file://".len..];
if (strings.indexOfChar(specifier, '?')) |i| {
query_string.* = specifier[i..];
@@ -1673,7 +1740,7 @@ pub const VirtualMachine = struct {
printed,
),
};
- res.* = ErrorableString.err(error.NameTooLong, ResolveMessage.create(global, VirtualMachine.get().allocator, msg, source.utf8()).asVoid());
+ res.* = ErrorableString.err(error.NameTooLong, ResolveMessage.create(global, VirtualMachine.get().allocator, msg, source_utf8.slice()).asVoid());
return;
}
@@ -1987,7 +2054,7 @@ pub const VirtualMachine = struct {
try this.entry_point.generate(
this.allocator,
- this.bun_watcher != null,
+ this.bun_watcher != .none,
Fs.PathName.init(entry_path),
main_file_name,
);
@@ -2044,7 +2111,7 @@ pub const VirtualMachine = struct {
defer JSValue.fromCell(promise).unprotect();
// pending_internal_promise can change if hot module reloading is enabled
- if (this.bun_watcher != null) {
+ if (this.isWatcherEnabled()) {
this.eventLoop().performGC();
switch (this.pending_internal_promise.status(this.global.vm())) {
JSC.JSPromise.Status.Pending => {
@@ -2099,7 +2166,7 @@ pub const VirtualMachine = struct {
var promise = try this.reloadEntryPoint(entry_path);
// pending_internal_promise can change if hot module reloading is enabled
- if (this.bun_watcher != null) {
+ if (this.isWatcherEnabled()) {
this.eventLoop().performGC();
switch (this.pending_internal_promise.status(this.global.vm())) {
JSC.JSPromise.Status.Pending => {
@@ -2125,6 +2192,21 @@ pub const VirtualMachine = struct {
return this.pending_internal_promise;
}
+ pub fn addListeningSocketForWatchMode(this: *VirtualMachine, socket: bun.FileDescriptor) void {
+ if (this.hot_reload != .watch) {
+ return;
+ }
+
+ this.rareData().addListeningSocketForWatchMode(socket);
+ }
+ pub fn removeListeningSocketForWatchMode(this: *VirtualMachine, socket: bun.FileDescriptor) void {
+ if (this.hot_reload != .watch) {
+ return;
+ }
+
+ this.rareData().removeListeningSocketForWatchMode(socket);
+ }
+
pub fn loadMacroEntryPoint(this: *VirtualMachine, entry_path: string, function_name: string, specifier: string, hash: i32) !*JSInternalPromise {
var entry_point_entry = try this.macro_entry_points.getOrPut(hash);
@@ -2742,9 +2824,8 @@ pub const VirtualMachine = struct {
pub const IPCInstance = struct {
globalThis: ?*JSGlobalObject,
- socket: IPC.Socket,
uws_context: *uws.SocketContext,
- ipc_buffer: bun.ByteList,
+ ipc: IPC.IPCData,
pub fn handleIPCMessage(
this: *IPCInstance,
@@ -2794,13 +2875,13 @@ pub const VirtualMachine = struct {
var instance = bun.default_allocator.create(IPCInstance) catch @panic("OOM");
instance.* = .{
.globalThis = this.global,
- .socket = socket,
.uws_context = context,
- .ipc_buffer = bun.ByteList{},
+ .ipc = .{ .socket = socket },
};
var ptr = socket.ext(*IPCInstance);
ptr.?.* = instance;
this.ipc = instance;
+ instance.ipc.writeVersionPacket();
}
comptime {
if (!JSC.is_bindgen)
@@ -2809,6 +2890,7 @@ pub const VirtualMachine = struct {
};
pub const HotReloader = NewHotReloader(VirtualMachine, JSC.EventLoop, false);
+pub const WatchReloader = NewHotReloader(VirtualMachine, JSC.EventLoop, true);
pub const Watcher = HotReloader.Watcher;
extern fn BunDebugger__willHotReload() void;
@@ -2835,6 +2917,8 @@ pub fn NewHotReloader(comptime Ctx: type, comptime EventLoopType: type, comptime
this.eventLoop().enqueueTaskConcurrent(task);
}
+ pub var clear_screen = false;
+
pub const HotReloadTask = struct {
reloader: *Reloader,
count: u8 = 0,
@@ -2860,11 +2944,16 @@ pub fn NewHotReloader(comptime Ctx: type, comptime EventLoopType: type, comptime
}
pub fn enqueue(this: *HotReloadTask) void {
+ JSC.markBinding(@src());
if (this.count == 0)
return;
if (comptime reload_immediately) {
- bun.reloadProcess(bun.default_allocator, Output.enable_ansi_colors);
+ Output.flush();
+ if (comptime Ctx == ImportWatcher) {
+ this.reloader.ctx.rareData().closeAllListenSocketsForWatchMode();
+ }
+ bun.reloadProcess(bun.default_allocator, clear_screen);
unreachable;
}
@@ -2898,23 +2987,51 @@ pub fn NewHotReloader(comptime Ctx: type, comptime EventLoopType: type, comptime
) void);
pub fn enableHotModuleReloading(this: *Ctx) void {
- if (this.bun_watcher != null)
- return;
+ if (comptime @TypeOf(this.bun_watcher) == ImportWatcher) {
+ if (this.bun_watcher != .none)
+ return;
+ } else {
+ if (this.bun_watcher != null)
+ return;
+ }
var reloader = bun.default_allocator.create(Reloader) catch @panic("OOM");
reloader.* = .{
.ctx = this,
.verbose = if (@hasField(Ctx, "log")) this.log.level.atLeast(.info) else false,
};
- this.bun_watcher = @This().Watcher.init(
- reloader,
- this.bundler.fs,
- bun.default_allocator,
- ) catch @panic("Failed to enable File Watcher");
- this.bundler.resolver.watcher = Resolver.ResolveWatcher(*@This().Watcher, onMaybeWatchDirectory).init(this.bun_watcher.?);
+ if (comptime @TypeOf(this.bun_watcher) == ImportWatcher) {
+ this.bun_watcher = if (reload_immediately)
+ .{ .watch = @This().Watcher.init(
+ reloader,
+ this.bundler.fs,
+ bun.default_allocator,
+ ) catch @panic("Failed to enable File Watcher") }
+ else
+ .{ .hot = @This().Watcher.init(
+ reloader,
+ this.bundler.fs,
+ bun.default_allocator,
+ ) catch @panic("Failed to enable File Watcher") };
+
+ if (reload_immediately) {
+ this.bundler.resolver.watcher = Resolver.ResolveWatcher(*@This().Watcher, onMaybeWatchDirectory).init(this.bun_watcher.watch);
+ } else {
+ this.bundler.resolver.watcher = Resolver.ResolveWatcher(*@This().Watcher, onMaybeWatchDirectory).init(this.bun_watcher.hot);
+ }
+ } else {
+ this.bun_watcher = @This().Watcher.init(
+ reloader,
+ this.bundler.fs,
+ bun.default_allocator,
+ ) catch @panic("Failed to enable File Watcher");
+ this.bundler.resolver.watcher = Resolver.ResolveWatcher(*@This().Watcher, onMaybeWatchDirectory).init(this.bun_watcher.?);
+ }
+
+ clear_screen = Output.enable_ansi_colors and !strings.eqlComptime(this.bundler.env.map.get("BUN_CONFIG_NO_CLEAR_TERMINAL_ON_RELOAD") orelse "0", "true");
- this.bun_watcher.?.start() catch @panic("Failed to start File Watcher");
+ reloader.getContext().start() catch @panic("Failed to start File Watcher");
}
pub fn onMaybeWatchDirectory(watch: *@This().Watcher, file_path: string, dir_fd: StoredFileDescriptorType) void {
@@ -2941,6 +3058,18 @@ pub fn NewHotReloader(comptime Ctx: type, comptime EventLoopType: type, comptime
Output.prettyErrorln("<r>Watcher crashed: <red><b>{s}<r>", .{@errorName(err)});
}
+ pub fn getContext(this: *@This()) *@This().Watcher {
+ if (comptime @TypeOf(this.ctx.bun_watcher) == ImportWatcher) {
+ if (reload_immediately) {
+ return this.ctx.bun_watcher.watch;
+ } else {
+ return this.ctx.bun_watcher.hot;
+ }
+ } else {
+ return this.ctx.bun_watcher.?;
+ }
+ }
+
pub fn onFileUpdate(
this: *@This(),
events: []watcher.WatchEvent,
@@ -2954,7 +3083,7 @@ pub fn NewHotReloader(comptime Ctx: type, comptime EventLoopType: type, comptime
const hashes = slice.items(.hash);
const parents = slice.items(.parent_hash);
var file_descriptors = slice.items(.fd);
- var ctx = this.ctx.bun_watcher.?;
+ var ctx = this.getContext();
defer ctx.flushEvictions();
defer Output.flush();
diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig
index cf86cb460..9a46d403b 100644
--- a/src/bun.js/module_loader.zig
+++ b/src/bun.js/module_loader.zig
@@ -154,21 +154,26 @@ const BunDebugHolder = struct {
pub var lock: bun.Lock = undefined;
};
-fn dumpSource(specifier: string, printer: anytype) !void {
+/// Dumps the module source to a file in /tmp/bun-debug-src/{filepath}
+///
+/// This can technically fail if concurrent access across processes happens, or permission issues.
+/// Errors here should always be ignored.
+fn dumpSource(specifier: string, printer: anytype) void {
if (BunDebugHolder.dir == null) {
- BunDebugHolder.dir = try std.fs.cwd().makeOpenPathIterable("/tmp/bun-debug-src/", .{});
+ BunDebugHolder.dir = std.fs.cwd().makeOpenPathIterable("/tmp/bun-debug-src/", .{}) catch return;
BunDebugHolder.lock = bun.Lock.init();
}
BunDebugHolder.lock.lock();
defer BunDebugHolder.lock.unlock();
+ const dir = BunDebugHolder.dir orelse return;
if (std.fs.path.dirname(specifier)) |dir_path| {
- var parent = try BunDebugHolder.dir.?.dir.makeOpenPathIterable(dir_path[1..], .{});
+ var parent = dir.dir.makeOpenPathIterable(dir_path[1..], .{}) catch return;
defer parent.close();
- try parent.dir.writeFile(std.fs.path.basename(specifier), printer.ctx.getWritten());
+ parent.dir.writeFile(std.fs.path.basename(specifier), printer.ctx.getWritten()) catch return;
} else {
- try BunDebugHolder.dir.?.dir.writeFile(std.fs.path.basename(specifier), printer.ctx.getWritten());
+ dir.dir.writeFile(std.fs.path.basename(specifier), printer.ctx.getWritten()) catch return;
}
}
@@ -363,18 +368,15 @@ pub const RuntimeTranspilerStore = struct {
var package_json: ?*PackageJSON = null;
const hash = JSC.Watcher.getHash(path.text);
- if (vm.bun_dev_watcher) |watcher| {
- if (watcher.indexOf(hash)) |index| {
- const _fd = watcher.watchlist.items(.fd)[index];
- fd = if (_fd > 0) _fd else null;
- package_json = watcher.watchlist.items(.package_json)[index];
- }
- } else if (vm.bun_watcher) |watcher| {
- if (watcher.indexOf(hash)) |index| {
- const _fd = watcher.watchlist.items(.fd)[index];
- fd = if (_fd > 0) _fd else null;
- package_json = watcher.watchlist.items(.package_json)[index];
- }
+ switch (vm.bun_watcher) {
+ .hot, .watch => {
+ if (vm.bun_watcher.indexOf(hash)) |index| {
+ const _fd = vm.bun_watcher.watchlist().items(.fd)[index];
+ fd = if (_fd > 0) _fd else null;
+ package_json = vm.bun_watcher.watchlist().items(.package_json)[index];
+ }
+ },
+ else => {},
}
// this should be a cheap lookup because 24 bytes == 8 * 3 so it's read 3 machine words
@@ -405,6 +407,7 @@ pub const RuntimeTranspilerStore = struct {
.file_hash = hash,
.macro_remappings = macro_remappings,
.jsx = bundler.options.jsx,
+ .emit_decorator_metadata = bundler.options.emit_decorator_metadata,
.virtual_source = null,
.dont_bundle_twice = true,
.allow_commonjs = true,
@@ -438,9 +441,9 @@ pub const RuntimeTranspilerStore = struct {
) orelse {
if (vm.isWatcherEnabled()) {
if (input_file_fd != 0) {
- if (vm.bun_watcher != null and !is_node_override and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) {
+ if (!is_node_override and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) {
should_close_input_file_fd = false;
- vm.bun_watcher.?.addFile(
+ vm.bun_watcher.addFile(
input_file_fd,
path.text,
hash,
@@ -459,11 +462,11 @@ pub const RuntimeTranspilerStore = struct {
if (vm.isWatcherEnabled()) {
if (input_file_fd != 0) {
- if (vm.bun_watcher != null and !is_node_override and
+ if (!is_node_override and
std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules"))
{
should_close_input_file_fd = false;
- vm.bun_watcher.?.addFile(
+ vm.bun_watcher.addFile(
input_file_fd,
path.text,
hash,
@@ -547,7 +550,7 @@ pub const RuntimeTranspilerStore = struct {
}
if (comptime Environment.dump_source) {
- dumpSource(specifier, &printer) catch {};
+ dumpSource(specifier, &printer);
}
this.resolved_source = ResolvedSource{
@@ -689,6 +692,7 @@ pub const ModuleLoader = struct {
.onPackageDownloadError = onPackageDownloadError,
.progress_bar = true,
},
+ true,
PackageManager.Options.LogLevel.default,
) catch unreachable;
} else {
@@ -701,6 +705,7 @@ pub const ModuleLoader = struct {
.onPackageManifestError = onPackageManifestError,
.onPackageDownloadError = onPackageDownloadError,
},
+ true,
PackageManager.Options.LogLevel.default_no_progress,
) catch unreachable;
}
@@ -1232,7 +1237,7 @@ pub const ModuleLoader = struct {
}
if (comptime Environment.dump_source) {
- try dumpSource(specifier, &printer);
+ dumpSource(specifier, &printer);
}
var commonjs_exports = try bun.default_allocator.alloc(ZigString, parse_result.ast.commonjs_export_names.len);
@@ -1244,8 +1249,8 @@ pub const ModuleLoader = struct {
var resolved_source = jsc_vm.refCountedResolvedSource(printer.ctx.written, bun.String.init(specifier), path.text, null, false);
if (parse_result.input_fd) |fd_| {
- if (jsc_vm.bun_watcher != null and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) {
- jsc_vm.bun_watcher.?.addFile(
+ if (std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) {
+ jsc_vm.bun_watcher.addFile(
fd_,
path.text,
this.hash,
@@ -1379,18 +1384,10 @@ pub const ModuleLoader = struct {
var fd: ?StoredFileDescriptorType = null;
var package_json: ?*PackageJSON = null;
- if (jsc_vm.bun_dev_watcher) |watcher| {
- if (watcher.indexOf(hash)) |index| {
- const _fd = watcher.watchlist.items(.fd)[index];
- fd = if (_fd > 0) _fd else null;
- package_json = watcher.watchlist.items(.package_json)[index];
- }
- } else if (jsc_vm.bun_watcher) |watcher| {
- if (watcher.indexOf(hash)) |index| {
- const _fd = watcher.watchlist.items(.fd)[index];
- fd = if (_fd > 0) _fd else null;
- package_json = watcher.watchlist.items(.package_json)[index];
- }
+ if (jsc_vm.bun_watcher.indexOf(hash)) |index| {
+ const _fd = jsc_vm.bun_watcher.watchlist().items(.fd)[index];
+ fd = if (_fd > 0) _fd else null;
+ package_json = jsc_vm.bun_watcher.watchlist().items(.package_json)[index];
}
var old = jsc_vm.bundler.log;
@@ -1438,6 +1435,7 @@ pub const ModuleLoader = struct {
.file_hash = hash,
.macro_remappings = macro_remappings,
.jsx = jsc_vm.bundler.options.jsx,
+ .emit_decorator_metadata = jsc_vm.bundler.options.emit_decorator_metadata,
.virtual_source = virtual_source,
.dont_bundle_twice = true,
.allow_commonjs = true,
@@ -1470,9 +1468,9 @@ pub const ModuleLoader = struct {
if (comptime !disable_transpilying) {
if (jsc_vm.isWatcherEnabled()) {
if (input_file_fd != 0) {
- if (jsc_vm.bun_watcher != null and !is_node_override and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) {
+ if (!is_node_override and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) {
should_close_input_file_fd = false;
- jsc_vm.bun_watcher.?.addFile(
+ jsc_vm.bun_watcher.addFile(
input_file_fd,
path.text,
hash,
@@ -1513,9 +1511,9 @@ pub const ModuleLoader = struct {
if (comptime !disable_transpilying) {
if (jsc_vm.isWatcherEnabled()) {
if (input_file_fd != 0) {
- if (jsc_vm.bun_watcher != null and !is_node_override and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) {
+ if (!is_node_override and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) {
should_close_input_file_fd = false;
- jsc_vm.bun_watcher.?.addFile(
+ jsc_vm.bun_watcher.addFile(
input_file_fd,
path.text,
hash,
@@ -1635,7 +1633,7 @@ pub const ModuleLoader = struct {
};
if (comptime Environment.dump_source) {
- try dumpSource(specifier, &printer);
+ dumpSource(specifier, &printer);
}
var commonjs_exports = try bun.default_allocator.alloc(ZigString, parse_result.ast.commonjs_export_names.len);
@@ -1715,7 +1713,7 @@ pub const ModuleLoader = struct {
// const hash = http.Watcher.getHash(path.text);
// if (jsc_vm.watcher) |watcher| {
// if (watcher.indexOf(hash)) |index| {
- // const _fd = watcher.watchlist.items(.fd)[index];
+ // const _fd = watcher.watchlist().items(.fd)[index];
// fd = if (_fd > 0) _fd else null;
// }
// }
@@ -1946,14 +1944,21 @@ pub const ModuleLoader = struct {
}
}
- const synchronous_loader = loader orelse
- // Unknown extensions are to be treated as file loader
- if (jsc_vm.has_loaded or jsc_vm.is_in_preload)
- options.Loader.file
- else
- // Unless it's potentially the main module
- // This is important so that "bun run ./foo-i-have-no-extension" works
- options.Loader.js;
+ const synchronous_loader = loader orelse loader: {
+ if (jsc_vm.has_loaded or jsc_vm.is_in_preload) {
+ // Extensionless files in this context are treated as the JS loader
+ if (path.name.ext.len == 0) {
+ break :loader options.Loader.tsx;
+ }
+
+ // Unknown extensions are to be treated as file loader
+ break :loader options.Loader.file;
+ } else {
+ // Unless it's potentially the main module
+ // This is important so that "bun run ./foo-i-have-no-extension" works
+ break :loader options.Loader.tsx;
+ }
+ };
var promise: ?*JSC.JSInternalPromise = null;
ret.* = ErrorableResolvedSource.ok(
@@ -1981,6 +1986,7 @@ pub const ModuleLoader = struct {
if (err == error.PluginError) {
return null;
}
+
VirtualMachine.processFetchLog(globalObject, specifier_ptr.*, referrer.*, &log, ret, err);
return null;
},
@@ -2152,7 +2158,7 @@ pub const ModuleLoader = struct {
const path = Fs.Path.init(specifier);
const loader = if (loader_ != ._none)
- options.Loader.fromString(@tagName(loader_)).?
+ options.Loader.fromAPI(loader_)
else
jsc_vm.bundler.options.loaders.get(path.name.ext) orelse brk: {
if (strings.eqlLong(specifier, jsc_vm.main, true)) {
@@ -2171,7 +2177,7 @@ pub const ModuleLoader = struct {
referrer_slice.slice(),
specifier_ptr.*,
path,
- options.Loader.fromString(@tagName(loader)).?,
+ loader,
&log,
&virtual_source,
ret,
diff --git a/src/bun.js/modules/BunJSCModule.h b/src/bun.js/modules/BunJSCModule.h
index 73823e16e..74e745bad 100644
--- a/src/bun.js/modules/BunJSCModule.h
+++ b/src/bun.js/modules/BunJSCModule.h
@@ -238,7 +238,7 @@ JSC_DEFINE_HOST_FUNCTION(functionCreateMemoryFootprint,
&peak_rss, &current_commit, &peak_commit, &page_faults);
// mi_process_info produces incorrect rss size on linux.
- Zig::getRSS(&current_rss);
+ Bun::getRSS(&current_rss);
VM &vm = globalObject->vm();
JSC::JSObject *object = JSC::constructEmptyObject(
@@ -746,7 +746,7 @@ JSC_DEFINE_HOST_FUNCTION(functionCodeCoverageForFile,
namespace Zig {
DEFINE_NATIVE_MODULE(BunJSC)
{
- INIT_NATIVE_MODULE(33);
+ INIT_NATIVE_MODULE(34);
putNativeFn(Identifier::fromString(vm, "callerSourceOrigin"_s), functionCallerSourceOrigin);
putNativeFn(Identifier::fromString(vm, "jscDescribe"_s), functionDescribe);
diff --git a/src/bun.js/modules/NodeConstantsModule.h b/src/bun.js/modules/NodeConstantsModule.h
index c1e324b0a..ce701f5e3 100644
--- a/src/bun.js/modules/NodeConstantsModule.h
+++ b/src/bun.js/modules/NodeConstantsModule.h
@@ -1,6 +1,8 @@
#include "_NativeModule.h"
-// Modelled off of https://github.com/nodejs/node/blob/main/src/node_constants.cc
-// Note that if you change any of this code, you probably also have to change ProcessBindingConstants.cpp
+// Modelled off of
+// https://github.com/nodejs/node/blob/main/src/node_constants.cc Note that if
+// you change any of this code, you probably also have to change
+// ProcessBindingConstants.cpp
// require('constants') is implemented in node as a spread of:
// - constants.os.dlopen
@@ -12,16 +14,17 @@
// Instead of loading $processBindingConstants, we just inline it
// These headers may not all be needed, but they are the ones node references.
-// Most of the constants are defined with #if checks on existing #defines, instead of platform-checks
-#include <openssl/ec.h>
-#include <openssl/ssl.h>
-#include <zlib.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+// Most of the constants are defined with #if checks on existing #defines,
+// instead of platform-checks
#include <cerrno>
#include <csignal>
+#include <fcntl.h>
#include <limits>
+#include <openssl/ec.h>
+#include <openssl/ssl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <zlib.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
@@ -47,870 +50,940 @@ namespace Zig {
using namespace WebCore;
DEFINE_NATIVE_MODULE(NodeConstants) {
- INIT_NATIVE_MODULE(63);
+ INIT_NATIVE_MODULE(0);
#ifdef RTLD_LAZY
- put(Identifier::fromString(vm, "RTLD_LAZY"_s), jsNumber(RTLD_LAZY));
+ put(Identifier::fromString(vm, "RTLD_LAZY"_s), jsNumber(RTLD_LAZY));
#endif
#ifdef RTLD_NOW
- put(Identifier::fromString(vm, "RTLD_NOW"_s), jsNumber(RTLD_NOW));
+ put(Identifier::fromString(vm, "RTLD_NOW"_s), jsNumber(RTLD_NOW));
#endif
#ifdef RTLD_GLOBAL
- put(Identifier::fromString(vm, "RTLD_GLOBAL"_s), jsNumber(RTLD_GLOBAL));
+ put(Identifier::fromString(vm, "RTLD_GLOBAL"_s), jsNumber(RTLD_GLOBAL));
#endif
#ifdef RTLD_LOCAL
- put(Identifier::fromString(vm, "RTLD_LOCAL"_s), jsNumber(RTLD_LOCAL));
+ put(Identifier::fromString(vm, "RTLD_LOCAL"_s), jsNumber(RTLD_LOCAL));
#endif
#ifdef RTLD_DEEPBIND
- put(Identifier::fromString(vm, "RTLD_DEEPBIND"_s), jsNumber(RTLD_DEEPBIND));
+ put(Identifier::fromString(vm, "RTLD_DEEPBIND"_s), jsNumber(RTLD_DEEPBIND));
#endif
#ifdef E2BIG
- put(Identifier::fromString(vm, "E2BIG"_s), jsNumber(E2BIG));
+ put(Identifier::fromString(vm, "E2BIG"_s), jsNumber(E2BIG));
#endif
#ifdef EACCES
- put(Identifier::fromString(vm, "EACCES"_s), jsNumber(EACCES));
+ put(Identifier::fromString(vm, "EACCES"_s), jsNumber(EACCES));
#endif
#ifdef EADDRINUSE
- put(Identifier::fromString(vm, "EADDRINUSE"_s), jsNumber(EADDRINUSE));
+ put(Identifier::fromString(vm, "EADDRINUSE"_s), jsNumber(EADDRINUSE));
#endif
#ifdef EADDRNOTAVAIL
- put(Identifier::fromString(vm, "EADDRNOTAVAIL"_s), jsNumber(EADDRNOTAVAIL));
+ put(Identifier::fromString(vm, "EADDRNOTAVAIL"_s), jsNumber(EADDRNOTAVAIL));
#endif
#ifdef EAFNOSUPPORT
- put(Identifier::fromString(vm, "EAFNOSUPPORT"_s), jsNumber(EAFNOSUPPORT));
+ put(Identifier::fromString(vm, "EAFNOSUPPORT"_s), jsNumber(EAFNOSUPPORT));
#endif
#ifdef EAGAIN
- put(Identifier::fromString(vm, "EAGAIN"_s), jsNumber(EAGAIN));
+ put(Identifier::fromString(vm, "EAGAIN"_s), jsNumber(EAGAIN));
#endif
#ifdef EALREADY
- put(Identifier::fromString(vm, "EALREADY"_s), jsNumber(EALREADY));
+ put(Identifier::fromString(vm, "EALREADY"_s), jsNumber(EALREADY));
#endif
#ifdef EBADF
- put(Identifier::fromString(vm, "EBADF"_s), jsNumber(EBADF));
+ put(Identifier::fromString(vm, "EBADF"_s), jsNumber(EBADF));
#endif
#ifdef EBADMSG
- put(Identifier::fromString(vm, "EBADMSG"_s), jsNumber(EBADMSG));
+ put(Identifier::fromString(vm, "EBADMSG"_s), jsNumber(EBADMSG));
#endif
#ifdef EBUSY
- put(Identifier::fromString(vm, "EBUSY"_s), jsNumber(EBUSY));
+ put(Identifier::fromString(vm, "EBUSY"_s), jsNumber(EBUSY));
#endif
#ifdef ECANCELED
- put(Identifier::fromString(vm, "ECANCELED"_s), jsNumber(ECANCELED));
+ put(Identifier::fromString(vm, "ECANCELED"_s), jsNumber(ECANCELED));
#endif
#ifdef ECHILD
- put(Identifier::fromString(vm, "ECHILD"_s), jsNumber(ECHILD));
+ put(Identifier::fromString(vm, "ECHILD"_s), jsNumber(ECHILD));
#endif
#ifdef ECONNABORTED
- put(Identifier::fromString(vm, "ECONNABORTED"_s), jsNumber(ECONNABORTED));
+ put(Identifier::fromString(vm, "ECONNABORTED"_s), jsNumber(ECONNABORTED));
#endif
#ifdef ECONNREFUSED
- put(Identifier::fromString(vm, "ECONNREFUSED"_s), jsNumber(ECONNREFUSED));
+ put(Identifier::fromString(vm, "ECONNREFUSED"_s), jsNumber(ECONNREFUSED));
#endif
#ifdef ECONNRESET
- put(Identifier::fromString(vm, "ECONNRESET"_s), jsNumber(ECONNRESET));
+ put(Identifier::fromString(vm, "ECONNRESET"_s), jsNumber(ECONNRESET));
#endif
#ifdef EDEADLK
- put(Identifier::fromString(vm, "EDEADLK"_s), jsNumber(EDEADLK));
+ put(Identifier::fromString(vm, "EDEADLK"_s), jsNumber(EDEADLK));
#endif
#ifdef EDESTADDRREQ
- put(Identifier::fromString(vm, "EDESTADDRREQ"_s), jsNumber(EDESTADDRREQ));
+ put(Identifier::fromString(vm, "EDESTADDRREQ"_s), jsNumber(EDESTADDRREQ));
#endif
#ifdef EDOM
- put(Identifier::fromString(vm, "EDOM"_s), jsNumber(EDOM));
+ put(Identifier::fromString(vm, "EDOM"_s), jsNumber(EDOM));
#endif
#ifdef EDQUOT
- put(Identifier::fromString(vm, "EDQUOT"_s), jsNumber(EDQUOT));
+ put(Identifier::fromString(vm, "EDQUOT"_s), jsNumber(EDQUOT));
#endif
#ifdef EEXIST
- put(Identifier::fromString(vm, "EEXIST"_s), jsNumber(EEXIST));
+ put(Identifier::fromString(vm, "EEXIST"_s), jsNumber(EEXIST));
#endif
#ifdef EFAULT
- put(Identifier::fromString(vm, "EFAULT"_s), jsNumber(EFAULT));
+ put(Identifier::fromString(vm, "EFAULT"_s), jsNumber(EFAULT));
#endif
#ifdef EFBIG
- put(Identifier::fromString(vm, "EFBIG"_s), jsNumber(EFBIG));
+ put(Identifier::fromString(vm, "EFBIG"_s), jsNumber(EFBIG));
#endif
#ifdef EHOSTUNREACH
- put(Identifier::fromString(vm, "EHOSTUNREACH"_s), jsNumber(EHOSTUNREACH));
+ put(Identifier::fromString(vm, "EHOSTUNREACH"_s), jsNumber(EHOSTUNREACH));
#endif
#ifdef EIDRM
- put(Identifier::fromString(vm, "EIDRM"_s), jsNumber(EIDRM));
+ put(Identifier::fromString(vm, "EIDRM"_s), jsNumber(EIDRM));
#endif
#ifdef EILSEQ
- put(Identifier::fromString(vm, "EILSEQ"_s), jsNumber(EILSEQ));
+ put(Identifier::fromString(vm, "EILSEQ"_s), jsNumber(EILSEQ));
#endif
#ifdef EINPROGRESS
- put(Identifier::fromString(vm, "EINPROGRESS"_s), jsNumber(EINPROGRESS));
+ put(Identifier::fromString(vm, "EINPROGRESS"_s), jsNumber(EINPROGRESS));
#endif
#ifdef EINTR
- put(Identifier::fromString(vm, "EINTR"_s), jsNumber(EINTR));
+ put(Identifier::fromString(vm, "EINTR"_s), jsNumber(EINTR));
#endif
#ifdef EINVAL
- put(Identifier::fromString(vm, "EINVAL"_s), jsNumber(EINVAL));
+ put(Identifier::fromString(vm, "EINVAL"_s), jsNumber(EINVAL));
#endif
#ifdef EIO
- put(Identifier::fromString(vm, "EIO"_s), jsNumber(EIO));
+ put(Identifier::fromString(vm, "EIO"_s), jsNumber(EIO));
#endif
#ifdef EISCONN
- put(Identifier::fromString(vm, "EISCONN"_s), jsNumber(EISCONN));
+ put(Identifier::fromString(vm, "EISCONN"_s), jsNumber(EISCONN));
#endif
#ifdef EISDIR
- put(Identifier::fromString(vm, "EISDIR"_s), jsNumber(EISDIR));
+ put(Identifier::fromString(vm, "EISDIR"_s), jsNumber(EISDIR));
#endif
#ifdef ELOOP
- put(Identifier::fromString(vm, "ELOOP"_s), jsNumber(ELOOP));
+ put(Identifier::fromString(vm, "ELOOP"_s), jsNumber(ELOOP));
#endif
#ifdef EMFILE
- put(Identifier::fromString(vm, "EMFILE"_s), jsNumber(EMFILE));
+ put(Identifier::fromString(vm, "EMFILE"_s), jsNumber(EMFILE));
#endif
#ifdef EMLINK
- put(Identifier::fromString(vm, "EMLINK"_s), jsNumber(EMLINK));
+ put(Identifier::fromString(vm, "EMLINK"_s), jsNumber(EMLINK));
#endif
#ifdef EMSGSIZE
- put(Identifier::fromString(vm, "EMSGSIZE"_s), jsNumber(EMSGSIZE));
+ put(Identifier::fromString(vm, "EMSGSIZE"_s), jsNumber(EMSGSIZE));
#endif
#ifdef EMULTIHOP
- put(Identifier::fromString(vm, "EMULTIHOP"_s), jsNumber(EMULTIHOP));
+ put(Identifier::fromString(vm, "EMULTIHOP"_s), jsNumber(EMULTIHOP));
#endif
#ifdef ENAMETOOLONG
- put(Identifier::fromString(vm, "ENAMETOOLONG"_s), jsNumber(ENAMETOOLONG));
+ put(Identifier::fromString(vm, "ENAMETOOLONG"_s), jsNumber(ENAMETOOLONG));
#endif
#ifdef ENETDOWN
- put(Identifier::fromString(vm, "ENETDOWN"_s), jsNumber(ENETDOWN));
+ put(Identifier::fromString(vm, "ENETDOWN"_s), jsNumber(ENETDOWN));
#endif
#ifdef ENETRESET
- put(Identifier::fromString(vm, "ENETRESET"_s), jsNumber(ENETRESET));
+ put(Identifier::fromString(vm, "ENETRESET"_s), jsNumber(ENETRESET));
#endif
#ifdef ENETUNREACH
- put(Identifier::fromString(vm, "ENETUNREACH"_s), jsNumber(ENETUNREACH));
+ put(Identifier::fromString(vm, "ENETUNREACH"_s), jsNumber(ENETUNREACH));
#endif
#ifdef ENFILE
- put(Identifier::fromString(vm, "ENFILE"_s), jsNumber(ENFILE));
+ put(Identifier::fromString(vm, "ENFILE"_s), jsNumber(ENFILE));
#endif
#ifdef ENOBUFS
- put(Identifier::fromString(vm, "ENOBUFS"_s), jsNumber(ENOBUFS));
+ put(Identifier::fromString(vm, "ENOBUFS"_s), jsNumber(ENOBUFS));
#endif
#ifdef ENODATA
- put(Identifier::fromString(vm, "ENODATA"_s), jsNumber(ENODATA));
+ put(Identifier::fromString(vm, "ENODATA"_s), jsNumber(ENODATA));
#endif
#ifdef ENODEV
- put(Identifier::fromString(vm, "ENODEV"_s), jsNumber(ENODEV));
+ put(Identifier::fromString(vm, "ENODEV"_s), jsNumber(ENODEV));
#endif
#ifdef ENOENT
- put(Identifier::fromString(vm, "ENOENT"_s), jsNumber(ENOENT));
+ put(Identifier::fromString(vm, "ENOENT"_s), jsNumber(ENOENT));
#endif
#ifdef ENOEXEC
- put(Identifier::fromString(vm, "ENOEXEC"_s), jsNumber(ENOEXEC));
+ put(Identifier::fromString(vm, "ENOEXEC"_s), jsNumber(ENOEXEC));
#endif
#ifdef ENOLCK
- put(Identifier::fromString(vm, "ENOLCK"_s), jsNumber(ENOLCK));
+ put(Identifier::fromString(vm, "ENOLCK"_s), jsNumber(ENOLCK));
#endif
#ifdef ENOLINK
- put(Identifier::fromString(vm, "ENOLINK"_s), jsNumber(ENOLINK));
+ put(Identifier::fromString(vm, "ENOLINK"_s), jsNumber(ENOLINK));
#endif
#ifdef ENOMEM
- put(Identifier::fromString(vm, "ENOMEM"_s), jsNumber(ENOMEM));
+ put(Identifier::fromString(vm, "ENOMEM"_s), jsNumber(ENOMEM));
#endif
#ifdef ENOMSG
- put(Identifier::fromString(vm, "ENOMSG"_s), jsNumber(ENOMSG));
+ put(Identifier::fromString(vm, "ENOMSG"_s), jsNumber(ENOMSG));
#endif
#ifdef ENOPROTOOPT
- put(Identifier::fromString(vm, "ENOPROTOOPT"_s), jsNumber(ENOPROTOOPT));
+ put(Identifier::fromString(vm, "ENOPROTOOPT"_s), jsNumber(ENOPROTOOPT));
#endif
#ifdef ENOSPC
- put(Identifier::fromString(vm, "ENOSPC"_s), jsNumber(ENOSPC));
+ put(Identifier::fromString(vm, "ENOSPC"_s), jsNumber(ENOSPC));
#endif
#ifdef ENOSR
- put(Identifier::fromString(vm, "ENOSR"_s), jsNumber(ENOSR));
+ put(Identifier::fromString(vm, "ENOSR"_s), jsNumber(ENOSR));
#endif
#ifdef ENOSTR
- put(Identifier::fromString(vm, "ENOSTR"_s), jsNumber(ENOSTR));
+ put(Identifier::fromString(vm, "ENOSTR"_s), jsNumber(ENOSTR));
#endif
#ifdef ENOSYS
- put(Identifier::fromString(vm, "ENOSYS"_s), jsNumber(ENOSYS));
+ put(Identifier::fromString(vm, "ENOSYS"_s), jsNumber(ENOSYS));
#endif
#ifdef ENOTCONN
- put(Identifier::fromString(vm, "ENOTCONN"_s), jsNumber(ENOTCONN));
+ put(Identifier::fromString(vm, "ENOTCONN"_s), jsNumber(ENOTCONN));
#endif
#ifdef ENOTDIR
- put(Identifier::fromString(vm, "ENOTDIR"_s), jsNumber(ENOTDIR));
+ put(Identifier::fromString(vm, "ENOTDIR"_s), jsNumber(ENOTDIR));
#endif
#ifdef ENOTEMPTY
- put(Identifier::fromString(vm, "ENOTEMPTY"_s), jsNumber(ENOTEMPTY));
+ put(Identifier::fromString(vm, "ENOTEMPTY"_s), jsNumber(ENOTEMPTY));
#endif
#ifdef ENOTSOCK
- put(Identifier::fromString(vm, "ENOTSOCK"_s), jsNumber(ENOTSOCK));
+ put(Identifier::fromString(vm, "ENOTSOCK"_s), jsNumber(ENOTSOCK));
#endif
#ifdef ENOTSUP
- put(Identifier::fromString(vm, "ENOTSUP"_s), jsNumber(ENOTSUP));
+ put(Identifier::fromString(vm, "ENOTSUP"_s), jsNumber(ENOTSUP));
#endif
#ifdef ENOTTY
- put(Identifier::fromString(vm, "ENOTTY"_s), jsNumber(ENOTTY));
+ put(Identifier::fromString(vm, "ENOTTY"_s), jsNumber(ENOTTY));
#endif
#ifdef ENXIO
- put(Identifier::fromString(vm, "ENXIO"_s), jsNumber(ENXIO));
+ put(Identifier::fromString(vm, "ENXIO"_s), jsNumber(ENXIO));
#endif
#ifdef EOPNOTSUPP
- put(Identifier::fromString(vm, "EOPNOTSUPP"_s), jsNumber(EOPNOTSUPP));
+ put(Identifier::fromString(vm, "EOPNOTSUPP"_s), jsNumber(EOPNOTSUPP));
#endif
#ifdef EOVERFLOW
- put(Identifier::fromString(vm, "EOVERFLOW"_s), jsNumber(EOVERFLOW));
+ put(Identifier::fromString(vm, "EOVERFLOW"_s), jsNumber(EOVERFLOW));
#endif
#ifdef EPERM
- put(Identifier::fromString(vm, "EPERM"_s), jsNumber(EPERM));
+ put(Identifier::fromString(vm, "EPERM"_s), jsNumber(EPERM));
#endif
#ifdef EPIPE
- put(Identifier::fromString(vm, "EPIPE"_s), jsNumber(EPIPE));
+ put(Identifier::fromString(vm, "EPIPE"_s), jsNumber(EPIPE));
#endif
#ifdef EPROTO
- put(Identifier::fromString(vm, "EPROTO"_s), jsNumber(EPROTO));
+ put(Identifier::fromString(vm, "EPROTO"_s), jsNumber(EPROTO));
#endif
#ifdef EPROTONOSUPPORT
- put(Identifier::fromString(vm, "EPROTONOSUPPORT"_s), jsNumber(EPROTONOSUPPORT));
+ put(Identifier::fromString(vm, "EPROTONOSUPPORT"_s),
+ jsNumber(EPROTONOSUPPORT));
#endif
#ifdef EPROTOTYPE
- put(Identifier::fromString(vm, "EPROTOTYPE"_s), jsNumber(EPROTOTYPE));
+ put(Identifier::fromString(vm, "EPROTOTYPE"_s), jsNumber(EPROTOTYPE));
#endif
#ifdef ERANGE
- put(Identifier::fromString(vm, "ERANGE"_s), jsNumber(ERANGE));
+ put(Identifier::fromString(vm, "ERANGE"_s), jsNumber(ERANGE));
#endif
#ifdef EROFS
- put(Identifier::fromString(vm, "EROFS"_s), jsNumber(EROFS));
+ put(Identifier::fromString(vm, "EROFS"_s), jsNumber(EROFS));
#endif
#ifdef ESPIPE
- put(Identifier::fromString(vm, "ESPIPE"_s), jsNumber(ESPIPE));
+ put(Identifier::fromString(vm, "ESPIPE"_s), jsNumber(ESPIPE));
#endif
#ifdef ESRCH
- put(Identifier::fromString(vm, "ESRCH"_s), jsNumber(ESRCH));
+ put(Identifier::fromString(vm, "ESRCH"_s), jsNumber(ESRCH));
#endif
#ifdef ESTALE
- put(Identifier::fromString(vm, "ESTALE"_s), jsNumber(ESTALE));
+ put(Identifier::fromString(vm, "ESTALE"_s), jsNumber(ESTALE));
#endif
#ifdef ETIME
- put(Identifier::fromString(vm, "ETIME"_s), jsNumber(ETIME));
+ put(Identifier::fromString(vm, "ETIME"_s), jsNumber(ETIME));
#endif
#ifdef ETIMEDOUT
- put(Identifier::fromString(vm, "ETIMEDOUT"_s), jsNumber(ETIMEDOUT));
+ put(Identifier::fromString(vm, "ETIMEDOUT"_s), jsNumber(ETIMEDOUT));
#endif
#ifdef ETXTBSY
- put(Identifier::fromString(vm, "ETXTBSY"_s), jsNumber(ETXTBSY));
+ put(Identifier::fromString(vm, "ETXTBSY"_s), jsNumber(ETXTBSY));
#endif
#ifdef EWOULDBLOCK
- put(Identifier::fromString(vm, "EWOULDBLOCK"_s), jsNumber(EWOULDBLOCK));
+ put(Identifier::fromString(vm, "EWOULDBLOCK"_s), jsNumber(EWOULDBLOCK));
#endif
#ifdef EXDEV
- put(Identifier::fromString(vm, "EXDEV"_s), jsNumber(EXDEV));
+ put(Identifier::fromString(vm, "EXDEV"_s), jsNumber(EXDEV));
#endif
#ifdef WSAEINTR
- put(Identifier::fromString(vm, "WSAEINTR"_s), jsNumber(WSAEINTR));
+ put(Identifier::fromString(vm, "WSAEINTR"_s), jsNumber(WSAEINTR));
#endif
#ifdef WSAEBADF
- put(Identifier::fromString(vm, "WSAEBADF"_s), jsNumber(WSAEBADF));
+ put(Identifier::fromString(vm, "WSAEBADF"_s), jsNumber(WSAEBADF));
#endif
#ifdef WSAEACCES
- put(Identifier::fromString(vm, "WSAEACCES"_s), jsNumber(WSAEACCES));
+ put(Identifier::fromString(vm, "WSAEACCES"_s), jsNumber(WSAEACCES));
#endif
#ifdef WSAEFAULT
- put(Identifier::fromString(vm, "WSAEFAULT"_s), jsNumber(WSAEFAULT));
+ put(Identifier::fromString(vm, "WSAEFAULT"_s), jsNumber(WSAEFAULT));
#endif
#ifdef WSAEINVAL
- put(Identifier::fromString(vm, "WSAEINVAL"_s), jsNumber(WSAEINVAL));
+ put(Identifier::fromString(vm, "WSAEINVAL"_s), jsNumber(WSAEINVAL));
#endif
#ifdef WSAEMFILE
- put(Identifier::fromString(vm, "WSAEMFILE"_s), jsNumber(WSAEMFILE));
+ put(Identifier::fromString(vm, "WSAEMFILE"_s), jsNumber(WSAEMFILE));
#endif
#ifdef WSAEWOULDBLOCK
- put(Identifier::fromString(vm, "WSAEWOULDBLOCK"_s), jsNumber(WSAEWOULDBLOCK));
+ put(Identifier::fromString(vm, "WSAEWOULDBLOCK"_s), jsNumber(WSAEWOULDBLOCK));
#endif
#ifdef WSAEINPROGRESS
- put(Identifier::fromString(vm, "WSAEINPROGRESS"_s), jsNumber(WSAEINPROGRESS));
+ put(Identifier::fromString(vm, "WSAEINPROGRESS"_s), jsNumber(WSAEINPROGRESS));
#endif
#ifdef WSAEALREADY
- put(Identifier::fromString(vm, "WSAEALREADY"_s), jsNumber(WSAEALREADY));
+ put(Identifier::fromString(vm, "WSAEALREADY"_s), jsNumber(WSAEALREADY));
#endif
#ifdef WSAENOTSOCK
- put(Identifier::fromString(vm, "WSAENOTSOCK"_s), jsNumber(WSAENOTSOCK));
+ put(Identifier::fromString(vm, "WSAENOTSOCK"_s), jsNumber(WSAENOTSOCK));
#endif
#ifdef WSAEDESTADDRREQ
- put(Identifier::fromString(vm, "WSAEDESTADDRREQ"_s), jsNumber(WSAEDESTADDRREQ));
+ put(Identifier::fromString(vm, "WSAEDESTADDRREQ"_s),
+ jsNumber(WSAEDESTADDRREQ));
#endif
#ifdef WSAEMSGSIZE
- put(Identifier::fromString(vm, "WSAEMSGSIZE"_s), jsNumber(WSAEMSGSIZE));
+ put(Identifier::fromString(vm, "WSAEMSGSIZE"_s), jsNumber(WSAEMSGSIZE));
#endif
#ifdef WSAEPROTOTYPE
- put(Identifier::fromString(vm, "WSAEPROTOTYPE"_s), jsNumber(WSAEPROTOTYPE));
+ put(Identifier::fromString(vm, "WSAEPROTOTYPE"_s), jsNumber(WSAEPROTOTYPE));
#endif
#ifdef WSAENOPROTOOPT
- put(Identifier::fromString(vm, "WSAENOPROTOOPT"_s), jsNumber(WSAENOPROTOOPT));
+ put(Identifier::fromString(vm, "WSAENOPROTOOPT"_s), jsNumber(WSAENOPROTOOPT));
#endif
#ifdef WSAEPROTONOSUPPORT
- put(Identifier::fromString(vm, "WSAEPROTONOSUPPORT"_s), jsNumber(WSAEPROTONOSUPPORT));
+ put(Identifier::fromString(vm, "WSAEPROTONOSUPPORT"_s),
+ jsNumber(WSAEPROTONOSUPPORT));
#endif
#ifdef WSAESOCKTNOSUPPORT
- put(Identifier::fromString(vm, "WSAESOCKTNOSUPPORT"_s), jsNumber(WSAESOCKTNOSUPPORT));
+ put(Identifier::fromString(vm, "WSAESOCKTNOSUPPORT"_s),
+ jsNumber(WSAESOCKTNOSUPPORT));
#endif
#ifdef WSAEOPNOTSUPP
- put(Identifier::fromString(vm, "WSAEOPNOTSUPP"_s), jsNumber(WSAEOPNOTSUPP));
+ put(Identifier::fromString(vm, "WSAEOPNOTSUPP"_s), jsNumber(WSAEOPNOTSUPP));
#endif
#ifdef WSAEPFNOSUPPORT
- put(Identifier::fromString(vm, "WSAEPFNOSUPPORT"_s), jsNumber(WSAEPFNOSUPPORT));
+ put(Identifier::fromString(vm, "WSAEPFNOSUPPORT"_s),
+ jsNumber(WSAEPFNOSUPPORT));
#endif
#ifdef WSAEAFNOSUPPORT
- put(Identifier::fromString(vm, "WSAEAFNOSUPPORT"_s), jsNumber(WSAEAFNOSUPPORT));
+ put(Identifier::fromString(vm, "WSAEAFNOSUPPORT"_s),
+ jsNumber(WSAEAFNOSUPPORT));
#endif
#ifdef WSAEADDRINUSE
- put(Identifier::fromString(vm, "WSAEADDRINUSE"_s), jsNumber(WSAEADDRINUSE));
+ put(Identifier::fromString(vm, "WSAEADDRINUSE"_s), jsNumber(WSAEADDRINUSE));
#endif
#ifdef WSAEADDRNOTAVAIL
- put(Identifier::fromString(vm, "WSAEADDRNOTAVAIL"_s), jsNumber(WSAEADDRNOTAVAIL));
+ put(Identifier::fromString(vm, "WSAEADDRNOTAVAIL"_s),
+ jsNumber(WSAEADDRNOTAVAIL));
#endif
#ifdef WSAENETDOWN
- put(Identifier::fromString(vm, "WSAENETDOWN"_s), jsNumber(WSAENETDOWN));
+ put(Identifier::fromString(vm, "WSAENETDOWN"_s), jsNumber(WSAENETDOWN));
#endif
#ifdef WSAENETUNREACH
- put(Identifier::fromString(vm, "WSAENETUNREACH"_s), jsNumber(WSAENETUNREACH));
+ put(Identifier::fromString(vm, "WSAENETUNREACH"_s), jsNumber(WSAENETUNREACH));
#endif
#ifdef WSAENETRESET
- put(Identifier::fromString(vm, "WSAENETRESET"_s), jsNumber(WSAENETRESET));
+ put(Identifier::fromString(vm, "WSAENETRESET"_s), jsNumber(WSAENETRESET));
#endif
#ifdef WSAECONNABORTED
- put(Identifier::fromString(vm, "WSAECONNABORTED"_s), jsNumber(WSAECONNABORTED));
+ put(Identifier::fromString(vm, "WSAECONNABORTED"_s),
+ jsNumber(WSAECONNABORTED));
#endif
#ifdef WSAECONNRESET
- put(Identifier::fromString(vm, "WSAECONNRESET"_s), jsNumber(WSAECONNRESET));
+ put(Identifier::fromString(vm, "WSAECONNRESET"_s), jsNumber(WSAECONNRESET));
#endif
#ifdef WSAENOBUFS
- put(Identifier::fromString(vm, "WSAENOBUFS"_s), jsNumber(WSAENOBUFS));
+ put(Identifier::fromString(vm, "WSAENOBUFS"_s), jsNumber(WSAENOBUFS));
#endif
#ifdef WSAEISCONN
- put(Identifier::fromString(vm, "WSAEISCONN"_s), jsNumber(WSAEISCONN));
+ put(Identifier::fromString(vm, "WSAEISCONN"_s), jsNumber(WSAEISCONN));
#endif
#ifdef WSAENOTCONN
- put(Identifier::fromString(vm, "WSAENOTCONN"_s), jsNumber(WSAENOTCONN));
+ put(Identifier::fromString(vm, "WSAENOTCONN"_s), jsNumber(WSAENOTCONN));
#endif
#ifdef WSAESHUTDOWN
- put(Identifier::fromString(vm, "WSAESHUTDOWN"_s), jsNumber(WSAESHUTDOWN));
+ put(Identifier::fromString(vm, "WSAESHUTDOWN"_s), jsNumber(WSAESHUTDOWN));
#endif
#ifdef WSAETOOMANYREFS
- put(Identifier::fromString(vm, "WSAETOOMANYREFS"_s), jsNumber(WSAETOOMANYREFS));
+ put(Identifier::fromString(vm, "WSAETOOMANYREFS"_s),
+ jsNumber(WSAETOOMANYREFS));
#endif
#ifdef WSAETIMEDOUT
- put(Identifier::fromString(vm, "WSAETIMEDOUT"_s), jsNumber(WSAETIMEDOUT));
+ put(Identifier::fromString(vm, "WSAETIMEDOUT"_s), jsNumber(WSAETIMEDOUT));
#endif
#ifdef WSAECONNREFUSED
- put(Identifier::fromString(vm, "WSAECONNREFUSED"_s), jsNumber(WSAECONNREFUSED));
+ put(Identifier::fromString(vm, "WSAECONNREFUSED"_s),
+ jsNumber(WSAECONNREFUSED));
#endif
#ifdef WSAELOOP
- put(Identifier::fromString(vm, "WSAELOOP"_s), jsNumber(WSAELOOP));
+ put(Identifier::fromString(vm, "WSAELOOP"_s), jsNumber(WSAELOOP));
#endif
#ifdef WSAENAMETOOLONG
- put(Identifier::fromString(vm, "WSAENAMETOOLONG"_s), jsNumber(WSAENAMETOOLONG));
+ put(Identifier::fromString(vm, "WSAENAMETOOLONG"_s),
+ jsNumber(WSAENAMETOOLONG));
#endif
#ifdef WSAEHOSTDOWN
- put(Identifier::fromString(vm, "WSAEHOSTDOWN"_s), jsNumber(WSAEHOSTDOWN));
+ put(Identifier::fromString(vm, "WSAEHOSTDOWN"_s), jsNumber(WSAEHOSTDOWN));
#endif
#ifdef WSAEHOSTUNREACH
- put(Identifier::fromString(vm, "WSAEHOSTUNREACH"_s), jsNumber(WSAEHOSTUNREACH));
+ put(Identifier::fromString(vm, "WSAEHOSTUNREACH"_s),
+ jsNumber(WSAEHOSTUNREACH));
#endif
#ifdef WSAENOTEMPTY
- put(Identifier::fromString(vm, "WSAENOTEMPTY"_s), jsNumber(WSAENOTEMPTY));
+ put(Identifier::fromString(vm, "WSAENOTEMPTY"_s), jsNumber(WSAENOTEMPTY));
#endif
#ifdef WSAEPROCLIM
- put(Identifier::fromString(vm, "WSAEPROCLIM"_s), jsNumber(WSAEPROCLIM));
+ put(Identifier::fromString(vm, "WSAEPROCLIM"_s), jsNumber(WSAEPROCLIM));
#endif
#ifdef WSAEUSERS
- put(Identifier::fromString(vm, "WSAEUSERS"_s), jsNumber(WSAEUSERS));
+ put(Identifier::fromString(vm, "WSAEUSERS"_s), jsNumber(WSAEUSERS));
#endif
#ifdef WSAEDQUOT
- put(Identifier::fromString(vm, "WSAEDQUOT"_s), jsNumber(WSAEDQUOT));
+ put(Identifier::fromString(vm, "WSAEDQUOT"_s), jsNumber(WSAEDQUOT));
#endif
#ifdef WSAESTALE
- put(Identifier::fromString(vm, "WSAESTALE"_s), jsNumber(WSAESTALE));
+ put(Identifier::fromString(vm, "WSAESTALE"_s), jsNumber(WSAESTALE));
#endif
#ifdef WSAEREMOTE
- put(Identifier::fromString(vm, "WSAEREMOTE"_s), jsNumber(WSAEREMOTE));
+ put(Identifier::fromString(vm, "WSAEREMOTE"_s), jsNumber(WSAEREMOTE));
#endif
#ifdef WSASYSNOTREADY
- put(Identifier::fromString(vm, "WSASYSNOTREADY"_s), jsNumber(WSASYSNOTREADY));
+ put(Identifier::fromString(vm, "WSASYSNOTREADY"_s), jsNumber(WSASYSNOTREADY));
#endif
#ifdef WSAVERNOTSUPPORTED
- put(Identifier::fromString(vm, "WSAVERNOTSUPPORTED"_s), jsNumber(WSAVERNOTSUPPORTED));
+ put(Identifier::fromString(vm, "WSAVERNOTSUPPORTED"_s),
+ jsNumber(WSAVERNOTSUPPORTED));
#endif
#ifdef WSANOTINITIALISED
- put(Identifier::fromString(vm, "WSANOTINITIALISED"_s), jsNumber(WSANOTINITIALISED));
+ put(Identifier::fromString(vm, "WSANOTINITIALISED"_s),
+ jsNumber(WSANOTINITIALISED));
#endif
#ifdef WSAEDISCON
- put(Identifier::fromString(vm, "WSAEDISCON"_s), jsNumber(WSAEDISCON));
+ put(Identifier::fromString(vm, "WSAEDISCON"_s), jsNumber(WSAEDISCON));
#endif
#ifdef WSAENOMORE
- put(Identifier::fromString(vm, "WSAENOMORE"_s), jsNumber(WSAENOMORE));
+ put(Identifier::fromString(vm, "WSAENOMORE"_s), jsNumber(WSAENOMORE));
#endif
#ifdef WSAECANCELLED
- put(Identifier::fromString(vm, "WSAECANCELLED"_s), jsNumber(WSAECANCELLED));
+ put(Identifier::fromString(vm, "WSAECANCELLED"_s), jsNumber(WSAECANCELLED));
#endif
#ifdef WSAEINVALIDPROCTABLE
- put(Identifier::fromString(vm, "WSAEINVALIDPROCTABLE"_s), jsNumber(WSAEINVALIDPROCTABLE));
+ put(Identifier::fromString(vm, "WSAEINVALIDPROCTABLE"_s),
+ jsNumber(WSAEINVALIDPROCTABLE));
#endif
#ifdef WSAEINVALIDPROVIDER
- put(Identifier::fromString(vm, "WSAEINVALIDPROVIDER"_s), jsNumber(WSAEINVALIDPROVIDER));
+ put(Identifier::fromString(vm, "WSAEINVALIDPROVIDER"_s),
+ jsNumber(WSAEINVALIDPROVIDER));
#endif
#ifdef WSAEPROVIDERFAILEDINIT
- put(Identifier::fromString(vm, "WSAEPROVIDERFAILEDINIT"_s), jsNumber(WSAEPROVIDERFAILEDINIT));
+ put(Identifier::fromString(vm, "WSAEPROVIDERFAILEDINIT"_s),
+ jsNumber(WSAEPROVIDERFAILEDINIT));
#endif
#ifdef WSASYSCALLFAILURE
- put(Identifier::fromString(vm, "WSASYSCALLFAILURE"_s), jsNumber(WSASYSCALLFAILURE));
+ put(Identifier::fromString(vm, "WSASYSCALLFAILURE"_s),
+ jsNumber(WSASYSCALLFAILURE));
#endif
#ifdef WSASERVICE_NOT_FOUND
- put(Identifier::fromString(vm, "WSASERVICE_NOT_FOUND"_s), jsNumber(WSASERVICE_NOT_FOUND));
+ put(Identifier::fromString(vm, "WSASERVICE_NOT_FOUND"_s),
+ jsNumber(WSASERVICE_NOT_FOUND));
#endif
#ifdef WSATYPE_NOT_FOUND
- put(Identifier::fromString(vm, "WSATYPE_NOT_FOUND"_s), jsNumber(WSATYPE_NOT_FOUND));
+ put(Identifier::fromString(vm, "WSATYPE_NOT_FOUND"_s),
+ jsNumber(WSATYPE_NOT_FOUND));
#endif
#ifdef WSA_E_NO_MORE
- put(Identifier::fromString(vm, "WSA_E_NO_MORE"_s), jsNumber(WSA_E_NO_MORE));
+ put(Identifier::fromString(vm, "WSA_E_NO_MORE"_s), jsNumber(WSA_E_NO_MORE));
#endif
#ifdef WSA_E_CANCELLED
- put(Identifier::fromString(vm, "WSA_E_CANCELLED"_s), jsNumber(WSA_E_CANCELLED));
+ put(Identifier::fromString(vm, "WSA_E_CANCELLED"_s),
+ jsNumber(WSA_E_CANCELLED));
#endif
#ifdef WSAEREFUSED
- put(Identifier::fromString(vm, "WSAEREFUSED"_s), jsNumber(WSAEREFUSED));
-#endif
- put(Identifier::fromString(vm, "PRIORITY_LOW"_s), jsNumber(19));
- put(Identifier::fromString(vm, "PRIORITY_BELOW_NORMAL"_s), jsNumber(10));
- put(Identifier::fromString(vm, "PRIORITY_NORMAL"_s), jsNumber(0));
- put(Identifier::fromString(vm, "PRIORITY_ABOVE_NORMAL"_s), jsNumber(-7));
- put(Identifier::fromString(vm, "PRIORITY_HIGH"_s), jsNumber(-14));
- put(Identifier::fromString(vm, "PRIORITY_HIGHEST"_s), jsNumber(-20));
+ put(Identifier::fromString(vm, "WSAEREFUSED"_s), jsNumber(WSAEREFUSED));
+#endif
+ put(Identifier::fromString(vm, "PRIORITY_LOW"_s), jsNumber(19));
+ put(Identifier::fromString(vm, "PRIORITY_BELOW_NORMAL"_s), jsNumber(10));
+ put(Identifier::fromString(vm, "PRIORITY_NORMAL"_s), jsNumber(0));
+ put(Identifier::fromString(vm, "PRIORITY_ABOVE_NORMAL"_s), jsNumber(-7));
+ put(Identifier::fromString(vm, "PRIORITY_HIGH"_s), jsNumber(-14));
+ put(Identifier::fromString(vm, "PRIORITY_HIGHEST"_s), jsNumber(-20));
#ifdef SIGHUP
- put(Identifier::fromString(vm, "SIGHUP"_s), jsNumber(SIGHUP));
+ put(Identifier::fromString(vm, "SIGHUP"_s), jsNumber(SIGHUP));
#endif
#ifdef SIGINT
- put(Identifier::fromString(vm, "SIGINT"_s), jsNumber(SIGINT));
+ put(Identifier::fromString(vm, "SIGINT"_s), jsNumber(SIGINT));
#endif
#ifdef SIGQUIT
- put(Identifier::fromString(vm, "SIGQUIT"_s), jsNumber(SIGQUIT));
+ put(Identifier::fromString(vm, "SIGQUIT"_s), jsNumber(SIGQUIT));
#endif
#ifdef SIGILL
- put(Identifier::fromString(vm, "SIGILL"_s), jsNumber(SIGILL));
+ put(Identifier::fromString(vm, "SIGILL"_s), jsNumber(SIGILL));
#endif
#ifdef SIGTRAP
- put(Identifier::fromString(vm, "SIGTRAP"_s), jsNumber(SIGTRAP));
+ put(Identifier::fromString(vm, "SIGTRAP"_s), jsNumber(SIGTRAP));
#endif
#ifdef SIGABRT
- put(Identifier::fromString(vm, "SIGABRT"_s), jsNumber(SIGABRT));
+ put(Identifier::fromString(vm, "SIGABRT"_s), jsNumber(SIGABRT));
#endif
#ifdef SIGIOT
- put(Identifier::fromString(vm, "SIGIOT"_s), jsNumber(SIGIOT));
+ put(Identifier::fromString(vm, "SIGIOT"_s), jsNumber(SIGIOT));
#endif
#ifdef SIGBUS
- put(Identifier::fromString(vm, "SIGBUS"_s), jsNumber(SIGBUS));
+ put(Identifier::fromString(vm, "SIGBUS"_s), jsNumber(SIGBUS));
#endif
#ifdef SIGFPE
- put(Identifier::fromString(vm, "SIGFPE"_s), jsNumber(SIGFPE));
+ put(Identifier::fromString(vm, "SIGFPE"_s), jsNumber(SIGFPE));
#endif
#ifdef SIGKILL
- put(Identifier::fromString(vm, "SIGKILL"_s), jsNumber(SIGKILL));
+ put(Identifier::fromString(vm, "SIGKILL"_s), jsNumber(SIGKILL));
#endif
#ifdef SIGUSR1
- put(Identifier::fromString(vm, "SIGUSR1"_s), jsNumber(SIGUSR1));
+ put(Identifier::fromString(vm, "SIGUSR1"_s), jsNumber(SIGUSR1));
#endif
#ifdef SIGSEGV
- put(Identifier::fromString(vm, "SIGSEGV"_s), jsNumber(SIGSEGV));
+ put(Identifier::fromString(vm, "SIGSEGV"_s), jsNumber(SIGSEGV));
#endif
#ifdef SIGUSR2
- put(Identifier::fromString(vm, "SIGUSR2"_s), jsNumber(SIGUSR2));
+ put(Identifier::fromString(vm, "SIGUSR2"_s), jsNumber(SIGUSR2));
#endif
#ifdef SIGPIPE
- put(Identifier::fromString(vm, "SIGPIPE"_s), jsNumber(SIGPIPE));
+ put(Identifier::fromString(vm, "SIGPIPE"_s), jsNumber(SIGPIPE));
#endif
#ifdef SIGALRM
- put(Identifier::fromString(vm, "SIGALRM"_s), jsNumber(SIGALRM));
+ put(Identifier::fromString(vm, "SIGALRM"_s), jsNumber(SIGALRM));
#endif
#ifdef SIGTERM
- put(Identifier::fromString(vm, "SIGTERM"_s), jsNumber(SIGTERM));
+ put(Identifier::fromString(vm, "SIGTERM"_s), jsNumber(SIGTERM));
#endif
#ifdef SIGCHLD
- put(Identifier::fromString(vm, "SIGCHLD"_s), jsNumber(SIGCHLD));
+ put(Identifier::fromString(vm, "SIGCHLD"_s), jsNumber(SIGCHLD));
#endif
#ifdef SIGSTKFLT
- put(Identifier::fromString(vm, "SIGSTKFLT"_s), jsNumber(SIGSTKFLT));
+ put(Identifier::fromString(vm, "SIGSTKFLT"_s), jsNumber(SIGSTKFLT));
#endif
#ifdef SIGCONT
- put(Identifier::fromString(vm, "SIGCONT"_s), jsNumber(SIGCONT));
+ put(Identifier::fromString(vm, "SIGCONT"_s), jsNumber(SIGCONT));
#endif
#ifdef SIGSTOP
- put(Identifier::fromString(vm, "SIGSTOP"_s), jsNumber(SIGSTOP));
+ put(Identifier::fromString(vm, "SIGSTOP"_s), jsNumber(SIGSTOP));
#endif
#ifdef SIGTSTP
- put(Identifier::fromString(vm, "SIGTSTP"_s), jsNumber(SIGTSTP));
+ put(Identifier::fromString(vm, "SIGTSTP"_s), jsNumber(SIGTSTP));
#endif
#ifdef SIGBREAK
- put(Identifier::fromString(vm, "SIGBREAK"_s), jsNumber(SIGBREAK));
+ put(Identifier::fromString(vm, "SIGBREAK"_s), jsNumber(SIGBREAK));
#endif
#ifdef SIGTTIN
- put(Identifier::fromString(vm, "SIGTTIN"_s), jsNumber(SIGTTIN));
+ put(Identifier::fromString(vm, "SIGTTIN"_s), jsNumber(SIGTTIN));
#endif
#ifdef SIGTTOU
- put(Identifier::fromString(vm, "SIGTTOU"_s), jsNumber(SIGTTOU));
+ put(Identifier::fromString(vm, "SIGTTOU"_s), jsNumber(SIGTTOU));
#endif
#ifdef SIGURG
- put(Identifier::fromString(vm, "SIGURG"_s), jsNumber(SIGURG));
+ put(Identifier::fromString(vm, "SIGURG"_s), jsNumber(SIGURG));
#endif
#ifdef SIGXCPU
- put(Identifier::fromString(vm, "SIGXCPU"_s), jsNumber(SIGXCPU));
+ put(Identifier::fromString(vm, "SIGXCPU"_s), jsNumber(SIGXCPU));
#endif
#ifdef SIGXFSZ
- put(Identifier::fromString(vm, "SIGXFSZ"_s), jsNumber(SIGXFSZ));
+ put(Identifier::fromString(vm, "SIGXFSZ"_s), jsNumber(SIGXFSZ));
#endif
#ifdef SIGVTALRM
- put(Identifier::fromString(vm, "SIGVTALRM"_s), jsNumber(SIGVTALRM));
+ put(Identifier::fromString(vm, "SIGVTALRM"_s), jsNumber(SIGVTALRM));
#endif
#ifdef SIGPROF
- put(Identifier::fromString(vm, "SIGPROF"_s), jsNumber(SIGPROF));
+ put(Identifier::fromString(vm, "SIGPROF"_s), jsNumber(SIGPROF));
#endif
#ifdef SIGWINCH
- put(Identifier::fromString(vm, "SIGWINCH"_s), jsNumber(SIGWINCH));
+ put(Identifier::fromString(vm, "SIGWINCH"_s), jsNumber(SIGWINCH));
#endif
#ifdef SIGIO
- put(Identifier::fromString(vm, "SIGIO"_s), jsNumber(SIGIO));
+ put(Identifier::fromString(vm, "SIGIO"_s), jsNumber(SIGIO));
#endif
#ifdef SIGPOLL
- put(Identifier::fromString(vm, "SIGPOLL"_s), jsNumber(SIGPOLL));
+ put(Identifier::fromString(vm, "SIGPOLL"_s), jsNumber(SIGPOLL));
#endif
#ifdef SIGLOST
- put(Identifier::fromString(vm, "SIGLOST"_s), jsNumber(SIGLOST));
+ put(Identifier::fromString(vm, "SIGLOST"_s), jsNumber(SIGLOST));
#endif
#ifdef SIGPWR
- put(Identifier::fromString(vm, "SIGPWR"_s), jsNumber(SIGPWR));
+ put(Identifier::fromString(vm, "SIGPWR"_s), jsNumber(SIGPWR));
#endif
#ifdef SIGINFO
- put(Identifier::fromString(vm, "SIGINFO"_s), jsNumber(SIGINFO));
+ put(Identifier::fromString(vm, "SIGINFO"_s), jsNumber(SIGINFO));
#endif
#ifdef SIGSYS
- put(Identifier::fromString(vm, "SIGSYS"_s), jsNumber(SIGSYS));
+ put(Identifier::fromString(vm, "SIGSYS"_s), jsNumber(SIGSYS));
#endif
#ifdef SIGUNUSED
- put(Identifier::fromString(vm, "SIGUNUSED"_s), jsNumber(SIGUNUSED));
+ put(Identifier::fromString(vm, "SIGUNUSED"_s), jsNumber(SIGUNUSED));
#endif
- put(Identifier::fromString(vm, "UV_FS_SYMLINK_DIR"_s), jsNumber(1));
- put(Identifier::fromString(vm, "UV_FS_SYMLINK_JUNCTION"_s), jsNumber(2));
- put(Identifier::fromString(vm, "O_RDONLY"_s), jsNumber(O_RDONLY));
- put(Identifier::fromString(vm, "O_WRONLY"_s), jsNumber(O_WRONLY));
- put(Identifier::fromString(vm, "O_RDWR"_s), jsNumber(O_RDWR));
+ put(Identifier::fromString(vm, "UV_FS_SYMLINK_DIR"_s), jsNumber(1));
+ put(Identifier::fromString(vm, "UV_FS_SYMLINK_JUNCTION"_s), jsNumber(2));
+ put(Identifier::fromString(vm, "O_RDONLY"_s), jsNumber(O_RDONLY));
+ put(Identifier::fromString(vm, "O_WRONLY"_s), jsNumber(O_WRONLY));
+ put(Identifier::fromString(vm, "O_RDWR"_s), jsNumber(O_RDWR));
- put(Identifier::fromString(vm, "UV_DIRENT_UNKNOWN"_s), jsNumber(0));
- put(Identifier::fromString(vm, "UV_DIRENT_FILE"_s), jsNumber(1));
- put(Identifier::fromString(vm, "UV_DIRENT_DIR"_s), jsNumber(2));
- put(Identifier::fromString(vm, "UV_DIRENT_LINK"_s), jsNumber(3));
- put(Identifier::fromString(vm, "UV_DIRENT_FIFO"_s), jsNumber(4));
- put(Identifier::fromString(vm, "UV_DIRENT_SOCKET"_s), jsNumber(5));
- put(Identifier::fromString(vm, "UV_DIRENT_CHAR"_s), jsNumber(6));
- put(Identifier::fromString(vm, "UV_DIRENT_BLOCK"_s), jsNumber(7));
+ put(Identifier::fromString(vm, "UV_DIRENT_UNKNOWN"_s), jsNumber(0));
+ put(Identifier::fromString(vm, "UV_DIRENT_FILE"_s), jsNumber(1));
+ put(Identifier::fromString(vm, "UV_DIRENT_DIR"_s), jsNumber(2));
+ put(Identifier::fromString(vm, "UV_DIRENT_LINK"_s), jsNumber(3));
+ put(Identifier::fromString(vm, "UV_DIRENT_FIFO"_s), jsNumber(4));
+ put(Identifier::fromString(vm, "UV_DIRENT_SOCKET"_s), jsNumber(5));
+ put(Identifier::fromString(vm, "UV_DIRENT_CHAR"_s), jsNumber(6));
+ put(Identifier::fromString(vm, "UV_DIRENT_BLOCK"_s), jsNumber(7));
- put(Identifier::fromString(vm, "S_IFMT"_s), jsNumber(S_IFMT));
- put(Identifier::fromString(vm, "S_IFREG"_s), jsNumber(S_IFREG));
- put(Identifier::fromString(vm, "S_IFDIR"_s), jsNumber(S_IFDIR));
- put(Identifier::fromString(vm, "S_IFCHR"_s), jsNumber(S_IFCHR));
+ put(Identifier::fromString(vm, "S_IFMT"_s), jsNumber(S_IFMT));
+ put(Identifier::fromString(vm, "S_IFREG"_s), jsNumber(S_IFREG));
+ put(Identifier::fromString(vm, "S_IFDIR"_s), jsNumber(S_IFDIR));
+ put(Identifier::fromString(vm, "S_IFCHR"_s), jsNumber(S_IFCHR));
#ifdef S_IFBLK
- put(Identifier::fromString(vm, "S_IFBLK"_s), jsNumber(S_IFBLK));
+ put(Identifier::fromString(vm, "S_IFBLK"_s), jsNumber(S_IFBLK));
#endif
#ifdef S_IFIFO
- put(Identifier::fromString(vm, "S_IFIFO"_s), jsNumber(S_IFIFO));
+ put(Identifier::fromString(vm, "S_IFIFO"_s), jsNumber(S_IFIFO));
#endif
#ifdef S_IFLNK
- put(Identifier::fromString(vm, "S_IFLNK"_s), jsNumber(S_IFLNK));
+ put(Identifier::fromString(vm, "S_IFLNK"_s), jsNumber(S_IFLNK));
#endif
#ifdef S_IFSOCK
- put(Identifier::fromString(vm, "S_IFSOCK"_s), jsNumber(S_IFSOCK));
+ put(Identifier::fromString(vm, "S_IFSOCK"_s), jsNumber(S_IFSOCK));
#endif
#ifdef O_CREAT
- put(Identifier::fromString(vm, "O_CREAT"_s), jsNumber(O_CREAT));
+ put(Identifier::fromString(vm, "O_CREAT"_s), jsNumber(O_CREAT));
#endif
#ifdef O_EXCL
- put(Identifier::fromString(vm, "O_EXCL"_s), jsNumber(O_EXCL));
+ put(Identifier::fromString(vm, "O_EXCL"_s), jsNumber(O_EXCL));
#endif
- put(Identifier::fromString(vm, "UV_FS_O_FILEMAP"_s), jsNumber(0));
+ put(Identifier::fromString(vm, "UV_FS_O_FILEMAP"_s), jsNumber(0));
#ifdef O_NOCTTY
- put(Identifier::fromString(vm, "O_NOCTTY"_s), jsNumber(O_NOCTTY));
+ put(Identifier::fromString(vm, "O_NOCTTY"_s), jsNumber(O_NOCTTY));
#endif
#ifdef O_TRUNC
- put(Identifier::fromString(vm, "O_TRUNC"_s), jsNumber(O_TRUNC));
+ put(Identifier::fromString(vm, "O_TRUNC"_s), jsNumber(O_TRUNC));
#endif
#ifdef O_APPEND
- put(Identifier::fromString(vm, "O_APPEND"_s), jsNumber(O_APPEND));
+ put(Identifier::fromString(vm, "O_APPEND"_s), jsNumber(O_APPEND));
#endif
#ifdef O_DIRECTORY
- put(Identifier::fromString(vm, "O_DIRECTORY"_s), jsNumber(O_DIRECTORY));
-#endif
-#ifdef O_EXCL
- put(Identifier::fromString(vm, "O_EXCL"_s), jsNumber(O_EXCL));
+ put(Identifier::fromString(vm, "O_DIRECTORY"_s), jsNumber(O_DIRECTORY));
#endif
#ifdef O_NOATIME
- put(Identifier::fromString(vm, "O_NOATIME"_s), jsNumber(O_NOATIME));
+ put(Identifier::fromString(vm, "O_NOATIME"_s), jsNumber(O_NOATIME));
#endif
#ifdef O_NOFOLLOW
- put(Identifier::fromString(vm, "O_NOFOLLOW"_s), jsNumber(O_NOFOLLOW));
+ put(Identifier::fromString(vm, "O_NOFOLLOW"_s), jsNumber(O_NOFOLLOW));
#endif
#ifdef O_SYNC
- put(Identifier::fromString(vm, "O_SYNC"_s), jsNumber(O_SYNC));
+ put(Identifier::fromString(vm, "O_SYNC"_s), jsNumber(O_SYNC));
#endif
#ifdef O_DSYNC
- put(Identifier::fromString(vm, "O_DSYNC"_s), jsNumber(O_DSYNC));
+ put(Identifier::fromString(vm, "O_DSYNC"_s), jsNumber(O_DSYNC));
#endif
#ifdef O_SYMLINK
- put(Identifier::fromString(vm, "O_SYMLINK"_s), jsNumber(O_SYMLINK));
+ put(Identifier::fromString(vm, "O_SYMLINK"_s), jsNumber(O_SYMLINK));
#endif
#ifdef O_DIRECT
- put(Identifier::fromString(vm, "O_DIRECT"_s), jsNumber(O_DIRECT));
+ put(Identifier::fromString(vm, "O_DIRECT"_s), jsNumber(O_DIRECT));
#endif
#ifdef O_NONBLOCK
- put(Identifier::fromString(vm, "O_NONBLOCK"_s), jsNumber(O_NONBLOCK));
+ put(Identifier::fromString(vm, "O_NONBLOCK"_s), jsNumber(O_NONBLOCK));
#endif
#ifdef S_IRWXU
- put(Identifier::fromString(vm, "S_IRWXU"_s), jsNumber(S_IRWXU));
+ put(Identifier::fromString(vm, "S_IRWXU"_s), jsNumber(S_IRWXU));
#endif
#ifdef S_IRUSR
- put(Identifier::fromString(vm, "S_IRUSR"_s), jsNumber(S_IRUSR));
+ put(Identifier::fromString(vm, "S_IRUSR"_s), jsNumber(S_IRUSR));
#endif
#ifdef S_IWUSR
- put(Identifier::fromString(vm, "S_IWUSR"_s), jsNumber(S_IWUSR));
+ put(Identifier::fromString(vm, "S_IWUSR"_s), jsNumber(S_IWUSR));
#endif
#ifdef S_IXUSR
- put(Identifier::fromString(vm, "S_IXUSR"_s), jsNumber(S_IXUSR));
+ put(Identifier::fromString(vm, "S_IXUSR"_s), jsNumber(S_IXUSR));
#endif
#ifdef S_IRWXG
- put(Identifier::fromString(vm, "S_IRWXG"_s), jsNumber(S_IRWXG));
+ put(Identifier::fromString(vm, "S_IRWXG"_s), jsNumber(S_IRWXG));
#endif
#ifdef S_IRGRP
- put(Identifier::fromString(vm, "S_IRGRP"_s), jsNumber(S_IRGRP));
+ put(Identifier::fromString(vm, "S_IRGRP"_s), jsNumber(S_IRGRP));
#endif
#ifdef S_IWGRP
- put(Identifier::fromString(vm, "S_IWGRP"_s), jsNumber(S_IWGRP));
+ put(Identifier::fromString(vm, "S_IWGRP"_s), jsNumber(S_IWGRP));
#endif
#ifdef S_IXGRP
- put(Identifier::fromString(vm, "S_IXGRP"_s), jsNumber(S_IXGRP));
+ put(Identifier::fromString(vm, "S_IXGRP"_s), jsNumber(S_IXGRP));
#endif
#ifdef S_IRWXO
- put(Identifier::fromString(vm, "S_IRWXO"_s), jsNumber(S_IRWXO));
+ put(Identifier::fromString(vm, "S_IRWXO"_s), jsNumber(S_IRWXO));
#endif
#ifdef S_IROTH
- put(Identifier::fromString(vm, "S_IROTH"_s), jsNumber(S_IROTH));
+ put(Identifier::fromString(vm, "S_IROTH"_s), jsNumber(S_IROTH));
#endif
#ifdef S_IWOTH
- put(Identifier::fromString(vm, "S_IWOTH"_s), jsNumber(S_IWOTH));
+ put(Identifier::fromString(vm, "S_IWOTH"_s), jsNumber(S_IWOTH));
#endif
#ifdef S_IXOTH
- put(Identifier::fromString(vm, "S_IXOTH"_s), jsNumber(S_IXOTH));
+ put(Identifier::fromString(vm, "S_IXOTH"_s), jsNumber(S_IXOTH));
#endif
#ifdef F_OK
- put(Identifier::fromString(vm, "F_OK"_s), jsNumber(F_OK));
+ put(Identifier::fromString(vm, "F_OK"_s), jsNumber(F_OK));
#endif
#ifdef R_OK
- put(Identifier::fromString(vm, "R_OK"_s), jsNumber(R_OK));
+ put(Identifier::fromString(vm, "R_OK"_s), jsNumber(R_OK));
#endif
#ifdef W_OK
- put(Identifier::fromString(vm, "W_OK"_s), jsNumber(W_OK));
+ put(Identifier::fromString(vm, "W_OK"_s), jsNumber(W_OK));
#endif
#ifdef X_OK
- put(Identifier::fromString(vm, "X_OK"_s), jsNumber(X_OK));
-#endif
- put(Identifier::fromString(vm, "UV_FS_COPYFILE_EXCL"_s), jsNumber(1));
- put(Identifier::fromString(vm, "COPYFILE_EXCL"_s), jsNumber(1));
- put(Identifier::fromString(vm, "UV_FS_COPYFILE_FICLONE"_s), jsNumber(2));
- put(Identifier::fromString(vm, "COPYFILE_FICLONE"_s), jsNumber(2));
- put(Identifier::fromString(vm, "UV_FS_COPYFILE_FICLONE_FORCE"_s), jsNumber(4));
- put(Identifier::fromString(vm, "COPYFILE_FICLONE_FORCE"_s), jsNumber(4));
+ put(Identifier::fromString(vm, "X_OK"_s), jsNumber(X_OK));
+#endif
+ put(Identifier::fromString(vm, "UV_FS_COPYFILE_EXCL"_s), jsNumber(1));
+ put(Identifier::fromString(vm, "COPYFILE_EXCL"_s), jsNumber(1));
+ put(Identifier::fromString(vm, "UV_FS_COPYFILE_FICLONE"_s), jsNumber(2));
+ put(Identifier::fromString(vm, "COPYFILE_FICLONE"_s), jsNumber(2));
+ put(Identifier::fromString(vm, "UV_FS_COPYFILE_FICLONE_FORCE"_s),
+ jsNumber(4));
+ put(Identifier::fromString(vm, "COPYFILE_FICLONE_FORCE"_s), jsNumber(4));
#ifdef OPENSSL_VERSION_NUMBER
- put(Identifier::fromString(vm, "OPENSSL_VERSION_NUMBER"_s), jsNumber(OPENSSL_VERSION_NUMBER));
+ put(Identifier::fromString(vm, "OPENSSL_VERSION_NUMBER"_s),
+ jsNumber(OPENSSL_VERSION_NUMBER));
#endif
#ifdef SSL_OP_ALL
- put(Identifier::fromString(vm, "SSL_OP_ALL"_s), jsNumber(SSL_OP_ALL));
+ put(Identifier::fromString(vm, "SSL_OP_ALL"_s), jsNumber(SSL_OP_ALL));
#endif
#ifdef SSL_OP_ALLOW_NO_DHE_KEX
- put(Identifier::fromString(vm, "SSL_OP_ALLOW_NO_DHE_KEX"_s), jsNumber(SSL_OP_ALLOW_NO_DHE_KEX));
+ put(Identifier::fromString(vm, "SSL_OP_ALLOW_NO_DHE_KEX"_s),
+ jsNumber(SSL_OP_ALLOW_NO_DHE_KEX));
#endif
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
- put(Identifier::fromString(vm, "SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION"_s), jsNumber(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
+ put(Identifier::fromString(vm, "SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION"_s),
+ jsNumber(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
#endif
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
- put(Identifier::fromString(vm, "SSL_OP_CIPHER_SERVER_PREFERENCE"_s), jsNumber(SSL_OP_CIPHER_SERVER_PREFERENCE));
+ put(Identifier::fromString(vm, "SSL_OP_CIPHER_SERVER_PREFERENCE"_s),
+ jsNumber(SSL_OP_CIPHER_SERVER_PREFERENCE));
#endif
#ifdef SSL_OP_CISCO_ANYCONNECT
- put(Identifier::fromString(vm, "SSL_OP_CISCO_ANYCONNECT"_s), jsNumber(SSL_OP_CISCO_ANYCONNECT));
+ put(Identifier::fromString(vm, "SSL_OP_CISCO_ANYCONNECT"_s),
+ jsNumber(SSL_OP_CISCO_ANYCONNECT));
#endif
#ifdef SSL_OP_COOKIE_EXCHANGE
- put(Identifier::fromString(vm, "SSL_OP_COOKIE_EXCHANGE"_s), jsNumber(SSL_OP_COOKIE_EXCHANGE));
+ put(Identifier::fromString(vm, "SSL_OP_COOKIE_EXCHANGE"_s),
+ jsNumber(SSL_OP_COOKIE_EXCHANGE));
#endif
#ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG
- put(Identifier::fromString(vm, "SSL_OP_CRYPTOPRO_TLSEXT_BUG"_s), jsNumber(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
+ put(Identifier::fromString(vm, "SSL_OP_CRYPTOPRO_TLSEXT_BUG"_s),
+ jsNumber(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
#endif
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
- put(Identifier::fromString(vm, "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS"_s), jsNumber(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
+ put(Identifier::fromString(vm, "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS"_s),
+ jsNumber(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
#endif
#ifdef SSL_OP_LEGACY_SERVER_CONNECT
- put(Identifier::fromString(vm, "SSL_OP_LEGACY_SERVER_CONNECT"_s), jsNumber(SSL_OP_LEGACY_SERVER_CONNECT));
+ put(Identifier::fromString(vm, "SSL_OP_LEGACY_SERVER_CONNECT"_s),
+ jsNumber(SSL_OP_LEGACY_SERVER_CONNECT));
#endif
#ifdef SSL_OP_NO_COMPRESSION
- put(Identifier::fromString(vm, "SSL_OP_NO_COMPRESSION"_s), jsNumber(SSL_OP_NO_COMPRESSION));
+ put(Identifier::fromString(vm, "SSL_OP_NO_COMPRESSION"_s),
+ jsNumber(SSL_OP_NO_COMPRESSION));
#endif
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC
- put(Identifier::fromString(vm, "SSL_OP_NO_ENCRYPT_THEN_MAC"_s), jsNumber(SSL_OP_NO_ENCRYPT_THEN_MAC));
+ put(Identifier::fromString(vm, "SSL_OP_NO_ENCRYPT_THEN_MAC"_s),
+ jsNumber(SSL_OP_NO_ENCRYPT_THEN_MAC));
#endif
#ifdef SSL_OP_NO_QUERY_MTU
- put(Identifier::fromString(vm, "SSL_OP_NO_QUERY_MTU"_s), jsNumber(SSL_OP_NO_QUERY_MTU));
+ put(Identifier::fromString(vm, "SSL_OP_NO_QUERY_MTU"_s),
+ jsNumber(SSL_OP_NO_QUERY_MTU));
#endif
#ifdef SSL_OP_NO_RENEGOTIATION
- put(Identifier::fromString(vm, "SSL_OP_NO_RENEGOTIATION"_s), jsNumber(SSL_OP_NO_RENEGOTIATION));
+ put(Identifier::fromString(vm, "SSL_OP_NO_RENEGOTIATION"_s),
+ jsNumber(SSL_OP_NO_RENEGOTIATION));
#endif
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
- put(Identifier::fromString(vm, "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION"_s), jsNumber(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION));
+ put(Identifier::fromString(vm,
+ "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION"_s),
+ jsNumber(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION));
#endif
#ifdef SSL_OP_NO_SSLv2
- put(Identifier::fromString(vm, "SSL_OP_NO_SSLv2"_s), jsNumber(SSL_OP_NO_SSLv2));
+ put(Identifier::fromString(vm, "SSL_OP_NO_SSLv2"_s),
+ jsNumber(SSL_OP_NO_SSLv2));
#endif
#ifdef SSL_OP_NO_SSLv3
- put(Identifier::fromString(vm, "SSL_OP_NO_SSLv3"_s), jsNumber(SSL_OP_NO_SSLv3));
+ put(Identifier::fromString(vm, "SSL_OP_NO_SSLv3"_s),
+ jsNumber(SSL_OP_NO_SSLv3));
#endif
#ifdef SSL_OP_NO_TICKET
- put(Identifier::fromString(vm, "SSL_OP_NO_TICKET"_s), jsNumber(SSL_OP_NO_TICKET));
+ put(Identifier::fromString(vm, "SSL_OP_NO_TICKET"_s),
+ jsNumber(SSL_OP_NO_TICKET));
#endif
#ifdef SSL_OP_NO_TLSv1
- put(Identifier::fromString(vm, "SSL_OP_NO_TLSv1"_s), jsNumber(SSL_OP_NO_TLSv1));
+ put(Identifier::fromString(vm, "SSL_OP_NO_TLSv1"_s),
+ jsNumber(SSL_OP_NO_TLSv1));
#endif
#ifdef SSL_OP_NO_TLSv1_1
- put(Identifier::fromString(vm, "SSL_OP_NO_TLSv1_1"_s), jsNumber(SSL_OP_NO_TLSv1_1));
+ put(Identifier::fromString(vm, "SSL_OP_NO_TLSv1_1"_s),
+ jsNumber(SSL_OP_NO_TLSv1_1));
#endif
#ifdef SSL_OP_NO_TLSv1_2
- put(Identifier::fromString(vm, "SSL_OP_NO_TLSv1_2"_s), jsNumber(SSL_OP_NO_TLSv1_2));
+ put(Identifier::fromString(vm, "SSL_OP_NO_TLSv1_2"_s),
+ jsNumber(SSL_OP_NO_TLSv1_2));
#endif
#ifdef SSL_OP_NO_TLSv1_3
- put(Identifier::fromString(vm, "SSL_OP_NO_TLSv1_3"_s), jsNumber(SSL_OP_NO_TLSv1_3));
+ put(Identifier::fromString(vm, "SSL_OP_NO_TLSv1_3"_s),
+ jsNumber(SSL_OP_NO_TLSv1_3));
#endif
#ifdef SSL_OP_PRIORITIZE_CHACHA
- put(Identifier::fromString(vm, "SSL_OP_PRIORITIZE_CHACHA"_s), jsNumber(SSL_OP_PRIORITIZE_CHACHA));
+ put(Identifier::fromString(vm, "SSL_OP_PRIORITIZE_CHACHA"_s),
+ jsNumber(SSL_OP_PRIORITIZE_CHACHA));
#endif
#ifdef SSL_OP_TLS_ROLLBACK_BUG
- put(Identifier::fromString(vm, "SSL_OP_TLS_ROLLBACK_BUG"_s), jsNumber(SSL_OP_TLS_ROLLBACK_BUG));
+ put(Identifier::fromString(vm, "SSL_OP_TLS_ROLLBACK_BUG"_s),
+ jsNumber(SSL_OP_TLS_ROLLBACK_BUG));
#endif
#ifndef OPENSSL_NO_ENGINE
#ifdef ENGINE_METHOD_RSA
- put(Identifier::fromString(vm, "ENGINE_METHOD_RSA"_s), jsNumber(ENGINE_METHOD_RSA));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_RSA"_s),
+ jsNumber(ENGINE_METHOD_RSA));
#endif
#ifdef ENGINE_METHOD_DSA
- put(Identifier::fromString(vm, "ENGINE_METHOD_DSA"_s), jsNumber(ENGINE_METHOD_DSA));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_DSA"_s),
+ jsNumber(ENGINE_METHOD_DSA));
#endif
#ifdef ENGINE_METHOD_DH
- put(Identifier::fromString(vm, "ENGINE_METHOD_DH"_s), jsNumber(ENGINE_METHOD_DH));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_DH"_s),
+ jsNumber(ENGINE_METHOD_DH));
#endif
#ifdef ENGINE_METHOD_RAND
- put(Identifier::fromString(vm, "ENGINE_METHOD_RAND"_s), jsNumber(ENGINE_METHOD_RAND));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_RAND"_s),
+ jsNumber(ENGINE_METHOD_RAND));
#endif
#ifdef ENGINE_METHOD_EC
- put(Identifier::fromString(vm, "ENGINE_METHOD_EC"_s), jsNumber(ENGINE_METHOD_EC));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_EC"_s),
+ jsNumber(ENGINE_METHOD_EC));
#endif
#ifdef ENGINE_METHOD_CIPHERS
- put(Identifier::fromString(vm, "ENGINE_METHOD_CIPHERS"_s), jsNumber(ENGINE_METHOD_CIPHERS));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_CIPHERS"_s),
+ jsNumber(ENGINE_METHOD_CIPHERS));
#endif
#ifdef ENGINE_METHOD_DIGESTS
- put(Identifier::fromString(vm, "ENGINE_METHOD_DIGESTS"_s), jsNumber(ENGINE_METHOD_DIGESTS));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_DIGESTS"_s),
+ jsNumber(ENGINE_METHOD_DIGESTS));
#endif
#ifdef ENGINE_METHOD_PKEY_METHS
- put(Identifier::fromString(vm, "ENGINE_METHOD_PKEY_METHS"_s), jsNumber(ENGINE_METHOD_PKEY_METHS));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_PKEY_METHS"_s),
+ jsNumber(ENGINE_METHOD_PKEY_METHS));
#endif
#ifdef ENGINE_METHOD_PKEY_ASN1_METHS
- put(Identifier::fromString(vm, "ENGINE_METHOD_PKEY_ASN1_METHS"_s), jsNumber(ENGINE_METHOD_PKEY_ASN1_METHS));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_PKEY_ASN1_METHS"_s),
+ jsNumber(ENGINE_METHOD_PKEY_ASN1_METHS));
#endif
#ifdef ENGINE_METHOD_ALL
- put(Identifier::fromString(vm, "ENGINE_METHOD_ALL"_s), jsNumber(ENGINE_METHOD_ALL));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_ALL"_s),
+ jsNumber(ENGINE_METHOD_ALL));
#endif
#ifdef ENGINE_METHOD_NONE
- put(Identifier::fromString(vm, "ENGINE_METHOD_NONE"_s), jsNumber(ENGINE_METHOD_NONE));
+ put(Identifier::fromString(vm, "ENGINE_METHOD_NONE"_s),
+ jsNumber(ENGINE_METHOD_NONE));
#endif
#endif // !OPENSSL_NO_ENGINE
#ifdef DH_CHECK_P_NOT_SAFE_PRIME
- put(Identifier::fromString(vm, "DH_CHECK_P_NOT_SAFE_PRIME"_s), jsNumber(DH_CHECK_P_NOT_SAFE_PRIME));
+ put(Identifier::fromString(vm, "DH_CHECK_P_NOT_SAFE_PRIME"_s),
+ jsNumber(DH_CHECK_P_NOT_SAFE_PRIME));
#endif
#ifdef DH_CHECK_P_NOT_PRIME
- put(Identifier::fromString(vm, "DH_CHECK_P_NOT_PRIME"_s), jsNumber(DH_CHECK_P_NOT_PRIME));
+ put(Identifier::fromString(vm, "DH_CHECK_P_NOT_PRIME"_s),
+ jsNumber(DH_CHECK_P_NOT_PRIME));
#endif
#ifdef DH_UNABLE_TO_CHECK_GENERATOR
- put(Identifier::fromString(vm, "DH_UNABLE_TO_CHECK_GENERATOR"_s), jsNumber(DH_UNABLE_TO_CHECK_GENERATOR));
+ put(Identifier::fromString(vm, "DH_UNABLE_TO_CHECK_GENERATOR"_s),
+ jsNumber(DH_UNABLE_TO_CHECK_GENERATOR));
#endif
#ifdef DH_NOT_SUITABLE_GENERATOR
- put(Identifier::fromString(vm, "DH_NOT_SUITABLE_GENERATOR"_s), jsNumber(DH_NOT_SUITABLE_GENERATOR));
+ put(Identifier::fromString(vm, "DH_NOT_SUITABLE_GENERATOR"_s),
+ jsNumber(DH_NOT_SUITABLE_GENERATOR));
#endif
#ifdef RSA_PKCS1_PADDING
- put(Identifier::fromString(vm, "RSA_PKCS1_PADDING"_s), jsNumber(RSA_PKCS1_PADDING));
+ put(Identifier::fromString(vm, "RSA_PKCS1_PADDING"_s),
+ jsNumber(RSA_PKCS1_PADDING));
#endif
#ifdef RSA_SSLV23_PADDING
- put(Identifier::fromString(vm, "RSA_SSLV23_PADDING"_s), jsNumber(RSA_SSLV23_PADDING));
+ put(Identifier::fromString(vm, "RSA_SSLV23_PADDING"_s),
+ jsNumber(RSA_SSLV23_PADDING));
#endif
#ifdef RSA_NO_PADDING
- put(Identifier::fromString(vm, "RSA_NO_PADDING"_s), jsNumber(RSA_NO_PADDING));
+ put(Identifier::fromString(vm, "RSA_NO_PADDING"_s), jsNumber(RSA_NO_PADDING));
#endif
#ifdef RSA_PKCS1_OAEP_PADDING
- put(Identifier::fromString(vm, "RSA_PKCS1_OAEP_PADDING"_s), jsNumber(RSA_PKCS1_OAEP_PADDING));
+ put(Identifier::fromString(vm, "RSA_PKCS1_OAEP_PADDING"_s),
+ jsNumber(RSA_PKCS1_OAEP_PADDING));
#endif
#ifdef RSA_X931_PADDING
- put(Identifier::fromString(vm, "RSA_X931_PADDING"_s), jsNumber(RSA_X931_PADDING));
+ put(Identifier::fromString(vm, "RSA_X931_PADDING"_s),
+ jsNumber(RSA_X931_PADDING));
#endif
#ifdef RSA_PKCS1_PSS_PADDING
- put(Identifier::fromString(vm, "RSA_PKCS1_PSS_PADDING"_s), jsNumber(RSA_PKCS1_PSS_PADDING));
+ put(Identifier::fromString(vm, "RSA_PKCS1_PSS_PADDING"_s),
+ jsNumber(RSA_PKCS1_PSS_PADDING));
#endif
#ifdef RSA_PSS_SALTLEN_DIGEST
- put(Identifier::fromString(vm, "RSA_PSS_SALTLEN_DIGEST"_s), jsNumber(RSA_PSS_SALTLEN_DIGEST));
+ put(Identifier::fromString(vm, "RSA_PSS_SALTLEN_DIGEST"_s),
+ jsNumber(RSA_PSS_SALTLEN_DIGEST));
#endif
#ifdef RSA_PSS_SALTLEN_MAX_SIGN
- put(Identifier::fromString(vm, "RSA_PSS_SALTLEN_MAX_SIGN"_s), jsNumber(RSA_PSS_SALTLEN_MAX_SIGN));
+ put(Identifier::fromString(vm, "RSA_PSS_SALTLEN_MAX_SIGN"_s),
+ jsNumber(RSA_PSS_SALTLEN_MAX_SIGN));
#endif
#ifdef RSA_PSS_SALTLEN_AUTO
- put(Identifier::fromString(vm, "RSA_PSS_SALTLEN_AUTO"_s), jsNumber(RSA_PSS_SALTLEN_AUTO));
-#endif
- auto cipherList = String("TLS_AES_256_GCM_SHA384:"
- "TLS_CHACHA20_POLY1305_SHA256:"
- "TLS_AES_128_GCM_SHA256:"
- "ECDHE-RSA-AES128-GCM-SHA256:"
- "ECDHE-ECDSA-AES128-GCM-SHA256:"
- "ECDHE-RSA-AES256-GCM-SHA384:"
- "ECDHE-ECDSA-AES256-GCM-SHA384:"
- "DHE-RSA-AES128-GCM-SHA256:"
- "ECDHE-RSA-AES128-SHA256:"
- "DHE-RSA-AES128-SHA256:"
- "ECDHE-RSA-AES256-SHA384:"
- "DHE-RSA-AES256-SHA384:"
- "ECDHE-RSA-AES256-SHA256:"
- "DHE-RSA-AES256-SHA256:"
- "HIGH:"
- "!aNULL:"
- "!eNULL:"
- "!EXPORT:"
- "!DES:"
- "!RC4:"
- "!MD5:"
- "!PSK:"
- "!SRP:"
- "!CAMELLIA"_s);
- put(Identifier::fromString(vm, "defaultCoreCipherList"_s),
- jsString(vm, cipherList));
- put(Identifier::fromString(vm, "defaultCipherList"_s),
- jsString(vm, cipherList));
+ put(Identifier::fromString(vm, "RSA_PSS_SALTLEN_AUTO"_s),
+ jsNumber(RSA_PSS_SALTLEN_AUTO));
+#endif
+ auto cipherList = String("TLS_AES_256_GCM_SHA384:"
+ "TLS_CHACHA20_POLY1305_SHA256:"
+ "TLS_AES_128_GCM_SHA256:"
+ "ECDHE-RSA-AES128-GCM-SHA256:"
+ "ECDHE-ECDSA-AES128-GCM-SHA256:"
+ "ECDHE-RSA-AES256-GCM-SHA384:"
+ "ECDHE-ECDSA-AES256-GCM-SHA384:"
+ "DHE-RSA-AES128-GCM-SHA256:"
+ "ECDHE-RSA-AES128-SHA256:"
+ "DHE-RSA-AES128-SHA256:"
+ "ECDHE-RSA-AES256-SHA384:"
+ "DHE-RSA-AES256-SHA384:"
+ "ECDHE-RSA-AES256-SHA256:"
+ "DHE-RSA-AES256-SHA256:"
+ "HIGH:"
+ "!aNULL:"
+ "!eNULL:"
+ "!EXPORT:"
+ "!DES:"
+ "!RC4:"
+ "!MD5:"
+ "!PSK:"
+ "!SRP:"
+ "!CAMELLIA"_s);
+ put(Identifier::fromString(vm, "defaultCoreCipherList"_s),
+ jsString(vm, cipherList));
+ put(Identifier::fromString(vm, "defaultCipherList"_s),
+ jsString(vm, cipherList));
#ifdef TLS1_VERSION
- put(Identifier::fromString(vm, "TLS1_VERSION"_s), jsNumber(TLS1_VERSION));
+ put(Identifier::fromString(vm, "TLS1_VERSION"_s), jsNumber(TLS1_VERSION));
#endif
#ifdef TLS1_1_VERSION
- put(Identifier::fromString(vm, "TLS1_1_VERSION"_s), jsNumber(TLS1_1_VERSION));
+ put(Identifier::fromString(vm, "TLS1_1_VERSION"_s), jsNumber(TLS1_1_VERSION));
#endif
#ifdef TLS1_2_VERSION
- put(Identifier::fromString(vm, "TLS1_2_VERSION"_s), jsNumber(TLS1_2_VERSION));
+ put(Identifier::fromString(vm, "TLS1_2_VERSION"_s), jsNumber(TLS1_2_VERSION));
#endif
#ifdef TLS1_3_VERSION
- put(Identifier::fromString(vm, "TLS1_3_VERSION"_s), jsNumber(TLS1_3_VERSION));
-#endif
- put(Identifier::fromString(vm, "POINT_CONVERSION_COMPRESSED"_s), jsNumber(POINT_CONVERSION_COMPRESSED));
- put(Identifier::fromString(vm, "POINT_CONVERSION_UNCOMPRESSED"_s), jsNumber(POINT_CONVERSION_UNCOMPRESSED));
- put(Identifier::fromString(vm, "POINT_CONVERSION_HYBRID"_s), jsNumber(POINT_CONVERSION_HYBRID));
- RETURN_NATIVE_MODULE();
+ put(Identifier::fromString(vm, "TLS1_3_VERSION"_s), jsNumber(TLS1_3_VERSION));
+#endif
+ put(Identifier::fromString(vm, "POINT_CONVERSION_COMPRESSED"_s),
+ jsNumber(POINT_CONVERSION_COMPRESSED));
+ put(Identifier::fromString(vm, "POINT_CONVERSION_UNCOMPRESSED"_s),
+ jsNumber(POINT_CONVERSION_UNCOMPRESSED));
+ put(Identifier::fromString(vm, "POINT_CONVERSION_HYBRID"_s),
+ jsNumber(POINT_CONVERSION_HYBRID));
+
+ // RETURN_NATIVE_MODULE();
}
} // namespace Zig
diff --git a/src/bun.js/modules/NodeModuleModule.h b/src/bun.js/modules/NodeModuleModule.h
index b3c34eb5e..804d1dd9d 100644
--- a/src/bun.js/modules/NodeModuleModule.h
+++ b/src/bun.js/modules/NodeModuleModule.h
@@ -1,8 +1,11 @@
+#pragma once
+
#include "CommonJSModuleRecord.h"
#include "ImportMetaObject.h"
#include "JavaScriptCore/JSBoundFunction.h"
#include "JavaScriptCore/ObjectConstructor.h"
#include "_NativeModule.h"
+#include "isBuiltinModule.h"
using namespace Zig;
using namespace JSC;
@@ -88,18 +91,6 @@ static constexpr ASCIILiteral builtinModuleNames[] = {
"zlib"_s,
};
-static bool isBuiltinModule(const String &namePossiblyWithNodePrefix) {
- String name = namePossiblyWithNodePrefix;
- if (name.startsWith("node:"_s))
- name = name.substringSharingImpl(5);
-
- for (auto &builtinModule : builtinModuleNames) {
- if (name == builtinModule)
- return true;
- }
- return false;
-}
-
JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleModuleConstructor,
(JSC::JSGlobalObject * globalObject,
JSC::CallFrame *callFrame)) {
@@ -158,7 +149,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionIsBuiltinModule,
auto moduleStr = moduleName.toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, JSValue::encode(jsBoolean(false)));
- return JSValue::encode(jsBoolean(isBuiltinModule(moduleStr)));
+ return JSValue::encode(jsBoolean(Bun::isBuiltinModule(moduleStr)));
}
JSC_DEFINE_HOST_FUNCTION(jsFunctionWrap, (JSC::JSGlobalObject * globalObject,
@@ -304,6 +295,39 @@ JSC_DEFINE_CUSTOM_SETTER(set_resolveFilename,
return false;
}
+// These two setters are only used if you directly hit
+// `Module.prototype.require` or `module.require`. When accessing the cjs
+// require argument, this is a bound version of `require`, which calls into the
+// overridden one.
+//
+// This require function also intentionally does not have .resolve on it, nor
+// does it have any of the other properties.
+//
+// Note: allowing require to be overridable at all is only needed for Next.js to
+// work (they do Module.prototype.require = ...)
+
+JSC_DEFINE_CUSTOM_GETTER(getterRequireFunction,
+ (JSC::JSGlobalObject * globalObject,
+ JSC::EncodedJSValue thisValue, JSC::PropertyName)) {
+ return JSValue::encode(globalObject->getDirect(
+ globalObject->vm(), WebCore::clientData(globalObject->vm())
+ ->builtinNames()
+ .overridableRequirePrivateName()));
+}
+
+JSC_DEFINE_CUSTOM_SETTER(setterRequireFunction,
+ (JSC::JSGlobalObject * globalObject,
+ JSC::EncodedJSValue thisValue,
+ JSC::EncodedJSValue value,
+ JSC::PropertyName propertyName)) {
+ globalObject->putDirect(globalObject->vm(),
+ WebCore::clientData(globalObject->vm())
+ ->builtinNames()
+ .overridableRequirePrivateName(),
+ JSValue::decode(value), 0);
+ return true;
+}
+
namespace Zig {
DEFINE_NATIVE_MODULE(NodeModule) {
@@ -330,13 +354,18 @@ DEFINE_NATIVE_MODULE(NodeModule) {
exportNames.append(name);
exportValues.append(value);
};
- exportNames.reserveCapacity(15);
- exportValues.ensureCapacity(15);
+ exportNames.reserveCapacity(16);
+ exportValues.ensureCapacity(16);
exportNames.append(vm.propertyNames->defaultKeyword);
exportValues.append(defaultObject);
put(Identifier::fromString(vm, "Module"_s), defaultObject);
+ // Module._extensions === require.extensions
+ put(Identifier::fromString(vm, "_extensions"_s),
+ globalObject->requireFunctionUnbound()->get(
+ globalObject, Identifier::fromString(vm, "extensions"_s)));
+
defaultObject->putDirectCustomAccessor(
vm, JSC::Identifier::fromString(vm, "_resolveFilename"_s),
JSC::CustomGetterSetter::create(vm, get_resolveFilename,
@@ -366,8 +395,15 @@ DEFINE_NATIVE_MODULE(NodeModule) {
put(Identifier::fromString(vm, "globalPaths"_s),
constructEmptyArray(globalObject, nullptr, 0));
- put(Identifier::fromString(vm, "prototype"_s),
- constructEmptyObject(globalObject));
+ auto prototype =
+ constructEmptyObject(globalObject, globalObject->objectPrototype(), 1);
+ prototype->putDirectCustomAccessor(
+ vm, JSC::Identifier::fromString(vm, "require"_s),
+ JSC::CustomGetterSetter::create(vm, getterRequireFunction,
+ setterRequireFunction),
+ 0);
+
+ defaultObject->putDirect(vm, vm.propertyNames->prototype, prototype);
JSC::JSArray *builtinModules = JSC::JSArray::create(
vm,
@@ -381,8 +417,6 @@ DEFINE_NATIVE_MODULE(NodeModule) {
}
put(JSC::Identifier::fromString(vm, "builtinModules"_s), builtinModules);
-
- RETURN_NATIVE_MODULE();
}
} // namespace Zig
diff --git a/src/bun.js/modules/NodeUtilTypesModule.h b/src/bun.js/modules/NodeUtilTypesModule.h
index de9b147a4..e0b990603 100644
--- a/src/bun.js/modules/NodeUtilTypesModule.h
+++ b/src/bun.js/modules/NodeUtilTypesModule.h
@@ -203,7 +203,10 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionIsWeakSet, (JSC::JSGlobalObject * globalObjec
JSC_DEFINE_HOST_FUNCTION(jsFunctionIsArrayBuffer, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe))
{
GET_FIRST_CELL
- return JSValue::encode(jsBoolean(jsDynamicCast<JSArrayBuffer*>(cell) != nullptr));
+ auto* arrayBuffer = jsDynamicCast<JSArrayBuffer*>(cell);
+ if (!arrayBuffer)
+ return JSValue::encode(jsBoolean(false));
+ return JSValue::encode(jsBoolean(!arrayBuffer->isShared()));
}
JSC_DEFINE_HOST_FUNCTION(jsFunctionIsDataView, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe))
{
diff --git a/src/bun.js/modules/_NativeModule.h b/src/bun.js/modules/_NativeModule.h
index b23906ad0..6d3d76176 100644
--- a/src/bun.js/modules/_NativeModule.h
+++ b/src/bun.js/modules/_NativeModule.h
@@ -40,18 +40,19 @@
// that what you passed to INIT_NATIVE_MODULE is indeed correct.
#define RETURN_NATIVE_MODULE() \
ASSERT_WITH_MESSAGE(numberOfActualExportNames == passedNumberOfExportNames, \
- "NATIVE_MODULE_START() was given the incorrect value.");
+ "NATIVE_MODULE_START() was should be given %d", numberOfActualExportNames);
-#define __NATIVE_MODULE_ASSERT_DECL \
+#define __NATIVE_MODULE_ASSERT_DECL(numberOfExportNames) \
int numberOfActualExportNames = 0; \
int passedNumberOfExportNames = numberOfExportNames; \
+
#define __NATIVE_MODULE_ASSERT_INCR numberOfActualExportNames++;
#else
#define RETURN_NATIVE_MODULE() ;
#define __NATIVE_MODULE_ASSERT_INCR ;
-#define __NATIVE_MODULE_ASSERT_DECL ;
+#define __NATIVE_MODULE_ASSERT_DECL(numberOfExportNames) ;
#endif
@@ -67,7 +68,7 @@
JSC::VM &vm = globalObject->vm(); \
JSC::JSObject *defaultObject = JSC::constructEmptyObject( \
globalObject, globalObject->objectPrototype(), numberOfExportNames); \
- __NATIVE_MODULE_ASSERT_DECL \
+ __NATIVE_MODULE_ASSERT_DECL(numberOfExportNames); \
auto put = [&](JSC::Identifier name, JSC::JSValue value) { \
defaultObject->putDirect(vm, name, value); \
exportNames.append(name); \
diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig
index d9e3ed119..173f750a5 100644
--- a/src/bun.js/node/node_fs.zig
+++ b/src/bun.js/node/node_fs.zig
@@ -55,468 +55,151 @@ else
// TODO:
0;
+const SliceWithUnderlyingStringOrBuffer = JSC.Node.SliceWithUnderlyingStringOrBuffer;
const ArrayBuffer = JSC.MarkedArrayBuffer;
const Buffer = JSC.Buffer;
const FileSystemFlags = JSC.Node.FileSystemFlags;
+pub const Async = struct {
+ pub const access = NewAsyncFSTask(Return.Access, Arguments.Access, NodeFS.access);
+ pub const appendFile = NewAsyncFSTask(Return.AppendFile, Arguments.AppendFile, NodeFS.appendFile);
+ pub const chmod = NewAsyncFSTask(Return.Chmod, Arguments.Chmod, NodeFS.chmod);
+ pub const chown = NewAsyncFSTask(Return.Chown, Arguments.Chown, NodeFS.chown);
+ pub const close = NewAsyncFSTask(Return.Close, Arguments.Close, NodeFS.close);
+ pub const copyFile = NewAsyncFSTask(Return.CopyFile, Arguments.CopyFile, NodeFS.copyFile);
+ pub const exists = NewAsyncFSTask(Return.Exists, Arguments.Exists, NodeFS.exists);
+ pub const fchmod = NewAsyncFSTask(Return.Fchmod, Arguments.FChmod, NodeFS.fchmod);
+ pub const fchown = NewAsyncFSTask(Return.Fchown, Arguments.Fchown, NodeFS.fchown);
+ pub const fdatasync = NewAsyncFSTask(Return.Fdatasync, Arguments.FdataSync, NodeFS.fdatasync);
+ pub const fstat = NewAsyncFSTask(Return.Fstat, Arguments.Fstat, NodeFS.fstat);
+ pub const fsync = NewAsyncFSTask(Return.Fsync, Arguments.Fsync, NodeFS.fsync);
+ pub const ftruncate = NewAsyncFSTask(Return.Ftruncate, Arguments.FTruncate, NodeFS.ftruncate);
+ pub const futimes = NewAsyncFSTask(Return.Futimes, Arguments.Futimes, NodeFS.futimes);
+ pub const lchmod = NewAsyncFSTask(Return.Lchmod, Arguments.LCHmod, NodeFS.lchmod);
+ pub const lchown = NewAsyncFSTask(Return.Lchown, Arguments.LChown, NodeFS.lchown);
+ pub const link = NewAsyncFSTask(Return.Link, Arguments.Link, NodeFS.link);
+ pub const lstat = NewAsyncFSTask(Return.Stat, Arguments.Stat, NodeFS.lstat);
+ pub const lutimes = NewAsyncFSTask(Return.Lutimes, Arguments.Lutimes, NodeFS.lutimes);
+ pub const mkdir = NewAsyncFSTask(Return.Mkdir, Arguments.Mkdir, NodeFS.mkdir);
+ pub const mkdtemp = NewAsyncFSTask(Return.Mkdtemp, Arguments.MkdirTemp, NodeFS.mkdtemp);
+ pub const open = NewAsyncFSTask(Return.Open, Arguments.Open, NodeFS.open);
+ pub const read = NewAsyncFSTask(Return.Read, Arguments.Read, NodeFS.read);
+ pub const readdir = NewAsyncFSTask(Return.Readdir, Arguments.Readdir, NodeFS.readdir);
+ pub const readFile = NewAsyncFSTask(Return.ReadFile, Arguments.ReadFile, NodeFS.readFile);
+ pub const readlink = NewAsyncFSTask(Return.Readlink, Arguments.Readlink, NodeFS.readlink);
+ pub const readv = NewAsyncFSTask(Return.Readv, Arguments.Readv, NodeFS.readv);
+ pub const realpath = NewAsyncFSTask(Return.Realpath, Arguments.Realpath, NodeFS.realpath);
+ pub const rename = NewAsyncFSTask(Return.Rename, Arguments.Rename, NodeFS.rename);
+ pub const rm = NewAsyncFSTask(Return.Rm, Arguments.Rm, NodeFS.rm);
+ pub const rmdir = NewAsyncFSTask(Return.Rmdir, Arguments.RmDir, NodeFS.rmdir);
+ pub const stat = NewAsyncFSTask(Return.Stat, Arguments.Stat, NodeFS.stat);
+ pub const symlink = NewAsyncFSTask(Return.Symlink, Arguments.Symlink, NodeFS.symlink);
+ pub const truncate = NewAsyncFSTask(Return.Truncate, Arguments.Truncate, NodeFS.truncate);
+ pub const unlink = NewAsyncFSTask(Return.Unlink, Arguments.Unlink, NodeFS.unlink);
+ pub const utimes = NewAsyncFSTask(Return.Utimes, Arguments.Utimes, NodeFS.utimes);
+ pub const write = NewAsyncFSTask(Return.Write, Arguments.Write, NodeFS.write);
+ pub const writeFile = NewAsyncFSTask(Return.WriteFile, Arguments.WriteFile, NodeFS.writeFile);
+ pub const writev = NewAsyncFSTask(Return.Writev, Arguments.Writev, NodeFS.writev);
+
+ pub const cp = AsyncCpTask;
+
+ fn NewAsyncFSTask(comptime ReturnType: type, comptime ArgumentType: type, comptime Function: anytype) type {
+ return struct {
+ promise: JSC.JSPromise.Strong,
+ args: ArgumentType,
+ globalObject: *JSC.JSGlobalObject,
+ task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback },
+ result: JSC.Maybe(ReturnType),
+ ref: JSC.PollRef = .{},
+ tracker: JSC.AsyncTaskTracker,
+
+ pub const Task = @This();
+
+ pub fn create(
+ globalObject: *JSC.JSGlobalObject,
+ args: ArgumentType,
+ vm: *JSC.VirtualMachine,
+ ) JSC.JSValue {
+ var task = bun.default_allocator.create(Task) catch @panic("out of memory");
+ task.* = Task{
+ .promise = JSC.JSPromise.Strong.init(globalObject),
+ .args = args,
+ .result = undefined,
+ .globalObject = globalObject,
+ .tracker = JSC.AsyncTaskTracker.init(vm),
+ };
+ task.ref.ref(vm);
+ task.args.toThreadSafe();
+ task.tracker.didSchedule(globalObject);
+ JSC.WorkPool.schedule(&task.task);
-pub const AsyncReaddirTask = struct {
- promise: JSC.JSPromise.Strong,
- args: Arguments.Readdir,
- globalObject: *JSC.JSGlobalObject,
- task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback },
- result: JSC.Maybe(Return.Readdir),
- ref: JSC.PollRef = .{},
- arena: bun.ArenaAllocator,
- tracker: JSC.AsyncTaskTracker,
-
- pub fn create(globalObject: *JSC.JSGlobalObject, readdir_args: Arguments.Readdir, vm: *JSC.VirtualMachine, arena: bun.ArenaAllocator) JSC.JSValue {
- var task = bun.default_allocator.create(AsyncReaddirTask) catch @panic("out of memory");
- task.* = AsyncReaddirTask{
- .promise = JSC.JSPromise.Strong.init(globalObject),
- .args = readdir_args,
- .result = undefined,
- .globalObject = globalObject,
- .arena = arena,
- .tracker = JSC.AsyncTaskTracker.init(vm),
- };
- task.ref.ref(vm);
- task.args.path.toThreadSafe();
- task.tracker.didSchedule(globalObject);
- JSC.WorkPool.schedule(&task.task);
-
- return task.promise.value();
- }
-
- fn workPoolCallback(task: *JSC.WorkPoolTask) void {
- var this: *AsyncReaddirTask = @fieldParentPtr(AsyncReaddirTask, "task", task);
-
- var node_fs = NodeFS{};
- this.result = node_fs.readdir(this.args, .promise);
-
- if (this.result == .err) {
- this.result.err.path = bun.default_allocator.dupe(u8, this.result.err.path) catch "";
- }
-
- this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, runFromJSThread));
- }
-
- fn runFromJSThread(this: *AsyncReaddirTask) void {
- var globalObject = this.globalObject;
-
- var success = @as(JSC.Maybe(Return.Readdir).Tag, this.result) == .result;
- const result = switch (this.result) {
- .err => |err| err.toJSC(globalObject),
- .result => |res| brk: {
- var exceptionref: JSC.C.JSValueRef = null;
- const out = JSC.JSValue.c(JSC.To.JS.withType(Return.Readdir, res, globalObject, &exceptionref));
- const exception = JSC.JSValue.c(exceptionref);
- if (exception != .zero) {
- success = false;
- break :brk exception;
- }
-
- break :brk out;
- },
- };
- var promise_value = this.promise.value();
- var promise = this.promise.get();
- promise_value.ensureStillAlive();
-
- const tracker = this.tracker;
- this.deinit();
-
- tracker.willDispatch(globalObject);
- defer tracker.didDispatch(globalObject);
- switch (success) {
- false => {
- promise.reject(globalObject, result);
- },
- true => {
- promise.resolve(globalObject, result);
- },
- }
- }
-
- pub fn deinit(this: *AsyncReaddirTask) void {
- this.ref.unref(this.globalObject.bunVM());
- this.args.deinitAndUnprotect();
- this.promise.strong.deinit();
- this.arena.deinit();
- bun.default_allocator.destroy(this);
- }
-};
-
-pub const AsyncStatTask = struct {
- promise: JSC.JSPromise.Strong,
- args: Arguments.Stat,
- globalObject: *JSC.JSGlobalObject,
- task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback },
- result: JSC.Maybe(Return.Stat),
- ref: JSC.PollRef = .{},
- is_lstat: bool = false,
- arena: bun.ArenaAllocator,
- tracker: JSC.AsyncTaskTracker,
-
- pub fn create(
- globalObject: *JSC.JSGlobalObject,
- readdir_args: Arguments.Stat,
- vm: *JSC.VirtualMachine,
- is_lstat: bool,
- arena: bun.ArenaAllocator,
- ) JSC.JSValue {
- var task = bun.default_allocator.create(AsyncStatTask) catch @panic("out of memory");
- task.* = AsyncStatTask{
- .promise = JSC.JSPromise.Strong.init(globalObject),
- .args = readdir_args,
- .result = undefined,
- .globalObject = globalObject,
- .is_lstat = is_lstat,
- .tracker = JSC.AsyncTaskTracker.init(vm),
- .arena = arena,
- };
- task.ref.ref(vm);
- task.args.path.toThreadSafe();
- task.tracker.didSchedule(globalObject);
-
- JSC.WorkPool.schedule(&task.task);
-
- return task.promise.value();
- }
+ return task.promise.value();
+ }
- fn workPoolCallback(task: *JSC.WorkPoolTask) void {
- var this: *AsyncStatTask = @fieldParentPtr(AsyncStatTask, "task", task);
+ fn workPoolCallback(task: *JSC.WorkPoolTask) void {
+ var this: *Task = @fieldParentPtr(Task, "task", task);
- var node_fs = NodeFS{};
- this.result = if (this.is_lstat)
- node_fs.lstat(this.args, .promise)
- else
- node_fs.stat(this.args, .promise);
+ var node_fs = NodeFS{};
+ this.result = Function(&node_fs, this.args, .promise);
- this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, runFromJSThread));
- }
-
- fn runFromJSThread(this: *AsyncStatTask) void {
- var globalObject = this.globalObject;
- var success = @as(JSC.Maybe(Return.Lstat).Tag, this.result) == .result;
- const result = switch (this.result) {
- .err => |err| err.toJSC(globalObject),
- .result => |res| brk: {
- var exceptionref: JSC.C.JSValueRef = null;
- const out = JSC.JSValue.c(JSC.To.JS.withType(Return.Lstat, res, globalObject, &exceptionref));
- const exception = JSC.JSValue.c(exceptionref);
- if (exception != .zero) {
- success = false;
- break :brk exception;
+ if (this.result == .err) {
+ this.result.err.path = bun.default_allocator.dupe(u8, this.result.err.path) catch "";
+ std.mem.doNotOptimizeAway(&node_fs);
}
- break :brk out;
- },
- };
- var promise_value = this.promise.value();
- var promise = this.promise.get();
- promise_value.ensureStillAlive();
-
- const tracker = this.tracker;
- tracker.willDispatch(globalObject);
- defer tracker.didDispatch(globalObject);
-
- this.deinit();
- switch (success) {
- false => {
- promise.reject(globalObject, result);
- },
- true => {
- promise.resolve(globalObject, result);
- },
- }
- }
-
- pub fn deinit(this: *AsyncStatTask) void {
- this.ref.unref(this.globalObject.bunVM());
- this.args.deinitAndUnprotect();
- this.promise.strong.deinit();
- this.arena.deinit();
- bun.default_allocator.destroy(this);
- }
-};
-
-pub const AsyncRealpathTask = struct {
- promise: JSC.JSPromise.Strong,
- args: Arguments.Realpath,
- globalObject: *JSC.JSGlobalObject,
- task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback },
- result: JSC.Maybe(Return.Realpath),
- ref: JSC.PollRef = .{},
- arena: bun.ArenaAllocator,
- tracker: JSC.AsyncTaskTracker,
-
- pub fn create(
- globalObject: *JSC.JSGlobalObject,
- args: Arguments.Realpath,
- vm: *JSC.VirtualMachine,
- arena: bun.ArenaAllocator,
- ) JSC.JSValue {
- var task = bun.default_allocator.create(AsyncRealpathTask) catch @panic("out of memory");
- task.* = AsyncRealpathTask{
- .promise = JSC.JSPromise.Strong.init(globalObject),
- .args = args,
- .result = undefined,
- .globalObject = globalObject,
- .arena = arena,
- .tracker = JSC.AsyncTaskTracker.init(vm),
- };
- task.ref.ref(vm);
- task.args.path.toThreadSafe();
- task.tracker.didSchedule(globalObject);
- JSC.WorkPool.schedule(&task.task);
-
- return task.promise.value();
- }
-
- fn workPoolCallback(task: *JSC.WorkPoolTask) void {
- var this: *AsyncRealpathTask = @fieldParentPtr(AsyncRealpathTask, "task", task);
-
- var node_fs = NodeFS{};
- this.result = node_fs.realpath(this.args, .promise);
-
- if (this.result == .err) {
- this.result.err.path = bun.default_allocator.dupe(u8, this.result.err.path) catch "";
- }
+ this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.create(JSC.Task.init(this)));
+ }
- this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, runFromJSThread));
- }
+ pub fn runFromJSThread(this: *Task) void {
+ var globalObject = this.globalObject;
+ var success = @as(JSC.Maybe(ReturnType).Tag, this.result) == .result;
+ const result = switch (this.result) {
+ .err => |err| err.toJSC(globalObject),
+ .result => |res| brk: {
+ var exceptionref: JSC.C.JSValueRef = null;
+ const out = JSC.JSValue.c(JSC.To.JS.withType(ReturnType, res, globalObject, &exceptionref));
+ const exception = JSC.JSValue.c(exceptionref);
+ if (exception != .zero) {
+ success = false;
+ break :brk exception;
+ }
- fn runFromJSThread(this: *AsyncRealpathTask) void {
- var globalObject = this.globalObject;
- var success = @as(JSC.Maybe(Return.Realpath).Tag, this.result) == .result;
- const result = switch (this.result) {
- .err => |err| err.toJSC(globalObject),
- .result => |res| brk: {
- var exceptionref: JSC.C.JSValueRef = null;
- const out = JSC.JSValue.c(JSC.To.JS.withType(Return.Realpath, res, globalObject, &exceptionref));
- const exception = JSC.JSValue.c(exceptionref);
- if (exception != .zero) {
- success = false;
- break :brk exception;
+ break :brk out;
+ },
+ };
+ var promise_value = this.promise.value();
+ var promise = this.promise.get();
+ promise_value.ensureStillAlive();
+
+ const tracker = this.tracker;
+ tracker.willDispatch(globalObject);
+ defer tracker.didDispatch(globalObject);
+
+ this.deinit();
+ switch (success) {
+ false => {
+ promise.reject(globalObject, result);
+ },
+ true => {
+ promise.resolve(globalObject, result);
+ },
}
+ }
- break :brk out;
- },
- };
- var promise_value = this.promise.value();
- var promise = this.promise.get();
- promise_value.ensureStillAlive();
-
- const tracker = this.tracker;
- tracker.willDispatch(globalObject);
- defer tracker.didDispatch(globalObject);
-
- this.deinit();
- switch (success) {
- false => {
- promise.reject(globalObject, result);
- },
- true => {
- promise.resolve(globalObject, result);
- },
- }
- }
-
- pub fn deinit(this: *AsyncRealpathTask) void {
- if (this.result == .err) {
- bun.default_allocator.free(this.result.err.path);
- }
-
- this.ref.unref(this.globalObject.bunVM());
- this.args.deinitAndUnprotect();
- this.promise.strong.deinit();
- this.arena.deinit();
- bun.default_allocator.destroy(this);
- }
-};
-
-pub const AsyncReadFileTask = struct {
- promise: JSC.JSPromise.Strong,
- args: Arguments.ReadFile,
- globalObject: *JSC.JSGlobalObject,
- task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback },
- result: JSC.Maybe(Return.ReadFile),
- ref: JSC.PollRef = .{},
- arena: bun.ArenaAllocator,
- tracker: JSC.AsyncTaskTracker,
-
- pub fn create(
- globalObject: *JSC.JSGlobalObject,
- args: Arguments.ReadFile,
- vm: *JSC.VirtualMachine,
- arena: bun.ArenaAllocator,
- ) JSC.JSValue {
- var task = bun.default_allocator.create(AsyncReadFileTask) catch @panic("out of memory");
- task.* = AsyncReadFileTask{
- .promise = JSC.JSPromise.Strong.init(globalObject),
- .args = args,
- .result = undefined,
- .globalObject = globalObject,
- .arena = arena,
- .tracker = JSC.AsyncTaskTracker.init(vm),
- };
- task.ref.ref(vm);
- task.args.path.toThreadSafe();
- task.tracker.didSchedule(globalObject);
- JSC.WorkPool.schedule(&task.task);
-
- return task.promise.value();
- }
-
- fn workPoolCallback(task: *JSC.WorkPoolTask) void {
- var this: *AsyncReadFileTask = @fieldParentPtr(AsyncReadFileTask, "task", task);
-
- var node_fs = NodeFS{};
- this.result = node_fs.readFile(this.args, .promise);
-
- if (this.result == .err) {
- this.result.err.path = bun.default_allocator.dupe(u8, this.result.err.path) catch "";
- }
-
- this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, runFromJSThread));
- }
-
- fn runFromJSThread(this: *AsyncReadFileTask) void {
- var globalObject = this.globalObject;
-
- var success = @as(JSC.Maybe(Return.ReadFile).Tag, this.result) == .result;
- const result = switch (this.result) {
- .err => |err| err.toJSC(globalObject),
- .result => |res| brk: {
- var exceptionref: JSC.C.JSValueRef = null;
- const out = JSC.JSValue.c(JSC.To.JS.withType(Return.ReadFile, res, globalObject, &exceptionref));
- const exception = JSC.JSValue.c(exceptionref);
- if (exception != .zero) {
- success = false;
- break :brk exception;
+ pub fn deinit(this: *Task) void {
+ if (this.result == .err) {
+ bun.default_allocator.free(this.result.err.path);
}
- break :brk out;
- },
- };
- var promise_value = this.promise.value();
- var promise = this.promise.get();
- promise_value.ensureStillAlive();
-
- const tracker = this.tracker;
- tracker.willDispatch(globalObject);
- defer tracker.didDispatch(globalObject);
-
- this.deinit();
- switch (success) {
- false => {
- promise.reject(globalObject, result);
- },
- true => {
- promise.resolve(globalObject, result);
- },
- }
- }
-
- pub fn deinit(this: *AsyncReadFileTask) void {
- this.ref.unref(this.globalObject.bunVM());
- this.args.deinitAndUnprotect();
- this.promise.strong.deinit();
- this.arena.deinit();
- bun.default_allocator.destroy(this);
- }
-};
-
-pub const AsyncCopyFileTask = struct {
- promise: JSC.JSPromise.Strong,
- args: Arguments.CopyFile,
- globalObject: *JSC.JSGlobalObject,
- task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback },
- result: JSC.Maybe(Return.CopyFile),
- ref: JSC.PollRef = .{},
- arena: bun.ArenaAllocator,
- tracker: JSC.AsyncTaskTracker,
-
- pub fn create(
- globalObject: *JSC.JSGlobalObject,
- copyfile_args: Arguments.CopyFile,
- vm: *JSC.VirtualMachine,
- arena: bun.ArenaAllocator,
- ) JSC.JSValue {
- var task = bun.default_allocator.create(AsyncCopyFileTask) catch @panic("out of memory");
- task.* = AsyncCopyFileTask{
- .promise = JSC.JSPromise.Strong.init(globalObject),
- .args = copyfile_args,
- .result = undefined,
- .globalObject = globalObject,
- .tracker = JSC.AsyncTaskTracker.init(vm),
- .arena = arena,
- };
- task.ref.ref(vm);
- task.args.src.toThreadSafe();
- task.args.dest.toThreadSafe();
- task.tracker.didSchedule(globalObject);
-
- JSC.WorkPool.schedule(&task.task);
-
- return task.promise.value();
- }
-
- fn workPoolCallback(task: *JSC.WorkPoolTask) void {
- var this: *AsyncCopyFileTask = @fieldParentPtr(AsyncCopyFileTask, "task", task);
-
- var node_fs = NodeFS{};
- this.result = node_fs.copyFile(this.args, .promise);
-
- if (this.result == .err) {
- this.result.err.path = bun.default_allocator.dupe(u8, this.result.err.path) catch "";
- }
-
- this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, runFromJSThread));
- }
-
- fn runFromJSThread(this: *AsyncCopyFileTask) void {
- var globalObject = this.globalObject;
- var success = @as(JSC.Maybe(Return.CopyFile).Tag, this.result) == .result;
- const result = switch (this.result) {
- .err => |err| err.toJSC(globalObject),
- .result => |res| brk: {
- var exceptionref: JSC.C.JSValueRef = null;
- const out = JSC.JSValue.c(JSC.To.JS.withType(Return.CopyFile, res, globalObject, &exceptionref));
- const exception = JSC.JSValue.c(exceptionref);
- if (exception != .zero) {
- success = false;
- break :brk exception;
+ this.ref.unref(this.globalObject.bunVM());
+ if (@hasDecl(ArgumentType, "deinitAndUnprotect")) {
+ this.args.deinitAndUnprotect();
+ } else {
+ this.args.deinit();
}
-
- break :brk out;
- },
+ this.promise.strong.deinit();
+ bun.default_allocator.destroy(this);
+ }
};
- var promise_value = this.promise.value();
- var promise = this.promise.get();
- promise_value.ensureStillAlive();
-
- const tracker = this.tracker;
- tracker.willDispatch(globalObject);
- defer tracker.didDispatch(globalObject);
-
- this.deinit();
- switch (success) {
- false => {
- promise.reject(globalObject, result);
- },
- true => {
- promise.resolve(globalObject, result);
- },
- }
- }
-
- pub fn deinit(this: *AsyncCopyFileTask) void {
- this.ref.unref(this.globalObject.bunVM());
- this.args.deinit();
- this.promise.strong.deinit();
- this.arena.deinit();
- bun.default_allocator.destroy(this);
}
};
@@ -710,6 +393,16 @@ pub const Arguments = struct {
this.new_path.deinit();
}
+ pub fn deinitAndUnprotect(this: @This()) void {
+ this.old_path.deinitAndUnprotect();
+ this.new_path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *@This()) void {
+ this.old_path.toThreadSafe();
+ this.new_path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Rename {
const old_path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -748,8 +441,16 @@ pub const Arguments = struct {
this.path.deinit();
}
+ pub fn deinitAndUnprotect(this: *@This()) void {
+ this.path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *@This()) void {
+ this.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Truncate {
- const path = PathOrFileDescriptor.fromJS(ctx, arguments, arguments.arena.allocator(), exception) orelse {
+ const path = PathOrFileDescriptor.fromJS(ctx, arguments, bun.default_allocator, exception) orelse {
if (exception.* == null) {
JSC.throwInvalidArguments(
"path must be a string or TypedArray",
@@ -783,6 +484,21 @@ pub const Arguments = struct {
pub fn deinit(_: *const @This()) void {}
+ pub fn deinitAndUnprotect(this: *const @This()) void {
+ this.buffers.value.unprotect();
+ this.buffers.buffers.deinit();
+ }
+
+ pub fn toThreadSafe(this: *@This()) void {
+ this.buffers.value.protect();
+
+ var clone = bun.default_allocator.dupe(std.os.iovec, this.buffers.buffers.items) catch @panic("out of memory");
+ this.buffers.buffers.deinit();
+ this.buffers.buffers.items = clone;
+ this.buffers.buffers.capacity = clone.len;
+ this.buffers.buffers.allocator = bun.default_allocator;
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Writev {
const fd_value = arguments.nextEat() orelse {
if (exception.* == null) {
@@ -855,7 +571,23 @@ pub const Arguments = struct {
buffers: JSC.Node.VectorArrayBuffer,
position: ?u52 = 0,
- pub fn deinit(_: *const @This()) void {}
+ pub fn deinit(this: *const @This()) void {
+ _ = this;
+ }
+
+ pub fn deinitAndUnprotect(this: *const @This()) void {
+ this.buffers.value.unprotect();
+ this.buffers.buffers.deinit();
+ }
+
+ pub fn toThreadSafe(this: *@This()) void {
+ this.buffers.value.protect();
+ var clone = bun.default_allocator.dupe(std.os.iovec, this.buffers.buffers.items) catch @panic("out of memory");
+ this.buffers.buffers.deinit();
+ this.buffers.buffers.items = clone;
+ this.buffers.buffers.capacity = clone.len;
+ this.buffers.buffers.allocator = bun.default_allocator;
+ }
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Readv {
const fd_value = arguments.nextEat() orelse {
@@ -932,6 +664,14 @@ pub const Arguments = struct {
_ = this;
}
+ pub fn deinitAndUnprotect(this: *@This()) void {
+ _ = this;
+ }
+
+ pub fn toThreadSafe(this: *const @This()) void {
+ _ = this;
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?FTruncate {
const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
if (exception.* == null) {
@@ -982,6 +722,14 @@ pub const Arguments = struct {
this.path.deinit();
}
+ pub fn deinitAndUnprotect(this: *@This()) void {
+ this.path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *@This()) void {
+ this.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Chown {
const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -1040,6 +788,8 @@ pub const Arguments = struct {
pub fn deinit(_: @This()) void {}
+ pub fn toThreadSafe(_: *const @This()) void {}
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Fchown {
const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
if (exception.* == null) {
@@ -1114,6 +864,14 @@ pub const Arguments = struct {
this.path.deinit();
}
+ pub fn deinitAndUnprotect(this: *@This()) void {
+ this.path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *@This()) void {
+ this.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Lutimes {
const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -1189,6 +947,14 @@ pub const Arguments = struct {
this.path.deinit();
}
+ pub fn toThreadSafe(this: *@This()) void {
+ this.path.toThreadSafe();
+ }
+
+ pub fn deinitAndUnprotect(this: *@This()) void {
+ this.path.deinitAndUnprotect();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Chmod {
const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -1234,6 +1000,10 @@ pub const Arguments = struct {
fd: FileDescriptor,
mode: Mode = 0x777,
+ pub fn deinit(_: *const @This()) void {}
+
+ pub fn toThreadSafe(_: *const @This()) void {}
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?FChmod {
const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
if (exception.* == null) {
@@ -1303,8 +1073,12 @@ pub const Arguments = struct {
this.path.deinitAndUnprotect();
}
+ pub fn toThreadSafe(this: *Stat) void {
+ this.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Stat {
- const path = PathLike.fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception) orelse {
+ const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
JSC.throwInvalidArguments(
"path must be a string or TypedArray",
@@ -1356,6 +1130,8 @@ pub const Arguments = struct {
pub fn deinit(_: @This()) void {}
+ pub fn toThreadSafe(_: *@This()) void {}
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Fstat {
const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
if (exception.* == null) {
@@ -1412,6 +1188,16 @@ pub const Arguments = struct {
this.new_path.deinit();
}
+ pub fn deinitAndUnprotect(this: *Link) void {
+ this.old_path.deinitAndUnprotect();
+ this.new_path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *Link) void {
+ this.old_path.toThreadSafe();
+ this.new_path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Link {
const old_path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -1454,6 +1240,16 @@ pub const Arguments = struct {
this.new_path.deinit();
}
+ pub fn deinitAndUnprotect(this: Symlink) void {
+ this.old_path.deinitAndUnprotect();
+ this.new_path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *@This()) void {
+ this.old_path.toThreadSafe();
+ this.new_path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Symlink {
const old_path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -1512,6 +1308,14 @@ pub const Arguments = struct {
this.path.deinit();
}
+ pub fn deinitAndUnprotect(this: *Readlink) void {
+ this.path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *Readlink) void {
+ this.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Readlink {
const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -1560,6 +1364,10 @@ pub const Arguments = struct {
this.path.deinitAndUnprotect();
}
+ pub fn toThreadSafe(this: *Realpath) void {
+ this.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Realpath {
const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -1599,6 +1407,18 @@ pub const Arguments = struct {
pub const Unlink = struct {
path: PathLike,
+ pub fn deinit(this: Unlink) void {
+ this.path.deinit();
+ }
+
+ pub fn deinitAndUnprotect(this: *Unlink) void {
+ this.path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *Unlink) void {
+ this.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Unlink {
const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -1620,13 +1440,7 @@ pub const Arguments = struct {
}
};
- pub const Rm = struct {
- path: PathLike,
- force: bool = false,
- max_retries: u32 = 0,
- recursive: bool = false,
- retry_delay: c_uint = 100,
- };
+ pub const Rm = RmDir;
pub const RmDir = struct {
path: PathLike,
@@ -1637,6 +1451,14 @@ pub const Arguments = struct {
recursive: bool = false,
retry_delay: c_uint = 100,
+ pub fn deinitAndUnprotect(this: *RmDir) void {
+ this.path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *RmDir) void {
+ this.path.toThreadSafe();
+ }
+
pub fn deinit(this: RmDir) void {
this.path.deinit();
}
@@ -1701,6 +1523,14 @@ pub const Arguments = struct {
this.path.deinit();
}
+ pub fn deinitAndUnprotect(this: *Mkdir) void {
+ this.path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *Mkdir) void {
+ this.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Mkdir {
const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -1752,10 +1582,18 @@ pub const Arguments = struct {
this.prefix.deinit();
}
+ pub fn deinitAndUnprotect(this: *MkdirTemp) void {
+ this.prefix.deinit();
+ }
+
+ pub fn toThreadSafe(this: *MkdirTemp) void {
+ this.prefix.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?MkdirTemp {
const prefix_value = arguments.next() orelse return MkdirTemp{};
- var prefix = JSC.Node.SliceOrBuffer.fromJS(ctx, arguments.arena.allocator(), prefix_value) orelse {
+ var prefix = JSC.Node.SliceOrBuffer.fromJS(ctx, bun.default_allocator, prefix_value) orelse {
if (exception.* == null) {
JSC.throwInvalidArguments(
"prefix must be a string or TypedArray",
@@ -1810,8 +1648,12 @@ pub const Arguments = struct {
this.path.deinitAndUnprotect();
}
+ pub fn toThreadSafe(this: *Readdir) void {
+ this.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Readdir {
- const path = PathLike.fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception) orelse {
+ const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
JSC.throwInvalidArguments(
"path must be a string or TypedArray",
@@ -1864,6 +1706,7 @@ pub const Arguments = struct {
fd: FileDescriptor,
pub fn deinit(_: Close) void {}
+ pub fn toThreadSafe(_: Close) void {}
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Close {
const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
@@ -1905,6 +1748,14 @@ pub const Arguments = struct {
this.path.deinit();
}
+ pub fn deinitAndUnprotect(this: Open) void {
+ this.path.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(this: *Open) void {
+ this.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Open {
const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -1971,6 +1822,10 @@ pub const Arguments = struct {
pub fn deinit(_: Futimes) void {}
+ pub fn toThreadSafe(self: *const @This()) void {
+ _ = self;
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Futimes {
const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
if (exception.* == null) {
@@ -2052,42 +1907,6 @@ pub const Arguments = struct {
}
};
- pub const FSync = struct {
- fd: FileDescriptor,
-
- pub fn deinit(_: FSync) void {}
-
- pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?FSync {
- const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
- if (exception.* == null) {
- JSC.throwInvalidArguments(
- "File descriptor is required",
- .{},
- ctx,
- exception,
- );
- }
- return null;
- }, exception) orelse {
- if (exception.* == null) {
- JSC.throwInvalidArguments(
- "fd must be a number",
- .{},
- ctx,
- exception,
- );
- }
- return null;
- };
-
- if (exception.* != null) return null;
-
- return FSync{
- .fd = fd,
- };
- }
- };
-
/// Write `buffer` to the file specified by `fd`. If `buffer` is a normal object, it
/// must have an own `toString` function property.
///
@@ -2114,14 +1933,24 @@ pub const Arguments = struct {
///
pub const Write = struct {
fd: FileDescriptor,
- buffer: StringOrBuffer,
+ buffer: JSC.Node.SliceWithUnderlyingStringOrBuffer,
// buffer_val: JSC.JSValue = JSC.JSValue.zero,
offset: u64 = 0,
length: u64 = std.math.maxInt(u64),
position: ?ReadPosition = null,
encoding: Encoding = Encoding.buffer,
- pub fn deinit(_: Write) void {}
+ pub fn deinit(this: *const @This()) void {
+ this.buffer.deinit();
+ }
+
+ pub fn deinitAndUnprotect(this: *@This()) void {
+ this.buffer.deinitAndUnprotect();
+ }
+
+ pub fn toThreadSafe(self: *@This()) void {
+ self.buffer.toThreadSafe();
+ }
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Write {
const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
@@ -2150,7 +1979,7 @@ pub const Arguments = struct {
if (exception.* != null) return null;
- const buffer = StringOrBuffer.fromJS(ctx.ptr(), arguments.arena.allocator(), arguments.next() orelse {
+ const buffer = SliceWithUnderlyingStringOrBuffer.fromJS(ctx.ptr(), bun.default_allocator, arguments.next() orelse {
if (exception.* == null) {
JSC.throwInvalidArguments(
"data is required",
@@ -2177,7 +2006,7 @@ pub const Arguments = struct {
.fd = fd,
.buffer = buffer,
.encoding = switch (buffer) {
- .string => Encoding.utf8,
+ .SliceWithUnderlyingString => Encoding.utf8,
.buffer => Encoding.buffer,
},
};
@@ -2190,7 +2019,7 @@ pub const Arguments = struct {
var current = current_;
switch (buffer) {
// fs.write(fd, string[, position[, encoding]], callback)
- .string => {
+ .SliceWithUnderlyingString => {
if (current.isNumber()) {
args.position = current.to(i52);
arguments.eat();
@@ -2239,6 +2068,14 @@ pub const Arguments = struct {
pub fn deinit(_: Read) void {}
+ pub fn toThreadSafe(this: Read) void {
+ this.buffer.buffer.value.protect();
+ }
+
+ pub fn deinitAndUnprotect(this: *Read) void {
+ this.buffer.buffer.value.unprotect();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Read {
const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
if (exception.* == null) {
@@ -2377,6 +2214,10 @@ pub const Arguments = struct {
self.path.deinitAndUnprotect();
}
+ pub fn toThreadSafe(self: *ReadFile) void {
+ self.path.toThreadSafe();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?ReadFile {
const path = PathOrFileDescriptor.fromJS(ctx, arguments, bun.default_allocator, exception) orelse {
if (exception.* == null) {
@@ -2463,8 +2304,16 @@ pub const Arguments = struct {
self.file.deinit();
}
+ pub fn toThreadSafe(self: *WriteFile) void {
+ self.file.toThreadSafe();
+ }
+
+ pub fn deinitAndUnprotect(self: *WriteFile) void {
+ self.file.deinitAndUnprotect();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?WriteFile {
- const file = PathOrFileDescriptor.fromJS(ctx, arguments, arguments.arena.allocator(), exception) orelse {
+ const file = PathOrFileDescriptor.fromJS(ctx, arguments, bun.default_allocator, exception) orelse {
if (exception.* == null) {
JSC.throwInvalidArguments(
"path must be a string or a file descriptor",
@@ -2478,7 +2327,7 @@ pub const Arguments = struct {
if (exception.* != null) return null;
- const data = StringOrBuffer.fromJS(ctx.ptr(), arguments.arena.allocator(), arguments.next() orelse {
+ const data = StringOrBuffer.fromJS(ctx.ptr(), bun.default_allocator, arguments.next() orelse {
if (exception.* == null) {
JSC.throwInvalidArguments(
"data is required",
@@ -2673,6 +2522,18 @@ pub const Arguments = struct {
}
}
+ pub fn toThreadSafe(this: *Exists) void {
+ if (this.path) |*path| {
+ path.toThreadSafe();
+ }
+ }
+
+ pub fn deinitAndUnprotect(this: *Exists) void {
+ if (this.path) |*path| {
+ path.deinitAndUnprotect();
+ }
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Exists {
return Exists{
.path = PathLike.fromJS(ctx, arguments, exception),
@@ -2688,6 +2549,14 @@ pub const Arguments = struct {
this.path.deinit();
}
+ pub fn toThreadSafe(this: *Access) void {
+ this.path.toThreadSafe();
+ }
+
+ pub fn deinitAndUnprotect(this: *Access) void {
+ this.path.deinitAndUnprotect();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Access {
const path = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
@@ -3002,6 +2871,9 @@ pub const Arguments = struct {
fd: FileDescriptor,
pub fn deinit(_: FdataSync) void {}
+ pub fn toThreadSafe(self: *const @This()) void {
+ _ = self;
+ }
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?FdataSync {
const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
@@ -3039,13 +2911,23 @@ pub const Arguments = struct {
dest: PathLike,
mode: Constants.Copyfile,
- fn deinit(this: CopyFile) void {
+ pub fn deinit(this: CopyFile) void {
this.src.deinit();
this.dest.deinit();
}
+ pub fn toThreadSafe(this: *CopyFile) void {
+ this.src.toThreadSafe();
+ this.dest.toThreadSafe();
+ }
+
+ pub fn deinitAndUnprotect(this: *CopyFile) void {
+ this.src.deinitAndUnprotect();
+ this.dest.deinitAndUnprotect();
+ }
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?CopyFile {
- const src = PathLike.fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception) orelse {
+ const src = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
JSC.throwInvalidArguments(
"src must be a string or buffer",
@@ -3059,7 +2941,7 @@ pub const Arguments = struct {
if (exception.* != null) return null;
- const dest = PathLike.fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception) orelse {
+ const dest = PathLike.fromJS(ctx, arguments, exception) orelse {
src.deinit();
if (exception.* == null) {
@@ -3109,7 +2991,7 @@ pub const Arguments = struct {
}
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Cp {
- const src = PathLike.fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception) orelse {
+ const src = PathLike.fromJS(ctx, arguments, exception) orelse {
if (exception.* == null) {
JSC.throwInvalidArguments(
"src must be a string or buffer",
@@ -3123,7 +3005,7 @@ pub const Arguments = struct {
if (exception.* != null) return null;
- const dest = PathLike.fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception) orelse {
+ const dest = PathLike.fromJS(ctx, arguments, exception) orelse {
defer src.deinit();
if (exception.* == null) {
JSC.throwInvalidArguments(
@@ -3196,6 +3078,9 @@ pub const Arguments = struct {
pub const Fsync = struct {
fd: FileDescriptor,
+ pub fn deinit(_: Fsync) void {}
+ pub fn toThreadSafe(_: *const @This()) void {}
+
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Fsync {
const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse {
if (exception.* == null) {
@@ -3411,69 +3296,49 @@ pub const NodeFS = struct {
}
pub fn appendFile(this: *NodeFS, args: Arguments.AppendFile, comptime flavor: Flavor) Maybe(Return.AppendFile) {
+ _ = flavor;
var data = args.data.slice();
switch (args.file) {
.fd => |fd| {
- switch (comptime flavor) {
- .sync => {
- while (data.len > 0) {
- const written = switch (Syscall.write(fd, data)) {
- .result => |result| result,
- .err => |err| return .{ .err = err },
- };
- data = data[written..];
- }
-
- return Maybe(Return.AppendFile).success;
- },
- else => {
- @compileError("Not implemented yet");
- },
+ while (data.len > 0) {
+ const written = switch (Syscall.write(fd, data)) {
+ .result => |result| result,
+ .err => |err| return .{ .err = err },
+ };
+ data = data[written..];
}
+
+ return Maybe(Return.AppendFile).success;
},
.path => |path_| {
const path = path_.sliceZ(&this.sync_error_buf);
- switch (comptime flavor) {
- .sync => {
- const fd = switch (Syscall.open(path, @intFromEnum(FileSystemFlags.a), 0o000666)) {
- .result => |result| result,
- .err => |err| return .{ .err = err },
- };
- defer {
- _ = Syscall.close(fd);
- }
+ const fd = switch (Syscall.open(path, @intFromEnum(FileSystemFlags.a), 0o000666)) {
+ .result => |result| result,
+ .err => |err| return .{ .err = err },
+ };
- while (data.len > 0) {
- const written = switch (Syscall.write(fd, data)) {
- .result => |result| result,
- .err => |err| return .{ .err = err },
- };
- data = data[written..];
- }
+ defer {
+ _ = Syscall.close(fd);
+ }
- return Maybe(Return.AppendFile).success;
- },
- else => {
- @compileError("Not implemented yet");
- },
+ while (data.len > 0) {
+ const written = switch (Syscall.write(fd, data)) {
+ .result => |result| result,
+ .err => |err| return .{ .err = err },
+ };
+ data = data[written..];
}
+
+ return Maybe(Return.AppendFile).success;
},
}
-
- return Maybe(Return.AppendFile).todo;
}
pub fn close(_: *NodeFS, args: Arguments.Close, comptime flavor: Flavor) Maybe(Return.Close) {
- switch (comptime flavor) {
- .sync => {
- return if (Syscall.close(args.fd)) |err| .{ .err = err } else Maybe(Return.Close).success;
- },
- else => {},
- }
-
- return .{ .err = Syscall.Error.todo };
+ _ = flavor;
+ return if (Syscall.close(args.fd)) |err| .{ .err = err } else Maybe(Return.Close).success;
}
// since we use a 64 KB stack buffer, we should not let this function get inlined
@@ -3714,132 +3579,92 @@ pub const NodeFS = struct {
}
pub fn exists(this: *NodeFS, args: Arguments.Exists, comptime flavor: Flavor) Maybe(Return.Exists) {
+ _ = flavor;
const Ret = Maybe(Return.Exists);
- switch (comptime flavor) {
- .sync => {
- const path = args.path orelse return Ret{ .result = false };
- const slice = path.sliceZ(&this.sync_error_buf);
- // access() may not work correctly on NFS file systems with UID
- // mapping enabled, because UID mapping is done on the server and
- // hidden from the client, which checks permissions. Similar
- // problems can occur to FUSE mounts.
- const rc = (system.access(slice, std.os.F_OK));
- return Ret{ .result = rc == 0 };
- },
- else => {},
- }
-
- return Ret.todo;
+ const path = args.path orelse return Ret{ .result = false };
+ const slice = path.sliceZ(&this.sync_error_buf);
+ // access() may not work correctly on NFS file systems with UID
+ // mapping enabled, because UID mapping is done on the server and
+ // hidden from the client, which checks permissions. Similar
+ // problems can occur to FUSE mounts.
+ const rc = (system.access(slice, std.os.F_OK));
+ return Ret{ .result = rc == 0 };
}
pub fn chown(this: *NodeFS, args: Arguments.Chown, comptime flavor: Flavor) Maybe(Return.Chown) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Fchmod).todo;
}
const path = args.path.sliceZ(&this.sync_error_buf);
- switch (comptime flavor) {
- .sync => return Syscall.chown(path, args.uid, args.gid),
- else => {},
- }
-
- return Maybe(Return.Chown).todo;
+ return Syscall.chown(path, args.uid, args.gid);
}
/// This should almost never be async
pub fn chmod(this: *NodeFS, args: Arguments.Chmod, comptime flavor: Flavor) Maybe(Return.Chmod) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Fchmod).todo;
}
const path = args.path.sliceZ(&this.sync_error_buf);
- switch (comptime flavor) {
- .sync => {
- return Maybe(Return.Chmod).errnoSysP(C.chmod(path, args.mode), .chmod, path) orelse
- Maybe(Return.Chmod).success;
- },
- else => {},
- }
-
- return Maybe(Return.Chmod).todo;
+ return Maybe(Return.Chmod).errnoSysP(C.chmod(path, args.mode), .chmod, path) orelse
+ Maybe(Return.Chmod).success;
}
/// This should almost never be async
pub fn fchmod(_: *NodeFS, args: Arguments.FChmod, comptime flavor: Flavor) Maybe(Return.Fchmod) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Fchmod).todo;
}
- switch (comptime flavor) {
- .sync => {
- return Syscall.fchmod(args.fd, args.mode);
- },
- else => {},
- }
-
- return Maybe(Return.Fchmod).todo;
+ return Syscall.fchmod(args.fd, args.mode);
}
pub fn fchown(_: *NodeFS, args: Arguments.Fchown, comptime flavor: Flavor) Maybe(Return.Fchown) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Fchown).todo;
}
- switch (comptime flavor) {
- .sync => {
- return Maybe(Return.Fchown).errnoSys(C.fchown(args.fd, args.uid, args.gid), .fchown) orelse
- Maybe(Return.Fchown).success;
- },
- else => {},
- }
-
- return Maybe(Return.Fchown).todo;
+ return Maybe(Return.Fchown).errnoSys(C.fchown(args.fd, args.uid, args.gid), .fchown) orelse
+ Maybe(Return.Fchown).success;
}
pub fn fdatasync(_: *NodeFS, args: Arguments.FdataSync, comptime flavor: Flavor) Maybe(Return.Fdatasync) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Fdatasync).todo;
}
- switch (comptime flavor) {
- .sync => return Maybe(Return.Fdatasync).errnoSys(system.fdatasync(args.fd), .fdatasync) orelse
- Maybe(Return.Fdatasync).success,
- else => {},
- }
-
- return Maybe(Return.Fdatasync).todo;
+ return Maybe(Return.Fdatasync).errnoSys(system.fdatasync(args.fd), .fdatasync) orelse
+ Maybe(Return.Fdatasync).success;
}
pub fn fstat(_: *NodeFS, args: Arguments.Fstat, comptime flavor: Flavor) Maybe(Return.Fstat) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Fstat).todo;
}
- switch (comptime flavor) {
- .sync => {
- if (comptime Environment.isPosix) {
- return switch (Syscall.fstat(args.fd)) {
- .result => |result| Maybe(Return.Fstat){ .result = Stats.init(result, false) },
- .err => |err| Maybe(Return.Fstat){ .err = err },
- };
- }
- },
- else => {},
+ if (comptime Environment.isPosix) {
+ return switch (Syscall.fstat(args.fd)) {
+ .result => |result| Maybe(Return.Fstat){ .result = Stats.init(result, false) },
+ .err => |err| Maybe(Return.Fstat){ .err = err },
+ };
}
return Maybe(Return.Fstat).todo;
}
pub fn fsync(_: *NodeFS, args: Arguments.Fsync, comptime flavor: Flavor) Maybe(Return.Fsync) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Fsync).todo;
}
- switch (comptime flavor) {
- .sync => return Maybe(Return.Fsync).errnoSys(system.fsync(args.fd), .fsync) orelse
- Maybe(Return.Fsync).success,
- else => {},
- }
-
- return Maybe(Return.Fsync).todo;
+ return Maybe(Return.Fsync).errnoSys(system.fsync(args.fd), .fsync) orelse
+ Maybe(Return.Fsync).success;
}
pub fn ftruncateSync(args: Arguments.FTruncate) Maybe(Return.Ftruncate) {
@@ -3847,14 +3672,11 @@ pub const NodeFS = struct {
}
pub fn ftruncate(_: *NodeFS, args: Arguments.FTruncate, comptime flavor: Flavor) Maybe(Return.Ftruncate) {
- switch (comptime flavor) {
- .sync => return ftruncateSync(args),
- else => {},
- }
-
- return Maybe(Return.Ftruncate).todo;
+ _ = flavor;
+ return ftruncateSync(args);
}
pub fn futimes(_: *NodeFS, args: Arguments.Futimes, comptime flavor: Flavor) Maybe(Return.Futimes) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Futimes).todo;
}
@@ -3870,66 +3692,43 @@ pub const NodeFS = struct {
},
};
- switch (comptime flavor) {
- .sync => return if (Maybe(Return.Futimes).errnoSys(system.futimens(args.fd, &times), .futimens)) |err|
- err
- else
- Maybe(Return.Futimes).success,
- else => {},
- }
-
- return Maybe(Return.Futimes).todo;
+ return if (Maybe(Return.Futimes).errnoSys(system.futimens(args.fd, &times), .futimens)) |err|
+ err
+ else
+ Maybe(Return.Futimes).success;
}
pub fn lchmod(this: *NodeFS, args: Arguments.LCHmod, comptime flavor: Flavor) Maybe(Return.Lchmod) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Lchmod).todo;
}
const path = args.path.sliceZ(&this.sync_error_buf);
- switch (comptime flavor) {
- .sync => {
- return Maybe(Return.Lchmod).errnoSysP(C.lchmod(path, args.mode), .lchmod, path) orelse
- Maybe(Return.Lchmod).success;
- },
- else => {},
- }
-
- return Maybe(Return.Lchmod).todo;
+ return Maybe(Return.Lchmod).errnoSysP(C.lchmod(path, args.mode), .lchmod, path) orelse
+ Maybe(Return.Lchmod).success;
}
pub fn lchown(this: *NodeFS, args: Arguments.LChown, comptime flavor: Flavor) Maybe(Return.Lchown) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Lchown).todo;
}
const path = args.path.sliceZ(&this.sync_error_buf);
- switch (comptime flavor) {
- .sync => {
- return Maybe(Return.Lchown).errnoSysP(C.lchown(path, args.uid, args.gid), .lchown, path) orelse
- Maybe(Return.Lchown).success;
- },
- else => {},
- }
-
- return Maybe(Return.Lchown).todo;
+ return Maybe(Return.Lchown).errnoSysP(C.lchown(path, args.uid, args.gid), .lchown, path) orelse
+ Maybe(Return.Lchown).success;
}
pub fn link(this: *NodeFS, args: Arguments.Link, comptime flavor: Flavor) Maybe(Return.Link) {
+ _ = flavor;
var new_path_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
const from = args.old_path.sliceZ(&this.sync_error_buf);
const to = args.new_path.sliceZ(&new_path_buf);
- switch (comptime flavor) {
- .sync => {
- return Maybe(Return.Link).errnoSysP(system.link(from, to, 0), .link, from) orelse
- Maybe(Return.Link).success;
- },
- else => {},
- }
-
- return Maybe(Return.Link).todo;
+ return Maybe(Return.Link).errnoSysP(system.link(from, to, 0), .link, from) orelse
+ Maybe(Return.Link).success;
}
pub fn lstat(this: *NodeFS, args: Arguments.Lstat, comptime flavor: Flavor) Maybe(Return.Lstat) {
if (comptime Environment.isWindows) {
@@ -3957,158 +3756,146 @@ pub const NodeFS = struct {
}
// Node doesn't absolute the path so we don't have to either
fn mkdirNonRecursive(this: *NodeFS, args: Arguments.Mkdir, comptime flavor: Flavor) Maybe(Return.Mkdir) {
- switch (comptime flavor) {
- .sync => {
- const path = args.path.sliceZ(&this.sync_error_buf);
- return switch (Syscall.mkdir(path, args.mode)) {
- .result => Maybe(Return.Mkdir){ .result = bun.String.empty },
- .err => |err| Maybe(Return.Mkdir){ .err = err },
- };
- },
- else => {},
- }
+ _ = flavor;
- return Maybe(Return.Mkdir).todo;
+ const path = args.path.sliceZ(&this.sync_error_buf);
+ return switch (Syscall.mkdir(path, args.mode)) {
+ .result => Maybe(Return.Mkdir){ .result = bun.String.empty },
+ .err => |err| Maybe(Return.Mkdir){ .err = err },
+ };
}
// TODO: windows
// TODO: verify this works correctly with unicode codepoints
pub fn mkdirRecursive(this: *NodeFS, args: Arguments.Mkdir, comptime flavor: Flavor) Maybe(Return.Mkdir) {
+ _ = flavor;
const Option = Maybe(Return.Mkdir);
if (comptime Environment.isWindows) return Option.todo;
- switch (comptime flavor) {
- // The sync version does no allocation except when returning the path
- .sync => {
- var buf: [bun.MAX_PATH_BYTES]u8 = undefined;
- const path = args.path.sliceZWithForceCopy(&buf, true);
- const len = @as(u16, @truncate(path.len));
+ var buf: [bun.MAX_PATH_BYTES]u8 = undefined;
+ const path = args.path.sliceZWithForceCopy(&buf, true);
+ const len = @as(u16, @truncate(path.len));
- // First, attempt to create the desired directory
- // If that fails, then walk back up the path until we have a match
- switch (Syscall.mkdir(path, args.mode)) {
- .err => |err| {
- switch (err.getErrno()) {
- else => {
- @memcpy(this.sync_error_buf[0..len], path[0..len]);
- return .{ .err = err.withPath(this.sync_error_buf[0..len]) };
- },
-
- .EXIST => {
- return Option{ .result = bun.String.empty };
- },
- // continue
- .NOENT => {},
- }
+ // First, attempt to create the desired directory
+ // If that fails, then walk back up the path until we have a match
+ switch (Syscall.mkdir(path, args.mode)) {
+ .err => |err| {
+ switch (err.getErrno()) {
+ else => {
+ @memcpy(this.sync_error_buf[0..len], path[0..len]);
+ return .{ .err = err.withPath(this.sync_error_buf[0..len]) };
},
- .result => {
- return Option{
- .result = if (args.path == .slice_with_underlying_string)
- args.path.slice_with_underlying_string.underlying
- else
- bun.String.create(args.path.slice()),
- };
+
+ .EXIST => {
+ return Option{ .result = bun.String.empty };
},
+ // continue
+ .NOENT => {},
}
+ },
+ .result => {
+ return Option{
+ .result = if (args.path == .slice_with_underlying_string)
+ args.path.slice_with_underlying_string.underlying
+ else
+ bun.String.create(args.path.slice()),
+ };
+ },
+ }
- var working_mem = &this.sync_error_buf;
- @memcpy(working_mem[0..len], path[0..len]);
+ var working_mem = &this.sync_error_buf;
+ @memcpy(working_mem[0..len], path[0..len]);
- var i: u16 = len - 1;
+ var i: u16 = len - 1;
- // iterate backwards until creating the directory works successfully
- while (i > 0) : (i -= 1) {
- if (path[i] == std.fs.path.sep) {
- working_mem[i] = 0;
- var parent: [:0]u8 = working_mem[0..i :0];
+ // iterate backwards until creating the directory works successfully
+ while (i > 0) : (i -= 1) {
+ if (path[i] == std.fs.path.sep) {
+ working_mem[i] = 0;
+ var parent: [:0]u8 = working_mem[0..i :0];
- switch (Syscall.mkdir(parent, args.mode)) {
- .err => |err| {
- working_mem[i] = std.fs.path.sep;
- switch (err.getErrno()) {
- .EXIST => {
- // Handle race condition
- break;
- },
- .NOENT => {
- continue;
- },
- else => return .{ .err = err.withPath(parent) },
- }
- },
- .result => {
- // We found a parent that worked
- working_mem[i] = std.fs.path.sep;
+ switch (Syscall.mkdir(parent, args.mode)) {
+ .err => |err| {
+ working_mem[i] = std.fs.path.sep;
+ switch (err.getErrno()) {
+ .EXIST => {
+ // Handle race condition
break;
},
- }
- }
- }
- var first_match: u16 = i;
- i += 1;
- // after we find one that works, we go forward _after_ the first working directory
- while (i < len) : (i += 1) {
- if (path[i] == std.fs.path.sep) {
- working_mem[i] = 0;
- var parent: [:0]u8 = working_mem[0..i :0];
-
- switch (Syscall.mkdir(parent, args.mode)) {
- .err => |err| {
- working_mem[i] = std.fs.path.sep;
- switch (err.getErrno()) {
- .EXIST => {
- if (Environment.allow_assert) std.debug.assert(false);
- continue;
- },
- else => return .{ .err = err },
- }
- },
-
- .result => {
- working_mem[i] = std.fs.path.sep;
+ .NOENT => {
+ continue;
},
+ else => return .{ .err = err.withPath(parent) },
}
- }
+ },
+ .result => {
+ // We found a parent that worked
+ working_mem[i] = std.fs.path.sep;
+ break;
+ },
}
+ }
+ }
+ var first_match: u16 = i;
+ i += 1;
+ // after we find one that works, we go forward _after_ the first working directory
+ while (i < len) : (i += 1) {
+ if (path[i] == std.fs.path.sep) {
+ working_mem[i] = 0;
+ var parent: [:0]u8 = working_mem[0..i :0];
- working_mem[len] = 0;
-
- // Our final directory will not have a trailing separator
- // so we have to create it once again
- switch (Syscall.mkdir(working_mem[0..len :0], args.mode)) {
+ switch (Syscall.mkdir(parent, args.mode)) {
.err => |err| {
+ working_mem[i] = std.fs.path.sep;
switch (err.getErrno()) {
- // handle the race condition
.EXIST => {
- var display_path = bun.String.empty;
- if (first_match != std.math.maxInt(u16)) {
- display_path = bun.String.create(working_mem[0..first_match]);
- }
- return Option{ .result = display_path };
- },
-
- // NOENT shouldn't happen here
- else => return .{
- .err = err.withPath(path),
+ if (Environment.allow_assert) std.debug.assert(false);
+ continue;
},
+ else => return .{ .err = err },
}
},
+
.result => {
- return Option{
- .result = if (first_match != std.math.maxInt(u16))
- bun.String.create(working_mem[0..first_match])
- else if (args.path == .slice_with_underlying_string)
- args.path.slice_with_underlying_string.underlying
- else
- bun.String.create(args.path.slice()),
- };
+ working_mem[i] = std.fs.path.sep;
},
}
- },
- else => {},
+ }
}
- return Maybe(Return.Mkdir).todo;
+ working_mem[len] = 0;
+
+ // Our final directory will not have a trailing separator
+ // so we have to create it once again
+ switch (Syscall.mkdir(working_mem[0..len :0], args.mode)) {
+ .err => |err| {
+ switch (err.getErrno()) {
+ // handle the race condition
+ .EXIST => {
+ var display_path = bun.String.empty;
+ if (first_match != std.math.maxInt(u16)) {
+ display_path = bun.String.create(working_mem[0..first_match]);
+ }
+ return Option{ .result = display_path };
+ },
+
+ // NOENT shouldn't happen here
+ else => return .{
+ .err = err.withPath(path),
+ },
+ }
+ },
+ .result => {
+ return Option{
+ .result = if (first_match != std.math.maxInt(u16))
+ bun.String.create(working_mem[0..first_match])
+ else if (args.path == .slice_with_underlying_string)
+ args.path.slice_with_underlying_string.underlying
+ else
+ bun.String.create(args.path.slice()),
+ };
+ },
+ }
}
pub fn mkdtemp(this: *NodeFS, args: Arguments.MkdirTemp, comptime _: Flavor) Maybe(Return.Mkdtemp) {
@@ -4136,75 +3923,54 @@ pub const NodeFS = struct {
return .{ .err = Syscall.Error{ .errno = @as(Syscall.Error.Int, @truncate(@intFromEnum(errno))), .syscall = .mkdtemp } };
}
pub fn open(this: *NodeFS, args: Arguments.Open, comptime flavor: Flavor) Maybe(Return.Open) {
- switch (comptime flavor) {
- // The sync version does no allocation except when returning the path
- .sync => {
- const path = args.path.sliceZ(&this.sync_error_buf);
- return switch (Syscall.open(path, @intFromEnum(args.flags), args.mode)) {
- .err => |err| .{
- .err = err.withPath(args.path.slice()),
- },
- .result => |fd| .{ .result = fd },
- };
+ _ = flavor;
+ const path = args.path.sliceZ(&this.sync_error_buf);
+ return switch (Syscall.open(path, @intFromEnum(args.flags), args.mode)) {
+ .err => |err| .{
+ .err = err.withPath(args.path.slice()),
},
- else => {},
- }
-
- return Maybe(Return.Open).todo;
+ .result => |fd| .{ .result = fd },
+ };
}
pub fn openDir(_: *NodeFS, _: Arguments.OpenDir, comptime _: Flavor) Maybe(Return.OpenDir) {
return Maybe(Return.OpenDir).todo;
}
fn _read(_: *NodeFS, args: Arguments.Read, comptime flavor: Flavor) Maybe(Return.Read) {
+ _ = flavor;
if (Environment.allow_assert) std.debug.assert(args.position == null);
+ var buf = args.buffer.slice();
+ buf = buf[@min(args.offset, buf.len)..];
+ buf = buf[0..@min(buf.len, args.length)];
- switch (comptime flavor) {
- // The sync version does no allocation except when returning the path
- .sync => {
- var buf = args.buffer.slice();
- buf = buf[@min(args.offset, buf.len)..];
- buf = buf[0..@min(buf.len, args.length)];
-
- return switch (Syscall.read(args.fd, buf)) {
- .err => |err| .{
- .err = err,
- },
- .result => |amt| .{
- .result = .{
- .bytes_read = @as(u52, @truncate(amt)),
- },
- },
- };
+ return switch (Syscall.read(args.fd, buf)) {
+ .err => |err| .{
+ .err = err,
},
- else => {},
- }
-
- return Maybe(Return.Read).todo;
+ .result => |amt| .{
+ .result = .{
+ .bytes_read = @as(u52, @truncate(amt)),
+ },
+ },
+ };
}
fn _pread(_: *NodeFS, args: Arguments.Read, comptime flavor: Flavor) Maybe(Return.Read) {
- switch (comptime flavor) {
- .sync => {
- var buf = args.buffer.slice();
- buf = buf[@min(args.offset, buf.len)..];
- buf = buf[0..@min(buf.len, args.length)];
-
- return switch (Syscall.pread(args.fd, buf, args.position.?)) {
- .err => |err| .{
- .err = err,
- },
- .result => |amt| .{
- .result = .{
- .bytes_read = @as(u52, @truncate(amt)),
- },
- },
- };
- },
- else => {},
- }
+ _ = flavor;
+ var buf = args.buffer.slice();
+ buf = buf[@min(args.offset, buf.len)..];
+ buf = buf[0..@min(buf.len, args.length)];
- return Maybe(Return.Read).todo;
+ return switch (Syscall.pread(args.fd, buf, args.position.?)) {
+ .err => |err| .{
+ .err = err,
+ },
+ .result => |amt| .{
+ .result = .{
+ .bytes_read = @as(u52, @truncate(amt)),
+ },
+ },
+ };
}
pub fn read(this: *NodeFS, args: Arguments.Read, comptime flavor: Flavor) Maybe(Return.Read) {
@@ -4236,127 +4002,91 @@ pub const NodeFS = struct {
return if (args.position != null) _pwrite(this, args, flavor) else _write(this, args, flavor);
}
fn _write(_: *NodeFS, args: Arguments.Write, comptime flavor: Flavor) Maybe(Return.Write) {
- switch (comptime flavor) {
- .sync => {
- var buf = args.buffer.slice();
- buf = buf[@min(args.offset, buf.len)..];
- buf = buf[0..@min(buf.len, args.length)];
-
- return switch (Syscall.write(args.fd, buf)) {
- .err => |err| .{
- .err = err,
- },
- .result => |amt| .{
- .result = .{
- .bytes_written = @as(u52, @truncate(amt)),
- },
- },
- };
- },
- else => {},
- }
+ _ = flavor;
- return Maybe(Return.Write).todo;
+ var buf = args.buffer.slice();
+ buf = buf[@min(args.offset, buf.len)..];
+ buf = buf[0..@min(buf.len, args.length)];
+
+ return switch (Syscall.write(args.fd, buf)) {
+ .err => |err| .{
+ .err = err,
+ },
+ .result => |amt| .{
+ .result = .{
+ .bytes_written = @as(u52, @truncate(amt)),
+ },
+ },
+ };
}
fn _pwrite(_: *NodeFS, args: Arguments.Write, comptime flavor: Flavor) Maybe(Return.Write) {
+ _ = flavor;
const position = args.position.?;
- switch (comptime flavor) {
- .sync => {
- var buf = args.buffer.slice();
- buf = buf[@min(args.offset, buf.len)..];
- buf = buf[0..@min(args.length, buf.len)];
+ var buf = args.buffer.slice();
+ buf = buf[@min(args.offset, buf.len)..];
+ buf = buf[0..@min(args.length, buf.len)];
- return switch (Syscall.pwrite(args.fd, buf, position)) {
- .err => |err| .{
- .err = err,
- },
- .result => |amt| .{ .result = .{
- .bytes_written = @as(u52, @truncate(amt)),
- } },
- };
+ return switch (Syscall.pwrite(args.fd, buf, position)) {
+ .err => |err| .{
+ .err = err,
},
- else => {},
- }
-
- return Maybe(Return.Write).todo;
+ .result => |amt| .{ .result = .{
+ .bytes_written = @as(u52, @truncate(amt)),
+ } },
+ };
}
fn _preadv(_: *NodeFS, args: Arguments.Readv, comptime flavor: Flavor) Maybe(Return.Readv) {
+ _ = flavor;
const position = args.position.?;
- switch (comptime flavor) {
- .sync => {
- return switch (Syscall.preadv(args.fd, args.buffers.buffers.items, position)) {
- .err => |err| .{
- .err = err,
- },
- .result => |amt| .{ .result = .{
- .bytes_read = @as(u52, @truncate(amt)),
- } },
- };
+ return switch (Syscall.preadv(args.fd, args.buffers.buffers.items, position)) {
+ .err => |err| .{
+ .err = err,
},
- else => {},
- }
-
- return Maybe(Return.Write).todo;
+ .result => |amt| .{ .result = .{
+ .bytes_read = @as(u52, @truncate(amt)),
+ } },
+ };
}
fn _readv(_: *NodeFS, args: Arguments.Readv, comptime flavor: Flavor) Maybe(Return.Readv) {
- switch (comptime flavor) {
- .sync => {
- return switch (Syscall.readv(args.fd, args.buffers.buffers.items)) {
- .err => |err| .{
- .err = err,
- },
- .result => |amt| .{ .result = .{
- .bytes_read = @as(u52, @truncate(amt)),
- } },
- };
+ _ = flavor;
+ return switch (Syscall.readv(args.fd, args.buffers.buffers.items)) {
+ .err => |err| .{
+ .err = err,
},
- else => {},
- }
-
- return Maybe(Return.Write).todo;
+ .result => |amt| .{ .result = .{
+ .bytes_read = @as(u52, @truncate(amt)),
+ } },
+ };
}
fn _pwritev(_: *NodeFS, args: Arguments.Writev, comptime flavor: Flavor) Maybe(Return.Write) {
+ _ = flavor;
const position = args.position.?;
-
- switch (comptime flavor) {
- .sync => {
- return switch (Syscall.pwritev(args.fd, args.buffers.buffers.items, position)) {
- .err => |err| .{
- .err = err,
- },
- .result => |amt| .{ .result = .{
- .bytes_written = @as(u52, @truncate(amt)),
- } },
- };
+ return switch (Syscall.pwritev(args.fd, args.buffers.buffers.items, position)) {
+ .err => |err| .{
+ .err = err,
},
- else => {},
- }
-
- return Maybe(Return.Write).todo;
+ .result => |amt| .{ .result = .{
+ .bytes_written = @as(u52, @truncate(amt)),
+ } },
+ };
}
fn _writev(_: *NodeFS, args: Arguments.Writev, comptime flavor: Flavor) Maybe(Return.Write) {
- switch (comptime flavor) {
- .sync => {
- return switch (Syscall.writev(args.fd, args.buffers.buffers.items)) {
- .err => |err| .{
- .err = err,
- },
- .result => |amt| .{ .result = .{
- .bytes_written = @as(u52, @truncate(amt)),
- } },
- };
+ _ = flavor;
+ return switch (Syscall.writev(args.fd, args.buffers.buffers.items)) {
+ .err => |err| .{
+ .err = err,
},
- else => {},
- }
-
- return Maybe(Return.Write).todo;
+ .result => |amt| .{ .result = .{
+ .bytes_written = @as(u52, @truncate(amt)),
+ } },
+ };
}
pub fn readdir(this: *NodeFS, args: Arguments.Readdir, comptime flavor: Flavor) Maybe(Return.Readdir) {
@@ -4751,50 +4481,39 @@ pub const NodeFS = struct {
return Maybe(Return.WriteFile).success;
}
- pub fn writeFile(this: *NodeFS, args: Arguments.WriteFile, comptime flavor: Flavor) Maybe(Return.WriteFile) {
- switch (comptime flavor) {
- .sync => return writeFileWithPathBuffer(&this.sync_error_buf, args),
- else => {},
- }
-
- return Maybe(Return.WriteFile).todo;
+ pub fn writeFile(this: *NodeFS, args: Arguments.WriteFile, comptime _: Flavor) Maybe(Return.WriteFile) {
+ return writeFileWithPathBuffer(&this.sync_error_buf, args);
}
- pub fn readlink(this: *NodeFS, args: Arguments.Readlink, comptime flavor: Flavor) Maybe(Return.Readlink) {
+ pub fn readlink(this: *NodeFS, args: Arguments.Readlink, comptime _: Flavor) Maybe(Return.Readlink) {
var outbuf: [bun.MAX_PATH_BYTES]u8 = undefined;
var inbuf = &this.sync_error_buf;
- switch (comptime flavor) {
- .sync => {
- const path = args.path.sliceZ(inbuf);
- const len = switch (Syscall.readlink(path, &outbuf)) {
- .err => |err| return .{
- .err = err.withPath(args.path.slice()),
- },
- .result => |buf_| buf_,
- };
+ const path = args.path.sliceZ(inbuf);
- return .{
- .result = switch (args.encoding) {
- .buffer => .{
- .buffer = Buffer.fromString(outbuf[0..len], bun.default_allocator) catch unreachable,
- },
- else => if (args.path == .slice_with_underlying_string and
- strings.eqlLong(args.path.slice_with_underlying_string.slice(), outbuf[0..len], true))
- .{
- .BunString = args.path.slice_with_underlying_string.underlying.dupeRef(),
- }
- else
- .{
- .BunString = bun.String.create(outbuf[0..len]),
- },
- },
- };
+ const len = switch (Syscall.readlink(path, &outbuf)) {
+ .err => |err| return .{
+ .err = err.withPath(args.path.slice()),
},
- else => {},
- }
+ .result => |buf_| buf_,
+ };
- return Maybe(Return.Readlink).todo;
+ return .{
+ .result = switch (args.encoding) {
+ .buffer => .{
+ .buffer = Buffer.fromString(outbuf[0..len], bun.default_allocator) catch unreachable,
+ },
+ else => if (args.path == .slice_with_underlying_string and
+ strings.eqlLong(args.path.slice_with_underlying_string.slice(), outbuf[0..len], true))
+ .{
+ .BunString = args.path.slice_with_underlying_string.underlying.dupeRef(),
+ }
+ else
+ .{
+ .BunString = bun.String.create(outbuf[0..len]),
+ },
+ },
+ };
}
pub fn realpath(this: *NodeFS, args: Arguments.Realpath, comptime _: Flavor) Maybe(Return.Realpath) {
var outbuf: [bun.MAX_PATH_BYTES]u8 = undefined;
@@ -4857,325 +4576,227 @@ pub const NodeFS = struct {
// return error.NotImplementedYet;
// }
pub fn rename(this: *NodeFS, args: Arguments.Rename, comptime flavor: Flavor) Maybe(Return.Rename) {
+ _ = flavor;
var from_buf = &this.sync_error_buf;
var to_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
- switch (comptime flavor) {
- .sync => {
- var from = args.old_path.sliceZ(from_buf);
- var to = args.new_path.sliceZ(&to_buf);
- return Syscall.rename(from, to);
- },
- else => {},
- }
-
- return Maybe(Return.Rename).todo;
+ var from = args.old_path.sliceZ(from_buf);
+ var to = args.new_path.sliceZ(&to_buf);
+ return Syscall.rename(from, to);
}
- pub fn rmdir(this: *NodeFS, args: Arguments.RmDir, comptime flavor: Flavor) Maybe(Return.Rmdir) {
- switch (comptime flavor) {
- .sync => {
- if (comptime Environment.isMac) {
- if (args.recursive) {
- var dest = args.path.sliceZ(&this.sync_error_buf);
-
- var flags: u32 = bun.C.darwin.RemoveFileFlags.cross_mount |
- bun.C.darwin.RemoveFileFlags.allow_long_paths |
- bun.C.darwin.RemoveFileFlags.recursive;
-
- while (true) {
- if (Maybe(Return.Rmdir).errnoSys(bun.C.darwin.removefileat(std.os.AT.FDCWD, dest, null, flags), .rmdir)) |errno| {
- switch (@as(os.E, @enumFromInt(errno.err.errno))) {
- .AGAIN, .INTR => continue,
- .NOENT => return Maybe(Return.Rmdir).success,
- .MLINK => {
- var copy: [bun.MAX_PATH_BYTES]u8 = undefined;
- @memcpy(copy[0..dest.len], dest);
- copy[dest.len] = 0;
- var dest_copy = copy[0..dest.len :0];
- switch (Syscall.unlink(dest_copy).getErrno()) {
- .AGAIN, .INTR => continue,
- .NOENT => return errno,
- .SUCCESS => continue,
- else => return errno,
- }
- },
- .SUCCESS => unreachable,
- else => return errno,
- }
- }
-
- return Maybe(Return.Rmdir).success;
- }
- }
-
- return Maybe(Return.Rmdir).errnoSysP(system.rmdir(args.path.sliceZ(&this.sync_error_buf)), .rmdir, args.path.slice()) orelse
- Maybe(Return.Rmdir).success;
- } else if (comptime Environment.isLinux) {
- if (args.recursive) {
- std.fs.cwd().deleteTree(args.path.slice()) catch |err| {
- const errno: std.os.E = switch (err) {
- error.InvalidHandle => .BADF,
- error.AccessDenied => .PERM,
- error.FileTooBig => .FBIG,
- error.SymLinkLoop => .LOOP,
- error.ProcessFdQuotaExceeded => .NFILE,
- error.NameTooLong => .NAMETOOLONG,
- error.SystemFdQuotaExceeded => .MFILE,
- error.SystemResources => .NOMEM,
- error.ReadOnlyFileSystem => .ROFS,
- error.FileSystem => .IO,
- error.FileBusy => .BUSY,
- error.DeviceBusy => .BUSY,
-
- // One of the path components was not a directory.
- // This error is unreachable if `sub_path` does not contain a path separator.
- error.NotDir => .NOTDIR,
- // On Windows, file paths must be valid Unicode.
- error.InvalidUtf8 => .INVAL,
-
- // On Windows, file paths cannot contain these characters:
- // '/', '*', '?', '"', '<', '>', '|'
- error.BadPathName => .INVAL,
-
- else => .FAULT,
- };
- return Maybe(Return.Rm){
- .err = bun.sys.Error.fromCode(errno, .rmdir),
- };
- };
+ pub fn rmdir(this: *NodeFS, args: Arguments.RmDir, comptime _: Flavor) Maybe(Return.Rmdir) {
+ if (comptime Environment.isPosix) {
+ if (args.recursive) {
+ std.fs.cwd().deleteTree(args.path.slice()) catch |err| {
+ const errno: std.os.E = switch (err) {
+ error.InvalidHandle => .BADF,
+ error.AccessDenied => .PERM,
+ error.FileTooBig => .FBIG,
+ error.SymLinkLoop => .LOOP,
+ error.ProcessFdQuotaExceeded => .NFILE,
+ error.NameTooLong => .NAMETOOLONG,
+ error.SystemFdQuotaExceeded => .MFILE,
+ error.SystemResources => .NOMEM,
+ error.ReadOnlyFileSystem => .ROFS,
+ error.FileSystem => .IO,
+ error.FileBusy => .BUSY,
+ error.DeviceBusy => .BUSY,
+
+ // One of the path components was not a directory.
+ // This error is unreachable if `sub_path` does not contain a path separator.
+ error.NotDir => .NOTDIR,
+ // On Windows, file paths must be valid Unicode.
+ error.InvalidUtf8 => .INVAL,
+
+ // On Windows, file paths cannot contain these characters:
+ // '/', '*', '?', '"', '<', '>', '|'
+ error.BadPathName => .INVAL,
+
+ else => .FAULT,
+ };
+ return Maybe(Return.Rm){
+ .err = bun.sys.Error.fromCode(errno, .rmdir),
+ };
+ };
- return Maybe(Return.Rmdir).success;
- }
+ return Maybe(Return.Rmdir).success;
+ }
- return Maybe(Return.Rmdir).errnoSysP(system.rmdir(args.path.sliceZ(&this.sync_error_buf)), .rmdir, args.path.slice()) orelse
- Maybe(Return.Rmdir).success;
- }
- },
- else => {},
+ return Maybe(Return.Rmdir).errnoSysP(system.rmdir(args.path.sliceZ(&this.sync_error_buf)), .rmdir, args.path.slice()) orelse
+ Maybe(Return.Rmdir).success;
}
return Maybe(Return.Rmdir).todo;
}
pub fn rm(this: *NodeFS, args: Arguments.RmDir, comptime flavor: Flavor) Maybe(Return.Rm) {
- switch (comptime flavor) {
- .sync => {
- if (comptime Environment.isMac) {
- var dest = args.path.sliceZ(&this.sync_error_buf);
-
- while (true) {
- var flags: u32 = 0;
- if (args.recursive) {
- flags |= bun.C.darwin.RemoveFileFlags.cross_mount;
- flags |= bun.C.darwin.RemoveFileFlags.allow_long_paths;
- flags |= bun.C.darwin.RemoveFileFlags.recursive;
- }
-
- if (Maybe(Return.Rm).errnoSys(bun.C.darwin.removefileat(std.os.AT.FDCWD, dest, null, flags), .unlink)) |errno| {
- switch (@as(os.E, @enumFromInt(errno.err.errno))) {
- .AGAIN, .INTR => continue,
- .NOENT => {
- if (args.force) {
- return Maybe(Return.Rm).success;
- }
-
- return errno;
- },
-
- .MLINK => {
- var copy: [bun.MAX_PATH_BYTES]u8 = undefined;
- @memcpy(copy[0..dest.len], dest);
- copy[dest.len] = 0;
- var dest_copy = copy[0..dest.len :0];
- switch (Syscall.unlink(dest_copy).getErrno()) {
- .AGAIN, .INTR => continue,
- .NOENT => {
- if (args.force) {
- continue;
- }
-
- return errno;
- },
- .SUCCESS => continue,
- else => return errno,
- }
- },
- .SUCCESS => unreachable,
- else => return errno,
- }
- }
+ _ = flavor;
+ if (comptime Environment.isPosix) {
+ // We cannot use removefileat() on macOS because it does not handle write-protected files as expected.
+ if (args.recursive) {
+ // TODO: switch to an implementation which does not use any "unreachable"
+ std.fs.cwd().deleteTree(args.path.slice()) catch |err| {
+ const errno: E = switch (err) {
+ error.InvalidHandle => .BADF,
+ error.AccessDenied => .PERM,
+ error.FileTooBig => .FBIG,
+ error.SymLinkLoop => .LOOP,
+ error.ProcessFdQuotaExceeded => .NFILE,
+ error.NameTooLong => .NAMETOOLONG,
+ error.SystemFdQuotaExceeded => .MFILE,
+ error.SystemResources => .NOMEM,
+ error.ReadOnlyFileSystem => .ROFS,
+ error.FileSystem => .IO,
+ error.FileBusy => .BUSY,
+ error.DeviceBusy => .BUSY,
+
+ // One of the path components was not a directory.
+ // This error is unreachable if `sub_path` does not contain a path separator.
+ error.NotDir => .NOTDIR,
+ // On Windows, file paths must be valid Unicode.
+ error.InvalidUtf8 => .INVAL,
+
+ // On Windows, file paths cannot contain these characters:
+ // '/', '*', '?', '"', '<', '>', '|'
+ error.BadPathName => .INVAL,
+
+ else => .FAULT,
+ };
+ if (args.force) {
return Maybe(Return.Rm).success;
}
- } else if (comptime Environment.isLinux or Environment.isWindows) {
- if (args.recursive) {
- std.fs.cwd().deleteTree(args.path.slice()) catch |err| {
- const errno: E = switch (err) {
- error.InvalidHandle => .BADF,
- error.AccessDenied => .PERM,
- error.FileTooBig => .FBIG,
- error.SymLinkLoop => .LOOP,
- error.ProcessFdQuotaExceeded => .NFILE,
- error.NameTooLong => .NAMETOOLONG,
- error.SystemFdQuotaExceeded => .MFILE,
- error.SystemResources => .NOMEM,
- error.ReadOnlyFileSystem => .ROFS,
- error.FileSystem => .IO,
- error.FileBusy => .BUSY,
- error.DeviceBusy => .BUSY,
-
- // One of the path components was not a directory.
- // This error is unreachable if `sub_path` does not contain a path separator.
- error.NotDir => .NOTDIR,
- // On Windows, file paths must be valid Unicode.
- error.InvalidUtf8 => .INVAL,
-
- // On Windows, file paths cannot contain these characters:
- // '/', '*', '?', '"', '<', '>', '|'
- error.BadPathName => .INVAL,
-
- else => .FAULT,
- };
- if (args.force) {
- return Maybe(Return.Rm).success;
- }
- return Maybe(Return.Rm){
- .err = bun.sys.Error.fromCode(errno, .unlink),
- };
- };
- return Maybe(Return.Rm).success;
- }
- }
-
- if (comptime Environment.isPosix) {
- var dest = args.path.osPath(&this.sync_error_buf);
- std.os.unlinkZ(dest) catch |er| {
- // empircally, it seems to return AccessDenied when the
- // file is actually a directory on macOS.
- if (args.recursive and
- (er == error.IsDir or er == error.NotDir or er == error.AccessDenied))
- {
- std.os.rmdirZ(dest) catch |err| {
- if (args.force) {
- return Maybe(Return.Rm).success;
- }
-
- const code: E = switch (err) {
- error.AccessDenied => .PERM,
- error.SymLinkLoop => .LOOP,
- error.NameTooLong => .NAMETOOLONG,
- error.SystemResources => .NOMEM,
- error.ReadOnlyFileSystem => .ROFS,
- error.FileBusy => .BUSY,
- error.FileNotFound => .NOENT,
- error.InvalidUtf8 => .INVAL,
- error.BadPathName => .INVAL,
- else => .FAULT,
- };
+ return Maybe(Return.Rm){
+ .err = bun.sys.Error.fromCode(errno, .unlink),
+ };
+ };
+ return Maybe(Return.Rm).success;
+ }
- return .{
- .err = bun.sys.Error.fromCode(
- code,
- .rmdir,
- ),
- };
- };
-
- return Maybe(Return.Rm).success;
- }
+ var dest = args.path.sliceZ(&this.sync_error_buf);
+ std.os.unlinkZ(dest) catch |er| {
+ // empircally, it seems to return AccessDenied when the
+ // file is actually a directory on macOS.
+ if (args.recursive and
+ (er == error.IsDir or er == error.NotDir or er == error.AccessDenied))
+ {
+ std.os.rmdirZ(dest) catch |err| {
if (args.force) {
return Maybe(Return.Rm).success;
}
- {
- const code: E = switch (er) {
- error.AccessDenied => .PERM,
- error.SymLinkLoop => .LOOP,
- error.NameTooLong => .NAMETOOLONG,
- error.SystemResources => .NOMEM,
- error.ReadOnlyFileSystem => .ROFS,
- error.FileBusy => .BUSY,
- error.InvalidUtf8 => .INVAL,
- error.BadPathName => .INVAL,
- error.FileNotFound => .NOENT,
- else => .FAULT,
- };
+ const code: E = switch (err) {
+ error.AccessDenied => .PERM,
+ error.SymLinkLoop => .LOOP,
+ error.NameTooLong => .NAMETOOLONG,
+ error.SystemResources => .NOMEM,
+ error.ReadOnlyFileSystem => .ROFS,
+ error.FileBusy => .BUSY,
+ error.FileNotFound => .NOENT,
+ error.InvalidUtf8 => .INVAL,
+ error.BadPathName => .INVAL,
+ else => .FAULT,
+ };
- return .{
- .err = bun.sys.Error.fromCode(
- code,
- .unlink,
- ),
- };
- }
+ return .{
+ .err = bun.sys.Error.fromCode(
+ code,
+ .rmdir,
+ ),
+ };
};
return Maybe(Return.Rm).success;
}
- if (comptime Environment.isWindows) {
- var dest = args.path.osPath(&this.sync_error_buf);
- std.os.windows.DeleteFile(dest, .{
- .dir = null,
- .remove_dir = brk: {
- const file_attrs = std.os.windows.GetFileAttributesW(dest.ptr) catch |err| {
- if (args.force) {
- return Maybe(Return.Rm).success;
- }
+ if (args.force) {
+ return Maybe(Return.Rm).success;
+ }
- const code: E = switch (err) {
- error.FileNotFound => .NOENT,
- error.PermissionDenied => .PERM,
- else => .INVAL,
- };
+ {
+ const code: E = switch (er) {
+ error.AccessDenied => .PERM,
+ error.SymLinkLoop => .LOOP,
+ error.NameTooLong => .NAMETOOLONG,
+ error.SystemResources => .NOMEM,
+ error.ReadOnlyFileSystem => .ROFS,
+ error.FileBusy => .BUSY,
+ error.InvalidUtf8 => .INVAL,
+ error.BadPathName => .INVAL,
+ error.FileNotFound => .NOENT,
+ else => .FAULT,
+ };
- return .{
- .err = bun.sys.Error.fromCode(
- code,
- .unlink,
- ),
- };
- };
- // TODO: check FILE_ATTRIBUTE_INVALID
- break :brk (file_attrs & std.os.windows.FILE_ATTRIBUTE_DIRECTORY) != 0;
- },
- }) catch |er| {
- // empircally, it seems to return AccessDenied when the
- // file is actually a directory on macOS.
+ return .{
+ .err = bun.sys.Error.fromCode(
+ code,
+ .unlink,
+ ),
+ };
+ }
+ };
+ return Maybe(Return.Rm).success;
+ }
+
+ if (comptime Environment.isWindows) {
+ var dest = args.path.osPath(&this.sync_error_buf);
+ std.os.windows.DeleteFile(dest, .{
+ .dir = null,
+ .remove_dir = brk: {
+ const file_attrs = std.os.windows.GetFileAttributesW(dest.ptr) catch |err| {
if (args.force) {
return Maybe(Return.Rm).success;
}
- {
- const code: E = switch (er) {
- error.FileNotFound => .NOENT,
- error.AccessDenied => .PERM,
- error.NameTooLong => .INVAL,
- error.FileBusy => .BUSY,
- error.NotDir => .NOTDIR,
- error.IsDir => .ISDIR,
- error.DirNotEmpty => .INVAL,
- error.NetworkNotFound => .NOENT,
- else => .UNKNOWN,
- };
+ const code: E = switch (err) {
+ error.FileNotFound => .NOENT,
+ error.PermissionDenied => .PERM,
+ else => .INVAL,
+ };
- return .{
- .err = bun.sys.Error.fromCode(
- code,
- .unlink,
- ),
- };
- }
+ return .{
+ .err = bun.sys.Error.fromCode(
+ code,
+ .unlink,
+ ),
+ };
};
+ // TODO: check FILE_ATTRIBUTE_INVALID
+ break :brk (file_attrs & std.os.windows.FILE_ATTRIBUTE_DIRECTORY) != 0;
+ },
+ }) catch |er| {
+ // empircally, it seems to return AccessDenied when the
+ // file is actually a directory on macOS.
+ if (args.force) {
return Maybe(Return.Rm).success;
}
- },
- else => {},
- }
- return Maybe(Return.Rm).todo;
+ {
+ const code: E = switch (er) {
+ error.FileNotFound => .NOENT,
+ error.AccessDenied => .PERM,
+ error.NameTooLong => .INVAL,
+ error.FileBusy => .BUSY,
+ error.NotDir => .NOTDIR,
+ error.IsDir => .ISDIR,
+ error.DirNotEmpty => .INVAL,
+ error.NetworkNotFound => .NOENT,
+ else => .UNKNOWN,
+ };
+
+ return .{
+ .err = bun.sys.Error.fromCode(
+ code,
+ .unlink,
+ ),
+ };
+ }
+ };
+
+ return Maybe(Return.Rm).success;
+ }
}
pub fn stat(this: *NodeFS, args: Arguments.Stat, comptime flavor: Flavor) Maybe(Return.Stat) {
if (comptime Environment.isWindows) {
@@ -5199,38 +4820,26 @@ pub const NodeFS = struct {
}
pub fn symlink(this: *NodeFS, args: Arguments.Symlink, comptime flavor: Flavor) Maybe(Return.Symlink) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Symlink).todo;
}
var to_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
- switch (comptime flavor) {
- .sync => {
- return Syscall.symlink(
- args.old_path.sliceZ(&this.sync_error_buf),
- args.new_path.sliceZ(&to_buf),
- );
- },
- else => {},
- }
-
- return Maybe(Return.Symlink).todo;
+ return Syscall.symlink(
+ args.old_path.sliceZ(&this.sync_error_buf),
+ args.new_path.sliceZ(&to_buf),
+ );
}
fn _truncate(this: *NodeFS, path: PathLike, len: JSC.WebCore.Blob.SizeType, comptime flavor: Flavor) Maybe(Return.Truncate) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Truncate).todo;
}
- switch (comptime flavor) {
- .sync => {
- return Maybe(Return.Truncate).errno(C.truncate(path.sliceZ(&this.sync_error_buf), len)) orelse
- Maybe(Return.Truncate).success;
- },
- else => {},
- }
-
- return Maybe(Return.Truncate).todo;
+ return Maybe(Return.Truncate).errno(C.truncate(path.sliceZ(&this.sync_error_buf), len)) orelse
+ Maybe(Return.Truncate).success;
}
pub fn truncate(this: *NodeFS, args: Arguments.Truncate, comptime flavor: Flavor) Maybe(Return.Truncate) {
return switch (args.path) {
@@ -5246,19 +4855,13 @@ pub const NodeFS = struct {
};
}
pub fn unlink(this: *NodeFS, args: Arguments.Unlink, comptime flavor: Flavor) Maybe(Return.Unlink) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Unlink).todo;
}
- switch (comptime flavor) {
- .sync => {
- return Maybe(Return.Unlink).errnoSysP(system.unlink(args.path.sliceZ(&this.sync_error_buf)), .unlink, args.path.slice()) orelse
- Maybe(Return.Unlink).success;
- },
- else => {},
- }
-
- return Maybe(Return.Unlink).todo;
+ return Maybe(Return.Unlink).errnoSysP(system.unlink(args.path.sliceZ(&this.sync_error_buf)), .unlink, args.path.slice()) orelse
+ Maybe(Return.Unlink).success;
}
pub fn watchFile(_: *NodeFS, args: Arguments.WatchFile, comptime flavor: Flavor) Maybe(Return.WatchFile) {
std.debug.assert(flavor == .sync);
@@ -5283,6 +4886,7 @@ pub const NodeFS = struct {
return Maybe(Return.UnwatchFile).todo;
}
pub fn utimes(this: *NodeFS, args: Arguments.Utimes, comptime flavor: Flavor) Maybe(Return.Utimes) {
+ _ = flavor;
if (comptime Environment.isWindows) {
return Maybe(Return.Utimes).todo;
}
@@ -5300,21 +4904,13 @@ pub const NodeFS = struct {
},
};
- switch (comptime flavor) {
- // futimes uses the syscall version
- // we use libc because here, not for a good reason
- // just missing from the linux syscall interface in zig and I don't want to modify that right now
- .sync => return if (Maybe(Return.Utimes).errnoSysP(std.c.utimes(args.path.sliceZ(&this.sync_error_buf), &times), .utimes, args.path.slice())) |err|
- err
- else
- Maybe(Return.Utimes).success,
- else => {},
- }
-
- return Maybe(Return.Utimes).todo;
+ return if (Maybe(Return.Utimes).errnoSysP(std.c.utimes(args.path.sliceZ(&this.sync_error_buf), &times), .utimes, args.path.slice())) |err|
+ err
+ else
+ Maybe(Return.Utimes).success;
}
- pub fn lutimes(this: *NodeFS, args: Arguments.Lutimes, comptime flavor: Flavor) Maybe(Return.Lutimes) {
+ pub fn lutimes(this: *NodeFS, args: Arguments.Lutimes, comptime _: Flavor) Maybe(Return.Lutimes) {
if (comptime Environment.isWindows) {
return Maybe(Return.Lutimes).todo;
}
@@ -5332,18 +4928,10 @@ pub const NodeFS = struct {
},
};
- switch (comptime flavor) {
- // futimes uses the syscall version
- // we use libc because here, not for a good reason
- // just missing from the linux syscall interface in zig and I don't want to modify that right now
- .sync => return if (Maybe(Return.Lutimes).errnoSysP(C.lutimes(args.path.sliceZ(&this.sync_error_buf), &times), .lutimes, args.path.slice())) |err|
- err
- else
- Maybe(Return.Lutimes).success,
- else => {},
- }
-
- return Maybe(Return.Lutimes).todo;
+ return if (Maybe(Return.Lutimes).errnoSysP(C.lutimes(args.path.sliceZ(&this.sync_error_buf), &times), .lutimes, args.path.slice())) |err|
+ err
+ else
+ Maybe(Return.Lutimes).success;
}
pub fn watch(_: *NodeFS, args: Arguments.Watch, comptime _: Flavor) Maybe(Return.Watch) {
if (comptime Environment.isWindows) {
diff --git a/src/bun.js/node/node_fs_binding.zig b/src/bun.js/node/node_fs_binding.zig
index b3866b557..967acbe53 100644
--- a/src/bun.js/node/node_fs_binding.zig
+++ b/src/bun.js/node/node_fs_binding.zig
@@ -67,6 +67,7 @@ fn callSync(comptime FunctionEnum: NodeFSFunctionEnum) NodeFSFunction {
args,
comptime Flavor.sync,
);
+
switch (result) {
.err => |err| {
globalObject.throwValue(JSC.JSValue.c(err.toJS(globalObject)));
@@ -108,14 +109,6 @@ fn call(comptime FunctionEnum: NodeFSFunctionEnum) NodeFSFunction {
globalObject: *JSC.JSGlobalObject,
callframe: *JSC.CallFrame,
) callconv(.C) JSC.JSValue {
- switch (comptime FunctionEnum) {
- .readdir, .lstat, .stat, .readFile, .realpath, .copyFile, .cp => {},
- else => {
- globalObject.throw("Not implemented yet", .{});
- return .zero;
- },
- }
-
var arguments = callframe.arguments(8);
var slice = ArgumentsSlice.init(globalObject.bunVM(), arguments.ptr[0..arguments.len]);
@@ -142,57 +135,12 @@ fn call(comptime FunctionEnum: NodeFSFunctionEnum) NodeFSFunction {
// TODO: handle globalObject.throwValue
- if (comptime FunctionEnum == .readdir) {
- return JSC.Node.AsyncReaddirTask.create(globalObject, args, slice.vm, slice.arena);
- }
-
- if (comptime FunctionEnum == .readFile) {
- return JSC.Node.AsyncReadFileTask.create(globalObject, args, slice.vm, slice.arena);
- }
-
- if (comptime FunctionEnum == .realpath) {
- return JSC.Node.AsyncRealpathTask.create(globalObject, args, slice.vm, slice.arena);
- }
-
- if (comptime FunctionEnum == .stat or FunctionEnum == .lstat) {
- return JSC.Node.AsyncStatTask.create(globalObject, args, slice.vm, FunctionEnum == .lstat, slice.arena);
- }
-
- if (comptime FunctionEnum == .copyFile) {
- return JSC.Node.AsyncCopyFileTask.create(globalObject, args, slice.vm, slice.arena);
- }
-
+ const Task = @field(JSC.Node.Async, @tagName(FunctionEnum));
if (comptime FunctionEnum == .cp) {
- return JSC.Node.AsyncCpTask.create(globalObject, args, slice.vm, slice.arena);
+ return Task.create(globalObject, args, globalObject.bunVM(), slice.arena);
+ } else {
+ return Task.create(globalObject, args, globalObject.bunVM());
}
-
- // defer {
- // for (arguments.len) |arg| {
- // JSC.C.JSValueUnprotect(ctx, arg);
- // }
- // slice.arena.deinit();
- // }
-
- // const args = if (comptime Arguments != void)
- // Arguments.fromJS(ctx, &slice, exception)
- // else
- // Arguments{};
- // if (exception.* != null) return null;
-
- // const result: Maybe(Result) = Function(this, comptime Flavor.sync, args);
- // switch (result) {
- // .err => |err| {
- // exception.* = err.toJS(ctx);
- // return null;
- // },
- // .result => |res| {
- // return switch (comptime Result) {
- // void => JSC.JSValue.jsUndefined().asRef(),
- // else => res.toJS(ctx),
- // };
- // },
- // }
- // unreachable;
}
};
return NodeBindingClosure.bind;
diff --git a/src/bun.js/node/node_fs_constant.zig b/src/bun.js/node/node_fs_constant.zig
index 0d8ec66c5..75211723d 100644
--- a/src/bun.js/node/node_fs_constant.zig
+++ b/src/bun.js/node/node_fs_constant.zig
@@ -6,8 +6,9 @@ fn get(comptime name: []const u8) comptime_int {
return if (@hasDecl(std.os.O, name))
return @field(std.os.O, name)
else
- return 0;
+ @compileError("Unknown Constant: " ++ name);
}
+
pub const Constants = struct {
// File Access Constants
/// Constant for fs.access(). File is visible to the calling process.
@@ -41,16 +42,15 @@ pub const Constants = struct {
};
/// Constant for fs.copyFile. Flag indicating the destination file should not be overwritten if it already exists.
- pub const COPYFILE_EXCL: i32 = 1 << Copyfile.exclusive;
-
+ pub const COPYFILE_EXCL: i32 = Copyfile.exclusive;
///
/// Constant for fs.copyFile. copy operation will attempt to create a copy-on-write reflink.
/// If the underlying platform does not support copy-on-write, then a fallback copy mechanism is used.
- pub const COPYFILE_FICLONE: i32 = 1 << Copyfile.clone;
+ pub const COPYFILE_FICLONE: i32 = Copyfile.clone;
///
/// Constant for fs.copyFile. Copy operation will attempt to create a copy-on-write reflink.
/// If the underlying platform does not support copy-on-write, then the operation will fail with an error.
- pub const COPYFILE_FICLONE_FORCE: i32 = 1 << Copyfile.force;
+ pub const COPYFILE_FICLONE_FORCE: i32 = Copyfile.force;
// File Open Constants
/// Constant for fs.open(). Flag indicating to open a file for read-only access.
pub const O_RDONLY = std.os.O.RDONLY;
@@ -142,64 +142,3 @@ pub const Constants = struct {
/// this flag is ignored.
pub const UV_FS_O_FILEMAP = 49152;
};
-
-// Due to zig's format support max 32 arguments, we need to split
-// here.
-const constants_string_format1 =
- \\var constants = {{
- \\ F_OK: {d},
- \\ R_OK: {d},
- \\ W_OK: {d},
- \\ X_OK: {d},
- \\ COPYFILE_EXCL: {d},
- \\ COPYFILE_FICLONE: {d},
- \\ COPYFILE_FICLONE_FORCE: {d},
- \\ O_RDONLY: {d},
- \\ O_WRONLY: {d},
- \\ O_RDWR: {d},
- \\ O_CREAT: {d},
- \\ O_EXCL: {d},
- \\ O_NOCTTY: {d},
- \\ O_TRUNC: {d},
- \\ O_APPEND: {d},
- \\ O_DIRECTORY: {d},
- \\ O_NOATIME: {d},
- \\ O_NOFOLLOW: {d},
- \\ O_SYNC: {d},
- \\ O_DSYNC: {d},
-;
-const constants_string_format2 =
- \\ O_SYMLINK: {s},
- \\ O_DIRECT: {d},
- \\ O_NONBLOCK: {d},
- \\ S_IFMT: {d},
- \\ S_IFREG: {d},
- \\ S_IFDIR: {d},
- \\ S_IFCHR: {d},
- \\ S_IFBLK: {d},
- \\ S_IFIFO: {d},
- \\ S_IFLNK: {d},
- \\ S_IFSOCK: {d},
- \\ S_IRWXU: {d},
- \\ S_IRUSR: {d},
- \\ S_IWUSR: {d},
- \\ S_IXUSR: {d},
- \\ S_IRWXG: {d},
- \\ S_IRGRP: {d},
- \\ S_IWGRP: {d},
- \\ S_IXGRP: {d},
- \\ S_IRWXO: {d},
- \\ S_IROTH: {d},
- \\ S_IWOTH: {d},
- \\ S_IXOTH: {d},
- \\ UV_FS_O_FILEMAP: {d}
- \\}};
- \\
-;
-
-const constants_string1 = std.fmt.comptimePrint(constants_string_format1, .{ Constants.F_OK, Constants.R_OK, Constants.W_OK, Constants.X_OK, Constants.COPYFILE_EXCL, Constants.COPYFILE_FICLONE, Constants.COPYFILE_FICLONE_FORCE, Constants.O_RDONLY, Constants.O_WRONLY, Constants.O_RDWR, Constants.O_CREAT, Constants.O_EXCL, Constants.O_NOCTTY, Constants.O_TRUNC, Constants.O_APPEND, Constants.O_DIRECTORY, Constants.O_NOATIME, Constants.O_NOFOLLOW, Constants.O_SYNC, Constants.O_DSYNC });
-
-const constants_string2 =
- std.fmt.comptimePrint(constants_string_format2, .{ if (@TypeOf(Constants.O_SYMLINK) == void) "undefined" else std.fmt.comptimePrint("{}", .{Constants.O_SYMLINK}), Constants.O_DIRECT, Constants.O_NONBLOCK, Constants.S_IFMT, Constants.S_IFREG, Constants.S_IFDIR, Constants.S_IFCHR, Constants.S_IFBLK, Constants.S_IFIFO, Constants.S_IFLNK, Constants.S_IFSOCK, Constants.S_IRWXU, Constants.S_IRUSR, Constants.S_IWUSR, Constants.S_IXUSR, Constants.S_IRWXG, Constants.S_IRGRP, Constants.S_IWGRP, Constants.S_IXGRP, Constants.S_IRWXO, Constants.S_IROTH, Constants.S_IWOTH, Constants.S_IXOTH, Constants.UV_FS_O_FILEMAP });
-
-pub const constants_string = constants_string1 ++ constants_string2;
diff --git a/src/bun.js/node/node_fs_stat_watcher.zig b/src/bun.js/node/node_fs_stat_watcher.zig
index c2690c200..158a08ff7 100644
--- a/src/bun.js/node/node_fs_stat_watcher.zig
+++ b/src/bun.js/node/node_fs_stat_watcher.zig
@@ -97,7 +97,7 @@ pub const StatWatcherScheduler = struct {
prev = next;
} else {
if (this.head.load(.Monotonic) == null) {
- this.timer.?.deinit();
+ this.timer.?.deinit(false);
this.timer = null;
// The scheduler is not deinit here, but it will get reused.
}
@@ -198,7 +198,7 @@ pub const StatWatcher = struct {
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Arguments {
const vm = ctx.vm();
- const path = PathLike.fromJS(ctx, arguments, exception) orelse {
+ const path = PathLike.fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception) orelse {
if (exception.* == null) {
JSC.throwInvalidArguments(
"filename must be a string or TypedArray",
diff --git a/src/bun.js/node/node_os.zig b/src/bun.js/node/node_os.zig
index 07dec1c7d..ae8f527ce 100644
--- a/src/bun.js/node/node_os.zig
+++ b/src/bun.js/node/node_os.zig
@@ -531,6 +531,9 @@ pub const Os = struct {
addr_data[3], addr_data[4], addr_data[5],
}) catch unreachable;
interface.put(globalThis, JSC.ZigString.static("mac"), JSC.ZigString.init(mac).withEncoding().toValueGC(globalThis));
+ } else {
+ const mac = "00:00:00:00:00:00";
+ interface.put(globalThis, JSC.ZigString.static("mac"), JSC.ZigString.init(mac).withEncoding().toValueGC(globalThis));
}
}
diff --git a/src/bun.js/node/path_watcher.zig b/src/bun.js/node/path_watcher.zig
index 4f44a68ff..e00451a38 100644
--- a/src/bun.js/node/path_watcher.zig
+++ b/src/bun.js/node/path_watcher.zig
@@ -286,17 +286,8 @@ pub const PathWatcherManager = struct {
if (!(path.len == 1 and entry_point[0] == '/')) {
path = path[entry_point.len..];
- if (path.len == 0) {
- while (path.len > 0) {
- if (bun.strings.startsWithChar(path, '/')) {
- path = path[1..];
- break;
- } else {
- path = path[1..];
- }
- }
- } else {
- // Skip forward slash
+ // Skip leading slash
+ if (bun.strings.startsWithChar(path, '/')) {
path = path[1..];
}
}
diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig
index 35daea52c..96d1a00ef 100644
--- a/src/bun.js/node/types.zig
+++ b/src/bun.js/node/types.zig
@@ -315,6 +315,89 @@ pub const StringOrBunStringOrBuffer = union(enum) {
}
};
+pub const SliceWithUnderlyingStringOrBuffer = union(enum) {
+ SliceWithUnderlyingString: bun.SliceWithUnderlyingString,
+ buffer: Buffer,
+
+ pub fn toThreadSafe(this: *@This()) void {
+ switch (this.*) {
+ .SliceWithUnderlyingString => this.SliceWithUnderlyingString.toThreadSafe(),
+ else => {},
+ }
+ }
+
+ pub fn toJS(this: *SliceWithUnderlyingStringOrBuffer, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.C.JSValueRef {
+ return switch (this) {
+ .SliceWithUnderlyingStringOrBuffer => {
+ defer {
+ this.SliceWithUnderlyingString.deinit();
+ this.SliceWithUnderlyingString.underlying = bun.String.empty;
+ this.SliceWithUnderlyingString.utf8 = .{};
+ }
+
+ return this.SliceWithUnderlyingString.underlying.toJS(ctx);
+ },
+ .buffer => this.buffer.toJSObjectRef(ctx, exception),
+ };
+ }
+
+ pub fn slice(this: *const SliceWithUnderlyingStringOrBuffer) []const u8 {
+ return switch (this.*) {
+ .SliceWithUnderlyingString => this.SliceWithUnderlyingString.slice(),
+ .buffer => this.buffer.slice(),
+ };
+ }
+
+ pub fn deinit(this: *const SliceWithUnderlyingStringOrBuffer) void {
+ switch (this.*) {
+ .SliceWithUnderlyingString => |*str| {
+ str.deinit();
+ },
+ else => {},
+ }
+ }
+
+ pub fn deinitAndUnprotect(this: *const SliceWithUnderlyingStringOrBuffer) void {
+ switch (this.*) {
+ .SliceWithUnderlyingString => |*str| {
+ str.deinit();
+ },
+ .buffer => |buffer| {
+ buffer.buffer.value.unprotect();
+ },
+ }
+ }
+
+ pub fn fromJS(global: *JSC.JSGlobalObject, allocator: std.mem.Allocator, value: JSC.JSValue, exception: JSC.C.ExceptionRef) ?SliceWithUnderlyingStringOrBuffer {
+ _ = exception;
+ return switch (value.jsType()) {
+ JSC.JSValue.JSType.String, JSC.JSValue.JSType.StringObject, JSC.JSValue.JSType.DerivedStringObject, JSC.JSValue.JSType.Object => {
+ var str = bun.String.tryFromJS(value, global) orelse return null;
+ str.ref();
+ return SliceWithUnderlyingStringOrBuffer{ .SliceWithUnderlyingString = str.toSlice(allocator) };
+ },
+
+ .ArrayBuffer,
+ .Int8Array,
+ .Uint8Array,
+ .Uint8ClampedArray,
+ .Int16Array,
+ .Uint16Array,
+ .Int32Array,
+ .Uint32Array,
+ .Float32Array,
+ .Float64Array,
+ .BigInt64Array,
+ .BigUint64Array,
+ .DataView,
+ => SliceWithUnderlyingStringOrBuffer{
+ .buffer = Buffer.fromArrayBuffer(global, value),
+ },
+ else => null,
+ };
+ }
+};
+
/// Like StringOrBuffer but actually returns a Node.js Buffer
pub const StringOrNodeBuffer = union(Tag) {
string: string,
@@ -401,6 +484,20 @@ pub const SliceOrBuffer = union(Tag) {
}
}
+ pub fn toThreadSafe(this: *SliceOrBuffer) void {
+ var buffer: ?Buffer = null;
+ if (this.* == .buffer) {
+ buffer = this.buffer;
+ this.buffer.buffer.value.ensureStillAlive();
+ }
+ defer {
+ if (buffer) |buf| {
+ buf.buffer.value.unprotect();
+ }
+ }
+ this.ensureCloned(bun.default_allocator) catch unreachable;
+ }
+
pub const Tag = enum { string, buffer };
pub fn slice(this: SliceOrBuffer) []const u8 {
@@ -650,6 +747,10 @@ pub const PathLike = union(Tag) {
if (this.* == .slice_with_underlying_string) {
this.slice_with_underlying_string.toThreadSafe();
}
+
+ if (this.* == .buffer) {
+ this.buffer.buffer.value.protect();
+ }
}
pub fn deinitAndUnprotect(this: *const PathLike) void {
@@ -722,7 +823,7 @@ pub const PathLike = union(Tag) {
}
pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?PathLike {
- return fromJSWithAllocator(ctx, arguments, arguments.arena.allocator(), exception);
+ return fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception);
}
pub fn fromJSWithAllocator(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, allocator: std.mem.Allocator, exception: JSC.C.ExceptionRef) ?PathLike {
const arg = arguments.next() orelse return null;
@@ -801,11 +902,7 @@ pub const Valid = struct {
pub fn pathSlice(zig_str: JSC.ZigString.Slice, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) bool {
switch (zig_str.len) {
- 0 => {
- JSC.throwInvalidArguments("Invalid path string: can't be empty", .{}, ctx, exception);
- return false;
- },
- 1...bun.MAX_PATH_BYTES => return true,
+ 0...bun.MAX_PATH_BYTES => return true,
else => {
// TODO: should this be an EINVAL?
JSC.throwInvalidArguments(
@@ -823,11 +920,7 @@ pub const Valid = struct {
pub fn pathStringLength(len: usize, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) bool {
switch (len) {
- 0 => {
- JSC.throwInvalidArguments("Invalid path string: can't be empty", .{}, ctx, exception);
- return false;
- },
- 1...bun.MAX_PATH_BYTES => return true,
+ 0...bun.MAX_PATH_BYTES => return true,
else => {
// TODO: should this be an EINVAL?
JSC.throwInvalidArguments(
@@ -2120,6 +2213,8 @@ pub const Path = struct {
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
if (args_len == 0) return JSC.ZigString.init("").toValue(globalThis);
var arena = @import("root").bun.ArenaAllocator.init(heap_allocator);
+ defer arena.deinit();
+
var arena_allocator = arena.allocator();
var stack_fallback_allocator = std.heap.stackFallback(
((32 * @sizeOf(string)) + 1024),
@@ -2127,18 +2222,27 @@ pub const Path = struct {
);
var allocator = stack_fallback_allocator.get();
- defer arena.deinit();
var buf: [bun.MAX_PATH_BYTES]u8 = undefined;
+ var count: usize = 0;
var to_join = allocator.alloc(string, args_len) catch unreachable;
for (args_ptr[0..args_len], 0..) |arg, i| {
const zig_str: JSC.ZigString = arg.getZigString(globalThis);
to_join[i] = zig_str.toSlice(allocator).slice();
+ count += to_join[i].len;
+ }
+
+ var buf_to_use: []u8 = &buf;
+ if (count * 2 >= buf.len) {
+ buf_to_use = allocator.alloc(u8, count * 2) catch {
+ globalThis.throwOutOfMemory();
+ return .zero;
+ };
}
const out = if (!isWindows)
- PathHandler.joinStringBuf(&buf, to_join, .posix)
+ PathHandler.joinStringBuf(buf_to_use, to_join, .posix)
else
- PathHandler.joinStringBuf(&buf, to_join, .windows);
+ PathHandler.joinStringBuf(buf_to_use, to_join, .windows);
var str = bun.String.create(out);
defer str.deref();
diff --git a/src/bun.js/rare_data.zig b/src/bun.js/rare_data.zig
index 44e482049..c9d742d96 100644
--- a/src/bun.js/rare_data.zig
+++ b/src/bun.js/rare_data.zig
@@ -39,6 +39,32 @@ mime_types: ?bun.HTTP.MimeType.Map = null,
node_fs_stat_watcher_scheduler: ?*StatWatcherScheduler = null,
+listening_sockets_for_watch_mode: std.ArrayListUnmanaged(bun.FileDescriptor) = .{},
+listening_sockets_for_watch_mode_lock: bun.Lock = bun.Lock.init(),
+
+pub fn addListeningSocketForWatchMode(this: *RareData, socket: bun.FileDescriptor) void {
+ this.listening_sockets_for_watch_mode_lock.lock();
+ defer this.listening_sockets_for_watch_mode_lock.unlock();
+ this.listening_sockets_for_watch_mode.append(bun.default_allocator, socket) catch {};
+}
+
+pub fn removeListeningSocketForWatchMode(this: *RareData, socket: bun.FileDescriptor) void {
+ this.listening_sockets_for_watch_mode_lock.lock();
+ defer this.listening_sockets_for_watch_mode_lock.unlock();
+ if (std.mem.indexOfScalar(bun.FileDescriptor, this.listening_sockets_for_watch_mode.items, socket)) |i| {
+ _ = this.listening_sockets_for_watch_mode.swapRemove(i);
+ }
+}
+
+pub fn closeAllListenSocketsForWatchMode(this: *RareData) void {
+ this.listening_sockets_for_watch_mode_lock.lock();
+ defer this.listening_sockets_for_watch_mode_lock.unlock();
+ for (this.listening_sockets_for_watch_mode.items) |socket| {
+ _ = Syscall.close(socket);
+ }
+ this.listening_sockets_for_watch_mode = .{};
+}
+
pub fn hotMap(this: *RareData, allocator: std.mem.Allocator) *HotMap {
if (this.hot_map == null) {
this.hot_map = HotMap.init(allocator);
diff --git a/src/bun.js/scripts/create_hash_table b/src/bun.js/scripts/create_hash_table
index e2645b429..bd604ceaa 100755
--- a/src/bun.js/scripts/create_hash_table
+++ b/src/bun.js/scripts/create_hash_table
@@ -5,7 +5,7 @@
# (c) 2000-2002 by Harri Porten <porten@kde.org> and
# David Faure <faure@kde.org>
# Modified (c) 2004 by Nikolas Zimmermann <wildfox@kde.org>
-# Copyright (C) 2007-2022 Apple Inc. All rights reserved.
+# Copyright (C) 2007-2023 Apple Inc. All rights reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -24,6 +24,7 @@
use strict;
use warnings;
+use Math::BigInt;
use Getopt::Long qw(:config pass_through);
my $file = shift @ARGV or die("Must provide source file as final argument.");
@@ -33,7 +34,6 @@ open(IN, $file) or die "No such file $file";
my @keys = ();
my @attrs = ();
my @values = ();
-my @hashes = ();
my @table = ();
my @links = ();
@@ -46,11 +46,13 @@ my $pefectHashSize;
my $compactSize;
my $compactHashSizeMask;
my $banner = 0;
-sub calcPerfectHashSize();
-sub calcCompactHashSize();
+my $mask64 = 2**64 - 1;
+my $mask32 = 2**32 - 1;
+sub calcPerfectHashSize($);
+sub calcCompactHashSize($);
sub output();
sub jsc_ucfirst($);
-sub hashValue($);
+sub hashValue($$);
while (<IN>) {
chomp;
@@ -64,16 +66,11 @@ while (<IN>) {
print STDERR "WARNING: \@begin without table name, skipping $_\n";
}
} elsif (/^\@end\s*$/ && $inside) {
- calcPerfectHashSize();
- calcCompactHashSize();
output();
@keys = ();
@attrs = ();
@values = ();
- @hashes = ();
- @table = ();
- @links = ();
$includeBuiltin = 0;
$inside = 0;
@@ -114,7 +111,6 @@ while (<IN>) {
} else {
push(@values, { "type" => "Lexer", "value" => $val });
}
- push(@hashes, hashValue($key));
} elsif ($inside) {
die "invalid data {" . $_ . "}";
}
@@ -147,13 +143,14 @@ sub ceilingToPowerOf2
return $powerOf2;
}
-sub calcPerfectHashSize()
+sub calcPerfectHashSize($)
{
+ my ($isMac) = @_;
tableSizeLoop:
for ($pefectHashSize = ceilingToPowerOf2(scalar @keys); ; $pefectHashSize += $pefectHashSize) {
my @table = ();
foreach my $key (@keys) {
- my $h = hashValue($key) % $pefectHashSize;
+ my $h = hashValue($key, $isMac) % $pefectHashSize;
next tableSizeLoop if $table[$h];
$table[$h] = 1;
}
@@ -166,8 +163,9 @@ sub leftShift($$) {
return (($value << $distance) & 0xFFFFFFFF);
}
-sub calcCompactHashSize()
+sub calcCompactHashSize($)
{
+ my ($isMac) = @_;
my $compactHashSize = ceilingToPowerOf2(2 * @keys);
$compactHashSizeMask = $compactHashSize - 1;
$compactSize = $compactHashSize;
@@ -176,7 +174,7 @@ sub calcCompactHashSize()
my $i = 0;
foreach my $key (@keys) {
my $depth = 0;
- my $h = hashValue($key) % $compactHashSize;
+ my $h = hashValue($key, $isMac) % $compactHashSize;
while (defined($table[$h])) {
if (defined($links[$h])) {
$h = $links[$h];
@@ -194,60 +192,222 @@ sub calcCompactHashSize()
}
}
+sub avalancheBits($) {
+ my ($value) = @_;
+
+ $value &= $mask32;
+
+ # Force "avalanching" of lower 32 bits
+ $value ^= leftShift($value, 3);
+ $value += ($value >> 5);
+ $value = ($value & $mask32);
+ $value ^= (leftShift($value, 2) & $mask32);
+ $value += ($value >> 15);
+ $value = $value & $mask32;
+ $value ^= (leftShift($value, 10) & $mask32);
+
+ return $value;
+}
+
+sub maskTop8BitsAndAvoidZero($) {
+ my ($value) = @_;
+
+ $value &= $mask32;
+
+ # Save 8 bits for StringImpl to use as flags.
+ $value &= 0xffffff;
+
+ # This avoids ever returning a hash code of 0, since that is used to
+ # signal "hash not computed yet". Setting the high bit maintains
+ # reasonable fidelity to a hash code of 0 because it is likely to yield
+ # exactly 0 when hash lookup masks out the high bits.
+ $value = (0x80000000 >> 8) if ($value == 0);
+
+ return $value;
+}
+
# Paul Hsieh's SuperFastHash
# http://www.azillionmonkeys.com/qed/hash.html
-sub hashValue($) {
- my @chars = split(/ */, $_[0]);
-
- # This hash is designed to work on 16-bit chunks at a time. But since the normal case
- # (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they
- # were 16-bit chunks, which should give matching results
-
- my $EXP2_32 = 4294967296;
-
- my $hash = 0x9e3779b9;
- my $l = scalar @chars; #I wish this was in Ruby --- Maks
- my $rem = $l & 1;
- $l = $l >> 1;
-
- my $s = 0;
-
- # Main loop
- for (; $l > 0; $l--) {
- $hash += ord($chars[$s]);
- my $tmp = leftShift(ord($chars[$s+1]), 11) ^ $hash;
- $hash = (leftShift($hash, 16)% $EXP2_32) ^ $tmp;
- $s += 2;
- $hash += $hash >> 11;
- $hash %= $EXP2_32;
- }
-
- # Handle end case
- if ($rem != 0) {
- $hash += ord($chars[$s]);
- $hash ^= (leftShift($hash, 11)% $EXP2_32);
- $hash += $hash >> 17;
- }
-
- # Force "avalanching" of final 127 bits
- $hash ^= leftShift($hash, 3);
- $hash += ($hash >> 5);
- $hash = ($hash% $EXP2_32);
- $hash ^= (leftShift($hash, 2)% $EXP2_32);
- $hash += ($hash >> 15);
- $hash = $hash% $EXP2_32;
- $hash ^= (leftShift($hash, 10)% $EXP2_32);
-
- # Save 8 bits for StringImpl to use as flags.
- $hash &= 0xffffff;
-
- # This avoids ever returning a hash code of 0, since that is used to
- # signal "hash not computed yet". Setting the high bit maintains
- # reasonable fidelity to a hash code of 0 because it is likely to yield
- # exactly 0 when hash lookup masks out the high bits.
- $hash = (0x80000000 >> 8) if ($hash == 0);
-
- return $hash;
+sub superFastHash {
+ my @chars = @_;
+
+ # This hash is designed to work on 16-bit chunks at a time. But since the normal case
+ # (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they
+ # were 16-bit chunks, which should give matching results
+
+ my $hash = 0x9e3779b9;
+ my $l = scalar @chars; #I wish this was in Ruby --- Maks
+ my $rem = $l & 1;
+ $l = $l >> 1;
+
+ my $s = 0;
+
+ # Main loop
+ for (; $l > 0; $l--) {
+ $hash += ord($chars[$s]);
+ my $tmp = leftShift(ord($chars[$s+1]), 11) ^ $hash;
+ $hash = (leftShift($hash, 16) & $mask32) ^ $tmp;
+ $s += 2;
+ $hash += $hash >> 11;
+ $hash &= $mask32;
+ }
+
+ # Handle end case
+ if ($rem != 0) {
+ $hash += ord($chars[$s]);
+ $hash ^= (leftShift($hash, 11) & $mask32);
+ $hash += $hash >> 17;
+ }
+
+ $hash = avalancheBits($hash);
+ return maskTop8BitsAndAvoidZero($hash);
+}
+
+sub uint64_add($$) {
+ my ($a, $b) = @_;
+ my $sum = $a + $b;
+ return $sum & $mask64;
+}
+
+sub uint64_multi($$) {
+ my ($a, $b) = @_;
+ my $product = $a * $b;
+ return $product & $mask64;
+}
+
+sub wymum($$) {
+ my ($A, $B) = @_;
+
+ my $ha = $A >> 32;
+ my $hb = $B >> 32;
+ my $la = $A & $mask32;
+ my $lb = $B & $mask32;
+ my $hi;
+ my $lo;
+ my $rh = uint64_multi($ha, $hb);
+ my $rm0 = uint64_multi($ha, $lb);
+ my $rm1 = uint64_multi($hb, $la);
+ my $rl = uint64_multi($la, $lb);
+ my $t = uint64_add($rl, ($rm0 << 32));
+ my $c = int($t < $rl);
+
+ $lo = uint64_add($t, ($rm1 << 32));
+ $c += int($lo < $t);
+ $hi = uint64_add($rh, uint64_add(($rm0 >> 32), uint64_add(($rm1 >> 32), $c)));
+
+ return ($lo, $hi);
+};
+
+sub wymix($$) {
+ my ($A, $B) = @_;
+ ($A, $B) = wymum($A, $B);
+ return $A ^ $B;
+}
+
+sub convert32BitTo64Bit($) {
+ my ($v) = @_;
+ my ($mask1) = 281470681808895; # 0x0000_ffff_0000_ffff
+ $v = ($v | ($v << 16)) & $mask1;
+ my ($mask2) = 71777214294589695; # 0x00ff_00ff_00ff_00ff
+ return ($v | ($v << 8)) & $mask2;
+}
+
+sub convert16BitTo32Bit($) {
+ my ($v) = @_;
+ return ($v | ($v << 8)) & 0x00ff_00ff;
+}
+
+sub wyhash {
+ # https://github.com/wangyi-fudan/wyhash
+ my @chars = @_;
+ my $charCount = scalar @chars;
+ my $byteCount = $charCount << 1;
+ my $charIndex = 0;
+ my $seed = 0;
+ my @secret = ( 11562461410679940143, 16646288086500911323, 10285213230658275043, 6384245875588680899 );
+ my $move1 = (($byteCount >> 3) << 2) >> 1;
+
+ $seed ^= wymix($seed ^ $secret[0], $secret[1]);
+ my $a = 0;
+ my $b = 0;
+
+ local *c2i = sub {
+ my ($i) = @_;
+ return ord($chars[$i]);
+ };
+
+ local *wyr8 = sub {
+ my ($i) = @_;
+ my $v = c2i($i) | (c2i($i + 1) << 8) | (c2i($i + 2) << 16) | (c2i($i + 3) << 24);
+ return convert32BitTo64Bit($v);
+ };
+
+ local *wyr4 = sub {
+ my ($i) = @_;
+ my $v = c2i($i) | (c2i($i + 1) << 8);
+ return convert16BitTo32Bit($v);
+ };
+
+ local *wyr2 = sub {
+ my ($i) = @_;
+ return c2i($i) << 16;
+ };
+
+ if ($byteCount <= 16) {
+ if ($byteCount >= 4) {
+ $a = (wyr4($charIndex) << 32) | wyr4($charIndex + $move1);
+ $charIndex = $charIndex + $charCount - 2;
+ $b = (wyr4($charIndex) << 32) | wyr4($charIndex - $move1);
+ } elsif ($byteCount > 0) {
+ $a = wyr2($charIndex);
+ $b = 0;
+ } else {
+ $a = $b = 0;
+ }
+ } else {
+ my $i = $byteCount;
+ if ($i > 48) {
+ my $see1 = $seed;
+ my $see2 = $seed;
+ do {
+ $seed = wymix(wyr8($charIndex) ^ $secret[1], wyr8($charIndex + 4) ^ $seed);
+ $see1 = wymix(wyr8($charIndex + 8) ^ $secret[2], wyr8($charIndex + 12) ^ $see1);
+ $see2 = wymix(wyr8($charIndex + 16) ^ $secret[3], wyr8($charIndex + 20) ^ $see2);
+ $charIndex += 24;
+ $i -= 48;
+ } while ($i > 48);
+ $seed ^= $see1 ^ $see2;
+ }
+ while ($i > 16) {
+ $seed = wymix(wyr8($charIndex) ^ $secret[1], wyr8($charIndex + 4) ^ $seed);
+ $i -= 16;
+ $charIndex += 8;
+ }
+ my $move2 = $i >> 1;
+ $a = wyr8($charIndex + $move2 - 8);
+ $b = wyr8($charIndex + $move2 - 4);
+ }
+ $a ^= $secret[1];
+ $b ^= $seed;
+
+ ($a, $b) = wymum($a, $b);
+ my $hash = wymix($a ^ $secret[0] ^ $byteCount, $b ^ $secret[1]) & $mask32;
+
+ return maskTop8BitsAndAvoidZero($hash);
+}
+
+sub hashValue($$) {
+ my ($string, $isMac) = @_;
+ my @chars = split(/ */, $string);
+ my $charCount = scalar @chars;
+ if ($isMac) {
+ if ($charCount <= 48) {
+ return superFastHash(@chars);
+ }
+ return wyhash(@chars);
+ } else {
+ return superFastHash(@chars);
+ }
}
sub output() {
@@ -267,81 +427,110 @@ sub output() {
print "\n";
print "namespace JSC {\n";
print "\n";
- if ($compactSize != 0) {
- print "static const struct CompactHashIndex ${nameIndex}\[$compactSize\] = {\n";
- for (my $i = 0; $i < $compactSize; $i++) {
- my $T = -1;
- if (defined($table[$i])) { $T = $table[$i]; }
- my $L = -1;
- if (defined($links[$i])) { $L = $links[$i]; }
- print " { $T, $L },\n";
+
+ local *generateHashTableHelper = sub {
+ my ($isMac, $setToOldValues) = @_;
+ my $oldCompactSize = $compactSize;
+ my $oldCompactHashSizeMask = $compactHashSizeMask;
+ calcPerfectHashSize($isMac);
+ calcCompactHashSize($isMac);
+
+ my $hashTableString = "";
+
+ if ($compactSize != 0) {
+ $hashTableString .= "static const struct CompactHashIndex ${nameIndex}\[$compactSize\] = {\n";
+ for (my $i = 0; $i < $compactSize; $i++) {
+ my $T = -1;
+ if (defined($table[$i])) { $T = $table[$i]; }
+ my $L = -1;
+ if (defined($links[$i])) { $L = $links[$i]; }
+ $hashTableString .= " { $T, $L },\n";
+ }
+ } else {
+ # MSVC dislikes empty arrays.
+ $hashTableString .= "static const struct CompactHashIndex ${nameIndex}\[1\] = {\n";
+ $hashTableString .= " { 0, 0 }\n";
}
- } else {
- # MSVC dislikes empty arrays.
- print "static const struct CompactHashIndex ${nameIndex}\[1\] = {\n";
- print " { 0, 0 }\n";
- }
- print "};\n";
- print "\n";
+ $hashTableString .= "};\n";
+ $hashTableString .= "\n";
- my $packedSize = scalar @keys;
- if ($packedSize != 0) {
- print "static const struct HashTableValue ${nameEntries}\[$packedSize\] = {\n";
- } else {
- # MSVC dislikes empty arrays.
- print "static const struct HashTableValue ${nameEntries}\[1\] = {\n";
- print " { { }, 0, NoIntrinsic, { HashTableValue::End } }\n";
- }
- my $i = 0;
- foreach my $key (@keys) {
- my $typeTag = "";
- my $firstValue = "";
- my $secondValue = "";
- my $hasSecondValue = 1;
- my $intrinsic = "NoIntrinsic";
-
- if ($values[$i]{"type"} eq "PropertyAttribute::Function") {
- $typeTag = "NativeFunction";
- $firstValue = $values[$i]{"function"};
- $secondValue = $values[$i]{"params"};
- $intrinsic = $values[$i]{"intrinsic"};
- } elsif ($values[$i]{"type"} eq "PropertyAttribute::Property") {
- $typeTag = "GetterSetter";
- $firstValue = $values[$i]{"get"};
- $secondValue = $values[$i]{"put"};
- } elsif ($values[$i]{"type"} eq "Lexer") {
- $typeTag = "Lexer";
- $firstValue = $values[$i]{"value"};
- $hasSecondValue = 0;
- } elsif ($values[$i]{"type"} eq "PropertyAttribute::CellProperty" || $values[$i]{"type"} eq "PropertyAttribute::ClassStructure") {
- $typeTag = ($values[$i]{"type"} eq "PropertyAttribute::CellProperty") ? "LazyCellProperty" : "LazyClassStructure";
- $values[$i]{"property"} =~ /\A([a-zA-Z0-9_]+)::(.*)\Z/ or die;
- $firstValue = "OBJECT_OFFSETOF($1, $2)";
- $hasSecondValue = 0;
- } elsif ($values[$i]{"type"} eq "PropertyAttribute::PropertyCallback") {
- $typeTag = "LazyProperty";
- $firstValue = $values[$i]{"cback"};
- $hasSecondValue = 0;
+ my $packedSize = scalar @keys;
+ if ($packedSize != 0) {
+ $hashTableString .= "static const struct HashTableValue ${nameEntries}\[$packedSize\] = {\n";
+ } else {
+ # MSVC dislikes empty arrays.
+ $hashTableString .= "static const struct HashTableValue ${nameEntries}\[1\] = {\n";
+ $hashTableString .= " { { }, 0, NoIntrinsic, { HashTableValue::End } }\n";
}
- my $attributes = "PropertyAttribute::" . $attrs[$i];
- $attributes =~ s/\|/\|PropertyAttribute::/g;
- $attributes = "static_cast<unsigned>(" . $attributes . ")";
- if ($values[$i]{"type"} eq "PropertyAttribute::Function" && $firstValue eq "JSBuiltin") {
- $typeTag = "BuiltinGenerator";
- my $tableHead = $name;
- $tableHead =~ s/Table$//;
- print " { \"$key\"_s, (($attributes) & ~PropertyAttribute::Function) | PropertyAttribute::Builtin, $intrinsic, { HashTableValue::" . $typeTag . "Type, " . $tableHead . ucfirst($key) . "CodeGenerator, $secondValue } },\n";
+ my $i = 0;
+ foreach my $key (@keys) {
+ my $typeTag = "";
+ my $firstValue = "";
+ my $secondValue = "";
+ my $hasSecondValue = 1;
+ my $intrinsic = "NoIntrinsic";
+
+ if ($values[$i]{"type"} eq "PropertyAttribute::Function") {
+ $typeTag = "NativeFunction";
+ $firstValue = $values[$i]{"function"};
+ $secondValue = $values[$i]{"params"};
+ $intrinsic = $values[$i]{"intrinsic"};
+ } elsif ($values[$i]{"type"} eq "PropertyAttribute::Property") {
+ $typeTag = "GetterSetter";
+ $firstValue = $values[$i]{"get"};
+ $secondValue = $values[$i]{"put"};
+ } elsif ($values[$i]{"type"} eq "Lexer") {
+ $typeTag = "Lexer";
+ $firstValue = $values[$i]{"value"};
+ $hasSecondValue = 0;
+ } elsif ($values[$i]{"type"} eq "PropertyAttribute::CellProperty" || $values[$i]{"type"} eq "PropertyAttribute::ClassStructure") {
+ $typeTag = ($values[$i]{"type"} eq "PropertyAttribute::CellProperty") ? "LazyCellProperty" : "LazyClassStructure";
+ $values[$i]{"property"} =~ /\A([a-zA-Z0-9_]+)::(.*)\Z/ or die;
+ $firstValue = "OBJECT_OFFSETOF($1, $2)";
+ $hasSecondValue = 0;
+ } elsif ($values[$i]{"type"} eq "PropertyAttribute::PropertyCallback") {
+ $typeTag = "LazyProperty";
+ $firstValue = $values[$i]{"cback"};
+ $hasSecondValue = 0;
+ }
+
+ my $attributes = "PropertyAttribute::" . $attrs[$i];
+ $attributes =~ s/\|/\|PropertyAttribute::/g;
+ $attributes = "static_cast<unsigned>(" . $attributes . ")";
+ if ($values[$i]{"type"} eq "PropertyAttribute::Function" && $firstValue eq "JSBuiltin") {
+ $typeTag = "BuiltinGenerator";
+ my $tableHead = $name;
+ $tableHead =~ s/Table$//;
+ $hashTableString .= " { \"$key\"_s, (($attributes) & ~PropertyAttribute::Function) | PropertyAttribute::Builtin, $intrinsic, { HashTableValue::" . $typeTag . "Type, " . $tableHead . ucfirst($key) . "CodeGenerator, $secondValue } },\n";
+ }
+ else {
+ $hashTableString .= " { \"$key\"_s, $attributes, $intrinsic, { HashTableValue::" . $typeTag . "Type, $firstValue" . ($hasSecondValue ? ", " . $secondValue : "") . " } },\n";
+ }
+ $i++;
}
- else {
- print " { \"$key\"_s, $attributes, $intrinsic, { HashTableValue::" . $typeTag . "Type, $firstValue" . ($hasSecondValue ? ", " . $secondValue : "") . " } },\n";
+ $hashTableString .= "};\n";
+ $hashTableString .= "\n";
+ $hashTableString .= "static const struct HashTable $name =\n";
+ $hashTableString .= " \{ $packedSize, $compactHashSizeMask, $hasSetter, nullptr, $nameEntries, $nameIndex \};\n";
+ $hashTableString .= "\n";
+
+ @table = ();
+ @links = ();
+ if ($setToOldValues) {
+ $compactSize = $oldCompactSize;
+ $compactHashSizeMask = $oldCompactHashSizeMask;
}
- $i++;
+ return $hashTableString;
+ };
+
+ my $hashTableForMacOS = generateHashTableHelper(1, 1);
+ my $hashTableForIOS = generateHashTableHelper(0, 0);
+ my $hashTableToWrite = $hashTableForMacOS;
+ if ($hashTableForMacOS ne $hashTableForIOS) {
+ $hashTableToWrite = "#if PLATFORM(MAC)\n" . $hashTableForMacOS . "#else\n" . $hashTableForIOS . "#endif\n";
}
- print "};\n";
- print "\n";
- print "static const struct HashTable $name =\n";
- print " \{ $packedSize, $compactHashSizeMask, $hasSetter, nullptr, $nameEntries, $nameIndex \};\n";
- print "\n";
+ print $hashTableToWrite;
+
print "} // namespace JSC\n";
}
diff --git a/src/bun.js/scripts/generate-classes.ts b/src/bun.js/scripts/generate-classes.ts
index b6fbe0915..ae28f4fe5 100644
--- a/src/bun.js/scripts/generate-classes.ts
+++ b/src/bun.js/scripts/generate-classes.ts
@@ -335,7 +335,7 @@ function generatePrototype(typeName, obj) {
this->putDirect(vm, vm.propertyNames->${symbol}Symbol, JSFunction::create(vm, globalObject, 1, String("${symbol}"_s), ${protoSymbolName(
typeName,
symbol,
- )}Callback, ImplementationVisibility::Public), PropertyAttribute::Function | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | 0);`;
+ )}Callback, ImplementationVisibility::Public), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | 0);`;
}
return `
@@ -420,6 +420,7 @@ function generatePrototypeHeader(typename) {
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(${proto}, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -555,7 +556,7 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES ${name}::construct(JSC::JSGlobalObj
${className(typeName)}* instance = ${className(typeName)}::create(vm, globalObject, structure, ptr);
${
obj.estimatedSize
- ? `vm.heap.reportExtraMemoryAllocated(${symbolName(obj.name, "estimatedSize")}(instance->wrapped()));`
+ ? `vm.heap.reportExtraMemoryAllocated(instance, ${symbolName(obj.name, "estimatedSize")}(instance->wrapped()));`
: ""
}
@@ -1208,7 +1209,11 @@ extern "C" EncodedJSValue ${typeName}__create(Zig::GlobalObject* globalObject, v
auto &vm = globalObject->vm();
JSC::Structure* structure = globalObject->${className(typeName)}Structure();
${className(typeName)}* instance = ${className(typeName)}::create(vm, globalObject, structure, ptr);
- ${obj.estimatedSize ? `vm.heap.reportExtraMemoryAllocated(${symbolName(obj.name, "estimatedSize")}(ptr));` : ""}
+ ${
+ obj.estimatedSize
+ ? `vm.heap.reportExtraMemoryAllocated(instance, ${symbolName(obj.name, "estimatedSize")}(ptr));`
+ : ""
+ }
return JSValue::encode(instance);
}
@@ -1556,43 +1561,19 @@ ${[...exports]
function generateLazyClassStructureHeader(typeName, { klass = {}, proto = {} }) {
return `
- JSC::Structure* ${className(typeName)}Structure() { return m_${className(
+ JSC::Structure* ${className(typeName)}Structure() { return m_${className(
typeName,
)}.getInitializedOnMainThread(this); }
- JSC::JSObject* ${className(typeName)}Constructor() { return m_${className(
+ JSC::JSObject* ${className(typeName)}Constructor() { return m_${className(
typeName,
)}.constructorInitializedOnMainThread(this); }
- JSC::JSValue ${className(typeName)}Prototype() { return m_${className(
+ JSC::JSValue ${className(typeName)}Prototype() { return m_${className(
typeName,
)}.prototypeInitializedOnMainThread(this); }
JSC::LazyClassStructure m_${className(typeName)};
- bool has${className(typeName)}SetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_${className(typeName)}SetterValue;
- `.trim();
-}
-
-function generateLazyStructureHeader(typeName, { klass = {}, proto = {} }) {
- return `
- JSC::Structure* ${className(typeName)}Structure() { return m_${className(typeName)}.get(this); }
- JSC::LazyProperty<Zig::GlobalObject, Structure> m_${className(typeName)};
- bool has${className(typeName)}SetterValue { false };
- mutable JSC::WriteBarrier<JSC::Unknown> m_${className(typeName)}SetterValue;
`.trim();
}
-function generateLazyStructureImpl(typeName, { klass = {}, proto = {} }) {
- return `
- m_${className(typeName)}.initLater(
- [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) {
- auto *prototype = WebCore::${className(
- typeName,
- )}::createPrototype(init.vm, reinterpret_cast<Zig::GlobalObject*>(init.owner));
- init.set(WebCore::${className(typeName)}::createStructure(init.vm, init.owner, prototype));
- });
-
- `.trim();
-}
-
function generateLazyClassStructureImpl(typeName, { klass = {}, proto = {}, noConstructor = false }) {
return `
m_${className(typeName)}.initLater(
@@ -1685,7 +1666,7 @@ const GENERATED_CLASSES_IMPL_FOOTER = `
function initLazyClasses(initLaterFunctions) {
return `
-void GlobalObject::initGeneratedLazyClasses() {
+ALWAYS_INLINE void GlobalObject::initGeneratedLazyClasses() {
${initLaterFunctions.map(a => a.trim()).join("\n ")}
}
@@ -1698,14 +1679,7 @@ function visitLazyClasses(classes) {
template<typename Visitor>
void GlobalObject::visitGeneratedLazyClasses(GlobalObject *thisObject, Visitor& visitor)
{
- ${classes
- .map(
- a =>
- `thisObject->m_${className(a.name)}.visit(visitor); visitor.append(thisObject->m_${className(
- a.name,
- )}SetterValue);`,
- )
- .join("\n ")}
+ ${classes.map(a => `thisObject->m_${className(a.name)}.visit(visitor);`).join("\n ")}
}
`.trim();
diff --git a/src/bun.js/scripts/generate-jssink.js b/src/bun.js/scripts/generate-jssink.js
index ef60efbba..758b1863b 100644
--- a/src/bun.js/scripts/generate-jssink.js
+++ b/src/bun.js/scripts/generate-jssink.js
@@ -548,6 +548,7 @@ public:
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(${prototypeName}, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -580,6 +581,7 @@ class ${controllerPrototypeName} final : public JSC::JSNonFinalObject {
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(${controllerPrototypeName}, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -636,17 +638,19 @@ void JS${controllerName}::detach() {
auto readableStream = m_weakReadableStream.get();
auto onClose = m_onClose.get();
- m_onClose.clear();
if (readableStream && onClose) {
- JSC::JSGlobalObject *globalObject = this->globalObject();
auto callData = JSC::getCallData(onClose);
- JSC::MarkedArgumentBuffer arguments;
- arguments.append(readableStream);
- arguments.append(jsUndefined());
- call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ if(callData.type != JSC::CallData::Type::None) {
+ JSC::JSGlobalObject *globalObject = this->globalObject();
+ JSC::MarkedArgumentBuffer arguments;
+ arguments.append(readableStream);
+ arguments.append(jsUndefined());
+ call(globalObject, onClose, callData, JSC::jsUndefined(), arguments);
+ }
}
-
+
+ m_onClose.clear();
m_weakReadableStream.clear();
}
`;
diff --git a/src/bun.js/test/expect.zig b/src/bun.js/test/expect.zig
index 0d3ff663e..f83a9b194 100644
--- a/src/bun.js/test/expect.zig
+++ b/src/bun.js/test/expect.zig
@@ -1518,7 +1518,7 @@ pub const Expect = struct {
}
const expected_diff = std.math.pow(f64, 10, -precision) / 2;
- const actual_diff = std.math.fabs(received - expected);
+ const actual_diff = @abs(received - expected);
var pass = actual_diff < expected_diff;
const not = this.flags.not;
@@ -1697,7 +1697,7 @@ pub const Expect = struct {
const result: JSValue = result_.?;
var formatter = JSC.ZigConsoleClient.Formatter{ .globalThis = globalObject, .quote_strings = true };
- if (expected_value.isEmpty()) {
+ if (expected_value.isEmpty() or expected_value.isUndefined()) {
const signature_no_args = comptime getSignature("toThrow", "", true);
if (result.toError()) |err| {
const name = err.get(globalObject, "name") orelse JSValue.undefined;
@@ -1780,7 +1780,7 @@ pub const Expect = struct {
const signature = comptime getSignature("toThrow", "<green>expected<r>", false);
if (did_throw) {
- if (expected_value.isEmpty()) return thisValue;
+ if (expected_value.isEmpty() or expected_value.isUndefined()) return thisValue;
const result: JSValue = if (result_.?.toError()) |r|
r
@@ -1915,7 +1915,7 @@ pub const Expect = struct {
var formatter = JSC.ZigConsoleClient.Formatter{ .globalThis = globalObject, .quote_strings = true };
const received_line = "Received function did not throw\n";
- if (expected_value.isEmpty()) {
+ if (expected_value.isEmpty() or expected_value.isUndefined()) {
const fmt = comptime getSignature("toThrow", "", false) ++ "\n\n" ++ received_line;
if (Output.enable_ansi_colors) {
globalObject.throw(Output.prettyFmt(fmt, true), .{});
@@ -2649,6 +2649,83 @@ pub const Expect = struct {
return .zero;
}
+ pub fn toEqualIgnoringWhitespace(this: *Expect, globalThis: *JSGlobalObject, callFrame: *CallFrame) callconv(.C) JSValue {
+ defer this.postMatch(globalThis);
+
+ const thisValue = callFrame.this();
+ const _arguments = callFrame.arguments(1);
+ const arguments: []const JSValue = _arguments.ptr[0.._arguments.len];
+
+ if (arguments.len < 1) {
+ globalThis.throwInvalidArguments("toEqualIgnoringWhitespace() requires 1 argument", .{});
+ return .zero;
+ }
+
+ active_test_expectation_counter.actual += 1;
+
+ const expected = arguments[0];
+ const value: JSValue = this.getValue(globalThis, thisValue, "toEqualIgnoringWhitespace", "<green>expected<r>") orelse return .zero;
+
+ if (!expected.isString()) {
+ globalThis.throw("toEqualIgnoringWhitespace() requires argument to be a string", .{});
+ return .zero;
+ }
+
+ const not = this.flags.not;
+ var pass = value.isString() and expected.isString();
+
+ if (pass) {
+ var valueStr = value.toString(globalThis).toSlice(globalThis, default_allocator).slice();
+ var expectedStr = expected.toString(globalThis).toSlice(globalThis, default_allocator).slice();
+
+ var left: usize = 0;
+ var right: usize = 0;
+
+ // Skip leading whitespaces
+ while (left < valueStr.len and std.ascii.isWhitespace(valueStr[left])) left += 1;
+ while (right < expectedStr.len and std.ascii.isWhitespace(expectedStr[right])) right += 1;
+
+ while (left < valueStr.len and right < expectedStr.len) {
+ const left_char = valueStr[left];
+ const right_char = expectedStr[right];
+
+ if (left_char != right_char) {
+ pass = false;
+ break;
+ }
+
+ left += 1;
+ right += 1;
+
+ // Skip trailing whitespaces
+ while (left < valueStr.len and std.ascii.isWhitespace(valueStr[left])) left += 1;
+ while (right < expectedStr.len and std.ascii.isWhitespace(expectedStr[right])) right += 1;
+ }
+
+ if (left < valueStr.len or right < expectedStr.len) {
+ pass = false;
+ }
+ }
+
+ if (not) pass = !pass;
+ if (pass) return thisValue;
+
+ // handle failure
+ var formatter = JSC.ZigConsoleClient.Formatter{ .globalThis = globalThis, .quote_strings = true };
+ const expected_fmt = expected.toFmt(globalThis, &formatter);
+ const value_fmt = value.toFmt(globalThis, &formatter);
+
+ if (not) {
+ const fmt = comptime getSignature("toEqualIgnoringWhitespace", "<green>expected<r>", true) ++ "\n\n" ++ "Expected: not <green>{any}<r>\n" ++ "Received: <red>{any}<r>\n";
+ globalThis.throwPretty(fmt, .{ expected_fmt, value_fmt });
+ return .zero;
+ }
+
+ const fmt = comptime getSignature("toEqualIgnoringWhitespace", "<green>expected<r>", false) ++ "\n\n" ++ "Expected: <green>{any}<r>\n" ++ "Received: <red>{any}<r>\n";
+ globalThis.throwPretty(fmt, .{ expected_fmt, value_fmt });
+ return .zero;
+ }
+
pub fn toBeSymbol(this: *Expect, globalThis: *JSGlobalObject, callFrame: *CallFrame) callconv(.C) JSValue {
defer this.postMatch(globalThis);
@@ -3271,7 +3348,7 @@ pub const Expect = struct {
globalObject.throw(Output.prettyFmt(fmt, false), .{calls.toFmt(globalObject, &formatter)});
return .zero;
} else {
- const signature = comptime getSignature("toHaveBeenCalled", "", true);
+ const signature = comptime getSignature("toHaveBeenCalled", "", false);
const fmt = signature ++ "\n\nExpected <green>{any}<r>\n";
if (Output.enable_ansi_colors) {
globalObject.throw(Output.prettyFmt(fmt, true), .{calls.toFmt(globalObject, &formatter)});
@@ -3326,7 +3403,7 @@ pub const Expect = struct {
globalObject.throw(Output.prettyFmt(fmt, false), .{calls.toFmt(globalObject, &formatter)});
return .zero;
} else {
- const signature = comptime getSignature("toHaveBeenCalledTimes", "<green>expected<r>", true);
+ const signature = comptime getSignature("toHaveBeenCalledTimes", "<green>expected<r>", false);
const fmt = signature ++ "\n\nExpected <green>{any}<r>\n";
if (Output.enable_ansi_colors) {
globalObject.throw(Output.prettyFmt(fmt, true), .{calls.toFmt(globalObject, &formatter)});
@@ -3437,8 +3514,11 @@ pub const Expect = struct {
return ExpectStringMatching.call(globalObject, callFrame);
}
+ pub fn arrayContaining(globalObject: *JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSValue {
+ return ExpectArrayContaining.call(globalObject, callFrame);
+ }
+
pub const extend = notImplementedStaticFn;
- pub const arrayContaining = notImplementedStaticFn;
pub const assertions = notImplementedStaticFn;
pub const hasAssertions = notImplementedStaticFn;
pub const objectContaining = notImplementedStaticFn;
@@ -3621,6 +3701,43 @@ pub const ExpectAny = struct {
}
};
+pub const ExpectArrayContaining = struct {
+ pub usingnamespace JSC.Codegen.JSExpectArrayContaining;
+
+ pub fn finalize(
+ this: *ExpectArrayContaining,
+ ) callconv(.C) void {
+ VirtualMachine.get().allocator.destroy(this);
+ }
+
+ pub fn call(globalObject: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSValue {
+ const args = callFrame.arguments(1).slice();
+
+ if (args.len == 0 or !args[0].jsType().isArray()) {
+ const fmt = "<d>expect.<r>arrayContaining<d>(<r>array<d>)<r>\n\nExpected a array\n";
+ globalObject.throwPretty(fmt, .{});
+ return .zero;
+ }
+
+ const array_value = args[0];
+ const array_containing = globalObject.bunVM().allocator.create(ExpectArrayContaining) catch unreachable;
+
+ if (Jest.runner.?.pending_test == null) {
+ const err = globalObject.createErrorInstance("expect.arrayContaining() must be called in a test", .{});
+ err.put(globalObject, ZigString.static("name"), ZigString.init("TestNotRunningError").toValueGC(globalObject));
+ globalObject.throwValue(err);
+ return .zero;
+ }
+
+ const array_containing_js_value = array_containing.toJS(globalObject);
+ ExpectArrayContaining.arrayValueSetCached(array_containing_js_value, globalObject, array_value);
+
+ var vm = globalObject.bunVM();
+ vm.autoGarbageCollect();
+ return array_containing_js_value;
+ }
+};
+
/// JSValue.zero is used to indicate it was not a JSMockFunction
/// If there were no calls, it returns an empty JSArray*
extern fn JSMockFunction__getCalls(JSValue) JSValue;
diff --git a/src/bun.js/test/jest.classes.ts b/src/bun.js/test/jest.classes.ts
index d40acbf07..f10d9fb37 100644
--- a/src/bun.js/test/jest.classes.ts
+++ b/src/bun.js/test/jest.classes.ts
@@ -49,6 +49,18 @@ export default [
proto: {},
}),
define({
+ name: "ExpectArrayContaining",
+ construct: false,
+ noConstructor: true,
+ call: true,
+ finalize: true,
+ JSType: "0b11101110",
+ values: ["arrayValue"],
+ configurable: false,
+ klass: {},
+ proto: {},
+ }),
+ define({
name: "Expect",
construct: true,
call: true,
@@ -333,6 +345,10 @@ export default [
fn: "toBeWithin",
length: 2,
},
+ toEqualIgnoringWhitespace: {
+ fn: "toEqualIgnoringWhitespace",
+ length: 1,
+ },
toBeSymbol: {
fn: "toBeSymbol",
length: 0,
diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig
index f3c9ffa26..a95897414 100644
--- a/src/bun.js/test/jest.zig
+++ b/src/bun.js/test/jest.zig
@@ -793,14 +793,33 @@ pub const DescribeScope = struct {
current_test_id: TestRunner.Test.ID = 0,
value: JSValue = .zero,
done: bool = false,
- is_skip: bool = false,
skip_count: u32 = 0,
tag: Tag = .pass,
- pub fn isAllSkipped(this: *const DescribeScope) bool {
- if (this.is_skip) return true;
- const total = this.tests.items.len;
- return total > 0 and @as(usize, this.skip_count) >= total;
+ fn isWithinOnlyScope(this: *const DescribeScope) bool {
+ if (this.tag == .only) return true;
+ if (this.parent != null) return this.parent.?.isWithinOnlyScope();
+ return false;
+ }
+
+ fn isWithinSkipScope(this: *const DescribeScope) bool {
+ if (this.tag == .skip) return true;
+ if (this.parent != null) return this.parent.?.isWithinSkipScope();
+ return false;
+ }
+
+ fn isWithinTodoScope(this: *const DescribeScope) bool {
+ if (this.tag == .todo) return true;
+ if (this.parent != null) return this.parent.?.isWithinTodoScope();
+ return false;
+ }
+
+ pub fn shouldEvaluateScope(this: *const DescribeScope) bool {
+ if (this.tag == .skip or
+ this.tag == .todo) return false;
+ if (Jest.runner.?.only and this.tag == .only) return true;
+ if (this.parent != null) return this.parent.?.shouldEvaluateScope();
+ return true;
}
pub fn push(new: *DescribeScope) void {
@@ -1114,7 +1133,7 @@ pub const DescribeScope = struct {
var i: TestRunner.Test.ID = 0;
- if (!this.isAllSkipped()) {
+ if (this.shouldEvaluateScope()) {
if (this.runCallback(globalObject, .beforeAll)) |_| {
while (i < end) {
Jest.runner.?.reportFailure(i + this.test_id_start, source.path.text, tests[i].label, 0, 0, this);
@@ -1168,7 +1187,7 @@ pub const DescribeScope = struct {
return;
}
- if (!this.isAllSkipped()) {
+ if (this.shouldEvaluateScope()) {
// Run the afterAll callbacks, in reverse order
// unless there were no tests for this scope
if (this.execCallback(globalThis, .afterAll)) |err| {
@@ -1267,8 +1286,8 @@ pub const TestRunnerTask = struct {
var test_: TestScope = this.describe.tests.items[test_id];
describe.current_test_id = test_id;
- if (test_.func == .zero or (describe.is_skip and test_.tag != .only)) {
- var tag = if (describe.is_skip) describe.tag else test_.tag;
+ if (test_.func == .zero or !describe.shouldEvaluateScope()) {
+ var tag = if (!describe.shouldEvaluateScope()) describe.tag else test_.tag;
switch (tag) {
.todo => {
this.processTestResult(globalThis, .{ .todo = {} }, test_, test_id, describe);
@@ -1609,8 +1628,7 @@ inline fn createScope(
.label = label,
.parent = parent,
.file_id = parent.file_id,
- .tag = if (parent.is_skip) parent.tag else tag,
- .is_skip = is_skip or parent.is_skip,
+ .tag = tag,
};
return scope.run(globalThis, function, &.{});
@@ -1983,8 +2001,7 @@ fn eachBind(
.label = formattedLabel,
.parent = parent,
.file_id = parent.file_id,
- .tag = if (parent.is_skip) parent.tag else .pass,
- .is_skip = parent.is_skip,
+ .tag = .pass,
};
const ret = scope.run(globalThis, function, function_args);
diff --git a/src/bun.js/webcore.zig b/src/bun.js/webcore.zig
index 168c4339b..411d3ed2e 100644
--- a/src/bun.js/webcore.zig
+++ b/src/bun.js/webcore.zig
@@ -107,9 +107,11 @@ fn confirm(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callcon
// 6. Pause until the user responds either positively or negatively.
var stdin = std.io.getStdIn();
- var reader = stdin.reader();
+ var unbuffered_reader = stdin.reader();
+ var buffered = std.io.bufferedReader(unbuffered_reader);
+ var reader = buffered.reader();
- const first_byte = reader.readByte() catch {
+ var first_byte = reader.readByte() catch {
return .false;
};
@@ -122,13 +124,14 @@ fn confirm(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callcon
'y', 'Y' => {
const next_byte = reader.readByte() catch {
// They may have said yes, but the stdin is invalid.
+
return .false;
};
if (next_byte == '\n') {
// 8. If the user responded positively, return true;
// otherwise, the user responded negatively: return false.
- return .false;
+ return .true;
}
},
else => {},
diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig
index 54c37e679..f9699cffc 100644
--- a/src/bun.js/webcore/blob.zig
+++ b/src/bun.js/webcore/blob.zig
@@ -1040,7 +1040,10 @@ pub const Blob = struct {
break :brk result;
},
.err => |err| {
- return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis));
+ return JSC.JSPromise.rejectedPromiseValue(
+ globalThis,
+ err.withPath(pathlike.path.slice()).toJSC(globalThis),
+ );
},
}
unreachable;
@@ -1080,8 +1083,13 @@ pub const Blob = struct {
needs_async.* = true;
return .zero;
}
-
- return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis));
+ if (comptime !needs_open) {
+ return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis));
+ }
+ return JSC.JSPromise.rejectedPromiseValue(
+ globalThis,
+ err.withPath(pathlike.path.slice()).toJSC(globalThis),
+ );
},
}
}
@@ -1110,7 +1118,10 @@ pub const Blob = struct {
break :brk result;
},
.err => |err| {
- return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis));
+ return JSC.JSPromise.rejectedPromiseValue(
+ globalThis,
+ err.withPath(pathlike.path.slice()).toJSC(globalThis),
+ );
},
}
unreachable;
@@ -1145,7 +1156,13 @@ pub const Blob = struct {
needs_async.* = true;
return .zero;
}
- return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis));
+ if (comptime !needs_open) {
+ return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis));
+ }
+ return JSC.JSPromise.rejectedPromiseValue(
+ globalThis,
+ err.withPath(pathlike.path.slice()).toJSC(globalThis),
+ );
},
}
}
@@ -1680,6 +1697,7 @@ pub const Blob = struct {
read_completion: HTTPClient.NetworkThread.Completion = undefined,
read_len: SizeType = 0,
read_off: SizeType = 0,
+ read_eof: bool = false,
size: SizeType = 0,
buffer: []u8 = undefined,
task: HTTPClient.NetworkThread.Task = undefined,
@@ -1797,8 +1815,7 @@ pub const Blob = struct {
pub fn onRead(this: *ReadFile, completion: *HTTPClient.NetworkThread.Completion, result: AsyncIO.ReadError!usize) void {
defer this.doReadLoop();
-
- this.read_len = @as(SizeType, @truncate(result catch |err| {
+ const read_len = @as(SizeType, @truncate(result catch |err| {
if (@hasField(HTTPClient.NetworkThread.Completion, "result")) {
this.errno = AsyncIO.asError(-completion.result);
this.system_error = (bun.sys.Error{
@@ -1821,6 +1838,8 @@ pub const Blob = struct {
this.read_len = 0;
return;
}));
+ this.read_eof = read_len == 0;
+ this.read_len = read_len;
}
fn runAsync(this: *ReadFile, task: *ReadFileTask) void {
@@ -1930,7 +1949,7 @@ pub const Blob = struct {
this.read_off += this.read_len;
var remain = this.buffer[@min(this.read_off, @as(Blob.SizeType, @truncate(this.buffer.len)))..];
- if (remain.len > 0 and this.errno == null) {
+ if (remain.len > 0 and this.errno == null and !this.read_eof) {
this.doRead();
return;
}
@@ -2287,7 +2306,7 @@ pub const Blob = struct {
this.source_fd = 0;
}
- this.system_error = errno.toSystemError();
+ this.system_error = errno.withPath(this.destination_file_store.pathlike.path.slice()).toSystemError();
return AsyncIO.asError(errno.errno);
},
};
@@ -2737,17 +2756,7 @@ pub const Blob = struct {
value: JSC.JSValue,
global: *JSGlobalObject,
) JSC.JSValue {
- if (value.isError()) {
- return JSC.JSPromise.rejectedPromiseValue(global, value);
- }
-
- if (value.jsType() == .JSPromise)
- return value;
-
- return JSPromise.resolvedPromiseValue(
- global,
- value,
- );
+ return JSC.JSPromise.wrap(global, value);
}
pub fn getText(
@@ -3011,12 +3020,13 @@ pub const Blob = struct {
}
}
+ const offset = this.offset +| @as(SizeType, @intCast(relativeStart));
const len = @as(SizeType, @intCast(@max(relativeEnd -| relativeStart, 0)));
// This copies over the is_all_ascii flag
// which is okay because this will only be a <= slice
var blob = this.dupe();
- blob.offset = @as(SizeType, @intCast(relativeStart));
+ blob.offset = offset;
blob.size = len;
// infer the content type if it was not specified
@@ -3671,11 +3681,7 @@ pub const Blob = struct {
if (comptime lifetime != .temporary) this.setIsASCIIFlag(true);
}
- if (comptime lifetime == .temporary) {
- return ZigString.init(buf).toJSONObject(global);
- } else {
- return ZigString.init(buf).toJSONObject(global);
- }
+ return ZigString.init(buf).toJSONObject(global);
}
pub fn toFormDataWithBytes(this: *Blob, global: *JSGlobalObject, buf: []u8, comptime _: Lifetime) JSValue {
diff --git a/src/bun.js/webcore/body.zig b/src/bun.js/webcore/body.zig
index 621acc0b3..e38f03c08 100644
--- a/src/bun.js/webcore/body.zig
+++ b/src/bun.js/webcore/body.zig
@@ -51,7 +51,6 @@ const Request = JSC.WebCore.Request;
// https://developer.mozilla.org/en-US/docs/Web/API/Body
pub const Body = struct {
- init: Init = Init{ .headers = null, .status_code = 200 },
value: Value, // = Value.empty,
pub inline fn len(this: *const Body) Blob.SizeType {
@@ -68,7 +67,6 @@ pub const Body = struct {
pub fn clone(this: *Body, globalThis: *JSGlobalObject) Body {
return Body{
- .init = this.init.clone(globalThis),
.value = this.value.clone(globalThis),
};
}
@@ -79,19 +77,7 @@ pub const Body = struct {
try formatter.writeIndent(Writer, writer);
try writer.writeAll(comptime Output.prettyFmt("<r>bodyUsed<d>:<r> ", enable_ansi_colors));
formatter.printAs(.Boolean, Writer, writer, JSC.JSValue.jsBoolean(this.value == .Used), .BooleanObject, enable_ansi_colors);
- formatter.printComma(Writer, writer, enable_ansi_colors) catch unreachable;
- try writer.writeAll("\n");
- // if (this.init.headers) |headers| {
- // try formatter.writeIndent(Writer, writer);
- // try writer.writeAll("headers: ");
- // try headers.leak().writeFormat(formatter, writer, comptime enable_ansi_colors);
- // try writer.writeAll("\n");
- // }
-
- try formatter.writeIndent(Writer, writer);
- try writer.writeAll(comptime Output.prettyFmt("<r>status<d>:<r> ", enable_ansi_colors));
- formatter.printAs(.Double, Writer, writer, JSC.JSValue.jsNumber(this.init.status_code), .NumberObject, enable_ansi_colors);
if (this.value == .Blob) {
try formatter.printComma(Writer, writer, enable_ansi_colors);
try writer.writeAll("\n");
@@ -113,87 +99,9 @@ pub const Body = struct {
}
pub fn deinit(this: *Body, _: std.mem.Allocator) void {
- if (this.init.headers) |headers| {
- this.init.headers = null;
-
- headers.deref();
- }
this.value.deinit();
}
- pub const Init = struct {
- headers: ?*FetchHeaders = null,
- status_code: u16,
- method: Method = Method.GET,
-
- pub fn clone(this: Init, ctx: *JSGlobalObject) Init {
- var that = this;
- var headers = this.headers;
- if (headers) |head| {
- that.headers = head.cloneThis(ctx);
- }
-
- return that;
- }
-
- pub fn init(allocator: std.mem.Allocator, ctx: *JSGlobalObject, response_init: JSC.JSValue) !?Init {
- var result = Init{ .status_code = 200 };
-
- if (!response_init.isCell())
- return null;
-
- if (response_init.jsType() == .DOMWrapper) {
- // fast path: it's a Request object or a Response object
- // we can skip calling JS getters
- if (response_init.as(Request)) |req| {
- if (req.headers) |headers| {
- if (!headers.isEmpty()) {
- result.headers = headers.cloneThis(ctx);
- }
- }
-
- result.method = req.method;
- return result;
- }
-
- if (response_init.as(Response)) |req| {
- return req.body.init.clone(ctx);
- }
- }
-
- if (response_init.fastGet(ctx, .headers)) |headers| {
- if (headers.as(FetchHeaders)) |orig| {
- if (!orig.isEmpty()) {
- result.headers = orig.cloneThis(ctx);
- }
- } else {
- result.headers = FetchHeaders.createFromJS(ctx.ptr(), headers);
- }
- }
-
- if (response_init.fastGet(ctx, .status)) |status_value| {
- const number = status_value.coerceToInt64(ctx);
- if ((200 <= number and number < 600) or number == 101) {
- result.status_code = @as(u16, @truncate(@as(u32, @intCast(number))));
- } else {
- const err = ctx.createRangeErrorInstance("The status provided ({d}) must be 101 or in the range of [200, 599]", .{number});
- ctx.throwValue(err);
- return null;
- }
- }
-
- if (response_init.fastGet(ctx, .method)) |method_value| {
- var method_str = method_value.toSlice(ctx, allocator);
- defer method_str.deinit();
- if (method_str.len > 0) {
- result.method = Method.which(method_str.slice()) orelse .GET;
- }
- }
-
- return result;
- }
- };
-
pub const PendingValue = struct {
promise: ?JSValue = null,
readable: ?JSC.WebCore.ReadableStream = null,
@@ -466,7 +374,10 @@ pub const Body = struct {
JSC.markBinding(@src());
switch (this.*) {
- .Used, .Empty => {
+ .Used => {
+ return JSC.WebCore.ReadableStream.used(globalThis);
+ },
+ .Empty => {
return JSC.WebCore.ReadableStream.empty(globalThis);
},
.Null => {
@@ -493,6 +404,9 @@ pub const Body = struct {
if (locked.readable) |readable| {
return readable.value;
}
+ if (locked.promise != null) {
+ return JSC.WebCore.ReadableStream.used(globalThis);
+ }
var drain_result: JSC.WebCore.DrainResult = .{
.estimated_size = 0,
};
@@ -998,72 +912,12 @@ pub const Body = struct {
}
};
- pub fn @"404"(_: js.JSContextRef) Body {
- return Body{
- .init = Init{
- .headers = null,
- .status_code = 404,
- },
- .value = Value{ .Null = {} },
- };
- }
-
- pub fn @"200"(_: js.JSContextRef) Body {
- return Body{
- .init = Init{
- .status_code = 200,
- },
- .value = Value{ .Null = {} },
- };
- }
-
- pub fn extract(
- globalThis: *JSGlobalObject,
- value: JSValue,
- ) ?Body {
- return extractBody(
- globalThis,
- value,
- false,
- JSValue.zero,
- );
- }
-
- pub fn extractWithInit(
- globalThis: *JSGlobalObject,
- value: JSValue,
- init: JSValue,
- ) ?Body {
- return extractBody(
- globalThis,
- value,
- true,
- init,
- );
- }
-
// https://github.com/WebKit/webkit/blob/main/Source/WebCore/Modules/fetch/FetchBody.cpp#L45
- inline fn extractBody(
+ pub fn extract(
globalThis: *JSGlobalObject,
value: JSValue,
- comptime has_init: bool,
- init: JSValue,
) ?Body {
- var body = Body{
- .value = Value{ .Null = {} },
- .init = Init{ .headers = null, .status_code = 200 },
- };
- var allocator = getAllocator(globalThis);
-
- if (comptime has_init) {
- if (Init.init(allocator, globalThis, init)) |maybeInit| {
- if (maybeInit) |init_| {
- body.init = init_;
- }
- } else |_| {
- return null;
- }
- }
+ var body = Body{ .value = Value{ .Null = {} } };
body.value = Value.fromJS(globalThis, value) orelse return null;
if (body.value == .Blob)
@@ -1104,8 +958,7 @@ pub fn BodyMixin(comptime Type: type) type {
var body: *Body.Value = this.getBodyValue();
if (body.* == .Used) {
- // TODO: make this closed
- return JSC.WebCore.ReadableStream.empty(globalThis);
+ return JSC.WebCore.ReadableStream.used(globalThis);
}
return body.toReadableStream(globalThis);
@@ -1136,7 +989,9 @@ pub fn BodyMixin(comptime Type: type) type {
}
var blob = value.useAsAnyBlobAllowNonUTF8String();
- return JSC.JSPromise.wrap(globalObject, blob.toJSON(globalObject, .share));
+ const result = blob.toJSON(globalObject, .share);
+
+ return JSC.JSPromise.wrap(globalObject, result);
}
fn handleBodyAlreadyUsed(globalObject: *JSC.JSGlobalObject) JSValue {
diff --git a/src/bun.js/webcore/encoding.classes.ts b/src/bun.js/webcore/encoding.classes.ts
index 118dfd09e..7114f210e 100644
--- a/src/bun.js/webcore/encoding.classes.ts
+++ b/src/bun.js/webcore/encoding.classes.ts
@@ -16,6 +16,9 @@ export default [
fatal: {
getter: "getFatal",
},
+ ignoreBOM: {
+ getter: "getIgnoreBOM",
+ },
decode: {
fn: "decode",
diff --git a/src/bun.js/webcore/encoding.zig b/src/bun.js/webcore/encoding.zig
index 53933fdb7..18e70b261 100644
--- a/src/bun.js/webcore/encoding.zig
+++ b/src/bun.js/webcore/encoding.zig
@@ -559,6 +559,13 @@ pub const TextDecoder = struct {
remainder = remainder[1..];
continue;
},
+ // BOM handling
+ 0xFEFF => {
+ buffer.ensureTotalCapacity(allocator, 1) catch unreachable;
+ buffer.items.ptr[buffer.items.len] = remainder[0];
+ buffer.items.len += 1;
+ remainder = remainder[1..];
+ },
// Is this an unpaired low surrogate or four-digit hex escape?
else => {
@@ -629,8 +636,13 @@ pub const TextDecoder = struct {
},
EncodingLabel.@"UTF-8" => {
const toUTF16 = if (stream) strings.toUTF16Alloc else strings.toUTF16AllocNoTrim;
+ const moved_buffer_slice_8 = if (!this.ignore_bom and buffer_slice.len > 3 and std.mem.eql(u8, &[_]u8{ '\xEF', '\xBB', '\xBF' }, buffer_slice[0..3]))
+ buffer_slice[3..]
+ else
+ buffer_slice;
+
if (this.fatal) {
- if (toUTF16(default_allocator, buffer_slice, true)) |result_| {
+ if (toUTF16(default_allocator, moved_buffer_slice_8, true)) |result_| {
if (result_) |result| {
return ZigString.toExternalU16(result.ptr, result.len, globalThis);
}
@@ -649,7 +661,7 @@ pub const TextDecoder = struct {
}
}
} else {
- if (toUTF16(default_allocator, buffer_slice, false)) |result_| {
+ if (toUTF16(default_allocator, moved_buffer_slice_8, false)) |result_| {
if (result_) |result| {
return ZigString.toExternalU16(result.ptr, result.len, globalThis);
}
@@ -664,15 +676,20 @@ pub const TextDecoder = struct {
}
// Experiment: using mimalloc directly is slightly slower
- return ZigString.init(buffer_slice).toValueGC(globalThis);
+ return ZigString.init(moved_buffer_slice_8).toValueGC(globalThis);
},
EncodingLabel.@"UTF-16LE" => {
- if (std.mem.isAligned(@intFromPtr(buffer_slice.ptr), @alignOf([*]const u16))) {
- return this.decodeUTF16WithAlignment([]align(2) const u16, @as([]align(2) const u16, @alignCast(std.mem.bytesAsSlice(u16, buffer_slice))), globalThis);
+ const moved_buffer_slice_16 = if (!this.ignore_bom and buffer_slice.len > 2 and std.mem.eql(u8, &[_]u8{ '\xFF', '\xFE' }, buffer_slice[0..2]))
+ buffer_slice[2..]
+ else
+ buffer_slice;
+
+ if (std.mem.isAligned(@intFromPtr(moved_buffer_slice_16.ptr), @alignOf([*]const u16))) {
+ return this.decodeUTF16WithAlignment([]align(2) const u16, @as([]align(2) const u16, @alignCast(std.mem.bytesAsSlice(u16, moved_buffer_slice_16))), globalThis);
}
- return this.decodeUTF16WithAlignment([]align(1) const u16, std.mem.bytesAsSlice(u16, buffer_slice), globalThis);
+ return this.decodeUTF16WithAlignment([]align(1) const u16, std.mem.bytesAsSlice(u16, moved_buffer_slice_16), globalThis);
},
else => {
globalThis.throwInvalidArguments("TextDecoder.decode set to unsupported encoding", .{});
@@ -702,6 +719,9 @@ pub const TextDecoder = struct {
globalThis.throwInvalidArguments("Unsupported encoding label \"{s}\"", .{str.slice()});
return null;
}
+ } else if (arguments[0].isUndefined()) {
+ // default to utf-8
+ decoder.encoding = EncodingLabel.@"UTF-8";
} else {
globalThis.throwInvalidArguments("TextDecoder(encoding) label is invalid", .{});
return null;
@@ -745,7 +765,7 @@ pub const Encoder = struct {
export fn Bun__encoding__writeLatin1(input: [*]const u8, len: usize, to: [*]u8, to_len: usize, encoding: u8) usize {
return switch (@as(JSC.Node.Encoding, @enumFromInt(encoding))) {
.utf8 => writeU8(input, len, to, to_len, .utf8),
- .latin1 => writeU8(input, len, to, to_len, .ascii),
+ .latin1 => writeU8(input, len, to, to_len, .latin1),
.ascii => writeU8(input, len, to, to_len, .ascii),
.ucs2 => writeU8(input, len, to, to_len, .utf16le),
.utf16le => writeU8(input, len, to, to_len, .utf16le),
@@ -947,13 +967,13 @@ pub const Encoder = struct {
// if (comptime encoding.isBinaryToText()) {}
switch (comptime encoding) {
- .buffer => {
+ .buffer, .latin1 => {
const written = @min(len, to_len);
@memcpy(to_ptr[0..written], input[0..written]);
return written;
},
- .latin1, .ascii => {
+ .ascii => {
const written = @min(len, to_len);
var to = to_ptr[0..written];
diff --git a/src/bun.js/webcore/request.zig b/src/bun.js/webcore/request.zig
index fc38e1825..95f92145b 100644
--- a/src/bun.js/webcore/request.zig
+++ b/src/bun.js/webcore/request.zig
@@ -50,6 +50,7 @@ const InternalBlob = JSC.WebCore.InternalBlob;
const BodyMixin = JSC.WebCore.BodyMixin;
const Body = JSC.WebCore.Body;
const Blob = JSC.WebCore.Blob;
+const Response = JSC.WebCore.Response;
const body_value_pool_size: u16 = 256;
pub const BodyValueRef = bun.HiveRef(Body.Value, body_value_pool_size);
@@ -68,7 +69,7 @@ pub const Request = struct {
signal: ?*AbortSignal = null,
body: *BodyValueRef,
method: Method = Method.GET,
- uws_request: ?*uws.Request = null,
+ request_context: JSC.API.AnyRequestContext = JSC.API.AnyRequestContext.Null,
https: bool = false,
upgrader: ?*anyopaque = null,
@@ -89,7 +90,7 @@ pub const Request = struct {
pub fn getContentType(
this: *Request,
) ?ZigString.Slice {
- if (this.uws_request) |req| {
+ if (this.request_context.getRequest()) |req| {
if (req.header("content-type")) |value| {
return ZigString.Slice.fromUTF8NeverFree(value);
}
@@ -324,7 +325,7 @@ pub const Request = struct {
if (this.url.length() > 0)
return this.url.byteSlice().len;
- if (this.uws_request) |req| {
+ if (this.request_context.getRequest()) |req| {
const req_url = req.url();
if (req_url.len > 0 and req_url[0] == '/') {
if (req.header("host")) |host| {
@@ -351,7 +352,7 @@ pub const Request = struct {
pub fn ensureURL(this: *Request) !void {
if (!this.url.isEmpty()) return;
- if (this.uws_request) |req| {
+ if (this.request_context.getRequest()) |req| {
const req_url = req.url();
if (req_url.len > 0 and req_url[0] == '/') {
if (req.header("host")) |host| {
@@ -507,10 +508,9 @@ pub const Request = struct {
};
const values_to_try = values_to_try_[0 .. @as(usize, @intFromBool(!is_first_argument_a_url)) +
@as(usize, @intFromBool(arguments.len > 1 and arguments[1].isObject()))];
-
for (values_to_try) |value| {
const value_type = value.jsType();
-
+ const explicit_check = values_to_try.len == 2 and value_type == .FinalObject and values_to_try[1].jsType() == .DOMWrapper;
if (value_type == .DOMWrapper) {
if (value.as(Request)) |request| {
if (values_to_try.len == 1) {
@@ -543,12 +543,12 @@ pub const Request = struct {
if (value.as(JSC.WebCore.Response)) |response| {
if (!fields.contains(.method)) {
- req.method = response.body.init.method;
+ req.method = response.init.method;
fields.insert(.method);
}
if (!fields.contains(.headers)) {
- if (response.body.init.headers) |headers| {
+ if (response.init.headers) |headers| {
req.headers = headers.cloneThis(globalThis);
fields.insert(.headers);
}
@@ -608,9 +608,8 @@ pub const Request = struct {
}
if (!fields.contains(.signal)) {
- if (value.get(globalThis, "signal")) |signal_| {
+ if (value.getTruthy(globalThis, "signal")) |signal_| {
fields.insert(.signal);
-
if (AbortSignal.fromJS(signal_)) |signal| {
//Keep it alive
signal_.ensureStillAlive();
@@ -625,24 +624,26 @@ pub const Request = struct {
}
if (!fields.contains(.method) or !fields.contains(.headers)) {
- if (Body.Init.init(globalThis.allocator(), globalThis, value) catch null) |init| {
- if (!fields.contains(.method)) {
- req.method = init.method;
- fields.insert(.method);
+ if (Response.Init.init(globalThis.allocator(), globalThis, value) catch null) |init| {
+ if (!explicit_check or (explicit_check and value.fastGet(globalThis, .method) != null)) {
+ if (!fields.contains(.method)) {
+ req.method = init.method;
+ fields.insert(.method);
+ }
}
-
- if (init.headers) |headers| {
- if (!fields.contains(.headers)) {
- req.headers = headers;
- fields.insert(.headers);
- } else {
- headers.deref();
+ if (!explicit_check or (explicit_check and value.fastGet(globalThis, .headers) != null)) {
+ if (init.headers) |headers| {
+ if (!fields.contains(.headers)) {
+ req.headers = headers;
+ fields.insert(.headers);
+ } else {
+ headers.deref();
+ }
}
}
}
}
}
-
if (req.url.isEmpty()) {
globalThis.throw("Failed to construct 'Request': url is required.", .{});
req.finalizeWithoutDeinit();
@@ -724,7 +725,7 @@ pub const Request = struct {
globalThis: *JSC.JSGlobalObject,
) callconv(.C) JSC.JSValue {
if (this.headers == null) {
- if (this.uws_request) |req| {
+ if (this.request_context.getRequest()) |req| {
this.headers = FetchHeaders.createFromUWS(globalThis, req);
} else {
this.headers = FetchHeaders.createEmpty();
@@ -743,7 +744,7 @@ pub const Request = struct {
pub fn cloneHeaders(this: *Request, globalThis: *JSGlobalObject) ?*FetchHeaders {
if (this.headers == null) {
- if (this.uws_request) |uws_req| {
+ if (this.request_context.getRequest()) |uws_req| {
this.headers = FetchHeaders.createFromUWS(globalThis, uws_req);
}
}
diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig
index 0e80adfc4..f7ada2862 100644
--- a/src/bun.js/webcore/response.zig
+++ b/src/bun.js/webcore/response.zig
@@ -63,8 +63,8 @@ pub const Response = struct {
allocator: std.mem.Allocator,
body: Body,
+ init: Init,
url: bun.String = bun.String.empty,
- status_text: bun.String = bun.String.empty,
redirected: bool = false,
// We must report a consistent value for this
@@ -89,7 +89,7 @@ pub const Response = struct {
return this.reported_estimated_size orelse brk: {
this.reported_estimated_size = @as(
u63,
- @intCast(this.body.value.estimatedSize() + this.url.byteSlice().len + this.status_text.byteSlice().len + @sizeOf(Response)),
+ @intCast(this.body.value.estimatedSize() + this.url.byteSlice().len + this.init.status_text.byteSlice().len + @sizeOf(Response)),
);
break :brk this.reported_estimated_size.?;
};
@@ -104,11 +104,11 @@ pub const Response = struct {
pub fn getFetchHeaders(
this: *Response,
) ?*FetchHeaders {
- return this.body.init.headers;
+ return this.init.headers;
}
pub inline fn statusCode(this: *const Response) u16 {
- return this.body.init.status_code;
+ return this.init.status_code;
}
pub fn redirectLocation(this: *const Response) ?[]const u8 {
@@ -116,7 +116,7 @@ pub const Response = struct {
}
pub fn header(this: *const Response, name: JSC.FetchHeaders.HTTPHeaderName) ?[]const u8 {
- return if ((this.body.init.headers orelse return null).fastGet(name)) |str|
+ return if ((this.init.headers orelse return null).fastGet(name)) |str|
str.slice()
else
null;
@@ -146,14 +146,20 @@ pub const Response = struct {
try writer.writeAll("\n");
try formatter.writeIndent(Writer, writer);
- try writer.writeAll(comptime Output.prettyFmt("<r>headers<d>:<r> ", enable_ansi_colors));
- formatter.printAs(.Private, Writer, writer, this.getHeaders(formatter.globalThis), .DOMWrapper, enable_ansi_colors);
+ try writer.writeAll(comptime Output.prettyFmt("<r>status<d>:<r> ", enable_ansi_colors));
+ formatter.printAs(.Double, Writer, writer, JSC.JSValue.jsNumber(this.init.status_code), .NumberObject, enable_ansi_colors);
formatter.printComma(Writer, writer, enable_ansi_colors) catch unreachable;
try writer.writeAll("\n");
try formatter.writeIndent(Writer, writer);
try writer.writeAll(comptime Output.prettyFmt("<r>statusText<d>:<r> ", enable_ansi_colors));
- try writer.print(comptime Output.prettyFmt("<r>\"<b>{}<r>\"", enable_ansi_colors), .{this.status_text});
+ try writer.print(comptime Output.prettyFmt("<r>\"<b>{}<r>\"", enable_ansi_colors), .{this.init.status_text});
+ formatter.printComma(Writer, writer, enable_ansi_colors) catch unreachable;
+ try writer.writeAll("\n");
+
+ try formatter.writeIndent(Writer, writer);
+ try writer.writeAll(comptime Output.prettyFmt("<r>headers<d>:<r> ", enable_ansi_colors));
+ formatter.printAs(.Private, Writer, writer, this.getHeaders(formatter.globalThis), .DOMWrapper, enable_ansi_colors);
formatter.printComma(Writer, writer, enable_ansi_colors) catch unreachable;
try writer.writeAll("\n");
@@ -162,6 +168,7 @@ pub const Response = struct {
formatter.printAs(.Boolean, Writer, writer, JSC.JSValue.jsBoolean(this.redirected), .BooleanObject, enable_ansi_colors);
formatter.printComma(Writer, writer, enable_ansi_colors) catch unreachable;
try writer.writeAll("\n");
+
formatter.resetLine();
try this.body.writeFormat(Formatter, formatter, writer, enable_ansi_colors);
}
@@ -172,7 +179,7 @@ pub const Response = struct {
}
pub fn isOK(this: *const Response) bool {
- return this.body.init.status_code == 304 or (this.body.init.status_code >= 200 and this.body.init.status_code <= 299);
+ return this.init.status_code >= 200 and this.init.status_code <= 299;
}
pub fn getURL(
@@ -187,7 +194,7 @@ pub const Response = struct {
this: *Response,
globalThis: *JSC.JSGlobalObject,
) callconv(.C) JSC.JSValue {
- if (this.body.init.status_code < 200) {
+ if (this.init.status_code < 200) {
return ZigString.init("error").toValue(globalThis);
}
@@ -199,7 +206,7 @@ pub const Response = struct {
globalThis: *JSC.JSGlobalObject,
) callconv(.C) JSC.JSValue {
// https://developer.mozilla.org/en-US/docs/Web/API/Response/statusText
- return this.status_text.toJS(globalThis);
+ return this.init.status_text.toJS(globalThis);
}
pub fn getRedirected(
@@ -219,18 +226,18 @@ pub const Response = struct {
}
fn getOrCreateHeaders(this: *Response, globalThis: *JSC.JSGlobalObject) *FetchHeaders {
- if (this.body.init.headers == null) {
- this.body.init.headers = FetchHeaders.createEmpty();
+ if (this.init.headers == null) {
+ this.init.headers = FetchHeaders.createEmpty();
if (this.body.value == .Blob) {
const content_type = this.body.value.Blob.content_type;
if (content_type.len > 0) {
- this.body.init.headers.?.put("content-type", content_type, globalThis);
+ this.init.headers.?.put("content-type", content_type, globalThis);
}
}
}
- return this.body.init.headers.?;
+ return this.init.headers.?;
}
pub fn getHeaders(
@@ -262,8 +269,8 @@ pub const Response = struct {
new_response.* = Response{
.allocator = allocator,
.body = this.body.clone(globalThis),
+ .init = this.init.clone(globalThis),
.url = this.url.clone(),
- .status_text = this.status_text.clone(),
.redirected = this.redirected,
};
}
@@ -279,17 +286,16 @@ pub const Response = struct {
_: *JSC.JSGlobalObject,
) callconv(.C) JSC.JSValue {
// https://developer.mozilla.org/en-US/docs/Web/API/Response/status
- return JSValue.jsNumber(this.body.init.status_code);
+ return JSValue.jsNumber(this.init.status_code);
}
pub fn finalize(
this: *Response,
) callconv(.C) void {
- this.body.deinit(this.allocator);
-
var allocator = this.allocator;
- this.status_text.deref();
+ this.init.deinit(allocator);
+ this.body.deinit(allocator);
this.url.deref();
allocator.destroy(this);
@@ -348,7 +354,7 @@ pub const Response = struct {
pub fn getContentType(
this: *Response,
) ?ZigString.Slice {
- if (this.body.init.headers) |headers| {
+ if (this.init.headers) |headers| {
if (headers.fastGet(.ContentType)) |value| {
return value.toSlice(bun.default_allocator);
}
@@ -373,11 +379,11 @@ pub const Response = struct {
var response = Response{
.body = Body{
- .init = Body.Init{
- .status_code = 200,
- },
.value = .{ .Empty = {} },
},
+ .init = Response.Init{
+ .status_code = 200,
+ },
.allocator = getAllocator(globalThis),
.url = bun.String.empty,
};
@@ -409,10 +415,10 @@ pub const Response = struct {
if (args.nextEat()) |init| {
if (init.isUndefinedOrNull()) {} else if (init.isNumber()) {
- response.body.init.status_code = @as(u16, @intCast(@min(@max(0, init.toInt32()), std.math.maxInt(u16))));
+ response.init.status_code = @as(u16, @intCast(@min(@max(0, init.toInt32()), std.math.maxInt(u16))));
} else {
- if (Body.Init.init(getAllocator(globalThis), globalThis, init) catch null) |_init| {
- response.body.init = _init;
+ if (Response.Init.init(getAllocator(globalThis), globalThis, init) catch null) |_init| {
+ response.init = _init;
}
}
}
@@ -434,10 +440,10 @@ pub const Response = struct {
// var response = getAllocator(globalThis).create(Response) catch unreachable;
var response = Response{
+ .init = Response.Init{
+ .status_code = 302,
+ },
.body = Body{
- .init = Body.Init{
- .status_code = 302,
- },
.value = .{ .Empty = {} },
},
.allocator = getAllocator(globalThis),
@@ -455,17 +461,17 @@ pub const Response = struct {
if (args.nextEat()) |init| {
if (init.isUndefinedOrNull()) {} else if (init.isNumber()) {
- response.body.init.status_code = @as(u16, @intCast(@min(@max(0, init.toInt32()), std.math.maxInt(u16))));
+ response.init.status_code = @as(u16, @intCast(@min(@max(0, init.toInt32()), std.math.maxInt(u16))));
} else {
- if (Body.Init.init(getAllocator(globalThis), globalThis, init) catch null) |_init| {
- response.body.init = _init;
- response.body.init.status_code = 302;
+ if (Response.Init.init(getAllocator(globalThis), globalThis, init) catch null) |_init| {
+ response.init = _init;
+ response.init.status_code = 302;
}
}
}
- response.body.init.headers = response.getOrCreateHeaders(globalThis);
- var headers_ref = response.body.init.headers.?;
+ response.init.headers = response.getOrCreateHeaders(globalThis);
+ var headers_ref = response.init.headers.?;
headers_ref.put("location", url_string_slice.slice(), globalThis);
var ptr = response.allocator.create(Response) catch unreachable;
ptr.* = response;
@@ -478,10 +484,10 @@ pub const Response = struct {
) callconv(.C) JSValue {
var response = getAllocator(globalThis).create(Response) catch unreachable;
response.* = Response{
+ .init = Response.Init{
+ .status_code = 0,
+ },
.body = Body{
- .init = Body.Init{
- .status_code = 0,
- },
.value = .{ .Empty = {} },
},
.allocator = getAllocator(globalThis),
@@ -494,6 +500,8 @@ pub const Response = struct {
globalThis: *JSC.JSGlobalObject,
callframe: *JSC.CallFrame,
) callconv(.C) ?*Response {
+ var allocator = getAllocator(globalThis);
+
const args_list = brk: {
var args = callframe.arguments(2);
if (args.len > 1 and args.ptr[1].isEmptyOrUndefinedOrNull()) {
@@ -503,17 +511,24 @@ pub const Response = struct {
};
const arguments = args_list.ptr[0..args_list.len];
- const body: Body = @as(?Body, brk: {
+
+ const init: Init = @as(?Init, brk: {
switch (arguments.len) {
0 => {
- break :brk Body.@"200"(globalThis);
+ break :brk Init{
+ .status_code = 200,
+ .headers = null,
+ };
},
1 => {
- break :brk Body.extract(globalThis, arguments[0]);
+ break :brk Init{
+ .status_code = 200,
+ .headers = null,
+ };
},
else => {
if (arguments[1].isObject()) {
- break :brk Body.extractWithInit(globalThis, arguments[0], arguments[1]);
+ break :brk Init.init(allocator, globalThis, arguments[1]) catch null;
}
std.debug.assert(!arguments[1].isEmptyOrUndefinedOrNull());
@@ -526,23 +541,152 @@ pub const Response = struct {
unreachable;
}) orelse return null;
- var response = getAllocator(globalThis).create(Response) catch unreachable;
+ const body: Body = brk: {
+ switch (arguments.len) {
+ 0 => {
+ break :brk Body{
+ .value = Body.Value{ .Null = {} },
+ };
+ },
+ else => {
+ break :brk Body.extract(globalThis, arguments[0]);
+ },
+ }
+ unreachable;
+ } orelse return null;
+
+ var response = allocator.create(Response) catch unreachable;
response.* = Response{
.body = body,
+ .init = init,
.allocator = getAllocator(globalThis),
};
if (response.body.value == .Blob and
- response.body.init.headers != null and
+ response.init.headers != null and
response.body.value.Blob.content_type.len > 0 and
- !response.body.init.headers.?.fastHas(.ContentType))
+ !response.init.headers.?.fastHas(.ContentType))
{
- response.body.init.headers.?.put("content-type", response.body.value.Blob.content_type, globalThis);
+ response.init.headers.?.put("content-type", response.body.value.Blob.content_type, globalThis);
}
return response;
}
+
+ pub const Init = struct {
+ headers: ?*FetchHeaders = null,
+ status_code: u16,
+ status_text: bun.String = bun.String.empty,
+ method: Method = Method.GET,
+
+ pub fn clone(this: Init, ctx: *JSGlobalObject) Init {
+ var that = this;
+ var headers = this.headers;
+ if (headers) |head| {
+ that.headers = head.cloneThis(ctx);
+ }
+ that.status_text = this.status_text.clone();
+
+ return that;
+ }
+
+ pub fn init(allocator: std.mem.Allocator, ctx: *JSGlobalObject, response_init: JSC.JSValue) !?Init {
+ var result = Init{ .status_code = 200 };
+
+ if (!response_init.isCell())
+ return null;
+
+ if (response_init.jsType() == .DOMWrapper) {
+ // fast path: it's a Request object or a Response object
+ // we can skip calling JS getters
+ if (response_init.as(Request)) |req| {
+ if (req.headers) |headers| {
+ if (!headers.isEmpty()) {
+ result.headers = headers.cloneThis(ctx);
+ }
+ }
+
+ result.method = req.method;
+ return result;
+ }
+
+ if (response_init.as(Response)) |resp| {
+ return resp.init.clone(ctx);
+ }
+ }
+
+ if (response_init.fastGet(ctx, .headers)) |headers| {
+ if (headers.as(FetchHeaders)) |orig| {
+ if (!orig.isEmpty()) {
+ result.headers = orig.cloneThis(ctx);
+ }
+ } else {
+ result.headers = FetchHeaders.createFromJS(ctx.ptr(), headers);
+ }
+ }
+
+ if (response_init.fastGet(ctx, .status)) |status_value| {
+ const number = status_value.coerceToInt64(ctx);
+ if ((200 <= number and number < 600) or number == 101) {
+ result.status_code = @as(u16, @truncate(@as(u32, @intCast(number))));
+ } else {
+ const err = ctx.createRangeErrorInstance("The status provided ({d}) must be 101 or in the range of [200, 599]", .{number});
+ ctx.throwValue(err);
+ return null;
+ }
+ }
+
+ if (response_init.fastGet(ctx, .statusText)) |status_text| {
+ result.status_text = bun.String.fromJS(status_text, ctx).dupeRef();
+ }
+
+ if (response_init.fastGet(ctx, .method)) |method_value| {
+ var method_str = method_value.toSlice(ctx, allocator);
+ defer method_str.deinit();
+ if (method_str.len > 0) {
+ result.method = Method.which(method_str.slice()) orelse .GET;
+ }
+ }
+
+ return result;
+ }
+
+ pub fn deinit(this: *Init, _: std.mem.Allocator) void {
+ if (this.headers) |headers| {
+ this.headers = null;
+
+ headers.deref();
+ }
+
+ this.status_text.deref();
+ }
+ };
+
+ pub fn @"404"(globalThis: *JSC.JSGlobalObject) Response {
+ return emptyWithStatus(globalThis, 404);
+ }
+
+ pub fn @"200"(globalThis: *JSC.JSGlobalObject) Response {
+ return emptyWithStatus(globalThis, 200);
+ }
+
+ inline fn emptyWithStatus(globalThis: *JSC.JSGlobalObject, status: u16) Response {
+ var allocator = getAllocator(globalThis);
+ var response = allocator.create(Response) catch unreachable;
+
+ response.* = Response{
+ .body = Body{
+ .value = Body.Value{ .Null = {} },
+ },
+ .init = Init{
+ .status_code = status,
+ },
+ .allocator = getAllocator(globalThis),
+ };
+
+ return response;
+ }
};
const null_fd = bun.invalid_fd;
@@ -778,27 +922,27 @@ pub const Fetch = struct {
if (!success) {
const err = this.onReject();
err.ensureStillAlive();
+ // if we are streaming update with error
+ if (this.readable_stream_ref.get()) |readable| {
+ readable.ptr.Bytes.onData(
+ .{
+ .err = .{ .JSValue = err },
+ },
+ bun.default_allocator,
+ );
+ }
+ // if we are buffering resolve the promise
if (this.response.get()) |response_js| {
if (response_js.as(Response)) |response| {
const body = response.body;
- if (body.value == .Locked) {
- if (body.value.Locked.readable) |readable| {
- readable.ptr.Bytes.onData(
- .{
- .err = .{ .JSValue = err },
- },
- bun.default_allocator,
- );
- return;
- }
+ if (body.value.Locked.promise) |promise_| {
+ const promise = promise_.asAnyPromise().?;
+ promise.reject(globalThis, err);
}
response.body.value.toErrorInstance(err, globalThis);
- return;
}
}
-
- globalThis.throwValue(err);
return;
}
@@ -1238,13 +1382,13 @@ pub const Fetch = struct {
return Response{
.allocator = allocator,
.url = bun.String.createAtomIfPossible(metadata.url),
- .status_text = bun.String.createAtomIfPossible(http_response.status),
.redirected = this.result.redirected,
+ .init = .{
+ .headers = FetchHeaders.createFromPicoHeaders(http_response.headers),
+ .status_code = @as(u16, @truncate(http_response.status_code)),
+ .status_text = bun.String.createAtomIfPossible(http_response.status),
+ },
.body = .{
- .init = .{
- .headers = FetchHeaders.createFromPicoHeaders(http_response.headers),
- .status_code = @as(u16, @truncate(http_response.status_code)),
- },
.value = this.toBodyValue(),
},
};
@@ -1488,15 +1632,15 @@ pub const Fetch = struct {
response.* = Response{
.body = Body{
- .init = Body.Init{
- .status_code = 200,
- },
.value = .{
.Blob = blob,
},
},
+ .init = Response.Init{
+ .status_code = 200,
+ .status_text = bun.String.createAtom("OK"),
+ },
.allocator = allocator,
- .status_text = bun.String.createAtom("OK"),
.url = data_url.url.dupeRef(),
};
@@ -1708,7 +1852,7 @@ pub const Fetch = struct {
if (decompress.isBoolean()) {
disable_decompression = !decompress.asBoolean();
} else if (decompress.isNumber()) {
- disable_keepalive = decompress.to(i32) == 0;
+ disable_decompression = decompress.to(i32) == 0;
}
}
@@ -1901,7 +2045,7 @@ pub const Fetch = struct {
if (decompress.isBoolean()) {
disable_decompression = !decompress.asBoolean();
} else if (decompress.isNumber()) {
- disable_keepalive = decompress.to(i32) == 0;
+ disable_decompression = decompress.to(i32) == 0;
}
}
@@ -2009,11 +2153,11 @@ pub const Fetch = struct {
response.* = Response{
.body = Body{
- .init = Body.Init{
- .status_code = 200,
- },
.value = .{ .Blob = bun_file },
},
+ .init = Response.Init{
+ .status_code = 200,
+ },
.allocator = bun.default_allocator,
.url = file_url_string.clone(),
};
diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig
index a578313d7..6c51daf94 100644
--- a/src/bun.js/webcore/streams.zig
+++ b/src/bun.js/webcore/streams.zig
@@ -225,6 +225,7 @@ pub const ReadableStream = struct {
extern fn ReadableStream__isDisturbed(possibleReadableStream: JSValue, globalObject: *JSGlobalObject) bool;
extern fn ReadableStream__isLocked(possibleReadableStream: JSValue, globalObject: *JSGlobalObject) bool;
extern fn ReadableStream__empty(*JSGlobalObject) JSC.JSValue;
+ extern fn ReadableStream__used(*JSGlobalObject) JSC.JSValue;
extern fn ReadableStream__cancel(stream: JSValue, *JSGlobalObject) void;
extern fn ReadableStream__abort(stream: JSValue, *JSGlobalObject) void;
extern fn ReadableStream__detach(stream: JSValue, *JSGlobalObject) void;
@@ -367,6 +368,12 @@ pub const ReadableStream = struct {
return ReadableStream__empty(globalThis);
}
+ pub fn used(globalThis: *JSGlobalObject) JSC.JSValue {
+ JSC.markBinding(@src());
+
+ return ReadableStream__used(globalThis);
+ }
+
const Base = @import("../../ast/base.zig");
pub const StreamTag = enum(usize) {
invalid = 0,
@@ -2634,6 +2641,7 @@ pub fn HTTPServerWritable(comptime ssl: bool) type {
}
fn flushFromJSNoWait(this: *@This()) JSC.Node.Maybe(JSValue) {
+ log("flushFromJSNoWait", .{});
if (this.hasBackpressure() or this.done) {
return .{ .result = JSValue.jsNumberFromInt32(0) };
}
@@ -3595,6 +3603,9 @@ pub const ByteStream = struct {
this.buffer = try std.ArrayList(u8).initCapacity(bun.default_allocator, chunk.len);
this.buffer.appendSliceAssumeCapacity(chunk);
},
+ .err => {
+ this.pending.result = .{ .err = stream.err };
+ },
else => unreachable,
}
return;
@@ -3604,6 +3615,9 @@ pub const ByteStream = struct {
.temporary_and_done, .temporary => {
try this.buffer.appendSlice(chunk);
},
+ .err => {
+ this.pending.result = .{ .err = stream.err };
+ },
// We don't support the rest of these yet
else => unreachable,
}
@@ -3788,7 +3802,6 @@ pub const FIFO = struct {
},
signal: JSC.WebCore.Signal = .{},
is_first_read: bool = true,
- auto_close: bool = true,
has_adjusted_pipe_size_on_linux: bool = false,
drained: bool = true,
@@ -3807,7 +3820,12 @@ pub const FIFO = struct {
pub fn close(this: *FIFO) void {
if (this.poll_ref) |poll| {
this.poll_ref = null;
- poll.deinit();
+ if (comptime Environment.isLinux) {
+ // force target fd to be removed from epoll
+ poll.deinitForceUnregister();
+ } else {
+ poll.deinit();
+ }
}
const fd = this.fd;
@@ -3815,8 +3833,7 @@ pub const FIFO = struct {
defer if (signal_close) this.signal.close(null);
if (signal_close) {
this.fd = bun.invalid_fd;
- if (this.auto_close)
- _ = bun.sys.close(fd);
+ _ = bun.sys.close(fd);
}
this.to_read = null;
@@ -3831,7 +3848,7 @@ pub const FIFO = struct {
pub fn getAvailableToReadOnLinux(this: *FIFO) u32 {
var len: c_int = 0;
- const rc: c_int = std.c.ioctl(this.fd, std.os.linux.T.FIONREAD, &len);
+ const rc: c_int = std.c.ioctl(this.fd, std.os.linux.T.FIONREAD, @as(*c_int, &len));
if (rc != 0) {
len = 0;
}
@@ -4198,10 +4215,15 @@ pub const File = struct {
file: *Blob.FileStore,
) StreamStart {
var file_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
- var auto_close = file.pathlike == .path;
- var fd = if (!auto_close)
- file.pathlike.fd
+ var fd = if (file.pathlike != .path)
+ // We will always need to close the file descriptor.
+ switch (Syscall.dup(@intCast(file.pathlike.fd))) {
+ .result => |_fd| _fd,
+ .err => |err| {
+ return .{ .err = err.withPath(file.pathlike.path.slice()) };
+ },
+ }
else switch (Syscall.open(file.pathlike.path.sliceZ(&file_buf), std.os.O.RDONLY | std.os.O.NONBLOCK | std.os.O.CLOEXEC, 0)) {
.result => |_fd| _fd,
.err => |err| {
@@ -4218,7 +4240,7 @@ pub const File = struct {
}
}
- if (!auto_close and !(file.is_atty orelse false)) {
+ if (file.pathlike != .path and !(file.is_atty orelse false)) {
if (comptime Environment.isWindows) {
bun.todo(@src(), {});
} else {
@@ -4229,7 +4251,6 @@ pub const File = struct {
// if we do not, clone the descriptor and set non-blocking
// it is important for us to clone it so we don't cause Weird Things to happen
if ((flags & std.os.O.NONBLOCK) == 0) {
- auto_close = true;
fd = switch (Syscall.fcntl(fd, std.os.F.DUPFD, 0)) {
.result => |_fd| @as(@TypeOf(fd), @intCast(_fd)),
.err => |err| return .{ .err = err },
@@ -4249,24 +4270,18 @@ pub const File = struct {
const stat: bun.Stat = switch (Syscall.fstat(fd)) {
.result => |result| result,
.err => |err| {
- if (auto_close) {
- _ = Syscall.close(fd);
- }
+ _ = Syscall.close(fd);
return .{ .err = err };
},
};
if (std.os.S.ISDIR(stat.mode)) {
- if (auto_close) {
- _ = Syscall.close(fd);
- }
+ _ = Syscall.close(fd);
return .{ .err = Syscall.Error.fromCode(.ISDIR, .fstat) };
}
if (std.os.S.ISSOCK(stat.mode)) {
- if (auto_close) {
- _ = Syscall.close(fd);
- }
+ _ = Syscall.close(fd);
return .{ .err = Syscall.Error.fromCode(.INVAL, .fstat) };
}
@@ -4292,9 +4307,7 @@ pub const File = struct {
file.max_size = this.remaining_bytes;
if (this.remaining_bytes == 0) {
- if (auto_close) {
- _ = Syscall.close(fd);
- }
+ _ = Syscall.close(fd);
return .{ .empty = {} };
}
@@ -4303,7 +4316,6 @@ pub const File = struct {
}
this.fd = fd;
- this.auto_close = auto_close;
return StreamStart{ .ready = {} };
}
@@ -4725,7 +4737,6 @@ pub const FileReader = struct {
.readable = .{
.FIFO = .{
.fd = readable_file.fd,
- .auto_close = readable_file.auto_close,
.drained = this.buffered_data.len == 0,
},
},
@@ -4885,7 +4896,7 @@ pub fn NewReadyWatcher(
const fd = @as(c_int, @intCast(fd_));
std.debug.assert(@as(c_int, @intCast(this.poll_ref.?.fd)) == fd);
std.debug.assert(
- this.poll_ref.?.unregister(JSC.VirtualMachine.get().event_loop_handle.?) == .result,
+ this.poll_ref.?.unregister(JSC.VirtualMachine.get().event_loop_handle.?, false) == .result,
);
}