Size: a a a

Compiler Development

2021 March 30

к

кана in Compiler Development
хм, мы говорим сугубо про язык, на реализацию пока что все равно
источник

к

кана in Compiler Development
под регистром понимается регистр в вм-ке, а не регистр проца
источник

AT

Alexander Tchitchigi... in Compiler Development
кана
вот у нас пустой стек: []
мы закинули два аргумента
[1, 2]
мы сделали кол, в стек попал адрес возврата, и frame pointer, текуший стал FP = 4
[1, 2, CP+1, OLDFP]
мы аллоцировали в функции 3 переменных локальных
[1, 2, CP+1, OLDFP, 0, 0, 0]
мы положили на стек результат
[1, 2, CP+1, OLDFP, 0, 0, 0, 42]
мы вычистили все локальные переменные, сбросив все до FP
[1, 2, CP+1, OLDFP]
восстановили FP до OLDFP, вернулись на CP+1
[1, 2]
результат потерялся, аргументы в стеке
Не-не-не, у Вас же два стека?
источник

AT

Alexander Tchitchigi... in Compiler Development
кана
почему add какой-нибудь возвращает результат на стек, а функции в регистр какой-то
Функция кладёт результат в регистр, команда ret делает возврат и перекладывает на стек. 😉
источник

к

кана in Compiler Development
Alexander Tchitchigin
Не-не-не, у Вас же два стека?
это вот я говорю про случай с одним стеком
источник

к

кана in Compiler Development
у меня сейчас два стека, да, но второй стек невидим для программиста
источник

AT

Alexander Tchitchigi... in Compiler Development
кана
это вот я говорю про случай с одним стеком
С одним не получится без произвольной адресации. Потому в Forth их два.
источник

AT

Alexander Tchitchigi... in Compiler Development
кана
у меня сейчас два стека, да, но второй стек невидим для программиста
Это не значит, что ВМ не может на него класть аргументы вызова а потом читать оттуда.
источник

к

кана in Compiler Development
с чисто двумя стеками тоже без произвольной адресации было не очень удобно, простейшие вещи превращались в огромное число перекидываний туда-обратно со свапами
источник

Z

Zaner in Compiler Development
кана
хм, мы говорим сугубо про язык, на реализацию пока что все равно
ну в том же байткоде jvm при коле забирается n аргументов, возвращается результат, и всякие адреса возврата скрыты в реализации, почему так не сделать?
источник

AT

Alexander Tchitchigi... in Compiler Development
кана
с чисто двумя стеками тоже без произвольной адресации было не очень удобно, простейшие вещи превращались в огромное число перекидываний туда-обратно со свапами
Welcome to the stack languages! 😂
источник

к

кана in Compiler Development
Zaner
ну в том же байткоде jvm при коле забирается n аргументов, возвращается результат, и всякие адреса возврата скрыты в реализации, почему так не сделать?
ну, вот сейчас так и сделано у меня, я просто сомневаюсь в хорошести этого решения
источник

AT

Alexander Tchitchigi... in Compiler Development
кана
ну, вот сейчас так и сделано у меня, я просто сомневаюсь в хорошести этого решения
Просто напишите JIT, который это всё соптимизирует! 😂
источник

PS

Peter Sovietov in Compiler Development
Alexander Tchitchigin
Просто напишите JIT, который это всё соптимизирует! 😂
источник

к

кана in Compiler Development
я так понимаю в jvm как раз и есть этот отдельный регистр для возвращаемого значения
источник

Z

Zaner in Compiler Development
кана
не понимаю как сделать стековый язык красиво

в данный момент у меня решение как раз такое как выше описано: у меня есть дата-стек, с которым работают все операции, и есть отдельный колстек, на котором лежат стекфреймы, где "стекфрейм" это адрес возврата + ссылка на собственную кучу для локальных переменных, куда идут все аргументы сразу при call

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

но стек использовать я так понимаю нельзя, что с ebp/fp, что без него, потому что результат функции тоже возвращается через стек, регистров же нет, нельзя сбрасывать стек до ebp

вот текущее решение - https://gist.github.com/kana-sama/31a7dbcda0d434f0013e4f2227b8c895
можно не выделять кучу на каждую функцию: запоминаем указатель стека при входе в процедуру, от него считаем локальные переменные, при выходе из процедуры копируем результат к себе, чистим стек и кладём результат обратно. Но опять же, я не понимаю вы про язык или реализацию
источник

к

кана in Compiler Development
там результат кладется не на стек, а через специальный [i|d|b|...]return возвращается
источник

PG

Per-Lorean Graph in Compiler Development
кана
вот у нас пустой стек: []
мы закинули два аргумента
[1, 2]
мы сделали кол, в стек попал адрес возврата, и frame pointer, текуший стал FP = 4
[1, 2, CP+1, OLDFP]
мы аллоцировали в функции 3 переменных локальных
[1, 2, CP+1, OLDFP, 0, 0, 0]
мы положили на стек результат
[1, 2, CP+1, OLDFP, 0, 0, 0, 42]
мы вычистили все локальные переменные, сбросив все до FP
[1, 2, CP+1, OLDFP]
восстановили FP до OLDFP, вернулись на CP+1
[1, 2]
результат потерялся, аргументы в стеке
Можете аллоцировать место на стеке в размером с тип возвращаемого значения, а в функции вместо return записывать данные по указателю
источник

PG

Per-Lorean Graph in Compiler Development
Zaner
можно не выделять кучу на каждую функцию: запоминаем указатель стека при входе в процедуру, от него считаем локальные переменные, при выходе из процедуры копируем результат к себе, чистим стек и кладём результат обратно. Но опять же, я не понимаю вы про язык или реализацию
Полагаю результат «скопировать» к себе вы можете только положив его на стэк.
источник

ДК

Дмитрий К in Compiler Development
Есть разные соглашения о вызовах. Где-то вызываемая функция подчищает за собой (восстанавливает регистры), где-то вызывающая, где-то обе - каждая свои регистры. Для простоты интеграции с сишными либами и скорости работы с ними, имеет смысл использовать то же соглашение.
источник