From ca06b3fadd763c1a36b8a420f8d8b27f96ce118a Mon Sep 17 00:00:00 2001 From: Runtian Zhou Date: Wed, 22 Mar 2023 15:33:42 -0700 Subject: [PATCH] fixup! Add interface example --- .../example/coin_interface/coin_interface.exp | 2 +- .../coin_interface/coin_interface.mvir | 120 +++++++++++++++++- 2 files changed, 117 insertions(+), 5 deletions(-) diff --git a/language/move-vm/transactional-tests/tests/function_pointers/example/coin_interface/coin_interface.exp b/language/move-vm/transactional-tests/tests/function_pointers/example/coin_interface/coin_interface.exp index b134af1aea..f33e2b18fc 100644 --- a/language/move-vm/transactional-tests/tests/function_pointers/example/coin_interface/coin_interface.exp +++ b/language/move-vm/transactional-tests/tests/function_pointers/example/coin_interface/coin_interface.exp @@ -1 +1 @@ -processed 5 tasks +processed 8 tasks diff --git a/language/move-vm/transactional-tests/tests/function_pointers/example/coin_interface/coin_interface.mvir b/language/move-vm/transactional-tests/tests/function_pointers/example/coin_interface/coin_interface.mvir index 47fd5137c1..41336c5ca7 100644 --- a/language/move-vm/transactional-tests/tests/function_pointers/example/coin_interface/coin_interface.mvir +++ b/language/move-vm/transactional-tests/tests/function_pointers/example/coin_interface/coin_interface.mvir @@ -25,6 +25,24 @@ module 0x42.CoinInterface { label b0: return *&move(self).T::merge; } + + public value(self: &Self.T, coin: &T): u64 { + let value: |&T| (u64); + let ret: u64; + label b0: + value = *&move(self).T::value; + ret = call_function_pointer<|&T| (u64)>(move(coin), move(value)); + return move(ret); + } + + public split(self: &Self.T, coin: &mut T, amount: u64): T { + let split: |&mut T, u64| (T); + let ret: T; + label b0: + split = *&move(self).T::split; + ret = call_function_pointer<|&mut T, u64| (T)>(move(coin), move(amount), move(split)); + return move(ret); + } } //# publish @@ -80,6 +98,59 @@ module 0x42.BasicCoin1 { } } + +//# publish +module 0x42.BasicCoin2 { + import 0x42.CoinInterface; + + struct Coin has store, drop { value: u64 } + + public zero(): Self.Coin { + label b0: + return Coin { value: 0 }; + } + + public mint(value: u64): Self.Coin { + label b0: + return Coin { value: move(value) }; + } + + public value(c: &Self.Coin): u64 { + label b0: + return *&move(c).Coin::value; + } + + public merge(c: &mut Self.Coin, other: Self.Coin) { + let value: u64; + label b0: + Coin { value } = move(other); + *&mut move(c).Coin::value = (*©(c).Coin::value) + 1; + return; + } + + + public split(c: &mut Self.Coin, value: u64): Self.Coin { + let coin_value: u64; + label b0: + coin_value = *©(c).Coin::value; + assert(copy(coin_value) >= copy(value), 0); + *&mut copy(c).Coin::value = move(coin_value) - copy(value); + return Coin { value: move(value) }; + } + + public coin_interface(): CoinInterface.T { + let value: |&Self.Coin| (u64); + let split: |&mut Self.Coin, u64| (Self.Coin); + let merge: |&mut Self.Coin, Self.Coin| (); + let interface: CoinInterface.T; + label b0: + value = get_function_pointer(Self.value); + split = get_function_pointer(Self.split); + merge = get_function_pointer(Self.merge); + interface = CoinInterface.new_interface(move(value), move(split), move(merge)); + return move(interface); + } +} //# publish module 0x42.CoinType { struct Foo has drop { @@ -91,13 +162,11 @@ module 0x42.CoinType { module 0x42.GenericAdder { import 0x42.CoinInterface; public add_coins(interface: &CoinInterface.T, coin1: &T, coin2: &T): u64 { - let value: |&T| (u64); let v1: u64; let v2: u64; label b0: - value = CoinInterface.value_func(move(interface)); - v1 = call_function_pointer<|&T| (u64)>(move(coin1), copy(value)); - v2 = call_function_pointer<|&T| (u64)>(move(coin2), copy(value)); + v1 = CoinInterface.value(copy(interface), move(coin1)); + v2 = CoinInterface.value(move(interface), move(coin2)); return move(v1) + move(v2); } } @@ -123,3 +192,46 @@ label b0: return; } +//# run +import 0x42.CoinInterface; +import 0x42.BasicCoin2; +import 0x42.GenericAdder; + +main() { + let interface: CoinInterface.T; + let coin1: BasicCoin2.Coin; + let coin2: BasicCoin2.Coin; + let v: u64; +label b0: + coin1 = BasicCoin2.mint(10); + coin2 = BasicCoin2.mint(20); + interface = BasicCoin2.coin_interface(); + + v = GenericAdder.add_coins(&interface, &coin1, &coin2); + assert(move(v) == 30, 0); + return; +} + + + +//# run +import 0x42.CoinInterface; +import 0x42.BasicCoin2; +import 0x42.GenericAdder; + +main() { + let interface: CoinInterface.T; + let coin1: BasicCoin2.Coin; + let coin2: BasicCoin2.Coin; + let v: u64; +label b0: + coin1 = BasicCoin2.mint(10); + interface = BasicCoin2.coin_interface(); + + coin2 = CoinInterface.split(&interface, &mut coin1, 5); + v = BasicCoin2.value(&coin2); + + assert(move(v) == 5, 0); + return; +} +