2. Proposal for _keyed opcodes ------------------------------ The thread with subject "pdd06_pasm, pdd08_keys: _keyed ops" clearly showes the shortcomings of the current _keyed opcodes and the implementation of these.[1]
My first proposal WRT a solution (modifying the run loop) did not earn much consent and when looking closer at JIT, I have to admit, that it seems rather impractical, or, when implemented might have bad influence on JIT execution times. So here is another possible solution: The current opcode: set_n_p_ki will translate into 2 opcodes: key_p_p_ki [2] set_n_p The 3 operand keyed add @a[$i] = @b[3] + %h{"k"}: add_p_ki_p_kic_p_kc (which we don't have) would be 4 ops key_p_p_ki [3] key_p_p_kic key_p_p_kc add_p_p_p So a keyed access would have a "key_" opcode, fetching a value pointer out of the aggregate, and a plain operation working on these values. Some thoughts on implementation ------------------------------- The assembler respectively imcc would generate this op sequence for the current bracketed keyed syntax. assembler.pl could reserve e.g. P29-P31 for the usage in one key sequence, imcc does dynamic register allocation anyway. [2] PerlHash stores a HASH_ENTRY (a "UnionVal", with a type), a PerlArray uses a "PMC *" entry for its data, MultiArray uses a different UnionVal based store. The UnionVal allowes for a compact storage of primitive types, while a PMC is more efficient for PMC types and a universal pointer. As a HASH_ENTRY stores the data type of the value, it would be possible to optimize above keyed set to: key_n_p_ki set_n_n ... with the drawback of some more opcodes. If the used types are known at compile time, imcc could optimize Binops too, to use native types. For LHS usage, we need a pointer into the aggregates storage, so we use a PMC anyway. [3] For LHS usage of compound keys (@a[$b][1] = ..), we might need a special opcode, if we should autovivify the intermediate aggregate. And finally: the stores must not move, while we are operating on the value PMCs. Comments welcome, leo [1] Current state and restrictions ---------------------------------- Looking from HL (perl6;-) down to the inyards of parrot, we have e.g.: $n = @a[$i]; # assuming native types which translates to PASM: set N0, P0[I0] giving an opcode: set_n_p_ki which calls get_number_keyed_int(...) on the perlarray PMC, returning directly the stored "num" from array. Now we have functions returning STRING, number, int and additionally two versions of these, one taking a KEY and the second (optimized) version taking directly an integer array index. Implementing e.g. @æ[$i] = $j + @b[$k] would need a "add_keyed_int()" function for perlint, swapping arguments would imply for perlarray to have such a function and so on. Now pdd06_pasm states, that all operations might have 3 keys, so we would end up with basically 64 times the opcodes, we have now, because each keyed access in the 3 operands has 4 possible types of keys (_k,_ki,_kic,_kc).