fix: 字符串面 GetIterator 尊重用户 @@iterator 覆盖

String 臂此前对原始串与装箱串一律走码元步进、忽略用户覆盖的
@@iterator。改为按 GetMethod 语义以值自身为 receiver 读 @@iterator
(原始串落 String.prototype、装箱串读自身→原型链),默认迭代器
自别名即 @@iterator 槽本身、以绑定层捕获的函数指针比较走快速
路径避免递归回本臂;覆盖则调用、receiver 为值。peek 对非字符串
原始值先装箱再读 @@iterator;Iterator.from 增 GetIteratorFlattenable
前置校验,非字符串原始值非对象 → TypeError(不装箱)。
This commit is contained in:
2026-09-15 02:18:12 +00:00
parent 4b0b52ade3
commit 0f5bd1577e
4 changed files with 252 additions and 6 deletions
@@ -72,6 +72,18 @@ pub fn bind_string(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
oxide_builtins::string::string_symbol_iterator::<crate::vm::Vm> as *const (),
0,
);
// 捕获默认迭代器函数对象指针写入 world:String 臂覆盖判定以此做指针比较。
// 此时槽为初始数据属性(用户覆盖尚未可能),读回即默认函数本体。
let iter_key = oxide_types::private_key::make_well_known_symbol_key(0);
if let Some(pos) = core.shape_forge().lookup_position(proto.shape_id(), iter_key) {
let v = proto.get_prop_at(pos);
if v.is_object() {
session
.builtin_world()
.string_default_iterator
.set(v.as_js_object_ptr() as *const JsObject);
}
}
// 全局 String 槽位既有槽原位更新(旧家族构造器指针不得滞留在属性 vec),
// 无槽时开新槽;描述符非枚举(规范 { writable:true, enumerable:false, configurable:true })。