aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-01-22 16:23:14 -0800
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-01-22 16:23:14 -0800
commitf4fbf8429448258195c4ec7e7f25100167048d28 (patch)
tree267a14300d631a36c2dd98f7844f8f2104cc7822
parent56ae4bcb55798fba374ec9dc5f387bb0a2584714 (diff)
downloadbun-f4fbf8429448258195c4ec7e7f25100167048d28.tar.gz
bun-f4fbf8429448258195c4ec7e7f25100167048d28.tar.zst
bun-f4fbf8429448258195c4ec7e7f25100167048d28.zip
Make `Ref` more safe
-rw-r--r--src/ast/base.zig34
-rw-r--r--src/fs.zig5
-rw-r--r--src/js_ast.zig6
-rw-r--r--src/js_parser/js_parser.zig2
4 files changed, 39 insertions, 8 deletions
diff --git a/src/ast/base.zig b/src/ast/base.zig
index 91e0bcafc..ad0d34efd 100644
--- a/src/ast/base.zig
+++ b/src/ast/base.zig
@@ -29,7 +29,17 @@ pub const RefHashCtx = struct {
}
pub fn eql(_: @This(), ref: Ref, b: Ref) bool {
- return ref.asBitInt() == b.asBitInt();
+ return ref.asU64() == b.asU64();
+ }
+};
+
+pub const RefCtx = struct {
+ pub fn hash(_: @This(), key: Ref) u64 {
+ return key.hash64();
+ }
+
+ pub fn eql(_: @This(), ref: Ref, b: Ref) bool {
+ return ref.asU64() == b.asU64();
}
};
@@ -61,14 +71,28 @@ pub const Ref = packed struct {
}
pub fn hash(key: Ref) u32 {
- return @truncate(u32, std.hash.Wyhash.hash(0, &@bitCast([8]u8, @as(u64, key.asBitInt()))));
+ return @truncate(u32, key.hash64());
+ }
+
+ pub inline fn asU64(key: Ref) u64 {
+ // This type isn't quite a u64 because it is used in a few other packed structs which have variables in them
+ // But, there are some footguns with the stage1 implementation of packed structs
+ // so it is safer to do comparisons as u64
+ // but we want to ensure that the value of the unused bits in the u64 are 0
+ // i have not looked at the assembly to verify that the unused bits default to 0
+ // so we set it to u64 0 just to be sure
+ return @as(u64, 0) | @as(u64, key.asBitInt());
+ }
+
+ pub inline fn hash64(key: Ref) u64 {
+ return std.hash.Wyhash.hash(0, &@bitCast([8]u8, key.asU64()));
}
pub fn eql(ref: Ref, b: Ref) bool {
- return asBitInt(ref) == b.asBitInt();
+ return asU64(ref) == b.asU64();
}
- pub fn isNull(self: *const Ref) bool {
- return self.source_index == max_ref_int and self.inner_index == max_ref_int;
+ pub fn isNull(self: Ref) bool {
+ return self.eql(Ref.None);
}
pub fn isSourceIndexNull(int: anytype) bool {
diff --git a/src/fs.zig b/src/fs.zig
index 694a6d3a2..f11651ae7 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -990,6 +990,7 @@ pub const File = struct { path: Path, contents: string };
pub const PathName = struct {
base: string,
dir: string,
+ /// includes the leading .
ext: string,
filename: string,
@@ -1085,6 +1086,10 @@ pub const Path = struct {
return strings.eqlComptime(this.namespace, "bun");
}
+ pub fn isMacro(this: *const Path) bool {
+ return strings.eqlComptime(this.namespace, "macro");
+ }
+
pub const PackageRelative = struct {
path: string,
name: string,
diff --git a/src/js_ast.zig b/src/js_ast.zig
index dfc43e27b..c5dd9c56f 100644
--- a/src/js_ast.zig
+++ b/src/js_ast.zig
@@ -18,6 +18,7 @@ const ObjectPool = @import("./pool.zig").ObjectPool;
const ImportRecord = @import("import_record.zig").ImportRecord;
const allocators = @import("allocators.zig");
+const RefCtx = @import("./ast/base.zig").RefCtx;
const _hash_map = @import("hash_map.zig");
const StringHashMap = _hash_map.StringHashMap;
const AutoHashMap = _hash_map.AutoHashMap;
@@ -3555,7 +3556,7 @@ pub const Part = struct {
jsx_import,
};
- pub const SymbolUseMap = _hash_map.AutoHashMapUnmanaged(Ref, Symbol.Use);
+ pub const SymbolUseMap = std.HashMapUnmanaged(Ref, Symbol.Use, RefCtx, 80);
pub fn jsonStringify(self: *const Part, options: std.json.StringifyOptions, writer: anytype) !void {
return std.json.stringify(self.stmts, options, writer);
}
@@ -3613,6 +3614,7 @@ pub const Scope = struct {
kind: Kind = Kind.block,
parent: ?*Scope,
children: std.ArrayListUnmanaged(*Scope) = .{},
+ // This is a special hash table that allows us to pass in the hash directly
members: StringHashMapUnmanaged(Member) = .{},
generated: std.ArrayListUnmanaged(Ref) = .{},
@@ -3794,7 +3796,7 @@ pub const Macro = struct {
const Bundler = @import("./bundler.zig").Bundler;
const MacroEntryPoint = @import("./bundler.zig").MacroEntryPoint;
const MacroRemap = @import("./resolver/package_json.zig").MacroMap;
- const MacroRemapEntry = @import("./resolver/package_json.zig").MacroImportReplacementMap;
+ pub const MacroRemapEntry = @import("./resolver/package_json.zig").MacroImportReplacementMap;
pub const namespace: string = "macro";
pub const namespaceWithColon: string = namespace ++ ":";
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index b5fdd0827..0921c5970 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -6250,7 +6250,7 @@ pub fn NewParser(
if (stmt.items.len > 0) {
var i: usize = 0;
- var list = std.ArrayListUnmanaged(js_ast.ClauseItem){ .items = stmt.items };
+ var list = std.ArrayListUnmanaged(js_ast.ClauseItem){ .items = stmt.items, .capacity = stmt.items.len };
// I do not like two passes here. This works around a bug
// where when the final import item of a remapped macro