fix: 函数 async/generator 标志纳入编译缓存键防字节码错配
This commit is contained in:
@@ -8,6 +8,8 @@ pub(super) fn hash_class_element(element: &ClassElement, h: &mut rustc_hash::FxH
|
|||||||
method.r#static.hash(h);
|
method.r#static.hash(h);
|
||||||
method.computed.hash(h);
|
method.computed.hash(h);
|
||||||
std::mem::discriminant(&method.kind).hash(h);
|
std::mem::discriminant(&method.kind).hash(h);
|
||||||
|
method.value.r#async.hash(h);
|
||||||
|
method.value.generator.hash(h);
|
||||||
property::hash_property_key(&method.key, h, include_binding_names);
|
property::hash_property_key(&method.key, h, include_binding_names);
|
||||||
if method.computed {
|
if method.computed {
|
||||||
property::hash_property_key(&method.key, h, include_binding_names);
|
property::hash_property_key(&method.key, h, include_binding_names);
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ pub(super) fn hash_expression(expr: &Expression, h: &mut rustc_hash::FxHasher, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::ArrowFunctionExpression(arrow) => {
|
Expression::ArrowFunctionExpression(arrow) => {
|
||||||
|
arrow.r#async.hash(h);
|
||||||
(arrow.params.items.len() as u32).hash(h);
|
(arrow.params.items.len() as u32).hash(h);
|
||||||
if include_binding_names {
|
if include_binding_names {
|
||||||
for param in &arrow.params.items {
|
for param in &arrow.params.items {
|
||||||
@@ -91,6 +92,8 @@ pub(super) fn hash_expression(expr: &Expression, h: &mut rustc_hash::FxHasher, i
|
|||||||
hash_function_body(&arrow.body, h, include_binding_names);
|
hash_function_body(&arrow.body, h, include_binding_names);
|
||||||
}
|
}
|
||||||
Expression::FunctionExpression(fe) => {
|
Expression::FunctionExpression(fe) => {
|
||||||
|
fe.r#async.hash(h);
|
||||||
|
fe.generator.hash(h);
|
||||||
(fe.params.items.len() as u32).hash(h);
|
(fe.params.items.len() as u32).hash(h);
|
||||||
if include_binding_names {
|
if include_binding_names {
|
||||||
if let Some(id) = &fe.id {
|
if let Some(id) = &fe.id {
|
||||||
|
|||||||
@@ -194,6 +194,8 @@ fn hash_for_statement(fr: &oxide_parser::ForStatement<'_>, h: &mut rustc_hash::F
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn hash_function_declaration(fd: &Function<'_>, h: &mut rustc_hash::FxHasher, include_binding_names: bool) {
|
fn hash_function_declaration(fd: &Function<'_>, h: &mut rustc_hash::FxHasher, include_binding_names: bool) {
|
||||||
|
fd.r#async.hash(h);
|
||||||
|
fd.generator.hash(h);
|
||||||
if include_binding_names {
|
if include_binding_names {
|
||||||
if let Some(id) = &fd.id {
|
if let Some(id) = &fd.id {
|
||||||
id.name.as_str().hash(h);
|
id.name.as_str().hash(h);
|
||||||
|
|||||||
@@ -130,3 +130,49 @@ fn function_body_directives_distinguished() {
|
|||||||
"identical sources must hash equally"
|
"identical sources must hash equally"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_async_generator_flags_distinguished() {
|
||||||
|
// 函数声明四形态:body 结构相同(return 1),仅标志不同,键必须互异。
|
||||||
|
// 修复前 async/generator 不入 hash → 四键全同 → 下方 assert_ne 全红。
|
||||||
|
let sync = compiled("function f(){ return 1 }");
|
||||||
|
let async_fn = compiled("async function f(){ return 1 }");
|
||||||
|
let gen = compiled("function* f(){ return 1 }");
|
||||||
|
let async_gen = compiled("async function* f(){ return 1 }");
|
||||||
|
assert_ne!(sync, async_fn, "sync vs async function declaration");
|
||||||
|
assert_ne!(sync, gen, "sync vs generator declaration");
|
||||||
|
assert_ne!(sync, async_gen, "sync vs async generator declaration");
|
||||||
|
assert_ne!(async_fn, gen, "async vs generator declaration");
|
||||||
|
assert_ne!(async_fn, async_gen, "async vs async generator declaration");
|
||||||
|
assert_ne!(gen, async_gen, "generator vs async generator declaration");
|
||||||
|
|
||||||
|
// 函数表达式(含对象字面量方法经 FunctionExpression 分支的覆盖路径)
|
||||||
|
assert_ne!(
|
||||||
|
compiled("var f = function(){ return 1 }"),
|
||||||
|
compiled("var f = async function(){ return 1 }"),
|
||||||
|
"function expression async flag"
|
||||||
|
);
|
||||||
|
assert_ne!(
|
||||||
|
compiled("var f = function(){ return 1 }"),
|
||||||
|
compiled("var f = function*(){ return 1 }"),
|
||||||
|
"function expression generator flag"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 箭头函数(仅 async 标志;箭头无 generator)
|
||||||
|
assert_ne!(compiled("var f = () => 1"), compiled("var f = async () => 1"), "arrow async flag");
|
||||||
|
|
||||||
|
// 类方法(kind 已入 hash,但 async/generator 与 kind 正交)
|
||||||
|
assert_ne!(compiled("class A { m(){ return 1 } }"), compiled("class A { async m(){ return 1 } }"));
|
||||||
|
assert_ne!(compiled("class A { m(){ return 1 } }"), compiled("class A { *m(){ return 1 } }"));
|
||||||
|
assert_ne!(compiled("class A { m(){ return 1 } }"), compiled("class A { async *m(){ return 1 } }"));
|
||||||
|
|
||||||
|
// 对象字面量方法
|
||||||
|
assert_ne!(
|
||||||
|
compiled("var o = { m(){ return 1 } }"),
|
||||||
|
compiled("var o = { async m(){ return 1 } }"),
|
||||||
|
"object literal method async flag"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 同源等价回归
|
||||||
|
assert_eq!(compiled("async function f(){ return 1 }"), compiled("async function f(){ return 1 }"));
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user