key_native/
lib.rs

1//! Key语言的Native Module库
2//! 
3//! 参见[Native Module开发](https://docs.subkey.top/native)
4//! 
5//! 由于已经决定了Rust为唯一Native编程语言,就不需要考虑C的行为了
6//! 
7//! 数据类型都可以直接使用Rust标准库, 调用约定也可以使用extern "Rust"
8#![feature(const_ptr_is_null)]
9#![allow(unused)]
10
11use std::{cell::UnsafeCell, collections::HashMap, mem::transmute};
12
13pub mod key;
14use key::*;
15
16/// 原生类型实例
17#[derive(Debug)]
18#[repr(C)]
19pub struct Instance {
20  /// 原生类实例的第一个可用值
21  pub v: usize,
22  /// 原生类实例的第二个可用值
23  pub w: usize,
24  /// 实例的原生类指针
25  pub cls: Class
26}
27
28impl Clone for Instance {
29  /// 调用自定义clone (key-native库中的默认clone行为也可用)
30  fn clone(&self) -> Self {
31    unsafe{((**self.cls.p.get()).onclone)(self)}
32  }
33}
34impl Drop for Instance {
35  /// 调用自定义drop (key-native的默认drop不做任何事)
36  fn drop(&mut self) {
37    unsafe{((**self.cls.p.get()).ondrop)(self)}
38  }
39}
40
41/// drop出错时可以判断你是不是没设置clone函数
42fn default_onclone(v:&Instance)-> Instance {
43  v.clone()
44}
45
46impl Instance {
47  /// 以T的格式读取v值, 请保证v是有效指针且可写
48  /// 
49  /// 虽说不带unsafe, 但还是很容易UB的
50  pub fn read<T>(&self)-> &mut T {
51    unsafe { &mut*(self.v as *mut T) }
52  }
53  /// w的read
54  pub fn readw<T>(&self)-> &mut T {
55    unsafe { &mut*(self.w as *mut T) }
56  }
57
58  /// 执行T的析构函数, 并把v覆盖为新值
59  /// 
60  /// 请务必保证set前后的指针类型相同
61  pub fn set<T>(&mut self, v:T) {
62    self.dropv::<T>();
63    self.v = to_ptr(v);
64  }
65  /// w的set
66  pub fn setw<T>(&mut self, w:T) {
67    self.dropw::<T>();
68    self.w = to_ptr(w);
69  }
70
71  /// 不pub, 所以不管安全性
72  fn dealloc<T>(&self, p:*mut T) {
73    assert!(!p.is_null(), "无法析构空指针.{}\n  详见https://docs.subkey.top/native/4.class", {
74      if unsafe{&**self.cls.p.get()}.onclone == default_onclone 
75        {"\n  你或许应该为class定义onclone"}else {""}
76    });
77    unsafe {
78      std::ptr::drop_in_place(p);
79      let lo = std::alloc::Layout::new::<T>();
80      std::alloc::dealloc(p as _, lo);
81    }
82  }
83  /// 将v作为T的指针, 将T的内存释放
84  pub fn dropv<T>(&mut self) {
85    self.dealloc(self.v as *mut T);
86    self.v = 0;
87  }
88  /// w版drop
89  pub fn dropw<T>(&mut self) {
90    self.dealloc(self.w as *mut T);
91    self.w = 0;
92  }
93}
94
95
96/// Key语言的原生模块的函数
97pub type NativeFn = fn(Vec<LitrRef>, Scope)-> Litr;
98/// Key语言的原生类型中为模块定义的方法
99pub type NativeMethod = fn(&mut Instance, args:Vec<LitrRef>, Scope)-> Litr;
100
101/// 原生类型定义
102#[derive(Debug, Clone)]
103#[repr(C)]
104struct ClassInner {
105  statics: Vec<(Ident, NativeFn)>,
106  methods: Vec<(Ident, NativeMethod)>,
107  name: Ident,
108  getter: fn(&Instance, get:Ident)-> Litr,
109  setter: fn(&mut Instance, set:Ident, to:Litr),
110  index_get: fn(&Instance, LitrRef)-> Litr,
111  index_set: fn(&mut Instance, LitrRef, Litr),
112  next: fn(&mut Instance)-> Litr,
113  to_str: fn(&Instance)-> String,
114  onclone: fn(&Instance)-> Instance,
115  ondrop: fn(&mut Instance)
116}
117
118/// 原生类型指针
119#[repr(transparent)]
120#[derive(Debug)]
121pub struct Class {
122  p: UnsafeCell<*mut ClassInner>
123}
124impl Clone for Class {
125  fn clone(&self) -> Self {
126    Class {p: UnsafeCell::new(unsafe{*self.p.get()})}
127  }
128}
129
130unsafe impl Send for Class {}
131unsafe impl Sync for Class {}
132
133macro_rules! impl_class_setter {($($doc:literal $f:ident($t:ty);)*) => {
134  $(
135    #[doc = $doc]
136    pub fn $f(&self, f:$t) {
137      self.assert();
138      unsafe{(**self.p.get()).$f = f;}
139    }
140  )*
141}}
142impl Class {
143  /// 为static创建一个空指针
144  /// 
145  /// 要在此后调用其new方法才能访问
146  pub const fn uninit()-> Self {
147    Class { p: UnsafeCell::new(std::ptr::null_mut()) }
148  }
149  #[inline]
150  /// 判断是否new过了
151  const fn assert(&self) {
152    unsafe{
153      assert!(!(
154        *((&self.p) as *const UnsafeCell<*mut ClassInner> as *const *mut ClassInner)
155      ).is_null(), "请先为Class调用new方法"
156    )}
157  }
158  /// 为Class内部创建一个新类
159  /// 
160  /// 重复调用会引起一个ClassInner的内存泄漏
161  pub fn new(&self, name:&str) {
162    let v = ClassInner { 
163      getter:|_,_|Litr::Uninit, 
164      setter:|_,_,_|(), 
165      statics: Vec::new(), 
166      methods: Vec::new() ,
167      index_get:|_,_|Litr::Uninit, 
168      index_set:|_,_,_|(),
169      next:|_|key::Sym::iter_end(), 
170      to_str: |v|format!("{} {{ Native }}", unsafe{&**v.cls.p.get()}.name),
171      onclone:default_onclone, 
172      ondrop:|_|(),
173      name:intern(name.as_bytes())
174    };
175    let p = Box::into_raw(Box::new(v));
176    unsafe{*self.p.get() = p}
177  }
178  /// 为此类创建一个实例
179  /// 
180  /// v是两个指针长度的内容,可以传任何东西然后as或者transmute
181  pub fn create_raw(&self, v:usize, w:usize)-> Instance {
182    self.assert();
183    Instance { cls: self.clone(), v, w }
184  }
185  /// 为此类创建一个实例并包装为Litr
186  /// 
187  /// v是两个指针长度的内容,可以传任何东西然后as或者transmute
188  pub fn create(&self, v:usize, w:usize)-> Litr {
189    Litr::Ninst(self.create_raw(v, w))
190  }
191  impl_class_setter!{
192    "设置getter, 用来处理`.`运算符"
193    getter(fn(&Instance, get:Ident)-> Litr);
194    "设置setter, 用来处理a.b = c的写法"
195    setter(fn(&mut Instance, set:Ident, to:Litr));
196    "设置index getter, 返回a[i]的值"
197    index_get(fn(&Instance, LitrRef)-> Litr);
198    "设置index setter, 处理a[i] = b"
199    index_set(fn(&mut Instance, LitrRef, Litr));
200    "设置迭代器, 处理for n:instance {}"
201    next(fn(&mut Instance)-> Litr);
202    "自定义复制行为(往往是赋值和传参)"
203    onclone(fn(&Instance)-> Instance);
204    "自定义垃圾回收回收行为(只需要写额外工作,不需要drop此指针)"
205    ondrop(fn(&mut Instance));
206    "自定义Str::from得到的字符串"
207    to_str(fn(&Instance)-> String);
208  }
209  /// 添加一个方法
210  pub fn method(&self, name:&str, f:NativeMethod) {
211    self.assert();
212    unsafe{(**self.p.get()).methods.push((intern(name.as_bytes()), f));}
213  }
214  /// 添加一个静态方法
215  pub fn static_method(&self, name:&str, f:NativeFn) {
216    self.assert();
217    unsafe{(**self.p.get()).statics.push((intern(name.as_bytes()), f));}
218  }
219}
220
221impl PartialEq for Class {
222  fn eq(&self, other: &Self) -> bool {
223    unsafe{*self.p.get() == *other.p.get()}
224  }
225}
226
227
228/// 传进main函数的可写空模块
229#[repr(C)]
230pub struct NativeModule {
231  funcs: *mut Vec<(Ident, NativeFn)>,
232  classes: *mut Vec<Class>
233}
234impl NativeModule {
235  /// 导出函数
236  pub fn export_fn(&mut self, name:&str, f:NativeFn) {
237    unsafe{&mut *self.funcs}.push((intern(name.as_bytes()), f))
238  }
239  /// 导出一个类
240  /// 
241  /// 可以提前调用此函数,之后再追加方法
242  pub fn export_cls(&mut self, cls:Class) {
243    cls.assert();
244    unsafe{&mut *self.classes}.push(cls);
245  }
246}
247
248#[macro_export]
249macro_rules! get_arg {
250  ($args:ident[$i:literal]?)=> {
251    $args.get($i).map_or(&Litr::Uninit, |n|&**n)
252  };
253  ($args:ident[$i:literal])=> {
254    match $args.get($i) {
255      Some(v)=> &**v,
256      _=> panic!("至少需要{}个参数", $i+1)
257    }
258  };
259  ($args:ident[$i:literal]:$t:ident)=> {
260    match $args.get($i) {
261      Some(v)=> match &**v {
262        Litr::$t(v)=> v,
263        _=> panic!("第{}个参数必须是{}", $i+1, stringify!($t))
264      },
265      _=> panic!("至少需要{}个参数", $i+1)
266    }
267  };
268  ($args:ident[$i:literal]:$t:ident?$def:expr)=> {
269    $args.get($i).map_or($def, |val|{
270      match &**val {
271        Litr::$t(n)=> *n as u64,
272        _=> $def
273      }
274    });
275  }
276}
277
278/// 将一个非指针的值转为方便实例储存的指针
279#[inline]
280pub fn to_ptr<T>(v:T)-> usize {
281  Box::into_raw(Box::new(v)) as usize
282}
283
284/// 增加该作用域的引用计数
285/// 
286/// 警告: 你应当在作用域用完时, 
287/// 为此调用对应的`outlive_dec`,
288/// 否则会导致该作用域以上所有作用域无法回收
289pub fn outlive_inc(s:Scope) {
290  unsafe{((*FUNCTABLE).outlive_inc)(s)};
291}
292/// 减少该作用域的引用计数
293pub fn outlive_dec(s:Scope) {
294  unsafe{((*FUNCTABLE).outlive_dec)(s)};
295}
296
297/// 阻塞主线程的计数+1
298pub fn wait_inc() {
299  unsafe{((*FUNCTABLE).wait_inc)()};
300}
301/// 阻塞主线程的计数-1
302pub fn wait_dec() {
303  unsafe{((*FUNCTABLE).wait_dec)()};
304}
305
306pub mod prelude {
307  pub use crate::key::{Litr, LitrRef, Scope, Ident};
308  pub use crate::{NativeModule, Class, get_arg, Instance, to_ptr};
309}