new "Too much recursion" error after upgrading

Hi,

I’m upgrading to the latest hotfix release (2.1.2). before that I think we were on 2.1.0. After upgrading, a specific spot in our code is getting this:

04-23 11:04:21.327: D/cocos2d-x debug info(29044): JS: .js:23:InternalError: too much recursion

Before the upgrade that code ran just fine, and it is not a recursive algorithm. I’ve checked and there’s no accidental recursion.

Does anyone know if the new Spidermonkey build has a reduced call stack limit? Or if there’s anything else changed in the new release that would be causing this?

Here’s the code for the function that triggers this:

    _autoUnlockCollection: function(newItemId) {
        var collections = GameDataManager.getAllCollections();
        for(var collectionId in collections) {
            if(this.hasUnlockedCollection(collectionId) === false) {
                var collection = collections[collectionId];
                var unlocked=true;
                for each(var collectionItemId in collection.items) {
                    if(this.hasItem(collectionItemId) === false) {
                        unlocked=false;
                        break;
                    }

                }

                if(unlocked) {
                    this.unlockCollection(collectionId);
                    break;
                }
            }
        }
    },

The error is thrown from the line of the first break statement, and commenting out the inner for each loop prevents this error.

EDIT this only happens on Android

Update:
I simplified the above code to not need to run the inner for loop in the case that was being hit, but am now receiving the same error at another spot in the code:

isPerfect:function() {
    var allowSkip=true;
    var isPerfect=true;
    for(var cardIdx in this._cards) {
        var card=this._cards[cardIdx];

        if(this._cards[cardIdx].isComplete()===false) {
            isPerfect=false;
            break;
        }
    }

    return isPerfect;
},

once again the error is being thrown from the “break;” line. In this case, this._cards only has 1 entry in it.

are you iterating through an object or array?

in case of array, try for(var i; i < array.length; i++) kind of loop

Hi Hao,

Thanks for the advice, but I want to identify what changed about the underlying systems that is causing this problem.

Changing the individual locations that throw this error is possible, but entirely the wrong approach to this problem. The JS code is valid syntax and runs with no issue on IOS, and these errors starting happening due to an upgrade to an underlying library. That means there’s a problem somewhere in the underlying code, which could hit everyone that’s using the JS bindings.

Hi Mark, thanks for your feedback.
Could you provide a simple demo to reproduce this issue? I’ll be happy to check it. Thanks. :slight_smile:

Mark Henderson wrote:

Hi Hao,
>
Thanks for the advice, but I want to identify what changed about the underlying systems that is causing this problem.
>
Changing the individual locations that throw this error is possible, but entirely the wrong approach to this problem. The JS code is valid syntax and runs with no issue on IOS, and these errors starting happening due to an upgrade to an underlying library. That means there’s a problem somewhere in the underlying code, which could hit everyone that’s using the JS bindings.

I asked about this on the development list, and got the solution from Rolando:
https://groups.google.com/forum/?fromgroups#!topic/cocos2d-js-devel/lI6MS81yyUA

I had to add some lines to createGlobalContext:

size_t stack = 500000;
JS_SetNativeStackQuota(this->rt_, stack);

I recommend that the two below commits be replicated in cocos2dx (they were applied to cocos2diphone



It looks like there’s some security calls that need to get added as well as the stack size being set.