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