ttvm 0.2.9

Runtime and compiler infrastructure API for Rust
Documentation
use super::*;

pub type CallError = mtk::Error;

#[derive(Clone)]
pub struct Routine {
    data: Vec<i128>,
    env: *mut Env
}

impl Routine {
    pub fn new(env: &mut Env) -> Routine {
        Routine {
            data: Vec::new(),
            env
        }
    }

    pub fn from(env: &mut Env, data: Vec<i128>) -> Routine {
        Routine { data, env }
    }

    pub fn push(&mut self, byte: i128) {
        self.data.push(byte)
    }

    pub fn pop(&mut self) -> Option<i128> {
        self.data.pop()
    }

    pub fn get(&self, index: usize) -> Option<&i128> {
        self.data.get(index)
    }

    pub fn get_mut(&mut self, index: usize) -> Option<&mut i128> {
        self.data.get_mut(index)
    }

    pub unsafe fn call(&mut self, argv: Vec<usize>) -> Result<Result<usize, usize>, CallError> {
        let mut pc = 0;

        let mut c: i128 = 0;
        let mut e: i128 = 0;

        while pc < self.data.len() {
            if self.data[pc] == ALLOC {
                pc += 1;

                let l = match self.data.get(pc) {
                    Some(some) => *some,
                    None => return Err(CallError::from(format!("can not get from index {}", pc + 1)))
                };

                c = match (*self.env).alloc(l as usize) {
                    Ok(ok) => ok as i128,
                    Err(err) => return Err(err.clone())
                };
            } else if self.data[pc] == DEALLOC {
                pc += 1;

                let l = match self.data.get(pc) {
                    Some(some) => *some,
                    None => return Err(CallError::from(format!("can not get from index {}", pc + 1)))
                };

                c = match (*self.env).dealloc(l as usize) {
                    Ok(ok) => ok as i128,
                    Err(err) => return Err(err.clone())
                };
            } else if self.data[pc] == THROW {
                pc += 1;

                let l = match self.data.get(pc) {
                    Some(some) => *some,
                    None => return Err(CallError::from(format!("can not get from index {}", pc + 1)))
                };

                return Ok(Err(l as usize));
            } else if self.data[pc] == RETURN {
                pc += 1;

                let l = match self.data.get(pc) {
                    Some(some) => *some,
                    None => return Err(CallError::from(format!("can not get from index {}", pc + 1)))
                };

                return Ok(Ok(l as usize));
            } else if self.data[pc] == CALL {
                pc += 1;

                let l = match self.data.get(pc) {
                    Some(some) => *some,
                    None => return Err(CallError::from(format!("can not get from index {}", pc + 1)))
                };

                pc += 1;

                let r = match self.data.get(pc) {
                    Some(some) => *some,
                    None => return Err(CallError::from(format!("can not get from index {}", pc + 1)))
                };

                let mut argv_p: Vec<usize> = Vec::new();

                match (*self.env).get_mem().get(r as usize) {
                    Some(some) => {
                        match some {
                            Some(some) => {
                                for elem in some.iter() {
                                    argv_p.push(*elem as usize);
                                }
                            },
                            None => return Err(CallError::from(format!("memory on address {} was deallocated", r)))
                        }
                    },
                    None => return Err(CallError::from(format!("no memory was allocated on address {}", r)))
                };
                
                let x = (*self.env).call(l as usize, argv_p);

                match x {
                    Ok(ok) => {
                        match ok {
                            Ok(ok) => c = ok as i128,
                            Err(err) => e = err as i128
                        }
                    },
                    Err(err) => return Err(err)
                };
            } else if self.data[pc] == RETURN_C {
                return Ok(Ok(c as usize));
            } else {
                pc += 1;
            }
        }

        Ok(Ok(0))
    }
}