JSObject* CreateGlobalObject(JSContext* cx, const JSClass* clasp, nsIPrincipal* principal, JS::CompartmentOptions& aOptions) { MOZ_ASSERT(NS_IsMainThread(), "using a principal off the main thread?"); MOZ_ASSERT(principal); MOZ_RELEASE_ASSERT(principal != nsContentUtils::GetNullSubjectPrincipal(), "The null subject principal is getting inherited - fix that!"); RootedObject global(cx, JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal), JS::DontFireOnNewGlobalHook, aOptions)); if (!global) return nullptr; JSAutoCompartment ac(cx, global); // The constructor automatically attaches the scope to the compartment private // of |global|. (void) new XPCWrappedNativeScope(cx, global); if (clasp->flags & JSCLASS_DOM_GLOBAL) { #ifdef DEBUG // Verify that the right trace hook is called. Note that this doesn't // work right for wrapped globals, since the tracing situation there is // more complicated. Manual inspection shows that they do the right // thing. Also note that we only check this for JSCLASS_DOM_GLOBAL // classes because xpc::TraceXPCGlobal won't call // TraceProtoAndIfaceCache unless that flag is set. if (!((const js::Class*)clasp)->isWrappedNative()) { VerifyTraceProtoAndIfaceCacheCalledTracer trc(JS_GetRuntime(cx)); TraceChildren(&trc, GCCellPtr(global.get())); MOZ_ASSERT(trc.ok, "Trace hook on global needs to call TraceXPCGlobal for XPConnect compartments."); } #endif const char* className = clasp->name; AllocateProtoAndIfaceCache(global, (strcmp(className, "Window") == 0 || strcmp(className, "ChromeWindow") == 0) ? ProtoAndIfaceCache::WindowLike : ProtoAndIfaceCache::NonWindowLike); } return global; }
AutoJSAPI::~AutoJSAPI() { if (mOwnErrorReporting) { ReportException(); // We need to do this _after_ processing the existing exception, because the // JS engine can throw while doing that, and uses this bit to determine what // to do in that case: squelch the exception if the bit is set, otherwise // call the error reporter. Calling WarningOnlyErrorReporter with a // non-warning will assert, so we need to make sure we do the former. JS::ContextOptionsRef(cx()).setAutoJSAPIOwnsErrorReporting(mOldAutoJSAPIOwnsErrorReporting); } if (mOldErrorReporter.isSome()) { JS_SetErrorReporter(JS_GetRuntime(cx()), mOldErrorReporter.value()); } }
static JSBool evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JSString *str; JSObject *sandbox; JSContext *subcx; const jschar *src; size_t srclen; JSBool ret = JS_FALSE; sandbox = NULL; if(!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sandbox)) { return JS_FALSE; } subcx = JS_NewContext(JS_GetRuntime(cx), 8L * 1024L); if(!subcx) { JS_ReportOutOfMemory(cx); return JS_FALSE; } SETUP_REQUEST(subcx); src = JS_GetStringChars(str); srclen = JS_GetStringLength(str); if(!sandbox) { sandbox = JS_NewObject(subcx, NULL, NULL, NULL); if(!sandbox || !JS_InitStandardClasses(subcx, sandbox)) { goto done; } } if(srclen == 0) { *rval = OBJECT_TO_JSVAL(sandbox); } else { JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, rval); } ret = JS_TRUE; done: FINISH_REQUEST(subcx); JS_DestroyContext(subcx); return ret; }
void AutoJSAPI::TakeOwnershipOfErrorReporting() { MOZ_ASSERT(!mOwnErrorReporting); mOwnErrorReporting = true; JSRuntime *rt = JS_GetRuntime(cx()); mOldAutoJSAPIOwnsErrorReporting = JS::ContextOptionsRef(cx()).autoJSAPIOwnsErrorReporting(); JS::ContextOptionsRef(cx()).setAutoJSAPIOwnsErrorReporting(true); // Workers have their own error reporting mechanism which deals with warnings // as well, so don't change the worker error reporter for now. Once we switch // all of workers to TakeOwnershipOfErrorReporting(), we will just make the // default worker error reporter assert that it only sees warnings. if (mIsMainThread) { JS_SetErrorReporter(rt, WarningOnlyErrorReporter); } }
NS_IMETHODIMP nsPerformanceStatsService::GetSnapshot(JSContext* cx, nsIPerformanceSnapshot * *aSnapshot) { nsRefPtr<nsPerformanceSnapshot> snapshot = new nsPerformanceSnapshot(); nsresult rv = snapshot->Init(cx, mProcessId); if (NS_FAILED(rv)) { return rv; } js::GetPerfMonitoringTestCpuRescheduling(JS_GetRuntime(cx), &mProcessStayed, &mProcessMoved); if (++mProcessUpdateCounter % 10 == 0) { mozilla::unused << UpdateTelemetry(); } snapshot.forget(aSnapshot); return NS_OK; }
static JSBool to_array(JSContext* js_context, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* retval) { VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context); JohnsonContext* context; JohnsonRuntime* runtime; Data_Get_Struct(ruby_context, JohnsonContext, context); VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context)); Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime); PREPARE_JROOTS(js_context, 0); VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL); JCHECK(call_ruby_from_js(runtime, retval, self, rb_intern("to_a"), 0)); JRETURN; }
/* * Like JSResolveOp, but flags provide contextual information as follows: * * JSRESOLVE_QUALIFIED a qualified property id: obj.id or obj[id], not id * JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment * JSRESOLVE_DETECTING 'if (o.p)...' or similar detection opcode sequence * JSRESOLVE_DECLARING var, const, or function prolog declaration opcode * JSRESOLVE_CLASSNAME class name used when constructing * * The *objp out parameter, on success, should be null to indicate that id * was not resolved; and non-null, referring to obj or one of its prototypes, * if id was resolved. */ static JSBool importer_new_resolve(JSContext *context, JSObject **obj, jsid *id, unsigned flags, JSObject **objp) { Importer *priv; char *name; JSBool ret = JS_TRUE; jsid module_init_name; *objp = NULL; module_init_name = gjs_runtime_get_const_string(JS_GetRuntime(context), GJS_STRING_MODULE_INIT); if (*id == module_init_name) return JS_TRUE; if (!gjs_get_string_id(context, *id, &name)) return JS_FALSE; /* let Object.prototype resolve these */ if (strcmp(name, "valueOf") == 0 || strcmp(name, "toString") == 0 || strcmp(name, "__iterator__") == 0) goto out; priv = priv_from_js(context, *obj); gjs_debug_jsprop(GJS_DEBUG_IMPORTER, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv); if (priv == NULL) /* we are the prototype, or have the wrong class */ goto out; JS_BeginRequest(context); if (do_import(context, *obj, priv, name)) { *objp = *obj; } else { ret = JS_FALSE; } JS_EndRequest(context); out: g_free(name); return ret; }
GClosure* gjs_closure_new(JSContext *context, JSObject *callable, const char *description, gboolean root_function) { Closure *c; c = (Closure*) g_closure_new_simple(sizeof(Closure), NULL); c->runtime = JS_GetRuntime(context); /* The saved context is used for lifetime management, so that the closure will * be torn down with the context that created it. The context could be attached to * the default context of the runtime using if we wanted the closure to survive * the context that created it. */ c->context = context; JS_BeginRequest(context); c->obj = callable; c->unref_on_global_object_finalized = FALSE; GJS_INC_COUNTER(closure); if (root_function) { /* Fully manage closure lifetime if so asked */ gjs_keep_alive_add_global_child(context, global_context_finalized, c->obj, c); g_closure_add_invalidate_notifier(&c->base, NULL, closure_invalidated); } else { /* Only mark the closure as invalid if memory is managed outside (i.e. by object.c for signals) */ g_closure_add_invalidate_notifier(&c->base, NULL, closure_set_invalid); } gjs_debug_closure("Create closure %p which calls object %p '%s'", c, c->obj, description); JS_EndRequest(context); return &c->base; }
/** Deletes all async callbacks associated with the current context. Suitable for use as as JSContextCallback. * This is NOT SAFE to call from within an async callback. * You must not call this function if you are not in the JSContext associated with the * callback you are removing. This function is intended for being called during the finalization of a JSContext (ie. * during the context callback, gpsee_contextCallback().) * * @note This call may traverse the entire linked list of registrations. Don't add and remove callbacks a lot. * * @param cx The state of the JS context if used as a JSContextCallback. If calling directly, pass JSCONTEXT_DESTROY. * @param contextOp * @returns JS_TRUE * * @todo Investigate using gpsee_removeAsyncCallbackContext() to clean up async callbacks on context shutdown. */ JSBool gpsee_removeAsyncCallbackContext(JSContext *cx, uintN contextOp) { gpsee_runtime_t *grt = (gpsee_runtime_t *) JS_GetRuntimePrivate(JS_GetRuntime(cx)); GPSEEAsyncCallback **cb, **cc, *freeme = NULL; #ifdef GPSEE_DEBUG_BUILD /* Assert that cx is on current thread */ JS_BeginRequest(cx); JS_EndRequest(cx); #endif if (contextOp != JSCONTEXT_DESTROY) return JS_TRUE; if (!grt->asyncCallbacks) return JS_TRUE; /* Acquire mutex protecting grt->asyncCallbacks */ PR_Lock(grt->asyncCallbacks_lock); /* Locate the first entry we want to remove */ for (cb = &grt->asyncCallbacks; *cb && (*cb)->cx != cx; cb = &(*cb)->next); if (*cb) { freeme = *cb; /* Locate the final entry we want remove */ for (cc = cb; *cc && (*cc)->cx == cx; cc = &(*cc)->next); /* Remove all the entries we grabbed */ *cb = *cc; } /* Relinquish mutex */ PR_Unlock(grt->asyncCallbacks_lock); /* Free the memory */ while (freeme) { GPSEEAsyncCallback *next = freeme->next; JS_free(cx, freeme); /* Break at end of removed segment */ if (&freeme->next == cc) break; freeme = next; } return JS_TRUE; }
JSObject* CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal, JS::CompartmentOptions& aOptions) { MOZ_ASSERT(NS_IsMainThread(), "using a principal off the main thread?"); MOZ_ASSERT(principal); RootedObject global(cx, JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal), JS::DontFireOnNewGlobalHook, aOptions)); if (!global) return nullptr; JSAutoCompartment ac(cx, global); // The constructor automatically attaches the scope to the compartment private // of |global|. (void) new XPCWrappedNativeScope(cx, global); #ifdef DEBUG // Verify that the right trace hook is called. Note that this doesn't // work right for wrapped globals, since the tracing situation there is // more complicated. Manual inspection shows that they do the right thing. if (!((const js::Class*)clasp)->ext.isWrappedNative) { VerifyTraceXPCGlobalCalledTracer trc; JS_TracerInit(&trc.base, JS_GetRuntime(cx), VerifyTraceXPCGlobalCalled); trc.ok = false; JS_TraceChildren(&trc.base, global, JSTRACE_OBJECT); MOZ_ASSERT(trc.ok, "Trace hook on global needs to call TraceXPCGlobal for XPConnect compartments."); } #endif if (clasp->flags & JSCLASS_DOM_GLOBAL) { const char* className = clasp->name; AllocateProtoAndIfaceCache(global, (strcmp(className, "Window") == 0 || strcmp(className, "ChromeWindow") == 0) ? ProtoAndIfaceCache::WindowLike : ProtoAndIfaceCache::NonWindowLike); } return global; }
PromiseResolverTask(Promise* aPromise, JS::Handle<JS::Value> aValue, Promise::PromiseState aState) : mPromise(aPromise) , mValue(aValue) , mState(aState) { MOZ_ASSERT(aPromise); MOZ_ASSERT(mState != Promise::Pending); MOZ_COUNT_CTOR(PromiseResolverTask); JSContext* cx = nsContentUtils::GetSafeJSContext(); /* It's safe to use unsafeGet() here: the unsafeness comes from the * possibility of updating the value of mJSObject without triggering the * barriers. However if the value will always be marked, post barriers * unnecessary. */ JS_AddNamedValueRootRT(JS_GetRuntime(cx), mValue.unsafeGet(), "PromiseResolverTask.mValue"); }
static gpsee_realm_t *getRealm(JSContext *cx) { JSObject *global = JS_GetGlobalObject(cx); gpsee_runtime_t *grt; gpsee_realm_t *realm = NULL; if ((realm = gpsee_getModuleScopeRealm(cx, NULL))) return realm; grt = JS_GetRuntimePrivate(JS_GetRuntime(cx)); gpsee_enterAutoMonitor(cx, &grt->monitors.realms); if (grt && grt->realmsByContext) realm = gpsee_ds_get(grt->realmsByContext, cx); gpsee_leaveAutoMonitor(grt->monitors.realms); if (global && JS_GET_CLASS(cx, global) == gpsee_getGlobalClass()) GPSEE_ASSERT(realm); return realm; }
/* * 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; }
/** Our "Operation Callback" multiplexes this Spidermonkey facility. It is called automatically by Spidermonkey, and is * triggered on a regular interval by gpsee_asyncCallbackTriggerThreadFunc() */ JSBool gpsee_operationCallback(JSContext *cx) { gpsee_runtime_t *grt = (gpsee_runtime_t *) JS_GetRuntimePrivate(JS_GetRuntime(cx)); GPSEEAsyncCallback *cb; /* The callbacks registered with GPSEE may want to invoke JSAPI functionality, which might toss us back out * to another invocation of gpsee_operationCallback(). The JSAPI docs for "operation callbacks" [1] suggest * removing the operation callback before calling JSAPI functionality from within an operation callback, * then resetting it when we're done making JSAPI calls. Since it's rather inexpensive, we'll just do it here * and then consumers of gpsee_addAsyncCallback() needn't worry about it (we don't want them touching that * callback slot anyway! * * [1] https://developer.mozilla.org/en/JS_SetOperationCallback * * Another side note: we do it before if(cb) because if gpsee_asyncCallbacks is empty, we want to uninstall our * operation callback altogether. */ JS_SetOperationCallback(cx, NULL); cb = grt->asyncCallbacks; if (cb) { GPSEEAsyncCallback *next; do { /* Save the 'next' link in case the callback deletes itself */ next = cb->next; /* Invoke callback */ if (!((*(cb->callback))(cb->cx, cb->userdata, cb))) /* Propagate exceptions */ return JS_FALSE; } while ((cb = next)); /* Reinstall our operation callback */ JS_SetOperationCallback(cx, gpsee_operationCallback); return JS_TRUE; } return JS_TRUE; }
cl_mem dpoCContext::CreateBuffer(JSContext *cx, cl_mem_flags flags, size_t size, void *ptr, cl_int *err) { #ifdef INCREMENTAL_MEM_RELEASE int freed; cl_mem result; bool didGC = false; do { freed = CheckFree(); result = clCreateBuffer(context, flags, size, ptr, err); if ((*err != CL_OUT_OF_HOST_MEMORY) && (*err != CL_MEM_OBJECT_ALLOCATION_FAILURE) && (*err != CL_OUT_OF_RESOURCES)) break; if (!freed && !didGC) { JS_GC(JS_GetRuntime(cx)); didGC = freed = true; } } while (freed); return result; #else /* INCREMENTAL_MEM_RELEASE */ return clCreateBuffer(context, flags, size, ptr, err); #endif /* INCREMENTAL_MEM_RELEASE */ }
JSDContext* jsd_JSDContextForJSContext(JSContext* context) { JSDContext* iter; JSDContext* jsdc = NULL; JSRuntime* runtime = JS_GetRuntime(context); JSD_LOCK(); for( iter = (JSDContext*)_jsd_context_list.next; iter != (JSDContext*)&_jsd_context_list; iter = (JSDContext*)iter->links.next ) { if( runtime == iter->jsrt ) { jsdc = iter; break; } } JSD_UNLOCK(); return jsdc; }
static JSBool error_constructor_value_of(JSContext *context, unsigned argc, jsval *vp) { jsval v_self, v_prototype; Error *priv; jsval v_out; jsid prototype_name; v_self = JS_THIS(context, vp); if (!JSVAL_IS_OBJECT(v_self)) { /* Lie a bit here... */ gjs_throw(context, "GLib.Error.valueOf() called on a non object"); return JS_FALSE; } prototype_name = gjs_runtime_get_const_string(JS_GetRuntime(context), GJS_STRING_PROTOTYPE); if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(v_self), "constructor", prototype_name, &v_prototype)) return JS_FALSE; if (!JSVAL_IS_OBJECT(v_prototype)) { gjs_throw(context, "GLib.Error.valueOf() called on something that is not" " a constructor"); return JS_FALSE; } priv = priv_from_js(context, JSVAL_TO_OBJECT(v_prototype)); if (priv == NULL) return JS_FALSE; v_out = INT_TO_JSVAL(priv->domain); JS_SET_RVAL(context, vp, v_out); return TRUE; }
/* XXX FIXME: Iargv/Ienviron are now associated with running. */ rpmjs rpmjsNew(char ** av, uint32_t flags) { rpmjs js = #ifdef NOTYET (flags & 0x80000000) ? rpmjsI() : #endif rpmjsGetPool(_rpmjsPool); JSI_t I = NULL; #if defined(WITH_GPSEE) if (flags == 0) flags = _rpmjs_options; if (F_ISSET(flags, NOUTF8) || getenv("GPSEE_NO_UTF8_C_STRINGS")) { JS_DestroyRuntime(JS_NewRuntime(1024)); putenv((char *) "GPSEE_NO_UTF8_C_STRINGS=1"); } /* XXX FIXME: js->Iargv/js->Ienviron for use by rpmjsRunFile() */ I = gpsee_createInterpreter(); #ifdef NOTYET /* FIXME: dig out where NOCACHE has moved. */ if (F_ISSET(flags, NOCACHE)) I->useCompilerCache = 0; #endif if (F_ISSET(flags, NOWARN)) { gpsee_runtime_t * grt = JS_GetRuntimePrivate(JS_GetRuntime(I->cx)); grt->errorReport |= er_noWarnings; } JS_SetOptions(I->cx, (flags & 0xffff)); #if defined(JS_GC_ZEAL) JS_SetGCZeal(I->cx, _rpmjs_zeal); #endif #endif /* WITH_GPSEE */ js->flags = flags; js->I = I; return rpmjsLink(js); }
static void gjstest_test_func_gjs_jsapi_util_array(void) { GjsUnitTestFixture fixture; JSContext *context; JSObject *global; GjsRootedArray *array; int i; jsval value; _gjs_unit_test_fixture_begin(&fixture); context = fixture.context; array = gjs_rooted_array_new(); global = JS_GetGlobalObject(context); JSCompartment *oldCompartment = JS_EnterCompartment(context, global); for (i = 0; i < N_ELEMS; i++) { value = STRING_TO_JSVAL(JS_NewStringCopyZ(context, "abcdefghijk")); gjs_rooted_array_append(context, array, value); } JS_GC(JS_GetRuntime(context)); for (i = 0; i < N_ELEMS; i++) { char *ascii; value = gjs_rooted_array_get(context, array, i); g_assert(JSVAL_IS_STRING(value)); gjs_string_to_utf8(context, value, &ascii); g_assert(strcmp(ascii, "abcdefghijk") == 0); g_free(ascii); } gjs_rooted_array_free(context, array, TRUE); JS_LeaveCompartment(context, oldCompartment); _gjs_unit_test_fixture_finish(&fixture); }
NS_IMETHODIMP IDBCursor::GetValue(JSContext* aCx, jsval* aValue) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); nsresult rv; if (mType == INDEX) { const Key& value = mKeyData[mDataIndex].value; NS_ASSERTION(!value.IsUnset() && !value.IsNull(), "Bad key!"); rv = IDBObjectStore::GetJSValFromKey(value, aCx, aValue); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } if (!mHaveCachedValue) { JSAutoRequest ar(aCx); if (!mJSRuntime) { JSRuntime* rt = JS_GetRuntime(aCx); JSBool ok = js_AddRootRT(rt, &mCachedValue, "IDBCursor::mCachedValue"); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); mJSRuntime = rt; } nsCOMPtr<nsIJSON> json(new nsJSON()); rv = json->DecodeToJSVal(mData[mDataIndex].value, aCx, &mCachedValue); NS_ENSURE_SUCCESS(rv, rv); mHaveCachedValue = true; } *aValue = mCachedValue; return NS_OK; }
static JSObject * load_module_init(JSContext *context, JSObject *in_object, const char *full_path) { JSObject *module_obj; JSBool found; jsid module_init_name; GFile *file; /* First we check if js module has already been loaded */ module_init_name = gjs_runtime_get_const_string(JS_GetRuntime(context), GJS_STRING_MODULE_INIT); if (JS_HasPropertyById(context, in_object, module_init_name, &found) && found) { jsval module_obj_val; if (JS_GetPropertyById(context, in_object, module_init_name, &module_obj_val)) { return JSVAL_TO_OBJECT(module_obj_val); } } module_obj = create_module_object (context); file = g_file_new_for_commandline_arg(full_path); if (!import_file (context, "__init__", file, module_obj)) goto out; if (!JS_DefinePropertyById(context, in_object, module_init_name, OBJECT_TO_JSVAL(module_obj), NULL, NULL, GJS_MODULE_PROP_FLAGS & ~JSPROP_PERMANENT)) goto out; out: g_object_unref (file); return module_obj; }
AutoJSAPI::~AutoJSAPI() { if (!mCx) { // No need to do anything here: we never managed to Init, so can't have an // exception on our (nonexistent) JSContext. We also don't need to restore // any state on it. return; } ReportException(); // We need to do this _after_ processing the existing exception, because the // JS engine can throw while doing that, and uses this bit to determine what // to do in that case: squelch the exception if the bit is set, otherwise // call the error reporter. Calling WarningOnlyErrorReporter with a // non-warning will assert, so we need to make sure we do the former. JS::ContextOptionsRef(cx()).setAutoJSAPIOwnsErrorReporting(mOldAutoJSAPIOwnsErrorReporting); if (mOldErrorReporter.isSome()) { JS_SetErrorReporter(JS_GetRuntime(cx()), mOldErrorReporter.value()); } }
static JSBool DelocalizeContextCallback(JSContext *cx, uintN contextOp) { NS_ABORT_IF_FALSE(JS_GetRuntime(cx) == sHookedRuntime, "unknown runtime!"); JSBool ok = JS_TRUE; if (sOldContextCallback && !sOldContextCallback(cx, contextOp)) { ok = JS_FALSE; // Even if the old callback fails, we still have to march on or // else we might leak the intl stuff hooked onto |cx| } if (contextOp == JSCONTEXT_DESTROY) { if (XPCLocaleCallbacks* lc = XPCLocaleCallbacks::MaybeThis(cx)) { // This is a JSContext for which xpc_LocalizeContext() was called. JS_SetLocaleCallbacks(cx, nsnull); delete lc; } } return ok; }
/** Registers a closure of the form callback(cx, userdata) to be called by Spidermonkey's Operation Callback API. * You must *NEVER* call this function from *within* a callback function which has been registered with this facility! * The punishment might just be deadlock! Don't call this function from a different thread/JSContext than the one that * that you're associating the callback with. * * This call may traverse the entire linked list of registrations. Don't add and remove callbacks a lot! * * @returns A pointer that can be used to delete the callback registration at a later time, or NULL on error. */ GPSEEAsyncCallback *gpsee_addAsyncCallback(JSContext *cx, GPSEEAsyncCallbackFunction callback, void *userdata) { gpsee_runtime_t *grt = (gpsee_runtime_t *) JS_GetRuntimePrivate(JS_GetRuntime(cx)); GPSEEAsyncCallback *newcb, **pp; /* Allocate the new callback entry struct */ newcb = JS_malloc(cx, sizeof(GPSEEAsyncCallback)); if (!newcb) { JS_ReportOutOfMemory(cx); return NULL; } /* Initialize the new callback entry struct (except 'next' member, which gets set while we have a lock on the list) */ newcb->callback = callback; newcb->userdata = userdata; newcb->cx = cx; /* Acquire mutex protecting grt->asyncCallbacks */ PR_Lock(grt->asyncCallbacks_lock); /* Insert the new callback into the list */ /* Locate a sorted insertion point into the linked list; sort by 'cx' member */ for (pp = &grt->asyncCallbacks; *pp && (*pp)->cx > cx; pp = &(*pp)->next); /* Insert! */ newcb->next = *pp; *pp = newcb; /* Relinquish mutex */ PR_Unlock(grt->asyncCallbacks_lock); /* If this is the first time this context has had a callback registered, we must register a context callback to clean * up all callbacks associated with this context. Note that we don't want to do this for the primordial context, but * it's a moot point because gpsee_maybeGC() is registered soon after context instantiation and should never be * removed until just before context finalization, anyway. */ if (!newcb->next || newcb->next->cx != cx) gpsee_getContextPrivate(cx, &grt->asyncCallbacks, 0, gpsee_removeAsyncCallbackContext); /* Return a pointer to the new callback entry struct */ return newcb; }
/* * ½«ANSI±àÂëµÄc×Ö·û´®×ª»»ÎªUTF-16±àÂëµÄjs×Ö·û´® */ JSString* c_str_to_js_str( JSContext* cx, const char* v, size_t length /*= -1*/ ) { if (v == nullptr) { return nullptr; } #if 0 JSString* str = JS_NewStringCopyZ(cx, v); #else if (length == -1) { length = strlen(v); } if (length == 0) { return JS_GetEmptyString(JS_GetRuntime(cx)); } JS::RootedString ret(cx); //std::u16string outUtf16; //bool result = UTF8ToUTF16(v, outUtf16); //if (!result) { // return JS_GetEmptyString(JS_GetRuntime(cx)); //} // ANSI -> UTF16 auto len = MultiByteToWideChar(CP_ACP, 0, v, -1, nullptr, 0); WCHAR *utf16Buf = new WCHAR[len]; MultiByteToWideChar(CP_ACP, 0, v, -1, utf16Buf, len); JSString* str = JS_NewUCStringCopyZ(cx, (const jschar*)utf16Buf); delete utf16Buf; #endif return str; }
static void finalize(JSContext* js_context, JSObject* obj) { VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context); if (ruby_context) { JohnsonContext* context; JohnsonRuntime* runtime; Data_Get_Struct(ruby_context, JohnsonContext, context); VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context)); Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime); VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL); // remove the proxy OID from the id map JS_HashTableRemove(runtime->rbids, (void *)self); // free up the ruby value for GC rb_funcall(ruby_runtime, rb_intern("remove_gcthing"), 1, rb_obj_id(self)); } }
static JSBool js_user_constructor(JSContext *cx, uintN argc, jsval *arglist) { JSObject *obj; jsval *argv=JS_ARGV(cx, arglist); int i; int32 val=0; user_t user; private_t* p; scfg_t* scfg; scfg=JS_GetRuntimePrivate(JS_GetRuntime(cx)); obj=JS_NewObject(cx, &js_user_class, NULL, NULL); JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj)); if(argc && (!JS_ValueToInt32(cx,argv[0],&val))) return JS_FALSE; user.number=(ushort)val; if(user.number!=0 && (i=getuserdat(scfg,&user))!=0) { JS_ReportError(cx,"Error %d reading user number %d",i,val); return(JS_FALSE); } if((p=(private_t*)malloc(sizeof(private_t)))==NULL) return(JS_FALSE); memset(p,0,sizeof(private_t)); p->storage = user; p->user = &p->storage; p->cached = (user.number==0 ? FALSE : TRUE); JS_SetPrivate(cx, obj, p); return(JS_TRUE); }
static JSBool js_chk_ar(JSContext *cx, uintN argc, jsval *arglist) { JSObject *obj=JS_THIS_OBJECT(cx, arglist); jsval *argv=JS_ARGV(cx, arglist); uchar* ar; private_t* p; jsrefcount rc; char *ars; scfg_t* scfg; scfg=JS_GetRuntimePrivate(JS_GetRuntime(cx)); JS_SET_RVAL(cx, arglist, JSVAL_VOID); if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) return JS_FALSE; JSVALUE_TO_MSTRING(cx,argv[0], ars, NULL); HANDLE_PENDING(cx); if(ars==NULL) return JS_FALSE; rc=JS_SUSPENDREQUEST(cx); ar = arstr(NULL,ars,scfg); free(ars); js_getuserdat(scfg,p); JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(chk_ar(scfg,ar,p->user,p->client))); if(ar!=NULL && ar!=nular) free(ar); JS_RESUMEREQUEST(cx, rc); return JS_TRUE; }
JSBool gjs_call_function_value(JSContext *context, JSObject *obj, jsval fval, uintN argc, jsval *argv, jsval *rval) { JSBool result; JSContext *call_context; JS_BeginRequest(context); call_context = gjs_runtime_get_call_context(JS_GetRuntime(context)); JS_BeginRequest(call_context); result = JS_CallFunctionValue(call_context, obj, fval, argc, argv, rval); gjs_move_exception(call_context, context); JS_EndRequest(call_context); JS_EndRequest(context); return result; }
NS_IMETHODIMP ArrayBufferInputStream::SetData(const JS::Value& aBuffer, uint32_t aByteOffset, uint32_t aLength, JSContext* aCx) { if (!aBuffer.isObject()) { return NS_ERROR_FAILURE; } JS::RootedObject arrayBuffer(aCx, &aBuffer.toObject()); if (!JS_IsArrayBufferObject(arrayBuffer)) { return NS_ERROR_FAILURE; } mRt = JS_GetRuntime(aCx); mArrayBuffer = aBuffer; JS_AddNamedValueRootRT(mRt, &mArrayBuffer, "mArrayBuffer"); uint32_t buflen = JS_GetArrayBufferByteLength(arrayBuffer); mOffset = std::min(buflen, aByteOffset); mBufferLength = std::min(buflen - mOffset, aLength); mBuffer = JS_GetArrayBufferData(arrayBuffer); return NS_OK; }