diff --git a/nac3artiq/src/codegen.rs b/nac3artiq/src/codegen.rs index 72b55aa7..77b1fd98 100644 --- a/nac3artiq/src/codegen.rs +++ b/nac3artiq/src/codegen.rs @@ -12,7 +12,7 @@ use nac3core::{ }, symbol_resolver::ValueEnum, toplevel::{helper::PrimDef, numpy::unpack_ndarray_var_tys, DefinitionId, GenCall}, - typecheck::typedef::{iter_type_vars, FunSignature, FuncArg, Type, TypeEnum, VarMap}, + typecheck::typedef::{iter_type_vars, FunSignature, FuncOption, FuncArg, Type, TypeEnum, VarMap}, }; use nac3parser::ast::{Expr, ExprKind, Located, Stmt, StmtKind, StrRef}; @@ -831,8 +831,6 @@ fn rpc_codegen_callback_fn<'ctx>( let ptr_type = int8.ptr_type(AddressSpace::default()); let tag_ptr_type = ctx.ctx.struct_type(&[ptr_type.into(), size_type.into()], false); - // println!("obj: {:?}", obj); - println!("fun: {:?}", fun); let service_id = int32.const_int(fun.1 .0 as u64, false); // -- setup rpc tags @@ -934,36 +932,63 @@ fn rpc_codegen_callback_fn<'ctx>( ctx.builder.build_store(arg_ptr, arg_slot).unwrap(); } + let is_async = fun.0.opts.iter().any(|opt| FuncOption::Async == *opt); + // call - let rpc_send = ctx.module.get_function("rpc_send").unwrap_or_else(|| { - ctx.module.add_function( - "rpc_send", - ctx.ctx.void_type().fn_type( - &[ - int32.into(), - tag_ptr_type.ptr_type(AddressSpace::default()).into(), - ptr_type.ptr_type(AddressSpace::default()).into(), - ], - false, - ), - None, - ) - }); - ctx.builder - .build_call(rpc_send, &[service_id.into(), tag_ptr.into(), args_ptr.into()], "rpc.send") - .unwrap(); + if is_async { + let rpc_send_async = ctx.module.get_function("rpc_send_async").unwrap_or_else(|| { + ctx.module.add_function( + "rpc_send_async", + ctx.ctx.void_type().fn_type( + &[ + int32.into(), + tag_ptr_type.ptr_type(AddressSpace::default()).into(), + ptr_type.ptr_type(AddressSpace::default()).into(), + ], + false, + ), + None, + ) + }); + ctx.builder + .build_call(rpc_send_async, &[service_id.into(), tag_ptr.into(), args_ptr.into()], "rpc.send") + .unwrap(); + } else { + let rpc_send = ctx.module.get_function("rpc_send").unwrap_or_else(|| { + ctx.module.add_function( + "rpc_send", + ctx.ctx.void_type().fn_type( + &[ + int32.into(), + tag_ptr_type.ptr_type(AddressSpace::default()).into(), + ptr_type.ptr_type(AddressSpace::default()).into(), + ], + false, + ), + None, + ) + }); + ctx.builder + .build_call(rpc_send, &[service_id.into(), tag_ptr.into(), args_ptr.into()], "rpc.send") + .unwrap(); + } // reclaim stack space used by arguments call_stackrestore(ctx, stackptr); - let result = format_rpc_ret(generator, ctx, fun.0.ret); - - if !result.is_some_and(|res| res.get_type().is_pointer_type()) { - // An RPC returning an NDArray would not touch here. - call_stackrestore(ctx, stackptr); + if is_async { + // async RPCs do not return any values + Ok(None) + } else { + let result = format_rpc_ret(generator, ctx, fun.0.ret); + + if !result.is_some_and(|res| res.get_type().is_pointer_type()) { + // An RPC returning an NDArray would not touch here. + call_stackrestore(ctx, stackptr); + } + + Ok(result) } - - Ok(result) } pub fn attributes_writeback( diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 5f8463f9..c22990a1 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -54,7 +54,7 @@ use nac3core::{ composer::{BuiltinFuncCreator, BuiltinFuncSpec, ComposerConfig, TopLevelComposer}, DefinitionId, GenCall, TopLevelDef, }, - typecheck::typedef::{FunSignature, FuncArg}, + typecheck::typedef::{FunSignature, FuncOption, FuncArg}, typecheck::{type_inferencer::PrimitiveStore, typedef::Type}, }; @@ -200,7 +200,7 @@ impl Nac3 { || id.to_string() == "rpc" } else if let ExprKind::Call { func, .. } = &decorator.node { // decorators with flags (e.g. rpc async) have Call for the node; - // this is to remove the middle + // this is to remove the middle part if let ExprKind::Name { id, .. } = func.node { if id.to_string() == "rpc" { println!("found rpc: {:?}", func); @@ -513,7 +513,7 @@ impl Nac3 { class_name, stmt.location ))); } - rpc_ids.push((Some((class_obj.clone(), *name)), def_id, Some(FuncFlags::Async))); + rpc_ids.push((Some((class_obj.clone(), *name)), def_id)); } } } @@ -616,7 +616,7 @@ impl Nac3 { { let rpc_codegen = rpc_codegen_callback(); let defs = top_level.definitions.read(); - for (class_data, id, flags) in &rpc_ids { + for (class_data, id) in &rpc_ids { let mut def = defs[id.0].write(); match &mut *def { TopLevelDef::Function { codegen_callback, .. } => { diff --git a/nac3core/src/typecheck/typedef/mod.rs b/nac3core/src/typecheck/typedef/mod.rs index dcb331ae..8837da86 100644 --- a/nac3core/src/typecheck/typedef/mod.rs +++ b/nac3core/src/typecheck/typedef/mod.rs @@ -123,8 +123,8 @@ impl FuncArg { } } -#[derive(Debug, Clone)] -pub enum FunOption { +#[derive(PartialEq, Debug, Clone)] +pub enum FuncOption { Async, } @@ -133,7 +133,7 @@ pub struct FunSignature { pub args: Vec, pub ret: Type, pub vars: VarMap, - pub opts: Vec, + pub opts: Vec, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]