Affix
view release on metacpan or search on metacpan
lib/Affix.c view on Meta::CPAN
symbol = _get_pin_from_sv(aTHX_ target_sv)->pointer;
is_raw_ptr_target = true;
}
else if (SvIOK(target_sv) && !sv_isobject(target_sv)) {
symbol = INT2PTR(void *, SvUV(target_sv));
is_raw_ptr_target = true;
}
// Symbol lookup (unles it's a raw pointer)
const char * symbol_name_str = nullptr;
const char * rename_str = nullptr;
infix_library_t * lib_handle_for_symbol = nullptr;
bool created_implicit_handle = false;
// We only process names/libraries if we don't already have a raw pointer address
if (!is_raw_ptr_target) {
SV * name_sv = ST(1);
// Handle rename: affix($lib, ['real', 'alias'], ...)
if (SvROK(name_sv) && SvTYPE(SvRV(name_sv)) == SVt_PVAV) {
if (ix == 1 || ix == 3) // wrap/direct_wrap
croak("Cannot rename an anonymous Affix'd wrapper");
AV * name_av = (AV *)SvRV(name_sv);
if (av_count(name_av) != 2)
croak("Name spec arrayref must contain exactly two elements: [symbol_name, new_sub_name]");
SV ** sym_sv = av_fetch(name_av, 0, 0);
SV ** alias_sv = av_fetch(name_av, 1, 0);
if (!sym_sv || !alias_sv)
croak("Invalid name spec");
rename_str = SvPV_nolen(*alias_sv);
// Is the symbol inside the array a raw pointer?
// affix(undef, [$ptr, 'name'], ...)
if (_get_pin_from_sv(aTHX_ * sym_sv))
symbol = _get_pin_from_sv(aTHX_ * sym_sv)->pointer;
else if (SvIOK(*sym_sv))
symbol = INT2PTR(void *, SvUV(*sym_sv));
else
symbol_name_str = SvPV_nolen(*sym_sv);
}
else {
// Name a Scalar? (string or raw pointer)
// wrap(undef, $ptr, ...)
if (_get_pin_from_sv(aTHX_ name_sv))
symbol = _get_pin_from_sv(aTHX_ name_sv)->pointer;
else if (SvIOK(name_sv))
symbol = INT2PTR(void *, SvUV(name_sv));
else {
// It's a string name
symbol_name_str = SvPV_nolen(name_sv);
rename_str = symbol_name_str;
}
}
// Only load library if we don't have a direct symbol pointer yet
if (!symbol) {
if (sv_isobject(target_sv) && sv_derived_from(target_sv, "Affix::Lib")) {
IV tmp = SvIV((SV *)SvRV(target_sv));
lib_handle_for_symbol = INT2PTR(infix_library_t *, tmp);
_lib_registry_inc_ref(aTHX_ lib_handle_for_symbol);
created_implicit_handle = true;
lib/Affix.c view on Meta::CPAN
if (!backend->pull_handler) {
infix_forward_destroy(backend->infix);
safefree(backend);
warn("Unsupported return type for affix_bundle");
XSRETURN_UNDEF;
}
backend->lib_handle = created_implicit_handle ? lib_handle_for_symbol : nullptr;
CV * cv_new =
newXSproto_portable((ix == 0 || ix == 2) ? rename_str : nullptr, Affix_trigger_backend, __FILE__, nullptr);
CvXSUBANY(cv_new).any_ptr = (void *)backend;
SV * obj = (ix == 1 || ix == 3) ? newRV_noinc(MUTABLE_SV(cv_new)) : newRV_inc(MUTABLE_SV(cv_new));
sv_bless(obj, gv_stashpv("Affix::Bundled", GV_ADD));
ST(0) = sv_2mortal(obj);
XSRETURN(1);
}
// Standard path (parse & prepare types)
lib/Affix.c view on Meta::CPAN
}
// Object init & trampoline generation
Affix * affix;
Newxz(affix, 1, Affix);
affix->return_sv = newSV(0);
affix->variadic_cache = newHV();
bool is_variadic = (strstr(signature, ";") != NULL);
affix->sig_str = savepv(signature);
if (rename_str)
affix->sym_name = savepv(rename_str);
affix->target_addr = symbol;
if (lib_handle_for_symbol)
affix->lib_handle = lib_handle_for_symbol;
// Create Trampoline using the JIT-optimized types
status = infix_forward_create_manual(&affix->infix, ret_type, jit_arg_types, num_args, num_fixed, symbol);
if (jit_arg_types)
safefree(jit_arg_types);
lib/Affix.c view on Meta::CPAN
for (size_t i = 0; i < affix->num_args; ++i)
strcat(prototype_buf, "$");
// Install XSUB
XSUBADDR_t trigger;
if (is_variadic)
trigger = Affix_trigger_variadic;
else
trigger = (affix->total_args_size <= 512) ? Affix_trigger_stack : Affix_trigger_arena;
CV * cv_new = newXSproto_portable(ix == 0 ? rename_str : nullptr, trigger, __FILE__, nullptr);
if (UNLIKELY(cv_new == nullptr)) {
infix_forward_destroy(affix->infix);
SvREFCNT_dec(affix->return_sv);
infix_arena_destroy(affix->args_arena);
infix_arena_destroy(affix->ret_arena);
safefree(affix->plan);
if (affix->out_param_info)
safefree(affix->out_param_info);
if (affix->c_args)
safefree(affix->c_args);
lib/Affix/Wrap.pod view on Meta::CPAN
# This parses demo.h and installs subroutines, constants,
# and types directly into the calling package.
Affix::Wrap->new( project_files => ['demo.h'] )->wrap($lib);
# Now you can use them:
my $obj = Demo_CreateStruct();
=head3 Manual Control
If you need to filter which functions are bound or rename them, you can iterate over the AST manually instead of
calling C<wrap>:
my $binder = Affix::Wrap->new( project_files => ['demo.h'] );
for my $node ( $binder->parse ) {
next if $node->name =~ m[^Internal_]; # Skip internal functions
# Manually bind
if ( $node->can('affix') ) {
$node->affix($lib);
}
}
( run in 1.766 second using v1.01-cache-2.11-cpan-39bf76dae61 )