refactor: 清理未使用符号,合并bind_constructor宏,统一init/rebind绑定列表,bind_number改为表驱动
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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::*;
|
||||||
|
|||||||
@@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user