Original: Wood Wild Fox, 2006-11-9, reprint please indicate the source.
Previous: IronPython Source Analysis Series (1): IronPython compiler
The execution of the Python program starts with the hosting program Ipy.exe, and his entry point is in the Console class: Class Pythoncommandline {
[STAThread]
static int Main (string [] Rawargs) {
//
Creating a Python engine
engine = new Pythonengine (options);
Creating __MAIN__ Modules
Createmainmodule ();
//
This calls the Run method
Return Run (engine, args = = null Null:args. Count > 0? ARGS[0]: null);
//
}
Run engine
private static int Run (Pythonengine engine, string fileName) {
try {
Input syntax:
Ipy-c "print ' OK '"
if (Consoleoptions.command!= null) {
Python code that executes a string representation directly
Return runstring (engine, Consoleoptions.command);
else if (FileName = = null) {
#if! Ironpython_window
Interactive execution
return runinteractive (engine);
#else
return 0;
#endif
} else {
Execute File Contents
Return Runfile (engine, fileName);
}
catch (System.Threading.ThreadAbortException tae) {
if (Tae. Exceptionstate is pythonkeyboardinterruptexception) {
Thread.resetabort ();
}
return-1;
}
}
}
Here we see that we can execute Python code in three main ways, respectively:
1. Interactive
Specifically, in the command line state, first open a console, and then enter the Python code execution in the shell.
The implementation is as follows: H:/ipy2 > Ipy
IronPython 1.0 (1.0.61005.1977) on. NET 2.0. 50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
>>> print "OK"
Ok
>>>
2. A code fragment that specifies a string representation directly as a parameter executes the
Under the console, enter the following command, performance: h:/ipy2 > ipy-c "print ' OK '"
Ok
H:/ipy2 >
3. Execution through source code files
Commands are as follows: Ipy b.py
Note that this command also has a parameter form as follows: Ipy-i b.py
The result of this command is that after the b.py program executes, a Python shell is automatically opened to allow some action to be done here.
Let's take a look at the execution flow in these cases in turn.
Interactive input (1) and direct execution of the Code fragment (2), the actual process is similar. See following code tracking:
Class Pythoncommandline {
Let Engine execute string command
private static int runstring (Pythonengine engine, string command) {
Some of the initialization actions
//
Perform
Engine. Executetoconsole (command);
//
}
private static int runinteractive (Pythonengine engine) {
Some of the initialization actions
//
result = Runinteractive ();
//
}
private static int runinteractive () {
return Runinteractiveloop ();
}
Loop Executive Console Interaction
private static int Runinteractiveloop () {
bool Continueinteraction = true;
int result = 0;
while (continueinteraction) {
result = Tryinteractiveaction (
Delegate (out bool continueinteractionargument) {
This method reads an interactive input and passes through the Pythonengine,
An attempt was made to parse the input string with Parser. If the failure is terminated
Continueinteractionargument = Dooneinteractive ();
return 0;
},
Out continueinteraction);
}
return result;
}
Do an interaction
public static bool Dooneinteractive () {
BOOL Continueinteraction;
Read a statement and try to parse the
string s = readstatement (out continueinteraction);
//
Performing read-in content
Engine. Executetoconsole (s);
return true;
}
}
OK, here we see the situation 1 and 2 at the same end, all of which are called engine. Executetoconsole (s);
Here's the Pythonengine (Python engine) we can consider as the core scheduler for the entire hosting program.
Now keep looking and see how engine executes the code passed in a string.
public class Pythonengine:idisposable {
Executes a string on the console
public void Executetoconsole (string text, Enginemodule Enginemodule, IDictionary < String, object > Locals) {
Modulescope Modulescope = Getmodulescope (Enginemodule, locals);
Compilercontext context = Defaultcompilercontext ("<stdin>");
Create Parser. Use this Parser to parse the input string.
Parser p = parser.fromstring (Sys, context, text);
BOOL isemptystmt = false;
Parse to statement
Statement s = P.parseinteractiveinput (false, out isemptystmt);
if (s!= null) {
Compiling the Build Code
Compiledcode Compiledcode = Outputgenerator.generatesnippet (context, S, true, false);
Exception ex = null;
If there is a command dispatcher, then give it to him to execute.
The mechanism of the dispatcher allows the code to be executed in another thread, such as the WinForm control,
Instead of fixing it on the console,
if (consolecommanddispatcher!= null) {
Create an anonymous delegate
CallTarget0 RunCode = delegate () {
Running compiled code
try {compiledcode.run (modulescope);} catch (Exception e) {ex = e;}
return null;
};
Handed over to the order dispatcher to execute
Consolecommanddispatcher (RunCode);
We catch and rethrow the exception since it could have been thrown on another thread