Author: jonathan
Date: Thu Mar 15 16:09:32 2007
New Revision: 17514
Modified:
trunk/CREDITS
trunk/src/ops/object.ops
trunk/src/pmc/parrotobject.pmc
trunk/t/pmc/object-meths.t
Log:
Allow overriding of a few more VTABLE methods in PIR, related to objects. Patch
courtesy of Alek Storm <[EMAIL PROTECTED]>. RT #41364.
Modified: trunk/CREDITS
==============================================================================
--- trunk/CREDITS (original)
+++ trunk/CREDITS Thu Mar 15 16:09:32 2007
@@ -572,3 +572,7 @@
N: Vishal Soni
E: [EMAIL PROTECTED]
D: Bug fixes in IMCC, ECMAScript
+
+N: Alek Storm
+E: [EMAIL PROTECTED]
+D: Fixed object vtable method overrides in PIR
Modified: trunk/src/ops/object.ops
==============================================================================
--- trunk/src/ops/object.ops (original)
+++ trunk/src/ops/object.ops Thu Mar 15 16:09:32 2007
@@ -54,13 +54,13 @@
object = $1;
meth = $2;
next = expr NEXT();
- interp->current_object = object;
- interp->current_cont = NEED_CONTINUATION;
method_pmc = VTABLE_find_method(interp, object, meth);
if (!method_pmc) {
real_exception(interp, next, METH_NOT_FOUND,
"Method '%Ss' not found", meth);
}
+ interp->current_object = object;
+ interp->current_cont = NEED_CONTINUATION;
dest = (opcode_t *)VTABLE_invoke(interp, method_pmc, next);
goto ADDRESS(dest);
}
@@ -90,13 +90,13 @@
object = $1;
meth = $2;
next = expr NEXT();
- interp->current_object = object;
- interp->current_cont = $3;
method_pmc = VTABLE_find_method(interp, object, meth);
if (!method_pmc) {
real_exception(interp, next, METH_NOT_FOUND,
"Method '%Ss' not found", meth);
}
+ interp->current_object = object;
+ interp->current_cont = $3;
dest = (opcode_t *)VTABLE_invoke(interp, method_pmc, next);
goto ADDRESS(dest);
}
@@ -124,14 +124,14 @@
object = $1;
meth = $2;
- interp->current_cont = CONTEXT(interp->ctx)->current_cont;
- PObj_get_FLAGS(interp->current_cont) |= SUB_FLAG_TAILCALL;
- interp->current_object = object;
method_pmc = VTABLE_find_method(interp, object, meth);
if (!method_pmc) {
real_exception(interp, next, METH_NOT_FOUND,
"Method '%Ss' not found", meth);
}
+ interp->current_cont = CONTEXT(interp->ctx)->current_cont;
+ PObj_get_FLAGS(interp->current_cont) |= SUB_FLAG_TAILCALL;
+ interp->current_object = object;
dest = (opcode_t *)VTABLE_invoke(interp, method_pmc, next);
goto ADDRESS(dest);
}
Modified: trunk/src/pmc/parrotobject.pmc
==============================================================================
--- trunk/src/pmc/parrotobject.pmc (original)
+++ trunk/src/pmc/parrotobject.pmc Thu Mar 15 16:09:32 2007
@@ -164,39 +164,90 @@
PMC* find_method(STRING* name) {
PMC *class = VTABLE_get_class(INTERP, SELF);
- return VTABLE_find_method(INTERP, class, name);
+ STRING *meth = CONST_STRING(interp, "__find_method");
+ STRING *meth_v = CONST_STRING(interp, "find_method");
+ PMC *sub = Parrot_find_vtable_meth(interp, SELF, meth_v);
+ if (PMC_IS_NULL(sub))
+ sub = find_meth(interp, SELF, meth);
+ if (PMC_IS_NULL(sub))
+ return VTABLE_find_method(INTERP, class, name);
+ return (PMC*) Parrot_run_meth_fromc_args(interp, sub,
+ SELF, meth, "PS", name);
}
PMC* get_attr(INTVAL idx) {
- return Parrot_get_attrib_by_num(INTERP, SELF, idx);
+ STRING *meth = CONST_STRING(interp, "__get_attr");
+ STRING *meth_v = CONST_STRING(interp, "get_attr");
+ PMC *sub = Parrot_find_vtable_meth(interp, SELF, meth_v);
+ if (PMC_IS_NULL(sub))
+ sub = find_meth(interp, SELF, meth);
+ if (PMC_IS_NULL(sub))
+ return Parrot_get_attrib_by_num(INTERP, SELF, idx);
+ return (PMC*) Parrot_run_meth_fromc_args(interp, sub,
+ SELF, meth, "PI", idx);
}
PMC* get_attr_str(STRING* idx) {
- return Parrot_get_attrib_by_str(INTERP, SELF, idx);
+ STRING *meth = CONST_STRING(interp, "__get_attr_str");
+ STRING *meth_v = CONST_STRING(interp, "get_attr_str");
+ PMC *sub = Parrot_find_vtable_meth(interp, SELF, meth_v);
+ PMC* r;
+ if (PMC_IS_NULL(sub))
+ sub = find_meth(interp, SELF, meth);
+ if (PMC_IS_NULL(sub))
+ r = Parrot_get_attrib_by_str(INTERP, SELF, idx);
+ else r = (PMC*) Parrot_run_meth_fromc_args(interp, sub,
+ SELF, meth, "PS", idx);
+ return r;
}
void set_attr(INTVAL idx, PMC* value) {
- Parrot_set_attrib_by_num(INTERP, SELF, idx, value);
+ STRING *meth = CONST_STRING(interp, "__set_attr");
+ STRING *meth_v = CONST_STRING(interp, "set_attr");
+ PMC *sub = Parrot_find_vtable_meth(interp, SELF, meth_v);
+ if (PMC_IS_NULL(sub))
+ sub = find_meth(interp, SELF, meth);
+ if (PMC_IS_NULL(sub))
+ return Parrot_set_attrib_by_num(INTERP, SELF, idx, value);
+ (PMC*) Parrot_run_meth_fromc_args(interp, sub,
+ SELF, meth, "vIP", idx, value);
}
void set_attr_str(STRING* idx, PMC* value) {
- Parrot_set_attrib_by_str(INTERP, SELF, idx, value);
+ STRING *meth = CONST_STRING(interp, "__set_attr_str");
+ STRING *meth_v = CONST_STRING(interp, "set_attr_str");
+ PMC *sub = Parrot_find_vtable_meth(interp, SELF, meth_v);
+ if (PMC_IS_NULL(sub))
+ sub = find_meth(interp, SELF, meth);
+ if (PMC_IS_NULL(sub))
+ return Parrot_set_attrib_by_str(INTERP, SELF, idx, value);
+ (PMC*) Parrot_run_meth_fromc_args(interp, sub,
+ SELF, meth, "vSP", idx, value);
}
PMC* get_class() {
- if (!PObj_is_PMC_shared_TEST(SELF)) {
- return GET_CLASS(PMC_data(SELF), SELF);
- }
- else {
- /* get the class object for this interpreter */
- /* XXX this is rather a hack, it is, however, necessary:
- * otherwise we will be accessing the wrong interpreter's
- * namespace
- */
- int type_num = SELF->vtable->base_type;
-
- return INTERP->vtables[type_num]->class;
- }
+ STRING *meth = CONST_STRING(interp, "__get_class");
+ STRING *meth_v = CONST_STRING(interp, "get_class");
+ PMC *sub = Parrot_find_vtable_meth(interp, SELF, meth_v);
+ if (PMC_IS_NULL(sub))
+ sub = find_meth(interp, SELF, meth);
+ if (PMC_IS_NULL(sub)) {
+ if (!PObj_is_PMC_shared_TEST(SELF)) {
+ return GET_CLASS(PMC_data(SELF), SELF);
+ }
+ else {
+ /* get the class object for this interpreter */
+ /* XXX this is rather a hack, it is, however, necessary:
+ * otherwise we will be accessing the wrong interpreter's
+ * namespace
+ */
+ int type_num = SELF->vtable->base_type;
+
+ return INTERP->vtables[type_num]->class;
+ }
+ }
+ return (PMC*) Parrot_run_meth_fromc_args(interp, sub,
+ SELF, meth, "P");
}
/*
Modified: trunk/t/pmc/object-meths.t
==============================================================================
--- trunk/t/pmc/object-meths.t (original)
+++ trunk/t/pmc/object-meths.t Thu Mar 15 16:09:32 2007
@@ -6,7 +6,7 @@
use warnings;
use lib qw( . lib ../lib ../../lib );
use Test::More;
-use Parrot::Test tests => 40;
+use Parrot::Test tests => 43;
=head1 NAME
@@ -1325,6 +1325,91 @@
init_pmc was called
OUTPUT
+
+pir_output_is( <<'CODE', <<'OUTPUT', "overloading find_method vtable" );
+.sub main :main
+ .local pmc cl, o
+ cl = newclass 'MyClass'
+ o = new 'MyClass'
+ o.'foo'()
+.end
+
+.namespace ['MyClass']
+
+.sub find_method :method :vtable
+ .param string methodname
+ print "find_method was called\n"
+ $P0 = find_global "MyClass", methodname
+ .return($P0)
+.end
+
+.sub foo
+ print "foo was called\n"
+.end
+
+CODE
+find_method was called
+foo was called
+OUTPUT
+
+pir_output_is( <<'CODE', <<'OUTPUT', "overloading attribute accessor vtable" );
+.sub main :main
+ .local pmc cl, o
+ cl = newclass 'MyClass'
+ o = new 'MyClass'
+ $P2 = new String
+ $P2 = "blue"
+ setattribute o, 0, $P2
+ setattribute o, "blue", $P2
+ $P1 = getattribute o, 0
+ $P1 = getattribute o, "blue"
+.end
+
+.namespace ['MyClass']
+
+.sub get_attr :method :vtable
+ .param int offset
+ print "get_attr was called\n"
+.end
+.sub get_attr_str :method :vtable
+ .param string attrname
+ print "get_attr_str was called\n"
+.end
+.sub set_attr :method :vtable
+ .param int offset
+ .param pmc val
+ print "set_attr was called\n"
+.end
+.sub set_attr_str :method :vtable
+ .param string attrname
+ .param pmc val
+ print "set_attr_str was called\n"
+.end
+CODE
+set_attr was called
+set_attr_str was called
+get_attr was called
+get_attr_str was called
+OUTPUT
+
+pir_output_is( <<'CODE', <<'OUTPUT', "overloading get_class vtable" );
+.sub main :main
+ .local pmc cl, o, cl2
+ cl = newclass 'MyClass'
+ o = new 'MyClass'
+ cl2 = class o
+.end
+
+.namespace ['MyClass']
+
+.sub get_class :method :vtable
+ print "get_class was called\n"
+.end
+
+CODE
+get_class was called
+OUTPUT
+
# Local Variables:
# mode: cperl
# cperl-indent-level: 4