evmjit homestead merge, compiles but tests do not pass yet
This commit is contained in:
		
							parent
							
								
									c5b81270a8
								
							
						
					
					
						commit
						3030b18683
					
				| @ -174,28 +174,37 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { | ||||
| 	fn call(&mut self, | ||||
| 				io_gas: *mut u64, | ||||
| 				call_gas: u64, | ||||
| 				sender_address: *const evmjit::H256, | ||||
| 				receive_address: *const evmjit::H256, | ||||
| 				value: *const evmjit::I256, | ||||
| 				code_address: *const evmjit::H256, | ||||
| 				transfer_value: *const evmjit::I256, | ||||
| 				_apparent_value: *const evmjit::I256, | ||||
| 				in_beg: *const u8, | ||||
| 				in_size: u64, | ||||
| 				out_beg: *mut u8, | ||||
| 				out_size: u64, | ||||
| 				code_address: *const evmjit::H256) -> bool { | ||||
| 				out_size: u64) -> bool { | ||||
| 
 | ||||
| 		let mut gas = unsafe { U256::from(*io_gas) }; | ||||
| 		let mut call_gas = U256::from(call_gas); | ||||
| 		let mut gas_cost = call_gas; | ||||
| 		let sender_address = unsafe { Address::from_jit(&*sender_address) }; | ||||
| 		let receive_address = unsafe { Address::from_jit(&*receive_address) }; | ||||
| 		let code_address = unsafe { Address::from_jit(&*code_address) }; | ||||
| 		let value = unsafe { U256::from_jit(&*value) }; | ||||
| 		let transfer_value = unsafe { U256::from_jit(&*transfer_value) }; | ||||
| 		let mut value = Some(transfer_value); | ||||
| 
 | ||||
| 		// receive address and code address are the same in normal calls
 | ||||
| 		let is_callcode = receive_address != code_address; | ||||
| 		if !is_callcode { | ||||
| 			// it's a delegatecall... fix it better.
 | ||||
| 			value = None; | ||||
| 		} | ||||
| 
 | ||||
| 		if !is_callcode && !self.ext.exists(&code_address) { | ||||
| 			gas_cost = gas_cost + U256::from(self.ext.schedule().call_new_account_gas); | ||||
| 		} | ||||
| 
 | ||||
| 		if value > U256::zero() { | ||||
| 		if transfer_value > U256::zero() { | ||||
| 			assert!(self.ext.schedule().call_value_transfer_gas > self.ext.schedule().call_stipend, "overflow possible"); | ||||
| 			gas_cost = gas_cost + U256::from(self.ext.schedule().call_value_transfer_gas); | ||||
| 			call_gas = call_gas + U256::from(self.ext.schedule().call_stipend); | ||||
| @ -211,7 +220,7 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { | ||||
| 		gas = gas - gas_cost; | ||||
| 
 | ||||
| 		// check if balance is sufficient and we are not too deep
 | ||||
| 		if self.ext.balance(&self.address) < value || self.ext.depth() >= self.ext.schedule().max_depth { | ||||
| 		if self.ext.balance(&self.address) < transfer_value || self.ext.depth() >= self.ext.schedule().max_depth { | ||||
| 			unsafe { | ||||
| 				*io_gas = (gas + call_gas).low_u64(); | ||||
| 				return false; | ||||
| @ -220,9 +229,9 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { | ||||
| 
 | ||||
| 		match self.ext.call( | ||||
| 					  &call_gas, 
 | ||||
| 					  &self.address, | ||||
| 					  &sender_address, | ||||
| 					  &receive_address, 
 | ||||
| 					  Some(value), | ||||
| 					  value, | ||||
| 					  unsafe { slice::from_raw_parts(in_beg, in_size as usize) }, | ||||
| 					  &code_address, | ||||
| 					  unsafe { slice::from_raw_parts_mut(out_beg, out_size as usize) }) { | ||||
| @ -305,11 +314,20 @@ impl evm::Evm for JitEvm { | ||||
| 		data.address = params.address.into_jit(); | ||||
| 		data.caller = params.sender.into_jit(); | ||||
| 		data.origin = params.origin.into_jit(); | ||||
| 		data.call_value = match params.value { | ||||
| 			ActionValue::Transfer(val) => val.into_jit(), | ||||
| 			ActionValue::Apparent(val) => val.into_jit() | ||||
| 		match params.value { | ||||
| 			ActionValue::Transfer(val) => { | ||||
| 				data.transfer_value = val.into_jit(); | ||||
| 				data.apparent_value = U256::zero().into_jit(); | ||||
| 			}, | ||||
| 			ActionValue::Apparent(val) => { | ||||
| 				data.transfer_value = U256::zero().into_jit(); | ||||
| 				data.apparent_value = val.into_jit(); | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
| 		let mut schedule = evmjit::ScheduleHandle::new(); | ||||
| 		schedule.have_delegate_call = ext.schedule().have_delegate_call; | ||||
| 
 | ||||
| 		data.author = ext.env_info().author.clone().into_jit(); | ||||
| 		data.difficulty = ext.env_info().difficulty.into_jit(); | ||||
| 		data.gas_limit = ext.env_info().gas_limit.into_jit(); | ||||
| @ -317,7 +335,7 @@ impl evm::Evm for JitEvm { | ||||
| 		// don't really know why jit timestamp is int..
 | ||||
| 		data.timestamp = ext.env_info().timestamp as i64; | ||||
| 
 | ||||
| 		let mut context = unsafe { evmjit::ContextHandle::new(data, &mut ext_handle) }; | ||||
| 		let mut context = unsafe { evmjit::ContextHandle::new(data, schedule, &mut ext_handle) }; | ||||
| 		let res = context.exec(); | ||||
| 		
 | ||||
| 		match res { | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| [package] | ||||
| name = "evmjit" | ||||
| version = "0.1.0" | ||||
| version = "0.9.0" | ||||
| authors = ["debris <marek.kotewicz@gmail.com>"] | ||||
| 
 | ||||
| [lib] | ||||
|  | ||||
| @ -45,7 +45,7 @@ pub use self::ffi::JitH256 as H256; | ||||
| /// Takes care of proper initialization and destruction of `RuntimeData`.
 | ||||
| ///
 | ||||
| /// This handle must be used to create runtime data,
 | ||||
| /// cause underneath it's a `C++` structure. Incombatible with rust
 | ||||
| /// cause underneath it's a `C++` structure. Incompatible with rust
 | ||||
| /// structs.
 | ||||
| pub struct RuntimeDataHandle { | ||||
| 	runtime_data: *mut JitRuntimeData | ||||
| @ -58,16 +58,6 @@ impl RuntimeDataHandle { | ||||
| 			runtime_data: unsafe { evmjit_create_runtime_data() } | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/// Returns immutable reference to runtime data.
 | ||||
| 	pub fn runtime_data(&self) -> &JitRuntimeData { | ||||
| 		unsafe { &*self.runtime_data } | ||||
| 	} | ||||
| 
 | ||||
| 	/// Returns mutable reference to runtime data.
 | ||||
| 	pub fn mut_runtime_data(&mut self) -> &mut JitRuntimeData { | ||||
| 		unsafe { &mut *self.runtime_data } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Drop for RuntimeDataHandle { | ||||
| @ -80,13 +70,51 @@ impl Deref for RuntimeDataHandle { | ||||
| 	type Target = JitRuntimeData; | ||||
| 
 | ||||
| 	fn deref(&self) -> &Self::Target { | ||||
| 		self.runtime_data() | ||||
| 		unsafe { &*self.runtime_data } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl DerefMut for RuntimeDataHandle { | ||||
| 	fn deref_mut(&mut self) -> &mut Self::Target { | ||||
| 		self.mut_runtime_data() | ||||
| 		unsafe { &mut *self.runtime_data } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// Takes care of proper initilization and destruction of `JitSchedule`.
 | ||||
| /// 
 | ||||
| /// This handle must be used to jit schedule,
 | ||||
| /// cause underneath it's a `C++` structure. Incompatible with rust
 | ||||
| /// structs.
 | ||||
| pub struct ScheduleHandle { | ||||
| 	schedule: *mut JitSchedule | ||||
| } | ||||
| 
 | ||||
| impl ScheduleHandle { | ||||
| 	/// Creates new `Schedule` handle.
 | ||||
| 	pub fn new() -> Self { | ||||
| 		ScheduleHandle { | ||||
| 			schedule: unsafe { evmjit_create_schedule() } | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Drop for ScheduleHandle { | ||||
| 	fn drop(&mut self) { | ||||
| 		unsafe { evmjit_destroy_schedule(self.schedule) } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Deref for ScheduleHandle { | ||||
| 	type Target = JitSchedule; | ||||
| 
 | ||||
| 	fn deref(&self) -> &Self::Target { | ||||
| 		unsafe { &*self.schedule } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl DerefMut for ScheduleHandle { | ||||
| 	fn deref_mut(&mut self) -> &mut Self::Target { | ||||
| 		unsafe { &mut *self.schedule } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -98,6 +126,7 @@ impl DerefMut for RuntimeDataHandle { | ||||
| pub struct ContextHandle { | ||||
| 	context: *mut JitContext, | ||||
| 	data_handle: RuntimeDataHandle, | ||||
| 	schedule_handle: ScheduleHandle | ||||
| } | ||||
| 
 | ||||
| impl ContextHandle { | ||||
| @ -107,19 +136,20 @@ impl ContextHandle { | ||||
| 	/// We also can't make ExtHandle a member of `ContextHandle` structure,
 | ||||
| 	/// cause this would be a move operation or it would require a template 
 | ||||
| 	/// lifetime to a reference. Both solutions are not possible.
 | ||||
| 	pub unsafe fn new(data_handle: RuntimeDataHandle, ext: &mut ExtHandle) -> Self { | ||||
| 	pub unsafe fn new(data_handle: RuntimeDataHandle, schedule_handle: ScheduleHandle, ext: &mut ExtHandle) -> Self { | ||||
| 		let mut handle = ContextHandle { | ||||
| 			context: std::mem::uninitialized(), | ||||
| 			schedule_handle: schedule_handle, | ||||
| 			data_handle: data_handle, | ||||
| 		}; | ||||
| 
 | ||||
| 		handle.context = evmjit_create_context(handle.data_handle.mut_runtime_data(), ext); | ||||
| 		handle.context = evmjit_create_context(handle.data_handle.deref_mut(), ext); | ||||
| 		handle | ||||
| 	} | ||||
| 
 | ||||
| 	/// Executes context.
 | ||||
| 	pub fn exec(&mut self) -> JitReturnCode { | ||||
| 		unsafe { evmjit_exec(self.context) } | ||||
| 		unsafe { evmjit_exec(self.context, self.schedule_handle.deref_mut()) } | ||||
| 	} | ||||
| 
 | ||||
| 	/// Returns output data.
 | ||||
| @ -162,13 +192,15 @@ pub trait Ext { | ||||
| 	fn call(&mut self, | ||||
| 				io_gas: *mut u64, | ||||
| 				call_gas: u64, | ||||
| 				sender_address: *const JitH256, | ||||
| 				receive_address: *const JitH256, | ||||
| 				value: *const JitI256, | ||||
| 				code_address: *const JitH256, | ||||
| 				transfer_value: *const JitI256, | ||||
| 				apparent_value: *const JitI256, | ||||
| 				in_beg: *const u8, | ||||
| 				in_size: u64, | ||||
| 				out_beg: *mut u8, | ||||
| 				out_size: u64, | ||||
| 				code_address: *const JitH256) -> bool; | ||||
| 				out_size: u64) -> bool; | ||||
| 
 | ||||
| 	fn log(&mut self, | ||||
| 		   beg: *const u8, | ||||
| @ -292,7 +324,8 @@ pub mod ffi { | ||||
| 		pub address: JitI256, | ||||
| 		pub caller: JitI256, | ||||
| 		pub origin: JitI256, | ||||
| 		pub call_value: JitI256, | ||||
| 		pub transfer_value: JitI256, | ||||
| 		pub apparent_value: JitI256, | ||||
| 		pub author: JitI256, | ||||
| 		pub difficulty: JitI256, | ||||
| 		pub gas_limit: JitI256, | ||||
| @ -303,6 +336,13 @@ pub mod ffi { | ||||
| 		pub code_hash: JitI256 | ||||
| 	} | ||||
| 
 | ||||
| 	#[repr(C)] | ||||
| 	#[derive(Debug)] | ||||
| 	/// Configurable properties of git schedule.
 | ||||
| 	pub struct JitSchedule { | ||||
| 		pub have_delegate_call: bool | ||||
| 	} | ||||
| 
 | ||||
| 	#[no_mangle] | ||||
| 	pub unsafe extern "C" fn env_sload(ext: *const ExtHandle, index: *const JitI256, out_value: *mut JitI256) { | ||||
| 		let ext = &*ext; | ||||
| @ -342,15 +382,17 @@ pub mod ffi { | ||||
| 	pub unsafe extern "C" fn env_call(ext: *mut ExtHandle, 
 | ||||
| 						   io_gas: *mut u64, | ||||
| 						   call_gas: u64, | ||||
| 						   sender_address: *const JitH256, | ||||
| 						   receive_address: *const JitH256, | ||||
| 						   value: *const JitI256, | ||||
| 						   code_address: *const JitH256, | ||||
| 						   transfer_value: *const JitI256, | ||||
| 						   apparent_value: *const JitI256, | ||||
| 						   in_beg: *const u8, | ||||
| 						   in_size: u64, | ||||
| 						   out_beg: *mut u8, | ||||
| 						   out_size: u64, | ||||
| 						   code_address: *const JitH256) -> bool { | ||||
| 						   out_size: u64) -> bool { | ||||
| 		let ext = &mut *ext; | ||||
| 		ext.call(io_gas, call_gas, receive_address, value, in_beg, in_size, out_beg, out_size, code_address) | ||||
| 		ext.call(io_gas, call_gas, sender_address, receive_address, code_address, transfer_value, apparent_value, in_beg, in_size, out_beg, out_size) | ||||
| 	} | ||||
| 
 | ||||
| 	#[no_mangle] | ||||
| @ -385,10 +427,12 @@ pub mod ffi { | ||||
| 
 | ||||
| 	#[link(name="evmjit")] | ||||
| 	extern "C" { | ||||
| 		pub fn evmjit_create_schedule() -> *mut JitSchedule; | ||||
| 		pub fn evmjit_destroy_schedule(schedule: *mut JitSchedule); | ||||
| 		pub fn evmjit_create_runtime_data() -> *mut JitRuntimeData; | ||||
| 		pub fn evmjit_destroy_runtime_data(data: *mut JitRuntimeData); | ||||
| 		pub fn evmjit_destroy_context(context: *mut JitContext); | ||||
| 		pub fn evmjit_exec(context: *mut JitContext) -> JitReturnCode; | ||||
| 		pub fn evmjit_exec(context: *mut JitContext, schedule: *mut JitSchedule) -> JitReturnCode; | ||||
| 	} | ||||
| 
 | ||||
| 	// ExtHandle is not a C type, so we need to allow "improper_ctypes" 
 | ||||
| @ -403,11 +447,13 @@ pub mod ffi { | ||||
| fn ffi_test() { | ||||
| 	unsafe { | ||||
| 		let data = evmjit_create_runtime_data(); | ||||
| 		let schedule = evmjit_create_schedule(); | ||||
| 		let context = evmjit_create_context(data, &mut ExtHandle::empty()); | ||||
| 
 | ||||
| 		let code = evmjit_exec(context); | ||||
| 		let code = evmjit_exec(context, schedule); | ||||
| 		assert_eq!(code, JitReturnCode::Stop); | ||||
| 
 | ||||
| 		evmjit_destroy_schedule(schedule); | ||||
| 		evmjit_destroy_runtime_data(data); | ||||
| 		evmjit_destroy_context(context); | ||||
| 	} | ||||
| @ -416,7 +462,8 @@ fn ffi_test() { | ||||
| #[test] | ||||
| fn handle_test() { | ||||
| 	unsafe { | ||||
| 		let mut context = ContextHandle::new(RuntimeDataHandle::new(), &mut ExtHandle::empty()); | ||||
| 		let mut ext = ExtHandle::empty(); | ||||
| 		let mut context = ContextHandle::new(RuntimeDataHandle::new(), ScheduleHandle::new(), &mut ext); | ||||
| 		assert_eq!(context.exec(), ReturnCode::Stop); | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user