示例#1
0
        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);
        }