@@ -15,7 +15,7 @@ use inkwell::{
1515 debug_info:: * ,
1616 module:: { FlagBehavior , Linkage , Module } ,
1717 targets:: { InitializationConfig , Target , TargetMachine } ,
18- types:: { BasicType , BasicTypeEnum , FunctionType , StructType } ,
18+ types:: { BasicType , BasicTypeEnum , FunctionType , PointerType , StructType } ,
1919 values:: {
2020 AnyValue , AnyValueEnum , BasicMetadataValueEnum , BasicValue , BasicValueEnum , CallableValue ,
2121 FunctionValue , PointerValue ,
@@ -66,6 +66,14 @@ pub struct MemberType<'ctx> {
6666 pub ptr_depth : usize ,
6767}
6868
69+ fn get_nth_mark_fn < ' ctx > ( f : FunctionValue < ' ctx > , n : u32 ) -> CallableValue < ' ctx > {
70+ f. get_nth_param ( n)
71+ . unwrap ( )
72+ . into_pointer_value ( )
73+ . try_into ( )
74+ . unwrap ( )
75+ }
76+
6977pub fn create_llvm_deps < ' ctx > (
7078 context : & ' ctx Context ,
7179 dir : & str ,
@@ -305,18 +313,18 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
305313 nh
306314 }
307315
308- fn gen_or_get_arr_visit_function ( & self , ctx : & mut Ctx < ' a > , v : & ARRType ) -> FunctionValue < ' ctx > {
309- let currentbb = self . builder . get_insert_block ( ) ;
310- self . builder . unset_current_debug_location ( ) ;
316+ fn visit_f_tp ( & self ) -> PointerType < ' ctx > {
311317 let i8ptrtp = self . context . i8_type ( ) . ptr_type ( AddressSpace :: default ( ) ) ;
312- let visit_ftp = self
313- . context
318+ self . context
314319 . void_type ( )
315320 . fn_type ( & [ i8ptrtp. into ( ) , i8ptrtp. into ( ) ] , false )
316- . ptr_type ( AddressSpace :: default ( ) ) ;
317- let ptrtp = self . arr_type ( v, ctx) . ptr_type ( AddressSpace :: default ( ) ) ;
318- let ty = ptrtp. get_element_type ( ) . into_struct_type ( ) ;
319- let ftp = self . context . void_type ( ) . fn_type (
321+ . ptr_type ( AddressSpace :: default ( ) )
322+ }
323+
324+ fn mark_fn_tp ( & self , ptrtp : PointerType < ' ctx > ) -> FunctionType < ' ctx > {
325+ let i8ptrtp = self . context . i8_type ( ) . ptr_type ( AddressSpace :: default ( ) ) ;
326+ let visit_ftp = self . visit_f_tp ( ) ;
327+ self . context . void_type ( ) . fn_type (
320328 & [
321329 ptrtp. into ( ) ,
322330 i8ptrtp. into ( ) ,
@@ -325,7 +333,15 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
325333 visit_ftp. into ( ) ,
326334 ] ,
327335 false ,
328- ) ;
336+ )
337+ }
338+
339+ fn gen_or_get_arr_visit_function ( & self , ctx : & mut Ctx < ' a > , v : & ARRType ) -> FunctionValue < ' ctx > {
340+ let currentbb = self . builder . get_insert_block ( ) ;
341+ self . builder . unset_current_debug_location ( ) ;
342+ let ptrtp = self . arr_type ( v, ctx) . ptr_type ( AddressSpace :: default ( ) ) ;
343+ let ty = ptrtp. get_element_type ( ) . into_struct_type ( ) ;
344+ let ftp = self . mark_fn_tp ( ptrtp) ;
329345 let arr_tp = ty. get_field_type_at_index ( 1 ) . unwrap ( ) . into_array_type ( ) ;
330346 let fname = & ( arr_tp. to_string ( ) + "@" + & ctx. plmod . path ) ;
331347 if let Some ( f) = self . module . get_function ( fname) {
@@ -366,26 +382,11 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
366382 )
367383 } ;
368384 let visitor = f. get_nth_param ( 1 ) . unwrap ( ) . into_pointer_value ( ) ;
369- let visit_ptr_f: CallableValue = f
370- . get_nth_param ( 2 )
371- . unwrap ( )
372- . into_pointer_value ( )
373- . try_into ( )
374- . unwrap ( ) ;
385+ let visit_ptr_f = get_nth_mark_fn ( f, 2 ) ;
375386 // complex type needs to provide a visit function by itself
376387 // which is stored in the first field of the struct
377- let visit_complex_f: CallableValue = f
378- . get_nth_param ( 3 )
379- . unwrap ( )
380- . into_pointer_value ( )
381- . try_into ( )
382- . unwrap ( ) ;
383- let visit_trait_f: CallableValue = f
384- . get_nth_param ( 4 )
385- . unwrap ( )
386- . into_pointer_value ( )
387- . try_into ( )
388- . unwrap ( ) ;
388+ let visit_complex_f = get_nth_mark_fn ( f, 3 ) ;
389+ let visit_trait_f = get_nth_mark_fn ( f, 4 ) ;
389390 match & * v. element_type . borrow ( ) {
390391 PLType :: ARR ( _) | PLType :: STRUCT ( _) => {
391392 // call the visit_complex function
@@ -980,90 +981,6 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
980981 self . get_llvm_value_handle ( & self . get_or_insert_fn ( pltp, ctx) . as_any_value_enum ( ) )
981982 }
982983
983- // fn mv2heap(&self, val: ValueHandle, ctx: &mut Ctx<'a>, tp: &PLType) -> ValueHandle {
984- // if !ctx.usegc {
985- // return val;
986- // }
987- // let val = self.get_llvm_value(val).unwrap();
988- // let gcmod = ctx.plmod.submods.get("gc").unwrap();
989- // let f: FNType = gcmod
990- // .get_type("DioGC__malloc")
991- // .unwrap()
992- // .borrow()
993- // .clone()
994- // .try_into()
995- // .unwrap();
996- // let f = self.get_or_insert_fn(&f, ctx);
997- // let td = self.targetmachine.get_target_data();
998- // let loaded = self.builder.build_load(val.into_pointer_value(), "loaded");
999- // let size = td.get_store_size(&loaded.get_type());
1000- // let size = self.context.i64_type().const_int(size as u64, false);
1001- // let tp = self
1002- // .context
1003- // .i8_type()
1004- // .const_int(tp.get_immix_type().int_value() as u64, false);
1005- // let heapptr = self
1006- // .builder
1007- // .build_call(f, &[size.into(), tp.into()], "gc_malloc")
1008- // .try_as_basic_value()
1009- // .left()
1010- // .unwrap();
1011- // let heapptr = self.builder.build_pointer_cast(
1012- // heapptr.into_pointer_value(),
1013- // val.get_type().into_pointer_type(),
1014- // "heapptr",
1015- // );
1016- // self.builder.build_store(heapptr, loaded);
1017- // self.get_llvm_value_handle(&heapptr.as_any_value_enum())
1018- // }
1019- // fn gc_rm_root(&self, stackptr: ValueHandle, ctx: &mut Ctx<'a>) {
1020- // if !ctx.usegc {
1021- // return;
1022- // }
1023- // self.builder.unset_current_debug_location();
1024- // let block = self.builder.get_insert_block().unwrap();
1025- // if let Some(inst) = block.get_first_instruction() {
1026- // self.builder.position_before(&inst);
1027- // }
1028- // self.gc_rm_root_current(stackptr, ctx);
1029- // }
1030- // fn gc_rm_root_current(&self, stackptr: ValueHandle, ctx: &mut Ctx<'a>) {
1031- // if !ctx.usegc {
1032- // return;
1033- // }
1034- // let stackptr = self.get_llvm_value(stackptr).unwrap();
1035- // let gcmod = ctx.plmod.submods.get("gc").unwrap();
1036- // let f: FNType = gcmod
1037- // .get_type("DioGC__rm_root")
1038- // .unwrap()
1039- // .borrow()
1040- // .clone()
1041- // .try_into()
1042- // .unwrap();
1043- // let f = self.get_or_insert_fn(&f, ctx);
1044- // let stackptr = self.builder.build_pointer_cast(
1045- // stackptr.into_pointer_value(),
1046- // self.context.i64_type().ptr_type(AddressSpace::default()),
1047- // "stackptr",
1048- // );
1049- // self.builder.build_call(f, &[stackptr.into()], "rm_root");
1050- // }
1051- // fn gc_collect(&self, ctx: &mut Ctx<'a>) {
1052- // if !ctx.usegc {
1053- // return;
1054- // }
1055- // self.builder.unset_current_debug_location();
1056- // let gcmod = ctx.plmod.submods.get("gc").unwrap();
1057- // let f: FNType = gcmod
1058- // .get_type("DioGC__collect")
1059- // .unwrap()
1060- // .borrow()
1061- // .clone()
1062- // .try_into()
1063- // .unwrap();
1064- // let f = self.get_or_insert_fn(&f, ctx);
1065- // self.builder.build_call(f, &[], "collect");
1066- // }
1067984 fn get_or_add_global (
1068985 & self ,
1069986 name : & str ,
@@ -1711,26 +1628,7 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
17111628 global. set_metadata ( exp. as_metadata_value ( self . context ) , 0 ) ;
17121629 self . get_llvm_value_handle ( & global. as_any_value_enum ( ) )
17131630 }
1714- /// ```ignore
1715- /// struct A {
1716- /// a: i32,
1717- /// b: *i32,
1718- /// c: *A,
1719- /// d: B,
1720- /// e: [i32; 3],
1721- /// f: [*i32; 3],
1722- /// g: [A; 3], // TODO 没考虑到
1723- /// h: Trait,
1724- /// i: *[*i32; 3],
1725- /// }
1726- /// visit_ptr(&a.b);
1727- /// visit_ptr(&a.c);
1728- /// a.d.vtable(visitfns..);
1729- /// a.e.vtable(visitfns..);
1730- /// a.f.vtable(visitfns..);
1731- /// visit_trait(&a.h);
1732- /// visit_ptr(&a.i);
1733- /// ```
1631+
17341632 fn gen_st_visit_function (
17351633 & self ,
17361634 ctx : & mut Ctx < ' a > ,
@@ -1740,23 +1638,9 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
17401638 let currentbb = ctx. block ;
17411639 self . builder . unset_current_debug_location ( ) ;
17421640 let i8ptrtp = self . context . i8_type ( ) . ptr_type ( AddressSpace :: default ( ) ) ;
1743- let visit_ftp = self
1744- . context
1745- . void_type ( )
1746- . fn_type ( & [ i8ptrtp. into ( ) , i8ptrtp. into ( ) ] , false )
1747- . ptr_type ( AddressSpace :: default ( ) ) ;
17481641 let ptrtp = self . struct_type ( v, ctx) . ptr_type ( AddressSpace :: default ( ) ) ;
17491642 let ty = ptrtp. get_element_type ( ) . into_struct_type ( ) ;
1750- let ftp = self . context . void_type ( ) . fn_type (
1751- & [
1752- ptrtp. into ( ) ,
1753- i8ptrtp. into ( ) ,
1754- visit_ftp. into ( ) ,
1755- visit_ftp. into ( ) ,
1756- visit_ftp. into ( ) ,
1757- ] ,
1758- false ,
1759- ) ;
1643+ let ftp = self . mark_fn_tp ( ptrtp) ;
17601644 let f = self . module . add_function (
17611645 & ( ty. get_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) + "@" ) ,
17621646 ftp,
@@ -1770,26 +1654,11 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
17701654 for i in 1 ..fieldn {
17711655 let field_pltp = & * field_tps[ i as usize - 1 ] . borrow ( ) ;
17721656 let visitor = f. get_nth_param ( 1 ) . unwrap ( ) . into_pointer_value ( ) ;
1773- let visit_ptr_f: CallableValue = f
1774- . get_nth_param ( 2 )
1775- . unwrap ( )
1776- . into_pointer_value ( )
1777- . try_into ( )
1778- . unwrap ( ) ;
1657+ let visit_ptr_f = get_nth_mark_fn ( f, 2 ) ;
17791658 // complex type needs to provide a visit function by itself
17801659 // which is stored in the first field of the struct
1781- let visit_complex_f: CallableValue = f
1782- . get_nth_param ( 3 )
1783- . unwrap ( )
1784- . into_pointer_value ( )
1785- . try_into ( )
1786- . unwrap ( ) ;
1787- let visit_trait_f: CallableValue = f
1788- . get_nth_param ( 4 )
1789- . unwrap ( )
1790- . into_pointer_value ( )
1791- . try_into ( )
1792- . unwrap ( ) ;
1660+ let visit_complex_f = get_nth_mark_fn ( f, 3 ) ;
1661+ let visit_trait_f = get_nth_mark_fn ( f, 4 ) ;
17931662 let f = self . builder . build_struct_gep ( st, i, "gep" ) . unwrap ( ) ;
17941663 // 指针类型,递归调用visit函数
17951664 if let PLType :: POINTER ( _) = field_pltp {
0 commit comments