Alien-TinyCDB
view release on metacpan or search on metacpan
.claude/skills/perl-xs/SKILL.md view on Meta::CPAN
The vtable address is also the type check. `mg_findext(sv, PERL_MAGIC_ext,
&Foo_magic)` matches only magic carrying that exact vtable, so a hand-blessed
hashref croaks at the boundary instead of segfaulting through an `INT2PTR` cast on
a pointer that was never there. That is the reason to skip `T_PTROBJ`, which stores
the pointer with `sv_setref_pv` and offers neither a free hook nor a real type
check.
## Four ways it goes wrong
1. **An unescaped `"` in the typemap.** xsubpp reads INPUT/OUTPUT templates as Perl
double-quoted strings, so a quote meant for the generated C must be written
`\"`. The failure surfaces as a C syntax error in code you never wrote.
2. **The refcount taken on the wrong SV.** `ST(0)` is the reference; `SvRV(ST(0))`
is the blessed referent carrying the magic. A child object that keeps its parent
alive must increment the **referent** â incrementing `ST(0)` survives scope exit
and segfaults on `undef $parent`, which is the case tests reach for last.
3. **`XSRETURN_UNDEF` bypasses the OUTPUT section.** It is the way to return undef
instead of an object, and it means everything allocated up to that point leaks
unless the branch frees it first.
4. **A NULL handle the C library tolerates.** After a close or free, many libraries
.claude/skills/perl-xs/references/typemap.md view on Meta::CPAN
|---|---|
| `$var` | the C variable being filled (INPUT) or read (OUTPUT) |
| `$arg` | the SV on the argument stack â `ST(n)` |
| `$type` | the C type, with `*` mangled to `Ptr` |
| `${pname}` | the fully qualified Perl name of the XSUB, for error messages |
| `$ntype` | the type without the `Ptr` suffix |
## The escaping rule
xsubpp evaluates INPUT/OUTPUT templates as **Perl double-quoted strings**. Every `"`
that has to reach the generated C must be written `\"`; an unescaped one ends the
Perl string early and the failure surfaces as an unrelated C syntax error, often
pointing at a line that looks fine.
```
# Wrong: sv_magicext(newSVrv($arg, "Foo"), ...);
# Correct: sv_magicext(newSVrv($arg, \"Foo\"), ...);
```
The same holds for `$` and `@` that are meant literally in the C code â escape them.
## The pattern for an object type
INPUT finds the magic and croaks if it is not there; OUTPUT creates the blessed SV
and attaches the magic. Together they mean an XSUB body only ever assigns `RETVAL`
â **blessing is the typemap's job, never the XSUB's.**
```
INPUT
T_FOO
( run in 2.032 seconds using v1.01-cache-2.11-cpan-54e63673c56 )