feat: implement Temporal Instant zoned conversion
This commit is contained in:
@@ -70,6 +70,10 @@ pub fn bind_symbol(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
|
||||
"asyncIterator",
|
||||
JsValue::from_js_object(session.builtin_world().sym_async_iterator.as_ptr() as *mut JsObject),
|
||||
),
|
||||
(
|
||||
"toStringTag",
|
||||
JsValue::from_js_object(session.builtin_world().sym_to_string_tag.as_ptr() as *mut JsObject),
|
||||
),
|
||||
] {
|
||||
bind_well_known_symbol(core, ctor, name, val);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::bindings::{apply_binding_table, bind_accessor_getter, bind_global_value, configure_native_constructor};
|
||||
use crate::bindings::{
|
||||
apply_binding_table, bind_accessor_getter, bind_global_value, bind_well_known_data_property,
|
||||
configure_native_constructor,
|
||||
};
|
||||
use oxide_kernel::kernel::{KernelCore, KernelSession};
|
||||
use oxide_types::object::JsObject;
|
||||
use oxide_types::object::{JsObject, PropAttributes};
|
||||
use oxide_types::value::JsValue;
|
||||
|
||||
/// 把 Temporal 命名空间及其子对象绑定到 global。
|
||||
@@ -98,10 +101,67 @@ pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &m
|
||||
0,
|
||||
),
|
||||
("toString", oxide_builtins::temporal::instant_to_string::<crate::vm::Vm> as *const (), 0),
|
||||
(
|
||||
"toZonedDateTimeISO",
|
||||
oxide_builtins::temporal::instant_to_zoned_date_time_iso::<crate::vm::Vm> as *const (),
|
||||
1,
|
||||
),
|
||||
("until", oxide_builtins::temporal::instant_until::<crate::vm::Vm> as *const (), 1),
|
||||
("valueOf", oxide_builtins::temporal::instant_value_of::<crate::vm::Vm> as *const (), 0),
|
||||
],
|
||||
);
|
||||
bind_well_known_data_property(
|
||||
core,
|
||||
instant_proto,
|
||||
9,
|
||||
JsValue::perm_string(
|
||||
core.perm_interner()
|
||||
.string_ptr(core.perm_interner().intern("Temporal.Instant").0),
|
||||
),
|
||||
PropAttributes::new(false, false, true),
|
||||
);
|
||||
|
||||
// Temporal.ZonedDateTime:最小构造器与三个稳定内部槽 getter。
|
||||
let zoned_date_time_ctor_ptr = world.zoned_date_time_constructor.as_ptr() as *mut JsObject;
|
||||
let zoned_date_time_ctor = unsafe { &mut *zoned_date_time_ctor_ptr };
|
||||
configure_native_constructor(
|
||||
zoned_date_time_ctor,
|
||||
oxide_builtins::temporal::zoned_date_time_constructor::<crate::vm::Vm> as *const (),
|
||||
2,
|
||||
);
|
||||
let zoned_date_time_proto_ptr = world.zoned_date_time_proto.as_ptr() as *mut JsObject;
|
||||
let zoned_date_time_proto = unsafe { &mut *zoned_date_time_proto_ptr };
|
||||
bind_accessor_getter(
|
||||
core,
|
||||
session,
|
||||
zoned_date_time_proto,
|
||||
"epochNanoseconds",
|
||||
oxide_builtins::temporal::zoned_date_time_epoch_nanoseconds::<crate::vm::Vm> as *const (),
|
||||
);
|
||||
bind_accessor_getter(
|
||||
core,
|
||||
session,
|
||||
zoned_date_time_proto,
|
||||
"timeZoneId",
|
||||
oxide_builtins::temporal::zoned_date_time_time_zone_id::<crate::vm::Vm> as *const (),
|
||||
);
|
||||
bind_accessor_getter(
|
||||
core,
|
||||
session,
|
||||
zoned_date_time_proto,
|
||||
"calendarId",
|
||||
oxide_builtins::temporal::zoned_date_time_calendar_id::<crate::vm::Vm> as *const (),
|
||||
);
|
||||
bind_well_known_data_property(
|
||||
core,
|
||||
zoned_date_time_proto,
|
||||
9,
|
||||
JsValue::perm_string(
|
||||
core.perm_interner()
|
||||
.string_ptr(core.perm_interner().intern("Temporal.ZonedDateTime").0),
|
||||
),
|
||||
PropAttributes::new(false, false, true),
|
||||
);
|
||||
|
||||
// Temporal.PlainDate:构造器 + from 静态方法 + year/month/day getter 与 toString。
|
||||
let plain_date_ctor_ptr = world.plain_date_constructor.as_ptr() as *mut JsObject;
|
||||
@@ -376,5 +436,6 @@ pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &m
|
||||
bind_global_value(core, temporal, "PlainDate", JsValue::from_js_object(plain_date_ctor_ptr));
|
||||
bind_global_value(core, temporal, "PlainTime", JsValue::from_js_object(plain_time_ctor_ptr));
|
||||
bind_global_value(core, temporal, "Duration", JsValue::from_js_object(duration_ctor_ptr));
|
||||
bind_global_value(core, temporal, "ZonedDateTime", JsValue::from_js_object(zoned_date_time_ctor_ptr));
|
||||
bind_global_value(core, global, "Temporal", JsValue::from_js_object(temporal_ptr));
|
||||
}
|
||||
|
||||
@@ -222,6 +222,18 @@ pub(crate) fn bind_well_known_method_alias(
|
||||
proto.bump_generation();
|
||||
}
|
||||
|
||||
/// 在对象上按 well-known symbol 键绑定数据属性。
|
||||
pub(crate) fn bind_well_known_data_property(
|
||||
core: &Arc<KernelCore>, target: &mut JsObject, well_known_id: u32, value: JsValue, attributes: PropAttributes,
|
||||
) {
|
||||
let key = oxide_types::private_key::make_well_known_symbol_key(well_known_id);
|
||||
let new_shape = core.shape_forge().make_shape(target.shape_id(), key);
|
||||
target.set_shape_id(new_shape);
|
||||
let pos = target.push_prop(value);
|
||||
target.set_data_meta(pos, attributes);
|
||||
target.bump_generation();
|
||||
}
|
||||
|
||||
pub(crate) fn bind_global_value(core: &Arc<KernelCore>, global: &mut JsObject, name: &str, value: JsValue) {
|
||||
let si = core.perm_interner().intern(name).0;
|
||||
let shape = core.shape_forge().make_shape(global.shape_id(), si);
|
||||
|
||||
@@ -905,6 +905,8 @@ impl Vm {
|
||||
Some(7)
|
||||
} else if std::ptr::eq(ptr, world.sym_async_iterator.as_ptr()) {
|
||||
Some(8)
|
||||
} else if std::ptr::eq(ptr, world.sym_to_string_tag.as_ptr()) {
|
||||
Some(9)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -985,7 +987,7 @@ impl Vm {
|
||||
// 数组属性存储索引 = array_prop_count + shape 槽位(与元素区分)。
|
||||
let idx = obj.array_prop_count as usize + pos as usize;
|
||||
let val = obj.get_prop_at(idx);
|
||||
if !val.is_undefined() {
|
||||
if !val.is_undefined() || obj.prop_vec_len() > idx {
|
||||
Some(idx as u32)
|
||||
} else {
|
||||
None
|
||||
|
||||
Reference in New Issue
Block a user