OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 25 Апрель, 2024 00:14

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
СообщениеДобавлено: Пятница, 09 Июнь, 2023 13:48 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
я тут подумал: у нас есть чудесная штука `SYSTEM.THISARRAY()`. всем хороша — кроме того, что опасная. но ведь мы можем сделать её безопасный усечённый вариант, и избавиться от постоянной передачи `arr, beg, end` и ты пы.

поскольку при передаче аргументов компилятор передаёт тэг и размеры массива (иначе THISARRAY была бы невозможна), мы можем ввести безопасную функцию `SLICE(arr, beg, end)`, которая сначала проверит, правильный ли тип у `arr`, и не выходят ли `beg` и `end` за его границы, а потом просто сделает `THISARRAY()`.

изменения в основном в CPP, для проверки правильного типа `arr`, и в кодогене вставление проверок `beg` и `end` (процедуры для этого уже есть). ещё я бы предложил считать `SHORTCHAR` и `BYTE` совместимыми, потому что давайте честно: знаковый байт нафиг никому не нужен, он такой потому что в жабке такой; а на деле все или сразу делают с ним `MOD 100H`, или используют напрямую `SHORTCHAR`. поэтому я вижу смысл разрешить такие слайсы.

плюсы: раз и навсегда избавляемся от глупостей `arr, beg, end`, и всех связаных с ними ручных ассертов: компилятор всё сделает за нас. при декларировании совместимости шортчаров и байтов перестаём делать в апи типа Files.Reader со товарищи отдельные обёртки для обработки байтовых массивов и шортчар-массивов. (ну да, нарушение типизации в какой-то степени; ну камон, вы реально где-то использовали байты для арифметики — особенно с учётом безвариантного их расширокивания до интов при любой операции?)

минусы: не вижу.

если что, в компиляторе уже есть подобный чит: `arr$`. это тот же самый слайс, только менее «генерализованый». поскольку любой компилятор CP обязан такую штуку поддерживать — то можно смело предполагать, что все компиляторы будут передавать массивы как `тэг, адрес, длина`, и наличие `SLICE()` никаких дополнительных ограничений на компилятор не накладывает.

изменения для mainline компилятора я сделаю, если что, вы, главное, мигните.

p.s.: слайсы динамических массивов совершенно безопасны, потому что динамические массивы заякорены вызывающей процедурой. а слайс в `POINTER TO ARRAY`, натурально, не разрешается.

p.p.s.: нет, библиотечно это не реализуется, в том-то и проблема. надо в язык добавлять.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 09 Июнь, 2023 14:00 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
rationale: я обнаружил, что у меня куча кода или засыпана бесполезной логикой с `beg, end`, или импортирует SYSTEM только для того, чтобы сделать с массивом THISARRAY, предварительно обложив козла матами^w^w всё ассертами. в итоге, несмотря на наличие SYSTEM, на самом деле код портабельный и безопасный; и ещё каждый раз приходится boilerplate руками писать. при том, что компилятор может справиться с этим самостоятельно, и намного лучше.

а. почему `beg, end`, а не `beg, len`? да фиг знает. я до сих пор не могу решить, что лучше: `beg, end` или `beg, len`, и что именно в апи использовать. собственно, сами омики тоже, поэтому в Files.Reader у них, например, `beg, len`, а в TextModel — `beg, end`. ужасно бесит, кстати, приходится помнить, где длина, а где конец. и не починишь уже, приходится с этим жить. я всё-таки склоняюсь к `beg, end`, потому что более высокоуровневая TextModel делает именно так.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 09 Июнь, 2023 20:20 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
собственно, некоторое ограничение: передавать обрезки массивов можно только в процедуры, которые принимают open array.

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

омики для случая `a$` и параметров-массивов фиксированой длины — не поверите — делают временную переменную на стеке точно нужного размера, копируют туда строку, и потом передают временную перменную. я, конечно, тоже так могу, но вот здесь не вижу смысла. потому что один фиг копия делается — так пусть программист её явно руками делает, а не удивляется, кто стек сожрал. вся идея `SLICE()` ровно в том, чтобы избегать копирования, когда оно не нужно, а не добавлять новое.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 09 Июнь, 2023 20:23 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
кстати, передача неоктрытых массивов без `IN` делает копии тоже по месту вызова, причём делается это уже силами кодогена, выделяя место на стеке через `ADD ESP, -size`. конечно, почистить это потом все забыли. ну ёлы-палы, ну… вот засунуть такое в длиииинный цикл — и офигеть от того, что внезапно, на пустом месте, закончится стек. какого чёрта это не делается в вызываемой процедуре?

отсюда запомните правило хорошего тона: никогда не вызывайте в цикле процедуру, которая принимает неоткрытый массив без `IN`.

короче, иллюстрация:
Код:
   TYPE S10 = ARRAY 10 OF CHAR;

   PROCEDURE Str2Proc (a: S10);

   PROCEDURE TestStr12;
   VAR b: S10;
   BEGIN
      Str2Proc(b); (* тут мы делаем копию b на стеке через ADD ESP *)
      Str2Proc(b); (* а тут ещё раз, забыв убрать старую копию, снова через ADD ESP *)
   END TestStr12;
делается две копии `b`. будет цикл — будет овердофига копий, место на стеке выделяется каждый раз. по-моему, это тупо баг, ребята забыли подкорректировать ESP в финале.

но.
Код:
   PROCEDURE Str0Proc (a: ARRAY OF CHAR);

   PROCEDURE TestStr13;
   VAR b: S10;
   BEGIN
      Str0Proc(b);
      Str0Proc(b);
   END TestStr13;
копии `b` делаются внутри `Str0Proc`, так что такой вызов из цикла безопасен.

Код:
   PROCEDURE Str1Proc (IN a: S10);

   PROCEDURE TestStr13;
   VAR b: S10;
   BEGIN
      Str1Proc(b);
      Str1Proc(b);
   END TestStr13;
никаких копий.

Код:
   PROCEDURE Str1Proc (IN a: S10);

   PROCEDURE TestStr14;
   VAR b: S10;
   BEGIN
      Str1Proc(b$);
      Str1Proc(b$);
   END TestStr14;
а вот тут всё происходит уровнем выше: заводятся две скрытые локальные перменные (по количеству вызовов). такая ерунда в цикле безопасна. то есть, место на стеке выделяется один раз, по визуальному счёту вызовов. собственно, реальный AST:
Код:
   PROCEDURE TestStr14
      VAR @str0: ARRAY 10 OF CHAR
      VAR @str1: ARRAY 10 OF CHAR
      VAR b: S10
   BEGIN
      COMPOUND
         @str0 := b$;
         CALL Str1Proc(@str0$);
      END COMPOUND;
      COMPOUND
         @str1 := b$;
         CALL Str1Proc(@str1$);
      END COMPOUND;
   END TestStr14


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 10 Июнь, 2023 08:58 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
реализовал PoC. как и сказано — передавать слайсы можно только в процедуры, которые принимают open array.

сделано не очень красиво, но я хотел по минимуму врезаться в кодоген. поэтому в кодогене добавлена отдельная процедурка в `DevCPV.ActualPar()`, а в DevCPB делается акробатика по переписыванию `SLICE(arr, beg, end)` в нечто типа: `SLICE(arr[beg], COMP(ASSERT((end >= beg) & (end <= LEN(arr)), inxTrap), end - beg))`. отдельная процедурка понадобилась затем, что кодоген такие компаунды не понимает, так что я использую компаунд чисто как контейнер для нод (анализаторы AST такие контейнеры понимают правильно).

как и полагается, если индексы — константы, и размер массива известен на стадии компиляции, то проверки будут сделаны на стадии компиляции, и в финальный код не попадут. это само собой получается за счёт constant folding.

присваивание слайсов не поддерживается. в смысле: `arr1 := SLICE(arr2, b, e)` распарзится, но потом компилятор обидится, потому что фича исключительно для параметров. опять же: сделать можно, но я не хочу.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 10 Июнь, 2023 11:51 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
ох, блин… омики меня в очередной раз обманули: нет у них ошибки с балансировкой стека. эти хитрые жуки чистят стек в вызываемом коде, через `RET оченьмного`.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 10 Июнь, 2023 11:59 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
вообще, интересно, кто у них кодоген для X86 делал. чувак с… неортодоксальным мышлением. это не в смысле завуалированого оскорбления, совсем наоборот: я восхищаюсь. потому что кодоген в CP2 не очень похож на OP2. то есть, совсем не похож, хотя основная идея сохранена.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 14 Июнь, 2023 12:30 
Аватара пользователя

Зарегистрирован: Воскресенье, 09 Декабрь, 2018 15:14
Сообщения: 113
Откуда: Equestria
arisu писал(а):
вообще, интересно, кто у них кодоген для X86 делал
Судя по заголовку в CPV486 - Beat Heeb. Кроме того, по комментам очевидно, что любые значитльные кромсания компилятора за его же авторством (DTC, CP, кодоген 486).


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB