diff --git a/CHANGELOG.md b/CHANGELOG.md index f5bd192f7..7c627ad11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The `SendDefaultMode` send mode constant to the standard library: PR [#1010](https://github.com/tact-lang/tact/pull/1010) - Docs: initial semi-automated Chinese translation of the documentation: PR [#942](https://github.com/tact-lang/tact/pull/942) - The `replace` and `replaceGet` methods for the `Map` type: PR [#941](https://github.com/tact-lang/tact/pull/941) -- Utility for logging errors in code that was supposed to be unreachable [#991](https://github.com/tact-lang/tact/pull/991) +- Utility for logging errors in code that was supposed to be unreachable: PR [#991](https://github.com/tact-lang/tact/pull/991) +- Docs: `preloadRef` method for the `Slice` type: PR [#1044](https://github.com/tact-lang/tact/pull/1044) ### Changed diff --git a/docs/src/content/docs/ref/core-cells.mdx b/docs/src/content/docs/ref/core-cells.mdx index f9bd67e71..f29d38650 100644 --- a/docs/src/content/docs/ref/core-cells.mdx +++ b/docs/src/content/docs/ref/core-cells.mdx @@ -634,15 +634,45 @@ Attempts to load more data than [`Slice{:tact}`][slice] contains throw an except Usage examples: ```tact -let s: Slice = beginCell().storeRef(emptyCell()).asSlice(); -let fizz: Cell = s.loadRef(); +let s1: Slice = beginCell().storeRef(emptyCell()).asSlice(); +let fizz: Cell = s1.loadRef(); -let s: Slice = beginCell() +let s2: Slice = beginCell() .storeRef(emptyCell()) + .storeRef(s1.asCell()) + .asSlice(); +let ref1: Cell = s2.loadRef(); +let ref2: Cell = s2.loadRef(); +ref1 == ref2; // false +``` + +## Slice.preloadRef + +```tact +extends fun preloadRef(self: Slice): Cell; +``` + +Extension function for the [`Slice{:tact}`][slice]. + +Preloads the next reference from the [`Slice{:tact}`][slice] as a [`Cell{:tact}`][cell]. Doesn't modify the original [`Slice{:tact}`][slice]. + +Attempts to preload such reference [`Cell{:tact}`][cell] when [`Slice{:tact}`][slice] doesn't contain it throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. + +Attempts to preload more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. + +Usage examples: + +```tact +let s1: Slice = beginCell().storeRef(emptyCell()).asSlice(); +let fizz: Cell = s1.preloadRef(); // didn't modify s1 + +let s2: Slice = beginCell() .storeRef(emptyCell()) + .storeRef(s1.asCell()) .asSlice(); -let ref1: Cell = s.loadRef(); -let ref2: Cell = s.loadRef(); +let ref1: Cell = s2.preloadRef(); +let ref2: Cell = s2.preloadRef(); +ref1 == ref2; // true ``` ## Slice.refs diff --git a/stdlib/std/cells.tact b/stdlib/std/cells.tact index eb9b1c561..2bb474d1a 100644 --- a/stdlib/std/cells.tact +++ b/stdlib/std/cells.tact @@ -74,6 +74,31 @@ asm extends fun beginParse(self: Cell): Slice { CTOS } asm(-> 1 0) extends mutates fun loadRef(self: Slice): Cell { LDREF } +/// Extension function for the `Slice`. Available since Tact 1.5.0. +/// +/// Preloads the next reference from the `Slice` as a `Cell`. Doesn't modify the original `Slice`. +/// +/// Attempts to preload such reference `Cell` when `Slice` doesn't contain it throw an exception with exit code 8: `Cell overflow`. +/// +/// Attempts to preload more data than `Slice` contains throw an exception with exit code 9: `Cell underflow`. +/// +/// ```tact +/// let s1: Slice = beginCell().storeRef(emptyCell()).asSlice(); +/// let fizz: Cell = s1.preloadRef(); // didn't modify s1 +/// +/// let s2: Slice = beginCell() +/// .storeRef(emptyCell()) +/// .storeRef(s1.asCell()) +/// .asSlice(); +/// let ref1: Cell = s2.preloadRef(); +/// let ref2: Cell = s2.preloadRef(); +/// ref1 == ref2; // true +/// ``` +/// +/// See: +/// * https://docs.tact-lang.org/ref/core-cells#slicepreloadref +/// * https://docs.tact-lang.org/book/exit-codes +/// asm extends fun preloadRef(self: Slice): Cell { PLDREF } // special treatment in Func compiler, so not replaced with asm "LDSLICEX"