NAME
XS::TCC - Embed, wrap & compile C code in Perl without going to disk
SYNOPSIS
use XS::TCC qw(tcc_inline);
tcc_inline q{
int foo(int bar) {
return bar * 2;
}
};
print foo(3), "\n"; # prints 6
# more elaborate functions involving Perl types work as well
DESCRIPTION
Before you consider adopting this module, please have a look at the C::Blocks module. C::Blocks
is a more powerful, more lovingly maintained piece of software. Due to current (as of early 2017) scarcity of spare time on my part, you can't expect to get a lot of support for XS::TCC
from me. This being said, XS::TCC
should work reliably at least on reasonably standard Linux systems. --Steffen
XS::TCC
allows you to embed C code into your Perl that is compiled and linked on the fly, in memory, without ever touching your disk except to read the Perl code in the first place. This amazing feat actually has very little to do with this module's code but rather with TCC (TinyCC, see tinycc.org) which allows compilation and linking in memory.
On my first-gen core i5 laptop, making two small-medium size functions available to Perl takes around 30ms including parse, wrapper code generation, typemapping, compilation, linking, and XSUB installation. Wrapping more code is bound to be relatively faster.
The output of TCC is slower than the equivalent function compiled with GCC, but both beat regular Perl by a wide margin {citation required}.
FUNCTIONS
tcc_inline
The optionally exported tcc_inline function is the main end user interface for XS::TCC
. In its simplest form, it simply takes a string of C code as its first parameter. The C code will be compiled with TCC on the fly (and in memory rather than on disk as with Inline
), and any C functions in that string will be bound under the same name as XS functions. The argument and return types will be mapped with Perl's standard typemap
functionality, see also the perlxstypemap man page.
Optionally, you can provide named parameters to tcc_inline
as key-value pairs preceding the code string:
tcc_inline(
option => 'value',
option2 => 'value2',
q{ int foo() {return 42;} }
);
Valid options are:
- package
-
The Perl package to put the XS functions into instead of your current package.
- typemap
-
The value for this option can be either a string of typemap code (ie. what you would put in a
TYPEMAP
block in XS or a typemap file in a Perl XS distribution) or an ExtUtils::Typemap object.In either case, the given typemap will be merged with the core perl typemaps (your custom ones will supercede the core ones where applicable) and the resulting merged typemap will be used for the compilation.
- ccopts
-
Any compiler flags you want to pass. By default,
XS::TCC
will use ExtUtils::Embed to intuit your CC options. If you pass accopts
value, those options will replace the default options fromExtUtils::Embed::ccopts
. - add_files
-
Can be a single path/file name or an array ref containing one or multiple. These additional C code-containing files will be passed to TCC to compile.
They will NOT be parsed for function signatures by
XS::TCC
. That is to say, functions in these files will NOT be exposed as XSUBs. - code
-
The C code to compile. You can use this form instead of the trailing code string. (But not both.)
- warn_code
-
Debugging: If this is set to a true value, the generated XS code will be passed to
warn
before compiling it.
ADVANCED NOTES
This is a very incomplete section with notes on advanced usage.
Perl Context
In XS, it's very common to pass a pointer to the currently active Perl interpreter, also known as THX
around. Many Perl API functions need to have such a context around to function properly. For convenience, one can find the currently active Perl interpreter without passing it around as a function parameter, but this comes at the cost of performance.
XS::TCC
allows you to include the standard pTHX
and pTHX_
macros in your function signatures to get the Perl context as an argument in your C function. To wit, the following to functions are equivalent in that they return the type of context that the function is called in (as the Perl internal integer ids corresponding to void/scalar/list contexts). This is a very useless thing to do, of course, this is for demonstration purposes only):
/* efficient */
int which_context(pTHX) {
return (int)GIMME_V;
}
/* less efficient */
int which_context_slow() {
dTHX;
return (int)GIMME_V;
}
Testing this with a simple script gives on a threaded perl:
$ perl -Mblib author_tools/dthx_benchmark.pl
Rate pTHX dTHX
pTHX 1860.2+-0.31/s -- -12.5%
dTHX 2124.91+-0.14/s 14.2% --
On a perl compiled without multi-threading support, the timings are equal between the two variants.
SEE ALSO
AUTHOR
Steffen Mueller <smueller@cpan.org>
With much appreciated contributions from:
Tokuhiro Matsuno
David Mertens
COPYRIGHT AND LICENSE
Copyright (C) 2013, 2014, 2016, 2017 by Steffen Mueller
XS::TCC is distributed under the GNU Lesser General Public License
(see COPYING file).