Y(xmr)engine cosmetics...
parent
2f94fa4dc7
commit
85b973ce1d
|
@ -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
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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 + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue