struct with reference serialization

This commit is contained in:
Nikolay Volf 2016-04-22 16:37:22 +03:00
parent 04e704603f
commit c97cb5d665
4 changed files with 32 additions and 12 deletions

View File

@ -298,14 +298,14 @@ 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> { pub fn strip_ptr(ty: &P<ast::Ty>) -> P<ast::Ty> {
if let ast::TyKind::Rptr(_, ref ptr_mut) = ty.node { if let ast::TyKind::Rptr(_, ref ptr_mut) = ty.node {
ptr_mut.ty.clone() ptr_mut.ty.clone()
} }
else { ty.clone() } else { ty.clone() }
} }
fn has_ptr(ty: &P<ast::Ty>) -> bool { pub fn has_ptr(ty: &P<ast::Ty>) -> bool {
if let ast::TyKind::Rptr(_, ref ptr_mut) = ty.node { if let ast::TyKind::Rptr(_, ref ptr_mut) = ty.node {
true true
} }

View File

@ -29,6 +29,8 @@ use syntax::ptr::P;
pub struct Error; pub struct Error;
use super::codegen;
pub fn expand_serialization_implementation( pub fn expand_serialization_implementation(
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
span: Span, span: Span,
@ -162,7 +164,9 @@ fn binary_expr_struct(
) -> Result<BinaryExpressions, Error> { ) -> Result<BinaryExpressions, Error> {
let size_exprs: Vec<P<ast::Expr>> = fields.iter().enumerate().map(|(index, field)| { let size_exprs: Vec<P<ast::Expr>> = fields.iter().enumerate().map(|(index, field)| {
let field_type_ident = builder.id(&::syntax::print::pprust::ty_to_string(&field.ty)); let field_type_ident = builder.id(
&::syntax::print::pprust::ty_to_string(
&codegen::strip_ptr(&field.ty)));
let index_ident = builder.id(format!("__field{}", index)); let index_ident = builder.id(format!("__field{}", index));
value_ident.and_then(|x| { value_ident.and_then(|x| {
let field_id = builder.id(field.ident.unwrap()); let field_id = builder.id(field.ident.unwrap());
@ -193,7 +197,9 @@ fn binary_expr_struct(
map_stmts.push(quote_stmt!(cx, let mut map = vec![0usize; $field_amount];).unwrap()); map_stmts.push(quote_stmt!(cx, let mut map = vec![0usize; $field_amount];).unwrap());
map_stmts.push(quote_stmt!(cx, let mut total = 0usize;).unwrap()); map_stmts.push(quote_stmt!(cx, let mut total = 0usize;).unwrap());
for (index, field) in fields.iter().enumerate() { for (index, field) in fields.iter().enumerate() {
let field_type_ident = builder.id(&::syntax::print::pprust::ty_to_string(&field.ty)); let field_type_ident = builder.id(
&::syntax::print::pprust::ty_to_string(
&codegen::strip_ptr(&field.ty)));
let member_expr = match value_ident { let member_expr = match value_ident {
Some(x) => { Some(x) => {
@ -225,13 +231,21 @@ fn binary_expr_struct(
map_stmts.push(quote_stmt!(cx, total = total + size;).unwrap()); map_stmts.push(quote_stmt!(cx, total = total + size;).unwrap());
}; };
let read_expr = if value_ident.is_some() { let read_expr = match fields.iter().any(|f| codegen::has_ptr(&f.ty)) {
true => {
// cannot create structs with pointers
quote_expr!(cx, Err(::ipc::binary::BinaryConvertError))
},
false => {
if value_ident.is_some() {
let instance_create = named_fields_sequence(cx, &ty, fields); let instance_create = named_fields_sequence(cx, &ty, fields);
quote_expr!(cx, { $map_stmts; $instance_create; Ok(result) }) quote_expr!(cx, { $map_stmts; $instance_create; Ok(result) })
} }
else { else {
let map_variant = P(fields_sequence(cx, &ty, fields, &instance_ident.unwrap_or(builder.id("Self")))); let map_variant = P(fields_sequence(cx, &ty, fields, &instance_ident.unwrap_or(builder.id("Self"))));
quote_expr!(cx, { $map_stmts; Ok($map_variant) }) quote_expr!(cx, { $map_stmts; Ok($map_variant) })
}
}
}; };
Ok(BinaryExpressions { Ok(BinaryExpressions {
@ -553,6 +567,7 @@ fn binary_expr_variant(
)); ));
let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read); let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read);
Ok(BinaryArm { Ok(BinaryArm {
size: quote_arm!(cx, $pat => { $size_expr } ), size: quote_arm!(cx, $pat => { $size_expr } ),
write: quote_arm!(cx, write: quote_arm!(cx,

View File

@ -14,6 +14,6 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![allow(dead_code, unused_assignments)] // codegen issues #![allow(dead_code, unused_assignments, unused_variables)] // codegen issues
include!(concat!(env!("OUT_DIR"), "/binary.rs")); include!(concat!(env!("OUT_DIR"), "/binary.rs"));

View File

@ -31,3 +31,8 @@ pub struct DoubleRoot {
pub x2: u64, pub x2: u64,
pub x3: u32, pub x3: u32,
} }
#[derive(Binary, PartialEq, Debug)]
pub struct ReferenceStruct<'a> {
pub ref_data: &'a u64,
}