diff options
author | UbitUmarov | 2018-02-25 00:49:44 +0000 |
---|---|---|
committer | UbitUmarov | 2018-02-25 00:49:44 +0000 |
commit | 5ff57f01b7ab8844c192136c7f42882133f7650a (patch) | |
tree | 701e9efd2dc5c10e989a12c39beed9d0d4155dcd /OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs | |
parent | Y(xmr)engine cosmetics... (diff) | |
download | opensim-SC-5ff57f01b7ab8844c192136c7f42882133f7650a.zip opensim-SC-5ff57f01b7ab8844c192136c7f42882133f7650a.tar.gz opensim-SC-5ff57f01b7ab8844c192136c7f42882133f7650a.tar.bz2 opensim-SC-5ff57f01b7ab8844c192136c7f42882133f7650a.tar.xz |
Yengine: change filename extentions on scripts state (better delete contents of bin/scriptengines/yengine .. btw bin/scriptdata is not used anymore )
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs | 736 |
1 files changed, 368 insertions, 368 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs index 88cd6c1..75eae53 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs | |||
@@ -511,16 +511,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
511 | } | 511 | } |
512 | public override bool MoveNext() | 512 | public override bool MoveNext() |
513 | { | 513 | { |
514 | // First off, return any targets the instruction can come up with. | 514 | // First off, return any targets the instruction can come up with. |
515 | if(realEnumerator.MoveNext()) | 515 | if(realEnumerator.MoveNext()) |
516 | { | 516 | { |
517 | nn = realEnumerator.Current; | 517 | nn = realEnumerator.Current; |
518 | return true; | 518 | return true; |
519 | } | 519 | } |
520 | 520 | ||
521 | // Then if this instruction is in a try section, say this instruction | 521 | // Then if this instruction is in a try section, say this instruction |
522 | // can potentially branch to the beginning of the corresponding | 522 | // can potentially branch to the beginning of the corresponding |
523 | // catch/finally. | 523 | // catch/finally. |
524 | if((index == 0) && (gn.tryBlock != null)) | 524 | if((index == 0) && (gn.tryBlock != null)) |
525 | { | 525 | { |
526 | index++; | 526 | index++; |
@@ -528,7 +528,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
528 | return true; | 528 | return true; |
529 | } | 529 | } |
530 | 530 | ||
531 | // That's all we can do. | 531 | // That's all we can do. |
532 | nn = null; | 532 | nn = null; |
533 | return false; | 533 | return false; |
534 | } | 534 | } |
@@ -569,16 +569,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
569 | switch(index) | 569 | switch(index) |
570 | { | 570 | { |
571 | case 0: | 571 | case 0: |
572 | { | 572 | { |
573 | index++; | 573 | index++; |
574 | nn = gn.nextLin; | 574 | nn = gn.nextLin; |
575 | return nn != null; | 575 | return nn != null; |
576 | } | 576 | } |
577 | case 1: | 577 | case 1: |
578 | { | 578 | { |
579 | nn = null; | 579 | nn = null; |
580 | return false; | 580 | return false; |
581 | } | 581 | } |
582 | } | 582 | } |
583 | throw new Exception(); | 583 | throw new Exception(); |
584 | } | 584 | } |
@@ -738,49 +738,49 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
738 | switch(index) | 738 | switch(index) |
739 | { | 739 | { |
740 | case 0: | 740 | case 0: |
741 | { | 741 | { |
742 | // start with the fallthru | 742 | // start with the fallthru |
743 | nn = gn.nextLin; | 743 | nn = gn.nextLin; |
744 | index++; | 744 | index++; |
745 | return true; | 745 | return true; |
746 | } | 746 | } |
747 | 747 | ||
748 | case 1: | 748 | case 1: |
749 | { | 749 | { |
750 | // get the first outer catch { } or finally { } | 750 | // get the first outer catch { } or finally { } |
751 | // pretend we last returned beginning of this catch { } | 751 | // pretend we last returned beginning of this catch { } |
752 | // then loop back to get next outer catch { } or finally { } | 752 | // then loop back to get next outer catch { } or finally { } |
753 | nn = gn; | 753 | nn = gn; |
754 | break; | 754 | break; |
755 | } | 755 | } |
756 | 756 | ||
757 | case 2: | 757 | case 2: |
758 | { | 758 | { |
759 | // nn points to a catch { } previously returned | 759 | // nn points to a catch { } previously returned |
760 | // get the corresponding try { } | 760 | // get the corresponding try { } |
761 | GraphNodeBeginExceptionBlock nntry = nn.excBlock; | 761 | GraphNodeBeginExceptionBlock nntry = nn.excBlock; |
762 | 762 | ||
763 | // step out to next outer try { } | 763 | // step out to next outer try { } |
764 | nntry = nntry.excBlock; | 764 | nntry = nntry.excBlock; |
765 | if(nntry == null) | 765 | if(nntry == null) |
766 | break; | 766 | break; |
767 | 767 | ||
768 | // return corresponding catch { } or finally { } | 768 | // return corresponding catch { } or finally { } |
769 | nn = nntry.catchFinallyBlock; | 769 | nn = nntry.catchFinallyBlock; |
770 | 770 | ||
771 | // if it's a finally { } we don't do anything after that | 771 | // if it's a finally { } we don't do anything after that |
772 | if(nn is GraphNodeBeginFinallyBlock) | 772 | if(nn is GraphNodeBeginFinallyBlock) |
773 | index++; | 773 | index++; |
774 | return true; | 774 | return true; |
775 | } | 775 | } |
776 | 776 | ||
777 | case 3: | 777 | case 3: |
778 | { | 778 | { |
779 | // we've returned the fallthru, catches and one finally | 779 | // we've returned the fallthru, catches and one finally |
780 | // so there's nothing more to say | 780 | // so there's nothing more to say |
781 | nn = null; | 781 | nn = null; |
782 | return false; | 782 | return false; |
783 | } | 783 | } |
784 | 784 | ||
785 | default: | 785 | default: |
786 | throw new Exception(); | 786 | throw new Exception(); |
@@ -914,12 +914,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
914 | case FlowControl.Throw: | 914 | case FlowControl.Throw: |
915 | return false; // throw | 915 | return false; // throw |
916 | default: | 916 | default: |
917 | { | 917 | { |
918 | string op = opcode.ToString(); | 918 | string op = opcode.ToString(); |
919 | if(op == "volatile.") | 919 | if(op == "volatile.") |
920 | return true; | 920 | return true; |
921 | throw new Exception("unknown flow control " + opcode.FlowControl + " for " + op); | 921 | throw new Exception("unknown flow control " + opcode.FlowControl + " for " + op); |
922 | } | 922 | } |
923 | } | 923 | } |
924 | } | 924 | } |
925 | 925 | ||
@@ -970,20 +970,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
970 | switch(index) | 970 | switch(index) |
971 | { | 971 | { |
972 | case 0: | 972 | case 0: |
973 | { | ||
974 | if(gn.CanFallThrough()) | ||
973 | { | 975 | { |
974 | if(gn.CanFallThrough()) | 976 | index++; |
975 | { | 977 | nn = gn.nextLin; |
976 | index++; | 978 | return nn != null; |
977 | nn = gn.nextLin; | ||
978 | return nn != null; | ||
979 | } | ||
980 | return false; | ||
981 | } | 979 | } |
980 | return false; | ||
981 | } | ||
982 | case 1: | 982 | case 1: |
983 | { | 983 | { |
984 | nn = null; | 984 | nn = null; |
985 | return false; | 985 | return false; |
986 | } | 986 | } |
987 | } | 987 | } |
988 | throw new Exception(); | 988 | throw new Exception(); |
989 | } | 989 | } |
@@ -1038,33 +1038,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1038 | case "ldc.i4.6": | 1038 | case "ldc.i4.6": |
1039 | case "ldc.i4.7": | 1039 | case "ldc.i4.7": |
1040 | case "ldc.i4.8": | 1040 | case "ldc.i4.8": |
1041 | { | 1041 | { |
1042 | coll.stackDepth.Push(typeof(int)); | 1042 | coll.stackDepth.Push(typeof(int)); |
1043 | break; | 1043 | break; |
1044 | } | 1044 | } |
1045 | case "dup": | 1045 | case "dup": |
1046 | { | 1046 | { |
1047 | Type t = coll.stackDepth.Peek(0); | 1047 | Type t = coll.stackDepth.Peek(0); |
1048 | bool b = coll.stackDepth.PeekBoxed(0); | 1048 | bool b = coll.stackDepth.PeekBoxed(0); |
1049 | coll.stackDepth.Push(t, b); | 1049 | coll.stackDepth.Push(t, b); |
1050 | break; | 1050 | break; |
1051 | } | 1051 | } |
1052 | case "pop": | 1052 | case "pop": |
1053 | { | 1053 | { |
1054 | coll.stackDepth.Pop(1); | 1054 | coll.stackDepth.Pop(1); |
1055 | break; | 1055 | break; |
1056 | } | 1056 | } |
1057 | case "ret": | 1057 | case "ret": |
1058 | { | ||
1059 | int sd = (coll.wrapped.retType != typeof(void)) ? 1 : 0; | ||
1060 | if(coll.stackDepth.Count != sd) | ||
1061 | throw new Exception("bad stack depth"); | ||
1062 | if(sd > 0) | ||
1058 | { | 1063 | { |
1059 | int sd = (coll.wrapped.retType != typeof(void)) ? 1 : 0; | 1064 | coll.stackDepth.Pop(coll.wrapped.retType); |
1060 | if(coll.stackDepth.Count != sd) | ||
1061 | throw new Exception("bad stack depth"); | ||
1062 | if(sd > 0) | ||
1063 | { | ||
1064 | coll.stackDepth.Pop(coll.wrapped.retType); | ||
1065 | } | ||
1066 | break; | ||
1067 | } | 1065 | } |
1066 | break; | ||
1067 | } | ||
1068 | case "add": | 1068 | case "add": |
1069 | case "sub": | 1069 | case "sub": |
1070 | case "mul": | 1070 | case "mul": |
@@ -1084,19 +1084,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1084 | case "mul.ovf.un": | 1084 | case "mul.ovf.un": |
1085 | case "sub.ovf": | 1085 | case "sub.ovf": |
1086 | case "sub.ovf.un": | 1086 | case "sub.ovf.un": |
1087 | { | 1087 | { |
1088 | coll.stackDepth.PopNumVal(); | 1088 | coll.stackDepth.PopNumVal(); |
1089 | Type t = coll.stackDepth.PopNumVal(); | 1089 | Type t = coll.stackDepth.PopNumVal(); |
1090 | coll.stackDepth.Push(t); | 1090 | coll.stackDepth.Push(t); |
1091 | break; | 1091 | break; |
1092 | } | 1092 | } |
1093 | case "neg": | 1093 | case "neg": |
1094 | case "not": | 1094 | case "not": |
1095 | { | 1095 | { |
1096 | Type t = coll.stackDepth.PopNumVal(); | 1096 | Type t = coll.stackDepth.PopNumVal(); |
1097 | coll.stackDepth.Push(t); | 1097 | coll.stackDepth.Push(t); |
1098 | break; | 1098 | break; |
1099 | } | 1099 | } |
1100 | case "conv.i1": | 1100 | case "conv.i1": |
1101 | case "conv.i2": | 1101 | case "conv.i2": |
1102 | case "conv.i4": | 1102 | case "conv.i4": |
@@ -1130,24 +1130,24 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1130 | case "conv.ovf.i": | 1130 | case "conv.ovf.i": |
1131 | case "conv.ovf.u": | 1131 | case "conv.ovf.u": |
1132 | case "conv.u": | 1132 | case "conv.u": |
1133 | { | 1133 | { |
1134 | coll.stackDepth.PopNumVal(); | 1134 | coll.stackDepth.PopNumVal(); |
1135 | coll.stackDepth.Push(ConvToType(opcode)); | 1135 | coll.stackDepth.Push(ConvToType(opcode)); |
1136 | break; | 1136 | break; |
1137 | } | 1137 | } |
1138 | case "throw": | 1138 | case "throw": |
1139 | { | 1139 | { |
1140 | if(coll.stackDepth.Count != 1) | 1140 | if(coll.stackDepth.Count != 1) |
1141 | throw new Exception("bad stack depth " + coll.stackDepth.Count); | 1141 | throw new Exception("bad stack depth " + coll.stackDepth.Count); |
1142 | coll.stackDepth.PopRef(); | 1142 | coll.stackDepth.PopRef(); |
1143 | break; | 1143 | break; |
1144 | } | 1144 | } |
1145 | case "ldlen": | 1145 | case "ldlen": |
1146 | { | 1146 | { |
1147 | coll.stackDepth.Pop(typeof(string)); | 1147 | coll.stackDepth.Pop(typeof(string)); |
1148 | coll.stackDepth.Push(typeof(int)); | 1148 | coll.stackDepth.Push(typeof(int)); |
1149 | break; | 1149 | break; |
1150 | } | 1150 | } |
1151 | case "ldelem.i1": | 1151 | case "ldelem.i1": |
1152 | case "ldelem.u1": | 1152 | case "ldelem.u1": |
1153 | case "ldelem.i2": | 1153 | case "ldelem.i2": |
@@ -1159,13 +1159,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1159 | case "ldelem.r4": | 1159 | case "ldelem.r4": |
1160 | case "ldelem.r8": | 1160 | case "ldelem.r8": |
1161 | case "ldelem.ref": | 1161 | case "ldelem.ref": |
1162 | { | 1162 | { |
1163 | Type t = coll.stackDepth.Peek(1).GetElementType(); | 1163 | Type t = coll.stackDepth.Peek(1).GetElementType(); |
1164 | coll.stackDepth.Pop(typeof(int)); | 1164 | coll.stackDepth.Pop(typeof(int)); |
1165 | coll.stackDepth.Pop(t.MakeArrayType()); | 1165 | coll.stackDepth.Pop(t.MakeArrayType()); |
1166 | coll.stackDepth.Push(t); | 1166 | coll.stackDepth.Push(t); |
1167 | break; | 1167 | break; |
1168 | } | 1168 | } |
1169 | case "stelem.i": | 1169 | case "stelem.i": |
1170 | case "stelem.i1": | 1170 | case "stelem.i1": |
1171 | case "stelem.i2": | 1171 | case "stelem.i2": |
@@ -1174,56 +1174,56 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1174 | case "stelem.r4": | 1174 | case "stelem.r4": |
1175 | case "stelem.r8": | 1175 | case "stelem.r8": |
1176 | case "stelem.ref": | 1176 | case "stelem.ref": |
1177 | { | 1177 | { |
1178 | Type t = coll.stackDepth.Peek(2).GetElementType(); | 1178 | Type t = coll.stackDepth.Peek(2).GetElementType(); |
1179 | coll.stackDepth.Pop(t); | 1179 | coll.stackDepth.Pop(t); |
1180 | coll.stackDepth.Pop(typeof(int)); | 1180 | coll.stackDepth.Pop(typeof(int)); |
1181 | coll.stackDepth.Pop(t.MakeArrayType()); | 1181 | coll.stackDepth.Pop(t.MakeArrayType()); |
1182 | break; | 1182 | break; |
1183 | } | 1183 | } |
1184 | case "endfinally": | 1184 | case "endfinally": |
1185 | case "rethrow": | 1185 | case "rethrow": |
1186 | { | ||
1187 | if(coll.stackDepth.Count != 0) | ||
1188 | throw new Exception("bad stack depth " + coll.stackDepth.Count); | ||
1189 | break; | ||
1190 | } | ||
1191 | case "ceq": | ||
1192 | { | ||
1193 | Type t = coll.stackDepth.Pop(1); | ||
1194 | if(t == null) | ||
1186 | { | 1195 | { |
1187 | if(coll.stackDepth.Count != 0) | 1196 | coll.stackDepth.PopRef(); |
1188 | throw new Exception("bad stack depth " + coll.stackDepth.Count); | ||
1189 | break; | ||
1190 | } | 1197 | } |
1191 | case "ceq": | 1198 | else |
1192 | { | 1199 | { |
1193 | Type t = coll.stackDepth.Pop(1); | 1200 | coll.stackDepth.Pop(t); |
1194 | if(t == null) | ||
1195 | { | ||
1196 | coll.stackDepth.PopRef(); | ||
1197 | } | ||
1198 | else | ||
1199 | { | ||
1200 | coll.stackDepth.Pop(t); | ||
1201 | } | ||
1202 | coll.stackDepth.Push(typeof(int)); | ||
1203 | break; | ||
1204 | } | 1201 | } |
1202 | coll.stackDepth.Push(typeof(int)); | ||
1203 | break; | ||
1204 | } | ||
1205 | case "cgt": | 1205 | case "cgt": |
1206 | case "cgt.un": | 1206 | case "cgt.un": |
1207 | case "clt": | 1207 | case "clt": |
1208 | case "clt.un": | 1208 | case "clt.un": |
1209 | { | 1209 | { |
1210 | coll.stackDepth.PopNumVal(); | 1210 | coll.stackDepth.PopNumVal(); |
1211 | coll.stackDepth.PopNumVal(); | 1211 | coll.stackDepth.PopNumVal(); |
1212 | coll.stackDepth.Push(typeof(int)); | 1212 | coll.stackDepth.Push(typeof(int)); |
1213 | break; | 1213 | break; |
1214 | } | 1214 | } |
1215 | case "ldind.i4": | 1215 | case "ldind.i4": |
1216 | { | 1216 | { |
1217 | coll.stackDepth.Pop(typeof(int).MakeByRefType()); | 1217 | coll.stackDepth.Pop(typeof(int).MakeByRefType()); |
1218 | coll.stackDepth.Push(typeof(int)); | 1218 | coll.stackDepth.Push(typeof(int)); |
1219 | break; | 1219 | break; |
1220 | } | 1220 | } |
1221 | case "stind.i4": | 1221 | case "stind.i4": |
1222 | { | 1222 | { |
1223 | coll.stackDepth.Pop(typeof(int)); | 1223 | coll.stackDepth.Pop(typeof(int)); |
1224 | coll.stackDepth.Pop(typeof(int).MakeByRefType()); | 1224 | coll.stackDepth.Pop(typeof(int).MakeByRefType()); |
1225 | break; | 1225 | break; |
1226 | } | 1226 | } |
1227 | default: | 1227 | default: |
1228 | throw new Exception("unknown opcode " + opcode.ToString()); | 1228 | throw new Exception("unknown opcode " + opcode.ToString()); |
1229 | } | 1229 | } |
@@ -1320,53 +1320,53 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1320 | 1320 | ||
1321 | // to start, return end of our finally { } | 1321 | // to start, return end of our finally { } |
1322 | case 0: | 1322 | case 0: |
1323 | { | 1323 | { |
1324 | GraphNodeBeginExceptionBlock thistry = gn.excBlock; | 1324 | GraphNodeBeginExceptionBlock thistry = gn.excBlock; |
1325 | nn = thistry.endExcBlock; | 1325 | nn = thistry.endExcBlock; |
1326 | if(nn == null) | 1326 | if(nn == null) |
1327 | throw new NullReferenceException("thistry.endExcBlock"); | 1327 | throw new NullReferenceException("thistry.endExcBlock"); |
1328 | index++; | 1328 | index++; |
1329 | return true; | 1329 | return true; |
1330 | } | 1330 | } |
1331 | 1331 | ||
1332 | // return next one of our finally { }'s leave targets | 1332 | // return next one of our finally { }'s leave targets |
1333 | // ie, where any leave instructions in the try { } want | 1333 | // ie, where any leave instructions in the try { } want |
1334 | // the finally { } to go to when it finishes | 1334 | // the finally { } to go to when it finishes |
1335 | case 1: | 1335 | case 1: |
1336 | { | ||
1337 | if(this.leaveTargetEnumerator.MoveNext()) | ||
1336 | { | 1338 | { |
1337 | if(this.leaveTargetEnumerator.MoveNext()) | 1339 | nn = this.leaveTargetEnumerator.Current; |
1338 | { | 1340 | if(nn == null) |
1339 | nn = this.leaveTargetEnumerator.Current; | 1341 | throw new NullReferenceException("this.leaveTargetEnumerator.Current"); |
1340 | if(nn == null) | 1342 | return true; |
1341 | throw new NullReferenceException("this.leaveTargetEnumerator.Current"); | ||
1342 | return true; | ||
1343 | } | ||
1344 | break; | ||
1345 | } | 1343 | } |
1344 | break; | ||
1345 | } | ||
1346 | 1346 | ||
1347 | // return beginning of next outer finally { } | 1347 | // return beginning of next outer finally { } |
1348 | case 2: | 1348 | case 2: |
1349 | { | ||
1350 | GraphNodeBeginExceptionBlock nntry = gn.excBlock; | ||
1351 | while((nntry = nntry.excBlock) != null) | ||
1349 | { | 1352 | { |
1350 | GraphNodeBeginExceptionBlock nntry = gn.excBlock; | 1353 | if(nntry.catchFinallyBlock is GraphNodeBeginFinallyBlock) |
1351 | while((nntry = nntry.excBlock) != null) | ||
1352 | { | 1354 | { |
1353 | if(nntry.catchFinallyBlock is GraphNodeBeginFinallyBlock) | 1355 | nn = nntry.catchFinallyBlock; |
1354 | { | 1356 | if(nn == null) |
1355 | nn = nntry.catchFinallyBlock; | 1357 | throw new NullReferenceException("nntry.catchFinallyBlock"); |
1356 | if(nn == null) | 1358 | index++; |
1357 | throw new NullReferenceException("nntry.catchFinallyBlock"); | 1359 | return true; |
1358 | index++; | ||
1359 | return true; | ||
1360 | } | ||
1361 | } | 1360 | } |
1362 | break; | ||
1363 | } | 1361 | } |
1362 | break; | ||
1363 | } | ||
1364 | 1364 | ||
1365 | // got nothing more | 1365 | // got nothing more |
1366 | case 3: | 1366 | case 3: |
1367 | { | 1367 | { |
1368 | return false; | 1368 | return false; |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | default: | 1371 | default: |
1372 | throw new Exception(); | 1372 | throw new Exception(); |
@@ -1527,61 +1527,61 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1527 | { | 1527 | { |
1528 | case "castclass": | 1528 | case "castclass": |
1529 | case "isinst": | 1529 | case "isinst": |
1530 | { | 1530 | { |
1531 | coll.stackDepth.PopRef(); | 1531 | coll.stackDepth.PopRef(); |
1532 | coll.stackDepth.Push(type, type.IsValueType); | 1532 | coll.stackDepth.Push(type, type.IsValueType); |
1533 | break; | 1533 | break; |
1534 | } | 1534 | } |
1535 | case "box": | 1535 | case "box": |
1536 | { | 1536 | { |
1537 | if(!type.IsValueType) | 1537 | if(!type.IsValueType) |
1538 | throw new Exception("can't box a non-value type"); | 1538 | throw new Exception("can't box a non-value type"); |
1539 | coll.stackDepth.Pop(type); | 1539 | coll.stackDepth.Pop(type); |
1540 | coll.stackDepth.Push(type, true); | 1540 | coll.stackDepth.Push(type, true); |
1541 | break; | 1541 | break; |
1542 | } | 1542 | } |
1543 | case "unbox": | 1543 | case "unbox": |
1544 | case "unbox.any": | 1544 | case "unbox.any": |
1545 | { | 1545 | { |
1546 | if(!type.IsValueType) | 1546 | if(!type.IsValueType) |
1547 | throw new Exception("can't unbox to a non-value type"); | 1547 | throw new Exception("can't unbox to a non-value type"); |
1548 | coll.stackDepth.PopRef(); | 1548 | coll.stackDepth.PopRef(); |
1549 | coll.stackDepth.Push(type); | 1549 | coll.stackDepth.Push(type); |
1550 | break; | 1550 | break; |
1551 | } | 1551 | } |
1552 | case "newarr": | 1552 | case "newarr": |
1553 | { | 1553 | { |
1554 | coll.stackDepth.Pop(typeof(int)); | 1554 | coll.stackDepth.Pop(typeof(int)); |
1555 | coll.stackDepth.Push(type.MakeArrayType()); | 1555 | coll.stackDepth.Push(type.MakeArrayType()); |
1556 | break; | 1556 | break; |
1557 | } | 1557 | } |
1558 | case "sizeof": | 1558 | case "sizeof": |
1559 | { | 1559 | { |
1560 | coll.stackDepth.Pop(1); | 1560 | coll.stackDepth.Pop(1); |
1561 | coll.stackDepth.Push(typeof(int)); | 1561 | coll.stackDepth.Push(typeof(int)); |
1562 | break; | 1562 | break; |
1563 | } | 1563 | } |
1564 | case "ldelem": | 1564 | case "ldelem": |
1565 | { | 1565 | { |
1566 | coll.stackDepth.Pop(typeof(int)); | 1566 | coll.stackDepth.Pop(typeof(int)); |
1567 | coll.stackDepth.Pop(type.MakeArrayType()); | 1567 | coll.stackDepth.Pop(type.MakeArrayType()); |
1568 | coll.stackDepth.Push(type); | 1568 | coll.stackDepth.Push(type); |
1569 | break; | 1569 | break; |
1570 | } | 1570 | } |
1571 | case "ldelema": | 1571 | case "ldelema": |
1572 | { | 1572 | { |
1573 | coll.stackDepth.Pop(typeof(int)); | 1573 | coll.stackDepth.Pop(typeof(int)); |
1574 | coll.stackDepth.Pop(type.MakeArrayType()); | 1574 | coll.stackDepth.Pop(type.MakeArrayType()); |
1575 | coll.stackDepth.Push(type.MakeByRefType()); | 1575 | coll.stackDepth.Push(type.MakeByRefType()); |
1576 | break; | 1576 | break; |
1577 | } | 1577 | } |
1578 | case "stelem": | 1578 | case "stelem": |
1579 | { | 1579 | { |
1580 | coll.stackDepth.Pop(type); | 1580 | coll.stackDepth.Pop(type); |
1581 | coll.stackDepth.Pop(typeof(int)); | 1581 | coll.stackDepth.Pop(typeof(int)); |
1582 | coll.stackDepth.Pop(type.MakeArrayType()); | 1582 | coll.stackDepth.Pop(type.MakeArrayType()); |
1583 | break; | 1583 | break; |
1584 | } | 1584 | } |
1585 | default: | 1585 | default: |
1586 | throw new Exception("unknown opcode " + opcode.ToString()); | 1586 | throw new Exception("unknown opcode " + opcode.ToString()); |
1587 | } | 1587 | } |
@@ -1618,10 +1618,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1618 | case "brtrue.s": | 1618 | case "brtrue.s": |
1619 | case "brfalse": | 1619 | case "brfalse": |
1620 | case "brtrue": | 1620 | case "brtrue": |
1621 | { | 1621 | { |
1622 | coll.stackDepth.Pop(1); | 1622 | coll.stackDepth.Pop(1); |
1623 | break; | 1623 | break; |
1624 | } | 1624 | } |
1625 | case "beq.s": | 1625 | case "beq.s": |
1626 | case "bge.s": | 1626 | case "bge.s": |
1627 | case "bgt.s": | 1627 | case "bgt.s": |
@@ -1642,20 +1642,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1642 | case "bgt.un": | 1642 | case "bgt.un": |
1643 | case "ble.un": | 1643 | case "ble.un": |
1644 | case "blt.un": | 1644 | case "blt.un": |
1645 | { | 1645 | { |
1646 | coll.stackDepth.PopNumVal(); | 1646 | coll.stackDepth.PopNumVal(); |
1647 | coll.stackDepth.PopNumVal(); | 1647 | coll.stackDepth.PopNumVal(); |
1648 | break; | 1648 | break; |
1649 | } | 1649 | } |
1650 | case "br": | 1650 | case "br": |
1651 | case "br.s": | 1651 | case "br.s": |
1652 | break; | 1652 | break; |
1653 | case "leave": | 1653 | case "leave": |
1654 | { | 1654 | { |
1655 | if(coll.stackDepth.Count != 0) | 1655 | if(coll.stackDepth.Count != 0) |
1656 | throw new Exception("bad stack depth " + coll.stackDepth.Count); | 1656 | throw new Exception("bad stack depth " + coll.stackDepth.Count); |
1657 | break; | 1657 | break; |
1658 | } | 1658 | } |
1659 | default: | 1659 | default: |
1660 | throw new Exception("unknown opcode " + opcode.ToString()); | 1660 | throw new Exception("unknown opcode " + opcode.ToString()); |
1661 | } | 1661 | } |
@@ -1699,47 +1699,47 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1699 | switch(gn.opcode.FlowControl) | 1699 | switch(gn.opcode.FlowControl) |
1700 | { | 1700 | { |
1701 | case FlowControl.Branch: | 1701 | case FlowControl.Branch: |
1702 | { | ||
1703 | // unconditional branch just goes to target and nothing else | ||
1704 | switch(index) | ||
1702 | { | 1705 | { |
1703 | // unconditional branch just goes to target and nothing else | 1706 | case 0: |
1704 | switch(index) | 1707 | { |
1708 | nn = gn.myLabel.whereAmI; | ||
1709 | index++; | ||
1710 | return nn != null; | ||
1711 | } | ||
1712 | case 1: | ||
1705 | { | 1713 | { |
1706 | case 0: | 1714 | return false; |
1707 | { | ||
1708 | nn = gn.myLabel.whereAmI; | ||
1709 | index++; | ||
1710 | return nn != null; | ||
1711 | } | ||
1712 | case 1: | ||
1713 | { | ||
1714 | return false; | ||
1715 | } | ||
1716 | } | 1715 | } |
1717 | throw new Exception(); | ||
1718 | } | 1716 | } |
1717 | throw new Exception(); | ||
1718 | } | ||
1719 | case FlowControl.Cond_Branch: | 1719 | case FlowControl.Cond_Branch: |
1720 | { | ||
1721 | // conditional branch goes inline and to target | ||
1722 | switch(index) | ||
1720 | { | 1723 | { |
1721 | // conditional branch goes inline and to target | 1724 | case 0: |
1722 | switch(index) | ||
1723 | { | 1725 | { |
1724 | case 0: | 1726 | nn = gn.nextLin; |
1725 | { | 1727 | index++; |
1726 | nn = gn.nextLin; | 1728 | return true; |
1727 | index++; | 1729 | } |
1728 | return true; | 1730 | case 1: |
1729 | } | 1731 | { |
1730 | case 1: | 1732 | nn = gn.myLabel.whereAmI; |
1731 | { | 1733 | index++; |
1732 | nn = gn.myLabel.whereAmI; | 1734 | return nn != null; |
1733 | index++; | 1735 | } |
1734 | return nn != null; | 1736 | case 2: |
1735 | } | 1737 | { |
1736 | case 2: | 1738 | return false; |
1737 | { | ||
1738 | return false; | ||
1739 | } | ||
1740 | } | 1739 | } |
1741 | throw new Exception(); | ||
1742 | } | 1740 | } |
1741 | throw new Exception(); | ||
1742 | } | ||
1743 | default: | 1743 | default: |
1744 | throw new Exception("unknown flow control " + gn.opcode.FlowControl.ToString() + | 1744 | throw new Exception("unknown flow control " + gn.opcode.FlowControl.ToString() + |
1745 | " of " + gn.opcode.ToString()); | 1745 | " of " + gn.opcode.ToString()); |
@@ -1816,10 +1816,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1816 | switch(opcode.ToString()) | 1816 | switch(opcode.ToString()) |
1817 | { | 1817 | { |
1818 | case "switch": | 1818 | case "switch": |
1819 | { | 1819 | { |
1820 | coll.stackDepth.Pop(typeof(int)); | 1820 | coll.stackDepth.Pop(typeof(int)); |
1821 | break; | 1821 | break; |
1822 | } | 1822 | } |
1823 | default: | 1823 | default: |
1824 | throw new Exception("unknown opcode " + opcode.ToString()); | 1824 | throw new Exception("unknown opcode " + opcode.ToString()); |
1825 | } | 1825 | } |
@@ -1869,7 +1869,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1869 | } | 1869 | } |
1870 | public override bool MoveNext() | 1870 | public override bool MoveNext() |
1871 | { | 1871 | { |
1872 | // Return next from list of switch case labels. | 1872 | // Return next from list of switch case labels. |
1873 | while(index < gn.myLabels.Length) | 1873 | while(index < gn.myLabels.Length) |
1874 | { | 1874 | { |
1875 | nn = gn.myLabels[index++].whereAmI; | 1875 | nn = gn.myLabels[index++].whereAmI; |
@@ -1877,7 +1877,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1877 | return true; | 1877 | return true; |
1878 | } | 1878 | } |
1879 | 1879 | ||
1880 | // If all ran out, the switch instruction falls through. | 1880 | // If all ran out, the switch instruction falls through. |
1881 | if(index == gn.myLabels.Length) | 1881 | if(index == gn.myLabels.Length) |
1882 | { | 1882 | { |
1883 | index++; | 1883 | index++; |
@@ -1885,7 +1885,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1885 | return true; | 1885 | return true; |
1886 | } | 1886 | } |
1887 | 1887 | ||
1888 | // Even ran out of that, say there's nothing more. | 1888 | // Even ran out of that, say there's nothing more. |
1889 | nn = null; | 1889 | nn = null; |
1890 | return false; | 1890 | return false; |
1891 | } | 1891 | } |
@@ -1913,17 +1913,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1913 | switch(opcode.ToString()) | 1913 | switch(opcode.ToString()) |
1914 | { | 1914 | { |
1915 | case "call": | 1915 | case "call": |
1916 | { | 1916 | { |
1917 | 1917 | ||
1918 | // calls have Varpop so pop the number of arguments | 1918 | // calls have Varpop so pop the number of arguments |
1919 | // they are all static so there is no separate 'this' parameter | 1919 | // they are all static so there is no separate 'this' parameter |
1920 | coll.stackDepth.Pop(this.method.argTypes); | 1920 | coll.stackDepth.Pop(this.method.argTypes); |
1921 | 1921 | ||
1922 | // calls are also Varpush so they push a return value iff non-void | 1922 | // calls are also Varpush so they push a return value iff non-void |
1923 | if(this.method.retType != typeof(void)) | 1923 | if(this.method.retType != typeof(void)) |
1924 | coll.stackDepth.Push(this.method.retType); | 1924 | coll.stackDepth.Push(this.method.retType); |
1925 | break; | 1925 | break; |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | default: | 1928 | default: |
1929 | throw new Exception("unknown opcode " + opcode.ToString()); | 1929 | throw new Exception("unknown opcode " + opcode.ToString()); |
@@ -1959,21 +1959,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1959 | { | 1959 | { |
1960 | case "call": | 1960 | case "call": |
1961 | case "callvirt": | 1961 | case "callvirt": |
1962 | { | 1962 | { |
1963 | |||
1964 | // calls have Varpop so pop the number of arguments | ||
1965 | coll.stackDepth.Pop(this.method.GetParameters()); | ||
1966 | if((this.method.CallingConvention & CallingConventions.HasThis) != 0) | ||
1967 | { | ||
1968 | coll.stackDepth.Pop(method.DeclaringType); | ||
1969 | } | ||
1970 | 1963 | ||
1971 | // calls are also Varpush so they push a return value iff non-void | 1964 | // calls have Varpop so pop the number of arguments |
1972 | if(this.method.ReturnType != typeof(void)) | 1965 | coll.stackDepth.Pop(this.method.GetParameters()); |
1973 | coll.stackDepth.Push(this.method.ReturnType); | 1966 | if((this.method.CallingConvention & CallingConventions.HasThis) != 0) |
1974 | break; | 1967 | { |
1968 | coll.stackDepth.Pop(method.DeclaringType); | ||
1975 | } | 1969 | } |
1976 | 1970 | ||
1971 | // calls are also Varpush so they push a return value iff non-void | ||
1972 | if(this.method.ReturnType != typeof(void)) | ||
1973 | coll.stackDepth.Push(this.method.ReturnType); | ||
1974 | break; | ||
1975 | } | ||
1976 | |||
1977 | default: | 1977 | default: |
1978 | throw new Exception("unknown opcode " + opcode.ToString()); | 1978 | throw new Exception("unknown opcode " + opcode.ToString()); |
1979 | } | 1979 | } |
@@ -2007,11 +2007,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2007 | switch(opcode.ToString()) | 2007 | switch(opcode.ToString()) |
2008 | { | 2008 | { |
2009 | case "newobj": | 2009 | case "newobj": |
2010 | { | 2010 | { |
2011 | coll.stackDepth.Pop(ctor.GetParameters()); | 2011 | coll.stackDepth.Pop(ctor.GetParameters()); |
2012 | coll.stackDepth.Push(ctor.DeclaringType); | 2012 | coll.stackDepth.Push(ctor.DeclaringType); |
2013 | break; | 2013 | break; |
2014 | } | 2014 | } |
2015 | 2015 | ||
2016 | default: | 2016 | default: |
2017 | throw new Exception("unknown opcode " + opcode.ToString()); | 2017 | throw new Exception("unknown opcode " + opcode.ToString()); |
@@ -2515,8 +2515,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2515 | if(curExcBlock != null) | 2515 | if(curExcBlock != null) |
2516 | throw new Exception("exception block still open"); | 2516 | throw new Exception("exception block still open"); |
2517 | 2517 | ||
2518 | // If an instruction says it doesn't fall through, remove all instructions to | 2518 | // If an instruction says it doesn't fall through, remove all instructions to |
2519 | // the end of the block. | 2519 | // the end of the block. |
2520 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2520 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2521 | { | 2521 | { |
2522 | if(!gn.CanFallThrough()) | 2522 | if(!gn.CanFallThrough()) |
@@ -2533,10 +2533,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2533 | } | 2533 | } |
2534 | } | 2534 | } |
2535 | 2535 | ||
2536 | // Scan for OpCodes.Leave instructions. | 2536 | // Scan for OpCodes.Leave instructions. |
2537 | // For each found, its target for flow analysis purposes is the beginning of the corresponding | 2537 | // For each found, its target for flow analysis purposes is the beginning of the corresponding |
2538 | // finally block. And the end of the finally block gets a conditional branch target of the | 2538 | // finally block. And the end of the finally block gets a conditional branch target of the |
2539 | // leave instruction's target. A leave instruction can unwind zero or more finally blocks. | 2539 | // leave instruction's target. A leave instruction can unwind zero or more finally blocks. |
2540 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2540 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2541 | { | 2541 | { |
2542 | if(gn is GraphNodeEmitLabelLeave) | 2542 | if(gn is GraphNodeEmitLabelLeave) |
@@ -2546,10 +2546,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2546 | GraphNodeBeginExceptionBlock leaveTargetsTryBlock = // try block directly enclosing leave target | 2546 | GraphNodeBeginExceptionBlock leaveTargetsTryBlock = // try block directly enclosing leave target |
2547 | (leaveTarget == null) ? null : leaveTarget.tryBlock; // ...it must not be unwound | 2547 | (leaveTarget == null) ? null : leaveTarget.tryBlock; // ...it must not be unwound |
2548 | 2548 | ||
2549 | // Step through try { }s from the leave instruction towards its target looking for try { }s with finally { }s. | 2549 | // Step through try { }s from the leave instruction towards its target looking for try { }s with finally { }s. |
2550 | // The leave instruction unconditionally branches to the beginning of the innermost one found. | 2550 | // The leave instruction unconditionally branches to the beginning of the innermost one found. |
2551 | // The end of the last one found conditionally branches to the leave instruction's target. | 2551 | // The end of the last one found conditionally branches to the leave instruction's target. |
2552 | // If none found, the leave is a simple unconditional branch to its target. | 2552 | // If none found, the leave is a simple unconditional branch to its target. |
2553 | GraphNodeBeginFinallyBlock innerFinallyBlock = null; | 2553 | GraphNodeBeginFinallyBlock innerFinallyBlock = null; |
2554 | for(GraphNodeBeginExceptionBlock tryBlock = leaveInstr.tryBlock; | 2554 | for(GraphNodeBeginExceptionBlock tryBlock = leaveInstr.tryBlock; |
2555 | tryBlock != leaveTargetsTryBlock; | 2555 | tryBlock != leaveTargetsTryBlock; |
@@ -2568,8 +2568,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2568 | } | 2568 | } |
2569 | } | 2569 | } |
2570 | 2570 | ||
2571 | // The end of the outermost finally being unwound can conditionally jump to the target of the leave instruction. | 2571 | // The end of the outermost finally being unwound can conditionally jump to the target of the leave instruction. |
2572 | // In the case of no finallies being unwound, the leave is just a simple unconditional branch. | 2572 | // In the case of no finallies being unwound, the leave is just a simple unconditional branch. |
2573 | if(innerFinallyBlock == null) | 2573 | if(innerFinallyBlock == null) |
2574 | { | 2574 | { |
2575 | leaveInstr.unwindTo = leaveTarget; | 2575 | leaveInstr.unwindTo = leaveTarget; |
@@ -2581,8 +2581,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2581 | } | 2581 | } |
2582 | } | 2582 | } |
2583 | 2583 | ||
2584 | // See which variables a particular block reads before writing. | 2584 | // See which variables a particular block reads before writing. |
2585 | // This just considers the block itself and nothing that it branches to or fallsthru to. | 2585 | // This just considers the block itself and nothing that it branches to or fallsthru to. |
2586 | GraphNodeBlock currentBlock = null; | 2586 | GraphNodeBlock currentBlock = null; |
2587 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2587 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2588 | { | 2588 | { |
@@ -2604,11 +2604,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2604 | } | 2604 | } |
2605 | } | 2605 | } |
2606 | 2606 | ||
2607 | // For every block we branch to, add that blocks readables to our list of readables, | 2607 | // For every block we branch to, add that blocks readables to our list of readables, |
2608 | // because we need to have those values valid on entry to our block. But if we write the | 2608 | // because we need to have those values valid on entry to our block. But if we write the |
2609 | // variable before we can possibly branch to that block, then we don't need to have it valid | 2609 | // variable before we can possibly branch to that block, then we don't need to have it valid |
2610 | // on entry to our block. So basically it looks like the branch instruction is reading | 2610 | // on entry to our block. So basically it looks like the branch instruction is reading |
2611 | // everything required by any blocks it can branch to. | 2611 | // everything required by any blocks it can branch to. |
2612 | do | 2612 | do |
2613 | { | 2613 | { |
2614 | this.resolvedSomething = false; | 2614 | this.resolvedSomething = false; |
@@ -2616,13 +2616,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2616 | this.ResolveBlock((GraphNodeBlock)firstLin); | 2616 | this.ResolveBlock((GraphNodeBlock)firstLin); |
2617 | } while(this.resolvedSomething); | 2617 | } while(this.resolvedSomething); |
2618 | 2618 | ||
2619 | // Repeat the cutting loops as long as we keep finding stuff. | 2619 | // Repeat the cutting loops as long as we keep finding stuff. |
2620 | bool didSomething; | 2620 | bool didSomething; |
2621 | do | 2621 | do |
2622 | { | 2622 | { |
2623 | didSomething = false; | 2623 | didSomething = false; |
2624 | 2624 | ||
2625 | // Strip out ldc.i4.1/xor/ldc.i4.1/xor | 2625 | // Strip out ldc.i4.1/xor/ldc.i4.1/xor |
2626 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2626 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2627 | { | 2627 | { |
2628 | if(!(gn is GraphNodeEmit)) | 2628 | if(!(gn is GraphNodeEmit)) |
@@ -2650,7 +2650,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2650 | didSomething = true; | 2650 | didSomething = true; |
2651 | } | 2651 | } |
2652 | 2652 | ||
2653 | // Replace c{cond}/ldc.i4.1/xor/br{false,true} -> c{cond}/br{true,false} | 2653 | // Replace c{cond}/ldc.i4.1/xor/br{false,true} -> c{cond}/br{true,false} |
2654 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2654 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2655 | { | 2655 | { |
2656 | if(!(gn is GraphNodeEmit)) | 2656 | if(!(gn is GraphNodeEmit)) |
@@ -2681,7 +2681,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2681 | didSomething = true; | 2681 | didSomething = true; |
2682 | } | 2682 | } |
2683 | 2683 | ||
2684 | // Replace c{cond}/br{false,true} -> b{!,}{cond} | 2684 | // Replace c{cond}/br{false,true} -> b{!,}{cond} |
2685 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2685 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2686 | { | 2686 | { |
2687 | if(!(gn is GraphNodeEmit)) | 2687 | if(!(gn is GraphNodeEmit)) |
@@ -2714,7 +2714,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2714 | didSomething = true; | 2714 | didSomething = true; |
2715 | } | 2715 | } |
2716 | 2716 | ||
2717 | // Replace ld{c.i4.0,null}/br{ne.un,eq} -> br{true,false} | 2717 | // Replace ld{c.i4.0,null}/br{ne.un,eq} -> br{true,false} |
2718 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2718 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2719 | { | 2719 | { |
2720 | if(!(gn is GraphNodeEmit)) | 2720 | if(!(gn is GraphNodeEmit)) |
@@ -2733,15 +2733,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2733 | didSomething = true; | 2733 | didSomething = true; |
2734 | } | 2734 | } |
2735 | 2735 | ||
2736 | // Replace: | 2736 | // Replace: |
2737 | // ldloc v1 | 2737 | // ldloc v1 |
2738 | // stloc v2 | 2738 | // stloc v2 |
2739 | // ld<anything> except ld<anything> v2 | 2739 | // ld<anything> except ld<anything> v2 |
2740 | // ldloc v2 | 2740 | // ldloc v2 |
2741 | // ...v2 unreferenced hereafter | 2741 | // ...v2 unreferenced hereafter |
2742 | // With: | 2742 | // With: |
2743 | // ld<anything> except ld<anything> v2 | 2743 | // ld<anything> except ld<anything> v2 |
2744 | // ldloc v1 | 2744 | // ldloc v1 |
2745 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2745 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2746 | { | 2746 | { |
2747 | 2747 | ||
@@ -2797,9 +2797,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2797 | didSomething = true; | 2797 | didSomething = true; |
2798 | } | 2798 | } |
2799 | 2799 | ||
2800 | // Remove all the stloc/ldloc that are back-to-back without the local | 2800 | // Remove all the stloc/ldloc that are back-to-back without the local |
2801 | // being needed afterwards. If it is needed afterwards, replace the | 2801 | // being needed afterwards. If it is needed afterwards, replace the |
2802 | // stloc/ldloc with dup/stloc. | 2802 | // stloc/ldloc with dup/stloc. |
2803 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2803 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2804 | { | 2804 | { |
2805 | if((gn is GraphNodeEmitLocal) && | 2805 | if((gn is GraphNodeEmitLocal) && |
@@ -2833,8 +2833,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2833 | } | 2833 | } |
2834 | } | 2834 | } |
2835 | 2835 | ||
2836 | // Remove all write-only local variables, ie, those with no ldloc[a] references. | 2836 | // Remove all write-only local variables, ie, those with no ldloc[a] references. |
2837 | // Replace any stloc instructions with pops. | 2837 | // Replace any stloc instructions with pops. |
2838 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2838 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2839 | { | 2839 | { |
2840 | ScriptMyLocal rdlcl = gn.ReadsLocal(); | 2840 | ScriptMyLocal rdlcl = gn.ReadsLocal(); |
@@ -2860,7 +2860,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2860 | } | 2860 | } |
2861 | } | 2861 | } |
2862 | 2862 | ||
2863 | // Remove any Ld<const>/Dup,Pop. | 2863 | // Remove any Ld<const>/Dup,Pop. |
2864 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) | 2864 | for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) |
2865 | { | 2865 | { |
2866 | if((gn is GraphNodeEmit) && | 2866 | if((gn is GraphNodeEmit) && |
@@ -2879,7 +2879,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2879 | } | 2879 | } |
2880 | } while(didSomething); | 2880 | } while(didSomething); |
2881 | 2881 | ||
2882 | // Dump out the results. | 2882 | // Dump out the results. |
2883 | if(DEBUG) | 2883 | if(DEBUG) |
2884 | { | 2884 | { |
2885 | Console.WriteLine(""); | 2885 | Console.WriteLine(""); |
@@ -2938,39 +2938,39 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2938 | if(currentBlock.hasBeenResolved == this.resolveSequence) | 2938 | if(currentBlock.hasBeenResolved == this.resolveSequence) |
2939 | return; | 2939 | return; |
2940 | 2940 | ||
2941 | // So we don't recurse forever on a backward branch. | 2941 | // So we don't recurse forever on a backward branch. |
2942 | currentBlock.hasBeenResolved = this.resolveSequence; | 2942 | currentBlock.hasBeenResolved = this.resolveSequence; |
2943 | 2943 | ||
2944 | // Assume we haven't written any locals yet. | 2944 | // Assume we haven't written any locals yet. |
2945 | List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>(); | 2945 | List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>(); |
2946 | 2946 | ||
2947 | // Scan through the instructions in this block. | 2947 | // Scan through the instructions in this block. |
2948 | for(GraphNode gn = currentBlock; gn != null;) | 2948 | for(GraphNode gn = currentBlock; gn != null;) |
2949 | { | 2949 | { |
2950 | 2950 | ||
2951 | // See if the instruction writes a local we don't know about yet. | 2951 | // See if the instruction writes a local we don't know about yet. |
2952 | ScriptMyLocal wrlcl = gn.WritesLocal(); | 2952 | ScriptMyLocal wrlcl = gn.WritesLocal(); |
2953 | if((wrlcl != null) && !localsWrittenSoFar.Contains(wrlcl)) | 2953 | if((wrlcl != null) && !localsWrittenSoFar.Contains(wrlcl)) |
2954 | { | 2954 | { |
2955 | localsWrittenSoFar.Add(wrlcl); | 2955 | localsWrittenSoFar.Add(wrlcl); |
2956 | } | 2956 | } |
2957 | 2957 | ||
2958 | // Scan through all the possible next instructions after this. | 2958 | // Scan through all the possible next instructions after this. |
2959 | // Note that if we are in the first part of a try/catch/finally block, | 2959 | // Note that if we are in the first part of a try/catch/finally block, |
2960 | // every instruction conditionally branches to the beginning of the | 2960 | // every instruction conditionally branches to the beginning of the |
2961 | // second part (the catch/finally block). | 2961 | // second part (the catch/finally block). |
2962 | GraphNode nextFallthruNode = null; | 2962 | GraphNode nextFallthruNode = null; |
2963 | foreach(GraphNode nn in gn.NextNodes) | 2963 | foreach(GraphNode nn in gn.NextNodes) |
2964 | { | 2964 | { |
2965 | if(nn is GraphNodeBlock) | 2965 | if(nn is GraphNodeBlock) |
2966 | { | 2966 | { |
2967 | // Start of a block, go through all locals needed by that block on entry. | 2967 | // Start of a block, go through all locals needed by that block on entry. |
2968 | GraphNodeBlock nextBlock = (GraphNodeBlock)nn; | 2968 | GraphNodeBlock nextBlock = (GraphNodeBlock)nn; |
2969 | ResolveBlock(nextBlock); | 2969 | ResolveBlock(nextBlock); |
2970 | foreach(ScriptMyLocal readByNextBlock in nextBlock.localsReadBeforeWritten) | 2970 | foreach(ScriptMyLocal readByNextBlock in nextBlock.localsReadBeforeWritten) |
2971 | { | 2971 | { |
2972 | // If this block hasn't written it by now and this block doesn't already | 2972 | // If this block hasn't written it by now and this block doesn't already |
2973 | // require it on entry, say this block requires it on entry. | 2973 | // require it on entry, say this block requires it on entry. |
2974 | if(!localsWrittenSoFar.Contains(readByNextBlock) && | 2974 | if(!localsWrittenSoFar.Contains(readByNextBlock) && |
2975 | !currentBlock.localsReadBeforeWritten.Contains(readByNextBlock)) | 2975 | !currentBlock.localsReadBeforeWritten.Contains(readByNextBlock)) |
2976 | { | 2976 | { |
@@ -2981,14 +2981,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
2981 | } | 2981 | } |
2982 | else | 2982 | else |
2983 | { | 2983 | { |
2984 | // Not start of a block, should be normal fallthru instruction. | 2984 | // Not start of a block, should be normal fallthru instruction. |
2985 | if(nextFallthruNode != null) | 2985 | if(nextFallthruNode != null) |
2986 | throw new Exception("more than one fallthru from " + gn.ToString()); | 2986 | throw new Exception("more than one fallthru from " + gn.ToString()); |
2987 | nextFallthruNode = nn; | 2987 | nextFallthruNode = nn; |
2988 | } | 2988 | } |
2989 | } | 2989 | } |
2990 | 2990 | ||
2991 | // Process next instruction if it isn't the start of a block. | 2991 | // Process next instruction if it isn't the start of a block. |
2992 | if(nextFallthruNode == gn) | 2992 | if(nextFallthruNode == gn) |
2993 | throw new Exception("can't fallthru to self"); | 2993 | throw new Exception("can't fallthru to self"); |
2994 | gn = nextFallthruNode; | 2994 | gn = nextFallthruNode; |