cocos2d-x 2.2.2 javascript binding crashes occasionally

I use the sample test but JSBinding is CCNode instead of CCObject.

     JSBool js_constructor(JSContext* cx, uint32_t argc, jsval* vp){
       cocos2d::CCLog("JS Constructor...");
     if (argc == 0) {
        JSB::JSBinding* cobj = new JSB::JSBinding();
   	if(!cobj) {
		CCLog("ERROR, ERROR, ERROR");
	}
        cocos2d::CCNode* ccobj = dynamic_cast<cocos2d::CCNode*>(cobj);
    
    if (ccobj) {
        ccobj->autorelease();
    }
    TypeTest<JSB::JSBinding> t;
    js_type_class_t* typeClass;
    uint32_t typeId = t.s_id();
    HASH_FIND_INT(_js_global_type_ht, &typeId, typeClass);
    assert(typeClass);    // crashes here sometimes.  but not all the time.  I don't know how to solve it.
    JSObject* obj = JS_NewObject(cx, typeClass->jsclass, typeClass->proto, typeClass->parentProto);
    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    
    js_proxy_t* p = jsb_new_proxy(cobj, obj);
    JS_AddNamedObjectRoot(cx, &p->obj, "JSB::JSBinding");
    
    return JS_TRUE;
   }

     JS_ReportError(cx, "Wrong number of arguments: %d, was expecting: %d", argc, 0);

     return JS_FALSE;
    }

The app got rejected because of the crash.

Found the problem. I copy the JSB_AUTO.cpp from the sample test.

in function js_register it should be

                  void js_register(JSContext* cx, JSObject* global){
       jsb_class = (JSClass *)calloc(1, sizeof(JSClass));
      jsb_class->name = "JSBinding";
       jsb_class->addProperty = JS_PropertyStub;
        jsb_class->delProperty = JS_PropertyStub;
      jsb_class->getProperty = JS_PropertyStub;
       jsb_class->setProperty = JS_StrictPropertyStub;
       jsb_class->enumerate = JS_EnumerateStub;
       jsb_class->resolve = JS_ResolveStub;
       jsb_class->convert = JS_ConvertStub;
        jsb_class->finalize = js_finalize;
         jsb_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
   
    static JSPropertySpec properties[] = {
           {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}
      };



static JSFunctionSpec funcs[] = {
    JS_FN("functionTest", js_functionTest, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
	JS_FN("featuredApp", js_featuredApp, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
	JS_FN("aboutUs", js_aboutUs, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
	JS_FN("moreGames", js_moreGames, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("inbox", js_inbox, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("viewPDF", js_viewPDF, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),

    JS_FS_END
};

// Binding create() function

static JSFunctionSpec st_funcs[] = {
    JS_FN("create", js_create, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FS_END
};

// Binding create() function and prototype

jsb_prototype = JS_InitClass(
                             cx, global,
                             NULL,
                             jsb_class,
                             js_constructor, 0,
                             properties,
                             funcs,
                             NULL,
                             st_funcs);
JSBool found;
JS_SetPropertyAttributes(cx, global, "JSB", JSPROP_ENUMERATE | JSPROP_READONLY, &found);

TypeTest<JSB::JSBinding> t;
js_type_class_t* p;
uint32_t typeId = t.s_id();
HASH_FIND_INT(_js_global_type_ht, &typeId, p);

if (!p) {
    p = (js_type_class_t* )malloc(sizeof(js_type_class_t));   
     ////// It was       p = (js_type_class_t* )malloc(sizeof(_js_global_type_ht));
    // the malloc datatype is different, it will cause malloc: checksum error.
    p->type = typeId;
    p->jsclass = jsb_class;
    p->proto = jsb_prototype;
    p->parentProto = NULL;
    HASH_ADD_INT(_js_global_type_ht, type, p);
}
}

I hope the cocos2d team will change the sample code too. :slight_smile:

Hi, why it was p = (js_type_class_t* )malloc(sizeof(_js_global_type_ht)); ??
Did you write this codes by your self?
Bindings-generator would generate the right codes. You could refer to

@dumganhar

No. The code is on the github sample code, not the autogen code. but the create your own javascript binding sample code.

Here is the link:

@emmyc You shouldn’t see iTyran’s repo. There is another tutorial about jsb manually.
https://github.com/cocos2d/cocos-docs/blob/master/manual/framework/native/scripting/javascript/jsb-manually/en.md

@iven HI Iven:

Thanks for the link. I have a question about how to call javascript from C++. Not from javascript to c++.

let’s see if I did some work at c++ and want to call a function in javascript.

On c++

      void InAppPurchase::productPruchased() {
        JSB::JSBinding *jsb = new JSB::JSBinding();
        jsb->retain();
        jsb->purchaseFullVersionCallback();
        jsb->release();
     }

I have javascript binding function here like this

    void JSB::JSBinding::purchaseFullVersionCallback() {
        js_proxy_t* p = jsb_get_native_proxy(this);
        jsval retval;
          jsval v[] = {
               v[0] = UINT_TO_JSVAL(0),
              v[1] = UINT_TO_JSVAL(2)
          };
          ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj),													   "callback", 2, v, &retval);
      }

But it does not work. Please advance how can I archive this.