-
Notifications
You must be signed in to change notification settings - Fork 966
deduplication for COPY operations #1655
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
9d196f3
6b15eee
1b72873
0453a50
9c685ad
dbc2d57
1474059
a1a488b
f92ff49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,23 +38,17 @@ pub fn codesize<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) | |
|
|
||
| pub fn codecopy<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) { | ||
| pop!(interpreter, memory_offset, code_offset, len); | ||
| let len = as_usize_or_fail!(interpreter, len); | ||
| gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); | ||
| if len == 0 { | ||
| return; | ||
| } | ||
| let memory_offset = as_usize_or_fail!(interpreter, memory_offset); | ||
| let code_offset = as_usize_saturated!(code_offset); | ||
| resize_memory!(interpreter, memory_offset, len); | ||
|
|
||
| let len = as_usize_or_fail!(interpreter, len); | ||
| // Inform the optimizer that the bytecode cannot be EOF to remove a bounds check. | ||
| assume!(!interpreter.contract.bytecode.is_eof()); | ||
| // Note: this can't panic because we resized memory to fit. | ||
| interpreter.shared_memory.set_data( | ||
| let source = interpreter.contract.bytecode.original_byte_slice(); | ||
| copy_to_memory( | ||
| interpreter, | ||
| memory_offset, | ||
| code_offset, | ||
| len, | ||
| interpreter.contract.bytecode.original_byte_slice(), | ||
| source as *const [u8], | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -94,20 +88,14 @@ pub fn callvalue<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) | |
| pub fn calldatacopy<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) { | ||
| pop!(interpreter, memory_offset, data_offset, len); | ||
| let len = as_usize_or_fail!(interpreter, len); | ||
| gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); | ||
| if len == 0 { | ||
| return; | ||
| } | ||
| let memory_offset = as_usize_or_fail!(interpreter, memory_offset); | ||
| let data_offset = as_usize_saturated!(data_offset); | ||
| resize_memory!(interpreter, memory_offset, len); | ||
|
|
||
| // Note: this can't panic because we resized memory to fit. | ||
| interpreter.shared_memory.set_data( | ||
| let source = interpreter.contract.input.as_ref(); | ||
| copy_to_memory( | ||
| interpreter, | ||
| memory_offset, | ||
| data_offset, | ||
| len, | ||
| &interpreter.contract.input, | ||
| source as *const [u8], | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -127,8 +115,6 @@ pub fn returndatacopy<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interprete | |
| pop!(interpreter, memory_offset, offset, len); | ||
|
|
||
| let len = as_usize_or_fail!(interpreter, len); | ||
| gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); | ||
|
|
||
| let data_offset = as_usize_saturated!(offset); | ||
| let data_end = data_offset.saturating_add(len); | ||
|
|
||
|
|
@@ -139,21 +125,13 @@ pub fn returndatacopy<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interprete | |
| return; | ||
| } | ||
|
|
||
| // if len is zero memory is not resized. | ||
| if len == 0 { | ||
| return; | ||
| } | ||
|
|
||
| // resize memory | ||
| let memory_offset = as_usize_or_fail!(interpreter, memory_offset); | ||
| resize_memory!(interpreter, memory_offset, len); | ||
|
|
||
| // Note: this can't panic because we resized memory to fit. | ||
| interpreter.shared_memory.set_data( | ||
| let source = interpreter.return_data_buffer.as_ref(); | ||
| copy_to_memory( | ||
| interpreter, | ||
| memory_offset, | ||
| data_offset, | ||
| len, | ||
| &interpreter.return_data_buffer, | ||
| source as *const [u8], | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -179,6 +157,29 @@ pub fn returndataload<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &m | |
| *offset = B256::from(output).into(); | ||
| } | ||
|
|
||
| // common logic for copying data from a source buffer to the EVM's memory | ||
| fn copy_to_memory( | ||
| interpreter: &mut Interpreter, | ||
| memory_offset: U256, | ||
| data_offset: usize, | ||
| len: usize, | ||
| source: *const [u8], | ||
| ) { | ||
| gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); | ||
| if len == 0 { | ||
| return; | ||
| } | ||
| let memory_offset = as_usize_or_fail!(interpreter, memory_offset); | ||
| resize_memory!(interpreter, memory_offset, len); | ||
|
|
||
| // Note: this can't panic because we resized memory to fit. | ||
| unsafe { | ||
| interpreter | ||
| .shared_memory | ||
| .set_data(memory_offset, data_offset, len, &*source); | ||
| } | ||
| } | ||
|
||
|
|
||
| pub fn gas<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) { | ||
| gas!(interpreter, gas::BASE); | ||
| push!(interpreter, U256::from(interpreter.gas.remaining())); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would return a
Option<usize>here that represents memory_offset.https://github.com/bluealloy/revm/pull/1655/files#r1694998333
Without return function silently fails, and can work only if it is in the last line of instruction.