Why Python won't work on .net

Duncan Booth duncan at NOSPAMrcp.co.uk
Mon Dec 8 05:17:40 EST 2003


martin at v.loewis.de (Martin v. =?iso-8859-15?q?L=F6wis?=) wrote in 
news:m3isksttf8.fsf at mira.informatik.hu-berlin.de:

> As for generating MSIL byte codes: This is also possible, and has been
> demonstrated. It also has been demonstrated that an initial
> implementation is likely to be *very* slow.
> 
> The question is whether a Python implementation for .NET would be CLS
> compliant (CLS == Common Language Specification). The existing
> implementation has shown that this is not possible without giving up
> parts of the Python semantics.
> 
The main problem is that functions are first class objects in Python, but 
not in the CLS. The CLS uses delegates to refer to functions, and a 
delegate encapsulates both an object and a pointer to a method.

The CLS does have pointers to methods, but the situations in which they can 
be used are limited by the code validator: there are two MSIL code 
sequences which may be used to construct delegates, one for static 
methods, one for non-static, both involve pushing a function pointer onto 
the stack and then calling the delegate constructor, but in neither case 
can the function pointer come from a variable.

To model Python within the environment, you can use a delegate to refer to 
a static function (the object reference is null in this case), or to refer 
to a bound method, but you cannot easily create a delegate to refer to an 
unbound method. This makes any Python code using classes extremely hard to 
model.

The original attempt at porting Python to this environment used the 
reflection classes to get around this. Using reflection you can get objects 
which indirectly reference classes and their methods, you can then create a 
delegate from a System.Reflection.MethodInfo object at the point where the 
unbound method becomes a bound method. Unfortunately, creating a delegate 
from a MethodInfo is a couple of hundred times slower than creating a 
delegate from a pointer to a method.

It is even possible to get a pointer to a method and then create a delegate 
from it entirely within the constraints applied by the code validator, but 
again this uses the Reflection classes and is at least as slow as using the 
MethodInfo object.

I have been playing around with a variant on the managed Python compiler, 
and I think I have figured a way to implement Python which might just get 
around this bottleneck. Unfortunately it requires a lot of refactoring from 
the original model, and I'm only working on it occasionally in my spare 
time. Basically the idea is to compile static wrapper functions for every 
method (at runtime). Obviously this is slow, but at least you only take the 
hit once per class. Every unbound method, or bound method can keep a 
delegate to the static wrapper, and we lose the overhead of the reflection 
classes. Wrapper functions can also wrap constructors.

So far most of my refactoring has been concentrating on replacing the 
original runtime with one based on a class hierarchy and modelling some of 
the more recent Python behaviour. This simplifies and also speeds up the 
code somewhat, although I think I have just about reached the limits I can 
achieve before I do the function wrappers.

-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?




More information about the Python-list mailing list