Skip to content

Commit

Permalink
pre allocate only
Browse files Browse the repository at this point in the history
  • Loading branch information
Brooooooklyn committed Jul 29, 2024
1 parent b15b680 commit 506565c
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 44 deletions.
16 changes: 0 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ unicode-id-start = "1" # Relaxed version so the user can decide which unicode
unicode-width = "0.1.13"
ureq = { version = "2.9.6", default-features = false }
url = "2.5.2"
v_jsonescape = "0.7.3"
walkdir = "2.5.0"
wasm-bindgen = "0.2.92"

Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_codegen/examples/sourcemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn main() -> std::io::Result<()> {
.build(&ret.program);

if let Some(source_map) = source_map {
let result = source_map.to_json_string();
let result = source_map.to_json_string().unwrap();
let hash = BASE64_STANDARD.encode(format!(
"{}\0{}{}\0{}",
source_text.len(),
Expand Down
1 change: 0 additions & 1 deletion crates/oxc_sourcemap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
base64-simd = { workspace = true }
cfg-if = { workspace = true }
v_jsonescape = { workspace = true, features = ["bytes-buf"] }

rayon = { workspace = true, optional = true }

Expand Down
43 changes: 22 additions & 21 deletions crates/oxc_sourcemap/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::borrow::Cow;

#[cfg(feature = "concurrent")]
use rayon::prelude::*;
use v_jsonescape::b_escape as simd_escape;

use crate::Error;
use crate::JSONSourceMap;
/// Port from https://github.com/getsentry/rust-sourcemap/blob/master/src/encoder.rs
/// It is a helper for encode `SourceMap` to vlq sourcemap string, but here some different.
Expand All @@ -27,7 +27,7 @@ pub fn encode(sourcemap: &SourceMap) -> JSONSourceMap {

// Here using `v_jsonescape::b_escape` to serialize `names` / `source_contents` / `sources`.
// It will escape the string to avoid invalid JSON string.
pub fn encode_to_string(sourcemap: &SourceMap) -> String {
pub fn encode_to_string(sourcemap: &SourceMap) -> Result<String, Error> {
let max_segments = 12
+ sourcemap.names.len() * 2
+ sourcemap.sources.len() * 2
Expand All @@ -49,11 +49,11 @@ pub fn encode_to_string(sourcemap: &SourceMap) -> String {
}

contents.push("\"names\":[".into());
contents.push_list(sourcemap.names.iter().map(escape_json_string));
contents.push_list(sourcemap.names.iter().map(escape_json_string))?;

contents.push("],\"sources\":[".into());

contents.push_list(sourcemap.sources.iter().map(escape_json_string));
contents.push_list(sourcemap.sources.iter().map(escape_json_string))?;

// Quote `source_content` in parallel
if let Some(source_contents) = &sourcemap.source_contents {
Expand All @@ -64,7 +64,7 @@ pub fn encode_to_string(sourcemap: &SourceMap) -> String {
.par_iter()
.map(escape_json_string)
.collect();
contents.push_list(quoted_source_contents.into_iter());
contents.push_list(quoted_source_contents.into_iter())?;
} else {
contents.push_list(source_contents.iter().map(escape_json_string));
}
Expand All @@ -73,7 +73,8 @@ pub fn encode_to_string(sourcemap: &SourceMap) -> String {

if let Some(x_google_ignore_list) = &sourcemap.x_google_ignore_list {
contents.push("],\"x_google_ignoreList\":[".into());
contents.push_list(x_google_ignore_list.iter().map(std::string::ToString::to_string));
contents
.push_list(x_google_ignore_list.iter().map(std::string::ToString::to_string).map(Ok))?;
}

contents.push("],\"mappings\":\"".into());
Expand All @@ -83,7 +84,7 @@ pub fn encode_to_string(sourcemap: &SourceMap) -> String {
// Check we calculated number of segments required correctly
debug_assert!(contents.num_segments() <= max_segments);

contents.consume()
Ok(contents.consume())
}

#[allow(clippy::cast_possible_truncation)]
Expand Down Expand Up @@ -210,19 +211,20 @@ impl<'a> PreAllocatedString<'a> {
}

#[inline]
fn push_list<I>(&mut self, mut iter: I)
fn push_list<I>(&mut self, mut iter: I) -> Result<(), Error>
where
I: Iterator<Item = String>,
I: Iterator<Item = Result<String, Error>>,
{
let Some(first) = iter.next() else {
return;
return Ok(());
};
self.push(Cow::Owned(first));
self.push(Cow::Owned(first?));

for other in iter {
self.push(Cow::Borrowed(","));
self.push(Cow::Owned(other));
self.push(Cow::Owned(other?));
}
Ok(())
}

#[inline]
Expand All @@ -237,13 +239,12 @@ impl<'a> PreAllocatedString<'a> {
}
}

fn escape_json_string<S: AsRef<str>>(s: S) -> String {
fn escape_json_string<S: AsRef<str>>(s: S) -> Result<String, Error> {
let s = s.as_ref();
let mut escaped = String::with_capacity(s.len() * 2 + 2);
escaped.push('"');
simd_escape(s.as_bytes(), &mut escaped);
escaped.push('"');
escaped
let mut escaped_buf = Vec::with_capacity(s.len() * 2 + 2);
serde::Serialize::serialize(s, &mut serde_json::Serializer::new(&mut escaped_buf))?;
// Safety: `escaped_buf` is valid utf8.
Ok(unsafe { String::from_utf8_unchecked(escaped_buf) })
}

#[test]
Expand All @@ -266,7 +267,7 @@ fn test_escape_json_string() {
for (c, expected) in FIXTURES {
let mut input = String::new();
input.push(*c);
assert_eq!(escape_json_string(input), *expected);
assert_eq!(escape_json_string(input).unwrap(), *expected);
}
}

Expand All @@ -280,7 +281,7 @@ fn test_encode() {
"mappings": "AAAA,GAAIA,GAAI,EACR,IAAIA,GAAK,EAAG,CACVC,MAAM"
}"#;
let sm = SourceMap::from_json_string(input).unwrap();
let sm2 = SourceMap::from_json_string(&sm.to_json_string()).unwrap();
let sm2 = SourceMap::from_json_string(&sm.to_json_string().unwrap()).unwrap();

for (tok1, tok2) in sm.get_tokens().zip(sm2.get_tokens()) {
assert_eq!(tok1, tok2);
Expand All @@ -301,7 +302,7 @@ fn test_encode_escape_string() {
);
sm.set_x_google_ignore_list(vec![0]);
assert_eq!(
sm.to_json_string(),
sm.to_json_string().unwrap(),
r#"{"version":3,"names":["name_length_greater_than_16_\u0000"],"sources":["\u0000"],"sourcesContent":["emoji-👀-\u0000"],"x_google_ignoreList":[0],"mappings":""}"#
);
}
4 changes: 2 additions & 2 deletions crates/oxc_sourcemap/src/sourcemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl SourceMap {
/// # Errors
///
/// The `serde_json` serialization Error.
pub fn to_json_string(&self) -> String {
pub fn to_json_string(&self) -> Result<String> {
encode_to_string(self)
}

Expand All @@ -83,7 +83,7 @@ impl SourceMap {
///
/// The `serde_json` serialization Error.
pub fn to_data_url(&self) -> Result<String> {
let base_64_str = base64_simd::STANDARD.encode_to_string(self.to_json_string().as_bytes());
let base_64_str = base64_simd::STANDARD.encode_to_string(self.to_json_string()?.as_bytes());
Ok(format!("data:application/json;charset=utf-8;base64,{base_64_str}"))
}

Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_sourcemap/src/sourcemap_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,5 @@ fn test_sourcemap_builder() {
assert_eq!(sm.get_file(), Some("file"));

let expected = r#"{"version":3,"file":"file","names":["x"],"sources":["baz.js"],"sourcesContent":[""],"mappings":""}"#;
assert_eq!(expected, sm.to_json_string());
assert_eq!(expected, sm.to_json_string().unwrap());
}
2 changes: 1 addition & 1 deletion tasks/benchmark/benches/sourcemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn bench_sourcemap(criterion: &mut Criterion) {
for i in 0..2 {
concat_sourcemap_builder.add_sourcemap(&sourcemap, lines * i);
}
concat_sourcemap_builder.into_sourcemap().to_json_string();
concat_sourcemap_builder.into_sourcemap().to_json_string().unwrap();
}
});
});
Expand Down

0 comments on commit 506565c

Please sign in to comment.