perf: typeof 改 js_type 单次提取并复用进程级静态字符串消除每次分配
This commit is contained in:
@@ -343,8 +343,12 @@ fn format_error_message_empty_name() {
|
||||
|
||||
#[test]
|
||||
fn error_stack_is_string() {
|
||||
let result = eval("typeof new Error().stack()").unwrap();
|
||||
let vm = make_vm();
|
||||
let allocator = oxide_parser::Allocator::default();
|
||||
let program = oxide_parser::parse(&allocator, "typeof new Error().stack()").unwrap();
|
||||
let module = Compiler::new().compile(&program).unwrap();
|
||||
let mut vm = make_vm();
|
||||
let result = vm.run(&module).unwrap();
|
||||
// typeof 结果复用进程级静态串,同 VM 上读取(跨 VM 指针存活由实现保证,不做假设)。
|
||||
let s = vm.lookup_str(result);
|
||||
assert_eq!(s, Some("string".to_string()));
|
||||
}
|
||||
|
||||
@@ -252,6 +252,40 @@ fn eval_signed_zero_object_is_and_array_methods() {
|
||||
assert_eq!(eval("[NaN].includes(NaN)"), "true");
|
||||
}
|
||||
|
||||
// typeof 结果断言需要真实字符串内容,单独用 (Vm, JsValue) 形态的辅助。
|
||||
fn eval_ty(source: &str) -> Result<(Vm, JsValue), String> {
|
||||
let allocator = oxide_parser::Allocator::default();
|
||||
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
|
||||
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
|
||||
let mut vm = Vm::new();
|
||||
let result = vm.run(&module)?;
|
||||
Ok((vm, result))
|
||||
}
|
||||
|
||||
// typeof:js_type 分派 + perm_string 的结果与语言类型一一对应。
|
||||
#[test]
|
||||
fn eval_typeof_all_kinds() {
|
||||
let cases: &[(&str, &str)] = &[
|
||||
("typeof 1", "number"),
|
||||
("typeof 1.5", "number"),
|
||||
("typeof NaN", "number"),
|
||||
("typeof 's'", "string"),
|
||||
("typeof true", "boolean"),
|
||||
("typeof null", "object"),
|
||||
("typeof undefined", "undefined"),
|
||||
("typeof function(){}", "function"),
|
||||
("typeof Symbol('x')", "symbol"),
|
||||
("typeof 1n", "bigint"),
|
||||
("typeof {}", "object"),
|
||||
("typeof []", "object"),
|
||||
];
|
||||
for (src, expected) in cases {
|
||||
let (vm, result) = eval_ty(src).unwrap_or_else(|e| panic!("{src} failed: {e}"));
|
||||
let actual = vm.lookup_str(result).unwrap_or_default();
|
||||
assert_eq!(actual, *expected, "{src} 的 typeof 结果不符");
|
||||
}
|
||||
}
|
||||
|
||||
// 算术 +:对象操作数经 valueOf 强转。
|
||||
#[test]
|
||||
fn add_object_valueof_coercion() {
|
||||
|
||||
@@ -20,9 +20,14 @@ fn run(module: &CompiledModule) -> JsValue {
|
||||
}
|
||||
|
||||
fn eval_str(source: &str) -> String {
|
||||
let v = eval(source);
|
||||
let allocator = Allocator::default();
|
||||
let program = oxide_parser::parse(&allocator, source).expect("parse failed");
|
||||
let module = Compiler::new().compile(&program).expect("compile failed");
|
||||
let mut vm = Vm::new();
|
||||
let v = vm.run(&module).expect("vm run failed");
|
||||
// 字符串结果须在同一 VM 上读:perm 串指向 VM 私有内核,VM drop 后指针悬垂。
|
||||
if v.is_string() {
|
||||
oxide_runtime_api::to_string(v)
|
||||
vm.lookup_str(v).unwrap_or_default()
|
||||
} else {
|
||||
format!("{v}")
|
||||
}
|
||||
|
||||
@@ -16,9 +16,10 @@ fn eval(source: &str) -> Result<(Vm, JsValue), String> {
|
||||
}
|
||||
|
||||
fn eval_str(source: &str) -> Result<String, String> {
|
||||
let (_vm, v) = eval(source)?;
|
||||
let (vm, v) = eval(source)?;
|
||||
// 字符串结果须在同一 VM 上读:perm 串指向 VM 私有内核,VM drop 后指针悬垂。
|
||||
if v.is_string() {
|
||||
Ok(oxide_runtime_api::to_string(v))
|
||||
Ok(vm.lookup_str(v).unwrap_or_default())
|
||||
} else {
|
||||
Ok(format!("{v}"))
|
||||
}
|
||||
|
||||
@@ -26,9 +26,14 @@ fn eval_int(source: &str) -> i32 {
|
||||
}
|
||||
|
||||
fn eval_str(source: &str) -> String {
|
||||
let v = eval(source);
|
||||
let allocator = Allocator::default();
|
||||
let program = oxide_parser::parse(&allocator, source).expect("parse failed");
|
||||
let module = Compiler::new().compile(&program).expect("compile failed");
|
||||
let mut vm = Vm::new();
|
||||
let v = vm.run(&module).expect("vm run failed");
|
||||
// 字符串结果须在同一 VM 上读:perm 串指向 VM 私有内核,VM drop 后指针悬垂。
|
||||
if v.is_string() {
|
||||
oxide_runtime_api::to_string(v)
|
||||
vm.lookup_str(v).unwrap_or_default()
|
||||
} else {
|
||||
format!("{v}")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user