Age | Commit message (Collapse) | Author |
|
f73822 was supposed to do this, but I messed up expanding the
C99_NARGS macro fully.
NARGS also needs to support 2X the desired number of parameters
as they're supplied in {type, name} pairs.
12 is the maximum number of pairs supported at this time, adding
more is trivial when needed.
|
|
Since thunk instances are utilized via initializer functions
which always initialize all the environment members, it made
sense to use plain malloc().
But with the addition of payloads, there's a component of the
allocation which gets split out for the caller to make use of
in a much more ad-hoc fashion.
In my personal programming style, I tend to take advantage of the
assumption that allocations are zeroed. The returned payload is
essentially used as a heap allocation, just coupled to the thunk
instance in terms of life cycle. So I prefer the payload space
be zeroed on allocation.
Since it still seems sensible to leave the thunk's environment
part of the instance exclusively initialized by it's init
function, this commit leaves the plain malloc and just memset's
the payload when present.
|
|
This shuts up gcc warnings w/-Wall for thunked functions.
It's expected there will be some unused functions, esp. since
there's the split init/alloc variants one may or may not use.
It's also nice in some scenarios to write a collection of small
closures a project may or may not take advantage of at any given
moment in its development. No point making a bunch of noise
about it.
|
|
In scenarios where a thunk instance must be dispatched multiple
times, the automatic free is a problem.
This commit moves the free out of the dispatch implementations
and into the thunk_dispatch() wrapper. So the behavior of
thunk_dispatch() is unchanged.
The new thunk_dispatch_keep() is a plain ->dispatch(). This does
implicitly turn 'thunk_t *' being a free() able allocation into
part of the API, which may be a problem later. But who cares,
this is a .h for vendoring, not a .so w/ABI guarantees.
|
|
The existing THUNK() instantiation macro has really nice ergonomics
taking the form of the bare function call wrapped by THUNK().
It's desirable however to sometimes enlarge the instance's allocation to
accomodate some user-specified data with an instance-boound life cycle.
There didn't seem to be a clean way to provide that with the existing THUNK()
interface.
This commit introduces a split THUNK() variant for such scenarios:
THUNK_ALLOC(function_name, payload_pointer, payload_size)
and
THUNK_INIT(function_name(thunk_instance, [function_args] ...))
It's expected that these be used in pairs, like so:
char *buf;
thunk_t *t = THUNK_ALLOC(foo_func, &buf, BUFSIZ);
THUNK_INIT(foo_func(t, foo_arg1, foo_arg2));
Note the THUNK_INIT's foo_func call has the thunk_t * passed as the first
parameter. This isn't part of foo_func's THUNK_DEFINE signature, it's only
part of the initializer for the function, followed by the real parameters
from the THUNK_DEFINE's signature if there are any.
This differs from the simpler THUNK() variant, where you'd do:
THUNK(foo_func(foo_arg1, foo_arg2));
Also note the THUNK_ALLOC() above has stored a pointer to BUFSIZ bytes
of payload memory @ *buf. This could then be supplied into foo_func,
which is sometimes convenient:
THUNK_INIT(foo_func(t, foo_arg1, buf));
The payloads are particularly useful when chaining up multiple thunks, and
there's a need for some shared state across them for inputs/outputs, that
you'd like automatically cleaned up when the instance the payload belongs to
executes and returns freeing itself.
|
|
This is necessarily split in two:
THUNK_DEFINE()
THUNK_DECLARE()
use is identical to the original THUNK_DEFINE (now THUNK_DEFINE_STATIC),
and you supply the same input to both DEFINE and DECLARE.
The THUNK_DECLARE() should go in the public header, which you also
include in the implementing .c file, not just from consumers.
The THUNK_DEFINE() goes in the implementing .c file, same as before.
Use this variant when you wish to instantiate via THUNK() from external
listings, just include the THUNK_DECLARE()-containing .h.
|
|
In preparation for supporting both public and private thunk defines,
convert the current assumed-private one to use a _STATIC suffix.
|
|
this is necessary for nested THUNK() constructions, e.g.:
thunk_t * closure = THUNK(a, b, c, THUNK(d, e, f));
|
|
this internal macro just generates the initializer, just switching to
a more accurate name.
|
|
Just bumping this limit a bit
|
|
Pragma isn't standardized and it didn't seem to be working properly
in a project where simply replacing it with this commit fixed
compilation
|
|
Overlooked this, but it's also odd how the __VA_ARGS__
when empty is still being passed as a separate argument
requiring the addition of the _nil placeholders.
|
|
If there comes a time when this is an issue, selector may be
added and a separate declaration macro provided.
For now, it appears static use is generally the appropriate
thing to do.
|
|
Something I slapped together in the interests of mechanizing the creation
of thunks in C. In this context a thunk is simply a helper function that
serves to normalize the calling convention of functions having potentially
varying arity.
This code has not been used in anything yet, I just put it together because
I anticipate using it soon based on some projects I've been thinking about.
example.c contains a trivial usage example.
|