refactor: 运行时符号键调用点改经 realm 维度编码

This commit is contained in:
2026-10-07 03:22:52 +00:00
parent 9b2ac86dbe
commit 30a5600466
12 changed files with 71 additions and 63 deletions
+3 -3
View File
@@ -9,7 +9,7 @@ use oxide_builtins::iterator::make_iter_result;
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_runtime_api::NativeResult;
use oxide_types::object::{JsObject, NativeFnPtr};
use oxide_types::private_key::make_well_known_symbol_key;
use oxide_types::private_key::encode_symbol_key;
use oxide_types::value::JsValue;
use crate::vm::Vm;
@@ -39,7 +39,7 @@ pub(crate) fn make_async_iterator(vm: &mut Vm, value: JsValue) -> Result<JsValue
}
};
let obj = unsafe { &*obj_value.as_js_object_ptr() };
let aiter_key = make_well_known_symbol_key(ASYNC_ITERATOR_SYMBOL_ID);
let aiter_key = encode_symbol_key(vm.realm_id(), ASYNC_ITERATOR_SYMBOL_ID);
let method = match vm.ordinary_get(obj, aiter_key, obj_value) {
Ok(m) => m,
Err(e) => {
@@ -92,7 +92,7 @@ impl Vm {
self.set_or_create_prop_value(obj, return_si, return_fn);
let throw_si = self.kernel_core.perm_interner().intern("throw").0;
self.set_or_create_prop_value(obj, throw_si, throw_fn);
let aiter_key = make_well_known_symbol_key(ASYNC_ITERATOR_SYMBOL_ID);
let aiter_key = encode_symbol_key(self.realm_id(), ASYNC_ITERATOR_SYMBOL_ID);
self.set_or_create_prop_value(obj, aiter_key, self_fn);
JsValue::from_js_object(ptr)
}
+6 -3
View File
@@ -630,7 +630,8 @@ pub(crate) fn init_async_intrinsics(vm: &mut Vm) {
let proto_si = sf.intern("prototype").0;
let proto_shape = sh.make_shape(af_ctor.shape_id(), proto_si);
af_ctor.set_shape_id(proto_shape);
let tag_key = oxide_types::private_key::make_well_known_symbol_key(
let tag_key = oxide_types::private_key::encode_symbol_key(
vm.realm_id(),
oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG,
);
let tag_shape = sh.make_shape(af_ctor.shape_id(), tag_key);
@@ -651,8 +652,10 @@ pub(crate) fn init_async_intrinsics(vm: &mut Vm) {
let cpos = af_proto.push_prop(JsValue::from_js_object(af_ctor_ptr));
af_proto.set_data_meta(cpos, PropAttributes::new(false, false, true));
// af_proto[Symbol.toStringTag] = "AsyncFunction"(数据属性,w/e/c = false/false/true)。
let tag_key =
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG);
let tag_key = oxide_types::private_key::encode_symbol_key(
vm.realm_id(),
oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG,
);
let tag_shape = sh.make_shape(af_proto.shape_id(), tag_key);
af_proto.set_shape_id(tag_shape);
let tag_pos = af_proto.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("AsyncFunction").0)));
+11 -6
View File
@@ -1529,14 +1529,16 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) {
("throw", async_generator_throw as *const (), 1),
);
// Symbol.toStringTag(Object.prototype.toString → "[object AsyncGenerator]")。
let tag_key =
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG);
let tag_key = oxide_types::private_key::encode_symbol_key(
vm.realm_id(),
oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG,
);
let tag_shape = sh.make_shape(ag_proto.shape_id(), tag_key);
ag_proto.set_shape_id(tag_shape);
let tag_pos = ag_proto.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("AsyncGenerator").0)));
ag_proto.set_data_meta(tag_pos, PropAttributes::new(false, false, true));
// @@asyncIterator:返回自身(异步生成器是异步可迭代对象,供 for-await-of 消费)。
let aiter_key = oxide_types::private_key::make_well_known_symbol_key(8);
let aiter_key = oxide_types::private_key::encode_symbol_key(vm.realm_id(), 8);
let _ = oxide_kernel::builtin::BuiltinWorld::bind_method_key_labeled_static(
&mut ag_proto,
sh,
@@ -1579,7 +1581,8 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) {
let proto_si = sf.intern("prototype").0;
let proto_shape = sh.make_shape(agf_ctor.shape_id(), proto_si);
agf_ctor.set_shape_id(proto_shape);
let tag_key = oxide_types::private_key::make_well_known_symbol_key(
let tag_key = oxide_types::private_key::encode_symbol_key(
vm.realm_id(),
oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG,
);
let tag_shape = sh.make_shape(agf_ctor.shape_id(), tag_key);
@@ -1604,8 +1607,10 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) {
let ppos2 = agf_proto.push_prop(JsValue::from_js_object(vm.realm.async_generator_proto.borrow().as_ptr() as *mut JsObject));
agf_proto.set_data_meta(ppos2, PropAttributes::new(false, false, true));
// agf_proto[Symbol.toStringTag] = "AsyncGeneratorFunction"(数据属性,w/e/c = false/false/true)。
let tag2_key =
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG);
let tag2_key = oxide_types::private_key::encode_symbol_key(
vm.realm_id(),
oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG,
);
let tag2_shape = sh.make_shape(agf_proto.shape_id(), tag2_key);
agf_proto.set_shape_id(tag2_shape);
let tag2_pos = agf_proto.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("AsyncGeneratorFunction").0)));
+2 -2
View File
@@ -3,7 +3,7 @@ use crate::{vm_error, vm_trace};
use oxide_bytecode::opcode;
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::{JsType, JsValue};
impl Vm {
@@ -368,7 +368,7 @@ impl Vm {
// @@iterator:与 Array.prototype[Symbol.iterator] 共享同一函数对象,
// 使 arguments 对象可迭代(可写、不可枚举、可配置)。
let sym_iter_si = make_well_known_symbol_key(0);
let sym_iter_si = encode_symbol_key(self.realm_id(), 0);
// SAFETY: array_proto 是 perm 层内置对象(BuiltinWorld 持有),地址稳定且
// 跨 epoch/session 存活,本调用期间无 GC 搬移。
let array_proto = self.realm.session.borrow().builtin_world().array_proto.as_ptr();
+11 -6
View File
@@ -818,14 +818,16 @@ pub(crate) fn init_generator_intrinsics(vm: &mut Vm) {
("throw", generator_throw as *const (), 1),
);
// Symbol.toStringTag(Object.prototype.toString → "[object Generator]")。
let tag_key =
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG);
let tag_key = oxide_types::private_key::encode_symbol_key(
vm.realm_id(),
oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG,
);
let tag_shape = sh.make_shape(gen_proto.shape_id(), tag_key);
gen_proto.set_shape_id(tag_shape);
let tag_pos = gen_proto.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("Generator").0)));
gen_proto.set_data_meta(tag_pos, oxide_types::object::PropAttributes::new(false, false, true));
// @@iterator:返回自身(生成器是可迭代对象)。
let iter_key = oxide_types::private_key::make_well_known_symbol_key(0);
let iter_key = oxide_types::private_key::encode_symbol_key(vm.realm_id(), 0);
let _ = oxide_kernel::builtin::BuiltinWorld::bind_method_key_labeled_static(
&mut gen_proto,
sh,
@@ -868,7 +870,8 @@ pub(crate) fn init_generator_intrinsics(vm: &mut Vm) {
let proto_si = sf.intern("prototype").0;
let proto_shape = sh.make_shape(gf_ctor.shape_id(), proto_si);
gf_ctor.set_shape_id(proto_shape);
let tag_key = oxide_types::private_key::make_well_known_symbol_key(
let tag_key = oxide_types::private_key::encode_symbol_key(
vm.realm_id(),
oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG,
);
let tag_shape = sh.make_shape(gf_ctor.shape_id(), tag_key);
@@ -892,8 +895,10 @@ pub(crate) fn init_generator_intrinsics(vm: &mut Vm) {
let ppos2 = gf_proto.push_prop(JsValue::from_js_object(vm.realm.generator_proto.borrow().as_ptr() as *mut JsObject));
gf_proto.set_data_meta(ppos2, oxide_types::object::PropAttributes::new(false, false, true));
// gf_proto[Symbol.toStringTag] = "GeneratorFunction"(数据属性,w/e/c = false/false/true)。
let tag2_key =
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG);
let tag2_key = oxide_types::private_key::encode_symbol_key(
vm.realm_id(),
oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG,
);
let tag2_shape = sh.make_shape(gf_proto.shape_id(), tag2_key);
gf_proto.set_shape_id(tag2_shape);
let tag2_pos = gf_proto.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("GeneratorFunction").0)));
+5 -14
View File
@@ -10,10 +10,7 @@
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_runtime_api::NativeResult;
use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes};
use oxide_types::private_key::{
is_symbol_key, make_int_key, make_symbol_key, make_well_known_symbol_key, symbol_index_from_key,
well_known_symbol_id_from_key, WELL_KNOWN_SYMBOL_COUNT,
};
use oxide_types::private_key::{decode_symbol_key, encode_symbol_key, is_symbol_key, make_int_key};
use oxide_types::value::JsValue;
use crate::native::NativeFn;
@@ -671,12 +668,7 @@ fn perform_promise_combine_keyed(
// 换算绝对存储下标,与 walk_own_keys 口径一致)。
let mut all_keys = oxide_builtins::object::walk_own_keys(vm, promises_obj);
for sym in oxide_builtins::object::own_symbol_key_values(vm, promises_obj) {
let idx = sym.as_symbol_index();
let si = if idx < WELL_KNOWN_SYMBOL_COUNT {
make_well_known_symbol_key(idx)
} else {
make_symbol_key(idx)
};
let si = encode_symbol_key(vm.realm_id(), sym.as_symbol_index());
if let Some(pos) = vm.kernel_core.shape_forge().lookup_position(promises_obj.shape_id(), si) {
let store = if promises_obj.is_array() { promises_obj.array_prop_count + pos } else { pos };
all_keys.push((si, store));
@@ -759,10 +751,9 @@ fn perform_promise_combine_keyed(
/// 键 si 物化为 JS 可见键值:字符串 / 数字串经文本还原,符号键还原为符号值。
fn key_si_to_key_value(vm: &mut Vm, si: u32) -> JsValue {
if is_symbol_key(si) {
if let Some(id) = well_known_symbol_id_from_key(si) {
return JsValue::symbol(id);
}
return JsValue::symbol(symbol_index_from_key(si));
// 键自含 realm 编号:解出 (realm 编号, 全局下标) 还原符号值,无需外部上下文。
let (realm_id, idx) = decode_symbol_key(si);
return JsValue::symbol_realm(realm_id, idx);
}
oxide_builtins::object::key_si_to_js_value(vm, si)
}
+6 -2
View File
@@ -279,7 +279,8 @@ impl Vm {
("catch", promise_catch as *const (), 1),
("finally", promise_finally as *const (), 1),
);
let tag_key = oxide_types::private_key::make_well_known_symbol_key(
let tag_key = oxide_types::private_key::encode_symbol_key(
self.realm_id(),
oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG,
);
let tag_shape = sh.make_shape(proto.shape_id(), tag_key);
@@ -349,7 +350,10 @@ impl Vm {
&self.kernel_core,
&self.realm.session.borrow(),
ctor_mut,
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES),
oxide_types::private_key::encode_symbol_key(
self.realm_id(),
oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES,
),
"get [Symbol.species]",
oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (),
);
+2 -2
View File
@@ -9,7 +9,7 @@
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_runtime_api::NativeResult;
use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes};
use oxide_types::private_key::{make_well_known_symbol_key, WELL_KNOWN_SYMBOL_SPECIES};
use oxide_types::private_key::{encode_symbol_key, WELL_KNOWN_SYMBOL_SPECIES};
use oxide_types::value::JsValue;
use crate::vm::Vm;
@@ -155,7 +155,7 @@ impl Vm {
}
// SAFETY: is_object 保证指针非空且指向存活对象;此处只读 @@species,不跨 GC/reset。
let c_obj = unsafe { &*ctor.as_js_object_ptr() };
let species_si = make_well_known_symbol_key(WELL_KNOWN_SYMBOL_SPECIES);
let species_si = encode_symbol_key(self.realm_id(), WELL_KNOWN_SYMBOL_SPECIES);
let s = match self.ordinary_get(c_obj, species_si, ctor) {
Ok(v) => v,
Err(e) => {
+3 -3
View File
@@ -5,7 +5,7 @@ use oxide_runtime_api as coercion;
use oxide_types::error::JsError;
use oxide_types::object::JsObject;
use oxide_types::private_key::{make_well_known_symbol_key, WELL_KNOWN_SYMBOL_TO_PRIMITIVE};
use oxide_types::private_key::{encode_symbol_key, WELL_KNOWN_SYMBOL_TO_PRIMITIVE};
use oxide_types::value::{JsValue, PTR_MASK};
use super::{format_error_message, js_error_kind, js_error_kind_name, Vm};
@@ -47,8 +47,8 @@ impl Vm {
}
// ECMA-262 §7.1.1 step 1:exotic 对象上(沿原型链读取)的 Symbol.toPrimitive 优先于
// OrdinaryToPrimitive;well-known symbol 键恒定,直接取保留槽。
let sym_si = make_well_known_symbol_key(WELL_KNOWN_SYMBOL_TO_PRIMITIVE);
// OrdinaryToPrimitive;well-known symbol 键经 realm 感知编码,直接取保留槽。
let sym_si = encode_symbol_key(self.realm_id(), WELL_KNOWN_SYMBOL_TO_PRIMITIVE);
let exotic = {
let obj = unsafe { &*obj_ptr };
self.ordinary_get(obj, sym_si, value)?
+3 -3
View File
@@ -3,8 +3,8 @@ use crate::vm_trace;
use oxide_runtime_api::{push_units_to, to_boolean, to_units_full};
use oxide_types::object::{JsObject, PropAttributes};
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,
INT_KEY_COUNT, WELL_KNOWN_SYMBOL_HAS_INSTANCE,
encode_symbol_key, int_key_value, is_int_key, is_private_name_key, is_symbol_key, make_int_key, INT_KEY_COUNT,
WELL_KNOWN_SYMBOL_HAS_INSTANCE,
};
use oxide_types::value::JsValue;
@@ -388,7 +388,7 @@ impl Vm {
return self.raise_type_error("INSTANCEOF right-hand side is not callable");
}
let has_instance_si = make_well_known_symbol_key(WELL_KNOWN_SYMBOL_HAS_INSTANCE);
let has_instance_si = encode_symbol_key(self.realm_id(), WELL_KNOWN_SYMBOL_HAS_INSTANCE);
let ctor_obj = unsafe { &*rhs_val.as_js_object_ptr() };
let has_instance_val = self.ordinary_get(ctor_obj, has_instance_si, rhs_val)?;