forked from M-Labs/nac3
nac3core: function codegen callback changes
Added code generator argument to the callback, so it would be easier to write complicated codegen with that callback. To prepare for RPC codegen.escape-analysis
parent
ffe89eec86
commit
050c862c1a
|
@ -371,13 +371,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some(callback) = codegen_callback {
|
if let Some(callback) = codegen_callback {
|
||||||
// TODO: Change signature
|
return callback.run(ctx, obj, fun, params, generator);
|
||||||
let obj = obj.map(|(t, v)| (t, v.to_basic_value_enum(ctx, generator)));
|
|
||||||
let params = params
|
|
||||||
.into_iter()
|
|
||||||
.map(|(name, val)| (name, val.to_basic_value_enum(ctx, generator)))
|
|
||||||
.collect();
|
|
||||||
return callback.run(ctx, obj, fun, params);
|
|
||||||
}
|
}
|
||||||
let old_key = ctx.get_subst_key(obj.as_ref().map(|a| a.0), fun.0, None);
|
let old_key = ctx.get_subst_key(obj.as_ref().map(|a| a.0), fun.0, None);
|
||||||
let mut keys = fun.0.args.clone();
|
let mut keys = fun.0.args.clone();
|
||||||
|
@ -431,7 +425,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
||||||
};
|
};
|
||||||
param_vals = real_params
|
param_vals = real_params
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|p| p.to_basic_value_enum(ctx, generator).into())
|
.map(|p| p.to_basic_value_enum(ctx, generator))
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
instance_to_symbol.get(&key).cloned()
|
instance_to_symbol.get(&key).cloned()
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,13 +62,13 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, fun, args| {
|
|ctx, _, fun, args, generator| {
|
||||||
let int32 = ctx.primitives.int32;
|
let int32 = ctx.primitives.int32;
|
||||||
let int64 = ctx.primitives.int64;
|
let int64 = ctx.primitives.int64;
|
||||||
let float = ctx.primitives.float;
|
let float = ctx.primitives.float;
|
||||||
let boolean = ctx.primitives.bool;
|
let boolean = ctx.primitives.bool;
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
if ctx.unifier.unioned(arg_ty, boolean) {
|
if ctx.unifier.unioned(arg_ty, boolean) {
|
||||||
Some(
|
Some(
|
||||||
ctx.builder
|
ctx.builder
|
||||||
|
@ -120,13 +120,13 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, fun, args| {
|
|ctx, _, fun, args, generator| {
|
||||||
let int32 = ctx.primitives.int32;
|
let int32 = ctx.primitives.int32;
|
||||||
let int64 = ctx.primitives.int64;
|
let int64 = ctx.primitives.int64;
|
||||||
let float = ctx.primitives.float;
|
let float = ctx.primitives.float;
|
||||||
let boolean = ctx.primitives.bool;
|
let boolean = ctx.primitives.bool;
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
if ctx.unifier.unioned(arg_ty, boolean)
|
if ctx.unifier.unioned(arg_ty, boolean)
|
||||||
|| ctx.unifier.unioned(arg_ty, int32)
|
|| ctx.unifier.unioned(arg_ty, int32)
|
||||||
{
|
{
|
||||||
|
@ -170,18 +170,18 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, fun, args| {
|
|ctx, _, fun, args, generator| {
|
||||||
let int32 = ctx.primitives.int32;
|
let int32 = ctx.primitives.int32;
|
||||||
let int64 = ctx.primitives.int64;
|
let int64 = ctx.primitives.int64;
|
||||||
let boolean = ctx.primitives.bool;
|
let boolean = ctx.primitives.bool;
|
||||||
let float = ctx.primitives.float;
|
let float = ctx.primitives.float;
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
if ctx.unifier.unioned(arg_ty, boolean)
|
if ctx.unifier.unioned(arg_ty, boolean)
|
||||||
|| ctx.unifier.unioned(arg_ty, int32)
|
|| ctx.unifier.unioned(arg_ty, int32)
|
||||||
|| ctx.unifier.unioned(arg_ty, int64)
|
|| ctx.unifier.unioned(arg_ty, int64)
|
||||||
{
|
{
|
||||||
let arg = args[0].1.into_int_value();
|
let arg = arg.into_int_value();
|
||||||
let val = ctx
|
let val = ctx
|
||||||
.builder
|
.builder
|
||||||
.build_signed_int_to_float(arg, ctx.ctx.f64_type(), "sitofp")
|
.build_signed_int_to_float(arg, ctx.ctx.f64_type(), "sitofp")
|
||||||
|
@ -207,8 +207,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_symbol: Default::default(),
|
instance_to_symbol: Default::default(),
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| {
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
let round_intrinsic =
|
let round_intrinsic =
|
||||||
ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
|
@ -244,8 +244,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_symbol: Default::default(),
|
instance_to_symbol: Default::default(),
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| {
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
let round_intrinsic =
|
let round_intrinsic =
|
||||||
ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
|
@ -294,7 +294,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_symbol: Default::default(),
|
instance_to_symbol: Default::default(),
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| {
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| {
|
||||||
let mut start = None;
|
let mut start = None;
|
||||||
let mut stop = None;
|
let mut stop = None;
|
||||||
let mut step = None;
|
let mut step = None;
|
||||||
|
@ -302,17 +302,17 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
let zero = int32.const_zero();
|
let zero = int32.const_zero();
|
||||||
for (i, arg) in args.iter().enumerate() {
|
for (i, arg) in args.iter().enumerate() {
|
||||||
if arg.0 == Some("start".into()) {
|
if arg.0 == Some("start".into()) {
|
||||||
start = Some(arg.1);
|
start = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
||||||
} else if arg.0 == Some("stop".into()) {
|
} else if arg.0 == Some("stop".into()) {
|
||||||
stop = Some(arg.1);
|
stop = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
||||||
} else if arg.0 == Some("step".into()) {
|
} else if arg.0 == Some("step".into()) {
|
||||||
step = Some(arg.1);
|
step = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
||||||
} else if i == 0 {
|
} else if i == 0 {
|
||||||
start = Some(arg.1);
|
start = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
||||||
} else if i == 1 {
|
} else if i == 1 {
|
||||||
stop = Some(arg.1);
|
stop = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
||||||
} else if i == 2 {
|
} else if i == 2 {
|
||||||
step = Some(arg.1);
|
step = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: error when step == 0
|
// TODO: error when step == 0
|
||||||
|
@ -356,8 +356,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_symbol: Default::default(),
|
instance_to_symbol: Default::default(),
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|_, _, _, args| {
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| {
|
||||||
Some(args[0].1)
|
Some(args[0].1.clone().to_basic_value_enum(ctx, generator))
|
||||||
})))),
|
})))),
|
||||||
})),
|
})),
|
||||||
Arc::new(RwLock::new(TopLevelDef::Function {
|
Arc::new(RwLock::new(TopLevelDef::Function {
|
||||||
|
@ -373,13 +373,13 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, fun, args| {
|
|ctx, _, fun, args, generator| {
|
||||||
let int32 = ctx.primitives.int32;
|
let int32 = ctx.primitives.int32;
|
||||||
let int64 = ctx.primitives.int64;
|
let int64 = ctx.primitives.int64;
|
||||||
let float = ctx.primitives.float;
|
let float = ctx.primitives.float;
|
||||||
let boolean = ctx.primitives.bool;
|
let boolean = ctx.primitives.bool;
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
if ctx.unifier.unioned(arg_ty, boolean) {
|
if ctx.unifier.unioned(arg_ty, boolean) {
|
||||||
Some(arg)
|
Some(arg)
|
||||||
} else if ctx.unifier.unioned(arg_ty, int32) {
|
} else if ctx.unifier.unioned(arg_ty, int32) {
|
||||||
|
@ -424,8 +424,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_symbol: Default::default(),
|
instance_to_symbol: Default::default(),
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| {
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
let floor_intrinsic =
|
let floor_intrinsic =
|
||||||
ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
|
@ -461,8 +461,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_symbol: Default::default(),
|
instance_to_symbol: Default::default(),
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| {
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
let floor_intrinsic =
|
let floor_intrinsic =
|
||||||
ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
|
@ -498,8 +498,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_symbol: Default::default(),
|
instance_to_symbol: Default::default(),
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| {
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
let ceil_intrinsic =
|
let ceil_intrinsic =
|
||||||
ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
|
@ -535,8 +535,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_symbol: Default::default(),
|
instance_to_symbol: Default::default(),
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| {
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
let ceil_intrinsic =
|
let ceil_intrinsic =
|
||||||
ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
|
@ -581,10 +581,10 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
||||||
instance_to_stmt: Default::default(),
|
instance_to_stmt: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, fun, args| {
|
|ctx, _, fun, args, generator| {
|
||||||
let range_ty = ctx.primitives.range;
|
let range_ty = ctx.primitives.range;
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
||||||
if ctx.unifier.unioned(arg_ty, range_ty) {
|
if ctx.unifier.unioned(arg_ty, range_ty) {
|
||||||
let arg = arg.into_pointer_value();
|
let arg = arg.into_pointer_value();
|
||||||
let (start, end, step) = destructure_range(ctx, arg);
|
let (start, end, step) = destructure_range(ctx, arg);
|
||||||
|
|
|
@ -11,20 +11,21 @@ use super::codegen::CodeGenContext;
|
||||||
use super::typecheck::type_inferencer::PrimitiveStore;
|
use super::typecheck::type_inferencer::PrimitiveStore;
|
||||||
use super::typecheck::typedef::{FunSignature, FuncArg, SharedUnifier, Type, TypeEnum, Unifier};
|
use super::typecheck::typedef::{FunSignature, FuncArg, SharedUnifier, Type, TypeEnum, Unifier};
|
||||||
use crate::{
|
use crate::{
|
||||||
symbol_resolver::SymbolResolver,
|
codegen::CodeGenerator,
|
||||||
|
symbol_resolver::{SymbolResolver, ValueEnum},
|
||||||
typecheck::{type_inferencer::CodeLocation, typedef::CallId},
|
typecheck::{type_inferencer::CodeLocation, typedef::CallId},
|
||||||
};
|
};
|
||||||
use itertools::{izip, Itertools};
|
|
||||||
use parking_lot::RwLock;
|
|
||||||
use nac3parser::ast::{self, Stmt, StrRef};
|
|
||||||
use inkwell::values::BasicValueEnum;
|
use inkwell::values::BasicValueEnum;
|
||||||
|
use itertools::{izip, Itertools};
|
||||||
|
use nac3parser::ast::{self, Stmt, StrRef};
|
||||||
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
|
||||||
pub struct DefinitionId(pub usize);
|
pub struct DefinitionId(pub usize);
|
||||||
|
|
||||||
|
pub mod builtins;
|
||||||
pub mod composer;
|
pub mod composer;
|
||||||
pub mod helper;
|
pub mod helper;
|
||||||
pub mod builtins;
|
|
||||||
pub mod type_annotation;
|
pub mod type_annotation;
|
||||||
use composer::*;
|
use composer::*;
|
||||||
use type_annotation::*;
|
use type_annotation::*;
|
||||||
|
@ -34,9 +35,10 @@ mod test;
|
||||||
type GenCallCallback = Box<
|
type GenCallCallback = Box<
|
||||||
dyn for<'ctx, 'a> Fn(
|
dyn for<'ctx, 'a> Fn(
|
||||||
&mut CodeGenContext<'ctx, 'a>,
|
&mut CodeGenContext<'ctx, 'a>,
|
||||||
Option<(Type, BasicValueEnum)>,
|
Option<(Type, ValueEnum<'ctx>)>,
|
||||||
(&FunSignature, DefinitionId),
|
(&FunSignature, DefinitionId),
|
||||||
Vec<(Option<StrRef>, BasicValueEnum<'ctx>)>,
|
Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||||
|
&mut dyn CodeGenerator,
|
||||||
) -> Option<BasicValueEnum<'ctx>>
|
) -> Option<BasicValueEnum<'ctx>>
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync,
|
+ Sync,
|
||||||
|
@ -54,11 +56,12 @@ impl GenCall {
|
||||||
pub fn run<'ctx, 'a>(
|
pub fn run<'ctx, 'a>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
obj: Option<(Type, BasicValueEnum<'ctx>)>,
|
obj: Option<(Type, ValueEnum<'ctx>)>,
|
||||||
fun: (&FunSignature, DefinitionId),
|
fun: (&FunSignature, DefinitionId),
|
||||||
args: Vec<(Option<StrRef>, BasicValueEnum<'ctx>)>,
|
args: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||||
|
generator: &mut dyn CodeGenerator,
|
||||||
) -> Option<BasicValueEnum<'ctx>> {
|
) -> Option<BasicValueEnum<'ctx>> {
|
||||||
(self.fp)(ctx, obj, fun, args)
|
(self.fp)(ctx, obj, fun, args, generator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +123,7 @@ pub enum TopLevelDef {
|
||||||
// symbol resolver of the module defined the class
|
// symbol resolver of the module defined the class
|
||||||
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
|
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
|
||||||
// custom codegen callback
|
// custom codegen callback
|
||||||
codegen_callback: Option<Arc<GenCall>>
|
codegen_callback: Option<Arc<GenCall>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue