//--------------------------------------------------------------------------- inline JSBool ejs_throw_error(JSContext *cx, JSObject *obj, const char *msg) { JSString *jsstr; // if we get errors during error reporting we report those if (((jsstr = JS_NewStringCopyZ(cx, msg))) && (JS_AddNamedRoot(cx, &jsstr, "jsstr"))) { jsval dummy; // We can't use JS_EvaluateScript since the stack would be wrong JSFunction *func; JSObject *fobj; const char *fbody = "throw new Error(msg);"; const char *argnames[] = { "msg" }; if ((func = JS_CompileFunction(cx, obj, NULL, 1, argnames, fbody, strlen(fbody), NULL, 0))) { // root function if (((fobj = JS_GetFunctionObject(func))) && (JS_AddNamedRoot(cx, &fobj, "fobj"))) { jsval args[] = { STRING_TO_JSVAL(jsstr) }; JS_CallFunction(cx, obj, func, 1, args, &dummy); JS_RemoveRoot(cx, &fobj); } } JS_RemoveRoot(cx, &jsstr); } return JS_FALSE; }//---------------------------------------------------------------------------
JSObject * lm_DefineLocation(MochaDecoder *decoder) { JSObject *obj; JSContext *cx; JSURL *url; obj = decoder->location; if (obj) return obj; cx = decoder->js_context; url = JS_malloc(cx, sizeof *url); if (!url) return NULL; XP_BZERO(url, sizeof *url); obj = JS_InitClass(cx, decoder->window_object, NULL, &lm_location_class, Location, 0, url_props, loc_methods, NULL, NULL); if (!obj || !JS_SetPrivate(cx, obj, url)) { JS_free(cx, url); return NULL; } /* XXX common subroutine this and above with lm_NewURL */ if (!JS_AddNamedRoot(cx, &url->href, "loc.text")) return NULL; if (!JS_AddNamedRoot(cx, &url->target, "loc.target")) return NULL; if (!JS_AddNamedRoot(cx, &url->text, "loc.text")) return NULL; if (!JS_DefineProperty(cx, decoder->window_object, lm_location_str, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY)) { return NULL; } if (!JS_DefineProperty(cx, decoder->document, lm_location_str, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY)) { return NULL; } /* Define the Location object (the current URL). */ url->url_decoder = HOLD_BACK_COUNT(decoder); url->url_type = FORM_TYPE_NONE; url->url_object = obj; url->index = URL_NOT_INDEXED; decoder->location = obj; return obj; }
static int js_init(void) { JSContext *cx; jsval val; JS_SetCStringsAreUTF8(); runtime = JS_NewRuntime(0x1000000); cx = js_newctx(err_reporter); JS_BeginRequest(cx); showtimeobj = JS_NewObject(cx, &showtime_class, NULL, NULL); JS_DefineFunctions(cx, showtimeobj, showtime_functions); val = INT_TO_JSVAL(showtime_get_version_int()); JS_SetProperty(cx, showtimeobj, "currentVersionInt", &val); val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, htsversion)); JS_SetProperty(cx, showtimeobj, "currentVersionString", &val); JSFunction *fn = JS_DefineFunction(cx, showtimeobj, "RichText", js_RichText, 1, 0); RichText = JS_GetFunctionObject(fn); JS_AddNamedRoot(cx, &showtimeobj, "showtime"); JS_EndRequest(cx); JS_DestroyContext(cx); return 0; }
JSBool js_createSettings(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { const char *title; const char *icon = NULL; const char *desc = NULL; char spath[URL_MAX]; if(!JS_ConvertArguments(cx, argc, argv, "s/ss", &title, &icon, &desc)) return JS_FALSE; js_plugin_t *jsp = JS_GetPrivate(cx, obj); snprintf(spath, sizeof(spath), "plugins/%s", jsp->jsp_id); js_setting_group_t *jsg = calloc(1, sizeof(js_setting_group_t)); JSObject *robj; jsg->jsg_refcount = 2; LIST_INSERT_HEAD(&jsp->jsp_setting_groups, jsg, jsg_link); jsg->jsg_frozen = 1; jsg->jsg_spath = strdup(spath); jsg->jsg_store = htsmsg_store_load(spath) ?: htsmsg_create_map(); jsg->jsg_root = settings_add_dir(settings_apps, _p(title), NULL, icon, desc ? _p(desc) : NULL); robj = JS_NewObjectWithGivenProto(cx, &setting_group_class, NULL, obj); jsg->jsg_val = *rval = OBJECT_TO_JSVAL(robj); JS_AddNamedRoot(cx, &jsg->jsg_val, "jsg"); JS_SetPrivate(cx, robj, jsg); JS_DefineFunctions(cx, robj, setting_functions); jsg->jsg_frozen = 0; return JS_TRUE; }
static int js_init(void) { JSContext *cx; JS_SetCStringsAreUTF8(); runtime = JS_NewRuntime(0x1000000); cx = js_newctx(err_reporter); JS_BeginRequest(cx); showtimeobj = JS_NewObject(cx, &showtime_class, NULL, NULL); JS_DefineFunctions(cx, showtimeobj, showtime_functions); JSFunction *fn = JS_DefineFunction(cx, showtimeobj, "RichText", js_RichText, 1, 0); RichText = JS_GetFunctionObject(fn); JS_AddNamedRoot(cx, &showtimeobj, "showtime"); JS_EndRequest(cx); JS_DestroyContext(cx); return 0; }
JSBool js_addsubprovider(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { js_subprovider_t *sp; js_plugin_t *jsp = JS_GetPrivate(cx, obj); if(!JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(argv[0]))) { JS_ReportError(cx, "Argument is not a function"); return JS_FALSE; } sp = calloc(1, sizeof(js_subprovider_t)); sp->super.sp_query = js_sub_query; sp->super.sp_retain = js_sub_retain; sp->sp_title = prop_create_root(NULL); prop_set_string(sp->sp_title, jsp->jsp_id); subtitle_provider_register(&sp->super, jsp->jsp_id, sp->sp_title, 0, "plugin", 1, 1); sp->sp_jsp = jsp; LIST_INSERT_HEAD(&jsp->jsp_subproviders, sp, sp_plugin_link); sp->sp_func = argv[0]; atomic_set(&sp->sp_refcnt, 1); JS_AddNamedRoot(cx, &sp->sp_func, "subprovider"); *rval = JSVAL_VOID; return JS_TRUE; }
static js_setting_t * jss_create(JSContext *cx, JSObject *obj, const char *id, jsval *rval, JSObject *func, js_setting_group_t *jsg, int persistent) { if(jsg->jsg_root == NULL) { JS_ReportError(cx, "Settings group has been destroyed"); return NULL; } if(!JS_ObjectIsFunction(cx, func)) { JS_ReportError(cx, "Callback is not a function"); return NULL; } js_setting_t *jss = calloc(1, sizeof(js_setting_t)); jss->jss_cx = cx; jss->jss_refcount = 1; jss->jss_jsg = jsg; jss->jss_key = persistent && jsg->jsg_kv_url ? strdup(id) : NULL; LIST_INSERT_HEAD(&jsg->jsg_settings, jss, jss_link); atomic_add(&jsg->jsg_refcount, 1); JS_AddNamedRoot(cx, &jss->jss_obj, "jss"); jss->jss_obj = OBJECT_TO_JSVAL(JS_DefineObject(cx, obj, id, &setting_class, NULL, 0)); *rval = jss->jss_obj; JS_SetPrivate(cx, JSVAL_TO_OBJECT(jss->jss_obj), jss); jsval v = OBJECT_TO_JSVAL(func); JS_SetProperty(cx, JSVAL_TO_OBJECT(jss->jss_obj), "callback", &v); return jss; }
JSString* jsd_GetValueString(JSDContext* jsdc, JSDValue* jsdval) { JSContext* cx = jsdc->dumbContext; JSExceptionState* exceptionState; if(!jsdval->string) { /* if the jsval is a string, then we don't need to double root it */ if(JSVAL_IS_STRING(jsdval->val)) jsdval->string = JSVAL_TO_STRING(jsdval->val); else { JS_BeginRequest(cx); exceptionState = JS_SaveExceptionState(cx); jsdval->string = JS_ValueToString(cx, jsdval->val); JS_RestoreExceptionState(cx, exceptionState); if(jsdval->string) { if(!JS_AddNamedRoot(cx, &jsdval->string, "ValueString")) jsdval->string = NULL; } JS_EndRequest(cx); } } return jsdval->string; }
JSDValue* jsd_NewValue(JSDContext* jsdc, jsval val) { JSDValue* jsdval; if(!(jsdval = (JSDValue*) calloc(1, sizeof(JSDValue)))) return NULL; if(JSVAL_IS_GCTHING(val)) { JSBool ok = JS_FALSE; JS_BeginRequest(jsdc->dumbContext); ok = JS_AddNamedRoot(jsdc->dumbContext, &jsdval->val, "JSDValue"); JS_EndRequest(jsdc->dumbContext); if(!ok) { free(jsdval); return NULL; } } jsdval->val = val; jsdval->nref = 1; JS_INIT_CLIST(&jsdval->props); return jsdval; }
static JSBool js_item_onEvent(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { js_item_t *ji = JS_GetPrivate(cx, obj); if(!JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(argv[1]))) { JS_ReportError(cx, "Argument is not a function"); return JS_FALSE; } if(ji->ji_eventsub == NULL) { ji->ji_eventsub = prop_subscribe(PROP_SUB_TRACK_DESTROY, PROP_TAG_CALLBACK, js_item_eventsub, ji, PROP_TAG_ROOT, ji->ji_root, PROP_TAG_COURIER, ji->ji_model->jm_pc, NULL); ji->ji_model->jm_subs++; ji->ji_this = OBJECT_TO_JSVAL(obj); JS_AddNamedRoot(cx, &ji->ji_this, "item_this"); } js_event_handler_create(cx, &ji->ji_event_handlers, JSVAL_IS_STRING(argv[0]) ? JS_GetStringBytes(JS_ValueToString(cx, argv[0])) : NULL, argv[1]); *rval = JSVAL_VOID; return JS_TRUE; }
static js_model_t * js_model_create(JSContext *cx, jsval openfunc) { js_model_t *jm = calloc(1, sizeof(js_model_t)); jm->jm_refcount = 1; jm->jm_openfunc = openfunc; JS_AddNamedRoot(cx, &jm->jm_openfunc, "openfunc"); return jm; }
void js_event_handler_create(JSContext *cx, struct js_event_handler_list *list, const char *filter, jsval fun) { js_event_handler_t *jeh; jeh = malloc(sizeof(js_event_handler_t)); jeh->jeh_filter = filter ? strdup(filter) : NULL; jeh->jeh_function = fun; JS_AddNamedRoot(cx, &jeh->jeh_function, "eventhandler"); LIST_INSERT_HEAD(list, jeh, jeh_link); }
ScriptValuePtr TraceMonkeyEngine::createObject() { JSObject* obj = JS_NewObject(context, NULL, NULL, NULL); bool success = JS_AddNamedRoot(context, &obj, "TraceMonkeyEngine::createObject temp val"); // Ensure our value won't be GCed assert(success); ScriptValuePtr ret( new TraceMonkeyValue( this, true, OBJECT_TO_JSVAL(obj) ) ); success = JS_RemoveRoot(context, &obj); assert(success); return ret; }
static js_model_t * js_model_create(JSContext *cx, jsval openfunc, int sync) { js_model_t *jm = calloc(1, sizeof(js_model_t)); jm->jm_refcount = 1; jm->jm_openfunc = openfunc; jm->jm_sync = sync; jm->jm_ctxpriv.jcp_c = &jm->jm_cancellable; JS_AddNamedRoot(cx, &jm->jm_openfunc, "openfunc"); TAILQ_INIT(&jm->jm_items); hts_mutex_lock(&js_model_mutex); LIST_INSERT_HEAD(&js_models, jm, jm_link); hts_mutex_unlock(&js_model_mutex); return jm; }
ScriptValuePtr TraceMonkeyEngine::createFunction(NativeFunction func, int numArgs) { JSFunction* jsFunc = JS_NewFunction(context, (JSNative)func, numArgs, 0, NULL, NULL); bool success = JS_AddNamedRoot(context, &jsFunc, "TraceMonkeyEngine::createFunction temp val");; // Ensure our value won't be GCed assert(success); assert(jsFunc != NULL); assert(JSVAL_IS_OBJECT(OBJECT_TO_JSVAL(jsFunc))); ScriptValuePtr ret( new TraceMonkeyValue( this, true, OBJECT_TO_JSVAL(jsFunc) ) ); success = JS_RemoveRoot(context, &jsFunc); assert(success); return ret; }
TraceMonkeyValue::TraceMonkeyValue(ScriptEngine* _engine, double _value) : ScriptValue(_engine) { debugName = "double value no. " + Utility::toString(__nameCounter); Logging::log(Logging::INFO, "Going to create a TM value of: %s\r\n", debugName.c_str()); INDENT_LOG(Logging::INFO); value = DOUBLE_TO_JSVAL(_value); bool ret = JS_AddNamedRoot(TraceMonkeyEngine::context, &(this->value), debugName.c_str()); // Ensure our value won't be GCed assert(ret); printJSVAL(value); Logging::log(Logging::INFO, "Created a TM value of: %s\r\n", debugName.c_str()); __nameCounter += 1; JS_GC(TraceMonkeyEngine::context); // XXX For debugging purposes Logging::log(Logging::INFO, "post-creation GC ok.\r\n"); }
/* * The caller must call DeleteLocalRef() on the returned object when no more * references remain. */ jobject jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj) { jobject java_wrapper_obj; JSObjectHandle *handle; /* Create a tiny stub object to act as the GC root that points to the JSObject from its netscape.javascript.JSObject counterpart. */ handle = (JSObjectHandle*)JS_malloc(cx, sizeof(JSObjectHandle)); if (!handle) return NULL; handle->js_obj = js_obj; handle->rt = JS_GetRuntime(cx); /* Create a new Java object that wraps the JavaScript object by storing its address in a private integer field. */ #ifndef OJI #if JS_BYTES_PER_LONG == 8 java_wrapper_obj = (*jEnv)->NewObject(jEnv, njJSObject, njJSObject_JSObject, (jlong)handle); #else java_wrapper_obj = (*jEnv)->NewObject(jEnv, njJSObject, njJSObject_JSObject, (jint)handle); #endif #else if (JSJ_callbacks && JSJ_callbacks->get_java_wrapper != NULL) { java_wrapper_obj = JSJ_callbacks->get_java_wrapper(jEnv, (jint)handle); } #endif /*! OJI */ if (!java_wrapper_obj) { jsj_UnexpectedJavaError(cx, jEnv, "Couldn't create new instance of " "netscape.javascript.JSObject"); goto done; } JS_AddNamedRoot(cx, &handle->js_obj, "&handle->js_obj"); done: return java_wrapper_obj; }
//-------------------------------------------------------------- Animation::Animation(string name_,string pathAbsScript_) : midiInterface() { M_zeroAll(); m_name = name_; m_pathAbsScript = pathAbsScript_; mp_obj = JS_NewObject(ofxJSGetContext(), NULL, NULL, ofxJSGetGlobalObj()); JSBool ok = JS_SetPrivate(ofxJSGetContext(), mp_obj, (void*)this); JS_AddNamedRoot(ofxJSGetContext(), &mp_obj, m_name.c_str()); ofxJSDefineFunctionObject(mp_obj, "newSlider", Animation::jsNewSlider, 4); ofxJSDefineFunctionObject(mp_obj, "newToggle", Animation::jsNewToggle, 4); sm_mapJSObj_Anim[mp_obj] = this; // printf("#### setting private %s for obj %p, this=%p\n", ok == JS_TRUE ? "OK" : "NO", mp_obj, this); setMidiName(m_name); populateConfigurations(); }
ScriptValuePtr TraceMonkeyValue::getProperty(std::string propertyName) { assert(isValid()); Logging::log(Logging::DEBUG, "TraceMonkeyValue::getProperty(%s): \r\n", propertyName.c_str()); printJSVAL(value); assert(JSVAL_IS_OBJECT(value)); jsval ret; assert(JS_GetProperty(TraceMonkeyEngine::context, JSVAL_TO_OBJECT(value), propertyName.c_str(), &ret)); bool success = JS_AddNamedRoot(TraceMonkeyEngine::context, &ret, "TraceMonkeyValue::getProperty temp val"); // Ensure our value won't be GCed assert(success); Logging::log(Logging::DEBUG, "returning: \r\n"); printJSVAL(ret); ScriptValuePtr retValue(new TraceMonkeyValue(engine, true, ret)); success = JS_RemoveRoot(TraceMonkeyEngine::context, &ret); // Allow GCing, it is already marked in the retValue assert(success); return retValue; }
ScriptValuePtr TraceMonkeyEngine::runScript(std::string script) { // printf("Running script: \r\n%s\r\n", script.c_str()); jsval ret; JS_EvaluateScript(context, global, script.c_str(), script.length(), "TraceMonkeyEngine", 0, &ret); bool success = JS_AddNamedRoot(context, &ret, "TraceMonkeyEngine::runScript temp val");; // Ensure our value won't be GCed assert(success); // printf("Script completed\r\n"); printJSVAL(ret); ScriptValuePtr retValue; if ( !JSVAL_IS_VOID(ret) ) retValue = ScriptValuePtr( new TraceMonkeyValue(this, true, ret) ); success = JS_RemoveRoot(context, &ret); assert(success); return retValue; }
ScriptValuePtr TraceMonkeyValue::call(std::string funcName, ScriptValueArgs& args) { assert(isValid()); Logging::log(Logging::DEBUG, "TMV::call(%s, (%d))\r\n", funcName.c_str(), args.args.size()); printJSVAL(value); assert(JSVAL_IS_OBJECT(value)); jsval func; bool success = JS_GetProperty(TraceMonkeyEngine::context, JSVAL_TO_OBJECT(value), funcName.c_str(), &func); assert(success); assert(JSVAL_IS_OBJECT(func)); assert(!JSVAL_IS_NULL(func)); int numArgs = args.args.size(); jsval jsArgs[numArgs+1]; // +1 for safety in case of 0 args for (int i = 0; i < numArgs; i++) { jsArgs[i] = dynamic_cast<TraceMonkeyValue*>(args.args[i].get())->value; } jsval ret; JS_CallFunctionValue(TraceMonkeyEngine::context, JSVAL_TO_OBJECT(value), func, numArgs, jsArgs, &ret); success = JS_AddNamedRoot(TraceMonkeyEngine::context, &ret, "TraceMonkeyValue::call temp val"); // Ensure our value won't be GCed assert(success); Logging::log(Logging::DEBUG, "returning: \r\n"); printJSVAL(ret); ScriptValuePtr retValue(new TraceMonkeyValue(engine, true, ret)); success = JS_RemoveRoot(TraceMonkeyEngine::context, &ret); // Allow GCing, it is already marked in the retValue assert(success); return retValue; }
static VALUE initialize_native(VALUE self, VALUE UNUSED(options)) { JohnsonRuntime* runtime; Data_Get_Struct(self, JohnsonRuntime, runtime); if ((runtime->js = JS_NewRuntime(0x100000)) && (runtime->jsids = create_id_hash()) && (runtime->rbids = create_id_hash()) ) { JS_SetRuntimePrivate(runtime->js, (void *)self); JS_SetGCCallbackRT(runtime->js, gc_callback); JSContext* context = johnson_get_current_context(runtime); if( (runtime->global = JS_GetGlobalObject(context)) && (JS_AddNamedRoot(context, &(runtime->global), "runtime->global")) ) { return self; } } if (runtime->rbids) JS_HashTableDestroy(runtime->rbids); if (runtime->jsids) JS_HashTableDestroy(runtime->jsids); if (runtime->js) JS_DestroyRuntime(runtime->js); rb_raise(rb_eRuntimeError, "Couldn't initialize the runtime!"); return Qnil; }
NORETURN(void) raise_js_error_in_ruby(JohnsonRuntime* runtime) { JSContext * context = johnson_get_current_context(runtime); JohnsonContext * johnson_context = OUR_CONTEXT(context); if (JS_IsExceptionPending(context)) { assert(JS_GetPendingException(context, &(johnson_context->ex))); JS_AddNamedRoot(context, &(johnson_context->ex), "raise_js_error_in_ruby"); JS_ClearPendingException(context); JS_RemoveRoot(context, &(johnson_context->ex)); } VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(runtime->js); if (johnson_context->ex) RAISE_JS_ERROR(ruby_runtime, johnson_context->ex); // FIXME: I don't think this is needed, it should // be done on the Ruby side. if (!johnson_context->msg) rb_raise(rb_eRuntimeError, "Unknown JavaScriptError"); // FIXME: I don't think this can ever happen.... rb_raise(rb_eRuntimeError, johnson_context->msg); }
/* * Class: netscape_javascript_JSObject * Method: call * Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object; */ JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_call(JNIEnv *jEnv, jobject java_wrapper_obj, jstring function_name_jstr, jobjectArray java_args) { int i, argc, arg_num; jsval *argv; JSContext *cx = NULL; JSObject *js_obj; jsval js_val, function_val; int dummy_cost; JSBool dummy_bool; const jchar *function_name_ucs2; jsize function_name_len; JSErrorReporter saved_reporter; jboolean is_copy; jobject result; JSJavaThreadState *jsj_env; jsj_env = jsj_enter_js(jEnv, NULL, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL); if (!jsj_env) return NULL; function_name_ucs2 = NULL; result = NULL; if (!function_name_jstr) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_NULL_FUNCTION_NAME); goto done; } /* Get the function name to eval as raw Unicode characters */ function_name_ucs2 = (*jEnv)->GetStringChars(jEnv, function_name_jstr, &is_copy); if (!function_name_ucs2) { JS_ASSERT(0); goto done; } function_name_len = (*jEnv)->GetStringLength(jEnv, function_name_jstr); /* Allocate space for JS arguments */ if (java_args) { argc = (*jEnv)->GetArrayLength(jEnv, java_args); argv = (jsval*)JS_malloc(cx, argc * sizeof(jsval)); } else { argc = 0; argv = 0; } /* Convert arguments from Java to JS values */ for (arg_num = 0; arg_num < argc; arg_num++) { jobject arg = (*jEnv)->GetObjectArrayElement(jEnv, java_args, arg_num); if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, arg, &argv[arg_num])) goto cleanup_argv; JS_AddNamedRoot(cx, &argv[arg_num], "&argv[arg_num]"); } if (!JS_GetUCProperty(cx, js_obj, function_name_ucs2, function_name_len, &function_val)) goto cleanup_argv; if (!JS_CallFunctionValue(cx, js_obj, function_val, argc, argv, &js_val)) goto cleanup_argv; jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv), &dummy_cost, &result, &dummy_bool); cleanup_argv: if (argv) { for (i = 0; i < arg_num; i++) JS_RemoveRoot(cx, &argv[i]); JS_free(cx, argv); } done: if (function_name_ucs2) (*jEnv)->ReleaseStringChars(jEnv, function_name_jstr, function_name_ucs2); if (!jsj_exit_js(cx, jsj_env, saved_reporter)) return NULL; return result; }
JSURL * lm_NewURL(JSContext *cx, MochaDecoder *decoder, LO_AnchorData *anchor_data, JSObject *document) { JSObject *obj; JSURL *url; JSString *str; if (!decoder->url_prototype) { obj = JS_InitClass(cx, decoder->window_object, decoder->event_receiver_prototype, &lm_url_class, Url, 0, url_props, NULL, NULL, NULL); if (!obj) return NULL; decoder->url_prototype = obj; } url = JS_malloc(cx, sizeof *url); if (!url) return NULL; XP_BZERO(url, sizeof *url); obj = JS_NewObject(cx, &lm_url_class, decoder->url_prototype, lm_GetOuterObject(decoder)); if (!obj || !JS_SetPrivate(cx, obj, url)) { JS_free(cx, url); return NULL; } if (!JS_DefineFunctions(cx, obj, url_methods)) return NULL; url->url_decoder = HOLD_BACK_COUNT(decoder); url->url_type = FORM_TYPE_NONE; url->index = URL_NOT_INDEXED; url->url_object = obj; str = JS_NewStringCopyZ(cx, (char *) anchor_data->anchor); if (!str) return NULL; url->href = str; if (!JS_AddNamedRoot(cx, &url->href, "url.href")) return NULL; if (anchor_data->target) { str = JS_NewStringCopyZ(cx, (char *) anchor_data->target); if (!str) return NULL; url->target = str; } if (!JS_AddNamedRoot(cx, &url->target, "url.target")) return NULL; if (anchor_data->element && anchor_data->element->type == LO_TEXT) { str = lm_LocalEncodingToStr(decoder->window_context, (char *) anchor_data->element->lo_text.text); if (!str) return NULL; url->text = str; } if (!JS_AddNamedRoot(cx, &url->text, "url.text")) return NULL; return url; }
jobject jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj) { jobject java_wrapper_obj; JSHashEntry *he, **hep; java_wrapper_obj = NULL; #ifdef JSJ_THREADSAFE PR_EnterMonitor(js_obj_reflections_monitor); #endif /* First, look in the hash table for an existing reflection of the same JavaScript object. If one is found, return it. */ hep = JS_HashTableRawLookup(js_obj_reflections, (JSHashNumber)js_obj, js_obj); /* If the same JSObject is reflected into Java more than once then we should return the same Java object, both for efficiency and so that the '==' operator works as expected in Java when comparing two JSObjects. However, it is not possible to hold a reference to a Java object without inhibiting GC of that object, at least not in a portable way, i.e. a weak reference. So, for now, JSObject identity is broken. */ he = *hep; if (he) { java_wrapper_obj = (jobject)he->value; JS_ASSERT(java_wrapper_obj); if (java_wrapper_obj) goto done; } /* No existing reflection found, so create a new Java object that wraps the JavaScript object by storing its address in a private integer field. */ #ifndef OJI java_wrapper_obj = (*jEnv)->NewObject(jEnv, njJSObject, njJSObject_JSObject, (jint)js_obj); #else if (JSJ_callbacks && JSJ_callbacks->get_java_wrapper != NULL) { java_wrapper_obj = JSJ_callbacks->get_java_wrapper(jEnv, (jint)handle); } #endif /*! OJI */ if (!java_wrapper_obj) { jsj_UnexpectedJavaError(cx, jEnv, "Couldn't create new instance of " "netscape.javascript.JSObject"); goto done; } /* Add the new reflection to the hash table. */ he = JS_HashTableRawAdd(js_obj_reflections, hep, (JSHashNumber)js_obj, js_obj, java_wrapper_obj); if (he) { /* Tell the JavaScript GC about this object since the only reference to it may be in Java-land. */ JS_AddNamedRoot(cx, (void*)&he->key, "&he->key"); } else { JS_ReportOutOfMemory(cx); /* No need to delete java_wrapper_obj because Java GC will reclaim it */ java_wrapper_obj = NULL; } /* * Release local reference to wrapper object, since some JVMs seem reticent * about collecting it otherwise. */ /* FIXME -- beard: this seems to make calls into Java with JSObject's fail. */ /* We should really be creating a global ref if we are putting it in a hash table. */ /* (*jEnv)->DeleteLocalRef(jEnv, java_wrapper_obj); */ done: #ifdef JSJ_THREADSAFE PR_ExitMonitor(js_obj_reflections_monitor); #endif return java_wrapper_obj; }
int js_plugin_load(const char *id, const char *url, char *errbuf, size_t errlen) { char *sbuf; struct fa_stat fs; JSContext *cx; js_plugin_t *jsp; JSObject *pobj, *gobj, *confobj; JSScript *s; char path[PATH_MAX]; jsval val; if((sbuf = fa_quickload(url, &fs, NULL, errbuf, errlen)) == NULL) return -1; cx = js_newctx(err_reporter); JS_BeginRequest(cx); /* Remove any plugin with same URL */ LIST_FOREACH(jsp, &js_plugins, jsp_link) if(!strcmp(jsp->jsp_id, id)) break; if(jsp != NULL) js_plugin_unload(cx, jsp); jsp = calloc(1, sizeof(js_plugin_t)); jsp->jsp_url = strdup(url); jsp->jsp_id = strdup(id); LIST_INSERT_HEAD(&js_plugins, jsp, jsp_link); gobj = JS_NewObject(cx, &global_class, NULL, NULL); JS_InitStandardClasses(cx, gobj); JS_DefineProperty(cx, gobj, "showtime", OBJECT_TO_JSVAL(showtimeobj), NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT); /* Plugin object */ pobj = JS_NewObject(cx, &plugin_class, NULL, gobj); JS_AddNamedRoot(cx, &pobj, "plugin"); JS_SetPrivate(cx, pobj, jsp); JS_DefineFunctions(cx, pobj, plugin_functions); /* Plugin config object */ confobj = JS_DefineObject(cx, pobj, "config", &plugin_conf_class, NULL, 0); JS_SetPrivate(cx, confobj, jsp); val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, url)); JS_SetProperty(cx, confobj, "url", &val); if(!fa_parent(path, sizeof(path), url)) { val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, path)); JS_SetProperty(cx, confobj, "path", &val); } JS_DefineProperty(cx, confobj, "URIRouting", BOOLEAN_TO_JSVAL(1), NULL, jsp_setEnableURIRoute, JSPROP_PERMANENT); JS_DefineProperty(cx, confobj, "search", BOOLEAN_TO_JSVAL(1), NULL, jsp_setEnableSearch, JSPROP_PERMANENT); s = JS_CompileScript(cx, pobj, sbuf, fs.fs_size, url, 1); free(sbuf); if(s != NULL) { JSObject *sobj = JS_NewScriptObject(cx, s); jsval result; JS_AddNamedRoot(cx, &sobj, "script"); JS_ExecuteScript(cx, pobj, s, &result); JS_RemoveRoot(cx, &sobj); } JS_RemoveRoot(cx, &pobj); JS_EndRequest(cx); JS_GC(cx); JS_DestroyContext(cx); return 0; }
static JSBool js_appendItem0(JSContext *cx, js_model_t *model, prop_t *parent, const char *url, const char *type, JSObject *metaobj, jsval *data, jsval *rval, int enabled, const char *metabind) { install_nodesub(model); prop_t *item = prop_create_root(NULL); rstr_t *rurl = url ? rstr_alloc(url) : NULL; if(url != NULL) prop_set(item, "url", PROP_SET_RSTRING, rurl); if(data != NULL) js_prop_set_from_jsval(cx, prop_create(item, "data"), *data); *rval = JSVAL_VOID; if(metabind != NULL) playinfo_bind_url_to_prop(metabind, item); if(type != NULL) { prop_set_string(prop_create(item, "type"), type); if(metaobj) js_prop_from_object(cx, metaobj, prop_create(item, "metadata")); } else if(url != NULL) { if(backend_resolve_item(url, item)) { prop_destroy(item); rstr_release(rurl); return JS_TRUE; } } prop_set_int(prop_create(item, "enabled"), enabled); prop_t *p = prop_ref_inc(item); if(prop_set_parent(item, parent)) { prop_destroy(item); prop_ref_dec(p); } else { JSObject *robj = JS_NewObjectWithGivenProto(cx, &item_class, JSVAL_TO_OBJECT(model->jm_item_proto), NULL); *rval = OBJECT_TO_JSVAL(robj); js_item_t *ji = calloc(1, sizeof(js_item_t)); atomic_add(&model->jm_refcount, 1); ji->ji_url = rstr_dup(rurl); ji->ji_model = model; ji->ji_root = p; TAILQ_INSERT_TAIL(&model->jm_items, ji, ji_link); JS_SetPrivate(cx, robj, ji); ji->ji_enable_set_property = 1; ji->ji_eventsub = prop_subscribe(PROP_SUB_TRACK_DESTROY, PROP_TAG_CALLBACK, js_item_eventsub, ji, PROP_TAG_ROOT, ji->ji_root, PROP_TAG_COURIER, model->jm_pc, NULL); model->jm_subs++; ji->ji_this = OBJECT_TO_JSVAL(robj); JS_AddNamedRoot(cx, &ji->ji_this, "item_this"); prop_tag_set(ji->ji_root, model, ji); } rstr_release(rurl); return JS_TRUE; }
static void js_sub_query(subtitle_provider_t *SP, sub_scanner_t *ss, int score, int autosel) { js_subprovider_t *sp = (js_subprovider_t *)SP; JSContext *cx = js_newctx(NULL); JS_BeginRequest(cx); if(ss != NULL) { JSObject *obj = JS_NewObject(cx, &subreq_class, NULL, NULL); JS_AddNamedRoot(cx, &obj, "subscanner"); if(sp->sp_jsp != NULL) usage_inc_plugin_counter(sp->sp_jsp->jsp_id, "subsearch", 1); js_sub_job_t *jsj = malloc(sizeof(js_sub_job_t)); jsj->jsj_ss = ss; jsj->jsj_score = score; jsj->jsj_autosel = autosel; sub_scanner_retain(ss); JS_SetPrivate(cx, obj, jsj); JS_DefineFunctions(cx, obj, sub_functions); js_set_prop_rstr(cx, obj, "title", ss->ss_title); js_set_prop_rstr(cx, obj, "imdb", ss->ss_imdbid); if(ss->ss_season > 0) js_set_prop_int(cx, obj, "season", ss->ss_season); if(ss->ss_year > 0) js_set_prop_int(cx, obj, "year", ss->ss_year); if(ss->ss_episode > 0) js_set_prop_int(cx, obj, "episode", ss->ss_episode); if(ss->ss_fsize > 0) js_set_prop_dbl(cx, obj, "filesize", ss->ss_fsize); if(ss->ss_hash_valid) { char str[64]; snprintf(str, sizeof(str), "%016" PRIx64, ss->ss_opensub_hash); js_set_prop_str(cx, obj, "opensubhash", str); bin2hex(str, sizeof(str), ss->ss_subdbhash, 16); js_set_prop_str(cx, obj, "subdbhash", str); } if(ss->ss_duration > 0) js_set_prop_int(cx, obj, "duration", ss->ss_duration); jsval result; jsval arg = OBJECT_TO_JSVAL(obj); JS_CallFunctionValue(cx, NULL, sp->sp_func, 1, &arg, &result); JS_RemoveRoot(cx, &obj); } js_subprovider_release(cx, sp); JS_DestroyContext(cx); }