The Labs \ Source Viewer \ SSCLI \ Microsoft.JScript.Vsa \ VsaEngine

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace Microsoft.JScript.Vsa
  16. {
  17.    
  18.     using Microsoft.JScript;
  19.     using Microsoft.Vsa;
  20.     using System;
  21.     using System.Collections;
  22.     using System.IO;
  23.     using System.Globalization;
  24.     using System.Reflection;
  25.     using System.Reflection.Emit;
  26.     using System.Resources;
  27.     using System.Text;
  28.     using System.Threading;
  29.     using System.Xml;
  30.     using System.Runtime.Remoting.Messaging;
  31.     using System.Security;
  32.     using System.Security.Cryptography;
  33.     using System.Security.Permissions;
  34.     using System.Runtime.InteropServices;
  35.    
  36.    
  37.     internal enum LoaderAPI
  38.     {
  39.         LoadFrom,
  40.         LoadFile,
  41.         ReflectionOnlyLoadFrom
  42.     }
  43.    
  44.    
  45.     [GuidAttribute("B71E484D-93ED-4b56-BFB9-CEED5134822B")]
  46.     [ComVisible(true)]
  47.     [Obsolete(VsaObsolete.Description)]
  48.     public sealed class VsaEngine : BaseVsaEngine, IEngine2, IRedirectOutput
  49.     {
  50.         internal bool alwaysGenerateIL;
  51.         private bool autoRef;
  52.         private Hashtable Defines;
  53.         internal bool doCRS;
  54.         internal bool doFast;
  55.         internal bool doPrint;
  56.         internal bool doSaveAfterCompile;
  57.         private bool doWarnAsError;
  58.         private int nWarningLevel;
  59.         internal bool genStartupClass;
  60.         internal bool isCLSCompliant;
  61.         internal bool versionSafe;
  62.         private string PEFileName;
  63.         internal PEFileKinds PEFileKind;
  64.         internal PortableExecutableKinds PEKindFlags;
  65.         internal ImageFileMachine PEMachineArchitecture;
  66.         internal LoaderAPI ReferenceLoaderAPI;
  67.         private Version versionInfo;
  68.        
  69.         private CultureInfo errorCultureInfo;
  70.        
  71.        
  72.         //In appdomain used to executing JScript debugger expression evaluator
  73.         static internal bool executeForJSEE = false;
  74.        
  75.         private string libpath;
  76.         private string[] libpathList;
  77.        
  78.         private bool isCompilerSet;
  79.        
  80.         internal VsaScriptScope globalScope;
  81.         private ArrayList packages;
  82.         private ArrayList scopes;
  83.         private ArrayList implicitAssemblies;
  84.         private SimpleHashtable implicitAssemblyCache;
  85.         private ICollection managedResources;
  86.         private string debugDirectory;
  87.         private string tempDirectory;
  88.         private RNGCryptoServiceProvider randomNumberGenerator;
  89.         private byte[] rawPE;
  90.         private byte[] rawPDB;
  91.         internal int classCounter;
  92.        
  93.         private SimpleHashtable cachedTypeLookups;
  94.        
  95.         internal Thread runningThread;
  96.         private CompilerGlobals compilerGlobals;
  97.         private Globals globals;
  98.        
  99.         // Used only during VsaEngine.Compile. It is reset at the beginning of the
  100.         // function. It is incremented as errors are reported via OnCompilerError.
  101.         private int numberOfErrors;
  102.        
  103.         private string runtimeDirectory;
  104.         private static readonly Version CurrentProjectVersion = new Version("1.0");
  105.        
  106.         private Hashtable typenameTable;
  107.         // for checking CLS compliance
  108.         private static string engineVersion = GetVersionString();
  109.         private static string GetVersionString()
  110.         {
  111.             return BuildVersionInfo.MajorVersion + "." + BuildVersionInfo.MinorVersion.ToString(CultureInfo.InvariantCulture).PadLeft(2, '0') + "." + BuildVersionInfo.Revision.ToString(CultureInfo.InvariantCulture) + "." + BuildVersionInfo.Build.ToString(CultureInfo.InvariantCulture).PadLeft(4, '0');
  112.            
  113.         }
  114.        
  115.         public VsaEngine() : this(true)
  116.         {
  117.         }
  118.        
  119.         public VsaEngine(bool fast) : base("JScript", VsaEngine.engineVersion, true)
  120.         {
  121.             this.alwaysGenerateIL = false;
  122.             this.autoRef = false;
  123.             this.doCRS = false;
  124.             this.doFast = fast;
  125.             this.genDebugInfo = false;
  126.             this.genStartupClass = true;
  127.             this.doPrint = false;
  128.             this.doWarnAsError = false;
  129.             this.nWarningLevel = 4;
  130.             this.isCLSCompliant = false;
  131.             this.versionSafe = false;
  132.             this.PEFileName = null;
  133.             this.PEFileKind = PEFileKinds.Dll;
  134.             this.PEKindFlags = PortableExecutableKinds.ILOnly;
  135.             this.PEMachineArchitecture = ImageFileMachine.I386;
  136.             this.ReferenceLoaderAPI = LoaderAPI.LoadFrom;
  137.             this.errorCultureInfo = null;
  138.             this.libpath = null;
  139.             this.libpathList = null;
  140.            
  141.             this.globalScope = null;
  142.             this.vsaItems = new VsaItems(this);
  143.             this.packages = null;
  144.             this.scopes = null;
  145.             this.classCounter = 0;
  146.             this.implicitAssemblies = null;
  147.             this.implicitAssemblyCache = null;
  148.             this.cachedTypeLookups = null;
  149.            
  150.             this.isEngineRunning = false;
  151.             this.isEngineCompiled = false;
  152.             this.isCompilerSet = false;
  153.             this.isClosed = false;
  154.            
  155.             this.runningThread = null;
  156.             this.compilerGlobals = null;
  157.             this.globals = null;
  158.             this.runtimeDirectory = null;
  159.             Globals.contextEngine = this;
  160.             this.runtimeAssembly = null;
  161.             this.typenameTable = null;
  162.         }
  163.        
  164.         private Assembly runtimeAssembly;
  165.         private static Hashtable assemblyReferencesTable = null;
  166.         // This constructor is called at run time to instantiate an engine for a given assembly
  167.         private VsaEngine(Assembly runtimeAssembly) : this(true)
  168.         {
  169.             this.runtimeAssembly = runtimeAssembly;
  170.         }
  171.        
  172.         private static Module reflectionOnlyVsaModule = null;
  173.         private static Module reflectionOnlyJScriptModule = null;
  174.        
  175.         internal void EnsureReflectionOnlyModulesLoaded()
  176.         {
  177.             if (VsaEngine.reflectionOnlyVsaModule == null) {
  178.                 VsaEngine.reflectionOnlyVsaModule = Assembly.ReflectionOnlyLoadFrom(typeof(IVsaEngine).Assembly.Location).GetModule("Microsoft.Vsa.dll");
  179.                 VsaEngine.reflectionOnlyJScriptModule = Assembly.ReflectionOnlyLoadFrom(typeof(VsaEngine).Assembly.Location).GetModule("Microsoft.JScript.dll");
  180.             }
  181.         }
  182.        
  183.         internal Module VsaModule {
  184.             get {
  185.                 if (this.ReferenceLoaderAPI != LoaderAPI.ReflectionOnlyLoadFrom)
  186.                     return typeof(IVsaEngine).Module;
  187.                 EnsureReflectionOnlyModulesLoaded();
  188.                 return VsaEngine.reflectionOnlyVsaModule;
  189.             }
  190.         }
  191.        
  192.         internal Module JScriptModule {
  193.             get {
  194.                 if (this.ReferenceLoaderAPI != LoaderAPI.ReflectionOnlyLoadFrom)
  195.                     return typeof(VsaEngine).Module;
  196.                 EnsureReflectionOnlyModulesLoaded();
  197.                 return VsaEngine.reflectionOnlyJScriptModule;
  198.             }
  199.         }
  200.        
  201.         private void AddChildAndValue(XmlDocument doc, XmlElement parent, string name, string value)
  202.         {
  203.             XmlElement option = doc.CreateElement(name);
  204.             this.CreateAttribute(doc, option, "Value", value);
  205.             parent.AppendChild(option);
  206.         }
  207.        
  208.         internal void AddPackage(PackageScope pscope)
  209.         {
  210.             if (this.packages == null)
  211.                 this.packages = new ArrayList(8);
  212.             IEnumerator e = this.packages.GetEnumerator();
  213.             while (e.MoveNext()) {
  214.                 PackageScope cps = (PackageScope)e.Current;
  215.                 if (cps.name.Equals(pscope.name)) {
  216.                     cps.owner.MergeWith(pscope.owner);
  217.                     return;
  218.                 }
  219.             }
  220.             this.packages.Add(pscope);
  221.         }
  222.        
  223.         internal void CheckForErrors()
  224.         {
  225.             if (!this.isClosed && !this.isEngineCompiled) {
  226.                 SetUpCompilerEnvironment();
  227.                 Globals.ScopeStack.Push(this.GetGlobalScope().GetObject());
  228.                 try {
  229.                     foreach (object item in this.vsaItems) {
  230.                         if (item is VsaReference)
  231.                             ((VsaReference)item).Compile();
  232.                         //Load the assembly into memory.
  233.                     }
  234.                     if (this.vsaItems.Count > 0)
  235.                         this.SetEnclosingContext(new WrappedNamespace("", this));
  236.                     //Provide a way to find types that are not inside of a name space
  237.                     foreach (object item in this.vsaItems) {
  238.                         if (!(item is VsaReference))
  239.                             ((VsaItem)item).CheckForErrors();
  240.                     }
  241.                     if (null != this.globalScope)
  242.                         this.globalScope.CheckForErrors();
  243.                     //In case the host added items to the global scope.
  244.                 }
  245.                 finally {
  246.                     Globals.ScopeStack.Pop();
  247.                 }
  248.             }
  249.             this.globalScope = null;
  250.         }
  251.        
  252.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  253.         public IVsaEngine Clone(AppDomain domain)
  254.         {
  255.             throw new NotImplementedException();
  256.         }
  257.        
  258.         // See security comment at BaseVsa.Run()
  259.         [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
  260.         public bool CompileEmpty()
  261.         {
  262.             this.TryObtainLock();
  263.             try {
  264.                 return this.DoCompile();
  265.             }
  266.             finally {
  267.                 this.ReleaseLock();
  268.             }
  269.         }
  270.        
  271.         private void CreateAttribute(XmlDocument doc, XmlElement elem, string name, string value)
  272.         {
  273.             XmlAttribute attribute = doc.CreateAttribute(name);
  274.             elem.SetAttributeNode(attribute);
  275.             elem.SetAttribute(name, value);
  276.         }
  277.        
  278.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  279.         public void ConnectEvents()
  280.         {
  281.         }
  282.        
  283.         internal CompilerGlobals CompilerGlobals {
  284.             get {
  285.                 if (this.compilerGlobals == null)
  286.                     this.compilerGlobals = new CompilerGlobals(this, this.Name, this.PEFileName, this.PEFileKind, this.doSaveAfterCompile || this.genStartupClass, !this.doSaveAfterCompile || this.genStartupClass, this.genDebugInfo, this.isCLSCompliant, this.versionInfo, this.globals
  287.                     );
  288.                 return this.compilerGlobals;
  289.             }
  290.         }
  291.        
  292.        
  293.         private static TypeReferences _reflectionOnlyTypeRefs;
  294.         private TypeReferences TypeRefs {
  295.             get {
  296.                 TypeReferences typeRefs;
  297.                 if (LoaderAPI.ReflectionOnlyLoadFrom == this.ReferenceLoaderAPI) {
  298.                     typeRefs = VsaEngine._reflectionOnlyTypeRefs;
  299.                     if (null == typeRefs)
  300.                         typeRefs = VsaEngine._reflectionOnlyTypeRefs = new TypeReferences(this.JScriptModule);
  301.                 }
  302.                 else
  303.                     typeRefs = Runtime.TypeRefs;
  304.                 return typeRefs;
  305.             }
  306.         }
  307.        
  308.         public static GlobalScope CreateEngineAndGetGlobalScope(bool fast, string[] assemblyNames)
  309.         {
  310.             VsaEngine engine = new VsaEngine(fast);
  311.             engine.InitVsaEngine("JScript.Vsa.VsaEngine://Microsoft.JScript.VsaEngine.Vsa", new DefaultVsaSite());
  312.             engine.doPrint = true;
  313.             engine.SetEnclosingContext(new WrappedNamespace("", engine));
  314.             foreach (string assemblyName in assemblyNames) {
  315.                 VsaReference r = (VsaReference)engine.vsaItems.CreateItem(assemblyName, VsaItemType.Reference, VsaItemFlag.None);
  316.                 r.AssemblyName = assemblyName;
  317.             }
  318.             VsaEngine.exeEngine = engine;
  319.             GlobalScope scope = (GlobalScope)engine.GetGlobalScope().GetObject();
  320.             scope.globalObject = engine.Globals.globalObject;
  321.             return scope;
  322.         }
  323.        
  324.         public static GlobalScope CreateEngineAndGetGlobalScopeWithType(bool fast, string[] assemblyNames, RuntimeTypeHandle callingTypeHandle)
  325.         {
  326.             return VsaEngine.CreateEngineAndGetGlobalScopeWithTypeAndRootNamespace(fast, assemblyNames, callingTypeHandle, null);
  327.         }
  328.        
  329.         public static GlobalScope CreateEngineAndGetGlobalScopeWithTypeAndRootNamespace(bool fast, string[] assemblyNames, RuntimeTypeHandle callingTypeHandle, string rootNamespace)
  330.         {
  331.             VsaEngine engine = new VsaEngine(fast);
  332.             engine.InitVsaEngine("JScript.Vsa.VsaEngine://Microsoft.JScript.VsaEngine.Vsa", new DefaultVsaSite());
  333.             engine.doPrint = true;
  334.             engine.SetEnclosingContext(new WrappedNamespace("", engine));
  335.             if (rootNamespace != null)
  336.                 engine.SetEnclosingContext(new WrappedNamespace(rootNamespace, engine));
  337.            
  338.             foreach (string assemblyName in assemblyNames) {
  339.                 VsaReference r = (VsaReference)engine.vsaItems.CreateItem(assemblyName, VsaItemType.Reference, VsaItemFlag.None);
  340.                 r.AssemblyName = assemblyName;
  341.             }
  342.             // Put the engine in the CallContext so that calls to CreateEngineWithType will return this engine
  343.             Type callingType = Type.GetTypeFromHandle(callingTypeHandle);
  344.             Assembly callingAssembly = callingType.Assembly;
  345.             System.Runtime.Remoting.Messaging.CallContext.SetData("JScript:" + callingAssembly.FullName, engine);
  346.             // Get and return the global scope
  347.             GlobalScope scope = (GlobalScope)engine.GetGlobalScope().GetObject();
  348.             scope.globalObject = engine.Globals.globalObject;
  349.             return scope;
  350.         }
  351.        
  352.         private static volatile VsaEngine exeEngine;
  353.         // Instance of VsaEngine used by JScript EXEs
  354.         // This factory method is called by EXE code only
  355.         public static VsaEngine CreateEngine()
  356.         {
  357.             if (VsaEngine.exeEngine == null) {
  358.                 VsaEngine e = new VsaEngine(true);
  359.                 e.InitVsaEngine("JScript.Vsa.VsaEngine://Microsoft.JScript.VsaEngine.Vsa", new DefaultVsaSite());
  360.                 VsaEngine.exeEngine = e;
  361.             }
  362.             return VsaEngine.exeEngine;
  363.         }
  364.        
  365.         static internal VsaEngine CreateEngineForDebugger()
  366.         {
  367.             VsaEngine engine = new VsaEngine(true);
  368.             engine.InitVsaEngine("JScript.Vsa.VsaEngine://Microsoft.JScript.VsaEngine.Vsa", new DefaultVsaSite());
  369.             GlobalScope scope = (GlobalScope)engine.GetGlobalScope().GetObject();
  370.             scope.globalObject = engine.Globals.globalObject;
  371.             return engine;
  372.         }
  373.        
  374.         // This factory method is called by DLL code only
  375.         public static VsaEngine CreateEngineWithType(RuntimeTypeHandle callingTypeHandle)
  376.         {
  377.             Type callingType = Type.GetTypeFromHandle(callingTypeHandle);
  378.             Assembly callingAssembly = callingType.Assembly;
  379.             object o = System.Runtime.Remoting.Messaging.CallContext.GetData("JScript:" + callingAssembly.FullName);
  380.             if (o != null) {
  381.                 VsaEngine e = o as VsaEngine;
  382.                 if (e != null)
  383.                     return e;
  384.             }
  385.            
  386.             VsaEngine engine = new VsaEngine(callingAssembly);
  387.             engine.InitVsaEngine("JScript.Vsa.VsaEngine://Microsoft.JScript.VsaEngine.Vsa", new DefaultVsaSite());
  388.            
  389.             GlobalScope scope = (GlobalScope)engine.GetGlobalScope().GetObject();
  390.             scope.globalObject = engine.Globals.globalObject;
  391.            
  392.             // for every global class generated in this assembly make an instance and call the global code method
  393.             int i = 0;
  394.             Type globalClassType = null;
  395.             do {
  396.                 string globalClassName = "JScript " + i.ToString(CultureInfo.InvariantCulture);
  397.                 globalClassType = callingAssembly.GetType(globalClassName, false);
  398.                 if (globalClassType != null) {
  399.                     engine.SetEnclosingContext(new WrappedNamespace("", engine));
  400.                     ConstructorInfo globalScopeConstructor = globalClassType.GetConstructor(new Type[] {typeof(GlobalScope)});
  401.                     MethodInfo globalCode = globalClassType.GetMethod("Global Code");
  402.                     try {
  403.                         object globalClassInstance = globalScopeConstructor.Invoke(new object[] {scope});
  404.                         globalCode.Invoke(globalClassInstance, new object[0]);
  405.                     }
  406.                     catch (SecurityException) {
  407.                         // [stesty] Due to bug 337909, if a JScript assembly is strongly-named but partially-trusted, it will
  408.                         // not succeed here unless it also has the AllowPartiallyTrustedCallersAttribute. We do not
  409.                         // want to run this constructor with elevated permissions, so we work around by abandoning
  410.                         // the attempt, thus disabling eval in this scenario.
  411.                         break;
  412.                     }
  413.                 }
  414.                 i++;
  415.             }
  416.             while (globalClassType != null);
  417.            
  418.             if (o == null)
  419.                 System.Runtime.Remoting.Messaging.CallContext.SetData("JScript:" + callingAssembly.FullName, engine);
  420.             return engine;
  421.         }
  422.        
  423.         private void AddReferences()
  424.         {
  425.             if (VsaEngine.assemblyReferencesTable == null) {
  426.                 // Create the cache
  427.                 Hashtable h = new Hashtable();
  428.                 VsaEngine.assemblyReferencesTable = Hashtable.Synchronized(h);
  429.             }
  430.            
  431.             string[] references = VsaEngine.assemblyReferencesTable[this.runtimeAssembly.FullName] as string[];
  432.             if (references != null) {
  433.                 for (int i = 0; i < references.Length; i++) {
  434.                     VsaReference r = (VsaReference)this.vsaItems.CreateItem(references[i], VsaItemType.Reference, VsaItemFlag.None);
  435.                     r.AssemblyName = references[i];
  436.                 }
  437.             }
  438.             else {
  439.                 // Read the references from the custom attribute on the assembly and create VsaReferences for each
  440.                 // of them.
  441.                 object[] attrs = CustomAttribute.GetCustomAttributes(this.runtimeAssembly, typeof(ReferenceAttribute), false);
  442.                 string[] references1 = new string[attrs.Length];
  443.                 for (int i = 0; i < attrs.Length; i++) {
  444.                     string assemblyName = ((ReferenceAttribute)attrs[i]).reference;
  445.                     VsaReference r = (VsaReference)this.vsaItems.CreateItem(assemblyName, VsaItemType.Reference, VsaItemFlag.None);
  446.                     r.AssemblyName = assemblyName;
  447.                     references1[i] = assemblyName;
  448.                 }
  449.                 VsaEngine.assemblyReferencesTable[this.runtimeAssembly.FullName] = references1;
  450.             }
  451.         }
  452.        
  453.         private void EmitReferences()
  454.         {
  455.             SimpleHashtable emitted = new SimpleHashtable((uint)this.vsaItems.Count + (this.implicitAssemblies == null ? 0 : (uint)this.implicitAssemblies.Count));
  456.             foreach (object item in this.vsaItems) {
  457.                 if (item is VsaReference) {
  458.                     string referenceName = ((VsaReference)item).Assembly.GetName().FullName;
  459.                     // do not write duplicate assemblies
  460.                     if (emitted[referenceName] == null) {
  461.                         CustomAttributeBuilder cab = new CustomAttributeBuilder(CompilerGlobals.referenceAttributeConstructor, new object[1] {referenceName});
  462.                         this.CompilerGlobals.assemblyBuilder.SetCustomAttribute(cab);
  463.                         emitted[referenceName] = item;
  464.                     }
  465.                 }
  466.             }
  467.             if (this.implicitAssemblies != null) {
  468.                 foreach (object item in this.implicitAssemblies) {
  469.                     Assembly a = item as Assembly;
  470.                     if (a != null) {
  471.                         string referenceName = a.GetName().FullName;
  472.                         // do not write duplicate assemblies
  473.                         if (emitted[referenceName] == null) {
  474.                             CustomAttributeBuilder cab = new CustomAttributeBuilder(CompilerGlobals.referenceAttributeConstructor, new object[1] {referenceName});
  475.                             this.CompilerGlobals.assemblyBuilder.SetCustomAttribute(cab);
  476.                             emitted[referenceName] = item;
  477.                         }
  478.                     }
  479.                 }
  480.             }
  481.         }
  482.        
  483.         private void CreateMain()
  484.         {
  485.             // define a class that will hold the main method
  486.             TypeBuilder mainClass = this.CompilerGlobals.module.DefineType("JScript Main", TypeAttributes.Public);
  487.            
  488.             // create a function with the following signature void Main(String[] args)
  489.             MethodBuilder main = mainClass.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, Typeob.Void, new Type[] {Typeob.ArrayOfString});
  490.             ILGenerator il = main.GetILGenerator();
  491.            
  492.             // emit code for main method
  493.                 /* site */            this.CreateEntryPointIL(il, null);
  494.            
  495.             // cook method and class
  496.             mainClass.CreateType();
  497.             // define the Main() method as the entry point for the exe
  498.             this.CompilerGlobals.assemblyBuilder.SetEntryPoint(main, this.PEFileKind);
  499.         }
  500.        
  501.         private void CreateStartupClass()
  502.         {
  503.             // define _Startup class for VSA (in the RootNamespace)
  504.             Debug.Assert(this.rootNamespace != null && this.rootNamespace.Length > 0);
  505.             TypeBuilder startupClass = this.CompilerGlobals.module.DefineType(this.rootNamespace + "._Startup", TypeAttributes.Public, Typeob.BaseVsaStartup);
  506.             FieldInfo site = Typeob.BaseVsaStartup.GetField("site", BindingFlags.NonPublic | BindingFlags.Instance);
  507.             // create a function with the following signature: public virtual void Startup()
  508.             MethodBuilder startup = startupClass.DefineMethod("Startup", MethodAttributes.Public | MethodAttributes.Virtual, Typeob.Void, Type.EmptyTypes);
  509.             this.CreateEntryPointIL(startup.GetILGenerator(), site, startupClass);
  510.             // create a function with the following signature: public virtual void Shutdown()
  511.             MethodBuilder shutdown = startupClass.DefineMethod("Shutdown", MethodAttributes.Public | MethodAttributes.Virtual, Typeob.Void, Type.EmptyTypes);
  512.             this.CreateShutdownIL(shutdown.GetILGenerator());
  513.            
  514.             // cook method and class
  515.             startupClass.CreateType();
  516.         }
  517.        
  518.         void CreateEntryPointIL(ILGenerator il, FieldInfo site)
  519.         {
  520.             this.CreateEntryPointIL(il, site, null);
  521.         }
  522.        
  523.         void CreateEntryPointIL(ILGenerator il, FieldInfo site, TypeBuilder startupClass)
  524.         {
  525.             LocalBuilder globalScope = il.DeclareLocal(Typeob.GlobalScope);
  526.            
  527.             //Emit code to create an engine. We do this explicitly so that we can control fast mode.
  528.             if (this.doFast)
  529.                 il.Emit(OpCodes.Ldc_I4_1);
  530.             else
  531.                 il.Emit(OpCodes.Ldc_I4_0);
  532.             //Run through the list of references and emit code to create an array of strings representing them
  533.             //but do not emit duplicates.
  534.             SimpleHashtable uniqueReferences = new SimpleHashtable((uint)this.vsaItems.Count);
  535.             ArrayList references = new ArrayList();
  536.             foreach (object item in this.vsaItems) {
  537.                 if (item is VsaReference) {
  538.                     string assemblyName = ((VsaReference)item).Assembly.GetName().FullName;
  539.                     if (uniqueReferences[assemblyName] == null) {
  540.                         references.Add(assemblyName);
  541.                         uniqueReferences[assemblyName] = item;
  542.                     }
  543.                 }
  544.             }
  545.             if (this.implicitAssemblies != null) {
  546.                 foreach (object item in this.implicitAssemblies) {
  547.                     Assembly a = item as Assembly;
  548.                     if (a != null) {
  549.                         string assemblyName = a.GetName().FullName;
  550.                         if (uniqueReferences[assemblyName] == null) {
  551.                             references.Add(assemblyName);
  552.                             uniqueReferences[assemblyName] = item;
  553.                         }
  554.                     }
  555.                 }
  556.             }
  557.            
  558.             ConstantWrapper.TranslateToILInt(il, references.Count);
  559.             il.Emit(OpCodes.Newarr, Typeob.String);
  560.             int num = 0;
  561.             foreach (string referenceName in references) {
  562.                 il.Emit(OpCodes.Dup);
  563.                 ConstantWrapper.TranslateToILInt(il, num++);
  564.                 il.Emit(OpCodes.Ldstr, referenceName);
  565.                 il.Emit(OpCodes.Stelem_Ref);
  566.             }
  567.             if (startupClass != null) {
  568.                 il.Emit(OpCodes.Ldtoken, startupClass);
  569.                 if (this.rootNamespace != null)
  570.                     il.Emit(OpCodes.Ldstr, this.rootNamespace);
  571.                 else
  572.                     il.Emit(OpCodes.Ldnull);
  573.                 MethodInfo createEngineAndGetGlobalScopeWithTypeAndRootNamespace = Typeob.VsaEngine.GetMethod("CreateEngineAndGetGlobalScopeWithTypeAndRootNamespace");
  574.                 il.Emit(OpCodes.Call, createEngineAndGetGlobalScopeWithTypeAndRootNamespace);
  575.             }
  576.             else {
  577.                 MethodInfo createEngineAndGetGlobalScope = Typeob.VsaEngine.GetMethod("CreateEngineAndGetGlobalScope");
  578.                 il.Emit(OpCodes.Call, createEngineAndGetGlobalScope);
  579.             }
  580.             il.Emit(OpCodes.Stloc, globalScope);
  581.            
  582.             // get global object instances and event source instances (CreateStartupClass scenario only)
  583.             if (site != null)
  584.                 this.CreateHostCallbackIL(il, site);
  585.            
  586.             bool setUserEntryPoint = this.genDebugInfo;
  587.            
  588.             // for every generated class make an instance and call the main routine method
  589.            
  590.             // When there are multiple VsaStaticCode items, all members of relevance are lifted to the
  591.             // first one. VsaStaticCode does not munge with the runtime scope chain, and instead
  592.             // relies on the code here to set things up before the global code is called.
  593.             bool codeToSetupGlobalScopeEmitted = false;
  594.             // have we hit the first VsaStaticCode item
  595.             foreach (object item in this.vsaItems) {
  596.                 Type compiledType = ((VsaItem)item).GetCompiledType();
  597.                 if (null != compiledType) {
  598.                     ConstructorInfo globalScopeConstructor = compiledType.GetConstructor(new Type[] {Typeob.GlobalScope});
  599.                     MethodInfo globalCode = compiledType.GetMethod("Global Code");
  600.                     if (setUserEntryPoint) {
  601.                         //Set the Global Code method of the first code item to be the place where the debugger breaks for the first step into
  602.                         this.CompilerGlobals.module.SetUserEntryPoint(globalCode);
  603.                         setUserEntryPoint = false;
  604.                         //Do it once only
  605.                     }
  606.                    
  607.                     il.Emit(OpCodes.Ldloc, globalScope);
  608.                     il.Emit(OpCodes.Newobj, globalScopeConstructor);
  609.                    
  610.                     if (!codeToSetupGlobalScopeEmitted && item is VsaStaticCode) {
  611.                         // This is the first VsaStaticCode item which holds all the relevant members.
  612.                         // Push it onto the runtime scope stack.
  613.                         LocalBuilder firstStaticScope = il.DeclareLocal(compiledType);
  614.                         // all members lifted to this object
  615.                         il.Emit(OpCodes.Stloc, firstStaticScope);
  616.                        
  617.                         // Call globalScope.engine.PushScriptObject(firstStaticScope)
  618.                         il.Emit(OpCodes.Ldloc, globalScope);
  619.                         il.Emit(OpCodes.Ldfld, CompilerGlobals.engineField);
  620.                         il.Emit(OpCodes.Ldloc, firstStaticScope);
  621.                         il.Emit(OpCodes.Call, CompilerGlobals.pushScriptObjectMethod);
  622.                        
  623.                         // Restore stack for the next Call instruction.
  624.                         il.Emit(OpCodes.Ldloc, firstStaticScope);
  625.                         codeToSetupGlobalScopeEmitted = true;
  626.                     }
  627.                    
  628.                     il.Emit(OpCodes.Call, globalCode);
  629.                     il.Emit(OpCodes.Pop);
  630.                 }
  631.             }
  632.            
  633.             if (codeToSetupGlobalScopeEmitted) {
  634.                 // A VsaStaticCode item was encountered and code to setup the runtime
  635.                 // stack was emitted. Restore the stack.
  636.                 il.Emit(OpCodes.Ldloc, globalScope);
  637.                 il.Emit(OpCodes.Ldfld, CompilerGlobals.engineField);
  638.                 il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
  639.                 il.Emit(OpCodes.Pop);
  640.             }
  641.            
  642.             // a method needs a return opcode
  643.             il.Emit(OpCodes.Ret);
  644.         }
  645.        
  646.         private void CreateHostCallbackIL(ILGenerator il, FieldInfo site)
  647.         {
  648.             // Do callbacks to the host for global object instances
  649.             MethodInfo getGlobalInstance = site.FieldType.GetMethod("GetGlobalInstance");
  650.             MethodInfo getEventSourceInstance = site.FieldType.GetMethod("GetEventSourceInstance");
  651.             foreach (object item in this.vsaItems) {
  652.                 if (item is VsaHostObject) {
  653.                     VsaHostObject hostObject = (VsaHostObject)item;
  654.                     // get global item instance from site
  655.                     il.Emit(OpCodes.Ldarg_0);
  656.                     il.Emit(OpCodes.Ldfld, site);
  657.                     il.Emit(OpCodes.Ldstr, hostObject.Name);
  658.                     il.Emit(OpCodes.Callvirt, getGlobalInstance);
  659.                     // cast instance to the correct type and store into the global field
  660.                     Type target_type = hostObject.Field.FieldType;
  661.                     il.Emit(OpCodes.Ldtoken, target_type);
  662.                     il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
  663.                     ConstantWrapper.TranslateToILInt(il, 0);
  664.                     il.Emit(OpCodes.Call, CompilerGlobals.coerceTMethod);
  665.                     if (target_type.IsValueType)
  666.                         Microsoft.JScript.Convert.EmitUnbox(il, target_type, Type.GetTypeCode(target_type));
  667.                     else
  668.                         il.Emit(OpCodes.Castclass, target_type);
  669.                     il.Emit(OpCodes.Stsfld, hostObject.Field);
  670.                 }
  671.             }
  672.         }
  673.        
  674.         private void CreateShutdownIL(ILGenerator il)
  675.         {
  676.             // release references to global instances
  677.             foreach (object item in this.vsaItems) {
  678.                 if (item is VsaHostObject) {
  679.                     il.Emit(OpCodes.Ldnull);
  680.                     il.Emit(OpCodes.Stsfld, ((VsaHostObject)item).Field);
  681.                 }
  682.             }
  683.             il.Emit(OpCodes.Ret);
  684.         }
  685.        
  686.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  687.         public void DisconnectEvents()
  688.         {
  689.         }
  690.        
  691.         protected override void DoClose()
  692.         {
  693.             ((VsaItems)this.vsaItems).Close();
  694.             if (null != this.globalScope)
  695.                 this.globalScope.Close();
  696.             this.vsaItems = null;
  697.             this.engineSite = null;
  698.             this.globalScope = null;
  699.             this.runningThread = null;
  700.             this.compilerGlobals = null;
  701.             this.globals = null;
  702.             ScriptStream.Out = Console.Out;
  703.             ScriptStream.Error = Console.Error;
  704.             this.rawPE = null;
  705.             this.rawPDB = null;
  706.             this.isClosed = true;
  707.             if (this.tempDirectory != null && Directory.Exists(this.tempDirectory))
  708.                 Directory.Delete(this.tempDirectory);
  709.         }
  710.        
  711.         protected override bool DoCompile()
  712.         {
  713.             if (!this.isClosed && !this.isEngineCompiled) {
  714.                 this.SetUpCompilerEnvironment();
  715.                 if (this.PEFileName == null) {
  716.                     // we use random default names to avoid overwriting cached assembly files when debugging VSA
  717.                     this.PEFileName = this.GenerateRandomPEFileName();
  718.                 }
  719.                 this.SaveSourceForDebugging();
  720.                 // Save sources needed for debugging (does nothing if no debug info)
  721.                 this.numberOfErrors = 0;
  722.                 // Records number of errors during compilation.
  723.                 this.isEngineCompiled = true;
  724.                 // OnCompilerError sets to false if it encounters an unrecoverable error.
  725.                 Globals.ScopeStack.Push(this.GetGlobalScope().GetObject());
  726.                 try {
  727.                     try {
  728.                         foreach (object item in this.vsaItems) {
  729.                             Debug.Assert(item is VsaReference || item is VsaStaticCode || item is VsaHostObject);
  730.                             if (item is VsaReference)
  731.                                 ((VsaReference)item).Compile();
  732.                             //Load the assembly into memory.
  733.                         }
  734.                         if (this.vsaItems.Count > 0)
  735.                             this.SetEnclosingContext(new WrappedNamespace("", this));
  736.                         //Provide a way to find types that are not inside of a name space
  737.                         // Add VSA global items to the global scope
  738.                         foreach (object item in this.vsaItems) {
  739.                             if (item is VsaHostObject)
  740.                                 ((VsaHostObject)item).Compile();
  741.                         }
  742.                         foreach (object item in this.vsaItems) {
  743.                             if (item is VsaStaticCode)
  744.                                 ((VsaStaticCode)item).Parse();
  745.                         }
  746.                         foreach (object item in this.vsaItems) {
  747.                             if (item is VsaStaticCode)
  748.                                 ((VsaStaticCode)item).ProcessAssemblyAttributeLists();
  749.                         }
  750.                         foreach (object item in this.vsaItems) {
  751.                             if (item is VsaStaticCode)
  752.                                 ((VsaStaticCode)item).PartiallyEvaluate();
  753.                         }
  754.                         foreach (object item in this.vsaItems) {
  755.                             if (item is VsaStaticCode)
  756.                                 ((VsaStaticCode)item).TranslateToIL();
  757.                         }
  758.                         foreach (object item in this.vsaItems) {
  759.                             if (item is VsaStaticCode)
  760.                                 ((VsaStaticCode)item).GetCompiledType();
  761.                         }
  762.                         if (null != this.globalScope)
  763.                             this.globalScope.Compile();
  764.                         //In case the host added items to the global scope
  765.                     }
  766.                     catch (JScriptException se) {
  767.                         // It's a bit strange because we may be capturing an exception
  768.                         // thrown by VsaEngine.OnCompilerError (in the case where
  769.                         // this.engineSite is null. This is fine though. All we end up doing
  770.                         // is capturing and then rethrowing the same error.
  771.                         this.OnCompilerError(se);
  772.                     }
  773.                     catch (System.IO.FileLoadException e) {
  774.                         JScriptException se = new JScriptException(JSError.ImplicitlyReferencedAssemblyNotFound);
  775.                         se.value = e.FileName;
  776.                         this.OnCompilerError(se);
  777.                         this.isEngineCompiled = false;
  778.                     }
  779.                     catch (EndOfFile) {
  780.                         // an error was reported during PartiallyEvaluate and the host decided to abort
  781.                         // swallow the exception and keep going
  782.                     }
  783.                     catch {
  784.                         // internal compiler error -- make sure we don't claim to have compiled, then rethrow
  785.                         this.isEngineCompiled = false;
  786.                         throw;
  787.                     }
  788.                 }
  789.                 finally {
  790.                     Globals.ScopeStack.Pop();
  791.                 }
  792.                 if (this.isEngineCompiled) {
  793.                     // there were no unrecoverable errors, but we want to return true only if there is IL
  794.                     this.isEngineCompiled = (this.numberOfErrors == 0 || this.alwaysGenerateIL);
  795.                 }
  796.             }
  797.            
  798.            
  799.             if (this.managedResources != null) {
  800.                 foreach (ResInfo managedResource in this.managedResources) {
  801.                     if (managedResource.isLinked) {
  802.                         this.CompilerGlobals.assemblyBuilder.AddResourceFile(managedResource.name, Path.GetFileName(managedResource.filename), managedResource.isPublic ? ResourceAttributes.Public : ResourceAttributes.Private);
  803.                     }
  804.                     else {
  805.                         try {
  806.                             using (ResourceReader reader = new ResourceReader(managedResource.filename)) {
  807.                                 IResourceWriter writer = this.CompilerGlobals.module.DefineResource(managedResource.name, managedResource.filename, managedResource.isPublic ? ResourceAttributes.Public : ResourceAttributes.Private);
  808.                                 foreach (DictionaryEntry resource in reader)
  809.                                     writer.AddResource((string)resource.Key, resource.Value);
  810.                             }
  811.                         }
  812.                         catch (System.ArgumentException) {
  813.                             JScriptException se = new JScriptException(JSError.InvalidResource);
  814.                             se.value = managedResource.filename;
  815.                             this.OnCompilerError(se);
  816.                             this.isEngineCompiled = false;
  817.                             return false;
  818.                         }
  819.                     }
  820.                 }
  821.             }
  822.            
  823.             if (this.isEngineCompiled)
  824.                 this.EmitReferences();
  825.            
  826.             // Save things out to a local PE file when doSaveAfterCompile is set; this is set when an
  827.             // output name is given (allows JSC to avoid IVsaEngine.SaveCompiledState). The proper
  828.             // values for VSA are doSaveAfterCompile == false and genStartupClass == true. We allow
  829.             // genStartupClass to be false for scenarios like JSTest and the Debugger
  830.             if (this.isEngineCompiled) {
  831.                 if (this.doSaveAfterCompile) {
  832.                     if (this.PEFileKind != PEFileKinds.Dll)
  833.                         this.CreateMain();
  834.                     // After executing this code path, it is an error to call SaveCompiledState (until the engine is recompiled)
  835.                     try {
  836.                         compilerGlobals.assemblyBuilder.Save(Path.GetFileName(this.PEFileName), this.PEKindFlags, this.PEMachineArchitecture);
  837.                     }
  838.                     catch (Exception e) {
  839.                         throw new VsaException(VsaError.SaveCompiledStateFailed, e.Message, e);
  840.                     }
  841.                     catch {
  842.                         throw new VsaException(VsaError.SaveCompiledStateFailed);
  843.                     }
  844.                 }
  845.                 else if (this.genStartupClass) {
  846.                     // this is generated for VSA hosting
  847.                     this.CreateStartupClass();
  848.                 }
  849.             }
  850.             return this.isEngineCompiled;
  851.         }
  852.        
  853.         internal CultureInfo ErrorCultureInfo {
  854.             get {
  855.                 if (this.errorCultureInfo == null || this.errorCultureInfo.LCID != this.errorLocale)
  856.                     this.errorCultureInfo = new CultureInfo(this.errorLocale);
  857.                 return this.errorCultureInfo;
  858.             }
  859.         }
  860.        
  861.         private string GenerateRandomPEFileName()
  862.         {
  863.             if (this.randomNumberGenerator == null)
  864.                 this.randomNumberGenerator = new RNGCryptoServiceProvider();
  865.             // Generate random bytes
  866.             byte[] data = new byte[6];
  867.             this.randomNumberGenerator.GetBytes(data);
  868.             // Turn them into a string containing only characters valid in file names
  869.             string randomString = System.Convert.ToBase64String(data);
  870.             randomString = randomString.Replace('/', '-');
  871.             randomString = randomString.Replace('+', '_');
  872.             // Use the first random filename as the engine's temp directory name
  873.             if (this.tempDirectory == null)
  874.                 this.tempDirectory = System.IO.Path.GetTempPath() + randomString;
  875.             string filename = randomString + (this.PEFileKind == PEFileKinds.Dll ? ".dll" : ".exe");
  876.             return this.tempDirectory + Path.DirectorySeparatorChar + filename;
  877.         }
  878.        
  879.         /////////////////////////////////////////////////////////////////////////////
  880.         //
  881.         // Security Issue
  882.         //
  883.         /////////////////////////////////////////////////////////////////////////////
  884.         //
  885.         // [EricLi] 10 November 2001
  886.         //
  887.         // Right now the VsaEngine class requires full trust to use as
  888.         // an engine that runs code or generates assemblies.
  889.         //
  890.         // Preventing untrusted callers from actually compiling and
  891.         // running code is clearly undesirable -- we want partially-
  892.         // trusted host scenarios to work. For this release however
  893.         // there are too many poorly-understood issues involving
  894.         // controling the evidence property.
  895.         //
  896.         /////////////////////////////////////////////////////////////////////////////
  897.        
  898.         [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
  899.         public Assembly GetAssembly()
  900.         {
  901.             this.TryObtainLock();
  902.             try {
  903.                 if (null != this.PEFileName)
  904.                     return Assembly.LoadFrom(this.PEFileName);
  905.                 else
  906.                     return compilerGlobals.assemblyBuilder;
  907.             }
  908.             finally {
  909.                 this.ReleaseLock();
  910.             }
  911.         }
  912.        
  913.         internal ClassScope GetClass(string className)
  914.         {
  915.             if (this.packages != null)
  916.                 for (int i = 0int n = this.packages.Count; i < n; i++) {
  917.                     PackageScope pscope = (PackageScope)this.packages[i];
  918.                     object pval = pscope.GetMemberValue(className, 1);
  919.                     if (!(pval is Microsoft.JScript.Missing)) {
  920.                         ClassScope csc = (ClassScope)pval;
  921.                         return csc;
  922.                     }
  923.                 }
  924.             return null;
  925.         }
  926.        
  927.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  928.         public IVsaItem GetItem(string itemName)
  929.         {
  930.             return this.vsaItems[itemName];
  931.         }
  932.        
  933.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  934.         public IVsaItem GetItemAtIndex(int index)
  935.         {
  936.             return this.vsaItems[index];
  937.         }
  938.        
  939.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  940.         public int GetItemCount()
  941.         {
  942.             return this.vsaItems.Count;
  943.         }
  944.        
  945.         public IVsaScriptScope GetGlobalScope()
  946.         {
  947.             if (null == this.globalScope) {
  948.                 this.globalScope = new VsaScriptScope(this, "Global", null);
  949.                 GlobalScope scope = (GlobalScope)this.globalScope.GetObject();
  950.                 scope.globalObject = this.Globals.globalObject;
  951.                 scope.fast = this.doFast;
  952.                 scope.isKnownAtCompileTime = this.doFast;
  953.             }
  954.             return this.globalScope;
  955.         }
  956.        
  957.         // Called by the debugger to get hold of the global scope from within a class method
  958.         public GlobalScope GetMainScope()
  959.         {
  960.             ScriptObject o = ScriptObjectStackTop();
  961.             while (o != null && !(o is GlobalScope))
  962.                 o = o.GetParent();
  963.             return (GlobalScope)o;
  964.         }
  965.        
  966.         public Module GetModule()
  967.         {
  968.             if (null != this.PEFileName) {
  969.                 Assembly a = GetAssembly();
  970.                 Module[] modules = a.GetModules();
  971.                 return modules[0];
  972.             }
  973.             else
  974.                 return this.CompilerGlobals.module;
  975.         }
  976.        
  977.         public ArrayConstructor GetOriginalArrayConstructor()
  978.         {
  979.             return this.Globals.globalObject.originalArray;
  980.         }
  981.        
  982.         public ObjectConstructor GetOriginalObjectConstructor()
  983.         {
  984.             return this.Globals.globalObject.originalObject;
  985.         }
  986.        
  987.         public RegExpConstructor GetOriginalRegExpConstructor()
  988.         {
  989.             return this.Globals.globalObject.originalRegExp;
  990.         }
  991.        
  992.         protected override object GetCustomOption(string name)
  993.         {
  994.             if (String.Compare(name, "CLSCompliant", StringComparison.OrdinalIgnoreCase) == 0)
  995.                 return this.isCLSCompliant;
  996.             else if (String.Compare(name, "fast", StringComparison.OrdinalIgnoreCase) == 0)
  997.                 return this.doFast;
  998.             else if (String.Compare(name, "output", StringComparison.OrdinalIgnoreCase) == 0)
  999.                 return this.PEFileName;
  1000.             else if (String.Compare(name, "PEFileKind", StringComparison.OrdinalIgnoreCase) == 0)
  1001.                 return this.PEFileKind;
  1002.             else if (String.Compare(name, "PortableExecutableKind", StringComparison.OrdinalIgnoreCase) == 0)
  1003.                 return this.PEKindFlags;
  1004.             else if (String.Compare(name, "ImageFileMachine", StringComparison.OrdinalIgnoreCase) == 0)
  1005.                 return this.PEMachineArchitecture;
  1006.             else if (String.Compare(name, "ReferenceLoaderAPI", StringComparison.OrdinalIgnoreCase) == 0) {
  1007.                 switch (this.ReferenceLoaderAPI) {
  1008.                     case LoaderAPI.LoadFrom:
  1009.                         return "LoadFrom";
  1010.                     case LoaderAPI.LoadFile:
  1011.                         return "LoadFile";
  1012.                     case LoaderAPI.ReflectionOnlyLoadFrom:
  1013.                         return "ReflectionOnlyLoadFrom";
  1014.                     default:
  1015.                         throw new VsaException(VsaError.OptionNotSupported);
  1016.                         break;
  1017.                 }
  1018.             }
  1019.             else if (String.Compare(name, "print", StringComparison.OrdinalIgnoreCase) == 0)
  1020.                 return this.doPrint;
  1021.             else if (String.Compare(name, "UseContextRelativeStatics", StringComparison.OrdinalIgnoreCase) == 0)
  1022.                 return this.doCRS;
  1023.             else if (String.Compare(name, "optimize", StringComparison.OrdinalIgnoreCase) == 0)
  1024.                 return null;
  1025.             else if (String.Compare(name, "define", StringComparison.OrdinalIgnoreCase) == 0)
  1026.                 return null;
  1027.             else if (String.Compare(name, "defines", StringComparison.OrdinalIgnoreCase) == 0)
  1028.                 return this.Defines;
  1029.             else if (String.Compare(name, "ee", StringComparison.OrdinalIgnoreCase) == 0)
  1030.                 return VsaEngine.executeForJSEE;
  1031.             else if (String.Compare(name, "version", StringComparison.OrdinalIgnoreCase) == 0)
  1032.                 return this.versionInfo;
  1033.             else if (String.Compare(name, "VersionSafe", StringComparison.OrdinalIgnoreCase) == 0)
  1034.                 return this.versionSafe;
  1035.             else if (String.Compare(name, "warnaserror", StringComparison.OrdinalIgnoreCase) == 0)
  1036.                 return this.doWarnAsError;
  1037.             else if (String.Compare(name, "WarningLevel", StringComparison.OrdinalIgnoreCase) == 0)
  1038.                 return this.nWarningLevel;
  1039.             else if (String.Compare(name, "managedResources", StringComparison.OrdinalIgnoreCase) == 0)
  1040.                 return this.managedResources;
  1041.             else if (String.Compare(name, "alwaysGenerateIL", StringComparison.OrdinalIgnoreCase) == 0)
  1042.                 return this.alwaysGenerateIL;
  1043.             else if (String.Compare(name, "DebugDirectory", StringComparison.OrdinalIgnoreCase) == 0)
  1044.                 return this.debugDirectory;
  1045.             else if (String.Compare(name, "AutoRef", StringComparison.OrdinalIgnoreCase) == 0)
  1046.                 return this.autoRef;
  1047.             else
  1048.                 // the next two are needed because of the ICompiler interface. They should not fail even though they may not do anything
  1049.                 throw new VsaException(VsaError.OptionNotSupported);
  1050.         }
  1051.        
  1052.         internal int GetStaticCodeBlockCount()
  1053.         {
  1054.             return ((VsaItems)this.vsaItems).staticCodeBlockCount;
  1055.         }
  1056.        
  1057.         internal Type GetType(string typeName)
  1058.         {
  1059.             if (this.cachedTypeLookups == null)
  1060.                 this.cachedTypeLookups = new SimpleHashtable(1000);
  1061.             object cacheResult = this.cachedTypeLookups[typeName];
  1062.             if (cacheResult == null) {
  1063.                 // proceed with lookup
  1064.                 for (int i = 0int n = this.Scopes.Count; i < n; i++) {
  1065.                     GlobalScope scope = (GlobalScope)this.scopes[i];
  1066.                     Type result = Globals.TypeRefs.ToReferenceContext(scope.GetType()).Assembly.GetType(typeName, false);
  1067.                     if (result != null) {
  1068.                         this.cachedTypeLookups[typeName] = result;
  1069.                         return result;
  1070.                     }
  1071.                 }
  1072.                
  1073.                 if (this.runtimeAssembly != null) {
  1074.                     this.AddReferences();
  1075.                     this.runtimeAssembly = null;
  1076.                 }
  1077.                
  1078.                 for (int i = 0int n = this.vsaItems.Count; i < n; i++) {
  1079.                     object item = this.vsaItems[i];
  1080.                     if (item is VsaReference) {
  1081.                         Type result = ((VsaReference)item).GetType(typeName);
  1082.                         if (result != null) {
  1083.                             this.cachedTypeLookups[typeName] = result;
  1084.                             return result;
  1085.                         }
  1086.                     }
  1087.                 }
  1088.                 if (this.implicitAssemblies == null) {
  1089.                     this.cachedTypeLookups[typeName] = false;
  1090.                     return null;
  1091.                 }
  1092.                 for (int i = 0int n = this.implicitAssemblies.Count; i < n; i++) {
  1093.                     Assembly assembly = (Assembly)this.implicitAssemblies[i];
  1094.                     Type result = assembly.GetType(typeName, false);
  1095.                     if (result != null) {
  1096.                         if (!result.IsPublic || CustomAttribute.IsDefined(result, typeof(System.Runtime.CompilerServices.RequiredAttributeAttribute), true))
  1097.                             result = null;
  1098.                         //Suppress the type if it is not public or if it is a funky C++ type.
  1099.                         else {
  1100.                             this.cachedTypeLookups[typeName] = result;
  1101.                             return result;
  1102.                         }
  1103.                     }
  1104.                 }
  1105.                
  1106.                 this.cachedTypeLookups[typeName] = false;
  1107.                 return null;
  1108.             }
  1109.             return (cacheResult as Type);
  1110.         }
  1111.        
  1112.         internal Globals Globals {
  1113.             get {
  1114.                 if (this.globals == null)
  1115.                     this.globals = new Globals(this.doFast, this);
  1116.                 return this.globals;
  1117.             }
  1118.         }
  1119.        
  1120.         internal bool HasErrors {
  1121.             get { return this.numberOfErrors != 0; }
  1122.         }
  1123.        
  1124.         // GetScannerInstance is used by IsValidNamespaceName and IsValidIdentifier to validate names.
  1125.         // We return an instance of the scanner only if there is no whitespace in the name text, since
  1126.         // we do not want to allow, say, "not. valid" to be a valid namespace name even though that
  1127.         // would produce a valid sequence of tokens.
  1128.         private JSScanner GetScannerInstance(string name)
  1129.         {
  1130.             // make sure there's no whitespace in the name (values copied from documentation on String.Trim())
  1131.             char[] anyWhiteSpace = {(char)9, (char)10, (char)11, (char)12, (char)13, (char)32, (char)160, (char)8192, (char)8193, (char)8194,
  1132.             (char)8195, (char)8196, (char)8197, (char)8198, (char)8199, (char)8200, (char)8201, (char)8202, (char)8203, (char)12288,
  1133.             (char)65279};
  1134.             if (name == null || name.IndexOfAny(anyWhiteSpace) > -1)
  1135.                 return null;
  1136.             // Create a code item whose source is the given text
  1137.             VsaItem item = new VsaStaticCode(this, "itemName", VsaItemFlag.None);
  1138.             Context context = new Context(new DocumentContext(item), name);
  1139.             context.errorReported = -1;
  1140.             JSScanner scanner = new JSScanner();
  1141.             //Use this constructor to avoid allocating a Globals instance
  1142.             scanner.SetSource(context);
  1143.             return scanner;
  1144.         }
  1145.        
  1146.         // Use this method to initialize the engine for non-VSA use. This includes JSC, JSTest, and the JSEE.
  1147.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  1148.         public void InitVsaEngine(string rootMoniker, IVsaSite site)
  1149.         {
  1150.             this.genStartupClass = false;
  1151.             this.engineMoniker = rootMoniker;
  1152.             this.engineSite = site;
  1153.             this.isEngineInitialized = true;
  1154.             this.rootNamespace = "JScript.DefaultNamespace";
  1155.             this.isEngineDirty = true;
  1156.             this.isEngineCompiled = false;
  1157.         }
  1158.        
  1159.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  1160.         public void Interrupt()
  1161.         {
  1162.             if (this.runningThread != null) {
  1163.                 this.runningThread.Abort();
  1164.                 this.runningThread = null;
  1165.             }
  1166.         }
  1167.        
  1168.         protected override bool IsValidNamespaceName(string name)
  1169.         {
  1170.             JSScanner scanner = this.GetScannerInstance(name);
  1171.             if (scanner == null)
  1172.                 return false;
  1173.             while (true) {
  1174.                 if (scanner.PeekToken() != JSToken.Identifier)
  1175.                     return false;
  1176.                 scanner.GetNextToken();
  1177.                 if (scanner.PeekToken() == JSToken.EndOfFile)
  1178.                     break;
  1179.                 if (scanner.PeekToken() != JSToken.AccessField)
  1180.                     return false;
  1181.                 scanner.GetNextToken();
  1182.             }
  1183.             return true;
  1184.         }
  1185.        
  1186.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  1187.         public override bool IsValidIdentifier(string ident)
  1188.         {
  1189.             JSScanner scanner = this.GetScannerInstance(ident);
  1190.             if (scanner == null)
  1191.                 return false;
  1192.             if (scanner.PeekToken() != JSToken.Identifier)
  1193.                 return false;
  1194.             scanner.GetNextToken();
  1195.             if (scanner.PeekToken() != JSToken.EndOfFile)
  1196.                 return false;
  1197.             return true;
  1198.         }
  1199.        
  1200.         public LenientGlobalObject LenientGlobalObject {
  1201.             get { return (LenientGlobalObject)this.Globals.globalObject; }
  1202.         }
  1203.        
  1204.         protected override Assembly LoadCompiledState()
  1205.         {
  1206.             Debug.Assert(this.haveCompiledState);
  1207.             byte[] pe;
  1208.             byte[] pdb;
  1209.             if (!this.genDebugInfo) {
  1210.                 System.Security.Policy.Evidence compilationEvidence = this.CompilerGlobals.compilationEvidence;
  1211.                 System.Security.Policy.Evidence executionEvidence = this.executionEvidence;
  1212.                 if (compilationEvidence == null && executionEvidence == null || compilationEvidence != null && compilationEvidence.Equals(executionEvidence))
  1213.                     return this.compilerGlobals.assemblyBuilder;
  1214.             }
  1215.             // we need to save/reload to properly associate debug symbols with the assembly
  1216.             this.DoSaveCompiledState(out pe, out pdb);
  1217.             return Assembly.Load(pe, pdb, this.executionEvidence);
  1218.         }
  1219.        
  1220.         protected override void DoLoadSourceState(IVsaPersistSite site)
  1221.         {
  1222.             // DoSaveSourceState puts everything in the project item (use null for the name)
  1223.             // We assume the site is valid and contains a valid project file so any errors are
  1224.             // wrapped in a VsaException and thrown
  1225.             string projectElement = site.LoadElement(null);
  1226.             try {
  1227.                 XmlDocument project = new XmlDocument();
  1228.                 project.LoadXml(projectElement);
  1229.                 XmlElement root = project.DocumentElement;
  1230.                
  1231.                 // verify that we support this version of the project file
  1232.                 if (this.LoadProjectVersion(root) == CurrentProjectVersion) {
  1233.                     this.LoadVsaEngineState(root);
  1234.                     this.isEngineDirty = false;
  1235.                 }
  1236.             }
  1237.             catch (Exception e) {
  1238.                 throw new VsaException(VsaError.UnknownError, e.ToString(), e);
  1239.             }
  1240.             catch {
  1241.                 throw new VsaException(VsaError.UnknownError);
  1242.             }
  1243.         }
  1244.        
  1245.         private Version LoadProjectVersion(XmlElement root)
  1246.         {
  1247.             return new Version(root["ProjectVersion"].GetAttribute("Version"));
  1248.         }
  1249.        
  1250.         private void LoadVsaEngineState(XmlElement parent)
  1251.         {
  1252.             XmlElement engine = parent["VsaEngine"];
  1253.             this.applicationPath = engine.GetAttribute("ApplicationBase");
  1254.             this.genDebugInfo = Boolean.Parse(engine.GetAttribute("GenerateDebugInfo"));
  1255.             this.scriptLanguage = engine.GetAttribute("Language");
  1256.             this.LCID = Int32.Parse(engine.GetAttribute("LCID"), CultureInfo.InvariantCulture);
  1257.             this.Name = engine.GetAttribute("Name");
  1258.             this.rootNamespace = engine.GetAttribute("RootNamespace");
  1259.             this.assemblyVersion = engine.GetAttribute("Version");
  1260.             this.LoadCustomOptions(engine);
  1261.             this.LoadVsaItems(engine);
  1262.         }
  1263.        
  1264.         private void LoadCustomOptions(XmlElement parent)
  1265.         {
  1266.             XmlElement options = parent["Options"];
  1267.             Debug.Assert(String.Compare(options.Name, "Options", StringComparison.OrdinalIgnoreCase) == 0);
  1268.             this.doFast = Boolean.Parse(options.GetAttribute("fast"));
  1269.             this.doPrint = Boolean.Parse(options.GetAttribute("print"));
  1270.             this.doCRS = Boolean.Parse(options.GetAttribute("UseContextRelativeStatics"));
  1271.             this.versionSafe = Boolean.Parse(options.GetAttribute("VersionSafe"));
  1272.             this.libpath = options.GetAttribute("libpath");
  1273.             this.doWarnAsError = Boolean.Parse(options.GetAttribute("warnaserror"));
  1274.             this.nWarningLevel = Int32.Parse(options.GetAttribute("WarningLevel"), CultureInfo.InvariantCulture);
  1275.             this.LoadUserDefines(options);
  1276.             this.LoadManagedResources(options);
  1277.         }
  1278.        
  1279.         private void LoadUserDefines(XmlElement parent)
  1280.         {
  1281.             XmlElement userDefines = parent["Defines"];
  1282.             XmlNodeList defines = userDefines.ChildNodes;
  1283.             foreach (XmlElement definition in defines)
  1284.                 this.Defines[definition.Name] = definition.GetAttribute("Value");
  1285.         }
  1286.        
  1287.         private void LoadManagedResources(XmlElement parent)
  1288.         {
  1289.             XmlElement resources = parent["ManagedResources"];
  1290.             XmlNodeList managedResources = resources.ChildNodes;
  1291.             if (managedResources.Count > 0) {
  1292.                 this.managedResources = new ArrayList(managedResources.Count);
  1293.                 foreach (XmlElement resource in managedResources) {
  1294.                     string name = resource.GetAttribute("Name");
  1295.                     string filename = resource.GetAttribute("FileName");
  1296.                     bool isPublic = Boolean.Parse(resource.GetAttribute("Public"));
  1297.                     bool isLinked = Boolean.Parse(resource.GetAttribute("Linked"));
  1298.                     ((ArrayList)this.managedResources).Add(new ResInfo(filename, name, isPublic, isLinked));
  1299.                 }
  1300.             }
  1301.         }
  1302.        
  1303.         private void LoadVsaItems(XmlElement parent)
  1304.         {
  1305.             XmlNodeList vsaItems = parent["VsaItems"].ChildNodes;
  1306.             string itemType;
  1307.             IVsaItem item;
  1308.             string reference = VsaItemType.Reference.ToString();
  1309.             string appGlobal = VsaItemType.AppGlobal.ToString();
  1310.             string code = VsaItemType.Code.ToString();
  1311.             foreach (XmlElement vsaItem in vsaItems) {
  1312.                 string name = vsaItem.GetAttribute("Name");
  1313.                 itemType = vsaItem.GetAttribute("ItemType");
  1314.                 if (String.Compare(itemType, reference, StringComparison.OrdinalIgnoreCase) == 0) {
  1315.                     item = this.vsaItems.CreateItem(name, VsaItemType.Reference, VsaItemFlag.None);
  1316.                     ((IVsaReferenceItem)item).AssemblyName = vsaItem.GetAttribute("AssemblyName");
  1317.                 }
  1318.                 else if (String.Compare(itemType, appGlobal, StringComparison.OrdinalIgnoreCase) == 0) {
  1319.                     item = this.vsaItems.CreateItem(name, VsaItemType.AppGlobal, VsaItemFlag.None);
  1320.                     ((IVsaGlobalItem)item).ExposeMembers = Boolean.Parse(vsaItem.GetAttribute("ExposeMembers"));
  1321.                     ((IVsaGlobalItem)item).TypeString = vsaItem.GetAttribute("TypeString");
  1322.                 }
  1323.                 else if (String.Compare(itemType, code, StringComparison.OrdinalIgnoreCase) == 0) {
  1324.                     item = this.vsaItems.CreateItem(name, VsaItemType.Code, VsaItemFlag.None);
  1325.                     XmlCDataSection sourceText = (XmlCDataSection)vsaItem.FirstChild;
  1326.                     string unescapedText = sourceText.Value.Replace(" >", ">");
  1327.                     ((IVsaCodeItem)item).SourceText = unescapedText;
  1328.                 }
  1329.                 else
  1330.                     throw new VsaException(VsaError.LoadElementFailed);
  1331.                 XmlNodeList vsaItemOptions = vsaItem["Options"].ChildNodes;
  1332.                 foreach (XmlElement option in vsaItemOptions) {
  1333.                     item.SetOption(option.Name, option.GetAttribute("Value"));
  1334.                 }
  1335.                 ((VsaItem)item).IsDirty = false;
  1336.             }
  1337.         }
  1338.        
  1339.         internal bool OnCompilerError(JScriptException se)
  1340.         {
  1341.             if (se.Severity == 0 || (this.doWarnAsError && se.Severity <= this.nWarningLevel))
  1342.                 this.numberOfErrors++;
  1343.             bool canRecover = this.engineSite.OnCompilerError(se);
  1344.             //true means carry on with compilation.
  1345.             if (!canRecover)
  1346.                 this.isEngineCompiled = false;
  1347.             return canRecover;
  1348.         }
  1349.        
  1350.         public ScriptObject PopScriptObject()
  1351.         {
  1352.             return (ScriptObject)this.Globals.ScopeStack.Pop();
  1353.         }
  1354.        
  1355.         public void PushScriptObject(ScriptObject obj)
  1356.         {
  1357.             this.Globals.ScopeStack.Push(obj);
  1358.         }
  1359.        
  1360.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  1361.         public void RegisterEventSource(string name)
  1362.         {
  1363.         }
  1364.        
  1365.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  1366.         public override void Reset()
  1367.         {
  1368.             if (this.genStartupClass)
  1369.                 base.Reset();
  1370.             else
  1371.                 this.ResetCompiledState();
  1372.         }
  1373.        
  1374.         protected override void ResetCompiledState()
  1375.         {
  1376.             if (this.globalScope != null) {
  1377.                 this.globalScope.Reset();
  1378.                 this.globalScope = null;
  1379.             }
  1380.             this.classCounter = 0;
  1381.             this.haveCompiledState = false;
  1382.             this.failedCompilation = true;
  1383.             this.compiledRootNamespace = null;
  1384.             this.startupClass = null;
  1385.             this.compilerGlobals = null;
  1386.             this.globals = null;
  1387.             foreach (object item in this.vsaItems)
  1388.                 ((VsaItem)item).Reset();
  1389.             this.implicitAssemblies = null;
  1390.             this.implicitAssemblyCache = null;
  1391.             this.cachedTypeLookups = null;
  1392.             this.isEngineCompiled = false;
  1393.             this.isEngineRunning = false;
  1394.             this.isCompilerSet = false;
  1395.             this.packages = null;
  1396.             if (!this.doSaveAfterCompile)
  1397.                 this.PEFileName = null;
  1398.             this.rawPE = null;
  1399.             this.rawPDB = null;
  1400.         }
  1401.        
  1402.         // the debugger restart the engine to run different expression evaluation
  1403.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  1404.         public void Restart()
  1405.         {
  1406.             this.TryObtainLock();
  1407.             try {
  1408.                 ((VsaItems)this.vsaItems).Close();
  1409.                 if (null != this.globalScope)
  1410.                     this.globalScope.Close();
  1411.                 this.globalScope = null;
  1412.                 this.vsaItems = new VsaItems(this);
  1413.                 this.isEngineRunning = false;
  1414.                 this.isEngineCompiled = false;
  1415.                 this.isCompilerSet = false;
  1416.                 this.isClosed = false;
  1417.                 this.runningThread = null;
  1418.                 this.globals = null;
  1419.             }
  1420.             finally {
  1421.                 this.ReleaseLock();
  1422.             }
  1423.         }
  1424.        
  1425.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  1426.         public void RunEmpty()
  1427.         {
  1428.             this.TryObtainLock();
  1429.             try {
  1430.                 Preconditions(Pre.EngineNotClosed | Pre.RootMonikerSet | Pre.SiteSet);
  1431.                 this.isEngineRunning = true;
  1432.                 // save the current thread so it can be interrupted
  1433.                 this.runningThread = Thread.CurrentThread;
  1434.                 if (null != this.globalScope)
  1435.                     this.globalScope.Run();
  1436.                 foreach (object item in this.vsaItems)
  1437.                     ((VsaItem)item).Run();
  1438.             }
  1439.             finally {
  1440.                 this.runningThread = null;
  1441.                 this.ReleaseLock();
  1442.             }
  1443.         }
  1444.        
  1445.         [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
  1446.         public void Run(AppDomain domain)
  1447.         {
  1448.             // managed engines are not supporting Run in user-provided AppDomains
  1449.             throw new System.NotImplementedException();
  1450.         }
  1451.        
  1452.         protected override void DoSaveCompiledState(out byte[] pe, out byte[] pdb)
  1453.         {
  1454.             pe = null;
  1455.             pdb = null;
  1456.             if (this.rawPE == null) {
  1457.                 try {
  1458.                     // Save things out to a local PE file, then read back into memory
  1459.                     // PEFileName was set in the Compile method and we must have compiled in order to be calling this
  1460.                     if (!Directory.Exists(this.tempDirectory))
  1461.                         Directory.CreateDirectory(this.tempDirectory);
  1462.                     this.compilerGlobals.assemblyBuilder.Save(Path.GetFileName(this.PEFileName), this.PEKindFlags, this.PEMachineArchitecture);
  1463.                     string tempPDBName = Path.ChangeExtension(this.PEFileName, ".ildb");
  1464.                     try {
  1465.                         FileStream stream = new FileStream(this.PEFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
  1466.                         try {
  1467.                             this.rawPE = new byte[(int)stream.Length];
  1468.                             stream.Read(this.rawPE, 0, this.rawPE.Length);
  1469.                         }
  1470.                         finally {
  1471.                             stream.Close();
  1472.                         }
  1473.                         // genDebugInfo could have been changed since we compiled, so check to make sure the symbols are there
  1474.                         if (File.Exists(tempPDBName)) {
  1475.                             stream = new FileStream(tempPDBName, FileMode.Open, FileAccess.Read, FileShare.Read);
  1476.                             try {
  1477.                                 this.rawPDB = new byte[(int)stream.Length];
  1478.                                 stream.Read(this.rawPDB, 0, this.rawPDB.Length);
  1479.                             }
  1480.                             finally {
  1481.                                 stream.Close();
  1482.                             }
  1483.                         }
  1484.                     }
  1485.                     finally {
  1486.                         File.Delete(this.PEFileName);
  1487.                         if (File.Exists(tempPDBName))
  1488.                             File.Delete(tempPDBName);
  1489.                     }
  1490.                 }
  1491.                 catch (Exception e) {
  1492.                     throw new VsaException(VsaError.SaveCompiledStateFailed, e.ToString(), e);
  1493.                 }
  1494.                 catch {
  1495.                     throw new VsaException(VsaError.SaveCompiledStateFailed);
  1496.                 }
  1497.             }
  1498.             pe = this.rawPE;
  1499.             pdb = this.rawPDB;
  1500.         }
  1501.        
  1502.         protected override void DoSaveSourceState(IVsaPersistSite site)
  1503.         {
  1504.             XmlDocument project = new XmlDocument();
  1505.             project.LoadXml("<project></project>");
  1506.             XmlElement root = project.DocumentElement;
  1507.             this.SaveProjectVersion(project, root);
  1508.             this.SaveVsaEngineState(project, root);
  1509.             site.SaveElement(null, project.OuterXml);
  1510.             this.SaveSourceForDebugging();
  1511.             this.isEngineDirty = false;
  1512.         }
  1513.        
  1514.         private void SaveSourceForDebugging()
  1515.         {
  1516.             if (!this.GenerateDebugInfo || this.debugDirectory == null || !this.isEngineDirty)
  1517.                 return;
  1518.             foreach (VsaItem item in this.vsaItems) {
  1519.                 if (item is VsaStaticCode) {
  1520.                     string fileName = this.debugDirectory + item.Name + ".js";
  1521.                     try {
  1522.                         using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write)) {
  1523.                             using (StreamWriter sw = new StreamWriter(file))
  1524.                                 sw.Write(((VsaStaticCode)item).SourceText);
  1525.                             item.SetOption("codebase", fileName);
  1526.                         }
  1527.                     }
  1528.                     catch {
  1529.                         // swallow any file creation exceptions
  1530.                     }
  1531.                 }
  1532.             }
  1533.         }
  1534.        
  1535.         private void SaveProjectVersion(XmlDocument project, XmlElement root)
  1536.         {
  1537.             XmlElement version = project.CreateElement("ProjectVersion");
  1538.             this.CreateAttribute(project, version, "Version", CurrentProjectVersion.ToString());
  1539.             root.AppendChild(version);
  1540.         }
  1541.        
  1542.         private void SaveVsaEngineState(XmlDocument project, XmlElement parent)
  1543.         {
  1544.             XmlElement engine = project.CreateElement("VsaEngine");
  1545.             // add IVsaEngine properties as attributes
  1546.             this.CreateAttribute(project, engine, "ApplicationBase", this.applicationPath);
  1547.             this.CreateAttribute(project, engine, "GenerateDebugInfo", this.genDebugInfo.ToString());
  1548.             this.CreateAttribute(project, engine, "Language", this.scriptLanguage);
  1549.             this.CreateAttribute(project, engine, "LCID", this.errorLocale.ToString(CultureInfo.InvariantCulture));
  1550.             this.CreateAttribute(project, engine, "Name", this.engineName);
  1551.             this.CreateAttribute(project, engine, "RootNamespace", this.rootNamespace);
  1552.             this.CreateAttribute(project, engine, "Version", this.assemblyVersion);
  1553.             this.SaveCustomOptions(project, engine);
  1554.             this.SaveVsaItems(project, engine);
  1555.             parent.AppendChild(engine);
  1556.         }
  1557.        
  1558.         private void SaveCustomOptions(XmlDocument project, XmlElement parent)
  1559.         {
  1560.             XmlElement options = project.CreateElement("Options");
  1561.             this.CreateAttribute(project, options, "fast", this.doFast.ToString());
  1562.             this.CreateAttribute(project, options, "print", this.doPrint.ToString());
  1563.             this.CreateAttribute(project, options, "UseContextRelativeStatics", this.doCRS.ToString());
  1564.             this.CreateAttribute(project, options, "VersionSafe", this.versionSafe.ToString());
  1565.             this.CreateAttribute(project, options, "libpath", this.libpath);
  1566.             this.CreateAttribute(project, options, "warnaserror", this.doWarnAsError.ToString());
  1567.             this.CreateAttribute(project, options, "WarningLevel", this.nWarningLevel.ToString(CultureInfo.InvariantCulture));
  1568.             this.SaveUserDefines(project, options);
  1569.             this.SaveManagedResources(project, options);
  1570.             parent.AppendChild(options);
  1571.         }
  1572.        
  1573.         private void SaveUserDefines(XmlDocument project, XmlElement parent)
  1574.         {
  1575.             XmlElement userDefines = project.CreateElement("Defines");
  1576.             if (this.Defines != null) {
  1577.                 foreach (string key in this.Defines.Keys) {
  1578.                     this.AddChildAndValue(project, userDefines, key, (string)this.Defines[key]);
  1579.                 }
  1580.             }
  1581.             parent.AppendChild(userDefines);
  1582.         }
  1583.        
  1584.         private void SaveManagedResources(XmlDocument project, XmlElement parent)
  1585.         {
  1586.             // Save managed resources
  1587.             XmlElement managedResources = project.CreateElement("ManagedResources");
  1588.             if (this.managedResources != null) {
  1589.                 foreach (ResInfo resinfo in this.managedResources) {
  1590.                     XmlElement resource = project.CreateElement(resinfo.name);
  1591.                     this.CreateAttribute(project, resource, "File", resinfo.filename);
  1592.                     this.CreateAttribute(project, resource, "Public", resinfo.isPublic.ToString());
  1593.                     this.CreateAttribute(project, resource, "Linked", resinfo.isLinked.ToString());
  1594.                     managedResources.AppendChild(resource);
  1595.                 }
  1596.             }
  1597.             parent.AppendChild(managedResources);
  1598.         }
  1599.        
  1600.         private void SaveVsaItems(XmlDocument project, XmlElement parent)
  1601.         {
  1602.             XmlElement vsaItems = project.CreateElement("VsaItems");
  1603.             foreach (IVsaItem item in this.vsaItems) {
  1604.                 XmlElement vsaItem = project.CreateElement("IVsaItem");
  1605.                 this.CreateAttribute(project, vsaItem, "Name", item.Name);
  1606.                 this.CreateAttribute(project, vsaItem, "ItemType", item.ItemType.ToString(CultureInfo.InvariantCulture));
  1607.                 XmlElement vsaItemOptions = project.CreateElement("Options");
  1608.                 if (item is VsaHostObject) {
  1609.                     // VsaItemType.AppGlobal
  1610.                     this.CreateAttribute(project, vsaItem, "TypeString", ((VsaHostObject)item).TypeString);
  1611.                     this.CreateAttribute(project, vsaItem, "ExposeMembers", ((VsaHostObject)item).ExposeMembers.ToString(CultureInfo.InvariantCulture));
  1612.                 }
  1613.                 else if (item is VsaReference) {
  1614.                     // VsaItemType.Reference
  1615.                     CreateAttribute(project, vsaItem, "AssemblyName", ((VsaReference)item).AssemblyName);
  1616.                 }
  1617.                 else if (item is VsaStaticCode) {
  1618.                     // VsaItemType.Code
  1619.                     string escapedText = ((VsaStaticCode)item).SourceText.Replace(">", " >");
  1620.                     XmlCDataSection source = project.CreateCDataSection(escapedText);
  1621.                     vsaItem.AppendChild(source);
  1622.                     string codebase = (string)item.GetOption("codebase");
  1623.                     if (codebase != null)
  1624.                         this.AddChildAndValue(project, vsaItemOptions, "codebase", codebase);
  1625.                 }
  1626.                 else
  1627.                     throw new VsaException(VsaError.SaveElementFailed);
  1628.                 ((VsaItem)item).IsDirty = false;
  1629.                 vsaItem.AppendChild(vsaItemOptions);
  1630.                 vsaItems.AppendChild(vsaItem);
  1631.             }
  1632.             parent.AppendChild(vsaItems);
  1633.         }
  1634.        
  1635.         internal ArrayList Scopes {
  1636.             get {
  1637.                 if (this.scopes == null)
  1638.                     this.scopes = new ArrayList(8);
  1639.                 return this.scopes;
  1640.             }
  1641.         }
  1642.        
  1643.         public ScriptObject ScriptObjectStackTop()
  1644.         {
  1645.             return (ScriptObject)this.Globals.ScopeStack.Peek();
  1646.         }
  1647.        
  1648.         internal void SetEnclosingContext(ScriptObject ob)
  1649.         {
  1650.             ScriptObject s = this.Globals.ScopeStack.Peek();
  1651.             while (s.GetParent() != null)
  1652.                 s = s.GetParent();
  1653.             s.SetParent(ob);
  1654.         }
  1655.        
  1656.         public void SetOutputStream(IMessageReceiver output)
  1657.         {
  1658.             COMCharStream stream = new COMCharStream(output);
  1659.             System.IO.StreamWriter writer = new System.IO.StreamWriter(stream, Encoding.Default);
  1660.             writer.AutoFlush = true;
  1661.             ScriptStream.Out = writer;
  1662.             ScriptStream.Error = writer;
  1663.         }
  1664.        
  1665.         protected override void SetCustomOption(string name, object value)
  1666.         {
  1667.             try {
  1668.                 if (String.Compare(name, "CLSCompliant", StringComparison.OrdinalIgnoreCase) == 0)
  1669.                     this.isCLSCompliant = (bool)value;
  1670.                 else if (String.Compare(name, "fast", StringComparison.OrdinalIgnoreCase) == 0)
  1671.                     this.doFast = (bool)value;
  1672.                 else if (String.Compare(name, "output", StringComparison.OrdinalIgnoreCase) == 0) {
  1673.                     if (value is string) {
  1674.                         this.PEFileName = (string)value;
  1675.                         this.doSaveAfterCompile = true;
  1676.                     }
  1677.                 }
  1678.                 else if (String.Compare(name, "PEFileKind", StringComparison.OrdinalIgnoreCase) == 0)
  1679.                     this.PEFileKind = (PEFileKinds)value;
  1680.                 else if (String.Compare(name, "PortableExecutableKind", StringComparison.OrdinalIgnoreCase) == 0)
  1681.                     this.PEKindFlags = (PortableExecutableKinds)value;
  1682.                 else if (String.Compare(name, "ImageFileMachine", StringComparison.OrdinalIgnoreCase) == 0)
  1683.                     this.PEMachineArchitecture = (ImageFileMachine)value;
  1684.                 else if (String.Compare(name, "ReferenceLoaderAPI", StringComparison.OrdinalIgnoreCase) == 0) {
  1685.                     string loaderAPI = (string)value;
  1686.                     if (String.Compare(loaderAPI, "LoadFrom", StringComparison.OrdinalIgnoreCase) == 0)
  1687.                         this.ReferenceLoaderAPI = LoaderAPI.LoadFrom;
  1688.                     else if (String.Compare(loaderAPI, "LoadFile", StringComparison.OrdinalIgnoreCase) == 0)
  1689.                         this.ReferenceLoaderAPI = LoaderAPI.LoadFile;
  1690.                     else if (String.Compare(loaderAPI, "ReflectionOnlyLoadFrom", StringComparison.OrdinalIgnoreCase) == 0)
  1691.                         this.ReferenceLoaderAPI = LoaderAPI.ReflectionOnlyLoadFrom;
  1692.                     else
  1693.                         throw new VsaException(VsaError.OptionInvalid);
  1694.                 }
  1695.                 else if (String.Compare(name, "print", StringComparison.OrdinalIgnoreCase) == 0)
  1696.                     this.doPrint = (bool)value;
  1697.                 else if (String.Compare(name, "UseContextRelativeStatics", StringComparison.OrdinalIgnoreCase) == 0)
  1698.                     this.doCRS = (bool)value;
  1699.                 else if (String.Compare(name, "optimize", StringComparison.OrdinalIgnoreCase) == 0)
  1700.                     return;
  1701.                 else if (String.Compare(name, "define", StringComparison.OrdinalIgnoreCase) == 0)
  1702.                     return;
  1703.                 else if (String.Compare(name, "defines", StringComparison.OrdinalIgnoreCase) == 0)
  1704.                     this.Defines = (Hashtable)value;
  1705.                 else if (String.Compare(name, "ee", StringComparison.OrdinalIgnoreCase) == 0)
  1706.                     VsaEngine.executeForJSEE = (bool)value;
  1707.                 else if (String.Compare(name, "version", StringComparison.OrdinalIgnoreCase) == 0)
  1708.                     this.versionInfo = (Version)value;
  1709.                 else if (String.Compare(name, "VersionSafe", StringComparison.OrdinalIgnoreCase) == 0)
  1710.                     this.versionSafe = (bool)value;
  1711.                 else if (String.Compare(name, "libpath", StringComparison.OrdinalIgnoreCase) == 0)
  1712.                     this.libpath = (string)value;
  1713.                 else if (String.Compare(name, "warnaserror", StringComparison.OrdinalIgnoreCase) == 0)
  1714.                     this.doWarnAsError = (bool)value;
  1715.                 else if (String.Compare(name, "WarningLevel", StringComparison.OrdinalIgnoreCase) == 0)
  1716.                     this.nWarningLevel = (int)value;
  1717.                 else if (String.Compare(name, "managedResources", StringComparison.OrdinalIgnoreCase) == 0)
  1718.                     this.managedResources = (ICollection)value;
  1719.                 else if (String.Compare(name, "alwaysGenerateIL", StringComparison.OrdinalIgnoreCase) == 0)
  1720.                     this.alwaysGenerateIL = (bool)value;
  1721.                 // the next two are needed because of the ICompiler interface. They should not fail even though they may not do anything
  1722.                 else if (String.Compare(name, "DebugDirectory", StringComparison.OrdinalIgnoreCase) == 0) {
  1723.                     // use null to turn off SaveSourceState source generation
  1724.                     if (value == null) {
  1725.                         this.debugDirectory = null;
  1726.                         return;
  1727.                     }
  1728.                     string dir = value as string;
  1729.                     if (dir == null)
  1730.                         throw new VsaException(VsaError.OptionInvalid);
  1731.                     try {
  1732.                         dir = Path.GetFullPath(dir + Path.DirectorySeparatorChar);
  1733.                         if (!Directory.Exists(dir))
  1734.                             Directory.CreateDirectory(dir);
  1735.                     }
  1736.                     catch (Exception e) {
  1737.                         // we couldn't create the specified directory
  1738.                         throw new VsaException(VsaError.OptionInvalid, "", e);
  1739.                     }
  1740.                     catch {
  1741.                         // we couldn't create the specified directory
  1742.                         throw new VsaException(VsaError.OptionInvalid);
  1743.                     }
  1744.                     this.debugDirectory = dir;
  1745.                 }
  1746.                 else if (String.Compare(name, "AutoRef", StringComparison.OrdinalIgnoreCase) == 0)
  1747.                     this.autoRef = (bool)value;
  1748.                 else
  1749.                     throw new VsaException(VsaError.OptionNotSupported);
  1750.             }
  1751.             catch (VsaException) {
  1752.                 throw;
  1753.             }
  1754.             catch {
  1755.                 throw new VsaException(VsaError.OptionInvalid);
  1756.             }
  1757.         }
  1758.        
  1759.         internal void SetUpCompilerEnvironment()
  1760.         {
  1761.             if (!this.isCompilerSet) {
  1762.                 Microsoft.JScript.Globals.TypeRefs = this.TypeRefs;
  1763.                 this.globals = this.Globals;
  1764.                 this.isCompilerSet = true;
  1765.             }
  1766.         }
  1767.        
  1768.         internal void TryToAddImplicitAssemblyReference(string name)
  1769.         {
  1770.             if (!this.autoRef)
  1771.                 return;
  1772.            
  1773.             string key;
  1774.             SimpleHashtable implictAssemblyCache = this.implicitAssemblyCache;
  1775.             if (implicitAssemblyCache == null) {
  1776.                 //Populate cache with things that should not be autoref'd. Canonical form is lower case without extension.
  1777.                 implicitAssemblyCache = new SimpleHashtable(50);
  1778.                
  1779.                 //PEFileName always includes an extension and is never NULL.
  1780.                 implicitAssemblyCache[Path.GetFileNameWithoutExtension(this.PEFileName).ToLowerInvariant()] = true;
  1781.                
  1782.                 foreach (object item in this.vsaItems) {
  1783.                     VsaReference assemblyReference = item as VsaReference;
  1784.                     if (assemblyReference == null || assemblyReference.AssemblyName == null)
  1785.                         continue;
  1786.                     key = Path.GetFileName(assemblyReference.AssemblyName).ToLowerInvariant();
  1787.                     if (key.EndsWith(".dll", StringComparison.Ordinal))
  1788.                         key = key.Substring(0, key.Length - 4);
  1789.                     implicitAssemblyCache[key] = true;
  1790.                 }
  1791.                 this.implicitAssemblyCache = implicitAssemblyCache;
  1792.             }
  1793.            
  1794.             key = name.ToLowerInvariant();
  1795.             if (implicitAssemblyCache[key] != null)
  1796.                 return;
  1797.             implicitAssemblyCache[key] = true;
  1798.            
  1799.             try {
  1800.                 VsaReference assemblyReference = new VsaReference(this, name + ".dll");
  1801.                 if (assemblyReference.Compile(false)) {
  1802.                     ArrayList implicitAssemblies = this.implicitAssemblies;
  1803.                     if (implicitAssemblies == null) {
  1804.                         implicitAssemblies = new ArrayList();
  1805.                         this.implicitAssemblies = implicitAssemblies;
  1806.                     }
  1807.                     implicitAssemblies.Add(assemblyReference.Assembly);
  1808.                 }
  1809.             }
  1810.             catch (VsaException) {
  1811.             }
  1812.         }
  1813.        
  1814.         internal string RuntimeDirectory {
  1815.             get {
  1816.                 if (this.runtimeDirectory == null) {
  1817.                     //Get the path to mscorlib.dll
  1818.                     string s = typeof(object).Module.FullyQualifiedName;
  1819.                     //Remove the file part to get the directory
  1820.                     this.runtimeDirectory = Path.GetDirectoryName(s);
  1821.                 }
  1822.                 return this.runtimeDirectory;
  1823.             }
  1824.         }
  1825.        
  1826.         internal string[] LibpathList {
  1827.             get {
  1828.                 if (this.libpathList == null) {
  1829.                     if (this.libpath == null)
  1830.                         this.libpathList = new string[] {typeof(object).Module.Assembly.Location};
  1831.                     else
  1832.                         this.libpathList = this.libpath.Split(new char[] {Path.PathSeparator});
  1833.                 }
  1834.                 return this.libpathList;
  1835.             }
  1836.         }
  1837.        
  1838.         internal string FindAssembly(string name)
  1839.         {
  1840.             string path = name;
  1841.             if (Path.GetFileName(name) == name) {
  1842.                 // just the filename, no path
  1843.                 // Look in current directory
  1844.                 if (File.Exists(name))
  1845.                     path = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + name;
  1846.                 else {
  1847.                     // Look in COM+ runtime directory
  1848.                     string path1 = this.RuntimeDirectory + Path.DirectorySeparatorChar + name;
  1849.                     if (File.Exists(path1))
  1850.                         path = path1;
  1851.                     else {
  1852.                         // Look on the LIBPATH
  1853.                         string[] libpathList = this.LibpathList;
  1854.                         foreach (string l in libpathList) {
  1855.                             if (l.Length > 0) {
  1856.                                 path1 = l + Path.DirectorySeparatorChar + name;
  1857.                                 if (File.Exists(path1)) {
  1858.                                     path = path1;
  1859.                                     break;
  1860.                                 }
  1861.                             }
  1862.                         }
  1863.                     }
  1864.                 }
  1865.             }
  1866.             if (!File.Exists(path))
  1867.                 return null;
  1868.             return path;
  1869.         }
  1870.        
  1871.         protected override void ValidateRootMoniker(string rootMoniker)
  1872.         {
  1873.             // We override this method to avoid reading the registry in a non-VSA scenario
  1874.             if (this.genStartupClass)
  1875.                 base.ValidateRootMoniker(rootMoniker);
  1876.             else if (rootMoniker == null || rootMoniker.Length == 0)
  1877.                 throw new VsaException(VsaError.RootMonikerInvalid);
  1878.         }
  1879.        
  1880.         static internal bool CheckIdentifierForCLSCompliance(string name)
  1881.         {
  1882.             if (name[0] == '_')
  1883.                 return false;
  1884.             for (int i = 0; i < name.Length; i++) {
  1885.                 if (name[i] == '$')
  1886.                     return false;
  1887.             }
  1888.             return true;
  1889.         }
  1890.        
  1891.         internal void CheckTypeNameForCLSCompliance(string name, string fullname, Context context)
  1892.         {
  1893.             if (!this.isCLSCompliant)
  1894.                 return;
  1895.             if (name[0] == '_') {
  1896.                 context.HandleError(JSError.NonCLSCompliantType);
  1897.                 return;
  1898.             }
  1899.             if (!VsaEngine.CheckIdentifierForCLSCompliance(fullname)) {
  1900.                 context.HandleError(JSError.NonCLSCompliantType);
  1901.                 return;
  1902.             }
  1903.             if (this.typenameTable == null)
  1904.                 this.typenameTable = new Hashtable(StringComparer.OrdinalIgnoreCase);
  1905.             if (this.typenameTable[fullname] == null)
  1906.                 this.typenameTable[fullname] = fullname;
  1907.             else
  1908.                 context.HandleError(JSError.NonCLSCompliantType);
  1909.         }
  1910.        
  1911.     }
  1912.    
  1913.     // The VSA spec requires that every IVsaEngine has a host property that is non-null.
  1914.     // Since every assembly that we generate creates an engine (see CreateEngineAndGetGlobalScope)
  1915.     // we must provide a default site for it.
  1916.    
  1917.     class DefaultVsaSite : BaseVsaSite
  1918.     {
  1919.         public override bool OnCompilerError(IVsaError error)
  1920.         {
  1921.             // We expect only JScriptExceptions here, and we throw them to be caught by the host
  1922.             throw (JScriptException)error;
  1923.         }
  1924.     }
  1925. }

Developer Fusion