I have a .js file that creates an object in the global namesspace.
I load that js file, and then I call methods of that object like:
auto root = engine->getRootObject();
auto child = root.getChild (juce::Identifier (obj));
child.invokeMethod (func, vargs, &err);
This works for a while and then starts failing with interrupted.
Turns out it fails if I haven’t called JavascriptEngine::evaluate recently, then resetTimeout doesn’t get called to update max execution time.
I’m not sure how to solve this as JSObject doesn’t have a pointer to the JavascriptEngine. Seems like the timeout should be handled in the quickjs implementation, not the outer juce engine class.
Code to reproduce:
#include <JuceHeader.h>
juce::String code = R"(
var ignore = 0;
function MyObj() {
this.i = 0;
this.func = function() {
// we need to do a bunch of stuff here to make sure interupt handler runs
for (var i = 1; i < 10000; i++)
ignore = i;
this.i++;
return this.i;
}
}
var myObj = new MyObj();
)";
//==============================================================================
int main (int argc, char* argv[])
{
auto err = juce::Result::ok();
juce::JavascriptEngine eng;
eng.maximumExecutionTime = juce::RelativeTime::seconds (10);
err = eng.execute (code);
if (! err.wasOk())
{
printf ("%s\n", err.getErrorMessage().toRawUTF8());
return 1;
}
for (auto i = 0; i < 100; i++)
{
auto root = eng.getRootObject();
auto child = root.getChild (juce::Identifier ("myObj"));
// uncomment to work around bug
//eng.execute (";");
auto res = child.invokeMethod ("func", {}, &err);
if (! err.wasOk())
{
printf ("\n\n%s\n", err.getErrorMessage().toRawUTF8());
return 1;
}
printf ("%d\n", int (res));
juce::Thread::sleep (1000);
}
return 0;
}
Output:
JUCE v8.0.6
1
2
3
4
5
6
7
8
9
10
interrupted
at <anonymous> (:9)
Program ended with exit code: 1
