Author: jonathan
Date: Thu Nov 27 17:48:51 2008
New Revision: 33289
Modified:
branches/bcanno/src/packfile.c
Log:
[core] Define packfile functions for annotations segment, apart from dump which
is still to do. (For those wondering, ain't we moving to PackFile PMCs - yes,
but that'll happen in a future branch, or more likely bit by bit in several of
them. I tried to do all of this together once before and it was epic fail. So
for now, we build bytecode annotations on top of what's already here.)
Modified: branches/bcanno/src/packfile.c
==============================================================================
--- branches/bcanno/src/packfile.c (original)
+++ branches/bcanno/src/packfile.c Thu Nov 27 17:48:51 2008
@@ -317,6 +317,31 @@
__attribute__nonnull__(1)
__attribute__nonnull__(3);
+PackFile_Segment *
+PackFile_Annotations_new(PARROT_INTERP,
+ struct PackFile *pf,
+ const char *name,
+ int add);
+
+void
+PackFile_Annotations_destroy(PARROT_INTERP,
+ struct PackFile_Segment *seg);
+
+size_t
+PackFile_Annotations_packed_size(PARROT_INTERP,
+ struct PackFile_Segment *seg);
+
+opcode_t *PackFile_Annotations_pack(PARROT_INTERP,
+ struct PackFile_Segment *seg,
+ opcode_t *cursor);
+
+opcode_t *PackFile_Annotations_unpack(PARROT_INTERP,
+ PackFile_Segment *seg,
+ opcode_t *cursor);
+
+void PackFile_Annotations_dump(PARROT_INTERP,
+ struct PackFile_Segment *seg);
+
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will
be lost. */
/* HEADERIZER END: static */
@@ -1384,12 +1409,23 @@
pf_debug_unpack,
pf_debug_dump
};
- PackFile_funcs_register(interp, pf, PF_DIR_SEG, dirf);
- PackFile_funcs_register(interp, pf, PF_UNKNOWN_SEG, defaultf);
- PackFile_funcs_register(interp, pf, PF_FIXUP_SEG, fixupf);
- PackFile_funcs_register(interp, pf, PF_CONST_SEG, constf);
- PackFile_funcs_register(interp, pf, PF_BYTEC_SEG, bytef);
- PackFile_funcs_register(interp, pf, PF_DEBUG_SEG, debugf);
+
+ const PackFile_funcs annotationf = {
+ PackFile_Annotations_new,
+ PackFile_Annotations_destroy,
+ PackFile_Annotations_packed_size,
+ PackFile_Annotations_pack,
+ PackFile_Annotations_unpack,
+ PackFile_Annotations_dump
+ };
+
+ PackFile_funcs_register(interp, pf, PF_DIR_SEG, dirf);
+ PackFile_funcs_register(interp, pf, PF_UNKNOWN_SEG, defaultf);
+ PackFile_funcs_register(interp, pf, PF_FIXUP_SEG, fixupf);
+ PackFile_funcs_register(interp, pf, PF_CONST_SEG, constf);
+ PackFile_funcs_register(interp, pf, PF_BYTEC_SEG, bytef);
+ PackFile_funcs_register(interp, pf, PF_DEBUG_SEG, debugf);
+ PackFile_funcs_register(interp, pf, PF_ANNOTATIONS_SEG, annotationf);
return;
}
@@ -3612,6 +3648,178 @@
return cursor;
}
+
+/*
+
+=item C<PackFile_Segment * PackFile_Annotations_new>
+
+Creates a new annotations segment structure. Ignores the parameters C<name>
+and C<add>.
+
+*/
+
+PackFile_Segment *
+PackFile_Annotations_new(PARROT_INTERP, struct PackFile *pf, const char *name,
+ int add) {
+ /* Allocate annotations structure; create it all zeroed, and we will
+ * allocate memory for each of the arrays on demand. */
+ PackFile_Annotations *seg = mem_allocate_typed(PackFile_Annotations);
+ return (PackFile_Segment *) seg;
+}
+
+
+/*
+
+=item C<void PackFile_Annotations_destroy>
+
+Frees all memory associated with an annotations segment.
+
+*/
+
+void
+PackFile_Annotations_destroy(PARROT_INTERP, struct PackFile_Segment *seg) {
+ PackFile_Annotations *self = (PackFile_Annotations *)seg;
+ INTVAL i;
+
+ /* Free any keys. */
+ if (self->keys) {
+ for (i = 0; i < self->num_keys; i++)
+ mem_sys_free(self->keys[i]);
+ mem_sys_free(self->keys);
+ }
+
+ /* Free any groups. */
+ if (self->groups) {
+ for (i = 0; i < self->num_groups; i++)
+ mem_sys_free(self->groups[i]);
+ mem_sys_free(self->groups);
+ }
+
+ /* Free any entries. */
+ if (self->entries) {
+ for (i = 0; i < self->num_entries; i++)
+ mem_sys_free(self->entries[i]);
+ mem_sys_free(self->entries);
+ }
+}
+
+
+/*
+
+=item C<size_t PackFile_Annotations_packed_size>
+
+Computes the number of opcode_ts we'll need to store the passed annotations
+segment.
+
+*/
+
+size_t
+PackFile_Annotations_packed_size(PARROT_INTERP, struct PackFile_Segment *seg) {
+ PackFile_Annotations *self = (PackFile_Annotations *)seg;
+ return 3 /* Counts. */
+ + self->num_keys * 2 /* Keys. */
+ + self->num_groups * 2 /* Groups. */
+ + self->num_entries * 3; /* Entries. */
+}
+
+
+/*
+
+=item C<opcode_t * PackFile_Annotations_pack>
+
+Packs this segment into bytecode.
+
+*/
+
+opcode_t *PackFile_Annotations_pack(PARROT_INTERP, struct PackFile_Segment
*seg,
+ opcode_t *cursor) {
+ PackFile_Annotations *self = (PackFile_Annotations *)seg;
+ INTVAL i;
+
+ /* Write key count and any keys. */
+ *cursor++ = self->num_keys;
+ for (i = 0; i < self->num_keys; i++) {
+ *cursor++ = self->keys[i]->name;
+ *cursor++ = self->keys[i]->type;
+ }
+
+ /* Write group count and any groups. */
+ *cursor++ = self->num_groups;
+ for (i = 0; i < self->num_groups; i++) {
+ *cursor++ = self->groups[i]->bytecode_offset;
+ *cursor++ = self->groups[i]->entries_offset;
+ }
+
+ /* Write entry count and any entries. */
+ *cursor++ = self->num_entries;
+ for (i = 0; i < self->num_entries; i++) {
+ *cursor++ = self->entries[i]->bytecode_offset;
+ *cursor++ = self->entries[i]->key;
+ *cursor++ = self->entries[i]->value.integer;
+ }
+
+ return cursor;
+}
+
+
+/*
+
+=item C<opcode_t * PackFile_Annotations_unpack>
+
+Unpacks this segment from the bytecode.
+
+*/
+
+opcode_t *PackFile_Annotations_unpack(PARROT_INTERP, PackFile_Segment *seg,
+ opcode_t *cursor) {
+ PackFile_Annotations *self = (PackFile_Annotations *)seg;
+ INTVAL i;
+
+ /* Unpack keys. */
+ self->num_keys = PF_fetch_opcode(seg->pf, &cursor);
+ self->keys = mem_allocate_n_typed(self->num_keys,
PackFile_Annotations_Key *);
+ for (i = 0; i < self->num_keys; i++) {
+ self->keys[i] = mem_allocate_typed(PackFile_Annotations_Key);
+ self->keys[i]->name = PF_fetch_opcode(seg->pf, &cursor);
+ self->keys[i]->type = PF_fetch_opcode(seg->pf, &cursor);
+ }
+
+ /* Unpack groups. */
+ self->num_groups = PF_fetch_opcode(seg->pf, &cursor);
+ self->groups = mem_allocate_n_typed(self->num_groups,
PackFile_Annotations_Group *);
+ for (i = 0; i < self->num_groups; i++) {
+ self->groups[i] =
mem_allocate_typed(PackFile_Annotations_Group);
+ self->groups[i]->bytecode_offset = PF_fetch_opcode(seg->pf, &cursor);
+ self->groups[i]->entries_offset = PF_fetch_opcode(seg->pf, &cursor);
+ }
+
+ /* Unpack entries. */
+ self->num_entries = PF_fetch_opcode(seg->pf, &cursor);
+ self->entries = mem_allocate_n_typed(self->num_entries,
PackFile_Annotations_Entry *);
+ for (i = 0; i < self->num_entries; i++) {
+ self->entries[i] =
mem_allocate_typed(PackFile_Annotations_Entry);
+ self->entries[i]->bytecode_offset = PF_fetch_opcode(seg->pf, &cursor);
+ self->entries[i]->key = PF_fetch_opcode(seg->pf, &cursor);
+ self->entries[i]->value.integer = PF_fetch_opcode(seg->pf, &cursor);
+ }
+
+ return cursor;
+}
+
+
+/*
+
+=item C<void PackFile_Annotations_dump>
+
+Produces a dump of the annotations segment.
+
+*/
+
+void PackFile_Annotations_dump(PARROT_INTERP, struct PackFile_Segment *seg) {
+ /* TODO */
+}
+
+
/*
=item C<static PackFile * PackFile_append_pbc>