From e27bf9150726870de4a41b0f4f66d8068d6515bf Mon Sep 17 00:00:00 2001 From: richarddavison <89518095+richarddavison@users.noreply.github.com> Date: Wed, 14 Feb 2024 09:38:07 +0100 Subject: [PATCH] Fix process hr-time-res (#156) --- src/console.rs | 8 ++++++++ src/encoding/mod.rs | 2 +- src/main.rs | 11 ++++++++--- src/process.rs | 41 ++++++++++++++++++++++++++--------------- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/console.rs b/src/console.rs index a034cab74c..1b6b428826 100644 --- a/src/console.rs +++ b/src/console.rs @@ -132,6 +132,7 @@ fn stringify_primitive<'js>( Type::Undefined => result.push_str(COLOR_BLACK), Type::Int | Type::Float | Type::Bool => result.push_str(COLOR_YELLOW), Type::Symbol => result.push_str(COLOR_GREEN), + Type::BigInt => result.push_str(COLOR_YELLOW), _ => has_color = false, } } @@ -144,6 +145,12 @@ fn stringify_primitive<'js>( } else { "false" }), + Type::BigInt => { + let mut buffer = itoa::Buffer::new(); + let big_int = value.as_big_int().unwrap(); + result.push_str(buffer.format(big_int.clone().to_i64()?)); + result.push('n'); + } Type::Int => { let mut buffer = itoa::Buffer::new(); result.push_str(buffer.format(value.as_int().unwrap())) @@ -194,6 +201,7 @@ fn is_primitive_like_or_void(typeof_value: Type) -> bool { | Type::Int | Type::Float | Type::String + | Type::BigInt | Type::Symbol | Type::Unknown ) diff --git a/src/encoding/mod.rs b/src/encoding/mod.rs index 344ac3d813..c287a139b5 100644 --- a/src/encoding/mod.rs +++ b/src/encoding/mod.rs @@ -143,7 +143,7 @@ impl StringBuilder { } } -pub fn atob<'js>(ctx: Ctx<'js>, encoded_value: String) -> Result { +pub fn atob(ctx: Ctx<'_>, encoded_value: String) -> Result { let vec = bytes_from_b64(encoded_value.as_bytes()).or_throw(&ctx)?; Ok(unsafe { String::from_utf8_unchecked(vec) }) } diff --git a/src/main.rs b/src/main.rs index 605fa5059c..38aab317a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,8 +37,9 @@ mod xml; use minimal_tracer::MinimalTracer; use rquickjs::{AsyncContext, Module}; use std::{ - env::{self}, + env, error::Error, + mem::MaybeUninit, path::{Path, PathBuf}, process::exit, sync::atomic::Ordering, @@ -59,13 +60,17 @@ const VERSION: &str = env!("CARGO_PKG_VERSION"); #[global_allocator] static ALLOC: snmalloc_rs::SnMalloc = snmalloc_rs::SnMalloc; +pub static mut STARTED: MaybeUninit = MaybeUninit::uninit(); + #[tokio::main] async fn main() -> Result<(), Box> { + let now = Instant::now(); + + unsafe { STARTED.write(Instant::now()) }; + MinimalTracer::register()?; trace!("Started runtime"); - let now = Instant::now(); - let vm = Vm::new().await?; trace!("Initialized VM in {}ms", now.elapsed().as_millis()); diff --git a/src/process.rs b/src/process.rs index 7e13cac272..e5e9edd0a2 100644 --- a/src/process.rs +++ b/src/process.rs @@ -1,17 +1,13 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use std::{ - collections::HashMap, - env, - time::{SystemTime, UNIX_EPOCH}, -}; +use std::{collections::HashMap, env}; use rquickjs::{ atom::PredefinedAtom, convert::Coerced, function::Constructor, object::Property, prelude::Func, - Ctx, IntoJs, Object, Result, Value, + Array, BigInt, Ctx, Function, IntoJs, Object, Result, Value, }; -use crate::VERSION; +use crate::{STARTED, VERSION}; fn cwd() -> String { env::current_dir().unwrap().to_string_lossy().to_string() @@ -37,11 +33,26 @@ pub fn get_platform() -> &'static str { platform } -fn current_time_micros() -> u64 { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_micros() as u64 +fn hr_time_big_int(ctx: Ctx<'_>) -> Result { + let started = unsafe { STARTED.assume_init() }; + let elapsed = started.elapsed().as_nanos() as u64; + + BigInt::from_u64(ctx, elapsed) +} + +fn hr_time(ctx: Ctx<'_>) -> Result> { + let started = unsafe { STARTED.assume_init() }; + let elapsed = started.elapsed().as_nanos() as u64; + + let seconds = elapsed / 1_000_000_000; + let remaining_nanos = elapsed % 1_000_000_000; + + let array = Array::new(ctx)?; + + array.set(0, seconds)?; + array.set(1, remaining_nanos)?; + + Ok(array) } fn exit(code: i32) { @@ -64,12 +75,12 @@ pub fn init(ctx: &Ctx<'_>) -> Result<()> { let process_versions = Object::new(ctx.clone())?; process_versions.set("llrt", VERSION)?; + let hr_time = Function::new(ctx.clone(), hr_time)?; + hr_time.set("bigint", Func::from(hr_time_big_int))?; + let release = Object::new(ctx.clone())?; release.prop("name", Property::from("llrt").enumerable())?; - let hr_time = Object::new(ctx.clone())?; - hr_time.set("bigint", Func::from(current_time_micros))?; - let env_map: HashMap = env::vars().collect(); let mut args: Vec = env::args().collect();