Skip to content
Draft
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
25 changes: 21 additions & 4 deletions src/cached_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ use rustc_hash::FxHasher;

use crate::{
helpers::{
stream_and_get_source_and_map, stream_chunks_of_raw_source,
stream_chunks_of_source_map, Chunks, GeneratedInfo, StreamChunks,
stream_and_get_source_and_map,
stream_chunks_of_raw_source_with_known_ascii,
stream_chunks_of_source_map_with_known_ascii, Chunks, GeneratedInfo,
StreamChunks,
},
object_pool::ObjectPool,
source::SourceValue,
Expand All @@ -20,6 +22,7 @@ use crate::{
struct CachedData {
hash: OnceLock<u64>,
size: OnceLock<usize>,
is_ascii: OnceLock<bool>,
chunks: OnceLock<Vec<&'static str>>,
columns_map: OnceLock<Option<SourceMap>>,
line_only_map: OnceLock<Option<SourceMap>>,
Expand Down Expand Up @@ -100,6 +103,15 @@ impl CachedSource {
}
})
}

fn is_ascii(&self) -> bool {
*self.cache.is_ascii.get_or_init(|| {
if let Some(chunks) = self.cache.chunks.get() {
return chunks.iter().all(|chunk| chunk.is_ascii());
}
self.inner.source().as_bytes().is_ascii()
})
}
}

impl Source for CachedSource {
Expand Down Expand Up @@ -169,16 +181,19 @@ struct CachedSourceChunks<'source> {
chunks: Box<dyn Chunks + 'source>,
cache: Arc<CachedData>,
source: Cow<'source, str>,
source_is_ascii: bool,
}

impl<'a> CachedSourceChunks<'a> {
fn new(cache_source: &'a CachedSource) -> Self {
let source = cache_source.source().into_string_lossy();
let source_is_ascii = cache_source.is_ascii();

Self {
chunks: cache_source.inner.stream_chunks(),
cache: cache_source.cache.clone(),
source,
source_is_ascii,
}
}
}
Expand All @@ -200,19 +215,21 @@ impl Chunks for CachedSourceChunks<'_> {
match cell.get() {
Some(map) => {
if let Some(map) = map {
stream_chunks_of_source_map(
stream_chunks_of_source_map_with_known_ascii(
options,
object_pool,
self.source.as_ref(),
self.source_is_ascii,
map,
on_chunk,
on_source,
on_name,
)
} else {
stream_chunks_of_raw_source(
stream_chunks_of_raw_source_with_known_ascii(
self.source.as_ref(),
options,
self.source_is_ascii,
on_chunk,
on_source,
on_name,
Expand Down
32 changes: 25 additions & 7 deletions src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,22 @@ const B64_CHARS: &[u8] =

#[inline(always)]
pub fn encode_vlq(out: &mut Vec<u8>, a: u32, b: u32) {
if a == b {
out.push(b'A');
return;
}

let mut num = if a >= b {
(a - b) << 1
} else {
((b - a) << 1) + 1
};

if num < 0b100000 {
out.push(B64_CHARS[num as usize]);
return;
}

loop {
let mut digit = num & 0b11111;
num >>= 5;
Expand All @@ -30,7 +40,7 @@ pub(crate) enum MappingsEncoder {
}

impl MappingsEncoder {
#[inline]
#[inline(always)]
pub fn encode(&mut self, mapping: &Mapping) {
match self {
MappingsEncoder::Full(enc) => enc.encode(mapping),
Expand Down Expand Up @@ -86,6 +96,7 @@ impl FullMappingsEncoder {
}

impl FullMappingsEncoder {
#[inline(always)]
fn encode(&mut self, mapping: &Mapping) {
if self.active_mapping && self.current_line == mapping.generated_line {
// A mapping is still active
Expand Down Expand Up @@ -137,12 +148,16 @@ impl FullMappingsEncoder {
);
self.current_source_index = original.source_index;
}
encode_vlq(
&mut self.mappings,
original.original_line,
self.current_original_line,
);
self.current_original_line = original.original_line;
if original.original_line == self.current_original_line {
self.mappings.push(b'A');
} else {
encode_vlq(
&mut self.mappings,
original.original_line,
self.current_original_line,
);
self.current_original_line = original.original_line;
}
if original.original_column == self.current_original_column {
self.mappings.push(b'A');
} else {
Expand All @@ -166,6 +181,7 @@ impl FullMappingsEncoder {
}

#[allow(unsafe_code)]
#[inline]
fn drain(&mut self) -> String {
unsafe {
// SAFETY: The `mappings` field in the source map consists solely of ASCII characters.
Expand Down Expand Up @@ -195,6 +211,7 @@ impl LinesOnlyMappingsEncoder {
}

impl LinesOnlyMappingsEncoder {
#[inline(always)]
fn encode(&mut self, mapping: &Mapping) {
if let Some(original) = &mapping.original {
if self.last_written_line == mapping.generated_line {
Expand Down Expand Up @@ -246,6 +263,7 @@ impl LinesOnlyMappingsEncoder {
}

#[allow(unsafe_code)]
#[inline]
fn drain(&mut self) -> String {
unsafe {
// SAFETY: The `mappings` field in the source map consists solely of ASCII characters.
Expand Down
Loading