diff --git a/build.zig b/build.zig index e7dfcb2e1f..3d5c0b659f 100644 --- a/build.zig +++ b/build.zig @@ -200,7 +200,10 @@ pub fn build(b: *Build) !void { b.option([]const u8, "codegen_path", "Set the generated code directory") orelse "build/debug/codegen", ); - const codegen_embed = b.option(bool, "codegen_embed", "If codegen files should be embedded in the binary") orelse false; + const codegen_embed = b.option(bool, "codegen_embed", "If codegen files should be embedded in the binary") orelse switch (b.release_mode) { + .off => false, + else => true, + }; const bun_version = b.option([]const u8, "version", "Value of `Bun.version`") orelse "0.0.0"; @@ -527,36 +530,36 @@ fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void { .{ .file = "ZigGeneratedClasses.zig", .import = "ZigGeneratedClasses" }, .{ .file = "ResolvedSourceTag.zig", .import = "ResolvedSourceTag" }, .{ .file = "ErrorCode.zig", .import = "ErrorCode" }, - .{ .file = "runtime.out.js" }, + .{ .file = "runtime.out.js", .enable = opts.shouldEmbedCode() }, .{ .file = "bake.client.js", .import = "bake-codegen/bake.client.js", .enable = opts.shouldEmbedCode() }, .{ .file = "bake.error.js", .import = "bake-codegen/bake.error.js", .enable = opts.shouldEmbedCode() }, .{ .file = "bake.server.js", .import = "bake-codegen/bake.server.js", .enable = opts.shouldEmbedCode() }, .{ .file = "bun-error/index.js", .enable = opts.shouldEmbedCode() }, .{ .file = "bun-error/bun-error.css", .enable = opts.shouldEmbedCode() }, .{ .file = "fallback-decoder.js", .enable = opts.shouldEmbedCode() }, - .{ .file = "node-fallbacks/assert.js" }, - .{ .file = "node-fallbacks/buffer.js" }, - .{ .file = "node-fallbacks/console.js" }, - .{ .file = "node-fallbacks/constants.js" }, - .{ .file = "node-fallbacks/crypto.js" }, - .{ .file = "node-fallbacks/domain.js" }, - .{ .file = "node-fallbacks/events.js" }, - .{ .file = "node-fallbacks/http.js" }, - .{ .file = "node-fallbacks/https.js" }, - .{ .file = "node-fallbacks/net.js" }, - .{ .file = "node-fallbacks/os.js" }, - .{ .file = "node-fallbacks/path.js" }, - .{ .file = "node-fallbacks/process.js" }, - .{ .file = "node-fallbacks/punycode.js" }, - .{ .file = "node-fallbacks/querystring.js" }, - .{ .file = "node-fallbacks/stream.js" }, - .{ .file = "node-fallbacks/string_decoder.js" }, - .{ .file = "node-fallbacks/sys.js" }, - .{ .file = "node-fallbacks/timers.js" }, - .{ .file = "node-fallbacks/tty.js" }, - .{ .file = "node-fallbacks/url.js" }, - .{ .file = "node-fallbacks/util.js" }, - .{ .file = "node-fallbacks/zlib.js" }, + .{ .file = "node-fallbacks/assert.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/buffer.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/console.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/constants.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/crypto.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/domain.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/events.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/http.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/https.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/net.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/os.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/path.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/process.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/punycode.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/querystring.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/stream.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/string_decoder.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/sys.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/timers.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/tty.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/url.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/util.js", .enable = opts.shouldEmbedCode() }, + .{ .file = "node-fallbacks/zlib.js", .enable = opts.shouldEmbedCode() }, }) |entry| { if (!@hasField(@TypeOf(entry), "enable") or entry.enable) { const path = b.pathJoin(&.{ opts.codegen_path, entry.file }); diff --git a/entitlements.debug.plist b/entitlements.debug.plist index ab2dcf4b47..4e35ad7543 100644 --- a/entitlements.debug.plist +++ b/entitlements.debug.plist @@ -2,19 +2,19 @@ - com.apple.security.cs.allow-jit - - com.apple.security.cs.allow-unsigned-executable-memory - - com.apple.security.cs.disable-executable-page-protection - - com.apple.security.cs.allow-dyld-environment-variables - - com.apple.security.cs.disable-library-validation - - com.apple.security.get-task-allow - - com.apple.security.cs.debugger - + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-executable-page-protection + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.cs.disable-library-validation + + com.apple.security.get-task-allow + + com.apple.security.cs.debugger + - + \ No newline at end of file diff --git a/packages/bun-types/bun.d.ts b/packages/bun-types/bun.d.ts index a2c2cc914f..907883f47a 100644 --- a/packages/bun-types/bun.d.ts +++ b/packages/bun-types/bun.d.ts @@ -1233,13 +1233,13 @@ declare module "bun" { /** * Deletes the file. ( same as unlink ) - */ - delete(): Promise + */ + delete(): Promise; /** * Provides useful information about the file. - */ - stat(): Promise + */ + stat(): Promise; } interface NetworkSink extends FileSink { /** diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig index dcb8327de4..fe13ad97fb 100644 --- a/src/bun.js/module_loader.zig +++ b/src/bun.js/module_loader.zig @@ -2496,7 +2496,7 @@ pub const ModuleLoader = struct { if (specifier.eqlComptime(Runtime.Runtime.Imports.Name)) { return ResolvedSource{ .allocator = null, - .source_code = String.init(Runtime.Runtime.source_code), + .source_code = String.init(Runtime.Runtime.sourceCode()), .specifier = specifier, .source_url = specifier, .hash = Runtime.Runtime.versionHash(), diff --git a/src/codegen/bake-codegen.ts b/src/codegen/bake-codegen.ts index c38993061c..a48fbaae4e 100644 --- a/src/codegen/bake-codegen.ts +++ b/src/codegen/bake-codegen.ts @@ -1,7 +1,7 @@ import assert from "node:assert"; -import { existsSync, writeFileSync, rmSync, readFileSync } from "node:fs"; +import { existsSync, readFileSync, rmSync } from "node:fs"; import { basename, join } from "node:path"; -import { argParse } from "./helpers"; +import { argParse, writeIfNotChanged } from "./helpers"; // arg parsing let { "codegen-root": codegenRoot, debug, ...rest } = argParse(["codegen-root", "debug"]); @@ -28,7 +28,7 @@ function convertZigEnum(zig: string) { async function run() { const devServerZig = readFileSync(join(base_dir, "DevServer.zig"), "utf-8"); - writeFileSync(join(base_dir, "generated.ts"), convertZigEnum(devServerZig)); + writeIfNotChanged(join(base_dir, "generated.ts"), convertZigEnum(devServerZig)); const results = await Promise.allSettled( ["client", "server", "error"].map(async file => { @@ -69,7 +69,7 @@ async function run() { `; const generated_entrypoint = join(base_dir, `.runtime-${file}.generated.ts`); - writeFileSync(generated_entrypoint, combined_source); + writeIfNotChanged(generated_entrypoint, combined_source); result = await Bun.build({ entrypoints: [generated_entrypoint], @@ -124,7 +124,7 @@ async function run() { } } - writeFileSync(join(codegenRoot, `bake.${file}.js`), code); + writeIfNotChanged(join(codegenRoot, `bake.${file}.js`), code); }), ); @@ -169,7 +169,7 @@ async function run() { console.log("-> bake.client.js, bake.server.js, bake.error.js"); const empty_file = join(codegenRoot, "bake_empty_file"); - if (!existsSync(empty_file)) writeFileSync(empty_file, "this is used to fulfill a cmake dependency"); + if (!existsSync(empty_file)) writeIfNotChanged(empty_file, "this is used to fulfill a cmake dependency"); } } diff --git a/src/js/node/stream.ts b/src/js/node/stream.ts index 49433352a4..fd12678fb2 100644 --- a/src/js/node/stream.ts +++ b/src/js/node/stream.ts @@ -5258,18 +5258,10 @@ function createNativeStreamReadable(Readable) { var handleNumberResult = function (nativeReadable, result, view, isClosed) { if (result > 0) { const slice = view.subarray(0, result); - const remainder = view.subarray(result); + view = slice.byteLength < view.byteLength ? view.subarray(result) : undefined; if (slice.byteLength > 0) { nativeReadable.push(slice); } - - if (isClosed) { - ProcessNextTick(() => { - nativeReadable.push(null); - }); - } - - return remainder.byteLength > 0 ? remainder : undefined; } if (isClosed) { diff --git a/src/node_fallbacks.zig b/src/node_fallbacks.zig index 89998d3a13..ae9785e7d0 100644 --- a/src/node_fallbacks.zig +++ b/src/node_fallbacks.zig @@ -17,7 +17,24 @@ comptime { pub const FallbackModule = struct { path: Fs.Path, package_json: *const PackageJSON, - code: string, + code: *const fn () string, + + // This workaround exists to allow bun.runtimeEmbedFile to work. + // Using `@embedFile` forces you to wait for the Zig build to finish in + // debug builds, even when you only changed JS builtins. + fn createSourceCodeGetter(comptime code_path: string) *const fn () string { + const Getter = struct { + fn get() string { + if (bun.Environment.codegen_embed) { + return @embedFile(code_path); + } + + return bun.runtimeEmbedFile(.codegen_eager, code_path); + } + }; + + return Getter.get; + } pub fn init(comptime name: string) FallbackModule { @setEvalBranchQuota(99999); @@ -35,7 +52,7 @@ pub const FallbackModule = struct { .source = logger.Source.initPathString(import_path ++ name ++ "/package.json", ""), .side_effects = .false, }, - .code = @embedFile(code_path), + .code = createSourceCodeGetter(code_path), }; } }; @@ -74,7 +91,7 @@ pub fn contentsFromPath(path: string) ?string { module_name = module_name[0 .. std.mem.indexOfScalar(u8, module_name, '/') orelse module_name.len]; if (Map.get(module_name)) |mod| { - return mod.code; + return mod.code(); } return null; diff --git a/src/runtime.zig b/src/runtime.zig index 3585fe11b0..b64cd8b7e9 100644 --- a/src/runtime.zig +++ b/src/runtime.zig @@ -149,12 +149,15 @@ pub const Fallback = struct { }; pub const Runtime = struct { - pub const source_code = @embedFile("runtime.out.js"); - pub const hash = brk: { - @setEvalBranchQuota(source_code.len * 50); - break :brk bun.Wyhash11.hash(0, source_code); - }; + pub fn sourceCode() string { + return if (Environment.codegen_embed) + @embedFile("runtime.out.js") + else + bun.runtimeEmbedFile(.src_eager, "runtime.out.js"); + } + pub fn versionHash() u32 { + const hash = bun.Wyhash11.hash(0, sourceCode()); return @truncate(hash); }