use crate::binding::*;
use crate::Isolate;
use crate::Local;
use crate::Value;
use std::ffi::c_void;
use std::marker::PhantomData;
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct CFunction(v8__CFunction);
impl CFunction {
pub const fn new(address: *const c_void, type_info: &CFunctionInfo) -> Self {
Self(v8__CFunction {
address_: address,
type_info_: &type_info.0,
})
}
pub const fn address(&self) -> *const c_void {
self.0.address_
}
pub const fn type_info(&self) -> &CFunctionInfo {
unsafe { &*(self.0.type_info_ as *const CFunctionInfo) }
}
}
#[repr(transparent)]
pub struct CFunctionInfo(v8__CFunctionInfo);
impl CFunctionInfo {
pub const fn new(
return_info: CTypeInfo,
arg_info: &[CTypeInfo],
repr: Int64Representation,
) -> Self {
Self(v8__CFunctionInfo {
arg_count_: arg_info.len() as _,
arg_info_: arg_info.as_ptr() as _,
repr_: repr as _,
return_info_: return_info.0,
})
}
}
#[derive(Clone, Copy)]
#[repr(u8)]
pub enum Int64Representation {
Number = v8_CFunctionInfo_Int64Representation_kNumber,
BigInt = v8_CFunctionInfo_Int64Representation_kBigInt,
}
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct CTypeInfo(v8_CTypeInfo);
impl CTypeInfo {
pub const fn new(
r#type: Type,
sequence_type: SequenceType,
flags: Flags,
) -> Self {
Self(v8_CTypeInfo {
flags_: flags.bits(),
sequence_type_: sequence_type as _,
type_: r#type as _,
})
}
}
#[derive(Clone, Copy)]
#[repr(u8)]
pub enum Type {
Void = v8_CTypeInfo_Type_kVoid,
Bool = v8_CTypeInfo_Type_kBool,
Uint8 = v8_CTypeInfo_Type_kUint8,
Int32 = v8_CTypeInfo_Type_kInt32,
Uint32 = v8_CTypeInfo_Type_kUint32,
Int64 = v8_CTypeInfo_Type_kInt64,
Uint64 = v8_CTypeInfo_Type_kUint64,
Float32 = v8_CTypeInfo_Type_kFloat32,
Float64 = v8_CTypeInfo_Type_kFloat64,
Pointer = v8_CTypeInfo_Type_kPointer,
V8Value = v8_CTypeInfo_Type_kV8Value,
SeqOneByteString = v8_CTypeInfo_Type_kSeqOneByteString,
ApiObject = v8_CTypeInfo_Type_kApiObject,
Any = v8_CTypeInfo_Type_kAny,
CallbackOptions = 255,
}
impl Type {
pub const fn scalar(self) -> CTypeInfo {
CTypeInfo::new(self, SequenceType::Scalar, Flags::empty())
}
pub const fn typed_array(self) -> CTypeInfo {
CTypeInfo::new(self, SequenceType::IsTypedArray, Flags::empty())
}
}
#[derive(Clone, Copy)]
#[repr(u8)]
pub enum SequenceType {
Scalar = v8_CTypeInfo_SequenceType_kScalar,
IsSequence = v8_CTypeInfo_SequenceType_kIsSequence,
IsTypedArray = v8_CTypeInfo_SequenceType_kIsTypedArray,
IsArrayBuffer = v8_CTypeInfo_SequenceType_kIsArrayBuffer,
}
bitflags::bitflags! {
pub struct Flags: u8 {
const AllowShared = v8_CTypeInfo_Flags_kAllowSharedBit;
const EnforceRange = v8_CTypeInfo_Flags_kEnforceRangeBit;
const Clamp = v8_CTypeInfo_Flags_kClampBit;
const IsRestricted = v8_CTypeInfo_Flags_kIsRestrictedBit;
}
}
#[repr(C)]
pub struct FastApiCallbackOptions<'a> {
pub isolate: *mut Isolate,
pub data: Local<'a, Value>,
}
#[allow(unused)] #[repr(transparent)]
pub struct FastApiTypedArray<T: Default>(v8__FastApiTypedArray, PhantomData<T>);
impl<T: Default> FastApiTypedArray<T> {
pub const fn length(&self) -> usize {
self.0._base.length_
}
#[inline(always)]
pub const fn get(&self, index: usize) -> T {
debug_assert!(index < self.length());
unsafe { std::ptr::read_unaligned((self.0.data_ as *const T).add(index)) }
}
#[inline(always)]
pub fn get_storage_if_aligned(&self) -> Option<&mut [T]> {
if self.length() == 0 {
return Some(&mut []);
}
let data = self.0.data_ as *mut T;
if data.is_null() || !data.is_aligned() {
None
} else {
Some(unsafe { std::slice::from_raw_parts_mut(data, self.length()) })
}
}
}
pub type FastApiArrayBufferView = v8__FastApiArrayBufferView;
pub type FastApiOneByteString = v8__FastOneByteString;
impl FastApiOneByteString {
#[inline(always)]
pub fn as_bytes(&self) -> &[u8] {
if self.data.is_null() {
return &mut [];
}
unsafe { std::slice::from_raw_parts(self.data as _, self.length as usize) }
}
}