• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2012 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(function(global, utils) {
6
7%CheckIsBootstrapping();
8
9// -------------------------------------------------------------------
10// Imports
11
12var GlobalString = global.String;
13var matchSymbol = utils.ImportNow("match_symbol");
14var searchSymbol = utils.ImportNow("search_symbol");
15
16//-------------------------------------------------------------------
17
18// ECMA-262, section 15.5.4.6
19function StringConcat(other /* and more */) {  // length == 1
20  "use strict";
21  CHECK_OBJECT_COERCIBLE(this, "String.prototype.concat");
22  var s = TO_STRING(this);
23  var len = arguments.length;
24  for (var i = 0; i < len; ++i) {
25    s = s + TO_STRING(arguments[i]);
26  }
27  return s;
28}
29
30
31// ES6 21.1.3.11.
32function StringMatchJS(pattern) {
33  CHECK_OBJECT_COERCIBLE(this, "String.prototype.match");
34
35  if (!IS_NULL_OR_UNDEFINED(pattern)) {
36    var matcher = pattern[matchSymbol];
37    if (!IS_UNDEFINED(matcher)) {
38      return %_Call(matcher, pattern, this);
39    }
40  }
41
42  var subject = TO_STRING(this);
43
44  // Equivalent to RegExpCreate (ES#sec-regexpcreate)
45  var regexp = %RegExpCreate(pattern);
46  return regexp[matchSymbol](subject);
47}
48
49// ES6 21.1.3.15.
50function StringSearch(pattern) {
51  CHECK_OBJECT_COERCIBLE(this, "String.prototype.search");
52
53  if (!IS_NULL_OR_UNDEFINED(pattern)) {
54    var searcher = pattern[searchSymbol];
55    if (!IS_UNDEFINED(searcher)) {
56      return %_Call(searcher, pattern, this);
57    }
58  }
59
60  var subject = TO_STRING(this);
61
62  // Equivalent to RegExpCreate (ES#sec-regexpcreate)
63  var regexp = %RegExpCreate(pattern);
64  return %_Call(regexp[searchSymbol], regexp, subject);
65}
66
67
68// ECMA-262 section 15.5.4.13
69function StringSlice(start, end) {
70  CHECK_OBJECT_COERCIBLE(this, "String.prototype.slice");
71
72  var s = TO_STRING(this);
73  var s_len = s.length;
74  var start_i = TO_INTEGER(start);
75  var end_i = s_len;
76  if (!IS_UNDEFINED(end)) {
77    end_i = TO_INTEGER(end);
78  }
79
80  if (start_i < 0) {
81    start_i += s_len;
82    if (start_i < 0) {
83      start_i = 0;
84    }
85  } else {
86    if (start_i > s_len) {
87      return '';
88    }
89  }
90
91  if (end_i < 0) {
92    end_i += s_len;
93    if (end_i < 0) {
94      return '';
95    }
96  } else {
97    if (end_i > s_len) {
98      end_i = s_len;
99    }
100  }
101
102  if (end_i <= start_i) {
103    return '';
104  }
105
106  return %_SubString(s, start_i, end_i);
107}
108
109
110// ES6 draft, revision 26 (2014-07-18), section B.2.3.2.1
111function HtmlEscape(str) {
112  return %RegExpInternalReplace(/"/g, TO_STRING(str), "&quot;");
113}
114
115
116// ES6 draft, revision 26 (2014-07-18), section B.2.3.2
117function StringAnchor(name) {
118  CHECK_OBJECT_COERCIBLE(this, "String.prototype.anchor");
119  return "<a name=\"" + HtmlEscape(name) + "\">" + TO_STRING(this) +
120         "</a>";
121}
122
123
124// ES6 draft, revision 26 (2014-07-18), section B.2.3.3
125function StringBig() {
126  CHECK_OBJECT_COERCIBLE(this, "String.prototype.big");
127  return "<big>" + TO_STRING(this) + "</big>";
128}
129
130
131// ES6 draft, revision 26 (2014-07-18), section B.2.3.4
132function StringBlink() {
133  CHECK_OBJECT_COERCIBLE(this, "String.prototype.blink");
134  return "<blink>" + TO_STRING(this) + "</blink>";
135}
136
137
138// ES6 draft, revision 26 (2014-07-18), section B.2.3.5
139function StringBold() {
140  CHECK_OBJECT_COERCIBLE(this, "String.prototype.bold");
141  return "<b>" + TO_STRING(this) + "</b>";
142}
143
144
145// ES6 draft, revision 26 (2014-07-18), section B.2.3.6
146function StringFixed() {
147  CHECK_OBJECT_COERCIBLE(this, "String.prototype.fixed");
148  return "<tt>" + TO_STRING(this) + "</tt>";
149}
150
151
152// ES6 draft, revision 26 (2014-07-18), section B.2.3.7
153function StringFontcolor(color) {
154  CHECK_OBJECT_COERCIBLE(this, "String.prototype.fontcolor");
155  return "<font color=\"" + HtmlEscape(color) + "\">" + TO_STRING(this) +
156         "</font>";
157}
158
159
160// ES6 draft, revision 26 (2014-07-18), section B.2.3.8
161function StringFontsize(size) {
162  CHECK_OBJECT_COERCIBLE(this, "String.prototype.fontsize");
163  return "<font size=\"" + HtmlEscape(size) + "\">" + TO_STRING(this) +
164         "</font>";
165}
166
167
168// ES6 draft, revision 26 (2014-07-18), section B.2.3.9
169function StringItalics() {
170  CHECK_OBJECT_COERCIBLE(this, "String.prototype.italics");
171  return "<i>" + TO_STRING(this) + "</i>";
172}
173
174
175// ES6 draft, revision 26 (2014-07-18), section B.2.3.10
176function StringLink(s) {
177  CHECK_OBJECT_COERCIBLE(this, "String.prototype.link");
178  return "<a href=\"" + HtmlEscape(s) + "\">" + TO_STRING(this) + "</a>";
179}
180
181
182// ES6 draft, revision 26 (2014-07-18), section B.2.3.11
183function StringSmall() {
184  CHECK_OBJECT_COERCIBLE(this, "String.prototype.small");
185  return "<small>" + TO_STRING(this) + "</small>";
186}
187
188
189// ES6 draft, revision 26 (2014-07-18), section B.2.3.12
190function StringStrike() {
191  CHECK_OBJECT_COERCIBLE(this, "String.prototype.strike");
192  return "<strike>" + TO_STRING(this) + "</strike>";
193}
194
195
196// ES6 draft, revision 26 (2014-07-18), section B.2.3.13
197function StringSub() {
198  CHECK_OBJECT_COERCIBLE(this, "String.prototype.sub");
199  return "<sub>" + TO_STRING(this) + "</sub>";
200}
201
202
203// ES6 draft, revision 26 (2014-07-18), section B.2.3.14
204function StringSup() {
205  CHECK_OBJECT_COERCIBLE(this, "String.prototype.sup");
206  return "<sup>" + TO_STRING(this) + "</sup>";
207}
208
209// ES6, section 21.1.3.13
210function StringRepeat(count) {
211  CHECK_OBJECT_COERCIBLE(this, "String.prototype.repeat");
212
213  var s = TO_STRING(this);
214  var n = TO_INTEGER(count);
215
216  if (n < 0 || n === INFINITY) throw %make_range_error(kInvalidCountValue);
217
218  // Early return to allow an arbitrarily-large repeat of the empty string.
219  if (s.length === 0) return "";
220
221  // The maximum string length is stored in a smi, so a longer repeat
222  // must result in a range error.
223  if (n > %_MaxSmi()) throw %make_range_error(kInvalidCountValue);
224
225  var r = "";
226  while (true) {
227    if (n & 1) r += s;
228    n >>= 1;
229    if (n === 0) return r;
230    s += s;
231  }
232}
233
234
235// ES6 Draft 05-22-2014, section 21.1.3.3
236function StringCodePointAt(pos) {
237  CHECK_OBJECT_COERCIBLE(this, "String.prototype.codePointAt");
238
239  var string = TO_STRING(this);
240  var size = string.length;
241  pos = TO_INTEGER(pos);
242  if (pos < 0 || pos >= size) {
243    return UNDEFINED;
244  }
245  var first = %_StringCharCodeAt(string, pos);
246  if (first < 0xD800 || first > 0xDBFF || pos + 1 == size) {
247    return first;
248  }
249  var second = %_StringCharCodeAt(string, pos + 1);
250  if (second < 0xDC00 || second > 0xDFFF) {
251    return first;
252  }
253  return (first - 0xD800) * 0x400 + second + 0x2400;
254}
255
256
257// -------------------------------------------------------------------
258// String methods related to templates
259
260// ES6 Draft 03-17-2015, section 21.1.2.4
261function StringRaw(callSite) {
262  "use strict";
263  var numberOfSubstitutions = arguments.length;
264  var cooked = TO_OBJECT(callSite);
265  var raw = TO_OBJECT(cooked.raw);
266  var literalSegments = TO_LENGTH(raw.length);
267  if (literalSegments <= 0) return "";
268
269  var result = TO_STRING(raw[0]);
270
271  for (var i = 1; i < literalSegments; ++i) {
272    if (i < numberOfSubstitutions) {
273      result += TO_STRING(arguments[i]);
274    }
275    result += TO_STRING(raw[i]);
276  }
277
278  return result;
279}
280
281// -------------------------------------------------------------------
282
283// Set up the non-enumerable functions on the String object.
284utils.InstallFunctions(GlobalString, DONT_ENUM, [
285  "raw", StringRaw
286]);
287
288// Set up the non-enumerable functions on the String prototype object.
289utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
290  "codePointAt", StringCodePointAt,
291  "concat", StringConcat,
292  "match", StringMatchJS,
293  "repeat", StringRepeat,
294  "search", StringSearch,
295  "slice", StringSlice,
296
297  "link", StringLink,
298  "anchor", StringAnchor,
299  "fontcolor", StringFontcolor,
300  "fontsize", StringFontsize,
301  "big", StringBig,
302  "blink", StringBlink,
303  "bold", StringBold,
304  "fixed", StringFixed,
305  "italics", StringItalics,
306  "small", StringSmall,
307  "strike", StringStrike,
308  "sub", StringSub,
309  "sup", StringSup
310]);
311
312})
313