Size: a a a

Compiler Development

2021 March 29

M

MaxGraey in Compiler Development
в том, что x >> y не определено если y > 31
источник

IP

Iaroslav Postovalov in Compiler Development
MaxGraey
в том, что x >> y не определено если y > 31
Понял
источник
2021 March 30

к

кана in Compiler Development
что почитать про то, как генерировать байткод стекового языка для функциональных языков?

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


; fib(N) -> fib(N, 1, 1).
; fib(0, _, B) -> B;
; fib(N, A, B) -> fib(N-1, B, A+B).

; A B | C D -- это дата стек [A, B] и return stack [D, C]

fib/1:           ; N |
fib/1[0]:        ; N |
 lit 1          ; N 1 |
 lit 1          ; N 1 1 |
 call fib/3     ; fib/3(N, 1, 1) |
 ret            ; fib/3(N, 1, 1) |

fib/3:
fib/3[0]:        ; N A B |
 rpush          ; N A | B
 rpush          ; N | A B
 dup            ; N N | A B
 rpop           ; N N A | B
 swap           ; N A N | B
 rpop           ; N A N B |
 swap           ; N A B N |
 lit 0          ; N A B N 0 |
 eq             ; N A B [0 или 1] |
 jmpf fib/3[1]  ; N A B
 rpush          ; N A | B
 drop           ; N | B
 drop           ; | B
 rpop           ; B |
 ret            ; B |
fib/3[1]:        ; N A B |
 rpush          ; N A | B
 rpush          ; N | A B
 lit 1          ; N 1 | A B
 sub            ; (N-1) | A B
 rpop           ; (N-1) A | B
 rpop           ; (N-1) A B |
 swap           ; (N-1) B A |
 rpush          ; (N-1) B | A
 dup            ; (N-1) B B | A
 rpop           ; (N-1) B B A |
 swap           ; (N-1) B A B |
 add            ; (N-1) B (A+B) |
 jmp fib/3      ; (N-1) B (A+B) |


rpush/rpop - это return stack, перекидывание из основно стека во вторичный и обратно
источник

к

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

D

Danya in Compiler Development
кана
что почитать про то, как генерировать байткод стекового языка для функциональных языков?

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


; fib(N) -> fib(N, 1, 1).
; fib(0, _, B) -> B;
; fib(N, A, B) -> fib(N-1, B, A+B).

; A B | C D -- это дата стек [A, B] и return stack [D, C]

fib/1:           ; N |
fib/1[0]:        ; N |
 lit 1          ; N 1 |
 lit 1          ; N 1 1 |
 call fib/3     ; fib/3(N, 1, 1) |
 ret            ; fib/3(N, 1, 1) |

fib/3:
fib/3[0]:        ; N A B |
 rpush          ; N A | B
 rpush          ; N | A B
 dup            ; N N | A B
 rpop           ; N N A | B
 swap           ; N A N | B
 rpop           ; N A N B |
 swap           ; N A B N |
 lit 0          ; N A B N 0 |
 eq             ; N A B [0 или 1] |
 jmpf fib/3[1]  ; N A B
 rpush          ; N A | B
 drop           ; N | B
 drop           ; | B
 rpop           ; B |
 ret            ; B |
fib/3[1]:        ; N A B |
 rpush          ; N A | B
 rpush          ; N | A B
 lit 1          ; N 1 | A B
 sub            ; (N-1) | A B
 rpop           ; (N-1) A | B
 rpop           ; (N-1) A B |
 swap           ; (N-1) B A |
 rpush          ; (N-1) B | A
 dup            ; (N-1) B B | A
 rpop           ; (N-1) B B A |
 swap           ; (N-1) B A B |
 add            ; (N-1) B (A+B) |
 jmp fib/3      ; (N-1) B (A+B) |


rpush/rpop - это return stack, перекидывание из основно стека во вторичный и обратно
Кажется ты в первом случае аргумент функции N не положил на стек
Или аргументы уже на стеке лежат?
источник

к

кана in Compiler Development
Danya
Кажется ты в первом случае аргумент функции N не положил на стек
Или аргументы уже на стеке лежат?
N уже на стеке, да
источник

D

Danya in Compiler Development
кана
N уже на стеке, да
А, ок
Просто в JVM по-другому сделано
источник

к

кана in Compiler Development
а как?
источник

D

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

к

кана in Compiler Development
хм, а как аргументы передаются в функцию? То есть как они могут быть локальными переменными [функции?], если функцию еще не вызвали?
источник

D

Danya in Compiler Development
А передаются через стек
А уже на стороне вызванной функции это локальные переменные
источник

D

Danya in Compiler Development
То есть fib/1 выглядело бы примерно так:
iload_0 // загрузка значения нулевой локальной переменной -> в данном случае аргумента
iconst_1
iconst_1
call fib/3
ret
источник

к

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

к

кана in Compiler Development
call знает арность функции и закидывает N значений со стека в локальные переменные?
источник

D

Danya in Compiler Development
кана
я не понимаю, а откуда бы переменная взялась там?
Ну вм перекинула со стека в значения локалок
источник

D

Danya in Compiler Development
кана
call знает арность функции и закидывает N значений со стека в локальные переменные?
Более того вм знает сигнатуры функций и в случае чего может бросить exception
источник

к

кана in Compiler Development
понял, выглядит удобно, сделаю так же
источник

D

Danya in Compiler Development
Если что, я совсем немного тыкал JVM и могу ошибаться
источник

D

Danya in Compiler Development
кана
понял, выглядит удобно, сделаю так же
https://docs.oracle.com/javase/specs/jvms/se7/html/index.html
Вот можешь спеку почитать)
источник

к

кана in Compiler Development
источник