| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 // ECMA-262 section 15.5.4.3 | 55 // ECMA-262 section 15.5.4.3 |
| 56 function StringValueOf() { | 56 function StringValueOf() { |
| 57 if (!IS_STRING(this) && !IS_STRING_WRAPPER(this)) | 57 if (!IS_STRING(this) && !IS_STRING_WRAPPER(this)) |
| 58 throw new $TypeError('String.prototype.valueOf is not generic'); | 58 throw new $TypeError('String.prototype.valueOf is not generic'); |
| 59 return %_ValueOf(this); | 59 return %_ValueOf(this); |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 // ECMA-262, section 15.5.4.4 | 63 // ECMA-262, section 15.5.4.4 |
| 64 function StringCharAt(pos) { | 64 function StringCharAt(pos) { |
| 65 var char_code = %_FastCharCodeAt(this, pos); | 65 var result = %_StringCharAt(this, pos); |
| 66 if (!%_IsSmi(char_code)) { | 66 if (%_IsSmi(result)) { |
| 67 var subject = TO_STRING_INLINE(this); | 67 result = %_StringCharAt(TO_STRING_INLINE(this), TO_INTEGER(pos)); |
| 68 var index = TO_INTEGER(pos); | |
| 69 if (index >= subject.length || index < 0) return ""; | |
| 70 char_code = %StringCharCodeAt(subject, index); | |
| 71 } | 68 } |
| 72 return %_CharFromCode(char_code); | 69 return result; |
| 73 } | 70 } |
| 74 | 71 |
| 75 | 72 |
| 76 // ECMA-262 section 15.5.4.5 | 73 // ECMA-262 section 15.5.4.5 |
| 77 function StringCharCodeAt(pos) { | 74 function StringCharCodeAt(pos) { |
| 78 var fast_answer = %_FastCharCodeAt(this, pos); | 75 var result = %_StringCharCodeAt(this, pos); |
| 79 if (%_IsSmi(fast_answer)) { | 76 if (!%_IsSmi(result)) { |
| 80 return fast_answer; | 77 result = %_StringCharCodeAt(TO_STRING_INLINE(this), TO_INTEGER(pos)); |
| 81 } | 78 } |
| 82 var subject = TO_STRING_INLINE(this); | 79 return result; |
| 83 var index = TO_INTEGER(pos); | |
| 84 return %StringCharCodeAt(subject, index); | |
| 85 } | 80 } |
| 86 | 81 |
| 87 | 82 |
| 88 // ECMA-262, section 15.5.4.6 | 83 // ECMA-262, section 15.5.4.6 |
| 89 function StringConcat() { | 84 function StringConcat() { |
| 90 var len = %_ArgumentsLength(); | 85 var len = %_ArgumentsLength(); |
| 91 var this_as_string = TO_STRING_INLINE(this); | 86 var this_as_string = TO_STRING_INLINE(this); |
| 92 if (len === 1) { | 87 if (len === 1) { |
| 93 return this_as_string + %_Arguments(0); | 88 return this_as_string + %_Arguments(0); |
| 94 } | 89 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 return RegExpExecNoTests(regexp, subject, 0); | 202 return RegExpExecNoTests(regexp, subject, 0); |
| 208 } | 203 } |
| 209 | 204 |
| 210 | 205 |
| 211 // SubString is an internal function that returns the sub string of 'string'. | 206 // SubString is an internal function that returns the sub string of 'string'. |
| 212 // If resulting string is of length 1, we use the one character cache | 207 // If resulting string is of length 1, we use the one character cache |
| 213 // otherwise we call the runtime system. | 208 // otherwise we call the runtime system. |
| 214 function SubString(string, start, end) { | 209 function SubString(string, start, end) { |
| 215 // Use the one character string cache. | 210 // Use the one character string cache. |
| 216 if (start + 1 == end) { | 211 if (start + 1 == end) { |
| 217 var char_code = %_FastCharCodeAt(string, start); | 212 return %_StringCharAt(string, start); |
| 218 if (!%_IsSmi(char_code)) { | |
| 219 char_code = %StringCharCodeAt(string, start); | |
| 220 } | |
| 221 return %_CharFromCode(char_code); | |
| 222 } | 213 } |
| 223 return %_SubString(string, start, end); | 214 return %_SubString(string, start, end); |
| 224 } | 215 } |
| 225 | 216 |
| 226 | 217 |
| 227 // This has the same size as the lastMatchInfo array, and can be used for | 218 // This has the same size as the lastMatchInfo array, and can be used for |
| 228 // functions that expect that structure to be returned. It is used when the | 219 // functions that expect that structure to be returned. It is used when the |
| 229 // needle is a string rather than a regexp. In this case we can't update | 220 // needle is a string rather than a regexp. In this case we can't update |
| 230 // lastMatchArray without erroneously affecting the properties on the global | 221 // lastMatchArray without erroneously affecting the properties on the global |
| 231 // RegExp object. | 222 // RegExp object. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // Compute the number of captures; see ECMA-262, 15.5.4.11, p. 102. | 306 // Compute the number of captures; see ECMA-262, 15.5.4.11, p. 102. |
| 316 var m = NUMBER_OF_CAPTURES(matchInfo) >> 1; // Includes the match. | 307 var m = NUMBER_OF_CAPTURES(matchInfo) >> 1; // Includes the match. |
| 317 | 308 |
| 318 if (next > 0) builder.add(SubString(string, 0, next)); | 309 if (next > 0) builder.add(SubString(string, 0, next)); |
| 319 var length = string.length; | 310 var length = string.length; |
| 320 | 311 |
| 321 while (true) { | 312 while (true) { |
| 322 var expansion = '$'; | 313 var expansion = '$'; |
| 323 var position = next + 1; | 314 var position = next + 1; |
| 324 if (position < length) { | 315 if (position < length) { |
| 325 var peek = %_FastCharCodeAt(string, position); | 316 var peek = %_StringCharCodeAt(string, position); |
| 326 if (!%_IsSmi(peek)) { | |
| 327 peek = %StringCharCodeAt(string, position); | |
| 328 } | |
| 329 if (peek == 36) { // $$ | 317 if (peek == 36) { // $$ |
| 330 ++position; | 318 ++position; |
| 331 builder.add('$'); | 319 builder.add('$'); |
| 332 } else if (peek == 38) { // $& - match | 320 } else if (peek == 38) { // $& - match |
| 333 ++position; | 321 ++position; |
| 334 builder.addSpecialSlice(matchInfo[CAPTURE0], | 322 builder.addSpecialSlice(matchInfo[CAPTURE0], |
| 335 matchInfo[CAPTURE1]); | 323 matchInfo[CAPTURE1]); |
| 336 } else if (peek == 96) { // $` - prefix | 324 } else if (peek == 96) { // $` - prefix |
| 337 ++position; | 325 ++position; |
| 338 builder.addSpecialSlice(0, matchInfo[CAPTURE0]); | 326 builder.addSpecialSlice(0, matchInfo[CAPTURE0]); |
| 339 } else if (peek == 39) { // $' - suffix | 327 } else if (peek == 39) { // $' - suffix |
| 340 ++position; | 328 ++position; |
| 341 builder.addSpecialSlice(matchInfo[CAPTURE1], subject.length); | 329 builder.addSpecialSlice(matchInfo[CAPTURE1], subject.length); |
| 342 } else if (peek >= 48 && peek <= 57) { // $n, 0 <= n <= 9 | 330 } else if (peek >= 48 && peek <= 57) { // $n, 0 <= n <= 9 |
| 343 ++position; | 331 ++position; |
| 344 var n = peek - 48; | 332 var n = peek - 48; |
| 345 if (position < length) { | 333 if (position < length) { |
| 346 peek = %_FastCharCodeAt(string, position); | 334 peek = %_StringCharCodeAt(string, position); |
| 347 if (!%_IsSmi(peek)) { | |
| 348 peek = %StringCharCodeAt(string, position); | |
| 349 } | |
| 350 // $nn, 01 <= nn <= 99 | 335 // $nn, 01 <= nn <= 99 |
| 351 if (n != 0 && peek == 48 || peek >= 49 && peek <= 57) { | 336 if (n != 0 && peek == 48 || peek >= 49 && peek <= 57) { |
| 352 var nn = n * 10 + (peek - 48); | 337 var nn = n * 10 + (peek - 48); |
| 353 if (nn < m) { | 338 if (nn < m) { |
| 354 // If the two digit capture reference is within range of | 339 // If the two digit capture reference is within range of |
| 355 // the captures, we use it instead of the single digit | 340 // the captures, we use it instead of the single digit |
| 356 // one. Otherwise, we fall back to using the single | 341 // one. Otherwise, we fall back to using the single |
| 357 // digit reference. This matches the behavior of | 342 // digit reference. This matches the behavior of |
| 358 // SpiderMonkey. | 343 // SpiderMonkey. |
| 359 ++position; | 344 ++position; |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 return %StringTrim(TO_STRING_INLINE(this), false, true); | 802 return %StringTrim(TO_STRING_INLINE(this), false, true); |
| 818 } | 803 } |
| 819 | 804 |
| 820 var static_charcode_array = new $Array(4); | 805 var static_charcode_array = new $Array(4); |
| 821 | 806 |
| 822 // ECMA-262, section 15.5.3.2 | 807 // ECMA-262, section 15.5.3.2 |
| 823 function StringFromCharCode(code) { | 808 function StringFromCharCode(code) { |
| 824 var n = %_ArgumentsLength(); | 809 var n = %_ArgumentsLength(); |
| 825 if (n == 1) { | 810 if (n == 1) { |
| 826 if (!%_IsSmi(code)) code = ToNumber(code); | 811 if (!%_IsSmi(code)) code = ToNumber(code); |
| 827 return %_CharFromCode(code & 0xffff); | 812 return %_StringCharFromCode(code & 0xffff); |
| 828 } | 813 } |
| 829 | 814 |
| 830 // NOTE: This is not super-efficient, but it is necessary because we | 815 // NOTE: This is not super-efficient, but it is necessary because we |
| 831 // want to avoid converting to numbers from within the virtual | 816 // want to avoid converting to numbers from within the virtual |
| 832 // machine. Maybe we can find another way of doing this? | 817 // machine. Maybe we can find another way of doing this? |
| 833 var codes = static_charcode_array; | 818 var codes = static_charcode_array; |
| 834 for (var i = 0; i < n; i++) { | 819 for (var i = 0; i < n; i++) { |
| 835 var code = %_Arguments(i); | 820 var code = %_Arguments(i); |
| 836 if (!%_IsSmi(code)) code = ToNumber(code); | 821 if (!%_IsSmi(code)) code = ToNumber(code); |
| 837 codes[i] = code; | 822 codes[i] = code; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 "small", StringSmall, | 997 "small", StringSmall, |
| 1013 "strike", StringStrike, | 998 "strike", StringStrike, |
| 1014 "sub", StringSub, | 999 "sub", StringSub, |
| 1015 "sup", StringSup, | 1000 "sup", StringSup, |
| 1016 "toJSON", StringToJSON | 1001 "toJSON", StringToJSON |
| 1017 )); | 1002 )); |
| 1018 } | 1003 } |
| 1019 | 1004 |
| 1020 | 1005 |
| 1021 SetupString(); | 1006 SetupString(); |
| OLD | NEW |