fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / docs / pdds / draft / pdd10_embedding.pod
bloba9ac2fded827cf709832821703d837419795efc1
1 # Copyright (c) 2001-2010, Parrot Foundation.
2 # $Id$
4 =head1 [DRAFT] PDD10: Embedding and Extending
6 =head2 Abstract
8 What we believe people will do when embedding and extending Parrot, why they
9 do it, and how.
11 {{ NOTE: some of this will later move into pdds 11 & 12, but for now
12 just want to get the stub checked in. }}
14 =head2 Version
16 $Revision$
18 =head2 Description
20 Why embed:
22 =over 4
24 =item * access to special features/libraries/languages Parrot provides
26 =item * need an interpreter for a DSL or existing language
28 =item * want to run Parrot on another platform or environment (dedicated
29 hardware, in a web server, et cetera)
31 =back
33 Why extend:
35 =over 4
37 =item * need something NCI doesn't provide
39 =item * writing a custom PMC
41 =back
43 Philosophical rules:
45 =over 4
47 =item * only ever use opaque pointers
49 =item * should be able to communicate through PMCs
51 =item * minimize conversions to and from C data
53 =over 4
55 =item * perhaps macros; Ruby does this fairly well and Perl 5 does this
56 poorly
58 =item * minimize the number of necessary functions
60 =item * probably can follow core Parrot code to some extent, but beware the
61 Perl 5 problem
63 =over 4
65 =item * do not expose Parrot internals that may change
67 =over 4
69 =item * minimize the number of headers used
71 =item * minimize the number of Parrot types exposed
73 =item * follow boundaries similar to those of PIR where possible
75 =back
77 =item * probably includes vtable functions on PMCs
79 =back
81 =back
83 =back
85 Gotchas:
87 =over 4
89 =item * who handles signals?
91 =item * who owns file descriptors and other Unix resources?
93 =item * is there an exception boundary?
95 =item * namespace issues -- especially key related
97 =item * probably a continuation/control flow boundary
99 =item * packfiles and subroutines probably too much information for
100 either
102 =item * do not let MMD and other implementation details escape
104 =item * okay to require some PBC/PIR/PASM for handling round-trip data
106 =item * Parrot should not spew errors to STDERR when embedded
108 =item * who allocates and deallocates resources passed through the boundary
109 level?
111 =item * should be access to Parrot's event loop when embedded
113 =item * passing var args to Parrot subs likely painful
115 =over 4
117 =item * perhaps macros/functions to add parameters to call
119 =item * build up a call signature somehow?
121 =item * some abstraction for a call frame?
123 =back
125 =item * compiling code from a string should return the PMC Sub entry point
126 (:main)
128 =item * are there still directory path, loading, and deployment issues?
130 =item * how do dynamic oplibs and custom PMCs interact?
132 =item * what's the best way to handle character sets and Unicode?
134 =back
136 =head2 Definitions
138 Embedding - using libparrot from within another program, likely with a
139 C/NCI/FFI interface
141 Extending - writing Parrot extensions, likely through C or another language
143 In practice, there is little difference between the two; mostly in terms of
144 who has control.  The necessary interfaces should stay the same.
146 =head2 Implementation
148 Implementation details.
150 Simplicity is the main goal; it should be almost trivial to embed Parrot in an
151 existing application.  It must be trivial to do the right thing; the APIs must
152 make it so much easier to work correctly than to make mistakes.  This means,
153 in particular, that:
155 =over 4
157 =item * it should never be possible to crash or corrupt the interpreter when
158 following the interface as documented
160 =item * each API call or element should have a single purpose
162 =item * names must be consistent in the API documentation and the examples
164 =item * it I<should> be possible to embed Parrot I<within> Parrot through NCI,
165 as a test both of the sanity of the external interface as well as NCI
167 =back
169 =head3 Working with Interpreters
171 It is the external code's duty to create, manage, and destroy interpreters.
173 C<Parrot_new( NULL )> returns an opaque pointer to a new interpreter:
175   Parrot_Interp Parrot_new(Parrot_Interp parent);
177 C<parent> can be NULL for the I<first> interpreter created.  All subsequent
178 calls to this function should pass an existing interpreter.
180 I<Note: it is not clear what happens if you fail to do so; is there a way to
181 detect this in the interface and give a warning?>
183 C<Parrot_destroy ( interp )> destroys an interpreter and frees its resources.
185   void Parrot_destroy(Parrot_Interp);
187 I<Note: It is not clear what happens if this interpreter has active children.>
189 =head3 Working with Source Code and PBC Files
191 Perhaps the most common case for working with code is loading it from an
192 external file.  This may often be PBC, but it must also be possible to load
193 code with any registered compiler.  This I<must> be a single-stage operation:
195   Parrot_PMC Parrot_load_bytecode( Parrot_Interp, const char *filepath );
197   Parrot_PMC Parrot_load_hll_code( Parrot_Interp, const char *compiler,
198                                                   const char *filepath );
200 The PMC returned will be the Sub PMC representing the entry point into the
201 code.  That is, it will be the PMC representing the C<:main> subroutine, if
202 one exists, or the first subroutine in the file.
204 If there is an error -- such that the file does not exist, the compiler is
205 unknown, or there was a compilation or invalid bytecode error -- the PMC
206 should be an Exception PMC instead.
208 I<Note: I suppose NULL would work as well; it might be more C-like.  Continue
209 considering.>
211 I<Note also: the current C<Parrot_pbc_read()> and C<Parrot_pbc_load()> exposes
212 the details of packfiles to the external API and uses two operations to
213 perform a single logical operation.>
215 I<Note: it may be worth reconsidering these names, if
216 C<Parrot_load_bytecode()> can load PBC, PIR, and PASM files without having a
217 compiler named explicitly.>
219 Compiling source code generated or read from the host application is also
220 possible:
222   Parrot_PMC Parrot_compile_string( Parrot_Interp, Parrot_String compiler,
223                                                    const char *code,
224                                                    Parrot_String error );
226 The potential return values are the same as for loading code from disk.
228 I<Note: this declaration should move from F<interpreter.h> to F<embed.h>.>
230 =head3 Working with PMCs
232 TBD.
234 =head3 Calling Functions
236 TBD.
238 =head3 Calling Opcodes
240 TBD.
242 =head2 Language Notes
244 It should be possible to register a compiler for an HLL with an interpreter
245 such that it is possible to load source code written in that language or pass
246 source code to an interpreter successfully.
248 =head2 References
250 None.
252 =cut
254 __END__
255 Local Variables:
256   fill-column:78
257 End: