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 |