parrotcode: Parrot PackFile API | |
Contents | C |
src/packfile.c - Parrot PackFile API
This file contains all the functions required for the processing of the structure of a PackFile. It is not intended to understand the byte code stream itself, but merely to dissect and reconstruct data from the various segments. See docs/parrotbyte.pod for information about the structure of the frozen bytecode.
void PackFile_destroy(struct PackFile *pf)
PackFile
.static INTVAL PackFile_check_segment_size(opcode_t segment_size, const char *debug)
segment_size % sizeof(opcode_t)
.static void make_code_pointers(struct PackFile_Segment *seg)
static int sub_pragma(Parrot_Interp interpreter, struct PackFile *pf, int action, PMC *sub_pmc)
static void run_sub(Parrot_Interp interpreter, PMC *sub_pmc)
static void fixup_subs(Interp *interpreter, struct PackFile *self, int action)
opcode_t PackFile_unpack(Interp *interpreter, struct PackFile *self, opcode_t *packed, size_t packed_size)
PackFile
from a block of memory.
The format is: byte wordsize
byte byteorder
byte major
byte minor
byte intvalsize
byte floattype
byte pad[10] = fingerprint
opcode_t magic
opcode_t language type
opcode_t dir_format
opcode_t padding
directory segment
* segment
...
- op_count ... total segment size incl. this count
- itype ... internal type of data
- id ... id of data e.g. byte code nr.
- size ... size of data oparray
- data[size] ... data array e.g. bytecode
segment specific data follows here ...
PackFiles
.INTVAL PackFile_map_segments (struct PackFile_Directory *dir, PackFile_map_segments_func_t callback, void *user_data)
dir
the callback function callback
is called. The pointer user_data
is append to each call.INTVAL PackFile_add_segment (struct PackFile_Directory *dir, struct PackFile_Segment *seg)
seg
to the directory dir
The PackFile becomes the owner of the segment; that means its getting destroyed, when the packfile gets destroyed.struct PackFile_Segment *PackFile_find_segment (struct PackFile_Directory *dir, const char *name, int sub_dir)
name
in the PackFile_Directory
if sub_dir
is true, directories are searched recursively The segment is returned, but its still owned by the PackFile
.struct PackFile_Segment *PackFile_remove_segment_by_name (struct PackFile_Directory *dir, const char *name)
name
in the PackFile_Directory
. The segment is returned and must be destroyed by the user.static void PackFile_set_header(struct PackFile *self)
PackFile
header with system specific data.struct PackFile *PackFile_new(INTVAL is_mapped)
PackFile
and setup the directory. +----------+----------+----------+----------+
| Segment Header |
| .............. |
+----------+----------+----------+----------+
+----------+----------+----------+----------+
| number of directory items |
+----------+----------+----------+----------+
+----------+----------+----------+----------+
| Segment type |
+----------+----------+----------+----------+
| "name" |
| ... '\0' padding bytes |
+----------+----------+----------+----------+
| Offset in the file |
+----------+----------+----------+----------+
| Size of the segment |
+----------+----------+----------+----------+
opcode_t
. - op_count total ops of segment incl. this count
- itype internal type of segment
- id internal id e.g code seg nr
- size size of following op array, 0 if none
* data possibly empty data, or e.g. byte code
INTVAL PackFile_funcs_register(struct PackFile *pf, UINTVAL type, struct PackFile_funcs funcs)
pack
/unpack
/... functions for a packfile type.static opcode_t *default_unpack (Interp *interpreter, struct PackFile_Segment *self, opcode_t *cursor)
void default_dump_header (Parrot_Interp interpreter, struct PackFile_Segment *self)
static void default_dump (Parrot_Interp interpreter, struct PackFile_Segment *self)
static INTVAL pf_register_standard_funcs(struct PackFile *pf)
PackFile_new()
register the standard functions.struct PackFile_Segment *PackFile_Segment_new_seg(struct PackFile_Directory *dir, UINTVAL type, const char *name, int add)
struct PackFile_ByteCode *PF_create_default_segs(Interp*, const char *file_name, int add)
file_nam
. If add
is true, the current packfile becomes the owner of these segments by adding the segments to the directory.void PackFile_Segment_destroy(struct PackFile_Segment *self)
size_t PackFile_Segment_packed_size(struct PackFile_Segment *self)
opcode_t *PackFile_Segment_pack(struct PackFile_Segment *self, opcode_t *cursor)
opcode_t *PackFile_Segment_unpack(Interp *interpreter, struct PackFile_Segment *self, opcode_t *cursor)
default_*
function.void PackFile_Segment_dump(Interp *interpreter, struct PackFile_Segment *self)
self
.static struct PackFile_Segment *directory_new(struct PackFile *pf, const char *name, int add)
PackFile_Directory
cast as a PackFile_Segment
.static void directory_dump(Interp *interpreter, struct PackFile_Segment *self)
self
.static opcode_t *directory_unpack(Interp *interpreter, struct PackFile_Segment *segp, opcode_t *cursor)
static void directory_destroy(struct PackFile_Segment *self)
static void sort_segs(struct PackFile_Directory *dir)
dir
.static size_t directory_packed_size(struct PackFile_Segment *self)
default_packed_size()
.static opcode_t *directory_pack(struct PackFile_Segment *self, opcode_t *cursor)
self
.PackFile_Segment
Functions static void segment_init(struct PackFile_Segment *self, struct PackFile *pf, const char *name)
self
.struct PackFile_Segment *PackFile_Segment_new(struct PackFile *pf, const char *name, int add)
The default functions are called before the segment specific functions and can read a block of opcode_t
data.
static void default_destroy(struct PackFile_Segment *self)
static size_t default_packed_size(struct PackFile_Segment *self)
self
.static opcode_t *default_pack(struct PackFile_Segment *self, opcode_t *dest)
static void byte_code_destroy(struct PackFile_Segment *self)
PackFile_ByteCode
segment self
.static struct PackFile_Segment *byte_code_new(struct PackFile *pf, const char *name, int add)
PackFile_ByteCode
segment.add
is ignored.static void pf_debug_destroy (struct PackFile_Segment *self)
PackFile_Debug
segment self
.static struct PackFile_Segment *pf_debug_new (struct PackFile *pf, const char *name, int add)
PackFile_Debug
segment.add
is ignored.static size_t pf_debug_packed_size (struct PackFile_Segment *self)
PackFile_Debug
segment's filename in opcode_t
units.static opcode_t *pf_debug_pack(struct PackFile_Segment *self, opcode_t *cursor)
static opcode_t *pf_debug_unpack(Interp *interpreter, struct PackFile_Segment *self, opcode_t *cursor)
struct PackFile_Debug *Parrot_new_debug_seg(Interp *interpreter, struct PackFile_ByteCode *cs, const char *filename, size_t size)
void Parrot_switch_to_cs_by_nr(Interp *interpreter, opcode_t seg)
seg
.struct PackFile_ByteCode *Parrot_switch_to_cs(Interp *interpreter, struct PackFile_ByteCode *new_cs, int really)
new_cs
, returning the old segment.void Parrot_pop_cs(Interp *interpreter)
void PackFile_FixupTable_clear(struct PackFile_FixupTable *self)
static void fixup_destroy (struct PackFile_Segment *self)
PackFile_FixupTable_clear()
with self
.static size_t fixup_packed_size(struct PackFile_Segment *self)
static opcode_t *fixup_pack (struct PackFile_Segment *self, opcode_t *cursor)
static struct PackFile_Segment *fixup_new(struct PackFile *pf, const char *name, int add)
PackFile_FixupTable
segment.static opcode_t *fixup_unpack(Interp *interpreter, struct PackFile_Segment *seg, opcode_t *cursor)
void PackFile_FixupTable_new_entry(Interp *interpreter, char *label, enum_fixup_t type, opcode_t offs)
static struct PackFile_FixupEntry *find_fixup(struct PackFile_FixupTable *ft, enum_fixup_t type, const char *name)
name
and returns it.static INTVAL find_fixup_iter(struct PackFile_Segment *seg, void *user_data)
struct PackFile_FixupEntry *PackFile_find_fixup_entry(Interp *interpreter, enum_fixup_t type, char *name)
void PackFile_ConstTable_clear(struct PackFile_ConstTable *self)
PackFile_ConstTable
self
.opcode_t *PackFile_ConstTable_unpack(Interp *interpreter, struct PackFile_Segment *seg, opcode_t *cursor)
opcode_t const_count
* constants
static struct PackFile_Segment *const_new(struct PackFile *pf, const char *name, int add)
PackFile_ConstTable
segment.static void const_destroy(struct PackFile_Segment *self)
PackFile_ConstTable
self
.struct PackFile_Constant *PackFile_Constant_new(void)
void PackFile_Constant_destroy(struct PackFile_Constant *self)
PackFile_Constant
self
.PMC
s or STRING
s, they are destroyed via DOD/GC.size_t PackFile_Constant_pack_size(struct PackFile_Constant *self)
opcode_t *PackFile_Constant_unpack(Interp *interpreter, struct PackFile_ConstTable *constt, struct PackFile_Constant *self, opcode_t *cursor)
opcode_t type
* data
opcode_t *PackFile_Constant_unpack_pmc(Interp *interpreter, struct PackFile_ConstTable *constt, struct PackFile_Constant *self, opcode_t *cursor)
opcode_t *PackFile_Constant_unpack_key(Interp *interpreter, struct PackFile_ConstTable *constt, struct PackFile_Constant *self, opcode_t *cursor)
opcode_t type
opcode_t value
static struct PackFile *PackFile_append_pbc(Interp *interpreter, const char *filename)
void Parrot_load_bytecode(Interp *interpreter, STRING *filename)
void PackFile_fixup_subs(Interp *interpreter, pbc_action_enum_t)
Rework by Melvin; new bytecode format, make bytecode portable. (Do endian conversion and wordsize transforms on the fly.)
leo applied and modified Juergen Boemmels packfile patch giving an extensible packfile format with directory reworked again, with common chunks (default_*
).
2003.11.21 leo: moved low level item fetch routines to new pf/pf_items.c
|