Fix regression from 419152 to test for 58274 (r/a=shaver).
authorbrendan@mozilla.org
Tue, 26 Feb 2008 09:01:52 -0800
changeset 12267 e8357d7b2f21f0ab4af3f04f1adbaf0a27d8fd80
parent 12266 7962f01056292368de168f0e73637916941917bc
child 12268 624cbd0e90bef8366beb822cf38f60cc6a6ed243
push idunknown
push userunknown
push dateunknown
bugs419152, 58274
milestone1.9b4pre
Fix regression from 419152 to test for 58274 (r/a=shaver).
js/src/jsinterp.c
js/src/jsstr.c
js/src/jsstr.h
--- a/js/src/jsinterp.c
+++ b/js/src/jsinterp.c
@@ -4384,23 +4384,24 @@ interrupt:
             /* Open-coded ELEMENT_OP optimized for strings and dense arrays. */
             SAVE_SP_AND_PC(fp);
             lval = FETCH_OPND(-2);
             rval = FETCH_OPND(-1);
             if (JSVAL_IS_STRING(lval) && JSVAL_IS_INT(rval)) {
                 str = JSVAL_TO_STRING(lval);
                 i = JSVAL_TO_INT(rval);
                 if ((size_t)i < JSSTRING_LENGTH(str)) {
-                    str = js_GetUnitString(cx, JSSTRING_CHARS(str)[i]);
+                    str = js_GetUnitString(cx, str, (size_t)i);
                     if (!str)
                         goto error;
                     rval = STRING_TO_JSVAL(str);
                     goto end_getelem;
                 }
             }
+
             VALUE_TO_OBJECT(cx, -2, lval, obj);
             if (JSVAL_IS_INT(rval)) {
                 if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
                     jsuint length;
                     
                     length = ARRAY_DENSE_LENGTH(obj);
                     i = JSVAL_TO_INT(rval);
                     if ((jsuint)i < length && 
@@ -4410,16 +4411,17 @@ interrupt:
                             goto end_getelem;
                     }
                 }
                 id = INT_JSVAL_TO_JSID(rval);
             } else {
                 if (!InternNonIntElementId(cx, obj, rval, &id))
                     goto error;
             }
+
             if (!OBJ_GET_PROPERTY(cx, obj, id, &rval))
                 goto error;
           end_getelem:
             sp--;
             STORE_OPND(-1, rval);
           END_CASE(JSOP_GETELEM)
 
           BEGIN_CASE(JSOP_CALLELEM)
--- a/js/src/jsstr.c
+++ b/js/src/jsstr.c
@@ -578,17 +578,17 @@ str_resolve(JSContext *cx, JSObject *obj
         return JS_TRUE;
 
     v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
     JS_ASSERT(JSVAL_IS_STRING(v));
     str = JSVAL_TO_STRING(v);
 
     slot = JSVAL_TO_INT(id);
     if ((size_t)slot < JSSTRING_LENGTH(str)) {
-        str1 = js_GetUnitString(cx, JSSTRING_CHARS(str)[slot]);
+        str1 = js_GetUnitString(cx, str, (size_t)slot);
         if (!str1)
             return JS_FALSE;
         if (!OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSID(slot),
                                  STRING_TO_JSVAL(str1), NULL, NULL,
                                  STRING_ELEMENT_ATTRS, NULL)) {
             return JS_FALSE;
         }
         *objp = obj;
@@ -844,17 +844,16 @@ str_localeCompare(JSContext *cx, uintN a
 }
 
 static JSBool
 str_charAt(JSContext *cx, uintN argc, jsval *vp)
 {
     jsval t, v;
     JSString *str;
     jsint i;
-    jschar c;
     jsdouble d;
 
     t = vp[1];
     v = vp[2];
     if (JSVAL_IS_STRING(t) && JSVAL_IS_INT(v)) {
         str = JSVAL_TO_STRING(t);
         i = JSVAL_TO_INT(v);
         if ((size_t)i >= JSSTRING_LENGTH(str))
@@ -872,20 +871,17 @@ str_charAt(JSContext *cx, uintN argc, js
             d = js_DoubleToInteger(d);
         }
 
         if (d < 0 || JSSTRING_LENGTH(str) <= d)
             goto out_of_range;
         i = (jsint) d;
     }
 
-    c = JSSTRING_CHARS(str)[i];
-    str = (c < UNIT_STRING_LIMIT)
-          ? js_GetUnitString(cx, c)
-          : js_NewDependentString(cx, str, i, 1);
+    str = js_GetUnitString(cx, str, (size_t)i);
     if (!str)
         return JS_FALSE;
     *vp = STRING_TO_JSVAL(str);
     return JS_TRUE;
 
 out_of_range:
     *vp = JS_GetEmptyStringValue(cx);
     return JS_TRUE;
@@ -1956,34 +1952,32 @@ str_concat(JSContext *cx, uintN argc, js
     return JS_TRUE;
 }
 
 static JSBool
 str_slice(JSContext *cx, uintN argc, jsval *vp)
 {
     jsval t, v;
     JSString *str;
-    jschar c;
 
     t = vp[1];
     v = vp[2];
     if (argc == 1 && JSVAL_IS_STRING(t) && JSVAL_IS_INT(v)) {
         size_t begin, end, length;
 
         str = JSVAL_TO_STRING(t);
         begin = JSVAL_TO_INT(v);
         end = JSSTRING_LENGTH(str);
         if (begin <= end) {
             length = end - begin;
             if (length == 0) {
                 str = cx->runtime->emptyString;
             } else {
-                str = (length == 1 &&
-                       (c = JSSTRING_CHARS(str)[begin]) < UNIT_STRING_LIMIT)
-                      ? js_GetUnitString(cx, c)
+                str = (length == 1)
+                      ? js_GetUnitString(cx, str, begin)
                       : js_NewDependentString(cx, str, begin, length);
                 if (!str)
                     return JS_FALSE;
             }
             *vp = STRING_TO_JSVAL(str);
             return JS_TRUE;
         }
     }
@@ -2348,23 +2342,27 @@ js_InitDeflatedStringCache(JSRuntime *rt
 #define UNIT_STRING_SPACE_RT(rt) UNIT_STRING_SPACE((rt)->unitStrings)
 
 #define IN_UNIT_STRING_SPACE(sp,cp)                                           \
     ((size_t)((cp) - UNIT_STRING_SPACE(sp)) < 2 * UNIT_STRING_LIMIT)
 #define IN_UNIT_STRING_SPACE_RT(rt,cp)                                        \
     IN_UNIT_STRING_SPACE((rt)->unitStrings, cp)
 
 JSString *
-js_GetUnitString(JSContext *cx, jschar c)
+js_GetUnitString(JSContext *cx, JSString *str, size_t index)
 {
+    jschar c, *cp, i;
     JSRuntime *rt;
-    JSString **sp, *str;
-    jschar *cp, i;
-
-    JS_ASSERT(c < UNIT_STRING_LIMIT);
+    JSString **sp;
+
+    JS_ASSERT(index < JSSTRING_LENGTH(str));
+    c = JSSTRING_CHARS(str)[index];
+    if (c >= UNIT_STRING_LIMIT)
+        return js_NewDependentString(cx, str, index, 1);
+
     rt = cx->runtime;
     if (!rt->unitStrings) {
         sp = (JSString **) calloc(UNIT_STRING_LIMIT * sizeof(JSString *) +
                                   UNIT_STRING_LIMIT * 2 * sizeof(jschar),
                                   1);
         if (!sp) {
             JS_ReportOutOfMemory(cx);
             return NULL;
--- a/js/src/jsstr.h
+++ b/js/src/jsstr.h
@@ -402,24 +402,21 @@ js_InitDeflatedStringCache(JSRuntime *rt
 
 /*
  * Maximum character code for which we will create a pinned unit string on
  * demand -- see JSRuntime.unitStrings in jscntxt.h.
  */
 #define UNIT_STRING_LIMIT 256U
 
 /*
- * Get the independent string containing only character code c (backstopped
- * with a NUL as usual for independent strings).
- *
- * This function must be called only for c < UNIT_STRING_LIMIT. It asserts to
- * insist on this requirement in DEBUG builds.
+ * Get the independent string containing only character code at index in str
+ * (backstopped with a zero character as usual for independent strings).
  */
 extern JSString *
-js_GetUnitString(JSContext *cx, jschar c);
+js_GetUnitString(JSContext *cx, JSString *str, size_t index);
 
 extern void
 js_FinishUnitStrings(JSRuntime *rt);
 
 extern void
 js_FinishRuntimeStringState(JSContext *cx);
 
 extern void