Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / src / harmony-string.js
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 'use strict';
6
7 // This file relies on the fact that the following declaration has been made
8 // in runtime.js:
9 // var $String = global.String;
10 // var $Array = global.Array;
11
12 // -------------------------------------------------------------------
13
14 // ES6 draft 01-20-14, section 21.1.3.13
15 function StringRepeat(count) {
16   CHECK_OBJECT_COERCIBLE(this, "String.prototype.repeat");
17
18   var s = TO_STRING_INLINE(this);
19   var n = ToInteger(count);
20   // The maximum string length is stored in a smi, so a longer repeat
21   // must result in a range error.
22   if (n < 0 || n > %_MaxSmi()) {
23     throw MakeRangeError("invalid_count_value", []);
24   }
25
26   var r = "";
27   while (true) {
28     if (n & 1) r += s;
29     n >>= 1;
30     if (n === 0) return r;
31     s += s;
32   }
33 }
34
35
36 // ES6 draft 04-05-14, section 21.1.3.18
37 function StringStartsWith(searchString /* position */) {  // length == 1
38   CHECK_OBJECT_COERCIBLE(this, "String.prototype.startsWith");
39
40   var s = TO_STRING_INLINE(this);
41
42   if (IS_REGEXP(searchString)) {
43     throw MakeTypeError("first_argument_not_regexp",
44                         ["String.prototype.startsWith"]);
45   }
46
47   var ss = TO_STRING_INLINE(searchString);
48   var pos = 0;
49   if (%_ArgumentsLength() > 1) {
50     pos = %_Arguments(1);  // position
51     pos = ToInteger(pos);
52   }
53
54   var s_len = s.length;
55   var start = MathMin(MathMax(pos, 0), s_len);
56   var ss_len = ss.length;
57   if (ss_len + start > s_len) {
58     return false;
59   }
60
61   return %StringIndexOf(s, ss, start) === start;
62 }
63
64
65 // ES6 draft 04-05-14, section 21.1.3.7
66 function StringEndsWith(searchString /* position */) {  // length == 1
67   CHECK_OBJECT_COERCIBLE(this, "String.prototype.endsWith");
68
69   var s = TO_STRING_INLINE(this);
70
71   if (IS_REGEXP(searchString)) {
72     throw MakeTypeError("first_argument_not_regexp",
73                         ["String.prototype.endsWith"]);
74   }
75
76   var ss = TO_STRING_INLINE(searchString);
77   var s_len = s.length;
78   var pos = s_len;
79   if (%_ArgumentsLength() > 1) {
80     var arg = %_Arguments(1);  // position
81     if (!IS_UNDEFINED(arg)) {
82       pos = ToInteger(arg);
83     }
84   }
85
86   var end = MathMin(MathMax(pos, 0), s_len);
87   var ss_len = ss.length;
88   var start = end - ss_len;
89   if (start < 0) {
90     return false;
91   }
92
93   return %StringLastIndexOf(s, ss, start) === start;
94 }
95
96
97 // ES6 draft 04-05-14, section 21.1.3.6
98 function StringContains(searchString /* position */) {  // length == 1
99   CHECK_OBJECT_COERCIBLE(this, "String.prototype.contains");
100
101   var s = TO_STRING_INLINE(this);
102
103   if (IS_REGEXP(searchString)) {
104     throw MakeTypeError("first_argument_not_regexp",
105                         ["String.prototype.contains"]);
106   }
107
108   var ss = TO_STRING_INLINE(searchString);
109   var pos = 0;
110   if (%_ArgumentsLength() > 1) {
111     pos = %_Arguments(1);  // position
112     pos = ToInteger(pos);
113   }
114
115   var s_len = s.length;
116   var start = MathMin(MathMax(pos, 0), s_len);
117   var ss_len = ss.length;
118   if (ss_len + start > s_len) {
119     return false;
120   }
121
122   return %StringIndexOf(s, ss, start) !== -1;
123 }
124
125
126 // ES6 Draft 05-22-2014, section 21.1.3.3
127 function StringCodePointAt(pos) {
128   CHECK_OBJECT_COERCIBLE(this, "String.prototype.codePointAt");
129
130   var string = TO_STRING_INLINE(this);
131   var size = string.length;
132   pos = TO_INTEGER(pos);
133   if (pos < 0 || pos >= size) {
134     return UNDEFINED;
135   }
136   var first = %_StringCharCodeAt(string, pos);
137   if (first < 0xD800 || first > 0xDBFF || pos + 1 == size) {
138     return first;
139   }
140   var second = %_StringCharCodeAt(string, pos + 1);
141   if (second < 0xDC00 || second > 0xDFFF) {
142     return first;
143   }
144   return (first - 0xD800) * 0x400 + second + 0x2400;
145 }
146
147
148 // ES6 Draft 05-22-2014, section 21.1.2.2
149 function StringFromCodePoint(_) {  // length = 1
150   var code;
151   var length = %_ArgumentsLength();
152   var index;
153   var result = "";
154   for (index = 0; index < length; index++) {
155     code = %_Arguments(index);
156     if (!%_IsSmi(code)) {
157       code = ToNumber(code);
158     }
159     if (code < 0 || code > 0x10FFFF || code !== TO_INTEGER(code)) {
160       throw MakeRangeError("invalid_code_point", [code]);
161     }
162     if (code <= 0xFFFF) {
163       result += %_StringCharFromCode(code);
164     } else {
165       code -= 0x10000;
166       result += %_StringCharFromCode((code >>> 10) & 0x3FF | 0xD800);
167       result += %_StringCharFromCode(code & 0x3FF | 0xDC00);
168     }
169   }
170   return result;
171 }
172
173
174 // -------------------------------------------------------------------
175
176 function ExtendStringPrototype() {
177   %CheckIsBootstrapping();
178
179   // Set up the non-enumerable functions on the String object.
180   InstallFunctions($String, DONT_ENUM, $Array(
181     "fromCodePoint", StringFromCodePoint
182   ));
183
184   // Set up the non-enumerable functions on the String prototype object.
185   InstallFunctions($String.prototype, DONT_ENUM, $Array(
186     "codePointAt", StringCodePointAt,
187     "contains", StringContains,
188     "endsWith", StringEndsWith,
189     "repeat", StringRepeat,
190     "startsWith", StringStartsWith
191   ));
192 }
193
194 ExtendStringPrototype();