=head1 NAME
C::Blocks - embeding a fast C compiler directly into your Perl parser
=for html
=head1 STATUS
Pre-Beta
The current blocker for beta is that C::Blocks::Object::Magic throws
segmentation faults. This is a blocker because the code in
C::Blocks::Object::Magic is not too complicated (as far as the compiler
should be conerned). Fixing this is a top priority of the Alpha stage.
C::Blocks::Object::Magic and its tests are not yet included in the CPAN
distribution, so even though this distribution is expected to pass its
test suite when installed from CPAN, it is still subtly broken. You can
be more confident in the distribution's robustness once it reaches
Beta.
For more on the milestones for Alpha, Beta, and v1.0, see Goals and
Milestones below.
I do not yet make any promises about backwards compatibility. (But, I
use this distribution in my own code, so you can anticipate that a fair
bit of the API has seen use and is not likely to change much.) In
particular, the compiler setup and type APIs will be ironed out, in
backwards-incompatible ways, during Beta.
=head1 DESCRIPTION
This distribution contains C, a module that adds a few
lexically scoped keywords to your Perl parser. These keywords delimit C
code blocks, and (in the current implementation) the code within them
is compiled during Perl's bytecode compilation phase. The keywords
including C, C, C, and C.
In addition, this distribution contains C, which
loads Perl's C API. I may eventually include similar modules for all
standard C libraries, such as libstdio, libmath, etc. Since libperl is
itself compiled with these libraries, I suspect that most of them will
be redundant for most people.
It can be difficult to safely attach C structs to Perl variables. This
problem was solved for XS authors with the module L.
This distribution provides a port of that module called
C.
This distribution presently includes C, which
provides a rudimentary vector type. It serves an important role as a
testing module. It will almost certainly be spun off into its own module
by the time C v1.0 is released, so you should not rely on its
presence in the base distribution.
=head1 BUILD NOTES
On Debian systems using system Perl (C or otherwise), the
bad-symbol auto-detection runs much, much faster if you have
C installed. This is strongly recommended, if possible. If
you use Perlbrew, it will not matter because your local Perl will have
libperl available.
=head1 GOALS AND MILESTONES
I have a number of goals I would like to accomplish for this project.
The basic set of milestones are (1) make it work, (2) test the heck out
of it, (3) settle on an API, and (4) decide whether to throw in the
kitchen sink.
=head2 Pre-Alpha
The goal during the pre-alpha stage was to get things mostly working on
most platforms. Once this was accomplished, I spun the first release on
CPAN. I declared victory on this stage when I got libperl caching
working on all three platforms I had easy access to, even though
StretchyBuffer still gave trouble on Windows.
=head2 Alpha CPAN Release, v0.01 - 0.49
The goal during the alpha stage is to achieve successful builds that
can be trusted to work on the three popular "user" operating systems:
Linux, Strawberry Windows, and Mac. Major work in the alpha stage will
focus on OS-specific build issues and vastly expanding the test suite.
The easiest and most important tests to add focus on Perl's own C API,
as well as porting XS::Object::Magic's tests for
C::Blocks::Object::Magic. Tests for things like scoping, memory
duration, and correct line number reporting need to be expanded as
well. A significant number of failures on Linux, Mac, or Strawberry
Windows systems will be considered blockers to finalizing the Alpha
stage.
Although originally planned as a much later addition, I have added
C::Blocks::Object::Magic during alpha. This modue is a port of
XS::Object::Magic. I want to keep this as a core module at least through
Beta. The idea it implements is too useful to distribute it elsewhere,
and it provides an excellent testing target. I hope to incorporate
XS::Object::Magic's test suite as part of the test build-up for Beta.
Besides Linux, Mac, and Strawberry, I plan to officially support all
operating systems for which Alien::TinyCCx successfully installs. (For
the moment, that includes the addition of gnukfreebsd.) TCC itself is
not guaranteed to work on Cygwin, for example, and I see no point in
holding back C::Blocks due to a failure of the underlying library. (See
the Beta requirements for more on Cygwin, and BSD.)
The API for tweaking the compiler will still be considered in flux, so
substantial library development is discouraged during Alpha.
It is easy to produce warnings saying
warning: assignment from incompatible pointer type
This is a bug with the underlying extended symbol table handling and
struct type checking. I would like this to be fixed sooner rather than
later. Thankfully, it is not hard to work around this warning, and it
is not a blocking issue.
=head2 Beta CPAN Release, v0.50 - v0.99
The goals after the distribution hits v0.50 include settling on a
compiler setup API, finalizing the automated type handling system,
cleaning up the internals, and officially supporting Cygwin and BSDs.
Pre-1.0 work will focus on expanding the documentation.
The current compiler setup API involves parsing global string
variables. This can certainly be done better. I want to work out a more
sophisticated and programatic approach to compiler setup so that
authors do not have to jump through too many hoops to set up C::Blocks
when wrapping a C library. In particular, L provides
information about functions and typemaps provided by other Perl XS
modules, and this API should make it easy to use this information.
C::Blocks pays attention to the type annotation of variables, and adds
init and cleanup code based on information from the type. The specific
mechanism for getting this type information is still in flux.
I believe that C and C represent a better
API for the lexically-scoped keywords introduced by C::Blocks. I used
the keyword API for prototyping because it was easy for me to get
started. During Beta, I would like to investigate using these. If this
alternative API represents an improvement over the keyword API, I want
the switch to take place during Beta.
The Alpha version of C::Blocks supports (but does not enforce)
single-threaded compilation of multi-threaded code. That is, it is
possible and perfectly safe for a thread to compile code that is run
simultaneously by many child threads. There are two problems with
threads. First, the Tiny C Compiler is not itself threadsafe, so if
multiple threads attempt to compile code simultaneously, things would
go horribly awry. Second, the actual object code produced when
C::Blocks compiles a chunk of code is stored in the parent's
thread-specific storage. If the parent exits before the child does
(which is not possible on Windows but is possible on POSIXy systems),
the child could try to execute code from memory that has been freed.
I would like to address these by protecting compilation with a mutex,
and by storing object code somewhere that can live across thread
boundaries. (Doing that in such a way that does not leak will be one of
the more challenging parts of this particular issue.) C::Blocks can
already produce thread-safe code following certain practies. The goal
here is to solve the problem with code, not programming practices.
Cygwin and BSD support will be added as soon as I can get
Alien::TinyCCx to build on those operating systems. Support for these
operating systems is a blocker for v1.0, and so this distribution will
not get out of Beta without sufficient work on Alien::TinyCCx (and
probably tcc itself).
With the settling of the compiler setup API, I also hope to make it
easier to write libraries that are export wrappers. The simplest
example would be something that, for the moment, I am calling
C. This module would make it easy to import a bunch of
C::Blocks modules in one shot, i.e.
use C::Blocks::lib qw(perl gsl prima);
would be equivalent to
use C::Blocks::libperl;
use C::Blocks::libgsl;
use C::Blocks::libprima;
Of course, I've not yet decided if I want to call all libraries
C, so this still needs some thought.
Finally, I want to create a module that helps automate the symbol table
load/dump functionality and symbol verification currently under
development for use with PerlAPI. During Beta, I want to create author
tools for L, L, L, and
other distribution tools so that build-time symbol table caching is
easy.
=head2 v1.0
When C::Blocks hits v1.0, it'll have a solid test suite and stable API.
From v1.0 onward, it'll simply be a question of what to include in the
distribution itself. Here are things I want to add (or at least think
about adding) after reaching v1.0:
=over
=item Simple C-based Object System?
I plan to write a module that makes it easy to write single-inheritance
object oriented C code. My current plans are to steal from Prima, which
does this sort of thing exceptionally well. Whether this is added to
the base distribution or released as an independent one is still up in
the air.
=item Generate Inline::C, XS, ExtUtils::Depends
Right now the C code gets compiled at Perl's parse time. Once the C
code is out of the prototyping stage, it would be nice to be able to
automatically extract it and generate .h and .c files that can be
compiled by the system's optimizing compiler. I need to write author
tools that would allow this to be done using Inline::C, or to generate
XS files with the proper scoping. Of course, it would also make sense
for the contents of those header files to be accessible to other XS
authors via ExtUtils::Depends.
=item Utilize ExtUtils::Depends
C::Blocks' consumption of ExtUtils::Depends information was a
Beta target. Going the other way, I an ExtUtils::Depends-like
result for C::Blocks distributions, would likely be a nice feature.
=item Threadsafe
The functions produced by the Tiny C Compiler are threadsafe. However,
compiling code with the Tiny C Compiler itself is not threadsafe.
uses lots of global variables and is therefore not
threadsafe. I would like to contribute back to the project by
encapsulating all of that global state into the compiler state object,
where it belongs. Others in the tcc community have expressed interest
in getting this done, so it is a welcome contribution.
=back
=head1 SEE ALSO
This module uses a special fork of the Tiny C Compiler. The fork is
located at L, and is distributed
through the Alien package provided by L. To learn more
about the Tiny C Compiler, see L and
L. The fork is a major
extension to the compiler that provides extended symbol table support.
For other ways of compiling C code in your Perl scripts, check out
L, L, L, and L.
For mechanisms for calling C code from Perl, see L and
L.
If you just want to mess with C struct data from Perl, see
L.
If you're just looking to write fast code with compact data structures,
L may be just the ticket. It produces highly
optmized code from a subset of the Perl language itself.
=head1 AUTHOR
David Mertens (dcmertens.perl@gmail.com)
=head1 BUGS
Please report any bugs or feature requests for the Alien bindings at
the project's main github page:
L.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc C::Blocks
You can also look for information at:
=over 4
=item * The Github issue tracker (report bugs here)
L
=item * AnnoCPAN: Annotated CPAN documentation
L
=item * CPAN Ratings
L
=item * Search CPAN
L
L
=back
=head1 ACKNOWLEDGEMENTS
This would not be possible without the amazing Tiny C Compiler or the
Perl pluggable keyword work. My thanks goes out to developers of both
of these amazing pieces of technology.
=head1 LICENSE AND COPYRIGHT
Code copyright 2013-2015 Dickinson College. Documentation copyright
2013-2015 David Mertens.
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
=cut