PageRenderTime 54ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/Languages/IronPython/IronPython/Runtime/PythonContext.cs

http://github.com/IronLanguages/main
C# | 4294 lines | 3348 code | 714 blank | 232 comment | 643 complexity | 6d50450b5a5d9ba0929681877a40b566 MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Apache License, Version 2.0, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Apache License, Version 2.0.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if FEATURE_CORE_DLR
  16. using System.Linq.Expressions;
  17. #else
  18. using dynamic = System.Object;
  19. using Microsoft.Scripting.Ast;
  20. #endif
  21. using System;
  22. using System.Collections;
  23. using System.Collections.Generic;
  24. using System.Diagnostics;
  25. using System.Dynamic;
  26. using System.Globalization;
  27. using System.IO;
  28. using System.Linq;
  29. using System.Reflection;
  30. using System.Runtime.CompilerServices;
  31. using System.Security;
  32. using System.Text;
  33. using System.Threading;
  34. using Microsoft.Scripting;
  35. using Microsoft.Scripting.Actions;
  36. using Microsoft.Scripting.Debugging.CompilerServices;
  37. using Microsoft.Scripting.Generation;
  38. using Microsoft.Scripting.Runtime;
  39. using Microsoft.Scripting.Utils;
  40. using IronPython.Compiler;
  41. using IronPython.Hosting;
  42. using IronPython.Modules;
  43. using IronPython.Runtime.Binding;
  44. using IronPython.Runtime.Exceptions;
  45. using IronPython.Runtime.Operations;
  46. using IronPython.Runtime.Types;
  47. using Debugging = Microsoft.Scripting.Debugging;
  48. using PyAst = IronPython.Compiler.Ast;
  49. #if NETCOREAPP1_0
  50. using Environment = System.FakeEnvironment;
  51. #endif
  52. namespace IronPython.Runtime
  53. {
  54. public delegate int HashDelegate(object o, ref HashDelegate dlg);
  55. public sealed partial class PythonContext : LanguageContext {
  56. internal const string/*!*/ IronPythonDisplayName = CurrentVersion.DisplayName;
  57. internal const string/*!*/ IronPythonNames = "IronPython;Python;py";
  58. internal const string/*!*/ IronPythonFileExtensions = ".py";
  59. private static readonly Guid PythonLanguageGuid = new Guid("03ed4b80-d10b-442f-ad9a-47dae85b2051");
  60. private static readonly Guid LanguageVendor_Microsoft = new Guid(-1723120188, -6423, 0x11d2, 0x90, 0x3f, 0, 0xc0, 0x4f, 0xa3, 2, 0xa1);
  61. // fields used during startup
  62. private readonly IDictionary<object, object>/*!*/ _modulesDict = new PythonDictionary();
  63. private readonly Dictionary<string, ModuleGlobalCache>/*!*/ _builtinCache = new Dictionary<string, ModuleGlobalCache>(StringComparer.Ordinal);
  64. private readonly Dictionary<Type, string>/*!*/ _builtinModuleNames = new Dictionary<Type, string>();
  65. private readonly PythonOptions/*!*/ _options;
  66. private readonly PythonModule/*!*/ _systemState;
  67. private readonly Dictionary<string, Type>/*!*/ _builtinModulesDict;
  68. private readonly PythonOverloadResolverFactory _sharedOverloadResolverFactory;
  69. private readonly PythonBinder _binder;
  70. private readonly SysModuleDictionaryStorage _sysDict = new SysModuleDictionaryStorage();
  71. #if FEATURE_FILESYSTEM
  72. #if FEATURE_ASSEMBLY_RESOLVE
  73. private readonly AssemblyResolveHolder _resolveHolder;
  74. #endif
  75. #if !CLR2
  76. private readonly HashSet<Assembly> _loadedAssemblies = new HashSet<Assembly>();
  77. #endif
  78. #endif
  79. private Encoding _defaultEncoding = PythonAsciiEncoding.Instance;
  80. // conditional variables for silverlight/desktop CLR features
  81. private Hosting.PythonService _pythonService;
  82. private string _initialExecutable, _initialPrefix = GetInitialPrefix();
  83. // other fields which might only be conditionally used
  84. private string _initialVersionString;
  85. private PythonModule _clrModule;
  86. private PythonDictionary _builtinDict;
  87. private PythonModule _builtins;
  88. private PythonFileManager _fileManager;
  89. private Dictionary<string, object> _errorHandlers;
  90. private List<object> _searchFunctions;
  91. private Dictionary<object, object> _moduleState;
  92. /// <summary> stored for copy_reg module, used for reduce protocol </summary>
  93. internal BuiltinFunction NewObject;
  94. /// <summary> stored for copy_reg module, used for reduce protocol </summary>
  95. internal BuiltinFunction PythonReconstructor;
  96. private Dictionary<Type, object> _genericSiteStorage;
  97. private CallSite<Func<CallSite, CodeContext, object, object>>[] _newUnarySites;
  98. private CallSite<Func<CallSite, CodeContext, object, object, object, object>>[] _newTernarySites;
  99. private CallSite<Func<CallSite, object, object, int>> _compareSite;
  100. private Dictionary<AttrKey, CallSite<Func<CallSite, object, object, object>>> _setAttrSites;
  101. private Dictionary<AttrKey, CallSite<Action<CallSite, object>>> _deleteAttrSites;
  102. private CallSite<Func<CallSite, CodeContext, object, string, PythonTuple, PythonDictionary, object>> _metaClassSite;
  103. private CallSite<Func<CallSite, CodeContext, object, string, object>> _writeSite;
  104. private CallSite<Func<CallSite, object, object, object>> _getIndexSite, _equalSite;
  105. private CallSite<Action<CallSite, object, object>> _delIndexSite;
  106. private CallSite<Func<CallSite, CodeContext, object, object>> _finalizerSite;
  107. private CallSite<Func<CallSite, CodeContext, PythonFunction, object>> _functionCallSite;
  108. private CallSite<Func<CallSite, object, object, bool>> _greaterThanSite, _lessThanSite, _greaterThanEqualSite, _lessThanEqualSite, _containsSite;
  109. private CallSite<Func<CallSite, CodeContext, object, object[], object>> _callSplatSite;
  110. private CallSite<Func<CallSite, CodeContext, object, object[], IDictionary<object, object>, object>> _callDictSite;
  111. private CallSite<Func<CallSite, CodeContext, object, object, object, object>> _callDictSiteLooselyTyped;
  112. private CallSite<Func<CallSite, CodeContext, object, string, PythonDictionary, PythonDictionary, PythonTuple, int, object>> _importSite;
  113. private CallSite<Func<CallSite, CodeContext, object, string, PythonDictionary, PythonDictionary, PythonTuple, object>> _oldImportSite;
  114. private CallSite<Func<CallSite, object, bool>> _isCallableSite;
  115. private CallSite<Func<CallSite, object, IList<string>>> _getSignaturesSite;
  116. private CallSite<Func<CallSite, object, object, object>> _addSite, _divModSite, _rdivModSite;
  117. private CallSite<Func<CallSite, object, object, object, object>> _setIndexSite, _delSliceSite;
  118. private CallSite<Func<CallSite, object, object, object, object, object>> _setSliceSite;
  119. private CallSite<Func<CallSite, object, string>> _docSite;
  120. // conversion sites
  121. private CallSite<Func<CallSite, object, int>> _intSite;
  122. private CallSite<Func<CallSite, object, string>> _tryStringSite;
  123. private CallSite<Func<CallSite, object, object>> _tryIntSite;
  124. private CallSite<Func<CallSite, object, IEnumerable>> _tryIEnumerableSite;
  125. private Dictionary<Type, CallSite<Func<CallSite, object, object>>> _implicitConvertSites;
  126. private Dictionary<PythonOperationKind, CallSite<Func<CallSite, object, object, object>>> _binarySites;
  127. private Dictionary<Type, DefaultPythonComparer> _defaultComparer;
  128. private CallSite<Func<CallSite, CodeContext, object, object, object, int>> _sharedFunctionCompareSite;
  129. private CallSite<Func<CallSite, CodeContext, PythonFunction, object, object, int>> _sharedPythonFunctionCompareSite;
  130. private CallSite<Func<CallSite, CodeContext, BuiltinFunction, object, object, int>> _sharedBuiltinFunctionCompareSite;
  131. private CallSite<Func<CallSite, CodeContext, object, int, object>> _getItemCallSite;
  132. private CallSite<Func<CallSite, CodeContext, object, object, object>> _propGetSite, _propDelSite;
  133. private CallSite<Func<CallSite, CodeContext, object, object, object, object>> _propSetSite;
  134. private CompiledLoader _compiledLoader;
  135. internal bool _importWarningThrows;
  136. private bool _importedEncodings;
  137. private Action<Action> _commandDispatcher; // can be null
  138. private ClrModule.ReferencesList _referencesList;
  139. private FloatFormat _floatFormat, _doubleFormat;
  140. private CultureInfo _collateCulture, _ctypeCulture, _timeCulture, _monetaryCulture, _numericCulture;
  141. private CodeContext _defaultContext, _defaultClsContext;
  142. private readonly TopNamespaceTracker _topNamespace;
  143. private readonly IEqualityComparer<object> _equalityComparer;
  144. private readonly IEqualityComparer _equalityComparerNonGeneric;
  145. private Dictionary<Type, CallSite<Func<CallSite, object, object, bool>>> _equalSites;
  146. private Dictionary<Type, PythonSiteCache> _systemSiteCache;
  147. internal static object _syntaxErrorNoCaret = new object();
  148. // atomized binders
  149. private PythonInvokeBinder _invokeNoArgs, _invokeOneArg;
  150. private Dictionary<CallSignature, PythonInvokeBinder/*!*/> _invokeBinders;
  151. private Dictionary<string/*!*/, PythonGetMemberBinder/*!*/> _getMemberBinders;
  152. private Dictionary<string/*!*/, PythonGetMemberBinder/*!*/> _tryGetMemberBinders;
  153. private Dictionary<string/*!*/, PythonSetMemberBinder/*!*/> _setMemberBinders;
  154. private Dictionary<string/*!*/, PythonDeleteMemberBinder/*!*/> _deleteMemberBinders;
  155. private Dictionary<string/*!*/, CompatibilityGetMember/*!*/> _compatGetMember;
  156. private Dictionary<string/*!*/, CompatibilityGetMember/*!*/> _compatGetMemberNoThrow;
  157. private Dictionary<PythonOperationKind, PythonOperationBinder/*!*/> _operationBinders;
  158. private Dictionary<ExpressionType, PythonUnaryOperationBinder/*!*/> _unaryBinders;
  159. private PythonBinaryOperationBinder[] _binaryBinders;
  160. private Dictionary<OperationRetTypeKey<ExpressionType>, BinaryRetTypeBinder/*!*/> _binaryRetTypeBinders;
  161. private Dictionary<OperationRetTypeKey<PythonOperationKind>, BinaryRetTypeBinder/*!*/> _operationRetTypeBinders;
  162. private Dictionary<Type/*!*/, PythonConversionBinder/*!*/>[] _conversionBinders;
  163. private Dictionary<Type/*!*/, DynamicMetaObjectBinder/*!*/>[] _convertRetObjectBinders;
  164. private Dictionary<CallSignature, CreateFallback/*!*/> _createBinders;
  165. private Dictionary<CallSignature, CompatibilityInvokeBinder/*!*/> _compatInvokeBinders;
  166. private PythonGetSliceBinder _getSlice;
  167. private PythonSetSliceBinder _setSlice;
  168. private PythonDeleteSliceBinder _deleteSlice;
  169. private PythonGetIndexBinder[] _getIndexBinders;
  170. private PythonSetIndexBinder[] _setIndexBinders;
  171. private PythonDeleteIndexBinder[] _deleteIndexBinders;
  172. private DynamicMetaObjectBinder _invokeTwoConvertToInt;
  173. private static CultureInfo _CCulture;
  174. private DynamicDelegateCreator _delegateCreator;
  175. // tracing / in-proc debugging support
  176. private DebugContext _debugContext;
  177. private Debugging.TracePipeline _tracePipeline;
  178. private readonly Microsoft.Scripting.Utils.ThreadLocal<PythonTracebackListener> _tracebackListeners = new Microsoft.Scripting.Utils.ThreadLocal<PythonTracebackListener>();
  179. private int _tracebackListenersCount;
  180. internal FunctionCode.CodeList _allCodes;
  181. internal readonly object _codeCleanupLock = new object(), _codeUpdateLock = new object();
  182. internal int _codeCount, _nextCodeCleanup = 200;
  183. private int _recursionLimit;
  184. internal readonly List<FunctionStack> _mainThreadFunctionStack;
  185. private CallSite<Func<CallSite, CodeContext, object, object>> _callSite0LightEh;
  186. private List<WeakReference> _weakExtensionMethodSets;
  187. // store the Python types mapping to each .NET type
  188. private CommonDictionaryStorage _systemPythonTypesWeakRefs = new CommonDictionaryStorage();
  189. #region Generated Python Shared Call Sites Storage
  190. // *** BEGIN GENERATED CODE ***
  191. // generated by function: gen_shared_call_sites_storage from: generate_calls.py
  192. private CallSite<Func<CallSite, CodeContext, object, object>> _callSite0;
  193. private CallSite<Func<CallSite, CodeContext, object, object, object>> _callSite1;
  194. private CallSite<Func<CallSite, CodeContext, object, object, object, object>> _callSite2;
  195. private CallSite<Func<CallSite, CodeContext, object, object, object, object, object>> _callSite3;
  196. private CallSite<Func<CallSite, CodeContext, object, object, object, object, object, object>> _callSite4;
  197. private CallSite<Func<CallSite, CodeContext, object, object, object, object, object, object, object>> _callSite5;
  198. private CallSite<Func<CallSite, CodeContext, object, object, object, object, object, object, object, object>> _callSite6;
  199. // *** END GENERATED CODE ***
  200. #endregion
  201. /// <summary>
  202. /// Creates a new PythonContext not bound to Engine.
  203. /// </summary>
  204. public PythonContext(ScriptDomainManager/*!*/ manager, IDictionary<string, object> options)
  205. : base(manager) {
  206. _options = new PythonOptions(options);
  207. _builtinModulesDict = CreateBuiltinTable();
  208. PythonDictionary defaultScope = new PythonDictionary();
  209. ModuleContext modContext = new ModuleContext(defaultScope, this);
  210. _defaultContext = modContext.GlobalContext;
  211. PythonDictionary sysDict = new PythonDictionary(_sysDict);
  212. _systemState = new PythonModule(sysDict);
  213. _systemState.__dict__["__name__"] = "sys";
  214. _systemState.__dict__["__package__"] = null;
  215. PythonBinder binder = new PythonBinder(this, _defaultContext);
  216. _sharedOverloadResolverFactory = new PythonOverloadResolverFactory(binder, Expression.Constant(_defaultContext));
  217. _binder = binder;
  218. CodeContext defaultClsContext = DefaultContext.CreateDefaultCLSContext(this);
  219. _defaultClsContext = defaultClsContext;
  220. if (DefaultContext._default == null) {
  221. DefaultContext.InitializeDefaults(_defaultContext, defaultClsContext);
  222. }
  223. InitializeBuiltins();
  224. InitializeSystemState();
  225. #if SILVERLIGHT
  226. AddToPath("");
  227. #endif
  228. // sys.argv always includes at least one empty string.
  229. SetSystemStateValue("argv", (_options.Arguments.Count == 0) ?
  230. new List(new object[] { String.Empty }) :
  231. new List(_options.Arguments)
  232. );
  233. if (_options.WarningFilters.Count > 0) {
  234. _systemState.__dict__["warnoptions"] = new List(_options.WarningFilters);
  235. }
  236. if (_options.Frames) {
  237. var getFrame = BuiltinFunction.MakeFunction(
  238. "_getframe",
  239. ArrayUtils.ConvertAll(typeof(SysModule).GetMember("_getframeImpl"), (x) => (MethodBase)x),
  240. typeof(SysModule)
  241. );
  242. _systemState.__dict__["_getframe"] = getFrame;
  243. }
  244. if (_options.Tracing) {
  245. EnsureDebugContext();
  246. }
  247. List path = new List(_options.SearchPaths);
  248. #if FEATURE_ASSEMBLY_RESOLVE && FEATURE_FILESYSTEM
  249. _resolveHolder = new AssemblyResolveHolder(this);
  250. try {
  251. Assembly entryAssembly = Assembly.GetEntryAssembly();
  252. // Can be null if called from unmanaged code (VS integration scenario)
  253. if (entryAssembly != null) {
  254. string entry = Path.GetDirectoryName(entryAssembly.Location);
  255. string lib = Path.Combine(entry, "Lib");
  256. path.append(lib);
  257. // add DLLs directory for user-defined extention modules
  258. path.append(Path.Combine(entry, "DLLs"));
  259. #if DEBUG
  260. // For developer use, add External.LCA_RESTRICTED/Languages/IronPython/27/Lib
  261. string devStdLib = Path.GetFullPath(Path.Combine(entry, @"../../External.LCA_RESTRICTED/Languages/IronPython/27/Lib"));
  262. if (Directory.Exists(devStdLib))
  263. path.append(devStdLib);
  264. #endif
  265. }
  266. } catch (SecurityException) {
  267. }
  268. #endif
  269. _systemState.__dict__["path"] = path;
  270. RecursionLimit = _options.RecursionLimit;
  271. #if FEATURE_ASSEMBLY_RESOLVE && FEATURE_FILESYSTEM
  272. object asmResolve;
  273. if (options == null ||
  274. !options.TryGetValue("NoAssemblyResolveHook", out asmResolve) ||
  275. !System.Convert.ToBoolean(asmResolve)) {
  276. try {
  277. HookAssemblyResolve();
  278. } catch (System.Security.SecurityException) {
  279. // We may not have SecurityPermissionFlag.ControlAppDomain.
  280. // If so, we will not look up sys.path for module loads
  281. }
  282. }
  283. #endif
  284. _equalityComparer = new PythonEqualityComparer(this);
  285. _equalityComparerNonGeneric = (IEqualityComparer)_equalityComparer;
  286. InitialHasher = InitialHasherImpl;
  287. IntHasher = IntHasherImpl;
  288. DoubleHasher = DoubleHasherImpl;
  289. StringHasher = StringHasherImpl;
  290. FallbackHasher = FallbackHasherImpl;
  291. _topNamespace = new TopNamespaceTracker(manager);
  292. foreach (Assembly asm in manager.GetLoadedAssemblyList()) {
  293. _topNamespace.LoadAssembly(asm);
  294. }
  295. manager.AssemblyLoaded += new EventHandler<AssemblyLoadedEventArgs>(ManagerAssemblyLoaded);
  296. _mainThreadFunctionStack = PythonOps.GetFunctionStack();
  297. }
  298. void ManagerAssemblyLoaded(object sender, AssemblyLoadedEventArgs e) {
  299. _topNamespace.LoadAssembly(e.Assembly);
  300. }
  301. /// <summary>
  302. /// Gets or sets the maximum depth of function calls. Equivalent to sys.getrecursionlimit
  303. /// and sys.setrecursionlimit.
  304. /// </summary>
  305. public int RecursionLimit {
  306. get {
  307. return _recursionLimit;
  308. }
  309. set {
  310. if (value < 0) {
  311. throw PythonOps.ValueError("recursion limit must be positive");
  312. }
  313. lock (_codeUpdateLock) {
  314. _recursionLimit = value;
  315. if ((_recursionLimit == Int32.MaxValue) != (value == Int32.MaxValue)) {
  316. // recursion setting has changed, we need to update all of our
  317. // function codes to enforce or un-enforce recursion.
  318. FunctionCode.UpdateAllCode(this);
  319. }
  320. }
  321. }
  322. }
  323. internal bool EnableTracing {
  324. get {
  325. return PythonOptions.Tracing || _tracebackListenersCount > 0;
  326. }
  327. }
  328. internal TopNamespaceTracker TopNamespace {
  329. get {
  330. return _topNamespace;
  331. }
  332. }
  333. #if FEATURE_THREAD
  334. /// <summary>
  335. /// Gets or sets the main thread which should be interupted by thread.interrupt_main
  336. /// </summary>
  337. public Thread MainThread {
  338. get {
  339. return _mainThread;
  340. }
  341. set {
  342. _mainThread = value;
  343. }
  344. }
  345. private Thread _mainThread;
  346. #endif
  347. public IEqualityComparer<object>/*!*/ EqualityComparer {
  348. get { return _equalityComparer; }
  349. }
  350. public IEqualityComparer/*!*/ EqualityComparerNonGeneric {
  351. get { return _equalityComparerNonGeneric; }
  352. }
  353. internal sealed class PythonEqualityComparer : IEqualityComparer, IEqualityComparer<object> {
  354. public readonly PythonContext/*!*/ Context;
  355. public PythonEqualityComparer(PythonContext/*!*/ context) {
  356. Assert.NotNull(context);
  357. Context = context;
  358. }
  359. bool IEqualityComparer.Equals(object x, object y) {
  360. return PythonOps.EqualRetBool(Context._defaultContext, x, y);
  361. }
  362. bool IEqualityComparer<object>.Equals(object x, object y) {
  363. return PythonOps.EqualRetBool(Context._defaultContext, x, y);
  364. }
  365. int IEqualityComparer.GetHashCode(object obj) {
  366. return PythonContext.Hash(obj);
  367. }
  368. int IEqualityComparer<object>.GetHashCode(object obj) {
  369. return PythonContext.Hash(obj);
  370. }
  371. }
  372. #region Specialized Hashers
  373. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  374. internal readonly HashDelegate InitialHasher;
  375. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  376. internal readonly HashDelegate IntHasher;
  377. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  378. internal readonly HashDelegate DoubleHasher;
  379. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  380. internal readonly HashDelegate StringHasher;
  381. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
  382. internal readonly HashDelegate FallbackHasher;
  383. private int InitialHasherImpl(object o, ref HashDelegate dlg) {
  384. if (o == null) {
  385. return NoneTypeOps.NoneHashCode;
  386. }
  387. switch (o.GetType().GetTypeCode()) {
  388. case TypeCode.String:
  389. dlg = StringHasher;
  390. return StringHasher(o, ref dlg);
  391. case TypeCode.Int32:
  392. dlg = IntHasher;
  393. return IntHasher(o, ref dlg);
  394. case TypeCode.Double:
  395. dlg = DoubleHasher;
  396. return DoubleHasher(o, ref dlg);
  397. default:
  398. if (o is IPythonObject) {
  399. dlg = new OptimizedUserHasher(this, ((IPythonObject)o).PythonType).Hasher;
  400. } else {
  401. dlg = new OptimizedBuiltinHasher(this, o.GetType()).Hasher;
  402. }
  403. return dlg(o, ref dlg);
  404. }
  405. }
  406. private int IntHasherImpl(object o, ref HashDelegate dlg) {
  407. if (o != null && o.GetType() == typeof(int)) {
  408. return o.GetHashCode();
  409. }
  410. dlg = FallbackHasher;
  411. return FallbackHasher(o, ref dlg);
  412. }
  413. private int DoubleHasherImpl(object o, ref HashDelegate dlg) {
  414. if (o != null && o.GetType() == typeof(double)) {
  415. return DoubleOps.__hash__((double)o);
  416. }
  417. dlg = FallbackHasher;
  418. return FallbackHasher(o, ref dlg);
  419. }
  420. private int StringHasherImpl(object o, ref HashDelegate dlg) {
  421. if (o != null && o.GetType() == typeof(string)) {
  422. return o.GetHashCode();
  423. }
  424. dlg = FallbackHasher;
  425. return FallbackHasher(o, ref dlg);
  426. }
  427. private int FallbackHasherImpl(object o, ref HashDelegate dlg) {
  428. return PythonOps.Hash(this.SharedContext, o);
  429. }
  430. private sealed class OptimizedUserHasher {
  431. private readonly PythonContext _context;
  432. private readonly PythonType _pt;
  433. public OptimizedUserHasher(PythonContext context, PythonType pt) {
  434. _context = context;
  435. _pt = pt;
  436. }
  437. public int Hasher(object o, ref HashDelegate dlg) {
  438. IPythonObject ipo = o as IPythonObject;
  439. if (ipo != null && ipo.PythonType == _pt) {
  440. return _pt.Hash(o);
  441. }
  442. dlg = _context.FallbackHasher;
  443. return _context.FallbackHasher(o, ref dlg);
  444. }
  445. }
  446. private sealed class OptimizedBuiltinHasher {
  447. private readonly PythonContext _context;
  448. private readonly Type _type;
  449. private readonly PythonType _pt;
  450. public OptimizedBuiltinHasher(PythonContext context, Type type) {
  451. _context = context;
  452. _type = type;
  453. _pt = DynamicHelpers.GetPythonTypeFromType(type);
  454. }
  455. public int Hasher(object o, ref HashDelegate dlg) {
  456. if (o != null && o.GetType() == _type) {
  457. return _pt.Hash(o);
  458. }
  459. dlg = _context.FallbackHasher;
  460. return _context.FallbackHasher(o, ref dlg);
  461. }
  462. }
  463. #endregion
  464. public override LanguageOptions/*!*/ Options {
  465. get { return PythonOptions; }
  466. }
  467. /// <summary>
  468. /// Checks to see if module state has the current value stored already.
  469. /// </summary>
  470. public bool HasModuleState(object key) {
  471. EnsureModuleState();
  472. lock (_moduleState) {
  473. return _moduleState.ContainsKey(key);
  474. }
  475. }
  476. private void EnsureModuleState() {
  477. if (_moduleState == null) {
  478. Interlocked.CompareExchange(ref _moduleState, new Dictionary<object, object>(), null);
  479. }
  480. }
  481. /// <summary>
  482. /// Gets per-runtime state used by a module. The module should have a unique key for
  483. /// each piece of state it needs to store.
  484. /// </summary>
  485. public object GetModuleState(object key) {
  486. EnsureModuleState();
  487. lock (_moduleState) {
  488. Debug.Assert(_moduleState.ContainsKey(key));
  489. return _moduleState[key];
  490. }
  491. }
  492. /// <summary>
  493. /// Sets per-runtime state used by a module. The module should have a unique key for
  494. /// each piece of state it needs to store.
  495. /// </summary>
  496. public void SetModuleState(object key, object value) {
  497. EnsureModuleState();
  498. lock (_moduleState) {
  499. _moduleState[key] = value;
  500. }
  501. }
  502. /// <summary>
  503. /// Sets per-runtime state used by a module and returns the previous value. The module
  504. /// should have a unique key for each piece of state it needs to store.
  505. /// </summary>
  506. public object GetSetModuleState(object key, object value) {
  507. EnsureModuleState();
  508. lock (_moduleState) {
  509. object result;
  510. _moduleState.TryGetValue(key, out result);
  511. _moduleState[key] = value;
  512. return result;
  513. }
  514. }
  515. /// <summary>
  516. /// Sets per-runtime state used by a module and returns the previous value. The module
  517. /// should have a unique key for each piece of state it needs to store.
  518. /// </summary>
  519. public T GetOrCreateModuleState<T>(object key, Func<T> value) where T : class {
  520. EnsureModuleState();
  521. lock (_moduleState) {
  522. object result;
  523. if (!_moduleState.TryGetValue(key, out result)) {
  524. _moduleState[key] = result = value();
  525. }
  526. return (result as T);
  527. }
  528. }
  529. public PythonType EnsureModuleException(object key, PythonDictionary dict, string name, string module) {
  530. return (PythonType)(dict[name] = GetOrCreateModuleState(
  531. key,
  532. () => PythonExceptions.CreateSubType(this, PythonExceptions.Exception, name, module, null, PythonType.DefaultMakeException)
  533. ));
  534. }
  535. public PythonType EnsureModuleException(object key, PythonType baseType, PythonDictionary dict, string name, string module) {
  536. return (PythonType)(dict[name] = GetOrCreateModuleState(
  537. key,
  538. () => PythonExceptions.CreateSubType(this, baseType, name, module, null, PythonType.DefaultMakeException)
  539. ));
  540. }
  541. public PythonType EnsureModuleException(object key, PythonType baseType, Type underlyingType, PythonDictionary dict, string name, string module, Func<string, Exception> exceptionMaker) {
  542. return (PythonType)(dict[name] = GetOrCreateModuleState(
  543. key,
  544. () => PythonExceptions.CreateSubType(this, baseType, underlyingType, name, module, null, exceptionMaker)
  545. ));
  546. }
  547. public PythonType EnsureModuleException(object key, PythonType[] baseTypes, Type underlyingType, PythonDictionary dict, string name, string module) {
  548. return (PythonType)(dict[name] = GetOrCreateModuleState(
  549. key,
  550. () => PythonExceptions.CreateSubType(this, baseTypes, underlyingType, name, module, null, PythonType.DefaultMakeException)
  551. ));
  552. }
  553. internal PythonOptions/*!*/ PythonOptions {
  554. get {
  555. return _options;
  556. }
  557. }
  558. public override Guid VendorGuid {
  559. get {
  560. return LanguageVendor_Microsoft;
  561. }
  562. }
  563. public override Guid LanguageGuid {
  564. get {
  565. return PythonLanguageGuid;
  566. }
  567. }
  568. public PythonModule/*!*/ SystemState {
  569. get {
  570. return _systemState;
  571. }
  572. }
  573. public PythonModule/*!*/ ClrModule {
  574. get {
  575. if (_clrModule == null) {
  576. Interlocked.CompareExchange(ref _clrModule, CreateBuiltinModule("clr"), null);
  577. }
  578. return _clrModule;
  579. }
  580. }
  581. internal bool TryGetSystemPath(out List path) {
  582. object val;
  583. if (SystemState.__dict__.TryGetValue("path", out val)) {
  584. path = val as List;
  585. } else {
  586. path = null;
  587. }
  588. return path != null;
  589. }
  590. internal object SystemStandardOut {
  591. get {
  592. return GetSystemStateValue("stdout");
  593. }
  594. }
  595. internal object SystemStandardIn {
  596. get {
  597. return GetSystemStateValue("stdin");
  598. }
  599. }
  600. internal object SystemStandardError {
  601. get {
  602. return GetSystemStateValue("stderr");
  603. }
  604. }
  605. internal IDictionary<object, object> SystemStateModules {
  606. get {
  607. return _modulesDict;
  608. }
  609. }
  610. internal void UpdateExceptionInfo(object type, object value, object traceback) {
  611. _sysDict.UpdateExceptionInfo(type, value, traceback);
  612. }
  613. internal void UpdateExceptionInfo(Exception clrException, object type, object value, List<DynamicStackFrame> traceback) {
  614. _sysDict.UpdateExceptionInfo(clrException, type, value, traceback);
  615. }
  616. internal void ExceptionHandled() {
  617. _sysDict.ExceptionHandled();
  618. }
  619. internal PythonModule GetModuleByName(string/*!*/ name) {
  620. Assert.NotNull(name);
  621. object scopeObj;
  622. PythonModule module;
  623. if (SystemStateModules.TryGetValue(name, out scopeObj) && (module = scopeObj as PythonModule) != null) {
  624. return module;
  625. }
  626. return null;
  627. }
  628. internal PythonModule GetModuleByPath(string/*!*/ path) {
  629. Assert.NotNull(path);
  630. foreach (object moduleObj in SystemStateModules.Values) {
  631. PythonModule module = moduleObj as PythonModule;
  632. if (module != null) {
  633. if (DomainManager.Platform.PathComparer.Compare(module.GetFile(), path) == 0) {
  634. return module;
  635. }
  636. }
  637. }
  638. return null;
  639. }
  640. public override Version LanguageVersion {
  641. get {
  642. // Assembly.GetName() can't be called in Silverlight...
  643. return GetPythonVersion();
  644. }
  645. }
  646. internal static Version GetPythonVersion() {
  647. return new AssemblyName(typeof(PythonContext).GetTypeInfo().Assembly.FullName).Version;
  648. }
  649. internal FloatFormat FloatFormat {
  650. get {
  651. return _floatFormat;
  652. }
  653. set {
  654. _floatFormat = value;
  655. }
  656. }
  657. internal FloatFormat DoubleFormat {
  658. get {
  659. return _doubleFormat;
  660. }
  661. set {
  662. _doubleFormat = value;
  663. }
  664. }
  665. /// <summary>
  666. /// Initializes the sys module on startup. Called both to load and reload sys
  667. /// </summary>
  668. private void InitializeSystemState() {
  669. // These fields do not get reset on "reload(sys)", we populate them once on startup
  670. SetSystemStateValue("argv", List.FromArrayNoCopy(new object[] { String.Empty }));
  671. SetSystemStateValue("modules", _modulesDict);
  672. InitializeSysFlags();
  673. _modulesDict["sys"] = _systemState;
  674. SetSystemStateValue("path", new List(3));
  675. SetStandardIO();
  676. SysModule.PerformModuleReload(this, _systemState.__dict__);
  677. }
  678. internal bool EmitDebugSymbols(SourceUnit sourceUnit) {
  679. return sourceUnit.EmitDebugSymbols && (PythonOptions.NoDebug == null || !PythonOptions.NoDebug.IsMatch(sourceUnit.Path));
  680. }
  681. private void InitializeSysFlags() {
  682. // sys.flags
  683. SysModule.SysFlags flags = new SysModule.SysFlags();
  684. SetSystemStateValue("flags", flags);
  685. flags.debug = _options.Debug ? 1 : 0;
  686. flags.py3k_warning = _options.WarnPython30 ? 1 : 0;
  687. SetSystemStateValue("py3kwarning", _options.WarnPython30);
  688. switch (_options.DivisionOptions) {
  689. case PythonDivisionOptions.Old:
  690. break;
  691. case PythonDivisionOptions.New:
  692. flags.division_new = 1;
  693. break;
  694. case PythonDivisionOptions.Warn:
  695. flags.division_warning = 1;
  696. break;
  697. case PythonDivisionOptions.WarnAll:
  698. flags.division_warning = 2;
  699. break;
  700. }
  701. flags.inspect = flags.interactive = _options.Inspect ? 1 : 0;
  702. if (_options.StripDocStrings) {
  703. flags.optimize = 2;
  704. } else if (_options.Optimize) {
  705. flags.optimize = 1;
  706. }
  707. flags.dont_write_bytecode = 1;
  708. SetSystemStateValue("dont_write_bytecode", true);
  709. flags.no_user_site = _options.NoUserSite ? 1 : 0;
  710. flags.no_site = _options.NoSite ? 1 : 0;
  711. flags.ignore_environment = _options.IgnoreEnvironment ? 1 : 0;
  712. switch (_options.IndentationInconsistencySeverity) {
  713. case Severity.Warning:
  714. flags.tabcheck = 1;
  715. break;
  716. case Severity.Error:
  717. flags.tabcheck = 2;
  718. break;
  719. }
  720. flags.verbose = _options.Verbose ? 1 : 0;
  721. flags.unicode = 1;
  722. flags.bytes_warning = _options.BytesWarning ? 1 : 0;
  723. }
  724. internal bool ShouldInterpret(PythonCompilerOptions options, SourceUnit source) {
  725. // We have to turn off adaptive compilation in debug mode to
  726. // support mangaged debuggers. Also turn off in optimized mode.
  727. bool adaptiveCompilation = !_options.NoAdaptiveCompilation && !EmitDebugSymbols(source);
  728. return options.Interpreted || adaptiveCompilation;
  729. }
  730. private static PyAst.PythonAst ParseAndBindAst(CompilerContext context) {
  731. ScriptCodeParseResult properties = ScriptCodeParseResult.Complete;
  732. bool propertiesSet = false;
  733. int errorCode = 0;
  734. PyAst.PythonAst ast;
  735. using (Parser parser = Parser.CreateParser(context, PythonContext.GetPythonOptions(null))) {
  736. switch (context.SourceUnit.Kind) {
  737. case SourceCodeKind.InteractiveCode:
  738. ast = parser.ParseInteractiveCode(out properties);
  739. propertiesSet = true;
  740. break;
  741. case SourceCodeKind.Expression:
  742. ast = parser.ParseTopExpression();
  743. break;
  744. case SourceCodeKind.SingleStatement:
  745. ast = parser.ParseSingleStatement();
  746. break;
  747. case SourceCodeKind.File:
  748. ast = parser.ParseFile(true, false);
  749. break;
  750. case SourceCodeKind.Statements:
  751. ast = parser.ParseFile(false, false);
  752. break;
  753. default:
  754. case SourceCodeKind.AutoDetect:
  755. ast = parser.ParseFile(true, true);
  756. break;
  757. }
  758. errorCode = parser.ErrorCode;
  759. }
  760. if (!propertiesSet && errorCode != 0) {
  761. properties = ScriptCodeParseResult.Invalid;
  762. }
  763. context.SourceUnit.CodeProperties = properties;
  764. if (errorCode != 0 || properties == ScriptCodeParseResult.Empty) {
  765. return null;
  766. }
  767. ast.Bind();
  768. return ast;
  769. }
  770. internal static ScriptCode CompilePythonCode(SourceUnit/*!*/ sourceUnit, CompilerOptions/*!*/ options, ErrorSink/*!*/ errorSink) {
  771. var pythonOptions = (PythonCompilerOptions)options;
  772. if (sourceUnit.Kind == SourceCodeKind.File) {
  773. pythonOptions.Module |= ModuleOptions.Initialize;
  774. }
  775. CompilerContext context = new CompilerContext(sourceUnit, options, errorSink);
  776. PyAst.PythonAst ast = ParseAndBindAst(context);
  777. if (ast == null) {
  778. return null;
  779. }
  780. return ast.ToScriptCode();
  781. }
  782. public override ScriptCode CompileSourceCode(SourceUnit/*!*/ sourceUnit, CompilerOptions/*!*/ options, ErrorSink/*!*/ errorSink) {
  783. ScriptCode res = CompilePythonCode(sourceUnit, options, errorSink);
  784. if (res != null) {
  785. Scope scope = res.CreateScope();
  786. // if this is an optimized module we need to initialize the optimized scope.
  787. // Optimized scopes come w/ extensions already attached so we use that to know
  788. // if we're optimized or not.
  789. PythonScopeExtension scopeExtension = (PythonScopeExtension)scope.GetExtension(ContextId);
  790. if (scopeExtension != null) {
  791. InitializeModule(sourceUnit.Path, scopeExtension.ModuleContext, res, ModuleOptions.None);
  792. }
  793. }
  794. return res;
  795. }
  796. public override ScriptCode/*!*/ LoadCompiledCode(Delegate/*!*/ method, string path, string customData) {
  797. SourceUnit su = new SourceUnit(this, NullTextContentProvider.Null, path, SourceCodeKind.File);
  798. return new OnDiskScriptCode((LookupCompilationDelegate)method, su, customData);
  799. }
  800. public override SourceCodeReader/*!*/ GetSourceReader(Stream/*!*/ stream, Encoding/*!*/ defaultEncoding, string path) {
  801. ContractUtils.RequiresNotNull(stream, "stream");
  802. ContractUtils.RequiresNotNull(defaultEncoding, "defaultEncoding");
  803. ContractUtils.Requires(stream.CanSeek && stream.CanRead, "stream", "The stream must support seeking and reading");
  804. // we choose ASCII by default, if the file has a Unicode header though
  805. // we'll automatically get it as unicode.
  806. Encoding encoding = PythonAsciiEncoding.SourceEncoding;
  807. long startPosition = stream.Position;
  808. StreamReader sr = new StreamReader(stream, PythonAsciiEncoding.SourceEncoding);
  809. byte[] bomBuffer = new byte[3];
  810. int bomRead = stream.Read(bomBuffer, 0, 3);
  811. int bytesRead = 0;
  812. bool isUtf8 = false;
  813. if (bomRead == 3 && (bomBuffer[0] == 0xef && bomBuffer[1] == 0xbb && bomBuffer[2] == 0xbf)) {
  814. isUtf8 = true;
  815. bytesRead = 3;
  816. } else {
  817. stream.Seek(0, SeekOrigin.Begin);
  818. }
  819. string line;
  820. try {
  821. line = ReadOneLine(sr, ref bytesRead);
  822. } catch (BadSourceException) {
  823. throw ReportEncodingError(stream, path);
  824. }
  825. bool gotEncoding = false;
  826. string encodingName = null;
  827. // magic encoding must be on line 1 or 2
  828. if (line != null && !(gotEncoding = Tokenizer.TryGetEncoding(defaultEncoding, line, ref encoding, out encodingName))) {
  829. try {
  830. line = ReadOneLine(sr, ref bytesRead);
  831. } catch (BadSourceException) {
  832. throw ReportEncodingError(stream, path);
  833. }
  834. if (line != null) {
  835. gotEncoding = Tokenizer.TryGetEncoding(defaultEncoding, line, ref encoding, out encodingName);
  836. }
  837. }
  838. if (gotEncoding && isUtf8 && encodingName != "utf-8") {
  839. // we have both a BOM & an encoding type, throw an error
  840. throw new IOException("file has both Unicode marker and PEP-263 file encoding. You can only use \"utf-8\" as the encoding name when a BOM is present.");
  841. } else if (encoding == null) {
  842. throw new IOException("unknown encoding type");
  843. }
  844. // if we didn't get an encoding seek back to the beginning...
  845. if (!gotEncoding || stream.Position != stream.Length) {
  846. stream.Seek(startPosition, SeekOrigin.Begin);
  847. }
  848. // re-read w/ the correct encoding type...
  849. return new SourceCodeReader(new StreamReader(stream, encoding), encoding);
  850. }
  851. internal static Exception ReportEncodingError(Stream stream, string path) {
  852. stream.Seek(0, SeekOrigin.Begin);
  853. byte[] buffer = new byte[1024];
  854. int bytesRead = 0;
  855. int curLine = 1, curOffset = 1, index = 0;
  856. while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != -1) {
  857. for (int i = 0; i < bytesRead; i++) {
  858. if (buffer[i] > 0x7f) {
  859. return PythonOps.BadSourceError(
  860. buffer[i],
  861. new SourceSpan(
  862. new SourceLocation(index, curLine, curOffset),
  863. new SourceLocation(index, curLine, curOffset)
  864. ),
  865. path
  866. );
  867. } else if (buffer[i] == '\n') {
  868. curLine++;
  869. curOffset = 1;
  870. } else {
  871. curOffset++;
  872. }
  873. index++;
  874. }
  875. }
  876. return new InvalidOperationException();
  877. }
  878. /// <summary>
  879. /// Reads one line keeping track of the # of bytes read
  880. /// </summary>
  881. private static string ReadOneLine(StreamReader reader, ref int totalRead) {
  882. Stream sr = reader.BaseStream;
  883. byte[] buffer = new byte[256];
  884. StringBuilder builder = null;
  885. int bytesRead = sr.Read(buffer, 0, buffer.Length);
  886. while (bytesRead > 0) {
  887. totalRead += bytesRead;
  888. bool foundEnd = false;
  889. for (int i = 0; i < bytesRead; i++) {
  890. if (buffer[i] == '\r') {
  891. if (i + 1 < bytesRead) {
  892. if (buffer[i + 1] == '\n') {
  893. totalRead -= (bytesRead - (i + 2)); // skip cr/lf
  894. sr.Seek(i + 2, SeekOrigin.Begin);
  895. reader.DiscardBufferedData();
  896. foundEnd = true;
  897. }
  898. } else {
  899. totalRead -= (bytesRead - (i + 1)); // skip cr
  900. sr.Seek(i + 1, SeekOrigin.Begin);
  901. reader.DiscardBufferedData();
  902. foundEnd = true;
  903. }
  904. } else if (buffer[i] == '\n') {
  905. totalRead -= (bytesRead - (i + 1)); // skip lf
  906. sr.Seek(i + 1, SeekOrigin.Begin);
  907. reader.DiscardBufferedData();
  908. foundEnd = true;
  909. }
  910. if (foundEnd) {
  911. if (builder != null) {
  912. builder.Append(buffer.MakeString(), 0, i);
  913. return builder.ToString();
  914. }
  915. return buffer.MakeString().Substring(0, i);
  916. }
  917. }
  918. if (builder == null) builder = new StringBuilder();
  919. builder.Append(buffer.MakeString(), 0, bytesRead);
  920. bytesRead = sr.Read(buffer, 0, buffer.Length);
  921. }
  922. // no string
  923. if (builder == null) {
  924. return null;
  925. }
  926. // no new-line
  927. return builder.ToString();
  928. }
  929. #if FEATURE_CODEDOM
  930. // Convert a CodeDom to source code, and output the generated code and the line number mappings (if any)
  931. public override SourceUnit/*!*/ GenerateSourceCode(System.CodeDom.CodeObject codeDom, string path, SourceCodeKind kind) {
  932. return new IronPython.Hosting.PythonCodeDomCodeGen().GenerateCode((System.CodeDom.CodeMemberMethod)codeDom, this, path, kind);
  933. }
  934. #endif
  935. #region Scopes
  936. public override Scope GetScope(string/*!*/ path) {
  937. PythonModule module = GetModuleByPath(path);
  938. return (module != null) ? module.Scope : null;
  939. }
  940. public PythonModule/*!*/ InitializeModule(string fileName, ModuleContext moduleContext, ScriptCode scriptCode, ModuleOptions options) {
  941. if ((options & ModuleOptions.NoBuiltins) == 0) {
  942. moduleContext.InitializeBuiltins((options & ModuleOptions.ModuleBuiltins) != 0);
  943. }
  944. // If the filename is __init__.py then this is the initialization code
  945. // for a package and we need to set the __path__ variable appropriately
  946. if (fileName != null && Path.GetFileName(fileName) == "__init__.py") {
  947. string dirname = Path.GetDirectoryName(fileName);
  948. string dir_path = DomainManager.Platform.GetFullPath(dirname);
  949. moduleContext.Globals["__path__"] = PythonOps.MakeList(dir_path);
  950. }
  951. moduleContext.ShowCls = (options & ModuleOptions.ShowClsMethods) != 0;
  952. moduleContext.Features = options;
  953. if ((options & ModuleOptions.Initialize) != 0) {
  954. scriptCode.Run(moduleContext.GlobalScope);
  955. if (!moduleContext.Globals.ContainsKey("__package__")) {
  956. moduleContext.Globals["__package__"] = null;
  957. }
  958. }
  959. return moduleContext.Module;
  960. }
  961. public override ScopeExtension CreateScopeExtension(Scope scope) {
  962. var ret = new PythonScopeExtension(this, scope);
  963. ret.ModuleContext.InitializeBuiltins(false);
  964. return ret;
  965. }
  966. public PythonModule/*!*/ CompileModule(string fileName, string moduleName, SourceUnit sourceCode, ModuleOptions options) {
  967. ScriptCode compiledCode;
  968. return CompileModule(fileName, moduleName, sourceCode, options, out compiledCode);
  969. }
  970. public PythonModule/*!*/ CompileModule(string fileName, string moduleName, SourceUnit sourceCode, ModuleOptions options, out ScriptCode scriptCode) {
  971. ContractUtils.RequiresNotNull(fileName, "fileName");
  972. ContractUtils.RequiresNotNull(moduleName, "moduleName");
  973. ContractUtils.RequiresNotNull(sourceCode, "sourceCode");
  974. scriptCode = GetScriptCode(sourceCode, moduleName, options);
  975. Scope scope = scriptCode.CreateScope();
  976. return InitializeModule(fileName, ((PythonScopeExtension)scope.GetExtension(ContextId)).ModuleContext, scriptCode, options);
  977. }
  978. internal ScriptCode GetScriptCode(SourceUnit sourceCode, string moduleName, ModuleOptions options) {
  979. return GetScriptCode(sourceCode, moduleName, options, null);
  980. }
  981. internal ScriptCode GetScriptCode(SourceUnit sourceCode, string moduleName, ModuleOptions options, Compiler.CompilationMode mode) {
  982. PythonCompilerOptions compilerOptions = GetPythonCompilerOptions();
  983. compilerOptions.SkipFirstLine = (options & ModuleOptions.SkipFirstLine) != 0;
  984. compilerOptions.ModuleName = m

Large files files are truncated, but you can click here to view the full file