<dev-c-local-variable/> elements to declare local variables in the generated C code. The first bug was that Dryverl allows such an element to be empty, which would mean that the generated C local variable declaration has no specific initial value. However, in that case, Dryverl generated invalid declarations, such as:
int some_var = ();
Dryverl 0.1.3 now correctly generates no initializer in such cases:
The second bug was in the generated code that encodes output data, i.e. data that is returned from the C side to the Erlang side of the driver. As several methods are available in the Erlang port driver API to communicate between C and Erlang, Dryverl-generated drivers try to automatically use the most efficient one. The most efficient of all is the port call method. In the case the C code is invoked by a port call from the Erlang side, the emulator allocates itself a buffer that must be used for returning the output encoded data. The code generated by Dryverl automatically uses that buffer whenever possible, to avoid unnecessary memory allocation. However, if the encoded data exceeds that buffer, the generated code automatically switches to another method, which is to encode the output data as a separately allocated Erlang binary term, and reference that term from the output data encoded in the port call buffer.
The bug was that when the port call output buffer is exceeded, the data already encoded into it was not copied into the newly allocated Erlang binary’s buffer, i.e. the start of that binary was left as garbage. The code generated by Dryverl 0.1.3 now correctly handles that case by copying the port call output buffer data into the Erlang binary buffer, before using that Erlang binary to further encode output data.
That second bug is of a kind that is very hard to trigger, because of the very large number of possible combinations of methods that can be used to communicate between Erlang and C, and because the code generated by Dryverl, and the strategy chosen by that code, depend on several conditions: are binaries sent in input? in output? are asynchronous threads used? is the encoded output data too large to fit the port call output buffer?, etc.
Thanks a lot to Hunter Morris for spotting those two bugs and for submitting a patch!