From c80944d375c1bcf5d5497b391a8a49a70c52f4ca Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Sun, 13 Sep 2026 12:26:12 +0000 Subject: [PATCH] =?UTF-8?q?emit/vm:=20=E5=8F=97=E9=99=90=E8=AF=8D=E6=B3=95?= =?UTF-8?q?=E5=90=8D=E9=9B=86=E5=9B=9E=E6=BB=9A=E4=B8=89=E5=B8=B8=E9=87=8F?= =?UTF-8?q?=E2=80=94=E2=80=94eval=20=E4=B8=BA=E5=8F=AF=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=85=A8=E5=B1=80=E5=B1=9E=E6=80=A7=E5=B1=9E=E5=90=88=E6=B3=95?= =?UTF-8?q?=E9=81=AE=E8=94=BD=EF=BC=88=E8=A7=84=E8=8C=83=E8=87=AA=E6=9C=89?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=87=82=E6=97=A0=E9=9D=99=E6=80=81=E5=8F=97?= =?UTF-8?q?=E9=99=90=E8=87=82=EF=BC=89=EF=BC=8Cclass=20eval=20=E7=BB=B4?= =?UTF-8?q?=E6=8C=81=E8=A7=A3=E6=9E=90=E6=9C=9F=E6=8B=92=E7=BB=9D=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E9=92=89=E4=BD=8F=EF=BC=88=E7=B1=BB=E4=BD=93=E6=81=92?= =?UTF-8?q?=E4=B8=A5=E6=A0=BC=EF=BC=8C=E4=B8=8E=E5=8F=97=E9=99=90=E9=9B=86?= =?UTF-8?q?=E6=97=A0=E5=85=B3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_emit/src/prepass.rs | 10 +++---- .../tests/decl_lex_restricted_global_tests.rs | 29 ++++++++++++------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/crates/oxide_emit/src/prepass.rs b/crates/oxide_emit/src/prepass.rs index f7ae3299..897d62dc 100644 --- a/crates/oxide_emit/src/prepass.rs +++ b/crates/oxide_emit/src/prepass.rs @@ -9,13 +9,13 @@ use oxide_parser::{ BindingPattern, Declaration, ExportDefaultDeclarationKind, Expression, Statement, VariableDeclarationKind, }; -/// 脚本顶层 lexical 声明(let/const/class)禁止使用的受限全局名:4 名静态集。 -/// 三常量是全局对象上 {configurable:false} 的自有属性名(声明实例化无法建立 -/// 遮蔽绑定);eval 属静态受限臂(顶层 lexical 声明不得遮蔽,var/function -/// 路径不受本集约束)。名基静态集(编译期不可查运行时描述符)。与 +/// 脚本顶层 lexical 声明(let/const/class)禁止使用的受限全局名:3 名静态集。 +/// 受限判定走规范自有属性臂:全局对象上 {configurable:false} 自有属性名(声明 +/// 实例化无法建立遮蔽绑定)——现行规范下恰为三常量;eval 与各 builtin 属性皆 +/// 可配置(合法遮蔽),不在此列。名基静态集(编译期不可查运行时描述符)。与 /// BUILTIN_GLOBALS 语义不同(后者是 put 写拦截/双写名单),不互相派生,交叠 /// 名由漂移守卫单测断言恒同步。 -pub(crate) const RESTRICTED_GLOBAL_LEXICAL_NAMES: &[&str] = &["undefined", "eval", "NaN", "Infinity"]; +pub(crate) const RESTRICTED_GLOBAL_LEXICAL_NAMES: &[&str] = &["undefined", "NaN", "Infinity"]; /// 脚本顶层 lexical 声明撞受限全局名 → SyntaxError(声明实例化期拒绝,整程序 /// 编译失败)。错误消息与既有重复声明错同形;非顶层或名不在受限集 → Ok。 diff --git a/crates/oxide_vm/tests/decl_lex_restricted_global_tests.rs b/crates/oxide_vm/tests/decl_lex_restricted_global_tests.rs index 3a415c3c..7e6b03d9 100644 --- a/crates/oxide_vm/tests/decl_lex_restricted_global_tests.rs +++ b/crates/oxide_vm/tests/decl_lex_restricted_global_tests.rs @@ -1,7 +1,10 @@ -//! 脚本顶层 lexical 声明撞受限全局名的编译期拒绝:let/const/class 声明名撞 -//! 受限集(undefined/eval/NaN/Infinity——三常量不可配置自有属性 + eval 静态 -//! 受限臂)→ SyntaxError(整程序编译失败)。局部作用域(函数体/块/try)与 +//! 脚本顶层 lexical 声明撞受限全局名的编译期拒绝:let/const 声明名撞 +//! 受限集(undefined/NaN/Infinity——三常量,全局对象 {configurable:false} +//! 自有属性名)→ SyntaxError(整程序编译失败)。局部作用域(函数体/块/try)与 //! eval 代码为合法遮蔽不拒;三常数值使用不受影响。 +//! +//! class 名撞 eval 不在本集(解析器 early-error 族独立拒绝,类体恒严格模式, +//! 与受限集检查无关,见 top_level_class_eval_name_rejected)。 use std::sync::Arc; @@ -108,21 +111,25 @@ fn top_level_let_uses_nan_value_allowed() { } #[test] -fn top_level_let_eval_name_rejected() { - // eval 属静态受限臂:顶层 lexical 声明不得遮蔽(var/function 路径不受 - // 本集约束)。 - assert_compile_err("let eval;"); +fn top_level_let_eval_name_allowed() { + // eval 是全局对象可配置自有属性(受限判定走自有属性臂,eval 不命中): + // 合法遮蔽,不在受限集。 + let r = assert_ok("let eval; 1"); + assert_eq!(r.as_int(), 1); } #[test] -fn top_level_const_eval_name_rejected() { - assert_compile_err("const eval = 1;"); +fn top_level_const_eval_name_allowed() { + let r = assert_ok("const eval = 1; 1"); + assert_eq!(r.as_int(), 1); } #[test] fn top_level_class_eval_name_rejected() { - // 若解析器更早拒绝(early error 族),亦接受该拒绝相位(整程序拒绝可观察 - // 行为同形)。 + // eval 不在受限集(let/const 合法遮蔽),但 class 名撞 eval 由解析器 + // early-error 族拒绝:类体恒严格模式,类名绑定检查落在类作用域 strict + // 判定内(V8 同形:sloppy `class eval {}` 亦 SyntaxError)。与本受限集 + // 检查无关,整程序拒绝可观察行为同形,断言任意拒绝相位。 assert!(eval("class eval {}").is_err(), "class eval 类名应被拒绝"); }