public void PerformScriptCompile( string source, string asset, UUID ownerUUID, bool alwaysRecompile, out string assembly, out Dictionary <KeyValuePair <int, int>, KeyValuePair <int, int> > linemap) { // m_log.DebugFormat("[Compiler]: Checking script for asset {0} in {1}\n{2}", asset, m_scriptEngine.World.Name, source); IScriptModuleComms comms = m_scriptEngine.World.RequestModuleInterface <IScriptModuleComms>(); linemap = null; m_warnings.Clear(); assembly = GetCompilerOutput(asset); // m_log.DebugFormat("[Compiler]: Retrieved assembly {0} for asset {1} in {2}", assembly, asset, m_scriptEngine.World.Name); CheckOrCreateScriptsDirectory(); // Don't recompile if we're not forced to and we already have it // Performing 3 file exists tests for every script can still be slow if (!alwaysRecompile && File.Exists(assembly) && File.Exists(assembly + ".text") && File.Exists(assembly + ".map")) { // m_log.DebugFormat("[Compiler]: Found existing assembly {0} for asset {1} in {2}", assembly, asset, m_scriptEngine.World.Name); // If we have already read this linemap file, then it will be in our dictionary. // Don't build another copy of the dictionary (saves memory) and certainly // don't keep reading the same file from disk multiple times. if (!m_lineMaps.ContainsKey(assembly)) { m_lineMaps[assembly] = ReadMapFile(assembly + ".map"); } linemap = m_lineMaps[assembly]; return; } // m_log.DebugFormat("[Compiler]: Compiling assembly {0} for asset {1} in {2}", assembly, asset, m_scriptEngine.World.Name); if (source == String.Empty) { throw new Exception("Cannot find script assembly and no script text present"); } enumCompileType language = DefaultCompileLanguage; if (source.StartsWith("//c#", true, CultureInfo.InvariantCulture)) { language = enumCompileType.cs; } if (source.StartsWith("//vb", true, CultureInfo.InvariantCulture)) { language = enumCompileType.vb; // We need to remove //vb, it won't compile with that source = source.Substring(4, source.Length - 4); } if (source.StartsWith("//lsl", true, CultureInfo.InvariantCulture)) { language = enumCompileType.lsl; } // m_log.DebugFormat("[Compiler]: Compile language is {0}", language); if (!AllowedCompilers.ContainsKey(language.ToString())) { // Not allowed to compile to this language! string errtext = String.Empty; errtext += "The compiler for language \"" + language.ToString() + "\" is not in list of allowed compilers. Script will not be executed!"; throw new Exception(errtext); } if (m_scriptEngine.World.Permissions.CanCompileScript(ownerUUID, (int)language) == false) { // Not allowed to compile to this language! string errtext = String.Empty; errtext += ownerUUID + " is not in list of allowed users for this scripting language. Script will not be executed!"; throw new Exception(errtext); } string compileScript = string.Empty; if (language == enumCompileType.lsl) { // Its LSL, convert it to C# StringBuilder sb = new StringBuilder(16394); LSL_Converter = (ICodeConverter) new CSCodeGenerator(comms, m_insertCoopTerminationCalls); AddCSScriptHeader( m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName, m_scriptEngine.ScriptBaseClassParameters, sb); LSL_Converter.Convert(source, sb); AddCSScriptTail(sb); compileScript = sb.ToString(); // copy converter warnings into our warnings. foreach (string warning in LSL_Converter.GetWarnings()) { AddWarning(warning); } linemap = ((CSCodeGenerator)LSL_Converter).PositionMap; // Write the linemap to a file and save it in our dictionary for next time. m_lineMaps[assembly] = linemap; WriteMapFile(assembly + ".map", linemap); LSL_Converter.Clear(); } else { switch (language) { case enumCompileType.cs: compileScript = CreateCSCompilerScript( compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName, m_scriptEngine.ScriptBaseClassParameters); break; case enumCompileType.vb: compileScript = CreateVBCompilerScript( compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName); break; } } assembly = CompileFromDotNetText(compileScript, language, asset, assembly); }