Skip to content

Commit 7ef5e29

Browse files
committed
interpreter: fix skipped blocks in recursive procedures using "stop this script"
Closes #249 Regression from 20f25f2
1 parent 2d29cdc commit 7ef5e29

File tree

4 files changed

+237
-1
lines changed

4 files changed

+237
-1
lines changed

src/engine/sequencer.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ class Sequencer {
194194
}
195195
// Save the current block ID to notice if we did control flow.
196196
while ((currentBlockId = thread.peekStack())) {
197+
const initialStackSize = thread.stack.length;
197198
let isWarpMode = thread.peekStackFrame().warpMode;
198199
if (isWarpMode && !thread.warpTimer) {
199200
// Initialize warp-mode timer if it hasn't been already.
@@ -239,7 +240,11 @@ class Sequencer {
239240
return;
240241
}
241242
// If no control flow has happened, switch to next block.
242-
if (thread.peekStack() === currentBlockId && !thread.peekStackFrame().waitingReporter) {
243+
if (
244+
thread.stack.length === initialStackSize &&
245+
thread.peekStack() === currentBlockId &&
246+
!thread.peekStackFrame().waitingReporter
247+
) {
243248
thread.goToNextBlock();
244249
}
245250
// If no next block has been found at this point, look on the stack.
40.2 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// TW Snapshot
2+
// Input SHA-256: ce657aa0f3e55d0c2166813c9fa3dd076c3f0c81df2e527f44d0ad31856a448d
3+
4+
// Sprite1 script
5+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
6+
const b0 = runtime.getOpcodeFunction("looks_say");
7+
return function* genXYZ () {
8+
yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, "Z", null);
9+
thread.procedures["Wrun"]();
10+
yield* thread.procedures["Wvalidate"]();
11+
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, "aw", null);
12+
retire(); return;
13+
}; })
14+
15+
// Sprite1 Wrun
16+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
17+
const b0 = stage.variables["EF^k=u-t@S)w60;RP?dZ-list-list"];
18+
const b1 = stage.variables["rQq!wAuU2T9DV9,S[/s."];
19+
return function funXYZ_run () {
20+
b0.value = [];
21+
for (var a0 = 100; a0 >= 0.5; a0--) {
22+
b0.value.push((b1.value[(((b0.value.length + 1) || 0) | 0) - 1] ?? ""));
23+
b0._monitorUpToDate = false;
24+
}
25+
thread.procedures["Wqsort %s %s"](1,b0.value.length);
26+
return "";
27+
}; })
28+
29+
// Sprite1 Wvalidate
30+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
31+
const b0 = stage.variables["7AH{dO^X;}C[{[l~g-7m"];
32+
const b1 = stage.variables["gPJ}c-PZz?Y+_L][iMU_"];
33+
const b2 = stage.variables["EF^k=u-t@S)w60;RP?dZ-list-list"];
34+
const b3 = stage.variables["FsKqV/2kid0gw0J+Jj(c"];
35+
const b4 = runtime.getOpcodeFunction("looks_say");
36+
return function* genXYZ_validate () {
37+
b0.value = 1;
38+
b1.value = 1;
39+
for (var a0 = b2.value.length; a0 >= 0.5; a0--) {
40+
if (!compareEqual(listGet(b2.value, b1.value), listGet(b3.value, b1.value))) {
41+
b0.value = 0;
42+
yield* executeInCompatibilityLayer({"MESSAGE":("fail mismatch at index " + ("" + b1.value)),}, b4, true, false, ",", null);
43+
}
44+
b1.value = ((+b1.value || 0) + 1);
45+
}
46+
if (((+b0.value || 0) === 1)) {
47+
yield* executeInCompatibilityLayer({"MESSAGE":"pass sorted",}, b4, true, false, "aE", null);
48+
}
49+
return "";
50+
}; })
51+
52+
// Sprite1 Wqsort %s %s
53+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
54+
const b0 = stage.variables["EF^k=u-t@S)w60;RP?dZ-pivot-"];
55+
const b1 = stage.variables["EF^k=u-t@S)w60;RP?dZ-list-list"];
56+
const b2 = stage.variables["EF^k=u-t@S)w60;RP?dZ-low-"];
57+
const b3 = stage.variables["EF^k=u-t@S)w60;RP?dZ-high-"];
58+
const b4 = stage.variables["EF^k=u-t@S)w60;RP?dZ-tmp-"];
59+
const b5 = target.variables["JIHtr29*ug5G;5*`f2.K-i-"];
60+
const b6 = target.variables["JIHtr29*ug5G;5*`f2.K-min pos-"];
61+
const b7 = target.variables["JIHtr29*ug5G;5*`f2.K-min-"];
62+
const b8 = target.variables["JIHtr29*ug5G;5*`f2.K-j-"];
63+
return function funXYZ_qsort__ (p0,p1) {
64+
if (compareLessThan(p0, p1)) {
65+
if (!(((+p1 || 0) - (+p0 || 0)) <= 7)) {
66+
b0.value = (b1.value[((((((+p1 || 0) + (+p0 || 0)) || 0) / 2) || 0) | 0) - 1] ?? "");
67+
b2.value = p0;
68+
b3.value = p1;
69+
while (true) {
70+
while (compareLessThan(listGet(b1.value, b2.value), b0.value)) {
71+
b2.value = ((+b2.value || 0) + 1);
72+
}
73+
while (compareGreaterThan(listGet(b1.value, b3.value), b0.value)) {
74+
b3.value = ((+b3.value || 0) + -1);
75+
}
76+
if (compareGreaterThan(b2.value, b3.value)) {
77+
thread.procedures["Wqsort %s %s"](p0,b3.value);
78+
thread.procedures["Wqsort %s %s"](b2.value,p1);
79+
return "";
80+
} else {
81+
b4.value = listGet(b1.value, b2.value);
82+
listReplace(b1, b2.value, listGet(b1.value, b3.value));
83+
listReplace(b1, b3.value, b4.value);
84+
b2.value = ((+b2.value || 0) + 1);
85+
b3.value = ((+b3.value || 0) + -1);
86+
}
87+
}
88+
} else {
89+
b5.value = p0;
90+
for (var a0 = (((+p1 || 0) - (+p0 || 0)) || 0); a0 >= 0.5; a0--) {
91+
b6.value = b5.value;
92+
b7.value = listGet(b1.value, b5.value);
93+
b8.value = ((+b5.value || 0) + 1);
94+
for (var a1 = (((+p1 || 0) - (+b5.value || 0)) || 0); a1 >= 0.5; a1--) {
95+
if (compareLessThan(listGet(b1.value, b8.value), b7.value)) {
96+
b7.value = listGet(b1.value, b8.value);
97+
b6.value = b8.value;
98+
}
99+
b8.value = ((+b8.value || 0) + 1);
100+
}
101+
if (compareEqual(b6.value, b5.value)) {
102+
} else {
103+
b4.value = listGet(b1.value, b5.value);
104+
listReplace(b1, b5.value, b7.value);
105+
listReplace(b1, b6.value, b4.value);
106+
}
107+
b5.value = ((+b5.value || 0) + 1);
108+
}
109+
}
110+
}
111+
return "";
112+
}; })
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// TW Snapshot
2+
// Input SHA-256: ce657aa0f3e55d0c2166813c9fa3dd076c3f0c81df2e527f44d0ad31856a448d
3+
4+
// Sprite1 script
5+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
6+
const b0 = runtime.getOpcodeFunction("looks_say");
7+
return function* genXYZ () {
8+
yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, "Z", null);
9+
yield* thread.procedures["Wrun"]();
10+
yield* thread.procedures["Wvalidate"]();
11+
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, "aw", null);
12+
retire(); return;
13+
}; })
14+
15+
// Sprite1 Wrun
16+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
17+
const b0 = stage.variables["EF^k=u-t@S)w60;RP?dZ-list-list"];
18+
const b1 = stage.variables["rQq!wAuU2T9DV9,S[/s."];
19+
return function* genXYZ_run () {
20+
b0.value = [];
21+
for (var a0 = 100; a0 >= 0.5; a0--) {
22+
b0.value.push((b1.value[(((b0.value.length + 1) || 0) | 0) - 1] ?? ""));
23+
b0._monitorUpToDate = false;
24+
if (isStuck()) yield;
25+
}
26+
yield* thread.procedures["Wqsort %s %s"](1,b0.value.length);
27+
return "";
28+
}; })
29+
30+
// Sprite1 Wvalidate
31+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
32+
const b0 = stage.variables["7AH{dO^X;}C[{[l~g-7m"];
33+
const b1 = stage.variables["gPJ}c-PZz?Y+_L][iMU_"];
34+
const b2 = stage.variables["EF^k=u-t@S)w60;RP?dZ-list-list"];
35+
const b3 = stage.variables["FsKqV/2kid0gw0J+Jj(c"];
36+
const b4 = runtime.getOpcodeFunction("looks_say");
37+
return function* genXYZ_validate () {
38+
b0.value = 1;
39+
b1.value = 1;
40+
for (var a0 = b2.value.length; a0 >= 0.5; a0--) {
41+
if (!compareEqual(listGet(b2.value, b1.value), listGet(b3.value, b1.value))) {
42+
b0.value = 0;
43+
yield* executeInCompatibilityLayer({"MESSAGE":("fail mismatch at index " + ("" + b1.value)),}, b4, true, false, ",", null);
44+
}
45+
b1.value = ((+b1.value || 0) + 1);
46+
if (isStuck()) yield;
47+
}
48+
if (((+b0.value || 0) === 1)) {
49+
yield* executeInCompatibilityLayer({"MESSAGE":"pass sorted",}, b4, true, false, "aE", null);
50+
}
51+
return "";
52+
}; })
53+
54+
// Sprite1 Wqsort %s %s
55+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
56+
const b0 = stage.variables["EF^k=u-t@S)w60;RP?dZ-pivot-"];
57+
const b1 = stage.variables["EF^k=u-t@S)w60;RP?dZ-list-list"];
58+
const b2 = stage.variables["EF^k=u-t@S)w60;RP?dZ-low-"];
59+
const b3 = stage.variables["EF^k=u-t@S)w60;RP?dZ-high-"];
60+
const b4 = stage.variables["EF^k=u-t@S)w60;RP?dZ-tmp-"];
61+
const b5 = target.variables["JIHtr29*ug5G;5*`f2.K-i-"];
62+
const b6 = target.variables["JIHtr29*ug5G;5*`f2.K-min pos-"];
63+
const b7 = target.variables["JIHtr29*ug5G;5*`f2.K-min-"];
64+
const b8 = target.variables["JIHtr29*ug5G;5*`f2.K-j-"];
65+
return function* genXYZ_qsort__ (p0,p1) {
66+
if (compareLessThan(p0, p1)) {
67+
if (!(((+p1 || 0) - (+p0 || 0)) <= 7)) {
68+
b0.value = (b1.value[((((((+p1 || 0) + (+p0 || 0)) || 0) / 2) || 0) | 0) - 1] ?? "");
69+
b2.value = p0;
70+
b3.value = p1;
71+
while (true) {
72+
while (compareLessThan(listGet(b1.value, b2.value), b0.value)) {
73+
b2.value = ((+b2.value || 0) + 1);
74+
if (isStuck()) yield;
75+
}
76+
while (compareGreaterThan(listGet(b1.value, b3.value), b0.value)) {
77+
b3.value = ((+b3.value || 0) + -1);
78+
if (isStuck()) yield;
79+
}
80+
if (compareGreaterThan(b2.value, b3.value)) {
81+
yield* thread.procedures["Wqsort %s %s"](p0,b3.value);
82+
yield* thread.procedures["Wqsort %s %s"](b2.value,p1);
83+
return "";
84+
} else {
85+
b4.value = listGet(b1.value, b2.value);
86+
listReplace(b1, b2.value, listGet(b1.value, b3.value));
87+
listReplace(b1, b3.value, b4.value);
88+
b2.value = ((+b2.value || 0) + 1);
89+
b3.value = ((+b3.value || 0) + -1);
90+
}
91+
if (isStuck()) yield;
92+
}
93+
} else {
94+
b5.value = p0;
95+
for (var a0 = (((+p1 || 0) - (+p0 || 0)) || 0); a0 >= 0.5; a0--) {
96+
b6.value = b5.value;
97+
b7.value = listGet(b1.value, b5.value);
98+
b8.value = ((+b5.value || 0) + 1);
99+
for (var a1 = (((+p1 || 0) - (+b5.value || 0)) || 0); a1 >= 0.5; a1--) {
100+
if (compareLessThan(listGet(b1.value, b8.value), b7.value)) {
101+
b7.value = listGet(b1.value, b8.value);
102+
b6.value = b8.value;
103+
}
104+
b8.value = ((+b8.value || 0) + 1);
105+
if (isStuck()) yield;
106+
}
107+
if (compareEqual(b6.value, b5.value)) {
108+
} else {
109+
b4.value = listGet(b1.value, b5.value);
110+
listReplace(b1, b5.value, b7.value);
111+
listReplace(b1, b6.value, b4.value);
112+
}
113+
b5.value = ((+b5.value || 0) + 1);
114+
if (isStuck()) yield;
115+
}
116+
}
117+
}
118+
return "";
119+
}; })

0 commit comments

Comments
 (0)