From 77597ae06c24c754f228ef494cc8b0329964a2c8 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Mon, 30 Sep 2019 16:03:34 +0200 Subject: [PATCH] Add the bignum add256 and sub256 host funcs --- Cargo.toml | 1 + src/main.rs | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 8de0544..137eb09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,4 @@ serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.8" log = "0.4" env_logger = "0.7" +primitive-types = "0.6" diff --git a/src/main.rs b/src/main.rs index 5bb90c7..78feed7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ extern crate wasmi; extern crate log; extern crate env_logger; +use primitive_types::U256; use rustc_hex::{FromHex, ToHex}; use serde::{Deserialize, Serialize}; use std::env; @@ -29,6 +30,8 @@ const DEBUG_PRINT32_FUNC: usize = 6; const DEBUG_PRINT64_FUNC: usize = 7; const DEBUG_PRINTMEM_FUNC: usize = 8; const DEBUG_PRINTMEMHEX_FUNC: usize = 9; +const BIGNUM_ADD256_FUNC: usize = 10; +const BIGNUM_SUB256_FUNC: usize = 11; struct Runtime<'a> { ticks_left: u32, @@ -166,6 +169,64 @@ impl<'a> Externals for Runtime<'a> { debug!("print.hex: {}", buf.to_hex()); Ok(None) } + BIGNUM_ADD256_FUNC => { + let a_ptr: u32 = args.nth(0); + let b_ptr: u32 = args.nth(1); + let c_ptr: u32 = args.nth(2); + + let mut a_raw = [0u8; 32]; + let mut b_raw = [0u8; 32]; + let mut c_raw = [0u8; 32]; + + let memory = self.memory.as_ref().expect("expects memory object"); + memory + .get_into(a_ptr, &mut a_raw) + .expect("expects reading from memory to succeed"); + memory + .get_into(b_ptr, &mut b_raw) + .expect("expects reading from memory to succeed"); + + let a = U256::from_big_endian(&a_raw); + let b = U256::from_big_endian(&b_raw); + let c = a.checked_add(b).expect("expects non-overflowing addition"); + c.to_big_endian(&mut c_raw); + + memory + .set(c_ptr, &c_raw) + .expect("expects writing to memory to succeed"); + + Ok(None) + } + BIGNUM_SUB256_FUNC => { + let a_ptr: u32 = args.nth(0); + let b_ptr: u32 = args.nth(1); + let c_ptr: u32 = args.nth(2); + + let mut a_raw = [0u8; 32]; + let mut b_raw = [0u8; 32]; + let mut c_raw = [0u8; 32]; + + let memory = self.memory.as_ref().expect("expects memory object"); + memory + .get_into(a_ptr, &mut a_raw) + .expect("expects reading from memory to succeed"); + memory + .get_into(b_ptr, &mut b_raw) + .expect("expects reading from memory to succeed"); + + let a = U256::from_big_endian(&a_raw); + let b = U256::from_big_endian(&b_raw); + let c = a + .checked_sub(b) + .expect("expects non-overflowing subtraction"); + c.to_big_endian(&mut c_raw); + + memory + .set(c_ptr, &c_raw) + .expect("expects writing to memory to succeed"); + + Ok(None) + } _ => panic!("unknown function index"), } } @@ -220,6 +281,14 @@ impl<'a> ModuleImportResolver for RuntimeModuleImportResolver { Signature::new(&[ValueType::I32, ValueType::I32][..], None), DEBUG_PRINTMEMHEX_FUNC, ), + "bignum_add256" => FuncInstance::alloc_host( + Signature::new(&[ValueType::I32, ValueType::I32, ValueType::I32][..], None), + BIGNUM_ADD256_FUNC, + ), + "bignum_sub256" => FuncInstance::alloc_host( + Signature::new(&[ValueType::I32, ValueType::I32, ValueType::I32][..], None), + BIGNUM_SUB256_FUNC, + ), _ => { return Err(InterpreterError::Function(format!( "host module doesn't export function with name {}",