Skip to content

Commit

Permalink
fix swap between same IndexedRef
Browse files Browse the repository at this point in the history
  • Loading branch information
igor-aptos committed Oct 21, 2024
1 parent 1aca75f commit 1c4d24e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
gas_feature_versions::{RELEASE_V1_18, RELEASE_V1_23},
gas_schedule::NativeGasParameters,
};
use aptos_gas_algebra::{InternalGas, InternalGasPerAbstractValueUnit, InternalGasPerByte};
use aptos_gas_algebra::{InternalGas, InternalGasPerByte};

crate::gas_schedule::macros::define_gas_parameters!(
MoveStdlibGasParameters,
Expand Down
38 changes: 35 additions & 3 deletions aptos-move/framework/move-stdlib/tests/mem_tests.move
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ module std::mem_tests {
assert!(vector::borrow(&v, 2) == &3, 1);
}


#[test]
fun test_replace_ints() {
let a = 1;
Expand All @@ -33,19 +32,19 @@ module std::mem_tests {
}

#[test_only]
struct SomeStruct has drop {
struct SomeStruct has drop, key {
f: u64,
v: vector<u64>,
}

#[test]
fun test_swap_struct() {
let a = 1;
let v = vector[20, 21];
let s1 = SomeStruct { f: 2, v: vector[3, 4]};
let s2 = SomeStruct { f: 5, v: vector[6, 7]};
let vs = vector[SomeStruct { f: 8, v: vector[9, 10]}, SomeStruct { f: 11, v: vector[12, 13]}];


swap(&mut s1, &mut s2);
assert!(&s1 == &SomeStruct { f: 5, v: vector[6, 7]}, 0);
assert!(&s2 == &SomeStruct { f: 2, v: vector[3, 4]}, 1);
Expand All @@ -61,5 +60,38 @@ module std::mem_tests {
swap(&mut s2, vector::borrow_mut(&mut vs, 0));
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));
assert!(&s1.f == &20, 8);
assert!(vector::borrow(&v, 0) == &6, 9);
}

#[test(creator = @0xcafe)]
fun test_swap_resource(creator: &signer) acquires SomeStruct {
use std::signer;
{
move_to(creator, SomeStruct { f: 5, v: vector[6, 7]});
};

{
let value = borrow_global_mut<SomeStruct>(signer::address_of(creator));
let s1 = SomeStruct { f: 2, v: vector[3, 4]};
let vs = vector[SomeStruct { f: 8, v: vector[9, 10]}, SomeStruct { f: 11, v: vector[12, 13]}];

swap(&mut s1, value);
assert!(&s1 == &SomeStruct { f: 5, v: vector[6, 7]}, 0);
assert!(value == &SomeStruct { f: 2, v: vector[3, 4]}, 1);

swap(value, vector::borrow_mut(&mut vs, 0));
assert!(value == &SomeStruct { f: 8, v: vector[9, 10]}, 2);
assert!(vector::borrow(&vs, 0) == &SomeStruct { f: 2, v: vector[3, 4]}, 3);

let v_ref = &mut value.v;
let other_v = vector[11,12];
swap(v_ref, &mut other_v);

assert!(v_ref == &vector[11, 12], 4);
assert!(&other_v == &vector[9, 10], 5);
}
}
}
24 changes: 18 additions & 6 deletions third_party/move/move-vm/types/src/values/values_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -992,12 +992,24 @@ impl IndexedRef {
use Container::*;

macro_rules! swap {
($r1:ident, $r2:ident) => {
mem::swap(
&mut $r1.borrow_mut()[self.idx],
&mut $r2.borrow_mut()[other.idx],
)
};
($r1:ident, $r2:ident) => {{
if Rc::ptr_eq($r1, $r2) {
if self.idx == other.idx {
return Err(PartialVMError::new(StatusCode::INTERNAL_TYPE_ERROR)
.with_message(format!(
"cannot swap references to the same item {:?}",
self
)));
}

$r1.borrow_mut().swap(self.idx, other.idx);
} else {
mem::swap(
&mut $r1.borrow_mut()[self.idx],
&mut $r2.borrow_mut()[other.idx],
)
}
}};
}

macro_rules! swap_g_s {
Expand Down

0 comments on commit 1c4d24e

Please sign in to comment.