key_native/
key.rs

1//! 负责和解释器交互的部分
2//! 
3//! 此模块定义Key语言中原生模块可能用到的类型
4
5pub use std::collections::HashMap;
6use std::fmt::Debug;
7use crate::Instance;
8
9
10/// premain函数接收的函数表
11#[repr(C)]
12pub struct FuncTable {
13  pub intern: fn(&[u8])-> Ident,
14  pub err: fn(&str)->!,
15  pub find_var: fn(Scope, Ident)-> Option<LitrRef>,
16  pub let_var: fn(Scope, Ident, Litr),
17  pub const_var: fn(Scope, Ident),
18  pub using: fn(Scope, Ident, crate::Class),
19  pub call_local: fn(&LocalFunc, Vec<Litr>)-> Litr,
20  pub call_at: fn(Scope, *mut Litr, &LocalFunc, Vec<Litr>)-> Litr,
21  pub get_self: fn(Scope)-> *mut Litr,
22  pub get_parent: fn(Scope)-> Option<Scope>,
23  pub outlive_inc: fn(Scope),
24  pub outlive_dec: fn(Scope),
25  pub symcls: fn()-> crate::Class,
26  pub wait_inc: fn(),
27  pub wait_dec: fn(),
28  pub planet_new: fn()-> (*mut (), crate::Class),
29  pub planet_ok: fn(*mut (), Litr),
30  pub local_instance_clone: fn(&[usize;3])-> [usize;3],
31  pub local_instance_drop: fn(&mut[usize;3]),
32}
33pub static mut FUNCTABLE:*const FuncTable = std::ptr::null();
34
35/// 将字符串缓存为指针(和Key解释器用一个缓存池)
36pub fn intern(s:&[u8])-> Ident {
37  unsafe{ ((*FUNCTABLE).intern)(s) }
38}
39
40#[no_mangle]
41extern fn premain(table: &FuncTable) {
42  // 使用kpanic
43  std::panic::set_hook(Box::new(|inf|{
44    let s = if let Some(s) = inf.payload().downcast_ref::<String>() {s}
45    else if let Some(s) = inf.payload().downcast_ref::<&str>() {s}else {"错误"};
46    unsafe{((*FUNCTABLE).err)(s)};
47  }));
48
49  unsafe {
50    FUNCTABLE = table;
51  }
52}
53
54/// 一个合法的标识符, 可以理解为字符串的指针
55#[derive(Debug, Clone, Copy)]
56pub struct Ident {
57  pub p: &'static Box<[u8]>
58}
59impl Ident {
60  /// 将ident作为字符串
61  pub fn str(&self)-> String {
62    String::from_utf8_lossy(&self.p).into_owned()
63  }
64  /// 获得ident的slice
65  pub fn slice(&self)-> &[u8] {
66    self
67  }
68}
69impl std::ops::Deref for Ident {
70  type Target = [u8];
71  fn deref(&self) -> &Self::Target {
72    &*self.p
73  }
74}
75impl std::fmt::Display for Ident {
76  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77    f.write_str(&self.str())
78  }
79}
80
81/// Key语言中的作用域
82#[derive(Debug, Clone, Copy)]
83pub struct Scope(*mut ());
84impl Scope {
85  /// 在此作用域找一个变量
86  pub fn find_var(self, s:&str)-> Option<LitrRef> {
87    unsafe{((*FUNCTABLE).find_var)(self, intern(s.as_bytes()))}
88  }
89  /// 在此作用域定义一个变量
90  pub fn let_var(self, s:&str, v:Litr) {
91    unsafe{((*FUNCTABLE).let_var)(self, intern(s.as_bytes()), v)}
92  }
93  /// 在此作用域锁定一个变量
94  pub fn const_var(self, s:&str) {
95    unsafe{((*FUNCTABLE).const_var)(self, intern(s.as_bytes()))}
96  }
97  /// 获取该作用域的self
98  pub fn get_self(self)-> *mut Litr {
99    unsafe{((*FUNCTABLE).get_self)(self)}
100  }
101  /// 获取该作用域的父作用域(如果有的话)
102  pub fn get_parent(self)-> Option<Scope> {
103    unsafe{((*FUNCTABLE).get_parent)(self)}
104  }
105  /// 为作用域创建一个`use`(`class A = m-:B`的行为)
106  /// 
107  /// 即使你的类没有被`export_cls`, 也可以被`using`正确使用
108  pub fn using(self, name:&str, cls:crate::Class) {
109    unsafe{((*FUNCTABLE).using)(self, intern(name.as_bytes()), cls)}
110  }
111}
112
113unsafe impl Send for Scope {}
114
115/// Key语言中的基本类型
116#[derive(Debug, Clone, Default)]
117pub enum Litr {
118  #[default]
119  /// `()`, `uninit`
120  Uninit,
121
122  /// `-1`, `-1i`
123  Int    (isize),
124  /// `1u`
125  Uint   (usize),
126  /// `1.0`, `1f`
127  Float  (f64),
128  /// `true`, `false`
129  Bool   (bool),
130
131  /// `||{..}`
132  Func   (Function), 
133  /// `"字符串"`
134  Str    (String),
135  /// `'buf,可以显示utf8'`
136  Buf    (Vec<u8>),
137  /// `[1,2,3]`
138  List   (Vec<Litr>),
139  /// 哈希表`{a:1, b:2}`
140  Obj    (HashMap<Ident, Litr>),
141  /// 本地声明的类实例, 原生模块不可干涉
142  Inst   ([usize;3]),
143  /// 原生模块的类实例`m-:A::new()`
144  Ninst  (Instance)
145}
146
147// SAFETY: 这确实不安全, 伙计
148unsafe impl Send for Litr {}
149unsafe impl Sync for Litr {}
150
151/// 函数枚举
152#[derive(Debug, Clone)]
153pub enum Function {
154  Native(crate::NativeFn),
155  Local(LocalFunc),
156  Extern([usize;4])
157}
158impl Function {
159  /// 调用函数, 需要传入`LitrRef`而非`Litr`的参数
160  /// 
161  /// 如需传入`Litr`参数请判断是否为本地函数, 调用`LocalFunc`的`call``
162  /// 
163  /// 该函数不会调用extern函数
164  pub fn call(&self, args:Vec<LitrRef>, cx:Scope)-> Litr {
165    match self {
166      Function::Local(f)=> unsafe{
167        let args = args.into_iter().map(|n|n.own()).collect();
168        ((*FUNCTABLE).call_at)(cx, cx.get_self(), f, args)
169      }
170      Function::Native(f)=> f(args, cx),
171      _=> Litr::Uninit
172    }
173  }
174}
175
176/// Key脚本内定义的本地函数
177#[derive(Debug)]
178#[repr(C)]
179pub struct LocalFunc {
180  ptr:*const (),
181  scope: Scope,
182}
183unsafe impl Send for LocalFunc {}
184
185// 因为Key允许开发者实现事件循环一样的效果
186// 所以必须保证原生模块的函数持有Key函数时
187// 该Key函数不能过期(因此需要实现Clone和Drop)
188impl Clone for LocalFunc {
189  fn clone(&self) -> Self {
190    let scope = self.scope;
191    crate::outlive_inc(scope);
192    LocalFunc { ptr: self.ptr, scope }
193  }
194}
195impl Drop for LocalFunc {
196  fn drop(&mut self) {
197    crate::outlive_dec(self.scope)
198  }
199}
200
201impl LocalFunc {
202  /// 调用Key本地函数
203  pub fn call(&self, args:Vec<Litr>)-> Litr {
204    unsafe{((*FUNCTABLE).call_local)(self, args)}
205  }
206  /// 在指定作用域调用该函数
207  /// 
208  /// 比起call多了两个参数: 
209  /// 
210  /// - `scope`: 要执行在哪个作用域, 可以使用`f.scope`缺省
211  /// 
212  /// - `kself`: Key脚本中的`self`指向, 可以使用`f.scope.get_self()`缺省
213  pub fn call_at(&self, scope:Scope, kself:*mut Litr, args:Vec<Litr>)-> Litr {
214    unsafe{((*FUNCTABLE).call_at)(scope, kself, self, args)}
215  }
216  /// 获取函数定义处的作用域
217  pub fn scope(&self)-> Scope {
218    self.scope
219  }
220}
221
222struct LocalInstance([usize;3]);
223impl Clone for LocalInstance {
224  fn clone(&self) -> Self {
225    LocalInstance((unsafe{&*FUNCTABLE}.local_instance_clone)(&self.0))
226  }
227}
228impl Drop for LocalInstance {
229  fn drop(&mut self) {
230    (unsafe{&*FUNCTABLE}.local_instance_drop)(&mut self.0)
231  }
232}
233
234
235/// Key语言的语法标志
236pub struct Sym;
237impl Sym {
238  pub const ITER_END:usize = 1;
239  pub fn is_sym(v:&Instance)-> bool {
240    v.cls == (unsafe{&*FUNCTABLE}.symcls)()
241  }
242  pub fn iter_end()-> Litr {
243    (unsafe{&*FUNCTABLE}.symcls)().create(Self::ITER_END, 0)
244  }
245}
246
247/// `Litr`的引用(是有生命周期的)
248/// 
249/// 注意如果你需要将`Litr`转移到别的线程等需要保证其生命周期的行为时
250/// 
251/// 调用`own`方法直接获取`Litr`的所有权
252pub enum LitrRef {
253  Ref(*mut Litr),
254  Own(Litr)
255}
256impl LitrRef {
257  /// 消耗CalcRef获取Litr所有权
258  pub fn own(self)-> Litr {
259    match self {
260      LitrRef::Ref(p)=> unsafe {(*p).clone()}
261      LitrRef::Own(v)=> v
262    }
263  }
264}
265
266impl std::ops::Deref for LitrRef {
267  type Target = Litr;
268  fn deref(&self) -> &Self::Target {
269    match self {
270      LitrRef::Ref(p)=> unsafe{&**p},
271      LitrRef::Own(b)=> b
272    }
273  }
274}
275impl std::ops::DerefMut for LitrRef {
276  fn deref_mut(&mut self) -> &mut Self::Target {
277    match self {
278      LitrRef::Ref(p)=> unsafe{&mut **p},
279      LitrRef::Own(b)=> b
280    }
281  }
282}
283
284impl Debug for LitrRef {
285  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286    f.write_fmt(format_args!("{:?}", &**self))
287  }
288}
289
290/// planet的内部拨号员, 可调用ok代表Planet结束
291pub struct PlanetCaller(*mut ());
292impl PlanetCaller {
293  /// 完成该次行星异步任务, 传入结果值
294  pub fn ok(&self, v:Litr) {
295    unsafe {((*FUNCTABLE).planet_ok)(self.0, v)}
296  }
297}
298// SAFETY: Ok只有第一次调用有用, 且不可复制
299unsafe impl Send for PlanetCaller {}
300unsafe impl Sync for PlanetCaller {}
301
302pub struct Planet;
303impl Planet {
304  /// 传入一个接受caller的闭包, 创建一个Planet的原生实例
305  /// 
306  /// 目前无法在原生模块中直接操作Planet, 因此该函数的返回值请直接返回给你的函数
307  pub fn new(f:impl FnOnce(PlanetCaller))-> Litr {
308    let (planet, planet_cls) = unsafe {((*FUNCTABLE).planet_new)()};
309    f(PlanetCaller(planet));
310    Litr::Ninst(Instance {cls:planet_cls, v:planet as _, w:0})
311  }
312}