refactor: 绑定与 kernel 符号键改经 realm 维度编码

This commit is contained in:
2026-10-07 03:48:59 +00:00
parent 30a5600466
commit aa881783bf
20 changed files with 244 additions and 116 deletions
Generated
+18 -18
View File
@@ -1160,7 +1160,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_builtins" name = "oxide_builtins"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"chrono", "chrono",
"fast-float", "fast-float",
@@ -1185,7 +1185,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_bytecode" name = "oxide_bytecode"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"num-bigint", "num-bigint",
"oxide_log", "oxide_log",
@@ -1193,7 +1193,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_cfg" name = "oxide_cfg"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_emit", "oxide_emit",
@@ -1204,7 +1204,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_cli" name = "oxide_cli"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"ansi_term", "ansi_term",
"bumpalo", "bumpalo",
@@ -1225,7 +1225,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_code_cache" name = "oxide_code_cache"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"lru", "lru",
"oxide_bytecode", "oxide_bytecode",
@@ -1234,7 +1234,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_compiler" name = "oxide_compiler"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_cfg", "oxide_cfg",
@@ -1253,7 +1253,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_dce" name = "oxide_dce"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_cfg", "oxide_cfg",
@@ -1267,7 +1267,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_emit" name = "oxide_emit"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"num-bigint", "num-bigint",
"oxc_allocator", "oxc_allocator",
@@ -1282,7 +1282,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_ir" name = "oxide_ir"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_log", "oxide_log",
@@ -1291,7 +1291,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_kernel" name = "oxide_kernel"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"dashmap", "dashmap",
@@ -1306,7 +1306,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_liveness" name = "oxide_liveness"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_cfg", "oxide_cfg",
@@ -1318,7 +1318,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_log" name = "oxide_log"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"tracing", "tracing",
"tracing-appender", "tracing-appender",
@@ -1327,7 +1327,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_parser" name = "oxide_parser"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"oxc_allocator", "oxc_allocator",
"oxc_ast", "oxc_ast",
@@ -1342,7 +1342,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_regalloc" name = "oxide_regalloc"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_cfg", "oxide_cfg",
@@ -1358,7 +1358,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_runtime_api" name = "oxide_runtime_api"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"num-bigint", "num-bigint",
"num-traits", "num-traits",
@@ -1370,7 +1370,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_test262" name = "oxide_test262"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_compiler", "oxide_compiler",
@@ -1387,7 +1387,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_types" name = "oxide_types"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"hashbrown 0.14.5", "hashbrown 0.14.5",
@@ -1399,7 +1399,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_vm" name = "oxide_vm"
version = "0.8.53" version = "0.8.54"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"chrono", "chrono",
+1 -1
View File
@@ -22,7 +22,7 @@ members = [
] ]
[workspace.package] [workspace.package]
version = "0.8.53" version = "0.8.54"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
rust-version = "1.80" rust-version = "1.80"
+13 -5
View File
@@ -3,7 +3,7 @@
use oxide_types::mem::P; use oxide_types::mem::P;
use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes}; use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes};
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_types::value::JsValue;
use super::{ArrayMethods, BuiltinWorld, ErrorMethods, FnWrapperKey, FunctionMethods, ObjectMethods, StringMethods}; use super::{ArrayMethods, BuiltinWorld, ErrorMethods, FnWrapperKey, FunctionMethods, ObjectMethods, StringMethods};
@@ -66,7 +66,12 @@ impl BuiltinWorld {
} }
/// 把 Array 家族方法安装到 Array 构造器与原型上。 /// 把 Array 家族方法安装到 Array 构造器与原型上。
pub fn bind_array_methods(&self, methods: &ArrayMethods, string_forge: &PermInterner, shape_forge: &ShapeForge) { ///
/// `realm_id` 是安装目标所属 realm 的编号:`@@iterator` 符号键按
/// (realm 编号, 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_array_methods(
&self, methods: &ArrayMethods, string_forge: &PermInterner, shape_forge: &ShapeForge, realm_id: u32,
) {
let ctor_ptr = P::as_ptr(&self.array_constructor) as *mut JsObject; let ctor_ptr = P::as_ptr(&self.array_constructor) as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr }; let ctor = unsafe { &mut *ctor_ptr };
bind_methods!( bind_methods!(
@@ -124,7 +129,7 @@ impl BuiltinWorld {
("with", methods.with_method, 2), ("with", methods.with_method, 2),
); );
let iterator_key = make_well_known_symbol_key(0); let iterator_key = encode_symbol_key(realm_id, 0);
let raw = methods.values; let raw = methods.values;
// SAFETY: methods.values 是 VM 绑定层传入的 NativeFn 函数项。 // SAFETY: methods.values 是 VM 绑定层传入的 NativeFn 函数项。
let func_ptr = unsafe { NativeFnPtr::from_raw(raw) }; let func_ptr = unsafe { NativeFnPtr::from_raw(raw) };
@@ -312,8 +317,11 @@ impl BuiltinWorld {
} }
/// 把 Function 原型方法安装到 Function.prototype 上。 /// 把 Function 原型方法安装到 Function.prototype 上。
///
/// `realm_id` 是安装目标所属 realm 的编号:`@@hasInstance` 符号键按
/// (realm 编号, 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_function_methods( pub fn bind_function_methods(
&self, methods: &FunctionMethods, string_forge: &PermInterner, shape_forge: &ShapeForge, &self, methods: &FunctionMethods, string_forge: &PermInterner, shape_forge: &ShapeForge, realm_id: u32,
) { ) {
let proto_ptr = P::as_ptr(&self.function_proto) as *mut JsObject; let proto_ptr = P::as_ptr(&self.function_proto) as *mut JsObject;
let proto = unsafe { &mut *proto_ptr }; let proto = unsafe { &mut *proto_ptr };
@@ -333,7 +341,7 @@ impl BuiltinWorld {
proto, proto,
shape_forge, shape_forge,
string_forge, string_forge,
make_well_known_symbol_key(6), encode_symbol_key(realm_id, 6),
"[Symbol.hasInstance]", "[Symbol.hasInstance]",
unsafe { NativeFnPtr::from_raw(methods.has_instance) }, unsafe { NativeFnPtr::from_raw(methods.has_instance) },
1, 1,
+7 -3
View File
@@ -8,7 +8,10 @@ use crate::bind_constructor;
use crate::bindings::apply_binding_table; use crate::bindings::apply_binding_table;
/// 把 Array 构造器与原型方法绑定到 global。 /// 把 Array 构造器与原型方法绑定到 global。
pub fn bind_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let _array_methods = ArrayMethods { let _array_methods = ArrayMethods {
is_array: oxide_builtins::array::array_is_array::<crate::vm::Vm> as *const (), is_array: oxide_builtins::array::array_is_array::<crate::vm::Vm> as *const (),
from: oxide_builtins::array::array_from::<crate::vm::Vm> as *const (), from: oxide_builtins::array::array_from::<crate::vm::Vm> as *const (),
@@ -55,6 +58,7 @@ pub fn bind_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
&_array_methods, &_array_methods,
core.perm_interner().as_ref(), core.perm_interner().as_ref(),
core.shape_forge().as_ref(), core.shape_forge().as_ref(),
realm_id,
); );
let array_proto_ptr = session.builtin_world().array_proto.as_ptr() as *mut JsObject; let array_proto_ptr = session.builtin_world().array_proto.as_ptr() as *mut JsObject;
@@ -71,7 +75,7 @@ pub fn bind_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
array_proto.set_data_meta(pos, PropAttributes::new(true, false, true)); array_proto.set_data_meta(pos, PropAttributes::new(true, false, true));
} }
// Array.prototype[@@iterator] 与 values 共享同一函数对象。 // Array.prototype[@@iterator] 与 values 共享同一函数对象。
super::bind_well_known_method_alias(core, array_proto, "values", 0); super::bind_well_known_method_alias(core, array_proto, "values", 0, realm_id);
let ctor_ptr = session.builtin_world().array_constructor.as_ptr() as *mut JsObject; let ctor_ptr = session.builtin_world().array_constructor.as_ptr() as *mut JsObject;
bind_constructor!(core, global, "Array", ctor_ptr, oxide_builtins::array::array_constructor::<crate::vm::Vm>, 1, hash: true); bind_constructor!(core, global, "Array", ctor_ptr, oxide_builtins::array::array_constructor::<crate::vm::Vm>, 1, hash: true);
@@ -82,7 +86,7 @@ pub fn bind_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
core, core,
session, session,
unsafe { &mut *ctor_ptr }, unsafe { &mut *ctor_ptr },
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES),
"get [Symbol.species]", "get [Symbol.species]",
oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (), oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (),
); );
@@ -8,7 +8,10 @@ use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::object::{JsObject, PropAttributes};
/// 把 ArrayBuffer 构造器与原型方法绑定到 global。 /// 把 ArrayBuffer 构造器与原型方法绑定到 global。
pub fn bind_array_buffer(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:`@@species` 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_array_buffer(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let ctor_ptr = session.builtin_world().array_buffer_constructor.as_ptr() as *mut JsObject; let ctor_ptr = session.builtin_world().array_buffer_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr }; let ctor = unsafe { &mut *ctor_ptr };
let proto_ptr = session.builtin_world().array_buffer_proto.as_ptr() as *mut JsObject; let proto_ptr = session.builtin_world().array_buffer_proto.as_ptr() as *mut JsObject;
@@ -37,7 +40,7 @@ pub fn bind_array_buffer(core: &Arc<KernelCore>, session: &KernelSession, global
core, core,
session, session,
ctor, ctor,
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES),
"get [Symbol.species]", "get [Symbol.species]",
oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (), oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (),
); );
@@ -16,7 +16,10 @@ use crate::bindings::{
/// 幂等:proto 上已有 `use` 方法(全新 proto 或已完整绑定)时整组跳过, /// 幂等:proto 上已有 `use` 方法(全新 proto 或已完整绑定)时整组跳过,
/// 保留原型经 dirty reset 重复经过时安全。`@@asyncDispose` 别名须在 /// 保留原型经 dirty reset 重复经过时安全。`@@asyncDispose` 别名须在
/// `disposeAsync` 绑定之后调用(读源槽 lookup_position,顺序敏感)。 /// `disposeAsync` 绑定之后调用(读源槽 lookup_position,顺序敏感)。
pub fn bind_async_disposable_stack_protos(core: &Arc<KernelCore>, session: &KernelSession) { ///
/// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_async_disposable_stack_protos(core: &Arc<KernelCore>, session: &KernelSession, realm_id: u32) {
let world = session.builtin_world(); let world = session.builtin_world();
let proto_ptr = world.async_disposable_stack_proto.as_ptr() as *mut JsObject; let proto_ptr = world.async_disposable_stack_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &mut *proto_ptr }; let proto = unsafe { &mut *proto_ptr };
@@ -61,10 +64,10 @@ pub fn bind_async_disposable_stack_protos(core: &Arc<KernelCore>, session: &Kern
oxide_builtins::disposable_stack::async_disposable_stack_disposed_getter::<crate::vm::Vm> as *const (), oxide_builtins::disposable_stack::async_disposable_stack_disposed_getter::<crate::vm::Vm> as *const (),
); );
// @@asyncDispose 与 disposeAsync 为同一函数对象(先绑 disposeAsync 再取源槽)。 // @@asyncDispose 与 disposeAsync 为同一函数对象(先绑 disposeAsync 再取源槽)。
bind_well_known_method_alias(core, proto, "disposeAsync", 11); bind_well_known_method_alias(core, proto, "disposeAsync", 11, realm_id);
let sf = core.perm_interner().as_ref(); let sf = core.perm_interner().as_ref();
let tag = JsValue::perm_string(sf.string_ptr(sf.intern("AsyncDisposableStack").0)); let tag = JsValue::perm_string(sf.string_ptr(sf.intern("AsyncDisposableStack").0));
bind_well_known_data_property(core, proto, 9, tag, PropAttributes::new(false, false, true)); bind_well_known_data_property(core, proto, 9, tag, PropAttributes::new(false, false, true), realm_id);
} }
/// 把 `AsyncDisposableStack` 构造器绑定到 global(init 与 full_reset global 重建共用)。 /// 把 `AsyncDisposableStack` 构造器绑定到 global(init 与 full_reset global 重建共用)。
@@ -72,7 +75,12 @@ pub fn bind_async_disposable_stack_protos(core: &Arc<KernelCore>, session: &Kern
/// proto.constructor 已有则复用(dirty reset 保留路径);否则 Box 自建构造器 /// proto.constructor 已有则复用(dirty reset 保留路径);否则 Box 自建构造器
/// (proto=Function.prototype,prototype 槽=AsyncDisposableStack.prototype, /// (proto=Function.prototype,prototype 槽=AsyncDisposableStack.prototype,
/// 描述符按规范)。幂等:protos 安装与 global 槽写入均自带重复跳过。 /// 描述符按规范)。幂等:protos 安装与 global 槽写入均自带重复跳过。
pub fn bind_async_disposable_stack(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_async_disposable_stack(
core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32,
) {
let world = session.builtin_world(); let world = session.builtin_world();
let proto_ptr = world.async_disposable_stack_proto.as_ptr() as *mut JsObject; let proto_ptr = world.async_disposable_stack_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &mut *proto_ptr }; let proto = unsafe { &mut *proto_ptr };
@@ -145,7 +153,7 @@ pub fn bind_async_disposable_stack(core: &Arc<KernelCore>, session: &KernelSessi
}; };
write_proto_constructor(core, proto, ctor_val); write_proto_constructor(core, proto, ctor_val);
bind_async_disposable_stack_protos(core, session); bind_async_disposable_stack_protos(core, session, realm_id);
bind_global_value(core, global, "AsyncDisposableStack", ctor_val); bind_global_value(core, global, "AsyncDisposableStack", ctor_val);
} }
+5 -2
View File
@@ -12,7 +12,10 @@ use oxide_types::value::JsValue;
/// 构造器/原型对象由 `BuiltinWorld` 创建(含 name/prototype/constructor 互指), /// 构造器/原型对象由 `BuiltinWorld` 创建(含 name/prototype/constructor 互指),
/// 这里只配置 native 实现并挂方法。`BigInt(value)` 当函数调用时返回 BigInt 值; /// 这里只配置 native 实现并挂方法。`BigInt(value)` 当函数调用时返回 BigInt 值;
/// `new BigInt()` 抛 TypeError(BigInt 不可 new)。 /// `new BigInt()` 抛 TypeError(BigInt 不可 new)。
pub fn bind_bigint(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:`@@toStringTag` 符号键按 (realm 编号,
/// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_bigint(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let world = session.builtin_world(); let world = session.builtin_world();
let ctor_ptr = world.bigint_constructor.as_ptr() as *mut JsObject; let ctor_ptr = world.bigint_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr }; let ctor = unsafe { &mut *ctor_ptr };
@@ -57,7 +60,7 @@ pub fn bind_bigint(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
// BigInt.prototype[@@toStringTag] = "BigInt",属性 { writable:false, enumerable:false, configurable:true }。 // BigInt.prototype[@@toStringTag] = "BigInt",属性 { writable:false, enumerable:false, configurable:true }。
let tag_si = core.perm_interner().intern("BigInt").0; let tag_si = core.perm_interner().intern("BigInt").0;
let tag_value = JsValue::perm_string(core.perm_interner().string_ptr(tag_si)); let tag_value = JsValue::perm_string(core.perm_interner().string_ptr(tag_si));
bind_well_known_data_property(core, proto, 9, tag_value, PropAttributes::new(false, false, true)); bind_well_known_data_property(core, proto, 9, tag_value, PropAttributes::new(false, false, true), realm_id);
bind_global_value(core, global, "BigInt", JsValue::from_js_object(ctor_ptr)); bind_global_value(core, global, "BigInt", JsValue::from_js_object(ctor_ptr));
} }
@@ -15,7 +15,10 @@ use crate::bindings::{
/// 幂等:proto 上已有 `use` 方法(全新 proto 或已完整绑定)时整组跳过, /// 幂等:proto 上已有 `use` 方法(全新 proto 或已完整绑定)时整组跳过,
/// 保留原型经 dirty reset 重复经过时安全。`@@dispose` 别名须在 `dispose` /// 保留原型经 dirty reset 重复经过时安全。`@@dispose` 别名须在 `dispose`
/// 绑定之后调用(读源槽 lookup_position,顺序敏感)。 /// 绑定之后调用(读源槽 lookup_position,顺序敏感)。
pub fn bind_disposable_stack_protos(core: &Arc<KernelCore>, session: &KernelSession) { ///
/// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_disposable_stack_protos(core: &Arc<KernelCore>, session: &KernelSession, realm_id: u32) {
let world = session.builtin_world(); let world = session.builtin_world();
let proto_ptr = world.disposable_stack_proto.as_ptr() as *mut JsObject; let proto_ptr = world.disposable_stack_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &mut *proto_ptr }; let proto = unsafe { &mut *proto_ptr };
@@ -64,10 +67,10 @@ pub fn bind_disposable_stack_protos(core: &Arc<KernelCore>, session: &KernelSess
oxide_builtins::disposable_stack::disposable_stack_disposed_getter::<crate::vm::Vm> as *const (), oxide_builtins::disposable_stack::disposable_stack_disposed_getter::<crate::vm::Vm> as *const (),
); );
// @@dispose 与 dispose 为同一函数对象(先绑 dispose 再取源槽)。 // @@dispose 与 dispose 为同一函数对象(先绑 dispose 再取源槽)。
bind_well_known_method_alias(core, proto, "dispose", 12); bind_well_known_method_alias(core, proto, "dispose", 12, realm_id);
let sf = core.perm_interner().as_ref(); let sf = core.perm_interner().as_ref();
let tag = JsValue::perm_string(sf.string_ptr(sf.intern("DisposableStack").0)); let tag = JsValue::perm_string(sf.string_ptr(sf.intern("DisposableStack").0));
bind_well_known_data_property(core, proto, 9, tag, PropAttributes::new(false, false, true)); bind_well_known_data_property(core, proto, 9, tag, PropAttributes::new(false, false, true), realm_id);
} }
/// 在 proto 上写 `constructor` 数据属性(非枚举,描述符 {t,f,t})。 /// 在 proto 上写 `constructor` 数据属性(非枚举,描述符 {t,f,t})。
@@ -90,7 +93,10 @@ pub(crate) fn write_proto_constructor(core: &Arc<KernelCore>, proto: &mut JsObje
/// proto.constructor 已有则复用(dirty reset 保留路径);否则 Box 自建构造器 /// proto.constructor 已有则复用(dirty reset 保留路径);否则 Box 自建构造器
/// (proto=Function.prototype,prototype 槽=DisposableStack.prototype,描述符按规范)。 /// (proto=Function.prototype,prototype 槽=DisposableStack.prototype,描述符按规范)。
/// 幂等:protos 安装与 global 槽写入均自带重复跳过。 /// 幂等:protos 安装与 global 槽写入均自带重复跳过。
pub fn bind_disposable_stack(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_disposable_stack(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let world = session.builtin_world(); let world = session.builtin_world();
let proto_ptr = world.disposable_stack_proto.as_ptr() as *mut JsObject; let proto_ptr = world.disposable_stack_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &mut *proto_ptr }; let proto = unsafe { &mut *proto_ptr };
@@ -162,7 +168,7 @@ pub fn bind_disposable_stack(core: &Arc<KernelCore>, session: &KernelSession, gl
}; };
write_proto_constructor(core, proto, ctor_val); write_proto_constructor(core, proto, ctor_val);
bind_disposable_stack_protos(core, session); bind_disposable_stack_protos(core, session, realm_id);
bind_global_value(core, global, "DisposableStack", ctor_val); bind_global_value(core, global, "DisposableStack", ctor_val);
} }
@@ -10,7 +10,10 @@ use super::bind_global_value;
use super::configure_native_constructor; use super::configure_native_constructor;
/// 把 Function 构造器与原型方法绑定到 global。 /// 把 Function 构造器与原型方法绑定到 global。
pub fn bind_function(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:`@@hasInstance` 符号键按 (realm 编号,
/// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_function(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let function_methods = FunctionMethods { let function_methods = FunctionMethods {
call: oxide_builtins::function::function_call::<crate::vm::Vm> as *const (), call: oxide_builtins::function::function_call::<crate::vm::Vm> as *const (),
apply: oxide_builtins::function::function_apply::<crate::vm::Vm> as *const (), apply: oxide_builtins::function::function_apply::<crate::vm::Vm> as *const (),
@@ -22,6 +25,7 @@ pub fn bind_function(core: &Arc<KernelCore>, session: &KernelSession, global: &m
&function_methods, &function_methods,
core.perm_interner().as_ref(), core.perm_interner().as_ref(),
core.shape_forge().as_ref(), core.shape_forge().as_ref(),
realm_id,
); );
let function_ctor = session.builtin_world().function_constructor.as_ptr() as *mut JsObject; let function_ctor = session.builtin_world().function_constructor.as_ptr() as *mut JsObject;
+6 -3
View File
@@ -9,7 +9,10 @@ use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
/// 把 Map 构造器与原型方法绑定到 global。 /// 把 Map 构造器与原型方法绑定到 global。
pub fn bind_map(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_map(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let ctor_ptr = session.builtin_world().map_constructor.as_ptr() as *mut JsObject; let ctor_ptr = session.builtin_world().map_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr }; let ctor = unsafe { &mut *ctor_ptr };
let proto_ptr = session.builtin_world().map_proto.as_ptr() as *mut JsObject; let proto_ptr = session.builtin_world().map_proto.as_ptr() as *mut JsObject;
@@ -42,7 +45,7 @@ pub fn bind_map(core: &Arc<KernelCore>, session: &KernelSession, global: &mut Js
); );
// Map 的 @@iterator(Symbol.iterator)是 entries 的同一函数对象。 // Map 的 @@iterator(Symbol.iterator)是 entries 的同一函数对象。
bind_well_known_method_alias(core, proto, "entries", 0); bind_well_known_method_alias(core, proto, "entries", 0, realm_id);
bind_accessor_getter(core, session, proto, "size", oxide_builtins::map::map_size::<crate::vm::Vm> as *const ()); bind_accessor_getter(core, session, proto, "size", oxide_builtins::map::map_size::<crate::vm::Vm> as *const ());
// Map[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链解析 // Map[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链解析
@@ -51,7 +54,7 @@ pub fn bind_map(core: &Arc<KernelCore>, session: &KernelSession, global: &mut Js
core, core,
session, session,
ctor, ctor,
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES),
"get [Symbol.species]", "get [Symbol.species]",
oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (), oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (),
); );
+10 -2
View File
@@ -10,7 +10,10 @@ use oxide_types::object::JsObject;
use crate::bind_constructor; use crate::bind_constructor;
/// 把 RegExp 构造器与原型方法绑定到 global。 /// 把 RegExp 构造器与原型方法绑定到 global。
pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let ctor_ptr = session.builtin_world().regexp_constructor.as_ptr() as *mut JsObject; let ctor_ptr = session.builtin_world().regexp_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr }; let ctor = unsafe { &mut *ctor_ptr };
let proto_ptr = session.builtin_world().regexp_proto.as_ptr() as *mut JsObject; let proto_ptr = session.builtin_world().regexp_proto.as_ptr() as *mut JsObject;
@@ -121,6 +124,7 @@ pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
"[Symbol.match]", "[Symbol.match]",
oxide_builtins::regexp::regexp_symbol_match::<crate::vm::Vm> as *const (), oxide_builtins::regexp::regexp_symbol_match::<crate::vm::Vm> as *const (),
1, 1,
realm_id,
); );
bind_well_known_method( bind_well_known_method(
world, world,
@@ -130,6 +134,7 @@ pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
"[Symbol.replace]", "[Symbol.replace]",
oxide_builtins::regexp::regexp_symbol_replace::<crate::vm::Vm> as *const (), oxide_builtins::regexp::regexp_symbol_replace::<crate::vm::Vm> as *const (),
2, 2,
realm_id,
); );
bind_well_known_method( bind_well_known_method(
world, world,
@@ -139,6 +144,7 @@ pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
"[Symbol.search]", "[Symbol.search]",
oxide_builtins::regexp::regexp_symbol_search::<crate::vm::Vm> as *const (), oxide_builtins::regexp::regexp_symbol_search::<crate::vm::Vm> as *const (),
1, 1,
realm_id,
); );
bind_well_known_method( bind_well_known_method(
world, world,
@@ -148,6 +154,7 @@ pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
"[Symbol.split]", "[Symbol.split]",
oxide_builtins::regexp::regexp_symbol_split::<crate::vm::Vm> as *const (), oxide_builtins::regexp::regexp_symbol_split::<crate::vm::Vm> as *const (),
2, 2,
realm_id,
); );
bind_well_known_method( bind_well_known_method(
world, world,
@@ -157,6 +164,7 @@ pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
"[Symbol.matchAll]", "[Symbol.matchAll]",
oxide_builtins::regexp::regexp_symbol_match_all::<crate::vm::Vm> as *const (), oxide_builtins::regexp::regexp_symbol_match_all::<crate::vm::Vm> as *const (),
1, 1,
realm_id,
); );
// RegExp[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链解析 // RegExp[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链解析
@@ -165,7 +173,7 @@ pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
core, core,
session, session,
ctor, ctor,
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES),
"get [Symbol.species]", "get [Symbol.species]",
oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (), oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (),
); );
+6 -3
View File
@@ -9,7 +9,10 @@ use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
/// 把 Set 构造器与原型方法绑定到 global。 /// 把 Set 构造器与原型方法绑定到 global。
pub fn bind_set(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_set(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let ctor_ptr = session.builtin_world().set_constructor.as_ptr() as *mut JsObject; let ctor_ptr = session.builtin_world().set_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr }; let ctor = unsafe { &mut *ctor_ptr };
let proto_ptr = session.builtin_world().set_proto.as_ptr() as *mut JsObject; let proto_ptr = session.builtin_world().set_proto.as_ptr() as *mut JsObject;
@@ -50,7 +53,7 @@ pub fn bind_set(core: &Arc<KernelCore>, session: &KernelSession, global: &mut Js
// keys 与 @@iterator(Symbol.iterator)是 values 的同一函数对象。 // keys 与 @@iterator(Symbol.iterator)是 values 的同一函数对象。
bind_method_alias(core, proto, "values", "keys"); bind_method_alias(core, proto, "values", "keys");
bind_well_known_method_alias(core, proto, "values", 0); bind_well_known_method_alias(core, proto, "values", 0, realm_id);
bind_accessor_getter(core, session, proto, "size", oxide_builtins::set::set_size::<crate::vm::Vm> as *const ()); bind_accessor_getter(core, session, proto, "size", oxide_builtins::set::set_size::<crate::vm::Vm> as *const ());
// Set[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链解析 // Set[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链解析
@@ -59,7 +62,7 @@ pub fn bind_set(core: &Arc<KernelCore>, session: &KernelSession, global: &mut Js
core, core,
session, session,
ctor, ctor,
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES),
"get [Symbol.species]", "get [Symbol.species]",
oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (), oxide_builtins::array::array_species_get::<crate::vm::Vm> as *const (),
); );
+6 -2
View File
@@ -7,7 +7,10 @@ use oxide_types::object::{JsObject, PropAttributes};
use oxide_types::value::JsValue; use oxide_types::value::JsValue;
/// 把 String 构造器与原型方法绑定到 global。 /// 把 String 构造器与原型方法绑定到 global。
pub fn bind_string(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:`@@iterator` 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_string(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let string_methods = StringMethods { let string_methods = StringMethods {
from_char_code: oxide_builtins::string::string_from_char_code::<crate::vm::Vm> as *const (), from_char_code: oxide_builtins::string::string_from_char_code::<crate::vm::Vm> as *const (),
index_of: oxide_builtins::string::string_index_of::<crate::vm::Vm> as *const (), index_of: oxide_builtins::string::string_index_of::<crate::vm::Vm> as *const (),
@@ -95,10 +98,11 @@ pub fn bind_string(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
"[Symbol.iterator]", "[Symbol.iterator]",
oxide_builtins::string::string_symbol_iterator::<crate::vm::Vm> as *const (), oxide_builtins::string::string_symbol_iterator::<crate::vm::Vm> as *const (),
0, 0,
realm_id,
); );
// 捕获默认迭代器函数对象指针写入 world:String 臂覆盖判定以此做指针比较。 // 捕获默认迭代器函数对象指针写入 world:String 臂覆盖判定以此做指针比较。
// 此时槽为初始数据属性(用户覆盖尚未可能),读回即默认函数本体。 // 此时槽为初始数据属性(用户覆盖尚未可能),读回即默认函数本体。
let iter_key = oxide_types::private_key::make_well_known_symbol_key(0); let iter_key = oxide_types::private_key::encode_symbol_key(realm_id, 0);
if let Some(pos) = core.shape_forge().lookup_position(proto.shape_id(), iter_key) { if let Some(pos) = core.shape_forge().lookup_position(proto.shape_id(), iter_key) {
let v = proto.get_prop_at(pos); let v = proto.get_prop_at(pos);
if v.is_object() { if v.is_object() {
+6 -2
View File
@@ -60,7 +60,10 @@ fn set_data_property(core: &Arc<KernelCore>, obj: &mut JsObject, si: u32, value:
/// stub 的 `constructor` 与 @@toStringTag)——规范 25.1 的 %Proxy% 无 /// stub 的 `constructor` 与 @@toStringTag)——规范 25.1 的 %Proxy% 无
/// prototype 属性,不装;描述符均不可枚举,`prototype` 另不可写、不可配置。 /// prototype 属性,不装;描述符均不可枚举,`prototype` 另不可写、不可配置。
/// 原型对象登记进 world 释放登记表,与 stub 对象同生死,session 收尾统一释放。 /// 原型对象登记进 world 释放登记表,与 stub 对象同生死,session 收尾统一释放。
pub fn bind_stubs(core: &Arc<KernelCore>, session: &mut KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:`@@toStringTag` 符号键按 (realm 编号,
/// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_stubs(core: &Arc<KernelCore>, session: &mut KernelSession, global: &mut JsObject, realm_id: u32) {
let builtin_world = Arc::get_mut(&mut session.builtin_world) let builtin_world = Arc::get_mut(&mut session.builtin_world)
.expect("BuiltinWorld must be uniquely owned during init_kernel_builtins"); .expect("BuiltinWorld must be uniquely owned during init_kernel_builtins");
let object_proto_ptr = builtin_world.object_proto.as_ptr() as *mut JsObject; let object_proto_ptr = builtin_world.object_proto.as_ptr() as *mut JsObject;
@@ -92,7 +95,8 @@ pub fn bind_stubs(core: &Arc<KernelCore>, session: &mut KernelSession, global: &
PropAttributes::new(true, false, true), PropAttributes::new(true, false, true),
); );
if let Some(tag_name) = tag { if let Some(tag_name) = tag {
let tag_key = oxide_types::private_key::make_well_known_symbol_key( let tag_key = oxide_types::private_key::encode_symbol_key(
realm_id,
oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG, oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG,
); );
let tag_val = let tag_val =
+7 -3
View File
@@ -5,13 +5,16 @@ use crate::bindings::{
}; };
use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::object::{JsObject, PropAttributes};
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; use oxide_types::value::JsValue;
use crate::bind_constructor; use crate::bind_constructor;
/// 把 Symbol 构造器与原型方法绑定到 global(含 `Symbol.iterator` 等 well-known symbols)。 /// 把 Symbol 构造器与原型方法绑定到 global(含 `Symbol.iterator` 等 well-known symbols)。
pub fn bind_symbol(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_symbol(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let ctor_ptr = session.builtin_world().symbol_constructor.as_ptr() as *mut JsObject; let ctor_ptr = session.builtin_world().symbol_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr }; let ctor = unsafe { &mut *ctor_ptr };
let proto_ptr = session.builtin_world().symbol_proto.as_ptr() as *mut JsObject; let proto_ptr = session.builtin_world().symbol_proto.as_ptr() as *mut JsObject;
@@ -57,8 +60,9 @@ pub fn bind_symbol(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
"[Symbol.toPrimitive]", "[Symbol.toPrimitive]",
oxide_builtins::symbol::symbol_to_primitive::<crate::vm::Vm> as *const (), oxide_builtins::symbol::symbol_to_primitive::<crate::vm::Vm> as *const (),
1, 1,
realm_id,
); );
let to_prim_key = make_well_known_symbol_key(WELL_KNOWN_SYMBOL_TO_PRIMITIVE); let to_prim_key = encode_symbol_key(realm_id, WELL_KNOWN_SYMBOL_TO_PRIMITIVE);
if let Some(pos) = core.shape_forge().lookup_position(proto.shape_id(), to_prim_key) { if let Some(pos) = core.shape_forge().lookup_position(proto.shape_id(), to_prim_key) {
proto.set_data_meta(pos, PropAttributes::new(false, false, true)); proto.set_data_meta(pos, PropAttributes::new(false, false, true));
proto.bump_generation(); proto.bump_generation();
+11 -1
View File
@@ -9,7 +9,10 @@ use oxide_types::object::{JsObject, PropAttributes};
use oxide_types::value::JsValue; use oxide_types::value::JsValue;
/// 把 Temporal 命名空间及其子对象绑定到 global。 /// 把 Temporal 命名空间及其子对象绑定到 global。
pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:`@@toStringTag` 符号键按 (realm 编号,
/// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let world = session.builtin_world(); let world = session.builtin_world();
let temporal_ptr = world.temporal_object.as_ptr() as *mut JsObject; let temporal_ptr = world.temporal_object.as_ptr() as *mut JsObject;
let temporal = unsafe { &mut *temporal_ptr }; let temporal = unsafe { &mut *temporal_ptr };
@@ -129,6 +132,7 @@ pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &m
.string_ptr(core.perm_interner().intern("Temporal.Instant").0), .string_ptr(core.perm_interner().intern("Temporal.Instant").0),
), ),
PropAttributes::new(false, false, true), PropAttributes::new(false, false, true),
realm_id,
); );
// Temporal.ZonedDateTime:最小构造器与三个稳定内部槽 getter。 // Temporal.ZonedDateTime:最小构造器与三个稳定内部槽 getter。
@@ -383,6 +387,7 @@ pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &m
.string_ptr(core.perm_interner().intern("Temporal.ZonedDateTime").0), .string_ptr(core.perm_interner().intern("Temporal.ZonedDateTime").0),
), ),
PropAttributes::new(false, false, true), PropAttributes::new(false, false, true),
realm_id,
); );
apply_binding_table( apply_binding_table(
world, world,
@@ -734,6 +739,7 @@ pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &m
.string_ptr(core.perm_interner().intern("Temporal.PlainTime").0), .string_ptr(core.perm_interner().intern("Temporal.PlainTime").0),
), ),
PropAttributes::new(false, false, true), PropAttributes::new(false, false, true),
realm_id,
); );
// Temporal.PlainDateTime:ISO 日期时间分量、拆分转换与禁止隐式原始值转换。 // Temporal.PlainDateTime:ISO 日期时间分量、拆分转换与禁止隐式原始值转换。
@@ -893,6 +899,7 @@ pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &m
.string_ptr(core.perm_interner().intern("Temporal.PlainDateTime").0), .string_ptr(core.perm_interner().intern("Temporal.PlainDateTime").0),
), ),
PropAttributes::new(false, false, true), PropAttributes::new(false, false, true),
realm_id,
); );
// Temporal.Duration:构造器、from、分量 getter 与 ISO 字符串转换。 // Temporal.Duration:构造器、from、分量 getter 与 ISO 字符串转换。
@@ -981,6 +988,7 @@ pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &m
.string_ptr(core.perm_interner().intern("Temporal.Duration").0), .string_ptr(core.perm_interner().intern("Temporal.Duration").0),
), ),
PropAttributes::new(false, false, true), PropAttributes::new(false, false, true),
realm_id,
); );
// Temporal.PlainMonthDay:构造器、3 个分量 getter 与 toString/toJSON。 // Temporal.PlainMonthDay:构造器、3 个分量 getter 与 toString/toJSON。
@@ -1069,6 +1077,7 @@ pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &m
.string_ptr(core.perm_interner().intern("Temporal.PlainMonthDay").0), .string_ptr(core.perm_interner().intern("Temporal.PlainMonthDay").0),
), ),
PropAttributes::new(false, false, true), PropAttributes::new(false, false, true),
realm_id,
); );
// Temporal.PlainYearMonth:构造器、10 个 getter 与 toString/toJSON。 // Temporal.PlainYearMonth:构造器、10 个 getter 与 toString/toJSON。
@@ -1194,6 +1203,7 @@ pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &m
.string_ptr(core.perm_interner().intern("Temporal.PlainYearMonth").0), .string_ptr(core.perm_interner().intern("Temporal.PlainYearMonth").0),
), ),
PropAttributes::new(false, false, true), PropAttributes::new(false, false, true),
realm_id,
); );
// 把子对象挂到 Temporal 命名空间对象上,再把 Temporal 挂到 global。 // 把子对象挂到 Temporal 命名空间对象上,再把 Temporal 挂到 global。
@@ -11,7 +11,10 @@ use oxide_types::value::JsValue;
/// 把 `%TypedArray%` 抽象构造器的 native 实现配置为恒抛 TypeError(不可 new/不可调用), /// 把 `%TypedArray%` 抽象构造器的 native 实现配置为恒抛 TypeError(不可 new/不可调用),
/// 设置 `length` 属性为 0,并挂载静态 `of`/`from`(具体构造器经原型链继承)。 /// 设置 `length` 属性为 0,并挂载静态 `of`/`from`(具体构造器经原型链继承)。
fn bind_typed_array_abstract_ctor(core: &Arc<KernelCore>, session: &KernelSession) { ///
/// `realm_id` 是目标所属 realm 的编号:`@@species` 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
fn bind_typed_array_abstract_ctor(core: &Arc<KernelCore>, session: &KernelSession, realm_id: u32) {
let ctor_ptr = session.builtin_world().typed_array_constructor.as_ptr() as *mut JsObject; let ctor_ptr = session.builtin_world().typed_array_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr }; let ctor = unsafe { &mut *ctor_ptr };
configure_native_constructor( configure_native_constructor(
@@ -61,7 +64,7 @@ fn bind_typed_array_abstract_ctor(core: &Arc<KernelCore>, session: &KernelSessio
// (及派生类)沿原型链解析 @@species 得自身(具体构造器无 own 属性)。绑定站 // (及派生类)沿原型链解析 @@species 得自身(具体构造器无 own 属性)。绑定站
// 与 TA 构造器后续消费面改造共用,先查槽位防重复绑定追加第二访问器槽。 // 与 TA 构造器后续消费面改造共用,先查槽位防重复绑定追加第二访问器槽。
let species_key = let species_key =
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES); oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES);
if core.shape_forge().lookup_position(ctor.shape_id(), species_key).is_none() { if core.shape_forge().lookup_position(ctor.shape_id(), species_key).is_none() {
bind_accessor_getter_key( bind_accessor_getter_key(
core, core,
@@ -112,7 +115,10 @@ macro_rules! bind_typed_array_constructor {
} }
/// 把所有 TypedArray 家族构造器(Int8Array/Uint8Array/.../BigUint64Array)与其共享原型绑定到 global。 /// 把所有 TypedArray 家族构造器(Int8Array/Uint8Array/.../BigUint64Array)与其共享原型绑定到 global。
pub fn bind_typed_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_typed_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32) {
let shared_proto_ptr = session.builtin_world().typed_array_proto.as_ptr() as *mut JsObject; let shared_proto_ptr = session.builtin_world().typed_array_proto.as_ptr() as *mut JsObject;
let shared_proto = unsafe { &mut *shared_proto_ptr }; let shared_proto = unsafe { &mut *shared_proto_ptr };
apply_binding_table( apply_binding_table(
@@ -214,7 +220,7 @@ pub fn bind_typed_array(core: &Arc<KernelCore>, session: &KernelSession, global:
); );
// `keys` 已由方法表独立绑定(索引流 ≠ 值流);@@iterator 与 `values` // `keys` 已由方法表独立绑定(索引流 ≠ 值流);@@iterator 与 `values`
// 共享同一函数对象。 // 共享同一函数对象。
bind_well_known_method_alias(core, shared_proto, "values", 0); bind_well_known_method_alias(core, shared_proto, "values", 0, realm_id);
// 原型访问器:视图属性(buffer/byteOffset/byteLength/length)读内部数据槽, // 原型访问器:视图属性(buffer/byteOffset/byteLength/length)读内部数据槽,
// @@toStringTag 返回具体类型名,供 Object.prototype.toString 区分类型。 // @@toStringTag 返回具体类型名,供 Object.prototype.toString 区分类型。
@@ -250,7 +256,7 @@ pub fn bind_typed_array(core: &Arc<KernelCore>, session: &KernelSession, global:
core, core,
session, session,
shared_proto, shared_proto,
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG), oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG),
"get [Symbol.toStringTag]", "get [Symbol.toStringTag]",
oxide_builtins::typed_array::typed_array_to_string_tag_getter::<crate::vm::Vm> as *const (), oxide_builtins::typed_array::typed_array_to_string_tag_getter::<crate::vm::Vm> as *const (),
); );
@@ -352,7 +358,7 @@ pub fn bind_typed_array(core: &Arc<KernelCore>, session: &KernelSession, global:
1, 1,
); );
bind_typed_array_abstract_ctor(core, session); bind_typed_array_abstract_ctor(core, session, realm_id);
// 把 `%TypedArray%` 抽象构造器暴露为全局 `TypedArray`(具体构造器的 [[Prototype]])。 // 把 `%TypedArray%` 抽象构造器暴露为全局 `TypedArray`(具体构造器的 [[Prototype]])。
let abstract_ctor_val = let abstract_ctor_val =
+5 -2
View File
@@ -48,7 +48,10 @@ fn bind_labeled_method(
/// 经 `bind_constructor!` 原位安装(既有槽更新槽值,不追加新槽)。 /// 经 `bind_constructor!` 原位安装(既有槽更新槽值,不追加新槽)。
/// - 方法 wrapper 带族名站点标签登记复用键,选择性重建时按键迁移, /// - 方法 wrapper 带族名站点标签登记复用键,选择性重建时按键迁移,
/// 登记表跨重建不增长。 /// 登记表跨重建不增长。
pub fn bind_weak_map(core: &Arc<KernelCore>, session: &mut KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是目标所属 realm 的编号:`@@toStringTag` 符号键按 (realm 编号,
/// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_weak_map(core: &Arc<KernelCore>, session: &mut KernelSession, global: &mut JsObject, realm_id: u32) {
// world 唯一属主期:全程走可变引用(stub_objects 留存 + 释放登记同表)。 // world 唯一属主期:全程走可变引用(stub_objects 留存 + 释放登记同表)。
let world = Arc::get_mut(&mut session.builtin_world) let world = Arc::get_mut(&mut session.builtin_world)
.expect("BuiltinWorld must be uniquely owned during init_kernel_builtins"); .expect("BuiltinWorld must be uniquely owned during init_kernel_builtins");
@@ -87,7 +90,7 @@ pub fn bind_weak_map(core: &Arc<KernelCore>, session: &mut KernelSession, global
let ctor_pos = proto.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1); let ctor_pos = proto.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1);
proto.set_data_meta(ctor_pos, PropAttributes::new(true, false, true)); proto.set_data_meta(ctor_pos, PropAttributes::new(true, false, true));
let tag_key = let tag_key =
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG); oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG);
let tag_shape = core.shape_forge().make_shape(proto.shape_id(), tag_key); let tag_shape = core.shape_forge().make_shape(proto.shape_id(), tag_key);
proto.set_shape_id(tag_shape); proto.set_shape_id(tag_shape);
proto.ensure_hash_props().push(JsValue::perm_string( proto.ensure_hash_props().push(JsValue::perm_string(
+76 -41
View File
@@ -354,15 +354,19 @@ pub(crate) fn bind_method_alias(core: &Arc<KernelCore>, proto: &mut JsObject, so
/// 在原型上按 well-known symbol 键绑定方法(键不字符串 intern,读键经 /// 在原型上按 well-known symbol 键绑定方法(键不字符串 intern,读键经
/// `property_key_si` 的 well-known 分支映射到同一键)。 /// `property_key_si` 的 well-known 分支映射到同一键)。
///
/// `realm_id` 是目标所属 realm 的编号:符号键按 (realm 编号, 局部下标) 编码,
/// realm 编号为 0 时与旧编码逐字节一致。
#[expect(clippy::too_many_arguments)]
pub(crate) fn bind_well_known_method( pub(crate) fn bind_well_known_method(
world: &BuiltinWorld, core: &Arc<KernelCore>, target: &mut JsObject, well_known_id: u32, method_name: &str, world: &BuiltinWorld, core: &Arc<KernelCore>, target: &mut JsObject, well_known_id: u32, method_name: &str,
func: *const (), nargs: u8, func: *const (), nargs: u8, realm_id: u32,
) { ) {
let shape_forge = core.shape_forge().as_ref(); let shape_forge = core.shape_forge().as_ref();
let string_forge = core.perm_interner().as_ref(); let string_forge = core.perm_interner().as_ref();
// SAFETY: func 是转成 *const () 的 NativeFn 函数项指针。 // SAFETY: func 是转成 *const () 的 NativeFn 函数项指针。
let fn_ptr = unsafe { oxide_types::object::NativeFnPtr::from_raw(func) }; let fn_ptr = unsafe { oxide_types::object::NativeFnPtr::from_raw(func) };
let key = oxide_types::private_key::make_well_known_symbol_key(well_known_id); let key = oxide_types::private_key::encode_symbol_key(realm_id, well_known_id);
let _ = oxide_kernel::builtin::BuiltinWorld::bind_method_key_static( let _ = oxide_kernel::builtin::BuiltinWorld::bind_method_key_static(
target, target,
shape_forge, shape_forge,
@@ -383,8 +387,11 @@ pub(crate) fn bind_well_known_method(
/// # 注意 /// # 注意
/// well-known 键已在位时原位更新值,不追加重复 shape 槽:初始化与重绑可多轮 /// well-known 键已在位时原位更新值,不追加重复 shape 槽:初始化与重绑可多轮
/// 经过同一原型,重复槽会让 delete 只删其一、读仍命中残留槽。 /// 经过同一原型,重复槽会让 delete 只删其一、读仍命中残留槽。
///
/// `realm_id` 是目标所属 realm 的编号:符号键按 (realm 编号, 局部下标) 编码,
/// realm 编号为 0 时与旧编码逐字节一致。
pub(crate) fn bind_well_known_method_alias( pub(crate) fn bind_well_known_method_alias(
core: &Arc<KernelCore>, proto: &mut JsObject, source: &str, well_known_id: u32, core: &Arc<KernelCore>, proto: &mut JsObject, source: &str, well_known_id: u32, realm_id: u32,
) { ) {
let shape_forge = core.shape_forge().as_ref(); let shape_forge = core.shape_forge().as_ref();
let string_forge = core.perm_interner().as_ref(); let string_forge = core.perm_interner().as_ref();
@@ -393,7 +400,7 @@ pub(crate) fn bind_well_known_method_alias(
return; return;
}; };
let value = proto.get_prop_at(pos); let value = proto.get_prop_at(pos);
let key = oxide_types::private_key::make_well_known_symbol_key(well_known_id); let key = oxide_types::private_key::encode_symbol_key(realm_id, well_known_id);
if let Some(existing) = shape_forge.lookup_position(proto.shape_id(), key) { if let Some(existing) = shape_forge.lookup_position(proto.shape_id(), key) {
proto.set_prop_at(existing, value); proto.set_prop_at(existing, value);
proto.set_data_meta(existing, PropAttributes::new(true, false, true)); proto.set_data_meta(existing, PropAttributes::new(true, false, true));
@@ -408,10 +415,14 @@ pub(crate) fn bind_well_known_method_alias(
} }
/// 在对象上按 well-known symbol 键绑定数据属性。 /// 在对象上按 well-known symbol 键绑定数据属性。
///
/// `realm_id` 是目标所属 realm 的编号:符号键按 (realm 编号, 局部下标) 编码,
/// realm 编号为 0 时与旧编码逐字节一致。
pub(crate) fn bind_well_known_data_property( pub(crate) fn bind_well_known_data_property(
core: &Arc<KernelCore>, target: &mut JsObject, well_known_id: u32, value: JsValue, attributes: PropAttributes, core: &Arc<KernelCore>, target: &mut JsObject, well_known_id: u32, value: JsValue, attributes: PropAttributes,
realm_id: u32,
) { ) {
let key = oxide_types::private_key::make_well_known_symbol_key(well_known_id); let key = oxide_types::private_key::encode_symbol_key(realm_id, well_known_id);
let new_shape = core.shape_forge().make_shape(target.shape_id(), key); let new_shape = core.shape_forge().make_shape(target.shape_id(), key);
target.set_shape_id(new_shape); target.set_shape_id(new_shape);
let pos = target.push_prop(value); let pos = target.push_prop(value);
@@ -455,14 +466,17 @@ pub(crate) fn bind_iterator_proto_next(
/// ///
/// 在迭代器原型全新重建后调用(object 家族 dirty 或全量初始化);各绑定点 /// 在迭代器原型全新重建后调用(object 家族 dirty 或全量初始化);各绑定点
/// 自带幂等检查,保留原型重复经过时安全跳过。 /// 自带幂等检查,保留原型重复经过时安全跳过。
fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession) { ///
/// `realm_id` 是原型所属 realm 的编号:well-known 符号键按 (realm 编号, 局部
/// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession, realm_id: u32) {
let world = session.builtin_world(); let world = session.builtin_world();
// %IteratorPrototype% 自身可迭代:@@iterator 返回 this,经原型链被全部 // %IteratorPrototype% 自身可迭代:@@iterator 返回 this,经原型链被全部
// 集合迭代器继承(it[Symbol.iterator]() === it 恒等)。 // 集合迭代器继承(it[Symbol.iterator]() === it 恒等)。
let iter_proto_ptr = world.iterator_proto.as_ptr() as *mut JsObject; let iter_proto_ptr = world.iterator_proto.as_ptr() as *mut JsObject;
let iter_proto = unsafe { &mut *iter_proto_ptr }; let iter_proto = unsafe { &mut *iter_proto_ptr };
let sym_iter = oxide_types::private_key::make_well_known_symbol_key(0); let sym_iter = oxide_types::private_key::encode_symbol_key(realm_id, 0);
if core.shape_forge().lookup_position(iter_proto.shape_id(), sym_iter).is_none() { if core.shape_forge().lookup_position(iter_proto.shape_id(), sym_iter).is_none() {
bind_well_known_method( bind_well_known_method(
world, world,
@@ -472,6 +486,7 @@ fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession) {
"iterator", "iterator",
oxide_builtins::iterator::iterator_symbol_iterator::<crate::vm::Vm> as *const (), oxide_builtins::iterator::iterator_symbol_iterator::<crate::vm::Vm> as *const (),
0, 0,
realm_id,
); );
} }
@@ -496,7 +511,7 @@ fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession) {
); );
} }
let sym_to_string_tag = let sym_to_string_tag =
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG); oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG);
if core if core
.shape_forge() .shape_forge()
.lookup_position(iter_proto.shape_id(), sym_to_string_tag) .lookup_position(iter_proto.shape_id(), sym_to_string_tag)
@@ -516,7 +531,7 @@ fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession) {
// %IteratorPrototype% 的 @@dispose:显式资源管理下用 return 关闭迭代器。 // %IteratorPrototype% 的 @@dispose:显式资源管理下用 return 关闭迭代器。
let dispose_id = oxide_types::private_key::WELL_KNOWN_SYMBOL_DISPOSE; let dispose_id = oxide_types::private_key::WELL_KNOWN_SYMBOL_DISPOSE;
let sym_dispose = oxide_types::private_key::make_well_known_symbol_key(dispose_id); let sym_dispose = oxide_types::private_key::encode_symbol_key(realm_id, dispose_id);
if core.shape_forge().lookup_position(iter_proto.shape_id(), sym_dispose).is_none() { if core.shape_forge().lookup_position(iter_proto.shape_id(), sym_dispose).is_none() {
bind_well_known_method( bind_well_known_method(
world, world,
@@ -526,6 +541,7 @@ fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession) {
"[Symbol.dispose]", "[Symbol.dispose]",
oxide_builtins::iterator::iterator_dispose::<crate::vm::Vm> as *const (), oxide_builtins::iterator::iterator_dispose::<crate::vm::Vm> as *const (),
0, 0,
realm_id,
); );
} }
@@ -571,7 +587,8 @@ fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession) {
// (经 return 方法关闭迭代器)。幂等:键槽已存在时跳过。 // (经 return 方法关闭迭代器)。幂等:键槽已存在时跳过。
let aiter_proto_ptr = world.async_iterator_proto.as_ptr() as *mut JsObject; let aiter_proto_ptr = world.async_iterator_proto.as_ptr() as *mut JsObject;
let aiter_proto = unsafe { &mut *aiter_proto_ptr }; let aiter_proto = unsafe { &mut *aiter_proto_ptr };
let sym_aiter = oxide_types::private_key::make_well_known_symbol_key( let sym_aiter = oxide_types::private_key::encode_symbol_key(
realm_id,
oxide_types::private_key::WELL_KNOWN_SYMBOL_ASYNC_ITERATOR, oxide_types::private_key::WELL_KNOWN_SYMBOL_ASYNC_ITERATOR,
); );
if core.shape_forge().lookup_position(aiter_proto.shape_id(), sym_aiter).is_none() { if core.shape_forge().lookup_position(aiter_proto.shape_id(), sym_aiter).is_none() {
@@ -583,10 +600,11 @@ fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession) {
"[Symbol.asyncIterator]", "[Symbol.asyncIterator]",
crate::async_generator::async_generator_symbol_async_iterator as *const (), crate::async_generator::async_generator_symbol_async_iterator as *const (),
0, 0,
realm_id,
); );
} }
let sym_adispose = let sym_adispose =
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_ASYNC_DISPOSE); oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_ASYNC_DISPOSE);
if core if core
.shape_forge() .shape_forge()
.lookup_position(aiter_proto.shape_id(), sym_adispose) .lookup_position(aiter_proto.shape_id(), sym_adispose)
@@ -600,6 +618,7 @@ fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession) {
"[Symbol.asyncDispose]", "[Symbol.asyncDispose]",
crate::async_generator::async_iterator_async_dispose as *const (), crate::async_generator::async_iterator_async_dispose as *const (),
0, 0,
realm_id,
); );
} }
@@ -632,7 +651,7 @@ fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession) {
{ {
let sf = core.perm_interner().as_ref(); let sf = core.perm_interner().as_ref();
let tag = JsValue::perm_string(sf.string_ptr(sf.intern("Iterator Helper").0)); let tag = JsValue::perm_string(sf.string_ptr(sf.intern("Iterator Helper").0));
bind_well_known_data_property(core, helper_proto, 9, tag, PropAttributes::new(false, false, true)); bind_well_known_data_property(core, helper_proto, 9, tag, PropAttributes::new(false, false, true), realm_id);
} }
// %ArrayIteratorPrototype% 服务 Array/TA 两族;Map/Set 共用按 `__mode__` // %ArrayIteratorPrototype% 服务 Array/TA 两族;Map/Set 共用按 `__mode__`
@@ -668,12 +687,15 @@ fn bind_iterator_protos(core: &Arc<KernelCore>, session: &KernelSession) {
/// ///
/// 幂等:目标已有 tag 键槽位时跳过(dirty reset 重复经过不追加重复属性槽)。 /// 幂等:目标已有 tag 键槽位时跳过(dirty reset 重复经过不追加重复属性槽)。
/// `%IteratorPrototype%` / BigInt 原型的 tag 已由各家族绑定点安装,不在此列。 /// `%IteratorPrototype%` / BigInt 原型的 tag 已由各家族绑定点安装,不在此列。
fn install_to_string_tags(core: &Arc<KernelCore>, session: &KernelSession) { ///
/// `realm_id` 是原型所属 realm 的编号:`@@toStringTag` 符号键按 (realm 编号,
/// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
fn install_to_string_tags(core: &Arc<KernelCore>, session: &KernelSession, realm_id: u32) {
let world = session.builtin_world(); let world = session.builtin_world();
let sf = core.perm_interner().as_ref(); let sf = core.perm_interner().as_ref();
let sh = core.shape_forge().as_ref(); let sh = core.shape_forge().as_ref();
let tag_id = oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG; let tag_id = oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG;
let tag_key = oxide_types::private_key::make_well_known_symbol_key(tag_id); let tag_key = oxide_types::private_key::encode_symbol_key(realm_id, tag_id);
let cases: [(*mut JsObject, &str); 14] = [ let cases: [(*mut JsObject, &str); 14] = [
(world.map_proto.as_ptr() as *mut JsObject, "Map"), (world.map_proto.as_ptr() as *mut JsObject, "Map"),
(world.array_buffer_proto.as_ptr() as *mut JsObject, "ArrayBuffer"), (world.array_buffer_proto.as_ptr() as *mut JsObject, "ArrayBuffer"),
@@ -697,7 +719,7 @@ fn install_to_string_tags(core: &Arc<KernelCore>, session: &KernelSession) {
continue; continue;
} }
let tag_val = JsValue::perm_string(sf.string_ptr(sf.intern(tag).0)); let tag_val = JsValue::perm_string(sf.string_ptr(sf.intern(tag).0));
bind_well_known_data_property(core, proto, tag_id, tag_val, PropAttributes::new(false, false, true)); bind_well_known_data_property(core, proto, tag_id, tag_val, PropAttributes::new(false, false, true), realm_id);
} }
} }
@@ -946,7 +968,12 @@ fn bind_stub_globals(core: &Arc<KernelCore>, session: &KernelSession, global: &m
/// ///
/// 在 global 对象重建(dirty reset)后调用:重新配置构造器 native 函数并重绑 /// 在 global 对象重建(dirty reset)后调用:重新配置构造器 native 函数并重绑
/// `Object`/`Array`/`Math` 等全局名、TypedArray 家族、stub 与 `globalThis`。 /// `Object`/`Array`/`Math` 等全局名、TypedArray 家族、stub 与 `globalThis`。
pub fn bind_global_builtin_slots(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { ///
/// `realm_id` 是 session 所属 realm 的编号:well-known 符号键按 (realm 编号,
/// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn bind_global_builtin_slots(
core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject, realm_id: u32,
) {
let world = session.builtin_world(); let world = session.builtin_world();
configure_existing_ctor( configure_existing_ctor(
@@ -1175,10 +1202,10 @@ pub fn bind_global_builtin_slots(core: &Arc<KernelCore>, session: &KernelSession
bind_reflect_global(core, session, global); bind_reflect_global(core, session, global);
bind_iterator_global(core, session, global); bind_iterator_global(core, session, global);
bind_disposable_stack::bind_disposable_stack(core, session, global); bind_disposable_stack::bind_disposable_stack(core, session, global, realm_id);
bind_async_disposable_stack::bind_async_disposable_stack(core, session, global); bind_async_disposable_stack::bind_async_disposable_stack(core, session, global, realm_id);
bind_stub_globals(core, session, global); bind_stub_globals(core, session, global);
bind_bigint::bind_bigint(core, session, global); bind_bigint::bind_bigint(core, session, global, realm_id);
bind_global_functions(core, session, global); bind_global_functions(core, session, global);
crate::test262_host::bind_test262_host(core, session, global); crate::test262_host::bind_test262_host(core, session, global);
let global_this = JsValue::from_js_object(global as *mut JsObject); let global_this = JsValue::from_js_object(global as *mut JsObject);
@@ -1187,10 +1214,15 @@ pub fn bind_global_builtin_slots(core: &Arc<KernelCore>, session: &KernelSession
/// 按脏标记重绑被污染的内置对象;`dirty` 为 `None` 时绑定全部(初始化路径)。 /// 按脏标记重绑被污染的内置对象;`dirty` 为 `None` 时绑定全部(初始化路径)。
/// ///
/// `realm_id` 是 session 所属 realm 的编号:well-known 符号键按 (realm 编号,
/// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
///
/// # 注意事项 /// # 注意事项
/// 维护:新增 `BuiltinDirtySet` 分组时,须同步更新本重绑映射、`BuiltinSnapshot` 与 /// 维护:新增 `BuiltinDirtySet` 分组时,须同步更新本重绑映射、`BuiltinSnapshot` 与
/// `BuiltinWorld::rebuild_with_dirty()`。 /// `BuiltinWorld::rebuild_with_dirty()`。
pub fn rebind_dirty_builtins(core: &Arc<KernelCore>, session: &mut KernelSession, dirty: Option<&BuiltinDirtySet>) { pub fn rebind_dirty_builtins(
core: &Arc<KernelCore>, session: &mut KernelSession, dirty: Option<&BuiltinDirtySet>, realm_id: u32,
) {
let global_ptr = session.global_object().as_ptr() as *mut JsObject; let global_ptr = session.global_object().as_ptr() as *mut JsObject;
let global = unsafe { &mut *global_ptr }; let global = unsafe { &mut *global_ptr };
@@ -1198,18 +1230,18 @@ pub fn rebind_dirty_builtins(core: &Arc<KernelCore>, session: &mut KernelSession
bind_object::bind_object(core, session, global); bind_object::bind_object(core, session, global);
// object 家族重建连带重建 6 个迭代器原型与两资源栈原型(其链到新 // object 家族重建连带重建 6 个迭代器原型与两资源栈原型(其链到新
// Object.prototype),须同步安装原型方法并让保留的 global 构造器指向新原型。 // Object.prototype),须同步安装原型方法并让保留的 global 构造器指向新原型。
bind_iterator_protos(core, session); bind_iterator_protos(core, session, realm_id);
sync_iterator_function_prototype(core, session, global); sync_iterator_function_prototype(core, session, global);
bind_disposable_stack::bind_disposable_stack_protos(core, session); bind_disposable_stack::bind_disposable_stack_protos(core, session, realm_id);
bind_disposable_stack::sync_disposable_stack_ctor(core, session, global); bind_disposable_stack::sync_disposable_stack_ctor(core, session, global);
bind_async_disposable_stack::bind_async_disposable_stack_protos(core, session); bind_async_disposable_stack::bind_async_disposable_stack_protos(core, session, realm_id);
bind_async_disposable_stack::sync_async_disposable_stack_ctor(core, session, global); bind_async_disposable_stack::sync_async_disposable_stack_ctor(core, session, global);
} }
if dirty.map_or(true, |d| d.array) { if dirty.map_or(true, |d| d.array) {
bind_array::bind_array(core, session, global); bind_array::bind_array(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.array_buffer) { if dirty.map_or(true, |d| d.array_buffer) {
bind_array_buffer::bind_array_buffer(core, session, global); bind_array_buffer::bind_array_buffer(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.shared_array_buffer) { if dirty.map_or(true, |d| d.shared_array_buffer) {
bind_shared_array_buffer::bind_shared_array_buffer(core, session, global); bind_shared_array_buffer::bind_shared_array_buffer(core, session, global);
@@ -1218,13 +1250,13 @@ pub fn rebind_dirty_builtins(core: &Arc<KernelCore>, session: &mut KernelSession
bind_data_view::bind_data_view(core, session, global); bind_data_view::bind_data_view(core, session, global);
} }
if dirty.map_or(true, |d| d.typed_array_family) { if dirty.map_or(true, |d| d.typed_array_family) {
bind_typed_array::bind_typed_array(core, session, global); bind_typed_array::bind_typed_array(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.error_family) { if dirty.map_or(true, |d| d.error_family) {
bind_error::bind_error(core, session, global); bind_error::bind_error(core, session, global);
} }
if dirty.map_or(true, |d| d.string) { if dirty.map_or(true, |d| d.string) {
bind_string::bind_string(core, session, global); bind_string::bind_string(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.number) { if dirty.map_or(true, |d| d.number) {
bind_number::bind_number(core, session, global); bind_number::bind_number(core, session, global);
@@ -1242,51 +1274,54 @@ pub fn rebind_dirty_builtins(core: &Arc<KernelCore>, session: &mut KernelSession
bind_date::bind_date(core, session, global); bind_date::bind_date(core, session, global);
} }
if dirty.map_or(true, |d| d.set) { if dirty.map_or(true, |d| d.set) {
bind_set::bind_set(core, session, global); bind_set::bind_set(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.map) { if dirty.map_or(true, |d| d.map) {
bind_map::bind_map(core, session, global); bind_map::bind_map(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.boolean) { if dirty.map_or(true, |d| d.boolean) {
bind_boolean::bind_boolean(core, session, global); bind_boolean::bind_boolean(core, session, global);
} }
if dirty.map_or(true, |d| d.function) { if dirty.map_or(true, |d| d.function) {
bind_function::bind_function(core, session, global); bind_function::bind_function(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.regexp) { if dirty.map_or(true, |d| d.regexp) {
bind_regexp::bind_regexp(core, session, global); bind_regexp::bind_regexp(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.symbol_family) { if dirty.map_or(true, |d| d.symbol_family) {
bind_symbol::bind_symbol(core, session, global); bind_symbol::bind_symbol(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.temporal) { if dirty.map_or(true, |d| d.temporal) {
bind_temporal::bind_temporal(core, session, global); bind_temporal::bind_temporal(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.stubs) { if dirty.map_or(true, |d| d.stubs) {
bind_stubs::bind_stubs(core, session, global); bind_stubs::bind_stubs(core, session, global, realm_id);
// WeakMap 真构造器面与 stub 族同脏位:原型对象经 leaked 登记表迁移, // WeakMap 真构造器面与 stub 族同脏位:原型对象经 leaked 登记表迁移,
// 重绑时全局槽原位更新,不占 BuiltinWorld 槽。 // 重绑时全局槽原位更新,不占 BuiltinWorld 槽。
bind_weak::bind_weak_map(core, session, global); bind_weak::bind_weak_map(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.stubs) { if dirty.map_or(true, |d| d.stubs) {
bind_bigint::bind_bigint(core, session, global); bind_bigint::bind_bigint(core, session, global, realm_id);
} }
if dirty.map_or(true, |d| d.console) { if dirty.map_or(true, |d| d.console) {
bind_console::bind_console(core, session, global); bind_console::bind_console(core, session, global);
} }
// tag 目标横跨多个脏分组(Map/Set/DataView/Math/JSON/迭代器原型), // tag 目标横跨多个脏分组(Map/Set/DataView/Math/JSON/迭代器原型),
// 各组各自重绑后统一补装;安装点自带幂等检查。 // 各组各自重绑后统一补装;安装点自带幂等检查。
install_to_string_tags(core, session); install_to_string_tags(core, session, realm_id);
} }
/// 完整初始化一个 session 的内置对象(全量绑定 + `globalThis` + 快照记录)。 /// 完整初始化一个 session 的内置对象(全量绑定 + `globalThis` + 快照记录)。
pub fn init_kernel_builtins(core: &Arc<KernelCore>, session: &mut KernelSession) { ///
rebind_dirty_builtins(core, session, None); /// `realm_id` 是 session 所属 realm 的编号:well-known 符号键按 (realm 编号,
/// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。
pub fn init_kernel_builtins(core: &Arc<KernelCore>, session: &mut KernelSession, realm_id: u32) {
rebind_dirty_builtins(core, session, None, realm_id);
let global_ptr = session.global_object().as_ptr() as *mut oxide_types::object::JsObject; let global_ptr = session.global_object().as_ptr() as *mut oxide_types::object::JsObject;
let global = unsafe { &mut *global_ptr }; let global = unsafe { &mut *global_ptr };
bind_iterator::bind_iterator(core, session, global); bind_iterator::bind_iterator(core, session, global);
bind_disposable_stack::bind_disposable_stack(core, session, global); bind_disposable_stack::bind_disposable_stack(core, session, global, realm_id);
bind_async_disposable_stack::bind_async_disposable_stack(core, session, global); bind_async_disposable_stack::bind_async_disposable_stack(core, session, global, realm_id);
bind_reflect::bind_reflect(core, session, global); bind_reflect::bind_reflect(core, session, global);
bind_global::bind_global(core, session, global); bind_global::bind_global(core, session, global);
bind_global_value(core, global, "globalThis", JsValue::from_js_object(global_ptr)); bind_global_value(core, global, "globalThis", JsValue::from_js_object(global_ptr));
+21 -9
View File
@@ -50,7 +50,10 @@ impl Vm {
pub fn new() -> Self { pub fn new() -> Self {
let core = KernelCore::new(KernelConfig::minimal()); let core = KernelCore::new(KernelConfig::minimal());
let mut session = KernelSession::new(&core); let mut session = KernelSession::new(&core);
bindings::init_kernel_builtins(&core, &mut session); // realm 编号在构造时分配并固化:首个 realm 编号为 0(与旧符号编码一致)。
// 须在 builtin 绑定之前分配:绑定按 (realm 编号, 局部下标) 编码 well-known 符号键。
let realm_id = core.alloc_realm_id();
bindings::init_kernel_builtins(&core, &mut session, realm_id);
// 在 builtin 绑定之后取 id:绑定过程已 intern "length",此处命中缓存得到 // 在 builtin 绑定之后取 id:绑定过程已 intern "length",此处命中缓存得到
// 稳定的 id,用于运行期常见属性(如函数 length 槽)的快路径。 // 稳定的 id,用于运行期常见属性(如函数 length 槽)的快路径。
let length_si = core.perm_interner().intern("length").0; let length_si = core.perm_interner().intern("length").0;
@@ -58,8 +61,6 @@ impl Vm {
let obj_proto = P::clone(&session.builtin_world().object_proto); let obj_proto = P::clone(&session.builtin_world().object_proto);
// 提前缓存执行期字符串 GC 初始水位(构造后 config 不再变化)。 // 提前缓存执行期字符串 GC 初始水位(构造后 config 不再变化)。
let gc_threshold = core.config().session_gc_threshold; let gc_threshold = core.config().session_gc_threshold;
// realm 编号在构造时分配并固化:首个 realm 编号为 0(与旧符号编码一致)。
let realm_id = core.alloc_realm_id();
let mut vm = Self { let mut vm = Self {
regs: [JsValue::undefined(); 256], regs: [JsValue::undefined(); 256],
pc: 0, pc: 0,
@@ -199,7 +200,10 @@ impl Vm {
/// 复用共享 `KernelCore` 创建 VM(VM 池路径),共享 intern/shape/code 缓存。 /// 复用共享 `KernelCore` 创建 VM(VM 池路径),共享 intern/shape/code 缓存。
pub fn with_kernel_core(core: Arc<KernelCore>) -> Self { pub fn with_kernel_core(core: Arc<KernelCore>) -> Self {
let mut session = KernelSession::new(&core); let mut session = KernelSession::new(&core);
bindings::init_kernel_builtins(&core, &mut session); // realm 编号在构造时分配并固化:首个 realm 编号为 0(与旧符号编码一致)。
// 须在 builtin 绑定之前分配:绑定按 (realm 编号, 局部下标) 编码 well-known 符号键。
let realm_id = core.alloc_realm_id();
bindings::init_kernel_builtins(&core, &mut session, realm_id);
// 在 builtin 绑定之后取 id:绑定过程已 intern "length",此处命中缓存得到 // 在 builtin 绑定之后取 id:绑定过程已 intern "length",此处命中缓存得到
// 稳定的 id,用于运行期常见属性(如函数 length 槽)的快路径。 // 稳定的 id,用于运行期常见属性(如函数 length 槽)的快路径。
let length_si = core.perm_interner().intern("length").0; let length_si = core.perm_interner().intern("length").0;
@@ -207,8 +211,6 @@ impl Vm {
let obj_proto = P::clone(&session.builtin_world().object_proto); let obj_proto = P::clone(&session.builtin_world().object_proto);
// 提前缓存执行期字符串 GC 初始水位(构造后 config 不再变化)。 // 提前缓存执行期字符串 GC 初始水位(构造后 config 不再变化)。
let gc_threshold = core.config().session_gc_threshold; let gc_threshold = core.config().session_gc_threshold;
// realm 编号在构造时分配并固化:首个 realm 编号为 0(与旧符号编码一致)。
let realm_id = core.alloc_realm_id();
let mut vm = Self { let mut vm = Self {
regs: [JsValue::undefined(); 256], regs: [JsValue::undefined(); 256],
pc: 0, pc: 0,
@@ -381,12 +383,22 @@ impl Vm {
} }
let dirty = self.realm.session.borrow_mut().selective_reset(&self.kernel_core); let dirty = self.realm.session.borrow_mut().selective_reset(&self.kernel_core);
if dirty.any_builtin_dirty() { if dirty.any_builtin_dirty() {
bindings::rebind_dirty_builtins(&self.kernel_core, &mut self.realm.session.borrow_mut(), Some(&dirty)); bindings::rebind_dirty_builtins(
&self.kernel_core,
&mut self.realm.session.borrow_mut(),
Some(&dirty),
self.realm_id(),
);
} }
if dirty.global { if dirty.global {
let global_ptr = self.realm.session.borrow().global_object().as_ptr() as *mut JsObject; let global_ptr = self.realm.session.borrow().global_object().as_ptr() as *mut JsObject;
let global = unsafe { &mut *global_ptr }; let global = unsafe { &mut *global_ptr };
bindings::bind_global_builtin_slots(&self.kernel_core, &self.realm.session.borrow_mut(), global); bindings::bind_global_builtin_slots(
&self.kernel_core,
&self.realm.session.borrow_mut(),
global,
self.realm_id(),
);
} }
*self.realm *self.realm
.object_prototype .object_prototype
@@ -405,7 +417,7 @@ impl Vm {
#[doc(hidden)] #[doc(hidden)]
pub fn full_reset_legacy_for_bench(&mut self) { pub fn full_reset_legacy_for_bench(&mut self) {
*self.realm.session.borrow_mut() = KernelSession::new(&self.kernel_core); *self.realm.session.borrow_mut() = KernelSession::new(&self.kernel_core);
bindings::init_kernel_builtins(&self.kernel_core, &mut self.realm.session.borrow_mut()); bindings::init_kernel_builtins(&self.kernel_core, &mut self.realm.session.borrow_mut(), self.realm_id());
*self.realm *self.realm
.object_prototype .object_prototype
.borrow_mut() = P::clone(&self.realm.session.borrow().builtin_world().object_proto); .borrow_mut() = P::clone(&self.realm.session.borrow().builtin_world().object_proto);