From a651cbff54ca61f08ead7c5afadcc03ff335045b Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Mon, 12 Oct 2026 17:25:40 +0000 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=BB=91=E5=AE=9A=E5=B1=82?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E7=AD=BE=E5=90=8D=E6=94=B6=E6=95=9B=E4=B8=BA?= =?UTF-8?q?=20BindEnv=20=E5=8D=95=E5=8F=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 42 +-- Cargo.toml | 2 +- crates/oxide_vm/src/bindings/bind_array.rs | 35 +- .../src/bindings/bind_array_buffer.rs | 39 +- .../bindings/bind_async_disposable_stack.rs | 61 ++-- crates/oxide_vm/src/bindings/bind_atomics.rs | 17 +- crates/oxide_vm/src/bindings/bind_bigint.rs | 27 +- crates/oxide_vm/src/bindings/bind_boolean.rs | 16 +- .../src/bindings/bind_broadcast_channel.rs | 29 +- crates/oxide_vm/src/bindings/bind_console.rs | 19 +- .../oxide_vm/src/bindings/bind_data_view.rs | 29 +- crates/oxide_vm/src/bindings/bind_date.rs | 23 +- .../src/bindings/bind_disposable_stack.rs | 65 ++-- crates/oxide_vm/src/bindings/bind_error.rs | 82 ++--- crates/oxide_vm/src/bindings/bind_event.rs | 35 +- crates/oxide_vm/src/bindings/bind_function.rs | 45 ++- crates/oxide_vm/src/bindings/bind_global.rs | 10 +- crates/oxide_vm/src/bindings/bind_iterator.rs | 20 +- crates/oxide_vm/src/bindings/bind_json.rs | 16 +- crates/oxide_vm/src/bindings/bind_map.rs | 28 +- crates/oxide_vm/src/bindings/bind_math.rs | 27 +- .../src/bindings/bind_message_channel.rs | 26 +- crates/oxide_vm/src/bindings/bind_number.rs | 32 +- crates/oxide_vm/src/bindings/bind_object.rs | 25 +- crates/oxide_vm/src/bindings/bind_reflect.rs | 16 +- crates/oxide_vm/src/bindings/bind_regexp.rs | 81 ++--- crates/oxide_vm/src/bindings/bind_set.rs | 27 +- .../src/bindings/bind_shared_array_buffer.rs | 25 +- crates/oxide_vm/src/bindings/bind_string.rs | 43 +-- crates/oxide_vm/src/bindings/bind_symbol.rs | 38 +- crates/oxide_vm/src/bindings/bind_temporal.rs | 344 +++++++----------- .../oxide_vm/src/bindings/bind_typed_array.rs | 156 ++++---- crates/oxide_vm/src/bindings/bind_weak.rs | 5 +- crates/oxide_vm/src/bindings/bind_worker.rs | 38 +- crates/oxide_vm/src/bindings/mod.rs | 281 +++++++------- crates/oxide_vm/src/promise/constructor.rs | 3 +- crates/oxide_vm/src/test262_host.rs | 22 +- 37 files changed, 770 insertions(+), 1059 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f8eea55..4c3ce87a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1160,7 +1160,7 @@ dependencies = [ [[package]] name = "oxide_builtins" -version = "0.17.2" +version = "0.17.3" dependencies = [ "chrono", "fast-float", @@ -1185,7 +1185,7 @@ dependencies = [ [[package]] name = "oxide_bytecode" -version = "0.17.2" +version = "0.17.3" dependencies = [ "num-bigint", "oxide_log", @@ -1193,7 +1193,7 @@ dependencies = [ [[package]] name = "oxide_cfg" -version = "0.17.2" +version = "0.17.3" dependencies = [ "oxide_bytecode", "oxide_emit", @@ -1204,7 +1204,7 @@ dependencies = [ [[package]] name = "oxide_cli" -version = "0.17.2" +version = "0.17.3" dependencies = [ "ansi_term", "bumpalo", @@ -1228,7 +1228,7 @@ dependencies = [ [[package]] name = "oxide_code_cache" -version = "0.17.2" +version = "0.17.3" dependencies = [ "lru", "oxide_bytecode", @@ -1237,7 +1237,7 @@ dependencies = [ [[package]] name = "oxide_compiler" -version = "0.17.2" +version = "0.17.3" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1258,7 +1258,7 @@ dependencies = [ [[package]] name = "oxide_dce" -version = "0.17.2" +version = "0.17.3" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1272,7 +1272,7 @@ dependencies = [ [[package]] name = "oxide_emit" -version = "0.17.2" +version = "0.17.3" dependencies = [ "num-bigint", "oxc_allocator", @@ -1288,7 +1288,7 @@ dependencies = [ [[package]] name = "oxide_engine" -version = "0.17.2" +version = "0.17.3" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1300,7 +1300,7 @@ dependencies = [ [[package]] name = "oxide_fold" -version = "0.17.2" +version = "0.17.3" dependencies = [ "num-bigint", "oxide_bytecode", @@ -1312,7 +1312,7 @@ dependencies = [ [[package]] name = "oxide_ir" -version = "0.17.2" +version = "0.17.3" dependencies = [ "oxide_bytecode", "oxide_log", @@ -1321,7 +1321,7 @@ dependencies = [ [[package]] name = "oxide_kernel" -version = "0.17.2" +version = "0.17.3" dependencies = [ "bumpalo", "dashmap", @@ -1335,7 +1335,7 @@ dependencies = [ [[package]] name = "oxide_liveness" -version = "0.17.2" +version = "0.17.3" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1347,7 +1347,7 @@ dependencies = [ [[package]] name = "oxide_log" -version = "0.17.2" +version = "0.17.3" dependencies = [ "tracing", "tracing-appender", @@ -1356,11 +1356,11 @@ dependencies = [ [[package]] name = "oxide_net" -version = "0.17.2" +version = "0.17.3" [[package]] name = "oxide_parser" -version = "0.17.2" +version = "0.17.3" dependencies = [ "oxc_allocator", "oxc_ast", @@ -1375,7 +1375,7 @@ dependencies = [ [[package]] name = "oxide_regalloc" -version = "0.17.2" +version = "0.17.3" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1391,7 +1391,7 @@ dependencies = [ [[package]] name = "oxide_runtime_api" -version = "0.17.2" +version = "0.17.3" dependencies = [ "num-bigint", "num-traits", @@ -1404,7 +1404,7 @@ dependencies = [ [[package]] name = "oxide_test262" -version = "0.17.2" +version = "0.17.3" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1424,7 +1424,7 @@ dependencies = [ [[package]] name = "oxide_types" -version = "0.17.2" +version = "0.17.3" dependencies = [ "bumpalo", "dashmap", @@ -1437,7 +1437,7 @@ dependencies = [ [[package]] name = "oxide_vm" -version = "0.17.2" +version = "0.17.3" dependencies = [ "bumpalo", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 81acefe1..c8a1a22c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ members = [ ] [workspace.package] -version = "0.17.2" +version = "0.17.3" edition = "2021" license = "MIT" rust-version = "1.80" diff --git a/crates/oxide_vm/src/bindings/bind_array.rs b/crates/oxide_vm/src/bindings/bind_array.rs index 75f855b3..ad993ee7 100644 --- a/crates/oxide_vm/src/bindings/bind_array.rs +++ b/crates/oxide_vm/src/bindings/bind_array.rs @@ -1,17 +1,14 @@ -use std::sync::Arc; - use oxide_kernel::builtin::ArrayMethods; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::{JsObject, PropAttributes}; use crate::bind_constructor; -use crate::bindings::apply_binding_table; +use crate::bindings::{apply_binding_table, BindEnv}; /// 把 Array 构造器与原型方法绑定到 global。 /// /// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_array(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { +pub fn bind_array(env: BindEnv<'_>, global: &mut JsObject) { let _array_methods = ArrayMethods { is_array: oxide_builtins::array::array_is_array:: as *const (), from: oxide_builtins::array::array_from:: as *const (), @@ -54,42 +51,40 @@ pub fn bind_array(core: &Arc, session: &KernelSession, global: &mut with_method: oxide_builtins::array::array_with:: as *const (), }; - session.builtin_world().bind_array_methods( + env.world().bind_array_methods( &_array_methods, - core.perm_interner().as_ref(), - core.shape_forge().as_ref(), - realm_id, + env.string_forge(), + env.shape_forge(), + env.realm_id, ); - let array_proto_ptr = session.builtin_world().array_proto.as_ptr() as *mut JsObject; + let array_proto_ptr = env.world().array_proto.as_ptr() as *mut JsObject; let array_proto = unsafe { &mut *array_proto_ptr }; apply_binding_table( - session.builtin_world(), + env, array_proto, - core, &[ ("toString", oxide_builtins::array::array_to_string:: as *const (), 0), ("toSource", oxide_builtins::to_source::to_source_array:: as *const (), 0), ], ); // 内置原型方法不可枚举(否则会泄漏进 for-in)。 - let si = core.perm_interner().intern("toString").0; - if let Some(pos) = core.shape_forge().lookup_position(array_proto.shape_id(), si) { + let si = env.string_forge().intern("toString").0; + if let Some(pos) = env.shape_forge().lookup_position(array_proto.shape_id(), si) { array_proto.set_data_meta(pos, PropAttributes::new(true, false, true)); } // Array.prototype[@@iterator] 与 values 共享同一函数对象。 - super::bind_well_known_method_alias(core, array_proto, "values", 0, realm_id); + super::bind_well_known_method_alias(env.core, array_proto, "values", 0, env.realm_id); - 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::, 1, hash: true); + let ctor_ptr = env.world().array_constructor.as_ptr() as *mut JsObject; + bind_constructor!(env, global, "Array", ctor_ptr, oxide_builtins::array::array_constructor::, 1, hash: true); // Array[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链 // 解析 @@species 得自身构造器(规范不给 class 默认 static @@species,类上 // 无 own 属性)。 super::bind_accessor_getter_key( - core, - session, + env, unsafe { &mut *ctor_ptr }, - oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), + oxide_types::private_key::encode_symbol_key(env.realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), "get [Symbol.species]", oxide_builtins::array::array_species_get:: as *const (), ); diff --git a/crates/oxide_vm/src/bindings/bind_array_buffer.rs b/crates/oxide_vm/src/bindings/bind_array_buffer.rs index 945f4f36..44f02bf2 100644 --- a/crates/oxide_vm/src/bindings/bind_array_buffer.rs +++ b/crates/oxide_vm/src/bindings/bind_array_buffer.rs @@ -1,20 +1,17 @@ -use std::sync::Arc; - use crate::bind_constructor; use crate::bindings::{ - apply_binding_table, bind_accessor_getter, bind_accessor_getter_key, configure_native_constructor, + apply_binding_table, bind_accessor_getter, bind_accessor_getter_key, configure_native_constructor, BindEnv, }; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::{JsObject, PropAttributes}; /// 把 ArrayBuffer 构造器与原型方法绑定到 global。 /// /// `realm_id` 是目标所属 realm 的编号:`@@species` 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_array_buffer(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { - let ctor_ptr = session.builtin_world().array_buffer_constructor.as_ptr() as *mut JsObject; +pub fn bind_array_buffer(env: BindEnv<'_>, global: &mut JsObject) { + let ctor_ptr = env.world().array_buffer_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - let proto_ptr = session.builtin_world().array_buffer_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().array_buffer_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; configure_native_constructor( @@ -24,9 +21,8 @@ pub fn bind_array_buffer(core: &Arc, session: &KernelSession, global ); apply_binding_table( - session.builtin_world(), + env, ctor, - core, &[( "isView", oxide_builtins::array_buffer::array_buffer_is_view:: as *const (), @@ -37,18 +33,16 @@ pub fn bind_array_buffer(core: &Arc, session: &KernelSession, global // ArrayBuffer[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链 // 解析 @@species 得自身构造器(规范不给 class 默认 static @@species,类上无 own)。 bind_accessor_getter_key( - core, - session, + env, ctor, - oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), + oxide_types::private_key::encode_symbol_key(env.realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), "get [Symbol.species]", oxide_builtins::array::array_species_get:: as *const (), ); apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ( "resize", @@ -91,8 +85,7 @@ pub fn bind_array_buffer(core: &Arc, session: &KernelSession, global // byteLength 原型访问器(set 恒 undefined):读载荷字节数,实例无 own 属性。 bind_accessor_getter( - core, - session, + env, proto, "byteLength", oxide_builtins::array_buffer::array_buffer_byte_length:: as *const (), @@ -100,8 +93,7 @@ pub fn bind_array_buffer(core: &Arc, session: &KernelSession, global // resizable 原型访问器(set 恒 undefined):读载荷 max_byte_length 状态位。 bind_accessor_getter( - core, - session, + env, proto, "resizable", oxide_builtins::array_buffer::array_buffer_resizable:: as *const (), @@ -110,8 +102,7 @@ pub fn bind_array_buffer(core: &Arc, session: &KernelSession, global // maxByteLength 原型访问器(set 恒 undefined):detached 回 +0,定长回 // 当前字节数,resizable 回存储态上限 − 1。 bind_accessor_getter( - core, - session, + env, proto, "maxByteLength", oxide_builtins::array_buffer::array_buffer_max_byte_length:: as *const (), @@ -119,8 +110,7 @@ pub fn bind_array_buffer(core: &Arc, session: &KernelSession, global // immutable 原型访问器(set 恒 undefined):读载荷 immutable 标志。 bind_accessor_getter( - core, - session, + env, proto, "immutable", oxide_builtins::array_buffer::array_buffer_immutable:: as *const (), @@ -128,15 +118,14 @@ pub fn bind_array_buffer(core: &Arc, session: &KernelSession, global // detached 原型访问器(set 恒 undefined):读载荷 data 存活位。 bind_accessor_getter( - core, - session, + env, proto, "detached", oxide_builtins::array_buffer::array_buffer_detached:: as *const (), ); bind_constructor!( - core, + env, global, "ArrayBuffer", ctor_ptr, diff --git a/crates/oxide_vm/src/bindings/bind_async_disposable_stack.rs b/crates/oxide_vm/src/bindings/bind_async_disposable_stack.rs index 08037844..9866f6eb 100644 --- a/crates/oxide_vm/src/bindings/bind_async_disposable_stack.rs +++ b/crates/oxide_vm/src/bindings/bind_async_disposable_stack.rs @@ -1,6 +1,3 @@ -use std::sync::Arc; - -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes}; use oxide_types::value::JsValue; @@ -8,7 +5,7 @@ use oxide_types::value::JsValue; use crate::async_disposable::dispose_async; use crate::bindings::{ apply_binding_table, bind_accessor_getter, bind_disposable_stack::write_proto_constructor, bind_global_value, - bind_well_known_data_property, bind_well_known_method_alias, configure_native_constructor, + bind_well_known_data_property, bind_well_known_method_alias, configure_native_constructor, BindEnv, }; /// 在 `AsyncDisposableStack.prototype` 上安装方法/别名/访问器/@@toStringTag。 @@ -19,19 +16,18 @@ use crate::bindings::{ /// /// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_async_disposable_stack_protos(core: &Arc, session: &KernelSession, realm_id: u32) { - let world = session.builtin_world(); +pub fn bind_async_disposable_stack_protos(env: BindEnv<'_>) { + let world = env.world(); let proto_ptr = world.async_disposable_stack_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - let si_use = core.perm_interner().intern("use").0; - if core.shape_forge().lookup_position(proto.shape_id(), si_use).is_some() { + let si_use = env.string_forge().intern("use").0; + if env.shape_forge().lookup_position(proto.shape_id(), si_use).is_some() { return; } apply_binding_table( - world, + env, proto, - core, &[ ( "use", @@ -57,17 +53,16 @@ pub fn bind_async_disposable_stack_protos(core: &Arc, session: &Kern ], ); bind_accessor_getter( - core, - session, + env, proto, "disposed", oxide_builtins::disposable_stack::async_disposable_stack_disposed_getter:: as *const (), ); // @@asyncDispose 与 disposeAsync 为同一函数对象(先绑 disposeAsync 再取源槽)。 - bind_well_known_method_alias(core, proto, "disposeAsync", 11, realm_id); - let sf = core.perm_interner().as_ref(); + bind_well_known_method_alias(env.core, proto, "disposeAsync", 11, env.realm_id); + let sf = env.string_forge(); 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), realm_id); + bind_well_known_data_property(env.core, proto, 9, tag, PropAttributes::new(false, false, true), env.realm_id); } /// 把 `AsyncDisposableStack` 构造器绑定到 global(init 与 full_reset global 重建共用)。 @@ -78,14 +73,12 @@ pub fn bind_async_disposable_stack_protos(core: &Arc, session: &Kern /// /// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_async_disposable_stack( - core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32, -) { - let world = session.builtin_world(); +pub fn bind_async_disposable_stack(env: BindEnv<'_>, global: &mut JsObject) { + let world = env.world(); let proto_ptr = world.async_disposable_stack_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - let si_constructor = core.perm_interner().intern("constructor").0; - let ctor_val = match core.shape_forge().lookup_position(proto.shape_id(), si_constructor) { + let si_constructor = env.string_forge().intern("constructor").0; + let ctor_val = match env.shape_forge().lookup_position(proto.shape_id(), si_constructor) { Some(pos) => { let existing = proto.get_prop_at(pos); if existing.is_object() { @@ -99,8 +92,8 @@ pub fn bind_async_disposable_stack( let ctor_val = if ctor_val.is_object() { ctor_val } else { - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); + let sf = env.string_forge(); + let sh = env.shape_forge(); let name_si = sf.intern("AsyncDisposableStack").0; // 选择性重建复用:非 P 目标(家族 0)按键查找前轮旧构造器迁移,避免每轮 // 新建导致登记表无界累积;槽键取 global 槽名,该命名空间内全局唯一。 @@ -152,9 +145,9 @@ pub fn bind_async_disposable_stack( JsValue::from_js_object(ctor_ptr) }; - write_proto_constructor(core, proto, ctor_val); - bind_async_disposable_stack_protos(core, session, realm_id); - bind_global_value(core, global, "AsyncDisposableStack", ctor_val); + write_proto_constructor(env, proto, ctor_val); + bind_async_disposable_stack_protos(env); + bind_global_value(env.core, global, "AsyncDisposableStack", ctor_val); } /// 对齐保留 global 上 `AsyncDisposableStack` 函数对象的 `prototype` 属性:object @@ -163,9 +156,9 @@ pub fn bind_async_disposable_stack( /// /// global 同时重建(global dirty)或初始化时无 `AsyncDisposableStack` 属性, /// 直接跳过——彼时由 `bind_async_disposable_stack` 以新原型创建函数对象。 -pub fn sync_async_disposable_stack_ctor(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let si_stack = core.perm_interner().intern("AsyncDisposableStack").0; - let Some(pos) = core.shape_forge().lookup_position(global.shape_id(), si_stack) else { +pub fn sync_async_disposable_stack_ctor(env: BindEnv<'_>, global: &mut JsObject) { + let si_stack = env.string_forge().intern("AsyncDisposableStack").0; + let Some(pos) = env.shape_forge().lookup_position(global.shape_id(), si_stack) else { return; }; let stack_val = global.get_prop_at(pos); @@ -173,14 +166,14 @@ pub fn sync_async_disposable_stack_ctor(core: &Arc, session: &Kernel return; } let ctor = unsafe { &mut *stack_val.as_js_object_ptr() }; - let si_prototype = core.perm_interner().intern("prototype").0; - let Some(proto_pos) = core.shape_forge().lookup_position(ctor.shape_id(), si_prototype) else { + let si_prototype = env.string_forge().intern("prototype").0; + let Some(proto_pos) = env.shape_forge().lookup_position(ctor.shape_id(), si_prototype) else { return; }; let new_proto = - JsValue::from_js_object(session.builtin_world().async_disposable_stack_proto.as_ptr() as *mut JsObject); + JsValue::from_js_object(env.world().async_disposable_stack_proto.as_ptr() as *mut JsObject); ctor.set_prop_at(proto_pos, new_proto); - let proto_ptr = session.builtin_world().async_disposable_stack_proto.as_ptr() as *mut JsObject; - write_proto_constructor(core, unsafe { &mut *proto_ptr }, stack_val); + let proto_ptr = env.world().async_disposable_stack_proto.as_ptr() as *mut JsObject; + write_proto_constructor(env, unsafe { &mut *proto_ptr }, stack_val); } diff --git a/crates/oxide_vm/src/bindings/bind_atomics.rs b/crates/oxide_vm/src/bindings/bind_atomics.rs index def6fd12..b84e2488 100644 --- a/crates/oxide_vm/src/bindings/bind_atomics.rs +++ b/crates/oxide_vm/src/bindings/bind_atomics.rs @@ -1,23 +1,20 @@ -use std::sync::Arc; - use oxide_kernel::bind_methods; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::JsObject; use oxide_types::value::JsValue; -use crate::bindings::bind_global_value; +use crate::bindings::{bind_global_value, BindEnv}; /// 把 Atomics 全局纯对象及其 10 个原子方法绑定到 global。 /// /// Atomics 非函数对象:原型链落 Object.prototype(`wire_builtin_world_links`), /// `@@toStringTag` 由 `install_to_string_tags` 统一补装;此处只装方法与全局槽。 -pub fn bind_atomics(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let atomics_ptr = session.builtin_world().atomics_object.as_ptr() as *mut JsObject; +pub fn bind_atomics(env: BindEnv<'_>, global: &mut JsObject) { + let atomics_ptr = env.world().atomics_object.as_ptr() as *mut JsObject; let atomics = unsafe { &mut *atomics_ptr }; - let bw = session.builtin_world(); - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); + let bw = env.world(); + let sf = env.string_forge(); + let sh = env.shape_forge(); bind_methods!( bw, @@ -41,5 +38,5 @@ pub fn bind_atomics(core: &Arc, session: &KernelSession, global: &mu ); let a_val = JsValue::from_js_object(atomics_ptr); - bind_global_value(core, global, "Atomics", a_val); + bind_global_value(env.core, global, "Atomics", a_val); } diff --git a/crates/oxide_vm/src/bindings/bind_bigint.rs b/crates/oxide_vm/src/bindings/bind_bigint.rs index 5a0cc185..b02cbd5d 100644 --- a/crates/oxide_vm/src/bindings/bind_bigint.rs +++ b/crates/oxide_vm/src/bindings/bind_bigint.rs @@ -1,9 +1,6 @@ -use std::sync::Arc; - use crate::bindings::{ - apply_binding_table, bind_global_value, bind_well_known_data_property, configure_native_constructor, + apply_binding_table, bind_global_value, bind_well_known_data_property, configure_native_constructor, BindEnv, }; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; @@ -15,8 +12,8 @@ use oxide_types::value::JsValue; /// /// `realm_id` 是目标所属 realm 的编号:`@@toStringTag` 符号键按 (realm 编号, /// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_bigint(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { - let world = session.builtin_world(); +pub fn bind_bigint(env: BindEnv<'_>, global: &mut JsObject) { + let world = env.world(); let ctor_ptr = world.bigint_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; let proto_ptr = world.bigint_proto.as_ptr() as *mut JsObject; @@ -24,8 +21,8 @@ pub fn bind_bigint(core: &Arc, session: &KernelSession, global: &mut configure_native_constructor(ctor, oxide_builtins::bigint::bigint_constructor:: as *const (), 1); // BigInt.length = 1,属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。 - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(ctor.shape_id(), length_si); ctor.set_shape_id(length_shape); ctor.ensure_hash_props().push(JsValue::int(1)); let length_pos = ctor.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1); @@ -33,9 +30,8 @@ pub fn bind_bigint(core: &Arc, session: &KernelSession, global: &mut // 静态方法:asIntN / asUintN(length 均为 2)。 apply_binding_table( - world, + env, ctor, - core, &[ ("asIntN", oxide_builtins::bigint::bigint_as_int_n:: as *const (), 2), ("asUintN", oxide_builtins::bigint::bigint_as_uint_n:: as *const (), 2), @@ -43,9 +39,8 @@ pub fn bind_bigint(core: &Arc, session: &KernelSession, global: &mut ); apply_binding_table( - world, + env, proto, - core, &[ ("toString", oxide_builtins::bigint::bigint_to_string:: as *const (), 0), ( @@ -58,9 +53,9 @@ pub fn bind_bigint(core: &Arc, session: &KernelSession, global: &mut ); // BigInt.prototype[@@toStringTag] = "BigInt",属性 { writable:false, enumerable:false, configurable:true }。 - let tag_si = core.perm_interner().intern("BigInt").0; - 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), realm_id); + let tag_si = env.string_forge().intern("BigInt").0; + let tag_value = JsValue::perm_string(env.string_forge().string_ptr(tag_si)); + bind_well_known_data_property(env.core, proto, 9, tag_value, PropAttributes::new(false, false, true), env.realm_id); - bind_global_value(core, global, "BigInt", JsValue::from_js_object(ctor_ptr)); + bind_global_value(env.core, global, "BigInt", JsValue::from_js_object(ctor_ptr)); } diff --git a/crates/oxide_vm/src/bindings/bind_boolean.rs b/crates/oxide_vm/src/bindings/bind_boolean.rs index 82562d70..73c40615 100644 --- a/crates/oxide_vm/src/bindings/bind_boolean.rs +++ b/crates/oxide_vm/src/bindings/bind_boolean.rs @@ -1,23 +1,19 @@ -use std::sync::Arc; - use crate::bind_constructor; -use crate::bindings::{apply_binding_table, configure_native_constructor}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{apply_binding_table, configure_native_constructor, BindEnv}; use oxide_types::object::JsObject; /// 把 Boolean 构造器与原型方法绑定到 global。 -pub fn bind_boolean(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let ctor_ptr = session.builtin_world().boolean_constructor.as_ptr() as *mut JsObject; +pub fn bind_boolean(env: BindEnv<'_>, global: &mut JsObject) { + let ctor_ptr = env.world().boolean_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - let proto_ptr = session.builtin_world().boolean_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().boolean_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; configure_native_constructor(ctor, oxide_builtins::boolean::boolean_constructor:: as *const (), 1); apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ( "valueOf", @@ -33,5 +29,5 @@ pub fn bind_boolean(core: &Arc, session: &KernelSession, global: &mu ], ); - bind_constructor!(core, global, "Boolean", ctor_ptr, oxide_builtins::boolean::boolean_constructor::, 1, hash: true); + bind_constructor!(env, global, "Boolean", ctor_ptr, oxide_builtins::boolean::boolean_constructor::, 1, hash: true); } diff --git a/crates/oxide_vm/src/bindings/bind_broadcast_channel.rs b/crates/oxide_vm/src/bindings/bind_broadcast_channel.rs index 70d4cae3..d7545c0d 100644 --- a/crates/oxide_vm/src/bindings/bind_broadcast_channel.rs +++ b/crates/oxide_vm/src/bindings/bind_broadcast_channel.rs @@ -1,8 +1,7 @@ -use std::sync::Arc; - use crate::bind_constructor; -use crate::bindings::{apply_binding_table, bind_accessor_getset, bind_accessor_getter, configure_native_constructor}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{ + apply_binding_table, bind_accessor_getset, bind_accessor_getter, configure_native_constructor, BindEnv, +}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; @@ -20,15 +19,15 @@ use oxide_types::value::JsValue; /// /// `realm_id` 未使用(BroadcastChannel 无 well-known 符号键),保留签名与其他 /// 绑定函数一致。 -pub fn bind_broadcast_channel(core: &Arc, session: &KernelSession, global: &mut JsObject, _realm_id: u32) { - let world = session.builtin_world(); +pub fn bind_broadcast_channel(env: BindEnv<'_>, global: &mut JsObject) { + let world = env.world(); let ctor_ptr = world.broadcast_channel_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; let proto_ptr = world.broadcast_channel_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); + let sf = env.string_forge(); + let sh = env.shape_forge(); // ---- 填构造器占位 ---- ctor.set_function(true); @@ -65,7 +64,7 @@ pub fn bind_broadcast_channel(core: &Arc, session: &KernelSession, g 1, ); bind_constructor!( - core, + env, global, "BroadcastChannel", ctor_ptr, @@ -93,9 +92,8 @@ pub fn bind_broadcast_channel(core: &Arc, session: &KernelSession, g let si_post_message = sf.intern("postMessage").0; if sh.lookup_position(proto.shape_id(), si_post_message).is_none() { apply_binding_table( - world, + env, proto, - core, &[ ( "postMessage", @@ -115,8 +113,7 @@ pub fn bind_broadcast_channel(core: &Arc, session: &KernelSession, g let si_name_proto = sf.intern("name").0; if sh.lookup_position(proto.shape_id(), si_name_proto).is_none() { bind_accessor_getter( - core, - session, + env, proto, "name", oxide_builtins::broadcast_channel::broadcast_channel_name:: as *const (), @@ -127,8 +124,7 @@ pub fn bind_broadcast_channel(core: &Arc, session: &KernelSession, g let si_ready_state = sf.intern("readyState").0; if sh.lookup_position(proto.shape_id(), si_ready_state).is_none() { bind_accessor_getter( - core, - session, + env, proto, "readyState", oxide_builtins::broadcast_channel::broadcast_channel_ready_state:: as *const (), @@ -141,8 +137,7 @@ pub fn bind_broadcast_channel(core: &Arc, session: &KernelSession, g let key = sf.intern(name).0; if sh.lookup_position(proto.shape_id(), key).is_none() { bind_accessor_getset( - core, - session, + env, proto, key, &format!("get {name}"), diff --git a/crates/oxide_vm/src/bindings/bind_console.rs b/crates/oxide_vm/src/bindings/bind_console.rs index 57f032ef..5eecb7a7 100644 --- a/crates/oxide_vm/src/bindings/bind_console.rs +++ b/crates/oxide_vm/src/bindings/bind_console.rs @@ -1,18 +1,15 @@ -use std::sync::Arc; - -use crate::bindings::bind_global_value; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{bind_global_value, BindEnv}; use oxide_types::object::JsObject; use oxide_types::value::JsValue; /// 把 Console 单例对象及其方法(log/warn/error/info/debug/trace)绑定到 global。 -pub fn bind_console(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let console_ptr = session.builtin_world().console_object.as_ptr() as *mut JsObject; +pub fn bind_console(env: BindEnv<'_>, global: &mut JsObject) { + let console_ptr = env.world().console_object.as_ptr() as *mut JsObject; let console = unsafe { &mut *console_ptr }; - let bw = session.builtin_world(); - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); + let bw = env.world(); + let sf = env.string_forge(); + let sh = env.shape_forge(); oxide_kernel::bind_methods!( bw, @@ -28,9 +25,9 @@ pub fn bind_console(core: &Arc, session: &KernelSession, global: &mu ); bind_global_value( - core, + env.core, global, "console", - JsValue::from_js_object(session.builtin_world().console_object.as_ptr() as *mut JsObject), + JsValue::from_js_object(env.world().console_object.as_ptr() as *mut JsObject), ); } diff --git a/crates/oxide_vm/src/bindings/bind_data_view.rs b/crates/oxide_vm/src/bindings/bind_data_view.rs index dad33d5d..0c8a772f 100644 --- a/crates/oxide_vm/src/bindings/bind_data_view.rs +++ b/crates/oxide_vm/src/bindings/bind_data_view.rs @@ -1,15 +1,12 @@ -use std::sync::Arc; - use crate::bind_constructor; -use crate::bindings::{apply_binding_table, bind_accessor_getter, configure_native_constructor}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{apply_binding_table, bind_accessor_getter, configure_native_constructor, BindEnv}; use oxide_types::object::{JsObject, PropAttributes}; /// 把 DataView 构造器与原型方法绑定到 global。 -pub fn bind_data_view(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let ctor_ptr = session.builtin_world().data_view_constructor.as_ptr() as *mut JsObject; +pub fn bind_data_view(env: BindEnv<'_>, global: &mut JsObject) { + let ctor_ptr = env.world().data_view_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - let proto_ptr = session.builtin_world().data_view_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().data_view_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; configure_native_constructor( @@ -19,9 +16,8 @@ pub fn bind_data_view(core: &Arc, session: &KernelSession, global: & ); apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ("getInt8", oxide_builtins::data_view::data_view_get_int8:: as *const (), 1), ( @@ -133,34 +129,31 @@ pub fn bind_data_view(core: &Arc, session: &KernelSession, global: & ], ); - bind_constructor!(core, global, "DataView", ctor_ptr, oxide_builtins::data_view::data_view_constructor::, 1, hash: true); + bind_constructor!(env, global, "DataView", ctor_ptr, oxide_builtins::data_view::data_view_constructor::, 1, hash: true); // length 属性描述符补 { writable:false, enumerable:false, configurable:true } // (bind_constructor! 宏的通用缺省 meta 不可写回,此处理仅覆盖 DataView)。 { - let length_si = core.perm_interner().intern("length").0; - if let Some(pos) = core.shape_forge().lookup_position(ctor.shape_id(), length_si) { + let length_si = env.string_forge().intern("length").0; + if let Some(pos) = env.shape_forge().lookup_position(ctor.shape_id(), length_si) { ctor.set_data_meta(pos, PropAttributes::new(false, false, true)); } } // buffer/byteOffset/byteLength 只读访问器(set 恒 undefined,getter 读视图状态盒)。 bind_accessor_getter( - core, - session, + env, proto, "buffer", oxide_builtins::data_view::data_view_buffer_getter:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "byteOffset", oxide_builtins::data_view::data_view_byte_offset_getter:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "byteLength", oxide_builtins::data_view::data_view_byte_length_getter:: as *const (), diff --git a/crates/oxide_vm/src/bindings/bind_date.rs b/crates/oxide_vm/src/bindings/bind_date.rs index ebc65801..606d638e 100644 --- a/crates/oxide_vm/src/bindings/bind_date.rs +++ b/crates/oxide_vm/src/bindings/bind_date.rs @@ -1,30 +1,26 @@ -use std::sync::Arc; - -use crate::bindings::{apply_binding_table, bind_global_value, configure_native_constructor}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{apply_binding_table, bind_global_value, configure_native_constructor, BindEnv}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; /// 把 Date 构造器与原型方法绑定到 global。 -pub fn bind_date(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let ctor_ptr = session.builtin_world().date_constructor.as_ptr() as *mut JsObject; +pub fn bind_date(env: BindEnv<'_>, global: &mut JsObject) { + let ctor_ptr = env.world().date_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - let proto_ptr = session.builtin_world().date_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().date_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; configure_native_constructor(ctor, oxide_builtins::date::date_constructor:: as *const (), 7); // Date.length = 7,描述符 { writable:false, enumerable:false, configurable:true }。 - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(ctor.shape_id(), length_si); ctor.set_shape_id(length_shape); ctor.ensure_hash_props().push(JsValue::int(7)); let length_pos = ctor.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1); ctor.set_data_meta(length_pos, PropAttributes::new(false, false, true)); apply_binding_table( - session.builtin_world(), + env, ctor, - core, &[ ("now", oxide_builtins::date::date_now:: as *const (), 0), ("parse", oxide_builtins::date::date_parse:: as *const (), 1), @@ -33,9 +29,8 @@ pub fn bind_date(core: &Arc, session: &KernelSession, global: &mut J ); apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ("getTime", oxide_builtins::date::date_get_time:: as *const (), 0), ("getFullYear", oxide_builtins::date::date_get_full_year:: as *const (), 0), @@ -143,5 +138,5 @@ pub fn bind_date(core: &Arc, session: &KernelSession, global: &mut J ], ); - bind_global_value(core, global, "Date", JsValue::from_js_object(ctor_ptr)); + bind_global_value(env.core, global, "Date", JsValue::from_js_object(ctor_ptr)); } diff --git a/crates/oxide_vm/src/bindings/bind_disposable_stack.rs b/crates/oxide_vm/src/bindings/bind_disposable_stack.rs index 8a6b45b5..439ad833 100644 --- a/crates/oxide_vm/src/bindings/bind_disposable_stack.rs +++ b/crates/oxide_vm/src/bindings/bind_disposable_stack.rs @@ -1,13 +1,10 @@ -use std::sync::Arc; - -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes}; use oxide_types::value::JsValue; use crate::bindings::{ apply_binding_table, bind_accessor_getter, bind_global_value, bind_well_known_data_property, - bind_well_known_method_alias, configure_native_constructor, + bind_well_known_method_alias, configure_native_constructor, BindEnv, }; /// 在 `DisposableStack.prototype` 上安装方法/别名/访问器/@@toStringTag。 @@ -18,19 +15,18 @@ use crate::bindings::{ /// /// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_disposable_stack_protos(core: &Arc, session: &KernelSession, realm_id: u32) { - let world = session.builtin_world(); +pub fn bind_disposable_stack_protos(env: BindEnv<'_>) { + let world = env.world(); let proto_ptr = world.disposable_stack_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - let si_use = core.perm_interner().intern("use").0; - if core.shape_forge().lookup_position(proto.shape_id(), si_use).is_some() { + let si_use = env.string_forge().intern("use").0; + if env.shape_forge().lookup_position(proto.shape_id(), si_use).is_some() { return; } apply_binding_table( - world, + env, proto, - core, &[ ( "use", @@ -60,23 +56,22 @@ pub fn bind_disposable_stack_protos(core: &Arc, session: &KernelSess ], ); bind_accessor_getter( - core, - session, + env, proto, "disposed", oxide_builtins::disposable_stack::disposable_stack_disposed_getter:: as *const (), ); // @@dispose 与 dispose 为同一函数对象(先绑 dispose 再取源槽)。 - bind_well_known_method_alias(core, proto, "dispose", 12, realm_id); - let sf = core.perm_interner().as_ref(); + bind_well_known_method_alias(env.core, proto, "dispose", 12, env.realm_id); + let sf = env.string_forge(); 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), realm_id); + bind_well_known_data_property(env.core, proto, 9, tag, PropAttributes::new(false, false, true), env.realm_id); } /// 在 proto 上写 `constructor` 数据属性(非枚举,描述符 {t,f,t})。 -pub(crate) fn write_proto_constructor(core: &Arc, proto: &mut JsObject, ctor_val: JsValue) { - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); +pub(crate) fn write_proto_constructor(env: BindEnv<'_>, proto: &mut JsObject, ctor_val: JsValue) { + let sf = env.string_forge(); + let sh = env.shape_forge(); let si_constructor = sf.intern("constructor").0; if sh.lookup_position(proto.shape_id(), si_constructor).is_some() { return; @@ -96,12 +91,12 @@ pub(crate) fn write_proto_constructor(core: &Arc, proto: &mut JsObje /// /// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_disposable_stack(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { - let world = session.builtin_world(); +pub fn bind_disposable_stack(env: BindEnv<'_>, global: &mut JsObject) { + let world = env.world(); let proto_ptr = world.disposable_stack_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - let si_constructor = core.perm_interner().intern("constructor").0; - let ctor_val = match core.shape_forge().lookup_position(proto.shape_id(), si_constructor) { + let si_constructor = env.string_forge().intern("constructor").0; + let ctor_val = match env.shape_forge().lookup_position(proto.shape_id(), si_constructor) { Some(pos) => { let existing = proto.get_prop_at(pos); if existing.is_object() { @@ -115,8 +110,8 @@ pub fn bind_disposable_stack(core: &Arc, session: &KernelSession, gl let ctor_val = if ctor_val.is_object() { ctor_val } else { - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); + let sf = env.string_forge(); + let sh = env.shape_forge(); let name_si = sf.intern("DisposableStack").0; // 选择性重建复用:非 P 目标(家族 0)按键查找前轮旧构造器迁移,避免每轮 // 新建导致登记表无界累积;槽键取 global 槽名,该命名空间内全局唯一。 @@ -167,9 +162,9 @@ pub fn bind_disposable_stack(core: &Arc, session: &KernelSession, gl JsValue::from_js_object(ctor_ptr) }; - write_proto_constructor(core, proto, ctor_val); - bind_disposable_stack_protos(core, session, realm_id); - bind_global_value(core, global, "DisposableStack", ctor_val); + write_proto_constructor(env, proto, ctor_val); + bind_disposable_stack_protos(env); + bind_global_value(env.core, global, "DisposableStack", ctor_val); } /// 对齐保留 global 上 `DisposableStack` 函数对象的 `prototype` 属性:object 家族 @@ -178,9 +173,9 @@ pub fn bind_disposable_stack(core: &Arc, session: &KernelSession, gl /// /// global 同时重建(global dirty)或初始化时无 `DisposableStack` 属性,直接跳过 /// ——彼时由 `bind_disposable_stack` 以新原型创建函数对象。 -pub fn sync_disposable_stack_ctor(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let si_stack = core.perm_interner().intern("DisposableStack").0; - let Some(pos) = core.shape_forge().lookup_position(global.shape_id(), si_stack) else { +pub fn sync_disposable_stack_ctor(env: BindEnv<'_>, global: &mut JsObject) { + let si_stack = env.string_forge().intern("DisposableStack").0; + let Some(pos) = env.shape_forge().lookup_position(global.shape_id(), si_stack) else { return; }; let stack_val = global.get_prop_at(pos); @@ -188,13 +183,13 @@ pub fn sync_disposable_stack_ctor(core: &Arc, session: &KernelSessio return; } let ctor = unsafe { &mut *stack_val.as_js_object_ptr() }; - let si_prototype = core.perm_interner().intern("prototype").0; - let Some(proto_pos) = core.shape_forge().lookup_position(ctor.shape_id(), si_prototype) else { + let si_prototype = env.string_forge().intern("prototype").0; + let Some(proto_pos) = env.shape_forge().lookup_position(ctor.shape_id(), si_prototype) else { return; }; - let new_proto = JsValue::from_js_object(session.builtin_world().disposable_stack_proto.as_ptr() as *mut JsObject); + let new_proto = JsValue::from_js_object(env.world().disposable_stack_proto.as_ptr() as *mut JsObject); ctor.set_prop_at(proto_pos, new_proto); - let proto_ptr = session.builtin_world().disposable_stack_proto.as_ptr() as *mut JsObject; - write_proto_constructor(core, unsafe { &mut *proto_ptr }, stack_val); + let proto_ptr = env.world().disposable_stack_proto.as_ptr() as *mut JsObject; + write_proto_constructor(env, unsafe { &mut *proto_ptr }, stack_val); } diff --git a/crates/oxide_vm/src/bindings/bind_error.rs b/crates/oxide_vm/src/bindings/bind_error.rs index 6210c2f0..6b73cdda 100644 --- a/crates/oxide_vm/src/bindings/bind_error.rs +++ b/crates/oxide_vm/src/bindings/bind_error.rs @@ -1,18 +1,17 @@ -use std::sync::Arc; - use oxide_kernel::builtin::ErrorMethods; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes}; use oxide_types::value::JsValue; +use super::BindEnv; + fn bind_error_subtype_constructor( - core: &Arc, session: &KernelSession, global: &mut JsObject, name: &str, proto_ptr: *mut JsObject, + env: BindEnv<'_>, global: &mut JsObject, name: &str, proto_ptr: *mut JsObject, ctor_fn: *const (), arg_count: u8, ) { - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); - let world = session.builtin_world(); + let sf = env.string_forge(); + let sh = env.shape_forge(); + let world = env.world(); let name_si = sf.intern(name).0; // SAFETY: ctor_fn 是调用方转成 *const () 的 NativeFn 函数项指针。 let ctor_fn_ptr = unsafe { NativeFnPtr::from_raw(ctor_fn) }; @@ -95,7 +94,7 @@ fn bind_error_subtype_constructor( } /// 把 Error 及各子类型(TypeError/ReferenceError/...)构造器与原型方法绑定到 global。 -pub fn bind_error(core: &Arc, session: &KernelSession, global: &mut JsObject) { +pub fn bind_error(env: BindEnv<'_>, global: &mut JsObject) { let error_methods = ErrorMethods { error: oxide_builtins::error::error_constructor:: as *const (), type_error: oxide_builtins::error::type_error_constructor:: as *const (), @@ -109,23 +108,22 @@ pub fn bind_error(core: &Arc, session: &KernelSession, global: &mut is_error: oxide_builtins::error::error_is_error:: as *const (), to_json: oxide_builtins::error::error_to_json:: as *const (), }; - session.builtin_world().bind_error_methods( + env.world().bind_error_methods( &error_methods, - core.perm_interner().as_ref(), - core.shape_forge().as_ref(), + env.string_forge(), + env.shape_forge(), ); // stack 为访问器成对安装(getter 现算栈串 / setter 走 // SetterThatIgnoresPrototypeProperties),经 getset 绑定器登记复用键, // 选择性重建时同槽迁移旧 wrapper。 { - let proto_ptr = session.builtin_world().error_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().error_proto.as_ptr() as *mut JsObject; // SAFETY: error_proto 由 session 持有,存活整个 session;本块内只改其 shape/属性区,无 reset。 let proto = unsafe { &mut *proto_ptr }; - let si_stack = core.perm_interner().intern("stack").0; + let si_stack = env.string_forge().intern("stack").0; super::bind_accessor_getset( - core, - session, + env, proto, si_stack, "get stack", @@ -138,25 +136,24 @@ pub fn bind_error(core: &Arc, session: &KernelSession, global: &mut // toSource 遗留扩展(Error 原型方法不走 kernel 侧 bind_error_methods, // 此处独立经 apply_binding_table 安装,描述符非枚举由绑定器内置)。 { - let proto_ptr = session.builtin_world().error_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().error_proto.as_ptr() as *mut JsObject; // SAFETY: error_proto 由 session 持有,存活整个 session;本块内只改其 shape/属性区,无 reset。 let proto = unsafe { &mut *proto_ptr }; super::apply_binding_table( - session.builtin_world(), + env, proto, - core, &[("toSource", oxide_builtins::to_source::to_source_error:: as *const (), 0)], ); } // 全局 Error 槽位既有槽原位更新(旧家族构造器指针不得滞留在属性 vec), // 无槽时开新槽;描述符非枚举(规范 { writable:true, enumerable:false, configurable:true })。 - let si_err = core.perm_interner().intern("Error").0; - let err_val = JsValue::from_js_object(session.builtin_world().error_constructor.as_ptr() as *mut JsObject); - if let Some(pos) = core.shape_forge().lookup_position(global.shape_id(), si_err) { + let si_err = env.string_forge().intern("Error").0; + let err_val = JsValue::from_js_object(env.world().error_constructor.as_ptr() as *mut JsObject); + if let Some(pos) = env.shape_forge().lookup_position(global.shape_id(), si_err) { global.set_prop_at(pos, err_val); } else { - let err_shape = core.shape_forge().make_shape(global.shape_id(), si_err); + let err_shape = env.shape_forge().make_shape(global.shape_id(), si_err); global.set_shape_id(err_shape); global.ensure_hash_props().push(err_val); let err_pos = global.prop_vec_len().saturating_sub(1) as u32; @@ -165,73 +162,66 @@ pub fn bind_error(core: &Arc, session: &KernelSession, global: &mut } bind_error_subtype_constructor( - core, - session, + env, global, "TypeError", - session.builtin_world().type_error_proto.as_ptr() as *mut JsObject, + env.world().type_error_proto.as_ptr() as *mut JsObject, oxide_builtins::error::type_error_constructor:: as *const (), 1, ); bind_error_subtype_constructor( - core, - session, + env, global, "ReferenceError", - session.builtin_world().reference_error_proto.as_ptr() as *mut JsObject, + env.world().reference_error_proto.as_ptr() as *mut JsObject, oxide_builtins::error::reference_error_constructor:: as *const (), 1, ); bind_error_subtype_constructor( - core, - session, + env, global, "RangeError", - session.builtin_world().range_error_proto.as_ptr() as *mut JsObject, + env.world().range_error_proto.as_ptr() as *mut JsObject, oxide_builtins::error::range_error_constructor:: as *const (), 1, ); bind_error_subtype_constructor( - core, - session, + env, global, "SyntaxError", - session.builtin_world().syntax_error_proto.as_ptr() as *mut JsObject, + env.world().syntax_error_proto.as_ptr() as *mut JsObject, oxide_builtins::error::syntax_error_constructor:: as *const (), 1, ); bind_error_subtype_constructor( - core, - session, + env, global, "URIError", - session.builtin_world().uri_error_proto.as_ptr() as *mut JsObject, + env.world().uri_error_proto.as_ptr() as *mut JsObject, oxide_builtins::error::uri_error_constructor:: as *const (), 1, ); bind_error_subtype_constructor( - core, - session, + env, global, "EvalError", - session.builtin_world().eval_error_proto.as_ptr() as *mut JsObject, + env.world().eval_error_proto.as_ptr() as *mut JsObject, oxide_builtins::error::eval_error_constructor:: as *const (), 1, ); // SuppressedError 为三参构造器(error, suppressed, message),length=3。 bind_error_subtype_constructor( - core, - session, + env, global, "SuppressedError", - session.builtin_world().suppressed_error_proto.as_ptr() as *mut JsObject, + env.world().suppressed_error_proto.as_ptr() as *mut JsObject, oxide_builtins::error::suppressed_error_constructor:: as *const (), 3, ); { - let err_ctor_ptr = session.builtin_world().error_constructor.as_ptr() as *mut JsObject; + let err_ctor_ptr = env.world().error_constructor.as_ptr() as *mut JsObject; let err_ctor = unsafe { &mut *err_ctor_ptr }; err_ctor.type_tag = JsObject::OBJ_TYPE_CONSTRUCTOR; // SAFETY: error_constructor 是 NativeFn 函数项。 @@ -239,8 +229,8 @@ pub fn bind_error(core: &Arc, session: &KernelSession, global: &mut NativeFnPtr::from_raw(oxide_builtins::error::error_constructor:: as *const ()) })); // 主 Error 构造器补 length 槽(值 1,与子类型构造器一致)。 - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); + let sf = env.string_forge(); + let sh = env.shape_forge(); let si_length = sf.intern("length").0; let length_shape = sh.make_shape(err_ctor.shape_id(), si_length); err_ctor.set_shape_id(length_shape); diff --git a/crates/oxide_vm/src/bindings/bind_event.rs b/crates/oxide_vm/src/bindings/bind_event.rs index 683dd9c6..7dba2a51 100644 --- a/crates/oxide_vm/src/bindings/bind_event.rs +++ b/crates/oxide_vm/src/bindings/bind_event.rs @@ -7,11 +7,8 @@ //! `custom_event_constructor` / `custom_event_proto` 两枚 P 字段占位(构造器 //! 本体与原型 getter),并绑全局 `CustomEvent`。 -use std::sync::Arc; - use crate::bind_constructor; -use crate::bindings::{apply_binding_table, bind_accessor_getter, configure_native_constructor}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{apply_binding_table, bind_accessor_getter, configure_native_constructor, BindEnv}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; @@ -31,15 +28,15 @@ use oxide_types::value::JsValue; /// `bind_constructor!` 的全局槽臂自带既有槽原位更新,天然幂等。 /// /// `realm_id` 未使用(Event 无 well-known 符号键),保留签名与其他绑定函数一致。 -pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut JsObject, _realm_id: u32) { - let world = session.builtin_world(); +pub fn bind_event(env: BindEnv<'_>, global: &mut JsObject) { + let world = env.world(); let ctor_ptr = world.event_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; let proto_ptr = world.event_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); + let sf = env.string_forge(); + let sh = env.shape_forge(); // ---- 填构造器占位 ---- ctor.set_function(true); @@ -72,7 +69,7 @@ pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut configure_native_constructor(ctor, oxide_builtins::event::event_constructor:: as *const (), 2); bind_constructor!( - core, + env, global, "Event", ctor_ptr, @@ -115,9 +112,8 @@ pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut let si_prevent_default = sf.intern("preventDefault").0; if sh.lookup_position(proto.shape_id(), si_prevent_default).is_none() { apply_binding_table( - world, + env, proto, - core, &[ ( "preventDefault", @@ -166,7 +162,7 @@ pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut for (name, fn_ptr) in getter_fns { let si = sf.intern(name).0; if sh.lookup_position(proto.shape_id(), si).is_none() { - bind_accessor_getter(core, session, proto, name, fn_ptr); + bind_accessor_getter(env, proto, name, fn_ptr); } } @@ -204,7 +200,7 @@ pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut 2, ); bind_constructor!( - core, + env, global, "MessageEvent", me_ctor_ptr, @@ -239,7 +235,7 @@ pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut for (name, fn_ptr) in me_getter_fns { let si = sf.intern(name).0; if sh.lookup_position(me_proto.shape_id(), si).is_none() { - bind_accessor_getter(core, session, me_proto, name, fn_ptr); + bind_accessor_getter(env, me_proto, name, fn_ptr); } } @@ -277,7 +273,7 @@ pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut 2, ); bind_constructor!( - core, + env, global, "ErrorEvent", ee_ctor_ptr, @@ -311,7 +307,7 @@ pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut for (name, fn_ptr) in ee_getter_fns { let si = sf.intern(name).0; if sh.lookup_position(ee_proto.shape_id(), si).is_none() { - bind_accessor_getter(core, session, ee_proto, name, fn_ptr); + bind_accessor_getter(env, ee_proto, name, fn_ptr); } } @@ -349,7 +345,7 @@ pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut 2, ); bind_constructor!( - core, + env, global, "CustomEvent", ce_ctor_ptr, @@ -374,7 +370,7 @@ pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut for (name, fn_ptr) in ce_getter_fns { let si = sf.intern(name).0; if sh.lookup_position(ce_proto.shape_id(), si).is_none() { - bind_accessor_getter(core, session, ce_proto, name, fn_ptr); + bind_accessor_getter(env, ce_proto, name, fn_ptr); } } @@ -390,9 +386,8 @@ pub fn bind_event(core: &Arc, session: &KernelSession, global: &mut let si_add = sf.intern("addEventListener").0; if sh.lookup_position(et_proto.shape_id(), si_add).is_none() { apply_binding_table( - world, + env, et_proto, - core, &[ ( "addEventListener", diff --git a/crates/oxide_vm/src/bindings/bind_function.rs b/crates/oxide_vm/src/bindings/bind_function.rs index 27c3bd50..af8602bd 100644 --- a/crates/oxide_vm/src/bindings/bind_function.rs +++ b/crates/oxide_vm/src/bindings/bind_function.rs @@ -1,7 +1,4 @@ -use std::sync::Arc; - use oxide_kernel::builtin::{FnWrapperKey, FunctionMethods}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes}; use oxide_types::value::JsValue; @@ -9,12 +6,13 @@ use oxide_types::value::JsValue; use super::apply_binding_table; use super::bind_global_value; use super::configure_native_constructor; +use super::BindEnv; /// 把 Function 构造器与原型方法绑定到 global。 /// /// `realm_id` 是目标所属 realm 的编号:`@@hasInstance` 符号键按 (realm 编号, /// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_function(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { +pub fn bind_function(env: BindEnv<'_>, global: &mut JsObject) { let function_methods = FunctionMethods { call: oxide_builtins::function::function_call:: as *const (), apply: oxide_builtins::function::function_apply:: as *const (), @@ -22,14 +20,14 @@ pub fn bind_function(core: &Arc, session: &KernelSession, global: &m to_string: oxide_builtins::function::function_to_string:: as *const (), has_instance: oxide_builtins::function::function_symbol_has_instance:: as *const (), }; - session.builtin_world().bind_function_methods( + env.world().bind_function_methods( &function_methods, - core.perm_interner().as_ref(), - core.shape_forge().as_ref(), - realm_id, + env.string_forge(), + env.shape_forge(), + env.realm_id, ); - let function_ctor = session.builtin_world().function_constructor.as_ptr() as *mut JsObject; + let function_ctor = env.world().function_constructor.as_ptr() as *mut JsObject; configure_native_constructor( unsafe { &mut *function_ctor }, oxide_builtins::function::function_constructor:: as *const (), @@ -37,8 +35,8 @@ pub fn bind_function(core: &Arc, session: &KernelSession, global: &m ); // 设置 Function.length = 1(configure_native_constructor 不写 length 属性), // 属性为不可写不可枚举可配置。 - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(unsafe { &*function_ctor }.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(unsafe { &*function_ctor }.shape_id(), length_si); let ctor = unsafe { &mut *function_ctor }; ctor.set_shape_id(length_shape); ctor.ensure_hash_props().push(JsValue::int(1)); @@ -47,36 +45,35 @@ pub fn bind_function(core: &Arc, session: &KernelSession, global: &m // Function.prototype 自身属性:length = 0、name = ""(不可写不可枚举可配置), // 自身属性名序 length 在 name 之前。 - let proto_ptr = session.builtin_world().function_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().function_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - let proto_length_shape = core.shape_forge().make_shape(proto.shape_id(), length_si); + let proto_length_shape = env.shape_forge().make_shape(proto.shape_id(), length_si); proto.set_shape_id(proto_length_shape); proto.ensure_hash_props().push(JsValue::int(0)); let proto_length_pos = proto.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1); proto.set_data_meta(proto_length_pos, PropAttributes::new(false, false, true)); - let name_si = core.perm_interner().intern("name").0; - let name_shape = core.shape_forge().make_shape(proto.shape_id(), name_si); + let name_si = env.string_forge().intern("name").0; + let name_shape = env.shape_forge().make_shape(proto.shape_id(), name_si); proto.set_shape_id(name_shape); proto .ensure_hash_props() - .push(JsValue::perm_string(core.perm_interner().string_ptr(core.perm_interner().intern("").0))); + .push(JsValue::perm_string(env.string_forge().string_ptr(env.string_forge().intern("").0))); let name_pos = proto.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1); proto.set_data_meta(name_pos, PropAttributes::new(false, false, true)); // caller/arguments 受限访问器:两属性 get/set 共用同一 %ThrowTypeError% // 函数对象,任何访问抛 TypeError(AddRestrictedFunctionProperties 语义)。 - bind_function_proto_restricted(core, session, proto); + bind_function_proto_restricted(env, proto); // toSource 遗留扩展(Function 原型方法不走 kernel 侧 bind_function_methods, // 此处独立经 apply_binding_table 安装,描述符非枚举由绑定器内置)。 apply_binding_table( - session.builtin_world(), + env, proto, - core, &[("toSource", oxide_builtins::to_source::to_source_function:: as *const (), 0)], ); - bind_global_value(core, global, "Function", JsValue::from_js_object(function_ctor)); + bind_global_value(env.core, global, "Function", JsValue::from_js_object(function_ctor)); } /// 在 Function.prototype 上绑定 caller/arguments 受限访问器:两属性的 @@ -92,10 +89,10 @@ pub fn bind_function(core: &Arc, session: &KernelSession, global: &m /// # 副作用 /// - 为 caller/arguments 各开 shape 槽位并写入访问器 meta;thrower 函数对象 /// 登记进 world 释放表(与 `bind_accessor_getter` 的 getter 同一生命周期)。 -fn bind_function_proto_restricted(core: &Arc, session: &KernelSession, proto: &mut JsObject) { - let shape_forge = core.shape_forge().as_ref(); - let string_forge = core.perm_interner().as_ref(); - let world = session.builtin_world(); +fn bind_function_proto_restricted(env: BindEnv<'_>, proto: &mut JsObject) { + let shape_forge = env.shape_forge(); + let string_forge = env.string_forge(); + let world = env.world(); let family = world.wrapper_family_of(proto as *const JsObject); let si_name = string_forge.intern("name").0; let si_length = string_forge.intern("length").0; diff --git a/crates/oxide_vm/src/bindings/bind_global.rs b/crates/oxide_vm/src/bindings/bind_global.rs index db4708f6..9092a279 100644 --- a/crates/oxide_vm/src/bindings/bind_global.rs +++ b/crates/oxide_vm/src/bindings/bind_global.rs @@ -1,16 +1,12 @@ -use std::sync::Arc; - -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::JsObject; -use crate::bindings::apply_binding_table; +use crate::bindings::{apply_binding_table, BindEnv}; /// 把普通全局函数(`isNaN`、`parseInt`、`decodeURIComponent` 等)绑定到 global。 -pub fn bind_global(core: &Arc, session: &KernelSession, global: &mut JsObject) { +pub fn bind_global(env: BindEnv<'_>, global: &mut JsObject) { apply_binding_table( - session.builtin_world(), + env, global, - core, &[ ("escape", oxide_builtins::global::js_escape:: as *const (), 1), ("unescape", oxide_builtins::global::js_unescape:: as *const (), 1), diff --git a/crates/oxide_vm/src/bindings/bind_iterator.rs b/crates/oxide_vm/src/bindings/bind_iterator.rs index 0447a599..724b2bca 100644 --- a/crates/oxide_vm/src/bindings/bind_iterator.rs +++ b/crates/oxide_vm/src/bindings/bind_iterator.rs @@ -1,13 +1,10 @@ -use std::sync::Arc; - -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_types::object::JsObject; use oxide_types::value::JsValue; use crate::bindings::{ apply_binding_table, bind_global_value, bind_iterator_ctor_identity, bind_iterator_function_prototype, - configure_native_constructor, + configure_native_constructor, BindEnv, }; /// 绑定 `Iterator` 全局构造器(`prototype` = %IteratorPrototype%、`from` 方法)。 @@ -15,8 +12,8 @@ use crate::bindings::{ /// 迭代器原型方法(%IteratorPrototype% 的 `@@iterator` 与各集合原型 `next`)由 /// `rebind_dirty_builtins` 的 object 分支统一安装,本入口不重复绑定,避免 /// 保留原型经 dirty reset 时属性槽膨胀。 -pub fn bind_iterator(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let function_proto = session.builtin_world().function_proto.as_ptr() as *mut JsObject; +pub fn bind_iterator(env: BindEnv<'_>, global: &mut JsObject) { + let function_proto = env.world().function_proto.as_ptr() as *mut JsObject; let mut iterator = Box::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(function_proto))); iterator.set_function(true); configure_native_constructor( @@ -24,18 +21,17 @@ pub fn bind_iterator(core: &Arc, session: &KernelSession, global: &m oxide_builtins::iterator::iterator_constructor:: as *const (), 0, ); - bind_iterator_ctor_identity(core, &mut iterator); - bind_iterator_function_prototype(core, session, &mut iterator); + bind_iterator_ctor_identity(env.core, &mut iterator); + bind_iterator_function_prototype(env, &mut iterator); apply_binding_table( - session.builtin_world(), + env, &mut iterator, - core, &[("from", oxide_builtins::iterator::iterator_from:: as *const (), 1)], ); let iterator_ptr = Box::into_raw(iterator); // 登记进 world 释放表:session 收尾统一释放构造器本体与属性区。 - session.builtin_world().track_leaked_object(iterator_ptr); - bind_global_value(core, global, "Iterator", JsValue::from_js_object(iterator_ptr)); + env.world().track_leaked_object(iterator_ptr); + bind_global_value(env.core, global, "Iterator", JsValue::from_js_object(iterator_ptr)); } diff --git a/crates/oxide_vm/src/bindings/bind_json.rs b/crates/oxide_vm/src/bindings/bind_json.rs index 879e0d89..243ea96f 100644 --- a/crates/oxide_vm/src/bindings/bind_json.rs +++ b/crates/oxide_vm/src/bindings/bind_json.rs @@ -1,19 +1,15 @@ -use std::sync::Arc; - -use crate::bindings::{apply_binding_table, bind_global_value}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{apply_binding_table, bind_global_value, BindEnv}; use oxide_types::object::JsObject; use oxide_types::value::JsValue; /// 把 JSON 单例对象及其方法(parse/stringify 等)绑定到 global。 -pub fn bind_json(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let json_ptr = session.builtin_world().json_object.as_ptr() as *mut JsObject; +pub fn bind_json(env: BindEnv<'_>, global: &mut JsObject) { + let json_ptr = env.world().json_object.as_ptr() as *mut JsObject; let json = unsafe { &mut *json_ptr }; apply_binding_table( - session.builtin_world(), + env, json, - core, &[ ("parse", oxide_builtins::json::json_parse:: as *const (), 2), ("stringify", oxide_builtins::json::json_stringify:: as *const (), 3), @@ -23,9 +19,9 @@ pub fn bind_json(core: &Arc, session: &KernelSession, global: &mut J ); bind_global_value( - core, + env.core, global, "JSON", - JsValue::from_js_object(session.builtin_world().json_object.as_ptr() as *mut JsObject), + JsValue::from_js_object(env.world().json_object.as_ptr() as *mut JsObject), ); } diff --git a/crates/oxide_vm/src/bindings/bind_map.rs b/crates/oxide_vm/src/bindings/bind_map.rs index f5226362..ccb26840 100644 --- a/crates/oxide_vm/src/bindings/bind_map.rs +++ b/crates/oxide_vm/src/bindings/bind_map.rs @@ -1,30 +1,26 @@ -use std::sync::Arc; - use crate::bind_constructor; use crate::bindings::{ apply_binding_table, bind_accessor_getter, bind_accessor_getter_key, bind_well_known_method_alias, - configure_native_constructor, + configure_native_constructor, BindEnv, }; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::JsObject; /// 把 Map 构造器与原型方法绑定到 global。 /// /// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_map(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { - let ctor_ptr = session.builtin_world().map_constructor.as_ptr() as *mut JsObject; +pub fn bind_map(env: BindEnv<'_>, global: &mut JsObject) { + let ctor_ptr = env.world().map_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - let proto_ptr = session.builtin_world().map_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().map_proto.as_ptr() as *mut JsObject; configure_native_constructor(ctor, oxide_builtins::map::map_constructor:: as *const (), 1); let proto = unsafe { &mut *proto_ptr }; // size 是访问器 getter,不进 apply_binding_table。 apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ("set", oxide_builtins::map::map_set:: as *const (), 2), ("get", oxide_builtins::map::map_get:: as *const (), 1), @@ -45,27 +41,25 @@ pub fn bind_map(core: &Arc, session: &KernelSession, global: &mut Js ); // Map 的 @@iterator(Symbol.iterator)是 entries 的同一函数对象。 - bind_well_known_method_alias(core, proto, "entries", 0, realm_id); - bind_accessor_getter(core, session, proto, "size", oxide_builtins::map::map_size:: as *const ()); + bind_well_known_method_alias(env.core, proto, "entries", 0, env.realm_id); + bind_accessor_getter(env, proto, "size", oxide_builtins::map::map_size:: as *const ()); // Map[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链解析 // @@species 得自身构造器(规范不给 class 默认 static @@species,类上无 own)。 bind_accessor_getter_key( - core, - session, + env, ctor, - oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), + oxide_types::private_key::encode_symbol_key(env.realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), "get [Symbol.species]", oxide_builtins::array::array_species_get:: as *const (), ); // Map.groupBy 静态方法。 apply_binding_table( - session.builtin_world(), + env, ctor, - core, &[("groupBy", oxide_builtins::map::map_group_by:: as *const (), 2)], ); - bind_constructor!(core, global, "Map", ctor_ptr, oxide_builtins::map::map_constructor::, 0, hash: true); + bind_constructor!(env, global, "Map", ctor_ptr, oxide_builtins::map::map_constructor::, 0, hash: true); } diff --git a/crates/oxide_vm/src/bindings/bind_math.rs b/crates/oxide_vm/src/bindings/bind_math.rs index a2a70644..4011ae83 100644 --- a/crates/oxide_vm/src/bindings/bind_math.rs +++ b/crates/oxide_vm/src/bindings/bind_math.rs @@ -1,18 +1,17 @@ -use std::sync::Arc; - use oxide_kernel::bind_methods; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; +use crate::bindings::BindEnv; + /// 把 Math 单例对象及其方法(abs/floor/max/random 等)绑定到 global。 -pub fn bind_math(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let math_ptr = session.builtin_world().math_object.as_ptr() as *mut JsObject; +pub fn bind_math(env: BindEnv<'_>, global: &mut JsObject) { + let math_ptr = env.world().math_object.as_ptr() as *mut JsObject; let math = unsafe { &mut *math_ptr }; - let bw = session.builtin_world(); - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); + let bw = env.world(); + let sf = env.string_forge(); + let sh = env.shape_forge(); bind_methods!( bw, @@ -68,8 +67,8 @@ pub fn bind_math(core: &Arc, session: &KernelSession, global: &mut J ("SQRT1_2", std::f64::consts::FRAC_1_SQRT_2), ("SQRT2", std::f64::consts::SQRT_2), ] { - let si = core.perm_interner().as_ref().intern(name).0; - let sh_c = core.shape_forge().as_ref().make_shape(math.shape_id(), si); + let si = env.string_forge().intern(name).0; + let sh_c = env.shape_forge().make_shape(math.shape_id(), si); math.set_shape_id(sh_c); math.ensure_hash_props().push(JsValue::float(val)); // Math 常量描述符:{ writable:false, enumerable:false, configurable:false }, @@ -80,12 +79,12 @@ pub fn bind_math(core: &Arc, session: &KernelSession, global: &mut J // 全局 Math 槽位既有槽原位更新(旧对象指针不得滞留在属性 vec),无槽时 // 开新槽;描述符非枚举(规范全局命名空间对象属性均 enumerable:false)。 - let si_m = core.perm_interner().intern("Math").0; - let m_val = JsValue::from_js_object(session.builtin_world().math_object.as_ptr() as *mut JsObject); - if let Some(pos) = core.shape_forge().lookup_position(global.shape_id(), si_m) { + let si_m = env.string_forge().intern("Math").0; + let m_val = JsValue::from_js_object(env.world().math_object.as_ptr() as *mut JsObject); + if let Some(pos) = env.shape_forge().lookup_position(global.shape_id(), si_m) { global.set_prop_at(pos, m_val); } else { - let m_shape = core.shape_forge().make_shape(global.shape_id(), si_m); + let m_shape = env.shape_forge().make_shape(global.shape_id(), si_m); global.set_shape_id(m_shape); global.ensure_hash_props().push(m_val); let pos = global.prop_vec_len().saturating_sub(1) as u32; diff --git a/crates/oxide_vm/src/bindings/bind_message_channel.rs b/crates/oxide_vm/src/bindings/bind_message_channel.rs index 3f38f4af..fa534b5d 100644 --- a/crates/oxide_vm/src/bindings/bind_message_channel.rs +++ b/crates/oxide_vm/src/bindings/bind_message_channel.rs @@ -1,8 +1,7 @@ -use std::sync::Arc; - use crate::bind_constructor; -use crate::bindings::{apply_binding_table, bind_accessor_getset, bind_accessor_getter, configure_native_constructor}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{ + apply_binding_table, bind_accessor_getset, bind_accessor_getter, configure_native_constructor, BindEnv, +}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; @@ -20,15 +19,15 @@ use oxide_types::value::JsValue; /// /// `realm_id` 未使用(MessageChannel 无 well-known 符号键),保留签名与其他 /// 绑定函数一致。 -pub fn bind_message_channel(core: &Arc, session: &KernelSession, global: &mut JsObject, _realm_id: u32) { - let world = session.builtin_world(); +pub fn bind_message_channel(env: BindEnv<'_>, global: &mut JsObject) { + let world = env.world(); let ctor_ptr = world.message_channel_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; let proto_ptr = world.message_port_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); + let sf = env.string_forge(); + let sh = env.shape_forge(); // ---- 填构造器占位 ---- ctor.set_function(true); @@ -65,7 +64,7 @@ pub fn bind_message_channel(core: &Arc, session: &KernelSession, glo 0, ); bind_constructor!( - core, + env, global, "MessageChannel", ctor_ptr, @@ -93,9 +92,8 @@ pub fn bind_message_channel(core: &Arc, session: &KernelSession, glo let si_post_message = sf.intern("postMessage").0; if sh.lookup_position(proto.shape_id(), si_post_message).is_none() { apply_binding_table( - world, + env, proto, - core, &[ ( "postMessage", @@ -120,8 +118,7 @@ pub fn bind_message_channel(core: &Arc, session: &KernelSession, glo let si_ready_state = sf.intern("readyState").0; if sh.lookup_position(proto.shape_id(), si_ready_state).is_none() { bind_accessor_getter( - core, - session, + env, proto, "readyState", oxide_builtins::message_channel::message_port_ready_state:: as *const (), @@ -134,8 +131,7 @@ pub fn bind_message_channel(core: &Arc, session: &KernelSession, glo let key = sf.intern(name).0; if sh.lookup_position(proto.shape_id(), key).is_none() { bind_accessor_getset( - core, - session, + env, proto, key, &format!("get {name}"), diff --git a/crates/oxide_vm/src/bindings/bind_number.rs b/crates/oxide_vm/src/bindings/bind_number.rs index 969fa76c..bd2f4404 100644 --- a/crates/oxide_vm/src/bindings/bind_number.rs +++ b/crates/oxide_vm/src/bindings/bind_number.rs @@ -1,24 +1,20 @@ -use std::sync::Arc; - use crate::bind_constructor; -use crate::bindings::{apply_binding_table, configure_native_constructor}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{apply_binding_table, configure_native_constructor, BindEnv}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; /// 把 Number 构造器与原型方法绑定到 global(含 NaN/POSITIVE_INFINITY 等常量)。 -pub fn bind_number(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let ctor_ptr = session.builtin_world().number_constructor.as_ptr() as *mut JsObject; +pub fn bind_number(env: BindEnv<'_>, global: &mut JsObject) { + let ctor_ptr = env.world().number_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - let proto_ptr = session.builtin_world().number_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().number_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; configure_native_constructor(ctor, oxide_builtins::number::number_constructor:: as *const (), 1); apply_binding_table( - session.builtin_world(), + env, ctor, - core, &[ ("isNaN", oxide_builtins::number::number_is_nan:: as *const (), 1), ("isFinite", oxide_builtins::number::number_is_finite:: as *const (), 1), @@ -35,9 +31,8 @@ pub fn bind_number(core: &Arc, session: &KernelSession, global: &mut ); apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ("toString", oxide_builtins::number::number_to_string:: as *const (), 1), ("toFixed", oxide_builtins::number::number_to_fixed:: as *const (), 1), @@ -75,18 +70,17 @@ pub fn bind_number(core: &Arc, session: &KernelSession, global: &mut ] { ctor.ensure_hash_props().push(value); let pos = ctor.ensure_hash_props().len() - 1; - let prop_si = core.perm_interner().intern(name).0; - let next_shape = core.shape_forge().make_shape(ctor.shape_id(), prop_si); + let prop_si = env.string_forge().intern(name).0; + let next_shape = env.shape_forge().make_shape(ctor.shape_id(), prop_si); ctor.set_shape_id(next_shape); ctor.set_data_meta(pos, PropAttributes::new(false, false, false)); } - bind_constructor!(core, global, "Number", ctor_ptr, oxide_builtins::number::number_constructor::, 1, hash: true); + bind_constructor!(env, global, "Number", ctor_ptr, oxide_builtins::number::number_constructor::, 1, hash: true); apply_binding_table( - session.builtin_world(), + env, global, - core, &[ // parseInt 形式参数为 (string, radix),length 按规范取 2。 ("parseInt", oxide_builtins::number::number_parse_int:: as *const (), 2), @@ -100,10 +94,10 @@ pub fn bind_number(core: &Arc, session: &KernelSession, global: &mut // 是同一函数对象(SameValue)。ctor 侧绑定先执行、产生独立 wrapper, // 此处把 global 侧 wrapper 值原位写回 ctor 同名槽,描述符形态不变。 for name in ["parseInt", "parseFloat"] { - let si = core.perm_interner().intern(name).0; - if let Some(global_pos) = core.shape_forge().lookup_position(global.shape_id(), si) { + let si = env.string_forge().intern(name).0; + if let Some(global_pos) = env.shape_forge().lookup_position(global.shape_id(), si) { let val = global.get_prop_at(global_pos); - if let Some(ctor_pos) = core.shape_forge().lookup_position(ctor.shape_id(), si) { + if let Some(ctor_pos) = env.shape_forge().lookup_position(ctor.shape_id(), si) { ctor.set_prop_at(ctor_pos, val); } } diff --git a/crates/oxide_vm/src/bindings/bind_object.rs b/crates/oxide_vm/src/bindings/bind_object.rs index d2af6e03..8972b77d 100644 --- a/crates/oxide_vm/src/bindings/bind_object.rs +++ b/crates/oxide_vm/src/bindings/bind_object.rs @@ -1,14 +1,11 @@ -use std::sync::Arc; - use oxide_kernel::builtin::ObjectMethods; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::{JsObject, PropAttributes}; use crate::bind_constructor; -use crate::bindings::apply_binding_table; +use crate::bindings::{apply_binding_table, BindEnv}; /// 把 Object 构造器与原型方法绑定到 global。 -pub fn bind_object(core: &Arc, session: &KernelSession, global: &mut JsObject) { +pub fn bind_object(env: BindEnv<'_>, global: &mut JsObject) { let methods = ObjectMethods { keys: oxide_builtins::object::object_keys:: as *const (), create: oxide_builtins::object::object_create:: as *const (), @@ -39,16 +36,14 @@ pub fn bind_object(core: &Arc, session: &KernelSession, global: &mut as *const (), group_by: oxide_builtins::object::object_group_by:: as *const (), }; - session - .builtin_world() - .bind_object_methods(&methods, core.perm_interner().as_ref(), core.shape_forge().as_ref()); + env.world() + .bind_object_methods(&methods, env.string_forge(), env.shape_forge()); - let object_proto_ptr = session.builtin_world().object_proto.as_ptr() as *mut JsObject; + let object_proto_ptr = env.world().object_proto.as_ptr() as *mut JsObject; let object_proto = unsafe { &mut *object_proto_ptr }; apply_binding_table( - session.builtin_world(), + env, object_proto, - core, &[ ( "toString", @@ -101,15 +96,15 @@ pub fn bind_object(core: &Arc, session: &KernelSession, global: &mut "__lookupSetter__", "toSource", ] { - let si = core.perm_interner().intern(name).0; - if let Some(pos) = core.shape_forge().lookup_position(object_proto.shape_id(), si) { + let si = env.string_forge().intern(name).0; + if let Some(pos) = env.shape_forge().lookup_position(object_proto.shape_id(), si) { object_proto.set_data_meta(pos, PropAttributes::new(true, false, true)); } } - let ctor_ptr = session.builtin_world().object_constructor.as_ptr() as *mut JsObject; + let ctor_ptr = env.world().object_constructor.as_ptr() as *mut JsObject; bind_constructor!( - core, + env, global, "Object", ctor_ptr, diff --git a/crates/oxide_vm/src/bindings/bind_reflect.rs b/crates/oxide_vm/src/bindings/bind_reflect.rs index 2b30d4b6..a408892b 100644 --- a/crates/oxide_vm/src/bindings/bind_reflect.rs +++ b/crates/oxide_vm/src/bindings/bind_reflect.rs @@ -1,22 +1,18 @@ -use std::sync::Arc; - -use crate::bindings::{apply_binding_table, bind_global_value}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{apply_binding_table, bind_global_value, BindEnv}; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_types::object::JsObject; use oxide_types::value::JsValue; /// 把 Reflect 单例对象及其方法(get/set/construct/defineProperty 等)绑定到 global。 -pub fn bind_reflect(core: &Arc, session: &KernelSession, global: &mut JsObject) { +pub fn bind_reflect(env: BindEnv<'_>, global: &mut JsObject) { let mut reflect = Box::new(JsObject::new_empty( EMPTY_SHAPE_ID, - JsValue::from_js_object(session.builtin_world().object_proto.as_ptr() as *mut JsObject), + JsValue::from_js_object(env.world().object_proto.as_ptr() as *mut JsObject), )); apply_binding_table( - session.builtin_world(), + env, &mut reflect, - core, &[ ("apply", oxide_builtins::reflect::reflect_apply:: as *const (), 3), ("construct", oxide_builtins::reflect::reflect_construct:: as *const (), 2), @@ -64,6 +60,6 @@ pub fn bind_reflect(core: &Arc, session: &KernelSession, global: &mu let reflect_ptr = Box::into_raw(reflect); // 登记进 world 释放表:session 收尾统一释放对象本体与属性区。 - session.builtin_world().track_leaked_object(reflect_ptr); - bind_global_value(core, global, "Reflect", JsValue::from_js_object(reflect_ptr)); + env.world().track_leaked_object(reflect_ptr); + bind_global_value(env.core, global, "Reflect", JsValue::from_js_object(reflect_ptr)); } diff --git a/crates/oxide_vm/src/bindings/bind_regexp.rs b/crates/oxide_vm/src/bindings/bind_regexp.rs index c884f706..d9c38e3b 100644 --- a/crates/oxide_vm/src/bindings/bind_regexp.rs +++ b/crates/oxide_vm/src/bindings/bind_regexp.rs @@ -1,10 +1,7 @@ -use std::sync::Arc; - use crate::bindings::{ apply_binding_table, bind_accessor_getset, bind_accessor_getter, bind_accessor_getter_key, bind_well_known_method, - configure_native_constructor, + configure_native_constructor, BindEnv, }; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::JsObject; use crate::bind_constructor; @@ -13,26 +10,24 @@ use crate::bind_constructor; /// /// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_regexp(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { - let ctor_ptr = session.builtin_world().regexp_constructor.as_ptr() as *mut JsObject; +pub fn bind_regexp(env: BindEnv<'_>, global: &mut JsObject) { + let ctor_ptr = env.world().regexp_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - let proto_ptr = session.builtin_world().regexp_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().regexp_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; configure_native_constructor(ctor, oxide_builtins::regexp::regexp_constructor:: as *const (), 2); // 静态方法 escape 装到构造器对象(wrapper 的 length/name 与槽属性由 bind_method 统一保证)。 apply_binding_table( - session.builtin_world(), + env, ctor, - core, &[("escape", oxide_builtins::regexp::regexp_escape:: as *const (), 1)], ); apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ("exec", oxide_builtins::regexp::regexp_exec:: as *const (), 1), ("test", oxide_builtins::regexp::regexp_test:: as *const (), 1), @@ -47,10 +42,10 @@ pub fn bind_regexp(core: &Arc, session: &KernelSession, global: &mut // [[RegExpInput]] 槽);其余 18 个为 getter(set 恒 undefined):lastMatch/$&、 // lastParen/$+、leftContext/$`、rightContext/$' 各共享一槽,index 与 $1-$9 各 // 独占一槽。 - let sf = core.perm_interner().as_ref(); + let sf = env.string_forge(); let mut bind_getset = |name: &str, getter: *const (), setter: *const ()| { let key = sf.intern(name).0; - bind_accessor_getset(core, session, ctor, key, &format!("get {name}"), &format!("set {name}"), getter, setter); + bind_accessor_getset(env, ctor, key, &format!("get {name}"), &format!("set {name}"), getter, setter); }; // input/$_:get+set 对(唯一带 setter 的遗留访问器)。 bind_getset( @@ -99,20 +94,18 @@ pub fn bind_regexp(core: &Arc, session: &KernelSession, global: &mut ("$8", oxide_builtins::regexp::regexp_legacy_get_dollar_8:: as *const ()), ("$9", oxide_builtins::regexp::regexp_legacy_get_dollar_9:: as *const ()), ] { - bind_accessor_getter(core, session, ctor, name, getter); + bind_accessor_getter(env, ctor, name, getter); } // source/flags 只读访问器(set 恒 undefined,getter 读实例字段)。 bind_accessor_getter( - core, - session, + env, proto, "source", oxide_builtins::regexp::regexp_get_source:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "flags", oxide_builtins::regexp::regexp_get_flags:: as *const (), @@ -120,125 +113,105 @@ pub fn bind_regexp(core: &Arc, session: &KernelSession, global: &mut // 8 个单 flag 只读访问器(set 恒 undefined,getter 读实例 flags 串判码元)。 bind_accessor_getter( - core, - session, + env, proto, "global", oxide_builtins::regexp::regexp_get_global:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "ignoreCase", oxide_builtins::regexp::regexp_get_ignore_case:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "multiline", oxide_builtins::regexp::regexp_get_multiline:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "dotAll", oxide_builtins::regexp::regexp_get_dot_all:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "sticky", oxide_builtins::regexp::regexp_get_sticky:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "unicode", oxide_builtins::regexp::regexp_get_unicode:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "hasIndices", oxide_builtins::regexp::regexp_get_has_indices:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "unicodeSets", oxide_builtins::regexp::regexp_get_unicode_sets:: as *const (), ); // well-known symbol 方法按 Symbol 键安装,name 属性取 `[Symbol.match]` 式标签,供 `re[Symbol.match]` 等读取。 - let world = session.builtin_world(); bind_well_known_method( - world, - core, + env, proto, 1, "[Symbol.match]", oxide_builtins::regexp::regexp_symbol_match:: as *const (), 1, - realm_id, ); bind_well_known_method( - world, - core, + env, proto, 2, "[Symbol.replace]", oxide_builtins::regexp::regexp_symbol_replace:: as *const (), 2, - realm_id, ); bind_well_known_method( - world, - core, + env, proto, 3, "[Symbol.search]", oxide_builtins::regexp::regexp_symbol_search:: as *const (), 1, - realm_id, ); bind_well_known_method( - world, - core, + env, proto, 4, "[Symbol.split]", oxide_builtins::regexp::regexp_symbol_split:: as *const (), 2, - realm_id, ); bind_well_known_method( - world, - core, + env, proto, 7, "[Symbol.matchAll]", oxide_builtins::regexp::regexp_symbol_match_all:: as *const (), 1, - realm_id, ); // RegExp[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链解析 // @@species 得自身构造器(规范不给 class 默认 static @@species,类上无 own)。 bind_accessor_getter_key( - core, - session, + env, ctor, - oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), + oxide_types::private_key::encode_symbol_key(env.realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), "get [Symbol.species]", oxide_builtins::array::array_species_get:: as *const (), ); - bind_constructor!(core, global, "RegExp", ctor_ptr, oxide_builtins::regexp::regexp_constructor::, 2, hash: true); + bind_constructor!(env, global, "RegExp", ctor_ptr, oxide_builtins::regexp::regexp_constructor::, 2, hash: true); } diff --git a/crates/oxide_vm/src/bindings/bind_set.rs b/crates/oxide_vm/src/bindings/bind_set.rs index 3f7f3d03..4dad8834 100644 --- a/crates/oxide_vm/src/bindings/bind_set.rs +++ b/crates/oxide_vm/src/bindings/bind_set.rs @@ -1,30 +1,26 @@ -use std::sync::Arc; - use crate::bind_constructor; use crate::bindings::{ apply_binding_table, bind_accessor_getter, bind_accessor_getter_key, bind_method_alias, - bind_well_known_method_alias, configure_native_constructor, + bind_well_known_method_alias, configure_native_constructor, BindEnv, }; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::JsObject; /// 把 Set 构造器与原型方法绑定到 global。 /// /// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_set(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { - let ctor_ptr = session.builtin_world().set_constructor.as_ptr() as *mut JsObject; +pub fn bind_set(env: BindEnv<'_>, global: &mut JsObject) { + let ctor_ptr = env.world().set_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - let proto_ptr = session.builtin_world().set_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().set_proto.as_ptr() as *mut JsObject; configure_native_constructor(ctor, oxide_builtins::set::set_constructor:: as *const (), 1); let proto = unsafe { &mut *proto_ptr }; // size 是访问器 getter,不进 apply_binding_table。 apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ("add", oxide_builtins::set::set_add:: as *const (), 1), ("has", oxide_builtins::set::set_has:: as *const (), 1), @@ -52,20 +48,19 @@ pub fn bind_set(core: &Arc, session: &KernelSession, global: &mut Js ); // keys 与 @@iterator(Symbol.iterator)是 values 的同一函数对象。 - bind_method_alias(core, proto, "values", "keys"); - bind_well_known_method_alias(core, proto, "values", 0, realm_id); - bind_accessor_getter(core, session, proto, "size", oxide_builtins::set::set_size:: as *const ()); + bind_method_alias(env.core, proto, "values", "keys"); + bind_well_known_method_alias(env.core, proto, "values", 0, env.realm_id); + bind_accessor_getter(env, proto, "size", oxide_builtins::set::set_size:: as *const ()); // Set[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链解析 // @@species 得自身构造器(规范不给 class 默认 static @@species,类上无 own)。 bind_accessor_getter_key( - core, - session, + env, ctor, - oxide_types::private_key::encode_symbol_key(realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), + oxide_types::private_key::encode_symbol_key(env.realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES), "get [Symbol.species]", oxide_builtins::array::array_species_get:: as *const (), ); - bind_constructor!(core, global, "Set", ctor_ptr, oxide_builtins::set::set_constructor::, 0, hash: true); + bind_constructor!(env, global, "Set", ctor_ptr, oxide_builtins::set::set_constructor::, 0, hash: true); } diff --git a/crates/oxide_vm/src/bindings/bind_shared_array_buffer.rs b/crates/oxide_vm/src/bindings/bind_shared_array_buffer.rs index 9b9e2761..24002399 100644 --- a/crates/oxide_vm/src/bindings/bind_shared_array_buffer.rs +++ b/crates/oxide_vm/src/bindings/bind_shared_array_buffer.rs @@ -1,15 +1,12 @@ -use std::sync::Arc; - use crate::bind_constructor; -use crate::bindings::{apply_binding_table, bind_accessor_getter, configure_native_constructor}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{apply_binding_table, bind_accessor_getter, configure_native_constructor, BindEnv}; use oxide_types::object::JsObject; /// 把 SharedArrayBuffer 构造器与原型访问器绑定到 global。 -pub fn bind_shared_array_buffer(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let ctor_ptr = session.builtin_world().shared_array_buffer_constructor.as_ptr() as *mut JsObject; +pub fn bind_shared_array_buffer(env: BindEnv<'_>, global: &mut JsObject) { + let ctor_ptr = env.world().shared_array_buffer_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - let proto_ptr = session.builtin_world().shared_array_buffer_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().shared_array_buffer_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; configure_native_constructor( @@ -21,9 +18,8 @@ pub fn bind_shared_array_buffer(core: &Arc, session: &KernelSession, // grow/slice 方法:grow 原地增长(只增不缩);slice 复制字节区间生成 // 新 SAB。 apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ( "grow", @@ -41,16 +37,14 @@ pub fn bind_shared_array_buffer(core: &Arc, session: &KernelSession, // byteLength/maxByteLength 两枚访问器(set 恒 undefined)读载荷字节数 / // 存储态上限,品牌校验抛 TypeError(proto 自身访问即抛)。 bind_accessor_getter( - core, - session, + env, proto, "byteLength", oxide_builtins::array_buffer::shared_array_buffer_byte_length:: as *const (), ); bind_accessor_getter( - core, - session, + env, proto, "maxByteLength", oxide_builtins::array_buffer::shared_array_buffer_max_byte_length:: as *const (), @@ -58,15 +52,14 @@ pub fn bind_shared_array_buffer(core: &Arc, session: &KernelSession, // growable 真值臂:读载荷存储态上限(0 定长 false / 非 0 growable true)。 bind_accessor_getter( - core, - session, + env, proto, "growable", oxide_builtins::array_buffer::shared_array_buffer_growable:: as *const (), ); bind_constructor!( - core, + env, global, "SharedArrayBuffer", ctor_ptr, diff --git a/crates/oxide_vm/src/bindings/bind_string.rs b/crates/oxide_vm/src/bindings/bind_string.rs index 406078d9..c336bd54 100644 --- a/crates/oxide_vm/src/bindings/bind_string.rs +++ b/crates/oxide_vm/src/bindings/bind_string.rs @@ -1,8 +1,5 @@ -use std::sync::Arc; - -use crate::bindings::{apply_binding_table, configure_native_constructor}; +use crate::bindings::{apply_binding_table, configure_native_constructor, BindEnv}; use oxide_kernel::builtin::StringMethods; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; @@ -10,7 +7,7 @@ use oxide_types::value::JsValue; /// /// `realm_id` 是目标所属 realm 的编号:`@@iterator` 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_string(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { +pub fn bind_string(env: BindEnv<'_>, global: &mut JsObject) { let string_methods = StringMethods { from_char_code: oxide_builtins::string::string_from_char_code:: as *const (), index_of: oxide_builtins::string::string_index_of:: as *const (), @@ -63,29 +60,28 @@ pub fn bind_string(core: &Arc, session: &KernelSession, global: &mut sub: oxide_builtins::string::string_sub:: as *const (), sup: oxide_builtins::string::string_sup:: as *const (), }; - session.builtin_world().bind_string_methods( + env.world().bind_string_methods( &string_methods, - core.perm_interner().as_ref(), - core.shape_forge().as_ref(), + env.string_forge(), + env.shape_forge(), ); - let ctor_ptr = session.builtin_world().string_constructor.as_ptr() as *mut JsObject; + let ctor_ptr = env.world().string_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; configure_native_constructor(ctor, oxide_builtins::string::string_constructor:: as *const (), 1); // String.length = 1,描述符 { writable:false, enumerable:false, configurable:true }。 - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(ctor.shape_id(), length_si); ctor.set_shape_id(length_shape); ctor.ensure_hash_props().push(JsValue::int(1)); let length_pos = ctor.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1); ctor.set_data_meta(length_pos, PropAttributes::new(false, false, true)); - let proto_ptr = session.builtin_world().string_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().string_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ("toString", oxide_builtins::string::string_to_string:: as *const (), 0), ("toSource", oxide_builtins::to_source::to_source_string:: as *const (), 0), @@ -94,23 +90,20 @@ pub fn bind_string(core: &Arc, session: &KernelSession, global: &mut // String.prototype[@@iterator]:逐 code point 迭代字符;name 属性按规范 // 落 "[Symbol.iterator]"。 super::bind_well_known_method( - session.builtin_world(), - core, + env, proto, 0, "[Symbol.iterator]", oxide_builtins::string::string_symbol_iterator:: as *const (), 0, - realm_id, ); // 捕获默认迭代器函数对象指针写入 world:String 臂覆盖判定以此做指针比较。 // 此时槽为初始数据属性(用户覆盖尚未可能),读回即默认函数本体。 - 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) { + let iter_key = oxide_types::private_key::encode_symbol_key(env.realm_id, 0); + if let Some(pos) = env.shape_forge().lookup_position(proto.shape_id(), iter_key) { let v = proto.get_prop_at(pos); if v.is_object() { - session - .builtin_world() + env.world() .string_default_iterator .set(v.as_js_object_ptr() as *const JsObject); } @@ -118,12 +111,12 @@ pub fn bind_string(core: &Arc, session: &KernelSession, global: &mut // 全局 String 槽位既有槽原位更新(旧家族构造器指针不得滞留在属性 vec), // 无槽时开新槽;描述符非枚举(规范 { writable:true, enumerable:false, configurable:true })。 - let si_str = core.perm_interner().intern("String").0; - let str_val = JsValue::from_js_object(session.builtin_world().string_constructor.as_ptr() as *mut JsObject); - if let Some(pos) = core.shape_forge().lookup_position(global.shape_id(), si_str) { + let si_str = env.string_forge().intern("String").0; + let str_val = JsValue::from_js_object(env.world().string_constructor.as_ptr() as *mut JsObject); + if let Some(pos) = env.shape_forge().lookup_position(global.shape_id(), si_str) { global.set_prop_at(pos, str_val); } else { - let str_shape = core.shape_forge().make_shape(global.shape_id(), si_str); + let str_shape = env.shape_forge().make_shape(global.shape_id(), si_str); global.set_shape_id(str_shape); global.ensure_hash_props().push(str_val); let pos = global.prop_vec_len().saturating_sub(1) as u32; diff --git a/crates/oxide_vm/src/bindings/bind_symbol.rs b/crates/oxide_vm/src/bindings/bind_symbol.rs index 41559ec9..8003f0e5 100644 --- a/crates/oxide_vm/src/bindings/bind_symbol.rs +++ b/crates/oxide_vm/src/bindings/bind_symbol.rs @@ -1,9 +1,6 @@ -use std::sync::Arc; - use crate::bindings::{ - apply_binding_table, bind_accessor_getter, bind_well_known_method, configure_native_constructor, + apply_binding_table, bind_accessor_getter, bind_well_known_method, configure_native_constructor, BindEnv, }; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::private_key::{encode_symbol_key, WELL_KNOWN_SYMBOL_TO_PRIMITIVE}; use oxide_types::value::JsValue; @@ -14,18 +11,17 @@ use crate::bind_constructor; /// /// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_symbol(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { - let ctor_ptr = session.builtin_world().symbol_constructor.as_ptr() as *mut JsObject; +pub fn bind_symbol(env: BindEnv<'_>, global: &mut JsObject) { + let ctor_ptr = env.world().symbol_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - let proto_ptr = session.builtin_world().symbol_proto.as_ptr() as *mut JsObject; + let proto_ptr = env.world().symbol_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; configure_native_constructor(ctor, oxide_builtins::symbol::symbol_constructor:: as *const (), 1); apply_binding_table( - session.builtin_world(), + env, ctor, - core, &[ ("for", oxide_builtins::symbol::symbol_for:: as *const (), 1), ("keyFor", oxide_builtins::symbol::symbol_key_for:: as *const (), 1), @@ -33,9 +29,8 @@ pub fn bind_symbol(core: &Arc, session: &KernelSession, global: &mut ); apply_binding_table( - session.builtin_world(), + env, proto, - core, &[ ("toString", oxide_builtins::symbol::symbol_to_string:: as *const (), 0), ("valueOf", oxide_builtins::symbol::symbol_value_of:: as *const (), 0), @@ -44,8 +39,7 @@ pub fn bind_symbol(core: &Arc, session: &KernelSession, global: &mut // description 是访问器 getter(Symbol 原始值成员访问经 Symbol.prototype 链命中)。 bind_accessor_getter( - core, - session, + env, proto, "description", oxide_builtins::symbol::symbol_description_getter:: as *const (), @@ -53,17 +47,15 @@ pub fn bind_symbol(core: &Arc, session: &KernelSession, global: &mut // [Symbol.toPrimitive] 方法:bind 默认描述符可写,规范为不可写,绑定后改 meta。 bind_well_known_method( - session.builtin_world(), - core, + env, proto, WELL_KNOWN_SYMBOL_TO_PRIMITIVE, "[Symbol.toPrimitive]", oxide_builtins::symbol::symbol_to_primitive:: as *const (), 1, - realm_id, ); - 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) { + let to_prim_key = encode_symbol_key(env.realm_id, WELL_KNOWN_SYMBOL_TO_PRIMITIVE); + if let Some(pos) = env.shape_forge().lookup_position(proto.shape_id(), to_prim_key) { proto.set_data_meta(pos, PropAttributes::new(false, false, true)); proto.bump_generation(); } @@ -74,15 +66,15 @@ pub fn bind_symbol(core: &Arc, session: &KernelSession, global: &mut // 非零 realm 下与键物化值保持同一符号。 for (id, full_name) in oxide_types::private_key::WELL_KNOWN_SYMBOL_NAMES.iter().enumerate() { let name = full_name.strip_prefix("Symbol.").unwrap_or(full_name); - bind_well_known_symbol(core, ctor, name, JsValue::symbol_realm(realm_id, id as u32)); + bind_well_known_symbol(env, ctor, name, JsValue::symbol_realm(env.realm_id, id as u32)); } - bind_constructor!(core, global, "Symbol", ctor_ptr, oxide_builtins::symbol::symbol_constructor::, 0, hash: true); + bind_constructor!(env, global, "Symbol", ctor_ptr, oxide_builtins::symbol::symbol_constructor::, 0, hash: true); } -fn bind_well_known_symbol(core: &Arc, ctor: &mut JsObject, name: &str, val: JsValue) { - let si = core.perm_interner().intern(name).0; - let shape_id = core.shape_forge().make_shape(ctor.shape_id(), si); +fn bind_well_known_symbol(env: BindEnv<'_>, ctor: &mut JsObject, name: &str, val: JsValue) { + let si = env.string_forge().intern(name).0; + let shape_id = env.shape_forge().make_shape(ctor.shape_id(), si); ctor.set_shape_id(shape_id); ctor.ensure_hash_props().push(val); // well-known symbol 属性按规范 { writable:false, enumerable:false, configurable:false }。 diff --git a/crates/oxide_vm/src/bindings/bind_temporal.rs b/crates/oxide_vm/src/bindings/bind_temporal.rs index 466e0b6e..f979aced 100644 --- a/crates/oxide_vm/src/bindings/bind_temporal.rs +++ b/crates/oxide_vm/src/bindings/bind_temporal.rs @@ -1,10 +1,7 @@ -use std::sync::Arc; - use crate::bindings::{ apply_binding_table, bind_accessor_getter, bind_global_value, bind_well_known_data_property, - configure_native_constructor, + configure_native_constructor, BindEnv, }; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; @@ -12,8 +9,8 @@ use oxide_types::value::JsValue; /// /// `realm_id` 是目标所属 realm 的编号:`@@toStringTag` 符号键按 (realm 编号, /// 局部下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { - let world = session.builtin_world(); +pub fn bind_temporal(env: BindEnv<'_>, global: &mut JsObject) { + let world = env.world(); let temporal_ptr = world.temporal_object.as_ptr() as *mut JsObject; let temporal = unsafe { &mut *temporal_ptr }; @@ -21,9 +18,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m let now_ptr = world.temporal_now_object.as_ptr() as *mut JsObject; let now = unsafe { &mut *now_ptr }; apply_binding_table( - world, + env, now, - core, &[ ("instant", oxide_builtins::temporal::now_instant:: as *const (), 0), ("timeZoneId", oxide_builtins::temporal::now_time_zone_id:: as *const (), 0), @@ -38,8 +34,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::instant_constructor:: as *const (), 1, ); - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(instant_ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(instant_ctor.shape_id(), length_si); instant_ctor.set_shape_id(length_shape); instant_ctor.ensure_hash_props().push(JsValue::int(1)); let length_pos = instant_ctor @@ -49,9 +45,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m instant_ctor.set_data_meta(length_pos, PropAttributes::new(false, false, true)); apply_binding_table( - world, + env, instant_ctor, - core, &[ ("from", oxide_builtins::temporal::instant_from:: as *const (), 1), ("compare", oxide_builtins::temporal::instant_compare:: as *const (), 2), @@ -70,37 +65,32 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m let instant_proto_ptr = world.instant_proto.as_ptr() as *mut JsObject; let instant_proto = unsafe { &mut *instant_proto_ptr }; bind_accessor_getter( - core, - session, + env, instant_proto, "epochSeconds", oxide_builtins::temporal::instant_epoch_seconds:: as *const (), ); bind_accessor_getter( - core, - session, + env, instant_proto, "epochMilliseconds", oxide_builtins::temporal::instant_epoch_milliseconds:: as *const (), ); bind_accessor_getter( - core, - session, + env, instant_proto, "epochMicroseconds", oxide_builtins::temporal::instant_epoch_microseconds:: as *const (), ); bind_accessor_getter( - core, - session, + env, instant_proto, "epochNanoseconds", oxide_builtins::temporal::instant_epoch_nanoseconds:: as *const (), ); apply_binding_table( - world, + env, instant_proto, - core, &[ ("add", oxide_builtins::temporal::instant_add:: as *const (), 1), ("equals", oxide_builtins::temporal::instant_equals:: as *const (), 1), @@ -124,15 +114,15 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m ], ); bind_well_known_data_property( - core, + env.core, instant_proto, 9, JsValue::perm_string( - core.perm_interner() - .string_ptr(core.perm_interner().intern("Temporal.Instant").0), + env.string_forge() + .string_ptr(env.string_forge().intern("Temporal.Instant").0), ), PropAttributes::new(false, false, true), - realm_id, + env.realm_id, ); // Temporal.ZonedDateTime:最小构造器与三个稳定内部槽 getter。 @@ -143,8 +133,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::zoned_date_time_constructor:: as *const (), 2, ); - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(zoned_date_time_ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(zoned_date_time_ctor.shape_id(), length_si); zoned_date_time_ctor.set_shape_id(length_shape); zoned_date_time_ctor.ensure_hash_props().push(JsValue::int(2)); let length_pos = zoned_date_time_ctor @@ -153,9 +143,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m .saturating_sub(1); zoned_date_time_ctor.set_data_meta(length_pos, PropAttributes::new(false, false, true)); apply_binding_table( - world, + env, zoned_date_time_ctor, - core, &[ ("from", oxide_builtins::temporal::zoned_date_time_from:: as *const (), 1), ( @@ -169,230 +158,199 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m let zoned_date_time_proto_ptr = world.zoned_date_time_proto.as_ptr() as *mut JsObject; let zoned_date_time_proto = unsafe { &mut *zoned_date_time_proto_ptr }; bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "epochNanoseconds", oxide_builtins::temporal::zoned_date_time_epoch_nanoseconds:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "timeZoneId", oxide_builtins::temporal::zoned_date_time_time_zone_id:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "calendarId", oxide_builtins::temporal::zoned_date_time_calendar_id:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "epochSeconds", oxide_builtins::temporal::zoned_date_time_epoch_seconds:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "epochMilliseconds", oxide_builtins::temporal::zoned_date_time_epoch_milliseconds:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "epochMicroseconds", oxide_builtins::temporal::zoned_date_time_epoch_microseconds:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "offset", oxide_builtins::temporal::zoned_date_time_offset:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "offsetNanoseconds", oxide_builtins::temporal::zoned_date_time_offset_nanoseconds:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "year", oxide_builtins::temporal::zoned_date_time_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "month", oxide_builtins::temporal::zoned_date_time_month:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "day", oxide_builtins::temporal::zoned_date_time_day:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "hour", oxide_builtins::temporal::zoned_date_time_hour:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "minute", oxide_builtins::temporal::zoned_date_time_minute:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "second", oxide_builtins::temporal::zoned_date_time_second:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "millisecond", oxide_builtins::temporal::zoned_date_time_millisecond:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "microsecond", oxide_builtins::temporal::zoned_date_time_microsecond:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "nanosecond", oxide_builtins::temporal::zoned_date_time_nanosecond:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "dayOfWeek", oxide_builtins::temporal::zoned_date_time_day_of_week:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "dayOfYear", oxide_builtins::temporal::zoned_date_time_day_of_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "weekOfYear", oxide_builtins::temporal::zoned_date_time_week_of_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "yearOfWeek", oxide_builtins::temporal::zoned_date_time_year_of_week:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "monthCode", oxide_builtins::temporal::zoned_date_time_month_code:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "daysInMonth", oxide_builtins::temporal::zoned_date_time_days_in_month:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "daysInWeek", oxide_builtins::temporal::zoned_date_time_days_in_week:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "daysInYear", oxide_builtins::temporal::zoned_date_time_days_in_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "monthsInYear", oxide_builtins::temporal::zoned_date_time_months_in_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "inLeapYear", oxide_builtins::temporal::zoned_date_time_in_leap_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "era", oxide_builtins::temporal::zoned_date_time_era:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "eraYear", oxide_builtins::temporal::zoned_date_time_era_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, zoned_date_time_proto, "hoursInDay", oxide_builtins::temporal::zoned_date_time_hours_in_day:: as *const (), ); bind_well_known_data_property( - core, + env.core, zoned_date_time_proto, 9, JsValue::perm_string( - core.perm_interner() - .string_ptr(core.perm_interner().intern("Temporal.ZonedDateTime").0), + env.string_forge() + .string_ptr(env.string_forge().intern("Temporal.ZonedDateTime").0), ), PropAttributes::new(false, false, true), - realm_id, + env.realm_id, ); apply_binding_table( - world, + env, zoned_date_time_proto, - core, &[ ( "toJSON", @@ -480,8 +438,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::plain_date_constructor:: as *const (), 3, ); - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(plain_date_ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(plain_date_ctor.shape_id(), length_si); plain_date_ctor.set_shape_id(length_shape); plain_date_ctor.ensure_hash_props().push(JsValue::int(3)); let length_pos = plain_date_ctor @@ -491,9 +449,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m plain_date_ctor.set_data_meta(length_pos, PropAttributes::new(false, false, true)); apply_binding_table( - world, + env, plain_date_ctor, - core, &[ ("from", oxide_builtins::temporal::plain_date_from:: as *const (), 1), ("compare", oxide_builtins::temporal::plain_date_compare:: as *const (), 2), @@ -502,121 +459,104 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m let plain_date_proto_ptr = world.plain_date_proto.as_ptr() as *mut JsObject; let plain_date_proto = unsafe { &mut *plain_date_proto_ptr }; bind_accessor_getter( - core, - session, + env, plain_date_proto, "year", oxide_builtins::temporal::plain_date_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "month", oxide_builtins::temporal::plain_date_month:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "day", oxide_builtins::temporal::plain_date_day:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "dayOfWeek", oxide_builtins::temporal::plain_date_day_of_week:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "dayOfYear", oxide_builtins::temporal::plain_date_day_of_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "daysInMonth", oxide_builtins::temporal::plain_date_days_in_month:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "daysInWeek", oxide_builtins::temporal::plain_date_days_in_week:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "daysInYear", oxide_builtins::temporal::plain_date_days_in_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "monthsInYear", oxide_builtins::temporal::plain_date_months_in_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "inLeapYear", oxide_builtins::temporal::plain_date_in_leap_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "weekOfYear", oxide_builtins::temporal::plain_date_week_of_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "yearOfWeek", oxide_builtins::temporal::plain_date_year_of_week:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "monthCode", oxide_builtins::temporal::plain_date_month_code:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "era", oxide_builtins::temporal::plain_date_era:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "eraYear", oxide_builtins::temporal::plain_date_era_year:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_date_proto, "calendarId", oxide_builtins::temporal::plain_date_calendar_id:: as *const (), ); apply_binding_table( - world, + env, plain_date_proto, - core, &[ ( "toString", @@ -641,8 +581,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::plain_time_constructor:: as *const (), 6, ); - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(plain_time_ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(plain_time_ctor.shape_id(), length_si); plain_time_ctor.set_shape_id(length_shape); plain_time_ctor.ensure_hash_props().push(JsValue::int(0)); let length_pos = plain_time_ctor @@ -651,9 +591,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m .saturating_sub(1); plain_time_ctor.set_data_meta(length_pos, PropAttributes::new(false, false, true)); apply_binding_table( - world, + env, plain_time_ctor, - core, &[ ("from", oxide_builtins::temporal::plain_time_from:: as *const (), 1), ("compare", oxide_builtins::temporal::plain_time_compare:: as *const (), 2), @@ -663,51 +602,44 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m let plain_time_proto_ptr = world.plain_time_proto.as_ptr() as *mut JsObject; let plain_time_proto = unsafe { &mut *plain_time_proto_ptr }; bind_accessor_getter( - core, - session, + env, plain_time_proto, "hour", oxide_builtins::temporal::plain_time_hour:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_time_proto, "minute", oxide_builtins::temporal::plain_time_minute:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_time_proto, "second", oxide_builtins::temporal::plain_time_second:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_time_proto, "millisecond", oxide_builtins::temporal::plain_time_millisecond:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_time_proto, "microsecond", oxide_builtins::temporal::plain_time_microsecond:: as *const (), ); bind_accessor_getter( - core, - session, + env, plain_time_proto, "nanosecond", oxide_builtins::temporal::plain_time_nanosecond:: as *const (), ); apply_binding_table( - world, + env, plain_time_proto, - core, &[ ( "toString", @@ -731,15 +663,15 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m ], ); bind_well_known_data_property( - core, + env.core, plain_time_proto, 9, JsValue::perm_string( - core.perm_interner() - .string_ptr(core.perm_interner().intern("Temporal.PlainTime").0), + env.string_forge() + .string_ptr(env.string_forge().intern("Temporal.PlainTime").0), ), PropAttributes::new(false, false, true), - realm_id, + env.realm_id, ); // Temporal.PlainDateTime:ISO 日期时间分量、拆分转换与禁止隐式原始值转换。 @@ -750,8 +682,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::plain_date_time_constructor:: as *const (), 3, ); - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(plain_date_time_ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(plain_date_time_ctor.shape_id(), length_si); plain_date_time_ctor.set_shape_id(length_shape); plain_date_time_ctor.ensure_hash_props().push(JsValue::int(3)); let length_pos = plain_date_time_ctor @@ -760,9 +692,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m .saturating_sub(1); plain_date_time_ctor.set_data_meta(length_pos, PropAttributes::new(false, false, true)); apply_binding_table( - world, + env, plain_date_time_ctor, - core, &[ ("from", oxide_builtins::temporal::plain_date_time_from:: as *const (), 1), ( @@ -843,12 +774,11 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::plain_date_time_calendar_id:: as *const (), ), ] { - bind_accessor_getter(core, session, plain_date_time_proto, name, getter); + bind_accessor_getter(env, plain_date_time_proto, name, getter); } apply_binding_table( - world, + env, plain_date_time_proto, - core, &[ ( "toPlainDate", @@ -891,15 +821,15 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m ], ); bind_well_known_data_property( - core, + env.core, plain_date_time_proto, 9, JsValue::perm_string( - core.perm_interner() - .string_ptr(core.perm_interner().intern("Temporal.PlainDateTime").0), + env.string_forge() + .string_ptr(env.string_forge().intern("Temporal.PlainDateTime").0), ), PropAttributes::new(false, false, true), - realm_id, + env.realm_id, ); // Temporal.Duration:构造器、from、分量 getter 与 ISO 字符串转换。 @@ -910,8 +840,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::duration_constructor:: as *const (), 10, ); - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(duration_ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(duration_ctor.shape_id(), length_si); duration_ctor.set_shape_id(length_shape); duration_ctor.ensure_hash_props().push(JsValue::int(0)); let length_pos = duration_ctor @@ -921,9 +851,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m duration_ctor.set_data_meta(length_pos, PropAttributes::new(false, false, true)); apply_binding_table( - world, + env, duration_ctor, - core, &[ ("from", oxide_builtins::temporal::duration_from:: as *const (), 1), ("compare", oxide_builtins::temporal::duration_compare:: as *const (), 2), @@ -954,12 +883,11 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m ("sign", oxide_builtins::temporal::duration_sign:: as *const ()), ("blank", oxide_builtins::temporal::duration_blank:: as *const ()), ] { - bind_accessor_getter(core, session, duration_proto, name, getter); + bind_accessor_getter(env, duration_proto, name, getter); } apply_binding_table( - world, + env, duration_proto, - core, &[ ("abs", oxide_builtins::temporal::duration_abs:: as *const (), 0), ("negated", oxide_builtins::temporal::duration_negated:: as *const (), 0), @@ -980,15 +908,15 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m ], ); bind_well_known_data_property( - core, + env.core, duration_proto, 9, JsValue::perm_string( - core.perm_interner() - .string_ptr(core.perm_interner().intern("Temporal.Duration").0), + env.string_forge() + .string_ptr(env.string_forge().intern("Temporal.Duration").0), ), PropAttributes::new(false, false, true), - realm_id, + env.realm_id, ); // Temporal.PlainMonthDay:构造器、3 个分量 getter 与 toString/toJSON。 @@ -999,8 +927,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::plain_month_day_constructor:: as *const (), 2, ); - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(plain_month_day_ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(plain_month_day_ctor.shape_id(), length_si); plain_month_day_ctor.set_shape_id(length_shape); plain_month_day_ctor.ensure_hash_props().push(JsValue::int(2)); let length_pos = plain_month_day_ctor @@ -1009,9 +937,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m .saturating_sub(1); plain_month_day_ctor.set_data_meta(length_pos, PropAttributes::new(false, false, true)); apply_binding_table( - world, + env, plain_month_day_ctor, - core, &[("from", oxide_builtins::temporal::plain_month_day_from:: as *const (), 1)], ); @@ -1028,12 +955,11 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::plain_month_day_calendar_id:: as *const (), ), ] { - bind_accessor_getter(core, session, plain_month_day_proto, name, getter); + bind_accessor_getter(env, plain_month_day_proto, name, getter); } apply_binding_table( - world, + env, plain_month_day_proto, - core, &[ ( "toString", @@ -1069,15 +995,15 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m ], ); bind_well_known_data_property( - core, + env.core, plain_month_day_proto, 9, JsValue::perm_string( - core.perm_interner() - .string_ptr(core.perm_interner().intern("Temporal.PlainMonthDay").0), + env.string_forge() + .string_ptr(env.string_forge().intern("Temporal.PlainMonthDay").0), ), PropAttributes::new(false, false, true), - realm_id, + env.realm_id, ); // Temporal.PlainYearMonth:构造器、10 个 getter 与 toString/toJSON。 @@ -1088,8 +1014,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::plain_year_month_constructor:: as *const (), 2, ); - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(plain_year_month_ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(plain_year_month_ctor.shape_id(), length_si); plain_year_month_ctor.set_shape_id(length_shape); plain_year_month_ctor.ensure_hash_props().push(JsValue::int(2)); let length_pos = plain_year_month_ctor @@ -1098,9 +1024,8 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m .saturating_sub(1); plain_year_month_ctor.set_data_meta(length_pos, PropAttributes::new(false, false, true)); apply_binding_table( - world, + env, plain_year_month_ctor, - core, &[ ("from", oxide_builtins::temporal::plain_year_month_from:: as *const (), 1), ( @@ -1146,12 +1071,11 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m oxide_builtins::temporal::plain_year_month_era_year:: as *const (), ), ] { - bind_accessor_getter(core, session, plain_year_month_proto, name, getter); + bind_accessor_getter(env, plain_year_month_proto, name, getter); } apply_binding_table( - world, + env, plain_year_month_proto, - core, &[ ( "toString", @@ -1195,26 +1119,26 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m ], ); bind_well_known_data_property( - core, + env.core, plain_year_month_proto, 9, JsValue::perm_string( - core.perm_interner() - .string_ptr(core.perm_interner().intern("Temporal.PlainYearMonth").0), + env.string_forge() + .string_ptr(env.string_forge().intern("Temporal.PlainYearMonth").0), ), PropAttributes::new(false, false, true), - realm_id, + env.realm_id, ); // 把子对象挂到 Temporal 命名空间对象上,再把 Temporal 挂到 global。 - bind_global_value(core, temporal, "Now", JsValue::from_js_object(now_ptr)); - bind_global_value(core, temporal, "Instant", JsValue::from_js_object(instant_ctor_ptr)); - bind_global_value(core, temporal, "PlainDate", JsValue::from_js_object(plain_date_ctor_ptr)); - bind_global_value(core, temporal, "PlainTime", JsValue::from_js_object(plain_time_ctor_ptr)); - bind_global_value(core, temporal, "PlainDateTime", JsValue::from_js_object(plain_date_time_ctor_ptr)); - bind_global_value(core, temporal, "Duration", JsValue::from_js_object(duration_ctor_ptr)); - bind_global_value(core, temporal, "ZonedDateTime", JsValue::from_js_object(zoned_date_time_ctor_ptr)); - bind_global_value(core, temporal, "PlainMonthDay", JsValue::from_js_object(plain_month_day_ctor_ptr)); - bind_global_value(core, temporal, "PlainYearMonth", JsValue::from_js_object(plain_year_month_ctor_ptr)); - bind_global_value(core, global, "Temporal", JsValue::from_js_object(temporal_ptr)); + bind_global_value(env.core, temporal, "Now", JsValue::from_js_object(now_ptr)); + bind_global_value(env.core, temporal, "Instant", JsValue::from_js_object(instant_ctor_ptr)); + bind_global_value(env.core, temporal, "PlainDate", JsValue::from_js_object(plain_date_ctor_ptr)); + bind_global_value(env.core, temporal, "PlainTime", JsValue::from_js_object(plain_time_ctor_ptr)); + bind_global_value(env.core, temporal, "PlainDateTime", JsValue::from_js_object(plain_date_time_ctor_ptr)); + bind_global_value(env.core, temporal, "Duration", JsValue::from_js_object(duration_ctor_ptr)); + bind_global_value(env.core, temporal, "ZonedDateTime", JsValue::from_js_object(zoned_date_time_ctor_ptr)); + bind_global_value(env.core, temporal, "PlainMonthDay", JsValue::from_js_object(plain_month_day_ctor_ptr)); + bind_global_value(env.core, temporal, "PlainYearMonth", JsValue::from_js_object(plain_year_month_ctor_ptr)); + bind_global_value(env.core, global, "Temporal", JsValue::from_js_object(temporal_ptr)); } diff --git a/crates/oxide_vm/src/bindings/bind_typed_array.rs b/crates/oxide_vm/src/bindings/bind_typed_array.rs index af19d5d8..f9aa96d5 100644 --- a/crates/oxide_vm/src/bindings/bind_typed_array.rs +++ b/crates/oxide_vm/src/bindings/bind_typed_array.rs @@ -1,11 +1,8 @@ -use std::sync::Arc; - use crate::bind_constructor; use crate::bindings::{ apply_binding_table, bind_accessor_getter, bind_accessor_getter_key, bind_global_value, - bind_well_known_method_alias, configure_native_constructor, + bind_well_known_method_alias, configure_native_constructor, BindEnv, }; -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; @@ -14,24 +11,24 @@ use oxide_types::value::JsValue; /// /// `realm_id` 是目标所属 realm 的编号:`@@species` 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -fn bind_typed_array_abstract_ctor(core: &Arc, session: &KernelSession, realm_id: u32) { - let ctor_ptr = session.builtin_world().typed_array_constructor.as_ptr() as *mut JsObject; +fn bind_typed_array_abstract_ctor(env: BindEnv<'_>) { + let ctor_ptr = env.world().typed_array_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; configure_native_constructor( ctor, oxide_builtins::typed_array::typed_array_abstract_constructor:: as *const (), 0, ); - let length_si = core.perm_interner().intern("length").0; - let length_shape = core.shape_forge().make_shape(ctor.shape_id(), length_si); + let length_si = env.string_forge().intern("length").0; + let length_shape = env.shape_forge().make_shape(ctor.shape_id(), length_si); ctor.set_shape_id(length_shape); ctor.ensure_hash_props().push(JsValue::int(0)); let pos = ctor.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1); ctor.set_data_meta(pos, PropAttributes::new(false, false, true)); - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); - let world = session.builtin_world(); + let sf = env.string_forge(); + let sh = env.shape_forge(); + let world = env.world(); let ctor_ptr = world.typed_array_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; // SAFETY: of/from 是转成 *const () 的 NativeFn 函数项指针。 @@ -64,11 +61,10 @@ fn bind_typed_array_abstract_ctor(core: &Arc, session: &KernelSessio // (及派生类)沿原型链解析 @@species 得自身(具体构造器无 own 属性)。绑定站 // 与 TA 构造器后续消费面改造共用,先查槽位防重复绑定追加第二访问器槽。 let species_key = - 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() { + oxide_types::private_key::encode_symbol_key(env.realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_SPECIES); + if env.shape_forge().lookup_position(ctor.shape_id(), species_key).is_none() { bind_accessor_getter_key( - core, - session, + env, ctor, species_key, "get [Symbol.species]", @@ -82,20 +78,20 @@ fn bind_typed_array_abstract_ctor(core: &Arc, session: &KernelSessio /// # 步骤 /// 1. 构造器走 hash_props 存储(与 `bind_constructor` 的 hash 路径一致)。 /// 2. 原型走 shape 属性存储(与 `bind_method`/`bind_accessor_getter` 一致)。 -fn set_bypes_per_element(core: &Arc, ctor_ptr: *mut JsObject, proto_ptr: *mut JsObject, bpe: u32) { - let bpe_si = core.perm_interner().intern("BYTES_PER_ELEMENT").0; +fn set_bypes_per_element(env: BindEnv<'_>, ctor_ptr: *mut JsObject, proto_ptr: *mut JsObject, bpe: u32) { + let bpe_si = env.string_forge().intern("BYTES_PER_ELEMENT").0; let bpe_val = JsValue::int(bpe as i32); let attrs = PropAttributes::new(false, false, false); let ctor = unsafe { &mut *ctor_ptr }; ctor.ensure_hash_props().push(bpe_val); let ctor_pos = ctor.ensure_hash_props().len() - 1; - let ctor_shape = core.shape_forge().make_shape(ctor.shape_id(), bpe_si); + let ctor_shape = env.shape_forge().make_shape(ctor.shape_id(), bpe_si); ctor.set_shape_id(ctor_shape); ctor.set_data_meta(ctor_pos as u32, attrs); let proto = unsafe { &mut *proto_ptr }; - let proto_shape = core.shape_forge().make_shape(proto.shape_id(), bpe_si); + let proto_shape = env.shape_forge().make_shape(proto.shape_id(), bpe_si); proto.set_shape_id(proto_shape); let proto_pos = proto.push_prop(bpe_val); proto.set_data_meta(proto_pos, attrs); @@ -103,14 +99,14 @@ fn set_bypes_per_element(core: &Arc, ctor_ptr: *mut JsObject, proto_ } macro_rules! bind_typed_array_constructor { - ($core:expr, $global:expr, $name:literal, $ctor_ptr:expr, $proto_ptr:expr, $bpe:expr, $ctor_fn:path) => {{ + ($env:expr, $global:expr, $name:literal, $ctor_ptr:expr, $proto_ptr:expr, $bpe:expr, $ctor_fn:path) => {{ let ctor = unsafe { &mut *$ctor_ptr }; configure_native_constructor(ctor, ($ctor_fn as fn(&mut $crate::vm::Vm, &[u8]) -> oxide_runtime_api::NativeResult) as *const (), 3); - bind_constructor!($core, $global, $name, $ctor_ptr, $ctor_fn, 3, hash: true); + bind_constructor!($env, $global, $name, $ctor_ptr, $ctor_fn, 3, hash: true); // Function.length 描述符:不可写、不可枚举、可配置。 let len_pos = ctor.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1); ctor.set_data_meta(len_pos, PropAttributes::new(false, false, true)); - set_bypes_per_element($core, $ctor_ptr, $proto_ptr, $bpe); + set_bypes_per_element($env, $ctor_ptr, $proto_ptr, $bpe); }}; } @@ -118,13 +114,12 @@ macro_rules! bind_typed_array_constructor { /// /// `realm_id` 是目标所属 realm 的编号:well-known 符号键按 (realm 编号, 局部 /// 下标) 编码,realm 编号为 0 时与旧编码逐字节一致。 -pub fn bind_typed_array(core: &Arc, session: &KernelSession, global: &mut JsObject, realm_id: u32) { - let shared_proto_ptr = session.builtin_world().typed_array_proto.as_ptr() as *mut JsObject; +pub fn bind_typed_array(env: BindEnv<'_>, global: &mut JsObject) { + let shared_proto_ptr = env.world().typed_array_proto.as_ptr() as *mut JsObject; let shared_proto = unsafe { &mut *shared_proto_ptr }; apply_binding_table( - session.builtin_world(), + env, shared_proto, - core, &[ ("at", oxide_builtins::typed_array::typed_array_at:: as *const (), 1), ("fill", oxide_builtins::typed_array::typed_array_fill:: as *const (), 1), @@ -220,44 +215,39 @@ pub fn bind_typed_array(core: &Arc, session: &KernelSession, global: ); // `keys` 已由方法表独立绑定(索引流 ≠ 值流);@@iterator 与 `values` // 共享同一函数对象。 - bind_well_known_method_alias(core, shared_proto, "values", 0, realm_id); + bind_well_known_method_alias(env.core, shared_proto, "values", 0, env.realm_id); // 原型访问器:视图属性(buffer/byteOffset/byteLength/length)读内部数据槽, // @@toStringTag 返回具体类型名,供 Object.prototype.toString 区分类型。 bind_accessor_getter( - core, - session, + env, shared_proto, "buffer", oxide_builtins::typed_array::typed_array_buffer_getter:: as *const (), ); bind_accessor_getter( - core, - session, + env, shared_proto, "byteOffset", oxide_builtins::typed_array::typed_array_byte_offset_getter:: as *const (), ); bind_accessor_getter( - core, - session, + env, shared_proto, "byteLength", oxide_builtins::typed_array::typed_array_byte_length_getter:: as *const (), ); bind_accessor_getter( - core, - session, + env, shared_proto, "length", oxide_builtins::typed_array::typed_array_length_getter:: as *const (), ); bind_accessor_getter_key( - core, - session, + env, shared_proto, oxide_types::private_key::encode_symbol_key( - realm_id, + env.realm_id, oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG, ), "get [Symbol.toStringTag]", @@ -266,12 +256,12 @@ pub fn bind_typed_array(core: &Arc, session: &KernelSession, global: // 共享原型的 own toString 与 Array.prototype.toString 共享同一函数对象 // (规范:同一内置函数对象;身份与描述符均按 own 属性验收)。 - let to_string_si = core.perm_interner().intern("toString").0; - let array_proto_ref = unsafe { &*session.builtin_world().array_proto.as_ptr() }; + let to_string_si = env.string_forge().intern("toString").0; + let array_proto_ref = unsafe { &*env.world().array_proto.as_ptr() }; // SAFETY: array_proto 由 BuiltinWorld 构造期建立,session 存活期内恒有效。 - if let Some(pos) = core.shape_forge().lookup_position(array_proto_ref.shape_id(), to_string_si) { + if let Some(pos) = env.shape_forge().lookup_position(array_proto_ref.shape_id(), to_string_si) { let value = array_proto_ref.get_prop_at(pos); - let new_shape = core.shape_forge().make_shape(shared_proto.shape_id(), to_string_si); + let new_shape = env.shape_forge().make_shape(shared_proto.shape_id(), to_string_si); shared_proto.set_shape_id(new_shape); let new_pos = shared_proto.push_prop(value); shared_proto.set_data_meta(new_pos, PropAttributes::new(true, false, true)); @@ -280,10 +270,10 @@ pub fn bind_typed_array(core: &Arc, session: &KernelSession, global: // base64/hex 四原型法挂 Uint8Array 专属原型(Uint8ClampedArray 经链继承、 // kind 校验拒绝);两静态法挂 Uint8Array 构造器。 - let world = session.builtin_world(); - let sh = core.shape_forge().as_ref(); - let sf = core.perm_interner().as_ref(); - let u8_proto_ptr = session.builtin_world().uint8array_proto.as_ptr() as *mut JsObject; + let world = env.world(); + let sh = env.shape_forge(); + let sf = env.string_forge(); + let u8_proto_ptr = env.world().uint8array_proto.as_ptr() as *mut JsObject; let u8_proto = unsafe { &mut *u8_proto_ptr }; // SAFETY: 指针来自 session 存活期内的 BuiltinWorld 对象。 let _ = world.bind_method( @@ -334,7 +324,7 @@ pub fn bind_typed_array(core: &Arc, session: &KernelSession, global: }, 1, ); - let u8_ctor_ptr = session.builtin_world().uint8array_constructor.as_ptr() as *mut JsObject; + let u8_ctor_ptr = env.world().uint8array_constructor.as_ptr() as *mut JsObject; let u8_ctor = unsafe { &mut *u8_ctor_ptr }; let _ = world.bind_method( u8_ctor, @@ -361,109 +351,109 @@ pub fn bind_typed_array(core: &Arc, session: &KernelSession, global: 1, ); - bind_typed_array_abstract_ctor(core, session, realm_id); + bind_typed_array_abstract_ctor(env); // 把 `%TypedArray%` 抽象构造器暴露为全局 `TypedArray`(具体构造器的 [[Prototype]])。 let abstract_ctor_val = - JsValue::from_js_object(session.builtin_world().typed_array_constructor.as_ptr() as *mut JsObject); - bind_global_value(core, global, "TypedArray", abstract_ctor_val); + JsValue::from_js_object(env.world().typed_array_constructor.as_ptr() as *mut JsObject); + bind_global_value(env.core, global, "TypedArray", abstract_ctor_val); bind_typed_array_constructor!( - core, + env, global, "Int8Array", - session.builtin_world().int8array_constructor.as_ptr() as *mut JsObject, - session.builtin_world().int8array_proto.as_ptr() as *mut JsObject, + env.world().int8array_constructor.as_ptr() as *mut JsObject, + env.world().int8array_proto.as_ptr() as *mut JsObject, 1, oxide_builtins::typed_array::int8array_constructor ); bind_typed_array_constructor!( - core, + env, global, "Uint8Array", - session.builtin_world().uint8array_constructor.as_ptr() as *mut JsObject, - session.builtin_world().uint8array_proto.as_ptr() as *mut JsObject, + env.world().uint8array_constructor.as_ptr() as *mut JsObject, + env.world().uint8array_proto.as_ptr() as *mut JsObject, 1, oxide_builtins::typed_array::uint8array_constructor ); bind_typed_array_constructor!( - core, + env, global, "Uint8ClampedArray", - session.builtin_world().uint8clampedarray_constructor.as_ptr() as *mut JsObject, - session.builtin_world().uint8clampedarray_proto.as_ptr() as *mut JsObject, + env.world().uint8clampedarray_constructor.as_ptr() as *mut JsObject, + env.world().uint8clampedarray_proto.as_ptr() as *mut JsObject, 1, oxide_builtins::typed_array::uint8clampedarray_constructor ); bind_typed_array_constructor!( - core, + env, global, "Int16Array", - session.builtin_world().int16array_constructor.as_ptr() as *mut JsObject, - session.builtin_world().int16array_proto.as_ptr() as *mut JsObject, + env.world().int16array_constructor.as_ptr() as *mut JsObject, + env.world().int16array_proto.as_ptr() as *mut JsObject, 2, oxide_builtins::typed_array::int16array_constructor ); bind_typed_array_constructor!( - core, + env, global, "Uint16Array", - session.builtin_world().uint16array_constructor.as_ptr() as *mut JsObject, - session.builtin_world().uint16array_proto.as_ptr() as *mut JsObject, + env.world().uint16array_constructor.as_ptr() as *mut JsObject, + env.world().uint16array_proto.as_ptr() as *mut JsObject, 2, oxide_builtins::typed_array::uint16array_constructor ); bind_typed_array_constructor!( - core, + env, global, "Int32Array", - session.builtin_world().int32array_constructor.as_ptr() as *mut JsObject, - session.builtin_world().int32array_proto.as_ptr() as *mut JsObject, + env.world().int32array_constructor.as_ptr() as *mut JsObject, + env.world().int32array_proto.as_ptr() as *mut JsObject, 4, oxide_builtins::typed_array::int32array_constructor ); bind_typed_array_constructor!( - core, + env, global, "Uint32Array", - session.builtin_world().uint32array_constructor.as_ptr() as *mut JsObject, - session.builtin_world().uint32array_proto.as_ptr() as *mut JsObject, + env.world().uint32array_constructor.as_ptr() as *mut JsObject, + env.world().uint32array_proto.as_ptr() as *mut JsObject, 4, oxide_builtins::typed_array::uint32array_constructor ); bind_typed_array_constructor!( - core, + env, global, "Float32Array", - session.builtin_world().float32array_constructor.as_ptr() as *mut JsObject, - session.builtin_world().float32array_proto.as_ptr() as *mut JsObject, + env.world().float32array_constructor.as_ptr() as *mut JsObject, + env.world().float32array_proto.as_ptr() as *mut JsObject, 4, oxide_builtins::typed_array::float32array_constructor ); bind_typed_array_constructor!( - core, + env, global, "Float64Array", - session.builtin_world().float64array_constructor.as_ptr() as *mut JsObject, - session.builtin_world().float64array_proto.as_ptr() as *mut JsObject, + env.world().float64array_constructor.as_ptr() as *mut JsObject, + env.world().float64array_proto.as_ptr() as *mut JsObject, 8, oxide_builtins::typed_array::float64array_constructor ); bind_typed_array_constructor!( - core, + env, global, "BigInt64Array", - session.builtin_world().bigint64array_constructor.as_ptr() as *mut JsObject, - session.builtin_world().bigint64array_proto.as_ptr() as *mut JsObject, + env.world().bigint64array_constructor.as_ptr() as *mut JsObject, + env.world().bigint64array_proto.as_ptr() as *mut JsObject, 8, oxide_builtins::typed_array::bigint64array_constructor ); bind_typed_array_constructor!( - core, + env, global, "BigUint64Array", - session.builtin_world().biguint64array_constructor.as_ptr() as *mut JsObject, - session.builtin_world().biguint64array_proto.as_ptr() as *mut JsObject, + env.world().biguint64array_constructor.as_ptr() as *mut JsObject, + env.world().biguint64array_proto.as_ptr() as *mut JsObject, 8, oxide_builtins::typed_array::biguint64array_constructor ); diff --git a/crates/oxide_vm/src/bindings/bind_weak.rs b/crates/oxide_vm/src/bindings/bind_weak.rs index 990e295e..297a0ca8 100644 --- a/crates/oxide_vm/src/bindings/bind_weak.rs +++ b/crates/oxide_vm/src/bindings/bind_weak.rs @@ -10,7 +10,7 @@ use std::sync::Arc; use crate::bind_constructor; -use crate::bindings::configure_native_constructor; +use crate::bindings::{configure_native_constructor, BindEnv}; use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_types::mem::P; @@ -151,8 +151,9 @@ pub fn bind_weak_map(core: &Arc, session: &mut KernelSession, global ctor.set_data_meta(proto_pos, PropAttributes::new(false, false, false)); world.stub_objects.push(stub); + let env = BindEnv::new(core, &*session, realm_id); bind_constructor!( - core, + env, global, "WeakMap", ctor_ptr, diff --git a/crates/oxide_vm/src/bindings/bind_worker.rs b/crates/oxide_vm/src/bindings/bind_worker.rs index 566a24fb..de6bc3ea 100644 --- a/crates/oxide_vm/src/bindings/bind_worker.rs +++ b/crates/oxide_vm/src/bindings/bind_worker.rs @@ -6,11 +6,8 @@ //! 登记表(session 收尾统一释放),全局 `Worker` 槽经 `bind_constructor!` 原位 //! 安装(既有槽更新槽值、无槽新开)。 -use std::sync::Arc; - use crate::bind_constructor; -use crate::bindings::{apply_binding_table, bind_accessor_getset, bind_accessor_getter, configure_native_constructor}; -use oxide_kernel::kernel::{KernelCore, KernelSession}; +use crate::bindings::{apply_binding_table, bind_accessor_getset, bind_accessor_getter, configure_native_constructor, BindEnv}; use oxide_kernel::shape_forge::{ShapeForge, EMPTY_SHAPE_ID}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::string_forge::PermInterner; @@ -33,10 +30,10 @@ use oxide_types::value::JsValue; /// 主 realm 无 `self` 时为无害占位)。 /// /// `realm_id` 未使用(Worker 无 well-known 符号键),保留签名与其他绑定函数一致。 -pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut JsObject, _realm_id: u32) { - let world = session.builtin_world(); - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); +pub fn bind_worker(env: BindEnv<'_>, global: &mut JsObject) { + let world = env.world(); + let sf = env.string_forge(); + let sh = env.shape_forge(); // ---- 构造器本体(Box 分配,不占 P 字段)---- // 幂等:全局 `Worker` 槽已有构造器时复用(不新建)。 @@ -113,9 +110,8 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut let si_post_message = sf.intern("postMessage").0; if sh.lookup_position(proto.shape_id(), si_post_message).is_none() { apply_binding_table( - world, + env, proto, - core, &[ ("postMessage", crate::worker::bindings::worker_post_message as *const (), 1), ("terminate", crate::worker::bindings::worker_terminate as *const (), 0), @@ -129,8 +125,7 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut let key = sf.intern(name).0; if sh.lookup_position(proto.shape_id(), key).is_none() { bind_accessor_getset( - core, - session, + env, proto, key, &format!("get {name}"), @@ -144,7 +139,7 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut // 全局 `Worker` 槽(bind_constructor! 自带既有槽原位更新、无槽新开)。 bind_constructor!( - core, + env, global, "Worker", ctor_ptr, @@ -158,9 +153,8 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut let si_self_post = sf.intern("postMessage").0; if sh.lookup_position(global.shape_id(), si_self_post).is_none() { apply_binding_table( - world, + env, global, - core, &[ ("postMessage", crate::worker::bindings::self_post_message as *const (), 1), ("close", crate::worker::bindings::self_close as *const (), 0), @@ -172,9 +166,8 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut let si_import_scripts = sf.intern("importScripts").0; if sh.lookup_position(global.shape_id(), si_import_scripts).is_none() { apply_binding_table( - world, + env, global, - core, &[("importScripts", crate::worker::bindings::import_scripts as *const (), 1)], ); } @@ -183,9 +176,8 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut let si_self_add = sf.intern("addEventListener").0; if sh.lookup_position(global.shape_id(), si_self_add).is_none() { apply_binding_table( - world, + env, global, - core, &[ ( "addEventListener", @@ -224,8 +216,7 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut let key = sf.intern(name).0; if sh.lookup_position(global.shape_id(), key).is_none() { bind_accessor_getset( - core, - session, + env, global, key, &format!("get {name}"), @@ -242,7 +233,7 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut let si_name_global = sf.intern("name").0; if sh.lookup_position(global.shape_id(), si_name_global).is_none() { if worker_realm { - bind_accessor_getter(core, session, global, "name", crate::worker::bindings::self_name as *const ()); + bind_accessor_getter(env, global, "name", crate::worker::bindings::self_name as *const ()); } else { bind_global_empty_string_property(global, sf, sh, si_name_global); } @@ -251,8 +242,7 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut if sh.lookup_position(global.shape_id(), si_location).is_none() { if worker_realm { bind_accessor_getter( - core, - session, + env, global, "location", crate::worker::bindings::self_location as *const (), diff --git a/crates/oxide_vm/src/bindings/mod.rs b/crates/oxide_vm/src/bindings/mod.rs index 32bda4a4..7bf06651 100644 --- a/crates/oxide_vm/src/bindings/mod.rs +++ b/crates/oxide_vm/src/bindings/mod.rs @@ -85,15 +85,19 @@ use oxide_types::value::JsValue; /// /// `Copy`:值语义轻量(两个引用加一个 u32),可自由复制传递。 #[derive(Copy, Clone)] -pub(crate) struct BindEnv<'a> { - core: &'a Arc, +pub struct BindEnv<'a> { + pub core: &'a Arc, session: &'a KernelSession, realm_id: u32, } -impl BindEnv<'_> { +impl<'a> BindEnv<'a> { + /// 构造绑定环境。 + pub(crate) fn new(core: &'a Arc, session: &'a KernelSession, realm_id: u32) -> Self { + BindEnv { core, session, realm_id } + } /// 当前 session 的 builtin world(共享借用)。 - fn world(&self) -> &BuiltinWorld { + pub fn world(&self) -> &BuiltinWorld { self.session.builtin_world() } /// 共享 shape forge。 @@ -108,18 +112,18 @@ impl BindEnv<'_> { #[macro_export] macro_rules! bind_constructor { - ($core:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path, $nargs:literal) => {{ - bind_constructor!($core, $global, $name, $ctor_ptr, $ctor_fn, $nargs, hash: false) + ($env:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path, $nargs:literal) => {{ + bind_constructor!($env, $global, $name, $ctor_ptr, $ctor_fn, $nargs, hash: false) }}; - ($core:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path, $nargs:literal, hash: $hash:literal) => {{ - let si = $core.perm_interner().intern($name).0; + ($env:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path, $nargs:literal, hash: $hash:literal) => {{ + let si = $env.string_forge().intern($name).0; let val = $crate::JsValue::from_js_object($ctor_ptr); - if let Some(pos) = $core.shape_forge().lookup_position($global.shape_id(), si) { + if let Some(pos) = $env.shape_forge().lookup_position($global.shape_id(), si) { // 既有槽(重建后保留的 global):原位更新槽值,不追加新槽——旧家族 // 构造器指针不得滞留属性 vec,shape 链不得继续增长。 $global.set_prop_at(pos, val); } else { - let shape = $core.shape_forge().make_shape($global.shape_id(), si); + let shape = $env.shape_forge().make_shape($global.shape_id(), si); $global.set_shape_id(shape); if $hash { $global.ensure_hash_props().push(val); @@ -139,8 +143,8 @@ macro_rules! bind_constructor { ctor.set_native_arg_count($nargs); ctor.type_tag = oxide_types::object::JsObject::OBJ_TYPE_CONSTRUCTOR; // 设置 constructor.length (Function.length = formal parameter count) - let length_si = $core.perm_interner().intern("length").0; - let length_shape = $core.shape_forge().make_shape(ctor.shape_id(), length_si); + let length_si = $env.string_forge().intern("length").0; + let length_shape = $env.shape_forge().make_shape(ctor.shape_id(), length_si); ctor.set_shape_id(length_shape); ctor.ensure_hash_props().push($crate::JsValue::int($nargs as i32)); // length 描述符 { writable:false, enumerable:false, configurable:true } @@ -180,11 +184,10 @@ fn configure_existing_ctor(ctor: &P, native_fn: *const (), arg_count: /// - 表中所有函数项指针须为合法的 `NativeFn`(转成 `*const ()`),此处经 /// `NativeFnPtr::from_raw` 转换。 /// - `bind_method` 的返回值被丢弃:单条绑定失败不中断后续条目。 -pub(crate) fn apply_binding_table( - world: &BuiltinWorld, target: &mut JsObject, core: &Arc, bindings: &[(&'static str, *const (), u8)], -) { - let shape_forge = core.shape_forge().as_ref(); - let string_forge = core.perm_interner().as_ref(); +pub(crate) fn apply_binding_table(env: BindEnv<'_>, target: &mut JsObject, bindings: &[(&'static str, *const (), u8)]) { + let world = env.world(); + let shape_forge = env.shape_forge(); + let string_forge = env.string_forge(); for (name, func, nargs) in bindings { // SAFETY: 绑定表中所有条目都是转成 *const () 的 NativeFn 函数项指针。 let fn_ptr = unsafe { oxide_types::object::NativeFnPtr::from_raw(*func) }; @@ -201,12 +204,10 @@ pub(crate) fn apply_binding_table( /// # 注意事项 /// getter 函数对象登记进 world 释放表,与 `bind_method` 的方法 wrapper 同一生命周期约定 /// (session 收尾时统一释放)。 -pub(crate) fn bind_accessor_getter( - core: &Arc, session: &KernelSession, proto: &mut JsObject, name: &str, getter_fn: *const (), -) { - let si = core.perm_interner().intern(name).0; +pub(crate) fn bind_accessor_getter(env: BindEnv<'_>, proto: &mut JsObject, name: &str, getter_fn: *const ()) { + let si = env.string_forge().intern(name).0; let getter_name = format!("get {name}"); - bind_accessor_getter_key(core, session, proto, si, &getter_name, getter_fn) + bind_accessor_getter_key(env, proto, si, &getter_name, getter_fn) } /// 在原型上按任意属性键(字符串 intern 键或 well-known symbol 键)绑定一个 @@ -220,12 +221,11 @@ pub(crate) fn bind_accessor_getter( /// getter 函数对象登记进 world 释放表,与 `bind_method` 的方法 wrapper 同一生命周期约定 /// (session 收尾时统一释放)。 pub(crate) fn bind_accessor_getter_key( - core: &Arc, session: &KernelSession, proto: &mut JsObject, key: u32, getter_label: &str, - getter_fn: *const (), + env: BindEnv<'_>, proto: &mut JsObject, key: u32, getter_label: &str, getter_fn: *const (), ) { - let shape_forge = core.shape_forge().as_ref(); - let string_forge = core.perm_interner().as_ref(); - let world = session.builtin_world(); + let shape_forge = env.shape_forge(); + let string_forge = env.string_forge(); + let world = env.world(); let si_label = string_forge.intern(getter_label).0; // SAFETY: getter_fn 是转成 *const () 的 NativeFn 函数项指针。 @@ -284,14 +284,13 @@ pub(crate) fn bind_accessor_getter_key( /// # 注意事项 /// getter/setter 函数对象登记进 world 释放表,session 收尾时统一释放, /// 与 `bind_accessor_getter` 的 getter 及方法 wrapper 同一生命周期约定。 -#[expect(clippy::too_many_arguments)] pub(crate) fn bind_accessor_getset( - core: &Arc, session: &KernelSession, proto: &mut JsObject, key: u32, getter_name: &str, - setter_name: &str, getter_fn: *const (), setter_fn: *const (), + env: BindEnv<'_>, proto: &mut JsObject, key: u32, getter_name: &str, setter_name: &str, + getter_fn: *const (), setter_fn: *const (), ) { - let shape_forge = core.shape_forge().as_ref(); - let string_forge = core.perm_interner().as_ref(); - let world = session.builtin_world(); + let shape_forge = env.shape_forge(); + let string_forge = env.string_forge(); + let world = env.world(); let family = world.wrapper_family_of(proto as *const JsObject); let si_length = string_forge.intern("length").0; let si_name = string_forge.intern("name").0; @@ -393,16 +392,15 @@ pub(crate) fn bind_method_alias(core: &Arc, proto: &mut JsObject, so /// /// `realm_id` 是目标所属 realm 的编号:符号键按 (realm 编号, 局部下标) 编码, /// realm 编号为 0 时与旧编码逐字节一致。 -#[expect(clippy::too_many_arguments)] pub(crate) fn bind_well_known_method( - world: &BuiltinWorld, core: &Arc, target: &mut JsObject, well_known_id: u32, method_name: &str, - func: *const (), nargs: u8, realm_id: u32, + env: BindEnv<'_>, target: &mut JsObject, well_known_id: u32, method_name: &str, func: *const (), nargs: u8, ) { - let shape_forge = core.shape_forge().as_ref(); - let string_forge = core.perm_interner().as_ref(); + let world = env.world(); + let shape_forge = env.shape_forge(); + let string_forge = env.string_forge(); // SAFETY: func 是转成 *const () 的 NativeFn 函数项指针。 let fn_ptr = unsafe { oxide_types::object::NativeFnPtr::from_raw(func) }; - let key = oxide_types::private_key::encode_symbol_key(realm_id, well_known_id); + let key = oxide_types::private_key::encode_symbol_key(env.realm_id, well_known_id); let _ = oxide_kernel::builtin::BuiltinWorld::bind_method_key_static( target, shape_forge, @@ -468,12 +466,10 @@ pub(crate) fn bind_well_known_data_property( /// 在 Iterator 函数对象上绑定 `prototype` 属性 = %IteratorPrototype%(规范形状: /// 构造器函数带 prototype 属性;描述符不可写/不可枚举/不可配置)。 -pub(crate) fn bind_iterator_function_prototype( - core: &Arc, session: &KernelSession, iterator: &mut JsObject, -) { - let iter_proto_ptr = session.builtin_world().iterator_proto.as_ptr() as *mut JsObject; - let sf = core.perm_interner().as_ref(); - let sh = core.shape_forge().as_ref(); +pub(crate) fn bind_iterator_function_prototype(env: BindEnv<'_>, iterator: &mut JsObject) { + let iter_proto_ptr = env.world().iterator_proto.as_ptr() as *mut JsObject; + let sf = env.string_forge(); + let sh = env.shape_forge(); let si_prototype = sf.intern("prototype").0; let iterator_shape = sh.make_shape(iterator.shape_id(), si_prototype); iterator.set_shape_id(iterator_shape); @@ -485,15 +481,13 @@ pub(crate) fn bind_iterator_function_prototype( /// 在集合迭代器原型上绑定 `next` 方法(规范形状:next 挂原型,wrapper 不设 own)。 /// /// `next` 键已存在时跳过:保留原型在 dirty reset 重复经过时不再追加重复属性槽。 -pub(crate) fn bind_iterator_proto_next( - core: &Arc, session: &KernelSession, proto: *mut JsObject, func: *const (), -) { +pub(crate) fn bind_iterator_proto_next(env: BindEnv<'_>, proto: *mut JsObject, func: *const ()) { let proto = unsafe { &mut *proto }; - let si_next = core.perm_interner().intern("next").0; - if core.shape_forge().lookup_position(proto.shape_id(), si_next).is_some() { + let si_next = env.string_forge().intern("next").0; + if env.shape_forge().lookup_position(proto.shape_id(), si_next).is_some() { return; } - apply_binding_table(session.builtin_world(), proto, core, &[("next", func, 0)]); + apply_binding_table(env, proto, &[("next", func, 0)]); } /// 把迭代器原型方法安装到当前 builtin world 的迭代器原型上: @@ -508,7 +502,6 @@ pub(crate) fn bind_iterator_proto_next( fn bind_iterator_protos(env: BindEnv<'_>) { let world = env.world(); let core = env.core; - let session = env.session; let realm_id = env.realm_id; // %IteratorPrototype% 自身可迭代:@@iterator 返回 this,经原型链被全部 @@ -518,14 +511,12 @@ fn bind_iterator_protos(env: BindEnv<'_>) { 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() { bind_well_known_method( - world, - core, + env, iter_proto, 0, "iterator", oxide_builtins::iterator::iterator_symbol_iterator:: as *const (), 0, - realm_id, ); } @@ -539,8 +530,7 @@ fn bind_iterator_protos(env: BindEnv<'_>) { .is_none() { bind_accessor_getset( - core, - session, + env, iter_proto, si_constructor, "get constructor", @@ -559,8 +549,7 @@ fn bind_iterator_protos(env: BindEnv<'_>) { .is_none() { bind_accessor_getset( - core, - session, + env, iter_proto, sym_to_string_tag, "get [Symbol.toStringTag]", @@ -575,14 +564,12 @@ fn bind_iterator_protos(env: BindEnv<'_>) { 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() { bind_well_known_method( - world, - core, + env, iter_proto, dispose_id, "[Symbol.dispose]", oxide_builtins::iterator::iterator_dispose:: as *const (), 0, - realm_id, ); } @@ -592,9 +579,8 @@ fn bind_iterator_protos(env: BindEnv<'_>) { let si_for_each = core.perm_interner().intern("forEach").0; if core.shape_forge().lookup_position(iter_proto.shape_id(), si_for_each).is_none() { apply_binding_table( - world, + env, iter_proto, - core, &[ ("forEach", oxide_builtins::iterator::iterator_for_each:: as *const (), 1), ("every", oxide_builtins::iterator::iterator_every:: as *const (), 1), @@ -611,9 +597,8 @@ fn bind_iterator_protos(env: BindEnv<'_>) { let si_map = core.perm_interner().intern("map").0; if core.shape_forge().lookup_position(iter_proto.shape_id(), si_map).is_none() { apply_binding_table( - world, + env, iter_proto, - core, &[ ("map", oxide_builtins::iterator::iterator_map:: as *const (), 1), ("filter", oxide_builtins::iterator::iterator_filter:: as *const (), 1), @@ -634,14 +619,12 @@ fn bind_iterator_protos(env: BindEnv<'_>) { ); if core.shape_forge().lookup_position(aiter_proto.shape_id(), sym_aiter).is_none() { bind_well_known_method( - world, - core, + env, aiter_proto, oxide_types::private_key::WELL_KNOWN_SYMBOL_ASYNC_ITERATOR, "[Symbol.asyncIterator]", crate::async_generator::async_generator_symbol_async_iterator as *const (), 0, - realm_id, ); } let sym_adispose = oxide_types::private_key::encode_symbol_key( @@ -654,14 +637,12 @@ fn bind_iterator_protos(env: BindEnv<'_>) { .is_none() { bind_well_known_method( - world, - core, + env, aiter_proto, oxide_types::private_key::WELL_KNOWN_SYMBOL_ASYNC_DISPOSE, "[Symbol.asyncDispose]", crate::async_generator::async_iterator_async_dispose as *const (), 0, - realm_id, ); } @@ -673,9 +654,8 @@ fn bind_iterator_protos(env: BindEnv<'_>) { let si_next = core.perm_interner().intern("next").0; if core.shape_forge().lookup_position(helper_proto.shape_id(), si_next).is_none() { apply_binding_table( - world, + env, helper_proto, - core, &[ ("next", oxide_builtins::iterator::iterator_helper_next:: as *const (), 0), ( @@ -700,26 +680,22 @@ fn bind_iterator_protos(env: BindEnv<'_>) { // %ArrayIteratorPrototype% 服务 Array/TA 两族;Map/Set 共用按 `__mode__` // 分发的实现;%RegExpStringIteratorPrototype% 供 matchAll。 bind_iterator_proto_next( - core, - session, + env, world.array_iterator_proto.as_ptr() as *mut JsObject, oxide_builtins::array::array_iterator_next:: as *const (), ); bind_iterator_proto_next( - core, - session, + env, world.map_iterator_proto.as_ptr() as *mut JsObject, oxide_builtins::iterator::map_set_iterator_next:: as *const (), ); bind_iterator_proto_next( - core, - session, + env, world.set_iterator_proto.as_ptr() as *mut JsObject, oxide_builtins::iterator::map_set_iterator_next:: as *const (), ); bind_iterator_proto_next( - core, - session, + env, world.regexp_string_iterator_proto.as_ptr() as *mut JsObject, oxide_builtins::string::string_match_all_next:: as *const (), ); @@ -876,9 +852,8 @@ fn bind_error_subtype_global( fn bind_global_functions(env: BindEnv<'_>, global: &mut JsObject) { apply_binding_table( - env.world(), + env, global, - env.core, &[ // parseInt 形式参数为 (string, radix),length 按规范取 2。 ("parseInt", oxide_builtins::number::number_parse_int:: as *const (), 2), @@ -915,9 +890,8 @@ fn bind_reflect_global(env: BindEnv<'_>, global: &mut JsObject) { JsValue::from_js_object(env.world().object_proto.as_ptr() as *mut JsObject), )); apply_binding_table( - env.world(), + env, &mut reflect, - env.core, &[ ("apply", oxide_builtins::reflect::reflect_apply:: as *const (), 3), ("construct", oxide_builtins::reflect::reflect_construct:: as *const (), 2), @@ -977,11 +951,10 @@ fn bind_iterator_global(env: BindEnv<'_>, global: &mut JsObject) { 0, ); bind_iterator_ctor_identity(env.core, &mut iterator); - bind_iterator_function_prototype(env.core, env.session, &mut iterator); + bind_iterator_function_prototype(env, &mut iterator); apply_binding_table( - env.world(), + env, &mut iterator, - env.core, &[("from", oxide_builtins::iterator::iterator_from:: as *const (), 1)], ); let iterator_ptr = Box::into_raw(iterator); @@ -1266,13 +1239,13 @@ pub fn bind_global_builtin_slots( bind_reflect_global(env, global); bind_iterator_global(env, global); - bind_worker::bind_worker(core, session, global, realm_id); - bind_disposable_stack::bind_disposable_stack(core, session, global, realm_id); - bind_async_disposable_stack::bind_async_disposable_stack(core, session, global, realm_id); + bind_worker::bind_worker(env, global); + bind_disposable_stack::bind_disposable_stack(env, global); + bind_async_disposable_stack::bind_async_disposable_stack(env, global); bind_stub_globals(env, global); - bind_bigint::bind_bigint(core, session, global, realm_id); + bind_bigint::bind_bigint(env, global); bind_global_functions(env, global); - crate::test262_host::bind_test262_host(core, session, global); + crate::test262_host::bind_test262_host(env, global); let global_this = JsValue::from_js_object(global as *mut JsObject); bind_existing_global(core, global, "globalThis", global_this); } @@ -1290,111 +1263,114 @@ pub fn rebind_dirty_builtins( ) { let global_ptr = session.global_object().as_ptr() as *mut JsObject; let global = unsafe { &mut *global_ptr }; + let env = BindEnv { + core, + session: &*session, + realm_id, + }; if dirty.map_or(true, |d| d.object) { - bind_object::bind_object(core, session, global); + bind_object::bind_object(env, global); // object 家族重建连带重建 6 个迭代器原型与两资源栈原型(其链到新 // Object.prototype),须同步安装原型方法并让保留的 global 构造器指向新原型。 - let env = BindEnv { - core, - session: &*session, - realm_id, - }; bind_iterator_protos(env); sync_iterator_function_prototype(env, global); - bind_disposable_stack::bind_disposable_stack_protos(core, session, realm_id); - bind_disposable_stack::sync_disposable_stack_ctor(core, session, global); - 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_disposable_stack::bind_disposable_stack_protos(env); + bind_disposable_stack::sync_disposable_stack_ctor(env, global); + bind_async_disposable_stack::bind_async_disposable_stack_protos(env); + bind_async_disposable_stack::sync_async_disposable_stack_ctor(env, global); } if dirty.map_or(true, |d| d.array) { - bind_array::bind_array(core, session, global, realm_id); + bind_array::bind_array(env, global); } if dirty.map_or(true, |d| d.array_buffer) { - bind_array_buffer::bind_array_buffer(core, session, global, realm_id); + bind_array_buffer::bind_array_buffer(env, global); } 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(env, global); } if dirty.map_or(true, |d| d.data_view) { - bind_data_view::bind_data_view(core, session, global); + bind_data_view::bind_data_view(env, global); } if dirty.map_or(true, |d| d.typed_array_family) { - bind_typed_array::bind_typed_array(core, session, global, realm_id); + bind_typed_array::bind_typed_array(env, global); } if dirty.map_or(true, |d| d.error_family) { - bind_error::bind_error(core, session, global); + bind_error::bind_error(env, global); } if dirty.map_or(true, |d| d.string) { - bind_string::bind_string(core, session, global, realm_id); + bind_string::bind_string(env, global); } if dirty.map_or(true, |d| d.number) { - bind_number::bind_number(core, session, global); + bind_number::bind_number(env, global); } if dirty.map_or(true, |d| d.math) { - bind_math::bind_math(core, session, global); + bind_math::bind_math(env, global); } if dirty.map_or(true, |d| d.atomics) { - bind_atomics::bind_atomics(core, session, global); + bind_atomics::bind_atomics(env, global); } if dirty.map_or(true, |d| d.json) { - bind_json::bind_json(core, session, global); + bind_json::bind_json(env, global); } if dirty.map_or(true, |d| d.date) { - bind_date::bind_date(core, session, global); + bind_date::bind_date(env, global); } if dirty.map_or(true, |d| d.set) { - bind_set::bind_set(core, session, global, realm_id); + bind_set::bind_set(env, global); } if dirty.map_or(true, |d| d.map) { - bind_map::bind_map(core, session, global, realm_id); + bind_map::bind_map(env, global); } if dirty.map_or(true, |d| d.boolean) { - bind_boolean::bind_boolean(core, session, global); + bind_boolean::bind_boolean(env, global); } if dirty.map_or(true, |d| d.function) { - bind_function::bind_function(core, session, global, realm_id); + bind_function::bind_function(env, global); } if dirty.map_or(true, |d| d.regexp) { - bind_regexp::bind_regexp(core, session, global, realm_id); + bind_regexp::bind_regexp(env, global); } if dirty.map_or(true, |d| d.symbol_family) { - bind_symbol::bind_symbol(core, session, global, realm_id); + bind_symbol::bind_symbol(env, global); } if dirty.map_or(true, |d| d.temporal) { - bind_temporal::bind_temporal(core, session, global, realm_id); + bind_temporal::bind_temporal(env, global); } + // 独占函数(bind_stubs / bind_weak_map)需要 session 的可变借用,与 env + // 的共享借用冲突;env 的最后一次使用在上面的 temporal 分支,独占调用 + // 之后重建 env 供后续分支使用。 if dirty.map_or(true, |d| d.stubs) { bind_stubs::bind_stubs(core, session, global, realm_id); // WeakMap 真构造器面与 stub 族同脏位:原型对象经 leaked 登记表迁移, // 重绑时全局槽原位更新,不占 BuiltinWorld 槽。 bind_weak::bind_weak_map(core, session, global, realm_id); } - if dirty.map_or(true, |d| d.stubs) { - bind_bigint::bind_bigint(core, session, global, realm_id); - } - if dirty.map_or(true, |d| d.message_channel) { - bind_message_channel::bind_message_channel(core, session, global, realm_id); - } - if dirty.map_or(true, |d| d.broadcast_channel) { - bind_broadcast_channel::bind_broadcast_channel(core, session, global, realm_id); - } - if dirty.map_or(true, |d| d.event) { - bind_event::bind_event(core, session, global, realm_id); - } - if dirty.map_or(true, |d| d.console) { - bind_console::bind_console(core, session, global); - } - // worker 构造器是 Box 分配对象(不在 BuiltinWorld 快照内),不占脏位: - // 无条件重绑(构造器经 lookup_position 守卫复用,幂等)。 - bind_worker::bind_worker(core, session, global, realm_id); - // tag 目标横跨多个脏分组(Map/Set/DataView/Math/JSON/迭代器原型), - // 各组各自重绑后统一补装;安装点自带幂等检查。 let env = BindEnv { core, session: &*session, realm_id, }; + if dirty.map_or(true, |d| d.stubs) { + bind_bigint::bind_bigint(env, global); + } + if dirty.map_or(true, |d| d.message_channel) { + bind_message_channel::bind_message_channel(env, global); + } + if dirty.map_or(true, |d| d.broadcast_channel) { + bind_broadcast_channel::bind_broadcast_channel(env, global); + } + if dirty.map_or(true, |d| d.event) { + bind_event::bind_event(env, global); + } + if dirty.map_or(true, |d| d.console) { + bind_console::bind_console(env, global); + } + // worker 构造器是 Box 分配对象(不在 BuiltinWorld 快照内),不占脏位: + // 无条件重绑(构造器经 lookup_position 守卫复用,幂等)。 + bind_worker::bind_worker(env, global); + // tag 目标横跨多个脏分组(Map/Set/DataView/Math/JSON/迭代器原型), + // 各组各自重绑后统一补装;安装点自带幂等检查。 install_to_string_tags(env); } @@ -1406,13 +1382,18 @@ pub fn init_kernel_builtins(core: &Arc, session: &mut KernelSession, rebind_dirty_builtins(core, session, None, realm_id); let global_ptr = session.global_object().as_ptr() as *mut oxide_types::object::JsObject; let global = unsafe { &mut *global_ptr }; - bind_iterator::bind_iterator(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, realm_id); - bind_reflect::bind_reflect(core, session, global); - bind_global::bind_global(core, session, global); + let env = BindEnv { + core, + session: &*session, + realm_id, + }; + bind_iterator::bind_iterator(env, global); + bind_disposable_stack::bind_disposable_stack(env, global); + bind_async_disposable_stack::bind_async_disposable_stack(env, global); + bind_reflect::bind_reflect(env, global); + bind_global::bind_global(env, global); bind_global_value(core, global, "globalThis", JsValue::from_js_object(global_ptr)); - bind_console::bind_console(core, session, global); - crate::test262_host::bind_test262_host(core, session, global); + bind_console::bind_console(env, global); + crate::test262_host::bind_test262_host(env, global); session.record_snapshot(); } diff --git a/crates/oxide_vm/src/promise/constructor.rs b/crates/oxide_vm/src/promise/constructor.rs index b0e043cf..5b8465a1 100644 --- a/crates/oxide_vm/src/promise/constructor.rs +++ b/crates/oxide_vm/src/promise/constructor.rs @@ -353,8 +353,7 @@ impl Vm { // Promise[Symbol.species] 访问器:getter 返回 receiver,派生类沿静态原型链 // 解析 @@species 得自身构造器。ctor 经本函数每次调用全新构造,同键槽不累积。 crate::bindings::bind_accessor_getter_key( - &self.kernel_core, - &self.realm.session.borrow(), + crate::bindings::BindEnv::new(&self.kernel_core, &self.realm.session.borrow(), self.realm_id()), ctor_mut, oxide_types::private_key::encode_symbol_key( self.realm_id(), diff --git a/crates/oxide_vm/src/test262_host.rs b/crates/oxide_vm/src/test262_host.rs index e08dc479..e146b8ae 100644 --- a/crates/oxide_vm/src/test262_host.rs +++ b/crates/oxide_vm/src/test262_host.rs @@ -5,15 +5,12 @@ //! `$262.*` 的测试真实执行而非一律抛 `ReferenceError` 被 runner 吞为 skip; //! 未实现的方法抛 `not supported` 错误,runner 按能力缺失归类。 -use std::sync::Arc; - -use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_runtime_api::{to_units_full, NativeResult}; use oxide_types::object::{JsObject, NativeFnPtr}; use oxide_types::value::JsValue; -use crate::bindings::{apply_binding_table, bind_global_value}; +use crate::bindings::{apply_binding_table, bind_global_value, BindEnv}; use crate::vm::Vm; /// `$262` 未实现方法统一抛错:消息带 `not supported`,runner 据此按能力缺失跳过。 @@ -111,13 +108,12 @@ pub fn is_html_dda_call(_vm: &mut Vm, _args: &[u8]) -> NativeResult { /// - 宿主对象登记进 world 释放表,session 收尾时统一释放(与 Reflect/Iterator /// 等全局对象同一约定);每次调用新建对象,同一 session 内重复绑定会泄漏旧对象 /// (全量初始化与 full_reset 频率低,可接受)。 -pub fn bind_test262_host(core: &Arc, session: &KernelSession, global: &mut JsObject) { - let object_proto = session.builtin_world().object_proto.as_ptr() as *mut JsObject; +pub fn bind_test262_host(env: BindEnv<'_>, global: &mut JsObject) { + let object_proto = env.world().object_proto.as_ptr() as *mut JsObject; let mut host = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto)); apply_binding_table( - session.builtin_world(), + env, &mut host, - core, &[ ("evalScript", eval_script as *const (), 1), ("detachArrayBuffer", detach_array_buffer as *const (), 1), @@ -127,7 +123,7 @@ pub fn bind_test262_host(core: &Arc, session: &KernelSession, global ], ); let global_this = JsValue::from_js_object(global as *mut JsObject); - bind_global_value(core, &mut host, "global", global_this); + bind_global_value(env.core, &mut host, "global", global_this); // [[IsHTMLDDA]] 宿主值(B.3.4):可调用(被调用时返回 null), // ToBoolean/typeof/宽松相等按 undefined 处理,Type 与其余强制转换按普通对象处理。 let mut dda = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto)); @@ -136,9 +132,9 @@ pub fn bind_test262_host(core: &Arc, session: &KernelSession, global dda.set_native_fn(Some(unsafe { NativeFnPtr::from_raw(is_html_dda_call as *const ()) })); dda.set_native_arg_count(0); let dda_ptr = Box::into_raw(Box::new(dda)); - session.builtin_world().track_leaked_object(dda_ptr); - bind_global_value(core, &mut host, "IsHTMLDDA", JsValue::from_js_object(dda_ptr)); + env.world().track_leaked_object(dda_ptr); + bind_global_value(env.core, &mut host, "IsHTMLDDA", JsValue::from_js_object(dda_ptr)); let host_ptr = Box::into_raw(Box::new(host)); - session.builtin_world().track_leaked_object(host_ptr); - bind_global_value(core, global, "$262", JsValue::from_js_object(host_ptr)); + env.world().track_leaked_object(host_ptr); + bind_global_value(env.core, global, "$262", JsValue::from_js_object(host_ptr)); }