Re: cvs commit: parrot/t/pmc object-meths.t

2005-02-01 Thread Leopold Toetsch
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

2005-02-01 Thread Sam Ruby
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

2005-02-01 Thread Leopold Toetsch
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

2005-02-01 Thread Sam Ruby
[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

2004-11-22 Thread Luke Palmer
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)