Skip to content

Commit 60fe5f0

Browse files
authoredJun 14, 2024··
perf(es/parser): Do not track raw by hand (#9047)
**Description:** We can skip this logic completely, as it's `raw`. ~I'm under the impression that I'm super stupid~
1 parent 0a3265e commit 60fe5f0

File tree

6 files changed

+44
-81
lines changed

6 files changed

+44
-81
lines changed
 

‎crates/swc_ecma_ast/src/expr.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,8 @@ pub struct TplElement {
10201020
/// don't have to worry about this value.
10211021
pub cooked: Option<Atom>,
10221022

1023+
/// You may need to perform. `.replace("\r\n", "\n").replace('\r', "\n")` on
1024+
/// this value.
10231025
pub raw: Atom,
10241026
}
10251027

‎crates/swc_ecma_codegen/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1965,11 +1965,12 @@ where
19651965
fn emit_quasi(&mut self, node: &TplElement) -> Result {
19661966
srcmap!(node, true);
19671967

1968+
let raw = node.raw.replace("\r\n", "\n").replace('\r', "\n");
19681969
if self.cfg.minify || (self.cfg.ascii_only && !node.raw.is_ascii()) {
1969-
let v = get_template_element_from_raw(&node.raw, self.cfg.ascii_only);
1970+
let v = get_template_element_from_raw(&raw, self.cfg.ascii_only);
19701971
self.wr.write_str_lit(DUMMY_SP, &v)?;
19711972
} else {
1972-
self.wr.write_str_lit(DUMMY_SP, &node.raw)?;
1973+
self.wr.write_str_lit(DUMMY_SP, &raw)?;
19731974
}
19741975

19751976
srcmap!(node, false);

‎crates/swc_ecma_codegen/tests/test262.rs

+2-17
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use std::{
2-
env,
32
fs::read_to_string,
4-
io::{self, Write},
53
path::{Path, PathBuf},
6-
sync::{Arc, RwLock},
74
};
85

96
use swc_common::comments::SingleThreadedComments;
@@ -105,7 +102,7 @@ fn do_test(entry: &Path, minify: bool) {
105102
"\n\n========== Running codegen test {}\nSource:\n{}\n",
106103
file_name, input
107104
);
108-
let mut wr = Buf(Arc::new(RwLock::new(vec![])));
105+
let mut wr = vec![];
109106

110107
::testing::run_test(false, |cm, handler| {
111108
let src = cm.load_file(entry).expect("failed to load file");
@@ -168,23 +165,11 @@ fn do_test(entry: &Path, minify: bool) {
168165
}
169166
let ref_file = format!("{}", ref_dir.join(&file_name).display());
170167

171-
let code_output = wr.0.read().unwrap();
168+
let code_output = wr;
172169
let with_srcmap =
173170
NormalizedOutput::from(String::from_utf8_lossy(&code_output).into_owned());
174171
with_srcmap.compare_to_file(ref_file).unwrap();
175172
Ok(())
176173
})
177174
.expect("failed to run test");
178175
}
179-
180-
#[derive(Debug, Clone)]
181-
struct Buf(Arc<RwLock<Vec<u8>>>);
182-
impl Write for Buf {
183-
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
184-
self.0.write().unwrap().write(data)
185-
}
186-
187-
fn flush(&mut self) -> io::Result<()> {
188-
self.0.write().unwrap().flush()
189-
}
190-
}

‎crates/swc_ecma_parser/src/lexer/jsx.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,7 @@ impl<'a> Lexer<'a> {
211211
pub(super) fn read_jsx_str(&mut self, quote: char) -> LexResult<Token> {
212212
debug_assert!(self.syntax.jsx());
213213

214-
let mut raw = String::new();
215-
216-
raw.push(quote);
214+
let start = self.input.cur_pos();
217215

218216
unsafe {
219217
// Safety: cur() was Some(quote)
@@ -243,8 +241,6 @@ impl<'a> Lexer<'a> {
243241

244242
out.push_str(value);
245243
out.push('\\');
246-
raw.push_str(value);
247-
raw.push('\\');
248244

249245
self.bump();
250246

@@ -264,12 +260,10 @@ impl<'a> Lexer<'a> {
264260
};
265261

266262
out.push_str(value);
267-
raw.push_str(value);
268263

269264
let jsx_entity = self.read_jsx_entity()?;
270265

271266
out.push(jsx_entity.0);
272-
raw.push_str(&jsx_entity.1);
273267

274268
chunk_start = self.input.cur_pos();
275269
} else if ch.is_line_terminator() {
@@ -279,16 +273,13 @@ impl<'a> Lexer<'a> {
279273
};
280274

281275
out.push_str(value);
282-
raw.push_str(value);
283276

284277
match self.read_jsx_new_line(false)? {
285278
Either::Left(s) => {
286279
out.push_str(s);
287-
raw.push_str(s);
288280
}
289281
Either::Right(c) => {
290282
out.push(c);
291-
raw.push(c);
292283
}
293284
}
294285

@@ -308,7 +299,6 @@ impl<'a> Lexer<'a> {
308299
};
309300

310301
out.push_str(value);
311-
raw.push_str(value);
312302

313303
// it might be at the end of the file when
314304
// the string literal is unterminated
@@ -319,7 +309,11 @@ impl<'a> Lexer<'a> {
319309
}
320310
}
321311

322-
raw.push(quote);
312+
let end = self.input.cur_pos();
313+
let raw = unsafe {
314+
// Safety: Both of `start` and `end` are generated from `cur_pos()`
315+
self.input.slice(start, end)
316+
};
323317

324318
Ok(Token::Str {
325319
value: self.atoms.atom(out),

‎crates/swc_ecma_parser/src/lexer/mod.rs

+24-37
Original file line numberDiff line numberDiff line change
@@ -1000,11 +1000,8 @@ impl<'a> Lexer<'a> {
10001000
fn read_str_lit(&mut self) -> LexResult<Token> {
10011001
debug_assert!(self.cur() == Some('\'') || self.cur() == Some('"'));
10021002
let start = self.cur_pos();
1003-
let mut raw = String::new();
10041003
let quote = self.cur().unwrap();
10051004

1006-
raw.push(quote);
1007-
10081005
self.bump(); // '"'
10091006

10101007
self.with_buf(|l, out| {
@@ -1015,42 +1012,40 @@ impl<'a> Lexer<'a> {
10151012
.input
10161013
.uncons_while(|c| c != quote && c != '\\' && !c.is_line_break());
10171014
out.push_str(s);
1018-
raw.push_str(s);
10191015
}
10201016
l.cur()
10211017
} {
10221018
match c {
10231019
c if c == quote => {
1024-
raw.push(c);
1025-
10261020
l.bump();
10271021

1022+
let end = l.cur_pos();
1023+
1024+
let raw = unsafe {
1025+
// Safety: start and end are valid position because we got them from
1026+
// `self.input`
1027+
l.input.slice(start, end)
1028+
};
1029+
10281030
return Ok(Token::Str {
10291031
value: l.atoms.atom(&*out),
10301032
raw: l.atoms.atom(raw),
10311033
});
10321034
}
10331035
'\\' => {
1034-
raw.push(c);
1035-
10361036
let mut wrapped = Raw(Some(Default::default()));
10371037

10381038
if let Some(chars) = l.read_escaped_char(&mut wrapped, false)? {
10391039
for c in chars {
10401040
out.extend(c);
10411041
}
10421042
}
1043-
1044-
raw.push_str(&wrapped.0.unwrap());
10451043
}
10461044
c if c.is_line_break() => {
1047-
raw.push(c);
1048-
10491045
break;
10501046
}
10511047
_ => {
10521048
out.push(c);
1053-
raw.push(c);
10541049

10551050
l.bump();
10561051
}
@@ -1059,6 +1054,13 @@ impl<'a> Lexer<'a> {
10591054

10601055
l.emit_error(start, SyntaxError::UnterminatedStrLit);
10611056

1057+
let end = l.cur_pos();
1058+
1059+
let raw = unsafe {
1060+
// Safety: start and end are valid position because we got them from
1061+
// `self.input`
1062+
l.input.slice(start, end)
1063+
};
10621064
Ok(Token::Str {
10631065
value: l.atoms.atom(&*out),
10641066
raw: l.atoms.atom(raw),
@@ -1160,19 +1162,7 @@ impl<'a> Lexer<'a> {
11601162

11611163
let mut cooked = Ok(String::new());
11621164
let mut cooked_slice_start = start;
1163-
let mut raw = SmartString::new();
1164-
let mut raw_slice_start = start;
1165-
1166-
macro_rules! consume_raw {
1167-
() => {{
1168-
let last_pos = self.cur_pos();
1169-
raw.push_str(unsafe {
1170-
// Safety: Both of start and last_pos are valid position because we got them
1171-
// from `self.input`
1172-
self.input.slice(raw_slice_start, last_pos)
1173-
});
1174-
}};
1175-
}
1165+
let raw_slice_start = start;
11761166

11771167
macro_rules! consume_cooked {
11781168
() => {{
@@ -1201,21 +1191,24 @@ impl<'a> Lexer<'a> {
12011191
}
12021192

12031193
consume_cooked!();
1204-
consume_raw!();
12051194

12061195
// TODO: Handle error
1196+
let end = self.input.cur_pos();
1197+
let raw = unsafe {
1198+
// Safety: Both of start and last_pos are valid position because we got them
1199+
// from `self.input`
1200+
self.input.slice(raw_slice_start, end)
1201+
};
12071202
return Ok(Token::Template {
12081203
cooked: cooked.map(Atom::from),
1209-
raw: self.atoms.atom(&*raw),
1204+
raw: self.atoms.atom(raw),
12101205
});
12111206
}
12121207

12131208
if c == '\\' {
12141209
consume_cooked!();
1215-
consume_raw!();
12161210

1217-
raw.push('\\');
1218-
let mut wrapped = Raw(Some(raw));
1211+
let mut wrapped = Raw(None);
12191212

12201213
match self.read_escaped_char(&mut wrapped, true) {
12211214
Ok(Some(chars)) => {
@@ -1231,17 +1224,13 @@ impl<'a> Lexer<'a> {
12311224
}
12321225
}
12331226

1234-
raw = wrapped.0.unwrap();
1235-
raw_slice_start = self.cur_pos();
12361227
cooked_slice_start = self.cur_pos();
12371228
} else if c.is_line_terminator() {
12381229
self.state.had_line_break = true;
12391230

12401231
consume_cooked!();
1241-
consume_raw!();
12421232

12431233
let c = if c == '\r' && self.peek() == Some('\n') {
1244-
raw.push('\r');
12451234
self.bump(); // '\r'
12461235
'\n'
12471236
} else {
@@ -1259,8 +1248,6 @@ impl<'a> Lexer<'a> {
12591248
if let Ok(ref mut cooked) = cooked {
12601249
cooked.push(c);
12611250
}
1262-
raw.push(c);
1263-
raw_slice_start = self.cur_pos();
12641251
cooked_slice_start = self.cur_pos();
12651252
} else {
12661253
self.bump();

‎crates/swc_ecma_parser/src/lexer/number.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ impl<'a> Lexer<'a> {
4747

4848
let start = self.cur_pos();
4949
let mut raw_val = SmartString::<LazyCompact>::new();
50-
let mut raw_str = SmartString::<LazyCompact>::new();
5150

5251
let val = if starts_with_dot {
5352
// first char is '.'
@@ -69,8 +68,6 @@ impl<'a> Lexer<'a> {
6968

7069
write!(raw_val, "{}", &s.value).unwrap();
7170

72-
raw_str.push_str(&raw);
73-
7471
if starts_with_zero {
7572
// TODO: I guess it would be okay if I don't use -ffast-math
7673
// (or something like that), but needs review.
@@ -132,7 +129,6 @@ impl<'a> Lexer<'a> {
132129
// `.1.a`, `.1e-4.a` are valid,
133130
if self.cur() == Some('.') {
134131
raw_val.push('.');
135-
raw_str.push('.');
136132

137133
self.bump();
138134

@@ -145,8 +141,6 @@ impl<'a> Lexer<'a> {
145141
// Read numbers after dot
146142
let dec_val = self.read_int::<10>(0, &mut raw)?;
147143

148-
raw_str.push_str(raw.0.as_ref().unwrap());
149-
150144
val = {
151145
if dec_val.is_some() {
152146
raw_val.push_str(raw.0.as_ref().unwrap());
@@ -170,7 +164,7 @@ impl<'a> Lexer<'a> {
170164
// 1e+2 = 100
171165
// 1e-2 = 0.01
172166
match self.cur() {
173-
Some(e @ 'e') | Some(e @ 'E') => {
167+
Some('e') | Some('E') => {
174168
self.bump();
175169

176170
let next = match self.cur() {
@@ -182,13 +176,10 @@ impl<'a> Lexer<'a> {
182176
};
183177

184178
raw_val.push('e');
185-
raw_str.push(e);
186179

187180
let positive = if next == '+' || next == '-' {
188181
self.bump(); // remove '+', '-'
189182

190-
raw_str.push(next);
191-
192183
next == '+'
193184
} else {
194185
true
@@ -197,8 +188,6 @@ impl<'a> Lexer<'a> {
197188
let mut raw = Raw(Some(Default::default()));
198189
let exp = self.read_number_no_dot::<10>(&mut raw)?;
199190

200-
raw_str.push_str(&raw.0.take().unwrap());
201-
202191
val = if exp == f64::INFINITY {
203192
if positive && val != 0.0 {
204193
f64::INFINITY
@@ -226,7 +215,12 @@ impl<'a> Lexer<'a> {
226215

227216
self.ensure_not_ident()?;
228217

229-
Ok(Either::Left((val, self.atoms.atom(&*raw_str))))
218+
let end = self.cur_pos();
219+
let raw_str = unsafe {
220+
// Safety: We got both start and end position from `self.input`
221+
self.input.slice(start, end)
222+
};
223+
Ok(Either::Left((val, raw_str.into())))
230224
}
231225

232226
/// Returns `Left(value)` or `Right(BigInt)`

0 commit comments

Comments
 (0)
Please sign in to comment.