forked from M-Labs/nac3
artiq: get decorator flags, check if rpc is async
This commit is contained in:
parent
2f7799c978
commit
733dc218d0
@ -824,6 +824,7 @@ fn rpc_codegen_callback_fn<'ctx>(
|
||||
fun: (&FunSignature, DefinitionId),
|
||||
args: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||
generator: &mut dyn CodeGenerator,
|
||||
is_async: bool,
|
||||
) -> Result<Option<BasicValueEnum<'ctx>>, String> {
|
||||
let int8 = ctx.ctx.i8_type();
|
||||
let int32 = ctx.ctx.i32_type();
|
||||
@ -932,8 +933,6 @@ fn rpc_codegen_callback_fn<'ctx>(
|
||||
ctx.builder.build_store(arg_ptr, arg_slot).unwrap();
|
||||
}
|
||||
|
||||
let is_async = false; // fun.0.opts.iter().any(|opt| FuncOption::Async == *opt);
|
||||
|
||||
// call
|
||||
if is_async {
|
||||
let rpc_send_async = ctx.module.get_function("rpc_send_async").unwrap_or_else(|| {
|
||||
@ -1083,7 +1082,7 @@ pub fn attributes_writeback(
|
||||
let args: Vec<_> =
|
||||
values.into_iter().map(|(_, val)| (None, ValueEnum::Dynamic(val))).collect();
|
||||
if let Err(e) =
|
||||
rpc_codegen_callback_fn(ctx, None, (&fun, PrimDef::Int32.id()), args, generator)
|
||||
rpc_codegen_callback_fn(ctx, None, (&fun, PrimDef::Int32.id()), args, generator, false)
|
||||
{
|
||||
return Ok(Err(e));
|
||||
}
|
||||
@ -1093,9 +1092,9 @@ pub fn attributes_writeback(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn rpc_codegen_callback() -> Arc<GenCall> {
|
||||
Arc::new(GenCall::new(Box::new(|ctx, obj, fun, args, generator| {
|
||||
rpc_codegen_callback_fn(ctx, obj, fun, args, generator)
|
||||
pub fn rpc_codegen_callback(is_async: bool) -> Arc<GenCall> {
|
||||
Arc::new(GenCall::new(Box::new(move |ctx, obj, fun, args, generator| {
|
||||
rpc_codegen_callback_fn(ctx, obj, fun, args, generator, is_async)
|
||||
})))
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ use nac3core::codegen::{gen_func_impl, CodeGenLLVMOptions, CodeGenTargetMachineO
|
||||
use nac3core::toplevel::builtins::get_exn_constructor;
|
||||
use nac3core::typecheck::typedef::{into_var_map, TypeEnum, Unifier, VarMap};
|
||||
use nac3parser::{
|
||||
ast::{ExprKind, Located, Stmt, StmtKind, StrRef},
|
||||
ast::{Constant, ExprKind, Located, Stmt, StmtKind, StrRef},
|
||||
parser::parse_program,
|
||||
};
|
||||
use pyo3::create_exception;
|
||||
@ -54,7 +54,7 @@ use nac3core::{
|
||||
composer::{BuiltinFuncCreator, BuiltinFuncSpec, ComposerConfig, TopLevelComposer},
|
||||
DefinitionId, GenCall, TopLevelDef,
|
||||
},
|
||||
typecheck::typedef::{FunSignature, FuncOption, FuncArg},
|
||||
typecheck::typedef::{FunSignature, FuncArg},
|
||||
typecheck::{type_inferencer::PrimitiveStore, typedef::Type},
|
||||
};
|
||||
|
||||
@ -477,7 +477,11 @@ impl Nac3 {
|
||||
StmtKind::FunctionDef { decorator_list, .. } => {
|
||||
if decorator_list.iter().any(|decorator| decorator_id_string(decorator) == Some("rpc".to_string())) {
|
||||
store_fun.call1(py, (def_id.0.into_py(py), module.getattr(py, name.to_string().as_str()).unwrap())).unwrap();
|
||||
rpc_ids.push((None, def_id));
|
||||
let is_async = decorator_list.iter().any(
|
||||
|decorator| decorator_get_flags(decorator).iter().any(
|
||||
|constant| *constant == Constant::Str("async".into())
|
||||
));
|
||||
rpc_ids.push((None, def_id, is_async));
|
||||
}
|
||||
}
|
||||
StmtKind::ClassDef { name, body, .. } => {
|
||||
@ -486,13 +490,17 @@ impl Nac3 {
|
||||
for stmt in body {
|
||||
if let StmtKind::FunctionDef { name, decorator_list, .. } = &stmt.node {
|
||||
if decorator_list.iter().any(|decorator| decorator_id_string(decorator) == Some("rpc".to_string())) {
|
||||
let is_async = decorator_list.iter().any(
|
||||
|decorator| decorator_get_flags(decorator).iter().any(
|
||||
|constant| *constant == Constant::Str("async".into())
|
||||
));
|
||||
if name == &"__init__".into() {
|
||||
return Err(CompileError::new_err(format!(
|
||||
"compilation failed\n----------\nThe constructor of class {} should not be decorated with rpc decorator (at {})",
|
||||
class_name, stmt.location
|
||||
)));
|
||||
}
|
||||
rpc_ids.push((Some((class_obj.clone(), *name)), def_id));
|
||||
rpc_ids.push((Some((class_obj.clone(), *name)), def_id, is_async));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -593,13 +601,12 @@ impl Nac3 {
|
||||
let top_level = Arc::new(composer.make_top_level_context());
|
||||
|
||||
{
|
||||
let rpc_codegen = rpc_codegen_callback();
|
||||
let defs = top_level.definitions.read();
|
||||
for (class_data, id) in &rpc_ids {
|
||||
for (class_data, id, is_async) in &rpc_ids {
|
||||
let mut def = defs[id.0].write();
|
||||
match &mut *def {
|
||||
TopLevelDef::Function { codegen_callback, .. } => {
|
||||
*codegen_callback = Some(rpc_codegen.clone());
|
||||
*codegen_callback = Some(rpc_codegen_callback(*is_async).clone());
|
||||
}
|
||||
TopLevelDef::Class { methods, .. } => {
|
||||
let (class_def, method_name) = class_data.as_ref().unwrap();
|
||||
@ -610,7 +617,7 @@ impl Nac3 {
|
||||
if let TopLevelDef::Function { codegen_callback, .. } =
|
||||
&mut *defs[id.0].write()
|
||||
{
|
||||
*codegen_callback = Some(rpc_codegen.clone());
|
||||
*codegen_callback = Some(rpc_codegen_callback(*is_async).clone());
|
||||
store_fun
|
||||
.call1(
|
||||
py,
|
||||
@ -854,6 +861,25 @@ fn decorator_id_string(decorator: &Located<ExprKind>) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
fn decorator_get_flags(decorator: &Located<ExprKind>) -> Vec<Constant> {
|
||||
let mut flags = vec![];
|
||||
if let ExprKind::Call { keywords, .. } = &decorator.node {
|
||||
for keyword in keywords.iter() {
|
||||
if keyword.node.arg != Some("flags".into()) {
|
||||
continue;
|
||||
}
|
||||
if let ExprKind::Set { elts } = &keyword.node.value.node {
|
||||
for elt in elts {
|
||||
if let ExprKind::Constant { value, .. } = &elt.node {
|
||||
flags.push(value.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
flags
|
||||
}
|
||||
|
||||
fn link_with_lld(elf_filename: String, obj_filename: String) -> PyResult<()> {
|
||||
let linker_args = vec![
|
||||
"-shared".to_string(),
|
||||
|
Loading…
Reference in New Issue
Block a user