mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-26 11:41:13 +08:00
fix: 顶层 var 全局属性求值前创建(声明定时语义)+ 无初始化 var 声明不再抹槽值
This commit is contained in:
@@ -1555,6 +1555,8 @@ impl Emitter {
|
||||
/// 随后由 `oxide_ir::lower::lower` 降为字节码。
|
||||
/// `repl_persist` 为 true 时脚本顶层 let/const 也写全局对象(REPL 跨轮次持久);
|
||||
/// `is_eval_script` 为 true 时顶层 var/function 声明落全局属性 configurable:true。
|
||||
/// 顶层 var 的全局对象属性在求值开始前统一创建(值 undefined),声明语句
|
||||
/// 保持赋值语义——声明语句出现之前的读取(typeof/反射/自引用)即见绑定。
|
||||
pub fn emit_program(
|
||||
&self, program: &oxide_parser::Program, repl_persist: bool, is_eval_script: bool,
|
||||
) -> Result<IRFunction, String> {
|
||||
@@ -1603,6 +1605,17 @@ impl Emitter {
|
||||
}
|
||||
}
|
||||
|
||||
// 全局声明实例化序言:脚本求值前为顶层 var 名创建全局对象属性(值 undefined),
|
||||
// 使声明语句执行前的读取(typeof、反射、自引用)可经全局对象见绑定;同名
|
||||
// 函数声明的属性由首个 sub-pass 以函数值覆盖,声明语句保持值更新语义。
|
||||
let gdi_var_names = self.collect_var_binding_names(&program.body);
|
||||
if !gdi_var_names.is_empty() {
|
||||
let undef_reg = self.emit_undefined(&mut ctx);
|
||||
for name in &gdi_var_names {
|
||||
self.emit_global_prop_write(name, undef_reg, &mut ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// 首个 sub-pass:发函数声明(hoisting),保证任何代码运行前函数对象已就绪。
|
||||
for stmt in &program.body {
|
||||
if matches!(stmt, Statement::FunctionDeclaration(_)) {
|
||||
|
||||
Reference in New Issue
Block a user