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            Self::Str => Ok(Dynamic::from(src.to_string())),
248            _ => Ok(src),
249        }
250    }
251
252    pub fn width(&self) -> u32 {
253        //所占字节数
254        self.storage_width()
255    }
256
257    pub fn is_void(&self) -> bool {
258        if let Self::Void = self { true } else { false }
259    }
260
261    pub fn is_bool(&self) -> bool {
262        if let Self::Bool = self { true } else { false }
263    }
264
265    pub fn is_str(&self) -> bool {
266        if let Self::Str = self { true } else { false }
267    }
268
269    pub fn is_native(&self) -> bool {
270        match self {
271            Self::F16 | Self::F32 | Self::F64 | Self::U8 | Self::I8 | Self::U16 | Self::I16 | Self::U32 | Self::I32 | Self::U64 | Self::I64 => true,
272            _ => false,
273        }
274    }
275
276    pub fn is_any(&self) -> bool {
277        match self {
278            Self::Any => true,
279            Self::Fn { tys: _, ret } => ret.is_any(),
280            _ => false,
281        }
282    }
283
284    pub fn is_ident(&self) -> bool {
285        if let Self::Ident { name: _, params: _ } = self { true } else { false }
286    }
287
288    pub fn is_struct(&self) -> bool {
289        if let Self::Struct { .. } = self { true } else { false }
290    }
291
292    pub fn get_field(&self, name: &str) -> Result<(usize, &Type)> {
293        if let Self::Struct { params: _, fields } = self {
294            fields.iter().enumerate().find(|(_, (field_name, _))| field_name == name).map(|(index, (_, ty))| (index, ty)).ok_or(anyhow!("{:?} 未发现属性 {}", self, name))
295        } else {
296            Err(anyhow!("不是结构体"))
297        }
298    }
299
300    pub fn add_field(&mut self, name: SmolStr, ty: Type) -> Result<u32> {
301        if let Self::Struct { params: _, fields } = self {
302            fields.push((name, ty));
303            Ok(fields.len() as u32 - 1)
304        } else {
305            Err(anyhow!("不是结构体"))
306        }
307    }
308
309    pub fn is_vec(&self) -> bool {
310        if let Self::Vec(_, _) = self { true } else { false }
311    }
312
313    pub fn is_array(&self) -> bool {
314        if let Self::Array(_, _) = self { true } else { false }
315    }
316
317    pub fn is_int(&self) -> bool {
318        match self {
319            Self::I8 | Self::I16 | Self::I32 | Self::I64 => true,
320            _ => false,
321        }
322    }
323
324    pub fn is_uint(&self) -> bool {
325        match self {
326            Self::U8 | Self::U16 | Self::U32 | Self::U64 => true,
327            _ => false,
328        }
329    }
330
331    pub fn sign(self) -> Self {
332        match self {
333            Self::U8 => Self::I8,
334            Self::U16 => Self::I16,
335            Self::U32 => Self::I32,
336            Self::U64 => Self::I64,
337            _ => self,
338        }
339    }
340
341    pub fn is_float(&self) -> bool {
342        match self {
343            Self::F16 | Self::F32 | Self::F64 => true,
344            _ => false,
345        }
346    }
347
348    pub fn is_f64(&self) -> bool {
349        match self {
350            Self::F64 => true,
351            _ => false,
352        }
353    }
354
355    pub fn is_f32(&self) -> bool {
356        match self {
357            Self::F32 => true,
358            _ => false,
359        }
360    }
361
362    pub fn is_fn(&self) -> bool {
363        if let Self::Fn { .. } = self { true } else { false }
364    }
365
366    pub fn from_args(args: Vec<(SmolStr, Type)>) -> (Self, Vec<SmolStr>) {
367        let (args, tys) = args.into_iter().fold((Vec::new(), Vec::new()), |mut v, a| {
368            v.0.push(a.0);
369            v.1.push(a.1);
370            v
371        });
372        (Self::Fn { tys, ret: Rc::new(Type::Any) }, args)
373    }
374}
375
376impl Dynamic {
377    pub fn get_type(&self) -> Type {
378        let len = self.len() as u32;
379        match self {
380            Self::Bool(_) => Type::Bool,
381            Self::I8(_) => Type::I8,
382            Self::I16(_) => Type::I16,
383            Self::I32(_) => Type::I32,
384            Self::I64(_) => Type::I64,
385            Self::U8(_) => Type::U8,
386            Self::U16(_) => Type::U16,
387            Self::U32(_) => Type::U32,
388            Self::U64(_) => Type::U64,
389            Self::F32(_) => Type::F32,
390            Self::F64(_) => Type::F64,
391            Self::Bytes(_) => Type::Vec(Rc::new(Type::U8), len),
392            Self::VecI8(_) => Type::Vec(Rc::new(Type::I8), len),
393            Self::VecI16(_) => Type::Vec(Rc::new(Type::I16), len),
394            Self::VecI32(_) => Type::Vec(Rc::new(Type::I32), len),
395            Self::VecI64(_) => Type::Vec(Rc::new(Type::I64), len),
396            Self::VecU16(_) => Type::Vec(Rc::new(Type::U16), len),
397            Self::VecU32(_) => Type::Vec(Rc::new(Type::U32), len),
398            Self::VecU64(_) => Type::Vec(Rc::new(Type::U64), len),
399            Self::VecF32(_) => Type::Vec(Rc::new(Type::F32), len),
400            Self::VecF64(_) => Type::Vec(Rc::new(Type::F64), len),
401            Self::String(_) | Self::StringBuf(_) => Type::Str,
402            Self::Map(_) => Type::Map,
403            Self::Struct { ty, .. } => ty.clone(),
404            Self::Custom(_) => Type::Any,
405            Self::Null => Type::Void,
406            Self::List(items) => {
407                let tys: Vec<Type> = items.read().unwrap().iter().map(|v| v.get_type()).collect();
408                if let Some(first) = tys.first() {
409                    if tys.iter().all(|x| x == first) {
410                        return Type::Array(Rc::new(first.clone()), len);
411                    }
412                }
413                Type::list_any()
414            }
415            Self::Iter { idx: _, keys: _, value: _ } => Type::Iter,
416        }
417    }
418}
419
420type DynamicReturnHandler = unsafe fn(*const Dynamic) -> Box<Dynamic>;
421
422static DYNAMIC_RETURN_HANDLER: RwLock<Option<DynamicReturnHandler>> = RwLock::new(None);
423
424pub fn set_dynamic_return_handler(handler: DynamicReturnHandler) {
425    *DYNAMIC_RETURN_HANDLER.write().unwrap() = Some(handler);
426}
427
428unsafe fn take_dynamic_return(ptr: *const Dynamic) -> Box<Dynamic> {
429    if let Some(handler) = *DYNAMIC_RETURN_HANDLER.read().unwrap() {
430        unsafe { handler(ptr) }
431    } else if ptr.is_null() {
432        Box::new(Dynamic::Null)
433    } else {
434        unsafe { Box::from_raw(ptr as *mut Dynamic) }
435    }
436}
437
438pub fn call_fn(ptr: i64, ret_ty: Type, param: Box<Dynamic>) -> Result<Box<Dynamic>> {
439    let param = Box::into_raw(param);
440    match ret_ty {
441        Type::Any => {
442            let fn_ptr: extern "C" fn(*const Dynamic) -> *mut Dynamic = unsafe { std::mem::transmute(ptr) };
443            let r = fn_ptr(param);
444            unsafe {
445                drop(Box::from_raw(param));
446            }
447            Ok(unsafe { take_dynamic_return(r) })
448        }
449        Type::Bool => {
450            let fn_ptr: extern "C" fn(*const Dynamic) -> i8 = unsafe { std::mem::transmute(ptr) };
451            let r = fn_ptr(param);
452            unsafe {
453                drop(Box::from_raw(param));
454            }
455            Ok(Box::new(Dynamic::Bool(r != 0)))
456        }
457        Type::Void => {
458            let fn_ptr: extern "C" fn(*const Dynamic) = unsafe { std::mem::transmute(ptr) };
459            fn_ptr(param);
460            unsafe {
461                drop(Box::from_raw(param));
462            }
463            Ok(Box::new(Dynamic::Null))
464        }
465        Type::F32 => {
466            let fn_ptr: extern "C" fn(*const Dynamic) -> f32 = unsafe { std::mem::transmute(ptr) };
467            let r = fn_ptr(param);
468            unsafe {
469                drop(Box::from_raw(param));
470            }
471            Ok(Box::new(Dynamic::F32(r)))
472        }
473        Type::F64 => {
474            let fn_ptr: extern "C" fn(*const Dynamic) -> f64 = unsafe { std::mem::transmute(ptr) };
475            let r = fn_ptr(param);
476            unsafe {
477                drop(Box::from_raw(param));
478            }
479            Ok(Box::new(Dynamic::F64(r)))
480        }
481        _ => {
482            let fn_ptr: extern "C" fn(*const Dynamic) -> i64 = unsafe { std::mem::transmute(ptr) };
483            let r = fn_ptr(param);
484            unsafe {
485                drop(Box::from_raw(param));
486            }
487            Ok(Box::new(Dynamic::I64(r)))
488        }
489    }
490}