mirror of
https://github.com/swc-project/swc.git
synced 2025-01-05 12:03:47 +03:00
perf(es/parser): Remove needless strcmp
ops (#8223)
**Description:** ## The current `main` ``` es/parser/angular time: [7.9848 ms 8.0003 ms 8.0243 ms] ``` ## This PR ``` es/parser/angular time: [7.3380 ms 7.3498 ms 7.3663 ms] ```
This commit is contained in:
parent
968345b7f6
commit
3833cf4e55
64
Cargo.lock
generated
64
Cargo.lock
generated
@ -2598,18 +2598,38 @@ version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
|
||||
dependencies = [
|
||||
"phf_macros",
|
||||
"phf_shared",
|
||||
"phf_macros 0.10.0",
|
||||
"phf_shared 0.10.0",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_macros 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"phf_shared 0.10.0",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||
dependencies = [
|
||||
"phf_shared 0.11.2",
|
||||
"rand",
|
||||
]
|
||||
|
||||
@ -2619,14 +2639,27 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"phf_generator 0.10.0",
|
||||
"phf_shared 0.10.0",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
||||
dependencies = [
|
||||
"phf_generator 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.10.0"
|
||||
@ -2636,6 +2669,15 @@ dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.12"
|
||||
@ -3598,7 +3640,7 @@ dependencies = [
|
||||
"new_debug_unreachable",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"phf_shared",
|
||||
"phf_shared 0.10.0",
|
||||
"precomputed-hash",
|
||||
"serde",
|
||||
]
|
||||
@ -3609,8 +3651,8 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"phf_generator 0.10.0",
|
||||
"phf_shared 0.10.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
@ -4139,6 +4181,7 @@ dependencies = [
|
||||
"bytecheck",
|
||||
"is-macro",
|
||||
"num-bigint",
|
||||
"phf 0.11.2",
|
||||
"rkyv",
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
@ -4389,7 +4432,7 @@ dependencies = [
|
||||
name = "swc_ecma_ext_transforms"
|
||||
version = "0.110.14"
|
||||
dependencies = [
|
||||
"phf",
|
||||
"phf 0.10.1",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
@ -4489,6 +4532,7 @@ dependencies = [
|
||||
"either",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"phf 0.11.2",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -4606,7 +4650,7 @@ dependencies = [
|
||||
"criterion",
|
||||
"indexmap 1.9.3",
|
||||
"once_cell",
|
||||
"phf",
|
||||
"phf 0.10.1",
|
||||
"rayon",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
|
@ -46,6 +46,7 @@ unicode-id = "0.3"
|
||||
string_enum = { version = "0.4.1", path = "../string_enum" }
|
||||
swc_atoms = { version = "0.6.0", path = "../swc_atoms" }
|
||||
swc_common = { version = "0.33.3", path = "../swc_common" }
|
||||
phf = { version = "0.11.2", features = ["macros"] }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = "1"
|
||||
|
@ -1,5 +1,6 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use phf::phf_set;
|
||||
use scoped_tls::scoped_thread_local;
|
||||
use swc_atoms::{js_word, Atom};
|
||||
use swc_common::{
|
||||
@ -317,66 +318,87 @@ impl Ident {
|
||||
}
|
||||
}
|
||||
|
||||
static RESERVED: phf::Set<&str> = phf_set!(
|
||||
"break",
|
||||
"case",
|
||||
"catch",
|
||||
"class",
|
||||
"const",
|
||||
"continue",
|
||||
"debugger",
|
||||
"default",
|
||||
"delete",
|
||||
"do",
|
||||
"else",
|
||||
"enum",
|
||||
"export",
|
||||
"extends",
|
||||
"false",
|
||||
"finally",
|
||||
"for",
|
||||
"function",
|
||||
"if",
|
||||
"import",
|
||||
"in",
|
||||
"instanceof",
|
||||
"new",
|
||||
"null",
|
||||
"package",
|
||||
"return",
|
||||
"super",
|
||||
"switch",
|
||||
"this",
|
||||
"throw",
|
||||
"true",
|
||||
"try",
|
||||
"typeof",
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
"with",
|
||||
);
|
||||
|
||||
static RESSERVED_IN_STRICT_MODE: phf::Set<&str> = phf_set!(
|
||||
"implements",
|
||||
"interface",
|
||||
"let",
|
||||
"package",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"static",
|
||||
"yield",
|
||||
);
|
||||
|
||||
static RESERVED_IN_ES3: phf::Set<&str> = phf_set!(
|
||||
"abstract",
|
||||
"boolean",
|
||||
"byte",
|
||||
"char",
|
||||
"double",
|
||||
"final",
|
||||
"float",
|
||||
"goto",
|
||||
"int",
|
||||
"long",
|
||||
"native",
|
||||
"short",
|
||||
"synchronized",
|
||||
"throws",
|
||||
"transient",
|
||||
"volatile",
|
||||
);
|
||||
|
||||
pub trait IdentExt: AsRef<str> {
|
||||
fn is_reserved(&self) -> bool {
|
||||
[
|
||||
"break",
|
||||
"case",
|
||||
"catch",
|
||||
"class",
|
||||
"const",
|
||||
"continue",
|
||||
"debugger",
|
||||
"default",
|
||||
"delete",
|
||||
"do",
|
||||
"else",
|
||||
"enum",
|
||||
"export",
|
||||
"extends",
|
||||
"false",
|
||||
"finally",
|
||||
"for",
|
||||
"function",
|
||||
"if",
|
||||
"import",
|
||||
"in",
|
||||
"instanceof",
|
||||
"new",
|
||||
"null",
|
||||
"package",
|
||||
"return",
|
||||
"super",
|
||||
"switch",
|
||||
"this",
|
||||
"throw",
|
||||
"true",
|
||||
"try",
|
||||
"typeof",
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
"with",
|
||||
]
|
||||
.contains(&self.as_ref())
|
||||
RESERVED.contains(self.as_ref())
|
||||
}
|
||||
|
||||
fn is_reserved_in_strict_mode(&self, is_module: bool) -> bool {
|
||||
if is_module && self.as_ref() == "await" {
|
||||
return true;
|
||||
}
|
||||
[
|
||||
"implements",
|
||||
"interface",
|
||||
"let",
|
||||
"package",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"static",
|
||||
"yield",
|
||||
]
|
||||
.contains(&self.as_ref())
|
||||
RESSERVED_IN_STRICT_MODE.contains(self.as_ref())
|
||||
}
|
||||
|
||||
fn is_reserved_in_strict_bind(&self) -> bool {
|
||||
@ -384,25 +406,7 @@ pub trait IdentExt: AsRef<str> {
|
||||
}
|
||||
|
||||
fn is_reserved_in_es3(&self) -> bool {
|
||||
[
|
||||
"abstract",
|
||||
"boolean",
|
||||
"byte",
|
||||
"char",
|
||||
"double",
|
||||
"final",
|
||||
"float",
|
||||
"goto",
|
||||
"int",
|
||||
"long",
|
||||
"native",
|
||||
"short",
|
||||
"synchronized",
|
||||
"throws",
|
||||
"transient",
|
||||
"volatile",
|
||||
]
|
||||
.contains(&self.as_ref())
|
||||
RESERVED_IN_ES3.contains(self.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ swc_atoms = { version = "0.6.0", path = "../swc_atoms" }
|
||||
swc_common = { version = "0.33.3", path = "../swc_common" }
|
||||
swc_ecma_ast = { version = "0.110.3", path = "../swc_ecma_ast" }
|
||||
swc_ecma_visit = { version = "0.96.3", path = "../swc_ecma_visit", optional = true }
|
||||
phf = { version = "0.11.2", features = ["macros"] }
|
||||
|
||||
[target.'cfg(not(any(target_arch = "wasm32", target_arch = "arm")))'.dependencies]
|
||||
stacker = { version = "0.1.15", optional = true }
|
||||
|
@ -21,7 +21,7 @@ pub use self::{
|
||||
};
|
||||
use crate::{
|
||||
error::{Error, SyntaxError},
|
||||
token::{BinOpToken, Token, Word},
|
||||
token::{BinOpToken, Keyword, Token, Word},
|
||||
Context, Syntax,
|
||||
};
|
||||
|
||||
@ -761,86 +761,54 @@ impl<'a> Lexer<'a> {
|
||||
|
||||
/// See https://tc39.github.io/ecma262/#sec-names-and-keywords
|
||||
fn read_ident_or_keyword(&mut self) -> LexResult<Token> {
|
||||
static KNOWN_WORDS: phf::Map<&str, Word> = phf::phf_map! {
|
||||
"await" => Word::Keyword(Keyword::Await),
|
||||
"break" => Word::Keyword(Keyword::Break),
|
||||
"case" => Word::Keyword(Keyword::Case),
|
||||
"catch" => Word::Keyword(Keyword::Catch),
|
||||
"class" => Word::Keyword(Keyword::Class),
|
||||
"const" => Word::Keyword(Keyword::Const),
|
||||
"continue" => Word::Keyword(Keyword::Continue),
|
||||
"debugger" => Word::Keyword(Keyword::Debugger),
|
||||
"default" => Word::Keyword(Keyword::Default_),
|
||||
"delete" => Word::Keyword(Keyword::Delete),
|
||||
"do" => Word::Keyword(Keyword::Do),
|
||||
"else" => Word::Keyword(Keyword::Else),
|
||||
"export" => Word::Keyword(Keyword::Export),
|
||||
"extends" => Word::Keyword(Keyword::Extends),
|
||||
"false" => Word::False,
|
||||
"finally" => Word::Keyword(Keyword::Finally),
|
||||
"for" => Word::Keyword(Keyword::For),
|
||||
"function" => Word::Keyword(Keyword::Function),
|
||||
"if" => Word::Keyword(Keyword::If),
|
||||
"import" => Word::Keyword(Keyword::Import),
|
||||
"in" => Word::Keyword(Keyword::In),
|
||||
"instanceof" => Word::Keyword(Keyword::InstanceOf),
|
||||
"let" => Word::Keyword(Keyword::Let),
|
||||
"new" => Word::Keyword(Keyword::New),
|
||||
"null" => Word::Null,
|
||||
"return" => Word::Keyword(Keyword::Return),
|
||||
"super" => Word::Keyword(Keyword::Super),
|
||||
"switch" => Word::Keyword(Keyword::Switch),
|
||||
"this" => Word::Keyword(Keyword::This),
|
||||
"throw" => Word::Keyword(Keyword::Throw),
|
||||
"true" => Word::True,
|
||||
"try" => Word::Keyword(Keyword::Try),
|
||||
"typeof" => Word::Keyword(Keyword::TypeOf),
|
||||
"var" => Word::Keyword(Keyword::Var),
|
||||
"void" => Word::Keyword(Keyword::Void),
|
||||
"while" => Word::Keyword(Keyword::While),
|
||||
"with" => Word::Keyword(Keyword::With),
|
||||
"yield" => Word::Keyword(Keyword::Yield),
|
||||
|
||||
};
|
||||
|
||||
debug_assert!(self.cur().is_some());
|
||||
let start = self.cur_pos();
|
||||
|
||||
let (word, has_escape) = self.read_word_as_str_with(|s| {
|
||||
use crate::token::Keyword::*;
|
||||
|
||||
if s.len() == 1 || s.len() > 10 {
|
||||
{}
|
||||
} else {
|
||||
match s.as_bytes()[0] {
|
||||
b'a' if s == "await" => return Await.into(),
|
||||
b'b' if s == "break" => return Break.into(),
|
||||
b'c' => match s {
|
||||
"case" => return Case.into(),
|
||||
"const" => return Const.into(),
|
||||
"class" => return Class.into(),
|
||||
"catch" => return Catch.into(),
|
||||
"continue" => return Continue.into(),
|
||||
_ => {}
|
||||
},
|
||||
b'd' => match s {
|
||||
"do" => return Do.into(),
|
||||
"default" => return Default_.into(),
|
||||
"delete" => return Delete.into(),
|
||||
"debugger" => return Debugger.into(),
|
||||
_ => {}
|
||||
},
|
||||
b'e' => match s {
|
||||
"else" => return Else.into(),
|
||||
"export" => return Export.into(),
|
||||
"extends" => return Extends.into(),
|
||||
_ => {}
|
||||
},
|
||||
b'f' => match s {
|
||||
"for" => return For.into(),
|
||||
"false" => return Word::False,
|
||||
"finally" => return Finally.into(),
|
||||
"function" => return Function.into(),
|
||||
_ => {}
|
||||
},
|
||||
b'i' => match s {
|
||||
"if" => return If.into(),
|
||||
"import" => return Import.into(),
|
||||
"in" => return In.into(),
|
||||
"instanceof" => return InstanceOf.into(),
|
||||
_ => {}
|
||||
},
|
||||
b'l' if s == "let" => return Let.into(),
|
||||
b'n' => match s {
|
||||
"new" => return New.into(),
|
||||
"null" => return Word::Null,
|
||||
_ => {}
|
||||
},
|
||||
b'r' if s == "return" => return Return.into(),
|
||||
b's' => match s {
|
||||
"super" => return Super.into(),
|
||||
"switch" => return Switch.into(),
|
||||
_ => {}
|
||||
},
|
||||
b't' => match s {
|
||||
"this" => return This.into(),
|
||||
"true" => return Word::True,
|
||||
"try" => return Try.into(),
|
||||
"throw" => return Throw.into(),
|
||||
"typeof" => return TypeOf.into(),
|
||||
_ => {}
|
||||
},
|
||||
b'v' => match s {
|
||||
"var" => return Var.into(),
|
||||
"void" => return Void.into(),
|
||||
_ => {}
|
||||
},
|
||||
b'w' => match s {
|
||||
"while" => return While.into(),
|
||||
"with" => return With.into(),
|
||||
_ => {}
|
||||
},
|
||||
b'y' if s == "yield" => return Yield.into(),
|
||||
_ => {}
|
||||
}
|
||||
if let Some(word) = KNOWN_WORDS.get(s) {
|
||||
return word.clone();
|
||||
}
|
||||
|
||||
Word::Ident(s.into())
|
||||
|
@ -60,8 +60,8 @@ impl Context {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_reserved_word(self, word: &str) -> bool {
|
||||
match word {
|
||||
pub fn is_reserved_word(self, word: &Atom) -> bool {
|
||||
match &**word {
|
||||
"let" => self.strict,
|
||||
// SyntaxError in the module only, not in the strict.
|
||||
// ```JavaScript
|
||||
|
@ -58,18 +58,14 @@ macro_rules! define_known_ident {
|
||||
)*
|
||||
}
|
||||
|
||||
impl std::str::FromStr for KnownIdent {
|
||||
type Err = ();
|
||||
static STR_TO_KNOWN_IDENT: phf::Map<&'static str, KnownIdent> = phf::phf_map! {
|
||||
$(
|
||||
$value => KnownIdent::$name,
|
||||
)*
|
||||
};
|
||||
|
||||
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
$(
|
||||
$value => Ok(Self::$name),
|
||||
)*
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KnownIdent> for Atom {
|
||||
|
||||
@ -140,6 +136,14 @@ define_known_ident!(
|
||||
Public => "public",
|
||||
);
|
||||
|
||||
impl std::str::FromStr for KnownIdent {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
STR_TO_KNOWN_IDENT.get(s).cloned().ok_or(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum WordKind {
|
||||
Keyword(Keyword),
|
||||
@ -576,6 +580,7 @@ impl From<&'_ str> for Word {
|
||||
}
|
||||
|
||||
impl From<&'_ str> for IdentLike {
|
||||
#[inline]
|
||||
fn from(s: &str) -> Self {
|
||||
s.parse::<KnownIdent>()
|
||||
.map(Self::Known)
|
||||
|
Loading…
Reference in New Issue
Block a user