|parrotcode: Python Proxy Type|
|Contents | Dynamic PMCs|
classes/pyproxytype.pmc - Python Proxy Type
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.
void *invoke(void *next)
invokeon the object without touching any parrot registers... this enables initializers with arguments to be run.
PMC *subclass(STRING *name)