__JSDownloaderDelegator::__JSDownloaderDelegator(JSContext *cx, JSObject *obj, const std::string &url, const jsval &callback) : _cx(cx) , _obj(obj) , _url(url) , _jsCallback(callback) , _buffer(nullptr) { _downloader = std::make_shared<cocos2d::extension::Downloader>(); _downloader->setConnectionTimeout(8); _downloader->setErrorCallback( std::bind(&__JSDownloaderDelegator::onError, this, std::placeholders::_1) ); _downloader->setSuccessCallback( std::bind(&__JSDownloaderDelegator::onSuccess, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3) ); JSContext *globalCx = ScriptingCore::getInstance()->getGlobalContext(); if (!JSVAL_IS_NULL(_jsCallback)) { JS_AddNamedValueRoot(globalCx, &_jsCallback, "JSB_DownloadDelegator_jsCallback"); } long contentSize = _downloader->getContentSize(_url); if (contentSize == -1) { cocos2d::extension::Downloader::Error err; onError(err); } else { _size = contentSize / sizeof(unsigned char); _buffer = (unsigned char*)malloc(contentSize); _downloader->downloadToBufferAsync(_url, _buffer, _size); } }
// JSFunctionWrapper JSFunctionWrapper::JSFunctionWrapper(JSContext* cx, JSObject *jsthis, jsval fval) : _cx(cx) , _jsthis(jsthis) , _fval(fval) { JS_AddNamedValueRoot(cx, &this->_fval, "JSFunctionWrapper"); JS_AddNamedObjectRoot(cx, &this->_jsthis, "JSFunctionWrapper"); }
static JSBool smjs_load_uri(JSContext *ctx, uintN argc, jsval *rval) { jsval *argv = JS_ARGV(ctx, rval); struct smjs_load_uri_hop *hop; struct download *download; JSString *jsstr; unsigned char *uri_string; struct uri *uri; if (argc < 2) return JS_FALSE; jsstr = JS_ValueToString(smjs_ctx, argv[0]); uri_string = JS_EncodeString(smjs_ctx, jsstr); uri = get_uri(uri_string, 0); if (!uri) return JS_FALSE; download = mem_alloc(sizeof(*download)); if (!download) { done_uri(uri); return JS_FALSE; } hop = mem_alloc(sizeof(*hop)); if (!hop) { mem_free(download); done_uri(uri); return JS_FALSE; } hop->callback = argv[1]; hop->ses = smjs_ses; if (!JS_AddNamedValueRoot(smjs_ctx, &hop->callback, "smjs_load_uri_hop.callback")) { mem_free(hop); mem_free(download); done_uri(uri); return JS_FALSE; } download->data = hop; download->callback = (download_callback_T *) smjs_loading_callback; load_uri(uri, NULL, download, PRI_MAIN, CACHE_MODE_NORMAL, -1); done_uri(uri); return JS_TRUE; }
/* * Create a new JSD value referring to a jsval. Copy string values into the * JSD compartment. Leave all other GCTHINGs in their native compartments * and access them through cross-compartment calls. */ JSDValue* jsd_NewValue(JSDContext* jsdc, jsval val) { JSDValue* jsdval; JSCrossCompartmentCall *call = NULL; if(!(jsdval = (JSDValue*) calloc(1, sizeof(JSDValue)))) return NULL; if(JSVAL_IS_GCTHING(val)) { JSBool ok; JS_BeginRequest(jsdc->dumbContext); call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, jsdc->glob); if(!call) { JS_EndRequest(jsdc->dumbContext); free(jsdval); return NULL; } ok = JS_AddNamedValueRoot(jsdc->dumbContext, &jsdval->val, "JSDValue"); if(ok && JSVAL_IS_STRING(val)) { if(!JS_WrapValue(jsdc->dumbContext, &val)) { ok = JS_FALSE; } } JS_LeaveCrossCompartmentCall(call); JS_EndRequest(jsdc->dumbContext); if(!ok) { free(jsdval); return NULL; } } jsdval->val = val; jsdval->nref = 1; JS_INIT_CLIST(&jsdval->props); return jsdval; }
FFSessionHandler::FFSessionHandler(HostChannel* channel) : SessionData(channel, this, getJSContext()), jsObjectId(0), jsObjectsById(NULL), stringObjectClass(NULL) { Debug::log(Debug::Debugging) << "FFSessionHandler::FFSessionHandler(this=" << this << ")" << Debug::flush; // TODO(jat): is there a way to avoid calling this twice, without keeping // JSContext in an instance field? JSContext* ctx = getJSContext(); if (!JS_AddNamedObjectRoot(ctx, &jsObjectsById, "jsObjectsById")) { Debug::log(Debug::Error) << "Error rooting jsObjectsById" << Debug::flush; } jsObjectsById = JS_NewArrayObject(ctx, 0, NULL); if (!jsObjectsById) { Debug::log(Debug::Error) << "Error rooting jsObjectsById" << Debug::flush; } if (!JS_AddNamedValueRoot(ctx, &toStringTearOff, "toStringTearOff")) { Debug::log(Debug::Error) << "Error rooting toStringTearOff" << Debug::flush; } getStringObjectClass(ctx); getToStringTearOff(ctx); }
/* * Create a new JSD value referring to a jsval. Copy string values into the * JSD compartment. Leave all other GCTHINGs in their native compartments * and access them through cross-compartment calls. */ JSDValue* jsd_NewValue(JSDContext* jsdc, jsval value) { JS::RootedValue val(jsdc->dumbContext, value); JSDValue* jsdval; JSCompartment* oldCompartment = NULL; if(!(jsdval = (JSDValue*) calloc(1, sizeof(JSDValue)))) return NULL; if(JSVAL_IS_GCTHING(val)) { JSBool ok; JS_BeginRequest(jsdc->dumbContext); oldCompartment = JS_EnterCompartment(jsdc->dumbContext, jsdc->glob); ok = JS_AddNamedValueRoot(jsdc->dumbContext, &jsdval->val, "JSDValue"); if(ok && JSVAL_IS_STRING(val)) { if(!JS_WrapValue(jsdc->dumbContext, val.address())) { ok = JS_FALSE; } } JS_LeaveCompartment(jsdc->dumbContext, oldCompartment); JS_EndRequest(jsdc->dumbContext); if(!ok) { free(jsdval); return NULL; } } jsdval->val = val; jsdval->nref = 1; JS_INIT_CLIST(&jsdval->props); return jsdval; }
void AutoRoot::Take() { count++; JS_AddNamedValueRoot(cx, &var, "AutoRoot"); //JS_AddNamedRootRT(ScriptEngine::GetRuntime(), &var, "AutoRoot"); }