fix: sloppy 普通函数调用 this 未定义/null 绑定全局对象

This commit is contained in:
2026-08-16 16:58:32 +08:00
parent 3e071d3337
commit cde3417e15
5 changed files with 192 additions and 11 deletions
+10 -1
View File
@@ -1326,6 +1326,7 @@ impl Vm {
let sub_n_registers = self.sub_modules[sub_idx].n_registers;
let sub_param_base = self.sub_modules[sub_idx].param_base as usize;
let sub_is_arrow = self.sub_modules[sub_idx].is_arrow;
let sub_is_strict = self.sub_modules[sub_idx].is_strict;
// 窗口 = min(调用方活动寄存器, 存活上界);call_window=0 表示调用方全量
// (运行时发起路径 / 未编码的旧模块)。恢复按窗口回拷,active_reg_limit
// 仍还原为调用方真实值(caller_active_reg_limit)。
@@ -1360,7 +1361,15 @@ impl Vm {
};
self.regs[sub_param_base + i] = v;
}
self.regs[254] = if sub_is_arrow { obj.captured_this() } else { this_value };
// this 绑定:箭头函数恒用词法捕获;sloppy 普通函数 this 为 null/undefined 时
// 替换为全局对象(ECMA-262 10.4.3);严格模式与显式方法/构造 this 原样保留。
self.regs[254] = if sub_is_arrow {
obj.captured_this()
} else if !sub_is_strict && this_value.is_nullish() {
JsValue::from_js_object(self.session.global_object().as_ptr() as *mut JsObject)
} else {
this_value
};
self.regs[255] = new_target;
self.saved_bytecode_stack.push(std::mem::take(&mut self.bytecode));
+9 -1
View File
@@ -381,7 +381,15 @@ impl Vm {
for i in 0..sub.n_args as usize {
self.regs[sub.param_base as usize + i] = args.get(i).copied().unwrap_or(JsValue::undefined());
}
self.regs[254] = if sub.is_arrow { callee_obj.captured_this() } else { receiver };
// this 绑定:箭头函数恒用词法捕获;sloppy 普通函数 this 为 null/undefined 时
// 替换为全局对象(ECMA-262 10.4.3);严格模式与显式 receiver 原样保留。
self.regs[254] = if sub.is_arrow {
callee_obj.captured_this()
} else if !sub.is_strict && receiver.is_nullish() {
JsValue::from_js_object(self.session.global_object().as_ptr() as *mut JsObject)
} else {
receiver
};
self.regs[255] = JsValue::undefined();
for (name, reg) in &sub.builtin_reg_map {
let si = self.kernel_core.perm_interner().intern(name.as_str()).0;