aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs112
1 files changed, 53 insertions, 59 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs
index da17a13..e29a515 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
66 { 66 {
67 public static readonly string OBJECT_CODE_MAGIC = "YObjectCode"; 67 public static readonly string OBJECT_CODE_MAGIC = "YObjectCode";
68 // reserve positive version values for original xmr 68 // reserve positive version values for original xmr
69 public static int COMPILED_VERSION_VALUE = -2; // decremented when compiler or object file changes 69 public static int COMPILED_VERSION_VALUE = -3; // decremented when compiler or object file changes
70 70
71 public static readonly int CALL_FRAME_MEMUSE = 64; 71 public static readonly int CALL_FRAME_MEMUSE = 64;
72 public static readonly int STRING_LEN_TO_MEMUSE = 2; 72 public static readonly int STRING_LEN_TO_MEMUSE = 2;
@@ -110,6 +110,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
110 private static FieldInfo rotationSFieldInfo = typeof(LSL_Rotation).GetField("s"); 110 private static FieldInfo rotationSFieldInfo = typeof(LSL_Rotation).GetField("s");
111 private static FieldInfo sdtXMRInstFieldInfo = typeof(XMRSDTypeClObj).GetField("xmrInst"); 111 private static FieldInfo sdtXMRInstFieldInfo = typeof(XMRSDTypeClObj).GetField("xmrInst");
112 private static FieldInfo stackLeftFieldInfo = typeof(XMRInstAbstract).GetField("m_StackLeft"); 112 private static FieldInfo stackLeftFieldInfo = typeof(XMRInstAbstract).GetField("m_StackLeft");
113 private static FieldInfo heapUsedFieldInfo = typeof(XMRInstAbstract).GetField("m_heapUsed");
113 private static FieldInfo vectorXFieldInfo = typeof(LSL_Vector).GetField("x"); 114 private static FieldInfo vectorXFieldInfo = typeof(LSL_Vector).GetField("x");
114 private static FieldInfo vectorYFieldInfo = typeof(LSL_Vector).GetField("y"); 115 private static FieldInfo vectorYFieldInfo = typeof(LSL_Vector).GetField("y");
115 private static FieldInfo vectorZFieldInfo = typeof(LSL_Vector).GetField("z"); 116 private static FieldInfo vectorZFieldInfo = typeof(LSL_Vector).GetField("z");
@@ -133,19 +134,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
133 private static MethodInfo stringConcat2MethodInfo = GetStaticMethod(typeof(String), "Concat", new Type[] { typeof(string), typeof(string) }); 134 private static MethodInfo stringConcat2MethodInfo = GetStaticMethod(typeof(String), "Concat", new Type[] { typeof(string), typeof(string) });
134 private static MethodInfo stringConcat3MethodInfo = GetStaticMethod(typeof(String), "Concat", new Type[] { typeof(string), typeof(string), typeof(string) }); 135 private static MethodInfo stringConcat3MethodInfo = GetStaticMethod(typeof(String), "Concat", new Type[] { typeof(string), typeof(string), typeof(string) });
135 private static MethodInfo stringConcat4MethodInfo = GetStaticMethod(typeof(String), "Concat", new Type[] { typeof(string), typeof(string), typeof(string), typeof(string) }); 136 private static MethodInfo stringConcat4MethodInfo = GetStaticMethod(typeof(String), "Concat", new Type[] { typeof(string), typeof(string), typeof(string), typeof(string) });
136 private static MethodInfo lslRotationNegateMethodInfo = GetStaticMethod(typeof(ScriptCodeGen), 137 private static MethodInfo lslRotationNegateMethodInfo = GetStaticMethod(typeof(ScriptCodeGen), "LSLRotationNegate", new Type[] { typeof(LSL_Rotation) });
137 "LSLRotationNegate", 138 private static MethodInfo lslVectorNegateMethodInfo = GetStaticMethod(typeof(ScriptCodeGen), "LSLVectorNegate", new Type[] { typeof(LSL_Vector) });
138 new Type[] { typeof(LSL_Rotation) });
139 private static MethodInfo lslVectorNegateMethodInfo = GetStaticMethod(typeof(ScriptCodeGen),
140 "LSLVectorNegate",
141 new Type[] { typeof(LSL_Vector) });
142 private static MethodInfo scriptRestoreCatchExceptionUnwrap = GetStaticMethod(typeof(ScriptRestoreCatchException), "Unwrap", new Type[] { typeof(Exception) }); 139 private static MethodInfo scriptRestoreCatchExceptionUnwrap = GetStaticMethod(typeof(ScriptRestoreCatchException), "Unwrap", new Type[] { typeof(Exception) });
143 private static MethodInfo thrownExceptionWrapMethodInfo = GetStaticMethod(typeof(ScriptThrownException), "Wrap", new Type[] { typeof(object) }); 140 private static MethodInfo thrownExceptionWrapMethodInfo = GetStaticMethod(typeof(ScriptThrownException), "Wrap", new Type[] { typeof(object) });
144 141 private static MethodInfo catchExcToStrMethodInfo = GetStaticMethod(typeof(ScriptCodeGen), "CatchExcToStr", new Type[] { typeof(Exception) });
145 private static MethodInfo catchExcToStrMethodInfo = GetStaticMethod(typeof(ScriptCodeGen),
146 "CatchExcToStr",
147 new Type[] { typeof(Exception) });
148
149 private static MethodInfo consoleWriteMethodInfo = GetStaticMethod(typeof(ScriptCodeGen), "ConsoleWrite", new Type[] { typeof(object) }); 142 private static MethodInfo consoleWriteMethodInfo = GetStaticMethod(typeof(ScriptCodeGen), "ConsoleWrite", new Type[] { typeof(object) });
150 public static void ConsoleWrite(object o) 143 public static void ConsoleWrite(object o)
151 { 144 {
@@ -186,6 +179,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
186 179
187 // These get cleared at beginning of every function definition 180 // These get cleared at beginning of every function definition
188 private ScriptMyLocal instancePointer; // holds XMRInstanceSuperType pointer 181 private ScriptMyLocal instancePointer; // holds XMRInstanceSuperType pointer
182 private ScriptMyLocal curHeapSize;
189 private ScriptMyLabel retLabel = null; // where to jump to exit function 183 private ScriptMyLabel retLabel = null; // where to jump to exit function
190 private ScriptMyLocal retValue = null; 184 private ScriptMyLocal retValue = null;
191 private ScriptMyLocal actCallNo = null; // for the active try/catch/finally stack or the big one outside them all 185 private ScriptMyLocal actCallNo = null; // for the active try/catch/finally stack or the big one outside them all
@@ -194,7 +188,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
194 public CallLabel openCallLabel = null; // only one call label can be open at a time 188 public CallLabel openCallLabel = null; // only one call label can be open at a time
195 // - the call label is open from the time of CallPre() until corresponding CallPost() 189 // - the call label is open from the time of CallPre() until corresponding CallPost()
196 // - so no non-trivial pushes/pops etc allowed between a CallPre() and a CallPost() 190 // - so no non-trivial pushes/pops etc allowed between a CallPre() and a CallPost()
197 public List<ScriptMyLocal> HeapLocals = new List<ScriptMyLocal>();
198 private ScriptMyILGen _ilGen; 191 private ScriptMyILGen _ilGen;
199 public ScriptMyILGen ilGen 192 public ScriptMyILGen ilGen
200 { 193 {
@@ -969,9 +962,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
969 string eventname = declFunc.GetSimpleName(); 962 string eventname = declFunc.GetSimpleName();
970 TokenArgDecl argDecl = declFunc.argDecl; 963 TokenArgDecl argDecl = declFunc.argDecl;
971 964
972 HeapLocals.Clear(); 965 // Make sure event handler name is valid and that number and type of arguments is correct.
973
974 // Make sure event handler name is valid and that number and type of arguments is correct.
975 // Apparently some scripts exist with fewer than correct number of args in their declaration 966 // Apparently some scripts exist with fewer than correct number of args in their declaration
976 // so allow for that. It is ok because the handlers are called with the arguments in an 967 // so allow for that. It is ok because the handlers are called with the arguments in an
977 // object[] array, and we just won't access the missing argments in the vector. But the 968 // object[] array, and we just won't access the missing argments in the vector. But the
@@ -1000,8 +991,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1000 ilGen.Emit(declFunc, OpCodes.Castclass, xmrInstSuperType); 991 ilGen.Emit(declFunc, OpCodes.Castclass, xmrInstSuperType);
1001 ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer); 992 ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer);
1002 993
1003 // Output args as variable definitions and initialize each from __sw.ehArgs[]. 994 if (curDeclFunc.fullName != "$globalvarinit()")
1004 // If the script writer goofed, the typecast will complain. 995 {
996 PushXMRInst();
997 ilGen.Emit(curDeclFunc, OpCodes.Ldfld, heapUsedFieldInfo);
998 curHeapSize = ilGen.DeclareLocal(typeof(int), "__curHeap");
999 ilGen.Emit(curDeclFunc, OpCodes.Stloc, curHeapSize);
1000 }
1001
1002 // Output args as variable definitions and initialize each from __sw.ehArgs[].
1003 // If the script writer goofed, the typecast will complain.
1005 int nArgs = argDecl.vars.Length; 1004 int nArgs = argDecl.vars.Length;
1006 for(int i = 0; i < nArgs; i++) 1005 for(int i = 0; i < nArgs; i++)
1007 { 1006 {
@@ -1112,19 +1111,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1112 */ 1111 */
1113 private void GenerateMethodBody(TokenDeclVar declFunc) 1112 private void GenerateMethodBody(TokenDeclVar declFunc)
1114 { 1113 {
1115 HeapLocals.Clear();
1116
1117 // Set up code generator for the function's contents. 1114 // Set up code generator for the function's contents.
1118 _ilGen = declFunc.ilGen; 1115 _ilGen = declFunc.ilGen;
1119 StartFunctionBody(declFunc); 1116 StartFunctionBody(declFunc);
1120 1117
1121 // Create a temp to hold XMRInstanceSuperType version of arg 0. 1118 // Create a temp to hold XMRInstanceSuperType version of arg 0.
1122 // For most functions, arg 0 is already XMRInstanceSuperType. 1119 // For most functions, arg 0 is already XMRInstanceSuperType.
1123 // But for script-defined class instance methods, arg 0 holds 1120 // But for script-defined class instance methods, arg 0 holds
1124 // the XMRSDTypeClObj pointer and so we read the XMRInstAbstract 1121 // the XMRSDTypeClObj pointer and so we read the XMRInstAbstract
1125 // pointer from its XMRSDTypeClObj.xmrInst field then cast it to 1122 // pointer from its XMRSDTypeClObj.xmrInst field then cast it to
1126 // XMRInstanceSuperType. 1123 // XMRInstanceSuperType.
1127 if(IsSDTInstMethod()) 1124 if (IsSDTInstMethod())
1128 { 1125 {
1129 instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst"); 1126 instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst");
1130 ilGen.Emit(declFunc, OpCodes.Ldarg_0); 1127 ilGen.Emit(declFunc, OpCodes.Ldarg_0);
@@ -1133,9 +1130,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1133 ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer); 1130 ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer);
1134 } 1131 }
1135 1132
1136 // Define location of all script-level arguments so script body can access them. 1133 if (curDeclFunc.fullName != "$globalvarinit()")
1137 // The argument indices need to have +1 added to them because XMRInstance or 1134 {
1138 // XMRSDTypeClObj is spliced in at arg 0. 1135 PushXMRInst();
1136 ilGen.Emit(curDeclFunc, OpCodes.Ldfld, heapUsedFieldInfo);
1137 curHeapSize = ilGen.DeclareLocal(typeof(int), "__curHeap");
1138 ilGen.Emit(curDeclFunc, OpCodes.Stloc, curHeapSize);
1139 }
1140
1141 // Define location of all script-level arguments so script body can access them.
1142 // The argument indices need to have +1 added to them because XMRInstance or
1143 // XMRSDTypeClObj is spliced in at arg 0.
1139 TokenArgDecl argDecl = declFunc.argDecl; 1144 TokenArgDecl argDecl = declFunc.argDecl;
1140 int nArgs = argDecl.vars.Length; 1145 int nArgs = argDecl.vars.Length;
1141 for(int i = 0; i < nArgs; i++) 1146 for(int i = 0; i < nArgs; i++)
@@ -1251,7 +1256,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1251 // an infinite loop. If it is, we don't need any CheckRun() 1256 // an infinite loop. If it is, we don't need any CheckRun()
1252 // stuff or any of the frame save/restore stuff. 1257 // stuff or any of the frame save/restore stuff.
1253 bool isTrivial = curDeclFunc.IsFuncTrivial(this); 1258 bool isTrivial = curDeclFunc.IsFuncTrivial(this);
1254 1259 bool doheap = curDeclFunc.fullName != "$globalvarinit()";
1255 // Clear list of all call labels. 1260 // Clear list of all call labels.
1256 // A call label is inserted just before every call that can possibly 1261 // A call label is inserted just before every call that can possibly
1257 // call CheckRun(), including any direct calls to CheckRun(). 1262 // call CheckRun(), including any direct calls to CheckRun().
@@ -1286,7 +1291,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1286 // if (instance.callMode != CallMode_NORMAL) goto __cmRestore; 1291 // if (instance.callMode != CallMode_NORMAL) goto __cmRestore;
1287 actCallNo = null; 1292 actCallNo = null;
1288 ScriptMyLabel cmRestore = null; 1293 ScriptMyLabel cmRestore = null;
1289 if(!isTrivial) 1294
1295 if (!isTrivial)
1290 { 1296 {
1291 actCallNo = ilGen.DeclareLocal(typeof(int), "__mainCallNo"); 1297 actCallNo = ilGen.DeclareLocal(typeof(int), "__mainCallNo");
1292 SetCallNo(curDeclFunc, actCallNo, -1); 1298 SetCallNo(curDeclFunc, actCallNo, -1);
@@ -1378,10 +1384,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1378 // Output code body. 1384 // Output code body.
1379 GenerateStmtBlock(curDeclFunc.body); 1385 GenerateStmtBlock(curDeclFunc.body);
1380 1386
1381 // If code falls through to this point, means they are missing 1387 if (doheap)
1382 // a return statement. And that is legal only if the function 1388 {
1383 // returns 'void'. 1389 PushXMRInst();
1384 if(mightGetHere) 1390 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, curHeapSize);
1391 ilGen.Emit(curDeclFunc, OpCodes.Stfld, heapUsedFieldInfo);
1392 }
1393
1394 // If code falls through to this point, means they are missing
1395 // a return statement. And that is legal only if the function
1396 // returns 'void'.
1397 if (mightGetHere)
1385 { 1398 {
1386 if(!(curDeclFunc.retType is TokenTypeVoid)) 1399 if(!(curDeclFunc.retType is TokenTypeVoid))
1387 { 1400 {
@@ -1414,6 +1427,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1414 } 1427 }
1415 } 1428 }
1416 } 1429 }
1430 if(doheap)
1431 activeTemps.Add(curHeapSize);
1417 1432
1418 // Output code to restore the args, locals and temps then jump to 1433 // Output code to restore the args, locals and temps then jump to
1419 // the call label that we were interrupted at. 1434 // the call label that we were interrupted at.
@@ -1450,35 +1465,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1450 ilGen.EndExceptionBlock(); 1465 ilGen.EndExceptionBlock();
1451 } 1466 }
1452 1467
1453 // Output the 'real' return opcode. 1468 // Output the 'real' return opcode.
1454 // push return value 1469 // push return value
1455 ilGen.MarkLabel(retLabel); 1470 ilGen.MarkLabel(retLabel);
1456 if (!(curDeclFunc.retType is TokenTypeVoid)) 1471 if (!(curDeclFunc.retType is TokenTypeVoid))
1457 { 1472 {
1458 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, retValue); 1473 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, retValue);
1459 } 1474 }
1460 1475
1461 // pseudo free memory usage
1462 foreach (ScriptMyLocal sml in HeapLocals)
1463 {
1464 Type t = sml.type;
1465 if (t == typeof(HeapTrackerList))
1466 {
1467 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, sml);
1468 HeapTrackerList.GenFree(curDeclFunc, ilGen);
1469 }
1470 else if (t == typeof(HeapTrackerString))
1471 {
1472 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, sml);
1473 HeapTrackerString.GenFree(curDeclFunc, ilGen);
1474 }
1475 else if (t == typeof(HeapTrackerObject))
1476 {
1477 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, sml);
1478 HeapTrackerObject.GenFree(curDeclFunc, ilGen);
1479 }
1480 }
1481
1482 ilGen.Emit(curDeclFunc, OpCodes.Ret); 1476 ilGen.Emit(curDeclFunc, OpCodes.Ret);
1483 retLabel = null; 1477 retLabel = null;
1484 retValue = null; 1478 retValue = null;