/** * @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); }
private void XmrTestPev(string[] args, int indx) { bool flagAll = false; int numScripts = 0; XMRInstance[] instances; // Decode command line options. int i, j; List <string> selargs = new List <string>(args.Length); MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods(); MethodInfo eventmethod; for (i = indx; i < args.Length; i++) { string arg = args[i]; if (arg == "-all") { flagAll = true; continue; } if (arg == "-help") { m_log.Info("[YEngine]: yeng pev -all | <part-of-script-name> <event-name> <params...>"); return; } if (arg[0] == '-') { m_log.Error("[YEngine]: unknown option " + arg + ", try 'yeng pev -help'"); return; } for (j = 0; j < eventmethods.Length; j++) { eventmethod = eventmethods[j]; if (eventmethod.Name == arg) { goto gotevent; } } selargs.Add(arg); } m_log.Error("[YEngine]: missing <event-name> <params...>, try 'yeng pev -help'"); return; gotevent: string eventname = eventmethod.Name; StringBuilder sourcesb = new StringBuilder(); while (++i < args.Length) { sourcesb.Append(' '); sourcesb.Append(args[i]); } string sourcest = sourcesb.ToString(); string sourcehash; youveanerror = false; Token t = TokenBegin.Construct("", null, ErrorMsg, sourcest, out sourcehash); if (youveanerror) { return; } ParameterInfo[] paraminfos = eventmethod.GetParameters(); object[] paramvalues = new object[paraminfos.Length]; i = 0; while (!((t = t.nextToken) is TokenEnd)) { if (i >= paramvalues.Length) { ErrorMsg(t, "extra parameter(s)"); return; } paramvalues[i] = ParseParamValue(ref t); if (paramvalues[i] == null) { return; } i++; } ScriptEngine.Shared.EventParams eps = new ScriptEngine.Shared.EventParams(eventname, paramvalues, zeroDetectParams); // Scan instance list to find those that match selection criteria. if (!Monitor.TryEnter(m_InstancesDict, 100)) { m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); return; } try { instances = new XMRInstance[m_InstancesDict.Count]; foreach (XMRInstance ins in m_InstancesDict.Values) { if (flagAll || InstanceMatchesArgs(ins, selargs.ToArray(), 0)) { instances[numScripts++] = ins; } } } finally { Monitor.Exit(m_InstancesDict); } // Post event to the matching instances. for (i = 0; i < numScripts; i++) { XMRInstance inst = instances[i]; m_log.Info("[YEngine]: post " + eventname + " to " + inst.m_DescName); inst.PostEvent(eps); } }
/** * @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); }