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

Diff of /trunk/js/jsstr.cpp

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

revision 399 by siliconforks, Tue Dec 9 03:37:47 2008 UTC revision 460 by siliconforks, Sat Sep 26 23:15:22 2009 UTC
# Line 70  Line 70 
70  #include "jsopcode.h"  #include "jsopcode.h"
71  #include "jsregexp.h"  #include "jsregexp.h"
72  #include "jsscope.h"  #include "jsscope.h"
73    #include "jsstaticcheck.h"
74  #include "jsstr.h"  #include "jsstr.h"
75  #include "jsbit.h"  #include "jsbit.h"
76    
# Line 98  Line 99 
99              JSPREFIX_SET_BASE(str, base);              JSPREFIX_SET_BASE(str, base);
100          } else if (start <= JSSTRDEP_START_MASK) {          } else if (start <= JSSTRDEP_START_MASK) {
101              length = JSSTRDEP_LENGTH(str);              length = JSSTRDEP_LENGTH(str);
102              JSSTRDEP_INIT(str, base, start, length);              JSSTRDEP_REINIT(str, base, start, length);
103          }          }
104      }      }
105      *basep = base;      *basep = base;
# Line 165  Line 166 
166      js_strncpy(s + ln, rs, rn);      js_strncpy(s + ln, rs, rn);
167      n = ln + rn;      n = ln + rn;
168      s[n] = 0;      s[n] = 0;
169    
170      str = js_NewString(cx, s, n);      str = js_NewString(cx, s, n);
171      if (!str) {      if (!str) {
172          /* Out of memory: clean up any space we (re-)allocated. */          /* Out of memory: clean up any space we (re-)allocated. */
# Line 180  Line 182 
182    
183          /* Morph left into a dependent prefix if we realloc'd its buffer. */          /* Morph left into a dependent prefix if we realloc'd its buffer. */
184          if (ldep) {          if (ldep) {
185              JSPREFIX_INIT(ldep, str, ln);              JSPREFIX_REINIT(ldep, str, ln);
186  #ifdef DEBUG  #ifdef DEBUG
187            {            {
188              JSRuntime *rt = cx->runtime;              JSRuntime *rt = cx->runtime;
# Line 212  Line 214 
214    
215          js_strncpy(s, JSSTRDEP_CHARS(str), n);          js_strncpy(s, JSSTRDEP_CHARS(str), n);
216          s[n] = 0;          s[n] = 0;
217          JSFLATSTR_INIT(str, s, n);          JSFLATSTR_REINIT(str, s, n);
218    
219  #ifdef DEBUG  #ifdef DEBUG
220          {          {
# Line 536  Line 538 
538  jschar      js_empty_ucstr[]  = {0};  jschar      js_empty_ucstr[]  = {0};
539  JSSubString js_EmptySubString = {0, js_empty_ucstr};  JSSubString js_EmptySubString = {0, js_empty_ucstr};
540    
 enum string_tinyid {  
     STRING_LENGTH = -1  
 };  
   
 static JSPropertySpec string_props[] = {  
     {js_length_str,     STRING_LENGTH,  
                         JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED, 0,0},  
     {0,0,0,0,0}  
 };  
   
541  static JSBool  static JSBool
542  str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)  str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
543  {  {
544      jsval v;      jsval v;
545      JSString *str;      JSString *str;
     jsint slot;  
   
     if (!JSVAL_IS_INT(id))  
         return JS_TRUE;  
546    
547      slot = JSVAL_TO_INT(id);      if (id == ATOM_KEY(cx->runtime->atomState.lengthAtom)) {
     if (slot == STRING_LENGTH) {  
548          if (OBJ_GET_CLASS(cx, obj) == &js_StringClass) {          if (OBJ_GET_CLASS(cx, obj) == &js_StringClass) {
549              /* Follow ECMA-262 by fetching intrinsic length of our string. */              /* Follow ECMA-262 by fetching intrinsic length of our string. */
550              v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);              v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
# Line 572  Line 559 
559    
560          *vp = INT_TO_JSVAL((jsint) JSSTRING_LENGTH(str));          *vp = INT_TO_JSVAL((jsint) JSSTRING_LENGTH(str));
561      }      }
562    
563      return JS_TRUE;      return JS_TRUE;
564  }  }
565    
# Line 797  Line 785 
785      JS_ASSERT(JSVAL_IS_STRING(v));      JS_ASSERT(JSVAL_IS_STRING(v));
786      return JSVAL_TO_STRING(v);      return JSVAL_TO_STRING(v);
787  }  }
   
 static JSString* FASTCALL  
 String_p_substring(JSContext* cx, JSString* str, int32 begin, int32 end)  
 {  
     JS_ASSERT(JS_ON_TRACE(cx));  
   
     size_t length = JSSTRING_LENGTH(str);  
     return SubstringTail(cx, str, length, begin, end);  
 }  
   
 static JSString* FASTCALL  
 String_p_substring_1(JSContext* cx, JSString* str, int32 begin)  
 {  
     JS_ASSERT(JS_ON_TRACE(cx));  
   
     size_t length = JSSTRING_LENGTH(str);  
     return SubstringTail(cx, str, length, begin, length);  
 }  
788  #endif  #endif
789    
790  JSString* JS_FASTCALL  JSString* JS_FASTCALL
# Line 1024  Line 994 
994  }  }
995    
996  #ifdef JS_TRACER  #ifdef JS_TRACER
997    extern jsdouble js_NaN;
998    
999    jsdouble FASTCALL
1000    js_String_p_charCodeAt(JSString* str, jsdouble d)
1001    {
1002        d = js_DoubleToInteger(d);
1003        if (d < 0 || (int32)JSSTRING_LENGTH(str) <= d)
1004            return js_NaN;
1005        return jsdouble(JSSTRING_CHARS(str)[jsuint(d)]);
1006    }
1007    
1008  int32 FASTCALL  int32 FASTCALL
1009  js_String_p_charCodeAt(JSString* str, int32 i)  js_String_p_charCodeAt_int(JSString* str, jsint i)
1010  {  {
1011      if (i < 0 || (int32)JSSTRING_LENGTH(str) <= i)      if (i < 0 || (int32)JSSTRING_LENGTH(str) <= i)
1012          return -1;          return 0;
1013      return JSSTRING_CHARS(str)[i];      return JSSTRING_CHARS(str)[i];
1014  }  }
1015    
1016    jsdouble FASTCALL
1017    js_String_p_charCodeAt0(JSString* str)
1018    {
1019        if ((int32)JSSTRING_LENGTH(str) == 0)
1020            return js_NaN;
1021        return jsdouble(JSSTRING_CHARS(str)[0]);
1022    }
1023    
1024    int32 FASTCALL
1025    js_String_p_charCodeAt0_int(JSString* str)
1026    {
1027        if ((int32)JSSTRING_LENGTH(str) == 0)
1028            return 0;
1029        return JSSTRING_CHARS(str)[0];
1030    }
1031    
1032    /*
1033     * The FuncFilter replaces the generic double version of charCodeAt with the
1034     * integer fast path if appropriate.
1035     */
1036    JS_DEFINE_CALLINFO_1(extern, INT32, js_String_p_charCodeAt0_int, STRING,        1, 1)
1037    JS_DEFINE_CALLINFO_2(extern, INT32, js_String_p_charCodeAt_int,  STRING, INT32, 1, 1)
1038  #endif  #endif
1039    
1040  jsint  jsint
# Line 1150  Line 1154 
1154      text = JSSTRING_CHARS(str);      text = JSSTRING_CHARS(str);
1155      textlen = (jsint) JSSTRING_LENGTH(str);      textlen = (jsint) JSSTRING_LENGTH(str);
1156    
1157      str2 = ArgToRootedString(cx, argc, vp, 0);      if (argc != 0 && JSVAL_IS_STRING(vp[2])) {
1158      if (!str2)          str2 = JSVAL_TO_STRING(vp[2]);
1159          return JS_FALSE;      } else {
1160            str2 = ArgToRootedString(cx, argc, vp, 0);
1161            if (!str2)
1162                return JS_FALSE;
1163        }
1164      pat = JSSTRING_CHARS(str2);      pat = JSSTRING_CHARS(str2);
1165      patlen = (jsint) JSSTRING_LENGTH(str2);      patlen = (jsint) JSSTRING_LENGTH(str2);
1166    
1167        i = textlen - patlen; // Start searching here
1168        if (i < 0) {
1169            *vp = INT_TO_JSVAL(-1);
1170            return JS_TRUE;
1171        }
1172    
1173      if (argc > 1) {      if (argc > 1) {
1174          d = js_ValueToNumber(cx, &vp[3]);          if (JSVAL_IS_INT(vp[3])) {
1175          if (JSVAL_IS_NULL(vp[3]))              j = JSVAL_TO_INT(vp[3]);
1176              return JS_FALSE;              if (j <= 0)
         if (JSDOUBLE_IS_NaN(d)) {  
             i = textlen;  
         } else {  
             d = js_DoubleToInteger(d);  
             if (d < 0)  
1177                  i = 0;                  i = 0;
1178              else if (d > textlen)              else if (j < i)
1179                  i = textlen;                  i = j;
1180              else          } else {
1181                  i = (jsint)d;              d = js_ValueToNumber(cx, &vp[3]);
1182                if (JSVAL_IS_NULL(vp[3]))
1183                    return JS_FALSE;
1184                if (!JSDOUBLE_IS_NaN(d)) {
1185                    d = js_DoubleToInteger(d);
1186                    if (d <= 0)
1187                        i = 0;
1188                    else if (d < i)
1189                        i = (jsint)d;
1190                }
1191          }          }
     } else {  
         i = textlen;  
1192      }      }
1193    
1194      if (patlen == 0) {      if (patlen == 0) {
# Line 1182  Line 1198 
1198    
1199      j = 0;      j = 0;
1200      while (i >= 0) {      while (i >= 0) {
1201          /* Don't assume that text is NUL-terminated: it could be dependent. */          /* This is always safe because i <= textlen - patlen and j < patlen */
1202          if (i + j < textlen && text[i + j] == pat[j]) {          if (text[i + j] == pat[j]) {
1203              if (++j == patlen)              if (++j == patlen)
1204                  break;                  break;
1205          } else {          } else {
# Line 1402  Line 1418 
1418      mdata = (MatchData *)data;      mdata = (MatchData *)data;
1419      arrayobj = JSVAL_TO_OBJECT(*mdata->arrayval);      arrayobj = JSVAL_TO_OBJECT(*mdata->arrayval);
1420      if (!arrayobj) {      if (!arrayobj) {
1421          arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL);          arrayobj = js_NewArrayObject(cx, 0, NULL);
1422          if (!arrayobj)          if (!arrayobj)
1423              return JS_FALSE;              return JS_FALSE;
1424          *mdata->arrayval = OBJECT_TO_JSVAL(arrayobj);          *mdata->arrayval = OBJECT_TO_JSVAL(arrayobj);
# Line 1418  Line 1434 
1434      return OBJ_SET_PROPERTY(cx, arrayobj, INT_TO_JSID(count), &v);      return OBJ_SET_PROPERTY(cx, arrayobj, INT_TO_JSID(count), &v);
1435  }  }
1436    
1437  JSBool  static JSBool
1438  js_StringMatchHelper(JSContext *cx, uintN argc, jsval *vp, jsbytecode *pc)  StringMatchHelper(JSContext *cx, uintN argc, jsval *vp, jsbytecode *pc)
1439  {  {
1440      JSTempValueRooter tvr;      JSTempValueRooter tvr;
1441      MatchData mdata;      MatchData mdata;
# Line 1440  Line 1456 
1456  static JSBool  static JSBool
1457  str_match(JSContext *cx, uintN argc, jsval *vp)  str_match(JSContext *cx, uintN argc, jsval *vp)
1458  {  {
1459      JSStackFrame *fp;      return StringMatchHelper(cx, argc, vp, js_GetCurrentBytecodePC(cx));
   
     for (fp = cx->fp; fp && !fp->regs; fp = fp->down)  
         JS_ASSERT(!fp->script);  
     return js_StringMatchHelper(cx, argc, vp, fp ? fp->regs->pc : NULL);  
1460  }  }
1461    
 #ifdef JS_TRACER  
 static JSObject* FASTCALL  
 String_p_match(JSContext* cx, JSString* str, jsbytecode *pc, JSObject* regexp)  
 {  
     jsval vp[3] = { JSVAL_NULL, STRING_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp) };  
     if (!js_StringMatchHelper(cx, 1, vp, pc))  
         return (JSObject*) JSVAL_TO_BOOLEAN(JSVAL_VOID);  
     JS_ASSERT(JSVAL_IS_NULL(vp[0]) ||  
               (!JSVAL_IS_PRIMITIVE(vp[0]) && OBJ_IS_ARRAY(cx, JSVAL_TO_OBJECT(vp[0]))));  
     return JSVAL_TO_OBJECT(vp[0]);  
 }  
   
 static JSObject* FASTCALL  
 String_p_match_obj(JSContext* cx, JSObject* str, jsbytecode *pc, JSObject* regexp)  
 {  
     jsval vp[3] = { JSVAL_NULL, OBJECT_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp) };  
     if (!js_StringMatchHelper(cx, 1, vp, pc))  
         return (JSObject*) JSVAL_TO_BOOLEAN(JSVAL_VOID);  
     JS_ASSERT(JSVAL_IS_NULL(vp[0]) ||  
               (!JSVAL_IS_PRIMITIVE(vp[0]) && OBJ_IS_ARRAY(cx, JSVAL_TO_OBJECT(vp[0]))));  
     return JSVAL_TO_OBJECT(vp[0]);  
 }  
 #endif  
   
1462  static JSBool  static JSBool
1463  str_search(JSContext *cx, uintN argc, jsval *vp)  str_search(JSContext *cx, uintN argc, jsval *vp)
1464  {  {
# Line 1552  Line 1540 
1540      return NULL;      return NULL;
1541  }  }
1542    
1543  static JSBool  static JS_REQUIRES_STACK JSBool
1544  find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep)  find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep)
1545  {  {
1546      JSString *repstr;      JSString *repstr;
# Line 1716  Line 1704 
1704      rdata->chars = NULL;      rdata->chars = NULL;
1705  }  }
1706    
1707  static JSBool  static JS_REQUIRES_STACK JSBool
1708  replace_glob(JSContext *cx, jsint count, GlobData *data)  replace_glob(JSContext *cx, jsint count, GlobData *data)
1709  {  {
1710      ReplaceData *rdata;      ReplaceData *rdata;
# Line 1752  Line 1740 
1740      return JS_TRUE;      return JS_TRUE;
1741  }  }
1742    
1743  static JSBool  static JS_REQUIRES_STACK JSBool
1744  str_replace(JSContext *cx, uintN argc, jsval *vp)  str_replace(JSContext *cx, uintN argc, jsval *vp)
1745  {  {
1746      JSObject *lambda;      JSObject *lambda;
# Line 1771  Line 1759 
1759      return js_StringReplaceHelper(cx, argc, lambda, repstr, vp);      return js_StringReplaceHelper(cx, argc, lambda, repstr, vp);
1760  }  }
1761    
1762  #ifdef JS_TRACER  JSBool JS_REQUIRES_STACK
 static JSString* FASTCALL  
 String_p_replace_str(JSContext* cx, JSString* str, JSObject* regexp, JSString* repstr)  
 {  
     jsval vp[4] = {  
         JSVAL_NULL, STRING_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp), STRING_TO_JSVAL(repstr)  
     };  
     if (!js_StringReplaceHelper(cx, 2, NULL, repstr, vp))  
         return NULL;  
     JS_ASSERT(JSVAL_IS_STRING(vp[0]));  
     return JSVAL_TO_STRING(vp[0]);  
 }  
   
 static JSString* FASTCALL  
 String_p_replace_str2(JSContext* cx, JSString* str, JSString* patstr, JSString* repstr)  
 {  
     jsval vp[4] = {  
         JSVAL_NULL, STRING_TO_JSVAL(str), STRING_TO_JSVAL(patstr), STRING_TO_JSVAL(repstr)  
     };  
     if (!js_StringReplaceHelper(cx, 2, NULL, repstr, vp))  
         return NULL;  
     JS_ASSERT(JSVAL_IS_STRING(vp[0]));  
     return JSVAL_TO_STRING(vp[0]);  
 }  
   
 static JSString* FASTCALL  
 String_p_replace_str3(JSContext* cx, JSString* str, JSString* patstr, JSString* repstr,  
                       JSString* flagstr)  
 {  
     jsval vp[5] = {  
         JSVAL_NULL, STRING_TO_JSVAL(str), STRING_TO_JSVAL(patstr), STRING_TO_JSVAL(repstr),  
         STRING_TO_JSVAL(flagstr)  
     };  
     if (!js_StringReplaceHelper(cx, 3, NULL, repstr, vp))  
         return NULL;  
     JS_ASSERT(JSVAL_IS_STRING(vp[0]));  
     return JSVAL_TO_STRING(vp[0]);  
 }  
 #endif  
   
 JSBool  
1763  js_StringReplaceHelper(JSContext *cx, uintN argc, JSObject *lambda,  js_StringReplaceHelper(JSContext *cx, uintN argc, JSObject *lambda,
1764                         JSString *repstr, jsval *vp)                         JSString *repstr, jsval *vp)
1765  {  {
# Line 1832  Line 1780 
1780      rdata.lambda = lambda;      rdata.lambda = lambda;
1781      rdata.repstr = repstr;      rdata.repstr = repstr;
1782      if (repstr) {      if (repstr) {
1783            if (!js_MakeStringImmutable(cx, repstr))
1784                return JS_FALSE;
1785          rdata.dollarEnd = JSSTRING_CHARS(repstr) + JSSTRING_LENGTH(repstr);          rdata.dollarEnd = JSSTRING_CHARS(repstr) + JSSTRING_LENGTH(repstr);
1786          rdata.dollar = js_strchr_limit(JSSTRING_CHARS(repstr), '$',          rdata.dollar = js_strchr_limit(JSSTRING_CHARS(repstr), '$',
1787                                         rdata.dollarEnd);                                         rdata.dollarEnd);
# Line 2025  Line 1975 
1975    
1976      NORMALIZE_THIS(cx, vp, str);      NORMALIZE_THIS(cx, vp, str);
1977    
1978      arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL);      arrayobj = js_NewArrayObject(cx, 0, NULL);
1979      if (!arrayobj)      if (!arrayobj)
1980          return JS_FALSE;          return JS_FALSE;
1981      *vp = OBJECT_TO_JSVAL(arrayobj);      *vp = OBJECT_TO_JSVAL(arrayobj);
# Line 2112  Line 2062 
2062      return ok;      return ok;
2063  }  }
2064    
 #ifdef JS_TRACER  
 static JSObject* FASTCALL  
 String_p_split(JSContext* cx, JSString* str, JSString* sepstr)  
 {  
     // FIXME: Avoid building and then parsing this array.  
     jsval vp[4] = { JSVAL_NULL, STRING_TO_JSVAL(str), STRING_TO_JSVAL(sepstr), JSVAL_VOID };  
     if (!str_split(cx, 2, vp))  
         return NULL;  
     JS_ASSERT(JSVAL_IS_OBJECT(vp[0]));  
     return JSVAL_TO_OBJECT(vp[0]);  
 }  
 #endif  
   
2065  #if JS_HAS_PERL_SUBSTR  #if JS_HAS_PERL_SUBSTR
2066  static JSBool  static JSBool
2067  str_substr(JSContext *cx, uintN argc, jsval *vp)  str_substr(JSContext *cx, uintN argc, jsval *vp)
# Line 2185  Line 2122 
2122    
2123      NORMALIZE_THIS(cx, vp, str);      NORMALIZE_THIS(cx, vp, str);
2124    
2125        /* Set vp (aka rval) early to handle the argc == 0 case. */
2126        *vp = STRING_TO_JSVAL(str);
2127    
2128      for (i = 0, argv = vp + 2; i < argc; i++) {      for (i = 0, argv = vp + 2; i < argc; i++) {
2129          str2 = js_ValueToString(cx, argv[i]);          str2 = js_ValueToString(cx, argv[i]);
2130          if (!str2)          if (!str2)
# Line 2194  Line 2134 
2134          str = js_ConcatStrings(cx, str, str2);          str = js_ConcatStrings(cx, str, str2);
2135          if (!str)          if (!str)
2136              return JS_FALSE;              return JS_FALSE;
2137            *vp = STRING_TO_JSVAL(str);
2138      }      }
2139    
     *vp = STRING_TO_JSVAL(str);  
2140      return JS_TRUE;      return JS_TRUE;
2141  }  }
2142    
 #ifdef JS_TRACER  
 static JSString* FASTCALL  
 String_p_concat_1int(JSContext* cx, JSString* str, int32 i)  
 {  
     // FIXME: should be able to use stack buffer and avoid istr...  
     JSString* istr = js_NumberToString(cx, i);  
     if (!istr)  
         return NULL;  
     return js_ConcatStrings(cx, str, istr);  
 }  
   
 static JSString* FASTCALL  
 String_p_concat_2str(JSContext* cx, JSString* str, JSString* a, JSString* b)  
 {  
     str = js_ConcatStrings(cx, str, a);  
     if (str)  
         return js_ConcatStrings(cx, str, b);  
     return NULL;  
 }  
   
 static JSString* FASTCALL  
 String_p_concat_3str(JSContext* cx, JSString* str, JSString* a, JSString* b, JSString* c)  
 {  
     str = js_ConcatStrings(cx, str, a);  
     if (str) {  
         str = js_ConcatStrings(cx, str, b);  
         if (str)  
             return js_ConcatStrings(cx, str, c);  
     }  
     return NULL;  
 }  
 #endif  
   
2143  static JSBool  static JSBool
2144  str_slice(JSContext *cx, uintN argc, jsval *vp)  str_slice(JSContext *cx, uintN argc, jsval *vp)
2145  {  {
# Line 2482  Line 2389 
2389  JS_DEFINE_CALLINFO_2(extern, INT32,  js_CompareStrings, STRING, STRING,                     1, 1)  JS_DEFINE_CALLINFO_2(extern, INT32,  js_CompareStrings, STRING, STRING,                     1, 1)
2390    
2391  JS_DEFINE_TRCINFO_1(str_toString,  JS_DEFINE_TRCINFO_1(str_toString,
2392      (2, (extern, STRING_FAIL,      String_p_toString, CONTEXT, THIS,                        1, 1)))      (2, (extern, STRING_RETRY,      String_p_toString, CONTEXT, THIS,                        1, 1)))
 JS_DEFINE_TRCINFO_2(str_substring,  
     (4, (static, STRING_FAIL,      String_p_substring, CONTEXT, THIS_STRING, INT32, INT32,   1, 1)),  
     (3, (static, STRING_FAIL,      String_p_substring_1, CONTEXT, THIS_STRING, INT32,        1, 1)))  
2393  JS_DEFINE_TRCINFO_1(str_charAt,  JS_DEFINE_TRCINFO_1(str_charAt,
2394      (3, (extern, STRING_FAIL,      js_String_getelem, CONTEXT, THIS_STRING, INT32,           1, 1)))      (3, (extern, STRING_RETRY,      js_String_getelem, CONTEXT, THIS_STRING, INT32,           1, 1)))
2395  JS_DEFINE_TRCINFO_1(str_charCodeAt,  JS_DEFINE_TRCINFO_2(str_charCodeAt,
2396      (2, (extern, INT32_FAIL,       js_String_p_charCodeAt, THIS_STRING, INT32,               1, 1)))      (1, (extern, DOUBLE,            js_String_p_charCodeAt0, THIS_STRING,                     1, 1)),
2397  JS_DEFINE_TRCINFO_4(str_concat,      (2, (extern, DOUBLE,            js_String_p_charCodeAt, THIS_STRING, DOUBLE,              1, 1)))
2398      (3, (static, STRING_FAIL,      String_p_concat_1int, CONTEXT, THIS_STRING, INT32,        1, 1)),  JS_DEFINE_TRCINFO_1(str_concat,
2399      (3, (extern, STRING_FAIL,      js_ConcatStrings, CONTEXT, THIS_STRING, STRING,           1, 1)),      (3, (extern, STRING_RETRY,      js_ConcatStrings, CONTEXT, THIS_STRING, STRING,           1, 1)))
     (4, (static, STRING_FAIL,      String_p_concat_2str, CONTEXT, THIS_STRING, STRING, STRING, 1, 1)),  
     (5, (static, STRING_FAIL,      String_p_concat_3str, CONTEXT, THIS_STRING, STRING, STRING, STRING, 1, 1)))  
 JS_DEFINE_TRCINFO_2(str_match,  
     (4, (static, OBJECT_FAIL_VOID, String_p_match, CONTEXT, THIS_STRING, PC, REGEXP,         1, 1)),  
     (4, (static, OBJECT_FAIL_VOID, String_p_match_obj, CONTEXT, THIS, PC, REGEXP,            1, 1)))  
 JS_DEFINE_TRCINFO_3(str_replace,  
     (4, (static, STRING_FAIL,      String_p_replace_str, CONTEXT, THIS_STRING, REGEXP, STRING, 1, 1)),  
     (4, (static, STRING_FAIL,      String_p_replace_str2, CONTEXT, THIS_STRING, STRING, STRING, 1, 1)),  
     (5, (static, STRING_FAIL,      String_p_replace_str3, CONTEXT, THIS_STRING, STRING, STRING, STRING, 1, 1)))  
 JS_DEFINE_TRCINFO_1(str_split,  
     (3, (static, OBJECT_FAIL_NULL, String_p_split, CONTEXT, THIS_STRING, STRING,             0, 0)))  
 JS_DEFINE_TRCINFO_1(str_toLowerCase,  
     (2, (extern, STRING_FAIL,      js_toLowerCase, CONTEXT, THIS_STRING,                     1, 1)))  
 JS_DEFINE_TRCINFO_1(str_toUpperCase,  
     (2, (extern, STRING_FAIL,      js_toUpperCase, CONTEXT, THIS_STRING,                     1, 1)))  
2400    
2401  #define GENERIC           JSFUN_GENERIC_NATIVE  #define GENERIC           JSFUN_GENERIC_NATIVE
2402  #define PRIMITIVE         JSFUN_THISP_PRIMITIVE  #define PRIMITIVE         JSFUN_THISP_PRIMITIVE
# Line 2523  Line 2412 
2412      JS_TN(js_toString_str,     str_toString,          0,JSFUN_THISP_STRING, str_toString_trcinfo),      JS_TN(js_toString_str,     str_toString,          0,JSFUN_THISP_STRING, str_toString_trcinfo),
2413      JS_FN(js_valueOf_str,      str_toString,          0,JSFUN_THISP_STRING),      JS_FN(js_valueOf_str,      str_toString,          0,JSFUN_THISP_STRING),
2414      JS_FN(js_toJSON_str,       str_toString,          0,JSFUN_THISP_STRING),      JS_FN(js_toJSON_str,       str_toString,          0,JSFUN_THISP_STRING),
2415      JS_TN("substring",         str_substring,         2,GENERIC_PRIMITIVE, str_substring_trcinfo),      JS_FN("substring",         str_substring,         2,GENERIC_PRIMITIVE),
2416      JS_TN("toLowerCase",       str_toLowerCase,       0,GENERIC_PRIMITIVE, str_toLowerCase_trcinfo),      JS_FN("toLowerCase",       str_toLowerCase,       0,GENERIC_PRIMITIVE),
2417      JS_TN("toUpperCase",       str_toUpperCase,       0,GENERIC_PRIMITIVE, str_toUpperCase_trcinfo),      JS_FN("toUpperCase",       str_toUpperCase,       0,GENERIC_PRIMITIVE),
2418      JS_TN("charAt",            str_charAt,            1,GENERIC_PRIMITIVE, str_charAt_trcinfo),      JS_TN("charAt",            str_charAt,            1,GENERIC_PRIMITIVE, str_charAt_trcinfo),
2419      JS_TN("charCodeAt",        str_charCodeAt,        1,GENERIC_PRIMITIVE, str_charCodeAt_trcinfo),      JS_TN("charCodeAt",        str_charCodeAt,        1,GENERIC_PRIMITIVE, str_charCodeAt_trcinfo),
2420      JS_FN("indexOf",           str_indexOf,           1,GENERIC_PRIMITIVE),      JS_FN("indexOf",           str_indexOf,           1,GENERIC_PRIMITIVE),
# Line 2538  Line 2427 
2427      JS_FN("localeCompare",     str_localeCompare,     1,GENERIC_PRIMITIVE),      JS_FN("localeCompare",     str_localeCompare,     1,GENERIC_PRIMITIVE),
2428    
2429      /* Perl-ish methods (search is actually Python-esque). */      /* Perl-ish methods (search is actually Python-esque). */
2430      JS_TN("match",             str_match,             1,GENERIC_PRIMITIVE, str_match_trcinfo),      JS_FN("match",             str_match,             1,GENERIC_PRIMITIVE),
2431      JS_FN("search",            str_search,            1,GENERIC_PRIMITIVE),      JS_FN("search",            str_search,            1,GENERIC_PRIMITIVE),
2432      JS_TN("replace",           str_replace,           2,GENERIC_PRIMITIVE, str_replace_trcinfo),      JS_FN("replace",           str_replace,           2,GENERIC_PRIMITIVE),
2433      JS_TN("split",             str_split,             2,GENERIC_PRIMITIVE, str_split_trcinfo),      JS_FN("split",             str_split,             2,GENERIC_PRIMITIVE),
2434  #if JS_HAS_PERL_SUBSTR  #if JS_HAS_PERL_SUBSTR
2435      JS_FN("substr",            str_substr,            2,GENERIC_PRIMITIVE),      JS_FN("substr",            str_substr,            2,GENERIC_PRIMITIVE),
2436  #endif  #endif
# Line 2570  Line 2459 
2459      JS_FS_END      JS_FS_END
2460  };  };
2461    
2462  static JSBool  JSBool
2463  String(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)  js_String(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2464  {  {
2465      JSString *str;      JSString *str;
2466    
# Line 2583  Line 2472 
2472      } else {      } else {
2473          str = cx->runtime->emptyString;          str = cx->runtime->emptyString;
2474      }      }
2475      if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {      if (!JS_IsConstructing(cx)) {
2476          *rval = STRING_TO_JSVAL(str);          *rval = STRING_TO_JSVAL(str);
2477          return JS_TRUE;          return JS_TRUE;
2478      }      }
2479      STOBJ_SET_SLOT(obj, JSSLOT_PRIVATE, STRING_TO_JSVAL(str));      obj->fslots[JSSLOT_PRIVATE] = STRING_TO_JSVAL(str);
2480      return JS_TRUE;      return JS_TRUE;
2481  }  }
2482    
2483    #ifdef JS_TRACER
2484    
2485    JSObject* FASTCALL
2486    js_String_tn(JSContext* cx, JSObject* proto, JSString* str)
2487    {
2488        JS_ASSERT(JS_ON_TRACE(cx));
2489        JSObject* obj = js_NewNativeObject(cx, &js_StringClass, proto, JSSLOT_PRIVATE + 1);
2490        if (!obj)
2491            return NULL;
2492    
2493        obj->fslots[JSSLOT_PRIVATE] = STRING_TO_JSVAL(str);
2494        return obj;
2495    }
2496    
2497    JS_DEFINE_CALLINFO_3(extern, OBJECT, js_String_tn, CONTEXT, CALLEE_PROTOTYPE, STRING, 0, 0)
2498    
2499    #endif /* !JS_TRACER */
2500    
2501  static JSBool  static JSBool
2502  str_fromCharCode(JSContext *cx, uintN argc, jsval *vp)  str_fromCharCode(JSContext *cx, uintN argc, jsval *vp)
2503  {  {
# Line 2644  Line 2551 
2551  #endif  #endif
2552    
2553  JS_DEFINE_TRCINFO_1(str_fromCharCode,  JS_DEFINE_TRCINFO_1(str_fromCharCode,
2554      (2, (static, STRING_FAIL, String_fromCharCode, CONTEXT, INT32, 1, 1)))      (2, (static, STRING_RETRY, String_fromCharCode, CONTEXT, INT32, 1, 1)))
2555    
2556  static JSFunctionSpec string_static_methods[] = {  static JSFunctionSpec string_static_methods[] = {
2557      JS_TN("fromCharCode", str_fromCharCode, 1, 0, str_fromCharCode_trcinfo),      JS_TN("fromCharCode", str_fromCharCode, 1, 0, str_fromCharCode_trcinfo),
# Line 2739  Line 2646 
2646          JS_LOCK_GC(rt);          JS_LOCK_GC(rt);
2647          if (!rt->unitStrings[c])          if (!rt->unitStrings[c])
2648              rt->unitStrings[c] = str;              rt->unitStrings[c] = str;
2649    #ifdef DEBUG
2650            else
2651                JSFLATSTR_INIT(str, NULL, 0);  /* avoid later assertion (bug 479381) */
2652    #endif
2653          JS_UNLOCK_GC(rt);          JS_UNLOCK_GC(rt);
2654      }      }
2655      return rt->unitStrings[c];      return rt->unitStrings[c];
# Line 2793  Line 2704 
2704      if (!JS_DefineFunctions(cx, obj, string_functions))      if (!JS_DefineFunctions(cx, obj, string_functions))
2705          return NULL;          return NULL;
2706    
2707      proto = JS_InitClass(cx, obj, NULL, &js_StringClass, String, 1,      proto = JS_InitClass(cx, obj, NULL, &js_StringClass, js_String, 1,
2708                           string_props, string_methods,                           NULL, string_methods,
2709                           NULL, string_static_methods);                           NULL, string_static_methods);
2710      if (!proto)      if (!proto)
2711          return NULL;          return NULL;
2712      STOBJ_SET_SLOT(proto, JSSLOT_PRIVATE,      proto->fslots[JSSLOT_PRIVATE] = STRING_TO_JSVAL(cx->runtime->emptyString);
2713                     STRING_TO_JSVAL(cx->runtime->emptyString));      if (!js_DefineNativeProperty(cx, proto, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
2714                                     JSVAL_VOID, NULL, NULL,
2715                                     JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED, 0, 0,
2716                                     NULL)) {
2717            return JS_FALSE;
2718        }
2719    
2720      return proto;      return proto;
2721  }  }
2722    
# Line 2809  Line 2726 
2726      JSString *str;      JSString *str;
2727    
2728      if (length > JSSTRING_LENGTH_MASK) {      if (length > JSSTRING_LENGTH_MASK) {
2729            if (JS_ON_TRACE(cx)) {
2730                /*
2731                 * If we can't leave the trace, signal OOM condition, otherwise
2732                 * exit from trace and proceed with GC.
2733                 */
2734                if (!js_CanLeaveTrace(cx))
2735                    return NULL;
2736    
2737                js_LeaveTrace(cx);
2738            }
2739          js_ReportAllocationOverflow(cx);          js_ReportAllocationOverflow(cx);
2740          return NULL;          return NULL;
2741      }      }
# Line 3010  Line 2937 
2937              }              }
2938          }          }
2939      }      }
2940      if (valid)      if (valid && JSSTRING_IS_DEFLATED(str))
2941          js_PurgeDeflatedStringCache(rt, str);          js_PurgeDeflatedStringCache(rt, str);
2942  }  }
2943    
# Line 3525  Line 3452 
3452      hep = JS_HashTableRawLookup(cache, hash, str);      hep = JS_HashTableRawLookup(cache, hash, str);
3453      JS_ASSERT(*hep == NULL);      JS_ASSERT(*hep == NULL);
3454      ok = JS_HashTableRawAdd(cache, hep, hash, str, bytes) != NULL;      ok = JS_HashTableRawAdd(cache, hep, hash, str, bytes) != NULL;
3455        if (ok) {
3456            JSSTRING_SET_DEFLATED(str);
3457  #ifdef DEBUG  #ifdef DEBUG
     if (ok)  
3458          rt->deflatedStringCacheBytes += length;          rt->deflatedStringCacheBytes += length;
3459  #endif  #endif
3460        }
3461    
3462      JS_RELEASE_LOCK(rt->deflatedStringCacheLock);      JS_RELEASE_LOCK(rt->deflatedStringCacheLock);
3463      return ok;      return ok;
# Line 3583  Line 3512 
3512  #ifdef DEBUG  #ifdef DEBUG
3513                  rt->deflatedStringCacheBytes += JSSTRING_LENGTH(str);                  rt->deflatedStringCacheBytes += JSSTRING_LENGTH(str);
3514  #endif  #endif
3515                    JSSTRING_SET_DEFLATED(str);
3516              } else {              } else {
3517                  if (cx)                  if (cx)
3518                      JS_free(cx, bytes);                      JS_free(cx, bytes);

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

  ViewVC Help
Powered by ViewVC 1.1.24