refactor: 内置符号键与符号值改经 realm 维度编码

This commit is contained in:
2026-10-07 03:59:07 +00:00
parent aa881783bf
commit c97b0207b4
8 changed files with 34 additions and 36 deletions
+2 -2
View File
@@ -8,7 +8,7 @@ use oxide_runtime_api::{NativeResult, VmHost};
use crate::builtins_debug;
use crate::builtins_error;
use oxide_types::private_key::{make_well_known_symbol_key, WELL_KNOWN_SYMBOL_IS_CONCAT_SPREADABLE};
use oxide_types::private_key::{encode_symbol_key, WELL_KNOWN_SYMBOL_IS_CONCAT_SPREADABLE};
use super::common::{
array_ptr, array_type_error, arraylike_get, arraylike_get_or_err, arraylike_index_present, check_array_create_len,
@@ -499,7 +499,7 @@ pub fn array_concat<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
// 结果钉入返回寄存器:其后的元素读取 / 写入窗口保 GC 根,返回时自钉位读回。
vm.set_reg(0, JsValue::from_js_object(a_ptr));
let spread_key = make_well_known_symbol_key(WELL_KNOWN_SYMBOL_IS_CONCAT_SPREADABLE);
let spread_key = encode_symbol_key(vm.realm_id(), WELL_KNOWN_SYMBOL_IS_CONCAT_SPREADABLE);
let length_si = vm.string_key_si("length");
let mut n_acc: u64 = 0;
let mut holes: Vec<usize> = Vec::new();
+2 -2
View File
@@ -2,7 +2,7 @@
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_types::object::{JsObject, PropAttributes, MAX_DENSE_PROPS};
use oxide_types::private_key::make_well_known_symbol_key;
use oxide_types::private_key::encode_symbol_key;
use oxide_types::value::JsValue;
use oxide_runtime_api::{NativeResult, VmHost};
@@ -333,7 +333,7 @@ pub(crate) fn array_species_create<H: VmHost>(
}
// 一切对象 C 均须查 @@species(null 归一为 undefined):S 为 undefined 回退
// ArrayCreate,S 非构造器抛 TypeError,否则以 S 构造。
let species_key = make_well_known_symbol_key(10);
let species_key = encode_symbol_key(vm.realm_id(), 10);
let s = match vm.ordinary_get(unsafe { &*c.as_js_object_ptr() }, species_key, c) {
Ok(v) => v,
Err(msg) => return Err(from_engine_error(vm, &msg)),
@@ -13,7 +13,7 @@
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_types::object::JsObject;
use oxide_types::private_key::make_well_known_symbol_key;
use oxide_types::private_key::encode_symbol_key;
use oxide_types::value::JsValue;
use oxide_runtime_api::{NativeResult, VmHost};
@@ -178,7 +178,7 @@ pub fn disposable_stack_use<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult
return NativeResult::Err(crate::error::create_type_error(vm, "value is not an Object"));
}
let value_obj = unsafe { &*value.as_js_object_ptr() };
let dispose_key = oxide_types::private_key::make_well_known_symbol_key(12);
let dispose_key = oxide_types::private_key::encode_symbol_key(vm.realm_id(), 12);
let method = match vm.ordinary_get(value_obj, dispose_key, value) {
Ok(m) => m,
Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)),
@@ -263,14 +263,14 @@ pub fn async_disposable_stack_use<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeR
return NativeResult::Err(crate::error::create_type_error(vm, "value is not an Object"));
}
let value_obj = unsafe { &*value.as_js_object_ptr() };
let async_dispose_key = make_well_known_symbol_key(11);
let async_dispose_key = encode_symbol_key(vm.realm_id(), 11);
let method = match vm.ordinary_get(value_obj, async_dispose_key, value) {
Ok(m) => m,
Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)),
};
if method.is_null() || method.is_undefined() {
// 键 11 缺失:回落读 @@dispose(读取顺序测试断言键 11 先、键 12 后)。
let dispose_key = make_well_known_symbol_key(12);
let dispose_key = encode_symbol_key(vm.realm_id(), 12);
let sync_method = match vm.ordinary_get(value_obj, dispose_key, value) {
Ok(m) => m,
Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)),
+7 -7
View File
@@ -1,6 +1,6 @@
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_types::object::{JsObject, PropAttributes};
use oxide_types::private_key::{make_int_key, make_well_known_symbol_key};
use oxide_types::private_key::{encode_symbol_key, make_int_key};
use oxide_types::value::JsValue;
use oxide_runtime_api::{to_object, NativeResult, VmHost};
@@ -135,7 +135,7 @@ pub fn iterator_constructor_setter<H: VmHost>(vm: &mut H, args: &[u8]) -> Native
/// `Symbol.toStringTag` 访问器的 setter(键为 `@@toStringTag`)。
pub fn iterator_to_string_tag_setter<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
iterator_setter_ignore_proto_props(vm, args, make_well_known_symbol_key(9))
iterator_setter_ignore_proto_props(vm, args, encode_symbol_key(vm.realm_id(), 9))
}
/// `%IteratorPrototype%[@@dispose]`:GetMethod(this, "return"),有则调用并返回
@@ -406,7 +406,7 @@ fn get_iterator_flattenable<H: VmHost>(vm: &mut H, value: JsValue) -> Result<(Js
return Err(crate::error::create_type_error(vm, "iterator mapper result is not an object"));
}
let obj = unsafe { &*value.as_js_object_ptr() };
let sym_iter_si = make_well_known_symbol_key(0);
let sym_iter_si = encode_symbol_key(vm.realm_id(), 0);
let method = match vm.ordinary_get(obj, sym_iter_si, value) {
Ok(m) => m,
Err(err) => return Err(engine_error(vm, &err)),
@@ -1408,7 +1408,7 @@ pub(crate) fn peek_iterator_method<H: VmHost>(vm: &mut H, value: JsValue) -> Res
let proto_ptr = vm.session().builtin_world().string_proto.as_ptr() as *mut JsObject;
// SAFETY: string_proto 是 BuiltinWorld 长驻原型对象,进程内有效且不被 GC 搬移。
let proto_obj = unsafe { &*proto_ptr };
let sym_iter_si = make_well_known_symbol_key(0);
let sym_iter_si = encode_symbol_key(vm.realm_id(), 0);
let method = match vm.ordinary_get(proto_obj, sym_iter_si, value) {
Ok(m) => m,
Err(err) => {
@@ -1442,7 +1442,7 @@ pub(crate) fn peek_iterator_method<H: VmHost>(vm: &mut H, value: JsValue) -> Res
};
if recv.is_object() {
let obj = unsafe { &*recv.as_js_object_ptr() };
let sym_iter_si = make_well_known_symbol_key(0);
let sym_iter_si = encode_symbol_key(vm.realm_id(), 0);
let method = match vm.ordinary_get(obj, sym_iter_si, value) {
Ok(m) => m,
Err(err) => {
@@ -1542,7 +1542,7 @@ fn get_iterator<H: VmHost>(vm: &mut H, value: JsValue) -> Result<Option<(JsValue
vm.session().builtin_world().string_proto.as_ptr() as *mut JsObject
};
let read_obj = unsafe { &*read_ptr };
let sym_iter_si = make_well_known_symbol_key(0);
let sym_iter_si = encode_symbol_key(vm.realm_id(), 0);
let method = match vm.ordinary_get(read_obj, sym_iter_si, value) {
Ok(m) => m,
Err(err) => {
@@ -1623,7 +1623,7 @@ fn get_iterator<H: VmHost>(vm: &mut H, value: JsValue) -> Result<Option<(JsValue
let obj = unsafe { &*obj_value.as_js_object_ptr() };
// 迭代协议:GetIterator 先取 value[Symbol.iterator] 并调用;装箱对象仅作查找
// 起点与鸭子回退 inner,receiver/this 用原始 value(GetV / GetIteratorFromMethod)。
let sym_iter_si = make_well_known_symbol_key(0);
let sym_iter_si = encode_symbol_key(vm.realm_id(), 0);
let method = match vm.ordinary_get(obj, sym_iter_si, value) {
Ok(m) => m,
Err(err) => {
+1 -1
View File
@@ -512,7 +512,7 @@ pub fn map_group_by<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
Err(msg) => return NativeResult::Err(crate::error::create_type_error(vm, &msg)),
};
let items_ptr = items_obj.as_js_object_ptr();
let sym_iter_si = oxide_types::private_key::make_well_known_symbol_key(0);
let sym_iter_si = oxide_types::private_key::encode_symbol_key(vm.realm_id(), 0);
let iter_method = match unsafe { vm.ordinary_get(&*items_ptr, sym_iter_si, items_val) } {
Ok(m) => m,
Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)),
+2 -2
View File
@@ -9,7 +9,7 @@
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_runtime_api::{NativeResult, VmHost};
use oxide_types::object::{Cell, JsObject, PropAttributes, PropMetaEntry};
use oxide_types::private_key::make_well_known_symbol_key;
use oxide_types::private_key::encode_symbol_key;
use oxide_types::value::JsValue;
/// `Symbol.toStringTag` 在 well-known symbol 表中的序号,命名空间标签键按其编码。
@@ -326,7 +326,7 @@ pub fn module_pre_register<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
/// `module_set`/`module_star` 的瞬态可扩展窗口旁路,其余写/定义一律拒绝。
pub fn module_object<H: VmHost>(vm: &mut H, _args: &[u8]) -> NativeResult {
let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
let tag_si = make_well_known_symbol_key(TO_STRING_TAG_SYMBOL_ID);
let tag_si = encode_symbol_key(vm.realm_id(), TO_STRING_TAG_SYMBOL_ID);
let tag_val = vm.new_string("Module");
let obj_ref = unsafe { &mut *obj };
if let Err(e) = vm.define_data_property(obj_ref, tag_si, tag_val, PropAttributes::new(false, false, false)) {
+10 -12
View File
@@ -2,8 +2,8 @@ use oxide_kernel::shape_forge::{ShapeForge, EMPTY_SHAPE_ID};
use oxide_kernel::string_forge::PermInterner;
use oxide_types::object::{JsObject, PropAttributes, PropMetaEntry};
use oxide_types::private_key::{
int_key_value, is_int_key, is_private_name_key, is_symbol_key, make_int_key, make_well_known_symbol_key,
symbol_index_from_key, well_known_symbol_id_from_key, INT_KEY_COUNT,
decode_symbol_key, encode_symbol_key, int_key_value, is_int_key, is_private_name_key, is_symbol_key, make_int_key,
INT_KEY_COUNT,
};
use oxide_types::value::JsValue;
@@ -178,13 +178,11 @@ pub(crate) fn walk_own_symbol_keys<H: VmHost>(vm: &H, obj: &JsObject) -> Vec<(u3
keys
}
/// 把 Symbol 键反解为对应的 Symbol 值:well-known 键还原为对应下标的符号原语,
/// 用户 symbol 键按偏移还原为 `JsValue::symbol` 值。
fn decode_symbol_key(key: u32) -> JsValue {
if let Some(id) = well_known_symbol_id_from_key(key) {
return JsValue::symbol(id);
}
JsValue::symbol(symbol_index_from_key(key))
/// 把 Symbol 键反解为对应的 Symbol 值:键自含 realm 编号与局部下标,
/// 直接还原为 realm 感知符号值,无需外部上下文。
fn symbol_key_to_value(key: u32) -> JsValue {
let (realm_id, local_index) = decode_symbol_key(key);
JsValue::symbol_realm(realm_id, local_index)
}
/// 收集对象自身全部 Symbol 键并按插入序物化为 Symbol 值。
@@ -200,7 +198,7 @@ fn decode_symbol_key(key: u32) -> JsValue {
pub fn own_symbol_key_values<H: VmHost>(vm: &H, obj: &JsObject) -> Vec<JsValue> {
walk_own_symbol_keys(vm, obj)
.iter()
.map(|(key, _)| decode_symbol_key(*key))
.map(|(key, _)| symbol_key_to_value(*key))
.collect()
}
@@ -1957,7 +1955,7 @@ pub fn object_proto_to_string<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResul
};
// @@toStringTag 为字符串时覆盖品牌名;非字符串(含缺失)回退品牌名,
// getter 抛错透传原异常。
let tag_key = make_well_known_symbol_key(9);
let tag_key = encode_symbol_key(vm.realm_id(), 9);
match vm.ordinary_get(obj, tag_key, obj_val) {
Ok(v) => {
// 先把 tag 字符串取出(结束对 vm 的不可变借用),再拼结果串。
@@ -2183,7 +2181,7 @@ pub fn object_group_by<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
Err(msg) => return NativeResult::Err(crate::error::create_type_error(vm, &msg)),
};
let items_ptr = items_obj.as_js_object_ptr();
let sym_iter_si = make_well_known_symbol_key(0);
let sym_iter_si = encode_symbol_key(vm.realm_id(), 0);
let iter_method = match unsafe { vm.ordinary_get(&*items_ptr, sym_iter_si, items_val) } {
Ok(m) => m,
Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)),
+6 -6
View File
@@ -48,7 +48,7 @@ pub fn symbol_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
};
let idx = vm.symbol_intern(description);
NativeResult::Ok(JsValue::symbol(idx))
NativeResult::Ok(JsValue::symbol_realm(vm.realm_id(), idx))
}
/// `Symbol.prototype.toString`:返回 `Symbol(description)` 形式字符串。
@@ -89,7 +89,7 @@ pub fn symbol_to_string<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
Ok(v) => v,
Err(e) => return NativeResult::Err(e),
};
let idx = sym.as_symbol_index();
let idx = sym.as_symbol_local_index();
let desc = vm.symbol_description(idx).unwrap_or_default();
let result = format!("Symbol({})", desc);
NativeResult::Ok(vm.new_string_owned(result))
@@ -127,7 +127,7 @@ pub fn symbol_description_getter<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeRe
Ok(v) => v,
Err(e) => return NativeResult::Err(e),
};
let idx = sym.as_symbol_index();
let idx = sym.as_symbol_local_index();
match vm.symbol_description(idx) {
Some(desc) => NativeResult::Ok(vm.new_string_owned(desc)),
None => NativeResult::Ok(JsValue::undefined()),
@@ -153,12 +153,12 @@ pub fn symbol_for<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
};
if let Some(idx) = vm.symbol_lookup_global(&key) {
return NativeResult::Ok(JsValue::symbol(idx));
return NativeResult::Ok(JsValue::symbol_realm(vm.realm_id(), idx));
}
let idx = vm.symbol_intern(Some(key.clone()));
vm.symbol_register_global(key, idx);
NativeResult::Ok(JsValue::symbol(idx))
NativeResult::Ok(JsValue::symbol_realm(vm.realm_id(), idx))
}
/// `Symbol.keyFor(sym)`:返回全局注册表中该 Symbol 的 key;未登记返回 undefined。
@@ -169,7 +169,7 @@ pub fn symbol_key_for<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
return NativeResult::Err(crate::error::create_type_error(vm, "is not a symbol"));
}
let idx = sym.as_symbol_index();
let idx = sym.as_symbol_local_index();
match vm.symbol_key_for_id(idx) {
Some(key) => NativeResult::Ok(vm.new_string(&key)),
None => NativeResult::Ok(JsValue::undefined()),