Dan Sugalski <[EMAIL PROTECTED]> wrote: > Okay, we've a long-running discussion between Leo and I about the > keyed variants for all the binary vtable entries.
Another long running discussion: do we need duplicate mmd tables. Here is a proof of concept to avoid it: #v+ --- parrot/src/mmd.c Thu Apr 29 07:49:31 2004 +++ parrot-leo/src/mmd.c Thu Apr 29 15:40:58 2004 @@ -81,14 +81,21 @@ right_type + left_type; real_function = (pmc_mmd_f)*(interpreter->binop_mmd_funcs->mmd_funcs[function] + offset); } - if (real_function) { + if ((UINTVAL)real_function & 1) { + sub = (PMC*)((UINTVAL)real_function & ~1); + Parrot_runops_fromc_args_save(interpreter, sub, "vPPP", + left, right, dest); + } + else (*real_function)(interpreter, left, right, dest); +#if 0 } else { /* Didn't find it. Go look for a bytecode version */ offset = interpreter->binop_mmd_funcs->x[function] * right_type + left_type; sub = (void*)((pmc_mmd_f)*(interpreter->bytecode_binop_mmd_funcs->mmd_funcs[function] + offset)); } +#endif } /* @@ -473,6 +480,16 @@ offset = interpreter->binop_mmd_funcs->x[type] * right_type + left_type; *(interpreter->binop_mmd_funcs->mmd_funcs[type] + offset) = funcptr; +} + +void +mmd_register_sub(Interp *interpreter, + INTVAL type, + INTVAL left_type, INTVAL right_type, + PMC *sub) +{ + PMC *fake = (PMC*)((UINTVAL) sub | 1); + mmd_register(interpreter, type, left_type, right_type, D2FPTR(fake)); } /* #v- This wouldn't really slow down MMD in C. The current if(func) isn't really necessary as empty slots are filled with the default function ptr. I don't think that we need a (23 * 56 * 56 * 4 + some bytes) table duplication (this is for current types only ...). .sub _main .include "pmctypes.pasm" .include "vtable_constants.pasm" # fake mmd_vtregister / mmdfunc opcode .local pmc NULL null NULL .local pmc mmd_register mmd_register = dlfunc NULL, "mmd_register_sub", "vIiiiP" .local pmc divide divide = global "Integer_divide_PerlInt" .pcc_begin prototyped .arg .VTABLE_DIVIDE .arg .Integer .arg .PerlInt .arg divide .nci_call mmd_register .pcc_end # done $P0 = new PerlInt $P1 = new Integer $P2 = new PerlInt $P1 = 10 $P2 = 3 $P0 = $P1 / $P2 print $P0 print "\n" end .end .sub Integer_divide_PerlInt .param pmc left .param pmc right .param pmc lhs $P0 = new PerlInt $I0 = left $P0 = $I0 lhs = $P0/right # don't call divide Integer/PerlInt here $N0 = lhs floor $N0 lhs = $N0 .end leo