Yengine temp file delete was still bad in case of script errors

httptests
UbitUmarov 2018-03-09 21:33:39 +00:00
parent cf5ec5d29c
commit c723a1be16
3 changed files with 53 additions and 51 deletions

View File

@ -835,33 +835,41 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// Do both global functions, script-defined class static methods and // Do both global functions, script-defined class static methods and
// script-defined instance methods, as we handle the differences // script-defined instance methods, as we handle the differences
// during compilation of the functions/methods themselves. // during compilation of the functions/methods themselves.
for(int pass = 0; pass < 2; pass++)
// headers
foreach(TokenDeclVar declFunc in tokenScript.variablesStack)
{ {
foreach(TokenDeclVar declFunc in tokenScript.variablesStack) if(declFunc.retType != null)
GenerateMethodHeader(declFunc);
}
foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues)
{
if(sdType is TokenDeclSDTypeClass)
{ {
if(declFunc.retType != null) TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType;
foreach(TokenDeclVar declFunc in sdtClass.members)
{ {
if(pass == 0) if((declFunc.retType != null) && ((declFunc.sdtFlags & ScriptReduce.SDT_ABSTRACT) == 0))
GenerateMethodHeader(declFunc); GenerateMethodHeader(declFunc);
else
GenerateMethodBody(declFunc);
} }
} }
foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) }
// now bodies
foreach(TokenDeclVar declFunc in tokenScript.variablesStack)
{
if(declFunc.retType != null)
GenerateMethodBody(declFunc);
}
foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues)
{
if(sdType is TokenDeclSDTypeClass)
{ {
if(sdType is TokenDeclSDTypeClass) TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType;
foreach(TokenDeclVar declFunc in sdtClass.members)
{ {
TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; if((declFunc.retType != null) && ((declFunc.sdtFlags & ScriptReduce.SDT_ABSTRACT) == 0))
foreach(TokenDeclVar declFunc in sdtClass.members) GenerateMethodBody(declFunc);
{
if((declFunc.retType != null) && ((declFunc.sdtFlags & ScriptReduce.SDT_ABSTRACT) == 0))
{
if(pass == 0)
GenerateMethodHeader(declFunc);
else
GenerateMethodBody(declFunc);
}
}
} }
} }
} }

View File

@ -90,46 +90,44 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// Create object file one way or another. // Create object file one way or another.
try try
{ {
objFileStream = File.Create (tmpFileName);
// Create abstract syntax tree from raw tokens. // Create abstract syntax tree from raw tokens.
TokenScript tokenScript = ScriptReduce.Reduce(tokenBegin); TokenScript tokenScript = ScriptReduce.Reduce(tokenBegin);
if (tokenScript == null) if (tokenScript == null)
{ {
m_log.Warn ("[YEngine]: reduction errors on " + m_ScriptObjCodeKey + " (" + m_CameFrom + ")"); m_log.Warn ("[YEngine]: reduction errors on " + m_ScriptObjCodeKey + " (" + m_CameFrom + ")");
PrintCompilerErrors(); PrintCompilerErrors();
objFileStream.Close();
return null; return null;
} }
// Compile abstract syntax tree to write object file. // Compile abstract syntax tree to write object file.
BinaryWriter objFileWriter = new BinaryWriter (objFileStream); 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 + ")"); bool ok = ScriptCodeGen.CodeGen(tokenScript, objFileWriter, sourceHash);
PrintCompilerErrors (); if (!ok)
objFileWriter.Close (); {
return null; m_log.Warn ("[YEngine]: compile error on " + m_ScriptObjCodeKey + " (" + m_CameFrom + ")");
PrintCompilerErrors ();
return null;
}
} }
objFileWriter.Close ();
// File has been completely written. // File has been completely written.
// If there is an old one laying around, delete it now. // If there is an old one laying around, delete it now.
// Then re-open the new file for reading from the beginning. // Then re-open the new file for reading from the beginning.
if (File.Exists (objFileName)) if (File.Exists(objFileName))
File.Replace (tmpFileName, objFileName, null); File.Replace(tmpFileName, objFileName, null);
else else
File.Move (tmpFileName, objFileName); File.Move(tmpFileName, objFileName);
objFileStream = File.OpenRead (objFileName); objFileStream = File.OpenRead(objFileName);
} }
finally finally
{ {
// In case something went wrong writing temp file, delete it. // In case something went wrong writing temp file, delete it.
try try
{ {
File.Delete (tmpFileName); if(File.Exists(tmpFileName))
File.Delete (tmpFileName);
} }
catch catch
{ {
@ -169,7 +167,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
private void PrintCompilerErrors () private void PrintCompilerErrors ()
{ {
m_log.Info ("[YEngine]: - " + m_Part.GetWorldPosition () + " " + m_DescName); m_log.Info ("[YEngine]: - " + m_Part.GetWorldPosition () + " " + m_DescName);
foreach (string error in m_CompilerErrors) { foreach (string error in m_CompilerErrors)
{
m_log.Info ("[YEngine]: - " + error); m_log.Info ("[YEngine]: - " + error);
} }
} }

View File

@ -399,8 +399,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
* Start event handler. * Start event handler.
* *
* Input: * Input:
* eventCode = code of event to be processed * newEventCode = code of event to be processed
* ehArgs = arguments for the event handler * newEhArgs = arguments for the event handler
* *
* Caution: * Caution:
* It is up to the caller to make sure ehArgs[] is correct for * It is up to the caller to make sure ehArgs[] is correct for
@ -409,15 +409,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
* from ehArgs[] and will throw an array bounds or cast exception * from ehArgs[] and will throw an array bounds or cast exception
* if it can't. * if it can't.
*/ */
private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs) private Exception StartEventHandler(ScriptEventCode newEventCode, object[] newEhArgs)
{ {
// We use this.eventCode == ScriptEventCode.None to indicate we are idle. // We use this.eventCode == ScriptEventCode.None to indicate we are idle.
// So trying to execute ScriptEventCode.None might make a mess. // So trying to execute ScriptEventCode.None might make a mess.
if(eventCode == ScriptEventCode.None) if(newEventCode == ScriptEventCode.None)
return new Exception("Can't process ScriptEventCode.None"); return new Exception("Can't process ScriptEventCode.None");
// Silly to even try if there is no handler defined for this event. // Silly to even try if there is no handler defined for this event.
if(((int)eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)eventCode] == null)) if(((int)newEventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)newEventCode] == null))
return null; return null;
// The microthread shouldn't be processing any event code. // The microthread shouldn't be processing any event code.
@ -427,8 +427,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// Save eventCode so we know what event handler to run in the microthread. // Save eventCode so we know what event handler to run in the microthread.
// And it also marks us busy so we can't be started again and this event lost. // And it also marks us busy so we can't be started again and this event lost.
this.eventCode = eventCode; this.eventCode = newEventCode;
this.ehArgs = ehArgs; this.ehArgs = newEhArgs;
// This calls ScriptUThread.Main() directly, and returns when Main() [indirectly] // This calls ScriptUThread.Main() directly, and returns when Main() [indirectly]
// calls Suspend() or when Main() returns, whichever occurs first. // calls Suspend() or when Main() returns, whichever occurs first.
@ -580,7 +580,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public void Reset() public void Reset()
{ {
checkstate: checkstate:
XMRInstState iState = m_IState; XMRInstState iState = m_IState;
switch(iState) switch(iState)
{ {
@ -834,17 +834,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
switch(this.callMode) switch(this.callMode)
{ {
// Now we are ready to suspend the microthread. // Now we are ready to suspend or resume.
// This is like a longjmp() to the most recent StartEx() or ResumeEx()
// with a simultaneous setjmp() so ResumeEx() can longjmp() back here.
// the script event handler wants to hibernate
// capture stack frames and unwind to Start() or Resume()
case CallMode_NORMAL: case CallMode_NORMAL:
m_CheckRunPhase = "suspending"; m_CheckRunPhase = "suspending";
callMode = XMRInstance.CallMode_SAVE; callMode = XMRInstance.CallMode_SAVE;
stackFrames = null; stackFrames = null;
throw new StackHibernateException(); throw new StackHibernateException(); // does not return
// We get here when the script state has been read in by MigrateInEventHandler(). // We get here when the script state has been read in by MigrateInEventHandler().
// Since the stack is completely restored at this point, any subsequent calls // Since the stack is completely restored at this point, any subsequent calls