Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Fixing Delegate Call in JIT #2378

Merged
merged 2 commits into from
Sep 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions ethcore/src/evm/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
receive_address: *const evmjit::H256,
code_address: *const evmjit::H256,
transfer_value: *const evmjit::I256,
// We are ignoring apparent value - it's handled in externalities.
_apparent_value: *const evmjit::I256,
in_beg: *const u8,
in_size: u64,
Expand All @@ -208,12 +209,13 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
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) };
// TODO Is it always safe in case of DELEGATE_CALL?
let transfer_value = unsafe { U256::from_jit(&*transfer_value) };
let value = Some(transfer_value);

// receive address and code address are the same in normal calls
let is_callcode = receive_address != code_address;
let is_delegatecall = is_callcode && sender_address != receive_address;

let value = if is_delegatecall { None } else { Some(transfer_value) };

if !is_callcode && !self.ext.exists(&code_address) {
gas_cost = gas_cost + U256::from(self.ext.schedule().call_new_account_gas);
Expand Down Expand Up @@ -242,10 +244,10 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
}
}

// TODO [ToDr] Any way to detect DelegateCall?
let call_type = match is_callcode {
true => CallType::CallCode,
false => CallType::Call,
let call_type = match (is_callcode, is_delegatecall) {
(_, true) => CallType::DelegateCall,
(true, false) => CallType::CallCode,
(false, false) => CallType::Call,
};

match self.ext.call(
Expand Down
13 changes: 9 additions & 4 deletions ethcore/src/executive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,8 +589,11 @@ mod tests {
assert_eq!(substate.contracts_created.len(), 0);
}

evm_test!{test_call_to_create: test_call_to_create_jit, test_call_to_create_int}
fn test_call_to_create(factory: Factory) {
#[test]
// Tracing is not suported in JIT
fn test_call_to_create() {
let factory = Factory::new(VMType::Interpreter);

// code:
//
// 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes?
Expand Down Expand Up @@ -712,8 +715,10 @@ mod tests {
assert_eq!(vm_tracer.drain().unwrap(), expected_vm_trace);
}

evm_test!{test_create_contract: test_create_contract_jit, test_create_contract_int}
fn test_create_contract(factory: Factory) {
#[test]
fn test_create_contract() {
// Tracing is not supported in JIT
let factory = Factory::new(VMType::Interpreter);
// code:
//
// 60 10 - push 16
Expand Down