/[jscoverage]/trunk/js/jsarray.cpp
ViewVC logotype

Diff of /trunk/js/jsarray.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 398 by siliconforks, Thu Oct 23 19:03:33 2008 UTC revision 399 by siliconforks, Tue Dec 9 03:37:47 2008 UTC
# Line 85  Line 85 
85  #include "jsatom.h"  #include "jsatom.h"
86  #include "jsbit.h"  #include "jsbit.h"
87  #include "jsbool.h"  #include "jsbool.h"
88    #include "jsbuiltins.h"
89  #include "jscntxt.h"  #include "jscntxt.h"
90  #include "jsversion.h"  #include "jsversion.h"
91  #include "jsdbgapi.h" /* for js_TraceWatchPoints */  #include "jsdbgapi.h" /* for js_TraceWatchPoints */
# Line 791  Line 792 
792      return JS_TRUE;      return JS_TRUE;
793  }  }
794    
795    #ifdef JS_TRACER
796    JSBool FASTCALL
797    js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
798    {
799        JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
800    
801        do {
802            jsuint length = ARRAY_DENSE_LENGTH(obj);
803            if ((jsuint)i < length) {
804                if (obj->dslots[i] == JSVAL_HOLE) {
805                    if (cx->runtime->anyArrayProtoHasElement)
806                        break;
807                    if (i >= obj->fslots[JSSLOT_ARRAY_LENGTH])
808                        obj->fslots[JSSLOT_ARRAY_LENGTH] = i + 1;
809                    obj->fslots[JSSLOT_ARRAY_COUNT]++;
810                }
811                obj->dslots[i] = v;
812                return JS_TRUE;
813            }
814        } while (0);
815        return OBJ_SET_PROPERTY(cx, obj, INT_TO_JSID(i), &v);
816    }
817    #endif
818    
819  static JSBool  static JSBool
820  array_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,  array_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
821                       JSPropertyOp getter, JSPropertyOp setter, uintN attrs,                       JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
822                       JSProperty **propp)                       JSProperty **propp)
823  {  {
824      uint32 i;      uint32 i;
825        JSBool isIndex;
826    
827      if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))      if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))
828          return JS_TRUE;          return JS_TRUE;
829    
830      if (!js_IdIsIndex(ID_TO_VALUE(id), &i) || attrs != JSPROP_ENUMERATE) {      isIndex = js_IdIsIndex(ID_TO_VALUE(id), &i);
831        if (!isIndex || attrs != JSPROP_ENUMERATE) {
832          if (!ENSURE_SLOW_ARRAY(cx, obj))          if (!ENSURE_SLOW_ARRAY(cx, obj))
833              return JS_FALSE;              return JS_FALSE;
834          return js_DefineProperty(cx, obj, id, value, getter, setter, attrs,          if (isIndex && STOBJ_IS_DELEGATE(obj))
835                                   propp);              cx->runtime->anyArrayProtoHasElement = JS_TRUE;
836            return js_DefineProperty(cx, obj, id, value, getter, setter, attrs, propp);
837      }      }
838    
839      return array_setProperty(cx, obj, id, &value);      return array_setProperty(cx, obj, id, &value);
# Line 1190  Line 1218 
1218      return JS_FALSE;      return JS_FALSE;
1219  }  }
1220    
1221    enum ArrayToStringOp {
1222        TO_STRING,
1223        TO_LOCALE_STRING,
1224        TO_SOURCE
1225    };
1226    
1227  /*  /*
1228   * When op is TO_STRING or TO_LOCALE_STRING sep indicates a separator to use   * When op is TO_STRING or TO_LOCALE_STRING sep indicates a separator to use
1229   * or "," when sep is NULL.   * or "," when sep is NULL.
1230   * When op is TO_SOURCE sep must be NULL.   * When op is TO_SOURCE sep must be NULL.
1231   */   */
1232  JSBool  static JSBool
1233  js_array_join_sub(JSContext *cx, JSObject *obj, enum ArrayToStringOp op,  array_join_sub(JSContext *cx, JSObject *obj, enum ArrayToStringOp op,
1234                    JSString *sep, jsval *rval)                 JSString *sep, jsval *rval)
1235  {  {
1236      JSBool ok, hole;      JSBool ok, hole;
1237      jsuint length, index;      jsuint length, index;
# Line 1415  Line 1449 
1449          !JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2)) {          !JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2)) {
1450          return JS_FALSE;          return JS_FALSE;
1451      }      }
1452      return js_array_join_sub(cx, obj, TO_SOURCE, NULL, vp);      return array_join_sub(cx, obj, TO_SOURCE, NULL, vp);
1453  }  }
1454  #endif  #endif
1455    
# Line 1429  Line 1463 
1463          !JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2)) {          !JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2)) {
1464          return JS_FALSE;          return JS_FALSE;
1465      }      }
1466      return js_array_join_sub(cx, obj, TO_STRING, NULL, vp);      return array_join_sub(cx, obj, TO_STRING, NULL, vp);
1467  }  }
1468    
1469  static JSBool  static JSBool
# Line 1447  Line 1481 
1481       *  Passing comma here as the separator. Need a way to get a       *  Passing comma here as the separator. Need a way to get a
1482       *  locale-specific version.       *  locale-specific version.
1483       */       */
1484      return js_array_join_sub(cx, obj, TO_LOCALE_STRING, NULL, vp);      return array_join_sub(cx, obj, TO_LOCALE_STRING, NULL, vp);
1485  }  }
1486    
1487  static JSBool  static JSBool
# Line 1503  Line 1537 
1537      return JS_TRUE;      return JS_TRUE;
1538  }  }
1539    
1540    #ifdef JS_TRACER
1541    static JSString* FASTCALL
1542    Array_p_join(JSContext* cx, JSObject* obj, JSString *str)
1543    {
1544        jsval v;
1545        if (!array_join_sub(cx, obj, TO_STRING, str, &v))
1546            return NULL;
1547        JS_ASSERT(JSVAL_IS_STRING(v));
1548        return JSVAL_TO_STRING(v);
1549    }
1550    
1551    static JSString* FASTCALL
1552    Array_p_toString(JSContext* cx, JSObject* obj)
1553    {
1554        jsval v;
1555        if (!array_join_sub(cx, obj, TO_STRING, NULL, &v))
1556            return NULL;
1557        JS_ASSERT(JSVAL_IS_STRING(v));
1558        return JSVAL_TO_STRING(v);
1559    }
1560    #endif
1561    
1562  /*  /*
1563   * Perl-inspired join, reverse, and sort.   * Perl-inspired join, reverse, and sort.
1564   */   */
1565  JSBool  static JSBool
1566  js_array_join(JSContext *cx, uintN argc, jsval *vp)  array_join(JSContext *cx, uintN argc, jsval *vp)
1567  {  {
1568      JSString *str;      JSString *str;
1569      JSObject *obj;      JSObject *obj;
# Line 1521  Line 1577 
1577          vp[2] = STRING_TO_JSVAL(str);          vp[2] = STRING_TO_JSVAL(str);
1578      }      }
1579      obj = JS_THIS_OBJECT(cx, vp);      obj = JS_THIS_OBJECT(cx, vp);
1580      return obj && js_array_join_sub(cx, obj, TO_STRING, str, vp);      return obj && array_join_sub(cx, obj, TO_STRING, str, vp);
1581  }  }
1582    
1583  static JSBool  static JSBool
# Line 2042  Line 2098 
2098  /*  /*
2099   * Perl-inspired push, pop, shift, unshift, and splice methods.   * Perl-inspired push, pop, shift, unshift, and splice methods.
2100   */   */
2101  JSBool  static JSBool
2102  js_array_push_slowly(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)  array_push_slowly(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2103  {  {
2104      jsuint length, newlength;      jsuint length, newlength;
2105    
# Line 2059  Line 2115 
2115      return js_SetLengthProperty(cx, obj, newlength);      return js_SetLengthProperty(cx, obj, newlength);
2116  }  }
2117    
2118  JSBool  static JSBool
2119  js_array_push1_dense(JSContext* cx, JSObject* obj, jsval v, jsval *rval)  array_push1_dense(JSContext* cx, JSObject* obj, jsval v, jsval *rval)
2120  {  {
2121      uint32 length = obj->fslots[JSSLOT_ARRAY_LENGTH];      uint32 length = obj->fslots[JSSLOT_ARRAY_LENGTH];
2122      if (INDEX_TOO_SPARSE(obj, length)) {      if (INDEX_TOO_SPARSE(obj, length)) {
2123          if (!js_MakeArraySlow(cx, obj))          if (!js_MakeArraySlow(cx, obj))
2124              return JS_FALSE;              return JS_FALSE;
2125          return js_array_push_slowly(cx, obj, 1, &v, rval);          return array_push_slowly(cx, obj, 1, &v, rval);
2126      }      }
2127    
2128      if (!EnsureLength(cx, obj, length + 1))      if (!EnsureLength(cx, obj, length + 1))
# Line 2079  Line 2135 
2135      return IndexToValue(cx, obj->fslots[JSSLOT_ARRAY_LENGTH], rval);      return IndexToValue(cx, obj->fslots[JSSLOT_ARRAY_LENGTH], rval);
2136  }  }
2137    
2138  JSBool  #ifdef JS_TRACER
2139  js_array_push(JSContext *cx, uintN argc, jsval *vp)  static jsval FASTCALL
2140    Array_p_push1(JSContext* cx, JSObject* obj, jsval v)
2141    {
2142        if (OBJ_IS_DENSE_ARRAY(cx, obj)
2143            ? array_push1_dense(cx, obj, v, &v)
2144            : array_push_slowly(cx, obj, 1, &v, &v)) {
2145            return v;
2146        }
2147        return JSVAL_ERROR_COOKIE;
2148    }
2149    #endif
2150    
2151    static JSBool
2152    array_push(JSContext *cx, uintN argc, jsval *vp)
2153  {  {
2154      JSObject *obj;      JSObject *obj;
2155    
# Line 2089  Line 2158 
2158      if (!obj)      if (!obj)
2159          return JS_FALSE;          return JS_FALSE;
2160      if (argc != 1 || !OBJ_IS_DENSE_ARRAY(cx, obj))      if (argc != 1 || !OBJ_IS_DENSE_ARRAY(cx, obj))
2161          return js_array_push_slowly(cx, obj, argc, vp + 2, vp);          return array_push_slowly(cx, obj, argc, vp + 2, vp);
2162    
2163      return js_array_push1_dense(cx, obj, vp[2], vp);      return array_push1_dense(cx, obj, vp[2], vp);
2164  }  }
2165    
2166  JSBool  static JSBool
2167  js_array_pop_slowly(JSContext *cx, JSObject* obj, jsval *vp)  array_pop_slowly(JSContext *cx, JSObject* obj, jsval *vp)
2168  {  {
2169      jsuint index;      jsuint index;
2170      JSBool hole;      JSBool hole;
# Line 2116  Line 2185 
2185      return js_SetLengthProperty(cx, obj, index);      return js_SetLengthProperty(cx, obj, index);
2186  }  }
2187    
2188  JSBool  static JSBool
2189  js_array_pop_dense(JSContext *cx, JSObject* obj, jsval *vp)  array_pop_dense(JSContext *cx, JSObject* obj, jsval *vp)
2190  {  {
2191      jsuint index;      jsuint index;
2192      JSBool hole;      JSBool hole;
# Line 2137  Line 2206 
2206            
2207  }  }
2208    
2209  JSBool  #ifdef JS_TRACER
2210  js_array_pop(JSContext *cx, uintN argc, jsval *vp)  static jsval FASTCALL
2211    Array_p_pop(JSContext* cx, JSObject* obj)
2212    {
2213        jsval v;
2214        if (OBJ_IS_DENSE_ARRAY(cx, obj)
2215            ? array_pop_dense(cx, obj, &v)
2216            : array_pop_slowly(cx, obj, &v)) {
2217            return v;
2218        }
2219        return JSVAL_ERROR_COOKIE;
2220    }
2221    #endif
2222    
2223    static JSBool
2224    array_pop(JSContext *cx, uintN argc, jsval *vp)
2225  {  {
2226      JSObject *obj;      JSObject *obj;
2227    
# Line 2146  Line 2229 
2229      if (!obj)      if (!obj)
2230          return JS_FALSE;          return JS_FALSE;
2231      if (OBJ_IS_DENSE_ARRAY(cx, obj))      if (OBJ_IS_DENSE_ARRAY(cx, obj))
2232          return js_array_pop_dense(cx, obj, vp);          return array_pop_dense(cx, obj, vp);
2233      return js_array_pop_slowly(cx, obj, vp);      return array_pop_slowly(cx, obj, vp);
2234  }  }
2235    
2236  static JSBool  static JSBool
# Line 2894  Line 2977 
2977      {0,0,0,0,0}      {0,0,0,0,0}
2978  };  };
2979    
2980    JS_DEFINE_TRCINFO_1(array_toString,
2981        (2, (static, STRING_FAIL, Array_p_toString, CONTEXT, THIS,      0, 0)))
2982    JS_DEFINE_TRCINFO_1(array_join,
2983        (3, (static, STRING_FAIL, Array_p_join, CONTEXT, THIS, STRING,  0, 0)))
2984    JS_DEFINE_TRCINFO_1(array_push,
2985        (3, (static, JSVAL_FAIL, Array_p_push1, CONTEXT, THIS, JSVAL,   0, 0)))
2986    JS_DEFINE_TRCINFO_1(array_pop,
2987        (2, (static, JSVAL_FAIL, Array_p_pop, CONTEXT, THIS,            0, 0)))
2988    
2989  static JSFunctionSpec array_methods[] = {  static JSFunctionSpec array_methods[] = {
2990  #if JS_HAS_TOSOURCE  #if JS_HAS_TOSOURCE
2991      JS_FN(js_toSource_str,      array_toSource,     0,0),      JS_FN(js_toSource_str,      array_toSource,     0,0),
2992  #endif  #endif
2993      JS_FN(js_toString_str,      array_toString,     0,0),      JS_TN(js_toString_str,      array_toString,     0,0, array_toString_trcinfo),
2994      JS_FN(js_toLocaleString_str,array_toLocaleString,0,0),      JS_FN(js_toLocaleString_str,array_toLocaleString,0,0),
2995    
2996      /* Perl-ish methods. */      /* Perl-ish methods. */
2997      JS_FN("join",               js_array_join,      1,JSFUN_GENERIC_NATIVE),      JS_TN("join",               array_join,         1,JSFUN_GENERIC_NATIVE, array_join_trcinfo),
2998      JS_FN("reverse",            array_reverse,      0,JSFUN_GENERIC_NATIVE),      JS_FN("reverse",            array_reverse,      0,JSFUN_GENERIC_NATIVE),
2999      JS_FN("sort",               array_sort,         1,JSFUN_GENERIC_NATIVE),      JS_FN("sort",               array_sort,         1,JSFUN_GENERIC_NATIVE),
3000      JS_FN("push",               js_array_push,      1,JSFUN_GENERIC_NATIVE),      JS_TN("push",               array_push,         1,JSFUN_GENERIC_NATIVE, array_push_trcinfo),
3001      JS_FN("pop",                js_array_pop,       0,JSFUN_GENERIC_NATIVE),      JS_TN("pop",                array_pop,          0,JSFUN_GENERIC_NATIVE, array_pop_trcinfo),
3002      JS_FN("shift",              array_shift,        0,JSFUN_GENERIC_NATIVE),      JS_FN("shift",              array_shift,        0,JSFUN_GENERIC_NATIVE),
3003      JS_FN("unshift",            array_unshift,      1,JSFUN_GENERIC_NATIVE),      JS_FN("unshift",            array_unshift,      1,JSFUN_GENERIC_NATIVE),
3004      JS_FN("splice",             array_splice,       2,JSFUN_GENERIC_NATIVE),      JS_FN("splice",             array_splice,       2,JSFUN_GENERIC_NATIVE),
# Line 2962  Line 3054 
3054      return InitArrayObject(cx, obj, length, vector);      return InitArrayObject(cx, obj, length, vector);
3055  }  }
3056    
3057    JS_STATIC_ASSERT(JSSLOT_PRIVATE == JSSLOT_ARRAY_LENGTH);
3058    JS_STATIC_ASSERT(JSSLOT_ARRAY_LENGTH + 1 == JSSLOT_ARRAY_COUNT);
3059    
3060    #ifdef JS_TRACER
3061    
3062    JSObject* FASTCALL
3063    js_FastNewArray(JSContext* cx, JSObject* proto)
3064    {
3065        JS_ASSERT(OBJ_IS_ARRAY(cx, proto));
3066    
3067        JS_ASSERT(JS_ON_TRACE(cx));
3068        JSObject* obj = (JSObject*) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));
3069        if (!obj)
3070            return NULL;
3071    
3072        JSClass* clasp = &js_ArrayClass;
3073        obj->classword = jsuword(clasp);
3074    
3075        obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
3076        obj->fslots[JSSLOT_PARENT] = proto->fslots[JSSLOT_PARENT];
3077    
3078        obj->fslots[JSSLOT_ARRAY_LENGTH] = 0;
3079        obj->fslots[JSSLOT_ARRAY_COUNT] = 0;
3080        for (unsigned i = JSSLOT_ARRAY_COUNT + 1; i != JS_INITIAL_NSLOTS; ++i)
3081            obj->fslots[i] = JSVAL_VOID;
3082    
3083        JSObjectOps* ops = clasp->getObjectOps(cx, clasp);
3084        obj->map = ops->newObjectMap(cx, 1, ops, clasp, obj);
3085        if (!obj->map)
3086            return NULL;
3087        obj->dslots = NULL;
3088        return obj;
3089    }
3090    
3091    JSObject* FASTCALL
3092    js_Array_1int(JSContext* cx, JSObject* proto, int32 i)
3093    {
3094        JS_ASSERT(JS_ON_TRACE(cx));
3095        JSObject* obj = js_FastNewArray(cx, proto);
3096        if (obj)
3097            obj->fslots[JSSLOT_ARRAY_LENGTH] = i;
3098        return obj;
3099    }
3100    
3101    #define ARRAY_CTOR_GUTS(exact_len, newslots_code)                             \
3102        JS_ASSERT(JS_ON_TRACE(cx));                                               \
3103        JSObject* obj = js_FastNewArray(cx, proto);                               \
3104        if (obj) {                                                                \
3105            const uint32 len = ARRAY_GROWBY;                                      \
3106            jsval* newslots = (jsval*) JS_malloc(cx, sizeof (jsval) * (len + 1)); \
3107            if (newslots) {                                                       \
3108                obj->dslots = newslots + 1;                                       \
3109                ARRAY_SET_DENSE_LENGTH(obj, len);                                 \
3110                {newslots_code}                                                   \
3111                while (++newslots < obj->dslots + len)                            \
3112                    *newslots = JSVAL_HOLE;                                       \
3113                obj->fslots[JSSLOT_ARRAY_LENGTH] = (exact_len);                   \
3114                return obj;                                                       \
3115            }                                                                     \
3116        }                                                                         \
3117        return NULL;
3118    
3119    JSObject* FASTCALL
3120    js_Array_1str(JSContext* cx, JSObject* proto, JSString *str)
3121    {
3122        ARRAY_CTOR_GUTS(1, *++newslots = STRING_TO_JSVAL(str);)
3123    }
3124    
3125    JSObject* FASTCALL
3126    js_Array_2obj(JSContext* cx, JSObject* proto, JSObject *obj1, JSObject* obj2)
3127    {
3128        ARRAY_CTOR_GUTS(2,
3129            *++newslots = OBJECT_TO_JSVAL(obj1);
3130            *++newslots = OBJECT_TO_JSVAL(obj2);)
3131    }
3132    
3133    JSObject* FASTCALL
3134    js_Array_3num(JSContext* cx, JSObject* proto, jsdouble n1, jsdouble n2, jsdouble n3)
3135    {
3136        ARRAY_CTOR_GUTS(3,
3137            if (!js_NewDoubleInRootedValue(cx, n1, ++newslots))
3138                return NULL;
3139            if (!js_NewDoubleInRootedValue(cx, n2, ++newslots))
3140                return NULL;
3141            if (!js_NewDoubleInRootedValue(cx, n3, ++newslots))
3142                return NULL;)
3143    }
3144    
3145    #endif /* JS_TRACER */
3146    
3147  JSObject *  JSObject *
3148  js_InitArrayClass(JSContext *cx, JSObject *obj)  js_InitArrayClass(JSContext *cx, JSObject *obj)
3149  {  {
# Line 3235  Line 3417 
3417    
3418      return JS_TRUE;      return JS_TRUE;
3419  }  }
3420    
3421    JS_DEFINE_CALLINFO_4(extern, BOOL,   js_Array_dense_setelem, CONTEXT, OBJECT, INT32, JSVAL,   0, 0)
3422    JS_DEFINE_CALLINFO_2(extern, OBJECT, js_FastNewArray, CONTEXT, OBJECT,                        0, 0)
3423    JS_DEFINE_CALLINFO_3(extern, OBJECT, js_Array_1int, CONTEXT, OBJECT, INT32,                   0, 0)
3424    JS_DEFINE_CALLINFO_3(extern, OBJECT, js_Array_1str, CONTEXT, OBJECT, STRING,                  0, 0)
3425    JS_DEFINE_CALLINFO_4(extern, OBJECT, js_Array_2obj, CONTEXT, OBJECT, OBJECT, OBJECT,          0, 0)
3426    JS_DEFINE_CALLINFO_5(extern, OBJECT, js_Array_3num, CONTEXT, OBJECT, DOUBLE, DOUBLE, DOUBLE,  0, 0)

Legend:
Removed from v.398  
changed lines
  Added in v.399

  ViewVC Help
Powered by ViewVC 1.1.24