Show EngineModule.cs syntax highlighted
/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for IronPython. A copy of the license can be found in the License.html file
* at the root of this distribution. If you can not locate the Shared Source License
* for IronPython, please send an email to ironpy@microsoft.com.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for IronPython.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Globalization;
using IronMath;
using IronPython.Runtime;
using IronPython.Runtime.Calls;
using IronPython.Runtime.Exceptions;
using IronPython.Runtime.Types;
using IronPython.Compiler;
namespace IronPython.Hosting {
/// <summary>
/// This represents a module created by the host. The host can create multiple EngineModules.
/// Code can then be executed in the EngineModule.
/// </summary>
public class EngineModule
{
IDictionary<string, object> _globals;
IDictionary<string, object> globals
{
get
{
return _globals;
}
set
{
_globals = value;
}
}
IAttributesDictionary globalsAdapter;
ModuleScope defaultModuleScope;
#region Public API
public IDictionary<string, object> Globals { get { return globals; } }
internal PythonModule Module { get { return defaultModuleScope.Module; } }
public string Name { get { return Module.ModuleName; } }
public override string ToString() {
string name = Name;
if (name == String.Empty) name = "<Empty Name>";
return base.ToString() + ":" + name;
}
/// <summary>
/// Usage:
/// engineModule.Import("sys")
/// engineModule.Import("foo.bar")
/// </summary>
public object Import(string moduleName) {
object module = Importer.ImportModule(CallerContext, moduleName, true);
if (module != null) {
string[] names = moduleName.Split('.');
string terminalName = names[names.Length - 1];
globalsAdapter[SymbolTable.StringToId(terminalName)] = module;
}
return module;
}
public bool TrueDivision {
get { return CallerContext.TrueDivision; }
set { CallerContext.TrueDivision = value; }
}
#endregion
internal IAttributesDictionary GlobalsAdapter { get { return globalsAdapter; } }
internal ICallerContext CallerContext { get { return defaultModuleScope; } }
internal ModuleScope GetModuleScope(IDictionary<string, object> locals) {
if (locals == null) {
// We can use defaultModuleScope in this case as we do not need to customize locals
Debug.Assert(defaultModuleScope.Globals == defaultModuleScope.Locals);
return defaultModuleScope;
}
ModuleScope scope = new ModuleScope(defaultModuleScope.Module, globalsAdapter, new StringDictionaryAdapterDict(locals));
return scope;
}
internal EngineModule(ModuleScope scope) {
defaultModuleScope = scope;
globalsAdapter = scope.Globals;
globals = new AttributesDictionaryAdapter(globalsAdapter);
}
internal EngineModule(string moduleName, IDictionary<string, object> globalsDict, SystemState systemState) {
Debug.Assert(moduleName != null);
globals = globalsDict;
if (globals is IAttributesDictionary)
globalsAdapter = globals as IAttributesDictionary;
else
globalsAdapter = new StringDictionaryAdapterDict(globalsDict);
PythonModule pythonModule = new PythonModule(moduleName, globalsAdapter, systemState);
defaultModuleScope = new ModuleScope(pythonModule);
}
}
/// <summary>
/// This represents a module whose global code is optimized. The restriction is that the user
/// cannot specify a globals dictionary of her liking.
/// Further code can be executed in the context of an OptimizedEngineModule. However, this
/// will not be optimized.
/// </summary>
public class OptimizedEngineModule : EngineModule {
bool globalCodeExecuted;
internal OptimizedEngineModule(ModuleScope moduleScope)
: base(moduleScope) {
Debug.Assert(GlobalsAdapter is CompiledModule);
}
/// <summary>
/// This executes the top-level global code of the module
/// </summary>
public void Execute() {
if (globalCodeExecuted)
throw new InvalidOperationException("Cannot execute global code multiple times");
globalCodeExecuted = true;
Module.Initialize();
}
}
}
See more files for this project here