Просмотр сообщений

В этом разделе можно просмотреть все сообщения, сделанные этим пользователем.


Сообщения - X512

Страницы: [1] 2 3
1
Уже прошло более 2 лет. Публиковать Сириус больше не планируется? Какого его текущее состояние?
Судя по сообщениям в Сириусе применяются уникальные интересные механизмы вроде охраны экземпляром, которые больше нигде не встречаются. Интересно было бы изучить.

2
Общий раздел / Re: BlackBox без MDI
« : Апрель 13, 2014, 12:43:55 pm »
Пожалуй, в предложенном варианте, без MDI, мне тоже было бы неудобно работать. С закладками для окон работать гораздо приятнее.
Тем не менее работать с MDI Blackbox одновременно с другими программами затруднительно. Убирание MDI Облегчает ситуацию. Конкретно для меня очень важно работать одновременно с несколькими программами. Например писать код ориентируясь на другой код, документацию, иллюстрации и т.п.
Конечно добавить вкладки было бы тоже неплохо, но они от MDI не зависят. Вообще MDI - плохая идея; это поняли даже в Microsoft. Новые программы с MDI уже никто не делает.
А в чём усть следующего изменения?
Извиняюсь, думал я не публиковал этого изменения. Это предназначено для точной настройки единиц измерения для моего монитора (для мониторов с другими размерами и разрешением надо поменять константы в соостветствии с инструкцией на монитор). Оказывается, что Windows даёт неверный DPI монитора.

3
Общий раздел / Re: BlackBox без MDI
« : Март 31, 2014, 07:18:37 pm »
Я уже давно хочу сделать тайловое рабочее пространство, но всё пока лень разбираться. Во-первых framework не имеет встроенной возможности вставить в документ другой документ из другого файла (не копию). Напрямую вставить View в другой View из другого домена нельзя (не меняя ничего в Framework'е). Можно только Frame. Во-вторых надо делать реализацию Containers.Model / View / Controller, опыта чего у меня пока нет. Когда-нибудь надо решиться сделать.

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

4
Общий раздел / Re: BlackBox без MDI
« : Март 31, 2014, 06:42:45 pm »
Какие моменты конкретно не устраивают? Как по вашему должна быть организована среда разработки?

5
Общий раздел / BlackBox без MDI
« : Март 31, 2014, 06:00:56 pm »
Уже более полтора года назад сделал версию BlackBox без MDI, т.к. оно мешает при одновременной работе с другими программами и занимает лишнее время на экране. Правда тогда я не решился выложить ту версию ввиду разных глюков, вызванными экспериментами с Framework'ом. Сегодня ещё раз реализовал тот же функционал поверх BlackBox 1.6 final (http://archive.oberoncore.org/blackbox16.7z).

В данной версии нет окна, в котором находятся все документы, окна BlackBox можно без проблем совмещать с окнами других программ. Меню по-прежнему общее. Теперь оно работает аналогично MacOS. Оно разположено в отдельном окне вверу экрана на всю ширину. Меню автоматически скрывается, если фокус переходит к другой программе, чтобы не мешать работе с другими программами. Также по-прежнему можно запускать несколько экзэмпляров BlackBox, правда их тогда будет трудно различить (для различия можно например первый пункт меню назвать по разному). Alt комбинации работают корректно.

Для установки декодировать файл во вложении на BlackBox 1.6 final. Возможно на других версиях тоже будет работать, но результат не гарантирован.

6
Исходники были опубликованы здесь: http://forum.oberoncore.ru/viewtopic.php?p=79715. Репозиторий (коммитов нет): https://bitbucket.org/petryxa/linref. Также написано, что они распространяются по BSD-подобной лицензии. Разрабатывалось Oberon Microsystems более 10-ти лет назад. Также вроде-бы есть закрытый форк, продолжающий разработки.

7
Изучая исходники BlackBox для Linux, также обнаружил ряд интересных модулей, не опубликованных в обычной версии BlackBox. В частности был найден дизассемблер для форматов Portable Executable (DevDecExe) и Oberon Code File(DevDecoder) и архитектур 86k, i486, ARM, PPC и SH3 (не знаю что это такое). ELF не поддерживается. Для Oberon Code File также выводятся дескрипторы типов и т.п. Также имеется компилятор для 68k.

Список модулей
DevDecBase
DevDecSH3
DevDecPPC
DevDecoder
DevDecExe
DevDecARM
DevDec68k
DevDec486


Также выкладываю исходники Blackbox для Linux, уже не помню откуда их взял.
http://rghost.ru/51613795
Сюда выложить не получилось, хотя в лимит вроде укладывается...

Может кому поможет при написании компиляторов.

8
Общий раздел / Re: Project Oberon (New Edition 2013)
« : Декабрь 27, 2013, 02:57:08 am »
Надо бы утилитку написать которая построит граф модулей.
Такая утилита уже есть в BlackBox, но толку от неё мало. При большом количестве модулей линии пересекаются и ничего не понятно.

Лучше сделать по типу http://www.dependencywalker.com/.

9
Общий раздел / Re: Горячая замена кода
« : Декабрь 18, 2013, 03:22:55 pm »
Кстати память частично освобождается при выгрузке модуля, но выгруженный участок памяти больше никогда не используется. Ограничение памяти под модули вероятно вызвано резервированием 1.5 ГБ виртуальной памяти под кучу в стандартном режиме (есть ещё режим "dllMode" в котором память выделяется через стандартную Win32 кучу). Для памяти под модули используется виртуальная память (VirtualAlloc), а не куча сборщика мусора.

10
Общий раздел / Re: Горячая замена кода
« : Декабрь 18, 2013, 02:56:47 pm »
А что тогда происходит, если миллион раз выгрузить/загрузить модуль? Память кончится?
Да, именно так. Элементарно проверяется, особенно если в выгружаемом модуле есть большие массивы (так память израсходуется быстрее).

Код проверки:
MODULE A;
   VAR
      a: ARRAY 1000 OF POINTER TO RECORD
         p: ANYPTR
      END;
END A.

MODULE B;
   IMPORT Kernel;
   
   PROCEDURE Do*;
      VAR mod: Kernel.Module;
   BEGIN
      mod := Kernel.ThisMod("A");
      WHILE mod # NIL DO
         Kernel.UnloadMod(mod);
         mod := Kernel.ThisMod("A")
      END
      (* mod = NIL, память кончилась *)
   END Do;
   
END B.

(!) B.Do

11
Общий раздел / Re: Горячая замена кода
« : Декабрь 18, 2013, 01:38:49 pm »
Поясняю: трап хреновый потому что он ровно из той же серии, что и разыменование невалидного (dangled) указателя в C/C++. Только в случае С/C++ никто не кричит, что такой трап штатный, а идут и фиксают :) Хотя, например, C++Builder из коробки такие трапы ловит не хуже ББ и ничего не падает (наследнику дельфи, чего с него взять).

Последствия/уязвимости у таких трапов, соответственно, точно такие же как и у традиционных небезопасных языков (форматирование жесткого диска и т.д. и т.п.).
Вообще то Blackbox вообще не умеет выгружать модули, он лишь умеет игнорировать "выгруженный" модуль при импорте и инвалидировать кодовую секцию (см. Kernel.UnloadMod). При этом модуль-зомби продолжает находиться в памяти до завершения процесса Blackbox.

Trap "illegal execution" просто показывает, что пытаются выполнять код без разрешения на чтение и исполнение, убранные при инвалидации.  Можно сделать Trap информативнее следующими правками процедуры "DevDebug.Trap":

   PROCEDURE Trap;
      VAR a0: TextModels.Attributes; prop: Properties.StdProp; action: Action;
          msg: ARRAY 512 OF CHAR; mod: Kernel.Module;
   BEGIN
      out.ConnectTo(TextModels.CloneOf(StdLog.buf));
      a0 := out.rider.attr;
      out.rider.SetAttr(TextModels.NewWeight(a0, Fonts.bold));
      IF Kernel.err = 129 THEN out.WriteSString("invalid WITH")
      ELSIF Kernel.err = 130 THEN out.WriteSString("invalid CASE")
      ELSIF Kernel.err = 131 THEN out.WriteSString("function without RETURN")
      ELSIF Kernel.err = 132 THEN out.WriteSString("type guard")
      ELSIF Kernel.err = 133 THEN out.WriteSString("implied type guard")
      ELSIF Kernel.err = 134 THEN out.WriteSString("value out of range")
      ELSIF Kernel.err = 135 THEN out.WriteSString("index out of range")
      ELSIF Kernel.err = 136 THEN out.WriteSString("string too long")
      ELSIF Kernel.err = 137 THEN out.WriteSString("stack overflow")
      ELSIF Kernel.err = 138 THEN out.WriteSString("integer overflow")
      ELSIF Kernel.err = 139 THEN out.WriteSString("division by zero")
      ELSIF Kernel.err = 140 THEN out.WriteSString("infinite real result")
      ELSIF Kernel.err = 141 THEN out.WriteSString("real underflow")
      ELSIF Kernel.err = 142 THEN out.WriteSString("real overflow")
      ELSIF Kernel.err = 143 THEN
         out.WriteSString("undefined real result  (");
         out.WriteIntForm(Kernel.val MOD 10000H, TextMappers.hexadecimal, 4, "0", TextMappers.hideBase); out.WriteSString(", ");
         out.WriteIntForm(Kernel.val DIV 10000H, TextMappers.hexadecimal, 3, "0", TextMappers.hideBase); out.WriteChar(")")
      ELSIF Kernel.err = 144 THEN out.WriteSString("not a number")
      ELSIF Kernel.err = 200 THEN out.WriteSString("keyboard interrupt")
      ELSIF Kernel.err = 201 THEN
         out.WriteSString("NIL dereference")
      ELSIF Kernel.err = 202 THEN
         out.WriteSString("illegal instruction: ");
         out.WriteIntForm(Kernel.val, TextMappers.hexadecimal, 5, "0", TextMappers.showBase)
      ELSIF Kernel.err = 203 THEN
         IF (Kernel.val >= -4) & (Kernel.val < 65536) THEN out.WriteSString("NIL dereference (read)")
         ELSE out.WriteSString("illegal memory read (ad = "); WriteHex(Kernel.val); out.WriteChar(")")
         END
      ELSIF Kernel.err = 204 THEN
         IF (Kernel.val >= -4) & (Kernel.val < 65536) THEN out.WriteSString("NIL dereference (write)")
         ELSE out.WriteSString("illegal memory write (ad = "); WriteHex(Kernel.val); out.WriteChar(")")
         END
      ELSIF Kernel.err = 205 THEN
         IF (Kernel.val >= -4) & (Kernel.val < 65536) THEN out.WriteSString("NIL procedure call")
         ELSE
            mod := Kernel.modList;
            WHILE (mod # NIL) & ~((mod.refcnt = -1) & (Kernel.val >= mod.code) & (Kernel.val < mod.code + mod.csize)) DO mod := mod.next END;
            IF mod # NIL THEN
               out.WriteSString('Call of unloaded module "'); out.WriteSString(mod.name); out.WriteChar('"')
            ELSE

               out.WriteSString("illegal execution (ad = "); WriteHex(Kernel.val); out.WriteChar(")")
            END
         END
      ELSIF Kernel.err = 257 THEN out.WriteSString("out of memory")
      ELSIF Kernel.err = 10001H THEN out.WriteSString("bus error")
      ELSIF Kernel.err = 10002H THEN out.WriteSString("address error")
      ELSIF Kernel.err = 10007H THEN out.WriteSString("fpu error")
      ELSIF Kernel.err < 0 THEN
         out.WriteSString("Exception "); out.WriteIntForm(-Kernel.err, TextMappers.hexadecimal, 3, "0", TextMappers.showBase)
      ELSE
         out.WriteSString("TRAP "); out.WriteInt(Kernel.err);
         IF Kernel.err = 126 THEN out.WriteSString("  (not yet implemented)")
         ELSIF Kernel.err = 125 THEN out.WriteSString("  (call of obsolete procedure)")
         ELSIF Kernel.err >= 100 THEN out.WriteSString("  (invariant violated)")
         ELSIF Kernel.err >= 60 THEN out.WriteSString("  (postcondition violated)")
         ELSIF Kernel.err >= 20 THEN out.WriteSString("  (precondition violated)")
         END
      END;
      GetTrapMsg(msg);
      IF msg # "" THEN out.WriteLn; out.WriteString(msg) END;

      out.WriteLn; out.rider.SetAttr(a0);
      out.WriteLn; ShowStack;
      NEW(action); action.text := out.rider.Base();
      Services.DoLater(action, Services.now);
      out.ConnectTo(NIL)
   END Trap;

12
А что, раньше пиратское ПО было - это нормально? 90-е уже прошли. Пора уже в России начать уважать авторское право и не быть варварами. К тому же для образовательных целей у многих программ есть особые лицензии.

13
Общий раздел / Re: [CP] Вопрос про Message Bus.
« : Февраль 02, 2013, 10:22:45 am »
Да, имеется ввиду именно такое. На счет рекурсивной отправки - было же сказано, что и в случае стека этим лучше не пользоваться. Впрочем, для такого подхода (через кучу) это решаемая проблема - делаем фабрику повторно используемых объектов, у которой при отправке просим выдать нам свободный экземпляр сообщения данного типа.

Впрочем, я кажется понимаю в чем проблема такого подхода - кто-нибудь может взять, и сохранить переданный ему указатель на сообщение для неких своих нужд. В результате получим не предсказуемое поведение - любое сообщение может быть модифицировано в любой момент времени непредсказуемым образом.
Рекурсия хоть и не рекомендуется, но и не запрещена. В BlackBox рекурсия посылок сообщений иногда используется.

Зачем делать пулы (избыточная сложность на пустом месте, к тому же добавление новых типов сообщений станет большой проблемой) я не понимаю, чем стек не угодил? Или в ваших Java/C# нет объектов на стеке и нужно делать костыли? Относительно непредсказуемого поведения: можно ведь передавать сообщение обработчику через VAR параметр, а не указатель и тогда проблем не будет. Или в Java/C# их нет?

Всё-же я не понимаю зачем использовать кучу вместо стека...

14
Общий раздел / Re: [CP] Вопрос про Message Bus.
« : Февраль 02, 2013, 09:47:25 am »
Насчёт тезисов: вы меньше OberonCore'а читайте, они пропогандируют то, что сами не понимают. Пытаются умолчать недостатки не понимая преемуществ.

15
Общий раздел / Re: [CP] Вопрос про Message Bus.
« : Февраль 02, 2013, 09:44:01 am »
То есть это выглядит примерно так?
Примерно так. Только в BlackBox нигде processed и аналогов не используются. Сообщения шлются либо конкретно заданному объекту, либо всем видимым отображениям с заданной моделью (тупо перебираются все фреймы окна и сравнивается модель), либо всем отображениям, которые находятся в пути фокуса. Есть ещё другие специфичные варианты, здесь их рассматривать не будем. При посылке конкретно заданному объекту процедура посылки, это лишь небольшая обёртка, выполняющая проверки и прочие мелкие операции, например процедура посылки сообщения свойств:
PROCEDURE HandlePropMsg* (v: View; VAR msg: PropMessage);
VAR a: View; op: INTEGER;
BEGIN
IF ~(handler IN v.bad) THEN (* проверяем, что в раньше в обработчике v не было TRAP'а *)
a := actView; op := actOp; actView := v; actOp := handler; (* запоминаем отображение и тит обработчика *)
v.HandlePropMsg(msg); (* вызываем обработчик *)
actView := a; actOp := op (* возвращаем всё как было *)
END
END HandlePropMsg;

Но тогда я не понимаю тезис про нагрузку на сборщик мусора - ведь при такой модели использования можно просто в куче создать по одному сообщению каждого типа и просто из повторно использовать. Даже если у нас типов сообщений действительно многого, штук 100, то все равно никакой значимой нагрузки на GC не будет. Да и аллокаций памяти не будет тоже.

Тоесть имеется ввиду что-то вроде:
TYPE MouseMovedMsg* = POINTER TO RECORD x, y: INTEGER END; (* встроить тип в VAR нельзя, иначе нельзя будет привести к нему сообщение *)
VAR mouseMoved: MouseMovedMsg;

PROCEDURE SendMouseMoved*(t: Target; x, y: INTEGER);
BEGIN
  mouseMoved.x := x; mouseMoved.y := y;
  t.Handle(mouseMoved)
END SendMouseMoved;

BEGIN
  NEW(mouseMoved)
?
Такой подход может не сработать, если обработчик рекурсивно шлёт сообщение того-же типа. Да и громоздко всё это, но впринципе работать будет, если добавить проверки на вложенную посылку сообщений.

Подход со стеком выглядит намного проще, понятнее и привлекательнее.

Страницы: [1] 2 3