diff options
author | 2022-01-22 16:23:14 -0800 | |
---|---|---|
committer | 2022-01-22 16:23:14 -0800 | |
commit | f4fbf8429448258195c4ec7e7f25100167048d28 (patch) | |
tree | 267a14300d631a36c2dd98f7844f8f2104cc7822 | |
parent | 56ae4bcb55798fba374ec9dc5f387bb0a2584714 (diff) | |
download | bun-f4fbf8429448258195c4ec7e7f25100167048d28.tar.gz bun-f4fbf8429448258195c4ec7e7f25100167048d28.tar.zst bun-f4fbf8429448258195c4ec7e7f25100167048d28.zip |
Make `Ref` more safe
-rw-r--r-- | src/ast/base.zig | 34 | ||||
-rw-r--r-- | src/fs.zig | 5 | ||||
-rw-r--r-- | src/js_ast.zig | 6 | ||||
-rw-r--r-- | src/js_parser/js_parser.zig | 2 |
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 |