XS::TCC and C::TinyCompiler
C::TinyCompiler
C::TinyCompiler needs to specify the types. It's bit tiresome. But it makes more better type operation in some case.
use strict;
use warnings;
use PDL;
use C::TinyCompiler;
my $context = C::TinyCompiler->new('::Callable');
# Write a function to create a sequence of prime numbers:
$context->code('Body') = q{
C::TinyCompiler::Callable
void prime_sequence (int * output, int length) {
/* Always start with 2 */
output[0] = 2;
int n_filled = 1;
int candidate = 3;
while(n_filled < length) {
for (int divisor_idx = 0; divisor_idx < n_filled; divisor_idx++) {
if (candidate % output[divisor_idx] == 0) goto NEXT_NUMBER;
if (output[divisor_idx] * output[divisor_idx] > candidate) break;
}
output[n_filled] = candidate;
n_filled++;
NEXT_NUMBER: candidate++;
}
}
};
# Compile our C code
$context->compile;
# Retrieve a subref to our function
my $prime_sequence = $context->get_callable_subref('prime_sequence');
# Allocate some memory for the operation
use PDL;
my $primes = zeroes(long, 20);
# Exercise the subref to create the first 20 primes
$prime_sequence->($primes->get_dataref, $primes->nelem);
print "First 20 primes are $primes\n";
XS::TCC
XS::TCC converts types by typemaps automatically, if can do it.
Hmm. But in this case, clean and sane type conversion is impossible. Then you need to call XS APIs.
(Basically, you don't need to call XS APIs in most of cases)
use v5.18.0;
use XS::TCC qw(tcc_inline);
tcc_inline(<<'...');
AV* foo(int length) {
AV* ret = newAV();
av_extend(ret, length);
av_push(ret, newSViv(2));
int n_filled = 1;
int candidate = 3;
while(n_filled < length) {
for (int divisor_idx = 0; divisor_idx < n_filled; divisor_idx++) {
SV ** entry = av_fetch(ret, divisor_idx, 0);
if (candidate % SvIV(*entry) == 0) goto NEXT_NUMBER;
if (SvIV(*entry) * SvIV(*entry) > candidate) break;
}
av_push(ret, newSViv(candidate));
n_filled++;
NEXT_NUMBER: candidate++;
}
return ret;
}
...
for (@{foo(10)}) {
say $_;
}
Conclusion
I may use XS::TCC. Because I can write XS code :P
Published: 2013-08-27(Tue) 19:47