| parrotcode: Untitled | |
| Contents | Compilers |

This file implements an API for generating bytecode.
All gory details are hidden.
In order to improve modularity,
all bytecode generating functions take a bytecode struct parameter,
which keeps track of the state; this includes a Parrot interpreter.
Since this state is private, the bytecode struct is declared in this C file, not in the header file. It is, however, declared in the header file as a struct, so you can use it as a type, but not touch its private bits. Everything you need to know should be accessible through accessor functions.

// create a bytecode object
bytecode *bc = new_bytecode(interp, "foo.pir", codesize, bytes);
// add a subroutine PMC
add_sub_pmc(bc, mysub->info, sub->needlex, mysub->pragmas);
while ( ... ) {
// write opcodes
int opcode = ...
emit_opcode(bc, opcode);
// emit constants
int mystring = add_string_const(bc, "hello");
// emit the constant index into bytecode stream
emit_int_arg(bc, mystring);
}
// write the pbc file
write_pbc_file(bc, "foo.pbc");
// clean up
destroy_bytecode(bc);

static int new_pbc_const(bytecode *const bc)int add_pmc_const(bytecode *const bc, PMC *pmc)pmc to the constant table. This function returns the index in the constant table where pmc is stored.
int add_string_const(bytecode *const bc, char const *const str, char const *charset)str to the constant table. This function returns the index in the constant table where str is stored. str is assumed to be a C-string; it is converted to a Parrot STRING object, using the character set passed in charset.XXX what to do with "encoding"?
f is stored is returned.
int add_key_const(bytecode *const bc, PMC *key)key is stored in the constants table is returned.
static void check_requested_constant(bytecode *const bc, unsigned index, int expectedtype)index is requested; this function checks whether the index is valid. Then, if so, the constant is checked for its type, which must be expectedtype. This must be one of: PFC_PMC, PFC_NUMBER, PFC_STRING.
PMC *get_pmc_const(bytecode *const bc, unsigned index)index in the PBC constant table.
FLOATVAL get_num_const(bytecode *const bc, unsigned index)index in the PBC constant table.
STRING *get_string_const(bytecode *const bc, unsigned index)index in the PBC constant table.
bytecode *new_bytecode(Interp *interp, char const *const filename)filename. The bytecode struct contains a PackFile, which is initialized and loaded into the Parrot interpreter interp. Default bytecode segments are created, and the interpreter's iglobals field is stored as a constant PMC in the bytecode's constant table.
void create_codesegment(bytecode *const bc, int codesize)codesize. bc's opcursor attribute is initialized; this is the pointer used to write opcodes and operands into the code segment.
void create_debugsegment(bytecode *const bc, size_t size, char const *const file)size.
void emit_debug_info(bytecode *const bc, int sourceline)sourceline number in the debug segment.
void create_annotations_segment(bytecode *const bc, char const *const name)void add_annotation(bytecode *const bc, opcode_t offset, opcode_t key, opcode_t type, opcode_t value)offset, having a key key, of type type and a value passed in value.
void destroy_bytecode(bytecode *bc)opcode_t emit_opcode(bytecode *const bc, opcode_t op)op into the bytecode stream. The bytecode offset where the instruction is written is returned.
opcode_t emit_int_arg(bytecode *const bc, int intval)int store_key_bytecode(bytecode *const bc, opcode_t *key)key. The bytecode is unpacked into the current PackFile, pointed to by the interpreter in bc. The key PMC is added to the constants table, and the index in the constants table is returned.
static STRING *add_string_const_from_cstring(bytecode *const bc, char const *const str)PMC *generate_multi_signature(bytecode *const bc)multi_types type_count indicates the number of types in the list.
static PMC *create_lexinfo(bytecode *const bc, PMC *sub, lexical *const lexicals, int needlex)sub. If there are no lexicals, but the :lex flag was specified, or the sub has an :outer flag, then a lexinfo is created after all. The created lexinfo is returned.
static PMC *find_outer_sub(bytecode *const bc, char const *const outername)outername. If not found, NULL is returned.XXX this function needs access to lexer, which adds a dependency. XXX This should be fixed, to make bcgen.c a complete independent module.
static PMC *get_namespace_pmc(bytecode *const bc, multi_type *const ns)ns.
static PMC *create_sub_pmc(bytecode *const bc, char const *const instanceof)instanceof is not NULL, it indicates the name of a class to be used. If it's NULL, and iscoroutine is true, a Coroutine sub PMC is created; otherwise it's a normal Sub. If there was a .HLL_map directive that maps either Coroutine or Sub to some user-defined class, then that mapped class is created.
void add_sub_pmc(bytecode *const bc, sub_info *const info, int needlex, int subpragmas)needlex is true, the sub will always get a lexpad; otherwise it will only have a lexpad if it has lexicals, or if it's lexically nested. The subpragmas parameter encode flags such as :immediate etc.
void write_pbc_file(bytecode *const bc, char const *const filename)filename.
|
|
|