These changes make it possible to override the value which is returned by llhelpers in case of error. This is needed to correctly implement certain HPy functions.
However, there is a blocker. See test_exceptiontransform.test_llhelper_can_raise_custome_error_value
for the details, but the basic problem is the folowing:
- we declare an llhelper to return -123 in case of exception
- we call this llhelper as the last statement from a normal RPython function, which should return -1 in case of exception
- as an optimization, exceptiontransform doesn't bother to check whether the llhelper raised, and just return its return value. This works if all the functions always return the same error value, but it's no longer the case.
Possible solutions:
-
remove this optimization and require to do the exception check always after an indirect call. But it's a bit annoying to potentially slow down general code for a feature which is useful only in a corner case
-
completely change the approach and attach the error_value to the TYPE of the function: this is the cleanest solution but probably the most complex. It would mean that you can't union functions returning different values for exceptions (which might or might not make sense, I don't know).
-
ignore the problem: AFAIK the value returned by rpython functions is NEVER checked explicitly: all the code checks the content of exc_data to determine whether an exception has occurred, so I think that after compilation everything will just work (Note that currently the test fails because of a check inside the llinterp that was introduced by this branch). We could declare that the return value of an rpython function in case of exception is "random", unless you specify
@llhelper_can_raise
: in that case, it is enforced.
@arigo I would appreciate your input on this.
While we are at it, design question: what about putting the error value inside the call to llhelper
. E.g., instead of this:
@llhelper_can_raise(error_value=-123)
def foo(): ...
fnptr = llhelper(F, foo)
we could do that:
def foo(): ...
fnptr = llhelper(F, foo, error_value=-123)