/// <summary> /// This routine loads a script (if it has not already been loaded), /// and sets up globals for the script. The script needs to be safe to /// have its entrypoint called from OBJECT_INVALID for this function to /// work properly. /// </summary> /// <param name="ScriptName">Supplies the name of the script to load.</param> /// <param name="ForceLoadScript">If true, forcibly attempt to load /// the script.</param> /// <param name="CallerScript">Supplies the script object owned by the /// caller.</param> /// <returns>The script object for the newly loaded script. On failure /// an exception is raised.</returns> public static IGeneratedScriptProgram LoadScript(string ScriptName, bool ForceLoadScript, CLRScriptBase CallerScript) { string AssemblyName = String.Format("NWScriptAsm_{0}, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", ScriptName); string TypeName = String.Format("NWScript.JITCode.{0}.ScriptProgram", ScriptName); Assembly ScriptAssembly; IGeneratedScriptProgram ScriptObject; Type ScriptObjectType; MethodInfo NWScriptInitGlobals; // // Check if the script is already loaded. If so, use the existing // script assembly. // ScriptAssembly = (from LoadedAsm in AppDomain.CurrentDomain.GetAssemblies() where LoadedAsm.FullName == AssemblyName select LoadedAsm).FirstOrDefault(); if (ScriptAssembly == null && ForceLoadScript) { // // The assembly is not yet loaded. Force it to be loaded via // a dummy ExecuteScript call. // CallerScript.ExecuteScript(ScriptName, CLRScriptBase.OBJECT_INVALID); ScriptAssembly = (from LoadedAsm in AppDomain.CurrentDomain.GetAssemblies() where LoadedAsm.FullName == AssemblyName select LoadedAsm).FirstOrDefault(); } if (ScriptAssembly == null) { throw new ApplicationException("Could not load script " + ScriptName); } // // Now that the script assembly is loaded, we can create a script // object out of the script for our own use. The script object // encapsulates a private set of global variables for the target // script. // ScriptObject = (IGeneratedScriptProgram)ScriptAssembly.CreateInstance( TypeName, false, BindingFlags.CreateInstance, null, new object[] { CallerScript.ScriptHost.Intrinsics, CallerScript.ScriptHost.Host }, null, null); ScriptObjectType = ScriptObject.GetType(); // // If the script had global variables, call the global variable // initializer on the script now. This will set the script object // up into a state as though we created all the global variables, // but stopped just before main() or StartingConditional(). // NWScriptInitGlobals = ScriptObjectType.GetMethod("NWScriptInitGlobals"); if (NWScriptInitGlobals != null) { NWScriptInitGlobals.Invoke(ScriptObject, null); } // // The private script object is ready to use. Return the instance // of the script that we had created. // return(ScriptObject); }