rust Cacher的例子要点

Cacher的例子要点

HelloWord.java
public class HelloWorld {

    public static void main(String[] args) {
        // Prints "Hello, World" to the terminal window.
        System.out.println("Hello, World");
    }

}
playground.rs
extern crate serde; // 1.0.85
extern crate serde_json; // 1.0.37

use serde::Serialize;

fn test(a: impl Serialize) {
    println!("{}", serde_json::to_string_pretty(&a).unwrap());
}

fn main() {
    test(25u32);
}

rust 代码从Rust Playground共享

代码从Rust Playground共享

foobar.md
# ok
playground.rs
fn boolinator() -> bool {
    match true {
        true => true,
        false => false,
    } 
    
    && 
    
    match false {
        true => true,
        false => false,
    }
}

fn main() {
    println!("{}", boolinator());
}

rust 使用Rusoto读取Amazon DynamoDB表项

使用Rusoto读取Amazon DynamoDB表项

main.rs
use std::error::Error;
use lambda_runtime::{error::HandlerError, lambda, Context};
use rusoto_core::Region;
use std::collections::HashMap;
use serde_json::Value;
use serde_derive::{Deserialize, Serialize};
use serde_dynamodb;
use env_logger;
use log::{error, warn, info, debug};
use std::env;

use rusoto_dynamodb::{AttributeValue, DynamoDb, DynamoDbClient, GetItemInput};

#[derive(Serialize, Deserialize, Debug, Default)]
struct Item {
    year: i64,
    title: String,
    info: ItemInfo,
}

#[derive(Serialize, Deserialize, Debug, Default)]
struct ItemInfo {
    plot: String,
    rating: f64,
}

fn main() -> Result<(), Box<dyn Error>>{
    env::set_var("RUST_LOG", "info");
    env_logger::init();
    lambda!(handler);
    Ok(())
}

fn handler(_: Value, c: Context) -> Result<Item, HandlerError> {
    let mut query_key: HashMap<String, AttributeValue> = HashMap::new();

    query_key.insert(
        "year".to_owned(),
        AttributeValue {
            n: Some("2013".to_owned()),
            ..Default::default()
        },
    );

    query_key.insert(
        "title".to_owned(),
        AttributeValue {
            s: Some("Rush".to_owned()),
            ..Default::default()
        },
    );

    let input: GetItemInput = GetItemInput {
        table_name: "Movies".to_owned(),
        key: query_key,
        ..Default::default()
    };

    let client = DynamoDbClient::new(Region::ApNortheast1);
    match client.get_item(input).sync() {
        Ok(result) => {
            match result.item {
                Some(item) => {
                    Ok(serde_dynamodb::from_hashmap(item).unwrap())
                }
                None => {
                    error!("{}", "no item was found.");
                    Ok(Default::default())
                }
            }
        },
        Err(error) => {
            Err(c.new_error(error.description()))
        }
    }
}

rust Rust的简单HTTP服务器示例

Rust的简单HTTP服务器示例

http_server.rs
// Updated example from http://rosettacode.org/wiki/Hello_world/Web_server#Rust
// to work with Rust 1.0 beta

use std::net::{TcpStream, TcpListener};
use std::io::{Read, Write};
use std::thread;


fn handle_read(mut stream: &TcpStream) {
    let mut buf = [0u8 ;4096];
    match stream.read(&mut buf) {
        Ok(_) => {
            let req_str = String::from_utf8_lossy(&buf);
            println!("{}", req_str);
            },
        Err(e) => println!("Unable to read stream: {}", e),
    }
}

fn handle_write(mut stream: TcpStream) {
    let response = b"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n<html><body>Hello world</body></html>\r\n";
    match stream.write(response) {
        Ok(_) => println!("Response sent"),
        Err(e) => println!("Failed sending response: {}", e),
    }
}

fn handle_client(stream: TcpStream) {
    handle_read(&stream);
    handle_write(stream);
}

fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
    println!("Listening for connections on port {}", 8080);

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                thread::spawn(|| {
                    handle_client(stream)
                });
            }
            Err(e) => {
                println!("Unable to connect: {}", e);
            }
        }
    }
}

rust linux.rs

linux.rs
use std::fs::File;
use std::io::{self, Seek, SeekFrom};
use std::time::Duration;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use mio;
use mio::unix::{EventedFd, UnixReady};
use nix::poll::{self, PollFd, EventFlags};
use libc::c_int;
use super::*;
use inotify;

use logger;

pub struct FileWatcher {
    inotify: inotify::Inotify,
    poll: mio::Poll,
    events: mio::Events,
}

impl FileWatcher {
    pub fn new(file_path: &str) -> io::Result<Self> {
        let mut inotify = inotify::Inotify::init()?;
        inotify.add_watch(file_path, inotify::WatchMask::MODIFY)?;
        let poll = mio::Poll::new()?;
        let events = mio::Events::with_capacity(1024);

        logger::log(&format!("ino:fd={}", inotify.as_raw_fd()));

        poll.register(
            &EventedFd(&inotify.as_raw_fd()),
            mio::Token(0),
            mio::Ready::readable(),
            mio::PollOpt::edge(),
        ).unwrap();

        Ok( Self { inotify, poll, events } )
    }
}

impl FileWatch for FileWatcher {
    fn block(&mut self, timeout: Option<Duration>) -> io::Result<Option<bool>> {
        self.poll.poll(&mut self.events, timeout)?;
        Ok(
            if self.events.is_empty() {
                logger::log("inotify:timeout");
                None
            } else {
                static token_id: usize = 0;
                let evt = &self.events.iter().next();
                let mut buf = [0u8; 1024];
                self.inotify.read_events(&mut buf)?;
                // self.poll.register(
                //     &EventedFd(&self.inotify.as_raw_fd()),
                //     mio::Token(if token_id == 0 { 1 } else { 0 }),
                //     mio::Ready::readable(),
                //     mio::PollOpt::edge(),
                //     ).unwrap();
                if let Some(e) = evt {
                    logger::log("inotify:some");
                    Some(UnixReady::from(e.readiness()).is_hup())
                } else {
                    logger::log("inotify:none");
                    None
                }
            }
        )
    }
}

pub struct StdinWatcher {
    poll: mio::Poll,
    events: mio::Events,
}

impl StdinWatcher {
    pub fn new(fd: RawFd) -> io::Result<Self> {
        let poll = mio::Poll::new()?;
        let events = mio::Events::with_capacity(1024);
        poll.register(
            &EventedFd(&fd),
            mio::Token(0),
            mio::Ready::readable(),
            mio::PollOpt::edge(),
        )?;

        Ok( Self{ poll, events } )
    }
}

impl FileWatch for StdinWatcher {
    fn block(&mut self, timeout: Option<Duration>) -> io::Result<Option<bool>> {
        self.poll.poll(&mut self.events, timeout)?;
        Ok(
            if self.events.is_empty() {
                None
            } else {
                let evt = &self.events.iter().next();
                if let Some(e) = evt {
                    Some(UnixReady::from(e.readiness()).is_hup())
                } else {
                    None
                }
            }
        )
    }
}

rust Rust Parallel Autoincrementer

这会产生一个新的线程,它将独特的整数写入通道。调用`next`将阻塞,直到新的整数准备就绪。它是线程安全的。

autoincrementer.rs
/// Autincrementer is a synchronized unique number generator.
/// It spawns a new thread which writes new numbers to a channel.
/// Each time it writes a new number, it will increment the value by one.
struct Autoincrementer (Receiver<Identifier>);

impl Autoincrementer {

    #[allow(unused_must_use)]
    fn new() -> Self {
        let (sender, receiver) = sync_channel(0);
        thread::spawn(move|| {
            let mut count = u64::min_value();
            loop {
                count = count + 1;
                sender.send(count);
            }
        });
        Autoincrementer(receiver)
    }

    fn next(&self) -> Identifier {
        self.0.recv().unwrap()
    }
}

rust 脱机Rust文档

脱机显示Rust文档。

sample.rs
# Open the standard library documentation offline
rustup doc --std 

# Open your local documentation
cargo doc --open

# Open the book
rustup doc --book

rust mio_stdin.rs

mio_stdin.rs
extern crate mio;
use mio::unix::EventedFd;
use mio::{Token, PollOpt, Ready, Poll, Events};
use std::io::ErrorKind;
use std::time::Duration;

fn main() {
    const IN: Token = Token(0);
    let fd0_e = EventedFd(&0);

    let poll = Poll::new().unwrap();

    poll.register(&fd0_e, IN, Ready::readable(),
                  PollOpt::edge()).unwrap();

    let mut events = Events::with_capacity(1024);

    'outer: loop {
        let ret = poll.poll(&mut events, Some(Duration::from_secs(5)));
        if let Err(x) = ret {
            eprintln!("Boo");
            if x.kind() == ErrorKind::Interrupted { continue; }
            break;
        }

        if events.is_empty() {
            println!("_____TMO_____");
        }

        for event in events.iter() {
            match event.token() {
                IN => println!("_____IN_____"),
                _ => unreachable!(),
            }
        }

    }
}

rust Rust基本的Operatrions

Rust基本的Operatrions

functional_nested_loop.rs
pub fn three_layer_nested_loop()  {
  let sum_result = 12 ;
    (1..sum_result)
        .flat_map(|a| (1..=(sum_result - a))
        .map(move |b| (a, b) ))
        .flat_map(move|a_and_b| (1..=(sum_result - (a_and_b.0+a_and_b.1)))
        .map(move|c| (a_and_b.0,a_and_b.1, c) ))
        .filter(move |&(a, b, c)| ((a, b, c).0 + (a, b, c).1  + (a, b, c).2 == sum_result ) && ((a, b, c).0 * (a, b, c).0 + (a, b, c).1 * (a, b, c).1 == (a, b, c).2 * (a, b, c).2) )
        .for_each(| filtered_number| {
            println!("a = {:#?}\n",  filtered_number.0);
            println!("b = {:#?}\n",  filtered_number.1);
            println!("c = {:#?} \n",  filtered_number.2);
            println!("=======================\n");
        });
}
subtrac_with_overflow_check.rs
let counter : u32 = 3;
let i : Option<u32> = counter.checked_sub(1);
if i.is_none() == false{
  let temp = i.unwrap();
}
str_to_sting_with_placeholder.rs
let res = format!("F... {} ... {} ...\n", x,y);
vec_to_string.rs
let expected = vec![
    "For want of a nail the shoe was lost.",
    "And all for the want of a nail.",
].join("\n");
concat.rs
// Concat a string inside a loop and trun it into a str
//https://users.rust-lang.org/t/how-do-i-avoid-temporary-value-created-here-errors-when-creating-an-array/9433/14
    let mut result: Vec<String> = Vec::new();
    let mut counter = 0;
    while counter < list.len() {
      if counter+1< list.len(){
        result.push(format!("For want of a {} the {} was lost.\n", list[counter], list[counter+1]));
      }
      if counter+1 == list.len(){
        result.push(format!("For want of a {} the {} was lost.\n", list[counter-1], list[counter]));
      }
      counter +=1;
    }
  let result = result.iter().map(|s| s.as_str()).collect::<Vec<_>>().join("\n");

rust brainf * ck jit

brainf * ck jit

main.rs
extern crate libc;

use std::env;
use std::fs::{self, File};
use std::io::Read;
use std::mem;
use std::ops::{Index, IndexMut};

#[derive(Debug)]
pub struct Inst {
    kind: InstKind,
    arg: usize,
}

#[derive(Debug, PartialEq)]
enum InstKind {
    MoveRight,         // >
    MoveLeft,          // <
    Incr,              //+
    Decr,              //-
    Output,            //.
    Input,             //,
    JumpIfZero,        //[
    JumpIfNonZero,     //]
    LoopSetToZero,     //[-]
    LoopIncrPtr,       //[>>>]
    LoopDecrPtr,       //[<<<]
    LoopMoveDataRight, //[->>>+<<<]
    LoopMoveDataLeft,  //[-<<<+>>>]
}

impl InstKind {
    fn try_from(f: u8) -> Option<Self> {
        match f {
            b'>' => Some(InstKind::MoveRight),
            b'<' => Some(InstKind::MoveLeft),
            b'+' => Some(InstKind::Incr),
            b'-' => Some(InstKind::Decr),
            b'.' => Some(InstKind::Output),
            b',' => Some(InstKind::Input),
            b'[' => Some(InstKind::JumpIfZero),
            b']' => Some(InstKind::JumpIfNonZero),
            _ => None,
        }
    }
}

fn optimize_loop(insts: &Vec<Inst>, loop_start: usize) -> Vec<Inst> {
    let mut new_insts = vec![];
    if insts.len() - loop_start == 2 {
        let inst = &insts[loop_start + 1];
        match inst.kind {
            InstKind::Incr | InstKind::Decr => {
                new_insts.push(Inst {
                    kind: InstKind::LoopSetToZero,
                    arg: 0,
                });
            }
            InstKind::MoveRight => {
                new_insts.push(Inst {
                    kind: InstKind::LoopIncrPtr,
                    arg: inst.arg,
                });
            }
            InstKind::MoveLeft => {
                new_insts.push(Inst {
                    kind: InstKind::LoopDecrPtr,
                    arg: inst.arg,
                });
            }
            _ => {}
        }
    } else if insts.len() - loop_start == 5 {
        if insts[loop_start + 1].kind == InstKind::Decr
            && insts[loop_start + 3].kind == InstKind::Incr
            && insts[loop_start + 1].arg == 1
            && insts[loop_start + 3].arg == 1
        {
            if insts[loop_start + 2].kind == InstKind::MoveRight
                && insts[loop_start + 4].kind == InstKind::MoveLeft
                && insts[loop_start + 2].arg == insts[loop_start + 4].arg
            {
                new_insts.push(Inst {
                    kind: InstKind::LoopMoveDataRight,
                    arg: insts[loop_start + 2].arg, // size to move pointer
                })
            } else if insts[loop_start + 2].kind == InstKind::MoveLeft
                && insts[loop_start + 4].kind == InstKind::MoveRight
                && insts[loop_start + 2].arg == insts[loop_start + 4].arg
            {
                new_insts.push(Inst {
                    kind: InstKind::LoopMoveDataLeft,
                    arg: insts[loop_start + 2].arg,
                });
            }
        }
    }
    new_insts
}

fn translate_program(program: &[u8]) -> Vec<Inst> {
    let mut insts = Vec::with_capacity(program.len());
    let mut idx = 0;
    let mut bracket_stack = Vec::new();
    while idx < program.len() {
        let p = program[idx];
        match InstKind::try_from(p) {
            Some(v) => match v {
                InstKind::JumpIfZero => {
                    bracket_stack.push(insts.len());
                    let inst = Inst {
                        kind: InstKind::JumpIfZero,
                        arg: 0,
                    };
                    insts.push(inst);
                    idx += 1;
                }
                InstKind::JumpIfNonZero => {
                    let open_idx = match bracket_stack.pop() {
                        Some(v) => v,
                        None => panic!("unmatched bracket"),
                    };
                    let new_insts = optimize_loop(&insts, open_idx);
                    if new_insts.is_empty() {
                        insts[open_idx].arg = insts.len();
                        let inst = Inst {
                            kind: InstKind::JumpIfNonZero,
                            arg: open_idx,
                        };
                        insts.push(inst);
                    } else {
                        insts.drain(open_idx..);
                        for i in new_insts {
                            insts.push(i);
                        }
                    }
                    idx += 1;
                }
                kind => {
                    let start = idx;
                    while program[idx] == p {
                        idx += 1;
                    }
                    let cnt = idx - start;
                    let inst = Inst { kind, arg: cnt };
                    insts.push(inst);
                }
            },
            None => {
                idx += 1;
            }
        };
    }
    insts
}

struct JitMemory {
    program: *mut u8,
    position: usize,
}

const PAGE_SIZE: usize = 4096;
impl JitMemory {
    fn new(size: usize) -> Self {
        let program: *mut u8;
        let size = size * PAGE_SIZE;
        let mut page: *mut libc::c_void;
        unsafe {
            page = mem::zeroed();
            libc::posix_memalign(&mut page, PAGE_SIZE, size);
            libc::mprotect(
                page,
                size,
                libc::PROT_EXEC | libc::PROT_READ | libc::PROT_WRITE,
            );
            program = mem::transmute(page);
        }
        JitMemory {
            program,
            position: 0,
        }
    }

    fn emit_byte(&mut self, b: u8) {
        unsafe {
            *(self.program.offset(self.position as isize)) = b;
        }
        self.position += 1;
    }

    fn emit_bytes(&mut self, bytes: &[u8]) {
        let mut i = 0;
        for b in bytes {
            unsafe {
                *(self.program.offset(self.position as isize + i)) = *b;
            }
            i += 1;
        }
        self.position += bytes.len();
    }

    fn emit_u64(&mut self, u: u64) {
        let bytes: [u8; 8] = unsafe { mem::transmute(u) };
        self.emit_bytes(&bytes);
    }

    fn emit_u32(&mut self, u: u32) {
        let bytes: [u8; 4] = unsafe { mem::transmute(u) };
        self.emit_bytes(&bytes);
    }

    fn emit_u16(&mut self, u: u16) {
        let bytes: [u8; 2] = unsafe { mem::transmute(u) };
        self.emit_bytes(&bytes);
    }
}

impl Index<usize> for JitMemory {
    type Output = u8;
    fn index(&self, index: usize) -> &Self::Output {
        unsafe { &*self.program.offset(index as isize) }
    }
}

impl IndexMut<usize> for JitMemory {
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        unsafe { &mut *self.program.offset(index as isize) }
    }
}

fn main() -> Result<(), String> {
    let mut args = env::args();
    let mut jit_mem = JitMemory::new(20);
    jit_mem.emit_bytes(&[0x49, 0xbd]);
    let memory: *mut u8;
    let _memory = unsafe { libc::malloc(50000) };
    memory = unsafe { mem::transmute(_memory) };
    jit_mem.emit_u64(memory as u64);
    let path = match args.nth(1) {
        Some(v) => v,
        None => {
            panic!("no file given");
        }
    };
    let mut file = match File::open(&path) {
        Ok(f) => f,
        Err(e) => return Err(format!("path: {}, {}", path, e)),
    };
    let meta = match fs::metadata(&path) {
        Ok(v) => v,
        Err(e) => return Err(format!("{}", e)),
    };
    let len = meta.len();
    let mut buf = Vec::with_capacity(len as usize);

    let _ = file.read_to_end(&mut buf).unwrap();
    let insts = translate_program(&buf);
    let mut pc = 0;
    let mut bracket_stack = vec![];
    while pc < insts.len() {
        let inst = &insts[pc];
        match inst.kind {
            InstKind::MoveRight => {
                if inst.arg < 128 {
                    jit_mem.emit_bytes(&[0x49, 0x83, 0xc5, inst.arg as u8]);
                } else {
                    jit_mem.emit_bytes(&[0x49, 0x81, 0xc5]);
                    jit_mem.emit_u32(inst.arg as u32);
                }
            }
            InstKind::MoveLeft => {
                if inst.arg < 128 {
                    jit_mem.emit_bytes(&[0x49, 0x83, 0xed, inst.arg as u8]);
                } else {
                    jit_mem.emit_bytes(&[0x49, 0x81, 0xed]);
                    jit_mem.emit_u32(inst.arg as u32);
                }
            }
            InstKind::Incr => {
                if inst.arg < 256 {
                    jit_mem.emit_bytes(&[0x41, 0x80, 0x45, 0x00, inst.arg as u8]);
                } else if inst.arg < 65536 {
                    jit_mem.emit_bytes(&[0x66, 0x41, 0x81, 0x45, 0x00]);
                    jit_mem.emit_u16(inst.arg as u16);
                } else {
                    panic!();
                }
            }
            InstKind::Decr => {
                if inst.arg < 256 {
                    jit_mem.emit_bytes(&[0x41, 0x80, 0x6d, 0x00, inst.arg as u8]);
                } else if inst.arg < 65536 {
                    jit_mem.emit_bytes(&[0x66, 0x41, 0x81, 0x6D, 0x00]);
                    jit_mem.emit_u16(inst.arg as u16);
                } else {
                    panic!();
                }
            }
            InstKind::Output => {
                jit_mem.emit_bytes(&[0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00]);
                jit_mem.emit_bytes(&[0x48, 0xc7, 0xc7, 0x01, 0x00, 0x00, 0x00]);
                jit_mem.emit_bytes(&[0x4c, 0x89, 0xee]);
                jit_mem.emit_bytes(&[0x48, 0xc7, 0xc2]);
                jit_mem.emit_u32(inst.arg as u32);
                jit_mem.emit_bytes(&[0x0f, 0x05]);
            }
            InstKind::Input => {
                jit_mem.emit_bytes(&[0x48, 0xc7, 0xc0, 0x00, 0x00, 0x00, 0x00]);
                jit_mem.emit_bytes(&[0x48, 0xc7, 0xc7, 0x00, 0x00, 0x00, 0x00]);
                jit_mem.emit_bytes(&[0x4c, 0x89, 0xee]);
                jit_mem.emit_bytes(&[0x48, 0xc7, 0xc2, 0x01, 0x00, 0x00, 0x00]);
                jit_mem.emit_bytes(&[0x0f, 0x05]);
            }
            InstKind::JumpIfZero => {
                jit_mem.emit_bytes(&[0x41, 0x80, 0x7d, 0x00, 0x00]);
                bracket_stack.push(jit_mem.position);
                jit_mem.emit_bytes(&[0x0f, 0x84]);
                jit_mem.emit_u32(0);
            }
            InstKind::JumpIfNonZero => {
                let open_pos = bracket_stack.pop().expect("open bracket stack is empty");
                jit_mem.emit_bytes(&[0x41, 0x80, 0x7d, 0x00, 0x00]);
                let jump_back_from = jit_mem.position + 6;
                let jump_back_to = open_pos + 6;
                let pcrel_offset_back: u32 = if jump_back_to >= jump_back_from {
                    (jump_back_to - jump_back_from) as u32
                } else {
                    (!(jump_back_from - jump_back_to) + 1) as u32
                };
                jit_mem.emit_bytes(&[0x0f, 0x85]);
                jit_mem.emit_u32(pcrel_offset_back);

                let jump_forward_from = open_pos + 6;
                let jump_forward_to = jit_mem.position;
                let pcrel_offset_forward: u32 = if jump_forward_to >= jump_back_from {
                    (jump_forward_to - jump_forward_from) as u32
                } else {
                    (!(jump_forward_from - jump_forward_to) + 1) as u32
                };
                jit_mem[open_pos + 2] = (pcrel_offset_forward & 0xff) as u8;
                jit_mem[open_pos + 3] = ((pcrel_offset_forward >> 8) & 0xff) as u8;
                jit_mem[open_pos + 4] = ((pcrel_offset_forward >> 16) & 0xff) as u8;
                jit_mem[open_pos + 5] = ((pcrel_offset_forward >> 24) & 0xff) as u8;
            }
            InstKind::LoopSetToZero => {
                jit_mem.emit_bytes(&[0x41, 0xC6, 0x45, 0x00, 0x00]);
            }
            InstKind::LoopIncrPtr => {
                jit_mem.emit_bytes(&[0x41, 0x80, 0x7d, 0x00, 0x00]);
                jit_mem.emit_bytes(&[0x0f, 0x84]);
                jit_mem.emit_u32(0x12);
                jit_mem.emit_bytes(&[0x49, 0x81, 0xc5]);
                jit_mem.emit_u32(inst.arg as u32);
                jit_mem.emit_bytes(&[0x41, 0x80, 0x7d, 0x00, 0x00]);
                jit_mem.emit_bytes(&[0x0f, 0x85]);
                jit_mem.emit_u32(0xffffffee);
            }
            InstKind::LoopDecrPtr => {
                jit_mem.emit_bytes(&[0x41, 0x80, 0x7d, 0x00, 0x00]);
                jit_mem.emit_bytes(&[0x0f, 0x84]);
                jit_mem.emit_u32(0x12);
                jit_mem.emit_bytes(&[0x49, 0x81, 0xed]);
                jit_mem.emit_u32(inst.arg as u32);
                jit_mem.emit_bytes(&[0x41, 0x80, 0x7d, 0x00, 0x00]);
                jit_mem.emit_bytes(&[0x0f, 0x85]);
                jit_mem.emit_u32(0xffffffee);
            }
            InstKind::LoopMoveDataRight => {
                // mov    al,BYTE PTR [r13+0x0]
                jit_mem.emit_bytes(&[0x41, 0x8A, 0x45, 0x00]);
                // addb [r13+inst.arg], rax
                jit_mem.emit_bytes(&[0x41, 0x00, 0x85]);
                jit_mem.emit_u32(inst.arg as u32);
                // movb rax, 0
                jit_mem.emit_bytes(&[0x41, 0xC6, 0x45, 0x00, 0x00]);
            }
            InstKind::LoopMoveDataLeft => {
                // mov    al,BYTE PTR [r13+0x0]
                jit_mem.emit_bytes(&[0x41, 0x8A, 0x45, 0x00]);
                // addq [r13+inst.arg], rax
                jit_mem.emit_bytes(&[0x41, 0x00, 0x85]);
                jit_mem.emit_u32((!(inst.arg) + 1) as u32);
                // movb rax, 0
                jit_mem.emit_bytes(&[0x41, 0xC6, 0x45, 0x00, 0x00]);
            }
        }
        pc += 1;
    }
    jit_mem.emit_byte(0xc3);

    unsafe {
        let f: fn() -> i64 = mem::transmute(jit_mem.program);
        f();
    }

    Ok(())
}