[t] Refactor some namespace pmc tests to use throws_like
[parrot.git] / docs / pmc.pod
blob0170d16f5b98adb243a6cc0e4ea9fb5eeddeb4eb
1 =head1 Title
3 docs/pmc.pod - PMC (PMC Makers Compendium)
5 =head1 PMC Structure Items Access
7 Ideally, there should be minimal direct access to a PMC's internals.  In order
8 to enforce encapsulation, most interaction with a PMC should be performed
9 through VTABLE function calls, which allow code to remain robust as PMC
10 internals are changed.  
12 When it is not possible or practical to use VTABLE functions (for instance when
13 implementing PMC internals), ATTRs should be used.  ATTRs are declared after
14 the C<pmclass> line in a .pmc file.  For a given pmc ("Foo"), an ATTR ("bar")
15 can be accessed either directly: C<< PARROT_FOO(pmc)->bar >> or via a
16 SETATTR/GETATTR accessor macro: C<GETATTR_Foo_bar(INTERP, x)>.  Note that
17 inside a PMC's source file, these can be shortened to C<GET_ATTR_bar(INTERP, x)>.
19 =head1 PMC Storage
21 PMCs can store data in two places.  8 bits can be stored in the PMC's flags.
22 These are accessed via PObj_private0_FLAG, PObj_private1_FLAG, etc, although
23 these flags should be #define'd on a per-PMC basis to have more meaningful
24 names.  If a PMC needs more than 8 bits of storage, it should declare ATTRs of
25 the appropriate type.  Storage for ATTRs hangs off of C<PMC_data()>.  See
26 src/pmc/exporter.pmc for example code that does this.
28 The PMC UnionVal is an obsolete storage area which was previously used to
29 provide a limited amount of storage.  The use of this storage encouraged poor
30 encapsulation and hidden dependencies between PMCs.  Any new code should not
31 use the UnionVal, which will eventually be removed from Parrot.
33 =head2 ATTRs and C<PMC_data()>
35 If your PMC needs to store more data than will fit into the 8 bits of the PMC
36 flags, it should declare ATTRs of the appropriate type.  The pmc2c code will
37 generate a struct containing all ATTRs, including those inherited via
38 C<extends> declarations.  This struct will be named in the form
39 C<Parrot_x_attributes>, where C<x> is the name of your PMC, e.g.
40 C<Parrot_FixedIntegerArray_attributes>.  When creating a PMC that has one or
41 more ATTRs, the C<Parrot_x_attributes> struct must be allocated and assigned to
42 C<PMC_data> in the PMC's C<init()> and C<init_pmc()> VTABLE functions (if used)
43 and it must be destroyed in the C<destroy()> VTABLE function.  PMCs with ATTRs
44 also need to indicate that they need active destruction by calling
45 C<PObj_custom_destroy_SET()> or C<PObj_custom_mark_destroy_SETALL()>.
47 If your PMC only needs to store a single pointer, it can use C<PMC_data> directly.
48 Note that this may make maintaining your PMC difficult, should more data ever
49 need to be stored.
51 =head1 PMC flags
53 Each PMC has 8 private flags named B<PObj_private0_FLAG> through
54 B<PObj_private7_FLAG>.  These may be used for storing 8 bits of PMC-specific
55 information.  See C<include/parrot/key.h> and C<src/pmc/key.pmc> for examples.
57 =head1 PMCs and GC
59 The GC system doesn't make any assumptions about your PMC's layout. Whenever a
60 PMC is found in the root set, B<Parrot_gc_mark_PObj_alive()> is called with that PMC.  The
61 PMC is responsible to mark all contained or referenced active Parrot objects
62 (Buffers, STRINGs or other PMCs) when its C<mark()> VTABLE function is called.
64 =head2 PMCs and System Resources
66 Whenever a PMC B<malloc()>s memory or opens a file or a database connection, it
67 has to take care of freeing or closing these resources.  This is done by
68 implementing the appropriate VTABLE functions (C<mark()> and C<destroy()>) and
69 setting the appropriate PObj flags.  The commonly used flags are described
70 below.
72 =head2 GC related flags
74 =over 4
76 =item PObj_custom_mark_FLAG
78 If your PMC contains any other B<PObj>s (STRINGs, PMCs, etc), your PMC must
79 implement the B<mark()> VTABLE function and set this flag.  The B<mark()>
80 VTABLE function must call B<Parrot_gc_mark_PObj_alive()> on all B<PObj>s which your PMC
81 contains.
83 =item PObj_custom_destroy_FLAG
85 If your PMC allocates any memory or opens any resources during its lifetime, it
86 must set B<PObj_custom_destroy> and implement the B<destroy()> VTABLE function to
87 free those resources.
89 =item PObj_needs_early_gc_FLAG
91 Set this flag if your PMC needs timely destruction, e.g. to close a file handle
92 at the end of a block scope if the PMC isn't alive any more.
94 =back
96 =head1 See also
98 F<include/parrot/pobj.h>, F<src/gc/api.c>, F<docs/pdds/pdd02_vtables.pod>