Y(xmr)engine cosmetics...

httptests
UbitUmarov 2018-02-25 00:18:41 +00:00
parent 2f94fa4dc7
commit 85b973ce1d
19 changed files with 2048 additions and 3766 deletions

View File

@ -35,7 +35,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public class InternalFuncDict: VarDict public class InternalFuncDict: VarDict
{ {
/** /**
* @brief build dictionary of internal functions from an interface. * @brief build dictionary of internal functions from an interface.
* @param iface = interface with function definitions * @param iface = interface with function definitions
@ -46,27 +45,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public InternalFuncDict(Type iface, bool inclSig) public InternalFuncDict(Type iface, bool inclSig)
: base(false) : base(false)
{ {
/* // Loop through list of all methods declared in the interface.
* Loop through list of all methods declared in the interface.
*/
System.Reflection.MethodInfo[] ifaceMethods = iface.GetMethods(); System.Reflection.MethodInfo[] ifaceMethods = iface.GetMethods();
foreach(System.Reflection.MethodInfo ifaceMethod in ifaceMethods) foreach(System.Reflection.MethodInfo ifaceMethod in ifaceMethods)
{ {
string key = ifaceMethod.Name; string key = ifaceMethod.Name;
/* // Only do ones that begin with lower-case letters...
* Only do ones that begin with lower-case letters... // as any others can't be referenced by scripts
* as any others can't be referenced by scripts
*/
if((key[0] < 'a') || (key[0] > 'z')) if((key[0] < 'a') || (key[0] > 'z'))
continue; continue;
try try
{ {
// Create a corresponding TokenDeclVar struct.
/*
* Create a corresponding TokenDeclVar struct.
*/
System.Reflection.ParameterInfo[] parameters = ifaceMethod.GetParameters(); System.Reflection.ParameterInfo[] parameters = ifaceMethod.GetParameters();
TokenArgDecl argDecl = new TokenArgDecl(null); TokenArgDecl argDecl = new TokenArgDecl(null);
for(int i = 0; i < parameters.Length; i++) for(int i = 0; i < parameters.Length; i++)
@ -81,9 +73,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
declFunc.retType = TokenType.FromSysType(null, ifaceMethod.ReturnType); declFunc.retType = TokenType.FromSysType(null, ifaceMethod.ReturnType);
declFunc.argDecl = argDecl; declFunc.argDecl = argDecl;
/* // Add the TokenDeclVar struct to the dictionary.
* Add the TokenDeclVar struct to the dictionary.
*/
this.AddEntry(declFunc); this.AddEntry(declFunc);
} }
catch(Exception except) catch(Exception except)

File diff suppressed because it is too large Load Diff

View File

@ -511,20 +511,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
public override bool MoveNext() public override bool MoveNext()
{ {
/* // First off, return any targets the instruction can come up with.
* First off, return any targets the instruction can come up with.
*/
if(realEnumerator.MoveNext()) if(realEnumerator.MoveNext())
{ {
nn = realEnumerator.Current; nn = realEnumerator.Current;
return true; return true;
} }
/* // Then if this instruction is in a try section, say this instruction
* Then if this instruction is in a try section, say this instruction // can potentially branch to the beginning of the corresponding
* can potentially branch to the beginning of the corresponding // catch/finally.
* catch/finally.
*/
if((index == 0) && (gn.tryBlock != null)) if((index == 0) && (gn.tryBlock != null))
{ {
index++; index++;
@ -532,9 +528,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return true; return true;
} }
/* // That's all we can do.
* That's all we can do.
*/
nn = null; nn = null;
return false; return false;
} }
@ -1875,9 +1869,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
public override bool MoveNext() public override bool MoveNext()
{ {
/* // Return next from list of switch case labels.
* Return next from list of switch case labels.
*/
while(index < gn.myLabels.Length) while(index < gn.myLabels.Length)
{ {
nn = gn.myLabels[index++].whereAmI; nn = gn.myLabels[index++].whereAmI;
@ -1885,9 +1877,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return true; return true;
} }
/* // If all ran out, the switch instruction falls through.
* If all ran out, the switch instruction falls through.
*/
if(index == gn.myLabels.Length) if(index == gn.myLabels.Length)
{ {
index++; index++;
@ -1895,9 +1885,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return true; return true;
} }
/* // Even ran out of that, say there's nothing more.
* Even ran out of that, say there's nothing more.
*/
nn = null; nn = null;
return false; return false;
} }
@ -2527,10 +2515,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(curExcBlock != null) if(curExcBlock != null)
throw new Exception("exception block still open"); throw new Exception("exception block still open");
/* // If an instruction says it doesn't fall through, remove all instructions to
* If an instruction says it doesn't fall through, remove all instructions to // the end of the block.
* the end of the block.
*/
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
if(!gn.CanFallThrough()) if(!gn.CanFallThrough())
@ -2547,12 +2533,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // Scan for OpCodes.Leave instructions.
* Scan for OpCodes.Leave instructions. // For each found, its target for flow analysis purposes is the beginning of the corresponding
* For each found, its target for flow analysis purposes is the beginning of the corresponding // finally block. And the end of the finally block gets a conditional branch target of the
* finally block. And the end of the finally block gets a conditional branch target of the // leave instruction's target. A leave instruction can unwind zero or more finally blocks.
* leave instruction's target. A leave instruction can unwind zero or more finally blocks.
*/
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
if(gn is GraphNodeEmitLabelLeave) if(gn is GraphNodeEmitLabelLeave)
@ -2562,12 +2546,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
GraphNodeBeginExceptionBlock leaveTargetsTryBlock = // try block directly enclosing leave target GraphNodeBeginExceptionBlock leaveTargetsTryBlock = // try block directly enclosing leave target
(leaveTarget == null) ? null : leaveTarget.tryBlock; // ...it must not be unwound (leaveTarget == null) ? null : leaveTarget.tryBlock; // ...it must not be unwound
/* // Step through try { }s from the leave instruction towards its target looking for try { }s with finally { }s.
* Step through try { }s from the leave instruction towards its target looking for try { }s with finally { }s. // The leave instruction unconditionally branches to the beginning of the innermost one found.
* The leave instruction unconditionally branches to the beginning of the innermost one found. // The end of the last one found conditionally branches to the leave instruction's target.
* The end of the last one found conditionally branches to the leave instruction's target. // If none found, the leave is a simple unconditional branch to its target.
* If none found, the leave is a simple unconditional branch to its target.
*/
GraphNodeBeginFinallyBlock innerFinallyBlock = null; GraphNodeBeginFinallyBlock innerFinallyBlock = null;
for(GraphNodeBeginExceptionBlock tryBlock = leaveInstr.tryBlock; for(GraphNodeBeginExceptionBlock tryBlock = leaveInstr.tryBlock;
tryBlock != leaveTargetsTryBlock; tryBlock != leaveTargetsTryBlock;
@ -2586,10 +2568,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // The end of the outermost finally being unwound can conditionally jump to the target of the leave instruction.
* The end of the outermost finally being unwound can conditionally jump to the target of the leave instruction. // In the case of no finallies being unwound, the leave is just a simple unconditional branch.
* In the case of no finallies being unwound, the leave is just a simple unconditional branch.
*/
if(innerFinallyBlock == null) if(innerFinallyBlock == null)
{ {
leaveInstr.unwindTo = leaveTarget; leaveInstr.unwindTo = leaveTarget;
@ -2601,10 +2581,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // See which variables a particular block reads before writing.
* See which variables a particular block reads before writing. // This just considers the block itself and nothing that it branches to or fallsthru to.
* This just considers the block itself and nothing that it branches to or fallsthru to.
*/
GraphNodeBlock currentBlock = null; GraphNodeBlock currentBlock = null;
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
@ -2626,13 +2604,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // For every block we branch to, add that blocks readables to our list of readables,
* For every block we branch to, add that blocks readables to our list of readables, // because we need to have those values valid on entry to our block. But if we write the
* because we need to have those values valid on entry to our block. But if we write the // variable before we can possibly branch to that block, then we don't need to have it valid
* variable before we can possibly branch to that block, then we don't need to have it valid // on entry to our block. So basically it looks like the branch instruction is reading
* on entry to our block. So basically it looks like the branch instruction is reading // everything required by any blocks it can branch to.
* everything required by any blocks it can branch to.
*/
do do
{ {
this.resolvedSomething = false; this.resolvedSomething = false;
@ -2640,17 +2616,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
this.ResolveBlock((GraphNodeBlock)firstLin); this.ResolveBlock((GraphNodeBlock)firstLin);
} while(this.resolvedSomething); } while(this.resolvedSomething);
/* // Repeat the cutting loops as long as we keep finding stuff.
* Repeat the cutting loops as long as we keep finding stuff.
*/
bool didSomething; bool didSomething;
do do
{ {
didSomething = false; didSomething = false;
/* // Strip out ldc.i4.1/xor/ldc.i4.1/xor
* Strip out ldc.i4.1/xor/ldc.i4.1/xor
*/
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
if(!(gn is GraphNodeEmit)) if(!(gn is GraphNodeEmit))
@ -2678,9 +2650,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
didSomething = true; didSomething = true;
} }
/* // Replace c{cond}/ldc.i4.1/xor/br{false,true} -> c{cond}/br{true,false}
* Replace c{cond}/ldc.i4.1/xor/br{false,true} -> c{cond}/br{true,false}
*/
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
if(!(gn is GraphNodeEmit)) if(!(gn is GraphNodeEmit))
@ -2711,9 +2681,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
didSomething = true; didSomething = true;
} }
/* // Replace c{cond}/br{false,true} -> b{!,}{cond}
* Replace c{cond}/br{false,true} -> b{!,}{cond}
*/
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
if(!(gn is GraphNodeEmit)) if(!(gn is GraphNodeEmit))
@ -2746,9 +2714,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
didSomething = true; didSomething = true;
} }
/* // Replace ld{c.i4.0,null}/br{ne.un,eq} -> br{true,false}
* Replace ld{c.i4.0,null}/br{ne.un,eq} -> br{true,false}
*/
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
if(!(gn is GraphNodeEmit)) if(!(gn is GraphNodeEmit))
@ -2767,17 +2733,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
didSomething = true; didSomething = true;
} }
/* // Replace:
* Replace: // ldloc v1
* ldloc v1 // stloc v2
* stloc v2 // ld<anything> except ld<anything> v2
* ld<anything> except ld<anything> v2 // ldloc v2
* ldloc v2 // ...v2 unreferenced hereafter
* ...v2 unreferenced hereafter // With:
* With: // ld<anything> except ld<anything> v2
* ld<anything> except ld<anything> v2 // ldloc v1
* ldloc v1
*/
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
@ -2833,11 +2797,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
didSomething = true; didSomething = true;
} }
/* // Remove all the stloc/ldloc that are back-to-back without the local
* Remove all the stloc/ldloc that are back-to-back without the local // being needed afterwards. If it is needed afterwards, replace the
* being needed afterwards. If it is needed afterwards, replace the // stloc/ldloc with dup/stloc.
* stloc/ldloc with dup/stloc.
*/
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
if((gn is GraphNodeEmitLocal) && if((gn is GraphNodeEmitLocal) &&
@ -2871,10 +2833,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // Remove all write-only local variables, ie, those with no ldloc[a] references.
* Remove all write-only local variables, ie, those with no ldloc[a] references. // Replace any stloc instructions with pops.
* Replace any stloc instructions with pops.
*/
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
ScriptMyLocal rdlcl = gn.ReadsLocal(); ScriptMyLocal rdlcl = gn.ReadsLocal();
@ -2900,9 +2860,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // Remove any Ld<const>/Dup,Pop.
* Remove any Ld<const>/Dup,Pop.
*/
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
{ {
if((gn is GraphNodeEmit) && if((gn is GraphNodeEmit) &&
@ -2921,9 +2879,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} while(didSomething); } while(didSomething);
/* // Dump out the results.
* Dump out the results.
*/
if(DEBUG) if(DEBUG)
{ {
Console.WriteLine(""); Console.WriteLine("");
@ -2982,55 +2938,39 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(currentBlock.hasBeenResolved == this.resolveSequence) if(currentBlock.hasBeenResolved == this.resolveSequence)
return; return;
/* // So we don't recurse forever on a backward branch.
* So we don't recurse forever on a backward branch.
*/
currentBlock.hasBeenResolved = this.resolveSequence; currentBlock.hasBeenResolved = this.resolveSequence;
/* // Assume we haven't written any locals yet.
* Assume we haven't written any locals yet.
*/
List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>(); List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>();
/* // Scan through the instructions in this block.
* Scan through the instructions in this block.
*/
for(GraphNode gn = currentBlock; gn != null;) for(GraphNode gn = currentBlock; gn != null;)
{ {
/* // See if the instruction writes a local we don't know about yet.
* See if the instruction writes a local we don't know about yet.
*/
ScriptMyLocal wrlcl = gn.WritesLocal(); ScriptMyLocal wrlcl = gn.WritesLocal();
if((wrlcl != null) && !localsWrittenSoFar.Contains(wrlcl)) if((wrlcl != null) && !localsWrittenSoFar.Contains(wrlcl))
{ {
localsWrittenSoFar.Add(wrlcl); localsWrittenSoFar.Add(wrlcl);
} }
/* // Scan through all the possible next instructions after this.
* Scan through all the possible next instructions after this. // Note that if we are in the first part of a try/catch/finally block,
* Note that if we are in the first part of a try/catch/finally block, // every instruction conditionally branches to the beginning of the
* every instruction conditionally branches to the beginning of the // second part (the catch/finally block).
* second part (the catch/finally block).
*/
GraphNode nextFallthruNode = null; GraphNode nextFallthruNode = null;
foreach(GraphNode nn in gn.NextNodes) foreach(GraphNode nn in gn.NextNodes)
{ {
if(nn is GraphNodeBlock) if(nn is GraphNodeBlock)
{ {
// Start of a block, go through all locals needed by that block on entry.
/*
* Start of a block, go through all locals needed by that block on entry.
*/
GraphNodeBlock nextBlock = (GraphNodeBlock)nn; GraphNodeBlock nextBlock = (GraphNodeBlock)nn;
ResolveBlock(nextBlock); ResolveBlock(nextBlock);
foreach(ScriptMyLocal readByNextBlock in nextBlock.localsReadBeforeWritten) foreach(ScriptMyLocal readByNextBlock in nextBlock.localsReadBeforeWritten)
{ {
// If this block hasn't written it by now and this block doesn't already
/* // require it on entry, say this block requires it on entry.
* If this block hasn't written it by now and this block doesn't already
* require it on entry, say this block requires it on entry.
*/
if(!localsWrittenSoFar.Contains(readByNextBlock) && if(!localsWrittenSoFar.Contains(readByNextBlock) &&
!currentBlock.localsReadBeforeWritten.Contains(readByNextBlock)) !currentBlock.localsReadBeforeWritten.Contains(readByNextBlock))
{ {
@ -3041,19 +2981,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
else else
{ {
// Not start of a block, should be normal fallthru instruction.
/*
* Not start of a block, should be normal fallthru instruction.
*/
if(nextFallthruNode != null) if(nextFallthruNode != null)
throw new Exception("more than one fallthru from " + gn.ToString()); throw new Exception("more than one fallthru from " + gn.ToString());
nextFallthruNode = nn; nextFallthruNode = nn;
} }
} }
/* // Process next instruction if it isn't the start of a block.
* Process next instruction if it isn't the start of a block.
*/
if(nextFallthruNode == gn) if(nextFallthruNode == gn)
throw new Exception("can't fallthru to self"); throw new Exception("can't fallthru to self");
gn = nextFallthruNode; gn = nextFallthruNode;

View File

@ -107,8 +107,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return (type.ToLSLWrapType() != null) ? type.ToLSLWrapType() : type.ToSysType(); return (type.ToLSLWrapType() != null) ? type.ToLSLWrapType() : type.ToSysType();
} }
// if a field of an XMRInstArrays array cannot be directly written, /*
// get the method that can write it * if a field of an XMRInstArrays array cannot be directly written,
* get the method that can write it
*/
private static MethodInfo ArrVarPopMeth(FieldInfo fi) private static MethodInfo ArrVarPopMeth(FieldInfo fi)
{ {
if(fi.Name == "iarLists") if(fi.Name == "iarLists")
@ -120,7 +122,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return null; return null;
} }
// emit code to push value onto stack /*
* emit code to push value onto stack
*/
public void PushVal(ScriptCodeGen scg, Token errorAt, TokenType stackType) public void PushVal(ScriptCodeGen scg, Token errorAt, TokenType stackType)
{ {
this.PushVal(scg, errorAt, stackType, false); this.PushVal(scg, errorAt, stackType, false);
@ -133,7 +137,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public abstract void PushVal(ScriptCodeGen scg, Token errorAt); public abstract void PushVal(ScriptCodeGen scg, Token errorAt);
public abstract void PushRef(ScriptCodeGen scg, Token errorAt); public abstract void PushRef(ScriptCodeGen scg, Token errorAt);
// emit code to pop value from stack /*
* emit code to pop value from stack
*/
public void PopPost(ScriptCodeGen scg, Token errorAt, TokenType stackType) public void PopPost(ScriptCodeGen scg, Token errorAt, TokenType stackType)
{ {
TypeCast.CastTopOfStack(scg, errorAt, stackType, this.type, false); TypeCast.CastTopOfStack(scg, errorAt, stackType, this.type, false);
@ -141,11 +147,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
public virtual void PopPre(ScriptCodeGen scg, Token errorAt) public virtual void PopPre(ScriptCodeGen scg, Token errorAt)
{ {
} // call this before pushing value to be popped }
/*
* call this before pushing value to be popped
*/
public abstract void PopPost(ScriptCodeGen scg, Token errorAt); // call this after pushing value to be popped public abstract void PopPost(ScriptCodeGen scg, Token errorAt); // call this after pushing value to be popped
// return true: doing a PushVal() does not involve CheckRun()
// false: otherwise /*
* return true: doing a PushVal() does not involve CheckRun()
* false: otherwise
*/
public virtual bool IsReadTrivial(ScriptCodeGen scg, Token readAt) public virtual bool IsReadTrivial(ScriptCodeGen scg, Token readAt)
{ {
return true; return true;
@ -173,12 +186,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return ((TokenTypeSDTypeDelegate)type).decl.GetArgSig(); return ((TokenTypeSDTypeDelegate)type).decl.GetArgSig();
} }
// These are used only if type is a delegate too /*
// - but it is a real delegate pointer in a global or local variable or a field, etc * These are used only if type is a delegate too
// ie, PushVal() pushes a delegate pointer * - but it is a real delegate pointer in a global or local variable or a field, etc
// - so we must have CallPre() push the delegate pointer as a 'this' for this.Invoke(...) * - ie, PushVal() pushes a delegate pointer
// - and CallPost() call the delegate's Invoke() method * - so we must have CallPre() push the delegate pointer as a 'this' for this.Invoke(...)
// - we assume the target function is non-trivial so we always use a call label * - and CallPost() call the delegate's Invoke() method
* - we assume the target function is non-trivial so we always use a call label
*/
public virtual void CallPre(ScriptCodeGen scg, Token errorAt) // call this before pushing arguments public virtual void CallPre(ScriptCodeGen scg, Token errorAt) // call this before pushing arguments
{ {
new ScriptCodeGen.CallLabel(scg, errorAt); new ScriptCodeGen.CallLabel(scg, errorAt);

View File

@ -64,9 +64,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
Dictionary<string, ScriptConst> sc = new Dictionary<string, ScriptConst>(); Dictionary<string, ScriptConst> sc = new Dictionary<string, ScriptConst>();
/* // For every event code, define XMREVENTCODE_<eventname> and XMREVENTMASKn_<eventname> symbols.
* For every event code, define XMREVENTCODE_<eventname> and XMREVENTMASKn_<eventname> symbols.
*/
for(int i = 0; i < 64; i++) for(int i = 0; i < 64; i++)
{ {
try try
@ -87,9 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
catch { } catch { }
} }
/* // Also get all the constants from XMRInstAbstract and ScriptBaseClass etc as well.
* Also get all the constants from XMRInstAbstract and ScriptBaseClass etc as well.
*/
for(Type t = typeof(XMRInstAbstract); t != typeof(object); t = t.BaseType) for(Type t = typeof(XMRInstAbstract); t != typeof(object); t = t.BaseType)
{ {
AddInterfaceConstants(sc, t.GetFields()); AddInterfaceConstants(sc, t.GetFields());
@ -132,10 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
Type fieldType = constField.FieldType; Type fieldType = constField.FieldType;
CompValu cv; CompValu cv;
/* // The location of a simple number is the number itself.
* The location of a simple number is the number itself. // Access to the value gets compiled as an ldc instruction.
* Access to the value gets compiled as an ldc instruction.
*/
if(fieldType == typeof(double)) if(fieldType == typeof(double))
{ {
cv = new CompValuFloat(new TokenTypeFloat(null), cv = new CompValuFloat(new TokenTypeFloat(null),
@ -152,10 +146,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
((LSL_Integer)constField.GetValue(null)).value); ((LSL_Integer)constField.GetValue(null)).value);
} }
/* // The location of a string is the string itself.
* The location of a string is the string itself. // Access to the value gets compiled as an ldstr instruction.
* Access to the value gets compiled as an ldstr instruction.
*/
else if(fieldType == typeof(string)) else if(fieldType == typeof(string))
{ {
cv = new CompValuString(new TokenTypeStr(null), cv = new CompValuString(new TokenTypeStr(null),
@ -167,18 +159,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
(string)(LSL_String)constField.GetValue(null)); (string)(LSL_String)constField.GetValue(null));
} }
/* // The location of everything else (objects) is the static field in the interface definition.
* The location of everything else (objects) is the static field in the interface definition. // Access to the value gets compiled as an ldsfld instruction.
* Access to the value gets compiled as an ldsfld instruction.
*/
else else
{ {
cv = new CompValuSField(TokenType.FromSysType(null, fieldType), constField); cv = new CompValuSField(TokenType.FromSysType(null, fieldType), constField);
} }
/* // Add to dictionary.
* Add to dictionary.
*/
new ScriptConst(sc, constField.Name, cv); new ScriptConst(sc, constField.Name, cv);
} }
} }

View File

@ -87,9 +87,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public ScriptObjCode(BinaryReader objFileReader, TextWriter asmFileWriter, TextWriter srcFileWriter) public ScriptObjCode(BinaryReader objFileReader, TextWriter asmFileWriter, TextWriter srcFileWriter)
{ {
/* // Check version number to make sure we know how to process file contents.
* Check version number to make sure we know how to process file contents.
*/
char[] ocm = objFileReader.ReadChars(ScriptCodeGen.OBJECT_CODE_MAGIC.Length); char[] ocm = objFileReader.ReadChars(ScriptCodeGen.OBJECT_CODE_MAGIC.Length);
if(new String(ocm) != ScriptCodeGen.OBJECT_CODE_MAGIC) if(new String(ocm) != ScriptCodeGen.OBJECT_CODE_MAGIC)
throw new Exception("not an XMR object file (bad magic)"); throw new Exception("not an XMR object file (bad magic)");
@ -206,14 +204,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public void EndMethod(DynamicMethod method, Dictionary<int, ScriptSrcLoc> srcLocs) public void EndMethod(DynamicMethod method, Dictionary<int, ScriptSrcLoc> srcLocs)
{ {
/* // Save method object code pointer.
* Save method object code pointer.
*/
dynamicMethods.Add(method.Name, method); dynamicMethods.Add(method.Name, method);
/* // Build and sort iloffset -> source code location array.
* Build and sort iloffset -> source code location array.
*/
int n = srcLocs.Count; int n = srcLocs.Count;
KeyValuePair<int, ScriptSrcLoc>[] srcLocArray = new KeyValuePair<int, ScriptSrcLoc>[n]; KeyValuePair<int, ScriptSrcLoc>[] srcLocArray = new KeyValuePair<int, ScriptSrcLoc>[n];
n = 0; n = 0;
@ -221,9 +215,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
srcLocArray[n++] = kvp; srcLocArray[n++] = kvp;
Array.Sort(srcLocArray, endMethodWrapper); Array.Sort(srcLocArray, endMethodWrapper);
/* // Save sorted array.
* Save sorted array.
*/
scriptSrcLocss.Add(method.Name, srcLocArray); scriptSrcLocss.Add(method.Name, srcLocArray);
} }

View File

@ -121,9 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
this.argTypes = argTypes; this.argTypes = argTypes;
this.objFileWriter = objFileWriter; this.objFileWriter = objFileWriter;
/* // Build list that translates system-defined types to script defined types.
* Build list that translates system-defined types to script defined types.
*/
foreach(TokenDeclSDType sdt in tokenScript.sdSrcTypesValues) foreach(TokenDeclSDType sdt in tokenScript.sdSrcTypesValues)
{ {
Type sys = sdt.GetSysType(); Type sys = sdt.GetSysType();
@ -131,11 +129,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
sdTypesRev[sys] = sdt.longName.val; sdTypesRev[sys] = sdt.longName.val;
} }
/* // This tells the reader to call 'new DynamicMethod()' to create
* This tells the reader to call 'new DynamicMethod()' to create // the function header. Then any forward reference calls to this
* the function header. Then any forward reference calls to this // method will have a MethodInfo struct to call.
* method will have a MethodInfo struct to call.
*/
objFileWriter.Write((byte)ScriptObjWriterCode.DclMethod); objFileWriter.Write((byte)ScriptObjWriterCode.DclMethod);
objFileWriter.Write(methName); objFileWriter.Write(methName);
objFileWriter.Write(GetStrFromType(retType)); objFileWriter.Write(GetStrFromType(retType));
@ -154,10 +150,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public void BegMethod() public void BegMethod()
{ {
/* // This tells the reader to call methodInfo.GetILGenerator()
* This tells the reader to call methodInfo.GetILGenerator() // so it can start writing CIL code for the method.
* so it can start writing CIL code for the method.
*/
objFileWriter.Write((byte)ScriptObjWriterCode.BegMethod); objFileWriter.Write((byte)ScriptObjWriterCode.BegMethod);
objFileWriter.Write(methName); objFileWriter.Write(methName);
} }
@ -167,11 +161,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public void EndMethod() public void EndMethod()
{ {
/* // This tells the reader that all code for the method has
* This tells the reader that all code for the method has // been written and so it will typically call CreateDelegate()
* been written and so it will typically call CreateDelegate() // to finalize the method and create an entrypoint.
* to finalize the method and create an entrypoint.
*/
objFileWriter.Write((byte)ScriptObjWriterCode.EndMethod); objFileWriter.Write((byte)ScriptObjWriterCode.EndMethod);
objFileWriter = null; objFileWriter = null;
@ -404,431 +396,385 @@ namespace OpenSim.Region.ScriptEngine.Yengine
while(true) while(true)
{ {
// Get IL instruction offset at beginning of instruction.
/*
* Get IL instruction offset at beginning of instruction.
*/
offset = 0; offset = 0;
if((ilGen != null) && (monoGetCurrentOffset != null)) if((ilGen != null) && (monoGetCurrentOffset != null))
{ {
offset = (int)monoGetCurrentOffset.Invoke(null, ilGenArg); offset = (int)monoGetCurrentOffset.Invoke(null, ilGenArg);
} }
/* // Read and decode next internal format code from input file (.xmrobj file).
* Read and decode next internal format code from input file (.xmrobj file).
*/
ScriptObjWriterCode code = (ScriptObjWriterCode)objReader.ReadByte(); ScriptObjWriterCode code = (ScriptObjWriterCode)objReader.ReadByte();
switch(code) switch(code)
{ {
// Reached end-of-file so we are all done.
/*
* Reached end-of-file so we are all done.
*/
case ScriptObjWriterCode.TheEnd: case ScriptObjWriterCode.TheEnd:
{ return;
return;
}
/* // Beginning of method's contents.
* Beginning of method's contents. // Method must have already been declared via DclMethod
* Method must have already been declared via DclMethod // so all we need is its name to retrieve from methods[].
* so all we need is its name to retrieve from methods[].
*/
case ScriptObjWriterCode.BegMethod: case ScriptObjWriterCode.BegMethod:
{ {
string methName = objReader.ReadString(); string methName = objReader.ReadString();
method = methods[methName]; method = methods[methName];
ilGen = method.GetILGenerator(); ilGen = method.GetILGenerator();
ilGenArg[0] = ilGen; ilGenArg[0] = ilGen;
labels.Clear(); labels.Clear();
locals.Clear(); locals.Clear();
labelNames.Clear(); labelNames.Clear();
localNames.Clear(); localNames.Clear();
srcLocs = new Dictionary<int, ScriptSrcLoc>(); srcLocs = new Dictionary<int, ScriptSrcLoc>();
if(objectTokens != null) if(objectTokens != null)
objectTokens.BegMethod(method); objectTokens.BegMethod(method);
break; break;
} }
/* // End of method's contents (ie, an OpCodes.Ret was probably just output).
* End of method's contents (ie, an OpCodes.Ret was probably just output). // Call the callback to tell it the method is complete, and it can do whatever
* Call the callback to tell it the method is complete, and it can do whatever // it wants with the method.
* it wants with the method.
*/
case ScriptObjWriterCode.EndMethod: case ScriptObjWriterCode.EndMethod:
{ {
ilGen = null; ilGen = null;
ilGenArg[0] = null; ilGenArg[0] = null;
scriptObjCode.EndMethod(method, srcLocs); scriptObjCode.EndMethod(method, srcLocs);
srcLocs = null; srcLocs = null;
if(objectTokens != null) if(objectTokens != null)
objectTokens.EndMethod(); objectTokens.EndMethod();
break; break;
} }
/* // Declare a label for branching to.
* Declare a label for branching to.
*/
case ScriptObjWriterCode.DclLabel: case ScriptObjWriterCode.DclLabel:
{ {
int number = objReader.ReadInt32(); int number = objReader.ReadInt32();
string name = objReader.ReadString(); string name = objReader.ReadString();
labels.Add(number, ilGen.DefineLabel()); labels.Add(number, ilGen.DefineLabel());
labelNames.Add(number, name + "_" + number.ToString()); labelNames.Add(number, name + "_" + number.ToString());
if(objectTokens != null) if(objectTokens != null)
objectTokens.DefineLabel(number, name); objectTokens.DefineLabel(number, name);
break; break;
} }
/* // Declare a local variable to store into.
* Declare a local variable to store into.
*/
case ScriptObjWriterCode.DclLocal: case ScriptObjWriterCode.DclLocal:
{ {
int number = objReader.ReadInt32(); int number = objReader.ReadInt32();
string name = objReader.ReadString(); string name = objReader.ReadString();
string type = objReader.ReadString(); string type = objReader.ReadString();
Type syType = GetTypeFromStr(sdTypes, type); Type syType = GetTypeFromStr(sdTypes, type);
locals.Add(number, ilGen.DeclareLocal(syType)); locals.Add(number, ilGen.DeclareLocal(syType));
localNames.Add(number, name + "_" + number.ToString()); localNames.Add(number, name + "_" + number.ToString());
if(objectTokens != null) if(objectTokens != null)
objectTokens.DefineLocal(number, name, type, syType); objectTokens.DefineLocal(number, name, type, syType);
break; break;
} }
/* // Declare a method that will subsequently be defined.
* Declare a method that will subsequently be defined. // We create the DynamicMethod object at this point in case there
* We create the DynamicMethod object at this point in case there // are forward references from other method bodies.
* are forward references from other method bodies.
*/
case ScriptObjWriterCode.DclMethod: case ScriptObjWriterCode.DclMethod:
{
string methName = objReader.ReadString();
Type retType = GetTypeFromStr(sdTypes, objReader.ReadString());
int nArgs = objReader.ReadInt32();
Type[] argTypes = new Type[nArgs];
string[] argNames = new string[nArgs];
for(int i = 0; i < nArgs; i++)
{ {
string methName = objReader.ReadString(); argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
Type retType = GetTypeFromStr(sdTypes, objReader.ReadString()); argNames[i] = objReader.ReadString();
int nArgs = objReader.ReadInt32();
Type[] argTypes = new Type[nArgs];
string[] argNames = new string[nArgs];
for(int i = 0; i < nArgs; i++)
{
argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
argNames[i] = objReader.ReadString();
}
methods.Add(methName, new DynamicMethod(methName, retType, argTypes));
if(objectTokens != null)
objectTokens.DefineMethod(methName, retType, argTypes, argNames);
break;
} }
methods.Add(methName, new DynamicMethod(methName, retType, argTypes));
if(objectTokens != null)
objectTokens.DefineMethod(methName, retType, argTypes, argNames);
break;
}
/* // Mark a previously declared label at this spot.
* Mark a previously declared label at this spot.
*/
case ScriptObjWriterCode.MarkLabel: case ScriptObjWriterCode.MarkLabel:
{ {
int number = objReader.ReadInt32(); int number = objReader.ReadInt32();
ilGen.MarkLabel(labels[number]); ilGen.MarkLabel(labels[number]);
if(objectTokens != null) if(objectTokens != null)
objectTokens.MarkLabel(offset, number); objectTokens.MarkLabel(offset, number);
break; break;
} }
/* // Try/Catch blocks.
* Try/Catch blocks.
*/
case ScriptObjWriterCode.BegExcBlk: case ScriptObjWriterCode.BegExcBlk:
{ {
ilGen.BeginExceptionBlock(); ilGen.BeginExceptionBlock();
if(objectTokens != null) if(objectTokens != null)
objectTokens.BegExcBlk(offset); objectTokens.BegExcBlk(offset);
break; break;
} }
case ScriptObjWriterCode.BegCatBlk: case ScriptObjWriterCode.BegCatBlk:
{ {
Type excType = GetTypeFromStr(sdTypes, objReader.ReadString()); Type excType = GetTypeFromStr(sdTypes, objReader.ReadString());
ilGen.BeginCatchBlock(excType); ilGen.BeginCatchBlock(excType);
if(objectTokens != null) if(objectTokens != null)
objectTokens.BegCatBlk(offset, excType); objectTokens.BegCatBlk(offset, excType);
break; break;
} }
case ScriptObjWriterCode.BegFinBlk: case ScriptObjWriterCode.BegFinBlk:
{ {
ilGen.BeginFinallyBlock(); ilGen.BeginFinallyBlock();
if(objectTokens != null) if(objectTokens != null)
objectTokens.BegFinBlk(offset); objectTokens.BegFinBlk(offset);
break; break;
} }
case ScriptObjWriterCode.EndExcBlk: case ScriptObjWriterCode.EndExcBlk:
{ {
ilGen.EndExceptionBlock(); ilGen.EndExceptionBlock();
if(objectTokens != null) if(objectTokens != null)
objectTokens.EndExcBlk(offset); objectTokens.EndExcBlk(offset);
break; break;
} }
/* // Emit an opcode with no operand.
* Emit an opcode with no operand.
*/
case ScriptObjWriterCode.EmitNull: case ScriptObjWriterCode.EmitNull:
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode); ilGen.Emit(opCode);
if(objectTokens != null) if(objectTokens != null)
objectTokens.EmitNull(offset, opCode); objectTokens.EmitNull(offset, opCode);
break; break;
} }
/* // Emit an opcode with a FieldInfo operand.
* Emit an opcode with a FieldInfo operand.
*/
case ScriptObjWriterCode.EmitField: case ScriptObjWriterCode.EmitField:
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
Type reflectedType = GetTypeFromStr(sdTypes, objReader.ReadString()); Type reflectedType = GetTypeFromStr(sdTypes, objReader.ReadString());
string fieldName = objReader.ReadString(); string fieldName = objReader.ReadString();
FieldInfo field = reflectedType.GetField(fieldName); FieldInfo field = reflectedType.GetField(fieldName);
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, field); ilGen.Emit(opCode, field);
if(objectTokens != null) if(objectTokens != null)
objectTokens.EmitField(offset, opCode, field); objectTokens.EmitField(offset, opCode, field);
break; break;
} }
/* // Emit an opcode with a LocalBuilder operand.
* Emit an opcode with a LocalBuilder operand.
*/
case ScriptObjWriterCode.EmitLocal: case ScriptObjWriterCode.EmitLocal:
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
int number = objReader.ReadInt32(); int number = objReader.ReadInt32();
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, locals[number]); ilGen.Emit(opCode, locals[number]);
if(objectTokens != null) if(objectTokens != null)
objectTokens.EmitLocal(offset, opCode, number); objectTokens.EmitLocal(offset, opCode, number);
break; break;
} }
/* // Emit an opcode with a Type operand.
* Emit an opcode with a Type operand.
*/
case ScriptObjWriterCode.EmitType: case ScriptObjWriterCode.EmitType:
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
string name = objReader.ReadString(); string name = objReader.ReadString();
Type type = GetTypeFromStr(sdTypes, name); Type type = GetTypeFromStr(sdTypes, name);
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, type); ilGen.Emit(opCode, type);
if(objectTokens != null) if(objectTokens != null)
objectTokens.EmitType(offset, opCode, type); objectTokens.EmitType(offset, opCode, type);
break; break;
} }
/* // Emit an opcode with a Label operand.
* Emit an opcode with a Label operand.
*/
case ScriptObjWriterCode.EmitLabel: case ScriptObjWriterCode.EmitLabel:
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
int number = objReader.ReadInt32(); int number = objReader.ReadInt32();
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, labels[number]); ilGen.Emit(opCode, labels[number]);
if(objectTokens != null) if(objectTokens != null)
objectTokens.EmitLabel(offset, opCode, number); objectTokens.EmitLabel(offset, opCode, number);
break; break;
} }
/* // Emit an opcode with a Label array operand.
* Emit an opcode with a Label array operand.
*/
case ScriptObjWriterCode.EmitLabels: case ScriptObjWriterCode.EmitLabels:
{
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
int nLabels = objReader.ReadInt32();
Label[] lbls = new Label[nLabels];
int[] nums = new int[nLabels];
for(int i = 0; i < nLabels; i++)
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); nums[i] = objReader.ReadInt32();
int nLabels = objReader.ReadInt32(); lbls[i] = labels[nums[i]];
Label[] lbls = new Label[nLabels];
int[] nums = new int[nLabels];
for(int i = 0; i < nLabels; i++)
{
nums[i] = objReader.ReadInt32();
lbls[i] = labels[nums[i]];
}
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, lbls);
if(objectTokens != null)
objectTokens.EmitLabels(offset, opCode, nums);
break;
} }
/* SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
* Emit an opcode with a MethodInfo operand (such as a call) of an external function. ilGen.Emit(opCode, lbls);
*/
if(objectTokens != null)
objectTokens.EmitLabels(offset, opCode, nums);
break;
}
// Emit an opcode with a MethodInfo operand (such as a call) of an external function.
case ScriptObjWriterCode.EmitMethodExt: case ScriptObjWriterCode.EmitMethodExt:
{
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
string methName = objReader.ReadString();
Type methType = GetTypeFromStr(sdTypes, objReader.ReadString());
int nArgs = objReader.ReadInt32();
Type[] argTypes = new Type[nArgs];
for(int i = 0; i < nArgs; i++)
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
string methName = objReader.ReadString();
Type methType = GetTypeFromStr(sdTypes, objReader.ReadString());
int nArgs = objReader.ReadInt32();
Type[] argTypes = new Type[nArgs];
for(int i = 0; i < nArgs; i++)
{
argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
}
MethodInfo methInfo = methType.GetMethod(methName, argTypes);
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, methInfo);
if(objectTokens != null)
objectTokens.EmitMethod(offset, opCode, methInfo);
break;
} }
MethodInfo methInfo = methType.GetMethod(methName, argTypes);
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, methInfo);
/* if(objectTokens != null)
* Emit an opcode with a MethodInfo operand of an internal function objectTokens.EmitMethod(offset, opCode, methInfo);
* (previously declared via DclMethod). break;
*/ }
// Emit an opcode with a MethodInfo operand of an internal function
// (previously declared via DclMethod).
case ScriptObjWriterCode.EmitMethodInt: case ScriptObjWriterCode.EmitMethodInt:
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
string methName = objReader.ReadString(); string methName = objReader.ReadString();
MethodInfo methInfo = methods[methName]; MethodInfo methInfo = methods[methName];
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, methInfo); ilGen.Emit(opCode, methInfo);
if(objectTokens != null) if(objectTokens != null)
objectTokens.EmitMethod(offset, opCode, methInfo); objectTokens.EmitMethod(offset, opCode, methInfo);
break; break;
} }
/* // Emit an opcode with a ConstructorInfo operand.
* Emit an opcode with a ConstructorInfo operand.
*/
case ScriptObjWriterCode.EmitCtor: case ScriptObjWriterCode.EmitCtor:
{
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
Type ctorType = GetTypeFromStr(sdTypes, objReader.ReadString());
int nArgs = objReader.ReadInt32();
Type[] argTypes = new Type[nArgs];
for(int i = 0; i < nArgs; i++)
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
Type ctorType = GetTypeFromStr(sdTypes, objReader.ReadString());
int nArgs = objReader.ReadInt32();
Type[] argTypes = new Type[nArgs];
for(int i = 0; i < nArgs; i++)
{
argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
}
ConstructorInfo ctorInfo = ctorType.GetConstructor(argTypes);
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, ctorInfo);
if(objectTokens != null)
objectTokens.EmitCtor(offset, opCode, ctorInfo);
break;
} }
/* ConstructorInfo ctorInfo = ctorType.GetConstructor(argTypes);
* Emit an opcode with a constant operand of various types. SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
*/ ilGen.Emit(opCode, ctorInfo);
if(objectTokens != null)
objectTokens.EmitCtor(offset, opCode, ctorInfo);
break;
}
// Emit an opcode with a constant operand of various types.
case ScriptObjWriterCode.EmitDouble: case ScriptObjWriterCode.EmitDouble:
{
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
double value = objReader.ReadDouble();
if(opCode != OpCodes.Ldc_R8)
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); throw new Exception("bad opcode " + opCode.ToString());
double value = objReader.ReadDouble();
if(opCode != OpCodes.Ldc_R8)
{
throw new Exception("bad opcode " + opCode.ToString());
}
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, value);
if(objectTokens != null)
objectTokens.EmitDouble(offset, opCode, value);
break;
} }
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, value);
if(objectTokens != null)
objectTokens.EmitDouble(offset, opCode, value);
break;
}
case ScriptObjWriterCode.EmitFloat: case ScriptObjWriterCode.EmitFloat:
{
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
float value = objReader.ReadSingle();
if(opCode != OpCodes.Ldc_R4)
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); throw new Exception("bad opcode " + opCode.ToString());
float value = objReader.ReadSingle();
if(opCode != OpCodes.Ldc_R4)
{
throw new Exception("bad opcode " + opCode.ToString());
}
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, value);
if(objectTokens != null)
objectTokens.EmitFloat(offset, opCode, value);
break;
} }
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, value);
if(objectTokens != null)
objectTokens.EmitFloat(offset, opCode, value);
break;
}
case ScriptObjWriterCode.EmitInteger: case ScriptObjWriterCode.EmitInteger:
{
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
int value = objReader.ReadInt32();
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
if(opCode == OpCodes.Ldc_I4)
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); if((value >= -1) && (value <= 8))
int value = objReader.ReadInt32();
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
if(opCode == OpCodes.Ldc_I4)
{ {
if((value >= -1) && (value <= 8)) opCode = opCodesLdcI4M1P8[value + 1];
{ ilGen.Emit(opCode);
opCode = opCodesLdcI4M1P8[value + 1]; if(objectTokens != null)
ilGen.Emit(opCode); objectTokens.EmitNull(offset, opCode);
if(objectTokens != null) break;
objectTokens.EmitNull(offset, opCode); }
break; if((value >= 0) && (value <= 127))
} {
if((value >= 0) && (value <= 127)) opCode = OpCodes.Ldc_I4_S;
{ ilGen.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
opCode = OpCodes.Ldc_I4_S; goto pemitint;
ilGen.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
goto pemitint;
}
} }
ilGen.Emit(opCode, value);
pemitint:
if(objectTokens != null)
objectTokens.EmitInteger(offset, opCode, value);
break;
} }
ilGen.Emit(opCode, value);
pemitint:
if(objectTokens != null)
objectTokens.EmitInteger(offset, opCode, value);
break;
}
case ScriptObjWriterCode.EmitString: case ScriptObjWriterCode.EmitString:
{ {
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
string value = objReader.ReadString(); string value = objReader.ReadString();
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
ilGen.Emit(opCode, value); ilGen.Emit(opCode, value);
if(objectTokens != null) if(objectTokens != null)
objectTokens.EmitString(offset, opCode, value); objectTokens.EmitString(offset, opCode, value);
break; break;
} }
/* // Who knows what?
* Who knows what?
*/
default: default:
throw new Exception("bad ScriptObjWriterCode " + ((byte)code).ToString()); throw new Exception("bad ScriptObjWriterCode " + ((byte)code).ToString());
} }

File diff suppressed because it is too large Load Diff

View File

@ -219,9 +219,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
sourceHash = null; sourceHash = null;
/* // Now do the tokenization.
* Now do the tokenization.
*/
TokenBegin tokenBegin = new TokenBegin(emsg, "", 0, 0); TokenBegin tokenBegin = new TokenBegin(emsg, "", 0, 0);
tokenBegin.cameFrom = cameFrom; tokenBegin.cameFrom = cameFrom;
tokenBegin.saveSource = saveSource; tokenBegin.saveSource = saveSource;
@ -384,17 +382,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(c == '\n') if(c == '\n')
{ {
/* // Increment source line number and set char index of beg of next line.
* Increment source line number and set char index of beg of next line.
*/
lineNo++; lineNo++;
bolIdx = i + 1; bolIdx = i + 1;
/* // Check for '#' lineno filename newline
* Check for '#' lineno filename newline // lineno is line number of next line in file
* lineno is line number of next line in file // If found, save values and remove tokens from stream
* If found, save values and remove tokens from stream
*/
if((lastToken is TokenStr) && if((lastToken is TokenStr) &&
(lastToken.prevToken is TokenInt) && (lastToken.prevToken is TokenInt) &&
(lastToken.prevToken.prevToken is TokenKwHash)) (lastToken.prevToken.prevToken is TokenKwHash))
@ -407,15 +401,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
continue; continue;
} }
/* // Skip over whitespace.
* Skip over whitespace.
*/
if(c <= ' ') if(c <= ' ')
continue; continue;
/* // Skip over comments.
* Skip over comments.
*/
if((i + 2 <= source.Length) && source.Substring(i, 2).Equals("//")) if((i + 2 <= source.Length) && source.Substring(i, 2).Equals("//"))
{ {
while((i < source.Length) && (source[i] != '\n')) while((i < source.Length) && (source[i] != '\n'))
@ -440,9 +430,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
continue; continue;
} }
/* // Check for numbers.
* Check for numbers.
*/
if((c >= '0') && (c <= '9')) if((c >= '0') && (c <= '9'))
{ {
int j = TryParseFloat(i); int j = TryParseFloat(i);
@ -459,9 +447,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
continue; continue;
} }
/* // Check for quoted strings.
* Check for quoted strings.
*/
if(c == '"') if(c == '"')
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -509,9 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
continue; continue;
} }
/* // Check for quoted characters.
* Check for quoted characters.
*/
if(c == '\'') if(c == '\'')
{ {
char cb = (char)0; char cb = (char)0;
@ -560,9 +544,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
continue; continue;
} }
/* // Check for keywords/names.
* Check for keywords/names.
*/
if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c == '$' && options.dollarsigns)) if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c == '$' && options.dollarsigns))
{ {
int j; int j;
@ -629,9 +611,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
continue; continue;
} }
/* // Check for option enables.
* Check for option enables.
*/
if((c == ';') && (lastToken is TokenName) && if((c == ';') && (lastToken is TokenName) &&
(lastToken.prevToken is TokenName) && (lastToken.prevToken is TokenName) &&
(strcasecmp(((TokenName)lastToken.prevToken).val, "yoption") == 0)) (strcasecmp(((TokenName)lastToken.prevToken).val, "yoption") == 0))
@ -669,9 +649,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
continue; continue;
} }
/* // Lastly, check for delimeters.
* Lastly, check for delimeters.
*/
{ {
int j; int j;
int len = 0; int len = 0;
@ -692,9 +670,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // Don't know what it is!
* Don't know what it is!
*/
TokenError(i, "unknown character '" + c + "'"); TokenError(i, "unknown character '" + c + "'");
} }
} }

View File

@ -177,11 +177,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public static bool IsAssignableFrom(TokenType dstType, TokenType srcType) public static bool IsAssignableFrom(TokenType dstType, TokenType srcType)
{ {
/* // Do a 'dry run' of the casting operation, discarding any emits and not printing any errors.
* Do a 'dry run' of the casting operation, discarding any emits and not printing any errors. // But if the casting tries to print error(s), return false.
* But if the casting tries to print error(s), return false. // Otherwise assume the cast is allowed and return true.
* Otherwise assume the cast is allowed and return true.
*/
SCGIAF scg = new SCGIAF(); SCGIAF scg = new SCGIAF();
scg.ok = true; scg.ok = true;
scg._ilGen = migiaf; scg._ilGen = migiaf;
@ -305,9 +303,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
string oldString = oldType.ToString(); string oldString = oldType.ToString();
string newString = newType.ToString(); string newString = newType.ToString();
/* // 'key' -> 'bool' is the only time we care about key being different than string.
* 'key' -> 'bool' is the only time we care about key being different than string.
*/
if((oldString == "key") && (newString == "bool")) if((oldString == "key") && (newString == "bool"))
{ {
LSLUnwrap(scg, errorAt, oldType); LSLUnwrap(scg, errorAt, oldType);
@ -316,18 +312,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // Treat key and string as same type for all other type casts.
* Treat key and string as same type for all other type casts.
*/
if(oldString == "key") if(oldString == "key")
oldString = "string"; oldString = "string";
if(newString == "key") if(newString == "key")
newString = "string"; newString = "string";
/* // If the types are the same, there is no conceptual casting needed.
* If the types are the same, there is no conceptual casting needed. // However, there may be wraping/unwraping to/from the LSL wrappers.
* However, there may be wraping/unwraping to/from the LSL wrappers.
*/
if(oldString == newString) if(oldString == newString)
{ {
if(oldType.ToLSLWrapType() != newType.ToLSLWrapType()) if(oldType.ToLSLWrapType() != newType.ToLSLWrapType())
@ -338,9 +330,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // Script-defined classes can be cast up and down the tree.
* Script-defined classes can be cast up and down the tree.
*/
if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeClass)) if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeClass))
{ {
TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl; TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl;
@ -369,11 +359,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
goto illcast; goto illcast;
} }
/* // One script-defined interface type cannot be cast to another script-defined interface type,
* One script-defined interface type cannot be cast to another script-defined interface type, // unless the old interface declares that it implements the new interface. That proves that
* unless the old interface declares that it implements the new interface. That proves that // the underlying object, no matter what type, implements the new interface.
* the underlying object, no matter what type, implements the new interface.
*/
if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeInterface)) if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeInterface))
{ {
TokenDeclSDTypeInterface oldDecl = ((TokenTypeSDTypeInterface)oldType).decl; TokenDeclSDTypeInterface oldDecl = ((TokenTypeSDTypeInterface)oldType).decl;
@ -385,11 +373,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // A script-defined class type can be implicitly cast to a script-defined interface type that it
* A script-defined class type can be implicitly cast to a script-defined interface type that it // implements. The result is an array of delegates that give the class's implementation of the
* implements. The result is an array of delegates that give the class's implementation of the // various methods defined by the interface.
* various methods defined by the interface.
*/
if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeInterface)) if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeInterface))
{ {
TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl; TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl;
@ -402,13 +388,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // A script-defined interface type can be explicitly cast to a script-defined class type by
* A script-defined interface type can be explicitly cast to a script-defined class type by // extracting the Target property from element 0 of the delegate array that is the interface
* extracting the Target property from element 0 of the delegate array that is the interface // object and making sure it casts to the correct script-defined class type.
* object and making sure it casts to the correct script-defined class type. //
* // But then only if the class type implements the interface type.
* But then only if the class type implements the interface type.
*/
if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeClass)) if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeClass))
{ {
TokenTypeSDTypeInterface oldSDTI = (TokenTypeSDTypeInterface)oldType; TokenTypeSDTypeInterface oldSDTI = (TokenTypeSDTypeInterface)oldType;
@ -423,17 +407,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // A script-defined interface type can be implicitly cast to object.
* A script-defined interface type can be implicitly cast to object.
*/
if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeObject)) if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeObject))
{ {
return; return;
} }
/* // An object can be explicitly cast to a script-defined interface.
* An object can be explicitly cast to a script-defined interface.
*/
if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeInterface)) if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeInterface))
{ {
ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); ExplCheck(scg, errorAt, explicitAllowed, oldString, newString);
@ -442,18 +422,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // Cast to void is always allowed, such as discarding value from 'i++' or function return value.
* Cast to void is always allowed, such as discarding value from 'i++' or function return value.
*/
if(newType is TokenTypeVoid) if(newType is TokenTypeVoid)
{ {
scg.ilGen.Emit(errorAt, OpCodes.Pop); scg.ilGen.Emit(errorAt, OpCodes.Pop);
return; return;
} }
/* // Cast from undef to object or script-defined type is always allowed.
* Cast from undef to object or script-defined type is always allowed.
*/
if((oldType is TokenTypeUndef) && if((oldType is TokenTypeUndef) &&
((newType is TokenTypeObject) || ((newType is TokenTypeObject) ||
(newType is TokenTypeSDTypeClass) || (newType is TokenTypeSDTypeClass) ||
@ -462,19 +438,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // Script-defined classes can be implicitly cast to objects.
* Script-defined classes can be implicitly cast to objects.
*/
if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeObject)) if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeObject))
{ {
return; return;
} }
/* // Script-defined classes can be explicitly cast from objects and other script-defined classes.
* Script-defined classes can be explicitly cast from objects and other script-defined classes. // Note that we must manually check that it is the correct SDTypeClass however because as far as
* Note that we must manually check that it is the correct SDTypeClass however because as far as // mono is concerned, all SDTypeClass's are the same.
* mono is concerned, all SDTypeClass's are the same.
*/
if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeClass)) if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeClass))
{ {
ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); ExplCheck(scg, errorAt, explicitAllowed, oldString, newString);
@ -483,9 +455,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // Delegates can be implicitly cast to/from objects.
* Delegates can be implicitly cast to/from objects.
*/
if((oldType is TokenTypeSDTypeDelegate) && (newType is TokenTypeObject)) if((oldType is TokenTypeSDTypeDelegate) && (newType is TokenTypeObject))
{ {
return; return;
@ -496,9 +466,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // Some actual conversion is needed, see if it is in table of legal casts.
* Some actual conversion is needed, see if it is in table of legal casts.
*/
string key = oldString + " " + newString; string key = oldString + " " + newString;
if(!legalTypeCasts.TryGetValue(key, out castDelegate)) if(!legalTypeCasts.TryGetValue(key, out castDelegate))
{ {
@ -508,11 +476,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); ExplCheck(scg, errorAt, explicitAllowed, oldString, newString);
} }
/* // Ok, output cast. But make sure it is in native form without any LSL wrapping
* Ok, output cast. But make sure it is in native form without any LSL wrapping // before passing to our casting routine. Then if caller is expecting an LSL-
* before passing to our casting routine. Then if caller is expecting an LSL- // wrapped value on the stack upon return, wrap it up after our casting.
* wrapped value on the stack upon return, wrap it up after our casting.
*/
LSLUnwrap(scg, errorAt, oldType); LSLUnwrap(scg, errorAt, oldType);
castDelegate(scg, errorAt); castDelegate(scg, errorAt);
LSLWrap(scg, errorAt, newType); LSLWrap(scg, errorAt, newType);

View File

@ -130,9 +130,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
throw new Exception("var dict is frozen"); throw new Exception("var dict is frozen");
} }
/* // Make sure we have a sub-dictionary based on the bare name (ie, no signature)
* Make sure we have a sub-dictionary based on the bare name (ie, no signature)
*/
Dictionary<ArgTypes, TDVEntry> typedic; Dictionary<ArgTypes, TDVEntry> typedic;
if(!master.TryGetValue(var.name.val, out typedic)) if(!master.TryGetValue(var.name.val, out typedic))
{ {
@ -140,19 +138,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
master.Add(var.name.val, typedic); master.Add(var.name.val, typedic);
} }
/* // See if there is an entry in the sub-dictionary that matches the argument signature.
* See if there is an entry in the sub-dictionary that matches the argument signature. // Note that fields have null argument lists.
* Note that fields have null argument lists. // Methods always have a non-null argument list, even if only 0 entries long.
* Methods always have a non-null argument list, even if only 0 entries long.
*/
ArgTypes types; ArgTypes types;
types.argTypes = (var.argDecl == null) ? null : KeyTypesToStringTypes(var.argDecl.types); types.argTypes = (var.argDecl == null) ? null : KeyTypesToStringTypes(var.argDecl.types);
if(typedic.ContainsKey(types)) if(typedic.ContainsKey(types))
return false; return false;
/* // It is unique, add to its name-specific sub-dictionary.
* It is unique, add to its name-specific sub-dictionary.
*/
TDVEntry entry; TDVEntry entry;
entry.count = ++count; entry.count = ++count;
entry.var = var; entry.var = var;
@ -175,28 +169,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public VarDict FreezeLocals() public VarDict FreezeLocals()
{ {
/* // If not local var frame, return original frame as is.
* If not local var frame, return original frame as is. // This will allow forward references as the future additions
* This will allow forward references as the future additions // will be seen by lookups done in this dictionary.
* will be seen by lookups done in this dictionary.
*/
if(!locals) if(!locals)
return this; return this;
/* // If local var frame, return a copy frozen at this point.
* If local var frame, return a copy frozen at this point. // This disallows forward referenes as those future additions
* This disallows forward referenes as those future additions // will not be seen by lookups done in the frozen dictionary.
* will not be seen by lookups done in the frozen dictionary.
*/
if((frozenLocals == null) || (frozenLocals.count != this.count)) if((frozenLocals == null) || (frozenLocals.count != this.count))
{ {
// Make a copy of the current var dictionary frame.
/* // We copy a reference to the dictionary, and though it may
* Make a copy of the current var dictionary frame. // contain additions made after this point, those additions
* We copy a reference to the dictionary, and though it may // will have a count .gt. frozen count and will be ignored.
* contain additions made after this point, those additions
* will have a count .gt. frozen count and will be ignored.
*/
frozenLocals = new VarDict(true); frozenLocals = new VarDict(true);
frozenLocals.outerVarDict = this.outerVarDict; frozenLocals.outerVarDict = this.outerVarDict;
@ -205,11 +192,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
frozenLocals.count = this.count; frozenLocals.count = this.count;
frozenLocals.frozenLocals = frozenLocals; frozenLocals.frozenLocals = frozenLocals;
/* // Mark it as being frozen.
* Mark it as being frozen. // - assert fail if any attempt is made to add to it
* - assert fail if any attempt is made to add to it // - ignore any additions to the dictionary with greater count
* - ignore any additions to the dictionary with greater count
*/
frozenLocals.isFrozen = true; frozenLocals.isFrozen = true;
} }
return frozenLocals; return frozenLocals;
@ -257,46 +242,34 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public TokenDeclVar FindExact(string name, TokenType[] argTypes) public TokenDeclVar FindExact(string name, TokenType[] argTypes)
{ {
/* // Look for list of stuff that matches the given name.
* Look for list of stuff that matches the given name.
*/
Dictionary<ArgTypes, TDVEntry> typedic; Dictionary<ArgTypes, TDVEntry> typedic;
if(!master.TryGetValue(name, out typedic)) if(!master.TryGetValue(name, out typedic))
return null; return null;
/* // Loop through all fields/methods declared by that name, regardless of arg signature.
* Loop through all fields/methods declared by that name, regardless of arg signature.
*/
foreach(TDVEntry entry in typedic.Values) foreach(TDVEntry entry in typedic.Values)
{ {
if(entry.count > this.count) if(entry.count > this.count)
continue; continue;
TokenDeclVar var = entry.var; TokenDeclVar var = entry.var;
/* // Get argument types of declaration.
* Get argument types of declaration. // fields are always null
* fields are always null // methods are always non-null, though may be zero-length
* methods are always non-null, though may be zero-length
*/
TokenType[] declArgs = (var.argDecl == null) ? null : var.argDecl.types; TokenType[] declArgs = (var.argDecl == null) ? null : var.argDecl.types;
/* // Convert any key args to string args.
* Convert any key args to string args.
*/
declArgs = KeyTypesToStringTypes(declArgs); declArgs = KeyTypesToStringTypes(declArgs);
/* // If both are null, they are signature-less (ie, both are fields), and so match.
* If both are null, they are signature-less (ie, both are fields), and so match.
*/
if((declArgs == null) && (argTypes == null)) if((declArgs == null) && (argTypes == null))
return var; return var;
/* // If calling a delegate, it is a match, regardless of delegate arg types.
* If calling a delegate, it is a match, regardless of delegate arg types. // If it turns out the arg types do not match, the compiler will give an error
* If it turns out the arg types do not match, the compiler will give an error // trying to cast the arguments to the delegate arg types.
* trying to cast the arguments to the delegate arg types. // We don't allow overloading same field name with different delegate types.
* We don't allow overloading same field name with different delegate types.
*/
if((declArgs == null) && (argTypes != null)) if((declArgs == null) && (argTypes != null))
{ {
TokenType fieldType = var.type; TokenType fieldType = var.type;
@ -304,15 +277,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return var; return var;
} }
/* // If not both null, no match, keep looking.
* If not both null, no match, keep looking.
*/
if((declArgs == null) || (argTypes == null)) if((declArgs == null) || (argTypes == null))
continue; continue;
/* // Both not null, match argument types to make sure we have correct overload.
* Both not null, match argument types to make sure we have correct overload.
*/
int i = declArgs.Length; int i = declArgs.Length;
if(i != argTypes.Length) if(i != argTypes.Length)
continue; continue;
@ -331,9 +300,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return var; return var;
} }
/* // No match.
* No match.
*/
return null; return null;
} }

View File

@ -108,10 +108,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
key = FixKey(key); key = FixKey(key);
/* // Update heap use throwing an exception on failure
* Update heap use throwing an exception on failure // before making any changes to the array.
* before making any changes to the array.
*/
int keysize = HeapTrackerObject.Size(key); int keysize = HeapTrackerObject.Size(key);
int newheapuse = heapUse; int newheapuse = heapUse;
object oldval; object oldval;
@ -125,10 +123,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
heapUse = inst.UpdateHeapUse(heapUse, newheapuse); heapUse = inst.UpdateHeapUse(heapUse, newheapuse);
/* // Save new value in array, replacing one of same key if there.
* Save new value in array, replacing one of same key if there. // null means remove the value, ie, script did array[key] = undef.
* null means remove the value, ie, script did array[key] = undef.
*/
if(value != null) if(value != null)
{ {
dnary[key] = value; dnary[key] = value;
@ -137,19 +133,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
dnary.Remove(key); dnary.Remove(key);
/* // Shrink the enumeration array, but always leave at least one element.
* Shrink the enumeration array, but always leave at least one element.
*/
if((array != null) && (dnary.Count < array.Length / 2)) if((array != null) && (dnary.Count < array.Length / 2))
{ {
Array.Resize<KeyValuePair<object, object>>(ref array, array.Length / 2); Array.Resize<KeyValuePair<object, object>>(ref array, array.Length / 2);
} }
} }
/* // The enumeration array is invalid because the dictionary has been modified.
* The enumeration array is invalid because the dictionary has been modified. // Next time a ForEach() call happens, it will repopulate 'array' as elements are retrieved.
* Next time a ForEach() call happens, it will repopulate 'array' as elements are retrieved.
*/
arrayValid = 0; arrayValid = 0;
} }
@ -236,29 +228,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
private bool ForEach(int number) private bool ForEach(int number)
{ {
/* // If we don't have any array, we can't have ever done
* If we don't have any array, we can't have ever done // any calls here before, so allocate an array big enough
* any calls here before, so allocate an array big enough // and set everything else to the beginning.
* and set everything else to the beginning.
*/
if(array == null) if(array == null)
{ {
array = new KeyValuePair<object, object>[dnary.Count]; array = new KeyValuePair<object, object>[dnary.Count];
arrayValid = 0; arrayValid = 0;
} }
/* // If dictionary modified since last enumeration, get a new enumerator.
* If dictionary modified since last enumeration, get a new enumerator.
*/
if(arrayValid == 0) if(arrayValid == 0)
{ {
enumr = dnary.GetEnumerator(); enumr = dnary.GetEnumerator();
enumrValid = true; enumrValid = true;
} }
/* // Make sure we have filled the array up enough for requested element.
* Make sure we have filled the array up enough for requested element.
*/
while((arrayValid <= number) && enumrValid && enumr.MoveNext()) while((arrayValid <= number) && enumrValid && enumr.MoveNext())
{ {
if(arrayValid >= array.Length) if(arrayValid >= array.Length)
@ -268,9 +254,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
array[arrayValid++] = enumr.Current; array[arrayValid++] = enumr.Current;
} }
/* // If we don't have that many elements, return end-of-array status.
* If we don't have that many elements, return end-of-array status.
*/
return number < arrayValid; return number < arrayValid;
} }
@ -281,10 +265,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public delegate void SendArrayObjDelegate(object graph); public delegate void SendArrayObjDelegate(object graph);
public void SendArrayObj(SendArrayObjDelegate sendObj) public void SendArrayObj(SendArrayObjDelegate sendObj)
{ {
/* // Set the count then the elements themselves.
* Set the count then the elements themselves. // UnfixKey() because sendObj doesn't handle XMRArrayListKeys.
* UnfixKey() because sendObj doesn't handle XMRArrayListKeys.
*/
sendObj(dnary.Count); sendObj(dnary.Count);
foreach(KeyValuePair<object, object> kvp in dnary) foreach(KeyValuePair<object, object> kvp in dnary)
{ {
@ -304,17 +286,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP); heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP);
/* // Cause any enumeration to refill the array from the sorted dictionary.
* Cause any enumeration to refill the array from the sorted dictionary. // Since it is a sorted dictionary, any enumerations will be in the same
* Since it is a sorted dictionary, any enumerations will be in the same // order as on the sending side.
* order as on the sending side.
*/
arrayValid = 0; arrayValid = 0;
enumrValid = false; enumrValid = false;
/* // Fill dictionary.
* Fill dictionary.
*/
dnary.Clear(); dnary.Clear();
int count = (int)recvObj(); int count = (int)recvObj();
while(--count >= 0) while(--count >= 0)
@ -375,9 +353,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public int Compare(object x, object y) // IComparer<object> public int Compare(object x, object y) // IComparer<object>
{ {
/* // Use short type name (eg, String, Int32, XMRArrayListKey) as most significant part of key.
* Use short type name (eg, String, Int32, XMRArrayListKey) as most significant part of key.
*/
string xtn = x.GetType().Name; string xtn = x.GetType().Name;
string ytn = y.GetType().Name; string ytn = y.GetType().Name;
int ctn = String.CompareOrdinal(xtn, ytn); int ctn = String.CompareOrdinal(xtn, ytn);

View File

@ -56,9 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
string outName = null; string outName = null;
XMRInstance[] instances; XMRInstance[] instances;
/* // Decode command line options.
* Decode command line options.
*/
for(int i = indx; i < args.Length; i++) for(int i = indx; i < args.Length; i++)
{ {
if(args[i] == "-full") if(args[i] == "-full")
@ -126,10 +124,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
try try
{ {
// Scan instance list to find those that match selection criteria.
/*
* Scan instance list to find those that match selection criteria.
*/
if(!Monitor.TryEnter(m_InstancesDict, 100)) if(!Monitor.TryEnter(m_InstancesDict, 100))
{ {
m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
@ -151,17 +146,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
Monitor.Exit(m_InstancesDict); Monitor.Exit(m_InstancesDict);
} }
/* // Maybe sort by descending CPU time.
* Maybe sort by descending CPU time.
*/
if(flagTopCPU) if(flagTopCPU)
{ {
Array.Sort<XMRInstance>(instances, CompareInstancesByCPUTime); Array.Sort<XMRInstance>(instances, CompareInstancesByCPUTime);
} }
/* // Print the entries.
* Print the entries.
*/
if(!flagFull) if(!flagFull)
{ {
outFile.WriteLine(" ItemID" + outFile.WriteLine(" ItemID" +
@ -176,15 +167,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
outFile.WriteLine(instances[i].RunTestLs(flagFull)); outFile.WriteLine(instances[i].RunTestLs(flagFull));
} }
/* // Print number of scripts that match selection criteria,
* Print number of scripts that match selection criteria, // even if we were told to print fewer.
* even if we were told to print fewer.
*/
outFile.WriteLine("total of {0} script(s)", numScripts); outFile.WriteLine("total of {0} script(s)", numScripts);
/* // If -queues given, print out queue contents too.
* If -queues given, print out queue contents too.
*/
if(flagQueues) if(flagQueues)
{ {
LsQueue(outFile, "start", m_StartQueue, args, indx); LsQueue(outFile, "start", m_StartQueue, args, indx);
@ -204,9 +191,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
int numScripts = 0; int numScripts = 0;
XMRInstance[] instances; XMRInstance[] instances;
/* // Decode command line options.
* Decode command line options.
*/
int i, j; int i, j;
List<string> selargs = new List<string>(args.Length); List<string> selargs = new List<string>(args.Length);
MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods(); MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods();
@ -271,9 +256,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
OpenSim.Region.ScriptEngine.Shared.EventParams eps = OpenSim.Region.ScriptEngine.Shared.EventParams eps =
new OpenSim.Region.ScriptEngine.Shared.EventParams(eventname, paramvalues, zeroDetectParams); new OpenSim.Region.ScriptEngine.Shared.EventParams(eventname, paramvalues, zeroDetectParams);
/* // Scan instance list to find those that match selection criteria.
* Scan instance list to find those that match selection criteria.
*/
if(!Monitor.TryEnter(m_InstancesDict, 100)) if(!Monitor.TryEnter(m_InstancesDict, 100))
{ {
m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
@ -296,9 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
Monitor.Exit(m_InstancesDict); Monitor.Exit(m_InstancesDict);
} }
/* // Post event to the matching instances.
* Post event to the matching instances.
*/
for(i = 0; i < numScripts; i++) for(i = 0; i < numScripts; i++)
{ {
XMRInstance inst = instances[i]; XMRInstance inst = instances[i];
@ -415,9 +396,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // Decode command line options.
* Decode command line options.
*/
for(int i = indx; i < args.Length; i++) for(int i = indx; i < args.Length; i++)
{ {
if(args[i] == "-all") if(args[i] == "-all")
@ -437,9 +416,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // Scan instance list to find those that match selection criteria.
* Scan instance list to find those that match selection criteria.
*/
if(!Monitor.TryEnter(m_InstancesDict, 100)) if(!Monitor.TryEnter(m_InstancesDict, 100))
{ {
m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
@ -462,9 +439,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
Monitor.Exit(m_InstancesDict); Monitor.Exit(m_InstancesDict);
} }
/* // Reset the instances as if someone clicked their "Reset" button.
* Reset the instances as if someone clicked their "Reset" button.
*/
for(int i = 0; i < numScripts; i++) for(int i = 0; i < numScripts; i++)
{ {
XMRInstance inst = instances[i]; XMRInstance inst = instances[i];
@ -499,10 +474,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
try try
{ {
// Try to print instance name.
/*
* Try to print instance name.
*/
if(InstanceMatchesArgs(inst, args, indx)) if(InstanceMatchesArgs(inst, args, indx))
{ {
outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName); outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName);
@ -510,10 +482,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
catch(Exception e) catch(Exception e)
{ {
// Sometimes there are instances in the queue that are disposed.
/*
* Sometimes there are instances in the queue that are disposed.
*/
outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName + ": " + e.Message); outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName + ": " + e.Message);
} }
} }

View File

@ -473,10 +473,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
ScriptEventHandler seh; ScriptEventHandler seh;
/* // CallMode_NORMAL: run event handler from the beginning normally
* CallMode_NORMAL: run event handler from the beginning normally // CallMode_RESTORE: restore event handler stack from stackFrames
* CallMode_RESTORE: restore event handler stack from stackFrames
*/
callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL : callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL :
XMRInstAbstract.CallMode_RESTORE; XMRInstAbstract.CallMode_RESTORE;
@ -723,25 +721,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(o is LSL_Vector) if(o is LSL_Vector)
return "vector"; return "vector";
/* // A script-defined interface is represented as an array of delegates.
* A script-defined interface is represented as an array of delegates. // If that is the case, convert it to the object of the script-defined
* If that is the case, convert it to the object of the script-defined // class that is implementing the interface. This should let the next
* class that is implementing the interface. This should let the next // step get the script-defined type name of the object.
* step get the script-defined type name of the object.
*/
if(o is Delegate[]) if(o is Delegate[])
o = ((Delegate[])o)[0].Target; o = ((Delegate[])o)[0].Target;
/* // If script-defined class instance, get the script-defined
* If script-defined class instance, get the script-defined // type name.
* type name.
*/
if(o is XMRSDTypeClObj) if(o is XMRSDTypeClObj)
return ((XMRSDTypeClObj)o).sdtcClass.longName.val; return ((XMRSDTypeClObj)o).sdtcClass.longName.val;
/* // If it's a delegate, maybe we can look up its script-defined type name.
* If it's a delegate, maybe we can look up its script-defined type name.
*/
Type ot = o.GetType(); Type ot = o.GetType();
if(o is Delegate) if(o is Delegate)
{ {
@ -750,9 +742,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return os; return os;
} }
/* // Don't know what it is, get the C#-level type name.
* Don't know what it is, get the C#-level type name.
*/
return ot.ToString(); return ot.ToString();
} }
@ -964,17 +954,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
TokenDeclSDType sdType = inst.m_ObjCode.sdObjTypesIndx[sdtypeindex]; TokenDeclSDType sdType = inst.m_ObjCode.sdObjTypesIndx[sdtypeindex];
/* // If it is a script-defined interface object, convert to the original XMRSDTypeClObj.
* If it is a script-defined interface object, convert to the original XMRSDTypeClObj.
*/
if(thrown is Delegate[]) if(thrown is Delegate[])
{ {
thrown = ((Delegate[])thrown)[0].Target; thrown = ((Delegate[])thrown)[0].Target;
} }
/* // If it is a script-defined delegate object, make sure it is an instance of the expected type.
* If it is a script-defined delegate object, make sure it is an instance of the expected type.
*/
if(thrown is Delegate) if(thrown is Delegate)
{ {
Type ot = thrown.GetType(); Type ot = thrown.GetType();
@ -982,17 +968,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return (ot == tt) ? thrown : null; return (ot == tt) ? thrown : null;
} }
/* // If it is a script-defined class object, make sure it is an instance of the expected class.
* If it is a script-defined class object, make sure it is an instance of the expected class.
*/
if(thrown is XMRSDTypeClObj) if(thrown is XMRSDTypeClObj)
{ {
// Step from the object's actual class rootward.
/* // If we find the requested class along the way, the cast is valid.
* Step from the object's actual class rootward. // If we run off the end of the root, the cast is not valid.
* If we find the requested class along the way, the cast is valid.
* If we run off the end of the root, the cast is not valid.
*/
for(TokenDeclSDTypeClass ac = ((XMRSDTypeClObj)thrown).sdtcClass; ac != null; ac = ac.extends) for(TokenDeclSDTypeClass ac = ((XMRSDTypeClObj)thrown).sdtcClass; ac != null; ac = ac.extends)
{ {
if(ac == sdType) if(ac == sdType)
@ -1000,9 +981,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // Don't know what it is, assume it is not what caller wants.
* Don't know what it is, assume it is not what caller wants.
*/
return null; return null;
} }
@ -1070,24 +1049,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public static void xmrArrayCopy(object srcobj, int srcstart, object dstobj, int dststart, int count) public static void xmrArrayCopy(object srcobj, int srcstart, object dstobj, int dststart, int count)
{ {
/* // The script writer should only pass us script-defined class objects.
* The script writer should only pass us script-defined class objects. // Throw exception otherwise.
* Throw exception otherwise.
*/
XMRSDTypeClObj srcsdt = (XMRSDTypeClObj)srcobj; XMRSDTypeClObj srcsdt = (XMRSDTypeClObj)srcobj;
XMRSDTypeClObj dstsdt = (XMRSDTypeClObj)dstobj; XMRSDTypeClObj dstsdt = (XMRSDTypeClObj)dstobj;
/* // Get the script-visible type name of the arrays, brackets and all.
* Get the script-visible type name of the arrays, brackets and all.
*/
string srctypename = srcsdt.sdtcClass.longName.val; string srctypename = srcsdt.sdtcClass.longName.val;
string dsttypename = dstsdt.sdtcClass.longName.val; string dsttypename = dstsdt.sdtcClass.longName.val;
/* // The part before the first '[' of each should match exactly,
* The part before the first '[' of each should match exactly, // meaning the basic data type (eg, float, List<string>) is the same.
* meaning the basic data type (eg, float, List<string>) is the same. // And there must be a '[' in each meaning that it is a script-defined array type.
* And there must be a '[' in each meaning that it is a script-defined array type.
*/
int i = srctypename.IndexOf('['); int i = srctypename.IndexOf('[');
int j = dsttypename.IndexOf('['); int j = dsttypename.IndexOf('[');
if((i < 0) || (j < 0)) if((i < 0) || (j < 0))
@ -1095,12 +1068,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if((i != j) || !srctypename.StartsWith(dsttypename.Substring(0, j))) if((i != j) || !srctypename.StartsWith(dsttypename.Substring(0, j)))
throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename); throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename);
/* // The number of brackets must match exactly.
* The number of brackets must match exactly. // This permits copying from something like a float[,][] to something like a float[][].
* This permits copying from something like a float[,][] to something like a float[][]. // But you cannot copy from a float[][] to a float[] or wisa wersa.
* But you cannot copy from a float[][] to a float[] or wisa wersa. // Counting either '[' or ']' would work equally well.
* Counting either '[' or ']' would work equally well.
*/
int srclen = srctypename.Length; int srclen = srctypename.Length;
int dstlen = dsttypename.Length; int dstlen = dsttypename.Length;
int srcjags = 0; int srcjags = 0;
@ -1114,9 +1085,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(dstjags != srcjags) if(dstjags != srcjags)
throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename); throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename);
/* // Perform the copy.
* Perform the copy.
*/
Array srcarray = (Array)srcsdt.instVars.iarObjects[0]; Array srcarray = (Array)srcsdt.instVars.iarObjects[0];
Array dstarray = (Array)dstsdt.instVars.iarObjects[0]; Array dstarray = (Array)dstsdt.instVars.iarObjects[0];
Array.Copy(srcarray, srcstart, dstarray, dststart, count); Array.Copy(srcarray, srcstart, dstarray, dststart, count);
@ -1131,19 +1100,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public static LSL_List xmrArray2List(object srcar, int start, int count) public static LSL_List xmrArray2List(object srcar, int start, int count)
{ {
/* // Get the script-visible type of the array.
* Get the script-visible type of the array. // We only do arrays.
* We only do arrays.
*/
XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; XMRSDTypeClObj array = (XMRSDTypeClObj)srcar;
TokenDeclSDTypeClass sdtClass = array.sdtcClass; TokenDeclSDTypeClass sdtClass = array.sdtcClass;
if(sdtClass.arrayOfRank == 0) if(sdtClass.arrayOfRank == 0)
throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
/* // Validate objects they want to put in the list.
* Validate objects they want to put in the list. // We can't allow anything funky that OpenSim runtime doesn't expect.
* We can't allow anything funky that OpenSim runtime doesn't expect.
*/
Array srcarray = (Array)array.instVars.iarObjects[0]; Array srcarray = (Array)array.instVars.iarObjects[0];
object[] output = new object[count]; object[] output = new object[count];
for(int i = 0; i < count; i++) for(int i = 0; i < count; i++)
@ -1179,9 +1144,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
throw new InvalidCastException("invalid element " + i + " type " + src.GetType().Name); throw new InvalidCastException("invalid element " + i + " type " + src.GetType().Name);
} }
/* // Make a list out of that now immutable array.
* Make a list out of that now immutable array.
*/
return new LSL_List(output); return new LSL_List(output);
} }
@ -1195,19 +1158,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public static void xmrList2Array(LSL_List srclist, int srcstart, object dstobj, int dststart, int count) public static void xmrList2Array(LSL_List srclist, int srcstart, object dstobj, int dststart, int count)
{ {
/* // Get the script-visible type of the destination.
* Get the script-visible type of the destination. // We only do arrays.
* We only do arrays.
*/
XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj;
TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass;
if(sdtClass.arrayOfType == null) if(sdtClass.arrayOfType == null)
throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
/* // Copy from the immutable array to the mutable array.
* Copy from the immutable array to the mutable array. // Strip off any LSL wrappers as the script code doesn't expect any.
* Strip off any LSL wrappers as the script code doesn't expect any.
*/
object[] srcarr = srclist.Data; object[] srcarr = srclist.Data;
Array dstarr = (Array)dstarray.instVars.iarObjects[0]; Array dstarr = (Array)dstarray.instVars.iarObjects[0];
@ -1233,18 +1192,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public static string xmrChars2String(object srcar, int start, int count) public static string xmrChars2String(object srcar, int start, int count)
{ {
/* // Make sure they gave us a script-defined array object.
* Make sure they gave us a script-defined array object.
*/
XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; XMRSDTypeClObj array = (XMRSDTypeClObj)srcar;
TokenDeclSDTypeClass sdtClass = array.sdtcClass; TokenDeclSDTypeClass sdtClass = array.sdtcClass;
if(sdtClass.arrayOfRank == 0) if(sdtClass.arrayOfRank == 0)
throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
/* // We get a type cast error from mono if they didn't give us a character array.
* We get a type cast error from mono if they didn't give us a character array. // But if it is ok, create a string from the requested characters.
* But if it is ok, create a string from the requested characters.
*/
char[] srcarray = (char[])array.instVars.iarObjects[0]; char[] srcarray = (char[])array.instVars.iarObjects[0];
return new string(srcarray, start, count); return new string(srcarray, start, count);
} }
@ -1259,18 +1214,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public static void xmrString2Chars(string srcstr, int srcstart, object dstobj, int dststart, int count) public static void xmrString2Chars(string srcstr, int srcstart, object dstobj, int dststart, int count)
{ {
/* // Make sure they gave us a script-defined array object.
* Make sure they gave us a script-defined array object.
*/
XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj;
TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass;
if(sdtClass.arrayOfType == null) if(sdtClass.arrayOfType == null)
throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
/* // We get a type cast error from mono if they didn't give us a character array.
* We get a type cast error from mono if they didn't give us a character array. // But if it is ok, copy from the string to the character array.
* But if it is ok, copy from the string to the character array.
*/
char[] dstarr = (char[])dstarray.instVars.iarObjects[0]; char[] dstarr = (char[])dstarray.instVars.iarObjects[0];
for(int i = 0; i < count; i++) for(int i = 0; i < count; i++)
dstarr[i + dststart] = srcstr[i + srcstart]; dstarr[i + dststart] = srcstr[i + srcstart];
@ -1343,12 +1294,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// '"'<string>'"' // '"'<string>'"'
case '"': case '"':
{ {
--idx; --idx;
string val = ParseJSONString(json, ref idx); string val = ParseJSONString(json, ref idx);
dict.SetByKey(keys, val); dict.SetByKey(keys, val);
break; break;
} }
// true false null // true false null
case 't': case 't':
if(json.Substring(idx, 3) != "rue") if(json.Substring(idx, 3) != "rue")
@ -1373,12 +1324,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// otherwise assume it's a number // otherwise assume it's a number
default: default:
{ {
--idx; --idx;
object val = ParseJSONNumber(json, ref idx); object val = ParseJSONNumber(json, ref idx);
dict.SetByKey(keys, val); dict.SetByKey(keys, val);
break; break;
} }
} }
return idx; return idx;
} }
@ -1805,9 +1756,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
BinaryWriter mow = this.migrateOutWriter; BinaryWriter mow = this.migrateOutWriter;
/* // Value types (including nulls) are always output directly.
* Value types (including nulls) are always output directly.
*/
if(graph == null) if(graph == null)
{ {
mow.Write((byte)Ser.NULL); mow.Write((byte)Ser.NULL);
@ -1893,20 +1842,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // Script instance pointer is always just that.
* Script instance pointer is always just that.
*/
if(graph == this) if(graph == this)
{ {
mow.Write((byte)Ser.XMRINST); mow.Write((byte)Ser.XMRINST);
return; return;
} }
/* // Convert lists to object type.
* Convert lists to object type. // This is compatible with old migration data and also
* This is compatible with old migration data and also // two vars pointing to same list won't duplicate it.
* two vars pointing to same list won't duplicate it.
*/
if(graph is LSL_List) if(graph is LSL_List)
{ {
object[] data = ((LSL_List)graph).Data; object[] data = ((LSL_List)graph).Data;
@ -1920,14 +1865,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
graph = oll; graph = oll;
} }
/* // If this same exact object was already serialized,
* If this same exact object was already serialized, // just output an index telling the receiver to use
* just output an index telling the receiver to use // that same old object, rather than creating a whole
* that same old object, rather than creating a whole // new object with the same values. Also this prevents
* new object with the same values. Also this prevents // self-referencing objects (like arrays) from causing
* self-referencing objects (like arrays) from causing // an infinite loop.
* an infinite loop.
*/
int ident; int ident;
if(this.migrateOutObjects.TryGetValue(graph, out ident)) if(this.migrateOutObjects.TryGetValue(graph, out ident))
{ {
@ -1936,20 +1879,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return; return;
} }
/* // Object not seen before, save its address with an unique
* Object not seen before, save its address with an unique // ident number that the receiver can easily regenerate.
* ident number that the receiver can easily regenerate.
*/
ident = this.migrateOutObjects.Count; ident = this.migrateOutObjects.Count;
this.migrateOutObjects.Add(graph, ident); this.migrateOutObjects.Add(graph, ident);
/* // Now output the object's value(s).
* Now output the object's value(s). // If the object self-references, the object is alreay entered
* If the object self-references, the object is alreay entered // in the dictionary and so the self-reference will just emit
* in the dictionary and so the self-reference will just emit // a DUPREF tag instead of trying to output the whole object
* a DUPREF tag instead of trying to output the whole object // again.
* again.
*/
if(graph is ObjLslList) if(graph is ObjLslList)
{ {
mow.Write((byte)Ser.LSLLIST); mow.Write((byte)Ser.LSLLIST);
@ -2182,43 +2121,43 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return new LSL_Key((string)RecvObjValue()); return new LSL_Key((string)RecvObjValue());
case Ser.LSLLIST: case Ser.LSLLIST:
{ {
this.migrateInObjects.Add(ident, null); // placeholder this.migrateInObjects.Add(ident, null); // placeholder
object[] data = (object[])RecvObjValue(); // read data, maybe using another index object[] data = (object[])RecvObjValue(); // read data, maybe using another index
LSL_List list = new LSL_List(data); // make LSL-level list LSL_List list = new LSL_List(data); // make LSL-level list
this.migrateInObjects[ident] = list; // fill in slot this.migrateInObjects[ident] = list; // fill in slot
return list; return list;
} }
case Ser.LSLROT: case Ser.LSLROT:
{ {
double x = mir.ReadDouble(); double x = mir.ReadDouble();
double y = mir.ReadDouble(); double y = mir.ReadDouble();
double z = mir.ReadDouble(); double z = mir.ReadDouble();
double w = mir.ReadDouble(); double w = mir.ReadDouble();
return new LSL_Rotation(x, y, z, w); return new LSL_Rotation(x, y, z, w);
} }
case Ser.LSLSTR: case Ser.LSLSTR:
return new LSL_String((string)RecvObjValue()); return new LSL_String((string)RecvObjValue());
case Ser.LSLVEC: case Ser.LSLVEC:
{ {
double x = mir.ReadDouble(); double x = mir.ReadDouble();
double y = mir.ReadDouble(); double y = mir.ReadDouble();
double z = mir.ReadDouble(); double z = mir.ReadDouble();
return new LSL_Vector(x, y, z); return new LSL_Vector(x, y, z);
} }
case Ser.SYSARRAY: case Ser.SYSARRAY:
{ {
Type eletype = String2SysType(mir.ReadString()); Type eletype = String2SysType(mir.ReadString());
int length = mir.ReadInt32(); int length = mir.ReadInt32();
Array array = Array.CreateInstance(eletype, length); Array array = Array.CreateInstance(eletype, length);
this.migrateInObjects.Add(ident, array); this.migrateInObjects.Add(ident, array);
for(int i = 0; i < length; i++) for(int i = 0; i < length; i++)
array.SetValue(RecvObjValue(), i); array.SetValue(RecvObjValue(), i);
return array; return array;
} }
case Ser.SYSBOOL: case Ser.SYSBOOL:
return mir.ReadBoolean(); return mir.ReadBoolean();
@ -2241,21 +2180,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return s; return s;
case Ser.XMRARRAY: case Ser.XMRARRAY:
{ {
XMR_Array array = new XMR_Array(this); XMR_Array array = new XMR_Array(this);
this.migrateInObjects.Add(ident, array); this.migrateInObjects.Add(ident, array);
array.RecvArrayObj(this.RecvObjValue); array.RecvArrayObj(this.RecvObjValue);
return array; return array;
} }
case Ser.DUPREF: case Ser.DUPREF:
{ {
ident = mir.ReadInt32(); ident = mir.ReadInt32();
object obj = this.migrateInObjects[ident]; object obj = this.migrateInObjects[ident];
if(obj is ObjLslList) if(obj is ObjLslList)
obj = new LSL_List(((ObjLslList)obj).objarray); obj = new LSL_List(((ObjLslList)obj).objarray);
return obj; return obj;
} }
case Ser.XMRINST: case Ser.XMRINST:
return this; return this;
@ -2276,29 +2215,29 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return clobj; return clobj;
case Ser.SYSERIAL: case Ser.SYSERIAL:
{ {
int rawLength = mir.ReadInt32(); int rawLength = mir.ReadInt32();
byte[] rawBytes = mir.ReadBytes(rawLength); byte[] rawBytes = mir.ReadBytes(rawLength);
MemoryStream memoryStream = new MemoryStream(rawBytes); MemoryStream memoryStream = new MemoryStream(rawBytes);
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
object graph = bformatter.Deserialize(memoryStream); object graph = bformatter.Deserialize(memoryStream);
this.migrateInObjects.Add(ident, graph); this.migrateInObjects.Add(ident, graph);
return graph; return graph;
} }
case Ser.THROWNEX: case Ser.THROWNEX:
{ {
int rawLength = mir.ReadInt32(); int rawLength = mir.ReadInt32();
byte[] rawBytes = mir.ReadBytes(rawLength); byte[] rawBytes = mir.ReadBytes(rawLength);
MemoryStream memoryStream = new MemoryStream(rawBytes); MemoryStream memoryStream = new MemoryStream(rawBytes);
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
object graph = bformatter.Deserialize(memoryStream); object graph = bformatter.Deserialize(memoryStream);
this.migrateInObjects.Add(ident, graph); this.migrateInObjects.Add(ident, graph);
((ScriptThrownException)graph).thrown = RecvObjValue(); ((ScriptThrownException)graph).thrown = RecvObjValue();
return graph; return graph;
} }
default: default:
throw new Exception("bad stream code " + code.ToString()); throw new Exception("bad stream code " + code.ToString());

View File

@ -249,22 +249,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
lock(m_QueueLock) lock(m_QueueLock)
{ {
/* // Say how long to sleep.
* Say how long to sleep.
*/
m_SleepUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(ms); m_SleepUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(ms);
/* // Don't wake on any events.
* Don't wake on any events.
*/
m_SleepEventMask1 = 0; m_SleepEventMask1 = 0;
m_SleepEventMask2 = 0; m_SleepEventMask2 = 0;
} }
/* // The compiler follows all calls to llSleep() with a call to CheckRun().
* The compiler follows all calls to llSleep() with a call to CheckRun(). // So tell CheckRun() to suspend the microthread.
* So tell CheckRun() to suspend the microthread.
*/
suspendOnCheckRunTemp = true; suspendOnCheckRunTemp = true;
} }
@ -327,10 +321,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(callMode == CallMode_NORMAL) if(callMode == CallMode_NORMAL)
goto findevent; goto findevent;
/* // Stack frame is being restored as saved via CheckRun...().
* Stack frame is being restored as saved via CheckRun...(). // Restore necessary values then jump to __call<n> label to resume processing.
* Restore necessary values then jump to __call<n> label to resume processing.
*/
sv = RestoreStackFrame("xmrEventDequeue", out callNo); sv = RestoreStackFrame("xmrEventDequeue", out callNo);
sleepUntil = DateTime.Parse((string)sv[0]); sleepUntil = DateTime.Parse((string)sv[0]);
returnMask1 = (int)sv[1]; returnMask1 = (int)sv[1];
@ -353,9 +345,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
throw new ScriptBadCallNoException(callNo); throw new ScriptBadCallNoException(callNo);
/* // Find first event that matches either the return or background masks.
* Find first event that matches either the return or background masks.
*/
findevent: findevent:
Monitor.Enter(m_QueueLock); Monitor.Enter(m_QueueLock);
for(lln = m_EventQueue.First; lln != null; lln = lln.Next) for(lln = m_EventQueue.First; lln != null; lln = lln.Next)
@ -369,9 +359,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
goto remfromq; goto remfromq;
} }
/* // Nothing found, sleep while one comes in.
* Nothing found, sleep while one comes in.
*/
m_SleepUntil = sleepUntil; m_SleepUntil = sleepUntil;
m_SleepEventMask1 = mask1; m_SleepEventMask1 = mask1;
m_SleepEventMask2 = mask2; m_SleepEventMask2 = mask2;
@ -382,9 +370,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
CheckRunQuick(); CheckRunQuick();
goto checktmo; goto checktmo;
/* // Found one, remove it from queue.
* Found one, remove it from queue.
*/
remfromq: remfromq:
m_EventQueue.Remove(lln); m_EventQueue.Remove(lln);
if((uint)evc1 < (uint)m_EventCounts.Length) if((uint)evc1 < (uint)m_EventCounts.Length)
@ -393,16 +379,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
Monitor.Exit(m_QueueLock); Monitor.Exit(m_QueueLock);
m_InstEHEvent++; m_InstEHEvent++;
/* // See if returnable or background event.
* See if returnable or background event.
*/
if((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) || if((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) ||
(((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0))) (((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0)))
{ {
/* // Returnable event, return its parameters in a list.
* Returnable event, return its parameters in a list. // Also set the detect parameters to what the event has.
* Also set the detect parameters to what the event has.
*/
int plen = evt.Params.Length; int plen = evt.Params.Length;
object[] plist = new object[plen + 1]; object[] plist = new object[plen + 1];
plist[0] = (LSL_Integer)evc1; plist[0] = (LSL_Integer)evc1;
@ -421,10 +403,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return new LSL_List(plist); return new LSL_List(plist);
} }
/* // It is a background event, simply call its event handler,
* It is a background event, simply call its event handler, // then check event queue again.
* then check event queue again.
*/
callNo = 1; callNo = 1;
__call1: __call1:
ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc1]; ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc1];
@ -450,28 +430,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
this.eventCode = saveEventCode; this.eventCode = saveEventCode;
} }
/* // Keep waiting until we find a returnable event or timeout.
* Keep waiting until we find a returnable event or timeout.
*/
checktmo: checktmo:
if(DateTime.UtcNow < sleepUntil) if(DateTime.UtcNow < sleepUntil)
goto findevent; goto findevent;
/* // We timed out, return an empty list.
* We timed out, return an empty list.
*/
return emptyList; return emptyList;
} }
finally finally
{ {
if(callMode != CallMode_NORMAL) if(callMode != CallMode_NORMAL)
{ {
// Stack frame is being saved by CheckRun...().
/* // Save everything we need at the __call<n> labels so we can restore it
* Stack frame is being saved by CheckRun...(). // when we need to.
* Save everything we need at the __call<n> labels so we can restore it
* when we need to.
*/
sv = CaptureStackFrame("xmrEventDequeue", callNo, 9); sv = CaptureStackFrame("xmrEventDequeue", callNo, 9);
sv[0] = sleepUntil.ToString(); // needed at __call0,__call1 sv[0] = sleepUntil.ToString(); // needed at __call0,__call1
sv[1] = returnMask1; // needed at __call0,__call1 sv[1] = returnMask1; // needed at __call0,__call1
@ -606,22 +579,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public override void StateChange() public override void StateChange()
{ {
/* // Cancel any llListen()s etc.
* Cancel any llListen()s etc. // But llSetTimerEvent() should persist.
* But llSetTimerEvent() should persist.
*/
object[] timers = m_XMRLSLApi.acm.TimerPlugin.GetSerializationData(m_ItemID); object[] timers = m_XMRLSLApi.acm.TimerPlugin.GetSerializationData(m_ItemID);
AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
m_XMRLSLApi.acm.TimerPlugin.CreateFromData(m_LocalID, m_ItemID, UUID.Zero, timers); m_XMRLSLApi.acm.TimerPlugin.CreateFromData(m_LocalID, m_ItemID, UUID.Zero, timers);
/* // Tell whoever cares which event handlers the new state has.
* Tell whoever cares which event handlers the new state has.
*/
m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(stateCode)); m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(stateCode));
/* // Clear out any old events from the queue.
* Clear out any old events from the queue.
*/
lock(m_QueueLock) lock(m_QueueLock)
{ {
m_EventQueue.Clear(); m_EventQueue.Clear();

View File

@ -390,9 +390,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
LoadScriptState(doc); LoadScriptState(doc);
} }
/* // Post event(s) saying what caused the script to start.
* Post event(s) saying what caused the script to start.
*/
if(m_PostOnRez) if(m_PostOnRez)
{ {
PostEvent(new EventParams("on_rez", PostEvent(new EventParams("on_rez",

View File

@ -74,14 +74,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public void Dispose() public void Dispose()
{ {
/* // Tell script stop executing next time it calls CheckRun().
* Tell script stop executing next time it calls CheckRun().
*/
suspendOnCheckRunHold = true; suspendOnCheckRunHold = true;
/* // Don't send us any more events.
* Don't send us any more events.
*/
lock(m_RunLock) lock(m_RunLock)
{ {
if(m_Part != null) if(m_Part != null)
@ -92,10 +88,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // Let script methods get garbage collected if no one else is using
* Let script methods get garbage collected if no one else is using // them.
* them.
*/
DecObjCodeRefCount(); DecObjCodeRefCount();
} }
@ -244,26 +238,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public static string GetScriptFileName(string scriptBasePath, string filename) public static string GetScriptFileName(string scriptBasePath, string filename)
{ {
/* // Get old path, ie, all files lumped in a single huge directory.
* Get old path, ie, all files lumped in a single huge directory.
*/
string oldPath = Path.Combine(scriptBasePath, filename); string oldPath = Path.Combine(scriptBasePath, filename);
/* // Get new path, ie, files split up based on first 2 chars of name.
* Get new path, ie, files split up based on first 2 chars of name. // string subdir = filename.Substring (0, 2);
*/ // filename = filename.Substring (2);
// string subdir = filename.Substring (0, 2);
// filename = filename.Substring (2);
string subdir = filename.Substring(0, 1); string subdir = filename.Substring(0, 1);
filename = filename.Substring(1); filename = filename.Substring(1);
scriptBasePath = Path.Combine(scriptBasePath, subdir); scriptBasePath = Path.Combine(scriptBasePath, subdir);
Directory.CreateDirectory(scriptBasePath); Directory.CreateDirectory(scriptBasePath);
string newPath = Path.Combine(scriptBasePath, filename); string newPath = Path.Combine(scriptBasePath, filename);
/* // If file exists only in old location, move to new location.
* If file exists only in old location, move to new location. // If file exists in both locations, delete old location.
* If file exists in both locations, delete old location.
*/
if(File.Exists(oldPath)) if(File.Exists(oldPath))
{ {
if(File.Exists(newPath)) if(File.Exists(newPath))
@ -276,9 +264,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // Always return new location.
* Always return new location.
*/
return newPath; return newPath;
} }

View File

@ -66,36 +66,27 @@ namespace OpenSim.Region.ScriptEngine.Yengine
ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
evt.EventName); evt.EventName);
/* // Put event on end of event queue.
* Put event on end of event queue.
*/
bool startIt = false; bool startIt = false;
bool wakeIt = false; bool wakeIt = false;
lock(m_QueueLock) lock(m_QueueLock)
{ {
bool construct = (m_IState == XMRInstState.CONSTRUCT); bool construct = (m_IState == XMRInstState.CONSTRUCT);
/* // Ignore event if we don't even have such an handler in any state.
* Ignore event if we don't even have such an handler in any state. // We can't be state-specific here because state might be different
* We can't be state-specific here because state might be different // by the time this event is dequeued and delivered to the script.
* by the time this event is dequeued and delivered to the script.
*/
if(!construct && // make sure m_HaveEventHandlers is filled in if(!construct && // make sure m_HaveEventHandlers is filled in
((uint)evc < (uint)m_HaveEventHandlers.Length) && ((uint)evc < (uint)m_HaveEventHandlers.Length) &&
!m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state
return; return;
// Not running means we ignore any incoming events.
/* // But queue if still constructing because m_Running is not yet valid.
* Not running means we ignore any incoming events.
* But queue if still constructing because m_Running is not yet valid.
*/
if(!m_Running && !construct) if(!m_Running && !construct)
return; return;
/* // Only so many of each event type allowed to queue.
* Only so many of each event type allowed to queue.
*/
if((uint)evc < (uint)m_EventCounts.Length) if((uint)evc < (uint)m_EventCounts.Length)
{ {
if(evc == ScriptEventCode.timer) if(evc == ScriptEventCode.timer)
@ -109,29 +100,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine
m_EventCounts[(int)evc]++; m_EventCounts[(int)evc]++;
} }
/* // Put event on end of instance's event queue.
* Put event on end of instance's event queue.
*/
LinkedListNode<EventParams> lln = new LinkedListNode<EventParams>(evt); LinkedListNode<EventParams> lln = new LinkedListNode<EventParams>(evt);
switch(evc) switch(evc)
{ {
/* // These need to go first. The only time we manually
* These need to go first. The only time we manually // queue them is for the default state_entry() and we
* queue them is for the default state_entry() and we // need to make sure they go before any attach() events
* need to make sure they go before any attach() events // so the heapLimit value gets properly initialized.
* so the heapLimit value gets properly initialized.
*/
case ScriptEventCode.state_entry: case ScriptEventCode.state_entry:
m_EventQueue.AddFirst(lln); m_EventQueue.AddFirst(lln);
break; break;
/* // The attach event sneaks to the front of the queue.
* The attach event sneaks to the front of the queue. // This is needed for quantum limiting to work because
* This is needed for quantum limiting to work because // we want the attach(NULL_KEY) event to come in front
* we want the attach(NULL_KEY) event to come in front // of all others so the m_DetachQuantum won't run out
* of all others so the m_DetachQuantum won't run out // before attach(NULL_KEY) is executed.
* before attach(NULL_KEY) is executed.
*/
case ScriptEventCode.attach: case ScriptEventCode.attach:
if(evt.Params[0].ToString() == UUID.Zero.ToString()) if(evt.Params[0].ToString() == UUID.Zero.ToString())
{ {
@ -150,11 +135,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
else else
m_EventQueue.AddBefore(lln2, lln); m_EventQueue.AddBefore(lln2, lln);
/* If we're detaching, limit the qantum. This will also // If we're detaching, limit the qantum. This will also
* cause the script to self-suspend after running this // cause the script to self-suspend after running this
* event // event
*/
m_DetachReady.Reset(); m_DetachReady.Reset();
m_DetachQuantum = 100; m_DetachQuantum = 100;
} }
@ -163,31 +146,25 @@ namespace OpenSim.Region.ScriptEngine.Yengine
break; break;
/* // All others just go on end in the order queued.
* All others just go on end in the order queued.
*/
default: default:
m_EventQueue.AddLast(lln); m_EventQueue.AddLast(lln);
break; break;
} }
/* // If instance is idle (ie, not running or waiting to run),
* If instance is idle (ie, not running or waiting to run), // flag it to be on m_StartQueue as we are about to do so.
* flag it to be on m_StartQueue as we are about to do so. // Flag it now before unlocking so another thread won't try
* Flag it now before unlocking so another thread won't try // to do the same thing right now.
* to do the same thing right now. // Dont' flag it if it's still suspended!
* Dont' flag it if it's still suspended!
*/
if((m_IState == XMRInstState.IDLE) && !m_Suspended) if((m_IState == XMRInstState.IDLE) && !m_Suspended)
{ {
m_IState = XMRInstState.ONSTARTQ; m_IState = XMRInstState.ONSTARTQ;
startIt = true; startIt = true;
} }
/* // If instance is sleeping (ie, possibly in xmrEventDequeue),
* If instance is sleeping (ie, possibly in xmrEventDequeue), // wake it up if event is in the mask.
* wake it up if event is in the mask.
*/
if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended) if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended)
{ {
int evc1 = (int)evc; int evc1 = (int)evc;
@ -198,16 +175,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // If transitioned from IDLE->ONSTARTQ, actually go insert it
* If transitioned from IDLE->ONSTARTQ, actually go insert it // on m_StartQueue and give the RunScriptThread() a wake-up.
* on m_StartQueue and give the RunScriptThread() a wake-up.
*/
if(startIt) if(startIt)
m_Engine.QueueToStart(this); m_Engine.QueueToStart(this);
/* // Likewise, if the event mask triggered a wake, wake it up.
* Likewise, if the event mask triggered a wake, wake it up.
*/
if(wakeIt) if(wakeIt)
{ {
m_SleepUntil = DateTime.MinValue; m_SleepUntil = DateTime.MinValue;
@ -215,20 +188,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // This is called in the script thread to step script until it calls
* This is called in the script thread to step script until it calls // CheckRun(). It returns what the instance's next state should be,
* CheckRun(). It returns what the instance's next state should be, // ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED.
* ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED.
*/
public XMRInstState RunOne() public XMRInstState RunOne()
{ {
DateTime now = DateTime.UtcNow; DateTime now = DateTime.UtcNow;
m_SliceStart = Util.GetTimeStampMS(); m_SliceStart = Util.GetTimeStampMS();
/* // If script has called llSleep(), don't do any more until time is up.
* If script has called llSleep(), don't do any more until time is
* up.
*/
m_RunOnePhase = "check m_SleepUntil"; m_RunOnePhase = "check m_SleepUntil";
if(m_SleepUntil > now) if(m_SleepUntil > now)
{ {
@ -236,9 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return XMRInstState.ONSLEEPQ; return XMRInstState.ONSLEEPQ;
} }
/* // Also, someone may have called Suspend().
* Also, someone may have called Suspend().
*/
m_RunOnePhase = "check m_SuspendCount"; m_RunOnePhase = "check m_SuspendCount";
if(m_SuspendCount > 0) if(m_SuspendCount > 0)
{ {
@ -246,11 +212,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return XMRInstState.SUSPENDED; return XMRInstState.SUSPENDED;
} }
/* // Make sure we aren't being migrated in or out and prevent that
* Make sure we aren't being migrated in or out and prevent that // whilst we are in here. If migration has it locked, don't call
* whilst we are in here. If migration has it locked, don't call // back right away, delay a bit so we don't get in infinite loop.
* back right away, delay a bit so we don't get in infinite loop.
*/
m_RunOnePhase = "lock m_RunLock"; m_RunOnePhase = "lock m_RunLock";
if(!Monitor.TryEnter(m_RunLock)) if(!Monitor.TryEnter(m_RunLock))
{ {
@ -264,18 +228,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
CheckRunLockInvariants(true); CheckRunLockInvariants(true);
Exception e = null; Exception e = null;
/* // Maybe it has been Disposed()
* Maybe it has been Disposed()
*/
if(m_Part == null) if(m_Part == null)
{ {
m_RunOnePhase = "runone saw it disposed"; m_RunOnePhase = "runone saw it disposed";
return XMRInstState.DISPOSED; return XMRInstState.DISPOSED;
} }
/* // Do some more of the last event if it didn't finish.
* Do some more of the last event if it didn't finish.
*/
if(this.eventCode != ScriptEventCode.None) if(this.eventCode != ScriptEventCode.None)
{ {
lock(m_QueueLock) lock(m_QueueLock)
@ -297,10 +257,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
e = ResumeEx(); e = ResumeEx();
} }
/* // Otherwise, maybe we can dequeue a new event and start
* Otherwise, maybe we can dequeue a new event and start // processing it.
* processing it.
*/
else else
{ {
m_RunOnePhase = "lock event queue"; m_RunOnePhase = "lock event queue";
@ -310,14 +268,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
lock(m_QueueLock) lock(m_QueueLock)
{ {
/* We can't get here unless the script has been resumed // We can't get here unless the script has been resumed
* after creation, then suspended again, and then had // after creation, then suspended again, and then had
* an event posted to it. We just pretend there is no // an event posted to it. We just pretend there is no
* event int he queue and let the normal mechanics // event int he queue and let the normal mechanics
* carry out the suspension. A Resume will handle the // carry out the suspension. A Resume will handle the
* restarting gracefully. This is taking the easy way // restarting gracefully. This is taking the easy way
* out and may be improved in the future. // out and may be improved in the future.
*/
if(m_Suspended) if(m_Suspended)
{ {
@ -336,11 +293,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
evt.EventName); evt.EventName);
if(evc != ScriptEventCode.attach) if(evc != ScriptEventCode.attach)
{ {
/* // This is the case where the attach event
* This is the case where the attach event // has completed and another event is queued
* has completed and another event is queued // Stop it from running and suspend
* Stop it from running and suspend
*/
m_Suspended = true; m_Suspended = true;
m_DetachReady.Set(); m_DetachReady.Set();
m_DetachQuantum = 0; m_DetachQuantum = 0;
@ -356,18 +311,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
m_EventCounts[(int)evc]--; m_EventCounts[(int)evc]--;
} }
/* // If there is no event to dequeue, don't run this script
* If there is no event to dequeue, don't run this script // until another event gets queued.
* until another event gets queued.
*/
if(evt == null) if(evt == null)
{ {
if(m_DetachQuantum > 0) if(m_DetachQuantum > 0)
{ {
/* // This will happen if the attach event has run
* This will happen if the attach event has run // and exited with time slice left.
* and exited with time slice left.
*/
m_Suspended = true; m_Suspended = true;
m_DetachReady.Set(); m_DetachReady.Set();
m_DetachQuantum = 0; m_DetachQuantum = 0;
@ -378,10 +329,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // Dequeued an event, so start it going until it either
* Dequeued an event, so start it going until it either // finishes or it calls CheckRun().
* finishes or it calls CheckRun().
*/
m_RunOnePhase = "start event handler"; m_RunOnePhase = "start event handler";
m_DetectParams = evt.DetectParams; m_DetectParams = evt.DetectParams;
m_LastRanAt = now; m_LastRanAt = now;
@ -391,9 +340,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
m_RunOnePhase = "done running"; m_RunOnePhase = "done running";
m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds; m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds;
/* // Maybe it puqued.
* Maybe it puqued.
*/
if(e != null) if(e != null)
{ {
m_RunOnePhase = "handling exception " + e.Message; m_RunOnePhase = "handling exception " + e.Message;
@ -403,9 +350,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return XMRInstState.FINISHED; return XMRInstState.FINISHED;
} }
/* // If event handler completed, get rid of detect params.
* If event handler completed, get rid of detect params.
*/
if(this.eventCode == ScriptEventCode.None) if(this.eventCode == ScriptEventCode.None)
m_DetectParams = null; m_DetectParams = null;
@ -417,9 +362,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
Monitor.Exit(m_RunLock); Monitor.Exit(m_RunLock);
} }
/* // Cycle script through the yield queue and call it back asap.
* Cycle script through the yield queue and call it back asap.
*/
m_RunOnePhase = "last return"; m_RunOnePhase = "last return";
return XMRInstState.ONYIELDQ; return XMRInstState.ONYIELDQ;
} }
@ -433,10 +376,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public void CheckRunLockInvariants(bool throwIt) public void CheckRunLockInvariants(bool throwIt)
{ {
/* // If not executing any event handler, there shouldn't be any saved stack frames.
* If not executing any event handler, there shouldn't be any saved stack frames. // If executing an event handler, there should be some saved stack frames.
* If executing an event handler, there should be some saved stack frames.
*/
bool active = (stackFrames != null); bool active = (stackFrames != null);
ScriptEventCode ec = this.eventCode; ScriptEventCode ec = this.eventCode;
if(((ec == ScriptEventCode.None) && active) || if(((ec == ScriptEventCode.None) && active) ||
@ -470,88 +411,67 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs) private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs)
{ {
/* // 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(eventCode == 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)eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)eventCode] == null))
return null; return null;
/* // The microthread shouldn't be processing any event code.
* The microthread shouldn't be processing any event code. // These are assert checks so we throw them directly as exceptions.
* These are assert checks so we throw them directly as exceptions.
*/
if(this.eventCode != ScriptEventCode.None) if(this.eventCode != ScriptEventCode.None)
throw new Exception("still processing event " + this.eventCode.ToString()); throw new Exception("still processing event " + this.eventCode.ToString());
/* // 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 = eventCode;
this.ehArgs = ehArgs; this.ehArgs = ehArgs;
/* // 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. // Setting stackFrames = null means run the event handler from the beginning
* Setting stackFrames = null means run the event handler from the beginning // without doing any stack frame restores first.
* without doing any stack frame restores first.
*/
this.stackFrames = null; this.stackFrames = null;
return StartEx(); return StartEx();
} }
/** /**
* @brief There was an exception whilst starting/running a script event handler. * @brief There was an exception whilst starting/running a script event handler.
* Maybe we handle it directly or just print an error message. * Maybe we handle it directly or just print an error message.
*/ */
private void HandleScriptException(Exception e) private void HandleScriptException(Exception e)
{ {
/* // The script threw some kind of exception that was not caught at
* The script threw some kind of exception that was not caught at // script level, so the script is no longer running an event handler.
* script level, so the script is no longer running an event handler.
*/
eventCode = ScriptEventCode.None; eventCode = ScriptEventCode.None;
if(e is ScriptDeleteException) if(e is ScriptDeleteException)
{ {
/* // Script did something like llRemoveInventory(llGetScriptName());
* Script did something like llRemoveInventory(llGetScriptName()); // ... to delete itself from the object.
* ... to delete itself from the object.
*/
m_SleepUntil = DateTime.MaxValue; m_SleepUntil = DateTime.MaxValue;
Verbose("[YEngine]: script self-delete {0}", m_ItemID); Verbose("[YEngine]: script self-delete {0}", m_ItemID);
m_Part.Inventory.RemoveInventoryItem(m_ItemID); m_Part.Inventory.RemoveInventoryItem(m_ItemID);
} }
else if(e is ScriptDieException) else if(e is ScriptDieException)
{ {
/* // Script did an llDie()
* Script did an llDie()
*/
m_RunOnePhase = "dying..."; m_RunOnePhase = "dying...";
m_SleepUntil = DateTime.MaxValue; m_SleepUntil = DateTime.MaxValue;
m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false); m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false);
} }
else if(e is ScriptResetException) else if(e is ScriptResetException)
{ {
/* // Script did an llResetScript().
* Script did an llResetScript().
*/
m_RunOnePhase = "resetting..."; m_RunOnePhase = "resetting...";
ResetLocked("HandleScriptResetException"); ResetLocked("HandleScriptResetException");
} }
else else
{ {
/* // Some general script error.
* Some general script error.
*/
SendErrorMessage(e); SendErrorMessage(e);
} }
return; return;
@ -570,16 +490,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
msg.Append(m_ItemID); msg.Append(m_ItemID);
msg.Append('\n'); msg.Append('\n');
/* // Add exception message.
* Add exception message.
*/
string des = e.Message; string des = e.Message;
des = (des == null) ? "" : (": " + des); des = (des == null) ? "" : (": " + des);
msg.Append(e.GetType().Name + des + "\n"); msg.Append(e.GetType().Name + des + "\n");
/* // Tell script owner what to do.
* Tell script owner what to do.
*/
msg.Append("Prim: <"); msg.Append("Prim: <");
msg.Append(m_Part.Name); msg.Append(m_Part.Name);
msg.Append(">, Script: <"); msg.Append(">, Script: <");
@ -595,20 +511,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
msg.Append((int)Math.Floor(pos.Z)); msg.Append((int)Math.Floor(pos.Z));
msg.Append(">\nScript must be Reset to re-enable.\n"); msg.Append(">\nScript must be Reset to re-enable.\n");
/* // Display full exception message in log.
* Display full exception message in log.
*/
m_log.Info(msg.ToString() + XMRExceptionStackString(e), e); m_log.Info(msg.ToString() + XMRExceptionStackString(e), e);
/* // Give script owner the stack dump.
* Give script owner the stack dump.
*/
msg.Append(XMRExceptionStackString(e)); msg.Append(XMRExceptionStackString(e));
/* // Send error message to owner.
* Send error message to owner. // Suppress internal code stack trace lines.
* Suppress internal code stack trace lines.
*/
string msgst = msg.ToString(); string msgst = msg.ToString();
if(!msgst.EndsWith("\n")) if(!msgst.EndsWith("\n"))
msgst += '\n'; msgst += '\n';
@ -630,10 +540,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
imstr.Append('\n'); imstr.Append('\n');
} }
/* // Send as instant message in case user not online.
* Send as instant message in case user not online. // Code modelled from llInstantMessage().
* Code modelled from llInstantMessage().
*/
IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>(); IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>();
if(transferModule != null) if(transferModule != null)
{ {
@ -661,10 +569,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
}); });
} }
/* // Say script is sleeping for a very long time.
* Say script is sleeping for a very long time. // Reset() is able to cancel this sleeping.
* Reset() is able to cancel this sleeping.
*/
m_SleepUntil = DateTime.MaxValue; m_SleepUntil = DateTime.MaxValue;
} }
@ -678,18 +584,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
XMRInstState iState = m_IState; XMRInstState iState = m_IState;
switch(iState) switch(iState)
{ {
/* // If it's really being constructed now, that's about as reset as we get.
* If it's really being constructed now, that's about as reset as we get.
*/
case XMRInstState.CONSTRUCT: case XMRInstState.CONSTRUCT:
return; return;
/* // If it's idle, that means it is ready to receive a new event.
* If it's idle, that means it is ready to receive a new event. // So we lock the event queue to prevent another thread from taking
* So we lock the event queue to prevent another thread from taking // it out of idle, verify that it is still in idle then transition
* it out of idle, verify that it is still in idle then transition // it to resetting so no other thread will touch it.
* it to resetting so no other thread will touch it.
*/
case XMRInstState.IDLE: case XMRInstState.IDLE:
lock(m_QueueLock) lock(m_QueueLock)
{ {
@ -701,12 +603,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
goto checkstate; goto checkstate;
/* // If it's on the start queue, that means it is about to dequeue an
* If it's on the start queue, that means it is about to dequeue an // event and start processing it. So we lock the start queue so it
* event and start processing it. So we lock the start queue so it // can't be started and transition it to resetting so no other thread
* can't be started and transition it to resetting so no other thread // will touch it.
* will touch it.
*/
case XMRInstState.ONSTARTQ: case XMRInstState.ONSTARTQ:
lock(m_Engine.m_StartQueue) lock(m_Engine.m_StartQueue)
{ {
@ -719,10 +619,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
goto checkstate; goto checkstate;
/* // If it's running, tell CheckRun() to suspend the thread then go back
* If it's running, tell CheckRun() to suspend the thread then go back // to see what it got transitioned to.
* to see what it got transitioned to.
*/
case XMRInstState.RUNNING: case XMRInstState.RUNNING:
suspendOnCheckRunHold = true; suspendOnCheckRunHold = true;
lock(m_QueueLock) lock(m_QueueLock)
@ -730,11 +628,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
goto checkstate; goto checkstate;
// If it's sleeping, remove it from sleep queue and transition it to
/* // resetting so no other thread will touch it.
* If it's sleeping, remove it from sleep queue and transition it to
* resetting so no other thread will touch it.
*/
case XMRInstState.ONSLEEPQ: case XMRInstState.ONSLEEPQ:
lock(m_Engine.m_SleepQueue) lock(m_Engine.m_SleepQueue)
{ {
@ -747,19 +642,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
goto checkstate; goto checkstate;
/* // It was just removed from the sleep queue and is about to be put
* It was just removed from the sleep queue and is about to be put // on the yield queue (ie, is being woken up).
* on the yield queue (ie, is being woken up). // Let that thread complete transition and try again.
* Let that thread complete transition and try again.
*/
case XMRInstState.REMDFROMSLPQ: case XMRInstState.REMDFROMSLPQ:
Sleep(10); Sleep(10);
goto checkstate; goto checkstate;
/* // If it's yielding, remove it from yield queue and transition it to
* If it's yielding, remove it from yield queue and transition it to // resetting so no other thread will touch it.
* resetting so no other thread will touch it.
*/
case XMRInstState.ONYIELDQ: case XMRInstState.ONYIELDQ:
lock(m_Engine.m_YieldQueue) lock(m_Engine.m_YieldQueue)
{ {
@ -772,52 +663,38 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
goto checkstate; goto checkstate;
/* // If it just finished running something, let that thread transition it
* If it just finished running something, let that thread transition it // to its next state then check again.
* to its next state then check again.
*/
case XMRInstState.FINISHED: case XMRInstState.FINISHED:
Sleep(10); Sleep(10);
goto checkstate; goto checkstate;
/* // If it's disposed, that's about as reset as it gets.
* If it's disposed, that's about as reset as it gets.
*/
case XMRInstState.DISPOSED: case XMRInstState.DISPOSED:
return; return;
/* // Some other thread is already resetting it, let it finish.
* Some other thread is already resetting it, let it finish.
*/
case XMRInstState.RESETTING: case XMRInstState.RESETTING:
return; return;
default: default:
throw new Exception("bad state"); throw new Exception("bad state");
} }
/* // This thread transitioned the instance to RESETTING so reset it.
* This thread transitioned the instance to RESETTING so reset it.
*/
lock(m_RunLock) lock(m_RunLock)
{ {
CheckRunLockInvariants(true); CheckRunLockInvariants(true);
/* // No other thread should have transitioned it from RESETTING.
* No other thread should have transitioned it from RESETTING.
*/
if(m_IState != XMRInstState.RESETTING) if(m_IState != XMRInstState.RESETTING)
throw new Exception("bad state"); throw new Exception("bad state");
/* // Mark it idle now so it can get queued to process new stuff.
* Mark it idle now so it can get queued to process new stuff.
*/
m_IState = XMRInstState.IDLE; m_IState = XMRInstState.IDLE;
/* // Reset everything and queue up default's start_entry() event.
* Reset everything and queue up default's start_entry() event.
*/
ClearQueue(); ClearQueue();
ResetLocked("external Reset"); ResetLocked("external Reset");
@ -886,16 +763,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
m_SleepUntil = DateTime.MinValue; // not doing llSleep() m_SleepUntil = DateTime.MinValue; // not doing llSleep()
m_ResetCount++; // has been reset once more m_ResetCount++; // has been reset once more
/* // Tell next call to 'default state_entry()' to reset all global
* Tell next call to 'default state_entry()' to reset all global // vars to their initial values.
* vars to their initial values.
*/
doGblInit = true; doGblInit = true;
/* // Set script to 'default' state and queue call to its
* Set script to 'default' state and queue call to its // 'state_entry()' event handler.
* 'state_entry()' event handler.
*/
m_RunOnePhase = "ResetLocked: posting default:state_entry() event"; m_RunOnePhase = "ResetLocked: posting default:state_entry() event";
stateCode = 0; stateCode = 0;
m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0)); m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0));
@ -903,9 +776,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
zeroObjectArray, zeroObjectArray,
zeroDetectParams)); zeroDetectParams));
/* // Tell CheckRun() to let script run.
* Tell CheckRun() to let script run.
*/
suspendOnCheckRunHold = false; suspendOnCheckRunHold = false;
suspendOnCheckRunTemp = false; suspendOnCheckRunTemp = false;
m_RunOnePhase = "ResetLocked: reset complete"; m_RunOnePhase = "ResetLocked: reset complete";
@ -955,9 +826,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
m_CheckRunPhase = "entered"; m_CheckRunPhase = "entered";
/* // Stay stuck in this loop as long as something wants us suspended.
* Stay stuck in this loop as long as something wants us suspended.
*/
while(suspendOnCheckRunHold || suspendOnCheckRunTemp) while(suspendOnCheckRunHold || suspendOnCheckRunTemp)
{ {
m_CheckRunPhase = "top of while"; m_CheckRunPhase = "top of while";
@ -997,10 +866,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
m_CheckRunPhase = "returning"; m_CheckRunPhase = "returning";
/* // Upon return from CheckRun() it should always be the case that the script is
* Upon return from CheckRun() it should always be the case that the script is // going to process calls normally, neither saving nor restoring stack frame state.
* going to process calls normally, neither saving nor restoring stack frame state.
*/
if(callMode != CallMode_NORMAL) if(callMode != CallMode_NORMAL)
throw new Exception("bad callMode " + callMode); throw new Exception("bad callMode " + callMode);
} }

View File

@ -501,10 +501,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
public override void EndMethod() public override void EndMethod()
{ {
/* // Convert CIL code to primitive statements.
* Convert CIL code to primitive statements. // There are a bunch of labels and internal code such as call stack save restore.
* There are a bunch of labels and internal code such as call stack save restore.
*/
topBlock = new OTStmtBlock(); topBlock = new OTStmtBlock();
blockstack.Push(topBlock); blockstack.Push(topBlock);
for(LinkedListNode<OTCilInstr> link = cilinstrs.First; link != null; link = link.Next) for(LinkedListNode<OTCilInstr> link = cilinstrs.First; link != null; link = link.Next)
@ -512,10 +510,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
link.Value.BuildStatements(this, link); link.Value.BuildStatements(this, link);
} }
/* // Strip out stuff we don't want, such as references to callMode.
* Strip out stuff we don't want, such as references to callMode. // This strips out stack frame capture and restore code.
* This strips out stack frame capture and restore code.
*/
topBlock.StripStuff(null); topBlock.StripStuff(null);
// including a possible final return statement // including a possible final return statement
@ -532,22 +528,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/** // At this point, all behind-the-scenes references are removed except
* At this point, all behind-the-scenes references are removed except // that the do/for/if/while blocks are represented by OTStmtCont-style
* that the do/for/if/while blocks are represented by OTStmtCont-style // if/jumps. So try to convert them to the higher-level structures.
* if/jumps. So try to convert them to the higher-level structures.
*/
topBlock.DetectDoForIfWhile(null); topBlock.DetectDoForIfWhile(null);
/* // Final strip to get rid of unneeded @forbreak_<suffix>; labels and the like.
* Final strip to get rid of unneeded @forbreak_<suffix>; labels and the like.
*/
topBlock.StripStuff(null); topBlock.StripStuff(null);
/* // Build reference counts so we don't output unneeded declarations,
* Build reference counts so we don't output unneeded declarations, // especially temps and internal variables.
* especially temps and internal variables.
*/
foreach(OTLocal local in locals.Values) foreach(OTLocal local in locals.Values)
{ {
local.nlclreads = 0; local.nlclreads = 0;
@ -564,10 +554,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // Strip the $n off of local vars that are not ambiguous.
* Strip the $n off of local vars that are not ambiguous. // Make sure they don't mask globals and arguments as well.
* Make sure they don't mask globals and arguments as well.
*/
Dictionary<string, int> namecounts = new Dictionary<string, int>(); Dictionary<string, int> namecounts = new Dictionary<string, int>();
foreach(Dictionary<int, string> varnames in scriptObjCode.globalVarNames.Values) foreach(Dictionary<int, string> varnames in scriptObjCode.globalVarNames.Values)
{ {
@ -607,9 +595,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
local.name = name; local.name = name;
} }
/* // Print out result.
* Print out result.
*/
if(method.Name == _globalvarinit) if(method.Name == _globalvarinit)
{ {
GlobalsDump(); GlobalsDump();
@ -725,10 +711,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/ */
private void GlobalsDump() private void GlobalsDump()
{ {
/* // Scan $globalvarinit(). It should only have global var assignments in it.
* Scan $globalvarinit(). It should only have global var assignments in it. // Also gather up list of variables it initializes.
* Also gather up list of variables it initializes.
*/
bool badinit = false; bool badinit = false;
Dictionary<string, string> inittypes = new Dictionary<string, string>(); Dictionary<string, string> inittypes = new Dictionary<string, string>();
foreach(OTStmt stmt in topBlock.blkstmts) foreach(OTStmt stmt in topBlock.blkstmts)
@ -748,11 +732,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
inittypes[globalop.PrintableString] = ""; inittypes[globalop.PrintableString] = "";
} }
/* // Scan through list of all global variables in the script.
* Scan through list of all global variables in the script. // Output declarations for those what don't have any init statement for them.
* Output declarations for those what don't have any init statement for them. // Save the type for those that do have init statements.
* Save the type for those that do have init statements.
*/
bool first = true; bool first = true;
foreach(string iartypename in scriptObjCode.globalVarNames.Keys) foreach(string iartypename in scriptObjCode.globalVarNames.Keys)
{ {
@ -778,10 +760,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
} }
/* // If $globalvarinit() has anything bad in it, output it as a function.
* If $globalvarinit() has anything bad in it, output it as a function. // Otherwise, output it as a series of global declarations with init values.
* Otherwise, output it as a series of global declarations with init values.
*/
if(badinit) if(badinit)
{ {
MethodDump(); MethodDump();
@ -809,19 +789,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
string indent; string indent;
/* // Event handlers don't have an argument list as such in the original
* Event handlers don't have an argument list as such in the original // code. Instead they have a series of assignments from ehargs[] to
* code. Instead they have a series of assignments from ehargs[] to // local variables. So make those local variables look like they are
* local variables. So make those local variables look like they are // an argument list.
* an argument list.
*/
int i = method.Name.IndexOf(' '); int i = method.Name.IndexOf(' ');
if(i >= 0) if(i >= 0)
{ {
// Maybe we have to output the state name.
/*
* Maybe we have to output the state name.
*/
string statename = method.Name.Substring(0, i); string statename = method.Name.Substring(0, i);
string eventname = method.Name.Substring(++i); string eventname = method.Name.Substring(++i);
@ -844,10 +819,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
twout.Write('\n'); twout.Write('\n');
} }
/* // Output event name and argument list.
* Output event name and argument list. // Remove from locals list so they don't print below.
* Remove from locals list so they don't print below.
*/
twout.Write('\n' + INDENT + eventname + " ("); twout.Write('\n' + INDENT + eventname + " (");
MethodInfo meth = typeof(IEventHandlers).GetMethod(eventname); MethodInfo meth = typeof(IEventHandlers).GetMethod(eventname);
i = 0; i = 0;
@ -873,35 +846,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine
} }
twout.Write(')'); twout.Write(')');
/* // Indent method body by 4 spaces.
* Indent method body by 4 spaces.
*/
indent = INDENT; indent = INDENT;
} }
else else
{ {
// Maybe need to close out previous state.
/*
* Maybe need to close out previous state.
*/
if(laststate != null) if(laststate != null)
{ {
twout.Write("\n}"); twout.Write("\n}");
laststate = null; laststate = null;
} }
/* // Output blank line and return type (if any).
* Output blank line and return type (if any).
*/
twout.Write("\n\n"); twout.Write("\n\n");
if(method.ReturnType != typeof(void)) if(method.ReturnType != typeof(void))
{ {
twout.Write(AbbrType(method.ReturnType) + ' '); twout.Write(AbbrType(method.ReturnType) + ' ');
} }
/* // Output method name and argument list.
* Output method name and argument list.
*/
int j = method.Name.IndexOf('('); int j = method.Name.IndexOf('(');
if(j < 0) if(j < 0)
{ {
@ -926,15 +890,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
twout.Write(')'); twout.Write(')');
} }
/* // Don't indent method body at all.
* Don't indent method body at all.
*/
indent = ""; indent = "";
} }
/* // Output local variable declarations.
* Output local variable declarations.
*/
twout.Write('\n' + indent + '{'); twout.Write('\n' + indent + '{');
bool didOne = false; bool didOne = false;
foreach(OTLocal local in locals.Values) foreach(OTLocal local in locals.Values)
@ -945,9 +905,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(didOne) if(didOne)
twout.Write('\n'); twout.Write('\n');
/* // Output statements.
* Output statements.
*/
if(topBlock.blkstmts.Count == 0) if(topBlock.blkstmts.Count == 0)
{ {
twout.Write(" }"); twout.Write(" }");
@ -1634,22 +1592,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{ {
switch(opCode.ToString()) switch(opCode.ToString())
{ {
// We don't handle non-empty stack at branch points.
/* //
* We don't handle non-empty stack at branch points. // So handle this case specially:
* //
* So handle this case specially: // dup
* // ldc.i4.0
* dup // bge.s llAbstemp << we are here
* ldc.i4.0 // neg
* bge.s llAbstemp << we are here // llAbstemp:
* neg //
* llAbstemp: // becomes:
* //
* becomes: // call llAbs
*
* call llAbs
*/
case "bge.s": case "bge.s":
{ {
OTOpnd rite = decompile.opstack.Pop(); // alleged zero OTOpnd rite = decompile.opstack.Pop(); // alleged zero
@ -2103,50 +2058,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public static OTOpnd Make(OTOpnd array, OTOpnd index, bool byref, OTDecompile decompile) public static OTOpnd Make(OTOpnd array, OTOpnd index, bool byref, OTDecompile decompile)
{ {
/* // arg$0.glblVars.iar<type>[<intconst>] is a reference to a global variable
* arg$0.glblVars.iar<type>[<intconst>] is a reference to a global variable // likewise so is __xmrinst.glblVars.iar<type>[<intconst>]
* likewise so is __xmrinst.glblVars.iar<type>[<intconst>]
*/
if((array is OTOpndField) && (index is OTOpndInt)) if((array is OTOpndField) && (index is OTOpndInt))
{ {
// arrayfield = (arg$0.glblVars).iar<type>
/* // arrayfieldobj = arg$0.glblVars
* arrayfield = (arg$0.glblVars).iar<type> // iartypename = iar<type>
* arrayfieldobj = arg$0.glblVars
* iartypename = iar<type>
*/
OTOpndField arrayfield = (OTOpndField)array; OTOpndField arrayfield = (OTOpndField)array;
OTOpnd arrayfieldobj = arrayfield.obj; OTOpnd arrayfieldobj = arrayfield.obj;
string iartypename = arrayfield.field.Name; string iartypename = arrayfield.field.Name;
/* // See if they are what they are supposed to be.
* See if they are what they are supposed to be.
*/
if((arrayfieldobj is OTOpndField) && iartypename.StartsWith("iar")) if((arrayfieldobj is OTOpndField) && iartypename.StartsWith("iar"))
{ {
// arrayfieldobjfield = arg$0.glblVars
/*
* arrayfieldobjfield = arg$0.glblVars
*/
OTOpndField arrayfieldobjfield = (OTOpndField)arrayfieldobj; OTOpndField arrayfieldobjfield = (OTOpndField)arrayfieldobj;
/* // See if the parts are what they are supposed to be.
* See if the parts are what they are supposed to be.
*/
if(IsArg0OrXMRInst(arrayfieldobjfield.obj) && (arrayfieldobjfield.field.Name == "glblVars")) if(IsArg0OrXMRInst(arrayfieldobjfield.obj) && (arrayfieldobjfield.field.Name == "glblVars"))
{ {
// Everything matches up, make a global variable instead of an array reference.
/*
* Everything matches up, make a global variable instead of an array reference.
*/
return new OTOpndGlobal(iartypename, ((OTOpndInt)index).value, byref, decompile.scriptObjCode); return new OTOpndGlobal(iartypename, ((OTOpndInt)index).value, byref, decompile.scriptObjCode);
} }
} }
} }
/* // Other array reference.
* Other array reference.
*/
OTOpndArrayElem it = new OTOpndArrayElem(); OTOpndArrayElem it = new OTOpndArrayElem();
it.array = array; it.array = array;
it.index = index; it.index = index;
@ -3097,17 +3035,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return false; return false;
int listsize = ((OTOpndInt)storeval.index).value; int listsize = ((OTOpndInt)storeval.index).value;
/* // Good chance of having list initializer, malloc an object to hold it.
* Good chance of having list initializer, malloc an object to hold it.
*/
OTOpndListIni it = new OTOpndListIni(); OTOpndListIni it = new OTOpndListIni();
it.values = new OTOpnd[listsize]; it.values = new OTOpnd[listsize];
/* // There should be exactly listsize statements following that of the form:
* There should be exactly listsize statements following that of the form: // dup$<n>[<i>] = bla
* dup$<n>[<i>] = bla // If so, save the bla values in the values[] array.
* If so, save the bla values in the values[] array.
*/
LinkedListNode<OTStmt> vallink = link; LinkedListNode<OTStmt> vallink = link;
for(int i = 0; i < listsize; i++) for(int i = 0; i < listsize; i++)
{ {
@ -3129,10 +3063,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
it.values[i] = valstore.value; it.values[i] = valstore.value;
} }
/* // The next statement should have a 'newobj list (dup$<n>)' in it somewhere
* The next statement should have a 'newobj list (dup$<n>)' in it somewhere // that we want to replace with 'it'.
* that we want to replace with 'it'.
*/
ConstructorInfo protoctor = typeof(LSL_List).GetConstructor(new Type[] { typeof(object[]) }); ConstructorInfo protoctor = typeof(LSL_List).GetConstructor(new Type[] { typeof(object[]) });
OTOpnd[] protoargs = new OTOpnd[] { storevar }; OTOpnd[] protoargs = new OTOpnd[] { storevar };
OTOpnd proto = OTOpndNewobj.Make(protoctor, protoargs); OTOpnd proto = OTOpndNewobj.Make(protoctor, protoargs);
@ -3140,9 +3072,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
vallink = vallink.Next; vallink = vallink.Next;
bool rc = vallink.Value.ReplaceOperand(proto, it); bool rc = vallink.Value.ReplaceOperand(proto, it);
/* // If successful, delete 'dup$n =' and all 'dup$n[i] =' statements.
* If successful, delete 'dup$n =' and all 'dup$n[i] =' statements.
*/
if(rc) if(rc)
{ {
do do