cvsuser 05/04/04 09:03:28
Modified: classes bound_nci.pmc default.pmc multisub.pmc nci.pmc
imcc pcc.c reg_alloc.c
src mmd.c
t/pmc mmd.t
Log:
MMD 17 - bound multi subs
* this sequence works now
m = getattribute l, '__add'
m(r, d)
* t/dynclass/pyclass_3 seems to be broken
unrelated to this patch - PyStrings don't mark their contents
Revision Changes Path
1.3 +23 -6 parrot/classes/bound_nci.pmc
Index: bound_nci.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/bound_nci.pmc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- bound_nci.pmc 19 Mar 2005 16:20:05 -0000 1.2
+++ bound_nci.pmc 4 Apr 2005 16:03:25 -0000 1.3
@@ -57,17 +57,34 @@
}
void* invoke (void * next) {
- Parrot_csub_t func = (Parrot_csub_t)D2FPTR(PMC_data(SELF));
- PMC *p2 = REG_PMC(2);
- REG_PMC(2) = PMC_pmc_val(SELF);
- SUPER(next);
- REG_PMC(2) = p2;
+ if (PObj_get_FLAGS(SELF) & PObj_private0_FLAG) {
+ /* bound multi sub
+ * XXX maybe create separate PMC class
+ * see also classes/default.pmc:get_attr_str()
+ * */
+ PMC *multi = PMC_struct_val(SELF);
+ INTVAL i = REG_INT(3)++;
+ while (i--)
+ REG_PMC(6+i)=REG_PMC(5+i);
+ REG_PMC(5) = PMC_pmc_val(SELF);
+ next = VTABLE_invoke(INTERP, multi, next);
+ }
+ else {
+ PMC *p2 = REG_PMC(2);
+ REG_PMC(2) = PMC_pmc_val(SELF);
+ SUPER(next);
+ REG_PMC(2) = p2;
+ }
return next;
}
void mark() {
if (PMC_pmc_val(SELF))
pobject_lives(INTERP, (PObj *)PMC_pmc_val(SELF));
+ if (PObj_get_FLAGS(SELF) & PObj_private0_FLAG) {
+ if (PMC_struct_val(SELF))
+ pobject_lives(INTERP, (PObj *)PMC_struct_val(SELF));
+ }
}
}
1.114 +12 -2 parrot/classes/default.pmc
Index: default.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/default.pmc,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -r1.113 -r1.114
--- default.pmc 4 Apr 2005 14:02:16 -0000 1.113
+++ default.pmc 4 Apr 2005 16:03:25 -0000 1.114
@@ -393,9 +393,12 @@
PMC* find_method(STRING* method_name) {
PMC *method = Parrot_find_method_with_cache(INTERP, SELF,
method_name);
- if (method && method->vtable->base_type == enum_class_MultiSub)
+ if (method && method->vtable->base_type == enum_class_MultiSub &&
+ REG_STR(1)) {
return Parrot_MMD_search_default_func(interpreter,
method_name, REG_STR(1));
+ }
+ return method;
}
void add_method(STRING *method_name, PMC *sub_pmc) {
@@ -836,6 +839,13 @@
VTABLE_set_pmc(INTERP, bound_meth, SELF);
return bound_meth;
}
+ else if (p->vtable->base_type == enum_class_MultiSub) {
+ PMC *bound_meth = pmc_new(INTERP, enum_class_Bound_NCI);
+ VTABLE_set_pmc(INTERP, bound_meth, SELF);
+ PMC_struct_val(bound_meth) = p;
+ PObj_get_FLAGS(bound_meth) |= PObj_private0_FLAG;
+ return bound_meth;
+ }
/* TODO bound user functions */
return p;
}
1.3 +9 -1 parrot/classes/multisub.pmc
Index: multisub.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/multisub.pmc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- multisub.pmc 3 Apr 2005 16:27:42 -0000 1.2
+++ multisub.pmc 4 Apr 2005 16:03:25 -0000 1.3
@@ -22,6 +22,9 @@
#include "parrot/parrot.h"
+/* XXX */
+PMC * Parrot_MMD_dispatch_func(Interp *, PMC *multi, STRING *signature);
+
pmclass MultiSub extends ResizablePMCArray need_ext does array {
void push_pmc(PMC* value) {
@@ -51,6 +54,11 @@
void set_number_keyed_int (INTVAL key, FLOATVAL value) {
internal_exception(1, "attempt to set non Sub PMC");
}
+
+ void* invoke(void *next) {
+ PMC *func = Parrot_MMD_dispatch_func(INTERP, SELF, REG_STR(1));
+ return VTABLE_invoke(INTERP, func, next);
+ }
}
/*
1.35 +1 -2 parrot/classes/nci.pmc
Index: nci.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/nci.pmc,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- nci.pmc 4 Apr 2005 14:02:16 -0000 1.34
+++ nci.pmc 4 Apr 2005 16:03:25 -0000 1.35
@@ -154,7 +154,6 @@
while (i--)
REG_PMC(6+i)=REG_PMC(5+i);
REG_PMC(5) = REG_PMC(2);
- ++REG_INT(3);
}
func(INTERP, SELF);
return next;
1.92 +2 -1 parrot/imcc/pcc.c
Index: pcc.c
===================================================================
RCS file: /cvs/public/parrot/imcc/pcc.c,v
retrieving revision 1.91
retrieving revision 1.92
diff -u -r1.91 -r1.92
--- pcc.c 4 Apr 2005 14:02:20 -0000 1.91
+++ pcc.c 4 Apr 2005 16:03:26 -0000 1.92
@@ -926,6 +926,8 @@
insert_ins(unit, ins, get_name);
ins = get_name;
}
+ else
+ ins = pcc_insert_signature(interp, unit, ins, sub->pcc_sub);
/*
@@ -951,7 +953,6 @@
else
ins = insINS(interp, unit, ins, "set", regs, 2);
}
- ins = pcc_insert_signature(interp, unit, ins, sub->pcc_sub);
if (sub->pcc_sub->nci)
goto move_sub;
}
1.29 +2 -2 parrot/imcc/reg_alloc.c
Index: reg_alloc.c
===================================================================
RCS file: /cvs/public/parrot/imcc/reg_alloc.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- reg_alloc.c 11 Jan 2005 16:30:45 -0000 1.28
+++ reg_alloc.c 4 Apr 2005 16:03:26 -0000 1.29
@@ -683,7 +683,7 @@
if (r0->set != r1->set)
return 0;
/* If the first time r0 appears is in the same instruction as the
- * last appearance of r1, or after its last appearance, then they
+ * last appearance of r1, or after its last appearance, then they
* can't interfere.
*
* Even if r0 and r1 are called in the same instruction, and even
@@ -904,7 +904,7 @@
static const char assignable[4][5] = {
/* 0 1 2 3 4 */
{ 0, 0, 0, 0, 0, }, /* I */
- { 0, 1, 1, 1, 1, }, /* S */
+ { 0, 0, 1, 1, 1, }, /* S */
{ 0, 0, 0, 1, 1, }, /* P */
{ 1, 1, 1, 1, 1, }, /* N */
};
1.63 +40 -1 parrot/src/mmd.c
Index: mmd.c
===================================================================
RCS file: /cvs/public/parrot/src/mmd.c,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -r1.62 -r1.63
--- mmd.c 4 Apr 2005 14:02:22 -0000 1.62
+++ mmd.c 4 Apr 2005 16:03:27 -0000 1.63
@@ -729,6 +729,37 @@
return mmd_search_default(interpreter, meth, arg_tuple);
}
+/* XXX */
+PMC * Parrot_MMD_dispatch_func(Interp *, PMC *multi, STRING *signature);
+
+PMC *
+Parrot_MMD_dispatch_func(Interp *interpreter, PMC *multi,
+ STRING *signature)
+{
+ PMC* arg_tuple, *pmc;
+ INTVAL n;
+ /*
+ * 1) create argument tuple
+ */
+ arg_tuple = mmd_arg_tuple_func(interpreter, signature);
+ n = VTABLE_elements(interpreter, multi);
+ if (!n)
+ return NULL;
+ /*
+ * 5) sort the list
+ */
+ if (n > 1)
+ mmd_sort_candidates(interpreter, arg_tuple, multi);
+ n = VTABLE_elements(interpreter, multi);
+ if (!n)
+ return NULL;
+ /*
+ * 6) Uff, return first one
+ */
+ pmc = VTABLE_get_pmc_keyed_int(interpreter, multi, 0);
+ return pmc;
+}
+
/*
=item C<
@@ -846,6 +877,14 @@
}
}
+ /*
+ * XXX invalidate S1
+ * this is needed for this seqeuence:
+ * "__add"(l, r, d) # multi sub call - create S1
+ * m = getattribute l, "__add" # create bound method
+ * m(r, d)
+ */
+ REG_STR(1) = NULL;
return arg_tuple;
}
1.23 +27 -2 parrot/t/pmc/mmd.t
Index: mmd.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/mmd.t,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- mmd.t 4 Apr 2005 14:02:24 -0000 1.22
+++ mmd.t 4 Apr 2005 16:03:28 -0000 1.23
@@ -16,7 +16,7 @@
=cut
-use Parrot::Test tests => 21;
+use Parrot::Test tests => 22;
pir_output_is(<<'CODE', <<'OUTPUT', "PASM divide");
@@ -719,3 +719,28 @@
CODE
42.42
OUTPUT
+
+pir_output_is(<<'CODE', <<'OUTPUT', "bound __add method");
+.sub main @MAIN
+ .local pmc d, l, r, m
+ d = new Integer
+ l = new Integer
+ r = new Float
+ l = 3
+ r = 39.42
+ m = getattribute l, "__add"
+ m(r, d)
+ print d
+ print "\n"
+ r = new Integer
+ r = 39
+ m = getattribute l, "__add"
+ m(r, d)
+ print d
+ print "\n"
+ end
+.end
+CODE
+42.42
+42
+OUTPUT