diff --git a/crates/oxide_emit/src/emit.rs b/crates/oxide_emit/src/emit.rs index 9e96fa41..07b4111d 100644 --- a/crates/oxide_emit/src/emit.rs +++ b/crates/oxide_emit/src/emit.rs @@ -1874,9 +1874,10 @@ impl Emitter { if matches!(stmt, Statement::FunctionDeclaration(_)) { continue; // Already emitted above } - match self.emit_statement(stmt, &mut ctx)? { - Some(r) => last_result = Some(r), - None => last_result = None, + // 空完成值语句(变量/函数等声明)不覆写此前结果:保留最后一个非空 + // 完成值,与函数体 emit_body_stmts 的收敛口径一致。 + if let Some(r) = self.emit_statement(stmt, &mut ctx)? { + last_result = Some(r); } } if let Some(r) = last_result { diff --git a/crates/oxide_emit/src/stmt/declaration/var.rs b/crates/oxide_emit/src/stmt/declaration/var.rs index a170ba33..5acd452e 100644 --- a/crates/oxide_emit/src/stmt/declaration/var.rs +++ b/crates/oxide_emit/src/stmt/declaration/var.rs @@ -18,10 +18,10 @@ impl Emitter { } /// 变量声明本体:供 export 声明复用(导出声明需先按普通声明 emit,再就地注册导出值)。 + /// 变量声明语句完成值按规范为空记录(对外 undefined),不回填结果寄存器。 pub(crate) fn emit_variable_declaration( &self, decl: &VariableDeclaration, ctx: &mut CompileCtx, ) -> Result, String> { - let mut r = None; for d in &decl.declarations { let is_const = matches!(decl.kind, VariableDeclarationKind::Const); if is_const && d.init.is_none() { @@ -39,7 +39,6 @@ impl Emitter { } } } - r = Some(val_reg); } else { let BindingPattern::BindingIdentifier(bi) = &d.id else { return Err("destructuring declaration requires an initializer".into()); @@ -82,9 +81,8 @@ impl Emitter { ctx.inst(Inst::new(OpCode::STORE_VAR, Operand::Reg(target_reg), Operand::Reg(tmp), Operand::None)); } ctx.init_var(bi.name.as_str()); - r = Some(var_reg); } } - Ok(r) + Ok(None) } } diff --git a/crates/oxide_vm/tests/var_binding_tests.rs b/crates/oxide_vm/tests/var_binding_tests.rs index af791df9..99d674f6 100644 --- a/crates/oxide_vm/tests/var_binding_tests.rs +++ b/crates/oxide_vm/tests/var_binding_tests.rs @@ -23,7 +23,8 @@ fn eval(source: &str) -> String { #[test] fn eval_var_declaration() { - assert_eq!(eval("var x = 42"), "42"); + // 变量声明语句完成值按规范为空记录(对外 undefined),不回填初始化器值。 + assert_eq!(eval("var x = 42"), "undefined"); } #[test]