Exception - pannous/warp GitHub Wiki
No exception needed: failed
Most errors need not be thrown at all: return one as a value and let the caller test it.
f(x) := if x < 0 then error "neg" else x
r = f(-1)
if r failed then 1 else 2 # 1
Only a raised error (raise, 1/0, an index out of range) propagates; a bare try keeps it as a value
(r = try 10/0; if r failed then 1 else 2 is 1), try … else or catch handles it.
In the ABI
Today a raised error is a WebAssembly exception: runtime errors throw the tag warp_error while a try runs, which
catches it with try_table, however deep it happened. The smart-pointer scheme below was the earlier plan.
Exceptions can be represented and handled in the ABI via smart pointers. We do not need extensions to the WASM MVP in order for this to work:
Every function call in the ABI can be made to be followed by a check whether the return value contains an Exception(pointer). If so, pass it on to the caller by returning immediately, unless the function contains a catch block. This is possible because all functions adhere to our universal smart pointer scheme.
So throw "no such file" is compiled to return 0xE0123456 where 0x0123456 is the position of the error object in linear memory. In the caller we find the wasm code
call $some_func
i32.and 0xF0000000
if i32.eq 0xE0000000 ;; error
if has catch
goto error handling
else
pop
return
end
end
else
pop ;; forget our i32.and calculation
end
These extra 20ish bytes per function call are forgivable, especially if the compiler is smart about whether the callee throws or not and whether there is a catch block.