Forth http://fforum.winglion.ru/ |
|
по поводу колбэков http://fforum.winglion.ru/viewtopic.php?f=25&t=3011 |
Страница 1 из 1 |
Автор: | gudleifr [ Ср авг 13, 2014 17:46 ] |
Заголовок сообщения: | по поводу колбэков |
mOleg писал(а): Трюк у меня тут другой - я не хочу в колбэке ничего обрабатывать, т.к. каждое окно у меня крутится в отдельном потоке и имеет собственные USER переменные (одноименные но разные у каждого потока). Это, по-моему, и есть "сложности ради сложностей". Зачем делать потоки, если запрещать им пользоваться локальными переменными?И повторю, вопрос не в выборе между CASE и "словарем" (по большому счету, это одно и то же - программная реализация отношения "имя-действие"). Речь о выборе между "полной компиляцией заранее" и "саморазворачиванием в процессе". |
Автор: | mOleg [ Ср авг 13, 2014 17:54 ] |
Заголовок сообщения: | Re: Требуются контрпримеры |
gudleifr писал(а): Это, по-моему, и есть "сложности ради сложностей". Зачем делать потоки, если запрещать им пользоваться локальными переменными? это особенности винды, т.к. колбэки вызываются как бы снаружи, т.е. из того места, которое нельзя перехватить. В итоге при обработке каждого колбэка приходится создавать каждый раз новое окружение: стеки, переменные,,,. Как без этого обойтись я пока не придумал 8( gudleifr писал(а): Речь о выборе между "полной компиляцией заранее" и "саморазворачиванием в процессе". Использование словаря уже нам эту свободу даст (хотя нужна ли эта свобода? для меня ответ не очевиден). Однако, если пойти дальше, и вспомнить, что у нас есть шикарный контекст словарей, мы можем создать некую иерархию словарей и совсем произвольным образом управлять оконными объектами (убирая, добавляя, заменяя словари в контексте, можно добиться любого необходимого эффекта). Имхо, так. |
Автор: | gudleifr [ Ср авг 13, 2014 18:01 ] |
Заголовок сообщения: | Re: Требуются контрпримеры |
mOleg писал(а): Как без этого обойтись я пока не придумал Проблема только в непонимании простоты процесса. Работа коллбэка отличается только в наличии некоторой запретной зоны на стеке, не дающей возможности, добраться до нижележащих значений (но это не имеет значения, т.к. стековая обстановкака на момент вызова нам неизвестна) и видом CALL и EXIT в начале и конце коллбэка - все остальные слова внутри него работают нормально и прекрасно обмениваются с остальной машиной через СЛОВАРЬ, а друг с другом - через тот же СТЕК. mOleg писал(а): Имхо, так. Это все не имеет отношения к вопросу.
|
Автор: | mOleg [ Ср авг 13, 2014 18:21 ] |
Заголовок сообщения: | Re: Требуются контрпримеры |
gudleifr писал(а): Проблема только в непонимании простоты процесса. я представляю процесс а вот как обойти проблему без переделывания кода винды не представляю, увы. gudleifr писал(а): Работа коллбэка отличается для меня в первую очередь тем, что Си вызывает Форт, и Си не сохраняет необходимые мне регистры-указатели на пользовательскую область памяти, вершины стеков и начала стеков. Из-за этого приходится городить воот-такой код: Код: \ поддержка callback вызовов
\ Ф-ция не снимает со стека параметры!!! то есть Си-ное соглашение вызова util/ envir.fts os/ import.fts vocs/ vocadd.fts ALSO IMPORT WINAPI: GlobalAlloc KERNEL32.DLL WINAPI: GlobalFree KERNEL32.DLL WINAPI: SetLastError KERNEL32.DLL WINAPI: SetLastError KERNEL32.DLL ALSO ENVIRONMENT \ нужно знать настройки системы ALSO HIDDEN DEFINITIONS \ выход из callback \ в случае возникновения ошибки попадаем сюда же : (BACK) ( --> ) [ \ 0xCD B, 0x03 B, \ INT3 только для отладки \! сначала восстанавливается указатель стека возвратов 0x64 B, 0x8B B, 0x25 B, 0 , \ MOV ESP , FS:[0] \! вернуть верхнее значение со стека данных в EAX 0x89 B, 0x44 B, 0x24 B, 48 B, \ MOV [ESP][16], EAX \! вернуть старый обработчик исключений на место 0x64 B, 0x8F B, 0x05 B, 0 , \ POP d,FS:[0] 0x58 B, \ POP EAX = drop \! память уже выделена? 0x64 B, 0xA1 B, 8 , \ MOV EAX , FS:[8] 0x0B B, 0xC0 B, \ OR EAX, EAX \ если пусто 0x0F B, 0x84 B, 9 , \ jz skipFree \ если память не выделялась \! освободить память! 0x50 B, \ PUSH EAX 0xA1 B, Origin GlobalFree , \ free memory 0xFF B, 0xD0 B, \ CALL EAX \ GlobalFree \! метка $skipFree \! восстановление регистров и переменных 0x64 B, 0x8F B, 0x05 B, 0xE10 , \ POP d,FS[E10] 0x64 B, 0x8F B, 0x05 B, 8 , \ POP d,FS[8] 0x64 B, 0x8F B, 0x05 B, 4 , \ POP d,FS[4] 0x61 B, \ POPAD 0x8D B, 0x64 B, 0x24 B, 0x04 B, \ LEA ESP, [ESP][-4] = drop ] ; unfeasible \ вход в callback : (CALLBACK) ( --> addr ) [ \ 0xCD B, 0x03 B, \ INT3 только для отладки \! сохранение регистров и важных переменных 0x60 B, \ PUSHAD \ все регистры сохранили 0x64 B, 0xFF B, 0x35 B, 4 , \ PUSH d,FS:[4] 0x64 B, 0xFF B, 0x35 B, 8 , \ PUSH d,FS:[8] 0x64 B, 0xC7 B, 0x05 B, 8 , 0 , \ MOV fs:[8], 0 0x64 B, 0xFF B, 0x35 B, 0xE10 , \ PUSH tls \! дальше надо установить собственный обработчик исключений 0x64 B, 0xA1 B, 0 , \ MOV EAX , FS:[0] 0x68 B, ' (BACK) , \ PUSH CbError 0x50 B, \ PUSH EAX 0x64 B, 0x89 B, 0x25 B, 0 , \ MOV FS:[0] , ESP \! дальше надо выделить память под стеки и пользовательскую область 0xA1 B, Origin GlobalAlloc , 0xFF B, 0x35 B, IMAGE-BASE 0xE0 + , \ PUSH [StackSize] 0x68 B, 0x0040 , \ PUSH GMEM_ZEROINIT 0xFF B, 0xD0 B, \ CALL EAX \ выделить память для стеков 0x0B B, 0xC0 B, \ OR EAX, EAX \ если ошибка 0x0F B, 0x84 B, ' (BACK) atod , \ JZ CbError \ переход на обработчик \! | .. <rstack| <dstack| <lstack|1024| user> | 0x64 B, 0xA3 B, 8 , \ MOV fs:[8], EAX \ новый указатель начала стека 0x03 B, 0x05 B, IMAGE-BASE 0xE0 + , \ ADD EAX, [IMAGE-BASE+0xE0] 0x64 B, 0xA3 B, 4 , \ MOV fs:[8], EAX \ новый указатель конца стековой области \! дальше размещаются стеки и пользовательская область \! <return| <data| <local|1024|user|H 0x8B B, 0xF8 B, \ MOV tls , EAX 0x2B B, 0x3D B, FROM TLS# , \ SUB tls , [ TLS# ] 0x64 B, 0x89 B, 0x3D B, 0xE10 , \ MOV fs:[E10], tls 0x8D B, 0x87 B, -1024 , \ LEA EAX, [tls][-1024] \ user area 0x8B B, 0xF0 B, \ MOV ltop , EAX \ local stack 0x8B B, 0xEE B, \ MOV TOP , ltop \ ESI>EBP 0x81 B, 0xED B, LocalStack# , \ SUB top , LocalStack# 0x8B B, 0xE5 B, \ MOV rtop, top 0x81 B, 0xEC B, DataStack# , \ SUB rtop , # DataStack# \! вытащить адрес перехода на ф-цию за (call) 0x68 B, ' (BACK) , \ PUSH ' (BACK) \ для любителей делать EXIT 0x64 B, 0xA1 B, 0 , \ MOV EAX , FS:[0] 0xFF B, 0x70 B, 52 B, \ PUSH d,[EAX+0x34] \ адрес кода за скомпилированным (CALL) 0xFF B, 0x70 B, 32 B, \ PUSH d,[EAX+0x20] \ ESP ] SP@ S0 ! LP@ L0 ! R> RP@ R0 ! ['] (~EXC) IS <EXC-DUMP> \ если надо получать сообщения об исключениях prefer @ BASE ! \ без этого не будет форматного преобразования ISO> INPUT-STREAM \ \-\-\ и нормальной работы со строками ['] (BACK) err-handler ! \ установка обработчика ошибок 8 + \ смещение в начало фрейма данных R> CATCH SetLastError DROP \ ловля возможных форт-исключений (BACK) \ автоматом выход из callback ; unfeasible ALSO FORTH THIS \ начать определение callback функции \ определение завершается обычным образом, то есть ';' : CB: ( / name --> ) :> COMPILE (CALLBACK) ; RECENT RECENT RECENT |
Автор: | Hishnik [ Ср авг 13, 2014 18:31 ] |
Заголовок сообщения: | Re: Требуются контрпримеры |
Я для подобных вещей ввел все обработчики непосредственно в ядро, так что все перемещения мышки, нажатия кнопок и т.д. уже обрабатываются и вызывают векторные слова. По диспетчеризации есть дешевое и сердитое решение - под экран "подкладывается" еще один массив, который хранит индекс элемента, последним отрисовавшим пиксель в данных координатах. PIXEL (который и так векторный) модифицируется при рисовании компонентов таким образом, чтобы еще и обновлять индекс в этом массиве. Таким образом, после клика на экране можно сразу узнать номер визуального компонента, на котором произошел щелчок, и добраться до его метода ACTION. |
Автор: | gudleifr [ Ср авг 13, 2014 18:38 ] |
Заголовок сообщения: | Re: Требуются контрпримеры |
А зачем в FORTH, написанном на C, реализовать оконную фигню через FORTH? Проще оставить ее в C-части. (Коллега Хищник именно это и предлагает). Вопрос риторический! Кончайте флудить. |
Автор: | Hishnik [ Ср авг 13, 2014 19:15 ] |
Заголовок сообщения: | Re: Требуются контрпримеры |
gudleifr писал(а): А зачем в FORTH, написанном на C, реализовать оконную фигню через FORTH? Проще оставить ее в C-части. (Коллега Хищник именно это и предлагает). Вопрос риторический! А где же кварк написан на С? Чистый ассемблер, и реализовывать какие-то кнопки все равно пришлось бы через низкоуровневые функции. Только они не упрощают программирование. Кроме того, все компоненты в данном случае рисуются самим Фортом, а не функциями API, так что с точки зрения Windows это один-единственный большой пользовательский TImage. |
Автор: | gudleifr [ Ср авг 13, 2014 19:22 ] |
Заголовок сообщения: | Re: Требуются контрпримеры |
Хищник писал(а): А где же кварк написан на С? Здесь подразумевалось не "на языке", а "в ядре".Целиком отказаться от Controls, пока не готов, пока ищу компромисс. Но к вопросу вид окнообразующих ф-ий отношения не имеет. |
Автор: | gudleifr [ Пт авг 15, 2014 21:43 ] |
Заголовок сообщения: | Re: по поводу колбэков |
Если срочно, можете посмотреть, как колбэки (самым тупым способом) сделаны в FOBOS. Все-таки надеюсь, что в ближайшее время выложу новую версию, где будет немного лучше причесано и откомментировано. |
Автор: | mOleg [ Сб авг 16, 2014 11:22 ] |
Заголовок сообщения: | Re: по поводу колбэков |
gudleifr писал(а): Если срочно, можете посмотреть, как колбэки (самым тупым способом) сделаны в FOBOS. Фобос многопоточный? Можете привести код в этой теме? Интересно |
Автор: | gudleifr [ Сб авг 16, 2014 11:30 ] |
Заголовок сообщения: | Re: по поводу колбэков |
mOleg писал(а): Фобос многопоточный? Если хотите, да. Один из примеров (15), как раз заключается в использовании Win-многопоточности.mOleg писал(а): Можете привести код в этой теме? Самый дубовый способ (на примере оконной функции, текущая версия FOBOS с моей странички) :Код: 64K ALLOCATE DROP CONSTANT WIN-STACK ( ДЛЯ ХРАНЕНИЯ КАДРОВ СТЕКА CALL-BACK-ОВ) VARIABLE WIN-SP WIN-STACK WIN-SP ! ... BEGIN-LOAD ASSEMBLER HEX : CALL-BACK CODE ( КОНЕЧНО НЕ ДЛЯ ВСЕХ CALL-BACK-ОВ, А ТОЛЬКО ДЛЯ ОКОННЫХ) /WO MOVA, WIN-SP , /WO MOV, DI A [8] 10 C, /WO MOV, SI A [8] 14 C, /WO MOV, B A [8] 18 C, /WO MOV, BP A [8] 1C C, C POPR, POPM, A [0] POPM, A [8] 4 C, POPM, A [8] 8 C, POPM, A [8] 0C C, C PUSHR, /SW ADDD, A [RG] 20 C, /DW MOVA, WIN-SP , /DW MOV, DI [DW] EDI-OLD , /DW MOV, BP [DW] EBP-OLD , SI MOVRDW, >MARK NEXT, >RESOLVE END-LOAD ] ; END-LOAD : WIN-H WIN-SP @ 32 - @ ; ( СООБЩЕНИЕ, СОХРАНЕННОЕ В КАДРЕ СТЕКА) : WIN-MSG WIN-SP @ 28 - @ ; : WIN-W WIN-SP @ 24 - @ ; : WIN-L WIN-SP @ 20 - @ ; CODE WIN-RET /WO MOV, BP [DW] EBP-OLD , A POPR, B PUSHR, ( ВОЗВРАТ ИЗ CALL-BACK) /WO MOV, DI [DW] EDI-OLD , /WO MOVA, WIN-SP , /SW SUBD, A [RG] 20 C, /DW MOV, DI A [8] 10 C, /DW MOV, SI A [8] 14 C, /DW MOV, B A [8] 18 C, /DW MOV, BP A [8] 1C C, /DW MOVA, WIN-SP , A POPR, RET, END-CODE ... VARIABLE WIN ( ПЕРЕМЕННАЯ СОДЕРЖАЩАЯ АДРЕС КОРНЯ ДЕРЕВА РАЗБОРА СООБЩЕНИЙ) CALL-BACK WIN-PROC WIN-MSG WIN @ RECEPTING WIN-RET ; ( ОКОННАЯ Ф-ИЯ) ... VARIABLE WIN-PROCEDURE ' WIN-PROC WIN-PROCEDURE ! ... ... WIN-PROCEDURE @ .... REGISTERCLASS CALL ... Ассемблер мой (он лежит в начале g2.txt). Кусок выдран где-то с 500 строки. Т.е. сначала выделяется дополнительный стек - чтобы не мучиться вопросом, что на самом деле где хранится. При входе в колбэк туда сохраняются регистры Винды и, заодно, параметры оконной функции. Восстанавливаются FORTH-регистры (их сохраняет CALL - вызов Win-API). RECEPTING - распознаватель win-сообщений. В принципе, между CALL-BACK и WIN-RET может быть любой FORTH-код. Единственное ограничение здесь список параметров оконной ф-ии. В новой версии FOBOS все немного по-другому - вызовы Win-API облегчены, количество промежуточных переменных сокращено... |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |