Skip to content

Commit

Permalink
BUGFIX: variable size discrepancy with FFI for Rust enums
Browse files Browse the repository at this point in the history
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
  • Loading branch information
9prady9 committed Jun 8, 2016
1 parent 84b6c59 commit cb7a6f4
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 18 deletions.
6 changes: 3 additions & 3 deletions src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
}
Expand Down
10 changes: 10 additions & 0 deletions src/defines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
30 changes: 15 additions & 15 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,37 @@ impl From<i32> for AfError {
}
}

impl From<u8> for DType {
fn from(t: u8) -> DType {
assert!(DType::F32 as u8 <= t && t <= DType::U64 as u8);
impl From<i32> for DType {
fn from(t: i32) -> DType {
assert!(DType::F32 as i32 <= t && t <= DType::U64 as i32);
unsafe { mem::transmute(t) }
}
}

impl From<u8> for InterpType {
fn from(t: u8) -> InterpType {
assert!(InterpType::NEAREST as u8 <= t && t <= InterpType::CUBIC as u8);
impl From<i32> for InterpType {
fn from(t: i32) -> InterpType {
assert!(InterpType::NEAREST as i32 <= t && t <= InterpType::CUBIC as i32);
unsafe { mem::transmute(t) }
}
}

impl From<u8> for ConvMode {
fn from(t: u8) -> ConvMode {
assert!(ConvMode::DEFAULT as u8 <= t && t <= ConvMode::EXPAND as u8);
impl From<i32> for ConvMode {
fn from(t: i32) -> ConvMode {
assert!(ConvMode::DEFAULT as i32 <= t && t <= ConvMode::EXPAND as i32);
unsafe { mem::transmute(t) }
}
}

impl From<u8> for ConvDomain {
fn from(t: u8) -> ConvDomain {
assert!(ConvDomain::AUTO as u8 <= t && t <= ConvDomain::FREQUENCY as u8);
impl From<i32> for ConvDomain {
fn from(t: i32) -> ConvDomain {
assert!(ConvDomain::AUTO as i32 <= t && t <= ConvDomain::FREQUENCY as i32);
unsafe { mem::transmute(t) }
}
}

impl From<u8> for MatchType {
fn from(t: u8) -> MatchType {
assert!(MatchType::SAD as u8 <= t && t <= MatchType::SHD as u8);
impl From<i32> for MatchType {
fn from(t: i32) -> MatchType {
assert!(MatchType::SAD as i32 <= t && t <= MatchType::SHD as i32);
unsafe { mem::transmute(t) }
}
}
Expand Down

0 comments on commit cb7a6f4

Please sign in to comment.