bool document_resolve(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp) { // If id is "all", resolve document.all=true. JS::RootedValue v(cx); if (!JS_IdToValue(cx, id, &v)) return false; if (JSVAL_IS_STRING(v)) { JSString *str = JSVAL_TO_STRING(v); JSFlatString *flatStr = JS_FlattenString(cx, str); if (!flatStr) return false; if (JS_FlatStringEqualsAscii(flatStr, "all")) { JS::Rooted<JSObject*> docAll(cx, JS_NewObject(cx, &DocumentAllClass, JS::NullPtr(), JS::NullPtr())); if (!docAll) return false; JS::Rooted<JS::Value> allValue(cx, ObjectValue(*docAll)); bool ok = JS_DefinePropertyById(cx, obj, id, allValue, nullptr, nullptr, 0); objp.set(ok ? obj.get() : nullptr); return ok; } } objp.set(nullptr); return true; }
bool JavaScriptShared::Unwrap(JSContext* cx, const InfallibleTArray<CpowEntry>& aCpows, JS::MutableHandleObject objp) { objp.set(nullptr); if (!aCpows.Length()) return true; RootedObject obj(cx, JS_NewPlainObject(cx)); if (!obj) return false; RootedValue v(cx); RootedString str(cx); for (size_t i = 0; i < aCpows.Length(); i++) { const nsString& name = aCpows[i].name(); if (!fromVariant(cx, aCpows[i].value(), &v)) return false; if (!JS_DefineUCProperty(cx, obj, name.BeginReading(), name.Length(), v, JSPROP_ENUMERATE)) { return false; } } objp.set(obj); return true; }
void CStdDeserializer::GetSerializablePrototype(const std::wstring& name, JS::MutableHandleObject ret) { std::map<std::wstring, JS::Heap<JSObject*> >::iterator it = m_SerializablePrototypes.find(name); if (it != m_SerializablePrototypes.end()) ret.set(it->second); else ret.set(NULL); }
bool doResolve(JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp) { CHECK_EQUAL(resolveExitCount, 0); AutoIncrCounters incr(this); CHECK_EQUAL(obj, obj1 || obj == obj2); CHECK(JSID_IS_STRING(id)); JSFlatString *str = JS_FlattenString(cx, JSID_TO_STRING(id)); CHECK(str); JS::RootedValue v(cx); if (JS_FlatStringEqualsAscii(str, "x")) { if (obj == obj1) { /* First resolve hook invocation. */ CHECK_EQUAL(resolveEntryCount, 1); EVAL("obj2.y = true", v.address()); CHECK_SAME(v, JSVAL_TRUE); CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_FALSE, NULL, NULL, 0)); objp.set(obj); return true; } if (obj == obj2) { CHECK_EQUAL(resolveEntryCount, 4); objp.set(NULL); return true; } } else if (JS_FlatStringEqualsAscii(str, "y")) { if (obj == obj2) { CHECK_EQUAL(resolveEntryCount, 2); CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_NULL, NULL, NULL, 0)); EVAL("obj1.x", v.address()); CHECK(JSVAL_IS_VOID(v)); EVAL("obj1.y", v.address()); CHECK_SAME(v, JSVAL_ZERO); objp.set(obj); return true; } if (obj == obj1) { CHECK_EQUAL(resolveEntryCount, 3); EVAL("obj1.x", v.address()); CHECK(JSVAL_IS_VOID(v)); EVAL("obj1.y", v.address()); CHECK(JSVAL_IS_VOID(v)); EVAL("obj2.y", v.address()); CHECK(JSVAL_IS_NULL(v)); EVAL("obj2.x", v.address()); CHECK(JSVAL_IS_VOID(v)); EVAL("obj1.y = 0", v.address()); CHECK_SAME(v, JSVAL_ZERO); objp.set(obj); return true; } } CHECK(false); return false; }
void get_or_create_js_obj(JSContext* cx, JS::HandleObject obj, const std::string &name, JS::MutableHandleObject jsObj) { JS::RootedValue nsval(cx); JS_GetProperty(cx, obj, name.c_str(), &nsval); if (nsval == JSVAL_VOID) { jsObj.set(JS_NewObject(cx, NULL, NULL, NULL)); nsval = OBJECT_TO_JSVAL(jsObj); JS_SetProperty(cx, obj, name.c_str(), nsval); } else { jsObj.set(nsval.toObjectOrNull()); } }
bool XPCWrappedNativeScope::GetComponentsJSObject(JS::MutableHandleObject obj) { AutoJSContext cx; if (!mComponents) { nsIPrincipal* p = GetPrincipal(); bool system = nsXPConnect::SecurityManager()->IsSystemPrincipal(p); mComponents = system ? new nsXPCComponents(this) : new nsXPCComponentsBase(this); } RootedValue val(cx); xpcObjectHelper helper(mComponents); bool ok = XPCConvert::NativeInterface2JSObject(&val, nullptr, helper, nullptr, nullptr, false, nullptr); if (NS_WARN_IF(!ok)) return false; if (NS_WARN_IF(!val.isObject())) return false; // The call to wrap() here is necessary even though the object is same- // compartment, because it applies our security wrapper. obj.set(&val.toObject()); if (NS_WARN_IF(!JS_WrapObject(cx, obj))) return false; return true; }
static bool env_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags, JS::MutableHandleObject objp) { JSString *idstr, *valstr; RootedValue idval(cx); if (!JS_IdToValue(cx, id, &idval)) return false; idstr = ToString(cx, idval); if (!idstr) return false; JSAutoByteString name(cx, idstr); if (!name) return false; const char *value = getenv(name.ptr()); if (value) { valstr = JS_NewStringCopyZ(cx, value); if (!valstr) return false; if (!JS_DefinePropertyById(cx, obj, id, STRING_TO_JSVAL(valstr), nullptr, nullptr, JSPROP_ENUMERATE)) { return false; } objp.set(obj); } return true; }
bool FilteringWrapper<Base, Policy>::getPrototypeOf(JSContext* cx, JS::HandleObject wrapper, JS::MutableHandleObject protop) const { // Filtering wrappers do not allow access to the prototype. protop.set(nullptr); return true; }
static void PreWrap(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj, JS::HandleObject objectPassedToWrap, JS::MutableHandleObject retObj) { JS_GC(cx); retObj.set(obj); }
bool CrossOriginXrayWrapper::getPrototypeOf(JSContext *cx, JS::HandleObject wrapper, JS::MutableHandleObject protop) const { // Cross-origin objects have null prototypes. protop.set(nullptr); return true; }
static JSBool fundamental_instance_new_resolve_interface(JSContext *context, JS::HandleObject obj, JS::MutableHandleObject objp, Fundamental *proto_priv, char *name) { GIFunctionInfo *method_info; JSBool ret; GType *interfaces; guint n_interfaces; guint i; ret = JS_TRUE; interfaces = g_type_interfaces(proto_priv->gtype, &n_interfaces); for (i = 0; i < n_interfaces; i++) { GIBaseInfo *base_info; GIInterfaceInfo *iface_info; base_info = g_irepository_find_by_gtype(g_irepository_get_default(), interfaces[i]); if (base_info == NULL) continue; /* An interface GType ought to have interface introspection info */ g_assert(g_base_info_get_type(base_info) == GI_INFO_TYPE_INTERFACE); iface_info = (GIInterfaceInfo *) base_info; method_info = g_interface_info_find_method(iface_info, name); g_base_info_unref(base_info); if (method_info != NULL) { if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { if (gjs_define_function(context, obj, proto_priv->gtype, (GICallableInfo *) method_info)) { objp.set(obj); } else { ret = JS_FALSE; } } g_base_info_unref((GIBaseInfo *) method_info); } } g_free(interfaces); return ret; }
static bool interface_new_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp) { Interface *priv; char *name; bool ret = false; GIFunctionInfo *method_info; if (!gjs_get_string_id(context, id, &name)) return true; priv = priv_from_js(context, obj); if (priv == NULL) goto out; /* If we have no GIRepository information then this interface was defined * from within GJS. In that case, it has no properties that need to be * resolved from within C code, as interfaces cannot inherit. */ if (priv->info == NULL) { ret = true; goto out; } method_info = g_interface_info_find_method((GIInterfaceInfo*) priv->info, name); if (method_info != NULL) { if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { if (gjs_define_function(context, obj, priv->gtype, (GICallableInfo*)method_info) == NULL) { g_base_info_unref((GIBaseInfo*)method_info); goto out; } objp.set(obj); } g_base_info_unref((GIBaseInfo*)method_info); } ret = true; out: g_free (name); return ret; }
bool ScriptInterface::GetProperty(JS::HandleValue obj, const char* name, JS::MutableHandleObject out) { JSContext* cx = GetContext(); JSAutoRequest rq(cx); JS::RootedValue val(cx); if (!GetProperty_(obj, name, &val)) return false; if (!val.isObject()) { LOGERROR("GetProperty failed: trying to get an object, but the property is not an object!"); return false; } out.set(&val.toObject()); return true; }
/* * 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, JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp) { Importer *priv; std::string name; JSBool ret = JS_TRUE; jsid module_init_name; module_init_name = gjs_context_get_const_string(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 (name == "valueOf" || name == "toString" || name == "__iterator__") goto out; priv = priv_from_js(context, obj); // std::cout << "Resolve prop '" << name << "' hook obj " << (uint32_t)*obj << " priv " << (uint32_t)priv << "\n"; 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.set(obj); } else { ret = JS_FALSE; } JS_EndRequest(context); out: return ret; }
bool StructuredCloneHelper::ReadTransferCallback(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag, void* aContent, uint64_t aExtraData, JS::MutableHandleObject aReturnObject) { MOZ_ASSERT(mSupportsTransferring); if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) { // This can be null. nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mParent); MOZ_ASSERT(aExtraData < mPortIdentifiers.Length()); const MessagePortIdentifier& portIdentifier = mPortIdentifiers[aExtraData]; // aExtraData is the index of this port identifier. ErrorResult rv; nsRefPtr<MessagePort> port = MessagePort::Create(window, portIdentifier, rv); if (NS_WARN_IF(rv.Failed())) { return false; } mTransferredPorts.AppendElement(port); JS::Rooted<JS::Value> value(aCx); if (!GetOrCreateDOMReflector(aCx, port, &value)) { JS_ClearPendingException(aCx); return false; } aReturnObject.set(&value.toObject()); return true; } return false; }
void getJsObjOrCreat(JSContext* cx, JS::HandleObject jsObj, const char* name, JS::MutableHandleObject retObj) { JS::RootedObject parent(cx); JS::RootedObject tempObj(cx); bool first = true; std::stringstream ss(name); std::string sub; const char* subChar; while(getline(ss, sub, '.')) { if(sub.empty())continue; subChar = sub.c_str(); if (first) { get_or_create_js_obj(cx, jsObj, subChar, &tempObj); first = false; } else { parent = tempObj; get_or_create_js_obj(cx, parent, subChar, &tempObj); } } retObj.set(tempObj.get()); }
/* * 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 ns_new_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp) { Ns *priv; char *name; GIRepository *repo; GIBaseInfo *info; JSBool ret = JS_FALSE; gboolean defined; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; /* not resolved, but no error */ /* let Object.prototype resolve these */ if (strcmp(name, "valueOf") == 0 || strcmp(name, "toString") == 0) { ret = JS_TRUE; goto out; } priv = priv_from_js(context, obj); gjs_debug_jsprop(GJS_DEBUG_GNAMESPACE, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv); if (priv == NULL) { ret = JS_TRUE; /* we are the prototype, or have the wrong class */ goto out; } JS_BeginRequest(context); repo = g_irepository_get_default(); info = g_irepository_find_by_name(repo, priv->gi_namespace, name); if (info == NULL) { /* No property defined, but no error either, so return TRUE */ JS_EndRequest(context); ret = JS_TRUE; goto out; } gjs_debug(GJS_DEBUG_GNAMESPACE, "Found info type %s for '%s' in namespace '%s'", gjs_info_type_name(g_base_info_get_type(info)), g_base_info_get_name(info), g_base_info_get_namespace(info)); if (gjs_define_info(context, obj, info, &defined)) { g_base_info_unref(info); if (defined) objp.set(obj); /* we defined the property in this object */ ret = JS_TRUE; } else { gjs_debug(GJS_DEBUG_GNAMESPACE, "Failed to define info '%s'", g_base_info_get_name(info)); g_base_info_unref(info); } JS_EndRequest(context); out: g_free(name); return ret; }
void CStdDeserializer::GetScriptBackref(u32 tag, JS::MutableHandleObject ret) { ENSURE(m_ScriptBackrefs.size() > tag); ret.set(m_ScriptBackrefs[tag]); }
/* * 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 fundamental 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 fundamental_instance_new_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp) { FundamentalInstance *priv; char *name; JSBool ret = JS_FALSE; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; /* not resolved, but no error */ priv = priv_from_js(context, obj); gjs_debug_jsprop(GJS_DEBUG_GFUNDAMENTAL, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv); if (priv == NULL) goto out; /* wrong class */ if (priv->prototype == NULL) { /* We are the prototype, so look for methods and other class properties */ Fundamental *proto_priv = (Fundamental *) priv; GIFunctionInfo *method_info; method_info = g_object_info_find_method((GIStructInfo*) proto_priv->info, name); if (method_info != NULL) { const char *method_name; #if GJS_VERBOSE_ENABLE_GI_USAGE _gjs_log_info_usage((GIBaseInfo *) method_info); #endif if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { method_name = g_base_info_get_name((GIBaseInfo *) method_info); /* we do not define deprecated methods in the prototype */ if (g_base_info_is_deprecated((GIBaseInfo *) method_info)) { gjs_debug(GJS_DEBUG_GFUNDAMENTAL, "Ignoring definition of deprecated method %s in prototype %s.%s", method_name, g_base_info_get_namespace((GIBaseInfo *) proto_priv->info), g_base_info_get_name((GIBaseInfo *) proto_priv->info)); g_base_info_unref((GIBaseInfo *) method_info); ret = JS_TRUE; goto out; } gjs_debug(GJS_DEBUG_GFUNDAMENTAL, "Defining method %s in prototype for %s.%s", method_name, g_base_info_get_namespace((GIBaseInfo *) proto_priv->info), g_base_info_get_name((GIBaseInfo *) proto_priv->info)); if (gjs_define_function(context, obj, proto_priv->gtype, method_info) == NULL) { g_base_info_unref((GIBaseInfo *) method_info); goto out; } objp.set(obj); } g_base_info_unref((GIBaseInfo *) method_info); } ret = fundamental_instance_new_resolve_interface(context, obj, objp, proto_priv, name); } else { /* We are an instance, not a prototype, so look for * per-instance props that we want to define on the * JSObject. Generally we do not want to cache these in JS, we * want to always pull them from the C object, or JS would not * see any changes made from C. So we use the get/set prop * hooks, not this resolve hook. */ } ret = JS_TRUE; out: g_free(name); return ret; }
/* * 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 boxed 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 union_new_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp) { Union *priv; char *name; JSBool ret = JS_TRUE; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; /* not resolved, but no error */ priv = priv_from_js(context, obj); gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv); if (priv == NULL) { ret = JS_FALSE; /* wrong class */ goto out; } if (priv->gboxed == NULL) { /* We are the prototype, so look for methods and other class properties */ GIFunctionInfo *method_info; method_info = g_union_info_find_method((GIUnionInfo*) priv->info, name); if (method_info != NULL) { JSObject *union_proto; const char *method_name; #if GJS_VERBOSE_ENABLE_GI_USAGE _gjs_log_info_usage((GIBaseInfo*) method_info); #endif if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { method_name = g_base_info_get_name( (GIBaseInfo*) method_info); gjs_debug(GJS_DEBUG_GBOXED, "Defining method %s in prototype for %s.%s", method_name, g_base_info_get_namespace( (GIBaseInfo*) priv->info), g_base_info_get_name( (GIBaseInfo*) priv->info)); union_proto = obj; if (gjs_define_function(context, union_proto, g_registered_type_info_get_g_type(priv->info), method_info) == NULL) { g_base_info_unref( (GIBaseInfo*) method_info); ret = JS_FALSE; goto out; } objp.set(union_proto); /* we defined the prop in object_proto */ } g_base_info_unref( (GIBaseInfo*) method_info); } } else { /* We are an instance, not a prototype, so look for * per-instance props that we want to define on the * JSObject. Generally we do not want to cache these in JS, we * want to always pull them from the C object, or JS would not * see any changes made from C. So we use the get/set prop * hooks, not this resolve hook. */ } out: g_free(name); return ret; }