When setting up the interrupt table using the code from lilith the lilith implementation does: (->kernel_cpu_exception0).pointer.address
However in assembly the ->kernel_cpu_exception0 effectively creates a wrapper function
push rax
call kernel_cpu_exception0
pop rax
ret
So we actually have the address of this wrapper function instead of the kernel_cpu_exception0 function. The address of the actual function is important to handle interrupts as we need to preserve CPU state before calling any additional functions (stack needs to be clean too)
I tried doing
fun kernel_cpu_exception0()
# ...
end
lib Kernel
$kernel_cpu_exception0 : Int64
end
pointerof(Kernel.kernel_cpu_exception0).address
However it looks like the compiler tries to avoid having the symbols clash and mangles the name? so that doesn’t work.
The general protection fault that is occurring because of the wrapper (at least I think this is the reason)
I did put in this workaround to attempt to undo the affect of the call instruction
Maybe it worked for lilith because it was previous to that change.
That said, it might be worth opening a feature request so that if you take do ->fun and that points to a fun, it doesn’t create a wrapper. Maybe in the general case it shouldn’t create a wrapper, but it’s hard to detect.
Also, if it’s ->foo (no args) I think it should never create a wrapper as there’s no way it could multidispatch, so another thing we could optimize there.