Details
-
Improvement
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
None
-
None
-
None
Description
Most Lucy methods which return objects may not return NULL. Internal Lucy
code does not NULL-check the return values of such methods before using them
– for efficiency's sake, it trusts that the source has upheld the API
contract and returned a real object of the correct type.
If we screw up our C code and return NULL from such a method we'll get a
segfault, but that's OK – we're C developers and we know how to deal with
segfaults.
The problem arises when a host-language user creates a custom subclass and
overrides a method that's not supposed to return NULL, but screws up and e.g.
returns undef from Perl. Their invalid undef gets translated to NULL at the
binding boundary, hits our C code and triggers a segfault – but this time,
the user is not prepared to troubleshoot segfaults.
We don't want to litter every single method invocation with NULL checks –
especially since only a small minority of methods which return pointers might
legally return NULL.
The solution is to introduce a "nullable" type qualifier to Clownfish.
/** Open an InStream, or set Err_error and return NULL on failure. * * @param path A relative filepath. * @return an InStream. */ public incremented nullable InStream* Open_In(Folder *self, const CharBuf *path);
The callback wrappers we auto-generate can then know that they should perform
NULL-checking of return values when the return type does not have a "nullable"
qualifier – and throw an exception before inner Lucy code has the chance to
deref the NULL pointer and segfault.