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