diff --git a/crates/oxide_builtins/src/array_buffer.rs b/crates/oxide_builtins/src/array_buffer.rs index 3c2b1d1e..61b32d73 100644 --- a/crates/oxide_builtins/src/array_buffer.rs +++ b/crates/oxide_builtins/src/array_buffer.rs @@ -95,9 +95,7 @@ pub fn array_buffer_native_size(obj: &JsObject) -> u64 { if data_ptr.is_null() { return 0; } - unsafe { - (std::mem::size_of::>() + (*data_ptr).capacity()) as u64 - } + unsafe { (std::mem::size_of::>() + (*data_ptr).capacity()) as u64 } } /// 释放 ArrayBuffer 的字节缓冲(native_fn 槽中的 `Box>`),返回字节数。 diff --git a/crates/oxide_builtins/src/console.rs b/crates/oxide_builtins/src/console.rs index 5e6cf7bf..abd946df 100644 --- a/crates/oxide_builtins/src/console.rs +++ b/crates/oxide_builtins/src/console.rs @@ -18,9 +18,8 @@ fn multi_string(vm: &mut H, args: &[u8]) -> String { let part = if val.is_string() { oxide_runtime_api::to_string(val) } else { - let primitive = - oxide_runtime_api::to_primitive(val, oxide_runtime_api::ToPrimitiveHint::String, vm) - .unwrap_or_else(|_| JsValue::undefined()); + let primitive = oxide_runtime_api::to_primitive(val, oxide_runtime_api::ToPrimitiveHint::String, vm) + .unwrap_or_else(|_| JsValue::undefined()); oxide_runtime_api::to_string(primitive) }; output.push_str(&part); diff --git a/crates/oxide_builtins/src/disposable_stack.rs b/crates/oxide_builtins/src/disposable_stack.rs index e547f05f..b0aab232 100644 --- a/crates/oxide_builtins/src/disposable_stack.rs +++ b/crates/oxide_builtins/src/disposable_stack.rs @@ -618,8 +618,8 @@ pub fn disposable_stack_native_size(obj: &JsObject) -> u64 { return 0; } unsafe { - (std::mem::size_of::() - + (*ptr).entries.capacity() * std::mem::size_of::()) as u64 + (std::mem::size_of::() + (*ptr).entries.capacity() * std::mem::size_of::()) + as u64 } } diff --git a/crates/oxide_builtins/src/iterator.rs b/crates/oxide_builtins/src/iterator.rs index 5d02d62e..5ce94114 100644 --- a/crates/oxide_builtins/src/iterator.rs +++ b/crates/oxide_builtins/src/iterator.rs @@ -1458,7 +1458,9 @@ fn next_array_like( let value = match vm.ordinary_get(arr, key_si, inner) { Ok(v) => v, Err(err) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_from_text(vm, &err)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_from_text(vm, &err)); return Err(exc); } }; diff --git a/crates/oxide_builtins/src/map.rs b/crates/oxide_builtins/src/map.rs index 78fcbc24..b7c21a92 100644 --- a/crates/oxide_builtins/src/map.rs +++ b/crates/oxide_builtins/src/map.rs @@ -144,9 +144,7 @@ pub fn map_native_size(obj: &JsObject) -> u64 { if inner.is_null() { return 0; } - unsafe { - (std::mem::size_of::() + (*inner).capacity() * std::mem::size_of::<(SetKey, JsValue)>()) as u64 - } + unsafe { (std::mem::size_of::() + (*inner).capacity() * std::mem::size_of::<(SetKey, JsValue)>()) as u64 } } /// 释放 Map 的 native 数据(IndexMap),返回释放的字节数供泄漏统计。 @@ -397,12 +395,17 @@ pub fn map_group_by(vm: &mut H, args: &[u8]) -> NativeResult { Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)), }; if !crate::iterator::is_callable(iter_method) { - return NativeResult::Err(crate::error::create_type_error(vm, "Map.groupBy: items[Symbol.iterator] is not callable")); + return NativeResult::Err(crate::error::create_type_error( + vm, + "Map.groupBy: items[Symbol.iterator] is not callable", + )); } let iter_val = match vm.call_function_sync(iter_method, items_val, &[]) { Ok(v) => v, Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } }; @@ -435,12 +438,17 @@ pub fn map_group_by(vm: &mut H, args: &[u8]) -> NativeResult { let next_result = match vm.call_function_sync(next_fn, iter_val, &[]) { Ok(v) => v, Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } }; if !next_result.is_object() || next_result.as_js_object_ptr().is_null() { - return NativeResult::Err(crate::error::create_type_error(vm, "Map.groupBy: iterator next() returned non-object")); + return NativeResult::Err(crate::error::create_type_error( + vm, + "Map.groupBy: iterator next() returned non-object", + )); } let nr = unsafe { &*next_result.as_js_object_ptr() }; let done_si = vm.kernel_core().perm_interner().intern("done").0; @@ -457,18 +465,23 @@ pub fn map_group_by(vm: &mut H, args: &[u8]) -> NativeResult { Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)), }; // 调用 callbackFn(element, counter):counter 对数组 items 即元素下标 k。 - let group_key = match vm.call_function_sync(callback_val, JsValue::undefined(), &[element, JsValue::int(counter)]) { - Ok(v) => v, - Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); - return NativeResult::Err(exc); - } - }; + let group_key = + match vm.call_function_sync(callback_val, JsValue::undefined(), &[element, JsValue::int(counter)]) { + Ok(v) => v, + Err(e) => { + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + return NativeResult::Err(exc); + } + }; // 取该键已有分组数组;无则新建空数组并 set 到 Map,再 push 元素。 let existing = match vm.call_function_sync(getter, map_val, &[group_key]) { Ok(v) => v, Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } }; @@ -487,7 +500,9 @@ pub fn map_group_by(vm: &mut H, args: &[u8]) -> NativeResult { )); let new_arr_val = JsValue::from_js_object(arr); if let Err(e) = vm.call_function_sync(adder, map_val, &[group_key, new_arr_val]) { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } new_arr_val diff --git a/crates/oxide_builtins/src/math.rs b/crates/oxide_builtins/src/math.rs index 28128050..5afac527 100644 --- a/crates/oxide_builtins/src/math.rs +++ b/crates/oxide_builtins/src/math.rs @@ -198,7 +198,11 @@ pub(crate) fn f16_bits_to_f64(h: u16) -> f64 { // 正规:(1 + mant/2¹⁰) × 2^(exp-15)。 (1.0 + mant / 1024.0) * 2.0f64.powi(exp - 15) }; - if sign == 1.0 { -v } else { v } + if sign == 1.0 { + -v + } else { + v + } } /// `Math.f16round`:把 double 舍入到 binary16 精度再还原为 double。 diff --git a/crates/oxide_builtins/src/object.rs b/crates/oxide_builtins/src/object.rs index 3f7b68d4..403ddf8d 100644 --- a/crates/oxide_builtins/src/object.rs +++ b/crates/oxide_builtins/src/object.rs @@ -1289,7 +1289,9 @@ pub fn object_proto_define_getter(vm: &mut H, args: &[u8]) -> NativeR let key_si = match vm.to_property_key_si(vm.reg(args[1])) { Ok(si) => si, Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } }; @@ -1378,12 +1380,17 @@ pub fn object_group_by(vm: &mut H, args: &[u8]) -> NativeResult { Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)), }; if !is_callable(iter_method) { - return NativeResult::Err(crate::error::create_type_error(vm, "Object.groupBy: items[Symbol.iterator] is not callable")); + return NativeResult::Err(crate::error::create_type_error( + vm, + "Object.groupBy: items[Symbol.iterator] is not callable", + )); } let iter_val = match vm.call_function_sync(iter_method, items_val, &[]) { Ok(v) => v, Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } }; @@ -1404,12 +1411,17 @@ pub fn object_group_by(vm: &mut H, args: &[u8]) -> NativeResult { let next_result = match vm.call_function_sync(next_fn, iter_val, &[]) { Ok(v) => v, Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } }; if !next_result.is_object() || next_result.as_js_object_ptr().is_null() { - return NativeResult::Err(crate::error::create_type_error(vm, "Object.groupBy: iterator next() returned non-object")); + return NativeResult::Err(crate::error::create_type_error( + vm, + "Object.groupBy: iterator next() returned non-object", + )); } let nr = unsafe { &*next_result.as_js_object_ptr() }; let done_si = vm.kernel_core().perm_interner().intern("done").0; @@ -1429,7 +1441,9 @@ pub fn object_group_by(vm: &mut H, args: &[u8]) -> NativeResult { let key = match vm.call_function_sync(callback_val, JsValue::undefined(), &[element, JsValue::int(counter)]) { Ok(v) => v, Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } }; @@ -1437,7 +1451,9 @@ pub fn object_group_by(vm: &mut H, args: &[u8]) -> NativeResult { let key_si = match vm.to_property_key_si(key) { Ok(si) => si, Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } }; @@ -1446,7 +1462,11 @@ pub fn object_group_by(vm: &mut H, args: &[u8]) -> NativeResult { let existing = match vm.ordinary_get(result_ref, key_si, result_val) { Ok(v) if v.is_object() && !v.as_js_object_ptr().is_null() => { let arr = unsafe { &*v.as_js_object_ptr() }; - if arr.is_array() { Some(v) } else { None } + if arr.is_array() { + Some(v) + } else { + None + } } _ => None, }; @@ -1454,7 +1474,12 @@ pub fn object_group_by(vm: &mut H, args: &[u8]) -> NativeResult { existing } else { let arr_proto = vm.session().builtin_world().array_proto.as_ptr() as *mut JsObject; - let arr = vm.alloc_object(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(arr_proto), 0, vm.epoch().bump())); + let arr = vm.alloc_object(JsObject::new_array( + EMPTY_SHAPE_ID, + JsValue::from_js_object(arr_proto), + 0, + vm.epoch().bump(), + )); let new_arr_val = JsValue::from_js_object(arr); let result_ref_mut = unsafe { &mut *result }; let promoted = vm.promote_if_needed_for_write_ptr(result, new_arr_val); diff --git a/crates/oxide_builtins/src/set.rs b/crates/oxide_builtins/src/set.rs index 09aa015a..094b7397 100644 --- a/crates/oxide_builtins/src/set.rs +++ b/crates/oxide_builtins/src/set.rs @@ -183,9 +183,7 @@ pub fn set_native_size(obj: &JsObject) -> u64 { if inner.is_null() { return 0; } - unsafe { - (std::mem::size_of::() + (*inner).capacity() * std::mem::size_of::()) as u64 - } + unsafe { (std::mem::size_of::() + (*inner).capacity() * std::mem::size_of::()) as u64 } } /// 释放 Set 的 native 数据(IndexSet),返回释放的字节数供泄漏统计。 diff --git a/crates/oxide_builtins/src/string.rs b/crates/oxide_builtins/src/string.rs index 4a070b37..9c53f9a5 100644 --- a/crates/oxide_builtins/src/string.rs +++ b/crates/oxide_builtins/src/string.rs @@ -1690,7 +1690,9 @@ pub fn string_raw(vm: &mut H, args: &[u8]) -> NativeResult { let raw_val = match vm.ordinary_get(template_obj, raw_si, template_val) { Ok(v) => v, Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } }; @@ -1708,21 +1710,21 @@ pub fn string_raw(vm: &mut H, args: &[u8]) -> NativeResult { // 原样传播),再按 ToLength 归一并截断(防超大 raw 数组导致 OOM)。 match oxide_runtime_api::to_number_full(v, vm) { Ok(n) => { - let len = if n.is_nan() || n <= 0.0 { - 0.0 - } else { - n.min(9_007_199_254_740_991.0) - }; + let len = if n.is_nan() || n <= 0.0 { 0.0 } else { n.min(9_007_199_254_740_991.0) }; (len.trunc() as u64).min(0x1FFFFF) as usize } Err(msg) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &msg)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &msg)); return NativeResult::Err(exc); } } } Err(e) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &e)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &e)); return NativeResult::Err(exc); } }; @@ -1740,7 +1742,9 @@ pub fn string_raw(vm: &mut H, args: &[u8]) -> NativeResult { Ok(v) => match oxide_runtime_api::to_string_full(v, vm) { Ok(s) => s, Err(msg) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &msg)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &msg)); return NativeResult::Err(exc); } }, @@ -1763,7 +1767,9 @@ pub fn string_raw(vm: &mut H, args: &[u8]) -> NativeResult { let sub_str = match oxide_runtime_api::to_string_full(sub_val, vm) { Ok(s) => s, Err(msg) => { - let exc = vm.take_uncaught_value().unwrap_or_else(|| crate::error::create_type_error(vm, &msg)); + let exc = vm + .take_uncaught_value() + .unwrap_or_else(|| crate::error::create_type_error(vm, &msg)); return NativeResult::Err(exc); } }; diff --git a/crates/oxide_builtins/src/temporal.rs b/crates/oxide_builtins/src/temporal.rs index e4ace922..0ff5de06 100644 --- a/crates/oxide_builtins/src/temporal.rs +++ b/crates/oxide_builtins/src/temporal.rs @@ -3849,9 +3849,7 @@ pub fn duration_add(vm: &mut H, args: &[u8]) -> NativeResult { /// # 边界与前提 /// - 任一侧含日历单位抛 RangeError(本批无 relativeTo 支持)。 /// - 全零与 nanosecond 分量和为 0 时直接返回零时长。 -fn add_duration_values( - vm: &mut H, receiver: &[f64; 10], other: &[f64; 10], -) -> Result<[f64; 10], JsValue> { +fn add_duration_values(vm: &mut H, receiver: &[f64; 10], other: &[f64; 10]) -> Result<[f64; 10], JsValue> { if receiver[..3].iter().any(|value| *value != 0.0) || other[..3].iter().any(|value| *value != 0.0) { return Err(crate::error::create_range_error(vm, "cannot add durations with calendar units")); } @@ -4068,12 +4066,10 @@ pub fn duration_compare(vm: &mut H, args: &[u8]) -> NativeResult { "relativeTo is required for calendar units", )); } - let one_ns = native_try!(duration_time_nanoseconds(&one).ok_or_else(|| { - crate::error::create_range_error(vm, "duration is out of range") - })); - let two_ns = native_try!(duration_time_nanoseconds(&two).ok_or_else(|| { - crate::error::create_range_error(vm, "duration is out of range") - })); + let one_ns = native_try!(duration_time_nanoseconds(&one) + .ok_or_else(|| { crate::error::create_range_error(vm, "duration is out of range") })); + let two_ns = native_try!(duration_time_nanoseconds(&two) + .ok_or_else(|| { crate::error::create_range_error(vm, "duration is out of range") })); one_ns.cmp(&two_ns) } Some(rel) => { @@ -4305,7 +4301,10 @@ pub fn duration_round(vm: &mut H, args: &[u8]) -> NativeResult { ]; for (index, scale) in (3..10).zip(UNIT_SCALES) { if result[index] != 0.0 && result[index].abs() * scale >= MAX_TIME_NANOSECONDS { - return NativeResult::Err(crate::error::create_range_error(vm, "duration time fields are out of range")); + return NativeResult::Err(crate::error::create_range_error( + vm, + "duration time fields are out of range", + )); } } return make_duration(vm, result); @@ -6944,9 +6943,7 @@ fn nudge_iso_difference( if did_expand && smallest_index != 2 { match bubble_relative_duration(sign, values, nudged_epoch, date1, time1_ns, largest_index, smallest_index) { Ok(bubbled) => values = bubbled, - Err(()) => { - return Err(crate::error::create_range_error(vm, "difference is out of range")) - } + Err(()) => return Err(crate::error::create_range_error(vm, "difference is out of range")), } } values diff --git a/crates/oxide_cli/src/main.rs b/crates/oxide_cli/src/main.rs index 4310ac38..ea8ff854 100644 --- a/crates/oxide_cli/src/main.rs +++ b/crates/oxide_cli/src/main.rs @@ -16,10 +16,10 @@ use oxide_kernel::{kernel_error, kernel_info}; use oxide_log::{Level, SUBSYSTEM_COUNT}; use oxide_parser::Allocator; use oxide_types::object::JsObject; +use oxide_vm::vm::Vm; use oxide_vm::vm_error; use oxide_vm::vm_pool::VmPool; use oxide_vm::JsValue; -use oxide_vm::vm::Vm; mod bench; diff --git a/crates/oxide_emit/src/expr/template/tagged.rs b/crates/oxide_emit/src/expr/template/tagged.rs index 0cfa5f36..5da05df9 100644 --- a/crates/oxide_emit/src/expr/template/tagged.rs +++ b/crates/oxide_emit/src/expr/template/tagged.rs @@ -34,12 +34,7 @@ impl Emitter { let site_no = ctx.next_template_site; ctx.next_template_site += 1; let template_reg = ctx.alloc_reg(); - ctx.inst(Inst::get_template_object( - Operand::Reg(template_reg), - site_no, - &cooked_words, - &raw_idxs, - )); + ctx.inst(Inst::get_template_object(Operand::Reg(template_reg), site_no, &cooked_words, &raw_idxs)); // 表达式实参:求值顺序在模板对象之后(规范 TaggedTemplate 求值序: // 标签引用 → GetTemplateObject → 实参表达式)。 @@ -173,4 +168,4 @@ impl Emitter { }; Ok(pair) } -} \ No newline at end of file +} diff --git a/crates/oxide_vm/src/bindings/bind_temporal.rs b/crates/oxide_vm/src/bindings/bind_temporal.rs index 0bf6fcd8..005d7f4e 100644 --- a/crates/oxide_vm/src/bindings/bind_temporal.rs +++ b/crates/oxide_vm/src/bindings/bind_temporal.rs @@ -893,11 +893,7 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m core, &[ ("from", oxide_builtins::temporal::duration_from:: as *const (), 1), - ( - "compare", - oxide_builtins::temporal::duration_compare:: as *const (), - 2, - ), + ("compare", oxide_builtins::temporal::duration_compare:: as *const (), 2), ], ); let duration_proto_ptr = world.duration_proto.as_ptr() as *mut JsObject; @@ -935,11 +931,7 @@ pub fn bind_temporal(core: &Arc, session: &KernelSession, global: &m ("abs", oxide_builtins::temporal::duration_abs:: as *const (), 0), ("negated", oxide_builtins::temporal::duration_negated:: as *const (), 0), ("add", oxide_builtins::temporal::duration_add:: as *const (), 1), - ( - "subtract", - oxide_builtins::temporal::duration_subtract:: as *const (), - 1, - ), + ("subtract", oxide_builtins::temporal::duration_subtract:: as *const (), 1), ("equals", oxide_builtins::temporal::duration_equals:: as *const (), 1), ("round", oxide_builtins::temporal::duration_round:: as *const (), 1), ("with", oxide_builtins::temporal::duration_with:: as *const (), 1), diff --git a/crates/oxide_vm/src/bindings/mod.rs b/crates/oxide_vm/src/bindings/mod.rs index 6d9a938c..e10913ba 100644 --- a/crates/oxide_vm/src/bindings/mod.rs +++ b/crates/oxide_vm/src/bindings/mod.rs @@ -12,6 +12,8 @@ pub mod bind_async_disposable_stack; pub mod bind_bigint; /// Boolean 构造器与原型的 native 方法绑定。 pub mod bind_boolean; +/// Console 单例对象及其方法绑定。 +pub mod bind_console; /// DataView 构造器与原型的 native 方法绑定。 pub mod bind_data_view; /// Date 构造器与原型的 native 方法绑定。 @@ -52,8 +54,6 @@ pub mod bind_symbol; pub mod bind_temporal; /// 各 TypedArray 构造器与共享原型的 native 方法绑定。 pub mod bind_typed_array; -/// Console 单例对象及其方法绑定。 -pub mod bind_console; use std::sync::Arc; diff --git a/crates/oxide_vm/src/promise.rs b/crates/oxide_vm/src/promise.rs index 532a32a7..d53a0469 100644 --- a/crates/oxide_vm/src/promise.rs +++ b/crates/oxide_vm/src/promise.rs @@ -1301,8 +1301,7 @@ fn promise_static_with_resolvers(vm: &mut Vm, args: &[u8]) -> NativeResult { Ok(t) => t, Err(err) => return NativeResult::Err(err), }; - let object_proto = - JsValue::from_js_object(vm.session.builtin_world().object_proto.as_ptr() as *mut JsObject); + let object_proto = JsValue::from_js_object(vm.session.builtin_world().object_proto.as_ptr() as *mut JsObject); let ptr = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, object_proto)); let obj = unsafe { &mut *ptr }; let sf = vm.kernel_core.perm_interner().as_ref(); diff --git a/crates/oxide_vm/src/session_arena.rs b/crates/oxide_vm/src/session_arena.rs index 02618737..77475f27 100644 --- a/crates/oxide_vm/src/session_arena.rs +++ b/crates/oxide_vm/src/session_arena.rs @@ -97,8 +97,8 @@ impl Vm { regexp::clone_regexp_native(src_ref, dst_ref); } // 账目计入:对象头 + 堆数据(属性/元素/meta Vec + native 状态盒),用 clone 后的 dst 核算。 - self.gc_state.session_bytes_allocated += std::mem::size_of::() - + crate::session_gc::SessionGc::object_heap_data_bytes(dst_ref) as usize; + self.gc_state.session_bytes_allocated += + std::mem::size_of::() + crate::session_gc::SessionGc::object_heap_data_bytes(dst_ref) as usize; dst } @@ -135,7 +135,8 @@ mod tests { fn plain_object(vm: &mut Vm) -> *mut JsObject { let proto = vm.session.builtin_world().object_proto.as_ptr() as *mut JsObject; - let ptr = vm.epoch + let ptr = vm + .epoch .alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto))); // 测试辅助函数绕过 alloc_object,需手动置位 EPOCH_BIT。 unsafe { (*ptr).set_is_epoch(true) }; diff --git a/crates/oxide_vm/src/session_gc.rs b/crates/oxide_vm/src/session_gc.rs index 1d4cdd93..4f6775fd 100644 --- a/crates/oxide_vm/src/session_gc.rs +++ b/crates/oxide_vm/src/session_gc.rs @@ -62,8 +62,7 @@ impl SessionGc { let elems_ptr = obj.array_elements_raw() as *const Vec; if !elems_ptr.is_null() { unsafe { - bytes += size_of::>() as u64 - + ((*elems_ptr).capacity() * size_of::()) as u64; + bytes += size_of::>() as u64 + ((*elems_ptr).capacity() * size_of::()) as u64; } } @@ -78,8 +77,7 @@ impl SessionGc { let hash_ptr = obj.hash_props_raw() as *const Vec; if !hash_ptr.is_null() { unsafe { - bytes += size_of::>() as u64 - + ((*hash_ptr).capacity() * size_of::()) as u64; + bytes += size_of::>() as u64 + ((*hash_ptr).capacity() * size_of::()) as u64; } } @@ -112,9 +110,7 @@ impl SessionGc { /// 单趟替代原 `object_edges` + `record_object_string_edges` 双遍模式:消除每对象 /// Vec 分配与重复字段遍历。 fn scan_edges_for_mark( - obj: &JsObject, - vm: &Vm, - stack: &mut Vec<*mut JsObject>, + obj: &JsObject, vm: &Vm, stack: &mut Vec<*mut JsObject>, live_strings: &mut HashSet<*mut JsString, FxBuildHasher>, live_bigints: &mut HashSet<*mut num_bigint::BigInt, FxBuildHasher>, ) { @@ -209,9 +205,7 @@ impl SessionGc { #[inline] fn process_edge( - value: JsValue, - vm: &Vm, - stack: &mut Vec<*mut JsObject>, + value: JsValue, vm: &Vm, stack: &mut Vec<*mut JsObject>, live_strings: &mut HashSet<*mut JsString, FxBuildHasher>, live_bigints: &mut HashSet<*mut num_bigint::BigInt, FxBuildHasher>, ) { @@ -591,7 +585,8 @@ impl SessionGc { forwarding.clear(); vm.gc_state.forwarding = forwarding; vm.gc_state.session_epoch = new_arena; - vm.gc_state.session_bytes_allocated = vm.gc_state + vm.gc_state.session_bytes_allocated = vm + .gc_state .session_object_ptrs .iter() .filter(|&&ptr| !ptr.is_null()) @@ -811,7 +806,8 @@ impl SessionGc { self.debug_assert_marked_object_strings_live(vm); // 扣减字符串账目(保留对象账目),再补回存活串字节。 - let object_bytes: usize = vm.gc_state + let object_bytes: usize = vm + .gc_state .session_object_ptrs .iter() .filter(|&&ptr| !ptr.is_null()) diff --git a/crates/oxide_vm/src/vm_dispatch_misc.rs b/crates/oxide_vm/src/vm_dispatch_misc.rs index 3582ea60..0824ed8e 100644 --- a/crates/oxide_vm/src/vm_dispatch_misc.rs +++ b/crates/oxide_vm/src/vm_dispatch_misc.rs @@ -141,8 +141,10 @@ impl Vm { )?; Ok(true) } else { - let error = - oxide_builtins::error::create_from_text(self, "NEW_EXPRESSION: bytecode constructors not yet supported"); + let error = oxide_builtins::error::create_from_text( + self, + "NEW_EXPRESSION: bytecode constructors not yet supported", + ); self.exception_value = Some(error); self.pending_error_kind = Some(self.thrown_error_kind(error)); self.unwind().map(|_| true) @@ -1053,7 +1055,8 @@ impl Vm { // 免 promote 搬移——若按 epoch 分配,首次写入 session 根会把对象搬到新 // 地址,缓存中的旧指针与新实例分叉,同一 site 两次取值将返回不同对象。 let mut alloc_session_array = |n: usize| { - let mut clone = JsObject::new_array(oxide_kernel::shape_forge::EMPTY_SHAPE_ID, proto_val, n, self.epoch.bump()); + let mut clone = + JsObject::new_array(oxide_kernel::shape_forge::EMPTY_SHAPE_ID, proto_val, n, self.epoch.bump()); // 标记 session 归属:session_epoch 分配的对象须显式置位,GC/释放路径 // 据 SESSION_EPOCH_BIT 判定归属(与 promote_object 的 clone 路径一致)。 clone.set_session_epoch(true); @@ -1095,7 +1098,7 @@ impl Vm { // 键,DefinePropertyOrThrow 默认 false)。先于冻结定义(冻结后不可扩展, // 新增属性会被拒)。 let raw_si = self.kernel_core.perm_interner().intern("raw").0; -// SAFETY: cooked 为本函数分配的 epoch 对象,借用仅在本次 define 内消费。 + // SAFETY: cooked 为本函数分配的 epoch 对象,借用仅在本次 define 内消费。 self.define_data_property(unsafe { &mut *cooked }, raw_si, raw_val, PropAttributes::new(false, false, false))?; // 冻结两个数组:不可扩展 + length writable=false(is_frozen 使 length diff --git a/crates/oxide_vm/tests/builtins_temporal_tests.rs b/crates/oxide_vm/tests/builtins_temporal_tests.rs index 74b7bb9d..b2bac855 100644 --- a/crates/oxide_vm/tests/builtins_temporal_tests.rs +++ b/crates/oxide_vm/tests/builtins_temporal_tests.rs @@ -2465,18 +2465,9 @@ fn duration_compare_calendar_units_require_relative() { fn duration_compare_relative_calendar_units() { let mut vm = Vm::new(); // relativeto-month 对拍:P1M vs P30D 取决于相对点所在月份长度。 - assert_eq!( - num(&mut vm, "Temporal.Duration.compare('P1M','P30D',{relativeTo:'2018-04-01'})"), - 0.0 - ); - assert_eq!( - num(&mut vm, "Temporal.Duration.compare('P1M','P30D',{relativeTo:'2018-03-01'})"), - 1.0 - ); - assert_eq!( - num(&mut vm, "Temporal.Duration.compare('P1M','P30D',{relativeTo:'2018-02-01'})"), - -1.0 - ); + assert_eq!(num(&mut vm, "Temporal.Duration.compare('P1M','P30D',{relativeTo:'2018-04-01'})"), 0.0); + assert_eq!(num(&mut vm, "Temporal.Duration.compare('P1M','P30D',{relativeTo:'2018-03-01'})"), 1.0); + assert_eq!(num(&mut vm, "Temporal.Duration.compare('P1M','P30D',{relativeTo:'2018-02-01'})"), -1.0); // string 与 PlainDate 对象等价。 assert_eq!( num( diff --git a/crates/oxide_vm/tests/mem_tests.rs b/crates/oxide_vm/tests/mem_tests.rs index ac538d14..3d26b95b 100644 --- a/crates/oxide_vm/tests/mem_tests.rs +++ b/crates/oxide_vm/tests/mem_tests.rs @@ -27,7 +27,6 @@ fn epoch_reset_increments_id() { assert_eq!(epoch.current_id(), 2); } - #[test] fn persistent_new_and_deref() { let p = P::new(42i32);