static JSBool perlsub_construct( JSContext *cx, DEFJSFSARGS_ ) { dTHX; DECJSFSARGS; JSObject *func = JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)); SV *callee = (SV *)JS_GetPrivate(cx, func); SV *caller = NULL; #if JS_VERSION < 185 JSObject *This = JSVAL_TO_OBJECT(argv[-1]); #else JSObject *This = JS_NewObjectForConstructor(cx, vp); #endif JSObject *proto = JS_GetPrototype(cx, This); PJS_DEBUG1("Want construct, This is a %s", PJS_GET_CLASS(cx, This)->name); if(PJS_GET_CLASS(cx, proto) == &perlpackage_class || ( JS_LookupProperty(cx, func, "prototype", &argv[-1]) && JSVAL_IS_OBJECT(argv[-1]) && !JSVAL_IS_NULL(argv[-1]) && (proto = JS_GetPrototype(cx, JSVAL_TO_OBJECT(argv[-1]))) && strEQ(PJS_GET_CLASS(cx, proto)->name, PJS_PACKAGE_CLASS_NAME)) ) { SV *rsv = NULL; char *pkgname = PJS_GetPackageName(aTHX_ cx, proto); #if JS_VERSION >= 185 JSAutoByteString bytes; bytes.initBytes(pkgname); #endif caller = newSVpv(pkgname, 0); argv[-1] = OBJECT_TO_JSVAL(This); if(!PJS_Call_sv_with_jsvals_rsv(aTHX_ cx, obj, callee, caller, argc, argv, &rsv, G_SCALAR)) return JS_FALSE; if(SvROK(rsv) && sv_derived_from(rsv, pkgname)) { JSObject *newobj = PJS_NewPerlObject(aTHX_ cx, JS_GetParent(cx, func), rsv); *rval = OBJECT_TO_JSVAL(newobj); return JS_TRUE; } JS_ReportError(cx, "%s's constructor don't return an object", SvPV_nolen(caller)); } else JS_ReportError(cx, "Can't use as a constructor"); // Yet! ;-) return JS_FALSE; }
JSDValue* jsd_GetValueConstructor(JSDContext* jsdc, JSDValue* jsdval) { if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_CTOR))) { JSObject* obj; JSObject* proto; JSObject* ctor; JS_ASSERT(!jsdval->ctor); SET_BIT_FLAG(jsdval->flags, GOT_CTOR); if(!JSVAL_IS_OBJECT(jsdval->val)) return NULL; if(!(obj = JSVAL_TO_OBJECT(jsdval->val))) return NULL; JS_BeginRequest(jsdc->dumbContext); proto = JS_GetPrototype(jsdc->dumbContext,obj); if(!proto) { JS_EndRequest(jsdc->dumbContext); return NULL; } ctor = JS_GetConstructor(jsdc->dumbContext,proto); JS_EndRequest(jsdc->dumbContext); if(!ctor) return NULL; jsdval->ctor = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(ctor)); } if(jsdval->ctor) jsdval->ctor->nref++; return jsdval->ctor; }
JSBool db_collection_resolve( JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp ){ if ( flags & JSRESOLVE_ASSIGNING ) return JS_TRUE; Convertor c( cx ); string collname = c.toString( id ); if ( isSpecialName( collname ) ) return JS_TRUE; if ( obj == c.getGlobalPrototype( "DBCollection" ) ) return JS_TRUE; JSObject * proto = JS_GetPrototype( cx , obj ); if ( c.hasProperty( obj , collname.c_str() ) || ( proto && c.hasProperty( proto , collname.c_str() ) ) ) return JS_TRUE; string name = c.toString( c.getProperty( obj , "_shortName" ) ); name += "."; name += collname; jsval db = c.getProperty( obj , "_db" ); if ( ! JSVAL_IS_OBJECT( db ) ) return JS_TRUE; JSObject * coll = doCreateCollection( cx , JSVAL_TO_OBJECT( db ) , name ); c.setProperty( obj , collname.c_str() , OBJECT_TO_JSVAL( coll ) ); *objp = obj; return JS_TRUE; }
bool ChromeObjectWrapper::get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, js::Value *vp) { // Start with a call to getPropertyDescriptor. We unfortunately need to do // this because the call signature of ::get doesn't give us any way to // determine the object upon which the property was found. JSPropertyDescriptor desc; memset(&desc, 0, sizeof(desc)); if (!ChromeObjectWrapperBase::getPropertyDescriptor(cx, wrapper, id, false, &desc)) { return false; } // Only call through to the get trap on the underlying object if we'll find // something, and if what we'll find is not on a standard prototype. vp->setUndefined(); if (desc.obj && !PropIsFromStandardPrototype(cx, &desc)) { // 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 = JS_GetPrototype(wrapper); if (!wrapperProto) return true; // Try the prototype. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); return js::GetGeneric(cx, wrapperProto, receiver, id, vp); }
bool ChromeObjectWrapper::getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set, js::PropertyDescriptor *desc) { // First, try the lookup on the base wrapper. This can throw for various // reasons, including sets (gets fail silently). There's nothing we can really // do for sets, so we can conveniently propagate any exception we hit here. desc->obj = NULL; if (!ChromeObjectWrapperBase::getPropertyDescriptor(cx, wrapper, id, set, desc)) { return false; } // If the property is something that can be found on a standard prototype, // prefer the one we'll get via the prototype chain in the content // compartment. if (desc->obj && PropIsFromStandardPrototype(cx, desc)) desc->obj = NULL; // If we found something, were doing a set, or have no proto, we're done. JSObject *wrapperProto = JS_GetPrototype(wrapper); if (desc->obj || set || !wrapperProto) return true; // If not, try doing the lookup on the prototype. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); return JS_GetPropertyDescriptorById(cx, wrapperProto, id, 0, desc); }
static FundamentalInstance * init_fundamental_instance(JSContext *context, JSObject *object) { Fundamental *proto_priv; FundamentalInstance *priv; JS_BeginRequest(context); priv = g_slice_new0(FundamentalInstance); GJS_INC_COUNTER(fundamental); g_assert(priv_from_js(context, object) == NULL); JS_SetPrivate(object, priv); gjs_debug_lifecycle(GJS_DEBUG_GFUNDAMENTAL, "fundamental instance constructor, obj %p priv %p proto %p ", object, priv, JS_GetPrototype (object)); proto_priv = proto_priv_from_js(context, object); g_assert(proto_priv != NULL); priv->prototype = proto_priv; JS_EndRequest(context); return priv; }
JSDValue* jsd_GetValuePrototype(JSDContext* jsdc, JSDValue* jsdval) { JSCrossCompartmentCall *call = NULL; if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROTO))) { JSObject* obj; JSObject* proto; JS_ASSERT(!jsdval->proto); SET_BIT_FLAG(jsdval->flags, GOT_PROTO); if(!JSVAL_IS_OBJECT(jsdval->val)) return NULL; if(!(obj = JSVAL_TO_OBJECT(jsdval->val))) return NULL; JS_BeginRequest(jsdc->dumbContext); call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, obj); if(!call) { JS_EndRequest(jsdc->dumbContext); return NULL; } proto = JS_GetPrototype(jsdc->dumbContext, obj); JS_LeaveCrossCompartmentCall(call); JS_EndRequest(jsdc->dumbContext); if(!proto) return NULL; jsdval->proto = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(proto)); } if(jsdval->proto) jsdval->proto->nref++; return jsdval->proto; }
JSDValue* jsd_GetValueConstructor(JSDContext* jsdc, JSDValue* jsdval) { JSCompartment* oldCompartment = NULL; JSContext* cx = jsdc->dumbContext; if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_CTOR))) { JS::RootedObject obj(cx); JS::RootedObject proto(cx); JS::RootedObject ctor(cx); JS_ASSERT(!jsdval->ctor); SET_BIT_FLAG(jsdval->flags, GOT_CTOR); if(JSVAL_IS_PRIMITIVE(jsdval->val)) return NULL; obj = JSVAL_TO_OBJECT(jsdval->val); if(!JS_GetPrototype(cx, obj, proto.address())) return NULL; if(!proto) return NULL; JS_BeginRequest(jsdc->dumbContext); oldCompartment = JS_EnterCompartment(jsdc->dumbContext, obj); ctor = JS_GetConstructor(jsdc->dumbContext,proto); JS_LeaveCompartment(jsdc->dumbContext, oldCompartment); JS_EndRequest(jsdc->dumbContext); if(!ctor) return NULL; jsdval->ctor = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(ctor)); } if(jsdval->ctor) jsdval->ctor->nref++; return jsdval->ctor; }
JSBool TCP_accept (JSContext* cx, JSObject* object, uintN argc, jsval* argv, jsval* rval) { jsdouble timeout = -1; if (argc) { JS_ValueToNumber(cx, argv[0], &timeout); } TCPInformation* data = (TCPInformation*) JS_GetPrivate(cx, object); JS_BeginRequest(cx); JS_EnterLocalRootScope(cx); JSObject* sock = JS_NewObject(cx, &TCP_class, JS_GetPrototype(cx, object), NULL); TCPInformation* newData = new TCPInformation; JS_SetPrivate(cx, sock, newData); PRNetAddr addr; newData->socket = PR_Accept(data->socket, &addr, (timeout == -1) ? PR_INTERVAL_NO_TIMEOUT : PR_MicrosecondsToInterval(timeout*1000000)); jsval property = JSVAL_TRUE; JS_SetProperty(cx, sock, "connected", &property); *rval = OBJECT_TO_JSVAL(sock); JS_LeaveLocalRootScope(cx); JS_EndRequest(cx); return JS_TRUE; }
static inline Fundamental * proto_priv_from_js(JSContext *context, JSObject *obj) { JSObject *proto; JS_GetPrototype(context, obj, &proto); return (Fundamental*) priv_from_js(context, proto); }
JSObject * WrapperFactory::WrapSOWObject(JSContext *cx, JSObject *obj) { JSObject *wrapperObj = Wrapper::New(cx, obj, JS_GetPrototype(obj), JS_GetGlobalForObject(cx, obj), &FilteringWrapper<SameCompartmentSecurityWrapper, OnlyIfSubjectIsSystem>::singleton); return wrapperObj; }
JSBool perlsub_as_constructor( JSContext *cx, JSObject *obj, pjsid id, DEFSTRICT_ jsval *vp ) { // dTHX; const char *key; if(!PJSID_IS(STRING, id)) { return JS_TRUE; } #if JS_VERSION < 185 key = JS_GetStringBytes(PJSID_TO(STRING, id)); #else JSAutoByteString bytes(cx, PJSID_TO(STRING, id)); key = bytes.ptr(); #endif if(strEQ(key, "constructor")) { JSObject *constructor; if(JSVAL_IS_OBJECT(*vp) && (constructor = JSVAL_TO_OBJECT(*vp)) && PJS_GET_CLASS(cx, constructor) == &perlsub_class) { /* TODO: Change the constructor 'name' */ jsval temp; JSObject *stash = JS_GetPrototype(cx, obj); JS_SetPrototype(cx, stash, JS_GetPrototype(cx, constructor)); JS_SetPrototype(cx, constructor, stash); JS_DefineProperty(cx, constructor, "prototype", OBJECT_TO_JSVAL(obj), NULL, NULL, 0); JS_LookupProperty(cx, obj, "__PACKAGE__", &temp); // warn("Constructor set for %s\n", JS_GetStringBytes(JSVAL_TO_STRING(temp))); return JS_TRUE; } else { JS_ReportError(cx, "Invalid constructor type"); return JS_FALSE; } } else warn ("Opps: setting %s?\n", key); return JS_TRUE; }
bool DOMProxyHandler::enumerate(JSContext* cx, JS::Handle<JSObject*> proxy, AutoIdVector& props) { JS::Rooted<JSObject*> proto(cx); if (!JS_GetPrototype(cx, proxy, &proto)) { return false; } return getOwnPropertyNames(cx, proxy, props) && (!proto || js::GetPropertyNames(cx, proto, 0, &props)); }
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; }
JSObject * WrapperFactory::WrapComponentsObject(JSContext *cx, HandleObject obj) { RootedObject proto(cx); if (!JS_GetPrototype(cx, obj, proto.address())) return NULL; JSObject *wrapperObj = Wrapper::New(cx, obj, proto, JS_GetGlobalForObject(cx, obj), &FilteringWrapper<SameCompartmentSecurityWrapper, ComponentsObjectPolicy>::singleton); return wrapperObj; }
JSObject * WrapperFactory::WrapComponentsObject(JSContext *cx, JSObject *obj) { JSObject *proto; if (!JS_GetPrototype(cx, obj, &proto)) return NULL; JSObject *wrapperObj = Wrapper::New(cx, obj, proto, JS_GetGlobalForObject(cx, obj), &FilteringWrapper<SameCompartmentSecurityWrapper, ComponentsObjectPolicy>::singleton); return wrapperObj; }
static JSBool perlsub_call( JSContext *cx, DEFJSFSARGS_ ) { dTHX; DECJSFSARGS; JSObject *func = JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)); SV *callee = (SV *)JS_GetPrivate(cx, func); JSObject *This = JSVAL_TO_OBJECT(argv[-1]); JSClass *clasp = PJS_GET_CLASS(cx, This); SV *caller; JSBool wanta, isclass = JS_FALSE; if(!JS_GetProperty(cx, func, "$wantarray", rval) || !JS_ValueToBoolean(cx, *rval, &wanta)) return JS_FALSE; PJS_DEBUG1("In PSC: obj is %s\n", PJS_GET_CLASS(cx, obj)->name); if(clasp == &perlpackage_class) { if(!JS_GetProperty(cx, This, "$__im_a_class", rval) || !JS_ValueToBoolean(cx, *rval, &isclass)) return JS_FALSE; } if(isclass || ( clasp == &perlsub_class /* Constructors has a Stash in __proto__ */ && (func = JS_GetPrototype(cx, This)) && PJS_GET_CLASS(cx, func) == &perlpackage_class) ) { // Caller is a stash, make a static call char *pkgname = PJS_GetPackageName(aTHX_ cx, This); if(!pkgname) return JS_FALSE; caller = newSVpv(pkgname, 0); PJS_DEBUG1("Caller is a stash: %s\n", pkgname); #if JS_VERSION >= 185 Safefree(pkgname); #endif } else if(IS_PERL_CLASS(clasp) && sv_isobject(caller = (SV *)JS_GetPrivate(cx, This)) ) { // Caller is a perl object SvREFCNT_inc_void_NN(caller); PJS_DEBUG1("Caller is an object: %s\n", SvPV_nolen(caller)); } else { caller = NULL; PJS_DEBUG1("Caller is %s\n", clasp->name); } return PJS_Call_sv_with_jsvals(aTHX_ cx, obj, callee, caller, argc, argv, rval, wanta ? G_ARRAY : G_SCALAR); }
JSObject * WrapperFactory::WrapSOWObject(JSContext *cx, JSObject *objArg) { RootedObject obj(cx, objArg); RootedObject proto(cx); if (!JS_GetPrototype(cx, obj, proto.address())) return NULL; JSObject *wrapperObj = Wrapper::New(cx, obj, proto, JS_GetGlobalForObject(cx, obj), &FilteringWrapper<SameCompartmentSecurityWrapper, OnlyIfSubjectIsSystem>::singleton); return wrapperObj; }
/* * "Steal" calls to netscape.security.PrivilegeManager.enablePrivilege, * et. al. so that code that worked with 4.0 can still work. */ NS_IMETHODIMP nsSecurityNameSet::InitializeNameSet(nsIScriptContext* aScriptContext) { JSContext *cx = (JSContext *) aScriptContext->GetNativeContext(); JSObject *global = JS_GetGlobalObject(cx); /* * Find Object.prototype's class by walking up the global object's * prototype chain. */ JSObject *obj = global; JSObject *proto; JSAutoRequest ar(cx); while ((proto = JS_GetPrototype(cx, obj)) != nsnull) obj = proto; JSClass *objectClass = JS_GET_CLASS(cx, obj); jsval v; if (!JS_GetProperty(cx, global, "netscape", &v)) return NS_ERROR_FAILURE; JSObject *securityObj; if (JSVAL_IS_OBJECT(v)) { /* * "netscape" property of window object exists; get the * "security" property. */ obj = JSVAL_TO_OBJECT(v); if (!JS_GetProperty(cx, obj, "security", &v) || !JSVAL_IS_OBJECT(v)) return NS_ERROR_FAILURE; securityObj = JSVAL_TO_OBJECT(v); } else { /* define netscape.security object */ obj = JS_DefineObject(cx, global, "netscape", objectClass, nsnull, 0); if (obj == nsnull) return NS_ERROR_FAILURE; securityObj = JS_DefineObject(cx, obj, "security", objectClass, nsnull, 0); if (securityObj == nsnull) return NS_ERROR_FAILURE; } /* Define PrivilegeManager object with the necessary "static" methods. */ obj = JS_DefineObject(cx, securityObj, "PrivilegeManager", objectClass, nsnull, 0); if (obj == nsnull) return NS_ERROR_FAILURE; return JS_DefineFunctions(cx, obj, PrivilegeManager_static_methods) ? NS_OK : NS_ERROR_FAILURE; }
JSObject * WrapperFactory::WrapSOWObject(JSContext *cx, JSObject *objArg) { RootedObject obj(cx, objArg); RootedObject proto(cx); // If we're not allowing XBL scopes, that means we're running as a remote // XUL domain, in which we can't have SOWs. We should never be called in // that case. MOZ_ASSERT(xpc::AllowXBLScope(js::GetContextCompartment(cx))); if (!JS_GetPrototype(cx, obj, &proto)) return NULL; JSObject *wrapperObj = Wrapper::New(cx, obj, proto, JS_GetGlobalForObject(cx, obj), &FilteringWrapper<SameCompartmentSecurityWrapper, Opaque>::singleton); return wrapperObj; }
void* gjs_get_instance_private_dynamic(JSContext *context, JSObject *obj, JSClass *static_clasp, jsval *argv) { RuntimeData *rd; JSClass *obj_class; void *instance; if (static_clasp->name != NULL) { g_warning("Dynamic class should not have a name in the JSClass struct"); return NULL; } JS_BeginRequest(context); obj_class = JS_GET_CLASS(context, obj); g_assert(obj_class != NULL); rd = get_data_from_context(context); g_assert(rd != NULL); /* Check that it's safe to cast to DynamicJSClass */ if (g_hash_table_lookup(rd->dynamic_classes, obj_class) == NULL) { gjs_throw(context, "Object %p proto %p doesn't have a dynamically-registered class, it has %s", obj, JS_GetPrototype(context, obj), obj_class->name); JS_EndRequest(context); return NULL; } if (static_clasp != ((DynamicJSClass*) obj_class)->static_class) { gjs_throw(context, "Object is not a dynamically-registered class based on expected static class pointer"); JS_EndRequest(context); return NULL; } instance = JS_GetInstancePrivate(context, obj, obj_class, argv); JS_EndRequest(context); return instance; }
bool ChromeObjectWrapper::has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) { // Try the lookup on the base wrapper. if (!ChromeObjectWrapperBase::has(cx, wrapper, id, bp)) return false; // If we found something or have no prototype, we're done. JSObject *wrapperProto = JS_GetPrototype(wrapper); if (*bp || !wrapperProto) return true; // Try the prototype if that failed. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); JSPropertyDescriptor desc; memset(&desc, 0, sizeof(desc)); if (!JS_GetPropertyDescriptorById(cx, wrapperProto, id, 0, &desc)) return false; *bp = !!desc.obj; return true; }
JSDValue* jsd_GetValuePrototype(JSDContext* jsdc, JSDValue* jsdval) { if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROTO))) { JSObject* obj; JSObject* proto; JS_ASSERT(!jsdval->proto); SET_BIT_FLAG(jsdval->flags, GOT_PROTO); if(JSVAL_IS_PRIMITIVE(jsdval->val)) return NULL; obj = JSVAL_TO_OBJECT(jsdval->val); proto = JS_GetPrototype(obj); if(!proto) return NULL; jsdval->proto = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(proto)); } if(jsdval->proto) jsdval->proto->nref++; return jsdval->proto; }
JSBool js_cocos2dx_CCNode_copy(JSContext *cx, uint32_t argc, jsval *vp) { if (argc == 0) { JSObject *obj = JS_THIS_OBJECT(cx, vp); js_proxy_t *proxy; JS_GET_NATIVE_PROXY(proxy, obj); cocos2d::CCNode *node = (cocos2d::CCNode *)(proxy ? proxy->ptr : NULL); TEST_NATIVE_OBJECT(cx, node) JSClass *jsclass = JS_GetClass(obj); JSObject *proto = JS_GetPrototype(obj); JSObject *parent = JS_GetParent(obj); JSObject *jsret = JS_NewObject(cx, jsclass, proto, parent); cocos2d::CCObject *ret = node->copy(); if (ret && jsret) { JS_NEW_PROXY(proxy, ret, jsret); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(jsret)); return JS_TRUE; } } return JS_FALSE; }
void DBQueryInfo::resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp) { *resolvedp = false; IdWrapper wid(cx, id); // We only use this for index access if (!wid.isInt()) { return; } JS::RootedObject parent(cx); if (!JS_GetPrototype(cx, obj, &parent)) uasserted(ErrorCodes::InternalError, "Couldn't get prototype"); ObjectWrapper parentWrapper(cx, parent); JS::RootedValue arrayAccess(cx); parentWrapper.getValue(InternedString::arrayAccess, &arrayAccess); if (arrayAccess.isObject() && JS_ObjectIsFunction(cx, arrayAccess.toObjectOrNull())) { JS::AutoValueArray<1> args(cx); args[0].setInt32(wid.toInt32()); JS::RootedValue vp(cx); ObjectWrapper(cx, obj).callMethod(arrayAccess, args, &vp); if (!vp.isNullOrUndefined()) { ObjectWrapper o(cx, obj); // Assumes the user won't modify the contents of what DBQuery::arrayAccess returns // otherwise we need to install a getter. o.defineProperty(id, vp, 0); } *resolvedp = true; } }
bool ScriptInterface::EnumeratePropertyNamesWithPrefix(jsval obj, const char* prefix, std::vector<std::string>& out) { utf16string prefix16 (prefix, prefix+strlen(prefix)); if (! JSVAL_IS_OBJECT(obj)) return false; // TODO: log error messages JSObject* it = JS_NewPropertyIterator(m->m_cx, JSVAL_TO_OBJECT(obj)); if (!it) return false; while (true) { jsid idp; jsval val; if (! JS_NextProperty(m->m_cx, it, &idp) || ! JS_IdToValue(m->m_cx, idp, &val)) return false; if (val == JSVAL_VOID) break; // end of iteration if (! JSVAL_IS_STRING(val)) continue; // ignore integer properties JSString* name = JSVAL_TO_STRING(val); size_t len; const jschar* chars = JS_GetStringCharsAndLength(m->m_cx, name, &len); if (chars && len >= prefix16.size() && memcmp(chars, prefix16.c_str(), prefix16.size()*2) == 0) out.push_back(std::string(chars, chars+len)); // handles Unicode poorly } // Recurse up the prototype chain JSObject* prototype = JS_GetPrototype(m->m_cx, JSVAL_TO_OBJECT(obj)); if (prototype) { if (! EnumeratePropertyNamesWithPrefix(OBJECT_TO_JSVAL(prototype), prefix, out)) return false; } return true; }
JSDValue* jsd_GetValuePrototype(JSDContext* jsdc, JSDValue* jsdval) { JSContext* cx = jsdc->dumbContext; if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROTO))) { JS::RootedObject obj(cx); JS::RootedObject proto(cx); JS_ASSERT(!jsdval->proto); SET_BIT_FLAG(jsdval->flags, GOT_PROTO); if(JSVAL_IS_PRIMITIVE(jsdval->val)) return NULL; obj = JSVAL_TO_OBJECT(jsdval->val); if(!JS_GetPrototype(cx, obj, proto.address())) return NULL; if(!proto) return NULL; jsdval->proto = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(proto)); } if(jsdval->proto) jsdval->proto->nref++; return jsdval->proto; }
JSBool db_resolve( JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp ){ if ( flags & JSRESOLVE_ASSIGNING ) return JS_TRUE; Convertor c( cx ); if ( obj == c.getGlobalPrototype( "DB" ) ) return JS_TRUE; string collname = c.toString( id ); if ( isSpecialName( collname ) ) return JS_TRUE; JSObject * proto = JS_GetPrototype( cx , obj ); if ( proto && c.hasProperty( proto , collname.c_str() ) ) return JS_TRUE; JSObject * coll = doCreateCollection( cx , obj , collname ); c.setProperty( obj , collname.c_str() , OBJECT_TO_JSVAL( coll ) ); *objp = obj; return JS_TRUE; }
void DBInfo::getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) { // 2nd look into real values, may be cached collection object if (!vp.isUndefined()) { auto scope = getScope(cx); auto opContext = scope->getOpContext(); if (opContext && vp.isObject()) { ObjectWrapper o(cx, vp); if (o.hasOwnField(InternedString::_fullName)) { // need to check every time that the collection did not get sharded if (haveLocalShardingInfo(opContext, o.getString(InternedString::_fullName))) uasserted(ErrorCodes::BadValue, "can't use sharded collection from db.eval"); } } return; } JS::RootedObject parent(cx); if (!JS_GetPrototype(cx, obj, &parent)) uasserted(ErrorCodes::JSInterpreterFailure, "Couldn't get prototype"); ObjectWrapper parentWrapper(cx, parent); if (parentWrapper.hasOwnField(id)) { parentWrapper.getValue(id, vp); return; } IdWrapper idw(cx, id); // if starts with '_' we dont return collection, one must use getCollection() if (idw.isString()) { JSStringWrapper jsstr; auto sname = idw.toStringData(&jsstr); if (sname.size() == 0 || sname[0] == '_') { return; } } // no hit, create new collection JS::RootedValue getCollection(cx); parentWrapper.getValue(InternedString::getCollection, &getCollection); if (!(getCollection.isObject() && JS_ObjectIsFunction(cx, getCollection.toObjectOrNull()))) { uasserted(ErrorCodes::BadValue, "getCollection is not a function"); } JS::AutoValueArray<1> args(cx); idw.toValue(args[0]); JS::RootedValue coll(cx); ObjectWrapper(cx, obj).callMethod(getCollection, args, &coll); uassert(16861, "getCollection returned something other than a collection", getScope(cx)->getProto<DBCollectionInfo>().instanceOf(coll)); // cache collection for reuse, don't enumerate ObjectWrapper(cx, obj).defineProperty(id, coll, 0); vp.set(coll); }
static int ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc) { const char rcfilename[] = "xpcshell.js"; FILE *rcfile; int i, j, length; JSObject *argsObj; char *filename = NULL; JSBool isInteractive = JS_TRUE; JSBool forceTTY = JS_FALSE; rcfile = fopen(rcfilename, "r"); if (rcfile) { printf("[loading '%s'...]\n", rcfilename); ProcessFile(cx, obj, rcfilename, rcfile, JS_FALSE); } /* * Scan past all optional arguments so we can create the arguments object * before processing any -f options, which must interleave properly with * -v and -w options. This requires two passes, and without getopt, we'll * have to keep the option logic here and in the second for loop in sync. */ for (i = 0; i < argc; i++) { if (argv[i][0] != '-' || argv[i][1] == '\0') { ++i; break; } switch (argv[i][1]) { case 'v': case 'f': case 'e': ++i; break; default:; } } /* * Create arguments early and define it to root it, so it's safe from any * GC calls nested below, and so it is available to -f <file> arguments. */ argsObj = JS_NewArrayObject(cx, 0, NULL); if (!argsObj) return 1; if (!JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj), NULL, NULL, 0)) { return 1; } length = argc - i; for (j = 0; j < length; j++) { JSString *str = JS_NewStringCopyZ(cx, argv[i++]); if (!str) return 1; if (!JS_DefineElement(cx, argsObj, j, STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE)) { return 1; } } for (i = 0; i < argc; i++) { if (argv[i][0] != '-' || argv[i][1] == '\0') { filename = argv[i++]; isInteractive = JS_FALSE; break; } switch (argv[i][1]) { case 'v': if (++i == argc) { return usage(); } JS_SetVersion(cx, JSVersion(atoi(argv[i]))); break; case 'W': reportWarnings = JS_FALSE; break; case 'w': reportWarnings = JS_TRUE; break; case 's': JS_ToggleOptions(cx, JSOPTION_STRICT); break; case 'x': JS_ToggleOptions(cx, JSOPTION_XML); break; case 'P': if (JS_GET_CLASS(cx, JS_GetPrototype(cx, obj)) != &global_class) { JSObject *gobj; if (!JS_SealObject(cx, obj, JS_TRUE)) return JS_FALSE; gobj = JS_NewObject(cx, &global_class, NULL, NULL); if (!gobj) return JS_FALSE; if (!JS_SetPrototype(cx, gobj, obj)) return JS_FALSE; JS_SetParent(cx, gobj, NULL); JS_SetGlobalObject(cx, gobj); obj = gobj; } break; case 'f': if (++i == argc) { return usage(); } Process(cx, obj, argv[i], JS_FALSE); /* * XXX: js -f foo.js should interpret foo.js and then * drop into interactive mode, but that breaks test * harness. Just execute foo.js for now. */ isInteractive = JS_FALSE; break; case 'i': isInteractive = forceTTY = JS_TRUE; break; case 'e': { jsval rval; if (++i == argc) { return usage(); } JS_EvaluateScript(cx, obj, argv[i], strlen(argv[i]), "-e", 1, &rval); isInteractive = JS_FALSE; break; } case 'C': compileOnly = JS_TRUE; isInteractive = JS_FALSE; break; #ifdef MOZ_SHARK case 'k': JS_ConnectShark(); break; #endif default: return usage(); } } if (filename || isInteractive) Process(cx, obj, filename, forceTTY); return gExitCode; }