Merge pull request #967 from ethcore/ipc-codegen-upgrades

IPC codegen - some minor fixes & enhancements
This commit is contained in:
Arkadiy Paronyan 2016-04-18 12:55:10 +02:00
commit 5aa54e0c1a
2 changed files with 60 additions and 25 deletions

View File

@ -110,27 +110,27 @@ fn push_invoke_signature_aster(
let mut arg_tys = Vec::new(); let mut arg_tys = Vec::new();
let arg_name = format!("{}", field_name(builder, &inputs[skip-1]).name); let arg_name = format!("{}", field_name(builder, &inputs[skip-1]).name);
let arg_ty = inputs[skip-1].ty.clone(); let arg_ty = &inputs[skip-1].ty;
let mut tree = builder.item() let mut tree = builder.item()
.attr().word("derive(Serialize, Deserialize)") .attr().word("derive(Serialize, Deserialize)")
.attr().word("allow(non_camel_case_types)") .attr().word("allow(non_camel_case_types)")
.struct_(name_str.as_str()) .struct_(name_str.as_str())
.field(arg_name.as_str()).ty() .field(arg_name.as_str()).ty()
.build(typegen::argument_replacement(builder, replacements, &arg_ty).unwrap_or(arg_ty.clone())); .build(typegen::argument_replacement(builder, replacements, arg_ty)
.unwrap_or(strip_ptr(arg_ty)));
arg_names.push(arg_name); arg_names.push(arg_name);
arg_tys.push(arg_ty); arg_tys.push(arg_ty.clone());
for arg in inputs.iter().skip(skip) { for arg in inputs.iter().skip(skip) {
let arg_name = format!("{}", field_name(builder, &arg)); let arg_name = format!("{}", field_name(builder, &arg));
let arg_ty = &arg.ty;
let mut arg_ty = arg.ty.clone(); tree = tree.field(arg_name.as_str()).ty().build(
arg_ty = typegen::argument_replacement(builder, replacements, &arg_ty).unwrap_or(arg_ty); typegen::argument_replacement(builder, replacements, arg_ty).unwrap_or(strip_ptr(arg_ty))
);
tree = tree.field(arg_name.as_str()).ty()
.build(typegen::argument_replacement(builder, replacements, &arg_ty).unwrap_or(arg_ty.clone()));
arg_names.push(arg_name); arg_names.push(arg_name);
arg_tys.push(arg_ty); arg_tys.push(arg_ty.clone());
} }
push(Annotatable::Item(tree.build())); push(Annotatable::Item(tree.build()));
@ -191,12 +191,15 @@ fn implement_dispatch_arm_invoke_stmt(
let input_args_exprs = dispatch.input_arg_names.iter().enumerate().map(|(arg_index, arg_name)| { let input_args_exprs = dispatch.input_arg_names.iter().enumerate().map(|(arg_index, arg_name)| {
let arg_ident = builder.id(arg_name); let arg_ident = builder.id(arg_name);
if typegen::argument_replacement(builder, replacements, &dispatch.input_arg_tys[arg_index]).is_some() { let expr = if typegen::argument_replacement(builder, replacements, &dispatch.input_arg_tys[arg_index]).is_some() {
quote_expr!(cx, input. $arg_ident .into()) quote_expr!(cx, input. $arg_ident .into())
} }
else { else {
quote_expr!(cx, input. $arg_ident) quote_expr!(cx, input. $arg_ident)
} };
if has_ptr(&dispatch.input_arg_tys[arg_index]) { quote_expr!(cx, & $expr) }
else { expr }
}).collect::<Vec<P<ast::Expr>>>(); }).collect::<Vec<P<ast::Expr>>>();
let ext_cx = &*cx; let ext_cx = &*cx;
@ -257,13 +260,14 @@ fn implement_dispatch_arm_invoke(
quote_expr!(cx, ::bincode::serde::deserialize_from(r, ::bincode::SizeLimit::Infinite).expect("ipc deserialization error, aborting")) quote_expr!(cx, ::bincode::serde::deserialize_from(r, ::bincode::SizeLimit::Infinite).expect("ipc deserialization error, aborting"))
}; };
let input_type_id = builder.id(dispatch.input_type_name.clone().unwrap().as_str());
let invoke_serialize_stmt = implement_dispatch_arm_invoke_stmt(cx, builder, dispatch, replacements); let invoke_serialize_stmt = implement_dispatch_arm_invoke_stmt(cx, builder, dispatch, replacements);
quote_expr!(cx, { dispatch.input_type_name.as_ref().map(|val| {
let input: $input_type_id = $deserialize_expr; let input_type_id = builder.id(val.clone().as_str());
$invoke_serialize_stmt quote_expr!(cx, {
}) let input: $input_type_id = $deserialize_expr;
$invoke_serialize_stmt
})
}).unwrap_or(quote_expr!(cx, { $invoke_serialize_stmt }))
} }
/// generates dispatch match for method id /// generates dispatch match for method id
@ -294,6 +298,20 @@ fn implement_dispatch_arms(
.map(|dispatch| { index = index + 1; implement_dispatch_arm(cx, builder, index as u32, dispatch, buffer, replacements) }).collect() .map(|dispatch| { index = index + 1; implement_dispatch_arm(cx, builder, index as u32, dispatch, buffer, replacements) }).collect()
} }
fn strip_ptr(ty: &P<ast::Ty>) -> P<ast::Ty> {
if let ast::TyKind::Rptr(_, ref ptr_mut) = ty.node {
ptr_mut.ty.clone()
}
else { ty.clone() }
}
fn has_ptr(ty: &P<ast::Ty>) -> bool {
if let ast::TyKind::Rptr(_, ref ptr_mut) = ty.node {
true
}
else { false }
}
/// returns an expression with the body for single operation that is being sent to server /// returns an expression with the body for single operation that is being sent to server
/// operation itself serializes input, writes to socket and waits for socket to respond /// operation itself serializes input, writes to socket and waits for socket to respond
/// (the latter only if original method signature returns anyting) /// (the latter only if original method signature returns anyting)
@ -321,15 +339,17 @@ fn implement_client_method_body(
) -> P<ast::Expr> ) -> P<ast::Expr>
{ {
let dispatch = &interface_map.dispatches[index as usize]; let dispatch = &interface_map.dispatches[index as usize];
let index_ident = builder.id(format!("{}", index + RESERVED_MESSAGE_IDS).as_str());
let request = if dispatch.input_arg_names.len() > 0 { let request = if dispatch.input_arg_names.len() > 0 {
let arg_name = dispatch.input_arg_names[0].as_str(); let arg_name = dispatch.input_arg_names[0].as_str();
let static_ty = &dispatch.input_arg_tys[0]; let static_ty = strip_ptr(&dispatch.input_arg_tys[0]);
let arg_ty = builder let arg_ty = builder
.ty().ref_() .ty().ref_()
.lifetime("'a") .lifetime("'a")
.ty() .ty()
.build(typegen::argument_replacement(builder, &interface_map.replacements, static_ty).unwrap_or(static_ty.clone())); .build(typegen::argument_replacement(builder, &interface_map.replacements, &static_ty).unwrap_or(static_ty.clone()));
let mut tree = builder.item() let mut tree = builder.item()
.attr().word("derive(Serialize)") .attr().word("derive(Serialize)")
@ -342,12 +362,13 @@ fn implement_client_method_body(
for arg_idx in 1..dispatch.input_arg_names.len() { for arg_idx in 1..dispatch.input_arg_names.len() {
let arg_name = dispatch.input_arg_names[arg_idx].as_str(); let arg_name = dispatch.input_arg_names[arg_idx].as_str();
let static_ty = &dispatch.input_arg_tys[arg_idx]; let static_ty = strip_ptr(&dispatch.input_arg_tys[arg_idx]);
let arg_ty = builder let arg_ty = builder
.ty().ref_() .ty().ref_()
.lifetime("'a") .lifetime("'a")
.ty() .ty()
.build(typegen::argument_replacement(builder, &interface_map.replacements, static_ty).unwrap_or(static_ty.clone())); .build(typegen::argument_replacement(builder, &interface_map.replacements, &static_ty).unwrap_or(static_ty));
tree = tree.field(arg_name).ty().build(arg_ty); tree = tree.field(arg_name).ty().build(arg_ty);
} }
@ -413,8 +434,6 @@ fn implement_client_method_body(
request_serialization_statements.push( request_serialization_statements.push(
quote_stmt!(cx, let serialized_payload = ::bincode::serde::serialize(&payload, ::bincode::SizeLimit::Infinite).unwrap())); quote_stmt!(cx, let serialized_payload = ::bincode::serde::serialize(&payload, ::bincode::SizeLimit::Infinite).unwrap()));
let index_ident = builder.id(format!("{}", index + RESERVED_MESSAGE_IDS).as_str());
request_serialization_statements.push( request_serialization_statements.push(
quote_stmt!(cx, ::ipc::invoke($index_ident, &Some(serialized_payload), &mut socket))); quote_stmt!(cx, ::ipc::invoke($index_ident, &Some(serialized_payload), &mut socket)));
@ -422,7 +441,14 @@ fn implement_client_method_body(
request_serialization_statements request_serialization_statements
} }
else { else {
vec![] let mut request_serialization_statements = Vec::new();
request_serialization_statements.push(
quote_stmt!(cx, let mut socket_ref = self.socket.borrow_mut()));
request_serialization_statements.push(
quote_stmt!(cx, let mut socket = socket_ref.deref_mut()));
request_serialization_statements.push(
quote_stmt!(cx, ::ipc::invoke($index_ident, Vec::new(), &mut socket)));
request_serialization_statements
}; };
if let Some(ref return_ty) = dispatch.return_type_ty { if let Some(ref return_ty) = dispatch.return_type_ty {

View File

@ -46,7 +46,11 @@ fn is_new_entry(path: &Path) -> Option<String> {
ident == "i32" || ident == "i32" ||
ident == "i64" || ident == "i64" ||
ident == "String" || ident == "String" ||
ident == "bool" ident == "bool" ||
ident == "H256" ||
ident == "U256" ||
ident == "H2048" ||
ident == "Address"
} }
}; };
@ -202,6 +206,11 @@ pub fn match_unknown_tys(
fringe.push(nested_ty); fringe.push(nested_ty);
} }
}, },
TyKind::Rptr(_, ref nested_ty) => {
if !stop_list.contains(&nested_ty.ty) {
fringe.push(&nested_ty.ty);
}
},
TyKind::Path(_, ref path) => { TyKind::Path(_, ref path) => {
if path.segments.len() > 0 && { if path.segments.len() > 0 && {
let first_segment = path.segments[0].identifier.name.as_str(); let first_segment = path.segments[0].identifier.name.as_str();