NS_IMETHODIMP nsAndroidBridge::HandleGeckoMessage(JS::HandleValue val, JSContext *cx) { if (val.isObject()) { JS::RootedObject object(cx, &val.toObject()); AndroidBridge::Bridge()->HandleGeckoMessage(cx, object); return NS_OK; } // Now handle legacy JSON messages. if (!val.isString()) { return NS_ERROR_INVALID_ARG; } JS::RootedString jsonStr(cx, val.toString()); JS::RootedValue jsonVal(cx); if (!JS_ParseJSON(cx, jsonStr, &jsonVal) || !jsonVal.isObject()) { return NS_ERROR_INVALID_ARG; } // Spit out a warning before sending the message. nsContentUtils::ReportToConsoleNonLocalized( NS_LITERAL_STRING("Use of JSON is deprecated. " "Please pass Javascript objects directly to handleGeckoMessage."), nsIScriptError::warningFlag, NS_LITERAL_CSTRING("nsIAndroidBridge"), nullptr); JS::RootedObject object(cx, &jsonVal.toObject()); AndroidBridge::Bridge()->HandleGeckoMessage(cx, object); return NS_OK; }
NS_IMETHODIMP calDateTime::SetJsDate(JSContext* aCx, JS::HandleValue aDate) { if (!aDate.isObject()) { mIsValid = false; return NS_OK; } JS::Rooted<JSObject*> dobj(aCx, &aDate.toObject()); dobj = js::CheckedUnwrap(dobj); if (!dobj) { mIsValid = false; return NS_OK; } JSAutoCompartment ac(aCx, dobj); if (!JS_ObjectIsDate(aCx, dobj) || !js_DateIsValid(dobj)) { mIsValid = false; return NS_OK; } PRTime utcTime = PRTime(js_DateGetMsecSinceEpoch(dobj)) * 1000; mIsValid = NS_SUCCEEDED(SetNativeTime(utcTime)); return NS_OK; }
template<> bool ScriptInterface::FromJSVal<std::wstring>(JSContext* cx, JS::HandleValue v, std::wstring& out) { JSAutoRequest rq(cx); WARN_IF_NOT(v.isString() || v.isNumber(), v); // allow implicit number conversions JS::RootedString str(cx, JS::ToString(cx, v)); if (!str) FAIL("Argument must be convertible to a string"); if (JS_StringHasLatin1Chars(str)) { size_t length; JS::AutoCheckCannotGC nogc; const JS::Latin1Char* ch = JS_GetLatin1StringCharsAndLength(cx, nogc, str, &length); if (!ch) FAIL("JS_GetLatin1StringCharsAndLength failed"); out.assign(ch, ch + length); } else { size_t length; JS::AutoCheckCannotGC nogc; const char16_t* ch = JS_GetTwoByteStringCharsAndLength(cx, nogc, str, &length); if (!ch) FAIL("JS_GetTwoByteStringsCharsAndLength failed"); // out of memory out.assign(ch, ch + length); } return true; }
void CodeInfo::construct(JSContext* cx, JS::CallArgs args) { uassert(ErrorCodes::BadValue, "Code needs 0, 1 or 2 arguments", args.length() == 0 || args.length() == 1 || args.length() == 2); auto scope = getScope(cx); JS::RootedObject thisv(cx); scope->getProto<CodeInfo>().newObject(&thisv); ObjectWrapper o(cx, thisv); if (args.length() == 0) { o.setString(InternedString::code, ""); } else if (args.length() == 1) { JS::HandleValue codeArg = args.get(0); if (!codeArg.isString()) uasserted(ErrorCodes::BadValue, "code must be a string"); o.setValue(InternedString::code, codeArg); } else { if (!args.get(0).isString()) uasserted(ErrorCodes::BadValue, "code must be a string"); if (!args.get(1).isObject()) uasserted(ErrorCodes::BadValue, "scope must be an object"); o.setValue(InternedString::code, args.get(0)); o.setValue(InternedString::scope, args.get(1)); } args.rval().setObjectOrNull(thisv); }
template<typename T> static bool FromJSVal_vector(JSContext* cx, JS::HandleValue v, std::vector<T>& out) { JSAutoRequest rq(cx); JS::RootedObject obj(cx); if (!v.isObject()) FAIL("Argument must be an array"); obj = &v.toObject(); if (!(JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj))) FAIL("Argument must be an array"); u32 length; if (!JS_GetArrayLength(cx, obj, &length)) FAIL("Failed to get array length"); out.reserve(length); for (u32 i = 0; i < length; ++i) { JS::RootedValue el(cx); if (!JS_GetElement(cx, obj, i, &el)) FAIL("Failed to read array element"); T el2; if (!ScriptInterface::FromJSVal<T>(cx, el, el2)) return false; out.push_back(el2); } return true; }
bool js_to_bool( JSContext *cx, JS::HandleValue vp, bool *ret ) { bool ok = vp.isBoolean(); if (ok) { *ret = vp.toBoolean(); } return ok; }
template<> bool ScriptInterface::FromJSVal<Entity>(JSContext* cx, JS::HandleValue v, Entity& out) { JSAutoRequest rq(cx); if (!v.isObject()) FAIL("Argument must be an object"); JS::RootedObject obj(cx, &v.toObject()); JS::RootedValue templateName(cx); JS::RootedValue id(cx); JS::RootedValue player(cx); JS::RootedValue position(cx); JS::RootedValue rotation(cx); // TODO: Report type errors if (!JS_GetProperty(cx, obj, "player", &player) || !FromJSVal(cx, player, out.playerID)) FAIL("Failed to read Entity.player property"); if (!JS_GetProperty(cx, obj, "templateName", &templateName) || !FromJSVal(cx, templateName, out.templateName)) FAIL("Failed to read Entity.templateName property"); if (!JS_GetProperty(cx, obj, "id", &id) || !FromJSVal(cx, id, out.entityID)) FAIL("Failed to read Entity.id property"); if (!JS_GetProperty(cx, obj, "position", &position) || !FromJSVal(cx, position, out.position)) FAIL("Failed to read Entity.position property"); if (!JS_GetProperty(cx, obj, "rotation", &rotation) || !FromJSVal(cx, rotation, out.rotation)) FAIL("Failed to read Entity.rotation property"); return true; }
bool JavaScriptShared::toVariant(JSContext *cx, JS::HandleValue from, JSVariant *to) { switch (JS_TypeOfValue(cx, from)) { case JSTYPE_VOID: *to = UndefinedVariant(); return true; case JSTYPE_OBJECT: case JSTYPE_FUNCTION: { RootedObject obj(cx, from.toObjectOrNull()); if (!obj) { MOZ_ASSERT(from == JSVAL_NULL); *to = NullVariant(); return true; } if (xpc_JSObjectIsID(cx, obj)) { JSIID iid; const nsID *id = xpc_JSObjectToID(cx, obj); ConvertID(*id, &iid); *to = iid; return true; } ObjectVariant objVar; if (!toObjectVariant(cx, obj, &objVar)) return false; *to = objVar; return true; } case JSTYPE_STRING: { nsAutoJSString autoStr; if (!autoStr.init(cx, from)) return false; *to = autoStr; return true; } case JSTYPE_NUMBER: if (from.isInt32()) *to = double(from.toInt32()); else *to = from.toDouble(); return true; case JSTYPE_BOOLEAN: *to = from.toBoolean(); return true; default: MOZ_ASSERT(false); return false; } }
bool js_to_number(JSContext *cx, JS::HandleValue v, double *dp) { if (v.isNumber()) { *dp = v.toNumber(); return true; } else { *dp = 0; return false; } }
bool GetOVRStringVal(JSContext* cx, JS::HandleValue val, OVR::String* out) { if (!val.isString()) { JS_ReportError(cx, "Expected a string"); return false; } JS::RootedString str(cx, val.toString()); bool resp = GetOVRString(cx, str, out); return resp; }
bool ScriptInterface::SetPrototype(JS::HandleValue objVal, JS::HandleValue protoVal) { JSAutoRequest rq(m->m_cx); if (!objVal.isObject() || !protoVal.isObject()) return false; JS::RootedObject obj(m->m_cx, &objVal.toObject()); JS::RootedObject proto(m->m_cx, &protoVal.toObject()); return JS_SetPrototype(m->m_cx, obj, proto); }
bool ScriptInterface::EnumeratePropertyNamesWithPrefix(JS::HandleValue objVal, const char* prefix, std::vector<std::string>& out) { JSAutoRequest rq(m->m_cx); if (!objVal.isObjectOrNull()) { LOGERROR("EnumeratePropertyNamesWithPrefix expected object type!"); return false; } if(objVal.isNull()) return true; // reached the end of the prototype chain JS::RootedObject obj(m->m_cx, &objVal.toObject()); JS::RootedObject it(m->m_cx, JS_NewPropertyIterator(m->m_cx, obj)); if (!it) return false; while (true) { JS::RootedId idp(m->m_cx); JS::RootedValue val(m->m_cx); if (! JS_NextProperty(m->m_cx, it, idp.address()) || ! JS_IdToValue(m->m_cx, idp, &val)) return false; if (val.isUndefined()) break; // end of iteration if (!val.isString()) continue; // ignore integer properties JS::RootedString name(m->m_cx, val.toString()); size_t len = strlen(prefix)+1; std::vector<char> buf(len); size_t prefixLen = strlen(prefix) * sizeof(char); JS_EncodeStringToBuffer(m->m_cx, name, &buf[0], prefixLen); buf[len-1]= '\0'; if(0 == strcmp(&buf[0], prefix)) { size_t len; const jschar* chars = JS_GetStringCharsAndLength(m->m_cx, name, &len); out.push_back(std::string(chars, chars+len)); } } // Recurse up the prototype chain JS::RootedObject prototype(m->m_cx); if (JS_GetPrototype(m->m_cx, obj, &prototype)) { JS::RootedValue prototypeVal(m->m_cx, JS::ObjectOrNullValue(prototype)); if (! EnumeratePropertyNamesWithPrefix(prototypeVal, prefix, out)) return false; } return true; }
bool ScriptInterface::GetProperty_(JS::HandleValue obj, const char* name, JS::MutableHandleValue out) { JSAutoRequest rq(m->m_cx); if (!obj.isObject()) return false; JS::RootedObject object(m->m_cx, &obj.toObject()); if (!JS_GetProperty(m->m_cx, object, name, out)) return false; return true; }
void CStdDeserializer::ScriptObjectAppend(const char* name, JS::HandleValue objVal) { JSContext* cx = m_ScriptInterface.GetContext(); JSAutoRequest rq(cx); if (!objVal.isObject()) throw PSERROR_Deserialize_ScriptError(); JS::RootedObject obj(cx, &objVal.toObject()); ReadScriptVal(name, obj); }
bool ScriptInterface::GetPropertyInt_(JS::HandleValue obj, int name, JS::MutableHandleValue out) { JSAutoRequest rq(m->m_cx); JS::RootedId nameId(m->m_cx, INT_TO_JSID(name)); if (!obj.isObject()) return false; JS::RootedObject object(m->m_cx, &obj.toObject()); if (!JS_GetPropertyById(m->m_cx, object, nameId, out)) return false; return true; }
bool ScriptInterface::HasProperty(JS::HandleValue obj, const char* name) { // TODO: proper errorhandling JSAutoRequest rq(m->m_cx); if (!obj.isObject()) return false; JS::RootedObject object(m->m_cx, &obj.toObject()); bool found; if (!JS_HasProperty(m->m_cx, object, name, &found)) return false; return found; }
void ScriptInterface::CallConstructor(JS::HandleValue ctor, JS::HandleValueArray argv, JS::MutableHandleValue out) { JSAutoRequest rq(m->m_cx); if (!ctor.isObject()) { LOGERROR("CallConstructor: ctor is not an object"); out.setNull(); return; } JS::RootedObject ctorObj(m->m_cx, &ctor.toObject()); out.setObjectOrNull(JS_New(m->m_cx, ctorObj, argv)); }
bool jsval_to_std_string(JSContext *cx, JS::HandleValue v, std::string* ret) { if(v.isString() || v.isNumber()) { JSString *tmp = JS::ToString(cx, v); JSB_PRECONDITION3(tmp, cx, false, "Error processing jsval_to_std_string"); JSStringWrapper str(tmp, cx); *ret = str.get(); return true; } return false; }
bool ScriptInterface::FreezeObject(JS::HandleValue objVal, bool deep) { JSAutoRequest rq(m->m_cx); if (!objVal.isObject()) return false; JS::RootedObject obj(m->m_cx, &objVal.toObject()); if (deep) return JS_DeepFreezeObject(m->m_cx, obj); else return JS_FreezeObject(m->m_cx, obj); }
template<> bool ScriptInterface::FromJSVal<std::string>(JSContext* cx, JS::HandleValue v, std::string& out) { JSAutoRequest rq(cx); WARN_IF_NOT(v.isString() || v.isNumber(), v); // allow implicit number conversions JS::RootedString str(cx, JS::ToString(cx, v)); if (!str) FAIL("Argument must be convertible to a string"); char* ch = JS_EncodeString(cx, str); // chops off high byte of each char16_t if (!ch) FAIL("JS_EncodeString failed"); // out of memory out.assign(ch, ch + JS_GetStringLength(str)); JS_free(cx, ch); return true; }
template<> bool ScriptInterface::FromJSVal<bool>(JSContext* cx, JS::HandleValue v, bool& out) { JSAutoRequest rq(cx); WARN_IF_NOT(v.isBoolean(), v); out = JS::ToBoolean(v); return true; }
bool jsval_to_physics3DRigidBodyDes(JSContext* cx, JS::HandleValue v, Physics3DRigidBodyDes* des) { JS::RootedObject jsobj(cx, v.toObjectOrNull()); JS::RootedValue tmp(cx); if(JS_GetProperty(cx, jsobj, "mass", &tmp)) { des->mass = tmp.toNumber(); } if(JS_GetProperty(cx, jsobj, "shape", &tmp)) { JS::RootedObject tmpObj(cx, tmp.toObjectOrNull()); js_proxy_t* proxy = jsb_get_js_proxy(tmpObj); des->shape = proxy ? (cocos2d::Physics3DShape*)proxy->ptr : nullptr; } if(JS_GetProperty(cx, jsobj, "localInertia", &tmp)) { Vec3 v3; jsval_to_vector3(cx, tmp, &v3); des->localInertia = v3; } if(JS_GetProperty(cx, jsobj, "originalTransform", &tmp)) { Mat4 m4; jsval_to_matrix(cx, tmp, &m4); des->originalTransform = m4; } if(JS_GetProperty(cx, jsobj, "disableSleep", &tmp)) { des->disableSleep = tmp.toBoolean(); } return true; }
bool jsval_to_animationInfo(JSContext* cx, JS::HandleValue vp, cocostudio::timeline::AnimationInfo* ret) { JS::RootedObject tmp(cx); JS::RootedValue jsName(cx); JS::RootedValue jsStartId(cx); JS::RootedValue jsEndId(cx); std::string name; double startIndex, endIndex; bool ok = vp.isObject() && JS_ValueToObject(cx, vp, &tmp) && JS_GetProperty(cx, tmp, "name", &jsName) && JS_GetProperty(cx, tmp, "startIndex", &jsStartId) && JS_GetProperty(cx, tmp, "endIndex", &jsEndId) && JS::ToNumber(cx, jsStartId, &startIndex) && JS::ToNumber(cx, jsEndId, &endIndex) && jsval_to_std_string(cx, jsName, &name) && !std::isnan(startIndex) && !std::isnan(endIndex); JSB_PRECONDITION3(ok, cx, false, "Error processing arguments"); ret->name = name; ret->startIndex = (int)startIndex; ret->endIndex = (int)endIndex; return true; }
void JSListenerBase::setJSDelegate(JSContext *cx, JS::HandleValue func) { if (nullptr != proFunc) { delete proFunc; proFunc = nullptr; } proFunc = new JS::PersistentRootedObject(cx, func.toObjectOrNull()); }
nsresult TranslateChoices( JS::HandleValue aChoices, const nsTArray<PermissionRequest>& aPermissionRequests, nsTArray<PermissionChoice>& aTranslatedChoices) { if (aChoices.isNullOrUndefined()) { // No choice is specified. } else if (aChoices.isObject()) { // Iterate through all permission types. for (uint32_t i = 0; i < aPermissionRequests.Length(); ++i) { nsCString type = aPermissionRequests[i].type(); JS::Rooted<JSObject*> obj(RootingCx(), &aChoices.toObject()); // People really shouldn't be passing WindowProxy or Location // objects for the choices here. obj = js::CheckedUnwrapStatic(obj); if (!obj) { return NS_ERROR_FAILURE; } AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); JSAutoRealm ar(cx, obj); JS::Rooted<JS::Value> val(cx); if (!JS_GetProperty(cx, obj, type.BeginReading(), &val) || !val.isString()) { // no setting for the permission type, clear exception and skip it jsapi.ClearException(); } else { nsAutoJSString choice; if (!choice.init(cx, val)) { jsapi.ClearException(); return NS_ERROR_FAILURE; } aTranslatedChoices.AppendElement(PermissionChoice(type, choice)); } } } else { MOZ_ASSERT(false, "SelectedChoices should be undefined or an JS object"); return NS_ERROR_FAILURE; } return NS_OK; }
template<> bool ScriptInterface::FromJSVal<u16>(JSContext* cx, JS::HandleValue v, u16& out) { JSAutoRequest rq(cx); WARN_IF_NOT(v.isNumber(), v); if (!JS::ToUint16(cx, v, &out)) return false; return true; }
NS_IMETHODIMP DesktopNotificationRequest::Allow(JS::HandleValue aChoices) { MOZ_ASSERT(aChoices.isUndefined()); nsresult rv = mDesktopNotification->SetAllow(true); mDesktopNotification = nullptr; return rv; }
bool ScriptInterface::SetPropertyInt_(JS::HandleValue obj, int name, JS::HandleValue value, bool constant, bool enumerate) { JSAutoRequest rq(m->m_cx); uint attrs = 0; if (constant) attrs |= JSPROP_READONLY | JSPROP_PERMANENT; if (enumerate) attrs |= JSPROP_ENUMERATE; if (!obj.isObject()) return false; JS::RootedObject object(m->m_cx, &obj.toObject()); if (! JS_DefinePropertyById(m->m_cx, object, INT_TO_JSID(name), value, NULL, NULL, attrs)) return false; return true; }
template<> bool ScriptInterface::FromJSVal<CFixedVector2D>(JSContext* cx, JS::HandleValue v, CFixedVector2D& out) { JSAutoRequest rq(cx); if (!v.isObject()) return false; // TODO: report type error JS::RootedObject obj(cx, &v.toObject()); JS::RootedValue p(cx); if (!JS_GetProperty(cx, obj, "x", &p)) return false; // TODO: report type errors if (!FromJSVal(cx, p, out.X)) return false; if (!JS_GetProperty(cx, obj, "y", &p)) return false; if (!FromJSVal(cx, p, out.Y)) return false; return true; }
NS_IMETHODIMP FileSystemPermissionRequest::Allow(JS::HandleValue aChoices) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aChoices.isUndefined()); ScheduleTask(); return NS_OK; }