.include "macros.s" .section .init .global _start _start: jmp _uskel_start .section .bss _memory_state: cell 0 # bottom of allocation (grows down) cell 0 # region start cell 0 # region end .section .text _uskel_alloc_basic_mem: mov $0x100000, %r15 # desired size mov $0x9, %rax # mmap mov $0, %rdi # addr = NULL mov %r15, %rsi # len = %rcx mov $0x3, %rdx # prot = PROT_READ 0x1 | PROT_WRITE 0x2 mov $0x22, %r10 # flags = MAP_PRIVATE 0x2 | MAP_ANONYMOUS 0x20 mov $-1, %r8 # fd = -1 mov $0, %r9 # off = 0 syscall mov $_memory_state, %rdi mov %rax, (%rdi) mov %rax, 0x8(%rdi) add %r15, %rax mov %rax, 0x10(%rdi) retq _uskel_start: call _uskel_alloc_basic_mem mov _memory_state, %rdi # push a thunk for main mov %rdi, %r15 # backup main for later movq $main, 0x00(%rdi) movq $0, 0x08(%rdi) add $0x10, %rdi # save the memory ptr mov %rdi, _memory_state mov $0, %rsi # set continuation to exit enter %r15 # run the program # Simple values and boxed machine integers # | ptr | value | CON_evacuate1: retq CON_scavenge1: add $0x10, %rsi retq INT_info_table: cell CON_evacuate1 cell CON_scavenge1 cell 0 INT_code: continue # List # | ptr | 0 | # | ptr | 1 | a | b | LIST_evacuate: # [] | a : b retq #TODO LIST_scavenge: mov 0x8(%rbp), %rax shl $1, %rax add $2, %rax shl $3, %rax add %rax, %rsi retq LIST_info_table: cell LIST_evacuate cell LIST_scavenge cell 0 LIST_code: continue # FUN/PAP combo objects # | ptr | thunkptr | args | arg[0] | arg[1] | ... | arg[args] | FUN_evacuate: retq #TODO FUN_scavenge: mov 0x10(%rbp), %rax add $3, %rax shl $3, %rax add %rax, %rsi retq # Simple info for n-ary functions # TODO continue to add as required fun1_info_table: cell FUN_evacuate cell FUN_scavenge cell 1 fun1_code: continue fun2_info_table: cell FUN_evacuate cell FUN_scavenge cell 2 fun2_code: continue fun3_info_table: cell FUN_evacuate cell FUN_scavenge cell 3 fun3_code: continue # indirection (Q: how to recognize IND and THUNK on return?) # | ptr | indptr | IND_evacuate: retq #TODO IND_scavenge: add $0x10,%rsi retq IND_info: cell IND_evacuate cell IND_scavenge cell 0 IND_code: enter 0x8(%rbp) # THU objects (gc implementation only, actual THUs are defined by functions) # | ptr | args | arg[0] | arg[1] | ... | arg[args] | # args wouldn't need to be here but let's keep them for gc simplicity THU_evacuate: retq #TODO THU_scavenge: mov 0x8(%rbp), %rax add $2,%rax shl $3,%rax add %rax,%rsi retq # # Actual code! # # || -> cont .makethunk main mov _memory_state, %r15 # push a new integer mov %r15, %r11 # backup first arg movq $INT_code, 0x00(%r15) movq $100, 0x08(%r15) add $0x10, %r15 # push another new integer mov %r15, %r12 # backup second arg movq $INT_code, 0x00(%r15) movq $23, 0x08(%r15) add $0x10, %r15 # push the plus mov %r15, %r13 # backup plus movq $plus, 0x00(%r15) movq $2, 0x08(%r15) mov %r11, 0x10(%r15) mov %r12, 0x18(%r15) add $0x20, %r15 # push a cont thunk for main_exit mov %r15, %r14 # backup cont thunk movq $main_exit, 0x00(%r15) movq $1, 0x08(%r15) mov %rsi, 0x10(%r15) add $0x18, %r15 mov %r15, _memory_state # evaluate into main_exit mov %r14, %rsi enter %r13 # exitcode -> | cont (unused, should be 0) | .makethunk main_exit mov 0x8(%rsi), %rdi mov $0x3c, %rax syscall # exit %rdi # | arg1 | arg2 | -> cont .makethunk plus # push a thunk for finishing the plus mov _memory_state, %r15 mov %r15, %r14 # plus_step1 origin movq $plus_step1, 0x00(%r15) movq $3, 0x08(%r15) mov 0x18(%rbp), %rax mov %rax, 0x10(%r15) mov %rbp, 0x18(%r15) mov %rsi, 0x20(%r15) add $0x28, %r15 mov %r15, _memory_state # evaluate arg0 mov %r14, %rsi enter 0x10(%rbp) # arg0 -> | arg1 | ret | cont | .makethunk plus_step1 # this is guaranteed to be entered only once (it's a cont), so we can rewrite the thunk in place mov 0x10(%rbp), %rax movq $plus_fini, 0x00(%rbp) mov %rsi, 0x10(%rbp) mov %rbp, %rsi # continue on the rewritten thunk enter %rax # evaluate arg1 # arg1 -> | arg0 | ret | cont | .makethunk plus_fini mov 0x8(%rsi), %rax # arg1 mov 0x10(%rbp), %rsi add 0x8(%rsi), %rax # + arg0 mov 0x18(%rbp), %rsi # rewrite the resulting thunk movq $INT_code, 0x00(%rsi) mov %rax, 0x08(%rsi) # result is in rsi already enter 0x20(%rbp) # Q: are there gonna be functions that have both the argument AND the cont? # A: No, either stuff is entered as return-continuation (takes res) or as forward call (takes cont) # (needs validation)