OCaml internals: Exceptions

前端 未结 1 1739
一生所求
一生所求 2020-12-13 19:19

I\'m curious to know how exceptions are dealt with in OCaml runtime to make them so lightweight. Do they use setjmp/longjmp or do they return a special value in each functio

相关标签:
1条回答
  • 2020-12-13 20:19

    OCaml exception handling

    It doesn't use setjmp/longjmp. When a try <expr> with <handle> is evaluated, a "trap" is placed on the stack, that contains information about the handler. The address of the topmost trap is kept in a register¹, and when you raise, it jumps directly to this trap, unwinding several stack frames in one go (this is better than checking each return code). A trap also stores the address of the previous trap, which is restored in the register at raise time.

    ¹: or a global, on architectures with not enough registers

    You can see for yourself in the code:

    • bytecode compilation: lines 635-641, two Kpushtrap/Kpoptrap bytecodes surround the try..withed expression
    • native compilation: lines 254-260, again instructions Lpushtrap/Lpoptrap around the expression
    • bytecode execution for the bytecode PUSHTRAP (places the trap/handler), POPTRAP (remove it, non-error case) and RAISE (jump to the trap)
    • native code emission on mips and on amd64 (for example)

    Comparison with setjmp

    Ocaml uses a non-standard calling convention with few or no callee-saved registers, which makes this (and tail-recursion) efficient. I suppose (but I'm no expert) that's the reason why C longjmp/setjmp isn't as efficient on most architectures. See for example this x86_64 setjmp implementation that looks exactly like the previous trapping mechanism plus callee-registers save.

    This is taken into account in the C/OCaml interface: the usual way to call a Caml function from C code, caml_callback, doesn't catch OCaml-land exceptions; you have to use a specific caml_callback_exn if you wish to, which setups its trap handler and saves/restores callee-saved registers of the C calling convention. See eg. the amd64 code, which saves the registers then jump to this label to setup the exception trap.

    0 讨论(0)
提交回复
热议问题