From 0c904563d186feb24d003a3c376ef8ff8462dbbe Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Fri, 7 Aug 2026 20:15:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=BB=98=E8=AE=A4=E5=8F=82=E6=95=B0/?= =?UTF-8?q?=E8=A7=A3=E6=9E=84=E9=BB=98=E8=AE=A4=E5=80=BC=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=90=8D=E6=8E=A8=E6=96=AD=EF=BC=88SetFunctionName=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_emit/src/emit.rs | 4 +-- crates/oxide_emit/src/shared/binding.rs | 33 ++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/crates/oxide_emit/src/emit.rs b/crates/oxide_emit/src/emit.rs index f5b7f546..89529738 100644 --- a/crates/oxide_emit/src/emit.rs +++ b/crates/oxide_emit/src/emit.rs @@ -811,7 +811,7 @@ impl Emitter { ParamSpec::Pattern { synthetic_name, pattern, initializer } => { let src_reg = ctx.lookup(synthetic_name)?; let src_reg = if let Some(init) = initializer { - self.emit_default_if_undefined(src_reg, init, ctx)? + self.emit_default_if_undefined(src_reg, init, Some(synthetic_name), ctx)? } else { src_reg }; @@ -821,7 +821,7 @@ impl Emitter { if let Some(init) = initializer { // 默认参数:实参为 undefined 时用默认值。 let reg = ctx.lookup(name)?; - self.emit_default_if_undefined(reg, init, ctx)?; + self.emit_default_if_undefined(reg, init, Some(name), ctx)?; } } } diff --git a/crates/oxide_emit/src/shared/binding.rs b/crates/oxide_emit/src/shared/binding.rs index f14e2cb2..2c62cc94 100644 --- a/crates/oxide_emit/src/shared/binding.rs +++ b/crates/oxide_emit/src/shared/binding.rs @@ -14,7 +14,7 @@ use oxide_parser::{ impl Emitter { pub(crate) fn emit_default_if_undefined( - &self, val_reg: u32, default_expr: &Expression, ctx: &mut CompileCtx, + &self, val_reg: u32, default_expr: &Expression, name: Option<&str>, ctx: &mut CompileCtx, ) -> Result { let undef_reg = self.emit_undefined(ctx); let eq_reg = ctx.alloc_reg(); @@ -28,6 +28,21 @@ impl Emitter { let end_label = ctx.next_label_id(); ctx.inst(Inst::jmp_if_false(eq_reg, end_label)); let default_reg = self.emit_expression(default_expr, ctx)?; + // 默认值表达式是匿名函数/箭头/class 时按绑定名推断 name(SetFunctionName)。 + if let Some(name) = name { + if matches!( + default_expr, + Expression::ArrowFunctionExpression(_) + | Expression::FunctionExpression(_) + | Expression::ClassExpression(_) + ) { + if let Some(sub_mod) = ctx.nested.last_mut() { + if sub_mod.function_name.is_none() { + sub_mod.function_name = Some(name.to_string()); + } + } + } + } ctx.inst(Inst::new( OpCode::LOAD_VAR, Operand::Reg(val_reg), @@ -110,7 +125,12 @@ impl Emitter { BindingPattern::ArrayPattern(ap) => self.emit_array_binding(ap, src_reg, kind, is_const, ctx), BindingPattern::ObjectPattern(op) => self.emit_object_binding(op, src_reg, kind, is_const, ctx), BindingPattern::AssignmentPattern(ap) => { - let val_reg = self.emit_default_if_undefined(src_reg, &ap.right, ctx)?; + // `[x = fn]`:默认值函数按绑定名推断 name。 + let name = match &ap.left { + BindingPattern::BindingIdentifier(bi) => Some(bi.name.as_str()), + _ => None, + }; + let val_reg = self.emit_default_if_undefined(src_reg, &ap.right, name, ctx)?; self.emit_binding_pattern(&ap.left, val_reg, kind, is_const, ctx) } } @@ -194,7 +214,11 @@ impl Emitter { ) -> Result<(), String> { match target { AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(default) => { - let val_reg = self.emit_default_if_undefined(src_reg, &default.init, ctx)?; + let name = match &default.binding { + AssignmentTarget::AssignmentTargetIdentifier(id) => Some(id.name.as_str()), + _ => None, + }; + let val_reg = self.emit_default_if_undefined(src_reg, &default.init, name, ctx)?; self.emit_assign_target(&default.binding, val_reg, ctx) } AssignmentTargetMaybeDefault::ArrayAssignmentTarget(ap) => self.emit_array_assignment(ap, src_reg, ctx), @@ -246,7 +270,8 @@ impl Emitter { excluded.push(key.clone()); let mut prop_reg = self.emit_object_property_read(src_reg, &key, ctx); if let Some(default_expr) = &id.init { - prop_reg = self.emit_default_if_undefined(prop_reg, default_expr, ctx)?; + let name = id.binding.name.as_str(); + prop_reg = self.emit_default_if_undefined(prop_reg, default_expr, Some(name), ctx)?; } let name = id.binding.name.as_str(); let var_reg = ctx.lookup_or_global(name);