refactor: 绑定层函数签名收敛为 BindEnv 单参

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