diff options
author | 2023-07-11 19:14:34 -0700 | |
---|---|---|
committer | 2023-07-11 19:14:34 -0700 | |
commit | cbb88672f217a90db1aa1eb29cd92d5d9035b22b (patch) | |
tree | 43a00501f3cde495967e116f0b660777051551f8 /src/bun.js/webcore | |
parent | 1f900cff453700b19bca2acadfe26da4468c1282 (diff) | |
parent | 34b0e7a2bbd8bf8097341cdb0075d0908283e834 (diff) | |
download | bun-jarred/esm-conditions.tar.gz bun-jarred/esm-conditions.tar.zst bun-jarred/esm-conditions.zip |
Merge branch 'main' into jarred/esm-conditionsjarred/esm-conditions
Diffstat (limited to 'src/bun.js/webcore')
-rw-r--r-- | src/bun.js/webcore/blob.zig | 207 | ||||
-rw-r--r-- | src/bun.js/webcore/body.zig | 6 | ||||
-rw-r--r-- | src/bun.js/webcore/encoding.zig | 114 | ||||
-rw-r--r-- | src/bun.js/webcore/request.zig | 20 | ||||
-rw-r--r-- | src/bun.js/webcore/response.classes.ts | 1 | ||||
-rw-r--r-- | src/bun.js/webcore/response.zig | 28 | ||||
-rw-r--r-- | src/bun.js/webcore/streams.zig | 49 |
7 files changed, 225 insertions, 200 deletions
diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig index 9b3ddb8df..ef2520049 100644 --- a/src/bun.js/webcore/blob.zig +++ b/src/bun.js/webcore/blob.zig @@ -249,7 +249,7 @@ pub const Blob = struct { var hex_buf: [70]u8 = undefined; const boundary = brk: { - var random = globalThis.bunVM().rareData().nextUUID(); + var random = globalThis.bunVM().rareData().nextUUID().bytes; var formatter = std.fmt.fmtSliceHexLower(&random); break :brk std.fmt.bufPrint(&hex_buf, "-WebkitFormBoundary{any}", .{formatter}) catch unreachable; }; @@ -319,6 +319,7 @@ pub const Blob = struct { }, ); } + pub fn writeFormat(this: *const Blob, comptime Formatter: type, formatter: *Formatter, writer: anytype, comptime enable_ansi_colors: bool) !void { const Writer = @TypeOf(writer); @@ -546,7 +547,7 @@ pub const Blob = struct { return JSPromise.resolvedPromiseValue(ctx.ptr(), cloned.toJS(ctx)).asObjectRef(); } else if (destination_type == .bytes and source_type == .file) { var fake_call_frame: [8]JSC.JSValue = undefined; - @memset(@ptrCast([*]u8, &fake_call_frame), 0, @sizeOf(@TypeOf(fake_call_frame))); + @memset(@ptrCast([*]u8, &fake_call_frame)[0..@sizeOf(@TypeOf(fake_call_frame))], 0); const blob_value = source_blob.getSlice(ctx, @ptrCast(*JSC.CallFrame, &fake_call_frame)); @@ -599,11 +600,14 @@ pub const Blob = struct { } var needs_async = false; + if (data.isString()) { + defer if (!needs_async and path_or_blob == .path) path_or_blob.path.deinit(); + const len = data.getLength(ctx); if (len < 256 * 1024 or bun.isMissingIOUring()) { - const str = data.getZigString(ctx); + const str = data.toBunString(ctx); const pathlike: JSC.Node.PathOrFileDescriptor = if (path_or_blob == .path) path_or_blob.path @@ -635,6 +639,8 @@ pub const Blob = struct { } } } else if (data.asArrayBuffer(ctx)) |buffer_view| { + defer if (!needs_async and path_or_blob == .path) path_or_blob.path.deinit(); + if (buffer_view.byte_len < 256 * 1024 or bun.isMissingIOUring()) { const pathlike: JSC.Node.PathOrFileDescriptor = if (path_or_blob == .path) path_or_blob.path @@ -784,7 +790,7 @@ pub const Blob = struct { fn writeStringToFileFast( globalThis: *JSC.JSGlobalObject, pathlike: JSC.Node.PathOrFileDescriptor, - str: ZigString, + str: bun.String, needs_async: *bool, comptime needs_open: bool, ) JSC.JSValue { @@ -807,7 +813,7 @@ pub const Blob = struct { unreachable; }; - var truncate = needs_open or str.len == 0; + var truncate = needs_open or str.isEmpty(); var jsc_vm = globalThis.bunVM(); var written: usize = 0; @@ -822,62 +828,12 @@ pub const Blob = struct { _ = JSC.Node.Syscall.close(fd); } } - if (str.len == 0) {} else if (str.is16Bit()) { - var decoded = str.toSlice(jsc_vm.allocator); + if (!str.isEmpty()) { + var decoded = str.toUTF8(jsc_vm.allocator); defer decoded.deinit(); var remain = decoded.slice(); - const end = remain.ptr + remain.len; - - while (remain.ptr != end) { - const result = JSC.Node.Syscall.write(fd, remain); - switch (result) { - .result => |res| { - written += res; - remain = remain[res..]; - if (res == 0) break; - }, - .err => |err| { - truncate = false; - if (err.getErrno() == .AGAIN) { - needs_async.* = true; - return .zero; - } - return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis)); - }, - } - } - } else if (str.isUTF8() or strings.isAllASCII(str.slice())) { - var remain = str.slice(); - const end = remain.ptr + remain.len; - - while (remain.ptr != end) { - const result = JSC.Node.Syscall.write(fd, remain); - switch (result) { - .result => |res| { - written += res; - remain = remain[res..]; - if (res == 0) break; - }, - .err => |err| { - truncate = false; - if (err.getErrno() == .AGAIN) { - needs_async.* = true; - return .zero; - } - - return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis)); - }, - } - } - } else { - var decoded = str.toOwnedSlice(jsc_vm.allocator) catch { - return JSC.JSPromise.rejectedPromiseValue(globalThis, ZigString.static("Out of memory").toErrorInstance(globalThis)); - }; - defer jsc_vm.allocator.free(decoded); - var remain = decoded; - const end = remain.ptr + remain.len; - while (remain.ptr != end) { + while (remain.len > 0) { const result = JSC.Node.Syscall.write(fd, remain); switch (result) { .result => |res| { @@ -997,6 +953,13 @@ pub const Blob = struct { switch (path_) { .path => { const slice = path_.path.slice(); + + if (vm.standalone_module_graph) |graph| { + if (graph.find(slice)) |file| { + return file.blob(globalThis).dupe(); + } + } + var cloned = (allocator.dupeZ(u8, slice) catch unreachable)[0..slice.len]; break :brk .{ @@ -1231,9 +1194,6 @@ pub const Blob = struct { .syscall = .open, }).toSystemError(); - // assert we never end up reusing the memory - std.debug.assert(@ptrToInt(this.system_error.?.path.slice().ptr) != @ptrToInt(path_buffer)); - callback(this, null_fd); return; }; @@ -1396,12 +1356,13 @@ pub const Blob = struct { return; } else if (this.store == null) { bun.default_allocator.destroy(this); - cb(cb_ctx, ResultType{ .err = SystemError{ - .code = ZigString.init("INTERNAL_ERROR"), - .path = ZigString.Empty, - .message = ZigString.init("assertion failure - store should not be null"), - .syscall = ZigString.init("read"), - } }); + cb(cb_ctx, ResultType{ + .err = SystemError{ + .code = bun.String.static("INTERNAL_ERROR"), + .message = bun.String.static("assertion failure - store should not be null"), + .syscall = bun.String.static("read"), + }, + }); return; } @@ -1433,12 +1394,12 @@ pub const Blob = struct { }).toSystemError(); } else { this.system_error = JSC.SystemError{ - .code = ZigString.init(bun.asByteSlice(@errorName(err))), + .code = bun.String.static(bun.asByteSlice(@errorName(err))), .path = if (this.file_store.pathlike == .path) - ZigString.init(this.file_store.pathlike.path.slice()) + bun.String.create(this.file_store.pathlike.path.slice()) else - ZigString.Empty, - .syscall = ZigString.init("read"), + bun.String.empty, + .syscall = bun.String.static("read"), }; this.errno = err; @@ -1495,13 +1456,13 @@ pub const Blob = struct { if (std.os.S.ISDIR(stat.mode)) { this.errno = error.EISDIR; this.system_error = JSC.SystemError{ - .code = ZigString.init("EISDIR"), + .code = bun.String.static("EISDIR"), .path = if (this.file_store.pathlike == .path) - ZigString.init(this.file_store.pathlike.path.slice()) + bun.String.create(this.file_store.pathlike.path.slice()) else - ZigString.Empty, - .message = ZigString.init("Directories cannot be read like files"), - .syscall = ZigString.init("read"), + bun.String.empty, + .message = bun.String.static("Directories cannot be read like files"), + .syscall = bun.String.static("read"), }; return; } @@ -1680,8 +1641,8 @@ pub const Blob = struct { this.wrote += @truncate(SizeType, result catch |errno| { this.errno = errno; this.system_error = this.system_error orelse JSC.SystemError{ - .code = ZigString.init(bun.asByteSlice(@errorName(errno))), - .syscall = ZigString.init("write"), + .code = bun.String.static(bun.asByteSlice(@errorName(errno))), + .syscall = bun.String.static("write"), }; this.wrote = 0; @@ -1739,14 +1700,14 @@ pub const Blob = struct { }; const unsupported_directory_error = SystemError{ - .errno = @intCast(c_int, @enumToInt(bun.C.SystemErrno.EISDIR)), - .message = ZigString.init("That doesn't work on folders"), - .syscall = ZigString.init("fstat"), + .errno = @intCast(c_int, @intFromEnum(bun.C.SystemErrno.EISDIR)), + .message = bun.String.static("That doesn't work on folders"), + .syscall = bun.String.static("fstat"), }; const unsupported_non_regular_file_error = SystemError{ - .errno = @intCast(c_int, @enumToInt(bun.C.SystemErrno.ENOTSUP)), - .message = ZigString.init("Non-regular files aren't supported yet"), - .syscall = ZigString.init("fstat"), + .errno = @intCast(c_int, @intFromEnum(bun.C.SystemErrno.ENOTSUP)), + .message = bun.String.static("Non-regular files aren't supported yet"), + .syscall = bun.String.static("fstat"), }; // blocking, but off the main thread @@ -1814,13 +1775,12 @@ pub const Blob = struct { pub fn reject(this: *CopyFile, promise: *JSC.JSPromise) void { var globalThis = this.globalThis; var system_error: SystemError = this.system_error orelse SystemError{}; - if (this.source_file_store.pathlike == .path and system_error.path.len == 0) { - system_error.path = ZigString.init(this.source_file_store.pathlike.path.slice()); - system_error.path.mark(); + if (this.source_file_store.pathlike == .path and system_error.path.isEmpty()) { + system_error.path = bun.String.create(this.source_file_store.pathlike.path.slice()); } - if (system_error.message.len == 0) { - system_error.message = ZigString.init("Failed to copy file"); + if (system_error.message.isEmpty()) { + system_error.message = bun.String.static("Failed to copy file"); } var instance = system_error.toErrorInstance(this.globalThis); @@ -1978,14 +1938,14 @@ pub const Blob = struct { } this.system_error = (JSC.Node.Syscall.Error{ - .errno = @intCast(JSC.Node.Syscall.Error.Int, @enumToInt(linux.E.INVAL)), + .errno = @intCast(JSC.Node.Syscall.Error.Int, @intFromEnum(linux.E.INVAL)), .syscall = TryWith.tag.get(use).?, }).toSystemError(); return AsyncIO.asError(linux.E.INVAL); }, else => |errno| { this.system_error = (JSC.Node.Syscall.Error{ - .errno = @intCast(JSC.Node.Syscall.Error.Int, @enumToInt(errno)), + .errno = @intCast(JSC.Node.Syscall.Error.Int, @intFromEnum(errno)), .syscall = TryWith.tag.get(use).?, }).toSystemError(); return AsyncIO.asError(errno); @@ -2000,7 +1960,7 @@ pub const Blob = struct { } pub fn doFCopyFile(this: *CopyFile) anyerror!void { - switch (JSC.Node.Syscall.fcopyfile(this.source_fd, this.destination_fd, os.system.COPYFILE_DATA)) { + switch (JSC.Node.Syscall.fcopyfile(this.source_fd, this.destination_fd, os.system.COPYFILE.DATA)) { .err => |errno| { this.system_error = errno.toSystemError(); @@ -2240,6 +2200,9 @@ pub const Blob = struct { cap: SizeType = 0, allocator: std.mem.Allocator, + /// Used by standalone module graph + stored_name: bun.PathString = bun.PathString.empty, + pub fn init(bytes: []u8, allocator: std.mem.Allocator) ByteStore { return .{ .ptr = bytes.ptr, @@ -2359,6 +2322,34 @@ pub const Blob = struct { return promisified(this.toFormData(globalThis, .temporary), globalThis); } + fn getExistsSync(this: *Blob) JSC.JSValue { + if (this.size == Blob.max_size) { + this.resolveSize(); + } + + // If there's no store that means it's empty and we just return true + // it will not error to return an empty Blob + var store = this.store orelse return JSValue.jsBoolean(true); + + if (store.data == .bytes) { + // Bytes will never error + return JSValue.jsBoolean(true); + } + + // We say regular files and pipes exist. + // This is mostly meant for "Can we use this in new Response(file)?" + return JSValue.jsBoolean(std.os.S.ISREG(store.data.file.mode) or std.os.S.ISFIFO(store.data.file.mode)); + } + + // This mostly means 'can it be read?' + pub fn getExists( + this: *Blob, + globalThis: *JSC.JSGlobalObject, + _: *JSC.CallFrame, + ) callconv(.C) JSValue { + return JSC.JSPromise.resolvedPromiseValue(globalThis, this.getExistsSync()); + } + pub fn getWriter( this: *Blob, globalThis: *JSC.JSGlobalObject, @@ -2573,17 +2564,31 @@ pub const Blob = struct { this: *Blob, globalThis: *JSC.JSGlobalObject, ) callconv(.C) JSValue { + if (this.getFileName()) |path| { + var str = bun.String.create(path); + return str.toJS(globalThis); + } + + return JSValue.undefined; + } + + pub fn getFileName( + this: *const Blob, + ) ?[]const u8 { if (this.store) |store| { if (store.data == .file) { if (store.data.file.pathlike == .path) { - return ZigString.fromUTF8(store.data.file.pathlike.path.slice()).toValueGC(globalThis); + return store.data.file.pathlike.path.slice(); } // we shouldn't return Number here. + } else if (store.data == .bytes) { + if (store.data.bytes.stored_name.slice().len > 0) + return store.data.bytes.stored_name.slice(); } } - return JSC.JSValue.jsUndefined(); + return null; } // TODO: Move this to a separate `File` object or BunFile @@ -3514,6 +3519,14 @@ pub const AnyBlob = union(enum) { InternalBlob: InternalBlob, WTFStringImpl: bun.WTF.StringImpl, + pub fn getFileName(this: *const AnyBlob) ?[]const u8 { + return switch (this.*) { + .Blob => this.Blob.getFileName(), + .WTFStringImpl => null, + .InternalBlob => null, + }; + } + pub inline fn fastSize(this: *const AnyBlob) Blob.SizeType { return switch (this.*) { .Blob => this.Blob.size, @@ -3816,10 +3829,10 @@ pub const InlineBlob = extern struct { var bytes_slice = inline_blob.bytes[0..total]; if (first.len > 0) - @memcpy(bytes_slice.ptr, first.ptr, first.len); + @memcpy(bytes_slice[0..first.len], first); if (second.len > 0) - @memcpy(bytes_slice.ptr + first.len, second.ptr, second.len); + @memcpy(bytes_slice[first.len..][0..second.len], second); inline_blob.len = @truncate(@TypeOf(inline_blob.len), total); return inline_blob; @@ -3834,7 +3847,7 @@ pub const InlineBlob = extern struct { }; if (data.len > 0) - @memcpy(&blob.bytes, data.ptr, data.len); + @memcpy(blob.bytes[0..data.len], data); return blob; } diff --git a/src/bun.js/webcore/body.zig b/src/bun.js/webcore/body.zig index df3ba3ce1..028b104b2 100644 --- a/src/bun.js/webcore/body.zig +++ b/src/bun.js/webcore/body.zig @@ -496,8 +496,10 @@ pub const Body = struct { locked.readable.?.value.protect(); return locked.readable.?.value; }, - - else => unreachable, + .Error => { + // TODO: handle error properly + return JSC.WebCore.ReadableStream.empty(globalThis); + }, } } diff --git a/src/bun.js/webcore/encoding.zig b/src/bun.js/webcore/encoding.zig index e4b8a4b95..dd47ccc29 100644 --- a/src/bun.js/webcore/encoding.zig +++ b/src/bun.js/webcore/encoding.zig @@ -68,7 +68,7 @@ pub const TextEncoder = struct { std.debug.assert(result.read == slice.len); const array_buffer = uint8array.asArrayBuffer(globalThis).?; std.debug.assert(result.written == array_buffer.len); - @memcpy(array_buffer.byteSlice().ptr, &buf, result.written); + @memcpy(array_buffer.byteSlice()[0..result.written], buf[0..result.written]); return uint8array; } else { const bytes = strings.allocateLatin1IntoUTF8(globalThis.bunVM().allocator, []const u8, slice) catch { @@ -103,7 +103,7 @@ pub const TextEncoder = struct { const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, 3); const array_buffer = uint8array.asArrayBuffer(globalThis).?; const replacement_char = [_]u8{ 239, 191, 189 }; - @memcpy(array_buffer.slice().ptr, &replacement_char, replacement_char.len); + @memcpy(array_buffer.slice()[0..replacement_char.len], &replacement_char); return uint8array; } const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, result.written); @@ -111,7 +111,7 @@ pub const TextEncoder = struct { std.debug.assert(result.read == slice.len); const array_buffer = uint8array.asArrayBuffer(globalThis).?; std.debug.assert(result.written == array_buffer.len); - @memcpy(array_buffer.slice().ptr, &buf, result.written); + @memcpy(array_buffer.slice()[0..result.written], buf[0..result.written]); return uint8array; } else { var bytes = strings.toUTF8AllocWithType( @@ -207,7 +207,7 @@ pub const TextEncoder = struct { if (array.isEmpty()) { array = JSC.JSValue.createUninitializedUint8Array(globalThis, length); array.ensureStillAlive(); - @memcpy(array.asArrayBuffer(globalThis).?.ptr, buf_to_use.ptr, length); + @memcpy(array.asArrayBuffer(globalThis).?.ptr[0..length], buf_to_use[0..length]); } return array; @@ -224,7 +224,7 @@ pub const TextEncoder = struct { var result: strings.EncodeIntoResult = strings.copyUTF16IntoUTF8(output, []const u16, input, false); if (output.len >= 3 and (result.read == 0 or result.written == 0)) { const replacement_char = [_]u8{ 239, 191, 189 }; - @memcpy(buf_ptr, &replacement_char, replacement_char.len); + @memcpy(buf_ptr[0..replacement_char.len], &replacement_char); result.read = 1; result.written = 3; } @@ -515,10 +515,10 @@ pub const TextDecoder = struct { buffer.ensureTotalCapacity(allocator, slice.len) catch unreachable; buffer.items.len = i; + var len = std.mem.sliceAsBytes(slice[0..i]).len; @memcpy( - std.mem.sliceAsBytes(buffer.items).ptr, - std.mem.sliceAsBytes(slice).ptr, - std.mem.sliceAsBytes(slice[0..i]).len, + std.mem.sliceAsBytes(buffer.items)[0..len], + std.mem.sliceAsBytes(slice)[0..len], ); const first_high_surrogate = 0xD800; @@ -537,10 +537,10 @@ pub const TextDecoder = struct { const prev = buffer.items.len; buffer.items.len += count; // Since this string is freshly allocated, we know it's not going to overlap + len = std.mem.sliceAsBytes(remainder[0..count]).len; @memcpy( - std.mem.sliceAsBytes(buffer.items[prev..]).ptr, - std.mem.sliceAsBytes(remainder).ptr, - std.mem.sliceAsBytes(remainder[0..count]).len, + std.mem.sliceAsBytes(buffer.items[prev..])[0..len], + std.mem.sliceAsBytes(remainder)[0..len], ); remainder = remainder[count..]; }, @@ -659,7 +659,7 @@ pub const TextDecoder = struct { }, EncodingLabel.@"UTF-16LE" => { - if (std.mem.isAligned(@ptrToInt(buffer_slice.ptr), @alignOf([*]const u16))) { + if (std.mem.isAligned(@intFromPtr(buffer_slice.ptr), @alignOf([*]const u16))) { return this.decodeUTF16WithAlignment([]const u16, @alignCast(2, std.mem.bytesAsSlice(u16, buffer_slice)), globalThis); } @@ -701,7 +701,7 @@ pub const TextDecoder = struct { pub const Encoder = struct { export fn Bun__encoding__writeLatin1(input: [*]const u8, len: usize, to: [*]u8, to_len: usize, encoding: u8) usize { - return switch (@intToEnum(JSC.Node.Encoding, encoding)) { + return switch (@enumFromInt(JSC.Node.Encoding, encoding)) { .utf8 => writeU8(input, len, to, to_len, .utf8), .latin1 => writeU8(input, len, to, to_len, .ascii), .ascii => writeU8(input, len, to, to_len, .ascii), @@ -714,7 +714,7 @@ pub const Encoder = struct { } catch 0; } export fn Bun__encoding__writeUTF16(input: [*]const u16, len: usize, to: [*]u8, to_len: usize, encoding: u8) usize { - return switch (@intToEnum(JSC.Node.Encoding, encoding)) { + return switch (@enumFromInt(JSC.Node.Encoding, encoding)) { .utf8 => writeU16(input, len, to, to_len, .utf8, false), .latin1 => writeU16(input, len, to, to_len, .ascii, false), .ascii => writeU16(input, len, to, to_len, .ascii, false), @@ -727,7 +727,7 @@ pub const Encoder = struct { } catch 0; } export fn Bun__encoding__byteLengthLatin1(input: [*]const u8, len: usize, encoding: u8) usize { - return switch (@intToEnum(JSC.Node.Encoding, encoding)) { + return switch (@enumFromInt(JSC.Node.Encoding, encoding)) { .utf8 => byteLengthU8(input, len, .utf8), .latin1 => byteLengthU8(input, len, .ascii), .ascii => byteLengthU8(input, len, .ascii), @@ -740,7 +740,7 @@ pub const Encoder = struct { }; } export fn Bun__encoding__byteLengthUTF16(input: [*]const u16, len: usize, encoding: u8) usize { - return switch (@intToEnum(JSC.Node.Encoding, encoding)) { + return switch (@enumFromInt(JSC.Node.Encoding, encoding)) { .utf8 => byteLengthU16(input, len, .utf8), .latin1 => byteLengthU16(input, len, .ascii), .ascii => byteLengthU16(input, len, .ascii), @@ -753,7 +753,7 @@ pub const Encoder = struct { }; } export fn Bun__encoding__constructFromLatin1(globalObject: *JSGlobalObject, input: [*]const u8, len: usize, encoding: u8) JSValue { - var slice = switch (@intToEnum(JSC.Node.Encoding, encoding)) { + var slice = switch (@enumFromInt(JSC.Node.Encoding, encoding)) { .hex => constructFromU8(input, len, .hex), .ascii => constructFromU8(input, len, .ascii), .base64url => constructFromU8(input, len, .base64url), @@ -766,7 +766,7 @@ pub const Encoder = struct { return JSC.JSValue.createBuffer(globalObject, slice, globalObject.bunVM().allocator); } export fn Bun__encoding__constructFromUTF16(globalObject: *JSGlobalObject, input: [*]const u16, len: usize, encoding: u8) JSValue { - var slice = switch (@intToEnum(JSC.Node.Encoding, encoding)) { + var slice = switch (@enumFromInt(JSC.Node.Encoding, encoding)) { .base64 => constructFromU16(input, len, .base64), .hex => constructFromU16(input, len, .hex), .base64url => constructFromU16(input, len, .base64url), @@ -785,7 +785,7 @@ pub const Encoder = struct { } export fn Bun__encoding__toString(input: [*]const u8, len: usize, globalObject: *JSC.JSGlobalObject, encoding: u8) JSValue { - return switch (@intToEnum(JSC.Node.Encoding, encoding)) { + return switch (@enumFromInt(JSC.Node.Encoding, encoding)) { .ucs2 => toString(input, len, globalObject, .utf16le), .utf16le => toString(input, len, globalObject, .utf16le), .utf8 => toString(input, len, globalObject, .utf8), @@ -802,7 +802,20 @@ pub const Encoder = struct { // pub fn writeUTF16AsUTF8(utf16: [*]const u16, len: usize, to: [*]u8, to_len: usize) callconv(.C) i32 { // return @intCast(i32, strings.copyUTF16IntoUTF8(to[0..to_len], []const u16, utf16[0..len], true).written); // } - + pub fn toStringAtRuntime(input: [*]const u8, len: usize, globalObject: *JSGlobalObject, encoding: JSC.Node.Encoding) JSValue { + return switch (encoding) { + .ucs2 => toString(input, len, globalObject, .utf16le), + .utf16le => toString(input, len, globalObject, .utf16le), + .utf8 => toString(input, len, globalObject, .utf8), + .ascii => toString(input, len, globalObject, .ascii), + .hex => toString(input, len, globalObject, .hex), + .base64 => toString(input, len, globalObject, .base64), + .base64url => toString(input, len, globalObject, .base64url), + .latin1 => toString(input, len, globalObject, .latin1), + // treat everything else as utf8 + else => toString(input, len, globalObject, .utf8), + }; + } pub fn toString(input_ptr: [*]const u8, len: usize, global: *JSGlobalObject, comptime encoding: JSC.Node.Encoding) JSValue { if (len == 0) return ZigString.Empty.toValue(global); @@ -816,23 +829,18 @@ pub const Encoder = struct { return ZigString.init(input).toValueGC(global); } - if (input.len < 512) { - var buf: [512]u8 = undefined; - var to = buf[0..input.len]; - strings.copyLatin1IntoASCII(to, input); - return ZigString.init(to).toValueGC(global); - } - - var to = allocator.alloc(u8, len) catch return ZigString.init("Out of memory").toErrorInstance(global); - strings.copyLatin1IntoASCII(to, input); - return ZigString.init(to).toExternalValue(global); + var str = bun.String.createUninitialized(.latin1, len) orelse return ZigString.init("Out of memory").toErrorInstance(global); + defer str.deref(); + strings.copyLatin1IntoASCII(@constCast(str.latin1()), input); + return str.toJS(global); }, .latin1 => { - var to = allocator.alloc(u8, len) catch return ZigString.init("Out of memory").toErrorInstance(global); + var str = bun.String.createUninitialized(.latin1, len) orelse return ZigString.init("Out of memory").toErrorInstance(global); + defer str.deref(); - @memcpy(to.ptr, input_ptr, to.len); + @memcpy(@constCast(str.latin1()), input_ptr[0..len]); - return ZigString.init(to).toExternalValue(global); + return str.toJS(global); }, .buffer, .utf8 => { const converted = strings.toUTF16Alloc(allocator, input, false) catch return ZigString.init("Out of memory").toErrorInstance(global); @@ -848,21 +856,22 @@ pub const Encoder = struct { // Avoid incomplete characters if (len / 2 == 0) return ZigString.Empty.toValue(global); - var output = allocator.alloc(u16, len / 2) catch return ZigString.init("Out of memory").toErrorInstance(global); - var output_bytes = std.mem.sliceAsBytes(output); + var output = bun.String.createUninitialized(.utf16, len / 2) orelse return ZigString.init("Out of memory").toErrorInstance(global); + defer output.deref(); + var output_bytes = std.mem.sliceAsBytes(@constCast(output.utf16())); output_bytes[output_bytes.len - 1] = 0; - @memcpy(output_bytes.ptr, input_ptr, output_bytes.len); - return ZigString.toExternalU16(output.ptr, output.len, global); + @memcpy(output_bytes, input_ptr[0..output_bytes.len]); + return output.toJS(global); }, .hex => { - var output = allocator.alloc(u8, input.len * 2) catch return ZigString.init("Out of memory").toErrorInstance(global); + var str = bun.String.createUninitialized(.latin1, len * 2) orelse return ZigString.init("Out of memory").toErrorInstance(global); + defer str.deref(); + var output = @constCast(str.latin1()); const wrote = strings.encodeBytesToHex(output, input); std.debug.assert(wrote == output.len); - var val = ZigString.init(output); - val.mark(); - return val.toExternalValue(global); + return str.toJS(global); }, .base64url => { @@ -892,7 +901,7 @@ pub const Encoder = struct { switch (comptime encoding) { .buffer => { const written = @min(len, to_len); - @memcpy(to_ptr, input, written); + @memcpy(to_ptr[0..written], input[0..written]); return written; }, @@ -903,7 +912,7 @@ pub const Encoder = struct { var remain = input[0..written]; if (bun.simdutf.validate.ascii(remain)) { - @memcpy(to.ptr, remain.ptr, written); + @memcpy(to_ptr[0..written], remain[0..written]); } else { strings.copyLatin1IntoASCII(to, remain); } @@ -919,7 +928,7 @@ pub const Encoder = struct { if (to_len < 2) return 0; - if (std.mem.isAligned(@ptrToInt(to_ptr), @alignOf([*]u16))) { + if (std.mem.isAligned(@intFromPtr(to_ptr), @alignOf([*]u16))) { var buf = input[0..len]; var output = @ptrCast([*]u16, @alignCast(@alignOf(u16), to_ptr))[0 .. to_len / 2]; @@ -972,6 +981,14 @@ pub const Encoder = struct { } } + pub fn encodeIntoFrom16(input: []const u16, to: []u8, comptime encoding: JSC.Node.Encoding, comptime allow_partial_write: bool) !usize { + return writeU16(input.ptr, input.len, to.ptr, to.len, encoding, allow_partial_write); + } + + pub fn encodeIntoFrom8(input: []const u8, to: []u8, comptime encoding: JSC.Node.Encoding) !usize { + return writeU8(input.ptr, input.len, to.ptr, to.len, encoding); + } + pub fn writeU16(input: [*]const u16, len: usize, to: [*]u8, to_len: usize, comptime encoding: JSC.Node.Encoding, comptime allow_partial_write: bool) !usize { if (len == 0) return 0; @@ -1065,14 +1082,14 @@ pub const Encoder = struct { switch (comptime encoding) { .buffer => { var to = allocator.alloc(u8, len) catch return &[_]u8{}; - @memcpy(to.ptr, input, len); + @memcpy(to[0..len], input[0..len]); return to; }, .latin1, .ascii => { var to = allocator.alloc(u8, len) catch return &[_]u8{}; - @memcpy(to.ptr, input, len); + @memcpy(to[0..len], input[0..len]); return to; }, @@ -1121,7 +1138,7 @@ pub const Encoder = struct { .latin1, .buffer, .ascii => { var to = allocator.alloc(u8, len) catch return &[_]u8{}; var input_bytes = std.mem.sliceAsBytes(input[0..len]); - @memcpy(to.ptr, input_bytes.ptr, input_bytes.len); + @memcpy(to[0..input_bytes.len], input_bytes); for (to[0..len], 0..) |c, i| { to[i] = @as(u8, @truncate(u7, c)); } @@ -1131,7 +1148,8 @@ pub const Encoder = struct { // string is already encoded, just need to copy the data .ucs2, .utf16le => { var to = std.mem.sliceAsBytes(allocator.alloc(u16, len * 2) catch return &[_]u8{}); - @memcpy(to.ptr, std.mem.sliceAsBytes(input[0..len]).ptr, std.mem.sliceAsBytes(input[0..len]).len); + const bytes = std.mem.sliceAsBytes(input[0..len]); + @memcpy(to[0..bytes.len], bytes); return to; }, diff --git a/src/bun.js/webcore/request.zig b/src/bun.js/webcore/request.zig index a8c648212..cff2ef2f3 100644 --- a/src/bun.js/webcore/request.zig +++ b/src/bun.js/webcore/request.zig @@ -255,19 +255,7 @@ pub const Request = struct { this: *Request, globalThis: *JSC.JSGlobalObject, ) callconv(.C) JSC.JSValue { - const string_contents: string = switch (this.method) { - .GET => "GET", - .HEAD => "HEAD", - .PATCH => "PATCH", - .PUT => "PUT", - .POST => "POST", - .OPTIONS => "OPTIONS", - .CONNECT => "CONNECT", - .TRACE => "TRACE", - .DELETE => "DELETE", - }; - - return ZigString.init(string_contents).toValueGC(globalThis); + return bun.String.static(@tagName(this.method)).toJSConst(globalThis); } pub fn getMode( @@ -472,8 +460,8 @@ pub const Request = struct { url_or_object, if (is_first_argument_a_url) JSValue.undefined else url_or_object, }; - const values_to_try = values_to_try_[0 .. @as(usize, @boolToInt(!is_first_argument_a_url)) + - @as(usize, @boolToInt(arguments.len > 1 and arguments[1].isObject()))]; + 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(); @@ -564,7 +552,7 @@ pub const Request = struct { fields.insert(.url); // first value - } else if (@enumToInt(value) == @enumToInt(values_to_try[values_to_try.len - 1]) and !is_first_argument_a_url and + } else if (@intFromEnum(value) == @intFromEnum(values_to_try[values_to_try.len - 1]) and !is_first_argument_a_url and value.implementsToString(globalThis)) { const slice = value.toSliceOrNull(globalThis) orelse { diff --git a/src/bun.js/webcore/response.classes.ts b/src/bun.js/webcore/response.classes.ts index b6ad452d2..c11cb10b2 100644 --- a/src/bun.js/webcore/response.classes.ts +++ b/src/bun.js/webcore/response.classes.ts @@ -132,6 +132,7 @@ export default [ slice: { fn: "getSlice", length: 2 }, stream: { fn: "getStream", length: 1 }, formData: { fn: "getFormData" }, + exists: { fn: "getExists", length: 0 }, type: { getter: "getType", diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig index beae4d182..e888ffa5a 100644 --- a/src/bun.js/webcore/response.zig +++ b/src/bun.js/webcore/response.zig @@ -386,7 +386,7 @@ pub const Response = struct { const json_value = args.nextEat() orelse JSC.JSValue.zero; - if (@enumToInt(json_value) != 0) { + if (@intFromEnum(json_value) != 0) { var zig_str = JSC.ZigString.init(""); // calling JSON.stringify on an empty string adds extra quotes // so this is correct @@ -448,7 +448,7 @@ pub const Response = struct { const url_string_value = args.nextEat() orelse JSC.JSValue.zero; var url_string = ZigString.init(""); - if (@enumToInt(url_string_value) != 0) { + if (@intFromEnum(url_string_value) != 0) { url_string = url_string_value.getZigString(globalThis.ptr()); } var url_string_slice = url_string.toSlice(getAllocator(globalThis)); @@ -777,15 +777,15 @@ pub const Fetch = struct { } const fetch_error = JSC.SystemError{ - .code = ZigString.init(@errorName(this.result.fail)), + .code = bun.String.static(@errorName(this.result.fail)), .message = switch (this.result.fail) { - error.ConnectionClosed => ZigString.init("The socket connection was closed unexpectedly. For more information, pass `verbose: true` in the second argument to fetch()"), - error.FailedToOpenSocket => ZigString.init("Was there a typo in the url or port?"), - error.TooManyRedirects => ZigString.init("The response redirected too many times. For more information, pass `verbose: true` in the second argument to fetch()"), - error.ConnectionRefused => ZigString.init("Unable to connect. Is the computer able to access the url?"), - else => ZigString.init("fetch() failed. For more information, pass `verbose: true` in the second argument to fetch()"), + error.ConnectionClosed => bun.String.static("The socket connection was closed unexpectedly. For more information, pass `verbose: true` in the second argument to fetch()"), + error.FailedToOpenSocket => bun.String.static("Was there a typo in the url or port?"), + error.TooManyRedirects => bun.String.static("The response redirected too many times. For more information, pass `verbose: true` in the second argument to fetch()"), + error.ConnectionRefused => bun.String.static("Unable to connect. Is the computer able to access the url?"), + else => bun.String.static("fetch() failed. For more information, pass `verbose: true` in the second argument to fetch()"), }, - .path = ZigString.init(this.http.?.url.href), + .path = bun.String.create(this.http.?.url.href), }; return fetch_error.toErrorInstance(this.global_this); @@ -1147,9 +1147,9 @@ pub const Fetch = struct { JSC.JSError(bun.default_allocator, "Out of memory", .{}, ctx, exception); return .zero; }; - @memcpy(buffer.ptr, url_slice.ptr, url_slice.len); + @memcpy(buffer[0..url_slice.len], url_slice); var proxy_url_slice = buffer[url_slice.len..]; - @memcpy(proxy_url_slice.ptr, proxy_url_zig.ptr, proxy_url_zig.len); + @memcpy(proxy_url_slice[0..proxy_url_zig.len], proxy_url_zig.ptr[0..proxy_url_zig.len]); url = ZigURL.parse(buffer[0..url_slice.len]); proxy = ZigURL.parse(proxy_url_slice); @@ -1283,9 +1283,9 @@ pub const Fetch = struct { JSC.JSError(bun.default_allocator, "Out of memory", .{}, ctx, exception); return .zero; }; - @memcpy(buffer.ptr, url_slice.ptr, url_slice.len); + @memcpy(buffer[0..url_slice.len], url_slice.ptr[0..url_slice.len]); var proxy_url_slice = buffer[url_slice.len..]; - @memcpy(proxy_url_slice.ptr, proxy_url_zig.ptr, proxy_url_zig.len); + @memcpy(proxy_url_slice[0..proxy_url_zig.len], proxy_url_zig.ptr[0..proxy_url_zig.len]); url = ZigURL.parse(buffer[0..url_slice.len]); proxy = ZigURL.parse(proxy_url_slice); @@ -1695,7 +1695,7 @@ pub const FetchEvent = struct { defer { if (!VirtualMachine.get().had_errors) { - Output.printElapsed(@intToFloat(f64, (request_context.timer.lap())) / std.time.ns_per_ms); + Output.printElapsed(@floatFromInt(f64, (request_context.timer.lap())) / std.time.ns_per_ms); Output.prettyError( " <b>{s}<r><d> - <b>{d}<r> <d>transpiled, <d><b>{d}<r> <d>imports<r>\n", diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig index dddfcbaf5..343ce37ab 100644 --- a/src/bun.js/webcore/streams.zig +++ b/src/bun.js/webcore/streams.zig @@ -247,7 +247,7 @@ pub const ReadableStream = struct { pub fn fromNative(globalThis: *JSGlobalObject, id: Tag, ptr: *anyopaque) JSC.JSValue { JSC.markBinding(@src()); - return ZigGlobalObject__createNativeReadableStream(globalThis, JSValue.fromPtr(ptr), JSValue.jsNumber(@enumToInt(id))); + return ZigGlobalObject__createNativeReadableStream(globalThis, JSValue.fromPtr(ptr), JSValue.jsNumber(@intFromEnum(id))); } pub fn fromBlob(globalThis: *JSGlobalObject, blob: *const Blob, recommended_chunk_size: Blob.SizeType) JSC.JSValue { @@ -329,11 +329,11 @@ pub const ReadableStream = struct { const filedes_ = @bitCast([8]u8, @as(usize, @truncate(u56, @intCast(usize, filedes)))); bytes[1..8].* = filedes_[0..7].*; - return @intToEnum(StreamTag, @bitCast(u64, bytes)); + return @enumFromInt(StreamTag, @bitCast(u64, bytes)); } pub fn fd(this: StreamTag) bun.FileDescriptor { - var bytes = @bitCast([8]u8, @enumToInt(this)); + var bytes = @bitCast([8]u8, @intFromEnum(this)); if (bytes[0] != 1) { return bun.invalid_fd; } @@ -780,13 +780,15 @@ pub const StreamResult = union(Tag) { .temporary => |temp| { var array = JSC.JSValue.createUninitializedUint8Array(globalThis, temp.len); var slice_ = array.asArrayBuffer(globalThis).?.slice(); - @memcpy(slice_.ptr, temp.ptr, temp.len); + const temp_slice = temp.slice(); + @memcpy(slice_[0..temp_slice.len], temp_slice); return array; }, .temporary_and_done => |temp| { var array = JSC.JSValue.createUninitializedUint8Array(globalThis, temp.len); var slice_ = array.asArrayBuffer(globalThis).?.slice(); - @memcpy(slice_.ptr, temp.ptr, temp.len); + const temp_slice = temp.slice(); + @memcpy(slice_[0..temp_slice.len], temp_slice); return array; }, .into_array => |array| { @@ -818,7 +820,7 @@ pub const Signal = struct { ptr: *anyopaque = dead, vtable: VTable = VTable.Dead, - pub const dead = @intToPtr(*anyopaque, 0xaaaaaaaa); + pub const dead = @ptrFromInt(*anyopaque, 0xaaaaaaaa); pub fn clear(this: *Signal) void { this.ptr = dead; @@ -920,7 +922,7 @@ pub const Sink = struct { used: bool = false, pub const pending = Sink{ - .ptr = @intToPtr(*anyopaque, 0xaaaaaaaa), + .ptr = @ptrFromInt(*anyopaque, 0xaaaaaaaa), .vtable = undefined, }; @@ -961,7 +963,8 @@ pub const Sink = struct { if (stack_size >= str.len) { var buf: [stack_size]u8 = undefined; - @memcpy(&buf, str.ptr, str.len); + @memcpy(buf[0..str.len], str); + strings.replaceLatin1WithUTF8(buf[0..str.len]); if (input.isDone()) { const result = writeFn(ctx, .{ .temporary_and_done = bun.ByteList.init(buf[0..str.len]) }); @@ -974,7 +977,8 @@ pub const Sink = struct { { var slice = bun.default_allocator.alloc(u8, str.len) catch return .{ .err = Syscall.Error.oom }; - @memcpy(slice.ptr, str.ptr, str.len); + @memcpy(slice[0..str.len], str); + strings.replaceLatin1WithUTF8(slice[0..str.len]); if (input.isDone()) { return writeFn(ctx, .{ .owned_and_done = bun.ByteList.init(slice) }); @@ -1262,7 +1266,7 @@ pub const FileSink = struct { const initial_remain = remain; defer { - std.debug.assert(total - initial == @ptrToInt(remain.ptr) - @ptrToInt(initial_remain.ptr)); + std.debug.assert(total - initial == @intFromPtr(remain.ptr) - @intFromPtr(initial_remain.ptr)); if (remain.len == 0) { this.head = 0; @@ -1908,15 +1912,15 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type { pub fn init(cpp: JSValue) Signal { // this one can be null @setRuntimeSafety(false); - return Signal.initWithType(SinkSignal, @intToPtr(*SinkSignal, @bitCast(usize, @enumToInt(cpp)))); + return Signal.initWithType(SinkSignal, @ptrFromInt(*SinkSignal, @bitCast(usize, @intFromEnum(cpp)))); } pub fn close(this: *@This(), _: ?Syscall.Error) void { - onClose(@bitCast(SinkSignal, @ptrToInt(this)).cpp, JSValue.jsUndefined()); + onClose(@bitCast(SinkSignal, @intFromPtr(this)).cpp, JSValue.jsUndefined()); } pub fn ready(this: *@This(), _: ?Blob.SizeType, _: ?Blob.SizeType) void { - onReady(@bitCast(SinkSignal, @ptrToInt(this)).cpp, JSValue.jsUndefined(), JSValue.jsUndefined()); + onReady(@bitCast(SinkSignal, @intFromPtr(this)).cpp, JSValue.jsUndefined(), JSValue.jsUndefined()); } pub fn start(_: *@This()) void {} @@ -1960,10 +1964,10 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type { pub const message = std.fmt.comptimePrint("{s} is not constructable", .{SinkType.name}); }; const err = JSC.SystemError{ - .message = ZigString.init(Static.message), - .code = ZigString.init(@as(string, @tagName(JSC.Node.ErrorCode.ERR_ILLEGAL_CONSTRUCTOR))), + .message = bun.String.static(Static.message), + .code = bun.String.static(@as(string, @tagName(JSC.Node.ErrorCode.ERR_ILLEGAL_CONSTRUCTOR))), }; - globalThis.vm().throwError(globalThis, err.toErrorInstance(globalThis)); + globalThis.throwValue(err.toErrorInstance(globalThis)); return JSC.JSValue.jsUndefined(); } @@ -1992,7 +1996,7 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type { if (this.sink.signal.isDead()) return; this.sink.signal.clear(); - const value = @intToEnum(JSValue, @bitCast(JSC.JSValueReprInt, @ptrToInt(ptr))); + const value = @enumFromInt(JSValue, @bitCast(JSC.JSValueReprInt, @intFromPtr(ptr))); value.unprotect(); detachPtr(value); } @@ -3127,7 +3131,7 @@ pub const ByteBlobLoader = struct { this.remain -|= copied; this.offset +|= copied; std.debug.assert(buffer.ptr != temporary.ptr); - @memcpy(buffer.ptr, temporary.ptr, temporary.len); + @memcpy(buffer[0..temporary.len], temporary); if (this.remain == 0) { return .{ .into_array_and_done = .{ .value = array, .len = copied } }; } @@ -3231,7 +3235,7 @@ pub const ByteStream = struct { } if (this.has_received_last_chunk) { - return .{ .chunk_size = @truncate(Blob.SizeType, @min(1024 * 1024 * 2, this.buffer.items.len)) }; + return .{ .chunk_size = @min(1024 * 1024 * 2, this.buffer.items.len) }; } if (this.highWaterMark == 0) { @@ -3292,7 +3296,7 @@ pub const ByteStream = struct { var to_copy = this.pending_buffer[0..@min(chunk.len, this.pending_buffer.len)]; const pending_buffer_len = this.pending_buffer.len; std.debug.assert(to_copy.ptr != chunk.ptr); - @memcpy(to_copy.ptr, chunk.ptr, to_copy.len); + @memcpy(to_copy, chunk[0..to_copy.len]); this.pending_buffer = &.{}; const is_really_done = this.has_received_last_chunk and to_copy.len <= pending_buffer_len; @@ -3382,7 +3386,7 @@ pub const ByteStream = struct { ); var remaining_in_buffer = this.buffer.items[this.offset..][0..to_write]; - @memcpy(buffer.ptr, this.buffer.items.ptr + this.offset, to_write); + @memcpy(buffer[0..to_write], this.buffer.items[this.offset..][0..to_write]); if (this.offset + to_write == this.buffer.items.len) { this.offset = 0; @@ -4071,7 +4075,7 @@ pub const File = struct { this.pending.result = .{ .err = Syscall.Error{ // this is too hacky - .errno = @truncate(Syscall.Error.Int, @intCast(u16, @max(1, @errorToInt(err)))), + .errno = @truncate(Syscall.Error.Int, @intCast(u16, @max(1, @intFromError(err)))), .syscall = .read, }, }; @@ -4655,4 +4659,3 @@ pub fn NewReadyWatcher( // pub fn onError(this: *Streamer): anytype, // }; // } - |