From 9fa4a693ce4cd2b1b176e916b320f1eabd852992 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 19 Jan 2016 12:04:27 +0100 Subject: [PATCH 1/2] fixed build issues with stabilized feature WrappingOps --- src/evm/interpreter.rs | 1 - src/lib.rs | 1 - util/src/lib.rs | 2 +- util/src/uint.rs | 217 ++++++++++++++++++++++------------------- 4 files changed, 117 insertions(+), 104 deletions(-) diff --git a/src/evm/interpreter.rs b/src/evm/interpreter.rs index bd3a153b9..88823cbea 100644 --- a/src/evm/interpreter.rs +++ b/src/evm/interpreter.rs @@ -4,7 +4,6 @@ use common::*; use evm; use super::instructions as instructions; use super::instructions::Instruction; -use std::num::wrapping::OverflowingOps; use std::marker::Copy; use evm::{MessageCallResult, ContractCreateResult}; diff --git a/src/lib.rs b/src/lib.rs index 8180736a5..20c59eafa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ #![feature(cell_extras)] #![feature(augmented_assignments)] -#![feature(wrapping)] //#![feature(plugin)] //#![plugin(interpolate_idents)] //! Ethcore's ethereum implementation diff --git a/util/src/lib.rs b/util/src/lib.rs index 4bc47e61c..a5dd7e8a2 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -1,7 +1,7 @@ #![feature(op_assign_traits)] #![feature(augmented_assignments)] #![feature(associated_consts)] -#![feature(wrapping)] +//#![feature(wrapping)] //! Ethcore-util library //! //! ### Rust version: diff --git a/util/src/uint.rs b/util/src/uint.rs index ec70cddb2..8afbe87f4 100644 --- a/util/src/uint.rs +++ b/util/src/uint.rs @@ -23,7 +23,7 @@ use standard::*; use from_json::*; -use std::num::wrapping::OverflowingOps; +//use std::num::wrapping::OverflowingOps; macro_rules! impl_map_from { ($thing:ident, $from:ty, $to:ty) => { @@ -97,6 +97,23 @@ pub trait Uint: Sized + Default + FromStr + From + FromJson + fmt::Debug + fn pow(self, other: Self) -> Self; /// Return wrapped eponentation `self**other` and flag if there was an overflow fn overflowing_pow(self, other: Self) -> (Self, bool); + + + fn overflowing_add(self, other: Self) -> (Self, bool); + + fn overflowing_sub(self, other: Self) -> (Self, bool); + + fn overflowing_mul(self, other: Self) -> (Self, bool); + + fn overflowing_div(self, other: Self) -> (Self, bool); + + fn overflowing_rem(self, other: Self) -> (Self, bool); + + fn overflowing_neg(self) -> (Self, bool); + + fn overflowing_shl(self, shift: u32) -> (Self, bool); + + fn overflowing_shr(self, shift: u32) -> (Self, bool); } macro_rules! construct_uint { @@ -259,6 +276,104 @@ macro_rules! construct_uint { let res = overflowing!(x.overflowing_mul(y), overflow); (res, overflow) } + + fn overflowing_add(self, other: $name) -> ($name, bool) { + let $name(ref me) = self; + let $name(ref you) = other; + let mut ret = [0u64; $n_words]; + let mut carry = [0u64; $n_words]; + let mut b_carry = false; + let mut overflow = false; + + for i in 0..$n_words { + ret[i] = me[i].wrapping_add(you[i]); + + if ret[i] < me[i] { + if i < $n_words - 1 { + carry[i + 1] = 1; + b_carry = true; + } else { + overflow = true; + } + } + } + if b_carry { + let ret = overflowing!($name(ret).overflowing_add($name(carry)), overflow); + (ret, overflow) + } else { + ($name(ret), overflow) + } + } + + fn overflowing_sub(self, other: $name) -> ($name, bool) { + let res = overflowing!((!other).overflowing_add(From::from(1u64))); + let res = overflowing!(self.overflowing_add(res)); + (res, self < other) + } + + fn overflowing_mul(self, other: $name) -> ($name, bool) { + let mut res = $name::from(0u64); + let mut overflow = false; + // TODO: be more efficient about this + for i in 0..(2 * $n_words) { + let v = overflowing!(self.overflowing_mul_u32((other >> (32 * i)).low_u32()), overflow); + let res2 = overflowing!(v.overflowing_shl(32 * i as u32), overflow); + res = overflowing!(res.overflowing_add(res2), overflow); + } + (res, overflow) + } + + fn overflowing_div(self, other: $name) -> ($name, bool) { + (self / other, false) + } + + fn overflowing_rem(self, other: $name) -> ($name, bool) { + (self % other, false) + } + + fn overflowing_neg(self) -> ($name, bool) { + (!self, true) + } + + fn overflowing_shl(self, shift32: u32) -> ($name, bool) { + let $name(ref original) = self; + let mut ret = [0u64; $n_words]; + let shift = shift32 as usize; + let word_shift = shift / 64; + let bit_shift = shift % 64; + for i in 0..$n_words { + // Shift + if i + word_shift < $n_words { + ret[i + word_shift] += original[i] << bit_shift; + } + // Carry + if bit_shift > 0 && i + word_shift + 1 < $n_words { + ret[i + word_shift + 1] += original[i] >> (64 - bit_shift); + } + } + // Detecting overflow + let last = $n_words - word_shift - if bit_shift > 0 { 1 } else { 0 }; + let overflow = if bit_shift > 0 { + (original[last] >> (64 - bit_shift)) > 0 + } else if word_shift > 0 { + original[last] > 0 + } else { + false + }; + + for i in last+1..$n_words-1 { + if original[i] > 0 { + return ($name(ret), true); + } + } + ($name(ret), overflow) + } + + fn overflowing_shr(self, _shift32: u32) -> ($name, bool) { + // TODO [todr] not used for now + unimplemented!(); + } + } impl $name { @@ -390,105 +505,6 @@ macro_rules! construct_uint { } } - impl OverflowingOps for $name { - fn overflowing_add(self, other: $name) -> ($name, bool) { - let $name(ref me) = self; - let $name(ref you) = other; - let mut ret = [0u64; $n_words]; - let mut carry = [0u64; $n_words]; - let mut b_carry = false; - let mut overflow = false; - - for i in 0..$n_words { - ret[i] = me[i].wrapping_add(you[i]); - - if ret[i] < me[i] { - if i < $n_words - 1 { - carry[i + 1] = 1; - b_carry = true; - } else { - overflow = true; - } - } - } - if b_carry { - let ret = overflowing!($name(ret).overflowing_add($name(carry)), overflow); - (ret, overflow) - } else { - ($name(ret), overflow) - } - } - - fn overflowing_sub(self, other: $name) -> ($name, bool) { - let res = overflowing!((!other).overflowing_add(From::from(1u64))); - let res = overflowing!(self.overflowing_add(res)); - (res, self < other) - } - - fn overflowing_mul(self, other: $name) -> ($name, bool) { - let mut res = $name::from(0u64); - let mut overflow = false; - // TODO: be more efficient about this - for i in 0..(2 * $n_words) { - let v = overflowing!(self.overflowing_mul_u32((other >> (32 * i)).low_u32()), overflow); - let res2 = overflowing!(v.overflowing_shl(32 * i as u32), overflow); - res = overflowing!(res.overflowing_add(res2), overflow); - } - (res, overflow) - } - - fn overflowing_div(self, other: $name) -> ($name, bool) { - (self / other, false) - } - - fn overflowing_rem(self, other: $name) -> ($name, bool) { - (self % other, false) - } - - fn overflowing_neg(self) -> ($name, bool) { - (!self, true) - } - - fn overflowing_shl(self, shift32: u32) -> ($name, bool) { - let $name(ref original) = self; - let mut ret = [0u64; $n_words]; - let shift = shift32 as usize; - let word_shift = shift / 64; - let bit_shift = shift % 64; - for i in 0..$n_words { - // Shift - if i + word_shift < $n_words { - ret[i + word_shift] += original[i] << bit_shift; - } - // Carry - if bit_shift > 0 && i + word_shift + 1 < $n_words { - ret[i + word_shift + 1] += original[i] >> (64 - bit_shift); - } - } - // Detecting overflow - let last = $n_words - word_shift - if bit_shift > 0 { 1 } else { 0 }; - let overflow = if bit_shift > 0 { - (original[last] >> (64 - bit_shift)) > 0 - } else if word_shift > 0 { - original[last] > 0 - } else { - false - }; - - for i in last+1..$n_words-1 { - if original[i] > 0 { - return ($name(ret), true); - } - } - ($name(ret), overflow) - } - - fn overflowing_shr(self, _shift32: u32) -> ($name, bool) { - // TODO [todr] not used for now - unimplemented!(); - } - } - impl Add<$name> for $name { type Output = $name; @@ -915,7 +931,6 @@ pub const BAD_U256: U256 = U256([0xffffffffffffffffu64; 4]); mod tests { use uint::{Uint, U128, U256, U512}; use std::str::FromStr; - use std::num::wrapping::OverflowingOps; #[test] pub fn assign_ops() { From 03bdecf23fc6f849180c4862f12ae04e7e868ce3 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 19 Jan 2016 12:05:53 +0100 Subject: [PATCH 2/2] removed commented lines --- util/src/lib.rs | 1 - util/src/uint.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/util/src/lib.rs b/util/src/lib.rs index a5dd7e8a2..84d67764c 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -1,7 +1,6 @@ #![feature(op_assign_traits)] #![feature(augmented_assignments)] #![feature(associated_consts)] -//#![feature(wrapping)] //! Ethcore-util library //! //! ### Rust version: diff --git a/util/src/uint.rs b/util/src/uint.rs index 8afbe87f4..60493688c 100644 --- a/util/src/uint.rs +++ b/util/src/uint.rs @@ -23,7 +23,6 @@ use standard::*; use from_json::*; -//use std::num::wrapping::OverflowingOps; macro_rules! impl_map_from { ($thing:ident, $from:ty, $to:ty) => {