feat: 支持 RegExpr 与 Symbol 部分方法

This commit is contained in:
2026-06-08 10:36:39 +08:00
parent 125b91ddae
commit b8fbc93bca
19 changed files with 1057 additions and 45 deletions
+3
View File
@@ -22,6 +22,7 @@ pub(crate) fn is_side_effect_free(expr: &Expression) -> bool {
| Expression::BooleanLiteral(_)
| Expression::NullLiteral(_)
| Expression::Identifier(_)
| Expression::RegExpLiteral(_)
)
}
@@ -198,6 +199,8 @@ impl CompileCtx {
"Date",
"Set",
"Map",
"RegExp",
"Symbol",
"parseInt",
"parseFloat",
"isNaN",
+5
View File
@@ -465,8 +465,13 @@ impl Compiler {
}
_ => {
ctx.alloc_reg();
ctx.projected_pc += 1;
}
},
Expression::RegExpLiteral(_) => {
ctx.alloc_reg();
ctx.projected_pc += 1;
}
_ => {
ctx.alloc_reg();
ctx.projected_pc += 1; // LOAD_CONST or LOAD_VAR
+32
View File
@@ -1041,6 +1041,38 @@ impl Compiler {
ctx.emit(opcode::encode(OpCode::LOAD_VAR, r, 254, 0));
Ok(r)
}
Expression::RegExpLiteral(lit) => {
if let Some(raw) = &lit.raw {
let raw_str = raw.to_string();
if raw_str.len() >= 2 && raw_str.starts_with('/') {
let last_slash = raw_str.rfind('/').unwrap_or(raw_str.len() - 1);
let pattern = &raw_str[1..last_slash];
let flags = &raw_str[last_slash + 1..];
let ci = ctx.add_constant(Constant::RegExp(
pattern.to_string(),
flags.to_string(),
));
let r = ctx.alloc_reg();
ctx.emit(opcode::encode(
OpCode::LOAD_CONST,
r,
(ci & 0xFF) as u8,
((ci >> 8) & 0xFF) as u8,
));
Ok(r)
} else {
Err(format!(
"unsupported expression type: {:?}",
expr
))
}
} else {
Err(format!(
"unsupported expression type: {:?}",
expr
))
}
}
_ => Err(format!("unsupported expression type: {:?}", expr)),
}
}
+6
View File
@@ -243,6 +243,12 @@ fn hash_expression(expr: &Expression, h: &mut rustc_hash::FxHasher) {
}
}
}
Expression::RegExpLiteral(lit) => {
if let Some(raw) = &lit.raw {
raw.to_string().hash(h);
}
std::mem::discriminant(expr).hash(h);
}
_ => {
std::mem::discriminant(expr).hash(h);
}
+1
View File
@@ -11,6 +11,7 @@ pub enum Constant {
Null,
Undefined,
BytecodeFunc(u32),
RegExp(String, String),
}
pub struct CompiledModule {