Files
fz-lang/docs/ru/reference/errors_print.md

121 lines
5.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Вывод ошибок
Если во время работы программы происходит ошибка рантайма, то ВМ выводит своё состояние на момент остановки.
Среди выводимой информации есть:
1. Указатель на адрес инструкции;
2. Стек данных;
3. Стек окружений;
4. Стек вызовов.
## Указатель на адрес инструкции (IP)
Он может быть полезен для отладки, в паре с выводом опкодов программы.
Если подать в ВМ флаг `--debug` (`-d`) вместе с путём к скомпилированной программой, то ВМ выведет список опкодов программы без её запуска.
Выглядит вывод программы примерно так:
```
0000: MK_ENVTABLE
0001: JMP IP: 53
0003: MK_ENVTABLE
0004: LOADCONST #0 ('a')
0006: STORE
0007: LOADCONST #0 ('a')
0009: WRITE
0010: MK_ENVTABLE
0011: LOADCONST #0 ('a')
0013: LOOKUP_ENV
0014: GET_FIELD #0
...
```
Порядковый номер позволяет быстро найти инструкцию, на которой произошло исключение.
Полный список опкодов и их описание можно найти в документе [списка опкодов](../internals/opcodes.md).
## Стек данных
Стек данных выводится как список значений в стиле `[T] V`, где `T` - номер типа, `V` - значение.
Если значение является строкой или объектом, то в начале дописывается `str: V` и `ref: V` соответственно.
Вот, как выглядит пример вывода стека:
```
> Data stack:
> [2] str: 'this'
```
Важно учесть, что значения выводятся сверху вниз. То есть, первыми будут выведены самые свежие значения.
## Стек окружения
Стек окружения выводится как два списка: объекты во владении и локальные для окружения имена.
Пример окружения:
```
> Environments:
> [1] 0x55a9d8196a20:
> Owned objects (0/2):
> Local entries (3/4):
> [14] b = 4
> [1] a = ref 0x55a9d81969e0
> [0] this = 0
> [0] 0x55a9d8196930:
> Owned objects (1/2):
> ref: 0x55a9d81969e0 (entries: 1)
> Local entries (1/2):
> [1] sum = ref 0x55a9d81969e0
```
`> [N] A` - это сама таблица окружения.
`N` - это уровень таблицы, который тем выше, чем глубже само окружение.
`A` - это адрес таблицы в памяти.
Внутри идёт первый список - "Owned objects", с указанием количества элементов и аллоцированным размером массива `(<кол-во>/<размер>)`.
Перечисление объектов идёт форматом `ref: A (entries: N)`, где `A` - адрес объекта в памяти, `N` - количество хранимых полей.
Далее идёт список локальных имён - "Local entries", с таким же указанием количества элементов к аллоцированному размеру.
Формат элемента - `[T] N = V`, где `T` - номер типа, `N` - имя элемента, а `V` - его значение.
## Стек вызовов
На стеке вызовов лежат точки возврата, которые попадают на стек при инструкции `CALL` и съедаются инструкцией `RET`.
```
> Call stack:
> [0] 53
```
Формат записи простой: `[L] IP`, где `L` - уровень вложенности (больше = глубже), а `IP` - указатель на номер инструкции, на которую нужно прыгнуть после возврата.
## Полный вывод
Итого, полный вывод ошибки выглядит следующим образом:
```
===== ERROR =====
> Caused on IP: 21
> Data stack:
> [2] str: 'this'
> Environments:
> [1] 0x55a9d8196a20:
> Owned objects (0/2):
> Local entries (3/4):
> [14] b = 4
> [1] a = ref 0x55a9d81969e0
> [0] this = 0
> [0] 0x55a9d8196930:
> Owned objects (1/2):
> ref: 0x55a9d81969e0 (entries: 1)
> Local entries (1/2):
> [1] sum = ref 0x55a9d81969e0
> Call stack:
> [0] 53
Error: runtime error - expected 2 values in data stack
```