Skip to main content

v8/
number.rs

1use std::alloc::Layout;
2use std::ptr::NonNull;
3
4use crate::Int32;
5use crate::Integer;
6use crate::Local;
7use crate::Number;
8use crate::Uint32;
9use crate::isolate::RealIsolate;
10use crate::scope::PinScope;
11
12unsafe extern "C" {
13  fn v8__Number__New(isolate: *mut RealIsolate, value: f64) -> *const Number;
14  fn v8__Number__Value(this: *const Number) -> f64;
15  fn v8__Integer__New(isolate: *mut RealIsolate, value: i32) -> *const Integer;
16  fn v8__Integer__NewFromUnsigned(
17    isolate: *mut RealIsolate,
18    value: u32,
19  ) -> *const Integer;
20  fn v8__Integer__Value(this: *const Integer) -> i64;
21  fn v8__Uint32__Value(this: *const Uint32) -> u32;
22  fn v8__Int32__Value(this: *const Int32) -> i32;
23}
24
25impl Number {
26  #[inline(always)]
27  pub fn new<'s>(
28    scope: &PinScope<'s, '_, ()>,
29    value: f64,
30  ) -> Local<'s, Number> {
31    unsafe {
32      scope.cast_local(|sd| v8__Number__New(sd.get_isolate_ptr(), value))
33    }
34    .unwrap()
35  }
36
37  #[inline(always)]
38  pub fn value(&self) -> f64 {
39    unsafe { v8__Number__Value(self) }
40  }
41}
42
43impl Integer {
44  #[inline(always)]
45  pub fn new<'s>(
46    scope: &PinScope<'s, '_, ()>,
47    value: i32,
48  ) -> Local<'s, Integer> {
49    unsafe {
50      scope.cast_local(|sd| v8__Integer__New(sd.get_isolate_ptr(), value))
51    }
52    .unwrap()
53  }
54
55  #[inline(always)]
56  pub fn new_from_unsigned<'s>(
57    scope: &PinScope<'s, '_, ()>,
58    value: u32,
59  ) -> Local<'s, Integer> {
60    unsafe {
61      scope.cast_local(|sd| {
62        v8__Integer__NewFromUnsigned(sd.get_isolate_ptr(), value)
63      })
64    }
65    .unwrap()
66  }
67
68  #[inline(always)]
69  pub fn value(&self) -> i64 {
70    unsafe { v8__Integer__Value(self) }
71  }
72
73  /// Internal helper function to produce a handle containing a SMI zero value,
74  /// without the need for the caller to provide (or have entered) a
75  /// `HandleScope`.
76  #[inline(always)]
77  pub(crate) fn zero<'s>() -> Local<'s, Integer> {
78    // The SMI representation of zero is also zero. In debug builds, double
79    // check this, so in the unlikely event that V8 changes its internal
80    // representation of SMIs such that this invariant no longer holds, we'd
81    // catch it.
82    static ZERO_SMI: usize = 0;
83    let zero_raw = &ZERO_SMI as *const _ as *mut Self;
84    let zero_nn = unsafe { NonNull::new_unchecked(zero_raw) };
85    let zero_local = unsafe { Local::from_non_null(zero_nn) };
86    debug_assert_eq!(Layout::new::<usize>(), Layout::new::<Local<Self>>());
87    debug_assert_eq!(zero_local.value(), 0);
88    zero_local
89  }
90}
91
92impl Uint32 {
93  #[inline(always)]
94  pub fn value(&self) -> u32 {
95    unsafe { v8__Uint32__Value(self) }
96  }
97}
98
99impl Int32 {
100  #[inline(always)]
101  pub fn value(&self) -> i32 {
102    unsafe { v8__Int32__Value(self) }
103  }
104}