fix: delete 严格报错补 SyntaxError、非箭头函数重置 super 作用域、runner 去两处 skip

- emitter.rs:delete 标识符报错文本补 "SyntaxError",负向用例按文案匹配
- compiler.rs + emitter.rs:compile_function_body(_with_bindings) 加 is_arrow 参数;
  非箭头函数重置 in_derived_constructor/in_instance_method/in_static_method 为 false,
  不再继承父级 super 标记
- main.rs:非负向 vm-error skip 列表移除 "RangeError" 文案匹配
- main.rs:compile-error skip 列表移除 "before initialization" 文案匹配
This commit is contained in:
2026-06-10 22:07:38 +08:00
parent 149b2ed7ce
commit 36ce02a03b
3 changed files with 57 additions and 21 deletions
+17 -6
View File
@@ -308,15 +308,19 @@ impl Compiler {
/// This performs both counting and emitting in one pass.
/// When `is_expression_body` is true (arrow function with expression body),
/// the last expression's value is returned instead of undefined.
/// `is_arrow` controls whether super flags are inherited from the parent scope
/// (true for arrow functions, which have lexical super) or reset to false
/// (false for regular functions, which create a new super scope).
pub(crate) fn compile_function_body<'a>(
&self, param_names: &[String], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, is_expression_body: bool,
&self, param_names: &[String], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
is_expression_body: bool, is_arrow: bool,
) -> Result<CompiledModule, String> {
self.compile_function_body_with_bindings(param_names, body_stmts, parent_ctx, is_expression_body, &[])
self.compile_function_body_with_bindings(param_names, body_stmts, parent_ctx, is_expression_body, &[], is_arrow)
}
pub(crate) fn compile_function_body_with_bindings<'a>(
&self, param_names: &[String], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, is_expression_body: bool,
extra_bindings: &[(&str, u8)],
extra_bindings: &[(&str, u8)], is_arrow: bool,
) -> Result<CompiledModule, String> {
let mut ctx = CompileCtx::new();
@@ -326,9 +330,16 @@ impl Compiler {
// Propagate enclosing_this_reg so nested arrow functions capture the correct `this`.
ctx.enclosing_this_reg = parent_ctx.enclosing_this_reg;
ctx.in_derived_constructor = parent_ctx.in_derived_constructor;
ctx.in_instance_method = parent_ctx.in_instance_method;
ctx.in_static_method = parent_ctx.in_static_method;
// Only arrow functions have lexical super; regular functions create a new super scope.
if is_arrow {
ctx.in_derived_constructor = parent_ctx.in_derived_constructor;
ctx.in_instance_method = parent_ctx.in_instance_method;
ctx.in_static_method = parent_ctx.in_static_method;
} else {
ctx.in_derived_constructor = false;
ctx.in_instance_method = false;
ctx.in_static_method = false;
}
// Inherit parent's global scope entries so previously-declared function names
// are visible from within the body.
+9 -9
View File
@@ -77,9 +77,9 @@ impl Compiler {
let mut ctor_module = if let Some(method) = constructor_method {
let (param_names, body_stmts) = self.extract_function_parts(method.value.as_ref())?;
self.compile_function_body_with_bindings(&param_names, body_stmts, ctx, false, &self_binding)?
self.compile_function_body_with_bindings(&param_names, body_stmts, ctx, false, &self_binding, false)?
} else {
let mut module = self.compile_function_body_with_bindings(&[], &[], ctx, false, &self_binding)?;
let mut module = self.compile_function_body_with_bindings(&[], &[], ctx, false, &self_binding, false)?;
if is_derived {
module.bytecode.clear();
module.constants.clear();
@@ -119,7 +119,7 @@ impl Compiler {
let saved_method = ctx.in_instance_method;
ctx.in_instance_method = true;
let mut method_module =
self.compile_function_body_with_bindings(&param_names, body_stmts, ctx, false, &self_binding)?;
self.compile_function_body_with_bindings(&param_names, body_stmts, ctx, false, &self_binding, false)?;
ctx.in_instance_method = saved_method;
method_module.function_name = Some(method_name.clone());
method_module.needs_home_object = true;
@@ -154,7 +154,7 @@ impl Compiler {
let saved_static = ctx.in_static_method;
ctx.in_static_method = true;
let mut method_module =
self.compile_function_body_with_bindings(&param_names, body_stmts, ctx, false, &self_binding)?;
self.compile_function_body_with_bindings(&param_names, body_stmts, ctx, false, &self_binding, false)?;
ctx.in_static_method = saved_static;
method_module.function_name = Some(method_name.clone());
method_module.needs_home_object = true;
@@ -214,7 +214,7 @@ impl Compiler {
ctx.in_instance_method = !method.r#static;
ctx.in_static_method = method.r#static;
let mut method_module =
self.compile_function_body_with_bindings(&param_names, body_stmts, ctx, false, self_binding)?;
self.compile_function_body_with_bindings(&param_names, body_stmts, ctx, false, self_binding, false)?;
ctx.in_instance_method = saved_instance;
ctx.in_static_method = saved_static;
method_module.function_name = Some(method_name.to_string());
@@ -550,7 +550,7 @@ impl Compiler {
let body_stmts: &[Statement] = if let Some(body) = &fd.body { &body.statements } else { &[] };
// Compile body into sub-module
let mut sub_module = self.compile_function_body(&param_names, body_stmts, ctx, false)?;
let mut sub_module = self.compile_function_body(&param_names, body_stmts, ctx, false, false)?;
sub_module.function_name = Some(name.clone());
ctx.sub_modules.push(sub_module);
// 1-indexed: 0 = no sub_module (sentinel)
@@ -791,7 +791,7 @@ impl Compiler {
}
UnaryOperator::Delete => match &un.argument {
Expression::Identifier(_) => {
Err("delete of global variable is not allowed in strict mode".into())
Err("SyntaxError: delete of an unqualified identifier in strict mode".into())
}
Expression::StaticMemberExpression(member) => {
let obj_reg = self.emit_expression(&member.object, ctx)?;
@@ -1274,7 +1274,7 @@ impl Compiler {
let body_stmts = &arrow.body.statements;
let is_expr_body = arrow.expression;
let mut sub_module = self.compile_function_body(&param_names, body_stmts, ctx, is_expr_body)?;
let mut sub_module = self.compile_function_body(&param_names, body_stmts, ctx, is_expr_body, true)?;
sub_module.is_arrow = true;
ctx.sub_modules.push(sub_module);
@@ -1297,7 +1297,7 @@ impl Compiler {
let body_stmts: &[Statement] = if let Some(body) = &fe.body { &body.statements } else { &[] };
let mut sub_module = self.compile_function_body(&param_names, body_stmts, ctx, false)?;
let mut sub_module = self.compile_function_body(&param_names, body_stmts, ctx, false, false)?;
if let Some(id) = &fe.id {
sub_module.function_name = Some(id.name.to_string());
}