void IDBCursor::GetKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult, ErrorResult& aRv) { AssertIsOnOwningThread(); MOZ_ASSERT(!mKey.IsUnset() || !mHaveValue); if (!mHaveValue) { aResult.setUndefined(); return; } if (!mHaveCachedKey) { if (!mRooted) { mozilla::HoldJSObjects(this); mRooted = true; } aRv = mKey.ToJSVal(aCx, mCachedKey); if (NS_WARN_IF(aRv.Failed())) { return; } mHaveCachedKey = true; } JS::ExposeValueToActiveJS(mCachedKey); aResult.set(mCachedKey); }
void IDBCursor::GetPrimaryKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult, ErrorResult& aRv) { AssertIsOnOwningThread(); if (!mHaveValue) { aResult.setUndefined(); return; } if (!mHaveCachedPrimaryKey) { if (!mRooted) { mozilla::HoldJSObjects(this); mRooted = true; } const Key& key = (mType == Type_ObjectStore || mType == Type_ObjectStoreKey) ? mKey : mPrimaryKey; MOZ_ASSERT(!key.IsUnset()); aRv = key.ToJSVal(aCx, mCachedPrimaryKey); if (NS_WARN_IF(aRv.Failed())) { return; } mHaveCachedPrimaryKey = true; } JS::ExposeValueToActiveJS(mCachedPrimaryKey); aResult.set(mCachedPrimaryKey); }
bool ChromeObjectWrapper::get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) { assertEnteredPolicy(cx, wrapper, id); vp.setUndefined(); JSPropertyDescriptor desc; // Only call through to the get trap on the underlying object if we're // allowed to see the property, and if what we'll find is not on a standard // prototype. if (AllowedByBase(cx, wrapper, id, js::Wrapper::GET) && !PropIsFromStandardPrototype(cx, wrapper, id)) { // Call the get trap. if (!ChromeObjectWrapperBase::get(cx, wrapper, receiver, id, vp)) return false; // If we found something, we're done. if (!vp.isUndefined()) return true; } // If we have no proto, we're done. JSObject *wrapperProto; if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) return false; if (!wrapperProto) return true; // Try the prototype. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); return js::GetGeneric(cx, wrapperProto, receiver, id, vp.address()); }
void IDBCursor::GetValue(JSContext* aCx, JS::MutableHandle<JS::Value> aResult, ErrorResult& aRv) { AssertIsOnOwningThread(); MOZ_ASSERT(mType == Type_ObjectStore || mType == Type_Index); if (!mHaveValue) { aResult.setUndefined(); return; } if (!mHaveCachedValue) { if (!mRooted) { mozilla::HoldJSObjects(this); mRooted = true; } JS::Rooted<JS::Value> val(aCx); if (NS_WARN_IF(!IDBObjectStore::DeserializeValue(aCx, mCloneInfo, &val))) { aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR); return; } IDBObjectStore::ClearCloneReadInfo(mCloneInfo); mCachedValue = val; mHaveCachedValue = true; } JS::ExposeValueToActiveJS(mCachedValue); aResult.set(mCachedValue); }
bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) override { aValue.setUndefined(); mServer->mServices.RemoveElement(mService); return true; }
nsresult FileHelper::GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); aVal.setUndefined(); return NS_OK; }
bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { aValue.setUndefined(); const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value(); NS_ENSURE_TRUE(v.type() == BluetoothValue::Tuint32_t, false); aValue.setInt32(static_cast<int32_t>(v.get_uint32_t())); return true; }
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { aValue.setUndefined(); const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value(); if (v.type() != BluetoothValue::Tbool) { BT_WARNING("Not a boolean!"); SetError(NS_LITERAL_STRING("BluetoothReplyTypeError")); return false; } aValue.setBoolean(v.get_bool()); return true; }
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { aValue.setUndefined(); const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value(); if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) { BT_WARNING("Not a BluetoothNamedValue array!"); SetError(NS_LITERAL_STRING("BluetoothReplyTypeError")); return false; } const InfallibleTArray<BluetoothNamedValue>& values = v.get_ArrayOfBluetoothNamedValue(); nsTArray<nsRefPtr<BluetoothDevice> > devices; for (uint32_t i = 0; i < values.Length(); i++) { const BluetoothValue properties = values[i].value(); if (properties.type() != BluetoothValue::TArrayOfBluetoothNamedValue) { BT_WARNING("Not a BluetoothNamedValue array!"); SetError(NS_LITERAL_STRING("BluetoothReplyTypeError")); return false; } nsRefPtr<BluetoothDevice> d = BluetoothDevice::Create(mAdapterPtr->GetOwner(), mAdapterPtr->GetPath(), properties); devices.AppendElement(d); } nsresult rv; nsIScriptContext* sc = mAdapterPtr->GetContextForEventHandlers(&rv); if (!sc) { BT_WARNING("Cannot create script context!"); SetError(NS_LITERAL_STRING("BluetoothScriptContextError")); return false; } AutoPushJSContext cx(sc->GetNativeContext()); JSObject* JsDevices = nullptr; rv = nsTArrayToJSArray(cx, devices, &JsDevices); if (!JsDevices) { BT_WARNING("Cannot create JS array!"); SetError(NS_LITERAL_STRING("BluetoothError")); return false; } aValue.setObject(*JsDevices); return true; }
bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { aValue.setUndefined(); const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value(); if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) { BT_WARNING("Not a BluetoothNamedValue array!"); SetError(NS_LITERAL_STRING("BluetoothReplyTypeError")); return false; } if (!mManagerPtr->GetOwner()) { BT_WARNING("Bluetooth manager was disconnected from owner window."); // Stop to create adapter since owner window of Bluetooth manager was // gone. These is no need to create a DOMEvent target which has no owner // to reply to. return false; } const InfallibleTArray<BluetoothNamedValue>& values = v.get_ArrayOfBluetoothNamedValue(); nsRefPtr<BluetoothAdapter> adapter = BluetoothAdapter::Create(mManagerPtr->GetOwner(), values); nsresult rv; nsIScriptContext* sc = mManagerPtr->GetContextForEventHandlers(&rv); if (!sc) { BT_WARNING("Cannot create script context!"); SetError(NS_LITERAL_STRING("BluetoothScriptContextError")); return false; } AutoPushJSContext cx(sc->GetNativeContext()); JS::Rooted<JSObject*> scope(cx, sc->GetWindowProxy()); JSAutoCompartment ac(cx, scope); rv = nsContentUtils::WrapNative(cx, adapter, aValue); if (NS_FAILED(rv)) { BT_WARNING("Cannot create native object!"); SetError(NS_LITERAL_STRING("BluetoothNativeObjectError")); return false; } return true; }
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { aValue.setUndefined(); const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value(); if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) { BT_WARNING("Not a BluetoothNamedValue array!"); SetError(NS_LITERAL_STRING("BluetoothReplyTypeError")); return false; } const InfallibleTArray<BluetoothNamedValue>& values = v.get_ArrayOfBluetoothNamedValue(); nsTArray<nsRefPtr<BluetoothDevice> > devices; for (uint32_t i = 0; i < values.Length(); i++) { const BluetoothValue properties = values[i].value(); if (properties.type() != BluetoothValue::TArrayOfBluetoothNamedValue) { BT_WARNING("Not a BluetoothNamedValue array!"); SetError(NS_LITERAL_STRING("BluetoothReplyTypeError")); return false; } nsRefPtr<BluetoothDevice> d = BluetoothDevice::Create(mAdapterPtr->GetOwner(), mAdapterPtr->GetPath(), properties); devices.AppendElement(d); } AutoJSAPI jsapi; if (!jsapi.Init(mAdapterPtr->GetOwner())) { BT_WARNING("Failed to initialise AutoJSAPI!"); SetError(NS_LITERAL_STRING("BluetoothAutoJSAPIInitError")); return false; } JSContext* cx = jsapi.cx(); JS::Rooted<JSObject*> JsDevices(cx); if (NS_FAILED(nsTArrayToJSArray(cx, devices, &JsDevices))) { BT_WARNING("Cannot create JS array!"); SetError(NS_LITERAL_STRING("BluetoothError")); return false; } aValue.setObject(*JsDevices); return true; }
bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { aValue.setUndefined(); const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value(); NS_ENSURE_TRUE(v.type() == BluetoothValue::TArrayOfuint8_t, false); AutoJSAPI jsapi; NS_ENSURE_TRUE(jsapi.Init(mCharacteristic->GetParentObject()), false); JSContext* cx = jsapi.cx(); if (!ToJSValue(cx, v.get_ArrayOfuint8_t(), aValue)) { JS_ClearPendingException(cx); return false; } return true; }
/* static */ void ThreadSafeChromeUtils::NondeterministicGetWeakSetKeys(GlobalObject& aGlobal, JS::Handle<JS::Value> aSet, JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv) { if (!aSet.isObject()) { aRetval.setUndefined(); } else { JSContext* cx = aGlobal.Context(); JS::Rooted<JSObject*> objRet(cx); JS::Rooted<JSObject*> setObj(cx, &aSet.toObject()); if (!JS_NondeterministicGetWeakSetKeys(cx, setObj, &objRet)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); } else { aRetval.set(objRet ? JS::ObjectValue(*objRet) : JS::UndefinedValue()); } } }
bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { aValue.setUndefined(); const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value(); NS_ENSURE_TRUE(v.type() == BluetoothValue::TArrayOfnsString, false); const InfallibleTArray<nsString>& uuids = v.get_ArrayOfnsString(); AutoJSAPI jsapi; NS_ENSURE_TRUE(jsapi.Init(mDevice->GetParentObject()), false); JSContext* cx = jsapi.cx(); if (!ToJSValue(cx, uuids, aValue)) { BT_WARNING("Cannot create JS array!"); JS_ClearPendingException(cx); return false; } return true; }
bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { /** * Unwrap BluetoothReply.BluetoothReplySuccess.BluetoothValue = * BluetoothNamedValue[] * | * |__ BluetoothNamedValue = * | {"Adapter", BluetoothValue = BluetoothNamedValue[]} * | * |__ BluetoothNamedValue = * | {"Adapter", BluetoothValue = BluetoothNamedValue[]} * ... */ // Extract the array of all adapters' properties const BluetoothValue& adaptersProperties = mReply->get_BluetoothReplySuccess().value(); NS_ENSURE_TRUE(adaptersProperties.type() == BluetoothValue::TArrayOfBluetoothNamedValue, false); const InfallibleTArray<BluetoothNamedValue>& adaptersPropertiesArray = adaptersProperties.get_ArrayOfBluetoothNamedValue(); BT_API2_LOGR("GetAdaptersTask: len[%d]", adaptersPropertiesArray.Length()); // Append a BluetoothAdapter into adapters array for each properties array uint32_t numAdapters = adaptersPropertiesArray.Length(); for (uint32_t i = 0; i < numAdapters; i++) { MOZ_ASSERT(adaptersPropertiesArray[i].name().EqualsLiteral("Adapter")); const BluetoothValue& properties = adaptersPropertiesArray[i].value(); mManager->AppendAdapter(properties); } aValue.setUndefined(); return true; }
bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) { aValue.setUndefined(); AutoJSAPI jsapi; NS_ENSURE_TRUE(jsapi.Init(mAdapter->GetParentObject()), false); JSContext* cx = jsapi.cx(); /** * Create a new discovery handle and wrap it to return. Each * discovery handle is one-time-use only. */ nsRefPtr<BluetoothDiscoveryHandle> discoveryHandle = BluetoothDiscoveryHandle::Create(mAdapter->GetParentObject()); if (!ToJSValue(cx, discoveryHandle, aValue)) { JS_ClearPendingException(cx); return false; } // Set the created discovery handle as the one in use. mAdapter->SetDiscoveryHandleInUse(discoveryHandle); return true; }
nsresult nsJSUtils::EvaluateString(JSContext* aCx, JS::SourceBufferHolder& aSrcBuf, JS::Handle<JSObject*> aScopeObject, JS::CompileOptions& aCompileOptions, const EvaluateOptions& aEvaluateOptions, JS::MutableHandle<JS::Value> aRetValue, void **aOffThreadToken) { PROFILER_LABEL("nsJSUtils", "EvaluateString", js::ProfileEntry::Category::JS); MOZ_ASSERT_IF(aCompileOptions.versionSet, aCompileOptions.version != JSVERSION_UNKNOWN); MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, aEvaluateOptions.needResult); MOZ_ASSERT_IF(!aEvaluateOptions.reportUncaught, aEvaluateOptions.needResult); MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext()); MOZ_ASSERT(aSrcBuf.get()); // Unfortunately, the JS engine actually compiles scripts with a return value // in a different, less efficient way. Furthermore, it can't JIT them in many // cases. So we need to be explicitly told whether the caller cares about the // return value. Callers can do this by calling the other overload of // EvaluateString() which calls this function with aEvaluateOptions.needResult // set to false. aRetValue.setUndefined(); JS::ExposeObjectToActiveJS(aScopeObject); nsAutoMicroTask mt; nsresult rv = NS_OK; bool ok = false; nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); NS_ENSURE_TRUE(ssm->ScriptAllowed(js::GetGlobalForObjectCrossCompartment(aScopeObject)), NS_OK); mozilla::Maybe<AutoDontReportUncaught> dontReport; if (!aEvaluateOptions.reportUncaught) { // We need to prevent AutoLastFrameCheck from reporting and clearing // any pending exceptions. dontReport.emplace(aCx); } // Scope the JSAutoCompartment so that we can later wrap the return value // into the caller's cx. { JSAutoCompartment ac(aCx, aScopeObject); JS::Rooted<JSObject*> rootedScope(aCx, aScopeObject); if (aOffThreadToken) { JS::Rooted<JSScript*> script(aCx, JS::FinishOffThreadScript(aCx, JS_GetRuntime(aCx), *aOffThreadToken)); *aOffThreadToken = nullptr; // Mark the token as having been finished. if (script) { if (aEvaluateOptions.needResult) { ok = JS_ExecuteScript(aCx, rootedScope, script, aRetValue); } else { ok = JS_ExecuteScript(aCx, rootedScope, script); } } else { ok = false; } } else { if (aEvaluateOptions.needResult) { ok = JS::Evaluate(aCx, rootedScope, aCompileOptions, aSrcBuf, aRetValue); } else { ok = JS::Evaluate(aCx, rootedScope, aCompileOptions, aSrcBuf); } } if (ok && aEvaluateOptions.coerceToString && !aRetValue.isUndefined()) { JS::Rooted<JS::Value> value(aCx, aRetValue); JSString* str = JS::ToString(aCx, value); ok = !!str; aRetValue.set(ok ? JS::StringValue(str) : JS::UndefinedValue()); } } if (!ok) { if (aEvaluateOptions.reportUncaught) { ReportPendingException(aCx); if (aEvaluateOptions.needResult) { aRetValue.setUndefined(); } } else { rv = JS_IsExceptionPending(aCx) ? NS_ERROR_FAILURE : NS_ERROR_OUT_OF_MEMORY; JS::Rooted<JS::Value> exn(aCx); JS_GetPendingException(aCx, &exn); if (aEvaluateOptions.needResult) { aRetValue.set(exn); } JS_ClearPendingException(aCx); } } // Wrap the return value into whatever compartment aCx was in. if (aEvaluateOptions.needResult) { JS::Rooted<JS::Value> v(aCx, aRetValue); if (!JS_WrapValue(aCx, &v)) { return NS_ERROR_OUT_OF_MEMORY; } aRetValue.set(v); } return rv; }
nsresult nsJSUtils::EvaluateString(JSContext* aCx, JS::SourceBufferHolder& aSrcBuf, JS::Handle<JSObject*> aEvaluationGlobal, JS::CompileOptions& aCompileOptions, const EvaluateOptions& aEvaluateOptions, JS::MutableHandle<JS::Value> aRetValue, void **aOffThreadToken) { PROFILER_LABEL("nsJSUtils", "EvaluateString", js::ProfileEntry::Category::JS); MOZ_ASSERT(JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting(), "Caller must own error reporting"); MOZ_ASSERT_IF(aCompileOptions.versionSet, aCompileOptions.version != JSVERSION_UNKNOWN); MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext()); MOZ_ASSERT(aSrcBuf.get()); MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) == aEvaluationGlobal); MOZ_ASSERT_IF(aOffThreadToken, aCompileOptions.noScriptRval); MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(nsContentUtils::IsInMicroTask()); // Unfortunately, the JS engine actually compiles scripts with a return value // in a different, less efficient way. Furthermore, it can't JIT them in many // cases. So we need to be explicitly told whether the caller cares about the // return value. Callers can do this by calling the other overload of // EvaluateString() which calls this function with // aCompileOptions.noScriptRval set to true. aRetValue.setUndefined(); nsresult rv = NS_OK; nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); NS_ENSURE_TRUE(ssm->ScriptAllowed(aEvaluationGlobal), NS_OK); bool ok = true; // Scope the JSAutoCompartment so that we can later wrap the return value // into the caller's cx. { JSAutoCompartment ac(aCx, aEvaluationGlobal); // Now make sure to wrap the scope chain into the right compartment. JS::AutoObjectVector scopeChain(aCx); if (!scopeChain.reserve(aEvaluateOptions.scopeChain.length())) { return NS_ERROR_OUT_OF_MEMORY; } for (size_t i = 0; i < aEvaluateOptions.scopeChain.length(); ++i) { JS::ExposeObjectToActiveJS(aEvaluateOptions.scopeChain[i]); scopeChain.infallibleAppend(aEvaluateOptions.scopeChain[i]); if (!JS_WrapObject(aCx, scopeChain[i])) { ok = false; break; } } if (ok && aOffThreadToken) { JS::Rooted<JSScript*> script(aCx, JS::FinishOffThreadScript(aCx, JS_GetRuntime(aCx), *aOffThreadToken)); *aOffThreadToken = nullptr; // Mark the token as having been finished. if (script) { ok = JS_ExecuteScript(aCx, scopeChain, script); } else { ok = false; } } else if (ok) { ok = JS::Evaluate(aCx, scopeChain, aCompileOptions, aSrcBuf, aRetValue); } } if (!ok) { if (JS_IsExceptionPending(aCx)) { rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW; } else { rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE; } if (!aCompileOptions.noScriptRval) { aRetValue.setUndefined(); } } // Wrap the return value into whatever compartment aCx was in. if (ok && !aCompileOptions.noScriptRval) { if (!JS_WrapValue(aCx, aRetValue)) { return NS_ERROR_OUT_OF_MEMORY; } } return rv; }