NAME

embed.pod - Parrot embedding system

SYNOPSIS

#include <parrot.h>
#include <parrot/embed.h>
#include <parrot/extend.h>

int main(int argc, char* argv[])
{
    Parrot_Interp interp;
    Parrot_PackFile pf;

    interp = Parrot_new(NULL);
    if (!interp) {
        return 1;
    }

    pf = Parrot_readbc(interp, "foo.pbc");
    Parrot_loadbc(interp, pf);
    Parrot_runcode(pf, argc, argv);

    Parrot_destroy(interp);

    return 0;
}

FILES

include/parrot.h
include/parrot/embed.h
include/parrot/extend.h

DESCRIPTION

This is the documentation for Parrot's embedding API.

Data structures

Parrot_Interp

The topmost data structure in Parrot is Parrot_Interp, which represents a Parrot interpreter. It is a required argument to almost every Parrot API function. The structure is opaque in an embedded environment, so you cannot directly access any of its members.

Parrot_PackFile

A Parrot packfile, the internal structure containing Parrot bytecode.

Parrot_String

Parrot's internal string type, which contains character encoding information.

Parrot_PMC

A Parrot Magic Cookie. This is the opaque external type for (PMC *). Note that this is a macro, so there can be only one Parrot_PMC declaration per line.

Parrot_Int
Parrot_Float
Parrot_Int
Parrot_UInt

Parrot's numeric types.

Constants

Not documented yet.

Type signatures

These are used with the Parrot_call_sub family of functions.

v - void (return only)
I - integer (return or argument)
N - float (return or argument)
S - string (return or argument)
P - PMC (return or argument)

Interpreter initialization and destruction

Parrot_Interp Parrot_new(Parrot_Interp parent)

Creates a new interpreter, inheriting some data structures from a parent interpreter, if supplied. The first interpreter in any process should be created with a NULL parent, and all subsequent interpreters in the same process should use the first interpreter as their parent. Failure to do so may result in unpredictable errors.

Parrot_set_flag(Parrot_Interp interp, Parrot_int flags)

Sets or unsets interpreter flags. Flags should be OR'd together. Valid flags include:

PARROT_NO_FLAGS
PARROT_BOUNDS_FLAG
PARROT_GC_DEBUG_FLAG
PARROT_EXTERN_CODE_FLAG
PARROT_DESTROY_FLAG
PARROT_IS_THREAD
PARROT_THR_COPY_INTERP
PARROT_THR_THREAD_POOL
PARROT_THR_TYPE_1
PARROT_THR_TYPE_2
PARROT_THR_TYPE_3

See interpreter.h for the definition of these flags (TODO: document flag definitions here).

void Parrot_set_run_core(Parrot_Interp interp, Parrot_Run_core_t core)

Sets the runcore for the interpreter. Must be called before executing any bytecode. Valid runcores include:

PARROT_SLOW_CORE
PARROT_FUNCTION_CORE
PARROT_FAST_CORE
PARROT_SWITCH_CORE
PARROT_CGP_CORE
PARROT_CGOTO_CORE
PARROT_JIT_CORE
PARROT_CGP_JIT_CORE
PARROT_SWITCH_JIT_CORE
PARROT_EXEC_CORE
PARROT_GC_DEBUG_CORE

See interpreter.h for the definitive list. If you're not sure which runcore to use, don't call this function. The default will be fine for most cases. (TODO: document runcores here).

Parrot_set_trace(Parrot_Interp, Parrot_UInt flags)

Sets the interpreter's trace flags. Flags should be OR'd together. Valid flags are:

PARROT_NO_TRACE
PARROT_TRACE_OPS_FLAG
PARROT_TRACE_FIND_METH_FLAG
PARROT_TRACE_SUB_CALL_FLAG
PARROT_ALL_TRACE_FLAGS

void Parrot_set_executable_name(Parrot_Interp interp, Parrot_string name)

Sets the executable name of the calling process. Note that the name is a Parrot string, not a C string.

void Parrot_destroy(Parrot_Interp interp)

Destroys an interpreter. At the time of this writing, this is a no-op. See <Parrot_really_destroy()>.

void Parrot_really_destroy(Parrot_Interp interp, int exit_code)

Destroys an interpreter, regardless of the environment. The exit code is currently unused.

void Parrot_exit(Parrot_Interp interp, int status)

Destroys the interpreter and exits with an exit code of status. Before exiting, the function calls all registered exit handlers in LIFO order. Parrot_really_destroy() is usually called as the last exit handler.

void Parrot_on_exit(Parrot_Interp interp, void (*handler)(Parrot_Interp, int, void *), void *arg)

Registers an exit handler to be called from Parrot_exit() in LIFO order. The handler function should accept as arguments an interpreter, an integer exit code, and an argument (which can be NULL).

void imcc_init(Parrot_Interp interp)

Initializes the IMCC subsystem. Required for compiling PIR.

Loading and running bytecode

Parrot_PackFile Parrot_readbc(Parrot_Interp interp, const char *path)

Reads Parrot bytecode or PIR from the file referenced by path. Returns a packfile structure for use by Parrot_loadbc().

void Parrot_loadbc(Parrot_Interp interp, Parrot_PackFile pf)

Loads a packfile into the interpreter. After this operation the interpreter is ready to run the bytecode in the packfile.

void Parrot_runcode(Parrot_Interp interp, int argc, char *argv[])

Runs the bytecode associated with the interpreter. Use argc and argv[] to pass arguments to the bytecode.

Parrot_PackFile PackFile_new_dummy(Parrot_Interp interp, char *name)

Creates a "dummy" packfile in lieu of actually creating one from a bytecode file on disk.

void Parrot_load_bytecode(Parrot_Interp interp, const char *path)

Reads and load Parrot bytecode or PIR from the file referenced by path. You should create a dummy packfile beforehand; see PackFile_new_dummy for details. Due to the void return type, the behavior of this function on error is unclear.

Data manipulation

Native types

int Parrot_PMC_typenum(Parrot_Interp interp, const char *type)

Returns the internal type number corresponding to type. Useful for instantiating various Parrot data types.

char *string_to_cstring(Parrot_Interp interp)

XXX needs to be a formal Parrot_* API. Returns the C string representation of a Parrot string.

STRING *string_from_cstring(Parrot_Interp interp, const char *string, int len)

XXX needs to be a formal Parrot_* API. Returns the Parrot string representation of a C string.

string_from_literal(Parrot_Interp interp, const char *string)

XXX needs to be a formal Parrot_* API. A macro for simplifying calls to string_from_cstring.

PMCs

Parrot_PMC Parrot_PMC_new(Parrot_Interp interp, int typenum)

Creates a new PMC of the type identified by typenum. Use Parrot_PMC_typenum to obtain the correct type number.

void Parrot_register_pmc(Parrot_PMC pmc)

Registers an externally created PMC with the garbage collector. You MUST call this for any PMCs you create outside of Parrot bytecode, otherwise your PMC may be garbage collected before you are finished using it.

void Parrot_unregister_pmc(Parrot_PMC pmc)

Unegisters an externally created PMC from the garbage collector. You MUST call this after you are finished using PMCs you create outside of Parrot bytecode, or risk memory leaks.

Globals

Parrot_PMC Parrot_find_global_cur(Parrot_Interp interp, Parrot_String name)

Find and return a global called name in the current namespace. Returns PMCNULL if not found.

Parrot_PMC Parrot_find_global_n(Parrot_Interp interp, Parrot_String namespace, Parrot_String name)

Not documented yet.

Parrot_PMC Parrot_find_global_s(Parrot_Interp interp, Parrot_String namespace, Parrot_String name)

Find and return a global called name in the namespace namespace. Returns PMCNULL if not found.

void Parrot_store_global_cur(Parrot_Interp interp, Parrot_String name, Parrot_PMC val)

Sets the value of a global called name in the current namespace. Does nothing if the global is not found.

void Parrot_store_global_n(Parrot_Interp interp, Parrot_String namespace, Parrot_String name, Parrot_PMC val)

Not documented yet.

void Parrot_store_global_s(Parrot_Interp interp, Parrot_String namespace, Parrot_String name, Parrot_PMC val)

Sets the value of a global called name in the namespace namespace. Does nothing if the global is not found.

Parrot_PMC Parrot_find_global_k(Parrot_Interp interp, Parrot_PMC namespace_key, Parrot_String name)

Find and return a global called name in the keyed namespace namespace. Returns PMCNULL if not found.

void Parrot_store_global_k(Parrot_Interp interp, Parrot_PMC namespace_key, Parrot_String name, Parrot_PMC val)

Sets the value of a global called name in the keyed namespace namespace. Does nothing if the global is not found.

Lexicals

Not documented yet.

Calling subroutines

void *Parrot_call_sub(Parrot_Interp interp, Parrot_PMC sub, const_char *signature)

Call a Parrot subroutine that returns a pointer using the supplied signature.

Parrot_Int Parrot_call_sub_ret_int(Parrot_Interp interp, Parrot_PMC sub, const_char *signature)

Call a Parrot subroutine that returns an integer using the supplied signature.

Parrot_Float Parrot_call_sub_ret_float(Parrot_Interp interp, Parrot_PMC sub, const_char *signature)

Call a Parrot subroutine that returns an float using the supplied signature.

Objects

Creating and destroying objects

Parrot_PMC Parrot_oo_get_class(Parrot_Interp interp, Parrot_PMC namespace)

Returns the class corresponding to the supplied namespace.

Parrot_PMC Parrot_Class_instantiate(Parrot_Interp interp, Parrot_PMC the_class Parrot_PMC arg)

Instantiates a new object of class the_class, which can be obtained from Parrot_oo_get_class(). Passes an optional PMC argument arg to the constructor (see init versus init_pmc). Use PMCNULL if you are not supplying an argument.

Calling methods

Not documented yet.

COMPILING

Note: This section is aimed at you if you are writing an application external to parrot which links against an installed parrot library.

Caveats

Several API functions are missing prototypes in Parrot's header files. This means you may receive type warnings during compilation even though the types of your arguments and return variables are correct. In this case it is safe to cast to the correct type; not doing so may cause undesired behavior.

Compiler and linker flags

Your application will need to include the appropriate header files and link against parrot and its dependencies.

Because the location of these files can vary from platform to platform, and build to build, a general method is provided to find out the necessary flags to use.

pkg-config is a helper tool, now common on many platforms, which many packages have adopted to provide the necessary compiler and linker flags required to build against a library. parrot will install a file called parrot.pc which can be queried using pkg-config.

To start with, find out what version of parrot is installed by running pkg-config with the --modversion flag. If this command fails with an error, skip to the end of this section.

pkg-config --modversion parrot

To find out the necessary -I flags, use --cflags:

pkg-config --cflags parrot

... and to find the necessary -L and -l flags, use --libs:

pkg-config --libs parrot

Where both compiling and linking are performed in one step, query both sets of flags with:

pkg-config --cflags --libs parrot

The pkg-config command can be incorporated with a compile as shown here.

cc src/disassemble.c `pkg-config --cflags --libs parrot`

Most applications will probably choose to run pkg-config as part of a configure script, so if you are using autoconf you could use a test such as this.

PARROT_REQUIRED_VERSION=0.4.1
AC_SUBST(PARROT_REQUIRED_VERSION)
PKG_CHECK_MODULES(PARROT, parrot >= $PARROT_REQUIRED_VERSION,
                  [AC_DEFINE([HAVE_PARROT], 1, [define if have parrot])])
AC_SUBST(PARROT_LIBS)
AC_SUBST(PARROT_CFLAGS)

If parrot has been installed system-wide, then any of the previous lines should have returned the relevant flags. If it is not installed in one of the standard places that pkg-config looks, then you will get an error message.

pkg-config --libs parrot
Package parrot was not found in the pkg-config search path.
Perhaps you should add the directory containing `parrot.pc'
to the PKG_CONFIG_PATH environment variable
No package 'parrot' found

As stated in the error message, use an environment variable to make pkg-config look in more locations.

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

The last part of the variable will almost certainly be .../lib/pkgconfig. Set this variable in your login scripts if you need it to be available in future.

EXAMPLES

Load bytecode as a library and run a single subroutine

#include <parrot/parrot.h>
#include <parrot/embed.h>
#include <parrot/extend.h>

int main(int argc, char *argv[])
{
    Parrot_Interp interp;
    Parrot_PackFile pf;
    Parrot_PMC sub;
    Parrot_String pstr;

    interp = Parrot_new(NULL);
    imcc_init(interp);

    /* create a new packfile -- any name will do */
    pf = PackFile_new_dummy(interp, "my-parrot-code");

    pstr = string_from_literal(interp, "foo.pir");
    Parrot_load_bytecode(interp, pstr);

    /* find the subroutine named "foo" in the global namespace */
    pstr = string_from_literal(interp, "foo");
    sub = Parrot_find_global_cur(interp, pstr);

    /* run foo(), which returns nothing */
    Parrot_call_sub(interp, sub, "v");

    Parrot_destroy(interp);

    return(0);
}

SEE ALSO

src/main.c and t/src/*.t for Parrot's use of the embedding system.

http://pkgconfig.freedesktop.org/wiki/ A pkg-config page