With a simple for loop I can trigger a potential infinite loop exception in the p5.js web editor
function setup() {
var cnt = 0;
var startTime = new Date().getTime();
for (i = 0; i < 80000; i++) {
console.log(cnt++);
}
var endTime = new Date().getTime();
console.log("done in " + (endTime - startTime) + " milliseconds");
}
Gives me output:
Exiting potential infinite loop at line 5. To disable loop protection: add "// noprotect" to your code done in 501 milliseconds
Which is not surprising as I see that the threshold has been increased to 500ms in p5.js-web-editor issues 174
What is surprising, at least to me, is that if I remove any of the semicolons the potential infinite loop is not detected after 500ms and my loop completes.
For example:
function setup() {
var cnt = 0 // no semicolon here..
var startTime = new Date().getTime();
for (i = 0; i < 80000; i++) {
console.log(cnt++);
}
var endTime = new Date().getTime();
console.log("done in " + (endTime - startTime) + " milliseconds");
}
Gives me output:
79999
done in 1737 milliseconds
My question is, why does removing a semicolon break the p5.js web editor's infinite loop detection?
The p5.js web editor can throw an exception when it detects what might be an infinite loop in a running sketch.
The logic the web editor uses to detect infinite loops is quite simple, if a loop executes for more than 500ms the exception is thrown. This exception may be confusing as the loop may have been almost ready to complete at the moment the exception was thrown with this message:
Exiting potential infinite loop
The word potential is important for understanding the message. This line of code will trigger the exception:
while(true);
but any finite loop that executes for more than 500ms will also trigger the message.
In cases where we know a loop is not infinite and we also know that it may take longer than 500ms to complete we can add a noprotect comment to disable infinite loop protection:
var cnt = 0;
// noprotect
while(cnt < 80000)console.log(cnt++);
This code will log the numbers 0 to 79999. Before adding the noprotect comment be sure and review the code carefully. A small mistake can turn a finite loop into an infinite loop:
var cnt = 0;
// noprotect
while(cnt < 80000)console.log(cnt);
By forgetting to increment cnt
we have created an infinite loop that will not be detected by the p5.js web editor. This loop will run until the browser detects it and prompts the user to stop it or wait.
The last part of the question asks why removing a semicolon at the end of a line changes the loop protect behavior. The simple answer is the editor must add instrumentation in order to provide the detection. Missing semicolons cause the editor to not correctly instrument the code. It is a good practice to end javascript statements with a semicolon. See answers to Do you recommend using semicolons after every statement in javascript
Summary
noprotect
comment for intentional long running loops