aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-29 17:40:00 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-29 17:40:00 -0700
commitb5612b303b934b668c35c1a70d64f498b7c62856 (patch)
tree422c9f2d9f3239036296335f0593a9e78434cb7a /src
parent3436ee9deddf21594a0b4fb3640a7596ea078093 (diff)
downloadbun-b5612b303b934b668c35c1a70d64f498b7c62856.tar.gz
bun-b5612b303b934b668c35c1a70d64f498b7c62856.tar.zst
bun-b5612b303b934b668c35c1a70d64f498b7c62856.zip
WIP
Former-commit-id: 55dcde581df46b425733508c3923e073ccdf880f
Diffstat (limited to 'src')
-rw-r--r--src/allocators.zig381
-rw-r--r--src/bundler.zig63
-rw-r--r--src/cli.zig5
-rw-r--r--src/hash_map.zig2
-rw-r--r--src/js_ast.zig679
-rw-r--r--src/js_lexer.zig2
-rw-r--r--src/js_parser/js_parser.zig17
-rw-r--r--src/thread_safe_hash_map.zig2
8 files changed, 498 insertions, 653 deletions
diff --git a/src/allocators.zig b/src/allocators.zig
index 8ebde9150..c9371426a 100644
--- a/src/allocators.zig
+++ b/src/allocators.zig
@@ -1,5 +1,8 @@
const std = @import("std");
+const hash_map = @import("hash_map.zig");
+
+const HashMapUnmanaged = hash_map.HashMapUnmanaged;
const Wyhash = std.hash.Wyhash;
const FixedBufferAllocator = std.heap.FixedBufferAllocator;
@@ -70,7 +73,7 @@ pub const IndexType = packed struct {
};
const HashKeyType = u64;
-const IndexMap = std.HashMapUnmanaged(HashKeyType, IndexType, hash_hashFn, hash_eqlFn, 80);
+const IndexMap = HashMapUnmanaged(HashKeyType, IndexType, hash_hashFn, hash_eqlFn, 80);
pub const Result = struct {
hash: HashKeyType,
index: IndexType,
@@ -88,7 +91,7 @@ pub const Result = struct {
return if (r.isOverflowing(count)) @intCast(IndexType, r.index - max_index) else r.index;
}
};
-const Seed = 999;
+const Seed = 0;
pub const NotFound = IndexType{
.index = std.math.maxInt(u31),
@@ -233,246 +236,227 @@ pub fn BSSList(comptime ValueType: type, comptime count: anytype) type {
}
};
}
-pub fn BSSStringList(comptime count: usize, comptime item_length: usize) type {
- const max_index = count - 1;
- const ValueType = []const u8;
- return struct {
- pub var slice_buf: [count][]const u8 = undefined;
- pub var slice_buf_used: u16 = 0;
- pub var backing_buf: [count * item_length]u8 = undefined;
- pub var backing_buf_used: u64 = undefined;
- const Allocator = std.mem.Allocator;
- const Self = @This();
- pub const ListIndex = packed struct {
- index: u31,
- is_overflowing: bool = false,
- };
- overflow_list: std.ArrayListUnmanaged(ValueType),
- allocator: *Allocator,
+// Like an ArrayList except:
+// - It only grows
+// - Pointer never invalidates
+pub const ByteBuffer = struct {
+ allocator: *std.mem.Allocator,
+ ptr: [*]u8,
+ len: usize,
- pub var instance: Self = undefined;
+ items: []u8,
- pub fn init(allocator: *std.mem.Allocator) *Self {
- instance = Self{
- .allocator = allocator,
- .overflow_list = std.ArrayListUnmanaged(ValueType){},
- };
+ pub fn init(allocator: *std.mem.Allocator, comptime min_length: usize) !ByteBuffer {
+ var items = if (min_length > 0) try allocator.alloc(u8, min_length) else &([_]u8{});
- return &instance;
+ return ByteBuffer{ .allocator = allocator, .items = items, .ptr = undefined, .len = min_length };
+ }
+
+ pub fn growIfNeeded(this: *ByteBuffer, min_length: usize) !void {
+ const len = std.math.ceilPowerOfTwo(usize, this.items.len + min_length) catch unreachable;
+ if (this.len >= len) {
+ return;
}
- pub fn isOverflowing() bool {
- return slice_buf_used >= @as(u16, count);
+ if (this.len == 0) {
+ const items = try this.allocator.alloc(u8, len);
+ this.ptr = items.ptr;
+ this.len = items.len;
+ } else {
+ const items = try this.allocator.realloc(this.ptr[0..this.len], len);
+ this.ptr = items.ptr;
+ this.len = items.len;
}
- pub fn at(self: *const Self, index: IndexType) ?ValueType {
- if (index.index == NotFound.index or index.index == Unassigned.index) return null;
+ this.items = this.ptr[0 .. this.items.len + min_length];
+ }
- if (index.is_overflowing) {
- return &self.overflow_list.items[index.index];
- } else {
- return &slice_buf[index.index];
- }
- }
+ pub fn reset(this: *ByteBuffer) void {
+ this.items = this.items[0..0];
+ }
- pub fn exists(self: *Self, value: ValueType) bool {
- return isSliceInBuffer(value, slice_buf);
- }
+ pub fn slice(this: *ByteBuffer, len: usize) ![]u8 {
+ try this.growIfNeeded(len);
- pub fn editableSlice(slice: []const u8) []u8 {
- return constStrToU8(slice);
+ return this.items[this.items.len - len ..];
+ }
+
+ pub fn append(this: *ByteBuffer, items: anytype) ![]u8 {
+ var writable = try this.slice(items.len);
+ @memcpy(writable.ptr, items.ptr, items.len);
+ return writable;
+ }
+};
+
+// Like an ArrayList except:
+// - It only grows
+// - Pointer never invalidates
+
+pub fn OverflowList(comptime ValueType: type) type {
+ return struct {
+ const Self = @This();
+ allocator: *std.mem.Allocator,
+ ptr: [*]ValueType,
+ len: usize,
+
+ items: []ValueType,
+
+ pub fn init(allocator: *std.mem.Allocator, comptime min_length: usize) !Self {
+ var items = if (min_length > 0) try allocator.alloc(ValueType, min_length) else &([_]ValueType{});
+
+ return Self{ .allocator = allocator, .items = items, .ptr = undefined, .len = min_length };
}
- pub fn append(self: *Self, _value: anytype) ![]const u8 {
- var value = _value;
- if (value.len + backing_buf_used < backing_buf.len - 1) {
- const start = backing_buf_used;
- backing_buf_used += value.len;
- std.mem.copy(u8, backing_buf[start..backing_buf_used], _value);
- value = backing_buf[start..backing_buf_used];
- } else {
- value = try self.allocator.dupe(u8, _value);
+ pub fn growIfNeeded(this: *Self, min_length: usize) !void {
+ const len = std.math.ceilPowerOfTwo(usize, this.items.len + min_length) catch unreachable;
+ if (this.len >= len) {
+ return;
}
- var result = ListIndex{ .index = std.math.maxInt(u31), .is_overflowing = slice_buf_used > max_index };
-
- if (result.is_overflowing) {
- result.index = @intCast(u31, self.overflow_list.items.len);
+ if (this.len == 0) {
+ const items = try this.allocator.alloc(ValueType, len);
+ this.ptr = items.ptr;
+ this.len = items.len;
} else {
- result.index = slice_buf_used;
- slice_buf_used += 1;
- if (slice_buf_used >= max_index) {
- self.overflow_list = try @TypeOf(self.overflow_list).initCapacity(self.allocator, count);
- }
+ const items = try this.allocator.realloc(this.ptr[0..this.len], len);
+ this.ptr = items.ptr;
+ this.len = items.len;
}
- if (result.is_overflowing) {
- if (self.overflow_list.items.len == result.index) {
- const real_index = self.overflow_list.items.len;
- try self.overflow_list.append(self.allocator, value);
- } else {
- self.overflow_list.items[result.index] = value;
- }
+ this.items = this.ptr[0 .. this.items.len + min_length];
+ }
- return self.overflow_list.items[result.index];
- } else {
- slice_buf[result.index] = value;
+ pub fn reset(this: *Self) void {
+ this.items = this.items[0..0];
+ }
- return slice_buf[result.index];
- }
+ pub fn slice(this: *Self, len: usize) ![]ValueType {
+ try this.growIfNeeded(len);
+
+ return this.items[this.items.len - len ..];
}
- pub fn remove(self: *Self, index: ListIndex) void {
- @compileError("Not implemented yet.");
- // switch (index) {
- // Unassigned.index => {
- // self.index.remove(_key);
- // },
- // NotFound.index => {
- // self.index.remove(_key);
- // },
- // 0...max_index => {
- // if (hasDeinit(ValueType)) {
- // slice_buf[index].deinit();
- // }
- // slice_buf[index] = undefined;
- // },
- // else => {
- // const i = index - count;
- // if (hasDeinit(ValueType)) {
- // self.overflow_list.items[i].deinit();
- // }
- // self.overflow_list.items[index - count] = undefined;
- // },
- // }
+ pub fn append(this: *Self, value: ValueType) !*ValueType {
+ try this.growIfNeeded(1);
+ const index = this.items.len - 1;
+ this.items[index] = value;
+ return &this.items[index];
+ }
- // return index;
+ pub fn appendGetIndex(this: *Self, value: ValueType) !usize {
+ try this.growIfNeeded(1);
+ const index = this.items.len - 1;
+ this.items[index] = value;
+ return index;
}
};
}
-pub fn TBSSStringList(comptime count: usize, comptime item_length: usize) type {
+// Growable array of variable-length strings
+// Copies the strings
+pub const StringList = struct {
+ const DataType = [][]u8;
+ buffer: ByteBuffer,
+ ptr: [*][]u8,
+ len: usize = 0,
+ allocator: *std.mem.Allocator,
+
+ items: DataType,
+
+ pub fn init(allocator: *std.mem.Allocator) StringList {
+ return StringList{
+ .ptr = undefined,
+ .allocator = allocator,
+ .len = 0,
+ .buffer = ByteBuffer.init(allocator, 0) catch unreachable,
+ .items = std.mem.zeroes(DataType),
+ };
+ }
+
+ pub fn reset(self: *StringList) void {
+ self.buffer.reset();
+ self.items = self.ptr[0..0];
+ }
+
+ pub fn appendCopy(self: *StringList, str: anytype, comptime copy: bool) ![]const u8 {
+ const index = try self.appendCopyIndex(str, copy);
+ return self.items[index];
+ }
+
+ pub fn appendCopyIndex(self: *StringList, str: anytype, comptime copy: bool) !usize {
+ if (self.len == 0) {
+ var items = try self.allocator.alloc([]u8, 8);
+ self.ptr = items.ptr;
+ self.len = items.len;
+ self.items = items[0..1];
+ } else if (self.items.len >= self.len) {
+ const end = self.len + 1;
+ const len = std.math.ceilPowerOfTwo(usize, self.len + 1) catch unreachable;
+ var items = try self.allocator.realloc(self.ptr[0..self.len], len);
+ self.ptr = items.ptr;
+ self.len = items.len;
+ self.items = self.ptr[0..end];
+ }
+
+ const index = self.items.len - 1;
+ self.items[index] = if (copy) try self.buffer.append(str) else str;
+ return index;
+ }
+
+ pub fn append(self: *StringList, str: anytype) ![]const u8 {
+ return try self.appendCopy(str, true);
+ }
+};
+
+pub fn BSSStringList(comptime count: usize, comptime item_length: usize) type {
const max_index = count - 1;
const ValueType = []const u8;
return struct {
+ pub var backing_buf: [count * item_length]u8 = undefined;
+ pub var backing_buf_used: u64 = undefined;
+
const Allocator = std.mem.Allocator;
const Self = @This();
-
- pub threadlocal var slice_buf: [count][]const u8 = undefined;
- pub threadlocal var slice_buf_used: u16 = 0;
- pub threadlocal var backing_buf: [count * item_length]u8 = undefined;
- pub threadlocal var backing_buf_used: u64 = undefined;
- pub threadlocal var instance: Self = undefined;
pub const ListIndex = packed struct {
index: u31,
is_overflowing: bool = false,
};
- overflow_list: std.ArrayListUnmanaged(ValueType),
+ list: StringList,
allocator: *Allocator,
+ pub var instance: Self = undefined;
+
pub fn init(allocator: *std.mem.Allocator) *Self {
instance = Self{
.allocator = allocator,
- .overflow_list = std.ArrayListUnmanaged(ValueType){},
+ .list = StringList.init(allocator),
};
return &instance;
}
- pub fn isOverflowing() bool {
- return slice_buf_used >= @as(u16, count);
- }
-
- pub fn at(self: *const Self, index: IndexType) ?ValueType {
- if (index.index == NotFound.index or index.index == Unassigned.index) return null;
-
- if (index.is_overflowing) {
- return &self.overflow_list.items[index.index];
- } else {
- return &slice_buf[index.index];
- }
- }
-
- pub fn exists(self: *Self, value: ValueType) bool {
- return isSliceInBuffer(value, slice_buf);
- }
-
pub fn editableSlice(slice: []const u8) []u8 {
return constStrToU8(slice);
}
- pub fn append(self: *Self, _value: anytype) ![]const u8 {
- var value = _value;
+ pub fn append(self: *Self, value: anytype) ![]const u8 {
if (value.len + backing_buf_used < backing_buf.len - 1) {
const start = backing_buf_used;
backing_buf_used += value.len;
- std.mem.copy(u8, backing_buf[start..backing_buf_used], _value);
- value = backing_buf[start..backing_buf_used];
- } else {
- value = try self.allocator.dupe(u8, _value);
+ std.mem.copy(u8, backing_buf[start..backing_buf_used], value);
+ return try self.list.appendCopy(backing_buf[start..backing_buf_used], false);
}
- var result = ListIndex{ .index = std.math.maxInt(u31), .is_overflowing = slice_buf_used > max_index };
-
- if (result.is_overflowing) {
- result.index = @intCast(u31, self.overflow_list.items.len);
- } else {
- result.index = slice_buf_used;
- slice_buf_used += 1;
- if (slice_buf_used >= max_index) {
- self.overflow_list = try @TypeOf(self.overflow_list).initCapacity(self.allocator, count);
- }
- }
-
- if (result.is_overflowing) {
- if (self.overflow_list.items.len == result.index) {
- const real_index = self.overflow_list.items.len;
- try self.overflow_list.append(self.allocator, value);
- } else {
- self.overflow_list.items[result.index] = value;
- }
-
- return self.overflow_list.items[result.index];
- } else {
- slice_buf[result.index] = value;
-
- return slice_buf[result.index];
- }
- }
-
- pub fn remove(self: *Self, index: ListIndex) void {
- @compileError("Not implemented yet.");
- // switch (index) {
- // Unassigned.index => {
- // self.index.remove(_key);
- // },
- // NotFound.index => {
- // self.index.remove(_key);
- // },
- // 0...max_index => {
- // if (hasDeinit(ValueType)) {
- // slice_buf[index].deinit();
- // }
- // slice_buf[index] = undefined;
- // },
- // else => {
- // const i = index - count;
- // if (hasDeinit(ValueType)) {
- // self.overflow_list.items[i].deinit();
- // }
- // self.overflow_list.items[index - count] = undefined;
- // },
- // }
-
- // return index;
+ return try self.list.appendCopy(value, true);
}
};
}
pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: bool, estimated_key_length: usize) type {
const max_index = count - 1;
+ const OverflowListType = OverflowList(ValueType);
const BSSMapType = struct {
pub var backing_buf: [count]ValueType = undefined;
pub var backing_buf_used: u16 = 0;
@@ -480,7 +464,7 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo
const Self = @This();
index: IndexMap,
- overflow_list: std.ArrayListUnmanaged(ValueType),
+ overflow_list: OverflowListType,
allocator: *Allocator,
pub var instance: Self = undefined;
@@ -489,7 +473,7 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo
instance = Self{
.index = IndexMap{},
.allocator = allocator,
- .overflow_list = std.ArrayListUnmanaged(ValueType){},
+ .overflow_list = OverflowListType.init(allocator, 0) catch unreachable,
};
return &instance;
@@ -501,7 +485,7 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo
pub fn getOrPut(self: *Self, key: []const u8) !Result {
const _key = Wyhash.hash(Seed, key);
- var index = try self.index.getOrPut(self.allocator, _key);
+ var index = try self.index.getOrPutWithHash(self.allocator, _key, _key);
if (index.found_existing) {
return Result{
@@ -525,12 +509,12 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo
pub fn get(self: *const Self, key: []const u8) ?*ValueType {
const _key = Wyhash.hash(Seed, key);
- const index = self.index.get(_key) orelse return null;
+ const index = self.index.getWithHash(_key, _key) orelse return null;
return self.atIndex(index);
}
pub fn markNotFound(self: *Self, result: Result) void {
- self.index.put(self.allocator, result.hash, NotFound) catch unreachable;
+ self.index.putWithHash(self.allocator, result.hash, result.hash, NotFound) catch unreachable;
}
pub fn atIndex(self: *const Self, index: IndexType) ?*ValueType {
@@ -551,23 +535,13 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo
} else {
result.index.index = backing_buf_used;
backing_buf_used += 1;
- if (backing_buf_used >= max_index) {
- self.overflow_list = try @TypeOf(self.overflow_list).initCapacity(self.allocator, count);
- }
}
}
- try self.index.put(self.allocator, result.hash, result.index);
+ try self.index.putWithHash(self.allocator, result.hash, result.hash, result.index);
if (result.index.is_overflow) {
- if (self.overflow_list.items.len == result.index.index) {
- const real_index = self.overflow_list.items.len;
- try self.overflow_list.append(self.allocator, value);
- } else {
- self.overflow_list.items[result.index.index] = value;
- }
-
- return &self.overflow_list.items[result.index.index];
+ return try self.overflow_list.append(value);
} else {
backing_buf[result.index.index] = value;
@@ -577,7 +551,7 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo
pub fn remove(self: *Self, key: string) IndexType {
const _key = Wyhash.hash(Seed, key);
- const index = self.index.get(_key) orelse return;
+ const index = self.index.getWithHash(_key, _key) orelse return;
switch (index) {
Unassigned.index => {
self.index.remove(_key);
@@ -614,13 +588,13 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo
var key_list_buffer: [count * estimated_key_length]u8 = undefined;
var key_list_buffer_used: usize = 0;
var key_list_slices: [count][]u8 = undefined;
- var key_list_overflow: std.ArrayListUnmanaged([]u8) = undefined;
+ var key_list_overflow: StringList = undefined;
pub fn init(allocator: *std.mem.Allocator) *Self {
instance = Self{
.map = BSSMapType.init(allocator),
};
-
+ key_list_overflow = key_list_overflow.init(allocator);
return &instance;
}
@@ -677,9 +651,10 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo
const start = key_list_buffer_used;
key_list_buffer_used += key.len;
slice = key_list_buffer[start..key_list_buffer_used];
- std.mem.copy(u8, slice, key);
+ @memcpy(slice.ptr, key.ptr, key.len);
} else {
- slice = try self.map.allocator.dupe(u8, key);
+ result.index = try key_list_overflow.appendCopyIndex(key, true);
+ return;
}
if (!result.index.is_overflow) {
@@ -692,7 +667,7 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo
}
key_list_overflow.items[result.index.index] = slice;
} else {
- try key_list_overflow.append(self.map.allocator, slice);
+ try key_list_overflow.appendCopy(self.map.allocator, slice, false);
}
}
}
diff --git a/src/bundler.zig b/src/bundler.zig
index 42b515678..aa7bfaec9 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -80,6 +80,9 @@ pub const Bundler = struct {
log: *logger.Log,
opts: Api.TransformOptions,
) !Bundler {
+ js_ast.Expr.Data.Store.create(allocator);
+ js_ast.Stmt.Data.Store.create(allocator);
+
var fs = try Fs.FileSystem.init1(allocator, opts.absolute_working_dir, opts.serve orelse false);
const bundle_options = try options.BundleOptions.fromApi(allocator, fs, log, opts);
@@ -168,35 +171,36 @@ pub const Bundler = struct {
bundler.needs_runtime = true;
}
+ import_record.path = try bundler.generateImportPath(source_dir, resolve_result.path_pair.primary.text);
+
// lazy means:
// Run the resolver
// Don't parse/print automatically.
if (bundler.options.resolve_mode != .lazy) {
- try bundler.enqueueResolveResult(&resolve_result);
+ try bundler.enqueueResolveResult(resolve_result);
}
-
- import_record.path = try bundler.generateImportPath(source_dir, resolve_result.path_pair.primary.text);
}
- pub fn resolveResultHashKey(bundler: *Bundler, resolve_result: *Resolver.Resolver.Result) string {
- var hash_key = resolve_result.path_pair.primary.text;
+ pub fn resolveResultHashKey(bundler: *Bundler, path: string) string {
+ var hash_key = path;
// Shorter hash key is faster to hash
- if (strings.startsWith(resolve_result.path_pair.primary.text, bundler.fs.top_level_dir)) {
- hash_key = resolve_result.path_pair.primary.text[bundler.fs.top_level_dir.len..];
+ if (strings.startsWith(path, bundler.fs.top_level_dir)) {
+ hash_key = path[bundler.fs.top_level_dir.len..];
}
return hash_key;
}
- pub fn enqueueResolveResult(bundler: *Bundler, resolve_result: *Resolver.Resolver.Result) !void {
- const hash_key = bundler.resolveResultHashKey(resolve_result);
+ pub fn enqueueResolveResult(bundler: *Bundler, resolve_result: Resolver.Resolver.Result) !void {
+ const hash_key = bundler.resolveResultHashKey(resolve_result.path_pair.primary.text);
const get_or_put_entry = try bundler.resolve_results.backing.getOrPut(hash_key);
+ get_or_put_entry.entry.value = resolve_result;
+
if (!get_or_put_entry.found_existing) {
- get_or_put_entry.entry.value = resolve_result.*;
- try bundler.resolve_queue.writeItem(resolve_result.*);
+ try bundler.resolve_queue.writeItem(resolve_result);
}
}
@@ -510,22 +514,17 @@ pub const Bundler = struct {
};
}
- pub fn bundle(
- allocator: *std.mem.Allocator,
- log: *logger.Log,
- opts: Api.TransformOptions,
- ) !options.TransformResult {
- var bundler = try Bundler.init(allocator, log, opts);
-
+ pub fn run(bundler: *Bundler) !options.TransformResult {
+ const allocator = bundler.allocator;
// 100.00 µs std.fifo.LinearFifo(resolver.resolver.Result,std.fifo.LinearFifoBufferType { .Dynamic = {}}).writeItemAssumeCapacity
- if (bundler.options.resolve_mode != .lazy) {
- try bundler.resolve_queue.ensureUnusedCapacity(1000);
- }
+ // if (bundler.options.resolve_mode != .lazy) {
+ // try bundler.resolve_queue.ensureUnusedCapacity(1000);
+ // }
var entry_points = try allocator.alloc(Resolver.Resolver.Result, bundler.options.entry_points.len);
if (isDebug) {
- log.level = .verbose;
+ bundler.log.level = .verbose;
bundler.resolver.debug_logs = try Resolver.Resolver.DebugLogs.init(allocator);
}
@@ -596,6 +595,10 @@ pub const Bundler = struct {
bundler.resolve_queue.writeItem(result) catch unreachable;
}
+ // The resolver may use the AST store when parsing package.json / tsconfig.json
+ js_ast.Stmt.Data.Store.reset();
+ js_ast.Expr.Data.Store.reset();
+
switch (bundler.options.resolve_mode) {
.lazy, .dev, .bundle => {
while (bundler.resolve_queue.readItem()) |item| {
@@ -628,7 +631,21 @@ pub const Bundler = struct {
);
}
- return try options.TransformResult.init(try allocator.dupe(u8, bundler.result.outbase), bundler.output_files.toOwnedSlice(), log, allocator);
+ return try options.TransformResult.init(
+ try allocator.dupe(u8, bundler.result.outbase),
+ bundler.output_files.toOwnedSlice(),
+ bundler.log,
+ bundler.allocator,
+ );
+ }
+
+ pub fn bundle(
+ allocator: *std.mem.Allocator,
+ log: *logger.Log,
+ opts: Api.TransformOptions,
+ ) !options.TransformResult {
+ var bundler = try Bundler.init(allocator, log, opts);
+ return try bundler.run();
}
};
diff --git a/src/cli.zig b/src/cli.zig
index 6e44d5e08..f20529875 100644
--- a/src/cli.zig
+++ b/src/cli.zig
@@ -392,8 +392,9 @@ pub const Cli = struct {
}
if (isDebug) {
- Output.println("Expr count: {d}", .{js_ast.Expr.icount});
- Output.println("Stmt count: {d}", .{js_ast.Stmt.icount});
+ Output.println("Expr count: {d}", .{js_ast.Expr.icount});
+ Output.println("Stmt count: {d}", .{js_ast.Stmt.icount});
+ Output.println("Binding count: {d}", .{js_ast.Binding.binding_count});
Output.println("File Descriptors: {d} / {d}", .{
fs.FileSystem.max_fd,
diff --git a/src/hash_map.zig b/src/hash_map.zig
index 69c56997c..7153795f2 100644
--- a/src/hash_map.zig
+++ b/src/hash_map.zig
@@ -688,7 +688,7 @@ pub fn HashMapUnmanaged(
}
pub fn getOrPutAssumeCapacity(self: *Self, key: K) GetOrPutResult {
- return @call(.{ .modifier = .always_inline }, Self.getOrPutAssumeCapacityWithHash, .{ self, key, hashFn(key) });
+ return self.getOrPutAssumeCapacityWithHash(key, hashFn(key));
}
pub fn getOrPutAssumeCapacityWithHash(self: *Self, key: K, hash: u64) GetOrPutResult {
diff --git a/src/js_ast.zig b/src/js_ast.zig
index 5b3f1a7c1..701abd474 100644
--- a/src/js_ast.zig
+++ b/src/js_ast.zig
@@ -12,6 +12,132 @@ const _hash_map = @import("hash_map.zig");
const StringHashMap = _hash_map.StringHashMap;
const AutoHashMap = _hash_map.AutoHashMap;
+pub fn NewBaseStore(comptime Union: anytype, count: usize) type {
+ var max_size: usize = 0;
+ var max_align: usize = 1;
+ for (Union) |kind| {
+ max_size = std.math.max(@sizeOf(kind), max_size);
+ max_align = if (@sizeOf(kind) == 0) max_align else std.math.max(@alignOf(kind), max_align);
+ }
+
+ max_size = std.mem.alignForward(max_size, max_align);
+ const element_size = max_size;
+ const total_byte_count = count * max_size;
+
+ return struct {
+ const Self = @This();
+ const OverflowList = std.ArrayListUnmanaged(u8);
+ pub threadlocal var byte_buffer: [total_byte_count]u8 align(max_align) = undefined;
+ pub threadlocal var bytes_used: usize = undefined;
+ pub threadlocal var bytes_element_count: usize = undefined;
+ pub threadlocal var instance: Self = undefined;
+ pub threadlocal var self: *Self = undefined;
+ pub threadlocal var has_loaded: bool = false;
+ allocator: *std.mem.Allocator,
+ overflow_list: []u8,
+ overflow_list_ptr: [*]u8 = undefined,
+ overflow_list_ptr_len: usize = 0,
+ overflow_element_count: usize = 0,
+
+ pub fn init(allocator: *std.mem.Allocator) *Self {
+ if (has_loaded) {
+ return self;
+ }
+
+ instance = Self{
+ .allocator = allocator,
+ .overflow_list = &([_]u8{}),
+ };
+ bytes_used = 0;
+ bytes_element_count = 0;
+ self = &instance;
+ has_loaded = true;
+ return self;
+ }
+
+ pub fn reset() void {
+ std.debug.assert(has_loaded);
+ self.overflow_list = &([_]u8{});
+ self.overflow_element_count = 0;
+ bytes_used = 0;
+ bytes_element_count = 0;
+ }
+
+ pub fn growOverflowListIfNeeded(store: *Self, to: usize) void {
+ if (store.overflow_list_ptr_len >= to) {
+ return;
+ }
+
+ const is_new = store.overflow_list_ptr_len == 0;
+ store.overflow_list_ptr_len = to + (max_size * 100);
+
+ if (!is_new) {
+ _ = store.allocator.resize(store.overflow_list_ptr[0..store.overflow_list_ptr_len], store.overflow_list_ptr_len) catch unreachable;
+ } else {
+ store.overflow_list_ptr = (store.allocator.alloc(u8, store.overflow_list_ptr_len) catch unreachable).ptr;
+ }
+ }
+
+ pub fn append(comptime ValueType: type, value: ValueType) ListIndex {
+ std.debug.assert(has_loaded);
+
+ if (bytes_used < max_size - 1) {
+ const index = bytes_element_count;
+ const offset = bytes_used;
+ bytes_element_count += 1;
+ bytes_used += max_size;
+ std.mem.copy(u8, byte_buffer[offset..bytes_used], std.mem.asBytes(&value));
+ return ListIndex{ .is_overflowing = false, .index = @intCast(u31, index) };
+ } else {
+ const index = self.overflow_element_count;
+ const offset = self.overflow_list.len;
+ self.overflow_element_count += 1;
+ const end_length = offset + max_size;
+ self.growOverflowListIfNeeded(end_length);
+ std.mem.copy(u8, self.overflow_list_ptr[offset..end_length], std.mem.asBytes(&value));
+ self.overflow_list = self.overflow_list_ptr[0..end_length];
+ return ListIndex{ .is_overflowing = true, .index = @intCast(u31, index) };
+ }
+ }
+
+ pub fn at(index: ListIndex, comptime ValueType: type) *ValueType {
+ std.debug.assert(index.index != allocators.NotFound.index and index.index != allocators.Unassigned.index);
+ @setRuntimeSafety(false);
+
+ const slice_begin = index.index * element_size;
+ const slice_end = slice_begin + element_size;
+
+ var slice: []u8 = undefined;
+ if (index.is_overflowing) {
+ slice = self.overflow_list_ptr[slice_begin..slice_end];
+ @setRuntimeSafety(false);
+ } else {
+ slice = byte_buffer[slice_begin..];
+ @setRuntimeSafety(false);
+ }
+
+ var aligned_slice = @alignCast(@alignOf(ValueType), slice.ptr);
+
+ return @ptrCast(
+ *ValueType,
+ aligned_slice,
+ );
+ }
+ };
+}
+
+pub fn NewStore(comptime BaseStore: type, comptime ValueType: type) type {
+ return struct {
+ pub fn at(index: ListIndex) *ValueType {
+ return BaseStore.at(index, ValueType);
+ }
+
+ pub fn append(value: ValueType) ListIndex {
+ return BaseStore.append(ValueType, value);
+ }
+ };
+}
+
pub const ListIndex = packed struct {
index: u31,
is_overflowing: bool = false,
@@ -197,7 +323,9 @@ pub const Binding = struct {
b_missing,
};
+ pub var binding_count: usize = 0;
pub fn init(t: anytype, loc: logger.Loc) Binding {
+ binding_count += 1;
switch (@TypeOf(t)) {
*B.Identifier => {
return Binding{ .loc = loc, .data = B{ .b_identifier = t } };
@@ -221,6 +349,7 @@ pub const Binding = struct {
}
pub fn alloc(allocator: *std.mem.Allocator, t: anytype, loc: logger.Loc) Binding {
+ binding_count += 1;
switch (@TypeOf(t)) {
B.Identifier => {
var data = allocator.create(B.Identifier) catch unreachable;
@@ -690,7 +819,7 @@ pub const E = struct {
op: Op.Code,
};
- pub const Boolean = packed struct { value: bool };
+ pub const Boolean = struct { value: bool };
pub const Super = struct {};
pub const Null = struct {};
pub const This = struct {};
@@ -777,7 +906,7 @@ pub const E = struct {
pub const Function = struct { func: G.Fn };
- pub const Identifier = packed struct {
+ pub const Identifier = struct {
ref: Ref = Ref.None,
// If we're inside a "with" statement, this identifier may be a property
@@ -1459,10 +1588,8 @@ pub const Stmt = struct {
s_class: ListIndex,
s_comment: ListIndex,
s_continue: ListIndex,
- s_debugger: S.Debugger,
s_directive: ListIndex,
s_do_while: ListIndex,
- s_empty: S.Empty, // special case, its a zero value type
s_enum: ListIndex,
s_export_clause: ListIndex,
s_export_default: ListIndex,
@@ -1484,113 +1611,85 @@ pub const Stmt = struct {
s_switch: ListIndex,
s_throw: ListIndex,
s_try: ListIndex,
- s_type_script: S.TypeScript,
s_while: ListIndex,
s_with: ListIndex,
+ s_type_script: S.TypeScript,
+ s_empty: S.Empty, // special case, its a zero value type
+ s_debugger: S.Debugger,
+
pub const Store = struct {
- pub const Block = NewStore(S.Block);
- pub const Break = NewStore(S.Break);
- pub const Class = NewStore(S.Class);
- pub const Comment = NewStore(S.Comment);
- pub const Continue = NewStore(S.Continue);
- pub const Directive = NewStore(S.Directive);
- pub const DoWhile = NewStore(S.DoWhile);
- pub const Enum = NewStore(S.Enum);
- pub const ExportClause = NewStore(S.ExportClause);
- pub const ExportDefault = NewStore(S.ExportDefault);
- pub const ExportEquals = NewStore(S.ExportEquals);
- pub const ExportFrom = NewStore(S.ExportFrom);
- pub const ExportStar = NewStore(S.ExportStar);
- pub const SExpr = NewStore(S.SExpr);
- pub const ForIn = NewStore(S.ForIn);
- pub const ForOf = NewStore(S.ForOf);
- pub const For = NewStore(S.For);
- pub const Function = NewStore(S.Function);
- pub const If = NewStore(S.If);
- pub const Import = NewStore(S.Import);
- pub const Label = NewStore(S.Label);
- pub const LazyExport = NewStore(S.LazyExport);
- pub const Local = NewStore(S.Local);
- pub const Namespace = NewStore(S.Namespace);
- pub const Return = NewStore(S.Return);
- pub const Switch = NewStore(S.Switch);
- pub const Throw = NewStore(S.Throw);
- pub const Try = NewStore(S.Try);
- pub const TypeScript = NewStore(S.TypeScript);
- pub const While = NewStore(S.While);
- pub const With = NewStore(S.With);
+ const Union = [_]type{
+ S.Block,
+ S.Break,
+ S.Class,
+ S.Comment,
+ S.Continue,
+ S.Directive,
+ S.DoWhile,
+ S.Enum,
+ S.ExportClause,
+ S.ExportDefault,
+ S.ExportEquals,
+ S.ExportFrom,
+ S.ExportStar,
+ S.SExpr,
+ S.ForIn,
+ S.ForOf,
+ S.For,
+ S.Function,
+ S.If,
+ S.Import,
+ S.Label,
+ S.LazyExport,
+ S.Local,
+ S.Namespace,
+ S.Return,
+ S.Switch,
+ S.Throw,
+ S.Try,
+ S.While,
+ S.With,
+ };
+ pub const BaseStore = NewBaseStore(&Union, 512);
+ pub const Block = NewStore(BaseStore, S.Block);
+ pub const Break = NewStore(BaseStore, S.Break);
+ pub const Class = NewStore(BaseStore, S.Class);
+ pub const Comment = NewStore(BaseStore, S.Comment);
+ pub const Continue = NewStore(BaseStore, S.Continue);
+ pub const Directive = NewStore(BaseStore, S.Directive);
+ pub const DoWhile = NewStore(BaseStore, S.DoWhile);
+ pub const Enum = NewStore(BaseStore, S.Enum);
+ pub const ExportClause = NewStore(BaseStore, S.ExportClause);
+ pub const ExportDefault = NewStore(BaseStore, S.ExportDefault);
+ pub const ExportEquals = NewStore(BaseStore, S.ExportEquals);
+ pub const ExportFrom = NewStore(BaseStore, S.ExportFrom);
+ pub const ExportStar = NewStore(BaseStore, S.ExportStar);
+ pub const SExpr = NewStore(BaseStore, S.SExpr);
+ pub const ForIn = NewStore(BaseStore, S.ForIn);
+ pub const ForOf = NewStore(BaseStore, S.ForOf);
+ pub const For = NewStore(BaseStore, S.For);
+ pub const Function = NewStore(BaseStore, S.Function);
+ pub const If = NewStore(BaseStore, S.If);
+ pub const Import = NewStore(BaseStore, S.Import);
+ pub const Label = NewStore(BaseStore, S.Label);
+ pub const LazyExport = NewStore(BaseStore, S.LazyExport);
+ pub const Local = NewStore(BaseStore, S.Local);
+ pub const Namespace = NewStore(BaseStore, S.Namespace);
+ pub const Return = NewStore(BaseStore, S.Return);
+ pub const Switch = NewStore(BaseStore, S.Switch);
+ pub const Throw = NewStore(BaseStore, S.Throw);
+ pub const Try = NewStore(BaseStore, S.Try);
+ pub const While = NewStore(BaseStore, S.While);
+ pub const With = NewStore(BaseStore, S.With);
threadlocal var has_inited = false;
pub fn create(allocator: *std.mem.Allocator) void {
- if (has_inited) {
- return;
- }
-
- has_inited = true;
- _ = Block.init(allocator);
- _ = Break.init(allocator);
- _ = Class.init(allocator);
- _ = Comment.init(allocator);
- _ = Continue.init(allocator);
- _ = Directive.init(allocator);
- _ = DoWhile.init(allocator);
- _ = Enum.init(allocator);
- _ = ExportClause.init(allocator);
- _ = ExportDefault.init(allocator);
- _ = ExportEquals.init(allocator);
- _ = ExportFrom.init(allocator);
- _ = ExportStar.init(allocator);
- _ = SExpr.init(allocator);
- _ = ForIn.init(allocator);
- _ = ForOf.init(allocator);
- _ = For.init(allocator);
- _ = Function.init(allocator);
- _ = If.init(allocator);
- _ = Import.init(allocator);
- _ = Label.init(allocator);
- _ = LazyExport.init(allocator);
- _ = Local.init(allocator);
- _ = Namespace.init(allocator);
- _ = Return.init(allocator);
- _ = Switch.init(allocator);
- _ = Throw.init(allocator);
- _ = Try.init(allocator);
- _ = While.init(allocator);
- _ = With.init(allocator);
+ _ = BaseStore.init(allocator);
}
pub fn reset() void {
- Block.reset();
- Break.reset();
- Class.reset();
- Comment.reset();
- Continue.reset();
- Directive.reset();
- DoWhile.reset();
- Enum.reset();
- ExportClause.reset();
- ExportDefault.reset();
- ExportEquals.reset();
- ExportFrom.reset();
- ExportStar.reset();
- SExpr.reset();
- ForIn.reset();
- ForOf.reset();
- For.reset();
- Function.reset();
- If.reset();
- Import.reset();
- Label.reset();
- LazyExport.reset();
- Local.reset();
- Namespace.reset();
- Return.reset();
- Switch.reset();
- Throw.reset();
- Try.reset();
- While.reset();
- With.reset();
+ BaseStore.reset();
}
pub fn append(comptime ValueType: type, value: anytype) ListIndex {
@@ -1695,76 +1794,6 @@ pub const Stmt = struct {
},
}
}
-
- pub fn NewStore(comptime ValueType: type) type {
- const count = 8096;
- const max_index = count - 1;
- const list_count = count;
- return struct {
- pub threadlocal var backing_buf: [count]ValueType = undefined;
- pub threadlocal var backing_buf_used: u16 = 0;
- const Allocator = std.mem.Allocator;
- const Self = @This();
- const NotFound = allocators.NotFound;
- const Unassigned = allocators.Unassigned;
-
- overflow_list: std.ArrayListUnmanaged(ValueType),
- allocator: *Allocator,
-
- pub threadlocal var instance: Self = undefined;
- pub threadlocal var self: *Self = undefined;
-
- pub fn reset() void {
- backing_buf_used = 0;
- self.overflow_list.items.len = 0;
- }
-
- pub fn init(allocator: *std.mem.Allocator) *Self {
- instance = Self{
- .allocator = allocator,
- .overflow_list = std.ArrayListUnmanaged(ValueType){},
- };
-
- self = &instance;
- return self;
- }
-
- pub fn isOverflowing() bool {
- return backing_buf_used >= @as(u16, count);
- }
-
- pub fn at(index: ListIndex) *ValueType {
- std.debug.assert(index.index != NotFound.index and index.index != Unassigned.index);
-
- if (index.is_overflowing) {
- return &self.overflow_list.items[index.index];
- } else {
- return &backing_buf[index.index];
- }
- }
-
- pub fn exists(value: ValueType) bool {
- return isSliceInBuffer(value, backing_buf);
- }
-
- pub fn append(value: ValueType) ListIndex {
- var result = ListIndex{ .index = std.math.maxInt(u31), .is_overflowing = backing_buf_used > max_index };
- if (result.is_overflowing) {
- result.index = @intCast(u31, self.overflow_list.items.len);
- self.overflow_list.append(self.allocator, value) catch unreachable;
- } else {
- result.index = backing_buf_used;
- backing_buf[result.index] = value;
- backing_buf_used += 1;
- if (backing_buf_used >= max_index and self.overflow_list.capacity == 0) {
- self.overflow_list = @TypeOf(self.overflow_list).initCapacity(self.allocator, 1) catch unreachable;
- }
- }
-
- return result;
- }
- };
- }
};
pub inline fn set(data: *Data, value: anytype) void {
@@ -3263,11 +3292,12 @@ pub const Expr = struct {
e_null: E.Null,
e_undefined: E.Undefined,
e_new_target: E.NewTarget,
+ e_import_meta: E.ImportMeta,
e_new: ListIndex,
e_function: ListIndex,
- e_import_meta: E.ImportMeta,
+
e_call: ListIndex,
e_dot: ListIndex,
e_index: ListIndex,
@@ -3293,41 +3323,67 @@ pub const Expr = struct {
e_import: ListIndex,
pub const Store = struct {
- pub const Array = NewStore(E.Array);
- pub const Unary = NewStore(E.Unary);
- pub const Binary = NewStore(E.Binary);
- pub const This = NewStore(E.This);
- pub const Class = NewStore(E.Class);
- pub const Boolean = NewStore(E.Boolean);
- pub const Super = NewStore(E.Super);
- pub const Null = NewStore(E.Null);
- pub const Undefined = NewStore(E.Undefined);
- pub const New = NewStore(E.New);
- pub const Function = NewStore(E.Function);
- pub const ImportMeta = NewStore(E.ImportMeta);
- pub const Call = NewStore(E.Call);
- pub const Dot = NewStore(E.Dot);
- pub const Index = NewStore(E.Index);
- pub const Arrow = NewStore(E.Arrow);
- pub const Identifier = NewStore(E.Identifier);
- pub const ImportIdentifier = NewStore(E.ImportIdentifier);
- pub const PrivateIdentifier = NewStore(E.PrivateIdentifier);
- pub const JSXElement = NewStore(E.JSXElement);
- pub const Missing = NewStore(E.Missing);
- pub const Number = NewStore(E.Number);
- pub const BigInt = NewStore(E.BigInt);
- pub const Object = NewStore(E.Object);
- pub const Spread = NewStore(E.Spread);
- pub const String = NewStore(E.String);
- pub const TemplatePart = NewStore(E.TemplatePart);
- pub const Template = NewStore(E.Template);
- pub const RegExp = NewStore(E.RegExp);
- pub const Await = NewStore(E.Await);
- pub const Yield = NewStore(E.Yield);
- pub const If = NewStore(E.If);
- pub const Require = NewStore(E.Require);
- pub const RequireOrRequireResolve = NewStore(E.RequireOrRequireResolve);
- pub const Import = NewStore(E.Import);
+ const Union = [_]type{
+ E.Array,
+ E.Unary,
+ E.Binary,
+ E.Class,
+ E.Boolean,
+ E.New,
+ E.Function,
+ E.Call,
+ E.Dot,
+ E.Index,
+ E.Arrow,
+ E.Identifier,
+ E.ImportIdentifier,
+ E.PrivateIdentifier,
+ E.JSXElement,
+ E.Number,
+ E.BigInt,
+ E.Object,
+ E.Spread,
+ E.String,
+ E.TemplatePart,
+ E.Template,
+ E.RegExp,
+ E.Await,
+ E.Yield,
+ E.If,
+ E.Require,
+ E.RequireOrRequireResolve,
+ E.Import,
+ };
+ pub const BaseStore = NewBaseStore(&Union, 2048);
+ pub const Array = NewStore(BaseStore, E.Array);
+ pub const Unary = NewStore(BaseStore, E.Unary);
+ pub const Binary = NewStore(BaseStore, E.Binary);
+ pub const Class = NewStore(BaseStore, E.Class);
+ pub const Boolean = NewStore(BaseStore, E.Boolean);
+ pub const New = NewStore(BaseStore, E.New);
+ pub const Function = NewStore(BaseStore, E.Function);
+ pub const Call = NewStore(BaseStore, E.Call);
+ pub const Dot = NewStore(BaseStore, E.Dot);
+ pub const Index = NewStore(BaseStore, E.Index);
+ pub const Arrow = NewStore(BaseStore, E.Arrow);
+ pub const Identifier = NewStore(BaseStore, E.Identifier);
+ pub const ImportIdentifier = NewStore(BaseStore, E.ImportIdentifier);
+ pub const PrivateIdentifier = NewStore(BaseStore, E.PrivateIdentifier);
+ pub const JSXElement = NewStore(BaseStore, E.JSXElement);
+ pub const Number = NewStore(BaseStore, E.Number);
+ pub const BigInt = NewStore(BaseStore, E.BigInt);
+ pub const Object = NewStore(BaseStore, E.Object);
+ pub const Spread = NewStore(BaseStore, E.Spread);
+ pub const String = NewStore(BaseStore, E.String);
+ pub const TemplatePart = NewStore(BaseStore, E.TemplatePart);
+ pub const Template = NewStore(BaseStore, E.Template);
+ pub const RegExp = NewStore(BaseStore, E.RegExp);
+ pub const Await = NewStore(BaseStore, E.Await);
+ pub const Yield = NewStore(BaseStore, E.Yield);
+ pub const If = NewStore(BaseStore, E.If);
+ pub const Require = NewStore(BaseStore, E.Require);
+ pub const RequireOrRequireResolve = NewStore(BaseStore, E.RequireOrRequireResolve);
+ pub const Import = NewStore(BaseStore, E.Import);
threadlocal var has_inited = false;
pub fn create(allocator: *std.mem.Allocator) void {
@@ -3336,73 +3392,11 @@ pub const Expr = struct {
}
has_inited = true;
- _ = Array.init(allocator);
- _ = Unary.init(allocator);
- _ = Binary.init(allocator);
- _ = This.init(allocator);
- _ = Class.init(allocator);
- _ = Boolean.init(allocator);
- _ = New.init(allocator);
- _ = Function.init(allocator);
- _ = ImportMeta.init(allocator);
- _ = Call.init(allocator);
- _ = Dot.init(allocator);
- _ = Index.init(allocator);
- _ = Arrow.init(allocator);
- _ = Identifier.init(allocator);
- _ = ImportIdentifier.init(allocator);
- _ = PrivateIdentifier.init(allocator);
- _ = JSXElement.init(allocator);
- _ = Missing.init(allocator);
- _ = Number.init(allocator);
- _ = BigInt.init(allocator);
- _ = Object.init(allocator);
- _ = Spread.init(allocator);
- _ = String.init(allocator);
- _ = TemplatePart.init(allocator);
- _ = Template.init(allocator);
- _ = RegExp.init(allocator);
- _ = Await.init(allocator);
- _ = Yield.init(allocator);
- _ = If.init(allocator);
- _ = Require.init(allocator);
- _ = RequireOrRequireResolve.init(allocator);
- _ = Import.init(allocator);
+ _ = BaseStore.init(allocator);
}
pub fn reset() void {
- Array.reset();
- Unary.reset();
- Binary.reset();
- This.reset();
- Class.reset();
- Boolean.reset();
- New.reset();
- Function.reset();
- ImportMeta.reset();
- Call.reset();
- Dot.reset();
- Index.reset();
- Arrow.reset();
- Identifier.reset();
- ImportIdentifier.reset();
- PrivateIdentifier.reset();
- JSXElement.reset();
- Missing.reset();
- Number.reset();
- BigInt.reset();
- Object.reset();
- Spread.reset();
- String.reset();
- TemplatePart.reset();
- Template.reset();
- RegExp.reset();
- Await.reset();
- Yield.reset();
- If.reset();
- Require.reset();
- RequireOrRequireResolve.reset();
- Import.reset();
+ BaseStore.reset();
}
pub fn append(comptime ValueType: type, value: anytype) ListIndex {
@@ -3520,77 +3514,6 @@ pub const Expr = struct {
},
}
}
-
- pub fn NewStore(comptime ValueType: type) type {
- const count = 8096;
- const max_index = count - 1;
- const list_count = count;
- return struct {
- pub threadlocal var backing_buf: [count]ValueType = undefined;
- pub threadlocal var backing_buf_used: u16 = 0;
- const Allocator = std.mem.Allocator;
- const Self = @This();
- const NotFound = allocators.NotFound;
- const Unassigned = allocators.Unassigned;
-
- overflow_list: std.ArrayListUnmanaged(ValueType),
- allocator: *Allocator,
-
- pub threadlocal var instance: Self = undefined;
- pub threadlocal var self: *Self = undefined;
-
- pub fn reset() void {
- backing_buf_used = 0;
- self.overflow_list.shrinkRetainingCapacity(0);
- }
-
- pub fn init(allocator: *std.mem.Allocator) *Self {
- instance = Self{
- .allocator = allocator,
- .overflow_list = std.ArrayListUnmanaged(ValueType){},
- };
-
- self = &instance;
- return self;
- }
-
- pub fn isOverflowing() bool {
- return backing_buf_used >= @as(u16, count);
- }
-
- pub fn at(index: ListIndex) *ValueType {
- std.debug.assert(index.index != NotFound.index and index.index != Unassigned.index);
-
- if (index.is_overflowing) {
- return &self.overflow_list.items[index.index];
- } else {
- return &backing_buf[index.index];
- }
- }
-
- pub fn exists(value: ValueType) bool {
- return isSliceInBuffer(value, backing_buf);
- }
-
- pub fn append(value: ValueType) ListIndex {
- var result = ListIndex{ .index = std.math.maxInt(u31), .is_overflowing = backing_buf_used > max_index };
- if (result.is_overflowing) {
- result.index = @intCast(u31, self.overflow_list.items.len);
- self.overflow_list.append(self.allocator, value) catch unreachable;
- } else {
- result.index = backing_buf_used;
- backing_buf[result.index] = value;
- backing_buf_used += 1;
-
- if (backing_buf_used >= max_index and self.overflow_list.capacity == 0) {
- self.overflow_list = @TypeOf(self.overflow_list).initCapacity(self.allocator, 1) catch unreachable;
- }
- }
-
- return result;
- }
- };
- }
};
pub fn isBooleanValue(self: *Expr) bool {
@@ -4148,78 +4071,6 @@ pub const Dependency = packed struct {
pub const ExprList = std.ArrayList(Expr);
pub const StmtList = std.ArrayList(Stmt);
pub const BindingList = std.ArrayList(Binding);
-pub const AstData = struct {
- expr_list: ExprList,
- stmt_list: StmtList,
- binding_list: BindingList,
-
- pub fn init(allocator: *std.mem.Allocator) AstData {
- return AstData{
- .expr_list = ExprList.init(allocator),
- .stmt_list = StmtList.init(allocator),
- .binding_list = BindingList.init(allocator),
- };
- }
-
- pub fn deinit(self: *AstData) void {
- self.expr_list.deinit();
- self.stmt_list.deinit();
- self.binding_list.deinit();
- }
-
- pub fn expr(self: *AstData, index: ExprNodeIndex) Expr {
- return self.expr_list.items[index];
- }
-
- pub fn stmt(self: *AstData, index: StmtNodeIndex) Stmt {
- return self.stmt_list.items[index];
- }
-
- pub fn binding(self: *AstData, index: BindingNodeIndex) Binding {
- return self.binding_list.items[index];
- }
-
- pub fn add_(self: *AstData, t: anytype) !void {
- return switch (@TypeOf(t)) {
- Stmt => {
- try self.stmt_list.append(t);
- },
- Expr => {
- try self.expr_list.append(t);
- },
- Binding => {
- try self.binding_list.append(t);
- },
- else => {
- @compileError("Invalid type passed to AstData.add. Expected Stmt, Expr, or Binding.");
- },
- };
- }
-
- pub fn add(self: *AstData, t: anytype) !NodeIndex {
- return &t;
- // return switch (@TypeOf(t)) {
- // Stmt => {
- // var len = self.stmt_list.items.len;
- // try self.stmt_list.append(t);
- // return @intCast(StmtNodeIndex, len);
- // },
- // Expr => {
- // var len = self.expr_list.items.len;
- // try self.expr_list.append(t);
- // return @intCast(ExprNodeIndex, len);
- // },
- // Binding => {
- // var len = self.binding_list.items.len;
- // try self.binding_list.append(t);
- // return @intCast(BindingNodeIndex, len);
- // },
- // else => {
- // @compileError("Invalid type passed to AstData.add. Expected Stmt, Expr, or Binding.");
- // },
- // };
- }
-};
// Each file is made up of multiple parts, and each part consists of one or
// more top-level statements. Parts are used for tree shaking and code
diff --git a/src/js_lexer.zig b/src/js_lexer.zig
index fef12bf47..e725a3a24 100644
--- a/src/js_lexer.zig
+++ b/src/js_lexer.zig
@@ -491,7 +491,7 @@ pub const Lexer = struct {
}
}
- pub const InnerStringLiteral = packed struct { suffix_len: u3, needs_slow_path: bool };
+ pub const InnerStringLiteral = struct { suffix_len: u3, needs_slow_path: bool };
fn parseStringLiteralInnter(lexer: *LexerType, comptime quote: CodePoint) !InnerStringLiteral {
var needs_slow_path = false;
var suffix_len: u3 = 1;
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index ffa401bb7..fd8121f43 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -501,7 +501,7 @@ pub const SideEffects = enum(u2) {
could_have_side_effects,
no_side_effects,
- pub const Result = packed struct {
+ pub const Result = struct {
side_effects: SideEffects,
ok: bool = false,
value: bool = false,
@@ -707,7 +707,7 @@ pub const SideEffects = enum(u2) {
}
}
- pub const Equality = packed struct { equal: bool = false, ok: bool = false };
+ pub const Equality = struct { equal: bool = false, ok: bool = false };
// Returns "equal, ok". If "ok" is false, then nothing is known about the two
// values. If "ok" is true, the equality or inequality of the two values is
@@ -1102,7 +1102,7 @@ const AsyncPrefixExpression = enum(u4) {
}
};
-const IdentifierOpts = packed struct {
+const IdentifierOpts = struct {
assign_target: js_ast.AssignTarget = js_ast.AssignTarget.none,
is_delete_target: bool = false,
was_originally_identifier: bool = false,
@@ -1140,7 +1140,7 @@ fn statementCaresAboutScope(stmt: Stmt) bool {
}
}
-const ExprIn = packed struct {
+const ExprIn = struct {
// This tells us if there are optional chain expressions (EDot, EIndex, or
// ECall) that are chained on to this expression. Because of the way the AST
// works, chaining expressions on to this expression means they are our
@@ -1297,7 +1297,7 @@ const ScopeOrder = struct {
scope: *js_ast.Scope,
};
-const ParenExprOpts = packed struct {
+const ParenExprOpts = struct {
async_range: logger.Range = logger.Range.None,
is_async: bool = false,
force_arrow_fn: bool = false,
@@ -1771,7 +1771,6 @@ pub const P = struct {
promise_ref: ?js_ast.Ref = null,
scopes_in_order_visitor_index: usize = 0,
has_classic_runtime_warned: bool = false,
- data: js_ast.AstData,
injected_define_symbols: List(Ref),
symbol_uses: SymbolUseMap,
@@ -10258,7 +10257,10 @@ pub const P = struct {
var has_spread = false;
var has_proto = false;
- for (e_.properties) |*property, i| {
+ for (e_.properties) |_, i| {
+ var property = e_.properties[i];
+ defer e_.properties[i] = property;
+
if (property.kind != .spread) {
property.key = p.visitExpr(property.key orelse Global.panic("Expected property key", .{}));
const key = property.key.?;
@@ -12822,7 +12824,6 @@ pub const P = struct {
.require_transposer = @TypeOf(_parser.require_transposer).init(_parser),
.require_resolve_transposer = @TypeOf(_parser.require_resolve_transposer).init(_parser),
.lexer = lexer,
- .data = js_ast.AstData.init(allocator),
};
return _parser;
diff --git a/src/thread_safe_hash_map.zig b/src/thread_safe_hash_map.zig
index 5c3a8cf51..df6dc07c2 100644
--- a/src/thread_safe_hash_map.zig
+++ b/src/thread_safe_hash_map.zig
@@ -13,7 +13,7 @@ pub fn ThreadSafeStringHashMap(comptime Value: type) type {
pub fn init(allocator: *std.mem.Allocator) !*HashMap {
var self = try allocator.create(HashMap);
self.* = HashMap{ .backing = HashMapType.init(allocator), .lock = sync.RwLock.init() };
-
+ try self.backing.ensureCapacity(10);
return self;
}