Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bundler): inlining/dead-code-elimination for import.meta.main (and --compile) #12867

Merged
merged 51 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
d01ebea
fix 12805
paperdave Jul 25, 2024
4b8e988
hi
paperdave Jul 26, 2024
032cf51
fix this
paperdave Jul 27, 2024
962c21b
cpp: missing uses of propertyNames (#12835)
nektro Jul 26, 2024
6f994a5
bindings: fix zig extern def of Bun__JSValue__deserialize (#12844)
nektro Jul 26, 2024
5f19e4d
ipc: make IPCInstance.context void on windows instead of u0 (#12840)
nektro Jul 26, 2024
0c032d1
uws: tidy use of ssl intFromBool (#12839)
nektro Jul 26, 2024
f432123
node:v8: expose DefaultDeserializer and DefaultSerializer exports (#1…
nektro Jul 26, 2024
56bd90f
bindings: better use of jsc api in Path_functionToNamespacedPath (#12…
nektro Jul 26, 2024
fe60dd7
use .undefined literal instead of jsUndefined() call (#12834)
nektro Jul 26, 2024
55437a7
launch.json: remove BUN_DEBUG_ALL=1 from 'bun run' (#12845)
nektro Jul 26, 2024
e643788
bump webkit (#12858)
dylan-conway Jul 26, 2024
0ea8ce3
Fix memory leak when printing any error's source code. (#12831)
paperdave Jul 26, 2024
9577ab2
Rename `JSC.Node.StringOrBuffer` -> `StringOrBuffer`
Jarred-Sumner Jul 26, 2024
ead7c64
When crash reporter is disabled also disable `resetSegfaultHanlder`
Jarred-Sumner Jul 26, 2024
ca2b20d
Configure libcpp assert to avoid macOS 13.0 issue (#12860)
Jarred-Sumner Jul 26, 2024
db806c8
fix(build): assertion failure when cross-compiling on windows (#12862)
dylan-conway Jul 27, 2024
c28f384
fix: make raiseIgnoringPanicHandler ignore the panic handler (#12578)
paperdave Jul 27, 2024
eec1767
ci: format: switch to mlugg/setup-zig (#12863)
nektro Jul 27, 2024
644c5c4
fix a bundler crash (#12864)
paperdave Jul 27, 2024
4effef3
Handle errors in node:http better (#12641)
Jarred-Sumner Jul 27, 2024
3285166
fix: check if we are crashing before exiting gracefully (#12865)
paperdave Jul 27, 2024
56acfa3
implement node:util.getSystemErrorName() (#12837)
nektro Jul 27, 2024
1d6dd3b
Slightly better error.stack (#12861)
Jarred-Sumner Jul 27, 2024
ee8f939
Bump versions of things
Jarred-Sumner Jul 27, 2024
2957aac
In debug builds on macOS, add malloc_zone_check when GC runs
Jarred-Sumner Jul 28, 2024
af581f2
textencoder: remove DOMJIT (#12868)
dylan-conway Jul 28, 2024
720448c
Fix memory leak in RuntimeTranspilerStore (#12900)
Jarred-Sumner Jul 28, 2024
5d67e7b
Use typed allocators in more places (#12899)
Jarred-Sumner Jul 29, 2024
22e080b
fix(build): use specific version of lld for link on unix (#12907)
billywhizz Jul 29, 2024
cd0306a
Fix debug build issue
Jarred-Sumner Jul 29, 2024
9316a7b
Add named allocator
Jarred-Sumner Jul 29, 2024
263a4b7
Add `BUN_FEATURE_FLAG_DISABLE_ASYNC_TRANSPILER` feature flag
Jarred-Sumner Jul 29, 2024
22238a4
Fix various Windows build issues
Jarred-Sumner Jul 29, 2024
4e5f579
Enable concurrent transpiler on Windows (#12915)
Jarred-Sumner Jul 29, 2024
a652645
Remove some dynamic memory allocations in uWebSockets (#12897)
Jarred-Sumner Jul 29, 2024
4dd7061
Enable buildkite (#12653)
Electroid Jul 29, 2024
2ce1fc5
Allow creating release builds with 'RELEASE=1'
Electroid Jul 29, 2024
cc5f659
Only upload canary artifacts when the build is canary
Electroid Jul 29, 2024
e1c76d8
Fix release script
Electroid Jul 29, 2024
e867bdc
fix edge cases
paperdave Jul 29, 2024
679f926
Merge remote-tracking branch 'origin/main' into dave/compile-import-m…
paperdave Jul 30, 2024
9b8100b
fix submodule
paperdave Jul 30, 2024
c264884
oops
paperdave Jul 30, 2024
6ceca86
oops
paperdave Jul 30, 2024
20f8965
fix commonjs
paperdave Jul 30, 2024
eaf4445
Merge branch 'main' into dave/compile-import-meta-main
paperdave Jul 31, 2024
2979579
Merge branch 'main' into dave/compile-import-meta-main
Jarred-Sumner Aug 1, 2024
0aec3c7
requested changes
paperdave Aug 1, 2024
75f9f36
Merge branch 'dave/compile-import-meta-main' of github.com:oven-sh/bu…
paperdave Aug 1, 2024
822428e
Merge remote-tracking branch 'origin/main' into dave/compile-import-m…
paperdave Aug 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/bun.js/RuntimeTranspilerCache.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/// ** Update the version number when any breaking changes are made to the cache format or to the JS parser **
/// Version 3: "Infinity" becomes "1/0".
/// Version 4: TypeScript enums are properly handled + more constant folding
const expected_version = 4;
/// Version 5: `require.main === module` no longer marks a module as CJS
const expected_version = 5;

const bun = @import("root").bun;
const std = @import("std");
Expand Down
1 change: 1 addition & 0 deletions src/bundler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,7 @@ pub const Bundler = struct {
.inline_require_and_import_errors = false,
.import_meta_ref = ast.import_meta_ref,
.runtime_transpiler_cache = runtime_transpiler_cache,
.target = bundler.options.target,
.print_dce_annotations = bundler.options.emit_dce_annotations,
},
enable_source_map,
Expand Down
20 changes: 18 additions & 2 deletions src/bundler/bundle_v2.zig
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ pub const BundleV2 = struct {
hash: ?u64,
batch: *ThreadPoolLib.Batch,
resolve: _resolver.Result,
is_entry_point: bool,
) !?Index.Int {
var result = resolve;
var path = result.path() orelse return null;
Expand Down Expand Up @@ -692,6 +693,7 @@ pub const BundleV2 = struct {
task.loader = loader;
task.task.node.next = null;
task.tree_shaking = this.linker.options.tree_shaking;
task.is_entry_point = is_entry_point;

// Handle onLoad plugins as entry points
if (!this.enqueueOnLoadPluginIfNeeded(task)) {
Expand Down Expand Up @@ -766,6 +768,7 @@ pub const BundleV2 = struct {
generator.linker.options.source_maps = bundler.options.source_map;
generator.linker.options.tree_shaking = bundler.options.tree_shaking;
generator.linker.options.public_path = bundler.options.public_path;
generator.linker.options.target = bundler.options.target;

var pool = try generator.graph.allocator.create(ThreadPool);
if (enable_reloading) {
Expand Down Expand Up @@ -822,7 +825,7 @@ pub const BundleV2 = struct {

for (entry_points) |entry_point| {
const resolved = this.bundler.resolveEntryPoint(entry_point) catch continue;
if (try this.enqueueItem(null, &batch, resolved)) |source_index| {
if (try this.enqueueItem(null, &batch, resolved, true)) |source_index| {
this.graph.entry_points.append(this.graph.allocator, Index.source(source_index)) catch unreachable;
} else {}
}
Expand All @@ -836,7 +839,7 @@ pub const BundleV2 = struct {

for (user_entry_points) |entry_point| {
const resolved = this.bundler.resolveEntryPoint(entry_point) catch continue;
if (try this.enqueueItem(null, &batch, resolved)) |source_index| {
if (try this.enqueueItem(null, &batch, resolved, true)) |source_index| {
this.graph.entry_points.append(this.graph.allocator, Index.source(source_index)) catch unreachable;
} else {}
}
Expand Down Expand Up @@ -2320,6 +2323,7 @@ pub const ParseTask = struct {
emit_decorator_metadata: bool = false,
ctx: *BundleV2,
package_version: string = "",
is_entry_point: bool = false,

/// Used by generated client components
presolved_source_indices: []const Index.Int = &.{},
Expand Down Expand Up @@ -2880,6 +2884,15 @@ pub const ParseTask = struct {
opts.features.emit_decorator_metadata = bundler.options.emit_decorator_metadata;
opts.ignore_dce_annotations = bundler.options.ignore_dce_annotations and !source.index.isRuntime();

// For files that are not user-specified entrypoints, set `import.meta.main` to `false`.
// Entrypoints will have `import.meta.main` set as "unknown", unless we use `--compile`,
// in which we inline `true`.
if (bundler.options.inline_entrypoint_import_meta_main or !task.is_entry_point) {
opts.import_meta_main_value = task.is_entry_point;
} else if (bundler.options.target == .node) {
opts.lower_import_meta_main_for_node_js = true;
}

opts.tree_shaking = if (source.index.isRuntime()) true else bundler.options.tree_shaking;
opts.module_type = task.module_type;
opts.features.unwrap_commonjs_packages = bundler.options.unwrap_commonjs_packages;
Expand Down Expand Up @@ -3862,6 +3875,7 @@ pub const LinkerContext = struct {
minify_syntax: bool = false,
minify_identifiers: bool = false,
source_maps: options.SourceMapOption = .none,
target: options.Target = .browser,

mode: Mode = Mode.bundle,

Expand Down Expand Up @@ -6810,6 +6824,7 @@ pub const LinkerContext = struct {
.minify_whitespace = c.options.minify_whitespace,
.minify_identifiers = c.options.minify_identifiers,
.minify_syntax = c.options.minify_syntax,
.target = c.options.target,
.print_dce_annotations = c.options.emit_dce_annotations,
// .const_values = c.graph.const_values,
};
Expand Down Expand Up @@ -9036,6 +9051,7 @@ pub const LinkerContext = struct {
c,
),
.line_offset_tables = c.graph.files.items(.line_offset_table)[part_range.source_index.get()],
.target = c.options.target,
};

writer.buffer.reset();
Expand Down
4 changes: 3 additions & 1 deletion src/cli.zig
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub const debug_flags = if (Environment.isDebug) struct {
}
return false;
}
} else @compileError("Do not access this namespace []const u8; in a release build");
} else @compileError("Do not access this namespace in a release build");

const LoaderMatcher = strings.ExactSizeMatcher(4);
const ColonListType = @import("./cli/colon_list_type.zig").ColonListType;
Expand Down Expand Up @@ -774,6 +774,7 @@ pub const Arguments = struct {

if (args.flag("--compile")) {
ctx.bundler_options.compile = true;
ctx.bundler_options.inline_entrypoint_import_meta_main = true;
}

if (args.option("--outdir")) |outdir| {
Expand Down Expand Up @@ -1279,6 +1280,7 @@ pub const Command = struct {
react_server_components: bool = false,
code_splitting: bool = false,
transform_only: bool = false,
inline_entrypoint_import_meta_main: bool = false,
minify_syntax: bool = false,
minify_whitespace: bool = false,
minify_identifiers: bool = false,
Expand Down
3 changes: 3 additions & 0 deletions src/cli/build_command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ pub const BuildCommand = struct {
this_bundler.options.react_server_components = ctx.bundler_options.react_server_components;
this_bundler.resolver.opts.react_server_components = ctx.bundler_options.react_server_components;

this_bundler.options.inline_entrypoint_import_meta_main = ctx.bundler_options.inline_entrypoint_import_meta_main;
this_bundler.resolver.opts.inline_entrypoint_import_meta_main = ctx.bundler_options.inline_entrypoint_import_meta_main;

this_bundler.options.code_splitting = ctx.bundler_options.code_splitting;
this_bundler.resolver.opts.code_splitting = ctx.bundler_options.code_splitting;

Expand Down
2 changes: 1 addition & 1 deletion src/crash_handler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1519,7 +1519,7 @@ pub fn dumpStackTrace(trace: std.builtin.StackTrace) void {
},
.linux => {
// Linux doesnt seem to be able to decode it's own debug info.
// TODO(@paperdave): see if zig 0.12 fixes this
// TODO(@paperdave): see if zig 0.14 fixes this
},
else => {
stdDumpStackTrace(trace);
Expand Down
61 changes: 43 additions & 18 deletions src/js_ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1550,6 +1550,12 @@ pub const E = struct {
range: logger.Range,
};
pub const ImportMeta = struct {};
pub const ImportMetaMain = struct {
/// If we want to print `!import.meta.main`, set this flag to true
/// instead of wrapping in a unary not. This way, the printer can easily
/// print `require.main != module` instead of `!(require.main == module)`
inverted: bool = false,
};

pub const Call = struct {
// Node:
Expand Down Expand Up @@ -4468,14 +4474,13 @@ pub const Expr = struct {
e_undefined,
e_new_target,
e_import_meta,
e_import_meta_main,
e_require_main,
e_inlined_enum,

/// A string that is UTF-8 encoded without escaping for use in JavaScript.
e_utf8_string,

// This should never make it to the printer
inline_identifier,

// object, regex and array may have had side effects
pub fn isPrimitiveLiteral(tag: Tag) bool {
return switch (tag) {
Expand Down Expand Up @@ -5156,8 +5161,8 @@ pub const Expr = struct {

e_require_string: E.RequireString,
e_require_resolve_string: E.RequireResolveString,
e_require_call_target: void,
e_require_resolve_call_target: void,
e_require_call_target,
e_require_resolve_call_target,

e_missing: E.Missing,
e_this: E.This,
Expand All @@ -5166,14 +5171,12 @@ pub const Expr = struct {
e_undefined: E.Undefined,
e_new_target: E.NewTarget,
e_import_meta: E.ImportMeta,
e_inlined_enum: *E.InlinedEnum,
e_import_meta_main: E.ImportMetaMain,
e_require_main,

e_inlined_enum: *E.InlinedEnum,
e_utf8_string: *E.UTF8String,

// This type should not exist outside of MacroContext
// If it ends up in JSParser or JSPrinter, it is a bug.
inline_identifier: i32,

pub fn as(data: Data, comptime tag: Tag) ?std.meta.FieldType(Data, tag) {
return if (data == tag) @field(data, @tagName(tag)) else null;
}
Expand Down Expand Up @@ -5754,6 +5757,14 @@ pub const Expr = struct {
equal: bool = false,
ok: bool = false,

/// This extra flag is unfortunately required for the case of visiting the expression
/// `require.main === module` (and any combination of !==, ==, !=, either ordering)
///
/// We want to replace this with the dedicated import_meta_main node, which:
/// - Stops this module from having p.require_ref, allowing conversion to ESM
/// - Allows us to inline `import.meta.main`'s value, if it is known (bun build --compile)
is_require_main_and_module: bool = false,

pub const @"true" = Equality{ .ok = true, .equal = true };
pub const @"false" = Equality{ .ok = true, .equal = false };
pub const unknown = Equality{ .ok = false };
Expand All @@ -5765,12 +5776,14 @@ pub const Expr = struct {
pub fn eql(
left: Expr.Data,
right: Expr.Data,
allocator: std.mem.Allocator,
p: anytype,
comptime kind: enum { loose, strict },
) Equality {
comptime bun.assert(@typeInfo(@TypeOf(p)).Pointer.size == .One); // pass *Parser

// https://dorey.github.io/JavaScript-Equality-Table/
switch (left) {
.e_inlined_enum => |inlined| return inlined.value.data.eql(right, allocator, kind),
.e_inlined_enum => |inlined| return inlined.value.data.eql(right, p, kind),

.e_null, .e_undefined => {
const ok = switch (@as(Expr.Tag, right)) {
Expand Down Expand Up @@ -5881,8 +5894,8 @@ pub const Expr = struct {
.e_string => |l| {
switch (right) {
.e_string => |r| {
r.resolveRopeIfNeeded(allocator);
l.resolveRopeIfNeeded(allocator);
r.resolveRopeIfNeeded(p.allocator);
l.resolveRopeIfNeeded(p.allocator);
return .{
.ok = true,
.equal = r.eql(E.String, l),
Expand All @@ -5892,8 +5905,8 @@ pub const Expr = struct {
if (inlined.value.data == .e_string) {
const r = inlined.value.data.e_string;

r.resolveRopeIfNeeded(allocator);
l.resolveRopeIfNeeded(allocator);
r.resolveRopeIfNeeded(p.allocator);
l.resolveRopeIfNeeded(p.allocator);

return .{
.ok = true,
Expand Down Expand Up @@ -5924,7 +5937,20 @@ pub const Expr = struct {
else => {},
}
},
else => {},

else => {
// Do not need to check left because e_require_main is
// always re-ordered to the right side.
if (right == .e_require_main) {
if (left.as(.e_identifier)) |id| {
if (id.ref.eql(p.module_ref)) return .{
.ok = true,
.equal = true,
.is_require_main_and_module = true,
};
}
}
},
}

return Equality.unknown;
Expand All @@ -5949,7 +5975,6 @@ pub const Expr = struct {

.e_identifier,
.e_import_identifier,
.inline_identifier,
.e_private_identifier,
.e_commonjs_export_identifier,
=> error.@"Cannot convert identifier to JS. Try a statically-known value",
Expand Down
Loading