Skip to content

Latest commit

 

History

History
115 lines (80 loc) · 4.49 KB

File metadata and controls

115 lines (80 loc) · 4.49 KB

Enum types

In Rust, enums are used to represent a choice among several different types. Notably, Rust enums allow each variant to have a different type.

This study examined the Option type commonly used from among the enum types of Rust. The Option type value is Some that returns the desired value if it is available or an empty value meaning the desired value is not available. We studied how this Option type is implemented at the assembly level. We also studied the assembly code of the expect() and unwrap() functions that we can use in connection with the Option type. Those functions cause a panic to occur.

Study results

  • In the Option type, a judgement value indicating Some or None is returned in the eax register. The eax register value 1 (one) means Some and the value 0 (zero) means None.
    • If it is Some, the desired value is returned in the edx register.

We found that the implementation described above is the same for 32-bit binaries, except how to pass arguments and the address lengths.

Details

The sample program we used in this study is shown [later](#Sample program we used) in this document.

Option type

We conducted this study using a debug build binary of the sample program that optimization poses no effect, because optimization removes unnecessary processing from release build and size-minimized binaries.

In the Option type of Rust, a value indicating Some or None is returned in the eax register: the value 1 means Some and the value 0 means None. Examining the return values associated with processing the Option type in the sample program shows that the eax register stores the value 1 and the edx register stores the value 2. The value 2 the edx register stores is the first even number found in the array the samples program defined. The program examines whether the eax register value is 1 or 0, and outputs the edx register value if the eax register value is 1 (Some) and outputs the string No even number found if the eax register value is 0 (None).

enum

expect()

We conducted this study using a debug build binary of the sample program that optimization poses no effect, because optimization removes unnecessary processing and expect() from release build and size-minimized binaries.

The expect() function receives a value indicating Some or None in its first argument, the Option type value in its second argument, a panic message in its third argument, the number of panic message characters in its fourth argument and the core::panic::Location struct in its fifth argument.

enum

The internal processing of expect() is shown below. It internally examines whether the Option type value is Some or None, and returns the second argument value as is if it is Some and triggers a panic if it is None.

enum

unwrap()

We conducted this study using a debug build binary of the sample program that optimization poses no effect, because optimization removes unnecessary processing and unwrap() from release build and size-minimized binaries.

The result of the sample program is shown below. The unwrap() function is inlined, and we can no longer determine whether unwrap() is used in this processing.

enum

Sample program we used

  • Option type
fn find_first_even_number(numbers: &[i32]) -> Option<i32> {
    for &number in numbers {
        if number % 2 == 0 {
            return Some(number);
        }
    }
    None
}

fn main(){
    let numbers = [1, 2, 3, 4, 5, 6];
    let result = find_first_even_number(&numbers);
    match result {
        Some(even_number) => println!("Even number: {}", even_number),
        None => println!("No even number found"),
    }
}
  • expect()
fn find_first_even_number(numbers: &[i32]) -> Option<i32> {
    for &number in numbers {
        if number % 2 == 0 {
            return Some(number);
        }
    }
    None
}

fn main() {
    let numbers = [1, 3, 7, 9];
    let result = find_first_even_number(&numbers);

    let even_number = result.expect("No even number found");
    
    println!("Even number: {}", even_number);
}
  • unwrap()
fn find_first_even_number(numbers: &[i32]) -> Option<i32> {
    for &number in numbers {
        if number % 2 == 0 {
            return Some(number);
        }
    }
    None
}

fn main() {
    let numbers = [1, 3, 7, 9];
    let result = find_first_even_number(&numbers);

    let even_number = result.unwrap();

    println!("Even number: {}", even_number);
}