Skip to content

Commit c08144f

Browse files
committed
feat(cli): add now builtin function
1 parent 4f89806 commit c08144f

File tree

4 files changed

+91
-2
lines changed

4 files changed

+91
-2
lines changed

nova_cli/src/helper.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use nova_vm::{
99
builtins::{ArgumentsList, Behaviour, BuiltinFunctionArgs, create_builtin_function},
1010
execution::{Agent, JsResult, agent::ExceptionType},
1111
types::{
12-
InternalMethods, IntoValue, Object, OrdinaryObject, PropertyDescriptor, PropertyKey,
13-
String, Value,
12+
BigInt, InternalMethods, IntoValue, Object, OrdinaryObject, PropertyDescriptor,
13+
PropertyKey, String, Value,
1414
},
1515
},
1616
engine::{
@@ -82,6 +82,21 @@ pub fn initialize_global_object(agent: &mut Agent, global: Object, mut gc: GcSco
8282
Ok(String::from_string(agent, file, gc.into_nogc()).into_value())
8383
}
8484

85+
// 'now' function
86+
fn now<'gc>(
87+
agent: &mut Agent,
88+
_this: Value,
89+
_args: ArgumentsList,
90+
gc: GcScope<'gc, '_>,
91+
) -> JsResult<'gc, Value<'gc>> {
92+
let now = std::time::SystemTime::now()
93+
.duration_since(std::time::UNIX_EPOCH)
94+
.unwrap()
95+
.as_nanos();
96+
let bigint = BigInt::from_u128(agent, now, gc.into_nogc());
97+
Ok(bigint.into_value())
98+
}
99+
85100
let function = create_builtin_function(
86101
agent,
87102
Behaviour::Regular(print),
@@ -127,6 +142,29 @@ pub fn initialize_global_object(agent: &mut Agent, global: Object, mut gc: GcSco
127142
gc.reborrow(),
128143
)
129144
.unwrap();
145+
146+
let function = create_builtin_function(
147+
agent,
148+
Behaviour::Regular(now),
149+
BuiltinFunctionArgs::new(0, "now"),
150+
gc.nogc(),
151+
);
152+
let property_key = PropertyKey::from_static_str(agent, "now", gc.nogc());
153+
global
154+
.get(agent)
155+
.internal_define_own_property(
156+
agent,
157+
property_key.unbind(),
158+
PropertyDescriptor {
159+
value: Some(function.into_value().unbind()),
160+
writable: Some(true),
161+
enumerable: Some(false),
162+
configurable: Some(true),
163+
..Default::default()
164+
},
165+
gc.reborrow(),
166+
)
167+
.unwrap();
130168
}
131169

132170
pub fn initialize_global_object_with_internals(agent: &mut Agent, global: Object, mut gc: GcScope) {

nova_vm/src/ecmascript/types/language/bigint.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,19 @@ impl<'a> BigInt<'a> {
189189
Self::SmallBigInt(SmallBigInt::zero())
190190
}
191191

192+
pub fn from_bigint(agent: &mut Agent, bigint: &BigIntHeapData, gc: NoGcScope<'a, '_>) -> Self {
193+
if let Ok(result) = SmallBigInt::try_from(&bigint.data) {
194+
Self::SmallBigInt(result)
195+
} else {
196+
agent
197+
.heap
198+
.create(BigIntHeapData {
199+
data: bigint.data.clone(),
200+
})
201+
.bind(gc)
202+
}
203+
}
204+
192205
#[inline]
193206
pub fn from_i64(agent: &mut Agent, value: i64) -> Self {
194207
if let Ok(result) = SmallBigInt::try_from(value) {
@@ -207,6 +220,30 @@ impl<'a> BigInt<'a> {
207220
}
208221
}
209222

223+
#[inline]
224+
pub fn from_i128(agent: &mut Agent, value: i128, gc: NoGcScope<'a, '_>) -> Self {
225+
if let Ok(result) = SmallBigInt::try_from(value) {
226+
Self::SmallBigInt(result)
227+
} else {
228+
agent
229+
.heap
230+
.create(BigIntHeapData { data: value.into() })
231+
.bind(gc)
232+
}
233+
}
234+
235+
#[inline]
236+
pub fn from_u128(agent: &mut Agent, value: u128, gc: NoGcScope<'a, '_>) -> Self {
237+
if let Ok(result) = SmallBigInt::try_from(value) {
238+
Self::SmallBigInt(result)
239+
} else {
240+
agent
241+
.heap
242+
.create(BigIntHeapData { data: value.into() })
243+
.bind(gc)
244+
}
245+
}
246+
210247
#[inline]
211248
pub(crate) fn from_num_bigint(agent: &mut Agent, value: num_bigint::BigInt) -> Self {
212249
if let Ok(result) = SmallBigInt::try_from(&value) {

nova_vm/src/engine/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,8 @@ trivially_bindable!(i32);
437437
trivially_bindable!(u32);
438438
trivially_bindable!(i64);
439439
trivially_bindable!(u64);
440+
trivially_bindable!(i128);
441+
trivially_bindable!(u128);
440442
trivially_bindable!(isize);
441443
trivially_bindable!(usize);
442444
#[cfg(feature = "proposal-float16array")]

nova_vm/src/engine/small_bigint.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,18 @@ impl TryFrom<u64> for SmallBigInt {
188188
}
189189
}
190190

191+
impl TryFrom<u128> for SmallBigInt {
192+
type Error = ();
193+
fn try_from(value: u128) -> Result<Self, Self::Error> {
194+
if (Self::MIN as u128..=Self::MAX as u128).contains(&value) {
195+
// SAFETY: Checked to be in range.
196+
Ok(unsafe { Self::from_i64_unchecked(value as i64) })
197+
} else {
198+
Err(())
199+
}
200+
}
201+
}
202+
191203
impl TryFrom<usize> for SmallBigInt {
192204
type Error = ();
193205
fn try_from(value: usize) -> Result<Self, Self::Error> {

0 commit comments

Comments
 (0)