src/packfile.c

NAME

src/packfile.c - Parrot PackFile API

DESCRIPTION

PackFile Manipulation Functions

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

Delete a PackFile.

static void make_code_pointers

Make compat/shorthand pointers.

The first segments read are the default segments.

static int sub_pragma

Check sub_pmc's pragmas (e.g. flags like :load, :main, etc.) returning 1 if the sub should be run for action, a pbc_action_enum_t.

static PMC* run_sub

Run the sub_pmc due to its :load, :immediate, ... pragma

static PMC* do_1_sub_pragma

Run autoloaded or immediate bytecode, mark MAIN subroutine entry

static void mark_1_seg

While the PMCs should be constant, their possible contents such as properties aren't constructed const, so we have to mark them.

static INTVAL find_const_iter

RT#48260: Not yet documented!!!

void mark_const_subs

RT#48260: Not yet documented!!!

void do_sub_pragmas

action is one of PBC_PBC, PBC_LOADED, PBC_INIT, or PBC_MAIN. Also store the eval_pmc in the sub structure, so that the eval PMC is kept alive by living subs.

opcode_t PackFile_unpack

Unpack a PackFile from a block of memory, ensuring the the magic number is valid, the bytecode version can be read by this Parrot and doing any endian and word size transforms that are required.

Returns size of unpacked if everything is OK, else zero (0).

INTVAL PackFile_map_segments

For each segment in the directory dir the callback function callback is called. The pointer user_data is included in each call.

If a callback returns non-zero the processing of segments is stopped, and this value is returned.

INTVAL PackFile_add_segment

Adds the Segment seg to the directory dir. The PackFile becomes the owner of the segment; it gets destroyed when the packfile does.

PackFile_Segment * PackFile_find_segment

Finds the segment with the name 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.

PackFile_Segment * PackFile_remove_segment_by_name

Finds and removes the segment with name name in the PackFile_Directory. The segment is returned and must be destroyed by the user.

PackFile Structure Functions

static void PackFile_set_header

Fill a PackFile header with system specific data.

PackFile * PackFile_new

Allocate a new empty PackFile and setup the directory.

Directory segment:

  +----------+----------+----------+----------+
  |    Segment Header                         |
  |    ..............                         |
  +----------+----------+----------+----------+

  +----------+----------+----------+----------+
  |    number of directory items              |
  +----------+----------+----------+----------+

followed by a sequence of items

  +----------+----------+----------+----------+
  |    Segment type                           |
  +----------+----------+----------+----------+
  |    "name"                                 |
  |    ...     '\0'       padding bytes       |
  +----------+----------+----------+----------+
  |    Offset in the file                     |
  +----------+----------+----------+----------+
  |    Size of the segment                    |
  +----------+----------+----------+----------+

"name" is a NUL-terminated c-string encoded in plain ASCII.

Segment types are defined in include/parrot/packfile.h.

Offset and size are in opcode_t.

A Segment Header has these entries:

 - 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
PackFile * PackFile_new_dummy

Create a new (initial) dummy PackFile. This is necessary if the interpreter doesn't load any bytecode but instead uses Parrot_compile_string.

INTVAL PackFile_funcs_register

Register the pack/unpack/... functions for a packfile type.

static const opcode_t * default_unpack

The default unpack function.

void default_dump_header

The default dump header function.

static void default_dump

The default dump function.

static void pf_register_standard_funcs

Called from within PackFile_new() register the standard functions.

PackFile_Segment * PackFile_Segment_new_seg

Create a new segment.

static PackFile_Segment * create_seg

RT#48260: Not yet documented!!!

PackFile_ByteCode * PF_create_default_segs

Create bytecode, constant, and fixup segment for 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

RT#48260: Not yet documented!!!

size_t PackFile_Segment_packed_size

RT#48260: Not yet documented!!!

opcode_t * PackFile_Segment_pack

RT#48260: Not yet documented!!!

const opcode_t * PackFile_Segment_unpack

All all these functions call the related default_* function.

If a special is defined this gets called after.

void PackFile_Segment_dump

Dumps the segment self.

Standard Directory Functions

static PackFile_Segment * directory_new

Returns a new PackFile_Directory cast as a PackFile_Segment.

static void directory_dump

Dumps the directory self.

static const opcode_t * directory_unpack

Unpacks the directory.

static void directory_destroy

Destroys the directory.

static void sort_segs

Sorts the segments in dir.

static size_t directory_packed_size

Returns the size of the directory minus the value returned by default_packed_size().

static opcode_t * directory_pack

Packs the directory self.

PackFile_Segment Functions

static void segment_init

Initializes the segment self.

PackFile_Segment * PackFile_Segment_new

Create a new default section.

Default Function Implementations

The default functions are called before the segment specific functions and can read a block of opcode_t data.

static void default_destroy

The default destroy function.

static size_t default_packed_size

Returns the default size of the segment self.

static opcode_t * default_pack

Performs the default pack.

ByteCode

static void byte_code_destroy

Destroys the PackFile_ByteCode segment self.

static PackFile_Segment * byte_code_new

New PackFile_ByteCode segment.

pf and add are ignored.

Debug Info

static void pf_debug_destroy

Destroys the PackFile_Debug segment self.

static PackFile_Segment * pf_debug_new

Returns a new PackFile_Debug segment.

pf and add ignored.

static size_t pf_debug_packed_size

Returns the size of the PackFile_Debug segment's filename in opcode_t units.

static opcode_t * pf_debug_pack

Pack the debug segment.

static const opcode_t * pf_debug_unpack

Unpack a debug segment into a PackFile_Debug structure.

static void pf_debug_dump

Dumps a debug segment to a human readable form.

PackFile_Debug * Parrot_new_debug_seg

Create and append (or resize) a new debug seg for a code segment.

void Parrot_debug_add_mapping

Add a bytecode offset to filename/source segment mapping. mapping_type may be one of PF_DEBUGMAPPINGTYPE_NONE (in which case the last two parameters are ignored), PF_DEBUGMAPPINGTYPE_FILENAME (in which case filename must be given) or PF_DEBUGMAPPINGTYPE_SOURCESEG (in which case source_seg should contains the number of the source segment in question).

STRING * Parrot_debug_pc_to_filename

Take a position in the bytecode and return the filename of the source for that position.

void Parrot_switch_to_cs_by_nr

Switch to byte code segment number seg.

PackFile_ByteCode * Parrot_switch_to_cs

Switch to a byte code segment new_cs, returning the old segment.

static PackFile_Constant * clone_constant

RT#48260: Not yet documented!!!

static PackFile_Constant ** find_constants

Find the constant table associated with a thread. For now, we need to copy constant tables because some entries aren't really constant; e.g. subroutines need to reference namespace pointers.

void Parrot_destroy_constants

RT#48260: Not yet documented!!!

PackFile FixupTable Structure Functions

void PackFile_FixupTable_clear

Clear a PackFile FixupTable.

static void fixup_destroy

Just calls PackFile_FixupTable_clear() with self.

static size_t fixup_packed_size

What does this do?

RT#48260: Not yet documented!!!

static opcode_t * fixup_pack

What does this do?

RT#48260: Not yet documented!!!

static PackFile_Segment * fixup_new

Returns a new PackFile_FixupTable segment.

static const opcode_t * fixup_unpack

Unpack a PackFile FixupTable from a block of memory.

Returns one (1) if everything is OK, else zero (0).

void PackFile_FixupTable_new_entry

What does this do?

RT#48260: Not yet documented!!!

static PackFile_FixupEntry * find_fixup

Finds the fix-up entry for name and returns it.

static INTVAL find_fixup_iter

What does this do?

RT#48260: Not yet documented!!!

PackFile_FixupEntry * PackFile_find_fixup_entry

What does this do?

RT#48260: Not yet documented!!!

PackFile ConstTable Structure Functions

void PackFile_ConstTable_clear

Clear the PackFile_ConstTable self.

const opcode_t * PackFile_ConstTable_unpack

Unpack a PackFile ConstTable from a block of memory. The format is:

  opcode_t const_count
  *  constants

Returns cursor if everything is OK, else zero (0).

static PackFile_Segment * const_new

Returns a new PackFile_ConstTable segment.

static void const_destroy

Destroys the PackFile_ConstTable self.

PackFile Constant Structure Functions

PackFile_Constant * PackFile_Constant_new

Allocate a new empty PackFile Constant.

This is only here so we can make a new one and then do an unpack.

void PackFile_Constant_destroy

Delete the PackFile_Constant self.

Don't delete PMCs or STRINGs, they are destroyed via DOD/GC.

size_t PackFile_Constant_pack_size

Determine the size of the buffer needed in order to pack the PackFile Constant into a contiguous region of memory.

const opcode_t * PackFile_Constant_unpack

Unpack a PackFile Constant from a block of memory. The format is:

  opcode_t type
  *  data

Returns cursor if everything is OK, else zero (0).

const opcode_t * PackFile_Constant_unpack_pmc

Unpack a constant PMC.

const opcode_t * PackFile_Constant_unpack_key

Unpack a PackFile Constant from a block of memory. The format consists of a sequence of key atoms, each with the following format:

  opcode_t type
  opcode_t value

Returns cursor if everything is OK, else zero (0).

static PackFile * PackFile_append_pbc

Read a PBC and append it to the current directory Fixup sub addresses in newly loaded bytecode and run :load subs.

void Parrot_load_bytecode

Load and append a bytecode, IMC or PASM file into interpreter.

Load some bytecode (PASM, PIR, PBC ...) and append it to the current directory.

void PackFile_fixup_subs

Run :load or :immediate subroutines for the current code segment. If eval is given, set this is the owner of the subroutines.

HISTORY

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


parrot