печать структур и массивов

Операционная система, написанная на языке Оберон и проект её перевода на русский язык. Только технические вопросы.
Ответить
БудДен
Сообщения: 854
Зарегистрирован: 07.10.18 14:01

печать структур и массивов

Сообщение БудДен » 29.12.19 18:12

Вместо содержимого структуры печатается просто её адрес - это неинтересно!
Начинаем копать:

См. http://вики-ч115.программирование-по-ру ... /Рефлексия

https://forum.oberoncore.ru/viewtopic.php?f=22&t=6484
Последний раз редактировалось БудДен 05.01.20 21:10, всего редактировалось 1 раз.

БудДен
Сообщения: 854
Зарегистрирован: 07.10.18 14:01

Re: печать структур

Сообщение БудДен » 02.01.20 00:27

По состоянию на 5bcb67084a23e66079c37fc40697564aa5e1f25b печатается так:

Код: Выделить всё

State Proba:
  m=<hence Absolute>068721B0 (Modules.Module)
  glob=<hence Absolute>1
  myRecordVar=<hence Absolute>... Address = 06872058([[Proba.myRecordType183:TYPE myRecordType 06872108
206: Scope
206:VAR stringField[offset=0]{{{06872058="AbCdEfG"}}}:ARRAY 8 OF CHAR
234:VAR integerField[offset=8]{{{06872060=105}}}:INTEGER
END
]])
Мы умеем теперь (для частного случая) выводить типы и значения полей записи в процедуре Reflection2.ModuleState .
(в данном случае значения - это "AbCdEfG" и 105.

Чтобы этого добиться, разобрался (в минимальной мере) в рефлексии и устройстве объекта в памяти.
Об этом добавлены две статьи на Вики.

http://вики-ч115.программирование-по-ру ... /Рефлексия
и
http://вики-ч115.программирование-по-ру ... ктаВПамяти

Смею надеяться, что по большому счёту задача об отладочной печати теперь решена, можно дальше двигаться мелкими
шажками размерами с поездку на работу. Впрочем, каникулы ещё не закончились.

БудДен
Сообщения: 854
Зарегистрирован: 07.10.18 14:01

Re: печать структур и массивов

Сообщение БудДен » 05.01.20 22:58

С массивами всё оказалось существенно сложнее.

Попробую записать то, что понял.
  • Точка входа в создание массива ищется по словам Global.New и далее как-то вызывается New.Array
  • если внутри массива (в его элементах) нет указателей, то он выделяется как нетипизированный кусок памяти
    и по значению указателя невозможно узнать его тип. TYPECODE для переменной такого типа тоже не работает. Возможное решение - начинать от корня списка модулей и находить именно переменную, в к-рой живёт этот массив (не адрес указателя), или же расширить TYPECODE до нужной степени.
  • если указатели в элементе есть (в т.ч. ARRAY OF POINTER TO ... удовлетворяет этому условию), то он выделяется как тип блока "массив" и в нём есть какая-то ссылка на тип элемента. Если это массив каких-то конкретных записей, то прямо эта запись и будет (доступна через TypeOf). Если это массив указателей на что-то, то TypeOf вернёт описание типа с именем @HdPtrDesc, и тогда можно привести тип массива к ARRAY OF ANY и выковырять оттуда элементы.
  • также отдельно обрабатывается массив нулевого размера.
  • если массив хранится не в куче, то мы не можем по тегу блока узнать даже, что это массив. Т.е. нам опять же нужно как-то добыть недостающую инфу о типе, подобно тому, как мы делаем с TYPECODE для записей, и опять упираемся в неработоспособность TYPECODE для типов-массивов.
  • по идее нужная инфа есть в refs модуля, но непонятно, как её пристегнуть. Возможно, поможет изучение интерпретатора.
Последний раз редактировалось БудДен 06.01.20 23:51, всего редактировалось 2 раза.

БудДен
Сообщения: 854
Зарегистрирован: 07.10.18 14:01

Re: печать структур и массивов

Сообщение БудДен » 06.01.20 01:47

Подчёркнутый текст - неправда, можно даже не читать.

Ох, оказывается, TypeDesc является как бы наследником от Heaps.StaticTypeDesc (или можно сказать, что там Union). При том, я-то думал, что там везде Modules.TypeDesc, т.к. обманулся функцией ThisTypeByAdr. А оказывается, оно так далеко не всегда. ПРежде всего, оно не так в декларациях типов блоков, из которых строятся объекты в памяти - там везде указан более убогий Heaps.StaticTypeDesc, в котором можно только узнать, где в данном объекте указатели. Но для записей там практически находится нечто, похожее по форме Modules.TypeDesc. А для массива с элементами, содержащими указатели, это уже и фактически не так...

Но в Heaps.StaticTypeDesc есть поле TypeInfo, живущее по отрицательному смещению, имеющее тип указателя на Heaps.TypeInfo, похожий на Modules.TypeDesc. Всё слегка запутано...

БудДен
Сообщения: 854
Зарегистрирован: 07.10.18 14:01

Re: печать структур и массивов

Сообщение БудДен » 07.01.20 00:28

На сегодня удалось напечатать ARRAY OF POINTER TO Запись. Наверное, благоразумно будет внедрить это в существующую печаталку и попробовать, будет ли это как-нибудь работать. Если массив плохого вида (ARRAY OF INTEGER) живёт в поле записи, то мы знаем об этом и можем его напечатать. Если же у наc изолированная переменная типа ARRAY OF INTEGER, которую мы обязательно хотим напечатать отдельно, можно завести какое-нибудь PechArrayOfInteger, и так мы практически преодолеем это затруднение, хотя это и коряво.

БудДен
Сообщения: 854
Зарегистрирован: 07.10.18 14:01

Re: печать структур и массивов

Сообщение БудДен » 17.01.20 22:37

Это было тяжело, но вроде теперь получилось в итоге. Порядка 10-15 системных модулей печатаются без падения.
Хотя вот ARRAY OF REAL пока не печатается.

БудДен
Сообщения: 854
Зарегистрирован: 07.10.18 14:01

Re: печать структур и массивов

Сообщение БудДен » 18.01.20 20:42

Если первым полем записи является запись, то это выглядит как циклическая ссылка...

БудДен
Сообщения: 854
Зарегистрирован: 07.10.18 14:01

Re: печать структур и массивов

Сообщение БудДен » 18.01.20 22:34

Также улучшил вывод стека - теперь можно подробно выводить стек. Правда, выглядит это довольно убого, но в целом инструмент должен оказаться полезным. Время покажет.

БудДен
Сообщения: 854
Зарегистрирован: 07.10.18 14:01

Re: печать структур и массивов

Сообщение БудДен » 19.05.20 19:01

Модуль для печати структур, кстати, называется PodrobnajaPechatq, и ещё есть модуль r, в котором собраны команды для интерактивного вызова.

Исправил недоработку. Раньше в записях с предках печатались поля только от самого младшего типа в иерархии, а поля предков не печатались. Теперь все печатаются.

Кроме того, уже некоторое время назад я сделал, чтобы по умолчанию модуль подробной печати использовался при выводе стека, например, при возникновении исключения.

Ответить