-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
[move][stdlib] Implement mem::swap native move call #14786
Conversation
⏱️ 1h 45m total CI duration on this PR
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #14786 +/- ##
========================================
Coverage 60.1% 60.1%
========================================
Files 856 857 +1
Lines 211110 211341 +231
========================================
+ Hits 126962 127147 +185
- Misses 84148 84194 +46 ☔ View full report in Codecov by Sentry. |
What's this for? |
This is needed to be able to modify fields, when they hold a non-copyable non-dropable type. For example, you cannot do this today:
https://aptos-org.slack.com/archives/C05V6JEKZQ9/p1727393314700309 |
093a454
to
06d6cb3
Compare
@wrwg I'm also wondering if we should just make this a bytecode instruction. Can probably do it later though. |
efbef47
to
7c0fbc1
Compare
c5f381e
to
8b0d35b
Compare
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.
is there a way to unit-test call_native?
i.e. we are relying for a lot of tests in third_party/move/move-vm/types/src/values/value_tests.rs that are not failing checks internally, to fail checks when native call types get checked.
Otherwise I am not sure how to have that test coverage, as in end-to-end tests - such code would not compile.
8b0d35b
to
170eca3
Compare
170eca3
to
a99eccd
Compare
addressed all comments and added more tests |
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.
Pass 1: everything but the values
@@ -0,0 +1,27 @@ | |||
/// Module with methods for safe memory manipulation. | |||
/// I.e. swapping/replacing non-copyable/non-droppable types. |
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.
nit: I.e.
reads a bit weird, maybe For example
? Also why break into 2 sentences?
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 think the example is just redundant, removing. swap below has the docstring as well.
@@ -69,7 +69,7 @@ | |||
/// global operations. | |||
/// - V1 | |||
/// - TBA | |||
pub const LATEST_GAS_FEATURE_VERSION: u64 = gas_feature_versions::RELEASE_V1_22; | |||
pub const LATEST_GAS_FEATURE_VERSION: u64 = gas_feature_versions::RELEASE_V1_23; |
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.
Please add documentation to new 1.23 in the comment above that new natives have been added
aptos-move/aptos-release-builder/src/components/feature_flags.rs
Outdated
Show resolved
Hide resolved
// Copyright © Aptos Foundation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
// Copyright (c) The Diem Core Contributors |
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 think this is wrong, multiple licenses and why we even have Diem here?
|
||
/// The feature is not enabled. | ||
/// (0xD is unavailable) | ||
pub const EFEATURE_NOT_ENABLED: u64 = 0x0D_0001; |
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.
Can we document this in Move code? Running into these errors is such a pain because you need to search through aptos-core hoping to get the right constant....
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.
Also, don't we have errors::unavailable
Rust helper already? I think it exists in aptos-types
though...
@@ -317,6 +320,10 @@ impl Features { | |||
self.is_enabled(FeatureFlag::TRANSACTION_SIMULATION_ENHANCEMENT) | |||
} | |||
|
|||
pub fn is_native_memory_operations_enabled(&self) -> bool { |
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.
nit: are
instead of is
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.
everything is using is
?
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.
It just reads weird to me because it is plural, but maybe a personal taste
fn swap_contents(&self, other: &Self) -> PartialVMResult<()> { | ||
use Container::*; | ||
|
||
// TODO: check if unique ownership? |
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.
If you add a todo, add a github handle or create a ticket to track this so someone else can have more context about it.
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.
oh this was from Victor's change, missed it. removing, and adding comment.
/// Swap contents of two passed mutable references. | ||
public(friend) native fun swap<T>(left: &mut T, right: &mut T); | ||
|
||
/// Replace value reference points to with the given new value, |
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 think articles are missing, but I am not a native speaker 😄
debug_assert!(args.len() == 2); | ||
|
||
if args.len() != 2 { | ||
return Err(SafeNativeError::InvariantViolation(PartialVMError::new( |
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.
Add a message?
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.
oh I missed your previous review, addressing that one and the new one
aptos-move/aptos-release-builder/src/components/feature_flags.rs
Outdated
Show resolved
Hide resolved
@@ -0,0 +1,27 @@ | |||
/// Module with methods for safe memory manipulation. | |||
/// I.e. swapping/replacing non-copyable/non-droppable types. |
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 think the example is just redundant, removing. swap below has the docstring as well.
fn swap_contents(&self, other: &Self) -> PartialVMResult<()> { | ||
use Container::*; | ||
|
||
// TODO: check if unique ownership? |
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.
oh this was from Victor's change, missed it. removing, and adding comment.
@@ -317,6 +320,10 @@ impl Features { | |||
self.is_enabled(FeatureFlag::TRANSACTION_SIMULATION_ENHANCEMENT) | |||
} | |||
|
|||
pub fn is_native_memory_operations_enabled(&self) -> bool { |
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.
everything is using is
?
23c63a3
to
c95646e
Compare
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.
Few minor comments
* gas cost: MEM_SWAP_BASE | ||
* | ||
**************************************************************************************************/ | ||
fn native_swap( |
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.
maybe add a comment that function pre-condition is that the two references are not the same.
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.
here we generally don't put much. but added into mem.move and into value_impl.rs, same places as we did for vector::move_range.
@@ -0,0 +1,65 @@ | |||
#[test_only] | |||
module std::mem_tests { |
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.
@igor-aptos
specialized indexed references are references to vec, vec, etc....
indexed ref is a reference to a, for instance, struct member, and vec
let a = 1; | ||
let b = 2; | ||
let v = vector[3, 4, 5, 6]; | ||
|
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.
Maybe add a struct with an integral member, and test swap with the member?
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.
see below
}}; | ||
} | ||
|
||
macro_rules! swap_g_s { |
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.
swap_general_with_specialized
, etc...
let's lower the future code readers' cognitive load.
c95646e
to
ac25522
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
assert!(&s2 == &SomeStruct { f: 8, v: vector[9, 10]}, 6); | ||
assert!(vector::borrow(&vs, 0) == &SomeStruct { f: 2, v: vector[3, 4]}, 7); | ||
|
||
swap(&mut s1.f, vector::borrow_mut(&mut v, 0)); |
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.
Maybe add a struct with an integral member, and test swap with the member?
this line should cover that?
let a = 1; | ||
let b = 2; | ||
let v = vector[3, 4, 5, 6]; | ||
|
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.
see below
@@ -0,0 +1,65 @@ | |||
#[test_only] | |||
module std::mem_tests { |
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 think tests now mostly cover things, but if you see anything that would be useful to add, let me know
* gas cost: MEM_SWAP_BASE | ||
* | ||
**************************************************************************************************/ | ||
fn native_swap( |
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.
here we generally don't put much. but added into mem.move and into value_impl.rs, same places as we did for vector::move_range.
✅ Forge suite
|
✅ Forge suite
|
✅ Forge suite
|
## Description If we have a field that contains non-copyable type, it is impossible to change it, and get the old value back. Adding two methods: * native mem::swap, that implements swap of contents of two mutable references * mem::replace, as a simple wrapper based on mem::swap ## How Has This Been Tested? provided unit tests ## Type of Change - [x] New feature ## Which Components or Systems Does This Change Impact? - [x] Move/Aptos Virtual Machine
Description
If we have a field that contains non-copyable type, it is impossible to change it, and get the old value back.
Adding two methods:
How Has This Been Tested?
provided unit tests
Type of Change
Which Components or Systems Does This Change Impact?
Checklist