Y(xmr)engine cosmetics...
parent
2f94fa4dc7
commit
85b973ce1d
|
@ -35,7 +35,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
public class InternalFuncDict: VarDict
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief build dictionary of internal functions from an interface.
|
||||
* @param iface = interface with function definitions
|
||||
|
@ -46,27 +45,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
public InternalFuncDict(Type iface, bool inclSig)
|
||||
: 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();
|
||||
foreach(System.Reflection.MethodInfo ifaceMethod in ifaceMethods)
|
||||
{
|
||||
string key = ifaceMethod.Name;
|
||||
|
||||
/*
|
||||
* Only do ones that begin with lower-case letters...
|
||||
* as any others can't be referenced by scripts
|
||||
*/
|
||||
// Only do ones that begin with lower-case letters...
|
||||
// as any others can't be referenced by scripts
|
||||
if((key[0] < 'a') || (key[0] > 'z'))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
/*
|
||||
* Create a corresponding TokenDeclVar struct.
|
||||
*/
|
||||
// Create a corresponding TokenDeclVar struct.
|
||||
System.Reflection.ParameterInfo[] parameters = ifaceMethod.GetParameters();
|
||||
TokenArgDecl argDecl = new TokenArgDecl(null);
|
||||
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.argDecl = argDecl;
|
||||
|
||||
/*
|
||||
* Add the TokenDeclVar struct to the dictionary.
|
||||
*/
|
||||
// Add the TokenDeclVar struct to the dictionary.
|
||||
this.AddEntry(declFunc);
|
||||
}
|
||||
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()
|
||||
{
|
||||
/*
|
||||
* 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())
|
||||
{
|
||||
nn = realEnumerator.Current;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Then if this instruction is in a try section, say this instruction
|
||||
* can potentially branch to the beginning of the corresponding
|
||||
* catch/finally.
|
||||
*/
|
||||
// Then if this instruction is in a try section, say this instruction
|
||||
// can potentially branch to the beginning of the corresponding
|
||||
// catch/finally.
|
||||
if((index == 0) && (gn.tryBlock != null))
|
||||
{
|
||||
index++;
|
||||
|
@ -532,9 +528,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* That's all we can do.
|
||||
*/
|
||||
// That's all we can do.
|
||||
nn = null;
|
||||
return false;
|
||||
}
|
||||
|
@ -1875,9 +1869,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
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)
|
||||
{
|
||||
nn = gn.myLabels[index++].whereAmI;
|
||||
|
@ -1885,9 +1877,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
{
|
||||
index++;
|
||||
|
@ -1895,9 +1885,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Even ran out of that, say there's nothing more.
|
||||
*/
|
||||
// Even ran out of that, say there's nothing more.
|
||||
nn = null;
|
||||
return false;
|
||||
}
|
||||
|
@ -2527,10 +2515,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
if(curExcBlock != null)
|
||||
throw new Exception("exception block still open");
|
||||
|
||||
/*
|
||||
* If an instruction says it doesn't fall through, remove all instructions to
|
||||
* the end of the block.
|
||||
*/
|
||||
// If an instruction says it doesn't fall through, remove all instructions to
|
||||
// the end of the block.
|
||||
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
|
||||
{
|
||||
if(!gn.CanFallThrough())
|
||||
|
@ -2547,12 +2533,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan for OpCodes.Leave instructions.
|
||||
* 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
|
||||
* leave instruction's target. A leave instruction can unwind zero or more finally blocks.
|
||||
*/
|
||||
// Scan for OpCodes.Leave instructions.
|
||||
// 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
|
||||
// leave instruction's target. A leave instruction can unwind zero or more finally blocks.
|
||||
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
|
||||
{
|
||||
if(gn is GraphNodeEmitLabelLeave)
|
||||
|
@ -2562,12 +2546,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
GraphNodeBeginExceptionBlock leaveTargetsTryBlock = // try block directly enclosing leave target
|
||||
(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.
|
||||
* 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.
|
||||
* If none found, the leave is a simple unconditional branch to its target.
|
||||
*/
|
||||
// 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 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.
|
||||
GraphNodeBeginFinallyBlock innerFinallyBlock = null;
|
||||
for(GraphNodeBeginExceptionBlock tryBlock = leaveInstr.tryBlock;
|
||||
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.
|
||||
* In the case of no finallies being unwound, the leave is just a simple unconditional branch.
|
||||
*/
|
||||
// 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.
|
||||
if(innerFinallyBlock == null)
|
||||
{
|
||||
leaveInstr.unwindTo = leaveTarget;
|
||||
|
@ -2601,10 +2581,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* See which variables a particular block reads before writing.
|
||||
* This just considers the block itself and nothing that it branches to or fallsthru to.
|
||||
*/
|
||||
// See which variables a particular block reads before writing.
|
||||
// This just considers the block itself and nothing that it branches to or fallsthru to.
|
||||
GraphNodeBlock currentBlock = null;
|
||||
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,
|
||||
* 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
|
||||
* on entry to our block. So basically it looks like the branch instruction is reading
|
||||
* everything required by any blocks it can branch to.
|
||||
*/
|
||||
// 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
|
||||
// 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
|
||||
// everything required by any blocks it can branch to.
|
||||
do
|
||||
{
|
||||
this.resolvedSomething = false;
|
||||
|
@ -2640,17 +2616,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
this.ResolveBlock((GraphNodeBlock)firstLin);
|
||||
} 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;
|
||||
do
|
||||
{
|
||||
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)
|
||||
{
|
||||
if(!(gn is GraphNodeEmit))
|
||||
|
@ -2678,9 +2650,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
{
|
||||
if(!(gn is GraphNodeEmit))
|
||||
|
@ -2711,9 +2681,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
{
|
||||
if(!(gn is GraphNodeEmit))
|
||||
|
@ -2746,9 +2714,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
{
|
||||
if(!(gn is GraphNodeEmit))
|
||||
|
@ -2767,17 +2733,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
didSomething = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace:
|
||||
* ldloc v1
|
||||
* stloc v2
|
||||
* ld<anything> except ld<anything> v2
|
||||
* ldloc v2
|
||||
* ...v2 unreferenced hereafter
|
||||
* With:
|
||||
* ld<anything> except ld<anything> v2
|
||||
* ldloc v1
|
||||
*/
|
||||
// Replace:
|
||||
// ldloc v1
|
||||
// stloc v2
|
||||
// ld<anything> except ld<anything> v2
|
||||
// ldloc v2
|
||||
// ...v2 unreferenced hereafter
|
||||
// With:
|
||||
// ld<anything> except ld<anything> v2
|
||||
// ldloc v1
|
||||
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
|
||||
{
|
||||
|
||||
|
@ -2833,11 +2797,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
didSomething = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove all the stloc/ldloc that are back-to-back without the local
|
||||
* being needed afterwards. If it is needed afterwards, replace the
|
||||
* stloc/ldloc with dup/stloc.
|
||||
*/
|
||||
// Remove all the stloc/ldloc that are back-to-back without the local
|
||||
// being needed afterwards. If it is needed afterwards, replace the
|
||||
// stloc/ldloc with dup/stloc.
|
||||
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
|
||||
{
|
||||
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.
|
||||
* Replace any stloc instructions with pops.
|
||||
*/
|
||||
// Remove all write-only local variables, ie, those with no ldloc[a] references.
|
||||
// Replace any stloc instructions with pops.
|
||||
for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if((gn is GraphNodeEmit) &&
|
||||
|
@ -2921,9 +2879,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
} while(didSomething);
|
||||
|
||||
/*
|
||||
* Dump out the results.
|
||||
*/
|
||||
// Dump out the results.
|
||||
if(DEBUG)
|
||||
{
|
||||
Console.WriteLine("");
|
||||
|
@ -2982,55 +2938,39 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
if(currentBlock.hasBeenResolved == this.resolveSequence)
|
||||
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;
|
||||
|
||||
/*
|
||||
* Assume we haven't written any locals yet.
|
||||
*/
|
||||
// Assume we haven't written any locals yet.
|
||||
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;)
|
||||
{
|
||||
|
||||
/*
|
||||
* 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();
|
||||
if((wrlcl != null) && !localsWrittenSoFar.Contains(wrlcl))
|
||||
{
|
||||
localsWrittenSoFar.Add(wrlcl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan through all the possible next instructions after this.
|
||||
* Note that if we are in the first part of a try/catch/finally block,
|
||||
* every instruction conditionally branches to the beginning of the
|
||||
* second part (the catch/finally block).
|
||||
*/
|
||||
// Scan through all the possible next instructions after this.
|
||||
// Note that if we are in the first part of a try/catch/finally block,
|
||||
// every instruction conditionally branches to the beginning of the
|
||||
// second part (the catch/finally block).
|
||||
GraphNode nextFallthruNode = null;
|
||||
foreach(GraphNode nn in gn.NextNodes)
|
||||
{
|
||||
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;
|
||||
ResolveBlock(nextBlock);
|
||||
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) &&
|
||||
!currentBlock.localsReadBeforeWritten.Contains(readByNextBlock))
|
||||
{
|
||||
|
@ -3041,19 +2981,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
* Not start of a block, should be normal fallthru instruction.
|
||||
*/
|
||||
// Not start of a block, should be normal fallthru instruction.
|
||||
if(nextFallthruNode != null)
|
||||
throw new Exception("more than one fallthru from " + gn.ToString());
|
||||
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)
|
||||
throw new Exception("can't fallthru to self");
|
||||
gn = nextFallthruNode;
|
||||
|
|
|
@ -107,8 +107,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
{
|
||||
if(fi.Name == "iarLists")
|
||||
|
@ -120,7 +122,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
{
|
||||
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 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
} // 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
|
||||
|
||||
// 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)
|
||||
{
|
||||
return true;
|
||||
|
@ -173,12 +186,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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
|
||||
// ie, PushVal() pushes a delegate pointer
|
||||
// - so we must have CallPre() push the delegate pointer as a 'this' for this.Invoke(...)
|
||||
// - and CallPost() call the delegate's Invoke() method
|
||||
// - we assume the target function is non-trivial so we always use a call label
|
||||
/*
|
||||
* 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
|
||||
* - ie, PushVal() pushes a delegate pointer
|
||||
* - so we must have CallPre() push the delegate pointer as a 'this' for this.Invoke(...)
|
||||
* - 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
|
||||
{
|
||||
new ScriptCodeGen.CallLabel(scg, errorAt);
|
||||
|
|
|
@ -64,9 +64,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
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++)
|
||||
{
|
||||
try
|
||||
|
@ -87,9 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
{
|
||||
AddInterfaceConstants(sc, t.GetFields());
|
||||
|
@ -132,10 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
Type fieldType = constField.FieldType;
|
||||
CompValu cv;
|
||||
|
||||
/*
|
||||
* The location of a simple number is the number itself.
|
||||
* Access to the value gets compiled as an ldc instruction.
|
||||
*/
|
||||
// The location of a simple number is the number itself.
|
||||
// Access to the value gets compiled as an ldc instruction.
|
||||
if(fieldType == typeof(double))
|
||||
{
|
||||
cv = new CompValuFloat(new TokenTypeFloat(null),
|
||||
|
@ -152,10 +146,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
((LSL_Integer)constField.GetValue(null)).value);
|
||||
}
|
||||
|
||||
/*
|
||||
* The location of a string is the string itself.
|
||||
* Access to the value gets compiled as an ldstr instruction.
|
||||
*/
|
||||
// The location of a string is the string itself.
|
||||
// Access to the value gets compiled as an ldstr instruction.
|
||||
else if(fieldType == typeof(string))
|
||||
{
|
||||
cv = new CompValuString(new TokenTypeStr(null),
|
||||
|
@ -167,18 +159,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
(string)(LSL_String)constField.GetValue(null));
|
||||
}
|
||||
|
||||
/*
|
||||
* The location of everything else (objects) is the static field in the interface definition.
|
||||
* Access to the value gets compiled as an ldsfld instruction.
|
||||
*/
|
||||
// The location of everything else (objects) is the static field in the interface definition.
|
||||
// Access to the value gets compiled as an ldsfld instruction.
|
||||
else
|
||||
{
|
||||
cv = new CompValuSField(TokenType.FromSysType(null, fieldType), constField);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add to dictionary.
|
||||
*/
|
||||
// Add to dictionary.
|
||||
new ScriptConst(sc, constField.Name, cv);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,9 +87,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
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);
|
||||
if(new String(ocm) != ScriptCodeGen.OBJECT_CODE_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)
|
||||
{
|
||||
/*
|
||||
* Save method object code pointer.
|
||||
*/
|
||||
// Save method object code pointer.
|
||||
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;
|
||||
KeyValuePair<int, ScriptSrcLoc>[] srcLocArray = new KeyValuePair<int, ScriptSrcLoc>[n];
|
||||
n = 0;
|
||||
|
@ -221,9 +215,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
srcLocArray[n++] = kvp;
|
||||
Array.Sort(srcLocArray, endMethodWrapper);
|
||||
|
||||
/*
|
||||
* Save sorted array.
|
||||
*/
|
||||
// Save sorted array.
|
||||
scriptSrcLocss.Add(method.Name, srcLocArray);
|
||||
}
|
||||
|
||||
|
|
|
@ -121,9 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
this.argTypes = argTypes;
|
||||
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)
|
||||
{
|
||||
Type sys = sdt.GetSysType();
|
||||
|
@ -131,11 +129,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
sdTypesRev[sys] = sdt.longName.val;
|
||||
}
|
||||
|
||||
/*
|
||||
* This tells the reader to call 'new DynamicMethod()' to create
|
||||
* the function header. Then any forward reference calls to this
|
||||
* method will have a MethodInfo struct to call.
|
||||
*/
|
||||
// This tells the reader to call 'new DynamicMethod()' to create
|
||||
// the function header. Then any forward reference calls to this
|
||||
// method will have a MethodInfo struct to call.
|
||||
objFileWriter.Write((byte)ScriptObjWriterCode.DclMethod);
|
||||
objFileWriter.Write(methName);
|
||||
objFileWriter.Write(GetStrFromType(retType));
|
||||
|
@ -154,10 +150,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
public void BegMethod()
|
||||
{
|
||||
/*
|
||||
* This tells the reader to call methodInfo.GetILGenerator()
|
||||
* so it can start writing CIL code for the method.
|
||||
*/
|
||||
// This tells the reader to call methodInfo.GetILGenerator()
|
||||
// so it can start writing CIL code for the method.
|
||||
objFileWriter.Write((byte)ScriptObjWriterCode.BegMethod);
|
||||
objFileWriter.Write(methName);
|
||||
}
|
||||
|
@ -167,11 +161,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
public void EndMethod()
|
||||
{
|
||||
/*
|
||||
* This tells the reader that all code for the method has
|
||||
* been written and so it will typically call CreateDelegate()
|
||||
* to finalize the method and create an entrypoint.
|
||||
*/
|
||||
// This tells the reader that all code for the method has
|
||||
// been written and so it will typically call CreateDelegate()
|
||||
// to finalize the method and create an entrypoint.
|
||||
objFileWriter.Write((byte)ScriptObjWriterCode.EndMethod);
|
||||
|
||||
objFileWriter = null;
|
||||
|
@ -404,431 +396,385 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
while(true)
|
||||
{
|
||||
|
||||
/*
|
||||
* Get IL instruction offset at beginning of instruction.
|
||||
*/
|
||||
// Get IL instruction offset at beginning of instruction.
|
||||
offset = 0;
|
||||
if((ilGen != null) && (monoGetCurrentOffset != null))
|
||||
{
|
||||
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();
|
||||
switch(code)
|
||||
{
|
||||
|
||||
/*
|
||||
* Reached end-of-file so we are all done.
|
||||
*/
|
||||
// Reached end-of-file so we are all done.
|
||||
case ScriptObjWriterCode.TheEnd:
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
/*
|
||||
* Beginning of method's contents.
|
||||
* Method must have already been declared via DclMethod
|
||||
* so all we need is its name to retrieve from methods[].
|
||||
*/
|
||||
// Beginning of method's contents.
|
||||
// Method must have already been declared via DclMethod
|
||||
// so all we need is its name to retrieve from methods[].
|
||||
case ScriptObjWriterCode.BegMethod:
|
||||
{
|
||||
string methName = objReader.ReadString();
|
||||
{
|
||||
string methName = objReader.ReadString();
|
||||
|
||||
method = methods[methName];
|
||||
ilGen = method.GetILGenerator();
|
||||
ilGenArg[0] = ilGen;
|
||||
method = methods[methName];
|
||||
ilGen = method.GetILGenerator();
|
||||
ilGenArg[0] = ilGen;
|
||||
|
||||
labels.Clear();
|
||||
locals.Clear();
|
||||
labelNames.Clear();
|
||||
localNames.Clear();
|
||||
labels.Clear();
|
||||
locals.Clear();
|
||||
labelNames.Clear();
|
||||
localNames.Clear();
|
||||
|
||||
srcLocs = new Dictionary<int, ScriptSrcLoc>();
|
||||
if(objectTokens != null)
|
||||
objectTokens.BegMethod(method);
|
||||
break;
|
||||
}
|
||||
srcLocs = new Dictionary<int, ScriptSrcLoc>();
|
||||
if(objectTokens != null)
|
||||
objectTokens.BegMethod(method);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* it wants with the method.
|
||||
*/
|
||||
// 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
|
||||
// it wants with the method.
|
||||
case ScriptObjWriterCode.EndMethod:
|
||||
{
|
||||
ilGen = null;
|
||||
ilGenArg[0] = null;
|
||||
scriptObjCode.EndMethod(method, srcLocs);
|
||||
srcLocs = null;
|
||||
if(objectTokens != null)
|
||||
objectTokens.EndMethod();
|
||||
break;
|
||||
}
|
||||
{
|
||||
ilGen = null;
|
||||
ilGenArg[0] = null;
|
||||
scriptObjCode.EndMethod(method, srcLocs);
|
||||
srcLocs = null;
|
||||
if(objectTokens != null)
|
||||
objectTokens.EndMethod();
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Declare a label for branching to.
|
||||
*/
|
||||
// Declare a label for branching to.
|
||||
case ScriptObjWriterCode.DclLabel:
|
||||
{
|
||||
int number = objReader.ReadInt32();
|
||||
string name = objReader.ReadString();
|
||||
{
|
||||
int number = objReader.ReadInt32();
|
||||
string name = objReader.ReadString();
|
||||
|
||||
labels.Add(number, ilGen.DefineLabel());
|
||||
labelNames.Add(number, name + "_" + number.ToString());
|
||||
if(objectTokens != null)
|
||||
objectTokens.DefineLabel(number, name);
|
||||
break;
|
||||
}
|
||||
labels.Add(number, ilGen.DefineLabel());
|
||||
labelNames.Add(number, name + "_" + number.ToString());
|
||||
if(objectTokens != null)
|
||||
objectTokens.DefineLabel(number, name);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Declare a local variable to store into.
|
||||
*/
|
||||
// Declare a local variable to store into.
|
||||
case ScriptObjWriterCode.DclLocal:
|
||||
{
|
||||
int number = objReader.ReadInt32();
|
||||
string name = objReader.ReadString();
|
||||
string type = objReader.ReadString();
|
||||
Type syType = GetTypeFromStr(sdTypes, type);
|
||||
{
|
||||
int number = objReader.ReadInt32();
|
||||
string name = objReader.ReadString();
|
||||
string type = objReader.ReadString();
|
||||
Type syType = GetTypeFromStr(sdTypes, type);
|
||||
|
||||
locals.Add(number, ilGen.DeclareLocal(syType));
|
||||
localNames.Add(number, name + "_" + number.ToString());
|
||||
if(objectTokens != null)
|
||||
objectTokens.DefineLocal(number, name, type, syType);
|
||||
break;
|
||||
}
|
||||
locals.Add(number, ilGen.DeclareLocal(syType));
|
||||
localNames.Add(number, name + "_" + number.ToString());
|
||||
if(objectTokens != null)
|
||||
objectTokens.DefineLocal(number, name, type, syType);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Declare a method that will subsequently be defined.
|
||||
* We create the DynamicMethod object at this point in case there
|
||||
* are forward references from other method bodies.
|
||||
*/
|
||||
// Declare a method that will subsequently be defined.
|
||||
// We create the DynamicMethod object at this point in case there
|
||||
// are forward references from other method bodies.
|
||||
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();
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark a previously declared label at this spot.
|
||||
*/
|
||||
// Mark a previously declared label at this spot.
|
||||
case ScriptObjWriterCode.MarkLabel:
|
||||
{
|
||||
int number = objReader.ReadInt32();
|
||||
{
|
||||
int number = objReader.ReadInt32();
|
||||
|
||||
ilGen.MarkLabel(labels[number]);
|
||||
ilGen.MarkLabel(labels[number]);
|
||||
|
||||
if(objectTokens != null)
|
||||
objectTokens.MarkLabel(offset, number);
|
||||
break;
|
||||
}
|
||||
if(objectTokens != null)
|
||||
objectTokens.MarkLabel(offset, number);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try/Catch blocks.
|
||||
*/
|
||||
// Try/Catch blocks.
|
||||
case ScriptObjWriterCode.BegExcBlk:
|
||||
{
|
||||
ilGen.BeginExceptionBlock();
|
||||
if(objectTokens != null)
|
||||
objectTokens.BegExcBlk(offset);
|
||||
break;
|
||||
}
|
||||
{
|
||||
ilGen.BeginExceptionBlock();
|
||||
if(objectTokens != null)
|
||||
objectTokens.BegExcBlk(offset);
|
||||
break;
|
||||
}
|
||||
|
||||
case ScriptObjWriterCode.BegCatBlk:
|
||||
{
|
||||
Type excType = GetTypeFromStr(sdTypes, objReader.ReadString());
|
||||
ilGen.BeginCatchBlock(excType);
|
||||
if(objectTokens != null)
|
||||
objectTokens.BegCatBlk(offset, excType);
|
||||
break;
|
||||
}
|
||||
{
|
||||
Type excType = GetTypeFromStr(sdTypes, objReader.ReadString());
|
||||
ilGen.BeginCatchBlock(excType);
|
||||
if(objectTokens != null)
|
||||
objectTokens.BegCatBlk(offset, excType);
|
||||
break;
|
||||
}
|
||||
|
||||
case ScriptObjWriterCode.BegFinBlk:
|
||||
{
|
||||
ilGen.BeginFinallyBlock();
|
||||
if(objectTokens != null)
|
||||
objectTokens.BegFinBlk(offset);
|
||||
break;
|
||||
}
|
||||
{
|
||||
ilGen.BeginFinallyBlock();
|
||||
if(objectTokens != null)
|
||||
objectTokens.BegFinBlk(offset);
|
||||
break;
|
||||
}
|
||||
|
||||
case ScriptObjWriterCode.EndExcBlk:
|
||||
{
|
||||
ilGen.EndExceptionBlock();
|
||||
if(objectTokens != null)
|
||||
objectTokens.EndExcBlk(offset);
|
||||
break;
|
||||
}
|
||||
{
|
||||
ilGen.EndExceptionBlock();
|
||||
if(objectTokens != null)
|
||||
objectTokens.EndExcBlk(offset);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit an opcode with no operand.
|
||||
*/
|
||||
// Emit an opcode with no operand.
|
||||
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);
|
||||
ilGen.Emit(opCode);
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode);
|
||||
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitNull(offset, opCode);
|
||||
break;
|
||||
}
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitNull(offset, opCode);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit an opcode with a FieldInfo operand.
|
||||
*/
|
||||
// Emit an opcode with a FieldInfo operand.
|
||||
case ScriptObjWriterCode.EmitField:
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
Type reflectedType = GetTypeFromStr(sdTypes, objReader.ReadString());
|
||||
string fieldName = objReader.ReadString();
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
Type reflectedType = GetTypeFromStr(sdTypes, objReader.ReadString());
|
||||
string fieldName = objReader.ReadString();
|
||||
|
||||
FieldInfo field = reflectedType.GetField(fieldName);
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, field);
|
||||
FieldInfo field = reflectedType.GetField(fieldName);
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, field);
|
||||
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitField(offset, opCode, field);
|
||||
break;
|
||||
}
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitField(offset, opCode, field);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit an opcode with a LocalBuilder operand.
|
||||
*/
|
||||
// Emit an opcode with a LocalBuilder operand.
|
||||
case ScriptObjWriterCode.EmitLocal:
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
int number = objReader.ReadInt32();
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, locals[number]);
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
int number = objReader.ReadInt32();
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, locals[number]);
|
||||
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitLocal(offset, opCode, number);
|
||||
break;
|
||||
}
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitLocal(offset, opCode, number);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit an opcode with a Type operand.
|
||||
*/
|
||||
// Emit an opcode with a Type operand.
|
||||
case ScriptObjWriterCode.EmitType:
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
string name = objReader.ReadString();
|
||||
Type type = GetTypeFromStr(sdTypes, name);
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
string name = objReader.ReadString();
|
||||
Type type = GetTypeFromStr(sdTypes, name);
|
||||
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, type);
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, type);
|
||||
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitType(offset, opCode, type);
|
||||
break;
|
||||
}
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitType(offset, opCode, type);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit an opcode with a Label operand.
|
||||
*/
|
||||
// Emit an opcode with a Label operand.
|
||||
case ScriptObjWriterCode.EmitLabel:
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
int number = objReader.ReadInt32();
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
int number = objReader.ReadInt32();
|
||||
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, labels[number]);
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, labels[number]);
|
||||
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitLabel(offset, opCode, number);
|
||||
break;
|
||||
}
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitLabel(offset, opCode, number);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit an opcode with a Label array operand.
|
||||
*/
|
||||
// Emit an opcode with a Label array operand.
|
||||
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);
|
||||
int nLabels = objReader.ReadInt32();
|
||||
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;
|
||||
nums[i] = objReader.ReadInt32();
|
||||
lbls[i] = labels[nums[i]];
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit an opcode with a MethodInfo operand (such as a call) of an external function.
|
||||
*/
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
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:
|
||||
{
|
||||
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);
|
||||
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;
|
||||
argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
|
||||
}
|
||||
MethodInfo methInfo = methType.GetMethod(methName, argTypes);
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, methInfo);
|
||||
|
||||
/*
|
||||
* Emit an opcode with a MethodInfo operand of an internal function
|
||||
* (previously declared via DclMethod).
|
||||
*/
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitMethod(offset, opCode, methInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
// Emit an opcode with a MethodInfo operand of an internal function
|
||||
// (previously declared via DclMethod).
|
||||
case ScriptObjWriterCode.EmitMethodInt:
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
string methName = objReader.ReadString();
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
string methName = objReader.ReadString();
|
||||
|
||||
MethodInfo methInfo = methods[methName];
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, methInfo);
|
||||
MethodInfo methInfo = methods[methName];
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, methInfo);
|
||||
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitMethod(offset, opCode, methInfo);
|
||||
break;
|
||||
}
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitMethod(offset, opCode, methInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit an opcode with a ConstructorInfo operand.
|
||||
*/
|
||||
// Emit an opcode with a ConstructorInfo operand.
|
||||
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);
|
||||
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;
|
||||
argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit an opcode with a constant operand of various types.
|
||||
*/
|
||||
ConstructorInfo ctorInfo = ctorType.GetConstructor(argTypes);
|
||||
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:
|
||||
{
|
||||
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);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
int value = objReader.ReadInt32();
|
||||
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
|
||||
if(opCode == OpCodes.Ldc_I4)
|
||||
if((value >= -1) && (value <= 8))
|
||||
{
|
||||
if((value >= -1) && (value <= 8))
|
||||
{
|
||||
opCode = opCodesLdcI4M1P8[value + 1];
|
||||
ilGen.Emit(opCode);
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitNull(offset, opCode);
|
||||
break;
|
||||
}
|
||||
if((value >= 0) && (value <= 127))
|
||||
{
|
||||
opCode = OpCodes.Ldc_I4_S;
|
||||
ilGen.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
|
||||
goto pemitint;
|
||||
}
|
||||
opCode = opCodesLdcI4M1P8[value + 1];
|
||||
ilGen.Emit(opCode);
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitNull(offset, opCode);
|
||||
break;
|
||||
}
|
||||
if((value >= 0) && (value <= 127))
|
||||
{
|
||||
opCode = OpCodes.Ldc_I4_S;
|
||||
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:
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
string value = objReader.ReadString();
|
||||
{
|
||||
OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
|
||||
string value = objReader.ReadString();
|
||||
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, value);
|
||||
SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
|
||||
ilGen.Emit(opCode, value);
|
||||
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitString(offset, opCode, value);
|
||||
break;
|
||||
}
|
||||
if(objectTokens != null)
|
||||
objectTokens.EmitString(offset, opCode, value);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Who knows what?
|
||||
*/
|
||||
// Who knows what?
|
||||
default:
|
||||
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;
|
||||
|
||||
/*
|
||||
* Now do the tokenization.
|
||||
*/
|
||||
// Now do the tokenization.
|
||||
TokenBegin tokenBegin = new TokenBegin(emsg, "", 0, 0);
|
||||
tokenBegin.cameFrom = cameFrom;
|
||||
tokenBegin.saveSource = saveSource;
|
||||
|
@ -384,17 +382,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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++;
|
||||
bolIdx = i + 1;
|
||||
|
||||
/*
|
||||
* Check for '#' lineno filename newline
|
||||
* lineno is line number of next line in file
|
||||
* If found, save values and remove tokens from stream
|
||||
*/
|
||||
// Check for '#' lineno filename newline
|
||||
// lineno is line number of next line in file
|
||||
// If found, save values and remove tokens from stream
|
||||
if((lastToken is TokenStr) &&
|
||||
(lastToken.prevToken is TokenInt) &&
|
||||
(lastToken.prevToken.prevToken is TokenKwHash))
|
||||
|
@ -407,15 +401,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over whitespace.
|
||||
*/
|
||||
// Skip over whitespace.
|
||||
if(c <= ' ')
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Skip over comments.
|
||||
*/
|
||||
// Skip over comments.
|
||||
if((i + 2 <= source.Length) && source.Substring(i, 2).Equals("//"))
|
||||
{
|
||||
while((i < source.Length) && (source[i] != '\n'))
|
||||
|
@ -440,9 +430,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for numbers.
|
||||
*/
|
||||
// Check for numbers.
|
||||
if((c >= '0') && (c <= '9'))
|
||||
{
|
||||
int j = TryParseFloat(i);
|
||||
|
@ -459,9 +447,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for quoted strings.
|
||||
*/
|
||||
// Check for quoted strings.
|
||||
if(c == '"')
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -509,9 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for quoted characters.
|
||||
*/
|
||||
// Check for quoted characters.
|
||||
if(c == '\'')
|
||||
{
|
||||
char cb = (char)0;
|
||||
|
@ -560,9 +544,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for keywords/names.
|
||||
*/
|
||||
// Check for keywords/names.
|
||||
if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c == '$' && options.dollarsigns))
|
||||
{
|
||||
int j;
|
||||
|
@ -629,9 +611,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for option enables.
|
||||
*/
|
||||
// Check for option enables.
|
||||
if((c == ';') && (lastToken is TokenName) &&
|
||||
(lastToken.prevToken is TokenName) &&
|
||||
(strcasecmp(((TokenName)lastToken.prevToken).val, "yoption") == 0))
|
||||
|
@ -669,9 +649,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lastly, check for delimeters.
|
||||
*/
|
||||
// Lastly, check for delimeters.
|
||||
{
|
||||
int j;
|
||||
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 + "'");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,11 +177,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
public static bool IsAssignableFrom(TokenType dstType, TokenType srcType)
|
||||
{
|
||||
/*
|
||||
* 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.
|
||||
* Otherwise assume the cast is allowed and return true.
|
||||
*/
|
||||
// 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.
|
||||
// Otherwise assume the cast is allowed and return true.
|
||||
SCGIAF scg = new SCGIAF();
|
||||
scg.ok = true;
|
||||
scg._ilGen = migiaf;
|
||||
|
@ -305,9 +303,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
string oldString = oldType.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"))
|
||||
{
|
||||
LSLUnwrap(scg, errorAt, oldType);
|
||||
|
@ -316,18 +312,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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")
|
||||
oldString = "string";
|
||||
if(newString == "key")
|
||||
newString = "string";
|
||||
|
||||
/*
|
||||
* If the types are the same, there is no conceptual casting needed.
|
||||
* However, there may be wraping/unwraping to/from the LSL wrappers.
|
||||
*/
|
||||
// If the types are the same, there is no conceptual casting needed.
|
||||
// However, there may be wraping/unwraping to/from the LSL wrappers.
|
||||
if(oldString == newString)
|
||||
{
|
||||
if(oldType.ToLSLWrapType() != newType.ToLSLWrapType())
|
||||
|
@ -338,9 +330,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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))
|
||||
{
|
||||
TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl;
|
||||
|
@ -369,11 +359,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
goto illcast;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* the underlying object, no matter what type, implements the new interface.
|
||||
*/
|
||||
// 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
|
||||
// the underlying object, no matter what type, implements the new interface.
|
||||
if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeInterface))
|
||||
{
|
||||
TokenDeclSDTypeInterface oldDecl = ((TokenTypeSDTypeInterface)oldType).decl;
|
||||
|
@ -385,11 +373,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* various methods defined by the interface.
|
||||
*/
|
||||
// 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
|
||||
// various methods defined by the interface.
|
||||
if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeInterface))
|
||||
{
|
||||
TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl;
|
||||
|
@ -402,13 +388,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* object and making sure it casts to the correct script-defined class type.
|
||||
*
|
||||
* But then only if the class type implements the interface type.
|
||||
*/
|
||||
// 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
|
||||
// object and making sure it casts to the correct script-defined class type.
|
||||
//
|
||||
// But then only if the class type implements the interface type.
|
||||
if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeClass))
|
||||
{
|
||||
TokenTypeSDTypeInterface oldSDTI = (TokenTypeSDTypeInterface)oldType;
|
||||
|
@ -423,17 +407,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
ExplCheck(scg, errorAt, explicitAllowed, oldString, newString);
|
||||
|
@ -442,18 +422,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
{
|
||||
scg.ilGen.Emit(errorAt, OpCodes.Pop);
|
||||
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) &&
|
||||
((newType is TokenTypeObject) ||
|
||||
(newType is TokenTypeSDTypeClass) ||
|
||||
|
@ -462,19 +438,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* mono is concerned, all SDTypeClass's are the same.
|
||||
*/
|
||||
// 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
|
||||
// mono is concerned, all SDTypeClass's are the same.
|
||||
if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeClass))
|
||||
{
|
||||
ExplCheck(scg, errorAt, explicitAllowed, oldString, newString);
|
||||
|
@ -483,9 +455,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delegates can be implicitly cast to/from objects.
|
||||
*/
|
||||
// Delegates can be implicitly cast to/from objects.
|
||||
if((oldType is TokenTypeSDTypeDelegate) && (newType is TokenTypeObject))
|
||||
{
|
||||
return;
|
||||
|
@ -496,9 +466,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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;
|
||||
if(!legalTypeCasts.TryGetValue(key, out castDelegate))
|
||||
{
|
||||
|
@ -508,11 +476,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
ExplCheck(scg, errorAt, explicitAllowed, oldString, newString);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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-
|
||||
* wrapped value on the stack upon return, wrap it up after our casting.
|
||||
*/
|
||||
// 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-
|
||||
// wrapped value on the stack upon return, wrap it up after our casting.
|
||||
LSLUnwrap(scg, errorAt, oldType);
|
||||
castDelegate(scg, errorAt);
|
||||
LSLWrap(scg, errorAt, newType);
|
||||
|
|
|
@ -130,9 +130,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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;
|
||||
if(!master.TryGetValue(var.name.val, out typedic))
|
||||
{
|
||||
|
@ -140,19 +138,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
master.Add(var.name.val, typedic);
|
||||
}
|
||||
|
||||
/*
|
||||
* See if there is an entry in the sub-dictionary that matches the argument signature.
|
||||
* Note that fields have null argument lists.
|
||||
* Methods always have a non-null argument list, even if only 0 entries long.
|
||||
*/
|
||||
// See if there is an entry in the sub-dictionary that matches the argument signature.
|
||||
// Note that fields have null argument lists.
|
||||
// Methods always have a non-null argument list, even if only 0 entries long.
|
||||
ArgTypes types;
|
||||
types.argTypes = (var.argDecl == null) ? null : KeyTypesToStringTypes(var.argDecl.types);
|
||||
if(typedic.ContainsKey(types))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* It is unique, add to its name-specific sub-dictionary.
|
||||
*/
|
||||
// It is unique, add to its name-specific sub-dictionary.
|
||||
TDVEntry entry;
|
||||
entry.count = ++count;
|
||||
entry.var = var;
|
||||
|
@ -175,28 +169,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
public VarDict FreezeLocals()
|
||||
{
|
||||
/*
|
||||
* If not local var frame, return original frame as is.
|
||||
* This will allow forward references as the future additions
|
||||
* will be seen by lookups done in this dictionary.
|
||||
*/
|
||||
// If not local var frame, return original frame as is.
|
||||
// This will allow forward references as the future additions
|
||||
// will be seen by lookups done in this dictionary.
|
||||
if(!locals)
|
||||
return this;
|
||||
|
||||
/*
|
||||
* If local var frame, return a copy frozen at this point.
|
||||
* This disallows forward referenes as those future additions
|
||||
* will not be seen by lookups done in the frozen dictionary.
|
||||
*/
|
||||
// If local var frame, return a copy frozen at this point.
|
||||
// This disallows forward referenes as those future additions
|
||||
// will not be seen by lookups done in the frozen dictionary.
|
||||
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
|
||||
* contain additions made after this point, those additions
|
||||
* will have a count .gt. frozen count and will be ignored.
|
||||
*/
|
||||
// Make a copy of the current var dictionary frame.
|
||||
// We copy a reference to the dictionary, and though it may
|
||||
// contain additions made after this point, those additions
|
||||
// will have a count .gt. frozen count and will be ignored.
|
||||
frozenLocals = new VarDict(true);
|
||||
|
||||
frozenLocals.outerVarDict = this.outerVarDict;
|
||||
|
@ -205,11 +192,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
frozenLocals.count = this.count;
|
||||
frozenLocals.frozenLocals = frozenLocals;
|
||||
|
||||
/*
|
||||
* Mark it as being frozen.
|
||||
* - assert fail if any attempt is made to add to it
|
||||
* - ignore any additions to the dictionary with greater count
|
||||
*/
|
||||
// Mark it as being frozen.
|
||||
// - assert fail if any attempt is made to add to it
|
||||
// - ignore any additions to the dictionary with greater count
|
||||
frozenLocals.isFrozen = true;
|
||||
}
|
||||
return frozenLocals;
|
||||
|
@ -257,46 +242,34 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
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;
|
||||
if(!master.TryGetValue(name, out typedic))
|
||||
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)
|
||||
{
|
||||
if(entry.count > this.count)
|
||||
continue;
|
||||
TokenDeclVar var = entry.var;
|
||||
|
||||
/*
|
||||
* Get argument types of declaration.
|
||||
* fields are always null
|
||||
* methods are always non-null, though may be zero-length
|
||||
*/
|
||||
// Get argument types of declaration.
|
||||
// fields are always null
|
||||
// methods are always non-null, though may be zero-length
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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))
|
||||
return var;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* trying to cast the arguments to the delegate arg types.
|
||||
* We don't allow overloading same field name with different delegate 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
|
||||
// trying to cast the arguments to the delegate arg types.
|
||||
// We don't allow overloading same field name with different delegate types.
|
||||
if((declArgs == null) && (argTypes != null))
|
||||
{
|
||||
TokenType fieldType = var.type;
|
||||
|
@ -304,15 +277,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
* If not both null, no match, keep looking.
|
||||
*/
|
||||
// If not both null, no match, keep looking.
|
||||
if((declArgs == null) || (argTypes == null))
|
||||
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;
|
||||
if(i != argTypes.Length)
|
||||
continue;
|
||||
|
@ -331,9 +300,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
* No match.
|
||||
*/
|
||||
// No match.
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,10 +108,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
key = FixKey(key);
|
||||
|
||||
/*
|
||||
* Update heap use throwing an exception on failure
|
||||
* before making any changes to the array.
|
||||
*/
|
||||
// Update heap use throwing an exception on failure
|
||||
// before making any changes to the array.
|
||||
int keysize = HeapTrackerObject.Size(key);
|
||||
int newheapuse = heapUse;
|
||||
object oldval;
|
||||
|
@ -125,10 +123,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
heapUse = inst.UpdateHeapUse(heapUse, newheapuse);
|
||||
|
||||
/*
|
||||
* Save new value in array, replacing one of same key if there.
|
||||
* null means remove the value, ie, script did array[key] = undef.
|
||||
*/
|
||||
// Save new value in array, replacing one of same key if there.
|
||||
// null means remove the value, ie, script did array[key] = undef.
|
||||
if(value != null)
|
||||
{
|
||||
dnary[key] = value;
|
||||
|
@ -137,19 +133,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
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))
|
||||
{
|
||||
Array.Resize<KeyValuePair<object, object>>(ref array, array.Length / 2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// 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.
|
||||
arrayValid = 0;
|
||||
}
|
||||
|
||||
|
@ -236,29 +228,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
private bool ForEach(int number)
|
||||
{
|
||||
/*
|
||||
* If we don't have any array, we can't have ever done
|
||||
* any calls here before, so allocate an array big enough
|
||||
* and set everything else to the beginning.
|
||||
*/
|
||||
// If we don't have any array, we can't have ever done
|
||||
// any calls here before, so allocate an array big enough
|
||||
// and set everything else to the beginning.
|
||||
if(array == null)
|
||||
{
|
||||
array = new KeyValuePair<object, object>[dnary.Count];
|
||||
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)
|
||||
{
|
||||
enumr = dnary.GetEnumerator();
|
||||
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())
|
||||
{
|
||||
if(arrayValid >= array.Length)
|
||||
|
@ -268,9 +254,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -281,10 +265,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
public delegate void SendArrayObjDelegate(object graph);
|
||||
public void SendArrayObj(SendArrayObjDelegate sendObj)
|
||||
{
|
||||
/*
|
||||
* Set the count then the elements themselves.
|
||||
* UnfixKey() because sendObj doesn't handle XMRArrayListKeys.
|
||||
*/
|
||||
// Set the count then the elements themselves.
|
||||
// UnfixKey() because sendObj doesn't handle XMRArrayListKeys.
|
||||
sendObj(dnary.Count);
|
||||
foreach(KeyValuePair<object, object> kvp in dnary)
|
||||
{
|
||||
|
@ -304,17 +286,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP);
|
||||
|
||||
/*
|
||||
* Cause any enumeration to refill the array from the sorted dictionary.
|
||||
* Since it is a sorted dictionary, any enumerations will be in the same
|
||||
* order as on the sending side.
|
||||
*/
|
||||
// Cause any enumeration to refill the array from the sorted dictionary.
|
||||
// Since it is a sorted dictionary, any enumerations will be in the same
|
||||
// order as on the sending side.
|
||||
arrayValid = 0;
|
||||
enumrValid = false;
|
||||
|
||||
/*
|
||||
* Fill dictionary.
|
||||
*/
|
||||
// Fill dictionary.
|
||||
dnary.Clear();
|
||||
int count = (int)recvObj();
|
||||
while(--count >= 0)
|
||||
|
@ -375,9 +353,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
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 ytn = y.GetType().Name;
|
||||
int ctn = String.CompareOrdinal(xtn, ytn);
|
||||
|
|
|
@ -56,9 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
string outName = null;
|
||||
XMRInstance[] instances;
|
||||
|
||||
/*
|
||||
* Decode command line options.
|
||||
*/
|
||||
// Decode command line options.
|
||||
for(int i = indx; i < args.Length; i++)
|
||||
{
|
||||
if(args[i] == "-full")
|
||||
|
@ -126,10 +124,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
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))
|
||||
{
|
||||
m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
|
||||
|
@ -151,17 +146,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
Monitor.Exit(m_InstancesDict);
|
||||
}
|
||||
|
||||
/*
|
||||
* Maybe sort by descending CPU time.
|
||||
*/
|
||||
// Maybe sort by descending CPU time.
|
||||
if(flagTopCPU)
|
||||
{
|
||||
Array.Sort<XMRInstance>(instances, CompareInstancesByCPUTime);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the entries.
|
||||
*/
|
||||
// Print the entries.
|
||||
if(!flagFull)
|
||||
{
|
||||
outFile.WriteLine(" ItemID" +
|
||||
|
@ -176,15 +167,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
outFile.WriteLine(instances[i].RunTestLs(flagFull));
|
||||
}
|
||||
|
||||
/*
|
||||
* Print number of scripts that match selection criteria,
|
||||
* even if we were told to print fewer.
|
||||
*/
|
||||
// Print number of scripts that match selection criteria,
|
||||
// even if we were told to print fewer.
|
||||
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)
|
||||
{
|
||||
LsQueue(outFile, "start", m_StartQueue, args, indx);
|
||||
|
@ -204,9 +191,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
int numScripts = 0;
|
||||
XMRInstance[] instances;
|
||||
|
||||
/*
|
||||
* Decode command line options.
|
||||
*/
|
||||
// Decode command line options.
|
||||
int i, j;
|
||||
List<string> selargs = new List<string>(args.Length);
|
||||
MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods();
|
||||
|
@ -271,9 +256,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
OpenSim.Region.ScriptEngine.Shared.EventParams eps =
|
||||
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))
|
||||
{
|
||||
m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
|
||||
|
@ -296,9 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
Monitor.Exit(m_InstancesDict);
|
||||
}
|
||||
|
||||
/*
|
||||
* Post event to the matching instances.
|
||||
*/
|
||||
// Post event to the matching instances.
|
||||
for(i = 0; i < numScripts; i++)
|
||||
{
|
||||
XMRInstance inst = instances[i];
|
||||
|
@ -415,9 +396,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode command line options.
|
||||
*/
|
||||
// Decode command line options.
|
||||
for(int i = indx; i < args.Length; i++)
|
||||
{
|
||||
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))
|
||||
{
|
||||
m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
|
||||
|
@ -462,9 +439,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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++)
|
||||
{
|
||||
XMRInstance inst = instances[i];
|
||||
|
@ -499,10 +474,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
try
|
||||
{
|
||||
|
||||
/*
|
||||
* Try to print instance name.
|
||||
*/
|
||||
// Try to print instance name.
|
||||
if(InstanceMatchesArgs(inst, args, indx))
|
||||
{
|
||||
outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName);
|
||||
|
@ -510,10 +482,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -473,10 +473,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
ScriptEventHandler seh;
|
||||
|
||||
/*
|
||||
* CallMode_NORMAL: run event handler from the beginning normally
|
||||
* CallMode_RESTORE: restore event handler stack from stackFrames
|
||||
*/
|
||||
// CallMode_NORMAL: run event handler from the beginning normally
|
||||
// CallMode_RESTORE: restore event handler stack from stackFrames
|
||||
callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL :
|
||||
XMRInstAbstract.CallMode_RESTORE;
|
||||
|
||||
|
@ -723,25 +721,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
if(o is LSL_Vector)
|
||||
return "vector";
|
||||
|
||||
/*
|
||||
* 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
|
||||
* class that is implementing the interface. This should let the next
|
||||
* step get the script-defined type name of the object.
|
||||
*/
|
||||
// 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
|
||||
// class that is implementing the interface. This should let the next
|
||||
// step get the script-defined type name of the object.
|
||||
if(o is Delegate[])
|
||||
o = ((Delegate[])o)[0].Target;
|
||||
|
||||
/*
|
||||
* If script-defined class instance, get the script-defined
|
||||
* type name.
|
||||
*/
|
||||
// If script-defined class instance, get the script-defined
|
||||
// type name.
|
||||
if(o is XMRSDTypeClObj)
|
||||
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();
|
||||
if(o is Delegate)
|
||||
{
|
||||
|
@ -750,9 +742,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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();
|
||||
}
|
||||
|
||||
|
@ -964,17 +954,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
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[])
|
||||
{
|
||||
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)
|
||||
{
|
||||
Type ot = thrown.GetType();
|
||||
|
@ -982,17 +968,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
{
|
||||
|
||||
/*
|
||||
* Step from the object's actual class rootward.
|
||||
* 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.
|
||||
*/
|
||||
// Step from the object's actual class rootward.
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1070,24 +1049,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
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.
|
||||
* Throw exception otherwise.
|
||||
*/
|
||||
// The script writer should only pass us script-defined class objects.
|
||||
// Throw exception otherwise.
|
||||
XMRSDTypeClObj srcsdt = (XMRSDTypeClObj)srcobj;
|
||||
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 dsttypename = dstsdt.sdtcClass.longName.val;
|
||||
|
||||
/*
|
||||
* The part before the first '[' of each should match exactly,
|
||||
* 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.
|
||||
*/
|
||||
// The part before the first '[' of each should match exactly,
|
||||
// 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.
|
||||
int i = srctypename.IndexOf('[');
|
||||
int j = dsttypename.IndexOf('[');
|
||||
if((i < 0) || (j < 0))
|
||||
|
@ -1095,12 +1068,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
if((i != j) || !srctypename.StartsWith(dsttypename.Substring(0, j)))
|
||||
throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename);
|
||||
|
||||
/*
|
||||
* The number of brackets must match exactly.
|
||||
* 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.
|
||||
* Counting either '[' or ']' would work equally well.
|
||||
*/
|
||||
// The number of brackets must match exactly.
|
||||
// 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.
|
||||
// Counting either '[' or ']' would work equally well.
|
||||
int srclen = srctypename.Length;
|
||||
int dstlen = dsttypename.Length;
|
||||
int srcjags = 0;
|
||||
|
@ -1114,9 +1085,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
if(dstjags != srcjags)
|
||||
throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename);
|
||||
|
||||
/*
|
||||
* Perform the copy.
|
||||
*/
|
||||
// Perform the copy.
|
||||
Array srcarray = (Array)srcsdt.instVars.iarObjects[0];
|
||||
Array dstarray = (Array)dstsdt.instVars.iarObjects[0];
|
||||
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)
|
||||
{
|
||||
/*
|
||||
* Get the script-visible type of the array.
|
||||
* We only do arrays.
|
||||
*/
|
||||
// Get the script-visible type of the array.
|
||||
// We only do arrays.
|
||||
XMRSDTypeClObj array = (XMRSDTypeClObj)srcar;
|
||||
TokenDeclSDTypeClass sdtClass = array.sdtcClass;
|
||||
if(sdtClass.arrayOfRank == 0)
|
||||
throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
|
||||
|
||||
/*
|
||||
* Validate objects they want to put in the list.
|
||||
* We can't allow anything funky that OpenSim runtime doesn't expect.
|
||||
*/
|
||||
// Validate objects they want to put in the list.
|
||||
// We can't allow anything funky that OpenSim runtime doesn't expect.
|
||||
Array srcarray = (Array)array.instVars.iarObjects[0];
|
||||
object[] output = new object[count];
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a list out of that now immutable array.
|
||||
*/
|
||||
// Make a list out of that now immutable array.
|
||||
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)
|
||||
{
|
||||
/*
|
||||
* Get the script-visible type of the destination.
|
||||
* We only do arrays.
|
||||
*/
|
||||
// Get the script-visible type of the destination.
|
||||
// We only do arrays.
|
||||
XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj;
|
||||
TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass;
|
||||
if(sdtClass.arrayOfType == null)
|
||||
throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
|
||||
|
||||
/*
|
||||
* Copy from the immutable array to the mutable array.
|
||||
* Strip off any LSL wrappers as the script code doesn't expect any.
|
||||
*/
|
||||
// Copy from the immutable array to the mutable array.
|
||||
// Strip off any LSL wrappers as the script code doesn't expect any.
|
||||
object[] srcarr = srclist.Data;
|
||||
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)
|
||||
{
|
||||
/*
|
||||
* Make sure they gave us a script-defined array object.
|
||||
*/
|
||||
// Make sure they gave us a script-defined array object.
|
||||
XMRSDTypeClObj array = (XMRSDTypeClObj)srcar;
|
||||
TokenDeclSDTypeClass sdtClass = array.sdtcClass;
|
||||
if(sdtClass.arrayOfRank == 0)
|
||||
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.
|
||||
* But if it is ok, create a string from the requested characters.
|
||||
*/
|
||||
// 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.
|
||||
char[] srcarray = (char[])array.instVars.iarObjects[0];
|
||||
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)
|
||||
{
|
||||
/*
|
||||
* Make sure they gave us a script-defined array object.
|
||||
*/
|
||||
// Make sure they gave us a script-defined array object.
|
||||
XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj;
|
||||
TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass;
|
||||
if(sdtClass.arrayOfType == null)
|
||||
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.
|
||||
* But if it is ok, copy from the string to the 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.
|
||||
char[] dstarr = (char[])dstarray.instVars.iarObjects[0];
|
||||
for(int i = 0; i < count; i++)
|
||||
dstarr[i + dststart] = srcstr[i + srcstart];
|
||||
|
@ -1343,12 +1294,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
// '"'<string>'"'
|
||||
case '"':
|
||||
{
|
||||
--idx;
|
||||
string val = ParseJSONString(json, ref idx);
|
||||
dict.SetByKey(keys, val);
|
||||
break;
|
||||
}
|
||||
{
|
||||
--idx;
|
||||
string val = ParseJSONString(json, ref idx);
|
||||
dict.SetByKey(keys, val);
|
||||
break;
|
||||
}
|
||||
// true false null
|
||||
case 't':
|
||||
if(json.Substring(idx, 3) != "rue")
|
||||
|
@ -1373,12 +1324,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
// otherwise assume it's a number
|
||||
default:
|
||||
{
|
||||
--idx;
|
||||
object val = ParseJSONNumber(json, ref idx);
|
||||
dict.SetByKey(keys, val);
|
||||
break;
|
||||
}
|
||||
{
|
||||
--idx;
|
||||
object val = ParseJSONNumber(json, ref idx);
|
||||
dict.SetByKey(keys, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
@ -1805,9 +1756,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
BinaryWriter mow = this.migrateOutWriter;
|
||||
|
||||
/*
|
||||
* Value types (including nulls) are always output directly.
|
||||
*/
|
||||
// Value types (including nulls) are always output directly.
|
||||
if(graph == null)
|
||||
{
|
||||
mow.Write((byte)Ser.NULL);
|
||||
|
@ -1893,20 +1842,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Script instance pointer is always just that.
|
||||
*/
|
||||
// Script instance pointer is always just that.
|
||||
if(graph == this)
|
||||
{
|
||||
mow.Write((byte)Ser.XMRINST);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert lists to object type.
|
||||
* This is compatible with old migration data and also
|
||||
* two vars pointing to same list won't duplicate it.
|
||||
*/
|
||||
// Convert lists to object type.
|
||||
// This is compatible with old migration data and also
|
||||
// two vars pointing to same list won't duplicate it.
|
||||
if(graph is LSL_List)
|
||||
{
|
||||
object[] data = ((LSL_List)graph).Data;
|
||||
|
@ -1920,14 +1865,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
graph = oll;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this same exact object was already serialized,
|
||||
* just output an index telling the receiver to use
|
||||
* that same old object, rather than creating a whole
|
||||
* new object with the same values. Also this prevents
|
||||
* self-referencing objects (like arrays) from causing
|
||||
* an infinite loop.
|
||||
*/
|
||||
// If this same exact object was already serialized,
|
||||
// just output an index telling the receiver to use
|
||||
// that same old object, rather than creating a whole
|
||||
// new object with the same values. Also this prevents
|
||||
// self-referencing objects (like arrays) from causing
|
||||
// an infinite loop.
|
||||
int ident;
|
||||
if(this.migrateOutObjects.TryGetValue(graph, out ident))
|
||||
{
|
||||
|
@ -1936,20 +1879,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Object not seen before, save its address with an unique
|
||||
* ident number that the receiver can easily regenerate.
|
||||
*/
|
||||
// Object not seen before, save its address with an unique
|
||||
// ident number that the receiver can easily regenerate.
|
||||
ident = this.migrateOutObjects.Count;
|
||||
this.migrateOutObjects.Add(graph, ident);
|
||||
|
||||
/*
|
||||
* Now output the object's value(s).
|
||||
* If the object self-references, the object is alreay entered
|
||||
* in the dictionary and so the self-reference will just emit
|
||||
* a DUPREF tag instead of trying to output the whole object
|
||||
* again.
|
||||
*/
|
||||
// Now output the object's value(s).
|
||||
// If the object self-references, the object is alreay entered
|
||||
// in the dictionary and so the self-reference will just emit
|
||||
// a DUPREF tag instead of trying to output the whole object
|
||||
// again.
|
||||
if(graph is ObjLslList)
|
||||
{
|
||||
mow.Write((byte)Ser.LSLLIST);
|
||||
|
@ -2182,43 +2121,43 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return new LSL_Key((string)RecvObjValue());
|
||||
|
||||
case Ser.LSLLIST:
|
||||
{
|
||||
this.migrateInObjects.Add(ident, null); // placeholder
|
||||
object[] data = (object[])RecvObjValue(); // read data, maybe using another index
|
||||
LSL_List list = new LSL_List(data); // make LSL-level list
|
||||
this.migrateInObjects[ident] = list; // fill in slot
|
||||
return list;
|
||||
}
|
||||
{
|
||||
this.migrateInObjects.Add(ident, null); // placeholder
|
||||
object[] data = (object[])RecvObjValue(); // read data, maybe using another index
|
||||
LSL_List list = new LSL_List(data); // make LSL-level list
|
||||
this.migrateInObjects[ident] = list; // fill in slot
|
||||
return list;
|
||||
}
|
||||
|
||||
case Ser.LSLROT:
|
||||
{
|
||||
double x = mir.ReadDouble();
|
||||
double y = mir.ReadDouble();
|
||||
double z = mir.ReadDouble();
|
||||
double w = mir.ReadDouble();
|
||||
return new LSL_Rotation(x, y, z, w);
|
||||
}
|
||||
{
|
||||
double x = mir.ReadDouble();
|
||||
double y = mir.ReadDouble();
|
||||
double z = mir.ReadDouble();
|
||||
double w = mir.ReadDouble();
|
||||
return new LSL_Rotation(x, y, z, w);
|
||||
}
|
||||
case Ser.LSLSTR:
|
||||
return new LSL_String((string)RecvObjValue());
|
||||
|
||||
case Ser.LSLVEC:
|
||||
{
|
||||
double x = mir.ReadDouble();
|
||||
double y = mir.ReadDouble();
|
||||
double z = mir.ReadDouble();
|
||||
return new LSL_Vector(x, y, z);
|
||||
}
|
||||
{
|
||||
double x = mir.ReadDouble();
|
||||
double y = mir.ReadDouble();
|
||||
double z = mir.ReadDouble();
|
||||
return new LSL_Vector(x, y, z);
|
||||
}
|
||||
|
||||
case Ser.SYSARRAY:
|
||||
{
|
||||
Type eletype = String2SysType(mir.ReadString());
|
||||
int length = mir.ReadInt32();
|
||||
Array array = Array.CreateInstance(eletype, length);
|
||||
this.migrateInObjects.Add(ident, array);
|
||||
for(int i = 0; i < length; i++)
|
||||
array.SetValue(RecvObjValue(), i);
|
||||
return array;
|
||||
}
|
||||
{
|
||||
Type eletype = String2SysType(mir.ReadString());
|
||||
int length = mir.ReadInt32();
|
||||
Array array = Array.CreateInstance(eletype, length);
|
||||
this.migrateInObjects.Add(ident, array);
|
||||
for(int i = 0; i < length; i++)
|
||||
array.SetValue(RecvObjValue(), i);
|
||||
return array;
|
||||
}
|
||||
|
||||
case Ser.SYSBOOL:
|
||||
return mir.ReadBoolean();
|
||||
|
@ -2241,21 +2180,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return s;
|
||||
|
||||
case Ser.XMRARRAY:
|
||||
{
|
||||
XMR_Array array = new XMR_Array(this);
|
||||
this.migrateInObjects.Add(ident, array);
|
||||
array.RecvArrayObj(this.RecvObjValue);
|
||||
return array;
|
||||
}
|
||||
{
|
||||
XMR_Array array = new XMR_Array(this);
|
||||
this.migrateInObjects.Add(ident, array);
|
||||
array.RecvArrayObj(this.RecvObjValue);
|
||||
return array;
|
||||
}
|
||||
|
||||
case Ser.DUPREF:
|
||||
{
|
||||
ident = mir.ReadInt32();
|
||||
object obj = this.migrateInObjects[ident];
|
||||
if(obj is ObjLslList)
|
||||
obj = new LSL_List(((ObjLslList)obj).objarray);
|
||||
return obj;
|
||||
}
|
||||
{
|
||||
ident = mir.ReadInt32();
|
||||
object obj = this.migrateInObjects[ident];
|
||||
if(obj is ObjLslList)
|
||||
obj = new LSL_List(((ObjLslList)obj).objarray);
|
||||
return obj;
|
||||
}
|
||||
|
||||
case Ser.XMRINST:
|
||||
return this;
|
||||
|
@ -2276,29 +2215,29 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return clobj;
|
||||
|
||||
case Ser.SYSERIAL:
|
||||
{
|
||||
int rawLength = mir.ReadInt32();
|
||||
byte[] rawBytes = mir.ReadBytes(rawLength);
|
||||
MemoryStream memoryStream = new MemoryStream(rawBytes);
|
||||
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
|
||||
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
|
||||
object graph = bformatter.Deserialize(memoryStream);
|
||||
this.migrateInObjects.Add(ident, graph);
|
||||
return graph;
|
||||
}
|
||||
{
|
||||
int rawLength = mir.ReadInt32();
|
||||
byte[] rawBytes = mir.ReadBytes(rawLength);
|
||||
MemoryStream memoryStream = new MemoryStream(rawBytes);
|
||||
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
|
||||
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
|
||||
object graph = bformatter.Deserialize(memoryStream);
|
||||
this.migrateInObjects.Add(ident, graph);
|
||||
return graph;
|
||||
}
|
||||
|
||||
case Ser.THROWNEX:
|
||||
{
|
||||
int rawLength = mir.ReadInt32();
|
||||
byte[] rawBytes = mir.ReadBytes(rawLength);
|
||||
MemoryStream memoryStream = new MemoryStream(rawBytes);
|
||||
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
|
||||
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
|
||||
object graph = bformatter.Deserialize(memoryStream);
|
||||
this.migrateInObjects.Add(ident, graph);
|
||||
((ScriptThrownException)graph).thrown = RecvObjValue();
|
||||
return graph;
|
||||
}
|
||||
{
|
||||
int rawLength = mir.ReadInt32();
|
||||
byte[] rawBytes = mir.ReadBytes(rawLength);
|
||||
MemoryStream memoryStream = new MemoryStream(rawBytes);
|
||||
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
|
||||
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
|
||||
object graph = bformatter.Deserialize(memoryStream);
|
||||
this.migrateInObjects.Add(ident, graph);
|
||||
((ScriptThrownException)graph).thrown = RecvObjValue();
|
||||
return graph;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Exception("bad stream code " + code.ToString());
|
||||
|
|
|
@ -249,22 +249,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
lock(m_QueueLock)
|
||||
{
|
||||
/*
|
||||
* Say how long to sleep.
|
||||
*/
|
||||
// Say how long to sleep.
|
||||
m_SleepUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(ms);
|
||||
|
||||
/*
|
||||
* Don't wake on any events.
|
||||
*/
|
||||
// Don't wake on any events.
|
||||
m_SleepEventMask1 = 0;
|
||||
m_SleepEventMask2 = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The compiler follows all calls to llSleep() with a call to CheckRun().
|
||||
* So tell CheckRun() to suspend the microthread.
|
||||
*/
|
||||
// The compiler follows all calls to llSleep() with a call to CheckRun().
|
||||
// So tell CheckRun() to suspend the microthread.
|
||||
suspendOnCheckRunTemp = true;
|
||||
}
|
||||
|
||||
|
@ -327,10 +321,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
if(callMode == CallMode_NORMAL)
|
||||
goto findevent;
|
||||
|
||||
/*
|
||||
* Stack frame is being restored as saved via CheckRun...().
|
||||
* Restore necessary values then jump to __call<n> label to resume processing.
|
||||
*/
|
||||
// Stack frame is being restored as saved via CheckRun...().
|
||||
// Restore necessary values then jump to __call<n> label to resume processing.
|
||||
sv = RestoreStackFrame("xmrEventDequeue", out callNo);
|
||||
sleepUntil = DateTime.Parse((string)sv[0]);
|
||||
returnMask1 = (int)sv[1];
|
||||
|
@ -353,9 +345,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
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:
|
||||
Monitor.Enter(m_QueueLock);
|
||||
for(lln = m_EventQueue.First; lln != null; lln = lln.Next)
|
||||
|
@ -369,9 +359,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
goto remfromq;
|
||||
}
|
||||
|
||||
/*
|
||||
* Nothing found, sleep while one comes in.
|
||||
*/
|
||||
// Nothing found, sleep while one comes in.
|
||||
m_SleepUntil = sleepUntil;
|
||||
m_SleepEventMask1 = mask1;
|
||||
m_SleepEventMask2 = mask2;
|
||||
|
@ -382,9 +370,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
CheckRunQuick();
|
||||
goto checktmo;
|
||||
|
||||
/*
|
||||
* Found one, remove it from queue.
|
||||
*/
|
||||
// Found one, remove it from queue.
|
||||
remfromq:
|
||||
m_EventQueue.Remove(lln);
|
||||
if((uint)evc1 < (uint)m_EventCounts.Length)
|
||||
|
@ -393,16 +379,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
Monitor.Exit(m_QueueLock);
|
||||
m_InstEHEvent++;
|
||||
|
||||
/*
|
||||
* See if returnable or background event.
|
||||
*/
|
||||
// See if returnable or background event.
|
||||
if((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) ||
|
||||
(((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0)))
|
||||
{
|
||||
/*
|
||||
* Returnable event, return its parameters in a list.
|
||||
* Also set the detect parameters to what the event has.
|
||||
*/
|
||||
// Returnable event, return its parameters in a list.
|
||||
// Also set the detect parameters to what the event has.
|
||||
int plen = evt.Params.Length;
|
||||
object[] plist = new object[plen + 1];
|
||||
plist[0] = (LSL_Integer)evc1;
|
||||
|
@ -421,10 +403,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return new LSL_List(plist);
|
||||
}
|
||||
|
||||
/*
|
||||
* It is a background event, simply call its event handler,
|
||||
* then check event queue again.
|
||||
*/
|
||||
// It is a background event, simply call its event handler,
|
||||
// then check event queue again.
|
||||
callNo = 1;
|
||||
__call1:
|
||||
ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc1];
|
||||
|
@ -450,28 +430,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
this.eventCode = saveEventCode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep waiting until we find a returnable event or timeout.
|
||||
*/
|
||||
// Keep waiting until we find a returnable event or timeout.
|
||||
checktmo:
|
||||
if(DateTime.UtcNow < sleepUntil)
|
||||
goto findevent;
|
||||
|
||||
/*
|
||||
* We timed out, return an empty list.
|
||||
*/
|
||||
// We timed out, return an empty list.
|
||||
return emptyList;
|
||||
}
|
||||
finally
|
||||
{
|
||||
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
|
||||
* when we need to.
|
||||
*/
|
||||
// Stack frame is being saved by CheckRun...().
|
||||
// Save everything we need at the __call<n> labels so we can restore it
|
||||
// when we need to.
|
||||
sv = CaptureStackFrame("xmrEventDequeue", callNo, 9);
|
||||
sv[0] = sleepUntil.ToString(); // needed at __call0,__call1
|
||||
sv[1] = returnMask1; // needed at __call0,__call1
|
||||
|
@ -606,22 +579,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
public override void StateChange()
|
||||
{
|
||||
/*
|
||||
* Cancel any llListen()s etc.
|
||||
* But llSetTimerEvent() should persist.
|
||||
*/
|
||||
// Cancel any llListen()s etc.
|
||||
// But llSetTimerEvent() should persist.
|
||||
object[] timers = m_XMRLSLApi.acm.TimerPlugin.GetSerializationData(m_ItemID);
|
||||
AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
|
||||
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));
|
||||
|
||||
/*
|
||||
* Clear out any old events from the queue.
|
||||
*/
|
||||
// Clear out any old events from the queue.
|
||||
lock(m_QueueLock)
|
||||
{
|
||||
m_EventQueue.Clear();
|
||||
|
|
|
@ -390,9 +390,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
{
|
||||
PostEvent(new EventParams("on_rez",
|
||||
|
|
|
@ -74,14 +74,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
public void Dispose()
|
||||
{
|
||||
/*
|
||||
* Tell script stop executing next time it calls CheckRun().
|
||||
*/
|
||||
// Tell script stop executing next time it calls CheckRun().
|
||||
suspendOnCheckRunHold = true;
|
||||
|
||||
/*
|
||||
* Don't send us any more events.
|
||||
*/
|
||||
// Don't send us any more events.
|
||||
lock(m_RunLock)
|
||||
{
|
||||
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
|
||||
* them.
|
||||
*/
|
||||
// Let script methods get garbage collected if no one else is using
|
||||
// them.
|
||||
DecObjCodeRefCount();
|
||||
}
|
||||
|
||||
|
@ -244,26 +238,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
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);
|
||||
|
||||
/*
|
||||
* Get new path, ie, files split up based on first 2 chars of name.
|
||||
*/
|
||||
// string subdir = filename.Substring (0, 2);
|
||||
// filename = filename.Substring (2);
|
||||
// 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, 1);
|
||||
filename = filename.Substring(1);
|
||||
scriptBasePath = Path.Combine(scriptBasePath, subdir);
|
||||
Directory.CreateDirectory(scriptBasePath);
|
||||
string newPath = Path.Combine(scriptBasePath, filename);
|
||||
|
||||
/*
|
||||
* If file exists only in old location, move to new location.
|
||||
* If file exists in both locations, delete old location.
|
||||
*/
|
||||
// If file exists only in old location, move to new location.
|
||||
// If file exists in both locations, delete old location.
|
||||
if(File.Exists(oldPath))
|
||||
{
|
||||
if(File.Exists(newPath))
|
||||
|
@ -276,9 +264,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Always return new location.
|
||||
*/
|
||||
// Always return new location.
|
||||
return newPath;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,36 +66,27 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
|
||||
evt.EventName);
|
||||
|
||||
/*
|
||||
* Put event on end of event queue.
|
||||
*/
|
||||
// Put event on end of event queue.
|
||||
bool startIt = false;
|
||||
bool wakeIt = false;
|
||||
lock(m_QueueLock)
|
||||
{
|
||||
bool construct = (m_IState == XMRInstState.CONSTRUCT);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* by the time this event is dequeued and delivered to the script.
|
||||
*/
|
||||
// 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
|
||||
// by the time this event is dequeued and delivered to the script.
|
||||
if(!construct && // make sure m_HaveEventHandlers is filled in
|
||||
((uint)evc < (uint)m_HaveEventHandlers.Length) &&
|
||||
!m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state
|
||||
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)
|
||||
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(evc == ScriptEventCode.timer)
|
||||
|
@ -109,29 +100,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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);
|
||||
switch(evc)
|
||||
{
|
||||
/*
|
||||
* These need to go first. The only time we manually
|
||||
* queue them is for the default state_entry() and we
|
||||
* need to make sure they go before any attach() events
|
||||
* so the heapLimit value gets properly initialized.
|
||||
*/
|
||||
// These need to go first. The only time we manually
|
||||
// queue them is for the default state_entry() and we
|
||||
// need to make sure they go before any attach() events
|
||||
// so the heapLimit value gets properly initialized.
|
||||
case ScriptEventCode.state_entry:
|
||||
m_EventQueue.AddFirst(lln);
|
||||
break;
|
||||
|
||||
/*
|
||||
* The attach event sneaks to the front of the queue.
|
||||
* This is needed for quantum limiting to work because
|
||||
* we want the attach(NULL_KEY) event to come in front
|
||||
* of all others so the m_DetachQuantum won't run out
|
||||
* before attach(NULL_KEY) is executed.
|
||||
*/
|
||||
// The attach event sneaks to the front of the queue.
|
||||
// This is needed for quantum limiting to work because
|
||||
// we want the attach(NULL_KEY) event to come in front
|
||||
// of all others so the m_DetachQuantum won't run out
|
||||
// before attach(NULL_KEY) is executed.
|
||||
case ScriptEventCode.attach:
|
||||
if(evt.Params[0].ToString() == UUID.Zero.ToString())
|
||||
{
|
||||
|
@ -150,11 +135,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
else
|
||||
m_EventQueue.AddBefore(lln2, lln);
|
||||
|
||||
/* If we're detaching, limit the qantum. This will also
|
||||
* cause the script to self-suspend after running this
|
||||
* event
|
||||
*/
|
||||
|
||||
// If we're detaching, limit the qantum. This will also
|
||||
// cause the script to self-suspend after running this
|
||||
// event
|
||||
m_DetachReady.Reset();
|
||||
m_DetachQuantum = 100;
|
||||
}
|
||||
|
@ -163,31 +146,25 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
break;
|
||||
|
||||
/*
|
||||
* All others just go on end in the order queued.
|
||||
*/
|
||||
// All others just go on end in the order queued.
|
||||
default:
|
||||
m_EventQueue.AddLast(lln);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 now before unlocking so another thread won't try
|
||||
* to do the same thing right now.
|
||||
* Dont' flag it if it's still suspended!
|
||||
*/
|
||||
// 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 now before unlocking so another thread won't try
|
||||
// to do the same thing right now.
|
||||
// Dont' flag it if it's still suspended!
|
||||
if((m_IState == XMRInstState.IDLE) && !m_Suspended)
|
||||
{
|
||||
m_IState = XMRInstState.ONSTARTQ;
|
||||
startIt = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If instance is sleeping (ie, possibly in xmrEventDequeue),
|
||||
* wake it up if event is in the mask.
|
||||
*/
|
||||
// If instance is sleeping (ie, possibly in xmrEventDequeue),
|
||||
// wake it up if event is in the mask.
|
||||
if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended)
|
||||
{
|
||||
int evc1 = (int)evc;
|
||||
|
@ -198,16 +175,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If transitioned from IDLE->ONSTARTQ, actually go insert it
|
||||
* on m_StartQueue and give the RunScriptThread() a wake-up.
|
||||
*/
|
||||
// If transitioned from IDLE->ONSTARTQ, actually go insert it
|
||||
// on m_StartQueue and give the RunScriptThread() a wake-up.
|
||||
if(startIt)
|
||||
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)
|
||||
{
|
||||
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
|
||||
* CheckRun(). It returns what the instance's next state should be,
|
||||
* ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED.
|
||||
*/
|
||||
// This is called in the script thread to step script until it calls
|
||||
// CheckRun(). It returns what the instance's next state should be,
|
||||
// ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED.
|
||||
public XMRInstState RunOne()
|
||||
{
|
||||
DateTime now = DateTime.UtcNow;
|
||||
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";
|
||||
if(m_SleepUntil > now)
|
||||
{
|
||||
|
@ -236,9 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return XMRInstState.ONSLEEPQ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Also, someone may have called Suspend().
|
||||
*/
|
||||
// Also, someone may have called Suspend().
|
||||
m_RunOnePhase = "check m_SuspendCount";
|
||||
if(m_SuspendCount > 0)
|
||||
{
|
||||
|
@ -246,11 +212,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return XMRInstState.SUSPENDED;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* back right away, delay a bit so we don't get in infinite loop.
|
||||
*/
|
||||
// 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
|
||||
// back right away, delay a bit so we don't get in infinite loop.
|
||||
m_RunOnePhase = "lock m_RunLock";
|
||||
if(!Monitor.TryEnter(m_RunLock))
|
||||
{
|
||||
|
@ -264,18 +228,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
CheckRunLockInvariants(true);
|
||||
Exception e = null;
|
||||
|
||||
/*
|
||||
* Maybe it has been Disposed()
|
||||
*/
|
||||
// Maybe it has been Disposed()
|
||||
if(m_Part == null)
|
||||
{
|
||||
m_RunOnePhase = "runone saw it 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)
|
||||
{
|
||||
lock(m_QueueLock)
|
||||
|
@ -297,10 +257,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
e = ResumeEx();
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise, maybe we can dequeue a new event and start
|
||||
* processing it.
|
||||
*/
|
||||
// Otherwise, maybe we can dequeue a new event and start
|
||||
// processing it.
|
||||
else
|
||||
{
|
||||
m_RunOnePhase = "lock event queue";
|
||||
|
@ -310,14 +268,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
lock(m_QueueLock)
|
||||
{
|
||||
|
||||
/* We can't get here unless the script has been resumed
|
||||
* after creation, then suspended again, and then had
|
||||
* an event posted to it. We just pretend there is no
|
||||
* event int he queue and let the normal mechanics
|
||||
* carry out the suspension. A Resume will handle the
|
||||
* restarting gracefully. This is taking the easy way
|
||||
* out and may be improved in the future.
|
||||
*/
|
||||
// We can't get here unless the script has been resumed
|
||||
// after creation, then suspended again, and then had
|
||||
// an event posted to it. We just pretend there is no
|
||||
// event int he queue and let the normal mechanics
|
||||
// carry out the suspension. A Resume will handle the
|
||||
// restarting gracefully. This is taking the easy way
|
||||
// out and may be improved in the future.
|
||||
|
||||
if(m_Suspended)
|
||||
{
|
||||
|
@ -336,11 +293,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
evt.EventName);
|
||||
if(evc != ScriptEventCode.attach)
|
||||
{
|
||||
/*
|
||||
* This is the case where the attach event
|
||||
* has completed and another event is queued
|
||||
* Stop it from running and suspend
|
||||
*/
|
||||
// This is the case where the attach event
|
||||
// has completed and another event is queued
|
||||
// Stop it from running and suspend
|
||||
m_Suspended = true;
|
||||
m_DetachReady.Set();
|
||||
m_DetachQuantum = 0;
|
||||
|
@ -356,18 +311,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
m_EventCounts[(int)evc]--;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no event to dequeue, don't run this script
|
||||
* until another event gets queued.
|
||||
*/
|
||||
// If there is no event to dequeue, don't run this script
|
||||
// until another event gets queued.
|
||||
if(evt == null)
|
||||
{
|
||||
if(m_DetachQuantum > 0)
|
||||
{
|
||||
/*
|
||||
* This will happen if the attach event has run
|
||||
* and exited with time slice left.
|
||||
*/
|
||||
// This will happen if the attach event has run
|
||||
// and exited with time slice left.
|
||||
m_Suspended = true;
|
||||
m_DetachReady.Set();
|
||||
m_DetachQuantum = 0;
|
||||
|
@ -378,10 +329,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Dequeued an event, so start it going until it either
|
||||
* finishes or it calls CheckRun().
|
||||
*/
|
||||
// Dequeued an event, so start it going until it either
|
||||
// finishes or it calls CheckRun().
|
||||
m_RunOnePhase = "start event handler";
|
||||
m_DetectParams = evt.DetectParams;
|
||||
m_LastRanAt = now;
|
||||
|
@ -391,9 +340,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
m_RunOnePhase = "done running";
|
||||
m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds;
|
||||
|
||||
/*
|
||||
* Maybe it puqued.
|
||||
*/
|
||||
// Maybe it puqued.
|
||||
if(e != null)
|
||||
{
|
||||
m_RunOnePhase = "handling exception " + e.Message;
|
||||
|
@ -403,9 +350,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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)
|
||||
m_DetectParams = null;
|
||||
|
||||
|
@ -417,9 +362,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
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";
|
||||
return XMRInstState.ONYIELDQ;
|
||||
}
|
||||
|
@ -433,10 +376,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
public void CheckRunLockInvariants(bool throwIt)
|
||||
{
|
||||
/*
|
||||
* 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 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.
|
||||
bool active = (stackFrames != null);
|
||||
ScriptEventCode ec = this.eventCode;
|
||||
if(((ec == ScriptEventCode.None) && active) ||
|
||||
|
@ -470,88 +411,67 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs)
|
||||
{
|
||||
/*
|
||||
* We use this.eventCode == ScriptEventCode.None to indicate we are idle.
|
||||
* So trying to execute ScriptEventCode.None might make a mess.
|
||||
*/
|
||||
// We use this.eventCode == ScriptEventCode.None to indicate we are idle.
|
||||
// So trying to execute ScriptEventCode.None might make a mess.
|
||||
if(eventCode == 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))
|
||||
return null;
|
||||
|
||||
/*
|
||||
* The microthread shouldn't be processing any event code.
|
||||
* These are assert checks so we throw them directly as exceptions.
|
||||
*/
|
||||
// The microthread shouldn't be processing any event code.
|
||||
// These are assert checks so we throw them directly as exceptions.
|
||||
if(this.eventCode != ScriptEventCode.None)
|
||||
throw new Exception("still processing event " + this.eventCode.ToString());
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// 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.
|
||||
this.eventCode = eventCode;
|
||||
this.ehArgs = ehArgs;
|
||||
|
||||
/*
|
||||
* This calls ScriptUThread.Main() directly, and returns when Main() [indirectly]
|
||||
* calls Suspend() or when Main() returns, whichever occurs first.
|
||||
* Setting stackFrames = null means run the event handler from the beginning
|
||||
* without doing any stack frame restores first.
|
||||
*/
|
||||
// This calls ScriptUThread.Main() directly, and returns when Main() [indirectly]
|
||||
// calls Suspend() or when Main() returns, whichever occurs first.
|
||||
// Setting stackFrames = null means run the event handler from the beginning
|
||||
// without doing any stack frame restores first.
|
||||
this.stackFrames = null;
|
||||
return StartEx();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief There was an exception whilst starting/running a script event handler.
|
||||
* Maybe we handle it directly or just print an error message.
|
||||
*/
|
||||
private void HandleScriptException(Exception e)
|
||||
{
|
||||
/*
|
||||
* The script threw some kind of exception that was not caught at
|
||||
* script level, so the script is no longer running an event handler.
|
||||
*/
|
||||
// The script threw some kind of exception that was not caught at
|
||||
// script level, so the script is no longer running an event handler.
|
||||
eventCode = ScriptEventCode.None;
|
||||
|
||||
if(e is ScriptDeleteException)
|
||||
{
|
||||
/*
|
||||
* Script did something like llRemoveInventory(llGetScriptName());
|
||||
* ... to delete itself from the object.
|
||||
*/
|
||||
// Script did something like llRemoveInventory(llGetScriptName());
|
||||
// ... to delete itself from the object.
|
||||
m_SleepUntil = DateTime.MaxValue;
|
||||
Verbose("[YEngine]: script self-delete {0}", m_ItemID);
|
||||
m_Part.Inventory.RemoveInventoryItem(m_ItemID);
|
||||
}
|
||||
else if(e is ScriptDieException)
|
||||
{
|
||||
/*
|
||||
* Script did an llDie()
|
||||
*/
|
||||
// Script did an llDie()
|
||||
m_RunOnePhase = "dying...";
|
||||
m_SleepUntil = DateTime.MaxValue;
|
||||
m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false);
|
||||
}
|
||||
else if(e is ScriptResetException)
|
||||
{
|
||||
/*
|
||||
* Script did an llResetScript().
|
||||
*/
|
||||
// Script did an llResetScript().
|
||||
m_RunOnePhase = "resetting...";
|
||||
ResetLocked("HandleScriptResetException");
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Some general script error.
|
||||
*/
|
||||
// Some general script error.
|
||||
SendErrorMessage(e);
|
||||
}
|
||||
return;
|
||||
|
@ -570,16 +490,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
msg.Append(m_ItemID);
|
||||
msg.Append('\n');
|
||||
|
||||
/*
|
||||
* Add exception message.
|
||||
*/
|
||||
// Add exception message.
|
||||
string des = e.Message;
|
||||
des = (des == null) ? "" : (": " + des);
|
||||
msg.Append(e.GetType().Name + des + "\n");
|
||||
|
||||
/*
|
||||
* Tell script owner what to do.
|
||||
*/
|
||||
// Tell script owner what to do.
|
||||
msg.Append("Prim: <");
|
||||
msg.Append(m_Part.Name);
|
||||
msg.Append(">, Script: <");
|
||||
|
@ -595,20 +511,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
msg.Append((int)Math.Floor(pos.Z));
|
||||
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);
|
||||
|
||||
/*
|
||||
* Give script owner the stack dump.
|
||||
*/
|
||||
// Give script owner the stack dump.
|
||||
msg.Append(XMRExceptionStackString(e));
|
||||
|
||||
/*
|
||||
* Send error message to owner.
|
||||
* Suppress internal code stack trace lines.
|
||||
*/
|
||||
// Send error message to owner.
|
||||
// Suppress internal code stack trace lines.
|
||||
string msgst = msg.ToString();
|
||||
if(!msgst.EndsWith("\n"))
|
||||
msgst += '\n';
|
||||
|
@ -630,10 +540,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
imstr.Append('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* Send as instant message in case user not online.
|
||||
* Code modelled from llInstantMessage().
|
||||
*/
|
||||
// Send as instant message in case user not online.
|
||||
// Code modelled from llInstantMessage().
|
||||
IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>();
|
||||
if(transferModule != null)
|
||||
{
|
||||
|
@ -661,10 +569,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Say script is sleeping for a very long time.
|
||||
* Reset() is able to cancel this sleeping.
|
||||
*/
|
||||
// Say script is sleeping for a very long time.
|
||||
// Reset() is able to cancel this sleeping.
|
||||
m_SleepUntil = DateTime.MaxValue;
|
||||
}
|
||||
|
||||
|
@ -678,18 +584,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
XMRInstState iState = m_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:
|
||||
return;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* it out of idle, verify that it is still in idle then transition
|
||||
* it to resetting so no other thread will touch it.
|
||||
*/
|
||||
// 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
|
||||
// it out of idle, verify that it is still in idle then transition
|
||||
// it to resetting so no other thread will touch it.
|
||||
case XMRInstState.IDLE:
|
||||
lock(m_QueueLock)
|
||||
{
|
||||
|
@ -701,12 +603,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
goto checkstate;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* can't be started and transition it to resetting so no other thread
|
||||
* will touch it.
|
||||
*/
|
||||
// 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
|
||||
// can't be started and transition it to resetting so no other thread
|
||||
// will touch it.
|
||||
case XMRInstState.ONSTARTQ:
|
||||
lock(m_Engine.m_StartQueue)
|
||||
{
|
||||
|
@ -719,10 +619,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
goto checkstate;
|
||||
|
||||
/*
|
||||
* If it's running, tell CheckRun() to suspend the thread then go back
|
||||
* to see what it got transitioned to.
|
||||
*/
|
||||
// If it's running, tell CheckRun() to suspend the thread then go back
|
||||
// to see what it got transitioned to.
|
||||
case XMRInstState.RUNNING:
|
||||
suspendOnCheckRunHold = true;
|
||||
lock(m_QueueLock)
|
||||
|
@ -730,11 +628,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
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:
|
||||
lock(m_Engine.m_SleepQueue)
|
||||
{
|
||||
|
@ -747,19 +642,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
goto checkstate;
|
||||
|
||||
/*
|
||||
* It was just removed from the sleep queue and is about to be put
|
||||
* on the yield queue (ie, is being woken up).
|
||||
* Let that thread complete transition and try again.
|
||||
*/
|
||||
// It was just removed from the sleep queue and is about to be put
|
||||
// on the yield queue (ie, is being woken up).
|
||||
// Let that thread complete transition and try again.
|
||||
case XMRInstState.REMDFROMSLPQ:
|
||||
Sleep(10);
|
||||
goto checkstate;
|
||||
|
||||
/*
|
||||
* If it's yielding, remove it from yield queue and transition it to
|
||||
* resetting so no other thread will touch it.
|
||||
*/
|
||||
// If it's yielding, remove it from yield queue and transition it to
|
||||
// resetting so no other thread will touch it.
|
||||
case XMRInstState.ONYIELDQ:
|
||||
lock(m_Engine.m_YieldQueue)
|
||||
{
|
||||
|
@ -772,52 +663,38 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
goto checkstate;
|
||||
|
||||
/*
|
||||
* If it just finished running something, let that thread transition it
|
||||
* to its next state then check again.
|
||||
*/
|
||||
// If it just finished running something, let that thread transition it
|
||||
// to its next state then check again.
|
||||
case XMRInstState.FINISHED:
|
||||
Sleep(10);
|
||||
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:
|
||||
return;
|
||||
|
||||
/*
|
||||
* Some other thread is already resetting it, let it finish.
|
||||
*/
|
||||
// Some other thread is already resetting it, let it finish.
|
||||
|
||||
case XMRInstState.RESETTING:
|
||||
return;
|
||||
|
||||
|
||||
default:
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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;
|
||||
|
||||
/*
|
||||
* Reset everything and queue up default's start_entry() event.
|
||||
*/
|
||||
// Reset everything and queue up default's start_entry() event.
|
||||
ClearQueue();
|
||||
ResetLocked("external Reset");
|
||||
|
||||
|
@ -886,16 +763,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
m_SleepUntil = DateTime.MinValue; // not doing llSleep()
|
||||
m_ResetCount++; // has been reset once more
|
||||
|
||||
/*
|
||||
* Tell next call to 'default state_entry()' to reset all global
|
||||
* vars to their initial values.
|
||||
*/
|
||||
// Tell next call to 'default state_entry()' to reset all global
|
||||
// vars to their initial values.
|
||||
doGblInit = true;
|
||||
|
||||
/*
|
||||
* Set script to 'default' state and queue call to its
|
||||
* 'state_entry()' event handler.
|
||||
*/
|
||||
// Set script to 'default' state and queue call to its
|
||||
// 'state_entry()' event handler.
|
||||
m_RunOnePhase = "ResetLocked: posting default:state_entry() event";
|
||||
stateCode = 0;
|
||||
m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0));
|
||||
|
@ -903,9 +776,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
zeroObjectArray,
|
||||
zeroDetectParams));
|
||||
|
||||
/*
|
||||
* Tell CheckRun() to let script run.
|
||||
*/
|
||||
// Tell CheckRun() to let script run.
|
||||
suspendOnCheckRunHold = false;
|
||||
suspendOnCheckRunTemp = false;
|
||||
m_RunOnePhase = "ResetLocked: reset complete";
|
||||
|
@ -955,9 +826,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
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)
|
||||
{
|
||||
m_CheckRunPhase = "top of while";
|
||||
|
@ -997,10 +866,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
m_CheckRunPhase = "returning";
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// 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.
|
||||
if(callMode != CallMode_NORMAL)
|
||||
throw new Exception("bad callMode " + callMode);
|
||||
}
|
||||
|
|
|
@ -501,10 +501,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
public override void EndMethod()
|
||||
{
|
||||
/*
|
||||
* Convert CIL code to primitive statements.
|
||||
* There are a bunch of labels and internal code such as call stack save restore.
|
||||
*/
|
||||
// Convert CIL code to primitive statements.
|
||||
// There are a bunch of labels and internal code such as call stack save restore.
|
||||
topBlock = new OTStmtBlock();
|
||||
blockstack.Push(topBlock);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Strip out stuff we don't want, such as references to callMode.
|
||||
* This strips out stack frame capture and restore code.
|
||||
*/
|
||||
// Strip out stuff we don't want, such as references to callMode.
|
||||
// This strips out stack frame capture and restore code.
|
||||
topBlock.StripStuff(null);
|
||||
|
||||
// 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
|
||||
* that the do/for/if/while blocks are represented by OTStmtCont-style
|
||||
* if/jumps. So try to convert them to the higher-level structures.
|
||||
*/
|
||||
// At this point, all behind-the-scenes references are removed except
|
||||
// that the do/for/if/while blocks are represented by OTStmtCont-style
|
||||
// if/jumps. So try to convert them to the higher-level structures.
|
||||
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);
|
||||
|
||||
/*
|
||||
* Build reference counts so we don't output unneeded declarations,
|
||||
* especially temps and internal variables.
|
||||
*/
|
||||
// Build reference counts so we don't output unneeded declarations,
|
||||
// especially temps and internal variables.
|
||||
foreach(OTLocal local in locals.Values)
|
||||
{
|
||||
local.nlclreads = 0;
|
||||
|
@ -564,10 +554,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Strip the $n off of local vars that are not ambiguous.
|
||||
* Make sure they don't mask globals and arguments as well.
|
||||
*/
|
||||
// Strip the $n off of local vars that are not ambiguous.
|
||||
// Make sure they don't mask globals and arguments as well.
|
||||
Dictionary<string, int> namecounts = new Dictionary<string, int>();
|
||||
foreach(Dictionary<int, string> varnames in scriptObjCode.globalVarNames.Values)
|
||||
{
|
||||
|
@ -607,9 +595,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
local.name = name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out result.
|
||||
*/
|
||||
// Print out result.
|
||||
if(method.Name == _globalvarinit)
|
||||
{
|
||||
GlobalsDump();
|
||||
|
@ -725,10 +711,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
*/
|
||||
private void GlobalsDump()
|
||||
{
|
||||
/*
|
||||
* Scan $globalvarinit(). It should only have global var assignments in it.
|
||||
* Also gather up list of variables it initializes.
|
||||
*/
|
||||
// Scan $globalvarinit(). It should only have global var assignments in it.
|
||||
// Also gather up list of variables it initializes.
|
||||
bool badinit = false;
|
||||
Dictionary<string, string> inittypes = new Dictionary<string, string>();
|
||||
foreach(OTStmt stmt in topBlock.blkstmts)
|
||||
|
@ -748,11 +732,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
inittypes[globalop.PrintableString] = "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan through list of all global variables in the script.
|
||||
* Output declarations for those what don't have any init statement for them.
|
||||
* Save the type for those that do have init statements.
|
||||
*/
|
||||
// Scan through list of all global variables in the script.
|
||||
// Output declarations for those what don't have any init statement for them.
|
||||
// Save the type for those that do have init statements.
|
||||
bool first = true;
|
||||
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.
|
||||
* Otherwise, output it as a series of global declarations with init values.
|
||||
*/
|
||||
// If $globalvarinit() has anything bad in it, output it as a function.
|
||||
// Otherwise, output it as a series of global declarations with init values.
|
||||
if(badinit)
|
||||
{
|
||||
MethodDump();
|
||||
|
@ -809,19 +789,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
string indent;
|
||||
|
||||
/*
|
||||
* Event handlers don't have an argument list as such in the original
|
||||
* code. Instead they have a series of assignments from ehargs[] to
|
||||
* local variables. So make those local variables look like they are
|
||||
* an argument list.
|
||||
*/
|
||||
// Event handlers don't have an argument list as such in the original
|
||||
// code. Instead they have a series of assignments from ehargs[] to
|
||||
// local variables. So make those local variables look like they are
|
||||
// an argument list.
|
||||
int i = method.Name.IndexOf(' ');
|
||||
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 eventname = method.Name.Substring(++i);
|
||||
|
||||
|
@ -844,10 +819,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
twout.Write('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* Output event name and argument list.
|
||||
* Remove from locals list so they don't print below.
|
||||
*/
|
||||
// Output event name and argument list.
|
||||
// Remove from locals list so they don't print below.
|
||||
twout.Write('\n' + INDENT + eventname + " (");
|
||||
MethodInfo meth = typeof(IEventHandlers).GetMethod(eventname);
|
||||
i = 0;
|
||||
|
@ -873,35 +846,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
twout.Write(')');
|
||||
|
||||
/*
|
||||
* Indent method body by 4 spaces.
|
||||
*/
|
||||
// Indent method body by 4 spaces.
|
||||
indent = INDENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
* Maybe need to close out previous state.
|
||||
*/
|
||||
// Maybe need to close out previous state.
|
||||
if(laststate != null)
|
||||
{
|
||||
twout.Write("\n}");
|
||||
laststate = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Output blank line and return type (if any).
|
||||
*/
|
||||
// Output blank line and return type (if any).
|
||||
twout.Write("\n\n");
|
||||
if(method.ReturnType != typeof(void))
|
||||
{
|
||||
twout.Write(AbbrType(method.ReturnType) + ' ');
|
||||
}
|
||||
|
||||
/*
|
||||
* Output method name and argument list.
|
||||
*/
|
||||
// Output method name and argument list.
|
||||
int j = method.Name.IndexOf('(');
|
||||
if(j < 0)
|
||||
{
|
||||
|
@ -926,15 +890,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
twout.Write(')');
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't indent method body at all.
|
||||
*/
|
||||
// Don't indent method body at all.
|
||||
indent = "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Output local variable declarations.
|
||||
*/
|
||||
// Output local variable declarations.
|
||||
twout.Write('\n' + indent + '{');
|
||||
bool didOne = false;
|
||||
foreach(OTLocal local in locals.Values)
|
||||
|
@ -945,9 +905,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
if(didOne)
|
||||
twout.Write('\n');
|
||||
|
||||
/*
|
||||
* Output statements.
|
||||
*/
|
||||
// Output statements.
|
||||
if(topBlock.blkstmts.Count == 0)
|
||||
{
|
||||
twout.Write(" }");
|
||||
|
@ -1634,22 +1592,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
{
|
||||
switch(opCode.ToString())
|
||||
{
|
||||
|
||||
/*
|
||||
* We don't handle non-empty stack at branch points.
|
||||
*
|
||||
* So handle this case specially:
|
||||
*
|
||||
* dup
|
||||
* ldc.i4.0
|
||||
* bge.s llAbstemp << we are here
|
||||
* neg
|
||||
* llAbstemp:
|
||||
*
|
||||
* becomes:
|
||||
*
|
||||
* call llAbs
|
||||
*/
|
||||
// We don't handle non-empty stack at branch points.
|
||||
//
|
||||
// So handle this case specially:
|
||||
//
|
||||
// dup
|
||||
// ldc.i4.0
|
||||
// bge.s llAbstemp << we are here
|
||||
// neg
|
||||
// llAbstemp:
|
||||
//
|
||||
// becomes:
|
||||
//
|
||||
// call llAbs
|
||||
case "bge.s":
|
||||
{
|
||||
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)
|
||||
{
|
||||
/*
|
||||
* arg$0.glblVars.iar<type>[<intconst>] is a reference to a global variable
|
||||
* likewise so is __xmrinst.glblVars.iar<type>[<intconst>]
|
||||
*/
|
||||
// arg$0.glblVars.iar<type>[<intconst>] is a reference to a global variable
|
||||
// likewise so is __xmrinst.glblVars.iar<type>[<intconst>]
|
||||
if((array is OTOpndField) && (index is OTOpndInt))
|
||||
{
|
||||
|
||||
/*
|
||||
* arrayfield = (arg$0.glblVars).iar<type>
|
||||
* arrayfieldobj = arg$0.glblVars
|
||||
* iartypename = iar<type>
|
||||
*/
|
||||
// arrayfield = (arg$0.glblVars).iar<type>
|
||||
// arrayfieldobj = arg$0.glblVars
|
||||
// iartypename = iar<type>
|
||||
OTOpndField arrayfield = (OTOpndField)array;
|
||||
OTOpnd arrayfieldobj = arrayfield.obj;
|
||||
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"))
|
||||
{
|
||||
|
||||
/*
|
||||
* arrayfieldobjfield = arg$0.glblVars
|
||||
*/
|
||||
// arrayfieldobjfield = arg$0.glblVars
|
||||
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"))
|
||||
{
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Other array reference.
|
||||
*/
|
||||
// Other array reference.
|
||||
OTOpndArrayElem it = new OTOpndArrayElem();
|
||||
it.array = array;
|
||||
it.index = index;
|
||||
|
@ -3097,17 +3035,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return false;
|
||||
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();
|
||||
it.values = new OTOpnd[listsize];
|
||||
|
||||
/*
|
||||
* There should be exactly listsize statements following that of the form:
|
||||
* dup$<n>[<i>] = bla
|
||||
* If so, save the bla values in the values[] array.
|
||||
*/
|
||||
// There should be exactly listsize statements following that of the form:
|
||||
// dup$<n>[<i>] = bla
|
||||
// If so, save the bla values in the values[] array.
|
||||
LinkedListNode<OTStmt> vallink = link;
|
||||
for(int i = 0; i < listsize; i++)
|
||||
{
|
||||
|
@ -3129,10 +3063,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
it.values[i] = valstore.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* The next statement should have a 'newobj list (dup$<n>)' in it somewhere
|
||||
* that we want to replace with 'it'.
|
||||
*/
|
||||
// The next statement should have a 'newobj list (dup$<n>)' in it somewhere
|
||||
// that we want to replace with 'it'.
|
||||
ConstructorInfo protoctor = typeof(LSL_List).GetConstructor(new Type[] { typeof(object[]) });
|
||||
OTOpnd[] protoargs = new OTOpnd[] { storevar };
|
||||
OTOpnd proto = OTOpndNewobj.Make(protoctor, protoargs);
|
||||
|
@ -3140,9 +3072,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
vallink = vallink.Next;
|
||||
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)
|
||||
{
|
||||
do
|
||||
|
|
Loading…
Reference in New Issue