In the code you have below we should generate everything as collectible code.  
As long as you hold onto the delegate to Run you'll keep all of the code alive. 
 Calling it after the engine is disposed will result in undefined behavior.  
And in this case Run will be generated as a dynamic method (as well as __init__ 
and DoWork).  Run will have a reference to it's module (how it finds Foo) which 
is the reason why all of this will stay alive until you drop the reference to 
Run.

Let me describe our general code collection strategy.  There are two points 
where we will generate non-collectible code.  The first is when you're 
inheriting from a .NET type such as:

class foo(object): pass

In this case we'll generate a subclass of object which overrides virtual 
methods and holds onto a python type object to track it's real type.  We'll 
share the generated type between all types that inherit from object (adding 
__slots__ to a type definition causes more types to get generated).  In your 
sample because you're using old-style classes no code is generated.

The 2nd place where we generate uncollectible code is for modules.  So if you 
have foo.py on disk and you do import foo we'll generate a type for the foo 
module.  This is really just a performance optimization and can be turned off 
in both 1.0 and 2.0 (-X:GenerateAsSnippets command line option in 1.0 and most 
of 2.0, -X:TupleBasedOptimizedScopes in the latest 2.0 builds).  This allows 
the modules to directly access static fields instead of having various values 
in dictionaries.

If you're just sending some code off to a PythonEngine to be compiled though 
we'll use DynamicMethods.  Those methods will be collected when the last 
reference to them goes away.

2.0 uses the same strategy here as 1.0 but when we compile modules in a 
collectibe way they run much faster than in 1.0.

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Masters, 
Christopher
Sent: Friday, February 29, 2008 7:22 AM
To: 'users@lists.ironpython.com'
Subject: [IronPython] Code generation questions

Hi

Sorry if this is documented somewhere but can anyone help me with the following?

If I (in 1.1.1) Execute() a string with code that defines some classes/defs 
methods, how long does the code generated last? For instance if I had the 
following script:

class Foo:
        def __init__(self):
                # ...
        def DoWork(self):
                print "Doing work"

def Run():
        Foo().DoWork()

And I hosted a runtime and executed this via:

using (PythonEngine pe = new PythonEngine())
{
        IronPython.Runtime.Calls.Function0 run;
        pe.Execute(_pack[_pack.Properties["EntryPoint"]]);
        run = (IronPython.Runtime.Calls.Function0)pe.Globals["Run"];
        run.Call();
}

Is Run emitted as a DynamicMethod? What happens to Foo? Is it a generated as a 
CLR type? In which case does it hang around forever?

What if I stored the Function0 reference and executed it later (after the 
PythonEngine is disposed)? Does the Foo type that Run instantiates still exist?

Does anything related to this change in 2.0?

Thanks

Chris

==============================================================================
Please access the attached hyperlink for an important electronic communications 
disclaimer:

http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html
==============================================================================

_______________________________________________
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
_______________________________________________
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

Reply via email to