![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Покажу, чем развлекаюсь в выходной день. Ищу багу в программе на Алголе-60, точнее в рантайм библиотеке. Где-то неправильно сохраняется-восстанавливается контекст выполнения, а именно отображение лексического уровня вложенности на фреймы в стеке. Вот тест, на котором проявляется ошибка:
Тест должен напечатать несколько чисел, но некоторые из них оказываются неправильными. Вряд ли у вас выйдет быстро пробежать глазами и понять, что тут происходит. 😀begin procedure A(k, x); value k; integer k, x; begin procedure B(y); integer y; begin print(k, x, y); if x > -10 then A(456, -10); if y < 0 then B(20); end B; print(k, x); B(x - 1); end A; A(123, -1); end
Нарисуем последовательность вызовов.
Stack Frames: 1-----------2---------------3---------------4-----------5-----------6 Program | A(123, -1) A |-------------->| | | B(-1-1) B | |---------->| | | | A(456, -10) A | | |-------------->| | | | | B(-10-1) B | | | |-------------->| | | | | | B(20) B | | | | |---------->| | | | | | return | | | | | |<----------| | | | | return | | | | |<--------------| | | | return | | | |<--------------| | | | | | | B(20) B | | |-------------->| | | | | A(456, -10) A | | | |-------------->| | | | | | B(-10-1) B | | | | |---------->| | | | | | | B(20) B | | | | | |---------->| | | | | | | return | | | | | | |<----------| | | | | | return | | | | | |<----------| | | | | return | | | | |<--------------| | | | return | | | |<--------------| | | return | | |<----------| | return | |<--------------| |Соотнести лексические уровни со стековыми фреймами нам поможет двумерная картинка. Это первая половина, до момента, когда процедура B(20) завершается на уровне 5:
Stack | Lexical Scope Level Level | 0 (global) 1 2 --------|---------------|-------------------|------------------------ 0 | A(123, -1) | | --------|---------------|-------------------|------------------------ 1 | | procedure A: | | | display[1] = 0 | | | k = 123 | | | print "123, -1" | | | B(x-1) | --------|---------------|-------------------|------------------------ 2 | | | procedure B: | | | display[2] = 011 | | | print "123, -1, -2" | | | A(456, -10) --------|---------------|-------------------|------------------------ 3 | | procedure A: | | | display[1] = 020 | | | k = 456 | | | print "456, -10" | | | B(x-1) | --------|---------------|-------------------|------------------------ 4 | | | procedure B: | | | display[2] = 031 | | | print "456, -10, -11" | | | B(20) --------|---------------|-------------------|------------------------ 5 | | | procedure B: | | | display[2] = 040 | | | print "456, -10, 20" --------|---------------|-------------------|------------------------Вторая половина:
Stack | Lexical Scope Level
Level | 0 (global) 1 2
--------|---------------|-------------------|------------------------
0 | A(123, -1) | |
--------|---------------|-------------------|------------------------
1 | | procedure A: |
| | display[1] = 0 |
| | k = 123 |
| | B(x-1) |
--------|---------------|-------------------|------------------------
2 | | | procedure B:
| | | display[2] = 011
| | | B(20)
--------|---------------|-------------------|------------------------
3 | | | procedure B:
| | | display[2] = 020
| | | print "0, 4718593, 20"
| | | A(456, -10)
--------|---------------|-------------------|------------------------
4 | | procedure A: |
| | display[1] = 027 |
| | k = 456 |
| | print "456, -10" |
| | B(x-1) |
--------|---------------|-------------------|------------------------
5 | | | procedure B:
| | | display[2] = 040
| | | print "456, -10, -11"
| | | B(20)
--------|---------------|-------------------|------------------------
6 | | | procedure B:
| | | display[2] = 047
| | | print "456, -10, 20"
--------|---------------|-------------------|------------------------
Ошибка выделена цветом. Эти значения неправильно извлекаются из стека.
no subject
Date: 2024-08-18 07:32 (UTC)no subject
Date: 2024-08-18 17:07 (UTC)no subject
Date: 2024-08-18 08:29 (UTC)no subject
Date: 2024-08-18 17:06 (UTC)