fix: instanceof 检查右侧可调用性并投递原生异常

This commit is contained in:
2026-10-14 06:00:55 +00:00
parent 669a68f55f
commit a65689a19b
7 changed files with 75 additions and 38 deletions
@@ -75,6 +75,16 @@ pub(crate) fn make_named_pair(
make_pair(string_forge, shape_forge, name, labels.prototype, labels.constructor, labels.name)
}
/// 把 Function.prototype 标成函数对象:规范规定其是 function object
/// (IsCallable 为真),typeof 报 "function"、Object.prototype.toString
/// 品牌表报 "[object Function]";调用/构造仍因无函数体抛 TypeError。
pub(crate) fn tag_function_proto(proto: &P<JsObject>) {
let ptr = proto.as_ptr() as *mut JsObject;
// SAFETY: proto 是 make_named_pair 刚建的本进程对象,P 引用与裸指针同址。
let obj = unsafe { &mut *ptr };
obj.set_function(true);
}
/// 把 Number.prototype 标成 Number 对象本体:规范 21.7.3 规定其是
/// [[NumberData]] = +0 的 Number object。type_tag 是 Object.prototype.toString
/// 品牌表的判据(置位后报 "[object Number]"),boxed 值供 thisNumberValue/
@@ -483,6 +493,7 @@ impl BuiltinWorld {
let (object_proto, object_constructor) = make_named_pair(string_forge, shape_forge, labels, "Object");
let (array_proto, array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Array");
let (function_proto, function_constructor) = make_named_pair(string_forge, shape_forge, labels, "Function");
tag_function_proto(&function_proto);
let (string_proto, string_constructor) = make_named_pair(string_forge, shape_forge, labels, "String");
tag_string_proto(&string_proto, string_forge, shape_forge);
let (number_proto, number_constructor) = make_named_pair(string_forge, shape_forge, labels, "Number");
+8 -3
View File
@@ -7,8 +7,9 @@ use oxide_types::object::JsObject;
use oxide_types::value::JsValue;
use super::construct::{
builtin_labels, make_error_subtypes, make_named_pair, make_typed_array_family, tag_boolean_proto, tag_number_proto,
tag_string_proto, wire_builtin_world_links, ErrorSubtypeProtos, TypedArrayFamily,
builtin_labels, make_error_subtypes, make_named_pair, make_typed_array_family, tag_boolean_proto,
tag_function_proto, tag_number_proto, tag_string_proto, wire_builtin_world_links, ErrorSubtypeProtos,
TypedArrayFamily,
};
use super::{BindEnv, BuiltinWorld};
use crate::kernel::BuiltinDirtySet;
@@ -173,7 +174,11 @@ impl BuiltinWorld {
(current.array_proto.clone(), current.array_constructor.clone())
};
let (function_proto, function_constructor) = if dirty.function {
make_named_pair(string_forge, shape_forge, labels, "Function")
// 脏重建与全量构造同形:原型本体须带函数对象标志,
// 漏此分支 full_reset 后 IsCallable(Function.prototype) 翻回假。
let (proto, ctor) = make_named_pair(string_forge, shape_forge, labels, "Function");
tag_function_proto(&proto);
(proto, ctor)
} else {
(current.function_proto.clone(), current.function_constructor.clone())
};
@@ -46,7 +46,9 @@ fn test_prototypes_are_not_functions() {
let w = make_world();
assert!(!w.object_proto.is_function());
assert!(!w.array_proto.is_function());
assert!(!w.function_proto.is_function());
// Function.prototype 是函数对象(规范规定其 IsCallable 为真),
// 其余原型均非函数。
assert!(w.function_proto.is_function());
assert!(!w.string_proto.is_function());
assert!(!w.number_proto.is_function());
assert!(!w.boolean_proto.is_function());