@@ -212,18 +212,30 @@ static std::string getMouseFuncName(EventMouse::MouseEventType eventType)
212
212
return funcName;
213
213
}
214
214
215
- void removeJSObject (JSContext* cx, void * nativeObj)
215
+ static void removeJSObject (JSContext* cx, cocos2d::Ref * nativeObj)
216
216
{
217
217
js_proxy_t * nproxy;
218
218
js_proxy_t * jsproxy;
219
219
220
220
nproxy = jsb_get_native_proxy (nativeObj);
221
- if (nproxy) {
222
- JS::RootedObject jsobj (cx, nproxy->obj );
223
- jsproxy = jsb_get_js_proxy (jsobj);
224
- RemoveObjectRoot (cx, &jsproxy->obj );
221
+ if (nproxy)
222
+ {
223
+ jsproxy = jsb_get_js_proxy (nproxy->obj );
224
+ JS::RemoveObjectRoot (cx, &jsproxy->obj );
225
+
226
+ #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
227
+ nativeObj->_rooted = false ;
228
+
229
+ // FIXME BUG TODO: remove this line... but if I do so
230
+ // another misterious bug appears
225
231
jsb_remove_proxy (nproxy, jsproxy);
232
+ #else
233
+ // only remove when not using GC,
234
+ // otherwise finalize won't be able to find the proxy
235
+ jsb_remove_proxy (nproxy, jsproxy);
236
+ #endif
226
237
}
238
+ else CCLOG (" removeJSObject: BUG: cannot find native object = %p" , nativeObj);
227
239
}
228
240
229
241
void ScriptingCore::executeJSFunctionWithThisObj (JS::HandleValue thisObj, JS::HandleValue callback)
@@ -874,15 +886,16 @@ void ScriptingCore::removeScriptObjectByObject(Ref* pObj)
874
886
nproxy = jsb_get_native_proxy (ptr);
875
887
if (nproxy)
876
888
{
877
- JSContext *cx = ScriptingCore::getInstance ()->getGlobalContext ();
878
- JS::RootedObject jsobj (cx, nproxy->obj );
879
- jsproxy = jsb_get_js_proxy (jsobj);
889
+ JSContext *cx = getGlobalContext ();
890
+ jsproxy = jsb_get_js_proxy (nproxy->obj );
880
891
if (jsproxy)
881
892
{
882
893
RemoveObjectRoot (cx, &jsproxy->obj );
883
894
jsb_remove_proxy (nproxy, jsproxy);
884
895
}
896
+ // else CCLOG("removeScriptObjectByObject. BUG: jsproxy not found = %p", nproxy);
885
897
}
898
+ // else CCLOG("removeScriptObjectByObject. BUG: nproxy not found = %p", nproxy);
886
899
}
887
900
888
901
@@ -1185,7 +1198,6 @@ bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::Eve
1185
1198
1186
1199
JS::RootedObject jsretArr (_cx, JS_NewArrayObject (this ->_cx , 0 ));
1187
1200
1188
- // AddNamedObjectRoot(this->_cx, &jsretArr, "touchArray");
1189
1201
int count = 0 ;
1190
1202
1191
1203
js_type_class_t *typeClassEvent = nullptr ;
@@ -1214,8 +1226,6 @@ bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::Eve
1214
1226
ret = executeFunctionWithOwner (OBJECT_TO_JSVAL (p->obj ), funcName.c_str (), 2 , dataVal, jsvalRet);
1215
1227
}
1216
1228
1217
- // JS_RemoveObjectRoot(this->_cx, &jsretArr);
1218
-
1219
1229
for (auto & touch : touches)
1220
1230
{
1221
1231
removeJSObject (this ->_cx , touch);
@@ -1570,11 +1580,9 @@ void ScriptingCore::rootObject(Ref* ref)
1570
1580
JSContext *cx = getGlobalContext ();
1571
1581
jsproxy = jsb_get_js_proxy (nproxy->obj );
1572
1582
JS::AddNamedObjectRoot (cx, &jsproxy->obj , typeid (*ref).name ());
1583
+ ref->_rooted = true ;
1573
1584
}
1574
- else
1575
- {
1576
- CCLOG (" BUG in rootObject" );
1577
- }
1585
+ else CCLOG (" rootObject: BUG. native not found: %p" , ref);
1578
1586
}
1579
1587
1580
1588
void ScriptingCore::unrootObject (Ref* ref)
@@ -1588,11 +1596,9 @@ void ScriptingCore::unrootObject(Ref* ref)
1588
1596
JSContext *cx = getGlobalContext ();
1589
1597
jsproxy = jsb_get_js_proxy (nproxy->obj );
1590
1598
JS::RemoveObjectRoot (cx, &jsproxy->obj );
1599
+ ref->_rooted = false ;
1591
1600
}
1592
- else
1593
- {
1594
- CCLOG (" BUG in unrootObject" );
1595
- }
1601
+ else CCLOG (" unrootObject: BUG. native not found: %p" , ref);
1596
1602
}
1597
1603
1598
1604
#pragma mark - Debug
@@ -1922,44 +1928,59 @@ js_proxy_t* jsb_new_proxy(void* nativeObj, JS::HandleObject jsObj)
1922
1928
{
1923
1929
js_proxy_t * p = nullptr ;
1924
1930
JSObject* ptr = jsObj.get ();
1925
- do {
1926
- p = (js_proxy_t *)malloc (sizeof (js_proxy_t ));
1927
- assert (p);
1928
- js_proxy_t * nativeObjJsObjtmp = NULL ;
1929
- HASH_FIND_PTR (_native_js_global_ht, &nativeObj, nativeObjJsObjtmp);
1930
- assert (!nativeObjJsObjtmp);
1931
- p->ptr = nativeObj;
1932
- p->obj = ptr;
1933
- HASH_ADD_PTR (_native_js_global_ht, ptr, p);
1934
- p = (js_proxy_t *)malloc (sizeof (js_proxy_t ));
1935
- assert (p);
1936
- nativeObjJsObjtmp = NULL ;
1937
- HASH_FIND_PTR (_js_native_global_ht, &ptr, nativeObjJsObjtmp);
1938
- assert (!nativeObjJsObjtmp);
1939
- p->ptr = nativeObj;
1940
- p->obj = ptr;
1941
- HASH_ADD_PTR (_js_native_global_ht, obj, p);
1942
- } while (0 );
1931
+
1932
+ // native to JS index
1933
+ p = (js_proxy_t *)malloc (sizeof (js_proxy_t ));
1934
+ assert (p);
1935
+ js_proxy_t * nativeObjJsObjtmp = NULL ;
1936
+ HASH_FIND_PTR (_native_js_global_ht, &nativeObj, nativeObjJsObjtmp);
1937
+ assert (!nativeObjJsObjtmp);
1938
+ p->ptr = nativeObj;
1939
+ p->obj = ptr;
1940
+ HASH_ADD_PTR (_native_js_global_ht, ptr, p);
1941
+
1942
+ // JS to native Index
1943
+ p = (js_proxy_t *)malloc (sizeof (js_proxy_t ));
1944
+ assert (p);
1945
+ nativeObjJsObjtmp = NULL ;
1946
+ HASH_FIND_PTR (_js_native_global_ht, &ptr, nativeObjJsObjtmp);
1947
+ assert (!nativeObjJsObjtmp);
1948
+ p->ptr = nativeObj;
1949
+ p->obj = ptr;
1950
+ HASH_ADD_PTR (_js_native_global_ht, obj, p);
1951
+
1943
1952
return p;
1944
1953
}
1945
1954
1946
1955
js_proxy_t * jsb_get_native_proxy (void * nativeObj)
1947
1956
{
1948
1957
js_proxy_t * p = nullptr ;
1949
- JS_GET_PROXY (p, nativeObj);
1958
+ HASH_FIND_PTR (_native_js_global_ht, & nativeObj, p );
1950
1959
return p;
1951
1960
}
1952
1961
1953
1962
js_proxy_t * jsb_get_js_proxy (JSObject* jsObj)
1954
1963
{
1955
1964
js_proxy_t * p = nullptr ;
1956
- JS_GET_NATIVE_PROXY (p, jsObj);
1965
+ HASH_FIND_PTR (_js_native_global_ht, & jsObj, p );
1957
1966
return p;
1958
1967
}
1959
1968
1960
1969
void jsb_remove_proxy (js_proxy_t * nativeProxy, js_proxy_t * jsProxy)
1961
1970
{
1962
- JS_REMOVE_PROXY (nativeProxy, jsProxy);
1971
+ if (nativeProxy)
1972
+ {
1973
+ HASH_DEL (_native_js_global_ht, nativeProxy);
1974
+ free (nativeProxy);
1975
+ }
1976
+ else CCLOG (" jsb_remove_proxy: BUG: nativeProxy is null" );
1977
+
1978
+ if (jsProxy)
1979
+ {
1980
+ HASH_DEL (_js_native_global_ht, jsProxy);
1981
+ free (jsProxy);
1982
+ }
1983
+ else CCLOG (" jsb_remove_proxy: BUG: jsProxy is null" );
1963
1984
}
1964
1985
1965
1986
//
@@ -2001,7 +2022,10 @@ JSObject* jsb_ref_get_or_create_jsobject(JSContext *cx, cocos2d::Ref *ref, js_ty
2001
2022
js_proxy_t * newproxy = jsb_new_proxy (ref, js_obj);
2002
2023
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
2003
2024
CC_UNUSED_PARAM (newproxy);
2004
- // don't retain it.
2025
+
2026
+ // retain first copy, and before "owning" to prevent it
2027
+ // from calling "rootObject"
2028
+ ref->retain ();
2005
2029
ref->_scriptOwned = true ;
2006
2030
#else
2007
2031
// don't autorelease it
@@ -2029,7 +2053,7 @@ void jsb_ref_init(JSContext* cx, JS::Heap<JSObject*> *obj, Ref* ref, const char*
2029
2053
(void )cx;
2030
2054
(void )obj;
2031
2055
ref->_scriptOwned = true ;
2032
- // don't retain it.
2056
+ // don't retain it, already retained
2033
2057
#else
2034
2058
// autorelease it
2035
2059
ref->autorelease ();
@@ -2043,9 +2067,10 @@ void jsb_ref_autoreleased_init(JSContext* cx, JS::Heap<JSObject*> *obj, Ref* ref
2043
2067
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
2044
2068
(void )cx;
2045
2069
(void )obj;
2046
- ref-> _scriptOwned = true ;
2047
- // retain it, since the object is autoreleased
2070
+ // retain first copy, and before "owning" to prevent it
2071
+ // from calling "rootObject"
2048
2072
ref->retain ();
2073
+ ref->_scriptOwned = true ;
2049
2074
#else
2050
2075
// don't autorelease it, since it is already autoreleased
2051
2076
JS::AddNamedObjectRoot (cx, obj, debug);
@@ -2059,8 +2084,7 @@ void jsb_ref_finalize(JSFreeOp* fop, JSObject* obj)
2059
2084
js_proxy_t * nproxy;
2060
2085
js_proxy_t * jsproxy;
2061
2086
2062
- JS::RootedObject jsobj (fop->runtime (), obj);
2063
- jsproxy = jsb_get_js_proxy (jsobj);
2087
+ jsproxy = jsb_get_js_proxy (obj);
2064
2088
if (jsproxy)
2065
2089
{
2066
2090
auto ref = static_cast <cocos2d::Ref*>(jsproxy->ptr );
@@ -2074,6 +2098,7 @@ void jsb_ref_finalize(JSFreeOp* fop, JSObject* obj)
2074
2098
else
2075
2099
jsb_remove_proxy (nullptr , jsproxy);
2076
2100
}
2101
+ else CCLOG (" jsb_ref_finalize: BUG: proxy not found for %p" , obj);
2077
2102
#else
2078
2103
// CCLOG("jsb_ref_finalize: JSObject address = %p", obj);
2079
2104
#endif
0 commit comments