Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions source/loaders/rs_loader/rust/compiler/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::rustc_ast::{
};
use super::{Function, FunctionParameter, FunctionType, Mutability, Reference};

pub fn handle_ty(ty: &rustc_ast::Ty) -> FunctionParameter {
pub fn handle_ty(ty: &rustc_ast::Ty, generics: &Vec<String>) -> FunctionParameter {
let mut result = FunctionParameter {
name: String::new(),
mutability: Mutability::No,
Expand All @@ -16,6 +16,12 @@ pub fn handle_ty(ty: &rustc_ast::Ty) -> FunctionParameter {
TyKind::Path(_, path) => {
let segment = &path.segments[0];
let symbol_string = segment.ident.name.to_string();

if generics.contains(&symbol_string) {
result.ty = FunctionType::Complex;
result.name = symbol_string;
return result;
}
match symbol_string.as_str() {
"i16" => result.ty = FunctionType::i16,
"i32" => result.ty = FunctionType::i32,
Expand All @@ -36,7 +42,7 @@ pub fn handle_ty(ty: &rustc_ast::Ty) -> FunctionParameter {
GenericArgs::AngleBracketed(AngleBracketedArgs { args, .. }) => {
for arg in args {
if let AngleBracketedArg::Arg(GenericArg::Type(ty)) = arg {
result.generic.push(handle_ty(ty))
result.generic.push(handle_ty(ty, generics))
}
}
}
Expand All @@ -52,7 +58,7 @@ pub fn handle_ty(ty: &rustc_ast::Ty) -> FunctionParameter {
GenericArgs::AngleBracketed(AngleBracketedArgs { args, .. }) => {
for arg in args {
if let AngleBracketedArg::Arg(GenericArg::Type(ty)) = arg {
result.generic.push(handle_ty(ty))
result.generic.push(handle_ty(ty, generics))
}
}
}
Expand All @@ -67,7 +73,7 @@ pub fn handle_ty(ty: &rustc_ast::Ty) -> FunctionParameter {
result.name = symbol_string;
}
TyKind::Ref(_, MutTy { ty, mutbl }) => {
let mut inner_ty = handle_ty(ty);
let mut inner_ty = handle_ty(ty, generics);
inner_ty.reference = Reference::Yes;
match mutbl {
rustc_ast::Mutability::Mut => inner_ty.mutability = Mutability::Yes,
Expand All @@ -91,15 +97,22 @@ fn handle_pat(pat: &Pat) -> Option<String> {
None
}

pub fn handle_fn(name: String, sig: &FnSig) -> Function {
pub fn handle_fn(name: String, sig: &FnSig, generics: &rustc_ast::Generics) -> Function {
let generics_params = generics
.params
.iter()
.map(|param| param.ident.name.to_string())
.collect::<Vec<String>>();

let mut function = Function {
name,
ret: None,
args: vec![],
generics: generics_params.clone(),
};
// parse input and output
for arg in &sig.decl.inputs {
let mut param = handle_ty(&arg.ty);
let mut param = handle_ty(&arg.ty, &generics_params);
// we need to extract the name from pat.
if let Some(name) = handle_pat(&arg.pat) {
param.name = name;
Expand All @@ -110,7 +123,7 @@ pub fn handle_fn(name: String, sig: &FnSig) -> Function {
match &sig.decl.output {
FnRetTy::Default(_) => function.ret = None,
FnRetTy::Ty(ty) => {
function.ret = Some(handle_ty(ty));
function.ret = Some(handle_ty(ty, &generics_params));
}
}
function
Expand Down
36 changes: 28 additions & 8 deletions source/loaders/rs_loader/rust/compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub mod memory;
mod middle;
pub mod package;
pub(crate) mod registrator;
pub mod template;
pub mod wrapper;
use wrapper::generate_wrapper;
pub mod api;
Expand Down Expand Up @@ -369,6 +370,8 @@ pub struct Function {
name: String,
ret: Option<FunctionParameter>,
args: Vec<FunctionParameter>,
#[allow(dead_code)]
generics: Vec<String>,
}

impl Function {
Expand All @@ -378,6 +381,16 @@ impl Function {
}
matches!(self.args[0].ty, FunctionType::This)
}

pub fn instantiate(&self, types: Vec<String>) -> Function {
let mut function = self.clone();

function.generics.clear();

function.name = format!("{}::<{}>", self.name, types.join(", "));

function
}
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -717,7 +730,7 @@ impl<'a> visit::Visitor<'a> for ItemVisitor {
if let Some(ident) = field.ident {
let attr = Attribute {
name: ident.to_string(),
ty: ast::handle_ty(&field.ty),
ty: ast::handle_ty(&field.ty, &vec![]),
};
class.attributes.push(attr);
}
Expand All @@ -728,6 +741,7 @@ impl<'a> visit::Visitor<'a> for ItemVisitor {
items,
self_ty,
of_trait,
generics,
..
} = impl_kind;
let impl_kind = match of_trait {
Expand Down Expand Up @@ -756,10 +770,10 @@ impl<'a> visit::Visitor<'a> for ItemVisitor {
if sig.decl.has_self() {
match impl_kind {
ImplKind::Drop => {
class.destructor = Some(ast::handle_fn(name, sig));
class.destructor = Some(ast::handle_fn(name, sig, generics));
}
_ => {
class.methods.push(ast::handle_fn(name, sig));
class.methods.push(ast::handle_fn(name, sig, generics));
}
}
} else {
Expand All @@ -771,20 +785,25 @@ impl<'a> visit::Visitor<'a> for ItemVisitor {
rustc_ast::TyKind::Path(_, p) => {
let ret_name = p.segments[0].ident.to_string();
if ret_name == "Self" || ret_name == class_name_str {
class.constructor = Some(ast::handle_fn(name, sig));
class.constructor =
Some(ast::handle_fn(name, sig, generics));
} else {
class
.static_methods
.push(ast::handle_fn(name, sig));
.push(ast::handle_fn(name, sig, generics));
}
}
_ => {
class.static_methods.push(ast::handle_fn(name, sig));
class
.static_methods
.push(ast::handle_fn(name, sig, generics));
}
}
}
rustc_ast::FnRetTy::Default(_) => {
class.static_methods.push(ast::handle_fn(name, sig));
class
.static_methods
.push(ast::handle_fn(name, sig, generics));
}
}
}
Expand All @@ -794,7 +813,8 @@ impl<'a> visit::Visitor<'a> for ItemVisitor {

ItemKind::Fn(box fn_item) => {
let item = fn_item.ident.to_string();
self.functions.push(ast::handle_fn(item, &fn_item.sig));
self.functions
.push(ast::handle_fn(item, &fn_item.sig, &fn_item.generics));
}
_ => {}
}
Expand Down
1 change: 1 addition & 0 deletions source/loaders/rs_loader/rust/compiler/src/middle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pub fn handle_fn<'a>(name: String, sig: &Binder<'a, FnSig<'a>>, names: &[Ident])
name,
ret: None,
args: vec![],
generics: vec![],
};
// parse input and output
let inputs = sig.inputs().skip_binder();
Expand Down
77 changes: 77 additions & 0 deletions source/loaders/rs_loader/rust/compiler/src/template.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#[allow(unused_imports)]
use crate::Function;

#[derive(Debug, Clone)]
pub enum TemplateKind {
Function,
Class,
}

#[derive(Debug, Clone)]
pub enum Type {
I32,
String,
Bool,
}

#[derive(Debug, Clone)]
pub struct Template {
pub name: String,
pub kind: TemplateKind,
pub parameters: Vec<String>,
}

pub fn template_instantiate_function(template: &Template, type_list: Vec<Type>) -> String {
format!("{}::<{:?}>", template.name, type_list)
}

pub fn template_instantiate_class(template: &Template, type_list: Vec<Type>) -> String {
format!("{}::<{:?}>", template.name, type_list)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_function_template_instantiation() {
let template = Template {
name: "identity".to_string(),
kind: TemplateKind::Function,
parameters: vec!["T".to_string()],
};

let result = template_instantiate_function(&template, vec![Type::I32]);

assert!(result.contains("identity"));
}

#[test]
fn test_class_template_instantiation() {
let template = Template {
name: "Wrapper".to_string(),
kind: TemplateKind::Class,
parameters: vec!["T".to_string()],
};

let result = template_instantiate_class(&template, vec![Type::I32]);

assert!(result.contains("Wrapper"));
}

#[test]
fn test_function_struct_template_instantiation() {
let function = Function {
name: "identity".to_string(),
ret: None,
args: vec![],
generics: vec!["T".to_string()],
};

let instantiated = function.instantiate(vec!["i32".to_string()]);

assert_eq!(instantiated.name, "identity::<i32>");

assert!(instantiated.generics.is_empty());
}
}
6 changes: 3 additions & 3 deletions source/loaders/rs_loader/rust/compiler/src/wrapper/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ impl ToMetaResult for bool {

impl ToMetaResult for char {
fn to_meta_result(self) -> Result<MetacallValue> {
Ok(unsafe { metacall_value_create_char(self as i8) })
Ok(unsafe { metacall_value_create_char(self as c_char) })
}
}

Expand All @@ -522,7 +522,7 @@ impl ToMetaResult for usize {

impl ToMetaResult for i8 {
fn to_meta_result(self) -> Result<MetacallValue> {
Ok(unsafe { metacall_value_create_char(self) })
Ok(unsafe { metacall_value_create_char(self as c_char) })
}
}

Expand Down Expand Up @@ -732,7 +732,7 @@ macro_rules! convert_to {

impl FromMeta for i8 {
unsafe fn from_meta(val: MetacallValue) -> Result<Self> {
Ok(unsafe { metacall_value_to_char(val) })
Ok(unsafe { metacall_value_to_char(val) as i8 })
}
}
impl FromMeta for i16 {
Expand Down
16 changes: 14 additions & 2 deletions source/loaders/rs_loader/rust/compiler/src/wrapper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@ fn generate_function_wrapper(functions: &[Function]) -> String {
"#[unsafe(no_mangle)]\npub unsafe extern \"C\" fn rs_loader_impl_register_fn_{}() -> *mut Function {{\n",
func.name
));
ret.push_str(&format!("\tlet f = Function::new({});\n", func.name));
ret.push_str("\tBox::into_raw(Box::new(f))\n}\n");
if func.generics.is_empty() {
ret.push_str(&format!("\tlet f = Function::new({});\n", func.name));

ret.push_str("\tBox::into_raw(Box::new(f))\n");
} else {
println!(
"Rust Loader: function {} is a template {:?}",
func.name, func.generics
);
ret.push_str("\tstd::ptr::null_mut()\n");
}
//ret.push_str(&format!("\tlet f = Function::new({});\n", func.name));
//ret.push_str("\tBox::into_raw(Box::new(f))\n}\n");
ret.push_str("}\n");
}
ret
}
Expand Down
2 changes: 1 addition & 1 deletion source/loaders/rs_loader/rust/src/lifecycle/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ where
if path_is_vector {
path = loadable_path.wrapping_add(i) as *const c_char
} else {
path = loadable_path as *const i8;
path = loadable_path as *const c_char;
}

let path_slice = unsafe { CStr::from_ptr(path) }
Expand Down
2 changes: 2 additions & 0 deletions source/reflect/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ set(headers
${include_path}/reflect_value_type_promotion.h
${include_path}/reflect_value_type_demotion.h
${include_path}/reflect_value_type_cast.h
${include_path}/reflect_template.h
)

set(sources
Expand All @@ -88,6 +89,7 @@ set(sources
${source_path}/reflect_value_type_promotion.c
${source_path}/reflect_value_type_demotion.c
${source_path}/reflect_value_type_cast.c
${source_path}/reflect_template.c
)

# Group source files
Expand Down
1 change: 1 addition & 0 deletions source/reflect/include/reflect/reflect.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <reflect/reflect_object.h>
#include <reflect/reflect_scope.h>
#include <reflect/reflect_signature.h>
#include <reflect/reflect_template.h>
#include <reflect/reflect_type.h>
#include <reflect/reflect_type_id.h>
#include <reflect/reflect_value.h>
Expand Down
Loading