# 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;

Reply via email to