Esempio n. 1
0
        /**
         * @brief Compile a script to produce a ScriptObjCode object
         * @returns object code pointer or null if compile error
         *          also can throw compile error exception
         */
        public ScriptObjCode Compile()
        {
            Stream       objFileStream = null;
            StreamWriter asmFileWriter = null;
            string       sourceHash    = null;
            TextWriter   saveSource    = null;

            string objFileName = GetScriptFileName(m_ScriptObjCodeKey + ".yobj");
            string tmpFileName = GetScriptFileName(m_ScriptObjCodeKey + ".ytmp");

            // If we already have an object file, don't bother compiling.
            if (!m_ForceRecomp && File.Exists(objFileName))
            {
                objFileStream = File.OpenRead(objFileName);
            }
            else
            {
                // If source file empty, try to read from asset server.
                if (EmptySource(m_SourceCode))
                {
                    m_SourceCode = FetchSource(m_CameFrom);
                }

                // Maybe write script source to a file for debugging.
                if (m_Engine.m_ScriptDebugSaveSource)
                {
                    string lslFileName = GetScriptFileName(m_ScriptObjCodeKey + ".lsl");
//                    m_log.Debug ("[YEngine]: MMRScriptCompileSaveSource: saving to " + lslFileName);
                    saveSource = File.CreateText(lslFileName);
                }

                // Parse source string into tokens.
                TokenBegin tokenBegin;
                try
                {
                    tokenBegin = TokenBegin.Construct(m_CameFrom, saveSource, ErrorHandler, m_SourceCode, out sourceHash);
                }
                finally
                {
                    if (saveSource != null)
                    {
                        saveSource.Close();
                    }
                }
                if (tokenBegin == null)
                {
                    m_log.Debug("[YEngine]: parsing errors on " + m_ScriptObjCodeKey);
                    return(null);
                }

                // Create object file one way or another.
                try
                {
                    // Create abstract syntax tree from raw tokens.
                    TokenScript tokenScript = ScriptReduce.Reduce(tokenBegin);
                    if (tokenScript == null)
                    {
                        m_log.Warn("[YEngine]: reduction errors on " + m_ScriptObjCodeKey + " (" + m_CameFrom + ")");
                        PrintCompilerErrors();
                        return(null);
                    }

                    // Compile abstract syntax tree to write object file.
                    using (BinaryWriter objFileWriter = new BinaryWriter(File.Create(tmpFileName)))
                    {
                        bool ok = ScriptCodeGen.CodeGen(tokenScript, objFileWriter, sourceHash);
                        if (!ok)
                        {
                            m_log.Warn("[YEngine]: compile error on " + m_ScriptObjCodeKey + " (" + m_CameFrom + ")");
                            PrintCompilerErrors();
                            return(null);
                        }
                    }

                    // File has been completely written.
                    // If there is an old one laying around, delete it now.
                    // Then re-open the new file for reading from the beginning.
                    if (File.Exists(objFileName))
                    {
                        File.Replace(tmpFileName, objFileName, null);
                    }
                    else
                    {
                        File.Move(tmpFileName, objFileName);
                    }

                    objFileStream = File.OpenRead(objFileName);
                }
                finally
                {
                    // In case something went wrong writing temp file, delete it.
                    File.Delete(tmpFileName);
                }

                // Since we just wrote the .xmrobj file, maybe save disassembly.
                if (m_Engine.m_ScriptDebugSaveIL)
                {
                    string asmFileName = GetScriptFileName(m_ScriptObjCodeKey + ".yasm");
//                    m_log.Debug ("[YEngine]: MMRScriptCompileSaveILGen: saving to " + asmFileName);
                    asmFileWriter = File.CreateText(asmFileName);
                }
            }

            // Read object file to create ScriptObjCode object.
            // Maybe also write disassembly to a file for debugging.
            BinaryReader  objFileReader = new BinaryReader(objFileStream);
            ScriptObjCode scriptObjCode = null;

            try
            {
                scriptObjCode = new ScriptObjCode(objFileReader, asmFileWriter, null);
            }
            finally
            {
                objFileReader.Close();
                if (asmFileWriter != null)
                {
                    asmFileWriter.Flush();
                    asmFileWriter.Close();
                }
            }

            return(scriptObjCode);
        }
Esempio n. 2
0
        /**
         * @brief Compile a script to produce a ScriptObjCode object
         * @returns object code pointer or null if compile error
         *          also can throw compile error exception
         */
        public ScriptObjCode Compile()
        {
            bool         oldObjFile    = false;
            Stream       objFileStream = null;
            StreamWriter asmFileWriter = null;
            string       envar         = null;
            string       sourceHash    = null;
            TextWriter   saveSource    = null;

            string asmFileName = GetScriptFileName(m_ScriptObjCodeKey + ".xmrasm");
            string lslFileName = GetScriptFileName(m_ScriptObjCodeKey + ".lsl");
            string objFileName = GetScriptFileName(m_ScriptObjCodeKey + ".xmrobj");
            string tmpFileName = GetScriptFileName(m_ScriptObjCodeKey + ".xmrtmp");

            /*
             * If we already have an object file, don't bother compiling.
             */
            if (!m_ForceRecomp && File.Exists(objFileName))
            {
                objFileStream = File.OpenRead(objFileName);
                oldObjFile    = true;
            }
            else
            {
                /*
                 * If source file empty, try to read from asset server.
                 */
                if (EmptySource(m_SourceCode))
                {
                    m_SourceCode = FetchSource(m_CameFrom);
                }

                /*
                 * Maybe write script source to a file for debugging.
                 */
                envar = Environment.GetEnvironmentVariable("MMRScriptCompileSaveSource");
                if ((envar != null) && ((envar[0] & 1) != 0))
                {
                    m_log.Debug("[XMREngine]: MMRScriptCompileSaveSource: saving to " + lslFileName);
                    saveSource = File.CreateText(lslFileName);
                }

                /*
                 * Parse source string into tokens.
                 */
                TokenBegin tokenBegin;
                try {
                    tokenBegin = TokenBegin.Construct(m_CameFrom, saveSource, ErrorHandler, m_SourceCode, out sourceHash);
                } finally {
                    if (saveSource != null)
                    {
                        saveSource.Close();
                    }
                }
                if (tokenBegin == null)
                {
                    m_log.Debug("[XMREngine]: parsing errors on " + m_ScriptObjCodeKey);
                    return(null);
                }

                /*
                 * Create object file one way or another.
                 */
                try {
                    objFileStream = File.Create(tmpFileName);

                    /*
                     * Create abstract syntax tree from raw tokens.
                     */
                    TokenScript tokenScript = ScriptReduce.Reduce(tokenBegin);
                    if (tokenScript == null)
                    {
                        m_log.Warn("[XMREngine]: reduction errors on " + m_ScriptObjCodeKey + " (" + m_CameFrom + ")");
                        PrintCompilerErrors();
                        return(null);
                    }

                    /*
                     * Compile abstract syntax tree to write object file.
                     */
                    BinaryWriter objFileWriter = new BinaryWriter(objFileStream);
                    bool         ok            = ScriptCodeGen.CodeGen(tokenScript, objFileWriter, sourceHash);
                    if (!ok)
                    {
                        m_log.Warn("[XMREngine]: compile error on " + m_ScriptObjCodeKey + " (" + m_CameFrom + ")");
                        PrintCompilerErrors();
                        objFileStream.Close();
                        return(null);
                    }
                    objFileStream.Close();

                    /*
                     * File has been completely written.
                     * If there is an old one laying around, delete it now.
                     * Then re-open the new file for reading from the beginning.
                     */
                    if (File.Exists(objFileName))
                    {
                        File.Replace(tmpFileName, objFileName, null);
                    }
                    else
                    {
                        File.Move(tmpFileName, objFileName);
                    }
                    objFileStream = File.OpenRead(objFileName);
                } finally {
                    /*
                     * In case something went wrong writing temp file, delete it.
                     */
                    try {
                        File.Delete(tmpFileName);
                    } catch {
                    }
                }

                /*
                 * Since we just wrote the .xmrobj file, maybe save disassembly.
                 */
                envar = Environment.GetEnvironmentVariable("MMRScriptCompileSaveILGen");
                if ((envar != null) && ((envar[0] & 1) != 0))
                {
                    m_log.Debug("[XMREngine]: MMRScriptCompileSaveILGen: saving to " + asmFileName);
                    asmFileWriter = File.CreateText(asmFileName);
                }
            }

            /*
             * Read object file to create ScriptObjCode object.
             * Maybe also write disassembly to a file for debugging.
             */
            BinaryReader  objFileReader = new BinaryReader(objFileStream);
            ScriptObjCode scriptObjCode = null;

            try {
                scriptObjCode = new ScriptObjCode(objFileReader, asmFileWriter, null);
                if (scriptObjCode != null)
                {
                    scriptObjCode.fileDateUtc = File.GetLastWriteTimeUtc(objFileName);
                }
            } finally {
                objFileReader.Close();
                if (asmFileWriter != null)
                {
                    asmFileWriter.Flush();
                    asmFileWriter.Close();
                }
            }

            /*
             * Maybe an old object file has reached its expiration date.
             */
            if (oldObjFile && (scriptObjCode != null) && scriptObjCode.IsExpired())
            {
                m_log.Debug("[XMREngine]: expiration reached on " + m_ScriptObjCodeKey + ", reloading");
                m_ForceRecomp = true;
                scriptObjCode = Compile();
            }

            return(scriptObjCode);
        }