Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion crates/oxc_mangler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ description.workspace = true
workspace = true

[lib]
test = false
test = true
doctest = false

[dependencies]
Expand Down
32 changes: 11 additions & 21 deletions crates/oxc_mangler/src/base54.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ const BASE54_CHARS: Aligned64 =
/// Get the shortest mangled name for a given n.
/// Code adapted from [terser](https://github.com/terser/terser/blob/8b966d687395ab493d2c6286cc9dd38650324c11/lib/scope.js#L1041-L1051)
//
// Maximum length of string is 11 (`ZrN6rN6rN6r` for `u64::MAX`), but set `CAPACITY` as 12,
// so the total size of `InlineString` is 16, including the `len` field.
// Then initializing the `InlineString` is a single `xmm` set, and with luck it'll sit in a register
// Maximum length of string is 6 (`xKrTKr` for `u32::MAX`), but set `CAPACITY` as 7,
// so the total size of `InlineString` is 8, including the `u8` length field.
// Then initializing the `InlineString` is a single instruction, and with luck it'll sit in a register
// throughout this function.
#[expect(clippy::items_after_statements)]
pub fn base54(n: usize) -> InlineString<12, u32> {
pub fn base54(n: u32) -> InlineString<7, u8> {
let mut str = InlineString::new();

let mut num = n;
let mut num = n as usize;

// Base 54 at first because these are the usable first characters in JavaScript identifiers
// <https://tc39.es/ecma262/#prod-IdentifierStart>
Expand Down Expand Up @@ -72,21 +72,11 @@ mod test {

#[test]
fn test_base54() {
assert_eq!(&*base54(0), "a");
assert_eq!(&*base54(25), "z");
assert_eq!(&*base54(26), "A");
assert_eq!(&*base54(51), "Z");
assert_eq!(&*base54(52), "$");
assert_eq!(&*base54(53), "_");
assert_eq!(&*base54(54), "aa");
assert_eq!(&*base54(55), "ab");

if cfg!(target_pointer_width = "64") {
assert_eq!(&*base54(usize::MAX), "ZrN6rN6rN6r");
}

if cfg!(target_pointer_width = "32") {
assert_eq!(&*base54(usize::MAX), "vUdzUd");
}
assert_eq!(&*base54(0), "e");
assert_eq!(&*base54(52), "Q");
assert_eq!(&*base54(53), "$");
assert_eq!(&*base54(54), "ee");
assert_eq!(&*base54(55), "te");
assert_eq!(&*base54(u32::MAX), "xKrTKr");
}
}
7 changes: 3 additions & 4 deletions crates/oxc_mangler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ impl Mangler {

fn build_with_symbols_and_scopes_impl<
const CAPACITY: usize,
G: Fn(usize) -> InlineString<CAPACITY, u32>,
G: Fn(u32) -> InlineString<CAPACITY, u8>,
>(
self,
semantic: Semantic<'_>,
Expand Down Expand Up @@ -450,9 +450,8 @@ fn is_keyword(s: &str) -> bool {
| "void" | "with")
}

// Maximum length of string is 25 (`slot_18446744073709551615` for `u64::MAX`)
// but set `CAPACITY` as 28 so the total size of `InlineString` is 32, including the `u32` length.
fn debug_name(n: usize) -> InlineString<28, u32> {
// Maximum length of string is 15 (`slot_4294967295` for `u32::MAX`).
fn debug_name(n: u32) -> InlineString<15, u8> {
// Using `format!` here allocates a string unnecessarily.
// But this function is not for use in production, so let's not worry about it.
// We shouldn't resort to unsafe code, when it's not critical for performance.
Expand Down
Loading