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,
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)
123            | (Type::List, Type::List) => true,
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    fn align_up(value: u32, align: u32) -> u32 {
151        if align <= 1 { value } else { (value + align - 1) & !(align - 1) }
152    }
153
154    pub fn align(&self) -> u32 {
155        self.storage_width().min(8).max(1)
156    }
157
158    pub fn storage_width(&self) -> u32 {
159        match self {
160            Self::Void => 0,
161            Self::Bool => 1,
162            Self::U8 | Self::I8 => 1,
163            Self::U16 | Self::I16 | Self::F16 => 2,
164            Self::U32 | Self::I32 | Self::F32 => 4,
165            Self::U64 | Self::I64 | Self::F64 => 8,
166            Self::Struct { params: _, fields } => Self::struct_layout(fields).0,
167            Self::Vec(ty, num) => num * ty.storage_width(),
168            Self::Array(ty, num) => num * ty.storage_width(),
169            Self::ArrayParam(ty, len) => {
170                if let Self::ConstInt(num) = len.as_ref() {
171                    if *num >= 0 { *num as u32 * ty.storage_width() } else { 8 }
172                } else {
173                    8
174                }
175            }
176            Self::ConstBinary { .. } => 8,
177            _ => 8,
178        }
179    }
180
181    pub fn struct_layout(fields: &[(SmolStr, Type)]) -> (u32, Vec<u32>) {
182        let mut offset = 0;
183        let mut offsets = Vec::with_capacity(fields.len());
184        let mut struct_align = 8;
185        for (_, ty) in fields {
186            let align = ty.align().min(8);
187            struct_align = struct_align.max(align);
188            offset = Self::align_up(offset, align);
189            offsets.push(offset);
190            offset += ty.storage_width();
191        }
192        (Self::align_up(offset, struct_align), offsets)
193    }
194
195    pub fn field_offset(&self, idx: usize) -> Option<u32> {
196        if let Self::Struct { params: _, fields } = self { Self::struct_layout(fields).1.get(idx).cloned() } else { None }
197    }
198
199    pub fn len(&self) -> usize {
200        match self {
201            Self::Struct { params: _, fields } => fields.len(),
202            Self::Tuple(items) => items.len(),
203            Self::Vec(_, num) | Self::Array(_, num) => *num as usize,
204            Self::ArrayParam(_, len) => {
205                if let Self::ConstInt(num) = len.as_ref() {
206                    if *num >= 0 { *num as usize } else { 0 }
207                } else {
208                    0
209                }
210            }
211            Self::ConstBinary { .. } => 0,
212            _ => 0,
213        }
214    }
215
216    pub fn compare_args(left: &[Type], right: &[Type]) -> Option<Vec<Type>> {
217        let mut tys = Vec::new();
218        for (left, right) in left.iter().zip(right.iter()) {
219            if left == right || right.is_any() {
220                tys.push(left.clone());
221            } else if left.is_any() {
222                tys.push(right.clone());
223            } else {
224                return None;
225            }
226        }
227        Some(tys)
228    }
229
230    pub fn force(&self, src: Dynamic) -> Result<Dynamic, DynamicErr> {
231        match self {
232            Self::Bool => src.try_into().map(Dynamic::Bool),
233            Self::I8 => src.try_into().map(Dynamic::I8),
234            Self::I16 => src.try_into().map(Dynamic::I16),
235            Self::I32 => src.try_into().map(Dynamic::I32),
236            Self::I64 => src.try_into().map(Dynamic::I64),
237            Self::U8 => src.try_into().map(Dynamic::U8),
238            Self::U16 => src.try_into().map(Dynamic::U16),
239            Self::U32 => src.try_into().map(Dynamic::U32),
240            Self::U64 => src.try_into().map(Dynamic::U64),
241            Self::F32 => src.try_into().map(Dynamic::F32),
242            Self::F64 => src.try_into().map(Dynamic::F64),
243            _ => Ok(src),
244        }
245    }
246
247    pub fn width(&self) -> u32 {
248        //所占字节数
249        self.storage_width()
250    }
251
252    pub fn is_void(&self) -> bool {
253        if let Self::Void = self { true } else { false }
254    }
255
256    pub fn is_bool(&self) -> bool {
257        if let Self::Bool = self { true } else { false }
258    }
259
260    pub fn is_str(&self) -> bool {
261        if let Self::Str = self { true } else { false }
262    }
263
264    pub fn is_native(&self) -> bool {
265        match self {
266            Self::F16 | Self::F32 | Self::F64 | Self::U8 | Self::I8 | Self::U16 | Self::I16 | Self::U32 | Self::I32 | Self::U64 | Self::I64 => true,
267            _ => false,
268        }
269    }
270
271    pub fn is_any(&self) -> bool {
272        match self {
273            Self::Any => true,
274            Self::Fn { tys: _, ret } => ret.is_any(),
275            _ => false,
276        }
277    }
278
279    pub fn is_ident(&self) -> bool {
280        if let Self::Ident { name: _, params: _ } = self { true } else { false }
281    }
282
283    pub fn is_struct(&self) -> bool {
284        if let Self::Struct { .. } = self { true } else { false }
285    }
286
287    pub fn get_field(&self, name: &str) -> Result<(usize, &Type)> {
288        if let Self::Struct { params: _, fields } = self {
289            fields.iter().enumerate().find(|(_, (field_name, _))| field_name == name).map(|(index, (_, ty))| (index, ty)).ok_or(anyhow!("{:?} 未发现属性 {}", self, name))
290        } else {
291            Err(anyhow!("不是结构体"))
292        }
293    }
294
295    pub fn add_field(&mut self, name: SmolStr, ty: Type) -> Result<u32> {
296        if let Self::Struct { params: _, fields } = self {
297            fields.push((name, ty));
298            Ok(fields.len() as u32 - 1)
299        } else {
300            Err(anyhow!("不是结构体"))
301        }
302    }
303
304    pub fn is_vec(&self) -> bool {
305        if let Self::Vec(_, _) = self { true } else { false }
306    }
307
308    pub fn is_array(&self) -> bool {
309        if let Self::Array(_, _) = self { true } else { false }
310    }
311
312    pub fn is_int(&self) -> bool {
313        match self {
314            Self::I8 | Self::I16 | Self::I32 | Self::I64 => true,
315            _ => false,
316        }
317    }
318
319    pub fn is_uint(&self) -> bool {
320        match self {
321            Self::U8 | Self::U16 | Self::U32 | Self::U64 => true,
322            _ => false,
323        }
324    }
325
326    pub fn sign(self) -> Self {
327        match self {
328            Self::U8 => Self::I8,
329            Self::U16 => Self::I16,
330            Self::U32 => Self::I32,
331            Self::U64 => Self::I64,
332            _ => self,
333        }
334    }
335
336    pub fn is_float(&self) -> bool {
337        match self {
338            Self::F16 | Self::F32 | Self::F64 => true,
339            _ => false,
340        }
341    }
342
343    pub fn is_f64(&self) -> bool {
344        match self {
345            Self::F64 => true,
346            _ => false,
347        }
348    }
349
350    pub fn is_f32(&self) -> bool {
351        match self {
352            Self::F32 => true,
353            _ => false,
354        }
355    }
356
357    pub fn is_fn(&self) -> bool {
358        if let Self::Fn { .. } = self { true } else { false }
359    }
360
361    pub fn from_args(args: Vec<(SmolStr, Type)>) -> (Self, Vec<SmolStr>) {
362        let (args, tys) = args.into_iter().fold((Vec::new(), Vec::new()), |mut v, a| {
363            v.0.push(a.0);
364            v.1.push(a.1);
365            v
366        });
367        (Self::Fn { tys, ret: Rc::new(Type::Any) }, args)
368    }
369}
370
371impl Dynamic {
372    pub fn get_type(&self) -> Type {
373        let len = self.len() as u32;
374        match self {
375            Self::Bool(_) => Type::Bool,
376            Self::I8(_) => Type::I8,
377            Self::I16(_) => Type::I16,
378            Self::I32(_) => Type::I32,
379            Self::I64(_) => Type::I64,
380            Self::U8(_) => Type::U8,
381            Self::U16(_) => Type::U16,
382            Self::U32(_) => Type::U32,
383            Self::U64(_) => Type::U64,
384            Self::F32(_) => Type::F32,
385            Self::F64(_) => Type::F64,
386            Self::Bytes(_) => Type::Vec(Rc::new(Type::U8), len),
387            Self::VecI8(_) => Type::Vec(Rc::new(Type::I8), len),
388            Self::VecI16(_) => Type::Vec(Rc::new(Type::I16), len),
389            Self::VecI32(_) => Type::Vec(Rc::new(Type::I32), len),
390            Self::VecI64(_) => Type::Vec(Rc::new(Type::I64), len),
391            Self::VecU16(_) => Type::Vec(Rc::new(Type::U16), len),
392            Self::VecU32(_) => Type::Vec(Rc::new(Type::U32), len),
393            Self::VecU64(_) => Type::Vec(Rc::new(Type::U64), len),
394            Self::VecF32(_) => Type::Vec(Rc::new(Type::F32), len),
395            Self::VecF64(_) => Type::Vec(Rc::new(Type::F64), len),
396            Self::String(_) => Type::Str,
397            Self::Map(_) => Type::Map,
398            Self::Struct { ty, .. } => ty.clone(),
399            Self::Custom(_) => Type::Any,
400            Self::Null => Type::Void,
401            Self::List(items) => {
402                let tys: Vec<Type> = items.read().unwrap().iter().map(|v| v.get_type()).collect();
403                if let Some(first) = tys.first() {
404                    if tys.iter().all(|x| x == first) {
405                        return Type::Array(Rc::new(first.clone()), len);
406                    }
407                }
408                Type::List
409            }
410            Self::Iter { idx: _, keys: _, value: _ } => Type::Iter,
411        }
412    }
413}
414
415type DynamicReturnHandler = unsafe fn(*const Dynamic) -> Box<Dynamic>;
416
417static DYNAMIC_RETURN_HANDLER: RwLock<Option<DynamicReturnHandler>> = RwLock::new(None);
418
419pub fn set_dynamic_return_handler(handler: DynamicReturnHandler) {
420    *DYNAMIC_RETURN_HANDLER.write().unwrap() = Some(handler);
421}
422
423unsafe fn take_dynamic_return(ptr: *const Dynamic) -> Box<Dynamic> {
424    if let Some(handler) = *DYNAMIC_RETURN_HANDLER.read().unwrap() {
425        unsafe { handler(ptr) }
426    } else if ptr.is_null() {
427        Box::new(Dynamic::Null)
428    } else {
429        unsafe { Box::from_raw(ptr as *mut Dynamic) }
430    }
431}
432
433pub fn call_fn(ptr: i64, ret_ty: Type, param: Box<Dynamic>) -> Result<Box<Dynamic>> {
434    let param = Box::into_raw(param);
435    match ret_ty {
436        Type::Any => {
437            let fn_ptr: extern "C" fn(*const Dynamic) -> *mut Dynamic = unsafe { std::mem::transmute(ptr) };
438            let r = fn_ptr(param);
439            unsafe {
440                drop(Box::from_raw(param));
441            }
442            Ok(unsafe { take_dynamic_return(r) })
443        }
444        Type::Bool => {
445            let fn_ptr: extern "C" fn(*const Dynamic) -> i8 = unsafe { std::mem::transmute(ptr) };
446            let r = fn_ptr(param);
447            unsafe {
448                drop(Box::from_raw(param));
449            }
450            Ok(Box::new(Dynamic::Bool(r != 0)))
451        }
452        Type::Void => {
453            let fn_ptr: extern "C" fn(*const Dynamic) = unsafe { std::mem::transmute(ptr) };
454            fn_ptr(param);
455            unsafe {
456                drop(Box::from_raw(param));
457            }
458            Ok(Box::new(Dynamic::Null))
459        }
460        Type::F32 => {
461            let fn_ptr: extern "C" fn(*const Dynamic) -> f32 = unsafe { std::mem::transmute(ptr) };
462            let r = fn_ptr(param);
463            unsafe {
464                drop(Box::from_raw(param));
465            }
466            Ok(Box::new(Dynamic::F32(r)))
467        }
468        Type::F64 => {
469            let fn_ptr: extern "C" fn(*const Dynamic) -> f64 = unsafe { std::mem::transmute(ptr) };
470            let r = fn_ptr(param);
471            unsafe {
472                drop(Box::from_raw(param));
473            }
474            Ok(Box::new(Dynamic::F64(r)))
475        }
476        _ => {
477            let fn_ptr: extern "C" fn(*const Dynamic) -> i64 = unsafe { std::mem::transmute(ptr) };
478            let r = fn_ptr(param);
479            unsafe {
480                drop(Box::from_raw(param));
481            }
482            Ok(Box::new(Dynamic::I64(r)))
483        }
484    }
485}