--- sbbs/include/mozilla/js/jsobj.h 2018/04/24 16:41:23 1.1 +++ sbbs/include/mozilla/js/jsobj.h 2018/04/24 16:41:58 1.1.1.2 @@ -1,4 +1,5 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sw=4 et tw=80: * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -61,13 +62,8 @@ struct JSObjectMap { }; /* Shorthand macros for frequently-made calls. */ -#if defined JS_THREADSAFE && defined DEBUG -#define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \ - (obj)->map->ops->lookupProperty(cx,obj,id,objp,propp,__FILE__,__LINE__) -#else #define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \ (obj)->map->ops->lookupProperty(cx,obj,id,objp,propp) -#endif #define OBJ_DEFINE_PROPERTY(cx,obj,id,value,getter,setter,attrs,propp) \ (obj)->map->ops->defineProperty(cx,obj,id,value,getter,setter,attrs,propp) #define OBJ_GET_PROPERTY(cx,obj,id,vp) \ @@ -105,6 +101,16 @@ struct JSObjectMap { ? (obj)->map->ops->setRequiredSlot(cx, obj, slot, v) \ : JS_TRUE) +#define OBJ_TO_INNER_OBJECT(cx,obj) \ + JS_BEGIN_MACRO \ + JSClass *clasp_ = OBJ_GET_CLASS(cx, obj); \ + if (clasp_->flags & JSCLASS_IS_EXTENDED) { \ + JSExtendedClass *xclasp_ = (JSExtendedClass*)clasp_; \ + if (xclasp_->innerObject) \ + obj = xclasp_->innerObject(cx, obj); \ + } \ + JS_END_MACRO + /* * In the original JS engine design, obj->slots pointed to a vector of length * JS_INITIAL_NSLOTS words if obj->map was shared with a prototype object, @@ -230,6 +236,59 @@ extern JS_FRIEND_DATA(JSObjectOps) js_Ob extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps; extern JSClass js_ObjectClass; extern JSClass js_WithClass; +extern JSClass js_BlockClass; + +/* + * Block scope object macros. The slots reserved by js_BlockClass are: + * + * JSSLOT_PRIVATE JSStackFrame * active frame pointer or null + * JSSLOT_BLOCK_DEPTH int depth of block slots in frame + * + * After JSSLOT_BLOCK_DEPTH come one or more slots for the block locals. + * OBJ_BLOCK_COUNT depends on this arrangement. + * + * A With object is like a Block object, in that both have one reserved slot + * telling the stack depth of the relevant slots (the slot whose value is the + * object named in the with statement, the slots containing the block's local + * variables); and both have a private slot referring to the JSStackFrame in + * whose activation they were created (or null if the with or block object + * outlives the frame). + */ +#define JSSLOT_BLOCK_DEPTH (JSSLOT_PRIVATE + 1) + +#define OBJ_BLOCK_COUNT(cx,obj) \ + ((obj)->map->freeslot - (JSSLOT_BLOCK_DEPTH + 1)) +#define OBJ_BLOCK_DEPTH(cx,obj) \ + JSVAL_TO_INT(OBJ_GET_SLOT(cx, obj, JSSLOT_BLOCK_DEPTH)) +#define OBJ_SET_BLOCK_DEPTH(cx,obj,depth) \ + OBJ_SET_SLOT(cx, obj, JSSLOT_BLOCK_DEPTH, INT_TO_JSVAL(depth)) + +/* + * To make sure this slot is well-defined, always call js_NewWithObject to + * create a With object, don't call js_NewObject directly. When creating a + * With object that does not correspond to a stack slot, pass -1 for depth. + * + * When popping the stack across this object's "with" statement, client code + * must call JS_SetPrivate(cx, withobj, NULL). + */ +extern JSObject * +js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth); + +/* + * Create a new block scope object not linked to any proto or parent object. + * Blocks are created by the compiler to reify let blocks and comprehensions. + * Only when dynamic scope is captured do they need to be cloned and spliced + * into an active scope chain. + */ +extern JSObject * +js_NewBlockObject(JSContext *cx); + +extern JSObject * +js_CloneBlockObject(JSContext *cx, JSObject *proto, JSObject *parent, + JSStackFrame *fp); + +extern JSBool +js_PutBlockObject(JSContext *cx, JSObject *obj); struct JSSharpObjectMap { jsrefcount depth; @@ -240,26 +299,40 @@ struct JSSharpObjectMap { #define SHARP_BIT ((jsatomid) 1) #define BUSY_BIT ((jsatomid) 2) #define SHARP_ID_SHIFT 2 -#define IS_SHARP(he) ((jsatomid)(he)->value & SHARP_BIT) -#define MAKE_SHARP(he) ((he)->value = (void*)((jsatomid)(he)->value|SHARP_BIT)) -#define IS_BUSY(he) ((jsatomid)(he)->value & BUSY_BIT) -#define MAKE_BUSY(he) ((he)->value = (void*)((jsatomid)(he)->value|BUSY_BIT)) -#define CLEAR_BUSY(he) ((he)->value = (void*)((jsatomid)(he)->value&~BUSY_BIT)) +#define IS_SHARP(he) (JS_PTR_TO_UINT32((he)->value) & SHARP_BIT) +#define MAKE_SHARP(he) ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)|SHARP_BIT)) +#define IS_BUSY(he) (JS_PTR_TO_UINT32((he)->value) & BUSY_BIT) +#define MAKE_BUSY(he) ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)|BUSY_BIT)) +#define CLEAR_BUSY(he) ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)&~BUSY_BIT)) extern JSHashEntry * js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, - jschar **sp); + jschar **sp); extern void js_LeaveSharpObject(JSContext *cx, JSIdArray **idap); +/* + * Mark objects stored in map if GC happens between js_EnterSharpObject + * and js_LeaveSharpObject. GC calls this when map->depth > 0. + */ +extern void +js_GCMarkSharpMap(JSContext *cx, JSSharpObjectMap *map); + extern JSBool js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, - jsval *rval); + jsval *rval); extern JSBool js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, - jsval *rval); + jsval *rval); + +extern JSBool +js_HasOwnPropertyHelper(JSContext *cx, JSObject *obj, JSLookupPropOp lookup, + uintN argc, jsval *argv, jsval *rval); + +extern JSObject* +js_InitBlockClass(JSContext *cx, JSObject* obj); extern JSObject * js_InitObjectClass(JSContext *cx, JSObject *obj); @@ -277,11 +350,11 @@ extern const char js_lookupSetter_str[]; extern void js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops, - JSClass *clasp); + JSClass *clasp); extern JSObjectMap * js_NewObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, - JSClass *clasp, JSObject *obj); + JSClass *clasp, JSObject *obj); extern void js_DestroyObjectMap(JSContext *cx, JSObjectMap *map); @@ -292,9 +365,25 @@ js_HoldObjectMap(JSContext *cx, JSObject extern JSObjectMap * js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj); +extern JSBool +js_GetClassId(JSContext *cx, JSClass *clasp, jsid *idp); + extern JSObject * js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); +/* + * Fast access to immutable standard objects (constructors and prototypes). + */ +extern JSBool +js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, + JSObject **objp); + +extern JSBool +js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject *cobj); + +extern JSBool +js_FindClassObject(JSContext *cx, JSObject *start, jsid id, jsval *vp); + extern JSObject * js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent, uintN argc, jsval *argv); @@ -309,6 +398,21 @@ extern void js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot); /* + * Native property add and lookup variants that hide id in the hidden atom + * subspace, so as to avoid collisions between internal properties such as + * formal arguments and local variables in function objects, and externally + * set properties with the same ids. + */ +extern JSScopeProperty * +js_AddHiddenProperty(JSContext *cx, JSObject *obj, jsid id, + JSPropertyOp getter, JSPropertyOp setter, uint32 slot, + uintN attrs, uintN flags, intN shortid); + +extern JSBool +js_LookupHiddenProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, + JSProperty **propp); + +/* * Find or create a property named by id in obj's scope, with the given getter * and setter, slot, attributes, and other members. */ @@ -336,8 +440,8 @@ js_ChangeNativePropertyAttrs(JSContext * */ extern JSBool js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, - JSPropertyOp getter, JSPropertyOp setter, uintN attrs, - JSProperty **propp); + JSPropertyOp getter, JSPropertyOp setter, uintN attrs, + JSProperty **propp); extern JSBool js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, @@ -351,33 +455,24 @@ js_DefineNativeProperty(JSContext *cx, J * *objp and *propp null. Therefore all callers who receive a non-null *propp * must later call OBJ_DROP_PROPERTY(cx, *objp, *propp). */ -#if defined JS_THREADSAFE && defined DEBUG -extern JS_FRIEND_API(JSBool) -_js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, - JSProperty **propp, const char *file, uintN line); - -#define js_LookupProperty(cx,obj,id,objp,propp) \ - _js_LookupProperty(cx,obj,id,objp,propp,__FILE__,__LINE__) -#else extern JS_FRIEND_API(JSBool) js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, - JSProperty **propp); -#endif + JSProperty **propp); /* * Specialized subroutine that allows caller to preset JSRESOLVE_* flags. + * JSRESOLVE_HIDDEN flags hidden function param/local name lookups, just for + * internal use by fun_resolve and similar built-ins. */ extern JSBool js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags, - JSObject **objp, JSProperty **propp -#if defined JS_THREADSAFE && defined DEBUG - , const char *file, uintN line -#endif - ); + JSObject **objp, JSProperty **propp); + +#define JSRESOLVE_HIDDEN 0x8000 extern JS_FRIEND_API(JSBool) js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp, - JSProperty **propp); + JSProperty **propp); extern JSObject * js_FindIdentifierBase(JSContext *cx, jsid id); @@ -385,6 +480,19 @@ js_FindIdentifierBase(JSContext *cx, jsi extern JSObject * js_FindVariableScope(JSContext *cx, JSFunction **funp); +/* + * NB: js_NativeGet and js_NativeSet are called with the scope containing sprop + * (pobj's scope for Get, obj's for Set) locked, and on successful return, that + * scope is again locked. But on failure, both functions return false with the + * scope containing sprop unlocked. + */ +extern JSBool +js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, + JSScopeProperty *sprop, jsval *vp); + +extern JSBool +js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp); + extern JSBool js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); @@ -393,11 +501,11 @@ js_SetProperty(JSContext *cx, JSObject * extern JSBool js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, - uintN *attrsp); + uintN *attrsp); extern JSBool js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, - uintN *attrsp); + uintN *attrsp); extern JSBool js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval); @@ -408,23 +516,29 @@ js_DefaultValue(JSContext *cx, JSObject extern JSIdArray * js_NewIdArray(JSContext *cx, jsint length); +/* + * Unlike realloc(3), this function frees ida on failure. + */ extern JSIdArray * -js_GrowIdArray(JSContext *cx, JSIdArray *ida, jsint length); +js_SetIdArrayLength(JSContext *cx, JSIdArray *ida, jsint length); extern JSBool js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, - jsval *statep, jsid *idp); + jsval *statep, jsid *idp); + +extern void +js_MarkNativeIteratorStates(JSContext *cx); extern JSBool js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, - jsval *vp, uintN *attrsp); + jsval *vp, uintN *attrsp); extern JSBool js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); extern JSBool js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, - jsval *rval); + jsval *rval); extern JSBool js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); @@ -436,11 +550,12 @@ extern JSBool js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); extern JSBool -js_GetClassPrototype(JSContext *cx, const char *name, JSObject **protop); +js_GetClassPrototype(JSContext *cx, JSObject *scope, jsid id, + JSObject **protop); extern JSBool js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto, - uintN attrs); + uintN attrs); extern JSBool js_ValueToObject(JSContext *cx, jsval v, JSObject **objp); @@ -453,7 +568,7 @@ js_TryValueOf(JSContext *cx, JSObject *o extern JSBool js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom, - uintN argc, jsval *argv, jsval *rval); + uintN argc, jsval *argv, jsval *rval); extern JSBool js_XDRObject(JSXDRState *xdr, JSObject **objp); @@ -470,6 +585,12 @@ js_GetRequiredSlot(JSContext *cx, JSObje extern JSBool js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v); +extern JSObject * +js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller); + +extern JSBool +js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj, + JSPrincipals *principals, JSAtom *caller); JS_END_EXTERN_C #endif /* jsobj_h___ */