Skip to main content

shape_jit/ffi/call_method/
time.rs

1// Heap allocation audit (PR-9 V8 Gap Closure):
2//   Category A (NaN-boxed returns): 2 sites
3//     box_string(...) — format, toString
4//   Category B (intermediate/consumed): 0 sites
5//   Category C (heap islands): 0 sites
6//!
7//! Time method implementations for JIT
8
9use crate::ffi::jit_kinds::*;
10use crate::ffi::value_ffi::*;
11use chrono::{Datelike, TimeZone, Timelike, Utc};
12
13/// Call a method on a time value
14#[inline(always)]
15pub fn call_time_method(receiver_bits: u64, method_name: &str, _args: &[u64]) -> u64 {
16    // Time is heap-allocated as i64 timestamp
17    if !is_heap_kind(receiver_bits, HK_TIME) {
18        return TAG_NULL;
19    }
20    let timestamp = unsafe { *unified_unbox::<i64>(receiver_bits) };
21
22    // Try to create DateTime from timestamp (treating as seconds)
23    let dt = match Utc.timestamp_opt(timestamp, 0) {
24        chrono::LocalResult::Single(dt) => dt,
25        _ => {
26            // Try milliseconds
27            match Utc.timestamp_millis_opt(timestamp) {
28                chrono::LocalResult::Single(dt) => dt,
29                _ => return TAG_NULL,
30            }
31        }
32    };
33
34    match method_name {
35        "format" => {
36            // Default format
37            let formatted = dt.format("%Y-%m-%d").to_string();
38            box_string(formatted)
39        }
40        "year" => box_number(dt.year() as f64),
41        "month" => box_number(dt.month() as f64),
42        "day" => box_number(dt.day() as f64),
43        "hour" => box_number(dt.hour() as f64),
44        "minute" => box_number(dt.minute() as f64),
45        "second" => box_number(dt.second() as f64),
46        "weekday" | "dayOfWeek" | "day_of_week" => {
47            // Monday = 0, Sunday = 6
48            box_number(dt.weekday().num_days_from_monday() as f64)
49        }
50        "timestamp" | "unix" => box_number(timestamp as f64),
51        "toString" | "to_string" => {
52            let s = dt.to_rfc3339();
53            box_string(s)
54        }
55        _ => TAG_NULL,
56    }
57}