Skip to content
This repository
branch: 777/no_pretty_…
Fetching contributors…

Cannot retrieve contributors at this time

file 336 lines (218 sloc) 10.379 kb

embed.pod - Parrot embedding system overview

    #include "parrot/api.h"

    int main(int argc, char* argv[])
    {
        Parrot_PMC interp = NULL;
        Parrot_PMC pf = NULL;
        Parrot_PMC args = NULL;

        if (!Parrot_api_make_interpreter(NULL, NULL, 0, &interp)) {
            fprintf(stderr, "Cannot create Parrot interpreter!\n");
            return 1;
        }

        if (!Parrot_api_load_bytecode_file(interp, "foo.pbc", &pf))
            show_last_error_and_exit(interp);
        
        if (!Parrot_api_pmc_wrap_string_array(interp, argc, argv, &args))
            show_last_error_and_exit(interp);
        
        if (!Parrot_api_run_bytecode(interp, pf, args))
            show_last_error_and_exit(interp);
            
        Parrot_api_destroy_interpreter(interp);
        exit(EXIT_SUCCESS);
    }
    
    static void
    show_last_error_and_exit(Parrot_PMC interp)
    {
        ASSERT_ARGS(show_last_error_and_exit)
        Parrot_String errmsg, backtrace;
        Parrot_Int exit_code, is_error;
        Parrot_PMC exception;

        if (!Parrot_api_get_result(interp, &is_error, &exception, &exit_code, &errmsg))
            exit(EXIT_FAILURE);
        if (is_error) {
            if (!Parrot_api_get_exception_backtrace(interp, exception, &backtrace))
                exit(EXIT_FAILURE);
            print_parrot_string(interp, stderr, errmsg, 1);
            print_parrot_string(interp, stderr, backtrace, 0);
        }

        exit(exit_code);
    }
    
    static void
    print_parrot_string(Parrot_PMC interp, ARGMOD(FILE *vector), Parrot_String str,
            int newline)
    {
        ASSERT_ARGS(print_parrot_string)
        char * msg_raw;
        if (!str)
            return;
        Parrot_api_string_export_ascii(interp, str, &msg_raw);
        if (msg_raw) {
            fprintf(vector, "%s%s", msg_raw, newline ? "\n" : "");
            Parrot_api_string_free_exported_ascii(interp, msg_raw);
        }
    }

This is the documentation for Parrot's embedding API.

Parrot defines a strict embedding API. This API may only be used by embedding applications, and other functions exported by libparrot may not be used at the same time. All embedding API functions are named Parrot_api_* and are located in the file include/parrot/api.h. No other header files are necessary or permissible for embedding applications.

All embedding API functions return an integer status code: 0 on failure and 1 on success. If a failure code is returned, other API calls can be made to retrieve the error object and then query information from it.

The embedding API makes use of very few core data types.

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

A Polymorphic Container object. This is the opaque external type for (PMC *). PMCs represent any object more complicated than a primitive string or number type, and can also provide high-level wrappers around primitive types.

Parrot's integer numeric type.

Parrot's floating point numeric type.

What is a function signature? It is a string which represents the calling and return conventions of a function. It is a very succinct representation of the answer to the question "How do I call this function and what does it return?".

All function signatures follow the form of:

    Foo->Bar

where Foo and Bar are a list of zero or more Parrot datatypes. Foo and Bar are individually called 'type signatures'. The datatypes on the left of the arrow are function arguments being passed in and the datatypes on the right are the datatype being returned. No spaces are allowed in a function signature.

There are four datatypes that can be used in Parrot function signatures:

    I <=> Parrot_Int
    N <=> Parrot_Float (Numeric)
    S <=> Parrot_String
    P <=> Parrot_PMC

Here are some example function signatures and what they mean:

   INN->N   In: Integer, two Numerics    Out: Numeric
   SIN->S   In: String, Integer, Numeric Out: String
   P->S     In: PMC                      Out: String
   PiP->S   In: PMC (method call)        Out: String
   NN->N    In: Two Numerics             Out: Numeric
   I->I     In: Integer                  Out: Integer
   I->N     In: Integer                  Out: Numeric
   N->P     In: Numeric                  Out: PMC
   Pi->     In: none (method call)       Out: none
   ->I      In: none                     Out: Integer
   ->       In: none                     Out: none

Parrot functions support an unlimited number of function inputs and outputs.

In addition to the basic signature elements shown above, lower-case letters may be used to modify some types of inputs and outputs:

    Pi -> the invocant for a method call. Pi must be the first argument, if it
          is to be used.
    Pf -> The PMC is an aggregate (Hash, Array). The elements of the PMC will
          be separated out and will be passed individually.
    Sn -> The String is the name of the previous argument, which is passed by
          name, not by position.

Parrot function signature strings are used when a Parrot function or method call needs to be made.

Creates a new interpreter, with optional initialization information and creation flags. The intepreter will have a child/parent relationship with parent, if provided. The returned interpreter object is itself a PMC, and can be operated on like any other PMC if desired.

Sets the executable name of the calling process.

Destroys an interpreter. After this call is made, the interpreter and all PMC and STRING objects created from it are dead and cannot be used.

Reads Parrot bytecode (.pbc) file from the specified location and returns it as a PMC.

Loads a PBC PMC into the interpreter but does not run it. It returns a reference to the :main Sub PMC, if one is available. This causes any :load Sub PMCs to be executed.

Loads and executes the given bytecode, executing any :init Sub PMCs, and then the :main Sub with the given arguments.

Returns the char* or wchar_t* representation of the Parrot string. An exported string must be explicitly freed to prevent memory leaks.

Free's a char* or wchar_t* which has been exported.

Converts a native char* or wchar_t* string into a Parrot_String.

Imports an unsigned char* array of bytes. It is not treated like a normal C string, and is not expected to be null-terminated.

Wraps a char** string array into a string array PMC

Creates a new PMC to wrap a Parrot_String.

Retrieves a Class PMC using a key PMC. The key can be a string, or a string array PMC.

Instantiates a new PMC from it's class object.

If alive is 1, the PMC becomes immortal and cannot be collected by Parrot's GC. Do this if the PMC is still being used, but is not reachable by Parrot's GC. This would be the case if the PMC reference were passed to an external library. If alive is 0, the PMC becomes mortal again and can be collected like normal if it is found to be unreachable.

  • TODO

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

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.

parrot_config is the helper tool for determining anything related to parrot configuration, determining compiler and linker flags to build against parrot is no different.

To start, you should find parrot_config in the path or allow your user to provide this location for you. You can check this by running parrot_config with VERSION as the argument to determine the version of parrot you are working with.

To determine the necessary C compiler flags, use embed-cflags:

  parrot_config embed-cflags

... and to find the necessary linker flags, use embed-ldflags:

  parrot_config embed-ldflags

The parrot_config command can be incorporated with a compile as shown here performing both compiling and linking in one step.

  cc src/disassemble.c `parrot_config embed-cflags` `parrot_config embed-ldflags`

    TODO

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

Something went wrong with that request. Please try again.