24
24
import rs .ac .bg .etf .pp1 .ast .DesignatorStatement ;
25
25
import rs .ac .bg .etf .pp1 .ast .DivideOp ;
26
26
import rs .ac .bg .etf .pp1 .ast .DoWhileDummyConditionEnd ;
27
+ import rs .ac .bg .etf .pp1 .ast .DoWhileDummyConditionStart ;
27
28
import rs .ac .bg .etf .pp1 .ast .DoWhileDummyStart ;
28
29
import rs .ac .bg .etf .pp1 .ast .EqualOp ;
29
30
import rs .ac .bg .etf .pp1 .ast .ExprListAddOpTerm ;
@@ -982,9 +983,15 @@ public void visit(MulOpFactorList mulOpFactorList) {
982
983
// do-while start instruction (for the purpose of returning back to the beginning of the do-while
983
984
private Stack <Integer > startDoWhileBlockAddressForPatchingStack = new Stack <Integer >();
984
985
985
- // the last instruction in the "then" block is unconditionally jump which will skip whole else part
986
+ // break in do-while will immediately stop its execution and jump to the very first instruction after whole do-while statement
987
+ // this will save addresses for patch when this address is found
986
988
private Stack <List <Integer >> endDoWhileBlockAddressPatchingFromBreakStatementStack = new Stack <List <Integer >>();
987
989
990
+ // continue in do-while will immediately jump to the condition check (very first instruction of the condition check)
991
+ // this will save addresses for patch when this address is found
992
+ private Stack <List <Integer >> startDoWhileConditionBlockAddressPatchingFromContinueStatementStack = new Stack <List <Integer >>();
993
+
994
+
988
995
@ Override
989
996
public void visit (DoWhileDummyStart DoWhileDummyStart ) {
990
997
// open new do-while scope by pushing new list of addresses for patching on stack
@@ -993,7 +1000,22 @@ public void visit(DoWhileDummyStart DoWhileDummyStart) {
993
1000
994
1001
// add "do" address
995
1002
startDoWhileBlockAddressForPatchingStack .push (Code .pc );
1003
+
996
1004
endDoWhileBlockAddressPatchingFromBreakStatementStack .push (new ArrayList <Integer >());
1005
+ startDoWhileConditionBlockAddressPatchingFromContinueStatementStack .push (new ArrayList <Integer >());
1006
+
1007
+ }
1008
+
1009
+ @ Override
1010
+ public void visit (DoWhileDummyConditionStart DoWhileDummyConditionStart ) {
1011
+
1012
+ // fix all jumps from continue to the conditions check
1013
+
1014
+ for (int placeForPatch : startDoWhileConditionBlockAddressPatchingFromContinueStatementStack .peek ()) {
1015
+ Code .fixup (placeForPatch );
1016
+ }
1017
+
1018
+ startDoWhileConditionBlockAddressPatchingFromContinueStatementStack .peek ().clear (); // all addresses has been patched so nothing should left
997
1019
998
1020
999
1021
}
@@ -1185,6 +1207,7 @@ public void visit(StatementDoWhile StatementDoWhile) {
1185
1207
destinationAddressPatchingFromORConditionBlockStack .pop ();
1186
1208
startDoWhileBlockAddressForPatchingStack .pop ();
1187
1209
endDoWhileBlockAddressPatchingFromBreakStatementStack .pop ();
1210
+ startDoWhileConditionBlockAddressPatchingFromContinueStatementStack .pop ();
1188
1211
}
1189
1212
1190
1213
@@ -1205,10 +1228,11 @@ public void visit(StatementBreak StatementBreak) {
1205
1228
@ Override
1206
1229
public void visit (StatementContinue StatementContinue ) {
1207
1230
1208
- // continue represents unconditionally jump to the first instruction in the (deepest) do-while statement
1209
-
1210
- Code .putJump (this .startDoWhileBlockAddressForPatchingStack .peek ());
1231
+ // continue represents unconditionally jump to the first instruction of the condition in the (deepest) do-while statement
1211
1232
1233
+ Code .putJump (0 );
1234
+ startDoWhileConditionBlockAddressPatchingFromContinueStatementStack .peek ().add (Code .pc - 2 ); // saved address for patching
1235
+
1212
1236
}
1213
1237
}
1214
1238
0 commit comments