/* spidermonkey 3 basic element 1.runtime 2.context 3.global object */ /* usefull apis 1.获取参数: jsval *argv = JS_ARGV(cx, vp); 2.获得调用该方法的对象object:JSObject*obj = JS_THIS_OBJECT(cx,vp); 3.设置私有数据 3.1 JS_SetPrivate(jsObj,void*) reqiure JSClass.flags 存在 ‘JSCLASS_HAS_PRIVATE‘ 3.2 void JS_SetReservedSlot(JSObject *obj, uint32_t index, jsval v); 要求 JSClass.flags has ‘JSCLASS_HAS_RESERVED_SLOTS(n)‘ 4. 用于回调js代码里函数: JS_CallFunctionValue JS_CallFunction JS_CallFunctionValue */
可以通过3.中的方法,将js对应的对象和方法保存起来,通过C代码回调(4中的函数)来调用js代码。
// 下面的代码将js对象和对象的方法通过JS_SetReservedSlot()保存起来
static void addCallBackAndThis(JSObject *obj, jsval callback, jsval &thisObj) { if(callback != JSVAL_VOID) { ScriptingCore::getInstance()->setReservedSpot(0, obj, callback); } if(thisObj != JSVAL_VOID) { ScriptingCore::getInstance()->setReservedSpot(1, obj, thisObj); } } JSBool ScriptingCore::setReservedSpot(uint32_t i, JSObject *obj, jsval value) { JS_SetReservedSlot(obj, i, value); return JS_TRUE; }
// 下面则通过JS_CallFunctionXXX 系列函数产生js的回调。
int ScriptingCore::handleMenuClickedEvent(void* data) { if (NULL == data) return 0; BasicScriptData* basicScriptData = static_cast<BasicScriptData*>(data); if (NULL == basicScriptData->nativeObject) return 0; MenuItem* menuItem = static_cast<MenuItem*>(basicScriptData->nativeObject); js_proxy_t * p = jsb_get_native_proxy(menuItem); if (!p) return 0; jsval retval; jsval dataVal; js_proxy_t *proxy = jsb_get_native_proxy(menuItem); dataVal = (proxy ? OBJECT_TO_JSVAL(proxy->obj) : JSVAL_NULL); executeJSFunctionFromReservedSpot(this->_cx, p->obj, dataVal, retval); return 1; }
static void executeJSFunctionFromReservedSpot(JSContext *cx, JSObject *obj, jsval &dataVal, jsval &retval) { jsval func = JS_GetReservedSlot(obj, 0); if (func == JSVAL_VOID) { return; } jsval thisObj = JS_GetReservedSlot(obj, 1); JSAutoCompartment ac(cx, obj); if (thisObj == JSVAL_VOID) { JS_CallFunctionValue(cx, obj, func, 1, &dataVal, &retval); } else { assert(!JSVAL_IS_PRIMITIVE(thisObj)); JS_CallFunctionValue(cx, JSVAL_TO_OBJECT(thisObj), func, 1, &dataVal, &retval); } }
原文:http://my.oschina.net/lyr/blog/382693