aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base64/bun-base64.c2
-rw-r--r--src/base64/fastavxbase64.c2
-rw-r--r--src/base64/fastavxbase64.h3
m---------src/bun.js/WebKit0
-rw-r--r--src/bun.js/node/syscall.zig8
-rw-r--r--src/bun.js/node/types.zig51
-rw-r--r--src/cli.zig2
-rw-r--r--src/cli/upgrade_command.zig172
-rw-r--r--src/env.zig2
-rw-r--r--src/http.zig6
-rw-r--r--src/http_client_async.zig2
-rw-r--r--src/install/install.zig56
-rw-r--r--src/runtime.footer.bun.js1
-rw-r--r--src/string_immutable.zig2
14 files changed, 267 insertions, 42 deletions
diff --git a/src/base64/bun-base64.c b/src/base64/bun-base64.c
index e11f88da5..6cf11bbe7 100644
--- a/src/base64/bun-base64.c
+++ b/src/base64/bun-base64.c
@@ -22,7 +22,7 @@ size_t bun_base64_encode(char *dest, const char *src, size_t len) {
return chromium_base64_encode(dest, src, len);
}
-#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
+#elif defined(__GNUC__) && (defined(__x86_64__) && defined(__AVX2__))
size_t bun_base64_decode(char *dest, const char *src, size_t len,
size_t *outlen) {
diff --git a/src/base64/fastavxbase64.c b/src/base64/fastavxbase64.c
index 47be824b4..305288fde 100644
--- a/src/base64/fastavxbase64.c
+++ b/src/base64/fastavxbase64.c
@@ -1,4 +1,4 @@
-#if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
+#if defined(__GNUC__) && defined(__x86_64__) && defined(__AVX2__)
#include "fastavxbase64.h"
#include <stdbool.h>
diff --git a/src/base64/fastavxbase64.h b/src/base64/fastavxbase64.h
index d1064a5d1..80f097ae8 100644
--- a/src/base64/fastavxbase64.h
+++ b/src/base64/fastavxbase64.h
@@ -1,4 +1,5 @@
-#if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
+
+#if defined(__GNUC__) && defined(__x86_64__) && defined(__AVX2__)
#ifndef EXPAVX_B64
#define EXPAVX_B64
diff --git a/src/bun.js/WebKit b/src/bun.js/WebKit
-Subproject 7e7774dabf1c2d94fe3604defb3c54a4c989c3b
+Subproject 6dd3cae7c03f061b30e09cce5da17b2e7b108ad
diff --git a/src/bun.js/node/syscall.zig b/src/bun.js/node/syscall.zig
index b931e9c0e..4378a4762 100644
--- a/src/bun.js/node/syscall.zig
+++ b/src/bun.js/node/syscall.zig
@@ -16,27 +16,29 @@ const C = @import("../../global.zig").C;
const linux = os.linux;
const Maybe = JSC.Maybe;
+// On Linux AARCh64, zig is missing stat & lstat syscalls
+const use_libc = (Environment.isLinux and Environment.isAarch64) or Environment.isMac;
pub const system = if (Environment.isLinux) linux else @import("io").darwin;
pub const S = struct {
pub usingnamespace if (Environment.isLinux) linux.S else std.os.S;
};
const sys = std.os.system;
-const statSym = if (Environment.isMac)
+const statSym = if (use_libc)
C.stat
else if (Environment.isLinux)
linux.stat
else
@compileError("STAT");
-const fstatSym = if (Environment.isMac)
+const fstatSym = if (use_libc)
C.fstat
else if (Environment.isLinux)
linux.fstat
else
@compileError("STAT");
-const lstat64 = if (Environment.isMac)
+const lstat64 = if (use_libc)
C.lstat
else if (Environment.isLinux)
linux.lstat
diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig
index 2e704037e..18d437d76 100644
--- a/src/bun.js/node/types.zig
+++ b/src/bun.js/node/types.zig
@@ -797,7 +797,7 @@ pub const FileSystemFlags = enum(Mode) {
}
};
-/// Milliseconds precision
+/// Milliseconds precision
pub const Date = enum(u64) {
_,
@@ -818,12 +818,27 @@ fn StatsLike(comptime name: [:0]const u8, comptime T: type) type {
This,
.{ .name = name },
.{
- .isFile = .{
- .rfn = JSC.wrap(This, "isFile", false),
+ .isBlockDevice = .{
+ .rfn = JSC.wrap(This, "isBlockDevice", false),
+ },
+ .isCharacterDevice = .{
+ .rfn = JSC.wrap(This, "isCharacterDevice", false),
},
.isDirectory = .{
.rfn = JSC.wrap(This, "isDirectory", false),
},
+ .isFIFO = .{
+ .rfn = JSC.wrap(This, "isFIFO", false),
+ },
+ .isFile = .{
+ .rfn = JSC.wrap(This, "isFile", false),
+ },
+ .isSocket = .{
+ .rfn = JSC.wrap(This, "isSocket", false),
+ },
+ .isSymbolicLink = .{
+ .rfn = JSC.wrap(This, "isSymbolicLink", false),
+ },
.finalize = finalize,
},
.{
@@ -957,13 +972,39 @@ fn StatsLike(comptime name: [:0]const u8, comptime T: type) type {
};
}
- pub fn isFile(this: *Stats) JSC.JSValue {
- return JSC.JSValue.jsBoolean(os.S.ISREG(@intCast(Mode, this.mode)));
+ pub fn isBlockDevice(this: *Stats) JSC.JSValue {
+ return JSC.JSValue.jsBoolean(os.S.ISBLK(@intCast(Mode, this.mode)));
+ }
+
+ pub fn isCharacterDevice(this: *Stats) JSC.JSValue {
+ return JSC.JSValue.jsBoolean(os.S.ISCHR(@intCast(Mode, this.mode)));
}
+
pub fn isDirectory(this: *Stats) JSC.JSValue {
return JSC.JSValue.jsBoolean(os.S.ISDIR(@intCast(Mode, this.mode)));
}
+ pub fn isFIFO(this: *Stats) JSC.JSValue {
+ return JSC.JSValue.jsBoolean(os.S.ISFIFO(@intCast(Mode, this.mode)));
+ }
+
+ pub fn isFile(this: *Stats) JSC.JSValue {
+ return JSC.JSValue.jsBoolean(os.S.ISREG(@intCast(Mode, this.mode)));
+ }
+
+ pub fn isSocket(this: *Stats) JSC.JSValue {
+ return JSC.JSValue.jsBoolean(os.S.ISSOCK(@intCast(Mode, this.mode)));
+ }
+
+ // Node.js says this method is only valid on the result of lstat()
+ // so it's fine if we just include it on stat() because it would
+ // still just return false.
+ //
+ // See https://nodejs.org/api/fs.html#statsissymboliclink
+ pub fn isSymbolicLink(this: *Stats) JSC.JSValue {
+ return JSC.JSValue.jsBoolean(os.S.ISLNK(@intCast(Mode, this.mode)));
+ }
+
pub fn toJS(this: Stats, ctx: JSC.C.JSContextRef, _: JSC.C.ExceptionRef) JSC.C.JSValueRef {
var _this = bun.default_allocator.create(Stats) catch unreachable;
_this.* = this;
diff --git a/src/cli.zig b/src/cli.zig
index 7bdf75dbb..e849d258f 100644
--- a/src/cli.zig
+++ b/src/cli.zig
@@ -55,7 +55,7 @@ const UpgradeCommand = @import("./cli/upgrade_command.zig").UpgradeCommand;
const MacroMap = @import("./resolver/package_json.zig").MacroMap;
const Reporter = @import("./report.zig");
-var start_time: i128 = undefined;
+pub var start_time: i128 = undefined;
const Bunfig = @import("./bunfig.zig").Bunfig;
pub const Cli = struct {
diff --git a/src/cli/upgrade_command.zig b/src/cli/upgrade_command.zig
index a64985bbb..fd101d775 100644
--- a/src/cli/upgrade_command.zig
+++ b/src/cli/upgrade_command.zig
@@ -56,17 +56,35 @@ pub const Version = struct {
size: u32 = 0,
pub fn name(this: Version) ?string {
- if (this.tag.len > "bun-v".len and strings.eqlComptime(this.tag[0.."bun-v".len], "bun-v")) {
- return this.tag[("bun-v".len)..];
- } else {
- return null;
+ if (this.tag.len <= "bun-v".len or !strings.hasPrefixComptime(this.tag, "bun-v")) {
+ if (strings.eqlComptime(this.tag, "canary")) {
+ const Cli = @import("../cli.zig");
+
+ return std.fmt.allocPrint(
+ bun.default_allocator,
+ "bun-canary-timestamp-{any}",
+ .{
+ std.fmt.fmtSliceHexLower(
+ std.mem.asBytes(
+ &bun.hash(
+ std.mem.asBytes(&Cli.start_time),
+ ),
+ ),
+ ),
+ },
+ ) catch unreachable;
+ }
+ return this.tag;
}
+
+ return this.tag["bun-v".len..];
}
pub const platform_label = if (Environment.isMac) "darwin" else "linux";
pub const arch_label = if (Environment.isAarch64) "aarch64" else "x64";
pub const triplet = platform_label ++ "-" ++ arch_label;
- pub const folder_name = "bun-" ++ triplet;
+ const suffix = if (Environment.baseline) "-baseline" else "";
+ pub const folder_name = "bun-" ++ triplet ++ suffix;
pub const zip_filename = folder_name ++ ".zip";
const current_version: string = "bun-v" ++ Global.package_json_version;
@@ -79,7 +97,10 @@ pub const Version = struct {
pub const UpgradeCheckerThread = struct {
var update_checker_thread: std.Thread = undefined;
pub fn spawn(env_loader: *DotEnv.Loader) void {
- if (env_loader.map.get("BUN_DISABLE_UPGRADE_CHECK") != null or env_loader.map.get("CI") != null) return;
+ if (env_loader.map.get("BUN_DISABLE_UPGRADE_CHECK") != null or
+ env_loader.map.get("CI") != null or
+ strings.eqlComptime(env_loader.get("BUN_CANARY") orelse "0", "1"))
+ return;
update_checker_thread = std.Thread.spawn(.{}, run, .{env_loader}) catch return;
update_checker_thread.detach();
}
@@ -352,12 +373,14 @@ pub const UpgradeCommand = struct {
break :brk DotEnv.Loader.init(map, ctx.allocator);
};
-
env_loader.loadProcess();
var version: Version = undefined;
+ const use_canary = strings.eqlComptime(env_loader.map.get("BUN_CANARY") orelse "0", "1") or
+ // TODO: add separate args just for "bun upgrade"?
+ strings.containsAny(bun.span(std.os.argv), "--canary");
- {
+ if (!use_canary) {
var refresher = std.Progress{};
var progress = refresher.start("Fetching version tags", 0);
@@ -383,12 +406,19 @@ pub const UpgradeCommand = struct {
);
Global.exit(1);
}
- }
- {
Output.prettyErrorln("<r><b>bun <cyan>v{s}<r> is out<r>! You're on <blue>{s}<r>\n", .{ version.name().?, Global.package_json_version });
Output.flush();
+ } else {
+ version = Version{
+ .tag = "canary",
+ .zip_url = "https://github.com/oven-sh/bun/releases/download/canary/" ++ Version.zip_filename,
+ .size = 0,
+ .buf = MutableString.initEmpty(bun.default_allocator),
+ };
+ }
+ {
var refresher = std.Progress{};
var progress = refresher.start("Downloading", version.size);
refresher.refresh();
@@ -412,7 +442,22 @@ pub const UpgradeCommand = struct {
const response = try async_http.sendSync(true);
switch (response.status_code) {
- 404 => return error.HTTP404,
+ 404 => {
+ if (use_canary) {
+ Output.prettyErrorln(
+ \\<r><red>error:<r> Canary builds are not available for this platform yet
+ \\
+ \\ Release: <cyan>https://github.com/oven-sh/bun/releases/tag/canary<r>
+ \\ Filename: <b>{s}<r>
+ \\
+ , .{
+ Version.zip_filename,
+ });
+ Global.exit(1);
+ }
+
+ return error.HTTP404;
+ },
403 => return error.HTTPForbidden,
429 => return error.HTTPTooManyRequests,
499...599 => return error.GitHubIsDown,
@@ -502,7 +547,6 @@ pub const UpgradeCommand = struct {
Global.exit(1);
}
}
-
{
var verify_argv = [_]string{
exe_subpath,
@@ -526,17 +570,21 @@ pub const UpgradeCommand = struct {
Global.exit(1);
}
- if (!strings.eql(std.mem.trim(u8, result.stdout, " \n\r\t"), version_name)) {
- save_dir_.deleteTree(version_name) catch {};
-
- Output.prettyErrorln(
- "<r><red>error<r>: The downloaded version of bun (<red>{s}<r>) doesn't match the expected version (<b>{s}<r>)<r>. Cancelled upgrade",
- .{
- result.stdout[0..@minimum(result.stdout.len, 128)],
- version_name,
- },
- );
- Global.exit(1);
+ // It should run successfully
+ // but we don't care about the version number if we're doing a canary build
+ if (!use_canary) {
+ if (!strings.eql(std.mem.trim(u8, result.stdout, " \n\r\t"), version_name)) {
+ save_dir_.deleteTree(version_name) catch {};
+
+ Output.prettyErrorln(
+ "<r><red>error<r>: The downloaded version of bun (<red>{s}<r>) doesn't match the expected version (<b>{s}<r>)<r>. Cancelled upgrade",
+ .{
+ result.stdout[0..@minimum(result.stdout.len, 128)],
+ version_name,
+ },
+ );
+ Global.exit(1);
+ }
}
}
@@ -555,6 +603,47 @@ pub const UpgradeCommand = struct {
Global.exit(1);
};
+ if (use_canary) {
+
+ // Check if the versions are the same
+ const target_stat = target_dir.statFile(target_filename) catch |err| {
+ save_dir_.deleteTree(version_name) catch {};
+ Output.prettyErrorln("<r><red>error:<r> Failed to stat target bun {s}", .{@errorName(err)});
+ Global.exit(1);
+ };
+
+ const dest_stat = save_dir.statFile(exe_subpath) catch |err| {
+ save_dir_.deleteTree(version_name) catch {};
+ Output.prettyErrorln("<r><red>error:<r> Failed to stat source bun {s}", .{@errorName(err)});
+ Global.exit(1);
+ };
+
+ if (target_stat.size == dest_stat.size and target_stat.size > 0) {
+ var input_buf = try ctx.allocator.alloc(u8, target_stat.size);
+
+ const target_hash = std.hash.Wyhash.hash(0, target_dir.readFile(target_filename, input_buf) catch |err| {
+ save_dir_.deleteTree(version_name) catch {};
+ Output.prettyErrorln("<r><red>error:<r> Failed to read target bun {s}", .{@errorName(err)});
+ Global.exit(1);
+ });
+
+ const source_hash = std.hash.Wyhash.hash(0, save_dir.readFile(exe_subpath, input_buf) catch |err| {
+ save_dir_.deleteTree(version_name) catch {};
+ Output.prettyErrorln("<r><red>error:<r> Failed to read source bun {s}", .{@errorName(err)});
+ Global.exit(1);
+ });
+
+ if (target_hash == source_hash) {
+ save_dir_.deleteTree(version_name) catch {};
+ Output.prettyErrorln(
+ "<r><green>Congrats!<r> You're already on the latest canary build of bun",
+ .{},
+ );
+ Global.exit(0);
+ }
+ }
+ }
+
if (env_loader.map.get("BUN_DRY_RUN") == null) {
C.moveFileZ(save_dir.fd, exe_subpath, target_dir.fd, target_filename) catch |err| {
save_dir_.deleteTree(version_name) catch {};
@@ -583,7 +672,42 @@ pub const UpgradeCommand = struct {
Output.printStartEnd(ctx.start_time, std.time.nanoTimestamp());
- Output.prettyErrorln("<r> Upgraded.\n\n<b><green>Welcome to bun v{s}!<r>\n\n Report any bugs:\n https://github.com/oven-sh/bun/issues\n\n What's new:\n https://github.com/oven-sh/bun/releases/tag/{s}<r>", .{ version_name, version.tag });
+ if (use_canary) {
+ Output.prettyErrorln(
+ \\<r> Upgraded.
+ \\
+ \\<b><green>Welcome to bun's latest canary build!<r>
+ \\
+ \\Report any bugs:
+ \\
+ \\ https://github.com/oven-sh/bun/issues
+ \\
+ \\What's new:
+ \\
+ \\ <cyan>https://github.com/oven-sh/bun/releases/tag/{s}<r>
+ \\
+ ,
+ .{version.tag},
+ );
+ } else {
+ Output.prettyErrorln(
+ \\<r> Upgraded.
+ \\
+ \\<b><green>Welcome to bun v{s}!<r>
+ \\
+ \\Report any bugs:
+ \\
+ \\ https://github.com/oven-sh/bun/issues
+ \\
+ \\What's new:
+ \\
+ \\ <cyan>https://github.com/oven-sh/bun/releases/tag/{s}<r>
+ \\
+ ,
+ .{ version_name, version.tag },
+ );
+ }
+
Output.flush();
return;
}
diff --git a/src/env.zig b/src/env.zig
index 0e4cbc414..aa0a6de86 100644
--- a/src/env.zig
+++ b/src/env.zig
@@ -25,4 +25,4 @@ pub const isX86 = @import("builtin").target.cpu.arch.isX86();
pub const isX64 = @import("builtin").target.cpu.arch == .x86_64;
pub const allow_assert = isDebug or isTest;
pub const analytics_url = if (isDebug) "http://localhost:4000/events" else "http://i.bun.sh/events";
-pub const simd = isX86 or isAarch64;
+pub const baseline = @import("build_options").baseline;
diff --git a/src/http.zig b/src/http.zig
index 1515f976f..605bd1840 100644
--- a/src/http.zig
+++ b/src/http.zig
@@ -1881,9 +1881,9 @@ pub const RequestContext = struct {
var reloader = Api.Reloader.disable;
if (ctx.bundler.options.hot_module_reloading) {
reloader = Api.Reloader.live;
- // if (ctx.bundler.options.jsx.supports_fast_refresh) {
- // reloader = Api.Reloader.fast_refresh;
- // }
+ if (ctx.bundler.options.jsx.supports_fast_refresh and ctx.bundler.env.get("BUN_FORCE_HMR") != null) {
+ reloader = Api.Reloader.fast_refresh;
+ }
}
const welcome_message = Api.WebsocketMessageWelcome{
diff --git a/src/http_client_async.zig b/src/http_client_async.zig
index 2da75b652..7b376c986 100644
--- a/src/http_client_async.zig
+++ b/src/http_client_async.zig
@@ -56,6 +56,8 @@ pub fn onThreadStart(_: ?*anyopaque) ?*anyopaque {
\\ <cyan>wsl --update<r>
\\ <cyan>wsl --shutdown<r>
\\
+ \\ Please make sure you're using WSL version 2 (not WSL 1).
+ \\
\\If that doesn't work (and you're on a Windows machine), try this:
\\ 1. Open Windows Update
\\ 2. Download any updates to Windows Subsystem for Linux
diff --git a/src/install/install.zig b/src/install/install.zig
index 8ae032022..7373cf90d 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -199,7 +199,61 @@ const NetworkTask = struct {
scope: *const Npm.Registry.Scope,
loaded_manifest: ?Npm.PackageManifest,
) !void {
- this.url_buf = try std.fmt.allocPrint(allocator, "{s}://{s}/{s}/{s}", .{ scope.url.displayProtocol(), scope.url.displayHostname(), strings.trim(scope.url.path, "/"), name });
+ const pathname: string = if (!strings.eqlComptime(scope.url.pathname, "/"))
+ scope.url.pathname
+ else
+ @as(string, "");
+
+ if (pathname.len > 0) {
+ if (scope.url.getPort()) |port_number| {
+ this.url_buf = try std.fmt.allocPrint(
+ allocator,
+ "{s}://{s}:{d}/{s}/{s}",
+ .{
+ scope.url.displayProtocol(),
+ scope.url.displayHostname(),
+ port_number,
+ pathname,
+ name,
+ },
+ );
+ } else {
+ this.url_buf = try std.fmt.allocPrint(
+ allocator,
+ "{s}://{s}/{s}/{s}",
+ .{
+ scope.url.displayProtocol(),
+ scope.url.displayHostname(),
+ pathname,
+ name,
+ },
+ );
+ }
+ } else {
+ if (scope.url.getPort()) |port_number| {
+ this.url_buf = try std.fmt.allocPrint(
+ allocator,
+ "{s}://{s}:{d}/{s}",
+ .{
+ scope.url.displayProtocol(),
+ scope.url.displayHostname(),
+ port_number,
+ name,
+ },
+ );
+ } else {
+ this.url_buf = try std.fmt.allocPrint(
+ allocator,
+ "{s}://{s}/{s}",
+ .{
+ scope.url.displayProtocol(),
+ scope.url.displayHostname(),
+ name,
+ },
+ );
+ }
+ }
+
var last_modified: string = "";
var etag: string = "";
if (loaded_manifest) |manifest| {
diff --git a/src/runtime.footer.bun.js b/src/runtime.footer.bun.js
index 72a2703e9..a5466f53a 100644
--- a/src/runtime.footer.bun.js
+++ b/src/runtime.footer.bun.js
@@ -22,5 +22,6 @@ export var __require = (globalThis.require ||= function (moduleId) {
return BUN_RUNTIME.__require(moduleId);
});
+__require.d ||= BUN_RUNTIME.__require.d;
globalThis.__internalIsCommonJSNamespace ||=
BUN_RUNTIME.__internalIsCommonJSNamespace;
diff --git a/src/string_immutable.zig b/src/string_immutable.zig
index ec3a2ecbe..801eacd51 100644
--- a/src/string_immutable.zig
+++ b/src/string_immutable.zig
@@ -78,7 +78,7 @@ pub inline fn containsComptime(self: string, comptime str: string) bool {
pub const includes = contains;
pub inline fn containsAny(in: anytype, target: string) bool {
- for (in) |str| if (contains(str, target)) return true;
+ for (in) |str| if (contains(bun.span(str), target)) return true;
return false;
}