📄 jsobj.c
字号:
jsval *rval){ jsid id; JSObject *obj2; JSProperty *prop; JSScopeProperty *sprop; if (!JS_ValueToId(cx, argv[0], &id)) return JS_FALSE; if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) return JS_FALSE; if (!prop) { *rval = JSVAL_FALSE; } else if (obj2 == obj) { *rval = JSVAL_TRUE; } else if (OBJ_IS_NATIVE(obj2)) { sprop = (JSScopeProperty *)prop; *rval = BOOLEAN_TO_JSVAL(SPROP_IS_SHARED_PERMANENT(sprop)); } else { *rval = JSVAL_FALSE; } if (prop) OBJ_DROP_PROPERTY(cx, obj2, prop); return JS_TRUE;}/* Proposed ECMA 15.2.4.6. */static JSBoolobj_isPrototypeOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSBool b; if (!js_IsDelegate(cx, obj, *argv, &b)) return JS_FALSE; *rval = BOOLEAN_TO_JSVAL(b); return JS_TRUE;}/* Proposed ECMA 15.2.4.7. */static JSBoolobj_propertyIsEnumerable(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ jsid id; uintN attrs; JSObject *obj2; JSProperty *prop; JSBool ok; if (!JS_ValueToId(cx, argv[0], &id)) return JS_FALSE; if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) return JS_FALSE; if (!prop) { *rval = JSVAL_FALSE; return JS_TRUE; } /* * XXX ECMA spec error compatible: return false unless hasOwnProperty. * The ECMA spec really should be fixed so propertyIsEnumerable and the * for..in loop agree on whether prototype properties are enumerable, * obviously by fixing this method (not by breaking the for..in loop!). * * We check here for shared permanent prototype properties, which should * be treated as if they are local to obj. They are an implementation * technique used to satisfy ECMA requirements; users should not be able * to distinguish a shared permanent proto-property from a local one. */ if (obj2 != obj && !(OBJ_IS_NATIVE(obj2) && SPROP_IS_SHARED_PERMANENT((JSScopeProperty *)prop))) { OBJ_DROP_PROPERTY(cx, obj2, prop); *rval = JSVAL_FALSE; return JS_TRUE; } ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs); OBJ_DROP_PROPERTY(cx, obj2, prop); if (ok) *rval = BOOLEAN_TO_JSVAL((attrs & JSPROP_ENUMERATE) != 0); return ok;}#endif /* JS_HAS_NEW_OBJ_METHODS */#if JS_HAS_GETTER_SETTERstatic JSBoolobj_defineGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ jsval fval, junk; jsid id; JSBool found; uintN attrs; fval = argv[1]; if (JS_TypeOfValue(cx, fval) != JSTYPE_FUNCTION) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_GETTER_OR_SETTER, js_getter_str); return JS_FALSE; } if (!JS_ValueToId(cx, argv[0], &id)) return JS_FALSE; if (!js_CheckRedeclaration(cx, obj, id, JSPROP_GETTER, &found)) return JS_FALSE; /* * Getters and setters are just like watchpoints from an access * control point of view. */ if (!OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &junk, &attrs)) return JS_FALSE; return OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, (JSPropertyOp) JSVAL_TO_OBJECT(fval), NULL, JSPROP_GETTER | JSPROP_SHARED, NULL);}static JSBoolobj_defineSetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ jsval fval, junk; jsid id; JSBool found; uintN attrs; fval = argv[1]; if (JS_TypeOfValue(cx, fval) != JSTYPE_FUNCTION) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_GETTER_OR_SETTER, js_setter_str); return JS_FALSE; } if (!JS_ValueToId(cx, argv[0], &id)) return JS_FALSE; if (!js_CheckRedeclaration(cx, obj, id, JSPROP_SETTER, &found)) return JS_FALSE; /* * Getters and setters are just like watchpoints from an access * control point of view. */ if (!OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &junk, &attrs)) return JS_FALSE; return OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, (JSPropertyOp) JSVAL_TO_OBJECT(fval), JSPROP_SETTER | JSPROP_SHARED, NULL);}static JSBoolobj_lookupGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ jsid id; JSObject *pobj; JSScopeProperty *sprop; if (!JS_ValueToId(cx, argv[0], &id)) return JS_FALSE; if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, (JSProperty **) &sprop)) return JS_FALSE; if (sprop) { if (sprop->attrs & JSPROP_GETTER) *rval = OBJECT_TO_JSVAL(sprop->getter); OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); } return JS_TRUE;}static JSBoolobj_lookupSetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ jsid id; JSObject *pobj; JSScopeProperty *sprop; if (!JS_ValueToId(cx, argv[0], &id)) return JS_FALSE; if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, (JSProperty **) &sprop)) return JS_FALSE; if (sprop) { if (sprop->attrs & JSPROP_SETTER) *rval = OBJECT_TO_JSVAL(sprop->setter); OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); } return JS_TRUE;}#endif /* JS_HAS_GETTER_SETTER */#if JS_HAS_OBJ_WATCHPOINTconst char js_watch_str[] = "watch";const char js_unwatch_str[] = "unwatch";#endif#if JS_HAS_NEW_OBJ_METHODSconst char js_hasOwnProperty_str[] = "hasOwnProperty";const char js_isPrototypeOf_str[] = "isPrototypeOf";const char js_propertyIsEnumerable_str[] = "propertyIsEnumerable";#endif#if JS_HAS_GETTER_SETTERconst char js_defineGetter_str[] = "__defineGetter__";const char js_defineSetter_str[] = "__defineSetter__";const char js_lookupGetter_str[] = "__lookupGetter__";const char js_lookupSetter_str[] = "__lookupSetter__";#endifstatic JSFunctionSpec object_methods[] = {#if JS_HAS_TOSOURCE {js_toSource_str, js_obj_toSource, 0, 0, OBJ_TOSTRING_EXTRA},#endif {js_toString_str, js_obj_toString, 0, 0, OBJ_TOSTRING_EXTRA}, {js_toLocaleString_str, js_obj_toString, 0, 0, OBJ_TOSTRING_EXTRA}, {js_valueOf_str, obj_valueOf, 0,0,0},#if 0 {js_eval_str, obj_eval, 1,0,0},#endif#if JS_HAS_OBJ_WATCHPOINT {js_watch_str, obj_watch, 2,0,0}, {js_unwatch_str, obj_unwatch, 1,0,0},#endif#if JS_HAS_NEW_OBJ_METHODS {js_hasOwnProperty_str, obj_hasOwnProperty, 1,0,0}, {js_isPrototypeOf_str, obj_isPrototypeOf, 1,0,0}, {js_propertyIsEnumerable_str, obj_propertyIsEnumerable, 1,0,0},#endif#if JS_HAS_GETTER_SETTER {js_defineGetter_str, obj_defineGetter, 2,0,0}, {js_defineSetter_str, obj_defineSetter, 2,0,0}, {js_lookupGetter_str, obj_lookupGetter, 1,0,0}, {js_lookupSetter_str, obj_lookupSetter, 1,0,0},#endif {0,0,0,0,0}};static JSBoolObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ if (argc == 0) { /* Trigger logic below to construct a blank object. */ obj = NULL; } else { /* If argv[0] is null or undefined, obj comes back null. */ if (!js_ValueToObject(cx, argv[0], &obj)) return JS_FALSE; } if (!obj) { JS_ASSERT(!argc || JSVAL_IS_NULL(argv[0]) || JSVAL_IS_VOID(argv[0])); if (cx->fp->flags & JSFRAME_CONSTRUCTING) return JS_TRUE; obj = js_NewObject(cx, &js_ObjectClass, NULL, NULL); if (!obj) return JS_FALSE; } *rval = OBJECT_TO_JSVAL(obj); return JS_TRUE;}/* * ObjectOps and Class for with-statement stack objects. */static JSBoolwith_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, JSProperty **propp#if defined JS_THREADSAFE && defined DEBUG , const char *file, uintN line#endif ){ JSObject *proto; JSScopeProperty *sprop; JSStackFrame *fp; proto = OBJ_GET_PROTO(cx, obj); if (!proto) return js_LookupProperty(cx, obj, id, objp, propp); if (!OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp)) return JS_FALSE; /* * Check whether id names an argument or local variable in an active * function. If so, pretend we didn't find it, so that the real arg or * var property can be found in the function's call object, later on in * the scope chain. But skip unshared arg and var properties -- those * result when a script explicitly sets a function "static" property of * the same name. See jsinterp.c:SetFunctionSlot. * * XXX blame pre-ECMA reflection of function args and vars as properties */ if ((sprop = (JSScopeProperty *) *propp) && (proto = *objp, OBJ_IS_NATIVE(proto)) && (sprop->getter == js_GetArgument || sprop->getter == js_GetLocalVariable) && (sprop->attrs & JSPROP_SHARED)) { JS_ASSERT(OBJ_GET_CLASS(cx, proto) == &js_FunctionClass); for (fp = cx->fp; fp && (!fp->fun || fp->fun->native); fp = fp->down) continue; if (fp && fp->fun == (JSFunction *) JS_GetPrivate(cx, proto)) { OBJ_DROP_PROPERTY(cx, proto, *propp); *objp = NULL; *propp = NULL; } } return JS_TRUE;}static JSBoolwith_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp){ JSObject *proto = OBJ_GET_PROTO(cx, obj); if (!proto) return js_GetProperty(cx, obj, id, vp); return OBJ_GET_PROPERTY(cx, proto, id, vp);}static JSBoolwith_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp){ JSObject *proto = OBJ_GET_PROTO(cx, obj); if (!proto) return js_SetProperty(cx, obj, id, vp); return OBJ_SET_PROPERTY(cx, proto, id, vp);}static JSBoolwith_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, uintN *attrsp){ JSObject *proto = OBJ_GET_PROTO(cx, obj); if (!proto) return js_GetAttributes(cx, obj, id, prop, attrsp); return OBJ_GET_ATTRIBUTES(cx, proto, id, prop, attrsp);}static JSBoolwith_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, uintN *attrsp){ JSObject *proto = OBJ_GET_PROTO(cx, obj); if (!proto) return js_SetAttributes(cx, obj, id, prop, attrsp); return OBJ_SET_ATTRIBUTES(cx, proto, id, prop, attrsp);}static JSBoolwith_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval){ JSObject *proto = OBJ_GET_PROTO(cx, obj); if (!proto) return js_DeleteProperty(cx, obj, id, rval); return OBJ_DELETE_PROPERTY(cx, proto, id, rval);}static JSBoolwith_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp){ JSObject *proto = OBJ_GET_PROTO(cx, obj); if (!proto) return js_DefaultValue(cx, obj, hint, vp); return OBJ_DEFAULT_VALUE(cx, proto, hint, vp);}static JSBoolwith_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp){ JSObject *proto = OBJ_GET_PROTO(cx, obj); if (!proto) return js_Enumerate(cx, obj, enum_op, statep, idp); return OBJ_ENUMERATE(cx, proto, enum_op, statep, idp);}static JSBoolwith_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, jsval *vp, uintN *attrsp){ JSObject *proto = OBJ_GET_PROTO(cx, obj); if (!proto) return js_CheckAccess(cx, obj, id, mode, vp, attrsp); return OBJ_CHECK_ACCESS(cx, proto, id, mode, vp, attrsp);}static JSObject *with_ThisObject(JSContext *cx, JSObject *obj){ JSObject *proto = OBJ_GET_PROTO(cx, obj); if (!proto) return obj; return OBJ_THIS_OBJECT(cx, proto);}JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps = { js_NewObjectMap, js_DestroyObjectMap, with_LookupProperty, js_DefineProperty, with_GetProperty, with_SetProperty, with_GetAttributes, with_SetAttributes, with_DeleteProperty, with_DefaultValue, with_Enumerate, with_CheckAccess, with_ThisObject, NATIVE_DROP_PROPERTY, NULL, NULL, NULL, NULL, js_SetProtoOrParent, js_SetProtoOrParent, js_Mark, js_Clear, NULL, NULL};static JSObjectOps *with_getObjectOps(JSContext *cx, const JSClass *clasp){ return &js_WithObjectOps;}JSClass js_WithClass = { "With", 0, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, with_getObjectOps, 0,0,0,0,0,0,0};#if JS_HAS_OBJ_PROTO_PROPstatic JSBoolWith(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSObject *parent, *proto;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -