Functions in Tolk can be defined using assembler code. It’s a low-level feature that requires understanding of stack layout, Fift, and TVM.Documentation Index
Fetch the complete documentation index at: https://companyname-a7d5b98e-closes-1950-ai-ai-ai-ai-ai-ai-ai.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Standard functions
Standard functions areasm wrappers. Many functions from the standard library are translated to the Fift assembler directly. For example, TVM has a HASHCU instruction, which is “calculate hash of a cell”. It pops a cell from the stack and pushes an integer in the range 0 to 2256-1. Therefore, the method cell.hash is defined:
CELL will be the topmost element (self).
Custom functions
incThenNegate(10) is translated into those commands.
Specify @pure if the body does not modify TVM state or throw exceptions.
The return type for asm functions is mandatory. For regular functions, it’s inferred from return statements.
Multi-line asm
To embed a multi-line command, use triple quotes:
// comments valid for Fift.
Stack order for multiple slots
When calling a function, arguments are pushed in the declared order. The last parameter becomes the topmost stack element. If an instruction produces several slots, the resulting type should be a tensor or a struct. For example, write a functionabs2 that calculates abs() for two values at once: abs2(-5, -10) = (5, 10). The comments show the stack layout for each step. The rightmost value represents the top of the stack.
Stack-based argument reordering
Sometimes a function accepts parameters in an order different from what a TVM instruction expects. For example,GETSTORAGEFEE expects the parameters in the order cells, bits, seconds, and workchain. For a clearer API, the function should take the workchain as its first argument. To reorder stack positions, use the asm(<INPUT_ORDER>) syntax:
asm(-> <RETURN_ORDER>) syntax:
asm(<INPUT_ORDER> -> <RETURN_ORDER>). Reordering is mostly used with mutate variables.
mutate and self in assembler functions
The mutate keyword, which makes a parameter mutable, implicitly returns updated values through the stack in both regular and asm functions.
Consider regular functions first. The compiler applies all transformations automatically.
increment() using asm:
void. The type system treats it as returning no value. However, INC leaves a number on the stack — that’s a hidden “return x” from a manual implementation.
Similarly, it works for mutate self. An asm function should place newSelf on the stack before the actual result:
self for chaining, specify a return type:
asm is compatible with structures
Methods on structures can be declared in asm when their field layout is known. Fields are placed sequentially. For example, a structure with a single field is equivalent to that field.
map<K, V> methods on TVM dictionaries:
Generics in asm should be single-slot
Consider tuple.push. The TPUSH instruction pops (tuple, someVal) and pushes (newTuple). It works with any T that occupies a single stack slot, such as int, int8, or slice.
t.push(somePoint) work? It does not compile, because Point { x, y } occupies two stack slots rather than one, which breaks the expected the stack.
asm do not.
Do not use asm for micro-optimizations
Use asm only for rarely used TVM instructions that are not covered by the standard library, such as manual merkle-proof parsing or extended hash calculations.
Using asm for micro-optimizations is discouraged. The compiler already produces bitcode from clear, structured logic. For example, it automatically inlines simple functions, so one-line helper methods do not add gas overhead.
32 STU sequence provides no advantage in this case. The compiler:
- inlines the function;
- merges constant
flagswith subsequent stores intoSTSLICECONST.