Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

266 lines (177 sloc) 5.804 kb
/*
Copyright (C) 2001-2014, Parrot Foundation.
=head1 NAME
src/pmc/packfilerawsegment.pmc - PackfileRawSegment PMC
=head1 DESCRIPTION
This class implements a PackfileRawSegment object, a low level view of a
segment that just splits it into an array of integers.
See packfile.pmc for the toplevel Packfile interface, see packfilesegment.pmc
for the list of common methods every packfile segment pmc must implement; see
PDD13 for the design spec.
=head2 Methods
=over 4
=cut
*/
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
pmclass PackfileRawSegment auto_attrs extends PackfileSegment {
/* Type of segment */
ATTR INTVAL type;
/* ResizableIntegerArray of opcodes */
ATTR PMC *opcodes;
/*
=item C<init>
Create empty PackfileRawSegment.
=cut
*/
VTABLE void init() {
Parrot_PackfileRawSegment_attributes * const attrs =
PMC_data_typed(SELF, Parrot_PackfileRawSegment_attributes*);
attrs->opcodes = Parrot_pmc_new(INTERP, enum_class_ResizableIntegerArray);
attrs->type = PF_BYTEC_SEG;
PObj_custom_mark_SET(SELF);
}
/*
=item C<void mark()>
Marks the object as live.
=cut
*/
VTABLE void mark() :no_wb {
Parrot_PackfileRawSegment_attributes * const attrs =
PARROT_PACKFILERAWSEGMENT(SELF);
Parrot_gc_mark_PMC_alive(INTERP, attrs->opcodes);
SUPER();
}
/*
=item C<set_pointer>
Initialize PackfileRawSegment from PackFile_Segment
=cut
*/
VTABLE void set_pointer(void * pointer) {
const PackFile_Segment * const pfseg =
(const PackFile_Segment *)pointer;
Parrot_PackfileRawSegment_attributes * const attrs =
PARROT_PACKFILERAWSEGMENT(SELF);
PMC * const opcodes = attrs->opcodes;
/* Preserve type of unpacked segment */
attrs->type = pfseg->type;
if (pfseg->size) {
size_t i;
/* copy data to own array */
VTABLE_set_integer_native(INTERP, opcodes, pfseg->size);
/* Not very efficient... */
for (i = 0; i < pfseg->size; ++i) {
VTABLE_set_integer_keyed_int(INTERP, opcodes, i, pfseg->data[i]);
}
}
}
/*
=item C<void *get_pointer()>
=cut
*/
VTABLE void *get_pointer() :no_wb {
PackFile_Segment * const pfseg =
(PackFile_Segment*)mem_gc_allocate_zeroed_typed(INTERP, PackFile_ByteCode);
const Parrot_PackfileRawSegment_attributes * const attrs =
PARROT_PACKFILERAWSEGMENT(SELF);
PMC * const opcodes = attrs->opcodes;
size_t i;
pfseg->type = attrs->type;
pfseg->size = VTABLE_get_integer(INTERP, opcodes);
pfseg->data = mem_gc_allocate_n_typed(INTERP, pfseg->size, opcode_t);
/* Not very efficient... */
for (i = 0; i < pfseg->size; ++i) {
pfseg->data[i] = VTABLE_get_integer_keyed_int(INTERP, opcodes, i);
}
return pfseg;
}
/*
=item C<INTVAL elements()>
Get the number of elements in the array.
=cut
*/
VTABLE INTVAL elements() :no_wb {
return VTABLE_elements(INTERP,
PARROT_PACKFILERAWSEGMENT(SELF)->opcodes);
}
VTABLE INTVAL get_integer() :no_wb {
return VTABLE_elements(INTERP,
PARROT_PACKFILERAWSEGMENT(SELF)->opcodes);
}
VTABLE FLOATVAL get_number() :no_wb {
return VTABLE_elements(INTERP,
PARROT_PACKFILERAWSEGMENT(SELF)->opcodes);
}
/*
=item C<INTVAL get_integer_keyed_int(INTVAL key)>
=item C<INTVAL get_pmc_keyed_int(INTVAL key)>
=item C<INTVAL get_pmc_keyed(PMC *key)>
Fetch an integer's worth of data from the segment.
=cut
*/
VTABLE INTVAL get_integer_keyed_int(INTVAL key) :no_wb {
return VTABLE_get_integer_keyed_int(INTERP,
PARROT_PACKFILERAWSEGMENT(SELF)->opcodes, key);
}
VTABLE PMC *get_pmc_keyed_int(INTVAL index) :no_wb {
return Parrot_pmc_box_integer(INTERP, STATICSELF.get_integer_keyed_int(index));
}
VTABLE PMC *get_pmc_keyed(PMC *key) :no_wb {
return STATICSELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
}
/*
=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
Set an integer's worth of data in the segment.
=cut
*/
VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) :manual_wb {
VTABLE_set_integer_keyed_int(INTERP,
PARROT_PACKFILERAWSEGMENT(SELF)->opcodes, key, value);
}
VTABLE void set_pmc_keyed(PMC *key, PMC *value) :manual_wb {
SELF.set_integer_keyed_int(
VTABLE_get_integer(INTERP, key),
VTABLE_get_integer(INTERP, value));
}
/*
=item C<void push_integer(INTVAL value)>
Append opcode to segment
=cut
*/
VTABLE void push_integer(INTVAL value) :manual_wb {
VTABLE_push_integer(INTERP,
PARROT_PACKFILERAWSEGMENT(SELF)->opcodes, value);
}
VTABLE void push_pmc(PMC *value) :manual_wb {
VTABLE_push_integer(INTERP,
PARROT_PACKFILERAWSEGMENT(SELF)->opcodes,
VTABLE_get_integer(INTERP, value));
}
/*
=item C<METHOD type()>
Set or get segment type.
=cut
TODO: Don't allow create Directory, Annotations, etc segments.
*/
METHOD type(INTVAL type :optional, INTVAL got_type :opt_flag) :no_wb {
Parrot_PackfileRawSegment_attributes * const attrs =
PARROT_PACKFILERAWSEGMENT(SELF);
INTVAL res;
if (got_type) {
attrs->type = type;
}
res = attrs->type;
RETURN(INTVAL res);
}
}
/*
=back
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/
Jump to Line
Something went wrong with that request. Please try again.