feat: Symbol.hasInstance 支持 instanceof 双路径分派

This commit is contained in:
爱特每羊队
2026-06-27 22:53:04 +08:00
parent db8aa7025e
commit 9da0ded18d
5 changed files with 86 additions and 2 deletions
@@ -57,6 +57,10 @@ pub fn bind_symbol(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
"toPrimitive",
JsValue::from_js_object(session.builtin_world().sym_to_primitive.as_ptr() as *mut JsObject),
),
(
"hasInstance",
JsValue::from_js_object(session.builtin_world().sym_has_instance.as_ptr() as *mut JsObject),
),
] {
bind_well_known_symbol(core, ctor, name, val);
}
+19
View File
@@ -208,6 +208,25 @@ impl Vm {
if !rhs_val.is_object() {
return self.raise_type_error("INSTANCEOF right-hand side is not callable");
}
let has_instance_ptr = self.session.builtin_world().sym_has_instance.as_ptr() as *mut JsObject;
let has_instance_key = JsValue::from_js_object(has_instance_ptr);
let has_instance_si = self.property_key_si(has_instance_key);
let ctor_obj = unsafe { &*rhs_val.as_js_object_ptr() };
let has_instance_val = self.ordinary_get(ctor_obj, has_instance_si, rhs_val)?;
if !has_instance_val.is_undefined() && !has_instance_val.is_null() {
let fn_ptr = has_instance_val.as_js_object_ptr();
if !fn_ptr.is_null() {
let fn_obj = unsafe { &*fn_ptr };
if fn_obj.is_function() {
let result = self.call_function_sync(has_instance_val, rhs_val, &[lhs_val])?;
self.regs[rd] = JsValue::bool(to_boolean(result));
return Ok(());
}
}
}
if !lhs_val.is_object() {
self.regs[rd] = JsValue::bool(false);
return Ok(());