mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
fix: sloppy 函数调用原始值 this 按规范盒装为包装对象
This commit is contained in:
@@ -273,13 +273,16 @@ impl Vm {
|
||||
self.regs[sub_param_base + i] = v;
|
||||
}
|
||||
// this 绑定:箭头函数恒用词法捕获;sloppy 普通函数 this 为 null/undefined 时
|
||||
// 替换为全局对象(ECMA-262 10.4.3);严格模式与显式方法/构造 this 原样保留。
|
||||
// 替换为全局对象,其余原始值经 ToObject 盒装(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 {
|
||||
} else if sub_is_strict {
|
||||
this_value
|
||||
} else {
|
||||
oxide_runtime_api::to_object(this_value, self)?
|
||||
};
|
||||
self.regs[255] = new_target;
|
||||
|
||||
|
||||
@@ -485,13 +485,16 @@ impl Vm {
|
||||
self.regs[sub.param_base as usize + i] = args.get(i).copied().unwrap_or(JsValue::undefined());
|
||||
}
|
||||
// this 绑定:箭头函数恒用词法捕获;sloppy 普通函数 this 为 null/undefined 时
|
||||
// 替换为全局对象(ECMA-262 10.4.3);严格模式与显式 receiver 原样保留。
|
||||
// 替换为全局对象,其余原始值经 ToObject 盒装(ECMA-262 10.4.3);严格模式
|
||||
// this 原样保留。
|
||||
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 {
|
||||
} else if sub.is_strict {
|
||||
receiver
|
||||
} else {
|
||||
oxide_runtime_api::to_object(receiver, self)?
|
||||
};
|
||||
self.regs[255] = JsValue::undefined();
|
||||
self.reload_builtin_mirror_slots(&sub.builtin_reg_map, 0);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! sloppy 普通函数 `this` 绑定语义测试:非箭头 && 非 strict && this 为 null/undefined
|
||||
//! 时替换为全局对象;箭头/严格/method/构造/显式 receiver 均不替换。
|
||||
//! 时替换为全局对象,其余原始值经 ToObject 盒装;箭头/严格/method/构造/显式
|
||||
//! receiver 均不替换。
|
||||
//! 覆盖普通调用、call/apply/bind、builtin 回调、构造、生成器、async、derived 构造。
|
||||
|
||||
use std::sync::Arc;
|
||||
@@ -119,6 +120,23 @@ fn strict_call_with_nullish_keeps_undefined() {
|
||||
assert_true(&mut vm, "function f(){ 'use strict'; return this === undefined; } f.call(undefined)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn call_with_primitive_this_boxes_object() {
|
||||
// sloppy 普通函数 call 原始值 this 经 ToObject 盒装为对应包装对象。
|
||||
let mut vm = Vm::new();
|
||||
assert_true(&mut vm, "function f(){ return typeof this === 'object'; } f.call('str')");
|
||||
assert_true(&mut vm, "function f(){ return typeof this === 'object'; } f.call(1)");
|
||||
assert_true(&mut vm, "function f(){ return typeof this === 'object'; } f.call(true)");
|
||||
assert_true(&mut vm, "function f(){ return typeof this === 'object'; } f.call(1n)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn strict_call_with_primitive_this_keeps_primitive() {
|
||||
// strict 函数 call 原始值 this 原样保留,不盒装。
|
||||
let mut vm = Vm::new();
|
||||
assert_true(&mut vm, "function f(){ 'use strict'; return typeof this === 'string'; } f.call('str')");
|
||||
}
|
||||
|
||||
// ── builtin 回调 / 生成器 / async ──
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user