# New Ticket Created by Leopold Toetsch
# Please include the string: [perl #20584]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=20584 >
This is a first try to solve the packfile wordsize issues.
Could people with 64 bit machines please test this.
Also committing some test files to t/native_pbc would be appreciated.
TIA,
leo
-- attachment 1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/49836/38410/a8b2d5/packfile5.patch
--- parrot/include/parrot/packfile.h Tue Jan 28 10:21:49 2003
+++ parrot-leo/include/parrot/packfile.h Tue Jan 28 12:56:08 2003
@@ -319,11 +319,13 @@
opcode_t * PackFile_Constant_unpack_key(struct Parrot_Interp *interpreter,
struct PackFile * pf, struct PackFile_Constant *, opcode_t * packed);
-opcode_t PackFile_fetch_op(struct PackFile *pf, opcode_t *stream);
+opcode_t PackFile_fetch_op(struct PackFile *pf, opcode_t **stream);
-INTVAL PackFile_fetch_iv(struct PackFile *pf, opcode_t *stream);
+INTVAL PackFile_fetch_iv(struct PackFile *pf, opcode_t **stream);
FLOATVAL PackFile_fetch_nv(struct PackFile *pf, opcode_t **stream);
+
+char * PackFile_fetch_cstring(struct PackFile *pf, opcode_t **stream);
void PackFile_assign_transforms(struct PackFile *pf);
--- parrot/packfile.c Tue Jan 28 10:21:48 2003
+++ parrot-leo/packfile.c Tue Jan 28 14:26:02 2003
@@ -95,13 +95,16 @@
***************************************/
opcode_t
-PackFile_fetch_op(struct PackFile *pf, opcode_t *stream) {
- if(pf->fetch_op == NULL)
- return *stream;
+PackFile_fetch_op(struct PackFile *pf, opcode_t **stream) {
+ opcode_t o;
+ if (!pf->fetch_op)
+ return *(*stream)++;
#if TRACE_PACKFILE == 2
PIO_eprintf(NULL, "PackFile_fetch_op: Reordering.\n");
#endif
- return (pf->fetch_op)(*stream);
+ o = (pf->fetch_op)(**stream);
+ ((unsigned char *) (*stream)) += pf->header->wordsize;
+ return o;
}
/***************************************
@@ -116,10 +119,12 @@
***************************************/
INTVAL
-PackFile_fetch_iv(struct PackFile *pf, opcode_t *stream) {
+PackFile_fetch_iv(struct PackFile *pf, opcode_t **stream) {
if(pf->fetch_iv == NULL)
- return *stream;
- return (pf->fetch_iv)(*stream);
+ return *(*stream++);
+ PIO_eprintf(NULL, "PackFile_fetch_iv: Unsupported.\n");
+ exit(1);
+ return (pf->fetch_iv)(**stream);
}
/***************************************
@@ -142,7 +147,7 @@
FLOATVAL f;
HUGEFLOATVAL g;
double d;
- if(pf->fetch_nv == NULL) {
+ if (!pf->fetch_nv) {
#if TRACE_PACKFILE
PIO_eprintf(NULL, "PackFile_fetch_nv: Native [%d bytes]..\n",
sizeof(FLOATVAL));
@@ -171,14 +176,52 @@
return f;
}
+static opcode_t
+fetch_op_mixed(opcode_t b)
+{
+ union {
+ unsigned char buf[8];
+ opcode_t o1;
+ opcode_t o2;
+ } u;
+ opcode_t o;
+
+#if PARROT_BIGENDIAN
+# if OPCODE_T_SIZE == 4
+ /* wordsize = 8 then */
+ fetch_buf_le_8(u.buf, (unsigned char *) b);
+ return u.o2; /* or u.o1 */
+# else
+ o = fetch_op_le(b); /* or fetch_be_le_4 and convert? */
+ return o >> 32; /* or o & 0xffffffff */
+# endif
+#else
+# if OPCODE_T_SIZE == 4
+ /* wordsize = 8 then */
+ fetch_buf_be_8(u.buf, (unsigned char *) b);
+ return u.o1; /* or u.o2 */
+# else
+ o = fetch_op_be(b);
+ return o & 0xffffffff;
+# endif
+
+#endif
+}
/*
* Assign transform functions to vtable
*/
-void PackFile_assign_transforms(struct PackFile *pf) {
+void
+PackFile_assign_transforms(struct PackFile *pf) {
#if PARROT_BIGENDIAN
if(pf->header->byteorder != PARROT_BIGENDIAN) {
pf->need_endianize = 1;
+ if (pf->header->wordsize == sizeof(opcode_t))
pf->fetch_op = fetch_op_le;
+ else {
+ pf->need_wordsize = 1;
+ pf->fetch_op = fetch_op_mixed;
+ }
+
pf->fetch_iv = fetch_iv_le;
if (pf->header->floattype == 0)
pf->fetch_nv = fetch_buf_le_8;
@@ -188,7 +231,13 @@
#else
if(pf->header->byteorder != PARROT_BIGENDIAN) {
pf->need_endianize = 1;
+ if (pf->header->wordsize == sizeof(opcode_t)) {
pf->fetch_op = fetch_op_be;
+ }
+ else {
+ pf->need_wordsize = 1;
+ pf->fetch_op = fetch_op_mixed;
+ }
pf->fetch_iv = fetch_iv_be;
if (pf->header->floattype == 0)
pf->fetch_nv = fetch_buf_be_8;
@@ -201,12 +250,16 @@
else if (NUMVAL_SIZE != 8 && pf->header->floattype == 0)
pf->fetch_nv = fetch_buf_le_8;
/* XXX else */
+ }
# if TRACE_PACKFILE
PIO_eprintf(NULL, "header->byteorder [%d] native byteorder [%d]\n",
pf->header->byteorder, PARROT_BIGENDIAN);
# endif
- }
#endif
+ if (pf->header->wordsize != sizeof(opcode_t)) {
+ pf->need_wordsize = 1;
+ pf->fetch_op = fetch_op_mixed;
+ }
}
/***************************************
@@ -370,7 +423,7 @@
/*
* Unpack and verify the magic which is stored byteorder of the file:
*/
- header->magic = PackFile_fetch_op(self, cursor++);
+ header->magic = PackFile_fetch_op(self, &cursor);
/*
* The magic and opcodetype fields are in native byteorder.
@@ -384,7 +437,7 @@
return 0;
}
- header->opcodetype = PackFile_fetch_op(self, cursor++);
+ header->opcodetype = PackFile_fetch_op(self, &cursor);
#if TRACE_PACKFILE
PIO_eprintf(NULL, "PackFile_unpack(): Magic verified.\n");
@@ -394,7 +447,7 @@
* Unpack the Fixup Table Segment:
*/
- header->dir_format = PackFile_fetch_op(self, cursor++);
+ header->dir_format = PackFile_fetch_op(self, &cursor);
/* old compat mode for assemble.pl */
if (header->dir_format == 0) {
@@ -402,7 +455,7 @@
/*
* Unpack the Constant Table Segment:
*/
- header->const_ss = PackFile_fetch_op(self, cursor++);
+ header->const_ss = PackFile_fetch_op(self, &cursor);
self->const_table->base.op_count = header->const_ss /
sizeof(opcode_t);
if (!PackFile_check_segment_size(header->const_ss,
@@ -426,7 +479,7 @@
* PackFile new did generate already a default code segment
*/
- header->bytecode_ss = PackFile_fetch_op(self, cursor++);
+ header->bytecode_ss = PackFile_fetch_op(self, &cursor);
if (!PackFile_check_segment_size(header->bytecode_ss,
"bytecode")) {
@@ -445,10 +498,10 @@
(int)header->dir_format);
return 0;
}
- cursor++; /* pad */
+ (void)PackFile_fetch_op(self, &cursor); /* pad */
self->directory->base.file_offset = (size_t)(cursor - self->src);
- cursor = PackFile_Segment_unpack(interpreter, (struct PackFile_Segment *)
- self->directory, cursor);
+ cursor = PackFile_Segment_unpack(interpreter,
+ (struct PackFile_Segment *) self->directory, cursor);
}
self->byte_code = self->cur_cs->base.data;
self->byte_code_size = self->cur_cs->base.size * sizeof(opcode_t);
@@ -662,10 +715,10 @@
struct PackFile_Segment *self, opcode_t *cursor)
{
if (self->pf->header->dir_format) {
- self->op_count = PackFile_fetch_op(self->pf, cursor++);
- self->itype = PackFile_fetch_op(self->pf, cursor++);
- self->id = PackFile_fetch_op(self->pf, cursor++);
- self->size = PackFile_fetch_op(self->pf, cursor++);
+ self->op_count = PackFile_fetch_op(self->pf, &cursor);
+ self->itype = PackFile_fetch_op(self->pf, &cursor);
+ self->id = PackFile_fetch_op(self->pf, &cursor);
+ self->size = PackFile_fetch_op(self->pf, &cursor);
}
if (self->size == 0)
return cursor;
@@ -696,7 +749,7 @@
else {
int i;
for(i = 0; i < (int)self->size ; i++) {
- self->data[i] = PackFile_fetch_op(self->pf, cursor++);
+ self->data[i] = PackFile_fetch_op(self->pf, &cursor);
#if TRACE_PACKFILE
PIO_eprintf(NULL, "op[%u]->[%u]\n", *(cursor-1),
self->data[i]);
@@ -928,8 +981,9 @@
size_t i;
struct PackFile_Directory *dir = (struct PackFile_Directory *) segp;
struct PackFile * self = dir->base.pf;
+ opcode_t *pos;
- dir->num_segments = PackFile_fetch_op (self, cursor++);
+ dir->num_segments = PackFile_fetch_op (self, &cursor);
dir->segments = mem_sys_realloc (dir->segments,
sizeof(struct PackFile_Segment *) * dir->num_segments);
@@ -939,7 +993,7 @@
size_t tmp;
UINTVAL type;
const char *name;
- type = PackFile_fetch_op (self, cursor++);
+ type = PackFile_fetch_op (self, &cursor);
/* get name */
str_len = strlen ((char *)cursor) + 1;
name = (char *)cursor;
@@ -969,10 +1023,11 @@
break;
}
- seg->file_offset = PackFile_fetch_iv(self, cursor++);
- seg->op_count = PackFile_fetch_op(self, cursor++);
+ seg->file_offset = PackFile_fetch_op(self, &cursor);
+ seg->op_count = PackFile_fetch_op(self, &cursor);
- tmp = PackFile_fetch_op (self, self->src + seg->file_offset);
+ pos = self->src + seg->file_offset;
+ tmp = PackFile_fetch_op (self, &pos);
if (seg->op_count != tmp) {
fprintf (stderr,
"%s: Size in directory (%d) doesn't match size "
@@ -994,7 +1049,6 @@
cursor += 4 - (cursor - self->src) % 4;
/* and now unpack contents of dir */
for (i = 0; cursor && i < dir->num_segments; i++) {
- opcode_t *pos;
size_t tmp = *cursor; /* check len again */
pos = PackFile_Segment_unpack (interpreter, dir->segments[i],
cursor);
@@ -1500,7 +1554,7 @@
PackFile_FixupTable_clear(self);
pf = self->base.pf;
- self->fixup_count = PackFile_fetch_op(pf, cursor++);
+ self->fixup_count = PackFile_fetch_op(pf, &cursor);
if (self->fixup_count) {
self->fixups = mem_sys_allocate_zeroed(self->fixup_count *
@@ -1517,12 +1571,12 @@
for (i = 0; i < self->fixup_count; i++) {
self->fixups[i] = mem_sys_allocate(sizeof(struct PackFile_FixupEntry));
- self->fixups[i]->type = PackFile_fetch_op(pf, cursor++);
+ self->fixups[i]->type = PackFile_fetch_op(pf, &cursor);
switch (self->fixups[i]->type) {
case 0:
self->fixups[i]->u.t0.code_seg =
- PackFile_fetch_op(pf, cursor++);
- self->fixups[i]->u.t0.offset = PackFile_fetch_op(pf, cursor++);
+ PackFile_fetch_op(pf, &cursor);
+ self->fixups[i]->u.t0.offset = PackFile_fetch_op(pf, &cursor);
break;
default:
PIO_eprintf(interpreter,
@@ -1618,7 +1672,7 @@
PackFile_ConstTable_clear(self);
- self->const_count = PackFile_fetch_op(pf, cursor++);
+ self->const_count = PackFile_fetch_op(pf, &cursor);
#if TRACE_PACKFILE
PIO_eprintf(interpreter,
@@ -1799,8 +1853,8 @@
opcode_t type;
opcode_t size;
- type = PackFile_fetch_op(pf, cursor++);
- size = PackFile_fetch_op(pf, cursor++);
+ type = PackFile_fetch_op(pf, &cursor);
+ size = PackFile_fetch_op(pf, &cursor);
#if TRACE_PACKFILE
PIO_eprintf(NULL, "PackFile_Constant_unpack(): Type is %ld ('%c')...\n",
@@ -1908,12 +1962,12 @@
size_t size;
/* don't let PBC mess our internals */
- flags = 0 ; cursor++;
- encoding = PackFile_fetch_op(pf, cursor++);
- type = PackFile_fetch_op(pf, cursor++);
+ flags = 0; (void)PackFile_fetch_op(pf, &cursor);
+ encoding = PackFile_fetch_op(pf, &cursor);
+ type = PackFile_fetch_op(pf, &cursor);
/* These may need to be separate */
- size = (size_t)PackFile_fetch_op(pf, cursor++);
+ size = (size_t)PackFile_fetch_op(pf, &cursor);
#if TRACE_PACKFILE
PIO_eprintf(NULL, "Constant_unpack_string(): flags are 0x%04x...\n", flags);
@@ -1959,8 +2013,9 @@
INTVAL components;
PMC *head;
PMC *tail;
+ opcode_t type, op;
- components = *cursor++;
+ components = (INTVAL)PackFile_fetch_op(pf, &cursor);
head = tail = NULL;
while (components-- > 0) {
@@ -1974,29 +2029,31 @@
tail->vtable->init(interpreter, tail);
- switch (*cursor++) {
+ type = PackFile_fetch_op(pf, &cursor);
+ op = PackFile_fetch_op(pf, &cursor);
+ switch (type) {
case PARROT_ARG_IC:
- key_set_integer(interpreter, tail, *cursor++);
+ key_set_integer(interpreter, tail, op);
break;
case PARROT_ARG_NC:
key_set_number(interpreter, tail,
- pf->const_table->constants[*cursor++]->u.number);
+ pf->const_table->constants[op]->u.number);
break;
case PARROT_ARG_SC:
key_set_string(interpreter, tail,
- pf->const_table->constants[*cursor++]->u.string);
+ pf->const_table->constants[op]->u.string);
break;
case PARROT_ARG_I:
- key_set_register(interpreter, tail, *cursor++, KEY_integer_FLAG);
+ key_set_register(interpreter, tail, op, KEY_integer_FLAG);
break;
case PARROT_ARG_N:
- key_set_register(interpreter, tail, *cursor++, KEY_number_FLAG);
+ key_set_register(interpreter, tail, op, KEY_number_FLAG);
break;
case PARROT_ARG_S:
- key_set_register(interpreter, tail, *cursor++, KEY_string_FLAG);
+ key_set_register(interpreter, tail, op, KEY_string_FLAG);
break;
case PARROT_ARG_P:
- key_set_register(interpreter, tail, *cursor++, KEY_pmc_FLAG);
+ key_set_register(interpreter, tail, op, KEY_pmc_FLAG);
break;
default:
return 0;