Skip to content

Commit fa2981b

Browse files
authored
docs: add comments for closure (#404)
1 parent 336be9c commit fa2981b

File tree

7 files changed

+224
-107
lines changed

7 files changed

+224
-107
lines changed

src/ast/builder/llvmbuilder.rs

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,9 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
988988
.add_function(&llvmname, fn_type, Some(Linkage::External))
989989
}
990990

991+
/// # get_fn_type
992+
///
993+
/// get_fn_type returns the inkwell function type for a pivot-lang function value.
991994
fn get_fn_type(&self, fnvalue: &FNValue, ctx: &mut Ctx<'a>) -> FunctionType<'ctx> {
992995
ctx.protect_generic_context(&fnvalue.fntype.generic_map, |ctx| {
993996
ctx.run_in_type_mod(fnvalue, |ctx, fnvalue| {
@@ -1017,6 +1020,7 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
10171020
!fnvalue.is_declare && fnvalue.name != "main",
10181021
)
10191022
.fn_type(&param_types, false);
1023+
10201024
fn_type
10211025
})
10221026
})
@@ -1570,14 +1574,16 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
15701574
}
15711575
}
15721576

1573-
/// try get function value from module
1577+
/// # get_or_insert_fn
15741578
///
1575-
/// if not found, create a declaration
1579+
/// it returns the emitted function from llvm if it exists,
1580+
/// otherwise it will emit the function value and the return the new value.
15761581
///
1577-
/// bool: 是否已经实现过该函数
1582+
/// The bool means whether the function exists in the llvm builder or not.
15781583
fn get_or_insert_fn(&self, pltp: &FNValue, ctx: &mut Ctx<'a>) -> (FunctionValue<'ctx>, bool) {
1579-
let llvmname = pltp.append_name_with_generic(pltp.llvmname.clone());
1580-
if let Some(v) = self.module.get_function(&llvmname) {
1584+
let final_llvm_name = pltp.append_name_with_generic(pltp.llvmname.clone());
1585+
1586+
if let Some(v) = self.module.get_function(&final_llvm_name) {
15811587
return (v, v.count_basic_blocks() != 0);
15821588
}
15831589
let fn_type = self.get_fn_type(pltp, ctx);
@@ -1587,7 +1593,9 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
15871593
} else {
15881594
Linkage::Private
15891595
};
1590-
let f = self.module.add_function(&llvmname, fn_type, Some(linkage));
1596+
let f = self
1597+
.module
1598+
.add_function(&final_llvm_name, fn_type, Some(linkage));
15911599
if !pltp.is_declare {
15921600
f.set_call_conventions(CALL_CONV);
15931601
}
@@ -1801,14 +1809,17 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
18011809
.yield_ctx_handle = ctx_handle;
18021810
self.builder.position_at_end(prev_bb);
18031811
}
1812+
/// # bitcast
1813+
///
1814+
/// it casts the origin handle into the pointer value
18041815
fn bitcast(
18051816
&self,
18061817
_ctx: &mut Ctx<'a>,
1807-
from: ValueHandle,
1818+
origin: ValueHandle,
18081819
_to: &PLType,
18091820
_name: &str,
18101821
) -> ValueHandle {
1811-
let lv = self.get_llvm_value(from).unwrap();
1822+
let lv = self.get_llvm_value(origin).unwrap();
18121823
let re = if lv.is_function_value() {
18131824
lv.into_function_value()
18141825
.as_global_value()
@@ -2058,6 +2069,10 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
20582069
fn_value.set_call_conventions(CALL_CONV);
20592070
self.get_llvm_value_handle(&fn_value.as_any_value_enum())
20602071
}
2072+
2073+
/// # opaque_struct_type
2074+
///
2075+
/// it creates an opaque StructType with no type definition yet defined.
20612076
fn opaque_struct_type(&self, name: &str) {
20622077
self.context.opaque_struct_type(name);
20632078
}
@@ -2621,24 +2636,28 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
26212636
Ok(())
26222637
}
26232638

2639+
/// # build_sub_program_by_pltp
2640+
///
2641+
/// it creates a subprogram for a closure, which helps to debug the closure
26242642
fn build_sub_program_by_pltp(
26252643
&self,
2626-
paralist: &[Arc<RefCell<PLType>>],
2627-
ret: Arc<RefCell<PLType>>,
2644+
param_tps: &[Arc<RefCell<PLType>>],
2645+
ret_tp: Arc<RefCell<PLType>>,
26282646
name: &str,
26292647
start_line: u32,
2630-
fnvalue: ValueHandle,
2648+
closure_fn_value: ValueHandle,
26312649
child: &mut Ctx<'a>,
26322650
) {
2633-
let mut param_ditypes = vec![];
2634-
for pltype in paralist.iter() {
2635-
param_ditypes.push(self.get_ditype(&pltype.borrow(), child).unwrap());
2651+
// debug information about types
2652+
let mut param_di_types = vec![];
2653+
for pltype in param_tps.iter() {
2654+
param_di_types.push(self.get_ditype(&pltype.borrow(), child).unwrap());
26362655
}
26372656
// debug info
26382657
let subroutine_type = self.dibuilder.create_subroutine_type(
26392658
self.get_cur_di_file(),
2640-
self.get_ditype(&ret.borrow(), child),
2641-
&param_ditypes,
2659+
self.get_ditype(&ret_tp.borrow(), child),
2660+
&param_di_types,
26422661
DIFlags::PUBLIC,
26432662
);
26442663
let subprogram = self.dibuilder.create_function(
@@ -2654,9 +2673,11 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
26542673
DIFlags::PUBLIC,
26552674
false,
26562675
);
2657-
let funcvalue = self.get_llvm_value(fnvalue).unwrap().into_function_value();
2676+
let funcvalue = self
2677+
.get_llvm_value(closure_fn_value)
2678+
.unwrap()
2679+
.into_function_value();
26582680
funcvalue.set_subprogram(subprogram);
2659-
// let discope = child.discope;
26602681
self.discope.set(subprogram.as_debug_info_scope());
26612682
}
26622683
fn build_return(&self, v: Option<ValueHandle>) {
@@ -2668,6 +2689,10 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
26682689
self.builder.build_return(None).unwrap();
26692690
}
26702691
}
2692+
2693+
/// # create_closure_variable_dbg
2694+
///
2695+
/// it creates the debug information for the closure variables
26712696
#[allow(clippy::too_many_arguments)]
26722697
fn create_closure_variable_dbg(
26732698
&self,
@@ -2679,7 +2704,7 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
26792704
allocab: BlockHandle,
26802705
name: &str,
26812706
) {
2682-
let divar = self.dibuilder.create_parameter_variable(
2707+
let di_var = self.dibuilder.create_parameter_variable(
26832708
self.discope.get(),
26842709
name,
26852710
i as u32,
@@ -2697,12 +2722,11 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
26972722
.try_into()
26982723
.unwrap();
26992724
let raw_tp = v.get_type();
2700-
// self.builder.position_at_end(allocab);
27012725
let alloca = self.builder.build_alloca(raw_tp, "para").unwrap();
27022726
self.builder.build_store(alloca, v).unwrap();
27032727
self.dibuilder.insert_declare_at_end(
27042728
alloca,
2705-
Some(divar),
2729+
Some(di_var),
27062730
None,
27072731
self.builder.get_current_debug_location().unwrap(),
27082732
allocab,
@@ -2921,6 +2945,9 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
29212945
self.get_llvm_value_handle(&global.as_any_value_enum())
29222946
}
29232947

2948+
/// # gen_st_visit_function
2949+
///
2950+
/// it generates the visit function for each structure field for GC use.
29242951
fn gen_st_visit_function(
29252952
&self,
29262953
ctx: &mut Ctx<'a>,
@@ -3134,6 +3161,11 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
31343161
self.get_llvm_value_handle(&funcvalue.get_nth_param(i).unwrap().as_any_value_enum()),
31353162
);
31363163
}
3164+
3165+
/// # create_closure_fn
3166+
///
3167+
/// create_closure_fn creates a function type in LLVM format and then emit it by the builder.
3168+
/// The first parameter of the function is an i8 pointer points to the captured data.
31373169
fn create_closure_fn(
31383170
&self,
31393171
ctx: &mut Ctx<'a>,
@@ -3160,6 +3192,7 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
31603192
f_v.set_call_conventions(CALL_CONV);
31613193
self.get_llvm_value_handle(&f_v.into())
31623194
}
3195+
31633196
/// # get_closure_trampoline
31643197
///
31653198
/// 为指定函数创建一个用于构建闭包的跳板函数

src/ast/ctx.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,10 @@ impl<'a, 'ctx> Ctx<'a> {
350350
disable_diag: false,
351351
}
352352
}
353+
354+
/// # new_child
355+
///
356+
/// it creates a new context inherited to the current context
353357
pub fn new_child(&'a self, start: Pos, builder: &'a BuilderEnum<'a, 'ctx>) -> Ctx<'a> {
354358
let mut root = self.root;
355359
if self.parent.is_none() {
@@ -616,7 +620,7 @@ impl<'a, 'ctx> Ctx<'a> {
616620
self.get_symbol_parent(name, builder, reference)
617621
}
618622

619-
/// # get_symbol in parent ctx
623+
/// # get_symbol_parent
620624
///
621625
/// search in all parent symbol tables
622626
pub fn get_symbol_parent<'b>(
@@ -972,6 +976,10 @@ impl<'a, 'ctx> Ctx<'a> {
972976
m
973977
}
974978

979+
/// # protect_generic_context
980+
///
981+
/// it appends the generic maps into the current context, processes the funciton f,
982+
/// and restores context generic types to its original value.
975983
pub fn protect_generic_context<'b, T, F: FnMut(&mut Ctx<'a>) -> T>(
976984
&mut self,
977985
generic_map: &IndexMap<String, Arc<RefCell<PLType>>>,
@@ -986,31 +994,35 @@ impl<'a, 'ctx> Ctx<'a> {
986994
res
987995
}
988996

997+
/// # run_in_type_mod
998+
///
999+
/// it executes the function f under the module of the custom_type
1000+
/// to ensure all the references could be found correctly.
9891001
pub fn run_in_type_mod<'b, TP: CustomType, R, F: FnMut(&mut Ctx<'a>, &TP) -> R>(
9901002
&'b mut self,
991-
u: &TP,
1003+
custom_type: &TP,
9921004
mut f: F,
9931005
) -> R {
994-
if u.get_path() != self.plmod.path && !u.get_path().is_empty() {
1006+
if custom_type.get_path() != self.plmod.path && !custom_type.get_path().is_empty() {
9951007
let ori_mod = unsafe { &*self.origin_mod as &Mod };
996-
let m = if u.get_path() == ori_mod.path {
1008+
let m = if custom_type.get_path() == ori_mod.path {
9971009
ori_mod.clone()
9981010
} else {
999-
self.db.get_module(&u.get_path()).unwrap()
1011+
self.db.get_module(&custom_type.get_path()).unwrap()
10001012
};
10011013
let oldm = self.set_mod(m);
10021014
let origin = self.origin_mod as isize == &self.plmod as *const Mod as isize;
10031015
if origin {
10041016
self.origin_mod = &oldm as *const Mod;
10051017
}
1006-
let res = f(self, u);
1018+
let res = f(self, custom_type);
10071019
self.set_mod(oldm);
10081020
if origin {
10091021
self.origin_mod = &self.plmod as *const Mod;
10101022
}
10111023
res
10121024
} else {
1013-
f(self, u)
1025+
f(self, custom_type)
10141026
}
10151027
}
10161028

@@ -1166,6 +1178,11 @@ impl<'a, 'ctx> Ctx<'a> {
11661178
Some(s)
11671179
}
11681180

1181+
/// # try_set_closure_alloca_bb
1182+
///
1183+
/// it tries to add the closure allocated block into the current context
1184+
/// if the respective closure captured exists.
1185+
/// Otherwise, it tries to add this block to its parent context
11691186
pub fn try_set_closure_alloca_bb(&self, bb: BlockHandle) {
11701187
if let Some(c) = &self.closure_data {
11711188
c.borrow_mut().alloca_bb = Some(bb);

src/ast/macros.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ macro_rules! generic_impl {
3939
($($args:ident),*) => (
4040
$(
4141
impl $args {
42+
/// # need_gen_code
43+
///
44+
/// need_gen_code reports whether it requires to generate code for generic
45+
/// by check whether the generic_map is empty or not
4246
pub fn need_gen_code(&self) -> bool {
4347
if self.generic_map.is_empty() {
4448
return false;

0 commit comments

Comments
 (0)