OberonCore https://forum.oberoncore.ru/ |
|
Название импортирующего модуля https://forum.oberoncore.ru/viewtopic.php?f=29&t=6857 |
Страница 1 из 1 |
Автор: | Александр К [ Пятница, 17 Июнь, 2022 15:59 ] |
Заголовок сообщения: | Название импортирующего модуля |
Может ли импортируемый модуль узнать имя импортирующего модуля, который вызывает его процедуру? |
Автор: | Иван Денисов [ Пятница, 17 Июнь, 2022 17:26 ] |
Заголовок сообщения: | Re: Название импортирующего модуля |
Александр К писал(а): Может ли импортируемый модуль узнать имя импортирующего модуля, который вызывает его процедуру? Теоретически может. Есть в StdDebug процедура ShowStack, которая из адреса раскручивает порядок вызова модулей, когда происходит аварийная остановка. Думаю, что аналогично возможно узнать, кто вызвал процедуру. |
Автор: | Comdiv [ Пятница, 17 Июнь, 2022 17:45 ] |
Заголовок сообщения: | Re: Название импортирующего модуля |
При таких вопросах больше всего интересует не основной ответ, а ответ на вопрос "зачем?". |
Автор: | Artyemov [ Суббота, 18 Июнь, 2022 01:12 ] |
Заголовок сообщения: | Re: Название импортирующего модуля |
Comdiv писал(а): При таких вопросах больше всего интересует не основной ответ, а ответ на вопрос "зачем?". Один из моих знакомых в подобных случаях отвечает:"Спросят, а у меня - есть..." |
Автор: | Иван Денисов [ Суббота, 18 Июнь, 2022 06:53 ] |
Заголовок сообщения: | Re: Название импортирующего модуля |
В целом это может быть какая-то разновизность параметризации вместо кастования типа, если спрашивает один модуль, то вычисляем одним образом, если другой — другим. Еще полезно может быть для отладки на лету, вместо ассерта, пишется в журнал, кто вызывал процедуру. Потом можно посчитать статитстику и т.п. |
Автор: | Илья Ермаков [ Суббота, 18 Июнь, 2022 14:48 ] |
Заголовок сообщения: | Re: Название импортирующего модуля |
Код: PROCEDURE ModOfCodeAddr (adr: Mem.AddrInt (* = INTEGER в стандартном ББ *)): Kernel.Module; VAR m: Kernel.Module; BEGIN (* TODO: Кэшировать *) m := Kernel.modList; WHILE (m # NIL) & ~ ((m.code <= adr) & (adr < m.code + m.csize)) DO m := m.next END; RETURN m END ModOfCodeAddr; PROCEDURE GetCallMod* (level: INTEGER; OUT mod: Kernel.Module); VAR ebp, ret: INTEGER; BEGIN S.GETREG(5, ebp); S.GET(ebp + 4, ret); WHILE level > 0 DO S.GET(ebp, ebp); S.GET(ebp + 4, ret); DEC(level) END; mod := ModOfCodeAddr(ret); END GetCallMod; PROCEDURE NameOfProcAddr (adr: Mem.AddrInt; OUT m: Kernel.Module; OUT name: ARRAY OF CHAR); VAR ref, radr: Mem.AddrInt; s: Kernel.Name; BEGIN m := NIL; name := ""; Kernel.SearchProcVar(adr, m, adr); IF m # NIL THEN IF m.refcnt < 0 THEN m := NIL ELSE ref := m.refs; REPEAT Kernel.GetRefProc(ref, radr, s) UNTIL (radr = 0) OR (adr < radr); IF adr < radr THEN name := s$ ELSE m := NIL END END END END NameOfProcAddr; PROCEDURE GetCallProc* (level: INTEGER; OUT mod, proc: ARRAY OF CHAR); VAR ebp, ret: INTEGER; m: Kernel.Module; BEGIN S.GETREG(5, ebp); S.GET(ebp + 4, ret); WHILE level > 0 DO S.GET(ebp, ebp); S.GET(ebp + 4, ret); DEC(level) END; NameOfProcAddr(ret, m, proc); IF m # NIL THEN mod := m.name$ ELSE mod := "" END END GetCallProc; Чисто имя модуля - GetCallMod. С точностью до имени процедуры - GetCallProc. level = 1 - непосредственно вызывающий уровень, 2 - ещё на уровень выше по стеку и т. д. (лучше было бы, наверное, в минус нумеровать). Код вырезан из двух модулей, чтобы опубликовать здесь, мелочи могут быть некомпилируемы, но разберётесь. |
Автор: | Александр К [ Суббота, 18 Июнь, 2022 14:56 ] |
Заголовок сообщения: | Re: Название импортирующего модуля |
Цитата: При таких вопросах больше всего интересует не основной ответ, а ответ на вопрос "зачем?". Я хочу сделать свой "Рабочий журнал". Все сообщения в нём будут делиться по важности на маловажные, важные и большой важности (степень важности будет указываться программистом при отправке сообщений). При этом пользователь будет иметь возможность настраивать внешний вид сообщений для каждой степени важности и выбирать какие по степени важности сообщения конкретных модулей или всех модулей показывать. Будет так же опция показа какое сообщение вывел какой модуль. Такое я видел в космической игре "Цивилизация". Там можно было выбрать, какие сообщения показывать (что-то вроде фильтра). |
Автор: | Илья Ермаков [ Суббота, 18 Июнь, 2022 15:19 ] |
Заголовок сообщения: | Re: Название импортирующего модуля |
Если пытаетесь сделать общее решение - то вряд ли получится, такую штуку нужно проектировать и дотачивать под конкретный тип применений. Если делаете именно под конкретное понимание - то хорошо. Если делаете "в общем" - то, в принципе, неплохая тренировка/пример. Который, опять же, можно будет взять за основу, если для какой-то конкретной системы что-то подобное потребуется. |
Автор: | Александр Ильин [ Суббота, 18 Июнь, 2022 17:38 ] |
Заголовок сообщения: | Re: Название импортирующего модуля |
Александр К писал(а): Может ли импортируемый модуль узнать имя импортирующего модуля, который вызывает его процедуру? Конечно! Достаточно в список параметров процедуры добавить параметр "ИмяВызывающегоМодуля". Все будут должны его предоставить при вызове.
|
Автор: | Иван Денисов [ Четверг, 01 Декабрь, 2022 05:31 ] |
Заголовок сообщения: | Re: Название импортирующего модуля |
Илья Ермаков писал(а): Чисто имя модуля - GetCallMod. С точностью до имени процедуры - GetCallProc. level = 1 - непосредственно вызывающий уровень, 2 - ещё на уровень выше по стеку и т. д. (лучше было бы, наверное, в минус нумеровать). Код вырезан из двух модулей, чтобы опубликовать здесь, мелочи могут быть некомпилируемы, но разберётесь. Илья, очень благодарен, что делишься кодом. Меня сильно выручил этот пример! Александр, а вам спасибо, что задаёте вопросы, которые пополняют базу знаний на форуме! |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |