aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs
diff options
context:
space:
mode:
authorUbitUmarov2018-02-25 00:49:44 +0000
committerUbitUmarov2018-02-25 00:49:44 +0000
commit5ff57f01b7ab8844c192136c7f42882133f7650a (patch)
tree701e9efd2dc5c10e989a12c39beed9d0d4155dcd /OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs
parentY(xmr)engine cosmetics... (diff)
downloadopensim-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.cs736
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;