Fix event handle function issue with compartment

and  Fix a crash issue caused by malformed js usage
This commit is contained in:
pandamicro 2015-12-18 19:25:56 +08:00
parent 8d712a4c45
commit 81918f51ea
3 changed files with 24 additions and 7 deletions

View File

@ -1481,8 +1481,9 @@ bool ScriptingCore::executeFunctionWithOwner(jsval owner, const char *name, cons
bool ScriptingCore::handleKeybardEvent(void* nativeObj, cocos2d::EventKeyboard::KeyCode keyCode, bool isPressed, cocos2d::Event* event)
{
JSAutoCompartment ac(_cx, _global.ref());
js_proxy_t * p = jsb_get_native_proxy(nativeObj);
if (nullptr == p)
return false;
@ -1510,8 +1511,9 @@ bool ScriptingCore::handleKeybardEvent(void* nativeObj, cocos2d::EventKeyboard::
bool ScriptingCore::handleFocusEvent(void* nativeObj, cocos2d::ui::Widget* widgetLoseFocus, cocos2d::ui::Widget* widgetGetFocus)
{
JSAutoCompartment ac(_cx, _global.ref());
js_proxy_t * p = jsb_get_native_proxy(nativeObj);
if (nullptr == p)
return false;
@ -2035,7 +2037,19 @@ js_proxy_t* jsb_new_proxy(void* nativeObj, JS::HandleObject jsHandle)
#endif
CC_ASSERT(_native_js_global_map.find(nativeObj) == _native_js_global_map.end() && "Native Key should not be present");
CC_ASSERT(_js_native_global_map.find(jsObj) == _js_native_global_map.end() && "JS Key should not be present");
// CC_ASSERT(_js_native_global_map.find(jsObj) == _js_native_global_map.end() && "JS Key should not be present");
// If native proxy doesn't exist, and js proxy exist, means previous js object in this location have already been released.
// In some circumstances, js object may be released without calling its finalizer, so the proxy haven't been removed.
// For ex: var seq = cc.sequence(moveBy, cc.callFunc(this.callback, this));
// In this code, cc.callFunc is created in parameter, and directly released after the native function call, the finalizer won't be triggered.
// The current solution keep the game running with a warning because it may cause memory leak as the native object may have been retained.
auto existJSProxy = _js_native_global_map.find(jsObj);
if (existJSProxy != _js_native_global_map.end()) {
#if COCOS2D_DEBUG
CCLOG("jsbindings: Failed to remove proxy for native object: %p, force removing it, but it may cause memory leak", existJSProxy->second->ptr);
#endif
jsb_remove_proxy(existJSProxy->second);
}
proxy->ptr = nativeObj;
proxy->obj = jsObj;
@ -2143,7 +2157,7 @@ JS::HandleObject jsb_create_weak_jsobject(JSContext *cx, void *native, js_type_c
#else
#if COCOS2D_DEBUG
CC_UNUSED_PARAM(proxy);
CCLOG("++++++WEAK_REF++++++ Cpp(%s): %p - JS: %p", debug, native, jsObj.get());
// CCLOG("++++++WEAK_REF++++++ Cpp(%s): %p - JS: %p", debug, native, jsObj.get());
#endif // COCOS2D_DEBUG
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
return jsObj;
@ -2213,7 +2227,7 @@ JS::HandleObject jsb_get_or_create_weak_jsobject(JSContext *cx, void *native, js
JS::AddNamedObjectRoot(cx, &proxy->obj, debug);
#else
#if COCOS2D_DEBUG
CCLOG("++++++WEAK_REF++++++ Cpp(%s): %p - JS: %p", debug, native, jsObj.get());
// CCLOG("++++++WEAK_REF++++++ Cpp(%s): %p - JS: %p", debug, native, jsObj.get());
#endif // COCOS2D_DEBUG
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
return jsObj;

View File

@ -5632,6 +5632,8 @@ void jsb_FinalizeHook_finalize(JSFreeOp *fop, JSObject *obj)
int count = refObj->getReferenceCount();
if (count == 1)
{
// Can't release directly the native object, otherwise any JS Object manipulation in destructor may cause JSB crash,
// because it's during garbage collection process
refObj->autorelease();
}
else
@ -5640,7 +5642,7 @@ void jsb_FinalizeHook_finalize(JSFreeOp *fop, JSObject *obj)
}
#if COCOS2D_DEBUG
ScriptingCore::retainCount--;
CCLOG("------RELEASED------ %d Native %p ref count: %d JSObj %p", ScriptingCore::retainCount, refObj, count-1, ownerPtr);
CCLOG("------RELEASED------ %d Cpp: %p - JS: %p", ScriptingCore::retainCount, refObj, ownerPtr);
#endif // COCOS2D_DEBUG
}
#if COCOS2D_DEBUG

View File

@ -453,7 +453,8 @@ var TestAnimationEvent = ArmatureTestLayer.extend({
if (movementID == "Fire") {
var moveBy = cc.moveBy(2, cc.p(300 * this._direction, 0));
this._armature.stopAllActions();
this._armature.runAction(cc.sequence(moveBy, cc.callFunc(this.callback, this)));
var callFunc = cc.callFunc(this.callback, this);
this._armature.runAction(cc.sequence(moveBy, callFunc));
this._armature.getAnimation().play("Walk");
this._direction *= -1;