> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ton.org/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.ton.org/feedback

```json
{
  "path": "/tolk/types/overall-tvm-stack",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# TVM stack representation

This page assumes prior knowledge of the [Tolk type system](/languages/tolk/types/list-of-types) and [TVM](/tvm/overview). It serves as a concise low-level reference.

A consolidated summary of how Tolk types are represented on the TVM stack.

## `int`, `intN`, `coins`

* All numeric types are backed by TVM `INT`.
* Type `intN` uses full 257-bit precision, so any integer value fits into it. Overflow occurs only during serialization.

## `bool`

* The `bool` type is backed by TVM `INT` with value `-1` or `0` at runtime.
* The unsafe cast `someBool as int` is valid and produces `-1` or `0`.

## `address`, `any_address`

* Both `address` and `any_address` are backed by TVM `SLICE` values containing raw binary data.
* A nullable `address?` is represented as either TVM `NULL` or `SLICE`.
* The unsafe cast `someAddr as slice` is valid and reversible.

## `cell`

* The `cell` type is backed by TVM `CELL`.
* The unsafe cast `someCell as Cell<T>` is valid.

## `Cell<T>`

* The `Cell<T>` type is also backed by TVM `CELL`. The type parameter `T` is compile‑time metadata.

## `slice`

* Type `slice` is backed by TVM `SLICE`.

## `bitsN`

* The `bitsN` type is backed by TVM `SLICE`.
* The unsafe cast `someSlice as bitsN` is valid and reversible.

## `RemainingBitsAndRefs`

* The `RemainingBitsAndRefs` type is backed TVM `SLICE`. It is an alias of `slice` that is handled specially during deserialization.

## `builder`

* The `builder` type is backed by TVM `BUILDER`. Bits written to a builder cannot be read directly. Access to the data is possible only by converting the `builder` to a `slice`.

## `struct`

Fields of a structure are placed sequentially on the stack. For example, `Point` occupies two stack slots, and `Line` occupies four:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
struct Point {
    x: int
    y: int
}

struct Line {
    start: Point
    end: Point
}
```

When constructing a `Line` value, four integers are placed onto the stack:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun generateLine() {
    val l: Line = {
        start: { x: 10, y: 20 },
        end: { x: 30, y: 40 },
    };
    // on a stack: 10 20 30 40
    return l;
}
```

Single-field structures have no overhead compared to the plain values.

## `enum`

* Every enum is backed by TVM `INT`. Tolk supports integer enums only; for example, not addresses.

## Nullable types `T?`

Primitive nullable types such as `int?`, `address?`, and `cell?` occupy a single stack slot. That slot holds either TVM `NULL` or the corresponding value.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun demo(maybeAddr: address?) {
    // maybeAddr is one stack slot: `NULL` or `SLICE`
}
```

A nullable structure with a single non-nullable primitive field can also be represented:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
struct MyId {
    value: int32
}

fun demo(maybeId: MyId?) {
    // maybeId is one stack slot: `NULL` or `INT`
}
```

Nullable values of multi-slot types, such as `Point` or a tensor `(bool, cell)`, occupy N + 1 stack slots. The last is used for "typeid".

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
struct Point {
    x: int
    y: int
}

fun demo(maybeP: Point?) {
    // maybeP is 3 stack slots:
    // when null: "NULL, NULL, INT (0)"
    // when not:  "INT (x), INT (y), INT (4567)"
}
```

For every nullable type, the compiler assigns a unique `typeid`; for example, 4567 for `Point`. The `typeid` is stored in an extra stack slot. The `typeid` value for `null` is `0`. Expressions such as `p == null` or `p is Point` check the `typeid` slot.

The following structure, when nullable, requires an extra stack slot:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
struct Tricky {
    opt: int?
}

fun demo(v: Tricky?) {
    // v occupies 2 stack slots,
    // because either `v == null` or `v.opt == null`:
    // when v == null: "NULL, INT (0)"
    // when v != null: "INT/NULL, INT (2345)"
}
```

## Union types `T1 | T2 | ...`

Union types are represented as tagged unions on the stack:

* each alternative type is assigned a unique `typeid`; e.g., 1234 for `int`;
* the union occupies N+1 stack slots, where N is the maximum size of `T_i`;
* the(N+1)-th slot contains the `typeid` of the current value.

Thus, `match` is implemented as a comparison of the (N+1)-th slot, and passing or assigning a value involves stack rearrangement.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun complex(v: int | slice | (int, int)) {
    // `v` is 3 stack slots:
    // - int:        (NULL, 100, 1234)
    // - slice:      (NULL, CS{...}, 2345)
    // - (int, int): (200, 300, 3456)
}

fun demo(someOf: int | slice) {
    // `someOf` is 2 stack slots: value and type-id
    // - int:   (100, 1234)
    // - slice: (CS{...}, 2345)
    match (someOf) {
        int => {     // IF TOP == 1234
            // slot1 is TVM `INT`, can be used in arithmetics
        }
        slice => {   // ELSE
            // slot1 is TVM `SLICE`, can be used to loadInt()
        }
    }

    complex(v);   // passes (NULL, v.slot1, v.typeid)
    complex(5);   // passes (NULL, 5, 1234)
}
```

`T | null` is called nullable and optimized for atomic types: `int?` uses a single slot. Non-atomics are handled generally, with `typeid=0`.

## Tensors `(T1, T2, ...)`

Tensor components are placed sequentially on the stack, identical to `struct` fields. For example, `(coins, Point, int?)` occupies 4 stack slots: `INT (coins), INT (p.x), INT (p.y), INT/NULL`.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
type MyTensor = (coins, Point, int?)

fun demo(t: MyTensor) {
    // t is 4 stack slots
    val p = t.1;
    // p is 2 stack slots
}
```

## `string`

Type `string` is backed by the TVM `CELL` containing character data in snake format: a chain of cells where each cell holds a portion of the string and a reference to the next.

For example, a string `"abcd"` can be stored as a single chunk — `cell(data: "abcd")`, with 32 bits inside. The same string can also use nested chunks: `cell(data: "ab", ref: cell(data: "cd"))`. Either way, a `string` is a `cell` that may contain chained refs.

## `unknown`

The `unknown` type is an opaque type that represents a single TVM stack slot.

Any type `T` can be cast to `unknown`. When cast, primitives remain as-is, while multi-slot types are packed into a sub-tuple.

For example, `5 as unknown` remains as `5` on the stack, whereas `(10, 20) as unknown` is converted to a 2-element tuple `[10 20]`.

## `array<T>` and `tuple`

An array of any `T` is backed by the TVM `TUPLE` and occupies a single stack slot, regardless of the number of elements within. The TVM `TUPLE` limit is 255 inner elements. The `tuple` is an alias for `array<unknown>`.

For example, `array<int> [1,2,3]` is a TVM tuple `[1 2 3]`, whereas for `array<Point> [ {x:10,y:20}, {x:30,y:40} ]` each sub-element is a 2-component tuple itself: `[ [10 20] [30 40] ]`. Under the hood, `T` is converted to `unknown` on write and reversed back on read: `points.get(0)` returns `{x:10,y:20}`.

## Shaped tuple `[T1, T2, ...]`

A shaped tuple is a fixed-size array backed by the TVM `TUPLE`, whose structure is known at compile-time:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun demo(t: [int, [int, int]]) {
    // t is one stack slot (TVM `TUPLE`)
    // t.0 is TVM `INT`
    // t.1 is TVM `TUPLE`
    return t.1.0;    // asm "1 INDEX" + "0 INDEX"
}
```

## `map<K, V>`

* `map<K, V>` occupies a single stack slot: either TVM `NULL` or `CELL`.
* Non-empty maps, `CELL`, have [a non-trivial bit-level layout](/languages/tl-b/complex-and-non-trivial-examples#hashmap).

## Callables `(...ArgsT) -> ResultT`

* A callable and `continuation` is backed by TVM `CONT`.

## `void`, `never`

* Both represent the absence of a value and occupy zero stack slots. For example, a function with return type `void` does not place any value onto the stack.
