2 Copyright (C) 2001-2006, The Perl Foundation.
3 This program is free software. It is subject to the same license as
9 src/packfile.c - Parrot PackFile API
13 =head2 PackFile Manipulation Functions
15 This file contains all the functions required for the processing of the
16 structure of a PackFile. It is not intended to understand the byte code
17 stream itself, but merely to dissect and reconstruct data from the
18 various segments. See F<docs/parrotbyte.pod> for information about the
19 structure of the frozen bytecode.
27 #include "parrot/parrot.h"
28 #include "parrot/embed.h"
29 #include "parrot/packfile.h"
33 #define TRACE_PACKFILE 0
34 #define TRACE_PACKFILE_PMC 0
39 static void segment_init(Interp
*, struct PackFile_Segment
*self
,
43 static void default_destroy(Interp
*, struct PackFile_Segment
*self
);
44 static size_t default_packed_size(Interp
*,
45 const struct PackFile_Segment
*self
);
46 static opcode_t
* default_pack(Interp
*, const struct PackFile_Segment
*self
,
48 static opcode_t
* default_unpack(Interp
*,
49 struct PackFile_Segment
*self
,
51 static void default_dump(Interp
*,
52 struct PackFile_Segment
*self
);
54 static struct PackFile_Segment
*directory_new(Interp
*, struct PackFile
*,
56 static void directory_destroy(Interp
*, struct PackFile_Segment
*self
);
57 static size_t directory_packed_size(Interp
*, struct PackFile_Segment
*self
);
58 static opcode_t
* directory_pack(Interp
*, struct PackFile_Segment
*,
60 static opcode_t
* directory_unpack(Interp
*,
61 struct PackFile_Segment
*,
63 static void directory_dump(Interp
*, struct PackFile_Segment
*);
65 static struct PackFile_Segment
*fixup_new(Interp
*, struct PackFile
*,
67 static size_t fixup_packed_size(Interp
*, struct PackFile_Segment
*self
);
68 static opcode_t
* fixup_pack(Interp
*, struct PackFile_Segment
* self
,
70 static opcode_t
* fixup_unpack(Interp
*,
71 struct PackFile_Segment
*, opcode_t
*cursor
);
72 static void fixup_destroy(Interp
*, struct PackFile_Segment
*self
);
74 static struct PackFile_Segment
*const_new(Interp
*, struct PackFile
*,
76 static void const_destroy(Interp
*, struct PackFile_Segment
*self
);
78 static struct PackFile_Segment
*byte_code_new(Interp
*, struct PackFile
*pf
,
80 static void byte_code_destroy(Interp
*, struct PackFile_Segment
*self
);
81 static INTVAL
pf_register_standard_funcs(Interp
*, struct PackFile
*pf
);
83 static struct PackFile_Segment
* pf_debug_new(Interp
*, struct PackFile
*,
85 static size_t pf_debug_packed_size(Interp
*, struct PackFile_Segment
*self
);
86 static opcode_t
* pf_debug_pack(Interp
*, struct PackFile_Segment
*self
,
88 static void pf_debug_dump(Interp
*, struct PackFile_Segment
*);
89 static opcode_t
* pf_debug_unpack(Interp
*,
90 struct PackFile_Segment
*self
, opcode_t
*);
91 static void pf_debug_destroy(Interp
*, struct PackFile_Segment
*self
);
93 static struct PackFile_Constant
**find_constants(Interp
*,
94 struct PackFile_ConstTable
*);
96 #define ROUND_16(val) (((val) & 0xf) ? 16 - ((val) & 0xf) : 0)
97 #define ALIGN_16(st, cursor) \
99 (cursor) = (opcode_t *) \
101 + ROUND_16((char *)(cursor) - (char *)(st))); \
107 PackFile_destroy(struct PackFile *pf)>
109 Delete a C<PackFile>.
116 PackFile_destroy(Interp
*interp
, struct PackFile
*pf
)
119 PIO_eprintf(NULL
, "PackFile_destroy: pf == NULL!\n");
122 #ifdef PARROT_HAS_HEADER_SYSMMAN
124 munmap((void*)pf
->src
, pf
->size
);
126 mem_sys_free(pf
->header
);
128 mem_sys_free(pf
->dirp
);
130 PackFile_Segment_destroy(interp
, &pf
->directory
.base
);
136 =item C<static INTVAL
137 PackFile_check_segment_size(opcode_t segment_size, const char *debug)>
139 Internal function to check C<segment_size % sizeof (opcode_t)>.
146 PackFile_check_segment_size(opcode_t segment_size
, const char *debug
)
149 PIO_eprintf(NULL
,"PackFile_unpack(): Unpacking %ld bytes for %s table...\n",
150 (long)segment_size
, debug
);
153 if (segment_size
% sizeof (opcode_t
)) {
155 "PackFile_unpack: Illegal %s table segment size "
156 "%ld (must be multiple of %ld)!\n",
157 debug
, (long)segment_size
, (long)sizeof (opcode_t
));
166 make_code_pointers(struct PackFile_Segment *seg)>
168 Make compat/shorthand pointers.
170 The first segments read are the default segments.
177 make_code_pointers(struct PackFile_Segment
*seg
)
179 struct PackFile
* const pf
= seg
->pf
;
184 pf
->cur_cs
= (struct PackFile_ByteCode
*)seg
;
188 if (!pf
->cur_cs
->fixups
) {
189 pf
->cur_cs
->fixups
= (struct PackFile_FixupTable
*)seg
;
190 pf
->cur_cs
->fixups
->code
= pf
->cur_cs
;
194 if (!pf
->cur_cs
->const_table
) {
195 pf
->cur_cs
->const_table
= (struct PackFile_ConstTable
*)seg
;
196 pf
->cur_cs
->const_table
->code
= pf
->cur_cs
;
199 if (memcmp(seg
->name
, "PIC_idx", 7) == 0)
200 pf
->cur_cs
->pic_index
= seg
;
203 pf
->cur_cs
->debugs
= (struct PackFile_Debug
*)seg
;
204 pf
->cur_cs
->debugs
->code
= pf
->cur_cs
;
215 sub_pragma(Parrot_Interp interp,
216 int action, PMC *sub_pmc)>
218 Handle :load, :main ... pragmas for B<sub_pmc>
225 sub_pragma(Parrot_Interp interp
, int action
, PMC
*sub_pmc
)
227 int pragmas
= PObj_get_FLAGS(sub_pmc
) & SUB_FLAG_PF_MASK
;
230 pragmas
&= ~SUB_FLAG_IS_OUTER
;
231 if (!pragmas
&& !Sub_comp_INIT_TEST(sub_pmc
))
236 if (interp
->resume_flag
& RESUME_INITIAL
) {
238 * denote MAIN entry in first loaded PASM
242 /* :init functions need to be called at MAIN time, so return 1 */
243 if (Sub_comp_INIT_TEST(sub_pmc
)) /* symreg.h:P_INIT */
247 if (pragmas
& SUB_FLAG_PF_LOAD
) /* symreg.h:P_LOAD */
251 if (pragmas
& (SUB_FLAG_PF_IMMEDIATE
| SUB_FLAG_PF_POSTCOMP
))
258 =item C<static PMC* run_sub(Parrot_Interp interp, PMC* sub_pmc)>
260 Run the B<sub_pmc> due its B<:load>, B<:immediate>, ... pragma
267 run_sub(Parrot_Interp interp
, PMC
* sub_pmc
)
269 const Parrot_Run_core_t old
= interp
->run_core
;
273 * turn off JIT and prederef - both would act on the whole
274 * PackFile which isn't worth the effort - probably
276 if (interp
->run_core
!= PARROT_CGOTO_CORE
&&
277 interp
->run_core
!= PARROT_SLOW_CORE
&&
278 interp
->run_core
!= PARROT_FAST_CORE
)
279 interp
->run_core
= PARROT_FAST_CORE
;
280 CONTEXT(interp
->ctx
)->constants
=
281 interp
->code
->const_table
->constants
;
282 retval
= Parrot_runops_fromc_args(interp
, sub_pmc
, "P");
283 interp
->run_core
= old
;
290 do_1_sub_pragma(Parrot_Interp interp, struct PackFile *self, int action)>
292 Run autoloaded or immediate bytecode, mark MAIN subroutine entry
299 do_1_sub_pragma(Parrot_Interp interp
, PMC
* sub_pmc
, int action
)
303 struct Parrot_sub
* const sub
= PMC_sub(sub_pmc
);
312 if (PObj_get_FLAGS(sub_pmc
) & SUB_FLAG_PF_IMMEDIATE
) {
313 PObj_get_FLAGS(sub_pmc
) &= ~SUB_FLAG_PF_IMMEDIATE
;
314 lo_var_ptr
= interp
->lo_var_ptr
;
315 result
= run_sub(interp
, sub_pmc
);
317 * reset initial flag so MAIN detection works
318 * and reset lo_var_ptr to prev
320 interp
->resume_flag
= RESUME_INITIAL
;
321 interp
->lo_var_ptr
= lo_var_ptr
;
329 if (PObj_get_FLAGS(sub_pmc
) & SUB_FLAG_PF_POSTCOMP
) {
330 PObj_get_FLAGS(sub_pmc
) &= ~SUB_FLAG_PF_POSTCOMP
;
331 run_sub(interp
, sub_pmc
);
333 * reset initial flag so MAIN detection works
335 interp
->resume_flag
= RESUME_INITIAL
;
341 if (PObj_get_FLAGS(sub_pmc
) & SUB_FLAG_PF_LOAD
) {
342 PObj_get_FLAGS(sub_pmc
) &= ~SUB_FLAG_PF_LOAD
;
343 Sub_comp_INIT_CLEAR(sub_pmc
); /* if loaded no need for init */
344 run_sub(interp
, sub_pmc
);
348 if (PObj_get_FLAGS(sub_pmc
) & SUB_FLAG_PF_MAIN
) {
349 if ((interp
->resume_flag
& RESUME_INITIAL
) &&
350 interp
->resume_offset
== 0) {
351 ptrdiff_t code
= (ptrdiff_t) sub
->seg
->base
.data
;
354 ((ptrdiff_t) VTABLE_get_pointer(interp
, sub_pmc
)
355 - code
) / sizeof (opcode_t
*);
356 interp
->resume_offset
= start_offs
;
357 PObj_get_FLAGS(sub_pmc
) &= ~SUB_FLAG_PF_MAIN
;
358 CONTEXT(interp
->ctx
)->current_sub
= sub_pmc
;
361 /* XXX which warn_class */
362 Parrot_warn(interp
, PARROT_WARNINGS_ALL_FLAG
,
363 ":main sub not allowed\n");
367 /* run :init tagged functions */
368 if (action
== PBC_MAIN
&& (Sub_comp_INIT_TEST(sub_pmc
))) {
369 Sub_comp_INIT_CLEAR(sub_pmc
); /* if loaded no need for init */
370 PObj_get_FLAGS(sub_pmc
) &= ~SUB_FLAG_PF_LOAD
; /* if inited no need for load */
371 run_sub(interp
, sub_pmc
);
372 interp
->resume_flag
= RESUME_INITIAL
;
380 * while the PMCs should be constant, there possible contents like
381 * a property isn't constructed const so we have to mark them
384 mark_1_seg(Parrot_Interp interp
, struct PackFile_ConstTable
*ct
)
387 struct PackFile_Constant
**constants
;
389 constants
= find_constants(interp
, ct
);
390 for (i
= 0; i
< ct
->const_count
; i
++) {
391 switch (constants
[i
]->type
) {
394 PMC
* const pmc
= constants
[i
]->u
.key
;
396 pobject_lives(interp
, (PObj
*)pmc
);
403 find_const_iter(Interp
* interp
,
404 struct PackFile_Segment
*seg
, void *user_data
)
406 if (seg
->type
== PF_DIR_SEG
) {
407 PackFile_map_segments(interp
, (struct PackFile_Directory
*)seg
,
408 find_const_iter
, user_data
);
410 else if (seg
->type
== PF_CONST_SEG
) {
411 mark_1_seg(interp
, (struct PackFile_ConstTable
*)seg
);
417 mark_const_subs(Parrot_Interp interp
)
419 struct PackFile_Directory
*dir
;
421 struct PackFile
* const self
= interp
->initial_pf
;
425 * locate top level dir
427 dir
= &self
->directory
;
429 * iterate over all dir/segs
431 PackFile_map_segments(interp
, dir
, find_const_iter
, NULL
);
437 do_sub_pragmas(Interp *interp, struct PackFile_Bytecode *self,
438 int action, PMC *eval_pmc)>
441 B<PBC_PBC>, B<PBC_LOADED>, B<PBC_INIT>, or B<PBC_MAIN>. Also store the C<eval_pmc>
442 in the sub structure, so that the eval PMC is kept alive be living subs.
449 do_sub_pragmas(Interp
*interp
, struct PackFile_ByteCode
*self
,
450 int action
, PMC
*eval_pmc
)
453 PMC
*sub_pmc
, *result
;
454 struct PackFile_FixupTable
*ft
= self
->fixups
;
455 struct PackFile_ConstTable
*ct
= self
->const_table
;
458 PIO_eprintf(NULL
, "PackFile: do_sub_pragmas (action=%d)\n", action
);
461 for (i
= 0; i
< ft
->fixup_count
; i
++) {
462 switch (ft
->fixups
[i
]->type
) {
466 * offset is an index into the const_table holding
469 const opcode_t ci
= ft
->fixups
[i
]->offset
;
470 if (ci
< 0 || ci
>= ct
->const_count
)
471 internal_exception(1,
472 "Illegal fixup offset (%d) in enum_fixup_sub");
473 sub_pmc
= ct
->constants
[ci
]->u
.key
;
474 PMC_sub(sub_pmc
)->eval_pmc
= eval_pmc
;
475 if (((PObj_get_FLAGS(sub_pmc
) & SUB_FLAG_PF_MASK
)
476 || (Sub_comp_get_FLAGS(sub_pmc
) & SUB_COMP_FLAG_MASK
))
477 && sub_pragma(interp
, action
, sub_pmc
)) {
478 result
= do_1_sub_pragma(interp
,
481 * replace the Sub PMC with the result of the
484 if (action
== PBC_IMMEDIATE
&&
485 !PMC_IS_NULL(result
)) {
486 ft
->fixups
[i
]->type
= enum_fixup_none
;
487 ct
->constants
[ci
]->u
.key
= result
;
492 case enum_fixup_label
:
493 /* fill in current bytecode seg */
494 ft
->fixups
[i
]->seg
= self
;
503 PackFile_unpack(Interp *interp, struct PackFile *self,
504 opcode_t *packed, size_t packed_size)>
506 Unpack a C<PackFile> from a block of memory. The format is:
514 byte pad[10] = fingerprint
517 opcode_t language type
526 All segments have this common header:
528 - op_count ... total segment size incl. this count
529 - itype ... internal type of data
530 - id ... id of data e.g. byte code nr.
531 - size ... size of data oparray
532 - data[size] ... data array e.g. bytecode
533 segment specific data follows here ...
535 Checks to see if the magic matches the Parrot magic number for
538 Returns size of unpacked if everything is OK, else zero (0).
545 PackFile_unpack(Interp
*interp
, struct PackFile
*self
,
546 opcode_t
*packed
, size_t packed_size
)
548 struct PackFile_Header
*header
= self
->header
;
552 PIO_eprintf(NULL
, "PackFile_unpack: self == NULL!\n");
556 self
->size
= packed_size
;
559 * Map the header on top of the buffer later when we are sure
560 * we have alignment done right.
562 cursor
= (opcode_t
*)((char*)packed
+ PACKFILE_HEADER_BYTES
);
563 memcpy(header
, packed
, PACKFILE_HEADER_BYTES
);
565 if (header
->wordsize
!= 4 && header
->wordsize
!= 8) {
566 PIO_eprintf(NULL
, "PackFile_unpack: Invalid wordsize %d\n",
570 if (header
->floattype
!= 0 && header
->floattype
!= 1) {
571 PIO_eprintf(NULL
, "PackFile_unpack: Invalid floattype %d\n",
576 PackFile_assign_transforms(self
);
579 PIO_eprintf(NULL
, "PackFile_unpack: Wordsize %d.\n", header
->wordsize
);
580 PIO_eprintf(NULL
, "PackFile_unpack: Floattype %d (%s).\n",
583 "x86 little endian 12 byte long double" :
584 "IEEE-754 8 byte double");
585 PIO_eprintf(NULL
, "PackFile_unpack: Byteorder %d (%sendian).\n",
586 header
->byteorder
, header
->byteorder
? "big " : "little-");
589 if (header
->major
!= PARROT_MAJOR_VERSION
||
590 header
->minor
!= PARROT_MINOR_VERSION
) {
591 PIO_eprintf(NULL
, "PackFile_unpack: Bytecode not valid for this "
592 "interpreter: version mismatch\n");
596 /* check the fingerprint */
597 if (!PackFile_check_fingerprint (header
->pad
)) {
598 PIO_eprintf(NULL
, "PackFile_unpack: Bytecode not valid for this "
599 "interpreter: fingerprint mismatch\n");
603 * Unpack and verify the magic which is stored byteorder of the file:
605 header
->magic
= PF_fetch_opcode(self
, &cursor
);
608 * The magic and opcodetype fields are in native byteorder.
610 if (header
->magic
!= PARROT_MAGIC
) {
611 PIO_eprintf(NULL
, "PackFile_unpack: Not a Parrot PackFile!\n");
612 PIO_eprintf(NULL
, "Magic number was 0x%08x not 0x%08x\n",
613 header
->magic
, PARROT_MAGIC
);
618 PIO_eprintf(NULL
, "PackFile_unpack: Magic 0x%08x.\n",
622 header
->opcodetype
= PF_fetch_opcode(self
, &cursor
);
625 PIO_eprintf(NULL
, "PackFile_unpack: Opcodetype 0x%x.\n",
630 * Unpack the dir_format
634 PIO_eprintf(NULL
, "PackFile_unpack: Directory, offset %d.\n",
635 (INTVAL
)cursor
- (INTVAL
)packed
);
637 header
->dir_format
= PF_fetch_opcode(self
, &cursor
);
639 /* dir_format 1 use directory */
640 if (header
->dir_format
!= PF_DIR_FORMAT
) {
642 "PackFile_unpack: Dir format was %d not %d\n",
643 header
->dir_format
, PF_DIR_FORMAT
);
647 PIO_eprintf(NULL
, "PackFile_unpack: Dirformat %d.\n", header
->dir_format
);
650 (void)PF_fetch_opcode(self
, &cursor
); /* padding */
652 PIO_eprintf(NULL
, "PackFile_unpack: Directory read, offset %d.\n",
653 (INTVAL
)cursor
- (INTVAL
)packed
);
656 self
->directory
.base
.file_offset
= (INTVAL
)cursor
- (INTVAL
)self
->src
;
658 * now unpack dir, which unpacks its contents ...
660 Parrot_block_DOD(interp
);
661 cursor
= PackFile_Segment_unpack(interp
,
662 &self
->directory
.base
, cursor
);
663 Parrot_unblock_DOD(interp
);
665 #ifdef PARROT_HAS_HEADER_SYSMMAN
666 if (self
->is_mmap_ped
&& (
667 self
->need_endianize
|| self
->need_wordsize
)) {
668 munmap((void *)self
->src
, self
->size
);
669 self
->is_mmap_ped
= 0;
674 PIO_eprintf(NULL
, "PackFile_unpack: Unpack done.\n");
677 return cursor
- packed
;
683 PackFile_map_segments(Interp*, struct PackFile_Directory *dir,
684 PackFile_map_segments_func_t callback,
687 For each segment in the directory C<dir> the callback function
688 C<callback> is called. The pointer C<user_data> is append to each call.
690 If a callback returns non-zero the processing of segments is stopped,
691 and this value is returned.
698 PackFile_map_segments(Interp
* interp
, struct PackFile_Directory
*dir
,
699 PackFile_map_segments_func_t callback
,
704 for (i
= 0; i
< dir
->num_segments
; i
++) {
705 const INTVAL ret
= callback(interp
, dir
->segments
[i
], user_data
);
716 PackFile_add_segment(struct PackFile_Directory *dir,
717 struct PackFile_Segment *seg)>
719 Adds the Segment C<seg> to the directory C<dir> The PackFile becomes the
720 owner of the segment; that means its getting destroyed, when the
721 packfile gets destroyed.
728 PackFile_add_segment(Interp
* interp
, struct PackFile_Directory
*dir
,
729 struct PackFile_Segment
*seg
)
734 mem_sys_realloc(dir
->segments
,
735 sizeof (struct PackFile_Segment
*) *
736 (dir
->num_segments
+1));
739 dir
->segments
= mem_sys_allocate(sizeof (struct PackFile_Segment
*) *
740 (dir
->num_segments
+1));
742 dir
->segments
[dir
->num_segments
] = seg
;
751 =item C<struct PackFile_Segment *
752 PackFile_find_segment(Interp *, struct PackFile_Directory *dir,
753 const char *name, int sub_dir)>
755 Finds the segment with the name C<name> in the C<PackFile_Directory> if
756 C<sub_dir> is true, directories are searched recursively The segment is
757 returned, but its still owned by the C<PackFile>.
763 struct PackFile_Segment
*
764 PackFile_find_segment(Interp
*interp
,
765 struct PackFile_Directory
*dir
, const char *name
, int sub_dir
)
771 for (i
=0; i
< dir
->num_segments
; i
++) {
772 struct PackFile_Segment
*seg
= dir
->segments
[i
];
773 if (seg
&& strcmp(seg
->name
, name
) == 0) {
776 if (sub_dir
&& seg
->type
== PF_DIR_SEG
) {
777 seg
= PackFile_find_segment(interp
,
778 (struct PackFile_Directory
*)seg
, name
, sub_dir
);
789 =item C<struct PackFile_Segment *
790 PackFile_remove_segment_by_name(Interp *, struct PackFile_Directory *dir,
793 Finds and removes the segment with name C<name> in the
794 C<PackFile_Directory>. The segment is returned and must be destroyed by
801 struct PackFile_Segment
*
802 PackFile_remove_segment_by_name(Interp
* interp
,
803 struct PackFile_Directory
*dir
, const char *name
)
807 for (i
=0; i
< dir
->num_segments
; i
++) {
808 struct PackFile_Segment
* const seg
= dir
->segments
[i
];
809 if (strcmp(seg
->name
, name
) == 0) {
811 if (i
!= dir
->num_segments
) {
812 /* We're not the last segment, so we need to move things */
813 memmove(&dir
->segments
[i
], &dir
->segments
[i
+1],
814 (dir
->num_segments
- i
) *
815 sizeof (struct PackFile_Segment
*));
828 =head2 PackFile Structure Functions
833 PackFile_set_header(struct PackFile *self)>
835 Fill a C<PackFile> header with system specific data.
842 PackFile_set_header(struct PackFile
*self
)
844 self
->header
->wordsize
= sizeof (opcode_t
);
845 self
->header
->byteorder
= PARROT_BIGENDIAN
;
846 self
->header
->major
= PARROT_MAJOR_VERSION
;
847 self
->header
->minor
= PARROT_MINOR_VERSION
;
848 self
->header
->intvalsize
= sizeof (INTVAL
);
849 if (NUMVAL_SIZE
== 8)
850 self
->header
->floattype
= 0;
852 self
->header
->floattype
= 1;
853 /* write the fingerprint */
854 PackFile_write_fingerprint(self
->header
->pad
);
859 =item C<struct PackFile *
860 PackFile_new(Interp*, INTVAL is_mapped)>
862 Allocate a new empty C<PackFile> and setup the directory.
866 +----------+----------+----------+----------+
869 +----------+----------+----------+----------+
871 +----------+----------+----------+----------+
872 | number of directory items |
873 +----------+----------+----------+----------+
875 followed by a sequence of items
877 +----------+----------+----------+----------+
879 +----------+----------+----------+----------+
881 | ... '\0' padding bytes |
882 +----------+----------+----------+----------+
883 | Offset in the file |
884 +----------+----------+----------+----------+
885 | Size of the segment |
886 +----------+----------+----------+----------+
888 "name" is a NUL-terminated c-string encoded in plain ASCII.
890 Segment types are defined in F<include/parrot/packfile.h>.
892 Offset and size are in C<opcode_t>.
894 A Segment Header has these entries:
896 - op_count total ops of segment incl. this count
897 - itype internal type of segment
898 - id internal id e.g code seg nr
899 - size size of following op array, 0 if none
900 * data possibly empty data, or e.g. byte code
907 PackFile_new(Interp
* interp
, INTVAL is_mapped
)
909 struct PackFile
* const pf
=
910 mem_sys_allocate_zeroed(sizeof (struct PackFile
));
913 PIO_eprintf(NULL
, "PackFile_new: Unable to allocate!\n");
916 pf
->is_mmap_ped
= is_mapped
;
919 mem_sys_allocate_zeroed(sizeof (struct PackFile_Header
));
921 PIO_eprintf(NULL
, "PackFile_new: Unable to allocate header!\n");
922 PackFile_destroy(interp
, pf
);
926 * fill header with system specific data
928 PackFile_set_header(pf
);
930 /* Other fields empty for now */
932 pf_register_standard_funcs(interp
, pf
);
933 /* create the master directory, all subirs go there */
934 pf
->directory
.base
.pf
= pf
;
935 pf
->dirp
= (struct PackFile_Directory
*)
936 PackFile_Segment_new_seg(interp
, &pf
->directory
,
937 PF_DIR_SEG
, DIRECTORY_SEGMENT_NAME
, 0);
938 pf
->directory
= *pf
->dirp
;
939 pf
->fetch_op
= (opcode_t (*)(unsigned char*)) NULLfunc
;
940 pf
->fetch_iv
= (INTVAL (*)(unsigned char*)) NULLfunc
;
941 pf
->fetch_nv
= (void (*)(unsigned char *, unsigned char *)) NULLfunc
;
947 =item C<struct PackFile * PackFile_new_dummy(Interp*, const char *name)>
949 Create a new (initial) dummy PackFile. This is needed, if the interpreter
950 doesn't load any bytecode, but is using Parrot_compile_string.
957 PackFile_new_dummy(Interp
* interp
, const char *name
)
961 pf
= PackFile_new(interp
, 0);
962 interp
->initial_pf
= pf
;
964 pf
->cur_cs
= PF_create_default_segs(interp
, name
, 1);
970 =item C<INTVAL PackFile_funcs_register(Interp*, struct PackFile *pf,
972 struct PackFile_funcs funcs)>
974 Register the C<pack>/C<unpack>/... functions for a packfile type.
981 PackFile_funcs_register(Interp
* interp
,
982 struct PackFile
*pf
, UINTVAL type
, struct PackFile_funcs funcs
)
984 /* TODO dynamic registering */
985 pf
->PackFuncs
[type
] = funcs
;
991 =item C<static opcode_t * default_unpack(Interp *interp,
992 struct PackFile_Segment *self, opcode_t *cursor)>
994 The default unpack function.
1001 default_unpack(Interp
*interp
,
1002 struct PackFile_Segment
*self
, opcode_t
*cursor
)
1004 if (self
->pf
->header
->dir_format
) {
1005 self
->op_count
= PF_fetch_opcode(self
->pf
, &cursor
);
1006 self
->itype
= PF_fetch_opcode(self
->pf
, &cursor
);
1007 self
->id
= PF_fetch_opcode(self
->pf
, &cursor
);
1008 self
->size
= PF_fetch_opcode(self
->pf
, &cursor
);
1010 if (self
->size
== 0)
1012 /* if the packfile is mmap()ed just point to it if we don't
1013 * need any fetch transforms
1015 if (self
->pf
->is_mmap_ped
&&
1016 !self
->pf
->need_endianize
&& !self
->pf
->need_wordsize
) {
1017 self
->data
= cursor
;
1018 cursor
+= self
->size
;
1021 /* else allocate mem */
1022 self
->data
= mem_sys_allocate(self
->size
* sizeof (opcode_t
));
1026 "PackFile_unpack: Unable to allocate data memory!\n");
1031 if (!self
->pf
->need_endianize
&& !self
->pf
->need_wordsize
) {
1032 mem_sys_memcopy(self
->data
, cursor
, self
->size
* sizeof (opcode_t
));
1033 cursor
+= self
->size
;
1037 for (i
= 0; i
< (int)self
->size
; i
++) {
1038 self
->data
[i
] = PF_fetch_opcode(self
->pf
, &cursor
);
1040 PIO_eprintf(NULL
, "op[#%d] %u\n", i
, self
->data
[i
]);
1051 default_dump_header(Parrot_Interp interp, struct PackFile_Segment *self)>
1053 The default dump header function.
1060 default_dump_header(Parrot_Interp interp
, struct PackFile_Segment
*self
)
1062 PIO_printf(interp
, "%s => [ # offs 0x%x(%d)",
1063 self
->name
, (int)self
->file_offset
, (int)self
->file_offset
);
1064 PIO_printf(interp
, " = op_count %d, itype %d, id %d, size %d, ...",
1065 (int)self
->op_count
, (int)self
->itype
,
1066 (int)self
->id
, (int)self
->size
);
1072 default_dump(Parrot_Interp interp, struct PackFile_Segment *self)>
1074 The default dump function.
1081 default_dump(Parrot_Interp interp
, struct PackFile_Segment
*self
)
1085 default_dump_header(interp
, self
);
1086 i
= self
->data
? 0: self
->file_offset
+ 4;
1088 PIO_printf(interp
, "\n %04x: ", (int) i
);
1090 for ( ; i
< (self
->data
? self
->size
:
1091 self
->file_offset
+ self
->op_count
); i
++) {
1093 PIO_printf(interp
, "\n %04x: ", (int) i
);
1095 PIO_printf(interp
, "%08lx ", (unsigned long)
1096 self
->data
? self
->data
[i
] : self
->pf
->src
[i
]);
1098 PIO_printf(interp
, "\n]\n");
1103 =item C<static INTVAL
1104 pf_register_standard_funcs(Interp*, struct PackFile *pf)>
1106 Called from within C<PackFile_new()> register the standard functions.
1113 pf_register_standard_funcs(Interp
* interp
, struct PackFile
*pf
)
1115 struct PackFile_funcs dirf
= {
1118 directory_packed_size
,
1123 struct PackFile_funcs defaultf
= {
1124 PackFile_Segment_new
,
1125 (PackFile_Segment_destroy_func_t
) NULLfunc
,
1126 (PackFile_Segment_packed_size_func_t
) NULLfunc
,
1127 (PackFile_Segment_pack_func_t
) NULLfunc
,
1128 (PackFile_Segment_unpack_func_t
) NULLfunc
,
1131 struct PackFile_funcs fixupf
= {
1139 struct PackFile_funcs constf
= {
1142 PackFile_ConstTable_pack_size
,
1143 PackFile_ConstTable_pack
,
1144 PackFile_ConstTable_unpack
,
1147 struct PackFile_funcs bytef
= {
1150 (PackFile_Segment_packed_size_func_t
) NULLfunc
,
1151 (PackFile_Segment_pack_func_t
) NULLfunc
,
1152 (PackFile_Segment_unpack_func_t
) NULLfunc
,
1155 struct PackFile_funcs debugf
= {
1158 pf_debug_packed_size
,
1163 PackFile_funcs_register(interp
, pf
, PF_DIR_SEG
, dirf
);
1164 PackFile_funcs_register(interp
, pf
, PF_UNKNOWN_SEG
, defaultf
);
1165 PackFile_funcs_register(interp
, pf
, PF_FIXUP_SEG
, fixupf
);
1166 PackFile_funcs_register(interp
, pf
, PF_CONST_SEG
, constf
);
1167 PackFile_funcs_register(interp
, pf
, PF_BYTEC_SEG
, bytef
);
1168 PackFile_funcs_register(interp
, pf
, PF_DEBUG_SEG
, debugf
);
1174 =item C<struct PackFile_Segment *
1175 PackFile_Segment_new_seg(Interp*, struct PackFile_Directory *dir, UINTVAL type,
1176 const char *name, int add)>
1178 Create a new segment.
1184 struct PackFile_Segment
*
1185 PackFile_Segment_new_seg(Interp
* interp
,
1186 struct PackFile_Directory
*dir
, UINTVAL type
,
1187 const char *name
, int add
)
1189 struct PackFile
* const pf
= dir
->base
.pf
;
1190 PackFile_Segment_new_func_t f
= pf
->PackFuncs
[type
].new_seg
;
1191 struct PackFile_Segment
* const seg
= (f
)(interp
, pf
, name
, add
);
1192 segment_init (interp
, seg
, pf
, name
);
1195 PackFile_add_segment(interp
, dir
, seg
);
1199 static struct PackFile_Segment
*
1200 create_seg(Interp
*interp
, struct PackFile_Directory
*dir
,
1201 pack_file_types t
, const char *name
, const char *file_name
, int add
)
1203 struct PackFile_Segment
*seg
;
1205 const size_t len
= strlen(name
) + strlen(file_name
) + 2;
1206 char * const buf
= malloc(len
);
1208 sprintf(buf
, "%s_%s", name
, file_name
);
1209 seg
= PackFile_Segment_new_seg(interp
, dir
, t
, buf
, add
);
1216 =item C<struct PackFile_ByteCode *
1217 PF_create_default_segs(Interp*, const char *file_name, int add)>
1219 Create bytecode, constant, and fixup segment for C<file_nam>. If C<add>
1220 is true, the current packfile becomes the owner of these segments by
1221 adding the segments to the directory.
1227 struct PackFile_ByteCode
*
1228 PF_create_default_segs(Interp
* interp
, const char *file_name
, int add
)
1230 struct PackFile
* const pf
= interp
->initial_pf
;
1231 struct PackFile_Segment
*seg
=
1232 create_seg(interp
, &pf
->directory
,
1233 PF_BYTEC_SEG
, BYTE_CODE_SEGMENT_NAME
, file_name
, add
);
1234 struct PackFile_ByteCode
* const cur_cs
= (struct PackFile_ByteCode
*)seg
;
1236 seg
= create_seg(interp
, &pf
->directory
,
1237 PF_FIXUP_SEG
, FIXUP_TABLE_SEGMENT_NAME
, file_name
, add
);
1238 cur_cs
->fixups
= (struct PackFile_FixupTable
*)seg
;
1239 cur_cs
->fixups
->code
= cur_cs
;
1241 seg
= create_seg(interp
, &pf
->directory
,
1242 PF_CONST_SEG
, CONSTANT_SEGMENT_NAME
, file_name
, add
);
1243 cur_cs
->const_table
= (struct PackFile_ConstTable
*) seg
;
1244 cur_cs
->const_table
->code
= cur_cs
;
1246 seg
= create_seg(interp
, &pf
->directory
,
1247 PF_UNKNOWN_SEG
, "PIC_idx", file_name
, add
);
1248 cur_cs
->pic_index
= seg
;
1255 PackFile_Segment_destroy(Interp *, struct PackFile_Segment * self)>
1262 PackFile_Segment_destroy(Interp
*interp
, struct PackFile_Segment
* self
)
1264 PackFile_Segment_destroy_func_t f
=
1265 self
->pf
->PackFuncs
[self
->type
].destroy
;
1268 default_destroy(interp
, self
); /* destroy self after specific */
1274 PackFile_Segment_packed_size(Interp*, struct PackFile_Segment * self)>
1281 PackFile_Segment_packed_size(Interp
* interp
,
1282 struct PackFile_Segment
* self
)
1284 size_t size
= default_packed_size(interp
, self
);
1285 PackFile_Segment_packed_size_func_t f
=
1286 self
->pf
->PackFuncs
[self
->type
].packed_size
;
1287 const size_t align
= 16/sizeof (opcode_t
);
1289 size
+= (f
)(interp
, self
);
1290 if (align
&& size
% align
)
1291 size
+= (align
- size
% align
); /* pad/align it */
1298 PackFile_Segment_pack(Interp*, struct PackFile_Segment * self,
1306 PackFile_Segment_pack(Interp
* interp
,
1307 struct PackFile_Segment
* self
, opcode_t
*cursor
)
1309 PackFile_Segment_pack_func_t f
=
1310 self
->pf
->PackFuncs
[self
->type
].pack
;
1311 const size_t align
= 16/sizeof (opcode_t
);
1313 cursor
= default_pack(interp
, self
, cursor
);
1317 cursor
= (f
)(interp
, self
, cursor
);
1318 if (align
&& (cursor
- self
->pf
->src
) % align
)
1319 cursor
+= align
- (cursor
- self
->pf
->src
) % align
;
1326 PackFile_Segment_unpack(Interp *interp,
1327 struct PackFile_Segment * self, opcode_t *cursor)>
1329 All all these functions call the related C<default_*> function.
1331 If a special is defined this gets called after.
1338 PackFile_Segment_unpack(Interp
*interp
,
1339 struct PackFile_Segment
* self
, opcode_t
*cursor
)
1341 PackFile_Segment_unpack_func_t f
=
1342 self
->pf
->PackFuncs
[self
->type
].unpack
;
1344 cursor
= default_unpack(interp
, self
, cursor
);
1348 cursor
= (f
)(interp
, self
, cursor
);
1352 ALIGN_16(self
->pf
->src
, cursor
);
1359 PackFile_Segment_dump(Interp *interp,
1360 struct PackFile_Segment *self)>
1362 Dumps the segment C<self>.
1369 PackFile_Segment_dump(Interp
*interp
,
1370 struct PackFile_Segment
*self
)
1372 self
->pf
->PackFuncs
[self
->type
].dump(interp
, self
);
1379 =head2 Standard Directory Functions
1383 =item C<static struct PackFile_Segment *
1384 directory_new(Interp*, struct PackFile *pf, const char *name, int add)>
1386 Returns a new C<PackFile_Directory> cast as a C<PackFile_Segment>.
1392 static struct PackFile_Segment
*
1393 directory_new(Interp
* interp
, struct PackFile
*pf
,
1394 const char *name
, int add
)
1396 struct PackFile_Directory
* const dir
=
1397 mem_sys_allocate(sizeof (struct PackFile_Directory
));
1399 dir
->num_segments
= 0;
1400 dir
->segments
= NULL
;
1402 return (struct PackFile_Segment
*)dir
;
1408 directory_dump(Interp *interp,
1409 struct PackFile_Segment *self)>
1411 Dumps the directory C<self>.
1418 directory_dump(Interp
*interp
, struct PackFile_Segment
*self
)
1420 struct PackFile_Directory
* const dir
= (struct PackFile_Directory
*) self
;
1423 default_dump_header(interp
, self
);
1424 PIO_printf(interp
, "\n\t# %d segments\n", dir
->num_segments
);
1425 for (i
=0; i
< dir
->num_segments
; i
++) {
1426 struct PackFile_Segment
*seg
= dir
->segments
[i
];
1428 "\ttype %d\t%s\t", (int)seg
->type
, seg
->name
);
1430 " offs 0x%x(0x%x)\top_count %d\n",
1431 (int)seg
->file_offset
,
1432 (int)seg
->file_offset
* sizeof (opcode_t
),
1433 (int)seg
->op_count
);
1435 PIO_printf(interp
, "]\n");
1436 for (i
=0; i
< dir
->num_segments
; i
++) {
1437 struct PackFile_Segment
* const seg
= dir
->segments
[i
];
1438 PackFile_Segment_dump(interp
, seg
);
1444 =item C<static opcode_t *
1445 directory_unpack(Interp *interp,
1446 struct PackFile_Segment *segp, opcode_t * cursor)>
1448 Unpacks the directory.
1455 directory_unpack(Interp
*interp
,
1456 struct PackFile_Segment
*segp
, opcode_t
* cursor
)
1459 struct PackFile_Directory
* const dir
= (struct PackFile_Directory
*) segp
;
1460 struct PackFile
* const pf
= dir
->base
.pf
;
1463 dir
->num_segments
= PF_fetch_opcode(pf
, &cursor
);
1464 if (dir
->segments
) {
1466 mem_sys_realloc (dir
->segments
,
1467 sizeof (struct PackFile_Segment
*) *
1472 mem_sys_allocate(sizeof (struct PackFile_Segment
*) *
1476 for (i
=0; i
< dir
->num_segments
; i
++) {
1477 struct PackFile_Segment
*seg
;
1483 type
= PF_fetch_opcode(pf
, &cursor
);
1484 if (type
>= PF_MAX_SEG
)
1485 type
= PF_UNKNOWN_SEG
;
1487 PIO_eprintf(NULL
, "Segment type %d.\n", type
);
1490 name
= PF_fetch_cstring(pf
, &cursor
);
1492 PIO_eprintf(NULL
, "Segment name \"%s\".\n", name
);
1496 seg
= PackFile_Segment_new_seg(interp
, dir
, type
, name
, 0);
1499 seg
->file_offset
= PF_fetch_opcode(pf
, &cursor
);
1500 seg
->op_count
= PF_fetch_opcode(pf
, &cursor
);
1502 if (pf
->need_wordsize
) {
1503 #if OPCODE_T_SIZE == 8
1504 if (pf
->header
->wordsize
== 4)
1505 pos
= pf
->src
+ seg
->file_offset
/ 2;
1507 if (pf
->header
->wordsize
== 8)
1508 pos
= pf
->src
+ seg
->file_offset
* 2;
1511 pos
= pf
->src
+ seg
->file_offset
;
1512 tmp
= PF_fetch_opcode(pf
, &pos
);
1513 if (seg
->op_count
!= tmp
) {
1515 "%s: Size in directory %d doesn't match size %d "
1516 "at offset 0x%x\n", seg
->name
, (int)seg
->op_count
,
1517 (int)tmp
, (int)seg
->file_offset
);
1520 struct PackFile_Segment
*last
= dir
->segments
[i
-1];
1521 if (last
->file_offset
+ last
->op_count
!= seg
->file_offset
) {
1522 fprintf(stderr
, "%s: sections are not back to back\n",
1526 make_code_pointers(seg
);
1528 /* store the segment */
1529 dir
->segments
[i
] = seg
;
1533 ALIGN_16(pf
->src
, cursor
);
1534 /* and now unpack contents of dir */
1535 for (i
= 0; cursor
&& i
< dir
->num_segments
; i
++) {
1536 opcode_t
*csave
= cursor
;
1537 size_t tmp
= PF_fetch_opcode(pf
, &cursor
); /* check len again */
1538 size_t delta
= 0; /* keep gcc -O silent */
1541 pos
= PackFile_Segment_unpack(interp
, dir
->segments
[i
],
1544 fprintf(stderr
, "PackFile_unpack segment '%s' failed\n",
1545 dir
->segments
[i
]->name
);
1548 if (pf
->need_wordsize
) {
1549 #if OPCODE_T_SIZE == 8
1550 if (pf
->header
->wordsize
== 4)
1551 delta
= (pos
- cursor
) * 2;
1553 if (pf
->header
->wordsize
== 8)
1554 delta
= (pos
- cursor
) / 2;
1557 delta
= pos
- cursor
;
1558 if ((size_t)delta
!= tmp
|| dir
->segments
[i
]->op_count
!= tmp
)
1559 fprintf(stderr
, "PackFile_unpack segment '%s' directory length %d "
1560 "length in file %d needed %d for unpack\n",
1561 dir
->segments
[i
]->name
,
1562 (int)dir
->segments
[i
]->op_count
, (int)tmp
,
1572 directory_destroy(Interp*, struct PackFile_Segment *self)>
1574 Destroys the directory.
1581 directory_destroy(Interp
* interp
, struct PackFile_Segment
*self
)
1583 struct PackFile_Directory
*dir
= (struct PackFile_Directory
*)self
;
1586 for (i
= 0; i
< dir
->num_segments
; i
++) {
1587 PackFile_Segment_destroy(interp
, dir
->segments
[i
]);
1589 if (dir
->segments
) {
1590 mem_sys_free(dir
->segments
);
1591 dir
->segments
= NULL
;
1598 sort_segs(Interp*, struct PackFile_Directory *dir)>
1600 Sorts the segments in C<dir>.
1607 sort_segs(Interp
* interp
, struct PackFile_Directory
*dir
)
1609 const size_t num_segs
= dir
->num_segments
;
1611 struct PackFile_Segment
*seg
= dir
->segments
[0];
1612 if (seg
->type
!= PF_BYTEC_SEG
) {
1614 for (i
= 1; i
< num_segs
; i
++) {
1615 struct PackFile_Segment
* const s2
= dir
->segments
[i
];
1616 if (s2
->type
== PF_BYTEC_SEG
) {
1617 dir
->segments
[0] = s2
;
1618 dir
->segments
[i
] = seg
;
1623 seg
= dir
->segments
[1];
1624 if (seg
->type
!= PF_FIXUP_SEG
) {
1626 for (i
= 2; i
< num_segs
; i
++) {
1627 struct PackFile_Segment
* const s2
= dir
->segments
[i
];
1628 if (s2
->type
== PF_FIXUP_SEG
) {
1629 dir
->segments
[1] = s2
;
1630 dir
->segments
[i
] = seg
;
1639 =item C<static size_t
1640 directory_packed_size(Interp*, struct PackFile_Segment *self)>
1642 Returns the size of the directory minus the value returned by
1643 C<default_packed_size()>.
1650 directory_packed_size(Interp
* interp
, struct PackFile_Segment
*self
)
1652 struct PackFile_Directory
* const dir
= (struct PackFile_Directory
*)self
;
1653 const size_t align
= 16/sizeof (opcode_t
);
1654 size_t size
, i
, seg_size
;
1656 /* need bytecode, fixup, other segs ... */
1657 sort_segs(interp
, dir
);
1658 /* number of segments + default, we need it for the offsets */
1659 size
= 1 + default_packed_size(interp
, self
);
1660 for (i
= 0; i
< dir
->num_segments
; i
++) {
1661 size
+= 3; /* type, offset, size */
1662 size
+= PF_size_cstring(dir
->segments
[i
]->name
);
1664 if (align
&& size
% align
)
1665 size
+= (align
- size
% align
); /* pad/align it */
1666 for (i
=0; i
< dir
->num_segments
; i
++) {
1667 dir
->segments
[i
]->file_offset
= size
+ self
->file_offset
;
1668 seg_size
= PackFile_Segment_packed_size(interp
, dir
->segments
[i
]);
1669 dir
->segments
[i
]->op_count
= seg_size
;
1672 self
->op_count
= size
;
1673 /* subtract default, it is added in PackFile_Segment_packed_size */
1674 return size
- default_packed_size(interp
, self
);
1679 =item C<static opcode_t *
1680 directory_pack(Interp*, struct PackFile_Segment *self, opcode_t *cursor)>
1682 Packs the directory C<self>.
1689 directory_pack(Interp
* interp
, struct PackFile_Segment
*self
,
1692 struct PackFile_Directory
*dir
= (struct PackFile_Directory
*)self
;
1695 const size_t num_segs
= dir
->num_segments
;
1697 *cursor
++ = num_segs
;
1699 for (i
= 0; i
< num_segs
; i
++) {
1700 const struct PackFile_Segment
* const seg
= dir
->segments
[i
];
1701 *cursor
++ = seg
->type
;
1702 cursor
= PF_store_cstring(cursor
, seg
->name
);
1703 *cursor
++ = seg
->file_offset
;
1704 *cursor
++ = seg
->op_count
;
1706 align
= 16/sizeof (opcode_t
);
1707 if (align
&& (cursor
- self
->pf
->src
) % align
)
1708 cursor
+= align
- (cursor
- self
->pf
->src
) % align
;
1709 /* now pack all segments into new format */
1710 for (i
= 0; i
< dir
->num_segments
; i
++) {
1711 struct PackFile_Segment
* const seg
= dir
->segments
[i
];
1712 const size_t size
= seg
->op_count
;
1714 PackFile_Segment_pack(interp
, seg
, cursor
);
1716 * XXX somehow it's smelling fishy here:
1717 * - either cursor is unaligned
1718 * - or the return result of _pack doesn't match
1721 * likely in combination with pbc_merge
1723 * the relevant code with size check is visible in:
1725 * svn diff -r15516:15517
1737 =head2 C<PackFile_Segment> Functions
1742 segment_init(Interp*, struct PackFile_Segment *self,
1743 struct PackFile *pf,
1746 Initializes the segment C<self>.
1753 segment_init(Interp
* interp
, struct PackFile_Segment
*self
,
1754 struct PackFile
*pf
,
1758 self
->type
= PF_UNKNOWN_SEG
;
1759 self
->file_offset
= 0;
1765 self
->name
= mem_sys_allocate(strlen(name
) + 1);
1766 strcpy(self
->name
, name
);
1771 =item C<struct PackFile_Segment *
1772 PackFile_Segment_new(Interp*, struct PackFile *pf, const char *name, int add)>
1774 Create a new default section.
1780 struct PackFile_Segment
*
1781 PackFile_Segment_new(Interp
* interp
,
1782 struct PackFile
*pf
, const char *name
, int add
)
1784 struct PackFile_Segment
* const seg
=
1785 mem_sys_allocate(sizeof (struct PackFile_Segment
));
1794 =head2 Default Function Implementations
1796 The default functions are called before the segment specific functions
1797 and can read a block of C<opcode_t> data.
1802 default_destroy(Interp*, struct PackFile_Segment *self)>
1804 The default destroy function.
1811 default_destroy(Interp
* interp
, struct PackFile_Segment
*self
)
1813 if (!self
->pf
->is_mmap_ped
&& self
->data
) {
1814 mem_sys_free(self
->data
);
1818 mem_sys_free(self
->name
);
1826 =item C<static size_t
1827 default_packed_size(Interp*, struct PackFile_Segment *self)>
1829 Returns the default size of the segment C<self>.
1836 default_packed_size(Interp
* interp
, const struct PackFile_Segment
*self
)
1838 /* op_count, itype, id, size */
1839 /* XXX There should be a constant defining this 4, and why */
1840 /* This is the 2nd place in the file that has this */
1841 return 4 + self
->size
;
1846 =item C<static opcode_t *
1847 default_pack(Interp*, struct PackFile_Segment *self,
1850 Performs the default pack.
1857 default_pack(Interp
* interp
, const struct PackFile_Segment
*self
,
1860 *dest
++ = self
->op_count
;
1861 *dest
++ = self
->itype
;
1863 *dest
++ = self
->size
;
1865 memcpy(dest
, self
->data
, self
->size
* sizeof (opcode_t
));
1866 return dest
+ self
->size
;
1869 /* XXX Should be declared elsewhere */
1870 extern void Parrot_destroy_jit(void *ptr
);
1881 byte_code_destroy(Interp*, struct PackFile_Segment *self)>
1883 Destroys the C<PackFile_ByteCode> segment C<self>.
1890 byte_code_destroy(Interp
* interp
, struct PackFile_Segment
*self
)
1892 struct PackFile_ByteCode
* const byte_code
=
1893 (struct PackFile_ByteCode
*)self
;
1896 Parrot_destroy_jit(byte_code
->jit_info
);
1898 parrot_PIC_destroy(interp
, byte_code
);
1899 if (byte_code
->prederef
.code
) {
1900 Parrot_free_memalign(byte_code
->prederef
.code
);
1901 byte_code
->prederef
.code
= NULL
;
1902 if (byte_code
->prederef
.branches
) {
1903 mem_sys_free(byte_code
->prederef
.branches
);
1904 byte_code
->prederef
.branches
= NULL
;
1907 byte_code
->fixups
= NULL
;
1908 byte_code
->debugs
= NULL
;
1909 byte_code
->const_table
= NULL
;
1910 byte_code
->pic_index
= NULL
;
1915 =item C<static struct PackFile_Segment *
1916 byte_code_new(Interp*, struct PackFile *pf, const char * name, int add)>
1918 New C<PackFile_ByteCode> segment.
1920 C<pf> and C<add> are ignored.
1926 static struct PackFile_Segment
*
1927 byte_code_new(Interp
* interp
, struct PackFile
*pf
,
1928 const char * name
, int add
)
1930 struct PackFile_ByteCode
*byte_code
=
1931 mem_sys_allocate(sizeof (struct PackFile_ByteCode
));
1933 byte_code
->base
.dir
= NULL
;
1935 byte_code
->prederef
.code
= NULL
;
1936 byte_code
->prederef
.branches
= NULL
;
1937 byte_code
->prederef
.n_allocated
= 0;
1938 byte_code
->jit_info
= NULL
;
1939 byte_code
->debugs
= NULL
;
1940 byte_code
->const_table
= NULL
;
1941 byte_code
->fixups
= NULL
;
1942 byte_code
->pic_index
= NULL
;
1943 byte_code
->pic_store
= NULL
;
1944 return (struct PackFile_Segment
*) byte_code
;
1956 pf_debug_destroy(Interp*, struct PackFile_Segment *self)>
1958 Destroys the C<PackFile_Debug> segment C<self>.
1965 pf_debug_destroy(Interp
* interp
, struct PackFile_Segment
*self
)
1967 struct PackFile_Debug
* const debug
= (struct PackFile_Debug
*) self
;
1970 /* Free each mapping. */
1971 for (i
= 0; i
< debug
->num_mappings
; i
++)
1972 mem_sys_free(debug
->mappings
[i
]);
1974 /* Free mappings pointer array. */
1975 mem_sys_free(debug
->mappings
);
1976 debug
->mappings
= NULL
;
1977 debug
->num_mappings
= 0;
1982 =item C<static struct PackFile_Segment *
1983 pf_debug_new(Interp*, struct PackFile *pf, const char * name, int add)>
1985 Returns a new C<PackFile_Debug> segment.
1987 C<pf> and C<add> ignored.
1993 static struct PackFile_Segment
*
1994 pf_debug_new(Interp
* interp
, struct PackFile
*pf
,
1995 const char * name
, int add
)
1997 struct PackFile_Debug
* const debug
=
1998 mem_sys_allocate(sizeof (struct PackFile_Debug
));
2001 debug
->mappings
= mem_sys_allocate(sizeof (Parrot_Pointer
));
2002 debug
->mappings
[0] = NULL
;
2003 debug
->num_mappings
= 0;
2005 return (struct PackFile_Segment
*)debug
;
2010 =item C<static size_t
2011 pf_debug_packed_size (Interp*, struct PackFile_Segment *self)>
2013 Returns the size of the C<PackFile_Debug> segment's filename in
2021 pf_debug_packed_size(Interp
* interp
, struct PackFile_Segment
*self
)
2023 struct PackFile_Debug
* const debug
= (struct PackFile_Debug
*) self
;
2027 /* Size of mappings count. */
2030 /* Size of entries in mappings list. */
2031 for (i
= 0; i
< debug
->num_mappings
; i
++) {
2032 /* Bytecode offset and mapping type */
2035 /* Mapping specific stuff. */
2036 switch (debug
->mappings
[i
]->mapping_type
) {
2037 case PF_DEBUGMAPPINGTYPE_NONE
:
2039 case PF_DEBUGMAPPINGTYPE_FILENAME
:
2040 case PF_DEBUGMAPPINGTYPE_SOURCESEG
:
2051 =item C<static opcode_t *
2052 pf_debug_pack(Interp*, struct PackFile_Segment *self, opcode_t *cursor)>
2054 Pack the debug segment.
2061 pf_debug_pack(Interp
* interp
, struct PackFile_Segment
*self
,
2064 struct PackFile_Debug
* const debug
= (struct PackFile_Debug
*) self
;
2067 /* Store number of mappings. */
2068 *cursor
++ = debug
->num_mappings
;
2070 /* Now store each mapping. */
2071 for (i
= 0; i
< debug
->num_mappings
; i
++) {
2072 /* Bytecode offset and mapping type */
2073 *cursor
++ = debug
->mappings
[i
]->offset
;
2074 *cursor
++ = debug
->mappings
[i
]->mapping_type
;
2076 /* Mapping specific stuff. */
2077 switch (debug
->mappings
[i
]->mapping_type
) {
2078 case PF_DEBUGMAPPINGTYPE_NONE
:
2080 case PF_DEBUGMAPPINGTYPE_FILENAME
:
2081 *cursor
++ = debug
->mappings
[i
]->u
.filename
;
2083 case PF_DEBUGMAPPINGTYPE_SOURCESEG
:
2084 *cursor
++ = debug
->mappings
[i
]->u
.source_seg
;
2094 =item C<static opcode_t *
2095 pf_debug_unpack(Interp *interp,
2096 struct PackFile_Segment *self, opcode_t *cursor)>
2098 Unpack a debug segment into a PackFile_Debug structure.
2105 pf_debug_unpack(Interp
*interp
,
2106 struct PackFile_Segment
*self
, opcode_t
*cursor
)
2108 struct PackFile_Debug
* const debug
= (struct PackFile_Debug
*) self
;
2109 struct PackFile_ByteCode
*code
;
2112 /* For some reason, we store the source file name in the segment
2113 name. So we can't find the bytecode seg without knowing the filename.
2114 But with the new scheme we can have many file names. For now, just
2115 base this on the name of the debug segment. */
2116 char *code_name
= NULL
;
2119 /* Number of mappings. */
2120 debug
->num_mappings
= PF_fetch_opcode(self
->pf
, &cursor
);
2122 /* Allocate space for mappings vector. */
2123 debug
->mappings
= mem_sys_allocate(sizeof (Parrot_Pointer
) *
2124 (debug
->num_mappings
+ 1));
2126 /* Read in each mapping. */
2127 for (i
= 0; i
< debug
->num_mappings
; i
++) {
2128 /* Allocate struct and get offset and mapping type. */
2129 debug
->mappings
[i
] =
2130 mem_sys_allocate(sizeof (struct PackFile_DebugMapping
));
2131 debug
->mappings
[i
]->offset
= PF_fetch_opcode(self
->pf
, &cursor
);
2132 debug
->mappings
[i
]->mapping_type
= PF_fetch_opcode(self
->pf
, &cursor
);
2134 /* Read mapping specific stuff. */
2135 switch (debug
->mappings
[i
]->mapping_type
) {
2136 case PF_DEBUGMAPPINGTYPE_NONE
:
2138 case PF_DEBUGMAPPINGTYPE_FILENAME
:
2139 debug
->mappings
[i
]->u
.filename
=
2140 PF_fetch_opcode(self
->pf
, &cursor
);
2142 case PF_DEBUGMAPPINGTYPE_SOURCESEG
:
2143 debug
->mappings
[i
]->u
.source_seg
=
2144 PF_fetch_opcode(self
->pf
, &cursor
);
2150 * find seg e.g. CODE_DB => CODE
2153 code_name
= strdup(debug
->base
.name
);
2154 str_len
= strlen(code_name
);
2155 code_name
[str_len
- 3] = 0;
2156 code
= (struct PackFile_ByteCode
*)PackFile_find_segment(interp
,
2157 self
->dir
, code_name
, 0);
2158 if (!code
|| code
->base
.type
!= PF_BYTEC_SEG
)
2159 internal_exception(1, "Code '%s' not found for debug segment '%s'\n",
2160 code_name
, self
->name
);
2161 code
->debugs
= debug
;
2171 pf_debug_dump(Interp *interp, struct PackFile_Segment *self)>
2173 Dumps a debug segment to a human readable form.
2180 pf_debug_dump(Parrot_Interp interp
, struct PackFile_Segment
*self
)
2184 struct PackFile_Debug
* const debug
= (struct PackFile_Debug
*) self
;
2187 default_dump_header(interp
, self
);
2189 PIO_printf(interp
, "\n mappings => [\n");
2190 for (i
= 0; i
< debug
->num_mappings
; i
++) {
2191 PIO_printf(interp
, " #%d\n [\n", i
);
2192 PIO_printf(interp
, " OFFSET => %d,\n",
2193 debug
->mappings
[i
]->offset
);
2194 switch (debug
->mappings
[i
]->mapping_type
) {
2195 case PF_DEBUGMAPPINGTYPE_NONE
:
2196 PIO_printf(interp
, " MAPPINGTYPE => NONE\n");
2198 case PF_DEBUGMAPPINGTYPE_FILENAME
:
2199 PIO_printf(interp
, " MAPPINGTYPE => FILENAME,\n");
2200 filename
= string_to_cstring(interp
, PF_CONST(debug
->code
,
2201 debug
->mappings
[i
]->u
.filename
)->u
.string
);
2202 PIO_printf(interp
, " FILENAME => %s\n", filename
);
2205 case PF_DEBUGMAPPINGTYPE_SOURCESEG
:
2206 PIO_printf(interp
, " MAPPINGTYPE => SOURCESEG,\n");
2207 PIO_printf(interp
, " SOURCESEG => %d\n",
2208 debug
->mappings
[i
]->u
.source_seg
);
2211 PIO_printf(interp
, " ],\n");
2213 PIO_printf(interp
, " ]\n");
2215 j
= self
->data
? 0: self
->file_offset
+ 4;
2217 PIO_printf(interp
, "\n %04x: ", (int) j
);
2219 for ( ; j
< (self
->data
? self
->size
:
2220 self
->file_offset
+ self
->op_count
); j
++) {
2222 PIO_printf(interp
, "\n %04x: ", (int) j
);
2224 PIO_printf(interp
, "%08lx ", (unsigned long)
2225 self
->data
? self
->data
[j
] : self
->pf
->src
[j
]);
2227 PIO_printf(interp
, "\n]\n");
2232 =item C<struct PackFile_Debug *
2233 Parrot_new_debug_seg(Interp *interp,
2234 struct PackFile_ByteCode *cs, size_t size)>
2236 Create and append (or resize) a new debug seg for a code segment.
2242 struct PackFile_Debug
*
2243 Parrot_new_debug_seg(Interp
*interp
,
2244 struct PackFile_ByteCode
*cs
, size_t size
)
2246 struct PackFile_Debug
*debug
;
2248 if (cs
->debugs
) { /* it exists already, resize it */
2250 debug
->base
.data
= mem_sys_realloc(debug
->base
.data
, size
*
2253 else { /* create one */
2254 const size_t len
= strlen(cs
->base
.name
) + 4;
2255 char * const name
= mem_sys_allocate(len
);
2257 sprintf(name
, "%s_DB", cs
->base
.name
);
2258 if (interp
->code
&& interp
->code
->base
.dir
) {
2259 debug
= (struct PackFile_Debug
*)
2260 PackFile_Segment_new_seg(interp
,
2261 interp
->code
->base
.dir
, PF_DEBUG_SEG
, name
, 1);
2264 /* used by eval - don't register the segment */
2265 debug
= (struct PackFile_Debug
*)
2266 PackFile_Segment_new_seg(interp
,
2267 cs
->base
.dir
? cs
->base
.dir
:
2268 &interp
->initial_pf
->directory
,
2269 PF_DEBUG_SEG
, name
, 0);
2273 debug
->base
.data
= mem_sys_allocate(size
* sizeof (opcode_t
));
2274 debug
->num_mappings
= 0;
2275 debug
->mappings
= mem_sys_allocate(1);
2280 debug
->base
.size
= size
;
2287 Parrot_debug_add_mapping(Interp *interp,
2288 struct PackFile_Debug *debug,
2289 opcode_t offset, int mapping_type,
2290 const char *filename, int source_seg)>
2292 Add a bytecode offset to filename/source segment mapping. mapping_type may be
2293 one of PF_DEBUGMAPPINGTYPE_NONE (in which case the last two parameters are
2294 ignored), PF_DEBUGMAPPINGTYPE_FILENAME (in which case filename must be given)
2295 or PF_DEBUGMAPPINGTYPE_SOURCESEG (in which case source_seg should contains the
2296 number of the source segment in question).
2302 Parrot_debug_add_mapping(Interp
*interp
,
2303 struct PackFile_Debug
*debug
,
2304 opcode_t offset
, int mapping_type
,
2305 const char *filename
, int source_seg
)
2307 struct PackFile_DebugMapping
*mapping
;
2308 struct PackFile_ConstTable
* const ct
= debug
->code
->const_table
;
2309 struct PackFile_Constant
*fnconst
;
2312 /* Allocate space for the extra entry. */
2313 debug
->mappings
= mem_sys_realloc(debug
->mappings
,
2314 sizeof (Parrot_Pointer
) * (debug
->num_mappings
+ 1));
2316 /* Can it just go on the end? */
2317 if (debug
->num_mappings
== 0 ||
2318 offset
>= debug
->mappings
[debug
->num_mappings
- 1]->offset
)
2320 insert_pos
= debug
->num_mappings
;
2323 /* Find the right place and shift stuff that's after it. */
2325 for (i
= 0; i
< debug
->num_mappings
; i
++) {
2326 if (debug
->mappings
[i
]->offset
> offset
) {
2328 memmove(debug
->mappings
+ i
+ 1, debug
->mappings
+ i
,
2329 debug
->num_mappings
- i
);
2335 /* Set up new entry and insert it. */
2336 mapping
= mem_sys_allocate(sizeof (struct PackFile_DebugMapping
));
2337 mapping
->offset
= offset
;
2338 mapping
->mapping_type
= mapping_type
;
2339 switch (mapping_type
) {
2340 case PF_DEBUGMAPPINGTYPE_NONE
:
2342 case PF_DEBUGMAPPINGTYPE_FILENAME
:
2343 /* Need to put filename in constants table. */
2344 ct
->const_count
= ct
->const_count
+ 1;
2346 ct
->constants
= mem_sys_realloc(ct
->constants
,
2347 ct
->const_count
* sizeof (Parrot_Pointer
));
2349 ct
->constants
= mem_sys_allocate(
2350 ct
->const_count
* sizeof (Parrot_Pointer
));
2351 fnconst
= PackFile_Constant_new(interp
);
2352 fnconst
->type
= PFC_STRING
;
2353 fnconst
->u
.string
= string_make_direct(interp
, filename
,
2354 strlen(filename
), PARROT_DEFAULT_ENCODING
,
2355 PARROT_DEFAULT_CHARSET
, PObj_constant_FLAG
);
2356 ct
->constants
[ct
->const_count
- 1] = fnconst
;
2357 mapping
->u
.filename
= ct
->const_count
- 1;
2359 case PF_DEBUGMAPPINGTYPE_SOURCESEG
:
2360 mapping
->u
.source_seg
= source_seg
;
2363 debug
->mappings
[insert_pos
] = mapping
;
2364 debug
->num_mappings
= debug
->num_mappings
+ 1;
2369 Parrot_debug_pc_to_filename(Interp *interp,
2370 struct PackFile_Debug *debug, opcode_t pc)>
2372 Take a position in the bytecode and return the filename of the source for
2380 Parrot_debug_pc_to_filename(Interp
*interp
,
2381 struct PackFile_Debug
*debug
, opcode_t pc
)
2383 /* Look through mappings until we find one that maps the passed
2386 for (i
= 0; i
< debug
->num_mappings
; i
++) {
2387 /* If this is the last mapping or the current position is
2388 between this mapping and the next one, return a filename. */
2389 if (i
+ 1 == debug
->num_mappings
||
2390 (debug
->mappings
[i
]->offset
<= pc
&&
2391 debug
->mappings
[i
+1]->offset
> pc
))
2393 switch (debug
->mappings
[i
]->mapping_type
) {
2394 case PF_DEBUGMAPPINGTYPE_NONE
:
2395 return string_from_const_cstring(interp
,
2396 "(unknown file)", 0);
2397 case PF_DEBUGMAPPINGTYPE_FILENAME
:
2398 return PF_CONST(debug
->code
,
2399 debug
->mappings
[i
]->u
.filename
)->u
.string
;
2400 case PF_DEBUGMAPPINGTYPE_SOURCESEG
:
2401 return string_from_const_cstring(interp
,
2402 "(unknown file)", 0);
2407 /* Otherwise, no mappings = no filename. */
2408 return string_from_const_cstring(interp
, "(unknown file)", 0);
2414 Parrot_switch_to_cs_by_nr(Interp *interp, opcode_t seg)>
2416 Switch to byte code segment number C<seg>.
2423 Parrot_switch_to_cs_by_nr(Interp
*interp
, opcode_t seg
)
2425 struct PackFile_Directory
* const dir
= interp
->code
->base
.dir
;
2426 const size_t num_segs
= dir
->num_segments
;
2430 /* TODO make an index of code segments for faster look up */
2431 for (i
= n
= 0; i
< num_segs
; i
++) {
2432 if (dir
->segments
[i
]->type
== PF_BYTEC_SEG
) {
2434 Parrot_switch_to_cs(interp
, (struct PackFile_ByteCode
*)
2435 dir
->segments
[i
], 1);
2441 internal_exception(1, "Segment number %d not found\n", (int) seg
);
2446 =item C<struct PackFile_ByteCode *
2447 Parrot_switch_to_cs(Interp *interp,
2448 struct PackFile_ByteCode *new_cs, int really)>
2450 Switch to a byte code segment C<new_cs>, returning the old segment.
2456 struct PackFile_ByteCode
*
2457 Parrot_switch_to_cs(Interp
*interp
,
2458 struct PackFile_ByteCode
*new_cs
, int really
)
2460 struct PackFile_ByteCode
* const cur_cs
= interp
->code
;
2463 internal_exception(NO_PREV_CS
, "No code segment to switch to\n");
2465 /* compiling source code uses this function too,
2466 * which gives misleading trace messages
2468 if (really
&& Interp_trace_TEST(interp
, PARROT_TRACE_SUB_CALL_FLAG
)) {
2469 Interp
*tracer
= interp
->debugger
?
2470 interp
->debugger
: interp
;
2471 PIO_eprintf(tracer
, "*** switching to %s\n",
2474 interp
->code
= new_cs
;
2475 CONTEXT(interp
->ctx
)->constants
=
2476 really
? find_constants(interp
, new_cs
->const_table
) :
2477 new_cs
->const_table
->constants
;
2478 /* new_cs->const_table->constants; */
2479 CONTEXT(interp
->ctx
)->pred_offset
=
2480 new_cs
->base
.data
- (opcode_t
*) new_cs
->prederef
.code
;
2482 prepare_for_run(interp
);
2488 =item C<static PackFile_Constant **
2489 find_constants(Interp *interp, struct PackFile_ConstTable *ct)>
2491 Find the constant table associated with a thread. For now, we need to copy
2492 constant tables because some entries aren't really constant; e.g.
2493 subroutines need to reference namespace pointers.
2499 static struct PackFile_Constant
*
2500 clone_constant(Interp
*interp
, struct PackFile_Constant
*old_const
) {
2501 STRING
* const _sub
= interp
->vtables
[enum_class_Sub
]->whoami
;
2503 if (old_const
->type
== PFC_PMC
2504 && VTABLE_isa(interp
, old_const
->u
.key
, _sub
)) {
2505 struct PackFile_Constant
*ret
;
2508 ret
= mem_sys_allocate(sizeof (struct PackFile_Constant
));
2510 ret
->type
= old_const
->type
;
2512 old_sub
= old_const
->u
.key
;
2513 new_sub
= Parrot_thaw_constants(interp
,
2514 Parrot_freeze(interp
, old_sub
));
2516 PMC_sub(new_sub
)->seg
= PMC_sub(old_sub
)->seg
;
2517 Parrot_store_sub_in_namespace(interp
, new_sub
);
2519 ret
->u
.key
= new_sub
;
2528 static struct PackFile_Constant
**
2529 find_constants(Interp
*interp
, struct PackFile_ConstTable
*ct
) {
2530 if (!n_interpreters
|| !interp
->thread_data
||
2531 interp
->thread_data
->tid
== 0) {
2532 return ct
->constants
;
2536 struct PackFile_Constant
**new_consts
;
2538 assert(interp
->thread_data
);
2540 if (!interp
->thread_data
->const_tables
) {
2541 interp
->thread_data
->const_tables
=
2542 mem_sys_allocate(sizeof (Hash
));
2543 parrot_new_pointer_hash(interp
,
2544 &interp
->thread_data
->const_tables
);
2547 tables
= interp
->thread_data
->const_tables
;
2549 new_consts
= parrot_hash_get(interp
, tables
, ct
);
2552 /* need to construct it */
2553 struct PackFile_Constant
**old_consts
;
2555 INTVAL
const num_consts
= ct
->const_count
;
2557 old_consts
= ct
->constants
;
2559 mem_sys_allocate(sizeof (struct PackFile_Constant
*)*num_consts
);
2561 for (i
= 0; i
< num_consts
; ++i
) {
2562 new_consts
[i
] = clone_constant(interp
, old_consts
[i
]);
2565 parrot_hash_put(interp
, tables
, ct
, new_consts
);
2573 Parrot_destroy_constants(Interp
*interp
) {
2576 if (!interp
->thread_data
) {
2580 hash
= interp
->thread_data
->const_tables
;
2586 for (i
= 0; i
<= hash
->mask
; ++i
) {
2587 HashBucket
*bucket
= hash
->bi
[i
];
2589 struct PackFile_ConstTable
*const table
= bucket
->key
;
2590 struct PackFile_Constant
**const orig_consts
= table
->constants
;
2591 struct PackFile_Constant
**const consts
= bucket
->value
;
2592 INTVAL
const const_count
= table
->const_count
;
2594 for (i
= 0; i
< const_count
; ++i
) {
2595 if (consts
[i
] != orig_consts
[i
]) {
2596 mem_sys_free(consts
[i
]);
2599 mem_sys_free(consts
);
2600 bucket
= bucket
->next
;
2604 parrot_hash_destroy(interp
, hash
);
2611 =head2 PackFile FixupTable Structure Functions
2616 PackFile_FixupTable_clear(Interp *, struct PackFile_FixupTable *self)>
2618 Clear a PackFile FixupTable.
2625 PackFile_FixupTable_clear(Interp
*interp
, struct PackFile_FixupTable
*self
)
2629 PIO_eprintf(NULL
, "PackFile_FixupTable_clear: self == NULL!\n");
2633 for (i
= 0; i
< self
->fixup_count
; i
++) {
2634 switch (self
->fixups
[i
]->type
) {
2635 case enum_fixup_label
:
2636 mem_sys_free(self
->fixups
[i
]->name
);
2637 self
->fixups
[i
]->name
= NULL
;
2640 mem_sys_free(self
->fixups
[i
]);
2641 self
->fixups
[i
] = NULL
;
2644 if (self
->fixup_count
) {
2645 mem_sys_free(self
->fixups
);
2646 self
->fixups
= NULL
;
2649 self
->fixups
= NULL
;
2650 self
->fixup_count
= 0;
2658 fixup_destroy(Interp*, struct PackFile_Segment *self)>
2660 Just calls C<PackFile_FixupTable_clear()> with C<self>.
2667 fixup_destroy(Interp
* interp
, struct PackFile_Segment
*self
)
2669 struct PackFile_FixupTable
* const ft
= (struct PackFile_FixupTable
*) self
;
2670 PackFile_FixupTable_clear(interp
, ft
);
2675 =item C<static size_t
2676 fixup_packed_size(Interp*, struct PackFile_Segment *self)>
2678 I<What does this do?>
2685 fixup_packed_size(Interp
* interp
, struct PackFile_Segment
*self
)
2687 struct PackFile_FixupTable
* const ft
= (struct PackFile_FixupTable
*) self
;
2691 size
= 1; /* fixup_count */
2692 for (i
= 0; i
< ft
->fixup_count
; i
++) {
2693 size
++; /* fixup_entry type */
2694 switch (ft
->fixups
[i
]->type
) {
2695 case enum_fixup_label
:
2696 case enum_fixup_sub
:
2697 size
+= PF_size_cstring(ft
->fixups
[i
]->name
);
2698 size
++; /* offset */
2700 case enum_fixup_none
:
2703 internal_exception(1, "Unknown fixup type\n");
2712 =item C<static opcode_t *
2713 fixup_pack(Interp*, struct PackFile_Segment *self, opcode_t *cursor)>
2715 I<What does this do?>
2722 fixup_pack(Interp
* interp
, struct PackFile_Segment
*self
, opcode_t
*cursor
)
2724 struct PackFile_FixupTable
* const ft
= (struct PackFile_FixupTable
*) self
;
2727 *cursor
++ = ft
->fixup_count
;
2728 for (i
= 0; i
< ft
->fixup_count
; i
++) {
2729 *cursor
++ = (opcode_t
) ft
->fixups
[i
]->type
;
2730 switch (ft
->fixups
[i
]->type
) {
2731 case enum_fixup_label
:
2732 case enum_fixup_sub
:
2733 cursor
= PF_store_cstring(cursor
, ft
->fixups
[i
]->name
);
2734 *cursor
++ = ft
->fixups
[i
]->offset
;
2736 case enum_fixup_none
:
2739 internal_exception(1, "Unknown fixup type\n");
2748 =item C<static struct PackFile_Segment *
2749 fixup_new(Interp*, struct PackFile *pf, const char *name, int add)>
2751 Returns a new C<PackFile_FixupTable> segment.
2757 static struct PackFile_Segment
*
2758 fixup_new(Interp
* interp
, struct PackFile
*pf
, const char *name
, int add
)
2760 struct PackFile_FixupTable
* const fixup
=
2761 mem_sys_allocate(sizeof (struct PackFile_FixupTable
));
2763 fixup
->fixup_count
= 0;
2764 fixup
->fixups
= NULL
;
2765 return (struct PackFile_Segment
*) fixup
;
2770 =item C<static opcode_t *
2771 fixup_unpack(Interp *interp,
2772 struct PackFile_Segment *seg, opcode_t *cursor)>
2774 Unpack a PackFile FixupTable from a block of memory.
2776 Returns one (1) if everything is OK, else zero (0).
2783 fixup_unpack(Interp
*interp
,
2784 struct PackFile_Segment
*seg
, opcode_t
*cursor
)
2787 struct PackFile
* pf
;
2788 struct PackFile_FixupTable
* const self
= (struct PackFile_FixupTable
*)seg
;
2791 PIO_eprintf(interp
, "PackFile_FixupTable_unpack: self == NULL!\n");
2795 PackFile_FixupTable_clear(interp
, self
);
2798 self
->fixup_count
= PF_fetch_opcode(pf
, &cursor
);
2800 if (self
->fixup_count
) {
2801 self
->fixups
= mem_sys_allocate_zeroed(self
->fixup_count
*
2802 sizeof (struct PackFile_FixupEntry
*));
2804 if (!self
->fixups
) {
2806 "PackFile_FixupTable_unpack: Could not allocate "
2807 "memory for array!\n");
2808 self
->fixup_count
= 0;
2813 for (i
= 0; i
< self
->fixup_count
; i
++) {
2814 struct PackFile_FixupEntry
* const entry
=
2816 mem_sys_allocate(sizeof (struct PackFile_FixupEntry
));
2817 self
->fixups
[i
]->type
= PF_fetch_opcode(pf
, &cursor
);
2818 switch (self
->fixups
[i
]->type
) {
2819 case enum_fixup_label
:
2820 case enum_fixup_sub
:
2821 self
->fixups
[i
]->name
= PF_fetch_cstring(pf
, &cursor
);
2822 self
->fixups
[i
]->offset
= PF_fetch_opcode(pf
, &cursor
);
2824 case enum_fixup_none
:
2828 "PackFile_FixupTable_unpack: Unknown fixup type %d!\n",
2829 self
->fixups
[i
]->type
);
2839 =item C<void PackFile_FixupTable_new_entry(Interp *interp,
2840 char *label, enum_fixup_t type, opcode_t offs)>
2842 I<What does this do?>
2849 PackFile_FixupTable_new_entry(Interp
*interp
,
2850 char *label
, enum_fixup_t type
, opcode_t offs
)
2852 struct PackFile_FixupTable
*self
= interp
->code
->fixups
;
2856 self
= (struct PackFile_FixupTable
*) PackFile_Segment_new_seg(
2858 interp
->code
->base
.dir
, PF_FIXUP_SEG
,
2859 FIXUP_TABLE_SEGMENT_NAME
, 1);
2860 interp
->code
->fixups
= self
;
2861 self
->code
= interp
->code
;
2863 i
= self
->fixup_count
;
2864 self
->fixup_count
++;
2867 mem_sys_realloc(self
->fixups
, self
->fixup_count
*
2868 sizeof (struct PackFile_FixupEntry
*));
2872 mem_sys_allocate(sizeof (struct PackFile_FixupEntry
*));
2874 self
->fixups
[i
] = mem_sys_allocate(sizeof (struct PackFile_FixupEntry
));
2875 self
->fixups
[i
]->type
= type
;
2876 self
->fixups
[i
]->name
= mem_sys_allocate(strlen(label
) + 1);
2877 strcpy(self
->fixups
[i
]->name
, label
);
2878 self
->fixups
[i
]->offset
= offs
;
2879 self
->fixups
[i
]->seg
= self
->code
;
2884 =item C<static struct PackFile_FixupEntry *
2885 find_fixup(struct PackFile_FixupTable *ft, enum_fixup_t type,
2888 Finds the fix-up entry for C<name> and returns it.
2894 static struct PackFile_FixupEntry
*
2895 find_fixup(struct PackFile_FixupTable
*ft
, enum_fixup_t type
,
2899 for (i
= 0; i
< ft
->fixup_count
; i
++) {
2900 if ((enum_fixup_t
)ft
->fixups
[i
]->type
== type
&&
2901 !strcmp(ft
->fixups
[i
]->name
, name
)) {
2902 ft
->fixups
[i
]->seg
= ft
->code
;
2903 return ft
->fixups
[i
];
2911 =item C<static INTVAL
2912 find_fixup_iter(Interp*, struct PackFile_Segment *seg, void *user_data)>
2914 I<What does this do?>
2921 find_fixup_iter(Interp
* interp
, struct PackFile_Segment
*seg
,
2924 if (seg
->type
== PF_DIR_SEG
) {
2925 if (PackFile_map_segments(interp
, (struct PackFile_Directory
*)seg
,
2926 find_fixup_iter
, user_data
))
2929 else if (seg
->type
== PF_FIXUP_SEG
) {
2930 struct PackFile_FixupEntry
** const e
= user_data
;
2931 struct PackFile_FixupEntry
* const fe
= find_fixup(
2932 (struct PackFile_FixupTable
*) seg
, (*e
)->type
, (*e
)->name
);
2943 =item C<struct PackFile_FixupEntry *
2944 PackFile_find_fixup_entry(Interp *interp, enum_fixup_t type,
2947 I<What does this do?>
2953 struct PackFile_FixupEntry
*
2954 PackFile_find_fixup_entry(Interp
*interp
, enum_fixup_t type
,
2957 /* TODO make a hash of all fixups */
2958 struct PackFile_Directory
*dir
= interp
->code
->base
.dir
;
2959 struct PackFile_FixupEntry
*ep
, e
;
2965 found
= PackFile_map_segments(interp
, dir
, find_fixup_iter
,
2967 return found
? ep
: NULL
;
2974 =head2 PackFile ConstTable Structure Functions
2979 PackFile_ConstTable_clear(Interp*, struct PackFile_ConstTable *self)>
2981 Clear the C<PackFile_ConstTable> C<self>.
2988 PackFile_ConstTable_clear(Interp
* interp
, struct PackFile_ConstTable
*self
)
2992 for (i
= 0; i
< self
->const_count
; i
++) {
2993 PackFile_Constant_destroy(interp
, self
->constants
[i
]);
2994 self
->constants
[i
] = NULL
;
2997 if (self
->const_count
) {
2998 mem_sys_free(self
->constants
);
3001 self
->constants
= NULL
;
3002 self
->const_count
= 0;
3008 struct PackFile_Constant
*exec_const_table
;
3014 PackFile_ConstTable_unpack(Interp *interp,
3015 struct PackFile_Segment *seg,
3018 Unpack a PackFile ConstTable from a block of memory. The format is:
3020 opcode_t const_count
3023 Returns cursor if everything is OK, else zero (0).
3030 PackFile_ConstTable_unpack(Interp
*interp
,
3031 struct PackFile_Segment
*seg
,
3035 struct PackFile_ConstTable
* const self
= (struct PackFile_ConstTable
*)seg
;
3036 struct PackFile
* const pf
= seg
->pf
;
3038 extern int Parrot_exec_run
;
3041 PackFile_ConstTable_clear(interp
, self
);
3043 self
->const_count
= PF_fetch_opcode(pf
, &cursor
);
3047 "PackFile_ConstTable_unpack: Unpacking %ld constants\n",
3051 if (self
->const_count
== 0) {
3055 self
->constants
= mem_sys_allocate_zeroed(self
->const_count
*
3056 sizeof (struct PackFile_Constant
*));
3058 if (!self
->constants
) {
3060 "PackFile_ConstTable_unpack: Could not allocate "
3061 "memory for array!\n");
3062 self
->const_count
= 0;
3066 for (i
= 0; i
< self
->const_count
; i
++) {
3069 "PackFile_ConstTable_unpack(): Unpacking constant %ld\n", i
);
3073 if (Parrot_exec_run
)
3074 self
->constants
[i
] = &exec_const_table
[i
];
3077 self
->constants
[i
] = PackFile_Constant_new(interp
);
3079 cursor
= PackFile_Constant_unpack(interp
, self
, self
->constants
[i
],
3087 =item C<static struct PackFile_Segment *
3088 const_new(Interp*, struct PackFile *pf, const char *name, int add)>
3090 Returns a new C<PackFile_ConstTable> segment.
3096 static struct PackFile_Segment
*
3097 const_new(Interp
*interp
, struct PackFile
*pf
, const char *name
, int add
)
3099 struct PackFile_ConstTable
*const_table
;
3101 const_table
= mem_sys_allocate(sizeof (struct PackFile_ConstTable
));
3103 const_table
->const_count
= 0;
3104 const_table
->constants
= NULL
;
3106 return (struct PackFile_Segment
*)const_table
;
3112 const_destroy(Interp*, struct PackFile_Segment *self)>
3114 Destroys the C<PackFile_ConstTable> C<self>.
3121 const_destroy(Interp
*interp
, struct PackFile_Segment
*self
)
3123 struct PackFile_ConstTable
* const ct
= (struct PackFile_ConstTable
*)self
;
3125 PackFile_ConstTable_clear(interp
, ct
);
3132 =head2 PackFile Constant Structure Functions
3136 =item C<struct PackFile_Constant *
3137 PackFile_Constant_new(Interp*)>
3139 Allocate a new empty PackFile Constant.
3141 This is only here so we can make a new one and then do an unpack.
3147 struct PackFile_Constant
*
3148 PackFile_Constant_new(Interp
*interp
)
3150 struct PackFile_Constant
* const self
=
3151 mem_sys_allocate_zeroed(sizeof (struct PackFile_Constant
));
3153 self
->type
= PFC_NONE
;
3161 PackFile_Constant_destroy(Interp*, struct PackFile_Constant *self)>
3163 Delete the C<PackFile_Constant> C<self>.
3165 Don't delete C<PMC>s or C<STRING>s, they are destroyed via DOD/GC.
3172 PackFile_Constant_destroy(Interp
*interp
, struct PackFile_Constant
*self
)
3180 PackFile_Constant_pack_size(Interp*, struct PackFile_Constant *self)>
3182 Determine the size of the buffer needed in order to pack the PackFile
3183 Constant into a contiguous region of memory.
3190 PackFile_Constant_pack_size(Interp
*interp
, struct PackFile_Constant
*self
)
3196 switch (self
->type
) {
3199 packed_size
= PF_size_number();
3203 packed_size
= PF_size_string(self
->u
.string
);
3209 for (component
= self
->u
.key
; component
;
3210 component
= PMC_data(component
))
3215 component
= self
->u
.key
; /* the pmc (Sub, ...) */
3218 * TODO create either
3219 * a) a frozen_size freeze entry or
3220 * b) change packout.c so that component size isn't needed
3222 image
= Parrot_freeze(interp
, component
);
3223 packed_size
= PF_size_string(image
);
3228 "Constant_packed_size: Unrecognized type '%c'!\n",
3233 /* Tack on space for the initial type field */
3234 return packed_size
+ 1;
3240 PackFile_Constant_unpack(Interp *interp,
3241 struct PackFile_ConstTable *constt,
3242 struct PackFile_Constant *self, opcode_t *cursor)>
3244 Unpack a PackFile Constant from a block of memory. The format is:
3249 Returns cursor if everything is OK, else zero (0).
3256 PackFile_Constant_unpack(Interp
*interp
,
3257 struct PackFile_ConstTable
*constt
,
3258 struct PackFile_Constant
*self
, opcode_t
*cursor
)
3260 struct PackFile
* const pf
= constt
->base
.pf
;
3261 const opcode_t type
= PF_fetch_opcode(pf
, &cursor
);
3263 /* #define TRACE_PACKFILE 1 */
3265 PIO_eprintf(NULL
, "PackFile_Constant_unpack(): Type is %ld ('%c')...\n",
3271 self
->u
.number
= PF_fetch_number(pf
, &cursor
);
3272 self
->type
= PFC_NUMBER
;
3276 self
->u
.string
= PF_fetch_string(interp
, pf
, &cursor
);
3277 self
->type
= PFC_STRING
;
3281 cursor
= PackFile_Constant_unpack_key(interp
, constt
,
3286 cursor
= PackFile_Constant_unpack_pmc(interp
, constt
,
3291 "Constant_unpack: Unrecognized type '%c' during unpack!\n",
3301 PackFile_Constant_unpack_pmc(Interp *interp,
3302 struct PackFile_ConstTable *constt,
3303 struct PackFile_Constant *self,
3306 Unpack a constant PMC.
3313 PackFile_Constant_unpack_pmc(Interp
*interp
,
3314 struct PackFile_ConstTable
*constt
,
3315 struct PackFile_Constant
*self
,
3318 struct PackFile
* const pf
= constt
->base
.pf
;
3319 STRING
*image
, *_sub
;
3323 * thawing the PMC needs the real packfile in place
3325 struct PackFile_ByteCode
* const cs_save
= interp
->code
;
3326 interp
->code
= pf
->cur_cs
;
3328 image
= PF_fetch_string(interp
, pf
, &cursor
);
3330 * TODO use thaw_constants
3331 * current issue: a constant Sub with attached properties
3332 * doesn't DOD mark the properties
3333 * for a constant PMC *all* contents have to be in the constant pools
3335 pmc
= Parrot_thaw(interp
, image
);
3337 * place item in const_table
3339 self
->type
= PFC_PMC
;
3342 _sub
= const_string(interp
, "Sub"); /* CONST_STRING */
3343 if (VTABLE_isa(interp
, pmc
, _sub
)) {
3345 * finally place the sub into some namespace stash
3346 * XXX place this code in Sub.thaw ?
3348 Parrot_store_sub_in_namespace(interp
, pmc
);
3353 interp
->code
= cs_save
;
3360 PackFile_Constant_unpack_key(Interp *interp,
3361 struct PackFile_ConstTable *constt,
3362 struct PackFile_Constant *self,
3365 Unpack a PackFile Constant from a block of memory. The format consists
3366 of a sequence of key atoms, each with the following format:
3371 Returns cursor if everything is OK, else zero (0).
3378 PackFile_Constant_unpack_key(Interp
*interp
,
3379 struct PackFile_ConstTable
*constt
,
3380 struct PackFile_Constant
*self
,
3385 opcode_t type
, op
, slice_bits
;
3386 struct PackFile
* const pf
= constt
->base
.pf
;
3387 int pmc_enum
= enum_class_Key
;
3389 INTVAL components
= (INTVAL
)PF_fetch_opcode(pf
, &cursor
);
3392 while (components
-- > 0) {
3393 type
= PF_fetch_opcode(pf
, &cursor
);
3394 slice_bits
= type
& PF_VT_SLICE_BITS
;
3395 type
&= ~PF_VT_SLICE_BITS
;
3396 if (!head
&& slice_bits
) {
3397 pmc_enum
= enum_class_Slice
;
3401 = constant_pmc_new_noinit(interp
, pmc_enum
);
3402 tail
= PMC_data(tail
);
3405 head
= tail
= constant_pmc_new_noinit(interp
, pmc_enum
);
3408 VTABLE_init(interp
, tail
);
3410 op
= PF_fetch_opcode(pf
, &cursor
);
3413 key_set_integer(interp
, tail
, op
);
3416 key_set_number(interp
, tail
, constt
->constants
[op
]->u
.number
);
3419 key_set_string(interp
, tail
, constt
->constants
[op
]->u
.string
);
3422 key_set_register(interp
, tail
, op
, KEY_integer_FLAG
);
3425 key_set_register(interp
, tail
, op
, KEY_number_FLAG
);
3428 key_set_register(interp
, tail
, op
, KEY_string_FLAG
);
3431 key_set_register(interp
, tail
, op
, KEY_pmc_FLAG
);
3437 if (slice_bits
& PF_VT_START_SLICE
)
3438 PObj_get_FLAGS(tail
) |= KEY_start_slice_FLAG
;
3439 if (slice_bits
& PF_VT_END_SLICE
)
3440 PObj_get_FLAGS(tail
) |= KEY_end_slice_FLAG
;
3441 if (slice_bits
& (PF_VT_START_ZERO
| PF_VT_END_INF
))
3442 PObj_get_FLAGS(tail
) |= KEY_inf_slice_FLAG
;
3446 self
->type
= PFC_KEY
;
3454 =item C<static struct PackFile *
3455 PackFile_append_pbc(Interp *interp, const char *filename)>
3457 Read a PBC and append it to the current directory
3458 Fixup sub addresses in newly loaded bytecode and run :load subs.
3464 static struct PackFile
*
3465 PackFile_append_pbc(Interp
*interp
, const char *filename
)
3467 struct PackFile
* const pf
= Parrot_readbc(interp
, filename
);
3470 PackFile_add_segment(interp
, &interp
->initial_pf
->directory
,
3471 &pf
->directory
.base
);
3472 do_sub_pragmas(interp
, pf
->cur_cs
, PBC_LOADED
, NULL
);
3479 Parrot_load_bytecode(Interp *interp, STRING *filename)>
3481 Load and append a bytecode, IMC or PASM file into interpreter.
3483 Load some bytecode (PASM, PIR, PBC ...) and append it to the current
3491 * intermediate hook during changes
3493 /* XXX Declare this elsewhere */
3494 void * IMCC_compile_file(Parrot_Interp interp
, const char *s
);
3497 Parrot_load_bytecode(Interp
*interp
, STRING
*file_str
)
3500 STRING
*wo_ext
, *ext
, *pbc
, *path
;
3501 enum_runtime_ft file_type
;
3502 PMC
*is_loaded_hash
;
3504 parrot_split_path_ext(interp
, file_str
, &wo_ext
, &ext
);
3505 /* check if wo_ext is loaded */
3506 is_loaded_hash
= VTABLE_get_pmc_keyed_int(interp
,
3507 interp
->iglobals
, IGLOBALS_PBC_LIBS
);
3508 if (VTABLE_exists_keyed_str(interp
, is_loaded_hash
, wo_ext
))
3510 pbc
= const_string(interp
, "pbc");
3511 if (string_equal(interp
, ext
, pbc
) == 0)
3512 file_type
= PARROT_RUNTIME_FT_PBC
;
3514 file_type
= PARROT_RUNTIME_FT_SOURCE
;
3516 path
= Parrot_locate_runtime_file_str(interp
, file_str
, file_type
);
3518 real_exception(interp
, NULL
, E_LibraryNotLoadedError
,
3519 "Couldn't find file '%Ss'", file_str
);
3522 /* remember wo_ext => full_path mapping */
3523 VTABLE_set_string_keyed_str(interp
, is_loaded_hash
,
3525 filename
= string_to_cstring(interp
, path
);
3526 if ( file_type
== PARROT_RUNTIME_FT_PBC
) {
3527 PackFile_append_pbc(interp
, filename
);
3531 struct PackFile_ByteCode
* const cs
= IMCC_compile_file_s(interp
,
3534 do_sub_pragmas(interp
, cs
, PBC_LOADED
, NULL
);
3537 real_exception(interp
, NULL
, E_LibraryNotLoadedError
,
3538 "compiler returned NULL ByteCode '%Ss' - %Ss", file_str
, err
);
3540 string_cstring_free(filename
);
3546 PackFile_fixup_subs(Interp *interp, pbc_action_enum_t what, PMC *eval)>
3548 Run :load or :immediate subroutines for the current code segment.
3549 If C<eval> is given, set this is the owner of the subroutines.
3556 PackFile_fixup_subs(Interp
*interp
, pbc_action_enum_t what
, PMC
*eval
)
3558 do_sub_pragmas(interp
, interp
->code
, what
, eval
);
3567 Rework by Melvin; new bytecode format, make bytecode portable. (Do
3568 endian conversion and wordsize transforms on the fly.)
3570 leo applied and modified Juergen Boemmels packfile patch giving an
3571 extensible packfile format with directory reworked again, with common
3572 chunks (C<default_*>).
3574 2003.11.21 leo: moved low level item fetch routines to new
3584 * c-file-style: "parrot"
3586 * vim: expandtab shiftwidth=4: