refactor: 清理未使用符号,合并bind_constructor宏,统一init/rebind绑定列表,bind_number改为表驱动

This commit is contained in:
爱特每羊队
2026-06-24 12:12:44 +08:00
parent f602ae5f00
commit 6bf5daa1af
27 changed files with 140 additions and 297 deletions
-12
View File
@@ -153,18 +153,6 @@ pub enum OpCode {
} }
impl OpCode { impl OpCode {
pub fn is_implemented(&self) -> bool {
!matches!(
self,
OpCode::PROFILE_TYPE
| OpCode::PROFILE_SHAPE
| OpCode::PROFILE_BRANCH
| OpCode::PROFILE_CALL
| OpCode::FORK
| OpCode::JOIN
)
}
pub fn has_ic_ext_words(&self) -> bool { pub fn has_ic_ext_words(&self) -> bool {
matches!( matches!(
self, self,
+1 -1
View File
@@ -646,7 +646,7 @@ impl Compiler {
) )
} }
#[allow(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub(crate) fn compile_function_body_with_field_hooks<'a, C, E>( pub(crate) fn compile_function_body_with_field_hooks<'a, C, E>(
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, &self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
is_expression_body: bool, extra_bindings: &[(&str, u8)], body_context: FunctionBodyContext, is_expression_body: bool, extra_bindings: &[(&str, u8)], body_context: FunctionBodyContext,
-44
View File
@@ -144,20 +144,6 @@ pub struct RegExpMethods {
pub to_string: *const (), pub to_string: *const (),
} }
pub struct NumberMethods {
pub is_nan: *const (),
pub is_finite: *const (),
pub parse_int: *const (),
pub parse_float: *const (),
pub to_string: *const (),
pub to_fixed: *const (),
pub is_integer: *const (),
pub is_safe_integer: *const (),
pub to_exponential: *const (),
pub to_precision: *const (),
pub value_of: *const (),
}
pub struct FunctionMethods { pub struct FunctionMethods {
pub call: *const (), pub call: *const (),
pub apply: *const (), pub apply: *const (),
@@ -979,36 +965,6 @@ impl BuiltinWorld {
); );
} }
pub fn bind_number_methods(&self, methods: &NumberMethods, string_forge: &StringForge, shape_forge: &ShapeForge) {
let ctor_ptr = P::as_ptr(&self.number_constructor) as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr };
let proto_ptr = P::as_ptr(&self.number_proto) as *mut JsObject;
let proto = unsafe { &mut *proto_ptr };
bind_methods!(
self,
ctor,
string_forge,
shape_forge,
("isNaN", methods.is_nan, 1),
("isFinite", methods.is_finite, 1),
("parseInt", methods.parse_int, 1),
("parseFloat", methods.parse_float, 1),
("isInteger", methods.is_integer, 1),
("isSafeInteger", methods.is_safe_integer, 1),
);
bind_methods!(
self,
proto,
string_forge,
shape_forge,
("toString", methods.to_string, 0),
("toFixed", methods.to_fixed, 0),
("toExponential", methods.to_exponential, 0),
("toPrecision", methods.to_precision, 0),
("valueOf", methods.value_of, 0),
);
}
pub fn bind_function_methods( pub fn bind_function_methods(
&self, methods: &FunctionMethods, string_forge: &StringForge, shape_forge: &ShapeForge, &self, methods: &FunctionMethods, string_forge: &StringForge, shape_forge: &ShapeForge,
) { ) {
-5
View File
@@ -80,11 +80,6 @@ impl KernelConfig {
pub fn set_session_gc_threshold(&mut self, bytes: usize) { pub fn set_session_gc_threshold(&mut self, bytes: usize) {
self.session_gc_threshold = bytes; self.session_gc_threshold = bytes;
} }
pub fn with_session_gc_threshold(mut self, bytes: usize) -> Self {
self.session_gc_threshold = bytes;
self
}
} }
impl Default for KernelConfig { impl Default for KernelConfig {
+2 -2
View File
@@ -14,8 +14,8 @@ pub fn hash16(s: &str) -> u16 {
} }
pub struct StringEntry { pub struct StringEntry {
pub data: String, pub(crate) data: String,
pub ref_count: AtomicU32, pub(crate) ref_count: AtomicU32,
pub hash: u16, pub hash: u16,
} }
+1 -1
View File
@@ -670,7 +670,7 @@ fn read_heartbeat(path: &Path) -> Option<Heartbeat> {
/// and a fresh child resumes from `culprit + 1`. A child that crashes mid-test /// and a fresh child resumes from `culprit + 1`. A child that crashes mid-test
/// is recovered through the same path. Timeouts/crashes count as skip by default /// is recovered through the same path. Timeouts/crashes count as skip by default
/// and fail under `--no-skip`. /// and fail under `--no-skip`.
#[allow(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
fn supervise_window( fn supervise_window(
exe: &Path, args: &[String], no_skip: bool, wstart: usize, wend: usize, timeout: Duration, startup_grace: Duration, exe: &Path, args: &[String], no_skip: bool, wstart: usize, wend: usize, timeout: Duration, startup_grace: Duration,
paths: &[PathBuf], window_id: usize, paths: &[PathBuf], window_id: usize,
+5 -7
View File
@@ -15,16 +15,14 @@ impl<T> P<T> {
Self(Arc::new(value)) Self(Arc::new(value))
} }
pub fn from_arena(value: &T) -> Self
where
T: Clone,
{
Self(Arc::new(value.clone()))
}
pub fn as_ptr(&self) -> *const T { pub fn as_ptr(&self) -> *const T {
Arc::as_ptr(&self.0) Arc::as_ptr(&self.0)
} }
#[inline(always)]
pub fn as_mut_ptr(&self) -> *mut T {
self.as_ptr() as *mut T
}
} }
impl<T> Clone for P<T> { impl<T> Clone for P<T> {
-11
View File
@@ -648,17 +648,6 @@ impl JsObject {
pos as u32 pos as u32
} }
/// Get a pointer to the JsValue at position.
/// Returns None if hash_props not allocated or position out of bounds.
pub fn prop_ptr_at(&self, position: impl PropIndex) -> Option<*const JsValue> {
if self.hash_props.is_null() {
return None;
}
// SAFETY: hash_props was set from Box<Vec<JsValue>> in ensure_hash_props/new_array.
let vec = unsafe { &*(self.hash_props as *const Vec<JsValue>) };
vec.get(position.to_u32() as usize).map(|v| v as *const JsValue)
}
/// Get the length of hash_props vec (returns 0 if not allocated). /// Get the length of hash_props vec (returns 0 if not allocated).
pub fn prop_vec_len(&self) -> usize { pub fn prop_vec_len(&self) -> usize {
if self.hash_props.is_null() { if self.hash_props.is_null() {
-4
View File
@@ -163,10 +163,6 @@ pub fn shape_prop_count(shape_id: ShapeId) -> u32 {
store().lock().unwrap().shape_prop_count(shape_id) store().lock().unwrap().shape_prop_count(shape_id)
} }
pub fn init_shape_store() {
let _ = store();
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
+2 -2
View File
@@ -4,7 +4,7 @@ use oxide_kernel::builtin::ArrayMethods;
use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
use crate::bind_constructor_hash; use crate::bind_constructor;
pub fn bind_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { pub fn bind_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let _array_methods = ArrayMethods { let _array_methods = ArrayMethods {
@@ -47,5 +47,5 @@ pub fn bind_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
); );
let ctor_ptr = session.builtin_world().array_constructor.as_ptr() as *mut JsObject; let ctor_ptr = session.builtin_world().array_constructor.as_ptr() as *mut JsObject;
bind_constructor_hash!(core, global, "Array", ctor_ptr, crate::builtins::array::array_constructor, 1); bind_constructor!(core, global, "Array", ctor_ptr, crate::builtins::array::array_constructor, 1, hash: true);
} }
@@ -1,6 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crate::bind_constructor_hash; use crate::bind_constructor;
use crate::bindings::{apply_binding_table, configure_native_constructor}; use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
@@ -31,12 +31,13 @@ pub fn bind_array_buffer(core: &Arc<KernelCore>, session: &KernelSession, global
], ],
); );
bind_constructor_hash!( bind_constructor!(
core, core,
global, global,
"ArrayBuffer", "ArrayBuffer",
ctor_ptr, ctor_ptr,
crate::builtins::array_buffer::array_buffer_constructor, crate::builtins::array_buffer::array_buffer_constructor,
1 1,
hash: true
); );
} }
+2 -2
View File
@@ -1,6 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crate::bind_constructor_hash; use crate::bind_constructor;
use crate::bindings::{apply_binding_table, configure_native_constructor}; use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
@@ -23,5 +23,5 @@ pub fn bind_boolean(core: &Arc<KernelCore>, session: &KernelSession, global: &mu
], ],
); );
bind_constructor_hash!(core, global, "Boolean", ctor_ptr, crate::builtins::boolean::boolean_constructor, 1); bind_constructor!(core, global, "Boolean", ctor_ptr, crate::builtins::boolean::boolean_constructor, 1, hash: true);
} }
@@ -1,6 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crate::bind_constructor_hash; use crate::bind_constructor;
use crate::bindings::{apply_binding_table, configure_native_constructor}; use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
@@ -42,5 +42,5 @@ pub fn bind_data_view(core: &Arc<KernelCore>, session: &KernelSession, global: &
], ],
); );
bind_constructor_hash!(core, global, "DataView", ctor_ptr, crate::builtins::data_view::data_view_constructor, 3); bind_constructor!(core, global, "DataView", ctor_ptr, crate::builtins::data_view::data_view_constructor, 3, hash: true);
} }
+2 -2
View File
@@ -1,6 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crate::bind_constructor_hash; use crate::bind_constructor;
use crate::bindings::{apply_binding_table, configure_native_constructor}; use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
@@ -27,5 +27,5 @@ pub fn bind_map(core: &Arc<KernelCore>, session: &KernelSession, global: &mut Js
], ],
); );
bind_constructor_hash!(core, global, "Map", ctor_ptr, crate::builtins::map::map_constructor, 1); bind_constructor!(core, global, "Map", ctor_ptr, crate::builtins::map::map_constructor, 1, hash: true);
} }
+54 -57
View File
@@ -1,72 +1,69 @@
use std::sync::Arc; use std::sync::Arc;
use oxide_kernel::bind_methods; use crate::bind_constructor;
use oxide_kernel::builtin::NumberMethods; use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::{JsObject, NativeFnPtr}; use oxide_types::object::JsObject;
use oxide_types::value::JsValue; use oxide_types::value::JsValue;
pub fn bind_number(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { pub fn bind_number(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let number_methods = NumberMethods { let ctor_ptr = session.builtin_world().number_constructor.as_ptr() as *mut JsObject;
is_nan: crate::builtins::number::number_is_nan as *const (), let ctor = unsafe { &mut *ctor_ptr };
is_finite: crate::builtins::number::number_is_finite as *const (), let proto_ptr = session.builtin_world().number_proto.as_ptr() as *mut JsObject;
parse_int: crate::builtins::number::number_parse_int as *const (), let proto = unsafe { &mut *proto_ptr };
parse_float: crate::builtins::number::number_parse_float as *const (),
to_string: crate::builtins::number::number_to_string as *const (), configure_native_constructor(ctor, crate::builtins::number::number_constructor as *const (), 1);
to_fixed: crate::builtins::number::number_to_fixed as *const (),
is_integer: crate::builtins::number::number_is_integer as *const (), apply_binding_table(
is_safe_integer: crate::builtins::number::number_is_safe_integer as *const (), session.builtin_world(),
to_exponential: crate::builtins::number::number_to_exponential as *const (), ctor,
to_precision: crate::builtins::number::number_to_precision as *const (), core,
value_of: crate::builtins::number::number_value_of as *const (), &[
}; ("isNaN", crate::builtins::number::number_is_nan as *const (), 1),
session.builtin_world().bind_number_methods( ("isFinite", crate::builtins::number::number_is_finite as *const (), 1),
&number_methods, ("isInteger", crate::builtins::number::number_is_integer as *const (), 1),
core.string_forge().as_ref(), ("isSafeInteger", crate::builtins::number::number_is_safe_integer as *const (), 1),
core.shape_forge().as_ref(), ],
); );
let si_num = core.string_forge().intern("Number").0; apply_binding_table(
let num_shape = core.shape_forge().make_shape(global.shape_id(), si_num); session.builtin_world(),
let num_val = JsValue::from_js_object(session.builtin_world().number_constructor.as_ptr() as *mut JsObject); proto,
global.set_shape_id(num_shape); core,
global.ensure_hash_props().push(num_val); &[
global.bump_generation(); ("toString", crate::builtins::number::number_to_string as *const (), 0),
("toFixed", crate::builtins::number::number_to_fixed as *const (), 0),
("toExponential", crate::builtins::number::number_to_exponential as *const (), 0),
("toPrecision", crate::builtins::number::number_to_precision as *const (), 0),
("valueOf", crate::builtins::number::number_value_of as *const (), 0),
],
);
{ for (name, value) in [
let num_ctor_ptr = session.builtin_world().number_constructor.as_ptr() as *mut JsObject; ("EPSILON", JsValue::float(2.220446049250313e-16)),
let num_ctor = unsafe { &mut *num_ctor_ptr }; ("MAX_SAFE_INTEGER", JsValue::float(9007199254740991f64)),
// SAFETY: number_constructor is a NativeFn fn-item. ("MIN_SAFE_INTEGER", JsValue::float(-9007199254740991f64)),
num_ctor.set_native_fn(Some(unsafe { ("MAX_VALUE", JsValue::float(1.7976931348623157e308)),
NativeFnPtr::from_raw(crate::builtins::number::number_constructor as *const ()) ("MIN_VALUE", JsValue::float(5e-324)),
})); ("NaN", JsValue::float(f64::NAN)),
num_ctor.set_native_arg_count(1); ("NEGATIVE_INFINITY", JsValue::float(f64::NEG_INFINITY)),
("POSITIVE_INFINITY", JsValue::float(f64::INFINITY)),
for (name, value) in [ ] {
("EPSILON", JsValue::float(2.220446049250313e-16)), ctor.ensure_hash_props().push(value);
("MAX_SAFE_INTEGER", JsValue::float(9007199254740991f64)), let prop_si = core.string_forge().intern(name).0;
("MIN_SAFE_INTEGER", JsValue::float(-9007199254740991f64)), let next_shape = core.shape_forge().make_shape(ctor.shape_id(), prop_si);
("MAX_VALUE", JsValue::float(1.7976931348623157e308)), ctor.set_shape_id(next_shape);
("MIN_VALUE", JsValue::float(5e-324)),
("NaN", JsValue::float(f64::NAN)),
("NEGATIVE_INFINITY", JsValue::float(f64::NEG_INFINITY)),
("POSITIVE_INFINITY", JsValue::float(f64::INFINITY)),
] {
num_ctor.ensure_hash_props().push(value);
let prop_si = core.string_forge().intern(name).0;
let next_shape = core.shape_forge().make_shape(num_ctor.shape_id(), prop_si);
num_ctor.set_shape_id(next_shape);
}
} }
let pi_fn = crate::builtins::number::number_parse_int as *const (); bind_constructor!(core, global, "Number", ctor_ptr, crate::builtins::number::number_constructor, 1, hash: true);
let pf_fn = crate::builtins::number::number_parse_float as *const ();
bind_methods!( apply_binding_table(
session.builtin_world(), session.builtin_world(),
global, global,
core.string_forge().as_ref(), core,
core.shape_forge().as_ref(), &[
("parseInt", pi_fn, 1), ("parseInt", crate::builtins::number::number_parse_int as *const (), 1),
("parseFloat", pf_fn, 1), ("parseFloat", crate::builtins::number::number_parse_float as *const (), 1),
],
); );
} }
+2 -2
View File
@@ -4,7 +4,7 @@ use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
use crate::bind_constructor_hash; use crate::bind_constructor;
pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().regexp_constructor.as_ptr() as *mut JsObject; let ctor_ptr = session.builtin_world().regexp_constructor.as_ptr() as *mut JsObject;
@@ -25,5 +25,5 @@ pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
], ],
); );
bind_constructor_hash!(core, global, "RegExp", ctor_ptr, crate::builtins::regexp::regexp_constructor, 2); bind_constructor!(core, global, "RegExp", ctor_ptr, crate::builtins::regexp::regexp_constructor, 2, hash: true);
} }
+2 -2
View File
@@ -1,6 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crate::bind_constructor_hash; use crate::bind_constructor;
use crate::bindings::{apply_binding_table, configure_native_constructor}; use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
@@ -26,5 +26,5 @@ pub fn bind_set(core: &Arc<KernelCore>, session: &KernelSession, global: &mut Js
], ],
); );
bind_constructor_hash!(core, global, "Set", ctor_ptr, crate::builtins::set::set_constructor, 1); bind_constructor!(core, global, "Set", ctor_ptr, crate::builtins::set::set_constructor, 1, hash: true);
} }
+2 -2
View File
@@ -5,7 +5,7 @@ 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::bind_constructor_hash; use crate::bind_constructor;
pub fn bind_symbol(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) { pub fn bind_symbol(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().symbol_constructor.as_ptr() as *mut JsObject; let ctor_ptr = session.builtin_world().symbol_constructor.as_ptr() as *mut JsObject;
@@ -57,7 +57,7 @@ pub fn bind_symbol(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
bind_well_known_symbol(core, ctor, name, val); bind_well_known_symbol(core, ctor, name, val);
} }
bind_constructor_hash!(core, global, "Symbol", ctor_ptr, crate::builtins::symbol::symbol_constructor, 1); bind_constructor!(core, global, "Symbol", ctor_ptr, crate::builtins::symbol::symbol_constructor, 1, hash: true);
} }
fn bind_well_known_symbol(core: &Arc<KernelCore>, ctor: &mut JsObject, name: &str, val: JsValue) { fn bind_well_known_symbol(core: &Arc<KernelCore>, ctor: &mut JsObject, name: &str, val: JsValue) {
@@ -1,6 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crate::bind_constructor_hash; use crate::bind_constructor;
use crate::bindings::{apply_binding_table, configure_native_constructor}; use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
@@ -9,7 +9,7 @@ macro_rules! bind_typed_array_constructor {
($core:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path) => {{ ($core:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path) => {{
let ctor = unsafe { &mut *$ctor_ptr }; let ctor = unsafe { &mut *$ctor_ptr };
configure_native_constructor(ctor, $ctor_fn as *const (), 1); configure_native_constructor(ctor, $ctor_fn as *const (), 1);
bind_constructor_hash!($core, $global, $name, $ctor_ptr, $ctor_fn, 1); bind_constructor!($core, $global, $name, $ctor_ptr, $ctor_fn, 1, hash: true);
}}; }};
} }
+28 -56
View File
@@ -32,29 +32,20 @@ use oxide_types::value::JsValue;
#[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) => {{ ($core:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path, $nargs:literal) => {{
let si = $core.string_forge().intern($name).0; bind_constructor!($core, $global, $name, $ctor_ptr, $ctor_fn, $nargs, hash: false)
let shape = $core.shape_forge().make_shape($global.shape_id(), si);
let val = $crate::JsValue::from_js_object($ctor_ptr);
$global.set_shape_id(shape);
$global.push_prop(val);
let ctor = unsafe { &mut *$ctor_ptr };
// SAFETY: $ctor_fn is a fn-item expression; casting to *const () preserves validity.
ctor.set_native_fn(Some(unsafe { oxide_types::object::NativeFnPtr::from_raw($ctor_fn as *const ()) }));
ctor.set_native_arg_count($nargs);
}}; }};
} ($core:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path, $nargs:literal, hash: $hash:literal) => {{
#[macro_export]
macro_rules! bind_constructor_hash {
($core:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path, $nargs:literal) => {{
let si = $core.string_forge().intern($name).0; let si = $core.string_forge().intern($name).0;
let shape = $core.shape_forge().make_shape($global.shape_id(), si); let shape = $core.shape_forge().make_shape($global.shape_id(), si);
let val = $crate::JsValue::from_js_object($ctor_ptr); let val = $crate::JsValue::from_js_object($ctor_ptr);
$global.set_shape_id(shape); $global.set_shape_id(shape);
$global.ensure_hash_props().push(val); if $hash {
$global.bump_generation(); $global.ensure_hash_props().push(val);
$global.bump_generation();
} else {
$global.push_prop(val);
}
let ctor = unsafe { &mut *$ctor_ptr }; let ctor = unsafe { &mut *$ctor_ptr };
// SAFETY: $ctor_fn is a fn-item expression; casting to *const () preserves validity.
ctor.set_native_fn(Some(unsafe { oxide_types::object::NativeFnPtr::from_raw($ctor_fn as *const ()) })); ctor.set_native_fn(Some(unsafe { oxide_types::object::NativeFnPtr::from_raw($ctor_fn as *const ()) }));
ctor.set_native_arg_count($nargs); ctor.set_native_arg_count($nargs);
}}; }};
@@ -383,92 +374,73 @@ pub fn bind_global_builtin_slots(core: &Arc<KernelCore>, session: &KernelSession
/// Maintenance: when adding a `BuiltinDirtySet` group, update this rebind map, /// Maintenance: when adding a `BuiltinDirtySet` group, update this rebind map,
/// `BuiltinSnapshot`, and `BuiltinWorld::rebuild_with_dirty()` together. /// `BuiltinSnapshot`, and `BuiltinWorld::rebuild_with_dirty()` together.
pub fn rebind_dirty_builtins(core: &Arc<KernelCore>, session: &mut KernelSession, dirty: &BuiltinDirtySet) { pub fn rebind_dirty_builtins(core: &Arc<KernelCore>, session: &mut KernelSession, dirty: Option<&BuiltinDirtySet>) {
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.object { if dirty.map_or(true, |d| d.object) {
bind_object::bind_object(core, session, global); bind_object::bind_object(core, session, global);
} }
if dirty.array { if dirty.map_or(true, |d| d.array) {
bind_array::bind_array(core, session, global); bind_array::bind_array(core, session, global);
} }
if dirty.array_buffer { if dirty.map_or(true, |d| d.array_buffer) {
bind_array_buffer::bind_array_buffer(core, session, global); bind_array_buffer::bind_array_buffer(core, session, global);
} }
if dirty.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(core, session, global);
} }
if dirty.typed_array_family { if dirty.map_or(true, |d| d.typed_array_family) {
bind_typed_array::bind_typed_array(core, session, global); bind_typed_array::bind_typed_array(core, session, global);
} }
if dirty.error_family { if dirty.map_or(true, |d| d.error_family) {
bind_error::bind_error(core, session, global); bind_error::bind_error(core, session, global);
} }
if dirty.string { if dirty.map_or(true, |d| d.string) {
bind_string::bind_string(core, session, global); bind_string::bind_string(core, session, global);
} }
if dirty.number { if dirty.map_or(true, |d| d.number) {
bind_number::bind_number(core, session, global); bind_number::bind_number(core, session, global);
} }
if dirty.math { if dirty.map_or(true, |d| d.math) {
bind_math::bind_math(core, session, global); bind_math::bind_math(core, session, global);
} }
if dirty.json { if dirty.map_or(true, |d| d.json) {
bind_json::bind_json(core, session, global); bind_json::bind_json(core, session, global);
} }
if dirty.date { if dirty.map_or(true, |d| d.date) {
bind_date::bind_date(core, session, global); bind_date::bind_date(core, session, global);
} }
if dirty.set { if dirty.map_or(true, |d| d.set) {
bind_set::bind_set(core, session, global); bind_set::bind_set(core, session, global);
} }
if dirty.map { if dirty.map_or(true, |d| d.map) {
bind_map::bind_map(core, session, global); bind_map::bind_map(core, session, global);
} }
if dirty.boolean { if dirty.map_or(true, |d| d.boolean) {
bind_boolean::bind_boolean(core, session, global); bind_boolean::bind_boolean(core, session, global);
} }
if dirty.function { if dirty.map_or(true, |d| d.function) {
bind_function::bind_function(core, session, global); bind_function::bind_function(core, session, global);
} }
if dirty.regexp { if dirty.map_or(true, |d| d.regexp) {
bind_regexp::bind_regexp(core, session, global); bind_regexp::bind_regexp(core, session, global);
} }
if dirty.symbol_family { if dirty.map_or(true, |d| d.symbol_family) {
bind_symbol::bind_symbol(core, session, global); bind_symbol::bind_symbol(core, session, global);
} }
if dirty.stubs { if dirty.map_or(true, |d| d.stubs) {
bind_stubs::bind_stubs(core, session, global); bind_stubs::bind_stubs(core, session, global);
} }
} }
pub fn init_kernel_builtins(core: &Arc<KernelCore>, session: &mut KernelSession) { pub fn init_kernel_builtins(core: &Arc<KernelCore>, session: &mut KernelSession) {
rebind_dirty_builtins(core, session, None);
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_object::bind_object(core, session, global);
bind_array::bind_array(core, session, global);
bind_array_buffer::bind_array_buffer(core, session, global);
bind_data_view::bind_data_view(core, session, global);
bind_typed_array::bind_typed_array(core, session, global);
bind_error::bind_error(core, session, global);
bind_string::bind_string(core, session, global);
bind_number::bind_number(core, session, global);
bind_math::bind_math(core, session, global);
bind_json::bind_json(core, session, global);
bind_date::bind_date(core, session, global);
bind_set::bind_set(core, session, global);
bind_map::bind_map(core, session, global);
bind_boolean::bind_boolean(core, session, global);
bind_function::bind_function(core, session, global);
bind_regexp::bind_regexp(core, session, global);
bind_symbol::bind_symbol(core, session, global);
bind_iterator::bind_iterator(core, session, global); bind_iterator::bind_iterator(core, session, global);
bind_reflect::bind_reflect(core, session, global); bind_reflect::bind_reflect(core, session, global);
bind_global::bind_global(core, session, global); bind_global::bind_global(core, session, global);
bind_stubs::bind_stubs(core, session, global);
bind_global_value(core, global, "globalThis", JsValue::from_js_object(global_ptr)); bind_global_value(core, global, "globalThis", JsValue::from_js_object(global_ptr));
session.record_snapshot(); session.record_snapshot();
} }
-4
View File
@@ -4,10 +4,6 @@ use oxide_types::object::JsObject;
use oxide_types::shape::EMPTY_SHAPE_ID; use oxide_types::shape::EMPTY_SHAPE_ID;
use oxide_types::value::JsValue; use oxide_types::value::JsValue;
pub fn to_primitive(val: JsValue) -> JsValue {
val
}
pub fn to_number(val: JsValue, string_forge: &StringForge) -> f64 { pub fn to_number(val: JsValue, string_forge: &StringForge) -> f64 {
if val.is_int() { if val.is_int() {
return val.as_int() as f64; return val.as_int() as f64;
-8
View File
@@ -15,14 +15,6 @@ impl NativeResult {
Self::Err(val) Self::Err(val)
} }
pub fn into_result(self) -> Result<JsValue, JsValue> {
match self {
Self::Ok(val) => Ok(val),
Self::Err(err) => Err(err),
Self::TailCall { .. } => panic!("TailCall cannot be converted to Result"),
}
}
pub fn unwrap(self) -> JsValue { pub fn unwrap(self) -> JsValue {
match self { match self {
Self::Ok(val) => val, Self::Ok(val) => val,
+23 -21
View File
@@ -25,22 +25,11 @@ pub struct SessionGc {
impl SessionGc { impl SessionGc {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
total_collections: 0,
total_bytes_freed: 0,
total_objects_scanned: 0,
total_objects_live: 0,
total_objects_dead: 0,
last_collection_objects_scanned: 0,
last_collection_objects_live: 0,
last_collection_objects_dead: 0,
last_collection_bytes_freed: 0,
last_collection_duration_us: 0,
max_collection_duration_us: 0,
min_collection_duration_us: u64::MAX,
}
} }
}
impl SessionGc {
#[inline] #[inline]
pub(crate) fn is_session_ptr(&self, vm: &Vm, obj_ptr: *mut JsObject) -> bool { pub(crate) fn is_session_ptr(&self, vm: &Vm, obj_ptr: *mut JsObject) -> bool {
vm.is_session_ptr(obj_ptr) vm.is_session_ptr(obj_ptr)
@@ -329,7 +318,20 @@ impl SessionGc {
impl Default for SessionGc { impl Default for SessionGc {
fn default() -> Self { fn default() -> Self {
Self::new() Self {
total_collections: 0,
total_bytes_freed: 0,
total_objects_scanned: 0,
total_objects_live: 0,
total_objects_dead: 0,
last_collection_objects_scanned: 0,
last_collection_objects_live: 0,
last_collection_objects_dead: 0,
last_collection_bytes_freed: 0,
last_collection_duration_us: 0,
max_collection_duration_us: 0,
min_collection_duration_us: u64::MAX,
}
} }
} }
@@ -487,7 +489,7 @@ mod tests {
vm.regs[0] = JsValue::from_js_object(root_session); vm.regs[0] = JsValue::from_js_object(root_session);
let roots = vm.gc_roots(); let roots = vm.gc_roots();
let mut gc = std::mem::replace(&mut vm.session_gc, SessionGc::new()); let mut gc = std::mem::take(&mut vm.session_gc);
gc.mark(&vm, &roots); gc.mark(&vm, &roots);
vm.session_gc = gc; vm.session_gc = gc;
@@ -512,7 +514,7 @@ mod tests {
vm.regs[0] = JsValue::from_js_object(root_session); vm.regs[0] = JsValue::from_js_object(root_session);
let dead_session = vm.promote_object(dead); let dead_session = vm.promote_object(dead);
let roots = vm.gc_roots(); let roots = vm.gc_roots();
let mut gc = std::mem::replace(&mut vm.session_gc, SessionGc::new()); let mut gc = std::mem::take(&mut vm.session_gc);
gc.mark(&vm, &roots); gc.mark(&vm, &roots);
let _ = gc.sweep(&mut vm); let _ = gc.sweep(&mut vm);
vm.session_gc = gc; vm.session_gc = gc;
@@ -624,7 +626,7 @@ mod tests {
let map_session = vm.promote_object(map_value.as_js_object_ptr()); let map_session = vm.promote_object(map_value.as_js_object_ptr());
vm.regs.fill(JsValue::undefined()); vm.regs.fill(JsValue::undefined());
vm.regs[0] = JsValue::from_js_object(map_session); vm.regs[0] = JsValue::from_js_object(map_session);
let mut gc = std::mem::replace(&mut vm.session_gc, SessionGc::new()); let mut gc = std::mem::take(&mut vm.session_gc);
gc.collect(&mut vm); gc.collect(&mut vm);
vm.session_gc = gc; vm.session_gc = gc;
@@ -647,7 +649,7 @@ mod tests {
let set_session = vm.promote_object(set_value.as_js_object_ptr()); let set_session = vm.promote_object(set_value.as_js_object_ptr());
vm.regs.fill(JsValue::undefined()); vm.regs.fill(JsValue::undefined());
vm.regs[0] = JsValue::from_js_object(set_session); vm.regs[0] = JsValue::from_js_object(set_session);
let mut gc = std::mem::replace(&mut vm.session_gc, SessionGc::new()); let mut gc = std::mem::take(&mut vm.session_gc);
gc.collect(&mut vm); gc.collect(&mut vm);
vm.session_gc = gc; vm.session_gc = gc;
@@ -686,7 +688,7 @@ mod tests {
let root_session = vm.promote_object(root); let root_session = vm.promote_object(root);
vm.regs.fill(JsValue::undefined()); vm.regs.fill(JsValue::undefined());
vm.regs[0] = JsValue::from_js_object(root_session); vm.regs[0] = JsValue::from_js_object(root_session);
let mut gc = std::mem::replace(&mut vm.session_gc, SessionGc::new()); let mut gc = std::mem::take(&mut vm.session_gc);
gc.collect(&mut vm); gc.collect(&mut vm);
vm.session_gc = gc; vm.session_gc = gc;
@@ -735,7 +737,7 @@ mod tests {
let view_session = vm.promote_object(view.as_js_object_ptr()); let view_session = vm.promote_object(view.as_js_object_ptr());
vm.regs.fill(JsValue::undefined()); vm.regs.fill(JsValue::undefined());
vm.regs[0] = JsValue::from_js_object(view_session); vm.regs[0] = JsValue::from_js_object(view_session);
let mut gc = std::mem::replace(&mut vm.session_gc, SessionGc::new()); let mut gc = std::mem::take(&mut vm.session_gc);
gc.collect(&mut vm); gc.collect(&mut vm);
vm.session_gc = gc; vm.session_gc = gc;
+1 -15
View File
@@ -315,12 +315,6 @@ impl Vm {
roots roots
} }
pub fn gc_clear_marks(&mut self) {
let mut session_gc = std::mem::take(&mut self.session_gc);
session_gc.clear_all_marks(self);
self.session_gc = session_gc;
}
pub(crate) fn maybe_collect_session_gc(&mut self) { pub(crate) fn maybe_collect_session_gc(&mut self) {
let mut session_gc = std::mem::take(&mut self.session_gc); let mut session_gc = std::mem::take(&mut self.session_gc);
session_gc.maybe_collect(self); session_gc.maybe_collect(self);
@@ -442,14 +436,6 @@ impl Vm {
self.regs[idx as usize] = val; self.regs[idx as usize] = val;
} }
pub fn regs_mut(&mut self) -> &mut [JsValue; 256] {
&mut self.regs
}
pub fn epoch_mut(&mut self) -> &mut Epoch {
&mut self.epoch
}
pub fn epoch(&self) -> &Epoch { pub fn epoch(&self) -> &Epoch {
&self.epoch &self.epoch
} }
@@ -603,7 +589,7 @@ impl Vm {
self.call_bytecode_function_inline(callee, callee_obj, receiver, args) self.call_bytecode_function_inline(callee, callee_obj, receiver, args)
} }
#[allow(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub(crate) fn push_bytecode_frame( pub(crate) fn push_bytecode_frame(
&mut self, callee: JsValue, this_value: JsValue, args: &[JsValue], construct_result_reg: Option<u8>, &mut self, callee: JsValue, this_value: JsValue, args: &[JsValue], construct_result_reg: Option<u8>,
constructed_this: Option<JsValue>, new_target: JsValue, continuation: FrameContinuation, constructed_this: Option<JsValue>, new_target: JsValue, continuation: FrameContinuation,
+4 -24
View File
@@ -15,8 +15,6 @@ pub struct VmPool {
kernel_core: Arc<KernelCore>, kernel_core: Arc<KernelCore>,
inner: Mutex<VmPoolInner>, inner: Mutex<VmPoolInner>,
condvar: Condvar, condvar: Condvar,
#[allow(dead_code)]
min_size: usize,
max_size: Option<usize>, max_size: Option<usize>,
} }
@@ -28,30 +26,16 @@ pub struct VmGuard {
} }
impl VmPool { impl VmPool {
pub fn new( pub fn new(kernel_core: Arc<KernelCore>, _min_size: usize, max_size: Option<usize>) -> Arc<Self> {
kernel_core: Arc<KernelCore>, #[allow(dead_code)] min_size: usize, max_size: Option<usize>, Arc::new(Self {
) -> Arc<Self> {
let pool = Arc::new(Self {
kernel_core, kernel_core,
inner: Mutex::new(VmPoolInner { inner: Mutex::new(VmPoolInner {
available: Vec::with_capacity(min_size), available: Vec::new(),
total_count: 0, total_count: 0,
}), }),
condvar: Condvar::new(), condvar: Condvar::new(),
min_size,
max_size, max_size,
}); })
{
let mut inner = pool.inner.lock().unwrap();
for _ in 0..min_size {
let vm = Self::new_vm(&pool.kernel_core);
inner.available.push(vm);
inner.total_count += 1;
}
}
pool
} }
fn new_vm(core: &Arc<KernelCore>) -> Vm { fn new_vm(core: &Arc<KernelCore>) -> Vm {
@@ -117,10 +101,6 @@ impl VmGuard {
pub fn vm_mut(&mut self) -> &mut Vm { pub fn vm_mut(&mut self) -> &mut Vm {
self.vm.as_mut().expect("VmGuard has no VM") self.vm.as_mut().expect("VmGuard has no VM")
} }
pub fn mark_dirty(&mut self) {
self.dirty = true;
}
} }
impl Drop for VmGuard { impl Drop for VmGuard {
-5
View File
@@ -157,11 +157,6 @@ impl Vm {
self.dispatch() self.dispatch()
} }
#[allow(dead_code)]
pub fn call_bytecode_func(&mut self, _callback_obj: &JsObject, _args_regs: &[u8]) -> Result<JsValue, String> {
Err("bytecode function calls not yet supported".into())
}
pub(crate) fn unwind(&mut self) -> Result<(), String> { pub(crate) fn unwind(&mut self) -> Result<(), String> {
while let Some(handler) = self.try_stack.pop() { while let Some(handler) = self.try_stack.pop() {
while self.frames.len() > handler.frame_depth { while self.frames.len() > handler.frame_depth {
+1 -1
View File
@@ -108,7 +108,7 @@ impl Vm {
pub fn full_reset(&mut self) { pub fn full_reset(&mut self) {
let dirty = self.session.selective_reset(&self.kernel_core); let dirty = self.session.selective_reset(&self.kernel_core);
if dirty.any_builtin_dirty() { if dirty.any_builtin_dirty() {
bindings::rebind_dirty_builtins(&self.kernel_core, &mut self.session, &dirty); bindings::rebind_dirty_builtins(&self.kernel_core, &mut self.session, Some(&dirty));
} }
if dirty.global { if dirty.global {
let global_ptr = self.session.global_object().as_ptr() as *mut JsObject; let global_ptr = self.session.global_object().as_ptr() as *mut JsObject;