Add static eval for literals

This commit is contained in:
Andrew Morris
2023-06-23 14:10:37 +10:00
parent c880dda7c9
commit a03aecedac
2 changed files with 43 additions and 16 deletions

View File

@@ -1391,21 +1391,13 @@ impl<'a> ExpressionCompiler<'a> {
}
pub fn compile_literal(&mut self, lit: &swc_ecma_ast::Lit) -> Value {
use swc_ecma_ast::Lit::*;
let (todo_name, message) = match lit {
Str(str_) => return Value::String(str_.value.to_string()),
Bool(bool_) => return Value::Bool(bool_.value),
Null(_) => return Value::Null,
Num(num) => return Value::Number(Number(num.value)),
BigInt(bigint) => return Value::BigInt(bigint.value.clone()),
Regex(_) => ("_todo_regex_literal", "Regex literals"),
JSXText(_) => ("_todo_jsxtext_literal", "JSXText literals"),
};
self.fnc.todo(lit.span(), message);
return Value::Register(self.fnc.allocate_numbered_reg(todo_name));
match value_from_literal(lit) {
Ok(value) => value,
Err(err) => {
self.fnc.todo(lit.span(), err);
return Value::Register(self.fnc.allocate_numbered_reg("_todo_unsupported_literal"));
}
}
}
pub fn pat(&mut self, pat: &swc_ecma_ast::Pat, register: &Register, skip_release: bool) {
@@ -1727,3 +1719,17 @@ pub fn make_update_op(op: swc_ecma_ast::UpdateOp, register: Register) -> Instruc
MinusMinus => Instruction::OpDec(register),
}
}
pub fn value_from_literal(lit: &swc_ecma_ast::Lit) -> Result<Value, &'static str> {
use swc_ecma_ast::Lit::*;
Ok(match lit {
Str(str_) => Value::String(str_.value.to_string()),
Bool(bool_) => Value::Bool(bool_.value),
Null(_) => Value::Null,
Num(num) => Value::Number(Number(num.value)),
BigInt(bigint) => Value::BigInt(bigint.value.clone()),
Regex(_) => return Err("Regex literals"),
JSXText(_) => return Err("JSXText literals"),
})
}

View File

@@ -1,6 +1,27 @@
use crate::asm::{Builtin, Value};
use crate::{
asm::{Builtin, Value},
expression_compiler::value_from_literal,
};
pub fn static_eval_expr(expr: &swc_ecma_ast::Expr) -> Option<Value> {
let symbol_iterator_opt = as_symbol_iterator(expr);
if symbol_iterator_opt.is_some() {
return symbol_iterator_opt;
}
match expr {
swc_ecma_ast::Expr::Lit(lit) => match value_from_literal(lit) {
Ok(value) => return Some(value),
_ => {}
},
_ => {} // TODO: Array, Object
}
None
}
fn as_symbol_iterator(expr: &swc_ecma_ast::Expr) -> Option<Value> {
let member_expr = match expr {
swc_ecma_ast::Expr::Member(member_expr) => member_expr,
_ => return None,