From 59e18ad65970d519c44e70d2f0421aca723dedc5 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Wed, 20 Apr 2016 15:55:08 +0300 Subject: [PATCH] making this work --- Cargo.lock | 8 ++ ipc/codegen/src/serialization.rs | 192 +++++++++++++++++++++++++++---- ipc/rpc/src/binary.rs | 2 +- ipc/rpc/src/lib.rs | 4 +- 4 files changed, 179 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39aed230f..453891fff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,11 +237,15 @@ dependencies = [ name = "ethcore" version = "1.1.0" dependencies = [ + "bincode 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.63 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.1.0", "ethcore-devtools 1.1.0", + "ethcore-ipc 1.1.0", + "ethcore-ipc-codegen 1.1.0", + "ethcore-ipc-nano 1.1.0", "ethcore-util 1.1.0", "ethjson 0.1.0", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -250,6 +254,10 @@ dependencies = [ "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/ipc/codegen/src/serialization.rs b/ipc/codegen/src/serialization.rs index 205b13f67..390f83170 100644 --- a/ipc/codegen/src/serialization.rs +++ b/ipc/codegen/src/serialization.rs @@ -122,7 +122,7 @@ fn binary_expr( ) -> Result { match item.node { ast::ItemKind::Struct(ref variant_data, _) => { - binary_expr_struct( + binary_expr_item_struct( cx, builder, impl_generics, @@ -149,29 +149,54 @@ fn binary_expr( } struct BinaryExpressions { - size: P, - write: P, - read: P, -} - -fn serialize_tuple_struct( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - impl_generics: &ast::Generics, - ty: P, - fields: usize, -) -> Result, Error> { - let type_name = field.ty; - let id = field.id; - - Ok(BinaryExpressions { - size: quote_expr!(cx, self. $id .size() ), - write: quote_stmt!(cx, self. $id .write(buffer); ), - read: quote_expr!(cx, Self { $id: $type_name ::from_bytes(buffer) }), - }); + pub size: P, + pub write: P, + pub read: P, } fn binary_expr_struct( + cx: &ExtCtxt, + builder: &aster::AstBuilder, + ty: P, + fields: &[ast::StructField], + value_ident: Option>, +) -> Result { + let type_name = field.ty; + let id = field.id; + + let mut size_exprs = Vec::new(); + fields.iter().enumerate(|(index, field)| { + let index_ident = builder.id(format!("{}", index)); + value_ident.and_then(|value_ident| size_exprs.push(quote_expr!(cx, $value_ident . $index_ident .size()))) + .unwrap_or_else(|| size_exprs.push(quote_expr!(cx, $index_ident .size()))); + }); + + let mut total_size_expr = size_exprs[0].clone(); + for index in 1..size_expr.len() { + let next_expr = size_exprs[i].clone(); + total_size_expr = quote_expr!(cx, $total_size_expr + $next_expr); + } + + let mut write_stmts = Vec::new(); + write_stmts.push(quote_stmt!(cx, let mut offset = 0usize;)); + fields.iter().enumerate(|(index, field)| { + let index_ident = builder.id(format!("{}", index)); + let size_expr = size_exprs[index]; + write_stmts.push(quote_stmt!(cx, let next_line = offset + $size_expr; )); + value_ident.and_then(|x| + write_stmts.push(quote_stmt!(cx, $x . $index_ident .write(&mut buffer[offset..next_line]);)) + ).unwrap_or_else(|| write_stmts.push(quote_stmt!(cx, $index_ident .write(&mut buffer[offset..next_line]);))); + write_stmts.push(quote_stmt!(cx, offset = next_line; )); + }); + + Ok(BinaryExpressions { + size: total_size_expr, + write: quote_stmt!(cx, { $write_stmts } ), + read: quote_expr!(cx, $ty { }), + }); +} + +fn binary_expr_item_struct( cx: &ExtCtxt, builder: &aster::AstBuilder, impl_generics: &ast::Generics, @@ -181,22 +206,139 @@ fn binary_expr_struct( ) -> Result { match *variant_data { ast::VariantData::Tuple(ref fields, _) => { - binary_expr_struct_tuple( + binary_expr_struct( cx, &builder, - impl_generics, ty, fields, ) } ast::VariantData::Struct(ref fields, _) => { - binary_expr_struct_inner( + binary_expr_struct( cx, &builder, - impl_generics, ty, fields, ) } } } + +fn binary_expr_enum( + cx: &ExtCtxt, + builder: &aster::AstBuilder, + type_ident: Ident, + impl_generics: &ast::Generics, + ty: P, + enum_def: &ast::EnumDef, +) -> Result { + let arms: Vec<_> = try!( + enum_def.variants.iter() + .enumerate() + .map(|(variant_index, variant)| { + binary_expr_variant( + cx, + builder, + type_ident, + impl_generics, + ty.clone(), + variant, + variant_index, + ) + }) + .collect() + ); + + let (size_arms, write_arms, read_arms) = ( + arms.iter().map(|x| x.size).collect::>>(), + arms.iter().map(|x| x.write).collect::>>(), + arms.iter().map(|x| x.read).collect::>>()); + + Ok(BinaryExpressions { + size: quote_expr!(cx, match *self { $size_arms }), + write: quote_stmt!(cx, match *self { $write_arms }; ), + read: quote_expr!(cx, match *self { $read_arms }), + }); + +} + +struct BinaryArm { + size: P, + write: P, + read: P, +} + +fn binary_expr_variant( + cx: &ExtCtxt, + builder: &aster::AstBuilder, + type_ident: Ident, + generics: &ast::Generics, + ty: P, + variant: &ast::Variant, + variant_index: usize, +) -> Result { + let type_name = ty.name; + + let variant_ident = variant.node.name; + + match variant.node.data { + ast::VariantData::Tuple(ref fields, _) => { + let field_names: Vec = (0 .. fields.len()) + .map(|i| builder.id(format!("__field{}", i))) + .collect(); + + let pat = builder.pat().enum_() + .id(type_ident).id(variant_ident).build() + .with_pats( + field_names.iter() + .map(|field| builder.pat().ref_id(field)) + ) + .build(); + + let binary_expr = try!(binary_expr_struct( + cx, + &builder, + ty, + fields, + None, + )); + + let (size_expr, write, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read); + + Ok(BinaryArm { + size: P(quote_arm!(cx, $pat => { $size_expr } )), + write: P(quote_arm!(cx, $pat => { $write } )), + read: P(quote_arm!(cx, $pat => { $read_expr } )), + }) + } + ast::VariantData::Struct(ref fields, _) => { + let field_names: Vec<_> = (0 .. fields.len()) + .map(|i| builder.id(format!("__field{}", i))) + .collect(); + + let pat = builder.pat().struct_() + .id(type_ident).id(variant_ident).build() + .with_pats( + field_names.iter() + .zip(fields.iter()) + .map(|(id, field)|(name, builder.pat().ref_id(id)))) + .build(); + + + let binary_expr = try!(binary_expr_struct( + cx, + &builder, + ty, + fields, + None, + )); + + let (size_expr, write, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read); + Ok(BinaryArm { + size: P(quote_arm!(cx, $pat => { $size_expr } )), + write: P(quote_arm!(cx, $pat => { $write } )), + read: P(quote_arm!(cx, $pat => { $read_expr } )), + }) + } + } +} diff --git a/ipc/rpc/src/binary.rs b/ipc/rpc/src/binary.rs index 3b9b0a561..2cc07f2d0 100644 --- a/ipc/rpc/src/binary.rs +++ b/ipc/rpc/src/binary.rs @@ -16,7 +16,7 @@ //! Binary representation of types -trait BinaryConvertable { +pub trait BinaryConvertable { fn size(&self) -> usize; fn to_bytes(buffer: &mut [u8]); diff --git a/ipc/rpc/src/lib.rs b/ipc/rpc/src/lib.rs index c771fb1b1..4d5902383 100644 --- a/ipc/rpc/src/lib.rs +++ b/ipc/rpc/src/lib.rs @@ -21,4 +21,6 @@ extern crate semver; extern crate nanomsg; pub mod interface; -pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket, BinaryConvertable}; +pub mod binary; +pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket}; +pub use binary::{BinaryConvertable};