--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -6189,18 +6189,20 @@ js_Interpret(JSContext *cx)
LOAD_ATOM(0);
id = ATOM_TO_JSID(atom);
/* Set the property named by obj[id] to rval. */
if (!js_CheckRedeclaration(cx, obj, id, JSPROP_INITIALIZER,
NULL, NULL)) {
goto error;
}
- if (!js_SetPropertyHelper(cx, obj, id, &rval, &entry))
+ if (!js_DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
+ JSPROP_ENUMERATE, 0, 0, NULL, &entry)) {
goto error;
+ }
#ifdef JS_TRACER
if (entry)
TRACE_1(SetPropMiss, entry);
#endif
} while (0);
/* Common tail for property cache hit and miss cases. */
regs.sp--;
@@ -6224,31 +6226,31 @@ js_Interpret(JSContext *cx)
* an object initialiser, not an array initialiser).
*/
if (!js_CheckRedeclaration(cx, obj, id, JSPROP_INITIALIZER, NULL,
NULL)) {
goto error;
}
/*
- * If rval is a hole, do not call OBJ_SET_PROPERTY. In this case,
+ * If rval is a hole, do not call OBJ_DEFINE_PROPERTY. In this case,
* obj must be an array, so if the current op is the last element
* initialiser, set the array length to one greater than id.
*/
if (rval == JSVAL_HOLE) {
JS_ASSERT(OBJ_IS_ARRAY(cx, obj));
JS_ASSERT(JSID_IS_INT(id));
JS_ASSERT((jsuint) JSID_TO_INT(id) < ARRAY_INIT_LIMIT);
if ((JSOp) regs.pc[JSOP_INITELEM_LENGTH] == JSOP_ENDINIT &&
!js_SetLengthProperty(cx, obj,
(jsuint) (JSID_TO_INT(id) + 1))) {
goto error;
}
} else {
- if (!OBJ_SET_PROPERTY(cx, obj, id, &rval))
+ if (!OBJ_DEFINE_PROPERTY(cx, obj, id, rval, NULL, NULL, JSPROP_ENUMERATE, NULL))
goto error;
}
regs.sp -= 2;
END_CASE(JSOP_INITELEM)
#if JS_HAS_SHARP_VARS
BEGIN_CASE(JSOP_DEFSHARP)
obj = fp->sharpArray;
@@ -6791,17 +6793,17 @@ js_Interpret(JSContext *cx)
*/
i = obj->fslots[JSSLOT_ARRAY_LENGTH];
if (i == ARRAY_INIT_LIMIT) {
JS_ReportErrorNumberUC(cx, js_GetErrorMessage, NULL,
JSMSG_ARRAY_INIT_TOO_BIG);
goto error;
}
id = INT_TO_JSID(i);
- if (!OBJ_SET_PROPERTY(cx, obj, id, &rval))
+ if (!OBJ_DEFINE_PROPERTY(cx, obj, id, rval, NULL, NULL, JSPROP_ENUMERATE, NULL))
goto error;
regs.sp--;
END_CASE(JSOP_ARRAYPUSH)
#endif /* JS_HAS_GENERATORS */
#if JS_THREADED_INTERP
L_JSOP_BACKPATCH:
L_JSOP_BACKPATCH_POP:
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3402,17 +3402,18 @@ js_DefineProperty(JSContext *cx, JSObjec
LOCKED_OBJ_WRITE_BARRIER(cx, obj, (sprop)->slot, *(vp)); \
} \
} \
JS_END_MACRO
JSBool
js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
- uintN flags, intN shortid, JSProperty **propp)
+ uintN flags, intN shortid, JSProperty **propp,
+ JSPropCacheEntry** entryp /* = NULL */)
{
JSClass *clasp;
JSScope *scope;
JSScopeProperty *sprop;
/* Convert string indices to integers if appropriate. */
CHECK_FOR_STRING_INDEX(id);
@@ -3498,16 +3499,23 @@ js_DefineNativeProperty(JSContext *cx, J
if (SPROP_HAS_VALID_SLOT(sprop, scope))
LOCKED_OBJ_WRITE_BARRIER(cx, obj, sprop->slot, value);
/* XXXbe called with lock held */
ADD_PROPERTY_HELPER(cx, clasp, obj, scope, sprop, &value,
js_RemoveScopeProperty(cx, scope, id);
goto bad);
+ if (entryp) {
+ JS_ASSERT_NOT_EXECUTING_TRACE(cx);
+ if (!(attrs & JSPROP_SHARED))
+ js_FillPropertyCache(cx, obj, OBJ_SHAPE(obj), 0, 0, obj, sprop, entryp);
+ else
+ PCMETER(JS_PROPERTY_CACHE(cx).nofills++);
+ }
if (propp)
*propp = (JSProperty *) sprop;
else
JS_UNLOCK_OBJ(cx, obj);
return JS_TRUE;
bad:
JS_UNLOCK_OBJ(cx, obj);
@@ -4111,17 +4119,17 @@ js_SetPropertyHelper(JSContext *cx, JSOb
*entryp = NULL;
}
if (SPROP_HAS_STUB_SETTER(sprop) &&
!(sprop->attrs & JSPROP_GETTER)) {
return JS_TRUE;
}
- return !!SPROP_SET(cx, sprop, obj, pobj, vp);
+ return SPROP_SET(cx, sprop, obj, pobj, vp);
}
/* Restore attrs to the ECMA default for new properties. */
attrs = JSPROP_ENUMERATE;
/*
* Preserve the shortid, getter, and setter when shadowing any
* property that has a shortid. An old API convention requires
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -544,17 +544,18 @@ js_ChangeNativePropertyAttrs(JSContext *
extern JSBool
js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
JSProperty **propp);
extern JSBool
js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
- uintN flags, intN shortid, JSProperty **propp);
+ uintN flags, intN shortid, JSProperty **propp,
+ JSPropCacheEntry** entryp = NULL);
/*
* Unlike js_DefineProperty, propp must be non-null. On success, and if id was
* found, return true with *objp non-null and locked, and with a held property
* stored in *propp. If successful but id was not found, return true with both
* *objp and *propp null. Therefore all callers who receive a non-null *propp
* must later call OBJ_DROP_PROPERTY(cx, *objp, *propp).
*/
--- a/js/src/jsscope.h
+++ b/js/src/jsscope.h
@@ -323,39 +323,52 @@ struct JSScopeProperty {
#define SPROP_INVALID_SLOT 0xffffffff
#define SLOT_IN_SCOPE(slot,scope) ((slot) < (scope)->map.freeslot)
#define SPROP_HAS_VALID_SLOT(sprop,scope) SLOT_IN_SCOPE((sprop)->slot, scope)
#define SPROP_HAS_STUB_GETTER(sprop) (!(sprop)->getter)
#define SPROP_HAS_STUB_SETTER(sprop) (!(sprop)->setter)
-/*
- * NB: SPROP_GET must not be called if SPROP_HAS_STUB_GETTER(sprop).
- */
-#define SPROP_GET(cx,sprop,obj,obj2,vp) \
- (((sprop)->attrs & JSPROP_GETTER) \
- ? js_InternalGetOrSet(cx, obj, (sprop)->id, \
- OBJECT_TO_JSVAL((sprop)->getter), JSACC_READ, \
- 0, 0, vp) \
- : (sprop)->getter(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
+static JS_INLINE JSBool
+SPROP_GET(JSContext* cx, JSScopeProperty* sprop, JSObject* obj, JSObject* obj2,
+ jsval* vp)
+{
+ JS_ASSERT(!SPROP_HAS_STUB_GETTER(sprop));
+
+ if (sprop->attrs & JSPROP_GETTER) {
+ return js_InternalGetOrSet(cx, obj, sprop->id,
+ OBJECT_TO_JSVAL(sprop->getter), JSACC_READ,
+ 0, 0, vp);
+ }
+
+ return sprop->getter(cx, OBJ_THIS_OBJECT(cx, obj), SPROP_USERID(sprop), vp);
+}
-/*
- * NB: SPROP_SET must not be called if (SPROP_HAS_STUB_SETTER(sprop) &&
- * !(sprop->attrs & JSPROP_GETTER)).
- */
-#define SPROP_SET(cx,sprop,obj,obj2,vp) \
- (((sprop)->attrs & JSPROP_SETTER) \
- ? js_InternalGetOrSet(cx, obj, (sprop)->id, \
- OBJECT_TO_JSVAL((sprop)->setter), JSACC_WRITE, \
- 1, vp, vp) \
- : ((sprop)->attrs & JSPROP_GETTER) \
- ? (JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, \
- JSMSG_GETTER_ONLY, NULL), JS_FALSE) \
- : (sprop)->setter(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
+static JS_INLINE JSBool
+SPROP_SET(JSContext* cx, JSScopeProperty* sprop, JSObject* obj, JSObject* obj2,
+ jsval* vp)
+{
+ JS_ASSERT(!(SPROP_HAS_STUB_SETTER(sprop) &&
+ !(sprop->attrs & JSPROP_GETTER)));
+
+ if ((sprop)->attrs & JSPROP_SETTER) {
+ return js_InternalGetOrSet(cx, obj, (sprop)->id,
+ OBJECT_TO_JSVAL((sprop)->setter),
+ JSACC_WRITE, 1, vp, vp);
+ }
+
+ if ((sprop)->attrs & JSPROP_GETTER) {
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+ JSMSG_GETTER_ONLY, NULL);
+ return JS_FALSE;
+ }
+
+ return sprop->setter(cx, OBJ_THIS_OBJECT(cx, obj), SPROP_USERID(sprop), vp);
+}
/* Macro for common expression to test for shared permanent attributes. */
#define SPROP_IS_SHARED_PERMANENT(sprop) \
((~(sprop)->attrs & (JSPROP_SHARED | JSPROP_PERMANENT)) == 0)
extern JSScope *
js_GetMutableScope(JSContext *cx, JSObject *obj);