2 Copyright (C) 2001-2010, Parrot Foundation.
7 src/pmc/packfileconstanttable.pmc - PackfileConstantTable PMC
11 This class implements a PackfileConstantTable object, a segment of the .pbc
12 data file used for storing constants of various types. (int, string, PMC)
14 See packfile.pmc for the toplevel Packfile interface, see packfilesegment.pmc
15 for the list of common methods every packfile segment pmc must implement; see
16 PDD13 for the design spec.
27 /* HEADERIZER HFILE: none */
28 /* HEADERIZER BEGIN: static */
29 /* HEADERIZER END: static */
31 pmclass PackfileConstantTable auto_attrs extends PackfileSegment {
32 /* ResizablePMCArray for storing constants */
35 /* ResizableIntegerArray for storing constant types */
42 Create empty PackfileConstantTable.
49 Parrot_PackfileConstantTable_attributes * const attrs =
50 PMC_data_typed(SELF, Parrot_PackfileConstantTable_attributes*);
52 attrs->constants = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
53 attrs->types = Parrot_pmc_new(INTERP, enum_class_ResizableIntegerArray);
55 PObj_custom_mark_SET(SELF);
56 PMC_data(SELF) = attrs;
63 Marks the object as live.
70 Parrot_PackfileConstantTable_attributes * const attrs =
71 PARROT_PACKFILECONSTANTTABLE(SELF);
73 Parrot_gc_mark_PMC_alive(INTERP, attrs->constants);
74 Parrot_gc_mark_PMC_alive(INTERP, attrs->types);
84 Set pointer to underlying PackFile_ConstTable
90 VTABLE void set_pointer(void * pointer) {
91 Parrot_PackfileConstantTable_attributes * const attrs =
92 PARROT_PACKFILECONSTANTTABLE(SELF);
93 const PackFile_ConstTable * const table =
94 (const PackFile_ConstTable *)(pointer);
97 /* Preallocate required amount of memory */
98 VTABLE_set_integer_native(INTERP, attrs->constants, table->const_count);
99 VTABLE_set_integer_native(INTERP, attrs->types, table->const_count);
101 for (i = 0; i < table->const_count; ++i) {
102 const PackFile_Constant * val = &table->constants[i];
107 SELF.set_number_keyed_int(i, val->u.number);
110 SELF.set_string_keyed_int(i, val->u.string);
115 SELF.set_pmc_keyed_int(i, val->u.key);
118 Parrot_ex_throw_from_c_args(INTERP, NULL,
119 EXCEPTION_MALFORMED_PACKFILE,
120 "Unknown PackFile constant type: %d", val->type);
127 =item C<void *get_pointer()>
131 VTABLE void *get_pointer() {
132 Parrot_PackfileConstantTable_attributes * const attrs =
133 PARROT_PACKFILECONSTANTTABLE(SELF);
134 PackFile_ConstTable * const pftable =
135 mem_gc_allocate_zeroed_typed(INTERP, PackFile_ConstTable);
138 pftable->base.type = PF_CONST_SEG;
140 /* Copy all constanst with respect of type */
141 pftable->const_count = VTABLE_get_integer(INTERP, attrs->constants);
142 pftable->constants = mem_gc_allocate_n_typed(INTERP,
143 pftable->const_count, PackFile_Constant);
145 for (i = 0; i < pftable->const_count; ++i) {
146 PackFile_Constant * const value = &pftable->constants[i];
147 value->type = VTABLE_get_integer_keyed_int(INTERP, attrs->types, i);
148 switch (value->type) {
152 value->u.number = VTABLE_get_number_keyed_int(INTERP,
153 attrs->constants, i);
156 value->u.string = VTABLE_get_string_keyed_int(INTERP,
157 attrs->constants, i);
161 value->u.key = VTABLE_get_pmc_keyed_int(INTERP,
162 attrs->constants, i);
165 Parrot_ex_throw_from_c_args(INTERP, NULL,
166 EXCEPTION_MALFORMED_PACKFILE,
167 "Unknown PackFile constant type: %d", value->type);
176 =item C<INTVAL elements()>
178 Get the number of elements in the array.
183 VTABLE INTVAL elements() {
184 return VTABLE_elements(INTERP,
185 PARROT_PACKFILECONSTANTTABLE(SELF)->constants);
191 =item C<FLOATVAL get_number_keyed_int(INTVAL index)>
193 Fetch a numeric constant. An exception is thrown if the given constant isn't
199 VTABLE FLOATVAL get_number_keyed_int(INTVAL index) {
200 return VTABLE_get_number_keyed_int(INTERP,
201 PARROT_PACKFILECONSTANTTABLE(SELF)->constants, index);
207 =item C<STRING *get_string_keyed_int(INTVAL index)>
209 Fetch a string constant. An exception is thrown if the given constant isn't
215 VTABLE STRING *get_string_keyed_int(INTVAL index) {
216 return VTABLE_get_string_keyed_int(INTERP,
217 PARROT_PACKFILECONSTANTTABLE(SELF)->constants, index);
223 =item C<PMC *get_pmc_keyed_int(INTVAL index)>
225 Fetch a PMC constant. An exception is thrown if the given constant isn't a PMC.
230 VTABLE PMC *get_pmc_keyed_int(INTVAL index) {
231 return VTABLE_get_pmc_keyed_int(INTERP,
232 PARROT_PACKFILECONSTANTTABLE(SELF)->constants, index);
238 =item C<void set_number_keyed_int(INTVAL index, FLOATVAL value)>
240 Set the constant to the given number.
245 VTABLE void set_number_keyed_int(INTVAL index, FLOATVAL value) {
246 Parrot_PackfileConstantTable_attributes * const attrs =
247 PARROT_PACKFILECONSTANTTABLE(SELF);
249 VTABLE_set_number_keyed_int(INTERP, attrs->constants, index, value);
250 VTABLE_set_integer_keyed_int(INTERP, attrs->types, index, PFC_NUMBER);
256 =item C<void set_string_keyed_int(INTVAL index, STRING *value)>
258 Set the constant to the given string.
264 VTABLE void set_string_keyed_int(INTVAL index, STRING *value) {
265 Parrot_PackfileConstantTable_attributes * const attrs =
266 PARROT_PACKFILECONSTANTTABLE(SELF);
268 VTABLE_set_string_keyed_int(INTERP, attrs->constants, index, value);
269 VTABLE_set_integer_keyed_int(INTERP, attrs->types, index, PFC_STRING);
275 =item C<void set_pmc_keyed_int(INTVAL index, PMC *value)>
277 Set the constant to the given PMC (or key).
282 VTABLE void set_pmc_keyed_int(INTVAL index, PMC *value) {
283 Parrot_PackfileConstantTable_attributes * const attrs =
284 PARROT_PACKFILECONSTANTTABLE(SELF);
285 const opcode_t type =
286 VTABLE_isa(INTERP, value, Parrot_str_new_constant(INTERP, "Key"))
290 VTABLE_set_pmc_keyed_int(INTERP, attrs->constants, index, value);
291 VTABLE_set_integer_keyed_int(INTERP, attrs->types, index, type);
297 =item C<INTVAL get_type(INTVAL index)>
299 Get the type of the specified constant. Possible type IDs:
303 =item 0x00 - No constant
305 =item 0x6E - Number constant
307 =item 0x73 - String constant
309 =item 0x70 - PMC constant
311 =item 0x6B - Key constant
318 METHOD get_type(INTVAL index) {
319 INTVAL rv = VTABLE_get_integer_keyed_int(INTERP,
320 PARROT_PACKFILECONSTANTTABLE(SELF)->types, index);
326 =item C<void set_main(INTVAL index)>
328 Set the :main flag in a Sub in the constant table.
330 Experimental. Use with care. There is no way to set the
331 private flags from PIR, so we need something like this.
333 If something goes wrong, blame NotFound.
338 METHOD set_main(INTVAL index) {
339 PMC *mainsub = SELF.get_pmc_keyed_int(index);
340 if (mainsub->vtable->base_type != enum_class_Sub)
341 Parrot_ex_throw_from_c_args(INTERP, NULL,
342 EXCEPTION_INVALID_OPERATION,
343 "Attempt to set main flag in a non Sub");
344 SUB_FLAG_flag_SET(PF_MAIN, mainsub);
349 =item C<INTVAL get_or_create_constant()>
351 Get or create constant for passed value.
356 MULTI INTVAL get_or_create_constant(STRING *value) {
357 Parrot_PackfileConstantTable_attributes * const attrs =
358 PARROT_PACKFILECONSTANTTABLE(SELF);
359 const INTVAL num = VTABLE_elements(INTERP, attrs->types);
362 for (i=0; i < num; ++i) {
363 const INTVAL type = VTABLE_get_integer_keyed_int(INTERP, attrs->types, i);
364 if (type == PFC_STRING) {
365 STRING * const str = VTABLE_get_string_keyed_int(INTERP, attrs->constants, i);
366 if (Parrot_str_equal(INTERP, value, str))
370 /* Constant not found. Add new one */
371 VTABLE_set_string_keyed_int(INTERP, SELF, i, value);
375 MULTI INTVAL get_or_create_constant(FLOATVAL value) {
376 Parrot_PackfileConstantTable_attributes * const attrs =
377 PARROT_PACKFILECONSTANTTABLE(SELF);
378 const INTVAL num = VTABLE_elements(INTERP, attrs->types);
381 for (i=0; i < num; ++i) {
382 const INTVAL type = VTABLE_get_integer_keyed_int(INTERP, attrs->types, i);
383 if (type == PFC_NUMBER) {
384 const FLOATVAL val = VTABLE_get_number_keyed_int(INTERP, attrs->constants, i);
385 if (FLOAT_IS_ZERO(fabs(val - value)))
389 /* Constant not found. Add new one */
390 VTABLE_set_number_keyed_int(INTERP, SELF, i, value);
394 MULTI INTVAL get_or_create_constant(PMC *value) {
395 Parrot_PackfileConstantTable_attributes * const attrs =
396 PARROT_PACKFILECONSTANTTABLE(SELF);
397 const INTVAL num = VTABLE_elements(INTERP, attrs->types);
399 const INTVAL val_type =
400 value->vtable->base_type == enum_class_Key
404 for (i=0; i < num; ++i) {
405 const INTVAL type = VTABLE_get_integer_keyed_int(INTERP, attrs->types, i);
406 if (type == val_type) {
407 PMC * const val = VTABLE_get_pmc_keyed_int(INTERP, attrs->constants, i);
408 if (VTABLE_is_equal(INTERP, value, val))
412 /* Constant not found. Add new one */
413 VTABLE_set_pmc_keyed_int(INTERP, SELF, i, value);
419 =item C<METHOD type()>
428 RETURN(INTVAL PF_CONST_SEG);
443 * c-file-style: "parrot"
445 * vim: expandtab shiftwidth=4: