From 0a1ca83661a8840ca73c9b7720a676a2004749ac Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Mon, 5 Oct 2026 22:38:53 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20if=20=E6=97=A0=20else=20=E5=81=87?= =?UTF-8?q?=E6=94=AF=E6=98=BE=E5=BC=8F=E5=86=99=20undefined=20=E6=B6=88?= =?UTF-8?q?=E9=99=A4=E5=AF=84=E5=AD=98=E5=99=A8=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E5=B7=A7=E5=90=88=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 36 ++++++++++----------- Cargo.toml | 2 +- crates/oxide_emit/src/stmt/control.rs | 10 ++++-- crates/oxide_vm/tests/control_flow_tests.rs | 8 +++++ 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa64bd55..ee23e472 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1095,7 +1095,7 @@ dependencies = [ [[package]] name = "oxide_builtins" -version = "0.8.14" +version = "0.8.15" dependencies = [ "chrono", "fast-float", @@ -1120,7 +1120,7 @@ dependencies = [ [[package]] name = "oxide_bytecode" -version = "0.8.14" +version = "0.8.15" dependencies = [ "num-bigint", "oxide_log", @@ -1128,7 +1128,7 @@ dependencies = [ [[package]] name = "oxide_cfg" -version = "0.8.14" +version = "0.8.15" dependencies = [ "oxide_bytecode", "oxide_emit", @@ -1139,7 +1139,7 @@ dependencies = [ [[package]] name = "oxide_cli" -version = "0.8.14" +version = "0.8.15" dependencies = [ "ansi_term", "bumpalo", @@ -1159,7 +1159,7 @@ dependencies = [ [[package]] name = "oxide_code_cache" -version = "0.8.14" +version = "0.8.15" dependencies = [ "lru", "oxide_bytecode", @@ -1168,7 +1168,7 @@ dependencies = [ [[package]] name = "oxide_compiler" -version = "0.8.14" +version = "0.8.15" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1187,7 +1187,7 @@ dependencies = [ [[package]] name = "oxide_dce" -version = "0.8.14" +version = "0.8.15" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1201,7 +1201,7 @@ dependencies = [ [[package]] name = "oxide_emit" -version = "0.8.14" +version = "0.8.15" dependencies = [ "num-bigint", "oxc_allocator", @@ -1216,7 +1216,7 @@ dependencies = [ [[package]] name = "oxide_ir" -version = "0.8.14" +version = "0.8.15" dependencies = [ "oxide_bytecode", "oxide_log", @@ -1225,7 +1225,7 @@ dependencies = [ [[package]] name = "oxide_kernel" -version = "0.8.14" +version = "0.8.15" dependencies = [ "bumpalo", "dashmap", @@ -1240,7 +1240,7 @@ dependencies = [ [[package]] name = "oxide_liveness" -version = "0.8.14" +version = "0.8.15" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1252,7 +1252,7 @@ dependencies = [ [[package]] name = "oxide_log" -version = "0.8.14" +version = "0.8.15" dependencies = [ "tracing", "tracing-appender", @@ -1261,7 +1261,7 @@ dependencies = [ [[package]] name = "oxide_parser" -version = "0.8.14" +version = "0.8.15" dependencies = [ "oxc_allocator", "oxc_ast", @@ -1276,7 +1276,7 @@ dependencies = [ [[package]] name = "oxide_regalloc" -version = "0.8.14" +version = "0.8.15" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1292,7 +1292,7 @@ dependencies = [ [[package]] name = "oxide_runtime_api" -version = "0.8.14" +version = "0.8.15" dependencies = [ "num-bigint", "num-traits", @@ -1304,7 +1304,7 @@ dependencies = [ [[package]] name = "oxide_test262" -version = "0.8.14" +version = "0.8.15" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1321,7 +1321,7 @@ dependencies = [ [[package]] name = "oxide_types" -version = "0.8.14" +version = "0.8.15" dependencies = [ "bumpalo", "hashbrown 0.14.5", @@ -1333,7 +1333,7 @@ dependencies = [ [[package]] name = "oxide_vm" -version = "0.8.14" +version = "0.8.15" dependencies = [ "bumpalo", "chrono", diff --git a/Cargo.toml b/Cargo.toml index d5c32f93..6902c391 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ members = [ ] [workspace.package] -version = "0.8.14" +version = "0.8.15" edition = "2021" license = "MIT" rust-version = "1.80" diff --git a/crates/oxide_emit/src/stmt/control.rs b/crates/oxide_emit/src/stmt/control.rs index 5e673469..8ced174e 100644 --- a/crates/oxide_emit/src/stmt/control.rs +++ b/crates/oxide_emit/src/stmt/control.rs @@ -32,9 +32,8 @@ impl Emitter { ctx.inst(Inst::load_const(Operand::Reg(result_reg), undef_idx)); } - if ifs.alternate.is_some() { - ctx.inst(Inst::jmp(end_label)); - } + // 真支无条件跳末尾,无 else 时防穿落假支。 + ctx.inst(Inst::jmp(end_label)); ctx.labels.set_label_pos(else_label, ctx.insts.len()); if let Some(alt) = &ifs.alternate { @@ -47,6 +46,11 @@ impl Emitter { let undef_idx = ctx.add_constant(Constant::Undefined); ctx.inst(Inst::load_const(Operand::Reg(result_reg), undef_idx)); } + } else { + // 无 else 的假支显式写 undefined:完成值在所有路径都有定义, + // 不依赖寄存器文件初始值,防物理槽别名泄漏前值。 + let undef_idx = ctx.add_constant(Constant::Undefined); + ctx.inst(Inst::load_const(Operand::Reg(result_reg), undef_idx)); } ctx.labels.set_label_pos(end_label, ctx.insts.len()); diff --git a/crates/oxide_vm/tests/control_flow_tests.rs b/crates/oxide_vm/tests/control_flow_tests.rs index 3a04ef99..f7134394 100644 --- a/crates/oxide_vm/tests/control_flow_tests.rs +++ b/crates/oxide_vm/tests/control_flow_tests.rs @@ -41,6 +41,14 @@ fn eval_if_without_else_false() { assert_eq!(eval("if (false) { 42 }"), "undefined"); } +#[test] +fn eval_if_no_else_false_branch_undefined() { + // 顶层脚本完成值直读 if 的 result_reg:假支前有用后死的 vreg(x 持 1, + // 被 keep 调用读取后死亡),其物理槽可能与 result_reg 别名。假支必须显式 + // 写 undefined,不得泄漏该槽前值。 + assert_eq!(eval("let x = 1; function keep(v){ return v; } keep(x); if (false) { }"), "undefined"); +} + #[test] fn eval_dangling_else() { assert_eq!(eval("if (true) { if (false) { 1 } else { 2 } }"), "2");