1 # Copyright (c) 2001-2010, Parrot Foundation.
4 =head1 [DRAFT] PDD10: Embedding and Extending
8 What we believe people will do when embedding and extending Parrot, why they
11 {{ NOTE: some of this will later move into pdds 11 & 12, but for now
12 just want to get the stub checked in. }}
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)
37 =item * need something NCI doesn't provide
39 =item * writing a custom PMC
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
55 =item * perhaps macros; Ruby does this fairly well and Perl 5 does this
58 =item * minimize the number of necessary functions
60 =item * probably can follow core Parrot code to some extent, but beware the
65 =item * do not expose Parrot internals that may change
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
77 =item * probably includes vtable functions on PMCs
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
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
111 =item * should be access to Parrot's event loop when embedded
113 =item * passing var args to Parrot subs likely painful
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?
125 =item * compiling code from a string should return the PMC Sub entry point
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?
138 Embedding - using libparrot from within another program, likely with a
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,
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
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
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
222 Parrot_PMC Parrot_compile_string( Parrot_Interp, Parrot_String compiler,
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
234 =head3 Calling Functions
238 =head3 Calling Opcodes
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.