Skip to main content

dynamic/
types.rs

1use crate::{Dynamic, DynamicErr};
2use smol_str::SmolStr;
3
4use anyhow::{Result, anyhow};
5use std::rc::Rc;
6use std::sync::RwLock;
7
8#[derive(Debug, Clone, Copy, Eq, PartialEq)]
9pub enum ConstIntOp {
10    Add,
11    Sub,
12    Mul,
13    Div,
14    Mod,
15}
16
17#[derive(Debug, Default, Clone, Eq)]
18pub enum Type {
19    #[default]
20    Any, //这个是任何类型 none 动态类型 可以是任何类型
21    Void, //整个是空类型  void()
22    Bool,
23    U8,
24    I8,
25    U16,
26    I16,
27    U32,
28    I32,
29    U64,
30    I64,
31    F16,
32    F32,
33    F64,
34    Str,
35    Map,
36    List(Rc<Type>),
37    Iter,
38    Ident {
39        name: SmolStr,
40        params: Vec<Type>,
41    },
42    ConstInt(i64),
43    ConstBinary {
44        op: ConstIntOp,
45        left: Rc<Type>,
46        right: Rc<Type>,
47    },
48    Tuple(Vec<Type>),
49    Struct {
50        params: Vec<Type>,
51        fields: Vec<(SmolStr, Type)>,
52    },
53    Vec(Rc<Type>, u32),   //spirv 特有 表示向量 一般在四个元素以下
54    Array(Rc<Type>, u32), //这是通常意义上的 类型数组,没有大小的限制
55    ArrayParam(Rc<Type>, Rc<Type>),
56    Fn {
57        tys: Vec<Type>,
58        ret: Rc<Type>,
59    }, //调用参数 和返回参数的类型 注意
60    Symbol {
61        id: u32,
62        params: Vec<Type>,
63    }, //自定义的类型 仅在有符号表的情况下有意义 可能是结构 有可能是函数 支持泛型参数
64}
65
66unsafe impl Send for Type {}
67unsafe impl Sync for Type {}
68
69impl std::ops::Add for Type {
70    type Output = Self;
71    fn add(self, rhs: Self) -> Self::Output {
72        if self == rhs {
73            self
74        } else if self.is_str() || rhs.is_str() {
75            Type::Str
76        } else if self.is_any() || rhs.is_any() {
77            Type::Any
78        } else if self.is_float() || rhs.is_float() {
79            if self.is_f64() || rhs.is_f64() { Type::F64 } else { Type::F32 }
80        } else if self.is_int() || rhs.is_int() {
81            let width = self.width().max(rhs.width());
82            match width {
83                1 => Type::I8,
84                2 => Type::I16,
85                4 => Type::I32,
86                8 => Type::I64,
87                _ => panic!("{:?} 非法类型", self),
88            }
89        } else if self.is_uint() || rhs.is_uint() {
90            let width = self.width().max(rhs.width());
91            match width {
92                1 => Type::U8,
93                2 => Type::U16,
94                4 => Type::U32,
95                8 => Type::U64,
96                _ => panic!("{:?} 非法类型", self),
97            }
98        } else {
99            Type::Any
100        }
101    }
102}
103
104impl PartialEq for Type {
105    fn eq(&self, other: &Self) -> bool {
106        match (self, other) {
107            (Type::Any, Type::Any) => true,
108            (Type::Void, Type::Void)
109            | (Type::Bool, Type::Bool)
110            | (Type::U8, Type::U8)
111            | (Type::I8, Type::I8)
112            | (Type::U16, Type::U16)
113            | (Type::I16, Type::I16)
114            | (Type::U32, Type::U32)
115            | (Type::I32, Type::I32)
116            | (Type::U64, Type::U64)
117            | (Type::I64, Type::I64)
118            | (Type::F16, Type::F16)
119            | (Type::F32, Type::F32)
120            | (Type::F64, Type::F64)
121            | (Type::Str, Type::Str)
122            | (Type::Map, Type::Map) => true,
123            (Type::List(left), Type::List(right)) => left == right,
124            (Type::Ident { name: name1, params: params1 }, Type::Ident { name: name2, params: params2 }) => name1 == name2 && params1 == params2,
125            (Type::ConstInt(left), Type::ConstInt(right)) => left == right,
126            (Type::ConstBinary { op: op1, left: left1, right: right1 }, Type::ConstBinary { op: op2, left: left2, right: right2 }) => op1 == op2 && left1 == left2 && right1 == right2,
127            (Type::Symbol { id: id1, params: p1 }, Type::Symbol { id: id2, params: p2 }) => id1 == id2 && p1 == p2,
128            (Type::Struct { params: p1, fields: f1 }, Type::Struct { params: p2, fields: f2 }) => {
129                p1.len() == p2.len() && f1.len() == f2.len() && p1.iter().zip(p2.iter()).position(|(t1, t2)| t1 != t2).is_none() && f1.iter().zip(f2.iter()).position(|(item1, item2)| item1 != item2).is_none()
130            }
131            (Type::Vec(elem_type1, len1), Type::Vec(elem_type2, len2)) => elem_type1 == elem_type2 && len1 == len2,
132            (Type::Array(elem_type1, len1), Type::Array(elem_type2, len2)) => elem_type1 == elem_type2 && len1 == len2,
133            (Type::ArrayParam(elem_type1, len1), Type::ArrayParam(elem_type2, len2)) => elem_type1 == elem_type2 && len1 == len2,
134            (Type::Fn { tys: t1, ret: r1 }, Type::Fn { tys: t2, ret: r2 }) => {
135                if t1 == t2 {
136                    if r1 != r2 {
137                        panic!("函数返回类型不一致")
138                    }
139                    true
140                } else {
141                    false
142                }
143            }
144            _ => false,
145        }
146    }
147}
148
149impl Type {
150    pub fn list_any() -> Self {
151        Self::List(Rc::new(Self::Any))
152    }
153
154    fn align_up(value: u32, align: u32) -> u32 {
155        if align <= 1 { value } else { (value + align - 1) & !(align - 1) }
156    }
157
158    pub fn align(&self) -> u32 {
159        self.storage_width().min(8).max(1)
160    }
161
162    pub fn storage_width(&self) -> u32 {
163        match self {
164            Self::Void => 0,
165            Self::Bool => 1,
166            Self::U8 | Self::I8 => 1,
167            Self::U16 | Self::I16 | Self::F16 => 2,
168            Self::U32 | Self::I32 | Self::F32 => 4,
169            Self::U64 | Self::I64 | Self::F64 => 8,
170            Self::Struct { params: _, fields } => Self::struct_layout(fields).0,
171            Self::Vec(ty, num) => num * ty.storage_width(),
172            Self::Array(ty, num) => num * ty.storage_width(),
173            Self::ArrayParam(ty, len) => {
174                if let Self::ConstInt(num) = len.as_ref() {
175                    if *num >= 0 { *num as u32 * ty.storage_width() } else { 8 }
176                } else {
177                    8
178                }
179            }
180            Self::ConstBinary { .. } => 8,
181            _ => 8,
182        }
183    }
184
185    pub fn struct_layout(fields: &[(SmolStr, Type)]) -> (u32, Vec<u32>) {
186        let mut offset = 0;
187        let mut offsets = Vec::with_capacity(fields.len());
188        let mut struct_align = 8;
189        for (_, ty) in fields {
190            let align = ty.align().min(8);
191            struct_align = struct_align.max(align);
192            offset = Self::align_up(offset, align);
193            offsets.push(offset);
194            offset += ty.storage_width();
195        }
196        (Self::align_up(offset, struct_align), offsets)
197    }
198
199    pub fn field_offset(&self, idx: usize) -> Option<u32> {
200        if let Self::Struct { params: _, fields } = self { Self::struct_layout(fields).1.get(idx).cloned() } else { None }
201    }
202
203    pub fn len(&self) -> usize {
204        match self {
205            Self::Struct { params: _, fields } => fields.len(),
206            Self::Tuple(items) => items.len(),
207            Self::Vec(_, num) | Self::Array(_, num) => *num as usize,
208            Self::ArrayParam(_, len) => {
209                if let Self::ConstInt(num) = len.as_ref() {
210                    if *num >= 0 { *num as usize } else { 0 }
211                } else {
212                    0
213                }
214            }
215            Self::ConstBinary { .. } => 0,
216            _ => 0,
217        }
218    }
219
220    pub fn compare_args(left: &[Type], right: &[Type]) -> Option<Vec<Type>> {
221        let mut tys = Vec::new();
222        for (left, right) in left.iter().zip(right.iter()) {
223            if left == right || right.is_any() {
224                tys.push(left.clone());
225            } else if left.is_any() {
226                tys.push(right.clone());
227            } else {
228                return None;
229            }
230        }
231        Some(tys)
232    }
233
234    pub fn force(&self, src: Dynamic) -> Result<Dynamic, DynamicErr> {
235        match self {
236            Self::Bool => src.try_into().map(Dynamic::Bool),
237            Self::I8 => src.try_into().map(Dynamic::I8),
238            Self::I16 => src.try_into().map(Dynamic::I16),
239            Self::I32 => src.try_into().map(Dynamic::I32),
240            Self::I64 => src.try_into().map(Dynamic::I64),
241            Self::U8 => src.try_into().map(Dynamic::U8),
242            Self::U16 => src.try_into().map(Dynamic::U16),
243            Self::U32 => src.try_into().map(Dynamic::U32),
244            Self::U64 => src.try_into().map(Dynamic::U64),
245            Self::F32 => src.try_into().map(Dynamic::F32),
246            Self::F64 => src.try_into().map(Dynamic::F64),
247            _ => Ok(src),
248        }
249    }
250
251    pub fn width(&self) -> u32 {
252        //所占字节数
253        self.storage_width()
254    }
255
256    pub fn is_void(&self) -> bool {
257        if let Self::Void = self { true } else { false }
258    }
259
260    pub fn is_bool(&self) -> bool {
261        if let Self::Bool = self { true } else { false }
262    }
263
264    pub fn is_str(&self) -> bool {
265        if let Self::Str = self { true } else { false }
266    }
267
268    pub fn is_native(&self) -> bool {
269        match self {
270            Self::F16 | Self::F32 | Self::F64 | Self::U8 | Self::I8 | Self::U16 | Self::I16 | Self::U32 | Self::I32 | Self::U64 | Self::I64 => true,
271            _ => false,
272        }
273    }
274
275    pub fn is_any(&self) -> bool {
276        match self {
277            Self::Any => true,
278            Self::Fn { tys: _, ret } => ret.is_any(),
279            _ => false,
280        }
281    }
282
283    pub fn is_ident(&self) -> bool {
284        if let Self::Ident { name: _, params: _ } = self { true } else { false }
285    }
286
287    pub fn is_struct(&self) -> bool {
288        if let Self::Struct { .. } = self { true } else { false }
289    }
290
291    pub fn get_field(&self, name: &str) -> Result<(usize, &Type)> {
292        if let Self::Struct { params: _, fields } = self {
293            fields.iter().enumerate().find(|(_, (field_name, _))| field_name == name).map(|(index, (_, ty))| (index, ty)).ok_or(anyhow!("{:?} 未发现属性 {}", self, name))
294        } else {
295            Err(anyhow!("不是结构体"))
296        }
297    }
298
299    pub fn add_field(&mut self, name: SmolStr, ty: Type) -> Result<u32> {
300        if let Self::Struct { params: _, fields } = self {
301            fields.push((name, ty));
302            Ok(fields.len() as u32 - 1)
303        } else {
304            Err(anyhow!("不是结构体"))
305        }
306    }
307
308    pub fn is_vec(&self) -> bool {
309        if let Self::Vec(_, _) = self { true } else { false }
310    }
311
312    pub fn is_array(&self) -> bool {
313        if let Self::Array(_, _) = self { true } else { false }
314    }
315
316    pub fn is_int(&self) -> bool {
317        match self {
318            Self::I8 | Self::I16 | Self::I32 | Self::I64 => true,
319            _ => false,
320        }
321    }
322
323    pub fn is_uint(&self) -> bool {
324        match self {
325            Self::U8 | Self::U16 | Self::U32 | Self::U64 => true,
326            _ => false,
327        }
328    }
329
330    pub fn sign(self) -> Self {
331        match self {
332            Self::U8 => Self::I8,
333            Self::U16 => Self::I16,
334            Self::U32 => Self::I32,
335            Self::U64 => Self::I64,
336            _ => self,
337        }
338    }
339
340    pub fn is_float(&self) -> bool {
341        match self {
342            Self::F16 | Self::F32 | Self::F64 => true,
343            _ => false,
344        }
345    }
346
347    pub fn is_f64(&self) -> bool {
348        match self {
349            Self::F64 => true,
350            _ => false,
351        }
352    }
353
354    pub fn is_f32(&self) -> bool {
355        match self {
356            Self::F32 => true,
357            _ => false,
358        }
359    }
360
361    pub fn is_fn(&self) -> bool {
362        if let Self::Fn { .. } = self { true } else { false }
363    }
364
365    pub fn from_args(args: Vec<(SmolStr, Type)>) -> (Self, Vec<SmolStr>) {
366        let (args, tys) = args.into_iter().fold((Vec::new(), Vec::new()), |mut v, a| {
367            v.0.push(a.0);
368            v.1.push(a.1);
369            v
370        });
371        (Self::Fn { tys, ret: Rc::new(Type::Any) }, args)
372    }
373}
374
375impl Dynamic {
376    pub fn get_type(&self) -> Type {
377        let len = self.len() as u32;
378        match self {
379            Self::Bool(_) => Type::Bool,
380            Self::I8(_) => Type::I8,
381            Self::I16(_) => Type::I16,
382            Self::I32(_) => Type::I32,
383            Self::I64(_) => Type::I64,
384            Self::U8(_) => Type::U8,
385            Self::U16(_) => Type::U16,
386            Self::U32(_) => Type::U32,
387            Self::U64(_) => Type::U64,
388            Self::F32(_) => Type::F32,
389            Self::F64(_) => Type::F64,
390            Self::Bytes(_) => Type::Vec(Rc::new(Type::U8), len),
391            Self::VecI8(_) => Type::Vec(Rc::new(Type::I8), len),
392            Self::VecI16(_) => Type::Vec(Rc::new(Type::I16), len),
393            Self::VecI32(_) => Type::Vec(Rc::new(Type::I32), len),
394            Self::VecI64(_) => Type::Vec(Rc::new(Type::I64), len),
395            Self::VecU16(_) => Type::Vec(Rc::new(Type::U16), len),
396            Self::VecU32(_) => Type::Vec(Rc::new(Type::U32), len),
397            Self::VecU64(_) => Type::Vec(Rc::new(Type::U64), len),
398            Self::VecF32(_) => Type::Vec(Rc::new(Type::F32), len),
399            Self::VecF64(_) => Type::Vec(Rc::new(Type::F64), len),
400            Self::String(_) | Self::StringBuf(_) => Type::Str,
401            Self::Map(_) => Type::Map,
402            Self::Struct { ty, .. } => ty.clone(),
403            Self::Custom(_) => Type::Any,
404            Self::Null => Type::Void,
405            Self::List(items) => {
406                let tys: Vec<Type> = items.read().unwrap().iter().map(|v| v.get_type()).collect();
407                if let Some(first) = tys.first() {
408                    if tys.iter().all(|x| x == first) {
409                        return Type::Array(Rc::new(first.clone()), len);
410                    }
411                }
412                Type::list_any()
413            }
414            Self::Iter { idx: _, keys: _, value: _ } => Type::Iter,
415        }
416    }
417}
418
419type DynamicReturnHandler = unsafe fn(*const Dynamic) -> Box<Dynamic>;
420
421static DYNAMIC_RETURN_HANDLER: RwLock<Option<DynamicReturnHandler>> = RwLock::new(None);
422
423pub fn set_dynamic_return_handler(handler: DynamicReturnHandler) {
424    *DYNAMIC_RETURN_HANDLER.write().unwrap() = Some(handler);
425}
426
427unsafe fn take_dynamic_return(ptr: *const Dynamic) -> Box<Dynamic> {
428    if let Some(handler) = *DYNAMIC_RETURN_HANDLER.read().unwrap() {
429        unsafe { handler(ptr) }
430    } else if ptr.is_null() {
431        Box::new(Dynamic::Null)
432    } else {
433        unsafe { Box::from_raw(ptr as *mut Dynamic) }
434    }
435}
436
437pub fn call_fn(ptr: i64, ret_ty: Type, param: Box<Dynamic>) -> Result<Box<Dynamic>> {
438    let param = Box::into_raw(param);
439    match ret_ty {
440        Type::Any => {
441            let fn_ptr: extern "C" fn(*const Dynamic) -> *mut Dynamic = unsafe { std::mem::transmute(ptr) };
442            let r = fn_ptr(param);
443            unsafe {
444                drop(Box::from_raw(param));
445            }
446            Ok(unsafe { take_dynamic_return(r) })
447        }
448        Type::Bool => {
449            let fn_ptr: extern "C" fn(*const Dynamic) -> i8 = unsafe { std::mem::transmute(ptr) };
450            let r = fn_ptr(param);
451            unsafe {
452                drop(Box::from_raw(param));
453            }
454            Ok(Box::new(Dynamic::Bool(r != 0)))
455        }
456        Type::Void => {
457            let fn_ptr: extern "C" fn(*const Dynamic) = unsafe { std::mem::transmute(ptr) };
458            fn_ptr(param);
459            unsafe {
460                drop(Box::from_raw(param));
461            }
462            Ok(Box::new(Dynamic::Null))
463        }
464        Type::F32 => {
465            let fn_ptr: extern "C" fn(*const Dynamic) -> f32 = unsafe { std::mem::transmute(ptr) };
466            let r = fn_ptr(param);
467            unsafe {
468                drop(Box::from_raw(param));
469            }
470            Ok(Box::new(Dynamic::F32(r)))
471        }
472        Type::F64 => {
473            let fn_ptr: extern "C" fn(*const Dynamic) -> f64 = unsafe { std::mem::transmute(ptr) };
474            let r = fn_ptr(param);
475            unsafe {
476                drop(Box::from_raw(param));
477            }
478            Ok(Box::new(Dynamic::F64(r)))
479        }
480        _ => {
481            let fn_ptr: extern "C" fn(*const Dynamic) -> i64 = unsafe { std::mem::transmute(ptr) };
482            let r = fn_ptr(param);
483            unsafe {
484                drop(Box::from_raw(param));
485            }
486            Ok(Box::new(Dynamic::I64(r)))
487        }
488    }
489}