Skip to content
Open
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
7 changes: 7 additions & 0 deletions src/ast/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ bitflags::bitflags! {
/// `arguments` object can). Set on the root of the symbol's link
/// chain. Read by HMR live bindings and the printer's same-target fold.
const HAS_BEEN_ASSIGNED_TO = 1 << 5;

/// Another symbol's `link` points at this one (a hoisted `var`
/// redeclaration, a catch binding, a replaced declaration), so uses
/// recorded on that symbol are uses of this one too and
/// `use_count_estimate` alone undercounts them.
const IS_LINK_TARGET = 1 << 6;
}
}

Expand All @@ -147,6 +153,7 @@ symbol_flag_accessors! {
must_not_be_renamed, set_must_not_be_renamed => MUST_NOT_BE_RENAMED;
remove_overwritten_function_declaration, set_remove_overwritten_function_declaration => REMOVE_OVERWRITTEN_FUNCTION_DECLARATION;
has_been_assigned_to, set_has_been_assigned_to => HAS_BEEN_ASSIGNED_TO;
is_link_target, set_is_link_target => IS_LINK_TARGET;
}

const _: () = assert!(core::mem::size_of::<Option<bun_alloc::AstBox<G::NamespaceAlias>>>() == 8);
Expand Down
19 changes: 0 additions & 19 deletions src/bun_core/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3252,25 +3252,6 @@ pub fn itoa<T: ::itoa::Integer>(buf: &mut ItoaBuf, n: T) -> &[u8] {
buf.format(n).as_bytes()
}

/// If `val` is exactly `10^e` for `e` in `4..=9`, return `Some(e)`; else `None`.
///
/// Used by `js_printer`'s non-negative-integer fast path to emit the
/// minified-JS forms `1e4`..`1e9` (which are shorter than the full digit
/// expansion). `e ≤ 3` is not shorter; `e ≥ 10` exceeds `u32::MAX` and is
/// handled by the printer's f64 path.
#[inline]
pub const fn pow10_exp_1e4_to_1e9(val: u64) -> Option<u8> {
match val {
10_000 => Some(4),
100_000 => Some(5),
1_000_000 => Some(6),
10_000_000 => Some(7),
100_000_000 => Some(8),
1_000_000_000 => Some(9),
_ => None,
}
}

/// Format `value`
/// into `buf` as base-10 ASCII and return the number of bytes written.
/// Panics if `buf` is too small — callers size the buffer by the type's max
Expand Down
1 change: 1 addition & 0 deletions src/js_parser/lower/lower_esm_exports_hmr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ impl<'a> ConvertESMExportsForHmr<'a> {
let symbol = &mut p.symbols[namespace_ref.inner_index() as usize];
symbol.use_count_estimate = 0;
symbol.link.set(stmt.namespace_ref);
p.symbols[stmt.namespace_ref.inner_index() as usize].set_is_link_target(true);
// Note: the concrete `P` always carries `symbol_uses`;
// once a `ParserLike` trait is introduced for
// AstBuilder, that variant should override this to a no-op.
Expand Down
16 changes: 16 additions & 0 deletions src/js_parser/p.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ pub struct P<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> {
pub(crate) stmt_expr_value: js_ast::ExprData,
pub(crate) call_target: js_ast::ExprData,
pub(crate) delete_target: js_ast::ExprData,
/// The tag of the template literal being visited, like `call_target`.
pub(crate) template_tag: js_ast::ExprData,
pub(crate) loop_body: js_ast::StmtData,
pub(crate) module_scope: js_ast::StoreRef<js_ast::Scope>,
pub(crate) module_scope_directive_loc: bun_ast::Loc,
Expand Down Expand Up @@ -599,6 +601,14 @@ pub struct P<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> {
pub(crate) temp_refs_to_declare: List<'a, TempRef>,
pub(crate) temp_ref_count: i32,

/// Rewrites that wait for the enclosing function body's use counts to be
/// final. Entries past the depth's saved length belong to the body being
/// visited; see `apply_fn_body_mangle_candidates`.
pub(crate) mangle_candidates: Vec<crate::visit::mangle::MangleCandidate>,
/// How many function bodies are being visited. Candidates are only
/// recorded inside one, since the module scope is visited part by part.
pub(crate) fn_body_depth: u32,

// When bundling, hoisted top-level local variables declared with "var" in
// nested scopes are moved up to be declared in the top-level scope instead.
// The old "var" statements are turned into regular assignments instead. This
Expand Down Expand Up @@ -3397,6 +3407,7 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O
{
// Silently merge this symbol into the existing symbol
self.symbols[symbol_idx].link.set(member_in_scope.ref_);
self.symbols[existing_idx].set_is_link_target(true);
// `StringHashMap` get_or_put already stores the key on insert and
// cannot hand out `&mut K` (see StringHashMapGetOrPut docs), so
// no key write is needed here.
Expand Down Expand Up @@ -3457,6 +3468,7 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O
// If this is a catch identifier, silently merge the existing symbol
// into this symbol but continue hoisting past this catch scope
self.symbols[existing_idx].link.set(value.ref_);
self.symbols[symbol_idx].set_is_link_target(true);
*_scope
.get_or_put_member_with_hash(name, hash.unwrap())
.value_ptr = value;
Expand Down Expand Up @@ -4894,6 +4906,7 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O
}
MR::ReplaceWithNew => {
self.symbols[symbol_idx].link.set(ref_);
self.symbols[ref_.inner_index() as usize].set_is_link_target(true);

// If these are both functions, remove the overwritten declaration
if kind.is_function() && self.symbols[symbol_idx].kind.is_function() {
Expand Down Expand Up @@ -9170,6 +9183,7 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O
allow_in: true,

call_target: null_expr_data(),
template_tag: null_expr_data(),
delete_target: null_expr_data(),
stmt_expr_value: null_expr_data(),
loop_body: null_stmt_data(),
Expand Down Expand Up @@ -9283,6 +9297,8 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O
has_non_local_export_declare_inside_namespace: false,
await_target: None,
temp_refs_to_declare: BumpVec::new_in(arena),
mangle_candidates: Vec::new(),
fn_body_depth: 0,
temp_ref_count: 0,
relocated_top_level_vars: BumpVec::new_in(arena),
after_arrow_body_loc: bun_ast::Loc::EMPTY,
Expand Down
Loading
Loading