📄 jsapi.c
字号:
/* Connect constructor and prototype by named properties. */ ctor = fun->object; if (!js_SetClassPrototype(cx, ctor, proto, JSPROP_READONLY | JSPROP_PERMANENT)) { goto bad; } /* Bootstrap Function.prototype (see also JS_InitStandardClasses). */ if (OBJ_GET_CLASS(cx, ctor) == clasp) { /* XXXMLM - this fails in framesets that are writing over * themselves! * JS_ASSERT(!OBJ_GET_PROTO(cx, ctor)); */ OBJ_SET_PROTO(cx, ctor, proto); } } /* Add properties and methods to the prototype and the constructor. */ if ((ps && !JS_DefineProperties(cx, proto, ps)) || (fs && !JS_DefineFunctions(cx, proto, fs)) || (static_ps && !JS_DefineProperties(cx, ctor, static_ps)) || (static_fs && !JS_DefineFunctions(cx, ctor, static_fs))) { goto bad; } return proto;bad: if (named) (void) OBJ_DELETE_PROPERTY(cx, obj, (jsid)atom, &junk); cx->newborn[GCX_OBJECT] = NULL; return NULL;}#ifdef JS_THREADSAFEJS_PUBLIC_API(JSClass *)JS_GetClass(JSContext *cx, JSObject *obj){ return (JSClass *) JSVAL_TO_PRIVATE(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_CLASS));}#elseJS_PUBLIC_API(JSClass *)JS_GetClass(JSObject *obj){ return LOCKED_OBJ_GET_CLASS(obj);}#endifJS_PUBLIC_API(JSBool)JS_InstanceOf(JSContext *cx, JSObject *obj, const JSClass *clasp, jsval *argv){ JSFunction *fun; CHECK_REQUEST(cx); if (OBJ_GET_CLASS(cx, obj) == clasp) return JS_TRUE; if (argv) { fun = js_ValueToFunction(cx, &argv[-2], 0); if (fun) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, clasp->name, JS_GetFunctionName(fun), OBJ_GET_CLASS(cx, obj)->name); } } return JS_FALSE;}JS_PUBLIC_API(void *)JS_GetPrivate(JSContext *cx, JSObject *obj){ jsval v; JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE); v = GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PRIVATE); if (!JSVAL_IS_INT(v)) return NULL; return JSVAL_TO_PRIVATE(v);}JS_PUBLIC_API(JSBool)JS_SetPrivate(JSContext *cx, JSObject *obj, void *data){ JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE); OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(data)); return JS_TRUE;}JS_PUBLIC_API(void *)JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv){ if (!JS_InstanceOf(cx, obj, clasp, argv)) return NULL; return JS_GetPrivate(cx, obj);}JS_PUBLIC_API(JSObject *)JS_GetPrototype(JSContext *cx, JSObject *obj){ JSObject *proto; CHECK_REQUEST(cx); proto = JSVAL_TO_OBJECT(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PROTO)); /* Beware ref to dead object (we may be called from obj's finalizer). */ return proto && proto->map ? proto : NULL;}JS_PUBLIC_API(JSBool)JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto){ CHECK_REQUEST(cx); if (obj->map->ops->setProto) return obj->map->ops->setProto(cx, obj, JSSLOT_PROTO, proto); OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto)); return JS_TRUE;}JS_PUBLIC_API(JSObject *)JS_GetParent(JSContext *cx, JSObject *obj){ JSObject *parent; parent = JSVAL_TO_OBJECT(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PARENT)); /* Beware ref to dead object (we may be called from obj's finalizer). */ return parent && parent->map ? parent : NULL;}JS_PUBLIC_API(JSBool)JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent){ CHECK_REQUEST(cx); if (obj->map->ops->setParent) return obj->map->ops->setParent(cx, obj, JSSLOT_PARENT, parent); OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent)); return JS_TRUE;}JS_PUBLIC_API(JSObject *)JS_GetConstructor(JSContext *cx, JSObject *proto){ jsval cval; CHECK_REQUEST(cx); if (!OBJ_GET_PROPERTY(cx, proto, (jsid)cx->runtime->atomState.constructorAtom, &cval)) { return NULL; } if (!JSVAL_IS_FUNCTION(cx, cval)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR, OBJ_GET_CLASS(cx, proto)->name); return NULL; } return JSVAL_TO_OBJECT(cval);}JS_PUBLIC_API(JSBool)JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp){ JS_ASSERT(((jsid)obj & JSVAL_TAGMASK) == 0); *idp = (jsid) obj | JSVAL_INT; return JS_TRUE;}JS_PUBLIC_API(JSObject *)JS_NewObject(JSContext *cx, const JSClass *clasp, JSObject *proto, JSObject *parent){ CHECK_REQUEST(cx); if (!clasp) clasp = &js_ObjectClass; /* default class is Object */ return js_NewObject(cx, clasp, proto, parent);}JS_PUBLIC_API(JSBool)JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep){ JSScope *scope; JSIdArray *ida; uint32 nslots; jsval v, *vp, *end; if (!OBJ_IS_NATIVE(obj)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_SEAL_OBJECT, OBJ_GET_CLASS(cx, obj)->name); return JS_FALSE; } scope = OBJ_SCOPE(obj);#if defined JS_THREADSAFE && defined DEBUG /* Insist on scope being used exclusively by cx's thread. */ if (scope->ownercx != cx) { JS_LOCK_OBJ(cx, obj); JS_ASSERT(OBJ_SCOPE(obj) == scope); JS_ASSERT(scope->ownercx == cx); JS_UNLOCK_SCOPE(cx, scope); }#endif /* Nothing to do if obj's scope is already sealed. */ if (SCOPE_IS_SEALED(scope)) return JS_TRUE; /* XXX Enumerate lazy properties now, as they can't be added later. */ ida = JS_Enumerate(cx, obj); if (!ida) return JS_FALSE; JS_DestroyIdArray(cx, ida); /* Ensure that obj has its own, mutable scope, and seal that scope. */ JS_LOCK_OBJ(cx, obj); scope = js_GetMutableScope(cx, obj); if (scope) SCOPE_SET_SEALED(scope); JS_UNLOCK_SCOPE(cx, scope); if (!scope) return JS_FALSE; /* If we are not sealing an entire object graph, we're done. */ if (!deep) return JS_TRUE; /* Walk obj->slots and if any value is a non-null object, seal it. */ nslots = JS_MIN(scope->map.freeslot, scope->map.nslots); for (vp = obj->slots, end = vp + nslots; vp < end; vp++) { v = *vp; if (JSVAL_IS_PRIMITIVE(v)) continue; if (!JS_SealObject(cx, JSVAL_TO_OBJECT(v), deep)) return JS_FALSE; } return JS_TRUE;}JS_PUBLIC_API(JSObject *)JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent){ CHECK_REQUEST(cx); if (!clasp) clasp = &js_ObjectClass; /* default class is Object */ return js_ConstructObject(cx, clasp, proto, parent, 0, NULL);}JS_PUBLIC_API(JSObject *)JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent, uintN argc, jsval *argv){ CHECK_REQUEST(cx); if (!clasp) clasp = &js_ObjectClass; /* default class is Object */ return js_ConstructObject(cx, clasp, proto, parent, argc, argv);}static JSBoolDefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value, JSPropertyOp getter, JSPropertyOp setter, uintN attrs, uintN flags, intN tinyid){ jsid id; JSAtom *atom; if (attrs & JSPROP_INDEX) { id = INT_TO_JSVAL(JS_PTR_TO_INT32(name)); atom = NULL; attrs &= ~JSPROP_INDEX; } else { atom = js_Atomize(cx, name, strlen(name), 0); if (!atom) return JS_FALSE; id = (jsid)atom; } if (flags != 0 && OBJ_IS_NATIVE(obj)) { return js_DefineNativeProperty(cx, obj, id, value, getter, setter, attrs, flags, tinyid, NULL); } return OBJ_DEFINE_PROPERTY(cx, obj, id, value, getter, setter, attrs, NULL);}#define AUTO_NAMELEN(s,n) (((n) == (size_t)-1) ? js_strlen(s) : (n))static JSBoolDefineUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval value, JSPropertyOp getter, JSPropertyOp setter, uintN attrs, uintN flags, intN tinyid){ JSAtom *atom; atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0); if (!atom) return JS_FALSE; if (flags != 0 && OBJ_IS_NATIVE(obj)) { return js_DefineNativeProperty(cx, obj, (jsid)atom, value, getter, setter, attrs, flags, tinyid, NULL); } return OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, value, getter, setter, attrs, NULL);}JS_PUBLIC_API(JSObject *)JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp, JSObject *proto, uintN attrs){ JSObject *nobj; CHECK_REQUEST(cx); if (!clasp) clasp = &js_ObjectClass; /* default class is Object */ nobj = js_NewObject(cx, clasp, proto, obj); if (!nobj) return NULL; if (!DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(nobj), NULL, NULL, attrs, 0, 0)) { cx->newborn[GCX_OBJECT] = NULL; return NULL; } return nobj;}JS_PUBLIC_API(JSBool)JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds){ JSBool ok; jsval value; uintN flags; CHECK_REQUEST(cx); for (ok = JS_TRUE; cds->name; cds++) { ok = js_NewNumberValue(cx, cds->dval, &value); if (!ok) break; flags = cds->flags; if (!flags) flags = JSPROP_READONLY | JSPROP_PERMANENT; ok = DefineProperty(cx, obj, cds->name, value, NULL, NULL, flags, 0, 0); if (!ok) break; } return ok;}JS_PUBLIC_API(JSBool)JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps){ JSBool ok; CHECK_REQUEST(cx); for (ok = JS_TRUE; ps->name; ps++) { ok = DefineProperty(cx, obj, ps->name, JSVAL_VOID, ps->getter, ps->setter, ps->flags, SPROP_HAS_SHORTID, ps->tinyid); if (!ok) break; } return ok;}JS_PUBLIC_API(JSBool)JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value, JSPropertyOp getter, JSPropertyOp setter, uintN attrs){ CHECK_REQUEST(cx); return DefineProperty(cx, obj, name, value, getter, setter, attrs, 0, 0);}JS_PUBLIC_API(JSBool)JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name, int8 tinyid, jsval value, JSPropertyOp getter, JSPropertyOp setter, uintN attrs){ CHECK_REQUEST(cx); return DefineProperty(cx, obj, name, value, getter, setter, attrs, SPROP_HAS_SHORTID, tinyid);}static JSBoolLookupProperty(JSContext *cx, JSObject *obj, const char *name, JSObject **objp, JSProperty **propp){ JSAtom *atom; atom = js_Atomize(cx, name, strlen(name), 0); if (!atom) return JS_FALSE; return OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, objp, propp);}static JSBoolLookupUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, JSObject **objp, JSProperty **propp){ JSAtom *atom; atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0); if (!atom) return JS_FALSE; return OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, objp, propp);}JS_PUBLIC_API(JSBool)JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, const char *alias){ JSObject *obj2; JSProperty *prop; JSAtom *atom; JSBool ok; JSScopeProperty *sprop; CHECK_REQUEST(cx); if (!LookupProperty(cx, obj, name, &obj2, &prop)) return JS_FALSE; if (!prop) { js_ReportIsNotDefined(cx, name); return JS_FALSE; } if (obj2 != obj || !OBJ_IS_NATIVE(obj)) { OBJ_DROP_PROPERTY(cx, obj2, prop); JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS, alias, name, OBJ_GET_CLASS(cx, obj2)->name); return JS_FALSE; } atom = js_Atomize(cx, alias, strlen(alias), 0); if (!atom) { ok = JS_FALSE; } else { sprop = (JSScopeProperty *)prop; ok = (js_AddNativeProperty(cx, obj, (jsid)atom, sprop->getter, sprop->setter, sprop->slot, sprop->attrs, sprop->flags | SPROP_IS_ALIAS, sprop->shortid) != NULL); } OBJ_DROP_PROPERTY(cx, obj, prop); return ok;}static jsvalLookupResult(JSContext *cx, JSObject *obj, JSObject *obj2, JSProperty *prop){ JSScopeProperty *sprop; jsval rval; if (!prop) { /* XXX bad API: no way to tell "not defined" from "void value" */ return JSVAL_VOID; } if (OBJ_IS_NATIVE(obj2)) { /* Peek at the native property's slot value, without doing a Get. */ sprop = (JSScopeProperty *)prop; rval = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2)) ? LOCKED_OBJ_GET_SLOT(obj2, sprop->slot) : JSVAL_TRUE; } else { /* XXX bad API: no way to return "defined but value unknown" */ rval = JSVAL_TRUE; } OBJ_DROP_PROPERTY(cx, obj2, prop); return rval;}static JSBoolGetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom, uintN *attrsp, JSBool *foundp){ JSObject *obj2; JSProperty *prop; JSBool ok; if (!atom) return JS_FALSE; if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop)) r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -