feat: 对小整数做额外枚举以优化性能

This commit is contained in:
爱特每羊队
2026-06-06 09:52:00 +08:00
parent 47dfb86293
commit 6502f7b5ee
5 changed files with 14 additions and 4 deletions
+9 -1
View File
@@ -8,6 +8,10 @@ pub use oxide_parser::{BinaryOperator, Expression, Statement, UnaryOperator};
pub struct Compiler;
fn is_int_literal(value: f64) -> bool {
value.fract() == 0.0 && value >= i32::MIN as f64 && value <= i32::MAX as f64
}
struct CompileCtx {
bytecode: Vec<opcode::Instr>,
constants: Vec<Constant>,
@@ -312,7 +316,11 @@ impl Compiler {
fn emit_expression(&self, expr: &Expression, ctx: &mut CompileCtx) -> Result<u8, String> {
match expr {
Expression::NumericLiteral(n) => {
let idx = ctx.add_constant(Constant::Number(n.value));
let idx = if is_int_literal(n.value) {
ctx.add_constant(Constant::Int(n.value as i32))
} else {
ctx.add_constant(Constant::Number(n.value))
};
let r = ctx.alloc_reg();
ctx.emit(opcode::encode(
OpCode::LOAD_CONST,
+1
View File
@@ -5,6 +5,7 @@ use crate::opcode::{self, OpCode};
#[derive(Debug, Clone, PartialEq)]
pub enum Constant {
Number(f64),
Int(i32),
String(String),
Boolean(bool),
Null,
@@ -34,7 +34,7 @@ fn compile_constants() {
assert!(!module.constants.is_empty());
assert_eq!(
module.constants[0],
oxide_compiler::compiler::Constant::Number(42.0)
oxide_compiler::compiler::Constant::Int(42)
);
}
@@ -120,7 +120,7 @@ fn compile_var_declaration() {
assert!(!module.bytecode.is_empty());
assert_eq!(
module.constants[0],
oxide_compiler::compiler::Constant::Number(42.0)
oxide_compiler::compiler::Constant::Int(42)
);
}
+1
View File
@@ -113,6 +113,7 @@ impl Vm {
.iter()
.map(|c| match c {
Constant::Number(v) => JsValue::float(*v),
Constant::Int(v) => JsValue::int(*v),
Constant::String(s) => self.intern(s),
Constant::Boolean(b) => JsValue::bool(*b),
Constant::Null => JsValue::null(),
+1 -1
View File
@@ -34,7 +34,7 @@ fn object_create_and_read() {
assert!(obj.is_object());
let obj_ref = unsafe { &*obj.as_js_object_ptr() };
assert_eq!(obj_ref.prop_count(), 1, "object should have 1 property");
assert!(obj_ref.get_inline_prop(0).is_double());
assert!(obj_ref.get_inline_prop(0).is_int());
}
#[test]