From 7dbb8aa2bf28b9577121c83cea0da0c5e782aae7 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Sun, 27 Sep 2026 00:31:38 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=85=B3=E7=B3=BB=E6=AF=94=E8=BE=83?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=99=A8=E8=A1=A5=20Symbol=20=E5=AE=88?= =?UTF-8?q?=E5=8D=AB=EF=BC=8C=E6=9B=BF=E6=8D=A2=20BigInt=20=E6=B7=B7?= =?UTF-8?q?=E5=90=88=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/dispatch/comparison.rs | 16 +++++++-------- crates/oxide_vm/tests/comparison_tests.rs | 24 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/crates/oxide_vm/src/dispatch/comparison.rs b/crates/oxide_vm/src/dispatch/comparison.rs index 915ffde8..76dc2d61 100644 --- a/crates/oxide_vm/src/dispatch/comparison.rs +++ b/crates/oxide_vm/src/dispatch/comparison.rs @@ -29,8 +29,8 @@ impl Vm { vm_trace!("LT rd={} r{}={:?} r{}={:?}", rd, a, self.regs[a], b, self.regs[b]); let va = self.coerce_primitive_bounded(self.regs[a], false)?; let vb = self.coerce_primitive_bounded(self.regs[b], false)?; - if (va.is_bigint() || vb.is_bigint()) && (va.is_symbol() || vb.is_symbol()) { - return self.raise_type_error("Cannot mix BigInt and other types, use explicit conversions"); + if va.is_symbol() || vb.is_symbol() { + return self.raise_type_error("Cannot convert a Symbol value to a number"); } match coercion::relational_compare(va, vb) { Some(r) => self.regs[rd] = JsValue::bool(r), @@ -47,8 +47,8 @@ impl Vm { vm_trace!("GT rd={} r{}={:?} r{}={:?}", rd, a, self.regs[a], b, self.regs[b]); let va = self.coerce_primitive_bounded(self.regs[a], false)?; let vb = self.coerce_primitive_bounded(self.regs[b], false)?; - if (va.is_bigint() || vb.is_bigint()) && (va.is_symbol() || vb.is_symbol()) { - return self.raise_type_error("Cannot mix BigInt and other types, use explicit conversions"); + if va.is_symbol() || vb.is_symbol() { + return self.raise_type_error("Cannot convert a Symbol value to a number"); } match coercion::relational_compare(vb, va) { Some(r) => self.regs[rd] = JsValue::bool(r), @@ -65,8 +65,8 @@ impl Vm { vm_trace!("LTE rd={} r{}={:?} r{}={:?}", rd, a, self.regs[a], b, self.regs[b]); let va = self.coerce_primitive_bounded(self.regs[a], false)?; let vb = self.coerce_primitive_bounded(self.regs[b], false)?; - if (va.is_bigint() || vb.is_bigint()) && (va.is_symbol() || vb.is_symbol()) { - return self.raise_type_error("Cannot mix BigInt and other types, use explicit conversions"); + if va.is_symbol() || vb.is_symbol() { + return self.raise_type_error("Cannot convert a Symbol value to a number"); } match coercion::relational_compare(vb, va) { Some(r) => self.regs[rd] = JsValue::bool(!r), @@ -83,8 +83,8 @@ impl Vm { vm_trace!("GTE rd={} r{}={:?} r{}={:?}", rd, a, self.regs[a], b, self.regs[b]); let va = self.coerce_primitive_bounded(self.regs[a], false)?; let vb = self.coerce_primitive_bounded(self.regs[b], false)?; - if (va.is_bigint() || vb.is_bigint()) && (va.is_symbol() || vb.is_symbol()) { - return self.raise_type_error("Cannot mix BigInt and other types, use explicit conversions"); + if va.is_symbol() || vb.is_symbol() { + return self.raise_type_error("Cannot convert a Symbol value to a number"); } match coercion::relational_compare(va, vb) { Some(r) => self.regs[rd] = JsValue::bool(!r), diff --git a/crates/oxide_vm/tests/comparison_tests.rs b/crates/oxide_vm/tests/comparison_tests.rs index 5fdd1b05..de561658 100644 --- a/crates/oxide_vm/tests/comparison_tests.rs +++ b/crates/oxide_vm/tests/comparison_tests.rs @@ -157,3 +157,27 @@ fn eval_string_relational_utf16_code_unit_order() { assert_eq!(eval(source), expected, "source: {source}"); } } + +#[test] +fn eval_relational_symbol_throws() { + // 关系比较任一侧为 Symbol 时按 ToNumber 抛 TypeError(规范 13.7.5 步骤 4/5)。 + assert_eq!( + eval("Object(Symbol()) <= ''"), + "vm error: uncaught TypeError: Cannot convert a Symbol value to a number" + ); + // symbol 与 bigint 混合时 symbol 消息优先(ToNumber 先于混合判定)。 + assert_eq!( + eval("Object(Symbol()) < 1n"), + "vm error: uncaught TypeError: Cannot convert a Symbol value to a number" + ); + assert_eq!( + eval("Object(Symbol()) > 1n"), + "vm error: uncaught TypeError: Cannot convert a Symbol value to a number" + ); + assert_eq!( + eval("1n >= Object(Symbol())"), + "vm error: uncaught TypeError: Cannot convert a Symbol value to a number" + ); + // 松散等值对 symbol 不抛,返回 false(回归钉)。 + assert_eq!(eval("Object(Symbol()) == 'Symbol()'"), "false"); +}