Re: cvs commit: parrot/t/pmc object-meths.t
Sam Ruby <[EMAIL PROTECTED]> wrote: > But then you effectively morph the resulting bound method into a NCI > instead of a PyNCI with the following line of code: > bound_meth->vtable = Parrot_base_vtables[enum_class_Bound_NCI]; Yes. That's a general problem in all places, where the Parrot core creates a PMC that might be overridden in a specific HLL. I've proposed that we should have a table of core PMC => HLL mappings so that depending on the current language a correct PMC class is created. This is probably more important for scalar types, as basic math operations are usually the same, then in object-ish code, where differences tend to be bigger. > Delegation is more appropriate in this instance, and would be able to > handle both NCIs and PIR methods with equal ease. How should default.pmc:get_attr_str() look like? > - Sam Ruby leo
Re: cvs commit: parrot/t/pmc object-meths.t
Leopold Toetsch wrote: Sam Ruby <[EMAIL PROTECTED]> wrote: [EMAIL PROTECTED] wrote: +else if (p->vtable->base_type == enum_class_NCI) { It was requested[1] that I not add any Python specific methods to the NCI method... accordingly, the majority of Python methods are morphed to a PyNCI class which subclasses the base NCI class. Well, I know that the above test isn't quite right. It should be: if (VTABLE_isa(INTERP, p, CONST_STRING(INTERP, "NCI"))) But that needs still more work - better PMC class inheritance in that case. I've proposed to add an "mro" array to PMCs to simplify inheritance checks. [ for now, I've put in above line - should work ] But then you effectively morph the resulting bound method into a NCI instead of a PyNCI with the following line of code: bound_meth->vtable = Parrot_base_vtables[enum_class_Bound_NCI]; Delegation is more appropriate in this instance, and would be able to handle both NCIs and PIR methods with equal ease. - Sam Ruby
Re: cvs commit: parrot/t/pmc object-meths.t
Sam Ruby <[EMAIL PROTECTED]> wrote: > [EMAIL PROTECTED] wrote: >> +else if (p->vtable->base_type == enum_class_NCI) { > It was requested[1] that I not add any Python specific methods to the > NCI method... accordingly, the majority of Python methods are morphed to > a PyNCI class which subclasses the base NCI class. Well, I know that the above test isn't quite right. It should be: if (VTABLE_isa(INTERP, p, CONST_STRING(INTERP, "NCI"))) But that needs still more work - better PMC class inheritance in that case. I've proposed to add an "mro" array to PMCs to simplify inheritance checks. [ for now, I've put in above line - should work ] > - Sam Ruby leo
Re: cvs commit: parrot/t/pmc object-meths.t
[EMAIL PROTECTED] wrote: +else if (p->vtable->base_type == enum_class_NCI) { It was requested[1] that I not add any Python specific methods to the NCI method... accordingly, the majority of Python methods are morphed to a PyNCI class which subclasses the base NCI class. - Sam Ruby [1] http://xrl.us/exsu
[PATCH] Re: cvs commit: parrot/t/pmc object-meths.t
Leopold Toetsch writes: > +if (arg->vtable->base_type == enum_class_Key) { > +while (arg) { > +UINTVAL flags = PObj_get_FLAGS(arg); > +if (flags & KEY_register_FLAG) { > +INTVAL n = PMC_int_val(arg); > +if (flags & KEY_integer_FLAG) > +REG_INT(n) = BP_REG_INT(bp, n); > +else if (flags & KEY_pmc_FLAG) > +REG_PMC(n) = BP_REG_PMC(bp, n); > +else if (flags & KEY_string_FLAG) > +REG_STR(n) = BP_REG_STR(bp, n); > +} > +arg = key_next(interpreter, arg); > +} > +} Ack! I don't think that's going to do it. What if the get_integer_keyed method were: .namespace ["Foo"] .sub __get_integer_keyed .param pmc key $S0 = "bar" print "Key = " print key print "\n" .return(0) .end The first line overwrites the register that was there before, and you get: Key = foo Key = bar (Assuming that $S0 was coincidentally mapped to the same register... which it was) Even more subtle and no less wrong. This patch solves the problem completely, but I'm wary of putting it in because it's so evil ugly. Is it safe to do this? Index: src/inter_run.c === RCS file: /cvs/public/parrot/src/inter_run.c,v retrieving revision 1.20 diff -u -u -r1.20 inter_run.c --- src/inter_run.c 22 Nov 2004 12:07:22 - 1.20 +++ src/inter_run.c 22 Nov 2004 12:51:02 - @@ -202,7 +202,7 @@ STRING *meth, const char* sig, va_list ap) { opcode_t offset, *dest; -struct parrot_regs_t *bp; +struct parrot_regs_t *bp, *old_bp; int next[4], count[4]; int i; PMC *ret_c; @@ -284,30 +284,21 @@ break; case 'P': /* REG_PMC */ arg = va_arg(ap, PMC*); + +/* Deal with key arguments, which might reference registers */ +if (arg->vtable->base_type == enum_class_Key) { +/* XXX EVIL! Making this work in a non-evil way requires + * a major rethinking in how this function operates... */ +old_bp = interpreter->ctx.bp; +interpreter->ctx.bp = bp; +arg = VTABLE_clone(interpreter, arg); +interpreter->ctx.bp = old_bp; +} + if (next[2] == 16) VTABLE_set_pmc_keyed_int(interpreter, p3, i++, arg); else REG_PMC(next[2]++) = arg; -/* - * if this is a Key PMC with registers, pass on these - * registers. - * XXX make a distinct 'K' signature ? - */ -if (arg->vtable->base_type == enum_class_Key) { -while (arg) { -UINTVAL flags = PObj_get_FLAGS(arg); -if (flags & KEY_register_FLAG) { -INTVAL n = PMC_int_val(arg); -if (flags & KEY_integer_FLAG) -REG_INT(n) = BP_REG_INT(bp, n); -else if (flags & KEY_pmc_FLAG) -REG_PMC(n) = BP_REG_PMC(bp, n); -else if (flags & KEY_string_FLAG) -REG_STR(n) = BP_REG_STR(bp, n); -} -arg = key_next(interpreter, arg); -} -} break; case 'N': /* REG_NUM */ if (next[3] == 16)