# New Ticket Created by Leopold Toetsch # Please include the string: [perl #17193] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=17193 >
Here is a patch, that is selfcontained in packfile.c, so should be useful for other potential users of packout.c in the future: - It's ugly - It works(tm) [1] Please apply. When the masters of KEY find a better solution, I will gladly toss this patch, but for now it's necessary to allow imcc to write .pbc files. I wrote: > imcc (0.0.9) has an integrated parrot interpreter and tries to write out > a PBC file too. Running code succeeds currently for ~95 % of perl6 > tests (in half the time ;-). > > But I've problems in writing out the .pbc, especially Const_Table, type > PFC_KEY / PARROT_ARG_SC (and _NC if one would use these). > > The problem seems to be, that all other key types can be looked up by > key.cache->int_val, but not _SC and _NC as there value is the contents > of another string or number constant. > > So packing a packfile seems not to be reversible. > > I see currently 3 possible ways to workaround this problem: > > 1) make another indirection in reading an _SC or _NC key, so that > key.cache->int_val is the index into the constant table and not the > string_val or the num_val itself. > > 2) don't use ->data as the key->next pointer but some structure > data -> { int idx, PMC *next } and store the constant index there. > > 3) > The easierst solution (for me): provide the possibility to call a > callback, that fills the packed structure with the required data. > Actually I have also this packed data, because on building the keys I > assemble this packed data, which on PackFile_Constant_unpack_key() > generates all the PMCs for runtime. > > 1) and 2) would be a general solution but require a major rewrite of key > functions / access and have drawback for speed / memory usage. > > 3) is "if you want to packout _SC keys, do it yourself" ;-) > 4) and this patch: search in the constant_table :-( > Comments welcome, Still, leo [1] imcc compiled PBC files of all perl6 tests ran through parrot give the same test results as the assembler.pl versions, i.e. succeed except 8_5. -- attachment 1 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/37291/30229/6a904c/packout.c.diff
--- packout.c Wed Aug 21 14:03:56 2002 +++ /home/lt/src/parrot-leo/packout.c Thu Sep 12 15:22:42 2002 @@ -178,6 +178,7 @@ NOTE: The memory block had better have at least the amount of memory indicated by PackFile_ConstTable_pack_size()! ***************************************/ +static struct PackFile_ConstTable *ct; void PackFile_ConstTable_pack(struct PackFile *packfile, @@ -192,6 +193,7 @@ } cursor = packed; + ct = self; *cursor = self->const_count; cursor++; @@ -206,6 +208,23 @@ return; } +/* this is really ugly, we don't know where our PARROT_ARG_SC + * key constant is in constant table, + * so we search for it @§$& + */ +static int find_in_const(PMC *key, int type) +{ + int i; + for (i = 0 ; i < ct->const_count; i++) + if (type == PFC_STRING && ct->constants[i]->string == + key->cache.string_val) + return i; + else if (type == PFC_NUMBER && ct->constants[i]->number == + key->cache.num_val) + return i; + fprintf(stderr, "find_in_const: couldn't find const for key\n"); + exit(1); +} /*************************************** Pack a PackFile Constant into a contiguous region of memory. NOTE: The memory block had better have at least the amount of memory indicated by @@ -223,6 +242,7 @@ size_t i; opcode_t padded_size; opcode_t packed_size; + struct PMC *key; if (!self) { /* TODO: OK to be silent here? */ @@ -260,7 +280,8 @@ padded_size = self->string->bufused; if (padded_size % sizeof(opcode_t)) { - padded_size += sizeof(opcode_t) - (padded_size % sizeof(opcode_t)); + padded_size += sizeof(opcode_t) - + (padded_size % sizeof(opcode_t)); } /* Include space for flags, encoding, type, and size fields. */ @@ -298,8 +319,60 @@ */ break; + case PFC_KEY: + packed_size = sizeof(opcode_t); + for (i = 0, key = self->key; key; key = key->data, i++) + packed_size += 2 * sizeof(opcode_t); + /* size */ + *cursor++ = packed_size; + /* number of key components */ + *cursor++ = i; + /* and now type / value per component */ + for (key = self->key; key; key = key->data) { + switch (key->flags & KEY_type_FLAGS) { + case KEY_integer_FLAG: + *cursor++ = PARROT_ARG_IC; + *cursor++ = key->cache.int_val; + break; + case KEY_number_FLAG: + *cursor++ = PARROT_ARG_NC; + *cursor++ = find_in_const(key, PFC_NUMBER); /* Argh */ + break; + case KEY_string_FLAG: + *cursor++ = PARROT_ARG_SC; + *cursor++ = find_in_const(key, PFC_STRING);/* Argh */ + break; + + case KEY_integer_FLAG | KEY_register_FLAG: + *cursor++ = PARROT_ARG_I; + *cursor++ = key->cache.int_val; + break; + case KEY_number_FLAG | KEY_register_FLAG: + *cursor++ = PARROT_ARG_N; + *cursor++ = key->cache.int_val; + break; + case KEY_string_FLAG | KEY_register_FLAG: + *cursor++ = PARROT_ARG_S; + *cursor++ = key->cache.int_val; + break; + case KEY_pmc_FLAG | KEY_register_FLAG: + *cursor++ = PARROT_ARG_P; + *cursor++ = key->cache.int_val; + break; + default: + fprintf(stderr, "PackFile_Constant_pack: " + "unsupported constant type\n"); + exit(1); + } + } + + break; + default: /* TODO: OK to be silent here? */ + /* ARGH, don't be silent -lt */ + fprintf(stderr, "PackFile_Constant_pack: unsupported constant\n"); + exit(1); break; }