From cb7a6f4f70e42e38e324417fac277bb5e85bacc8 Mon Sep 17 00:00:00 2001 From: pradeep Date: Wed, 8 Jun 2016 11:24:54 +0530 Subject: [PATCH] BUGFIX: variable size discrepancy with FFI for Rust enums Rust enums use 8-bit number for representation of values where as c uses 32-bit number. This caused the issue in release mode. The compiler optimized these variables in release mode which must have caused over-bound writes thus causing the program crash. Fixes #73 --- src/array.rs | 6 +++--- src/defines.rs | 10 ++++++++++ src/util.rs | 30 +++++++++++++++--------------- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/array.rs b/src/array.rs index 890fd9422..a47851d29 100644 --- a/src/array.rs +++ b/src/array.rs @@ -26,7 +26,7 @@ extern { fn af_get_elements(out: MutAfArray, arr: AfArray) -> c_int; - fn af_get_type(out: *mut uint8_t, arr: AfArray) -> c_int; + fn af_get_type(out: *mut c_int, arr: AfArray) -> c_int; fn af_get_dims(dim0: *mut c_longlong, dim1: *mut c_longlong, dim2: *mut c_longlong, dim3: *mut c_longlong, arr: AfArray) -> c_int; @@ -206,8 +206,8 @@ impl Array { /// Returns the Array data type pub fn get_type(&self) -> DType { unsafe { - let mut ret_val: u8 = 0; - let err_val = af_get_type(&mut ret_val as *mut uint8_t, self.handle as AfArray); + let mut ret_val: i32 = 0; + let err_val = af_get_type(&mut ret_val as *mut c_int, self.handle as AfArray); HANDLE_ERROR(AfError::from(err_val)); DType::from(ret_val) } diff --git a/src/defines.rs b/src/defines.rs index 60cf76350..669f2e053 100644 --- a/src/defines.rs +++ b/src/defines.rs @@ -106,6 +106,7 @@ impl Error for AfError { } /// Types of Array data type +#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum DType { /// 32 bit float @@ -135,6 +136,7 @@ pub enum DType { } /// Dictates the interpolation method to be used by a function +#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum InterpType { /// Nearest Neighbor interpolation method @@ -148,6 +150,7 @@ pub enum InterpType { } /// Helps determine how to pad kernels along borders +#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum BorderType { /// Pad using zeros @@ -157,6 +160,7 @@ pub enum BorderType { } /// Used by `regions` function to identify type of connectivity +#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum Connectivity { /// North-East-South-West (N-E-S-W) connectivity from given pixel/point @@ -166,6 +170,7 @@ pub enum Connectivity { } /// Helps determine the size of output of convolution +#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum ConvMode { /// Default convolution mode where output size is same as input size @@ -175,6 +180,7 @@ pub enum ConvMode { } /// Helps determine if convolution is in Spatial or Frequency domain +#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum ConvDomain { /// ArrayFire chooses whether the convolution will be in spatial domain or frequency domain @@ -186,6 +192,7 @@ pub enum ConvDomain { } /// Error metric used by `matchTemplate` function +#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum MatchType { /// Sum of Absolute Differences @@ -209,6 +216,7 @@ pub enum MatchType { } /// Identify the color space of given image(Array) +#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum ColorSpace { /// Grayscale color space @@ -220,6 +228,7 @@ pub enum ColorSpace { } /// Helps determine the type of a Matrix +#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum MatProp { /// Default (no-op) @@ -248,6 +257,7 @@ pub enum MatProp { /// Norm type #[allow(non_camel_case_types)] +#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub enum NormType { /// Treats input as a vector and return sum of absolute values diff --git a/src/util.rs b/src/util.rs index 8fa568aa9..ba1726453 100644 --- a/src/util.rs +++ b/src/util.rs @@ -11,37 +11,37 @@ impl From for AfError { } } -impl From for DType { - fn from(t: u8) -> DType { - assert!(DType::F32 as u8 <= t && t <= DType::U64 as u8); +impl From for DType { + fn from(t: i32) -> DType { + assert!(DType::F32 as i32 <= t && t <= DType::U64 as i32); unsafe { mem::transmute(t) } } } -impl From for InterpType { - fn from(t: u8) -> InterpType { - assert!(InterpType::NEAREST as u8 <= t && t <= InterpType::CUBIC as u8); +impl From for InterpType { + fn from(t: i32) -> InterpType { + assert!(InterpType::NEAREST as i32 <= t && t <= InterpType::CUBIC as i32); unsafe { mem::transmute(t) } } } -impl From for ConvMode { - fn from(t: u8) -> ConvMode { - assert!(ConvMode::DEFAULT as u8 <= t && t <= ConvMode::EXPAND as u8); +impl From for ConvMode { + fn from(t: i32) -> ConvMode { + assert!(ConvMode::DEFAULT as i32 <= t && t <= ConvMode::EXPAND as i32); unsafe { mem::transmute(t) } } } -impl From for ConvDomain { - fn from(t: u8) -> ConvDomain { - assert!(ConvDomain::AUTO as u8 <= t && t <= ConvDomain::FREQUENCY as u8); +impl From for ConvDomain { + fn from(t: i32) -> ConvDomain { + assert!(ConvDomain::AUTO as i32 <= t && t <= ConvDomain::FREQUENCY as i32); unsafe { mem::transmute(t) } } } -impl From for MatchType { - fn from(t: u8) -> MatchType { - assert!(MatchType::SAD as u8 <= t && t <= MatchType::SHD as u8); +impl From for MatchType { + fn from(t: i32) -> MatchType { + assert!(MatchType::SAD as i32 <= t && t <= MatchType::SHD as i32); unsafe { mem::transmute(t) } } }