JUCE Javascript engine dies if you only use JSObject::invokeMethod

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

Thank you for reporting. A fix is now out on develop

1 Like