B::Hoo...tation(3pm)
π NAME π
B::Hooks::OP::Annotation β annotate and delegate hooked OPs π
okay so bestie, if you're out here hijacking OP op_ppaddr functions in XS and you need a way to hand things back to whoever was there before you? this is literally the module. it's giving "polite takeover" energy. π
β¨ SYNOPSIS β¨
#include "hook_op_check.h"
#include "hook_op_annotation.h"
STATIC OPAnnotationGroup MYMODULE_ANNOTATIONS;
STATIC void mymodule_mydata_free(pTHX_ void *mydata) {
// ...
}
STATIC OP * mymodule_check_entersub(pTHX_ OP *op, void *unused) {
MyData * mydata;
mydata = mymodule_get_mydata(); /* metadata to be associated with this OP */
op_annotate(MYMODULE_ANNOTATIONS, op, mydata, mymodule_mydata_free);
op->op_ppaddr = mymodule_entersub;
return op;
}
STATIC OP * mymodule_entersub(pTHX) {
OPAnnotation * annotation;
MyData * mydata;
OP *op = PL_op;
annotation = op_annotation_get(MYMODULE_ANNOTATIONS, op);
mydata = (MyData *)annotation->data;
// ...
if (ok) {
return NORMAL;
} else if (mymodule_stop_hooking(op)) { /* restore the previous op_ppaddr */
op->op_ppaddr = annotation->op_ppaddr;
op_annotation_delete(MYMODULE_ANNOTATIONS, op);
return op->op_ppaddr(aTHX);
} else {
return annotation->op_ppaddr(aTHX); /* delegate to the previous op_ppaddr */
}
}
MODULE = mymodule PACKAGE = mymodule
BOOT:
MYMODULE_ANNOTATIONS = op_annotation_group_new();
void
END()
CODE:
op_annotation_group_free(aTHX_ MYMODULE_ANNOTATIONS);
void
setup()
CODE:
mymodule_hook_op_entersub_id = hook_op_check(
OP_ENTERSUB,
mymodule_check_entersub,
NULL
);
void
teardown()
CODE:
hook_op_check_remove(OP_ENTERSUB, mymodule_hook_op_entersub_id);
πΈ DESCRIPTION πΈ
So here's the tea β: this module gives XS code that hijacks OP op_ppaddr functions a whole system for delegating to (or restoring) the previous functions β no matter whether perl itself or some other module put them there. Lowkey essential. Typically you'd use this alongside B::Hooks::OP::Check.
B::Hooks::OP::Annotation hands its types and functions over to your XS code via ExtUtils::Depends. So if your module wants these exports in its XS, you should use B::OP::Hooks::Annotation in the Perl module that loads the XS, and drop something like this into your Makefile.PL:
use ExtUtils::MakeMaker;
use ExtUtils::Depends;
our %XS_PREREQUISITES = (
'B::Hooks::OP::Annotation' => '0.44',
'B::Hooks::OP::Check' => '0.15',
);
our %XS_DEPENDENCIES = ExtUtils::Depends->new(
'Your::XS::Module',
keys(%XS_PREREQUISITES)
)->get_makefile_vars();
WriteMakefile(
NAME => 'Your::XS::Module',
VERSION_FROM => 'lib/Your/XS/Module.pm',
PREREQ_PM => {
'B::Hooks::EndOfScope' => '0.07',
%XS_PREREQUISITES
},
($ExtUtils::MakeMaker::VERSION >= 6.46 ?
(META_MERGE => {
configure_requires => {
'ExtUtils::Depends' => '0.301',
%XS_PREREQUISITES
}})
: ()
),
%XS_DEPENDENCIES,
# ...
);
π¦ TYPES π¦
OPAnnotation
This struct is the little stash of metadata tied to one specific OP β so like, the data itself, a destructor for that data, and the op_ppaddr function that was set at the moment the annotation got created by op_annotate or op_annotation_new. π
op_ppaddrβ the OP's previousop_ppaddrfunction (of typeOPAnnotationPPAddr)dataβ avoid *to metadata that should be associated with the OPdtorβ a function (of typeOPAnnotationDtor) used to free the metadata
All of these fields are read/write, meaning you can still change them after the annotation has been created. no lock-in bestie π«Ά
OPAnnotationGroup
Annotations live in groups, periodt. You can make as many groups as you want, and each one manages all of the annotations that belong to it.
You can boot an annotation out of the group and free it by calling op_annotation_delete, and you can nuke the group plus every member in it by calling op_annotation_group_free. π
OPAnnotationPPAddr
This typedef matches the type of perl's op_ppaddr functions, i.e.
typedef OP *(*OPAnnotationPPAddr)(pTHX);
OPAnnotationDtor
This is the typedef for the destructor used to free the metadata associated with the OP.
typedef void (*OPAnnotationDtor)(pTHX_ void *data);
π FUNCTIONS π
op_annotation_new
This function creates and returns a brand new OP annotation. β¨
It takes an OPAnnotationGroup, an OP, a pointer to the metadata to be associated with the OP, and a destructor for that data. The data can be NULL and the destructor can be NULL if no cleanup is required.
If an annotation has already been assigned for the OP, then it gets replaced by the new annotation, and the old annotation is freed β which triggers the destruction of its data (if supplied) by its destructor (if supplied).
OPAnnotation * op_annotation_new(
OPAnnotationGroup group,
OP *op,
void *data,
OPAnnotationDtor dtor
);
op_annotate
This one is a void version of op_annotation_new, for when you don't actually need the new annotation back. still iconic tho
void op_annotate(
OPAnnotationGroup group,
OP *op,
void *data,
OPAnnotationDtor dtor
);
op_annotation_get
This retrieves the annotation associated with the supplied OP. If no annotation has been assigned for that OP, it raises a fatal exception. so like, know before you go π
OPAnnotation * op_annotation_get(OPAnnotationGroup group, OP *op);
op_annotation_delete
This removes the specified annotation from the group and frees its memory. If a destructor was supplied, it's called on the value in the data field (if supplied).
void op_annotation_delete(pTHX_ OPAnnotationGroup group, OP *op);
op_annotation_group_new
This function creates a new annotation group. fresh start energy π±
OPAnnotationGroup op_annotation_group_new(void);
op_annotation_group_free
This function destroys the annotations in an annotation group and frees the memory allocated for the group.
void op_annotation_group_free(pTHX_ OPAnnotationGroup group);
π EXPORT π
None by default.
β VERSION β
0.44
π₯ SEE ALSO π₯
B::Hooks::OP::CheckB::Hooks::OP::PPAddr
π AUTHOR π
chocolateboy <chocolate@cpan.org>
π COPYRIGHT AND LICENSE π
Copyright (c) 2009-2011 chocolateboy
This module is free software.
You may distribute this code under the same terms as Perl itself.
k that's the whole page bestie, go forth and annotate responsibly πβ¨π¦
perl v5.42.3 Β· 2026-08-19 Β· mwah, slay, bye π«ΆπΈ
π¦ where this page comes from
- ubuntu stonking: libb-hooks-op-annotation-perl 0.44-3build6 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms