diff --git a/samples/helloworld.ks b/samples/helloworld.ks index a70b51f..cc16d38 100644 --- a/samples/helloworld.ks +++ b/samples/helloworld.ks @@ -1,4 +1,5 @@ mod D:\code\rs\key-native\target\debug\key_native.dll> m -let a = m-.test(); +let a = m-:Okk::new(555); +log(a) diff --git a/src/native.rs b/src/native.rs index 364cf95..353743d 100644 --- a/src/native.rs +++ b/src/native.rs @@ -5,50 +5,59 @@ use crate::{ }; pub type NativeFn = fn(Vec)-> Litr; -pub type Getter = fn(get:&[u8]); -pub type Setter = fn(set:&[u8], to:Litr); -pub type IndexGetter = fn(get:usize)-> Litr; -pub type IndexSetter = fn(set:usize, to:Litr)-> Litr; pub type NativeMethod = fn(kself:&mut Litr, Vec)-> Litr; +pub type Getter = fn(get:Interned)-> Litr; +pub type Setter = fn(set:Interned, to:Litr); +pub type IndexGetter = fn(get:usize)-> Litr; +pub type IndexSetter = fn(set:usize, to:Litr); #[derive(Debug, Clone)] pub struct NativeMod { pub name: Interned, pub funcs: Vec<(Interned, NativeFn)>, - pub classes: Vec + pub classes: Vec<*const NativeClassDef> } +#[repr(C)] #[derive(Debug, Clone)] pub struct NativeClassDef { pub name: Interned, - pub getters: Vec<(Interned, Getter)>, - pub setters: Vec<(Interned, Setter)>, - pub igetters: Vec<(Interned, IndexGetter)>, - pub isetters: Vec<(Interned, IndexSetter)>, + pub getter: Getter, + pub setter: Setter, + pub igetter: IndexGetter, + pub isetter: IndexSetter, pub statics: Vec<(Interned, NativeFn)>, pub methods: Vec<(Interned, NativeMethod)> } -pub struct NativeApis<'a> { - export_fn: &'a mut dyn FnMut(&'a [u8], NativeFn), - export_cls: &'a mut dyn FnMut(NativeClassDef), +/// 传进main里的东西,作为与原生的接口 +#[repr(C)] +struct NativeInterface { + intern: fn(&[u8])-> Interned, + err: fn(&str)->!, + funcs: *mut Vec<(Interned, NativeFn)>, + classes: *mut Vec<*const NativeClassDef> } -#[repr(transparent)] +/// 原生类型实例 +#[derive(Debug, Clone)] +#[repr(C)] pub struct NativeInstance { - pub p: usize + pub cls: *mut NativeClassDef, + pub v: [usize;2], } pub fn parse(name:Interned,path:&[u8])-> Result { let lib = Clib::load(path)?; let mut funcs = Vec::new(); - let export_fn = &mut |name, f|funcs.push((intern(name), f)); let mut classes = Vec::new(); - let export_cls = &mut |c|classes.push(c); + fn err(s:&str)->! { + panic!("{} \n 运行时({})", s, unsafe{crate::runtime::LINE}) + } unsafe { - let keymain:extern fn(&mut NativeApis) = std::mem::transmute(lib.get(b"keymain").ok_or("模块需要'KeyMain'作为主运行函数")?); - keymain(&mut NativeApis { - export_fn, export_cls + let keymain:extern fn(&mut NativeInterface) = std::mem::transmute(lib.get(b"keymain").ok_or("模块需要'KeyMain'作为主运行函数")?); + keymain(&mut NativeInterface { + intern, err, funcs: &mut funcs, classes: &mut classes }); } Ok(NativeMod{ diff --git a/src/runtime/externer.rs b/src/runtime/externer.rs index f270862..a85bdd5 100644 --- a/src/runtime/externer.rs +++ b/src/runtime/externer.rs @@ -77,6 +77,7 @@ pub fn translate(arg:Litr)-> Result { List(_)=> Err("列表类型不可作为C指针传递".to_string()), Obj=> Err("Ks对象不可作为C指针传递".to_string()), Inst(_)=> Err("Ks实例不可作为C指针传递".to_string()), + Ninst(_)=> Err("Ks原生实例不可作为C指针传递".to_string()) } } diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index c273dd0..8296179 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -27,7 +27,7 @@ mod externer; /// 运行期追踪行号 /// /// 只有主线程会访问,不存在多线程同步问题 -static mut LINE:usize = 0; +pub static mut LINE:usize = 0; #[macro_use] macro_rules! err {($($a:expr$(,)?)*) => { panic!("{} 运行时({})", format_args!($($a,)*), unsafe{LINE}) }} @@ -226,11 +226,12 @@ impl Scope { Module::Native(p)=> { let m = unsafe {&*p}; for cls in m.classes.iter() { - if cls.name == s { - return Class::Native(cls); + let name = unsafe {&**cls}.name; + if name == s { + return Class::Native(*cls); } } - err!("模块'{}'中没有'{}'类型",modname.str(), s.str()) + err!("原生模块'{}'中没有'{}'类型",modname.str(), s.str()) } } } diff --git a/src/scan/literal.rs b/src/scan/literal.rs index 6ead9d0..41e0c09 100644 --- a/src/scan/literal.rs +++ b/src/scan/literal.rs @@ -4,13 +4,13 @@ use super::{ expr::* }; -use crate::runtime::{Module, Scope}; +use crate::{native::NativeInstance, runtime::{Module, Scope}}; use crate::intern::Interned; use std::collections::HashMap; -/// 变量或字面量 +#[repr(C)] #[derive(Debug, Clone)] pub enum Litr { Uninit, @@ -25,7 +25,8 @@ pub enum Litr { Buffer (Box>), List (Box>), Obj, - Inst (Box) + Inst (Box), + Ninst (Box) } impl Litr { /// 由Key编译器提供的转字符 @@ -87,6 +88,12 @@ impl Litr { str.push_str(" }"); str } + Ninst(inst)=> { + let mut s = String::new(); + s.push_str(&unsafe{&*inst.cls}.name.str()); + s.push_str(" { Native }"); + s + } } } }