cvsuser 04/12/13 13:51:00
Modified: . MANIFEST
config/gen/makefiles dynclasses.in
dynclasses pyclass.pmc pygen.pmc pyint.pmc pyobject.pmc
pytype.pmc
languages/python Makefile
src inter_run.c
Added: dynclasses pyproxyclass.pmc pyproxytype.pmc
Log:
All languages/python/t/basic tests now pass.
Revision Changes Path
1.806 +2 -0 parrot/MANIFEST
Index: MANIFEST
===================================================================
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.805
retrieving revision 1.806
diff -u -r1.805 -r1.806
--- MANIFEST 13 Dec 2004 13:45:57 -0000 1.805
+++ MANIFEST 13 Dec 2004 21:50:56 -0000 1.806
@@ -377,6 +377,8 @@
dynclasses/pymodule.pmc [devel]
dynclasses/pynone.pmc [devel]
dynclasses/pyobject.pmc [devel]
+dynclasses/pyproxyclass.pmc [devel]
+dynclasses/pyproxytype.pmc [devel]
dynclasses/pystring.pmc [devel]
dynclasses/pytuple.pmc [devel]
dynclasses/pytype.pmc [devel]
1.16 +3 -1 parrot/config/gen/makefiles/dynclasses.in
Index: dynclasses.in
===================================================================
RCS file: /cvs/public/parrot/config/gen/makefiles/dynclasses.in,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- dynclasses.in 11 Dec 2004 02:17:52 -0000 1.15
+++ dynclasses.in 13 Dec 2004 21:50:57 -0000 1.16
@@ -27,7 +27,9 @@
pynone \
pytype \
pystring \
- pytuple
+ pytuple \
+pyproxytype \
+pyproxyclass
BUILD = ${perl} build.pl
1.10 +11 -7 parrot/dynclasses/pyclass.pmc
Index: pyclass.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pyclass.pmc,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- pyclass.pmc 11 Dec 2004 22:44:29 -0000 1.9
+++ pyclass.pmc 13 Dec 2004 21:50:58 -0000 1.10
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: pyclass.pmc,v 1.9 2004/12/11 22:44:29 rubys Exp $
+$Id: pyclass.pmc,v 1.10 2004/12/13 21:50:58 rubys Exp $
=head1 NAME
@@ -169,9 +169,11 @@
STRING* get_repr() {
PMC *repr = VTABLE_find_method(INTERP, SELF, REPR);
- if (repr)
- return (STRING*) Parrot_run_meth_fromc_args(INTERP, repr, SELF,
- REPR, "S");
+ if (repr) {
+ PMC *ret;
+ ret = Parrot_run_meth_fromc_args(INTERP, repr, SELF, REPR, "P");
+ return VTABLE_get_string(INTERP, ret);
+ }
else {
STRING *res;
@@ -201,9 +203,11 @@
STRING* get_string() {
PMC *repr = VTABLE_find_method(INTERP, SELF, STR);
- if (repr)
- return (STRING*) Parrot_run_meth_fromc_args(INTERP, repr, SELF,
- REPR, "S");
+ if (repr) {
+ PMC *ret;
+ ret = Parrot_run_meth_fromc_args(INTERP, repr, SELF, REPR, "P");
+ return VTABLE_get_string(INTERP, ret);
+ }
else {
return VTABLE_get_repr(INTERP, SELF);
}
1.3 +3 -5 parrot/dynclasses/pygen.pmc
Index: pygen.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pygen.pmc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- pygen.pmc 6 Dec 2004 18:09:31 -0000 1.2
+++ pygen.pmc 13 Dec 2004 21:50:58 -0000 1.3
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: pygen.pmc,v 1.2 2004/12/06 18:09:31 rubys Exp $
+$Id: pygen.pmc,v 1.3 2004/12/13 21:50:58 rubys Exp $
=head1 NAME
@@ -118,12 +118,10 @@
if (!setjmp(INTERP->exceptions->destination)) {
PMC_struct_val(SELF) =
Parrot_runops_fromc_args(INTERP, PMC_pmc_val(SELF), "P");
- pop_exception(INTERP);
} else {
- /* TODO: check for something better than the message */
PMC *exception = REG_PMC(5);
- STRING *message = VTABLE_get_string_keyed_int(INTERP, exception,
0);
- if (0 != string_compare(INTERP, message, STOPITERATION)) {
+ INTVAL extype = VTABLE_get_integer_keyed_int(INTERP, exception,
1);
+ if (extype != E_StopIteration) {
rethrow_exception(INTERP, REG_PMC(5));
}
}
1.8 +21 -2 parrot/dynclasses/pyint.pmc
Index: pyint.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pyint.pmc,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- pyint.pmc 11 Dec 2004 02:17:54 -0000 1.7
+++ pyint.pmc 13 Dec 2004 21:50:58 -0000 1.8
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: pyint.pmc,v 1.7 2004/12/11 02:17:54 rubys Exp $
+$Id: pyint.pmc,v 1.8 2004/12/13 21:50:58 rubys Exp $
=head1 NAME
@@ -26,6 +26,8 @@
static INTVAL dynclass_PyFloat;
static INTVAL dynclass_PyString;
+static PMC* base_class;
+
pmclass PyInt extends PyObject dynpmc group python_group {
/*
@@ -45,6 +47,9 @@
dynclass_PyComplex = Parrot_PMC_typenum(INTERP, "PyComplex");
dynclass_PyFloat = Parrot_PMC_typenum(INTERP, "PyFloat");
dynclass_PyString = Parrot_PMC_typenum(INTERP, "PyString");
+
+ /* TODO: make Int have a real base class */
+ base_class = pmc_new(INTERP, dynclass_PyInt);
}
}
@@ -500,6 +505,20 @@
/*
+=item C<PMC *get_class()>
+
+Return the class of this object.
+
+=cut
+
+*/
+
+ PMC* get_class() {
+ return base_class;
+ }
+
+/*
+
=item C<INTVAL get_integer()>
Returns the integer value of the integer.
@@ -558,7 +577,7 @@
=item C<void* invoke(void *next)>
-Create a new dictionary from a sequence
+Create a new integer
=cut
1.7 +28 -9 parrot/dynclasses/pyobject.pmc
Index: pyobject.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pyobject.pmc,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- pyobject.pmc 12 Dec 2004 23:03:47 -0000 1.6
+++ pyobject.pmc 13 Dec 2004 21:50:58 -0000 1.7
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: pyobject.pmc,v 1.6 2004/12/12 23:03:47 chromatic Exp $
+$Id: pyobject.pmc,v 1.7 2004/12/13 21:50:58 rubys Exp $
=head1 NAME
@@ -51,8 +51,6 @@
REG_PMC(2) = SELF; \
return REG_PMC(5);
-extern PMC* Parrot_PyType_subclass(Interp* interpreter, PMC *pmc, STRING*
name);
-
pmclass PyObject dynpmc group python_group {
/*
@@ -784,9 +782,12 @@
=item C<PMC* subclass(STRING *name)>
-Create a subclass of the given class. Note that this merely creates
-a new PyType... all the interesting details that make it a subclass
-need to be filled in.
+Create a subclass of the builtin class. In additon to creating a
+new class (of type PyProxyType), an instance of PyProxyClass is also
+created and defined as the base class for the new class.
+
+See the description of PyProxyType and PyProxyClass to see how
+new instances are created and how methods are forwarded respectively.
=cut
@@ -796,9 +797,27 @@
*/
PMC* subclass(STRING* name) {
- PMC *ret = Parrot_PyType_subclass(INTERP, SELF, name);
- INTVAL dynclass_PyType = Parrot_PMC_typenum(INTERP, "PyType");
- return ret;
+ INTVAL dynclass_PyProxyType, dynclass_PyProxyClass;
+ PMC *proxy_type, *adaptor_class, *nameprop;
+ STRING *NAME, *BASES;
+
+ dynclass_PyProxyClass = Parrot_PMC_typenum(INTERP, "PyProxyClass");
+ adaptor_class = pmc_new(INTERP, dynclass_PyProxyClass);
+
+ BASES = const_string(INTERP, "__bases__");
+ VTABLE_setprop(INTERP, adaptor_class, BASES, SELF);
+
+ dynclass_PyProxyType = Parrot_PMC_typenum(INTERP, "PyProxyType");
+ proxy_type = pmc_new(INTERP, dynclass_PyProxyType);
+
+ NAME = const_string(INTERP, "__name__");
+ nameprop = pmc_new(INTERP, dynclass_PyString);
+ VTABLE_setprop(INTERP, proxy_type, NAME, nameprop);
+ VTABLE_set_string_native(INTERP, nameprop, name);
+
+ VTABLE_setprop(INTERP, proxy_type, BASES, adaptor_class);
+
+ return proxy_type;
}
/*
1.6 +2 -2 parrot/dynclasses/pytype.pmc
Index: pytype.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pytype.pmc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- pytype.pmc 11 Dec 2004 22:44:29 -0000 1.5
+++ pytype.pmc 13 Dec 2004 21:50:58 -0000 1.6
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: pytype.pmc,v 1.5 2004/12/11 22:44:29 rubys Exp $
+$Id: pytype.pmc,v 1.6 2004/12/13 21:50:58 rubys Exp $
=head1 NAME
@@ -131,7 +131,7 @@
init = VTABLE_find_method(INTERP, object, INIT);
if (init) {
- REG_PMC(2) = object;
+ INTERP->ctx.current_object = object;
Parrot_runops_fromc(INTERP, init);
}
1.1 parrot/dynclasses/pyproxyclass.pmc
Index: pyproxyclass.pmc
===================================================================
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
$Id: pyproxyclass.pmc,v 1.1 2004/12/13 21:50:58 rubys Exp $
=head1 NAME
classes/pyproxyclass.pmc - Python Proxy Class
=head1 DESCRIPTION
Forward method and attribute requests onto the object that is
being proxied.
=head2 Methods
=over 4
TODO: handle attributes.
=cut
*/
#include "parrot/parrot.h"
static INTVAL dynclass_PyProxyClass;
STRING *PROXY;
pmclass PyProxyClass extends PyObject dynpmc group python_group {
/*
=item C<void class_init()>
Class initialization. Caches the type id of various PMCs because
they will be used frequently here.
=cut
*/
void class_init() {
if (pass) {
dynclass_PyProxyClass = Parrot_PMC_typenum(INTERP,
"PyProxyClass");
PROXY = const_string(INTERP, "__proxy__");
}
}
/*
=item C<void init()>
Initializes the instance.
=cut
*/
void init () {
PMC_pmc_val(SELF) = 0;
PMC_struct_val(SELF) = 0;
}
/*
=item C<PMC *find_method(STRING *method_name)>
Looks up the method for C<*method_name> and returns it.
=cut
*/
PMC* find_method(STRING* method_name) {
PMC *method = SUPER(method_name);
if (method) {
PMC *forwarder = pmc_new(INTERP, dynclass_PyProxyClass);
PMC_struct_val(forwarder) = method;
method = forwarder;
}
return method;
}
/*
=item C<void* invoke(void *next)>
Invoke the real method
=cut
*/
void* invoke(void *next) {
PMC *proxy = INTERP->ctx.current_object;
if (!PMC_struct_val(SELF))
internal_exception(1, "Invoke() called on a PyProxyClass object");
INTERP->ctx.current_object = REG_PMC(2) =
VTABLE_getprop(INTERP, proxy, PROXY);
return VTABLE_invoke(INTERP, (PMC*)PMC_struct_val(SELF), next);
}
/*
=back
=cut
*/
}
/*
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*
* vim: expandtab shiftwidth=4:
*/
1.1 parrot/dynclasses/pyproxytype.pmc
Index: pyproxytype.pmc
===================================================================
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
$Id: pyproxytype.pmc,v 1.1 2004/12/13 21:50:58 rubys Exp $
=head1 NAME
classes/pyproxytype.pmc - Python Proxy Type
=head1 DESCRIPTION
This is the type that you get when you subclass a non-PyClass
(i.e., a builtin PyObject, like PyInt).
Invoking instances of this type (which is Python's way of
instantiating instances) actually causes two objects to be created:
one of type PyClass (the "proxy"), and one of intended class
(the "real object").
The one "trick" is that the an additional parent is inserted into
the inheritance hierarchy of type PyProxyClass. The sole function of
PyProxyClass is to delegate of all method and attribute calls back onto
the real object.
The combination of PyClass, PyProxyClass, and PyObject allows subclasses
of builtins to redefine methods. This is because PyClass knows how to
translate Parrot calls (like "get_string") into Python methods (like
"__str__"), find_method on PyClass knows how to look up the inheritance
chain, and having a PyProxyClass on the top of the chain knows how to
forward such method talls to a PyObject, which in turn knows how to
map Python method calls onto Parrot calls.
While this seems like a lot of work, lets consider all the cases:
"pure" builtins (not subclassed by Python):
* operations like indexing and addition are done at Parrot
speeds with no lookaside to see if methods have been
overridden.
* explict calls to methods (such as __str__) are relatively
rare, but are handled by an NCI method which maps between
Python and Parrot syntax and semantics.
"pure" Python classes (base class is object):
* operations like addition are relatively rare, but are
accomplished by an NCI method which maps between Python
and Parrot syntax and semantics.
* explicit calls to methods directly check the set of
properties (currently a hash) for each class.
"mixed" classes (base class is builin - relatively rare):
* operations like indexing and addition require a
mapping to Python method names, an inheritance search,
and mapping back to Parrot method names.
* explicit calls to methods require only the ProxyClass and
a mapping to Parrot methods.
=head2 Methods
=over 4
=cut
*/
#include "parrot/parrot.h"
INTVAL dynclass_PyClass;
STRING *BASES;
STRING *CLASS;
STRING *INIT;
STRING *PROXY;
pmclass PyProxyType extends PyType dynpmc group python_group {
/*
=item C<void class_init()>
Class initialization. Caches the type id of various PMCs because
they will be used frequently here.
=cut
*/
void class_init() {
if (pass) {
dynclass_PyClass = Parrot_PMC_typenum(INTERP, "PyClass");
BASES = const_string(INTERP, "__bases__");
CLASS = const_string(INTERP, "__class__");
INIT = const_string(INTERP, "__init__");
PROXY = const_string(INTERP, "__proxy__");
}
}
/*
=item C<void* invoke(void *next)>
Create a new object and proxy. Note: invokes C<invoke> on the
object without touching any parrot registers... this enables
initializers with arguments to be run.
=cut
TODO: reconcile this with Parrot's instantiate VTABLE entry.
*/
void* invoke(void *next) {
PMC *proxy_class, *object_class, *proxy, *object, *init;
proxy_class = VTABLE_getprop(INTERP, SELF, BASES);
object_class = VTABLE_getprop(INTERP, proxy_class, BASES);
object = pmc_new(INTERP, object_class->vtable->base_type);
proxy = pmc_new(interpreter, dynclass_PyClass);
VTABLE_setprop(INTERP, proxy, CLASS, REG_PMC(0));
init = VTABLE_find_method(INTERP, proxy, INIT);
if (init) {
INTERP->ctx.current_object = proxy;
Parrot_runops_fromc(INTERP, init);
}
else {
VTABLE_invoke(INTERP, object, next);
object = REG_PMC(5);
}
VTABLE_setprop(INTERP, proxy, PROXY, object);
REG_PMC(5) = proxy;
return next;
}
/*
=back
=cut
*/
}
/*
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*
* vim: expandtab shiftwidth=4:
*/
1.7 +1 -1 parrot/languages/python/Makefile
Index: Makefile
===================================================================
RCS file: /cvs/public/parrot/languages/python/Makefile,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Makefile 11 Dec 2004 02:17:56 -0000 1.6
+++ Makefile 13 Dec 2004 21:50:59 -0000 1.7
@@ -1,7 +1,7 @@
all:
test:
- perl t/harness t/basic/0*.t t/basic/func.t t/basic/iter.t
t/basic/oo_attr.t
+ perl t/harness t/basic/*.t
testbench:
perl t/harness t/pie/b1.t
1.24 +2 -2 parrot/src/inter_run.c
Index: inter_run.c
===================================================================
RCS file: /cvs/public/parrot/src/inter_run.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- inter_run.c 11 Dec 2004 12:08:11 -0000 1.23
+++ inter_run.c 13 Dec 2004 21:51:00 -0000 1.24
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: inter_run.c,v 1.23 2004/12/11 12:08:11 leo Exp $
+$Id: inter_run.c,v 1.24 2004/12/13 21:51:00 rubys Exp $
=head1 NAME
@@ -225,10 +225,10 @@
bp = interpreter->ctx.bp;
ret_c = new_ret_continuation_pmc(interpreter, NULL);
- dest = VTABLE_invoke(interpreter, sub, NULL);
interpreter->ctx.current_sub = sub;
interpreter->ctx.current_cont = ret_c;
interpreter->ctx.current_object = obj;
+ dest = VTABLE_invoke(interpreter, sub, NULL);
/*
* count arguments, check for overflow