Skip to content

Commit

Permalink
feat: refactor Symbols and remove a lot of ReferenceId (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyf0 committed Oct 25, 2023
1 parent 6576d2c commit 5b980d5
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 75 deletions.
8 changes: 4 additions & 4 deletions crates/rolldown/src/bundler/graph/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl<'graph> Linker<'graph> {
symbols,
);
importer.generate_symbol_import_and_use(
importee.namespace_symbol.0,
importee.namespace_symbol,
importer_linker_module,
symbols,
);
Expand Down Expand Up @@ -366,7 +366,7 @@ impl<'graph> Linker<'graph> {
match importee {
Module::Normal(importee) => {
let resolved_ref = if info.is_imported_star {
importee.namespace_symbol.0
importee.namespace_symbol
} else {
match importee.resolve_export_for_esm_and_cjs(
&info.imported,
Expand All @@ -382,12 +382,12 @@ impl<'graph> Linker<'graph> {
linker_module.unresolved_symbols.insert(
info.imported_as,
UnresolvedSymbol {
importee_namespace: importee.namespace_symbol.0,
importee_namespace: importee.namespace_symbol,
reference_name,
},
);
importer.generate_symbol_import_and_use(
importee.namespace_symbol.0,
importee.namespace_symbol,
linker_module,
symbols,
);
Expand Down
72 changes: 40 additions & 32 deletions crates/rolldown/src/bundler/graph/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ use rolldown_common::{ModuleId, SymbolRef};
use rolldown_utils::reserved_word::is_reserved_word;
use rustc_hash::FxHashMap;

#[derive(Debug)]
pub struct Symbol {
pub name: Atom,
/// The symbol that this symbol is linked to.
pub link: Option<SymbolRef>,
}

#[derive(Debug, Default)]
pub struct SymbolMap {
pub names: IndexVec<SymbolId, Atom>,
Expand All @@ -28,26 +35,32 @@ impl SymbolMap {
self.names.push(name)
}
}

pub fn create_reference(&mut self, id: Option<SymbolId>) -> ReferenceId {
self.references.push(id)
}

pub fn get_name(&self, id: SymbolId) -> &Atom {
&self.names[id]
}
}

// Information about symbols for all modules
#[derive(Debug, Default)]
pub struct Symbols {
pub(crate) tables: IndexVec<ModuleId, SymbolMap>,
canonical_refs: IndexVec<ModuleId, FxHashMap<SymbolId, SymbolRef>>,
inner: IndexVec<ModuleId, IndexVec<SymbolId, Symbol>>,
pub(crate) references_table: IndexVec<ModuleId, IndexVec<ReferenceId, Option<SymbolId>>>,
}

impl Symbols {
pub fn new(tables: IndexVec<ModuleId, SymbolMap>) -> Self {
Self { canonical_refs: tables.iter().map(|_table| FxHashMap::default()).collect(), tables }
let mut reference_table = IndexVec::with_capacity(tables.len());
let inner = tables
.into_iter()
.map(|table| {
reference_table.push(table.references);
table.names.into_iter().map(|name| Symbol { name, link: None }).collect()
})
.collect();

Self { inner, references_table: reference_table }
}

pub fn create_symbol(&mut self, owner: ModuleId, name: Atom) -> SymbolRef {
let symbol_id = self.inner[owner].push(Symbol { name, link: None });
SymbolRef { owner, symbol: symbol_id }
}

/// Make a point to b
Expand All @@ -58,29 +71,35 @@ impl Symbols {
if root_a == root_b {
return;
}
self.canonical_refs[a.owner].insert(a.symbol, root_b);
self.get_mut(root_a).link = Some(root_b);
}

pub fn get_original_name(&self, refer: SymbolRef) -> &Atom {
self.tables[refer.owner].get_name(refer.symbol)
&self.get(refer).name
}

pub fn get(&self, refer: SymbolRef) -> &Symbol {
&self.inner[refer.owner][refer.symbol]
}

pub fn get_mut(&mut self, refer: SymbolRef) -> &mut Symbol {
&mut self.inner[refer.owner][refer.symbol]
}

pub fn get_canonical_ref(&mut self, target: SymbolRef) -> SymbolRef {
let mut canonical = target;
while let Some(founded) = self.canonical_refs[canonical.owner].get(&canonical.symbol).copied() {
debug_assert!(founded != target);
canonical = founded;
}
let canonical = self.par_get_canonical_ref(target);
if target != canonical {
self.canonical_refs[target.owner].insert(target.symbol, canonical);
// update the link to the canonical so that the next time we can get the canonical directly
self.get_mut(target).link = Some(canonical);
}
canonical
}

// Used for the situation where rust require `&self`
pub fn par_get_canonical_ref(&self, target: SymbolRef) -> SymbolRef {
let mut canonical = target;
while let Some(founded) = self.canonical_refs[canonical.owner].get(&canonical.symbol).copied() {
debug_assert!(founded != canonical);
while let Some(founded) = self.get(canonical).link {
debug_assert!(founded != target);
canonical = founded;
}
canonical
Expand All @@ -95,14 +114,3 @@ pub fn get_symbol_final_name<'a>(
let final_ref = symbols.par_get_canonical_ref(symbol);
final_names.get(&final_ref)
}

#[allow(dead_code)]
pub fn get_reference_final_name<'a>(
module_id: ModuleId,
reference_id: ReferenceId,
symbols: &'a Symbols,
final_names: &'a FxHashMap<SymbolRef, Atom>,
) -> Option<&'a Atom> {
symbols.tables[module_id].references[reference_id]
.and_then(|symbol| get_symbol_final_name((module_id, symbol).into(), symbols, final_names))
}
2 changes: 1 addition & 1 deletion crates/rolldown/src/bundler/module/external_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl ExternalModule {
self
.symbols_imported_by_others
.entry(symbol.clone())
.or_insert_with(|| (self.id, symbols.tables[self.id].create_symbol(symbol.clone())).into());
.or_insert_with(|| symbols.create_symbol(self.id, symbol.clone()));
}

pub fn resolve_export(&self, exported: &Atom, is_star: bool) -> SymbolRef {
Expand Down
7 changes: 3 additions & 4 deletions crates/rolldown/src/bundler/module/module_builder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use index_vec::IndexVec;
use oxc::{
semantic::{ReferenceId, ScopeTree, SymbolId},
semantic::{ScopeTree, SymbolId},
span::{Atom, Span},
};
use rolldown_common::{
Expand All @@ -27,7 +27,7 @@ pub struct NormalModuleBuilder {
pub star_exports: Option<Vec<ImportRecordId>>,
pub scope: Option<ScopeTree>,
pub default_export_symbol: Option<SymbolId>,
pub namespace_symbol: Option<(SymbolRef, ReferenceId)>,
pub namespace_symbol: Option<SymbolRef>,
pub exports_kind: Option<ExportsKind>,
pub module_type: ModuleType,
pub is_entry: bool,
Expand All @@ -37,8 +37,7 @@ impl NormalModuleBuilder {
pub fn initialize_namespace_binding(&mut self, symbol_table: &mut SymbolMap) {
let name = format!("{}_ns", self.path.as_ref().unwrap().generate_unique_name());
let symbol_ref: SymbolRef = (self.id.unwrap(), symbol_table.create_symbol(name.into())).into();
let refer = symbol_table.create_reference(Some(symbol_ref.symbol));
self.namespace_symbol = Some((symbol_ref, refer));
self.namespace_symbol = Some(symbol_ref);
}

pub fn build(self) -> NormalModule {
Expand Down
23 changes: 11 additions & 12 deletions crates/rolldown/src/bundler/module/normal_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt::Debug;

use index_vec::IndexVec;
use oxc::{
semantic::{ReferenceId, ScopeTree, SymbolId},
semantic::{ScopeTree, SymbolId},
span::{Atom, Span},
};
use rolldown_common::{
Expand Down Expand Up @@ -42,7 +42,7 @@ pub struct NormalModule {
pub star_exports: Vec<ImportRecordId>,
pub exports_kind: ExportsKind,
pub scope: ScopeTree,
pub namespace_symbol: (SymbolRef, ReferenceId),
pub namespace_symbol: SymbolRef,
pub default_export_symbol: Option<SymbolId>,
}

Expand Down Expand Up @@ -105,7 +105,7 @@ impl NormalModule {
if !self_linker_module.is_symbol_for_namespace_referenced {
self_linker_module.is_symbol_for_namespace_referenced = true;
self_linker_module.virtual_stmt_infos.push(VirtualStmtInfo {
declared_symbols: vec![self.namespace_symbol.0.symbol],
declared_symbols: vec![self.namespace_symbol.symbol],
..Default::default()
});
}
Expand Down Expand Up @@ -174,7 +174,7 @@ impl NormalModule {
match importee {
Module::Normal(importee) => {
let resolved = if named_import.is_imported_star {
Resolution::Found(importee.namespace_symbol.0)
Resolution::Found(importee.namespace_symbol)
} else {
importee.resolve_export(&named_import.imported, resolve_set, modules, symbols)
};
Expand All @@ -199,7 +199,7 @@ impl NormalModule {
match importee {
Module::Normal(importee) => {
if re.is_imported_star {
return Resolution::Found(importee.namespace_symbol.0);
return Resolution::Found(importee.namespace_symbol);
}
importee.resolve_export(&re.imported, resolve_set, modules, symbols)
}
Expand Down Expand Up @@ -279,7 +279,7 @@ impl NormalModule {
match importee {
Module::Normal(importee) => {
if importee.exports_kind == ExportsKind::CommonJs {
return Resolution::Runtime(importee.namespace_symbol.0);
return Resolution::Runtime(importee.namespace_symbol);
}
}
Module::External(_) => {}
Expand All @@ -292,15 +292,15 @@ impl NormalModule {
match importee {
Module::Normal(importee) => {
if importee.exports_kind == ExportsKind::CommonJs {
return Resolution::Runtime(importee.namespace_symbol.0);
return Resolution::Runtime(importee.namespace_symbol);
}
}
Module::External(_) => {}
}
}
}
} else if has_cjs_star_resolution || self.exports_kind == ExportsKind::CommonJs {
return Resolution::Runtime(self.namespace_symbol.0);
return Resolution::Runtime(self.namespace_symbol);
}
return Resolution::None;
}
Expand Down Expand Up @@ -335,7 +335,7 @@ impl NormalModule {
self.resource_id.generate_unique_name()
)
.into();
let symbol = symbols.tables[self.id].create_symbol(name);
let symbol = symbols.create_symbol(self.id, name).symbol;
self_linker_module.wrap_symbol = Some((self.id, symbol).into());
self_linker_module
.virtual_stmt_infos
Expand All @@ -362,13 +362,12 @@ impl NormalModule {
self_linker_module: &mut LinkerModule,
symbols: &mut Symbols,
) -> SymbolRef {
let local_symbol = symbols.tables[self.id].create_symbol(name);
let local_symbol_ref = (self.id, local_symbol).into();
let local_symbol_ref = symbols.create_symbol(self.id, name);
self_linker_module.virtual_stmt_infos.push(VirtualStmtInfo {
// FIXME: should store the symbol in `used_symbols` instead of `declared_symbols`.
// The deconflict for runtime symbols would be handled in the deconflict on cross-chunk-imported
// symbols
declared_symbols: vec![local_symbol],
declared_symbols: vec![local_symbol_ref.symbol],
..Default::default()
});
local_symbol_ref
Expand Down
29 changes: 7 additions & 22 deletions crates/rolldown/src/bundler/visitors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,14 @@ pub mod commonjs_source_render;
pub mod esm_source_render;
pub mod esm_wrap_source_render;
pub mod scanner;
use oxc::{
semantic::ReferenceId,
span::{Atom, GetSpan, Span},
};
use rolldown_common::{ExportsKind, ModuleId, ResolvedExport, SymbolRef};
use oxc::span::{Atom, GetSpan, Span};
use rolldown_common::{ExportsKind, ResolvedExport, SymbolRef};
use rustc_hash::FxHashMap;
use string_wizard::{MagicString, UpdateOptions};

use super::{
chunk::chunk_graph::ChunkGraph,
graph::{
graph::Graph,
linker::LinkerModule,
symbols::{get_reference_final_name, get_symbol_final_name},
},
graph::{graph::Graph, linker::LinkerModule, symbols::get_symbol_final_name},
module::{module::Module, NormalModule},
};

Expand Down Expand Up @@ -47,7 +40,7 @@ impl<'ast> RendererContext<'ast> {
let wrap_symbol_name =
linker_module.wrap_symbol.and_then(|s| get_symbol_final_name(s, &graph.symbols, final_names));
let namespace_symbol_name = get_symbol_final_name(
(module.id, module.namespace_symbol.0.symbol).into(),
(module.id, module.namespace_symbol.symbol).into(),
&graph.symbols,
final_names,
);
Expand Down Expand Up @@ -90,14 +83,6 @@ impl<'ast> RendererContext<'ast> {
get_symbol_final_name(symbol, &self.graph.symbols, self.final_names)
}

pub fn _get_reference_final_name(
&self,
module_id: ModuleId,
reference_id: ReferenceId,
) -> Option<&Atom> {
get_reference_final_name(module_id, reference_id, &self.graph.symbols, self.final_names)
}

pub fn get_runtime_symbol_final_name(&self, name: &Atom) -> &Atom {
let symbol = self.graph.runtime.resolve_symbol(name);
self.get_symbol_final_name(symbol).unwrap()
Expand Down Expand Up @@ -143,7 +128,7 @@ impl<'ast> RendererContext<'ast> {
if self.module.module_type.is_esm() { ", 1" } else { "" }
);
if with_namespace_init {
let namespace_name = self.get_symbol_final_name(importee.namespace_symbol.0).unwrap();
let namespace_name = self.get_symbol_final_name(importee.namespace_symbol).unwrap();
format!("var {namespace_name} = {code};\n")
} else {
code
Expand All @@ -166,7 +151,7 @@ impl<'ast> RendererContext<'ast> {

pub fn visit_identifier_reference(&mut self, ident: &'ast oxc::ast::ast::IdentifierReference) {
if let Some(symbol_id) =
self.graph.symbols.tables[self.module.id].references[ident.reference_id.get().unwrap()]
self.graph.symbols.references_table[self.module.id][ident.reference_id.get().unwrap()]
{
let symbol_ref = (self.module.id, symbol_id).into();
if let Some(unresolved_symbol) = self.linker_module.unresolved_symbols.get(&symbol_ref) {
Expand Down Expand Up @@ -276,7 +261,7 @@ impl<'ast> RendererContext<'ast> {
self.source.update(expr.span.start, expr.span.end, format!("{wrap_symbol_name}()"));
} else {
let namespace_name = self
.get_symbol_final_name((importee.id, importee.namespace_symbol.0.symbol).into())
.get_symbol_final_name((importee.id, importee.namespace_symbol.symbol).into())
.unwrap();
let to_commonjs_runtime_symbol_name =
self.get_runtime_symbol_final_name(&"__toCommonJS".into());
Expand Down

0 comments on commit 5b980d5

Please sign in to comment.