Merge.
authorAndreas Gal <gal@mozilla.com>
Thu, 05 Feb 2009 15:15:50 -0800
changeset 24855 131934bdfa19a7105acc72d7346a46f5b23d66c7
parent 24854 21494181fdb84b3dad6db774cbfd25be8cc9425c (current diff)
parent 24852 da50f697779fd6bee3aa95a5421a6c67ca8ee621 (diff)
child 24856 b2f377e7e00a8215986ec42402877f8e497a714b
push idunknown
push userunknown
push dateunknown
milestone1.9.2a1pre
Merge.
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1,9 +1,9 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sw=4 et tw=79:
  *
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
@@ -6239,18 +6239,23 @@ 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_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
+                    ? !js_SetPropertyHelper(cx, obj, id, &rval, &entry)
+                    : !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--;
@@ -6268,37 +6273,34 @@ js_Interpret(JSContext *cx)
 
             /* Fetch id now that we have obj. */
             FETCH_ELEMENT_ID(obj, -2, id);
 
             /*
              * Check for property redeclaration strict warning (we may be in
              * an object initialiser, not an array initialiser).
              */
-            if (!js_CheckRedeclaration(cx, obj, id, JSPROP_INITIALIZER, NULL,
-                                       NULL)) {
+            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))) {
+                    !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;
@@ -6841,17 +6843,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
@@ -3423,25 +3423,28 @@ js_DefineProperty(JSContext *cx, JSObjec
         }                                                                     \
         if (STOBJ_IS_DELEGATE(obj) && JSID_IS_INT(sprop->id))                 \
             cx->runtime->anyArrayProtoHasElement = JS_TRUE;                   \
     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);
 
+    uint32 shape = OBJ_SHAPE(obj);
+
 #if JS_HAS_GETTER_SETTER
     /*
      * If defining a getter or setter, we must check for its counterpart and
      * update the attributes and property ops.  A getter or setter is really
      * only half of a property.
      */
     sprop = NULL;
     if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
@@ -3519,16 +3522,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_ON_TRACE(cx);
+        if (!(attrs & JSPROP_SHARED))
+            js_FillPropertyCache(cx, obj, shape, 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);
@@ -4151,17 +4161,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
@@ -541,20 +541,23 @@ js_ChangeNativePropertyAttrs(JSContext *
  * result parameters must later call OBJ_DROP_PROPERTY(cx, obj, *propp) both to
  * drop the held property, and to release the lock on obj.
  */
 extern JSBool
 js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
                   JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
                   JSProperty **propp);
 
+#ifdef __cplusplus /* FIXME: bug 442399 removes this LiveConnect requirement. */
 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);
+#endif
 
 /*
  * 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,50 @@ 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((JSObject *) (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((JSObject *) 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((JSObject *) (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((JSObject *) 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);