1ef4e973fdc8dd1baff155916e15b1e75155cc88
[platform/upstream/v8.git] / src / runtime.js
1 // Copyright 2006-2008 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 // This files contains runtime support implemented in JavaScript.
6
7 // CAUTION: Some of the functions specified in this file are called
8 // directly from compiled code. These are the functions with names in
9 // ALL CAPS. The compiled code passes the first argument in 'this'.
10
11
12 // The following declarations are shared with other native JS files.
13 // They are all declared at this one spot to avoid redeclaration errors.
14 var $defaultString;
15 var $NaN;
16 var $nonNumberToNumber;
17 var $nonStringToString;
18 var $sameValue;
19 var $sameValueZero;
20 var $toInteger;
21 var $toLength;
22 var $toName;
23 var $toNumber;
24 var $toPositiveInteger;
25 var $toPrimitive;
26 var $toString;
27
28 (function(global, utils) {
29
30 %CheckIsBootstrapping();
31
32 var GlobalArray = global.Array;
33 var GlobalBoolean = global.Boolean;
34 var GlobalString = global.String;
35 var GlobalNumber = global.Number;
36
37 // ----------------------------------------------------------------------------
38
39 /* -----------------------------------
40 - - -   C o m p a r i s o n   - - -
41 -----------------------------------
42 */
43
44 // ECMA-262 Section 11.9.3.
45 function EQUALS(y) {
46   if (IS_STRING(this) && IS_STRING(y)) return %StringEquals(this, y);
47   var x = this;
48
49   while (true) {
50     if (IS_NUMBER(x)) {
51       while (true) {
52         if (IS_NUMBER(y)) return %NumberEquals(x, y);
53         if (IS_NULL_OR_UNDEFINED(y)) return 1;  // not equal
54         if (!IS_SPEC_OBJECT(y)) {
55           if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1;  // not equal
56           // String or boolean.
57           return %NumberEquals(x, %to_number_fun(y));
58         }
59         y = %to_primitive(y, NO_HINT);
60       }
61     } else if (IS_STRING(x)) {
62       while (true) {
63         if (IS_STRING(y)) return %StringEquals(x, y);
64         if (IS_NUMBER(y)) return %NumberEquals(%to_number_fun(x), y);
65         if (IS_BOOLEAN(y)) {
66           return %NumberEquals(%to_number_fun(x), %to_number_fun(y));
67         }
68         if (IS_NULL_OR_UNDEFINED(y)) return 1;  // not equal
69         if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1;  // not equal
70         y = %to_primitive(y, NO_HINT);
71       }
72     } else if (IS_SYMBOL(x)) {
73       if (IS_SYMBOL(y)) return %_ObjectEquals(x, y) ? 0 : 1;
74       return 1; // not equal
75     } else if (IS_BOOLEAN(x)) {
76       if (IS_BOOLEAN(y)) return %_ObjectEquals(x, y) ? 0 : 1;
77       if (IS_NULL_OR_UNDEFINED(y)) return 1;
78       if (IS_NUMBER(y)) return %NumberEquals(%to_number_fun(x), y);
79       if (IS_STRING(y)) {
80         return %NumberEquals(%to_number_fun(x), %to_number_fun(y));
81       }
82       if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1;  // not equal
83       // y is object.
84       x = %to_number_fun(x);
85       y = %to_primitive(y, NO_HINT);
86     } else if (IS_NULL_OR_UNDEFINED(x)) {
87       return IS_NULL_OR_UNDEFINED(y) ? 0 : 1;
88     } else if (IS_SIMD_VALUE(x)) {
89       if (!IS_SIMD_VALUE(y)) return 1;  // not equal
90        return %SimdEquals(x, y);
91     } else {
92       // x is an object.
93       if (IS_SPEC_OBJECT(y)) return %_ObjectEquals(x, y) ? 0 : 1;
94       if (IS_NULL_OR_UNDEFINED(y)) return 1;  // not equal
95       if (IS_BOOLEAN(y)) {
96         y = %to_number_fun(y);
97       } else if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) {
98         return 1;  // not equal
99       }
100       x = %to_primitive(x, NO_HINT);
101     }
102   }
103 }
104
105
106 // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as
107 // the result when either (or both) the operands are NaN.
108 function COMPARE(x, ncr) {
109   var left;
110   var right;
111   // Fast cases for string, numbers and undefined compares.
112   if (IS_STRING(this)) {
113     if (IS_STRING(x)) return %_StringCompare(this, x);
114     if (IS_UNDEFINED(x)) return ncr;
115     left = this;
116   } else if (IS_NUMBER(this)) {
117     if (IS_NUMBER(x)) return %NumberCompare(this, x, ncr);
118     if (IS_UNDEFINED(x)) return ncr;
119     left = this;
120   } else if (IS_UNDEFINED(this)) {
121     if (!IS_UNDEFINED(x)) {
122       %to_primitive(x, NUMBER_HINT);
123     }
124     return ncr;
125   } else if (IS_UNDEFINED(x)) {
126     %to_primitive(this, NUMBER_HINT);
127     return ncr;
128   } else {
129     left = %to_primitive(this, NUMBER_HINT);
130   }
131
132   right = %to_primitive(x, NUMBER_HINT);
133   if (IS_STRING(left) && IS_STRING(right)) {
134     return %_StringCompare(left, right);
135   } else {
136     var left_number = %to_number_fun(left);
137     var right_number = %to_number_fun(right);
138     if (NUMBER_IS_NAN(left_number) || NUMBER_IS_NAN(right_number)) return ncr;
139     return %NumberCompare(left_number, right_number, ncr);
140   }
141 }
142
143 // Strong mode COMPARE throws if an implicit conversion would be performed
144 function COMPARE_STRONG(x, ncr) {
145   if (IS_STRING(this) && IS_STRING(x)) return %_StringCompare(this, x);
146   if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberCompare(this, x, ncr);
147
148   throw %make_type_error(kStrongImplicitConversion);
149 }
150
151
152
153 /* -----------------------------------
154    - - -   A r i t h m e t i c   - - -
155    -----------------------------------
156 */
157
158 // ECMA-262, section 11.6.1, page 50.
159 function ADD(x) {
160   // Fast case: Check for number operands and do the addition.
161   if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x);
162   if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x);
163
164   // Default implementation.
165   var a = %to_primitive(this, NO_HINT);
166   var b = %to_primitive(x, NO_HINT);
167
168   if (IS_STRING(a)) {
169     return %_StringAdd(a, %to_string_fun(b));
170   } else if (IS_STRING(b)) {
171     return %_StringAdd(%non_string_to_string(a), b);
172   } else {
173     return %NumberAdd(%to_number_fun(a), %to_number_fun(b));
174   }
175 }
176
177
178 // Strong mode ADD throws if an implicit conversion would be performed
179 function ADD_STRONG(x) {
180   if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x);
181   if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x);
182
183   throw %make_type_error(kStrongImplicitConversion);
184 }
185
186
187 // Left operand (this) is already a string.
188 function STRING_ADD_LEFT(y) {
189   if (!IS_STRING(y)) {
190     if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) {
191       y = %_ValueOf(y);
192     } else {
193       y = IS_NUMBER(y)
194           ? %_NumberToString(y)
195           : %to_string_fun(%to_primitive(y, NO_HINT));
196     }
197   }
198   return %_StringAdd(this, y);
199 }
200
201
202 // Right operand (y) is already a string.
203 function STRING_ADD_RIGHT(y) {
204   var x = this;
205   if (!IS_STRING(x)) {
206     if (IS_STRING_WRAPPER(x) && %_IsStringWrapperSafeForDefaultValueOf(x)) {
207       x = %_ValueOf(x);
208     } else {
209       x = IS_NUMBER(x)
210           ? %_NumberToString(x)
211           : %to_string_fun(%to_primitive(x, NO_HINT));
212     }
213   }
214   return %_StringAdd(x, y);
215 }
216
217
218 // ECMA-262, section 11.6.2, page 50.
219 function SUB(y) {
220   var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
221   if (!IS_NUMBER(y)) y = %non_number_to_number(y);
222   return %NumberSub(x, y);
223 }
224
225
226 // Strong mode SUB throws if an implicit conversion would be performed
227 function SUB_STRONG(y) {
228   if (IS_NUMBER(this) && IS_NUMBER(y)) {
229     return %NumberSub(this, y);
230   }
231   throw %make_type_error(kStrongImplicitConversion);
232 }
233
234
235 // ECMA-262, section 11.5.1, page 48.
236 function MUL(y) {
237   var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
238   if (!IS_NUMBER(y)) y = %non_number_to_number(y);
239   return %NumberMul(x, y);
240 }
241
242
243 // Strong mode MUL throws if an implicit conversion would be performed
244 function MUL_STRONG(y) {
245   if (IS_NUMBER(this) && IS_NUMBER(y)) {
246     return %NumberMul(this, y);
247   }
248   throw %make_type_error(kStrongImplicitConversion);
249 }
250
251
252 // ECMA-262, section 11.5.2, page 49.
253 function DIV(y) {
254   var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
255   if (!IS_NUMBER(y)) y = %non_number_to_number(y);
256   return %NumberDiv(x, y);
257 }
258
259
260 // Strong mode DIV throws if an implicit conversion would be performed
261 function DIV_STRONG(y) {
262   if (IS_NUMBER(this) && IS_NUMBER(y)) {
263     return %NumberDiv(this, y);
264   }
265   throw %make_type_error(kStrongImplicitConversion);
266 }
267
268
269 // ECMA-262, section 11.5.3, page 49.
270 function MOD(y) {
271   var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
272   if (!IS_NUMBER(y)) y = %non_number_to_number(y);
273   return %NumberMod(x, y);
274 }
275
276
277 // Strong mode MOD throws if an implicit conversion would be performed
278 function MOD_STRONG(y) {
279   if (IS_NUMBER(this) && IS_NUMBER(y)) {
280     return %NumberMod(this, y);
281   }
282   throw %make_type_error(kStrongImplicitConversion);
283 }
284
285
286 /* -------------------------------------------
287    - - -   B i t   o p e r a t i o n s   - - -
288    -------------------------------------------
289 */
290
291 // ECMA-262, section 11.10, page 57.
292 function BIT_OR(y) {
293   var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
294   if (!IS_NUMBER(y)) y = %non_number_to_number(y);
295   return %NumberOr(x, y);
296 }
297
298
299 // Strong mode BIT_OR throws if an implicit conversion would be performed
300 function BIT_OR_STRONG(y) {
301   if (IS_NUMBER(this) && IS_NUMBER(y)) {
302     return %NumberOr(this, y);
303   }
304   throw %make_type_error(kStrongImplicitConversion);
305 }
306
307
308 // ECMA-262, section 11.10, page 57.
309 function BIT_AND(y) {
310   var x;
311   if (IS_NUMBER(this)) {
312     x = this;
313     if (!IS_NUMBER(y)) y = %non_number_to_number(y);
314   } else {
315     x = %non_number_to_number(this);
316     // Make sure to convert the right operand to a number before
317     // bailing out in the fast case, but after converting the
318     // left operand. This ensures that valueOf methods on the right
319     // operand are always executed.
320     if (!IS_NUMBER(y)) y = %non_number_to_number(y);
321     // Optimize for the case where we end up AND'ing a value
322     // that doesn't convert to a number. This is common in
323     // certain benchmarks.
324     if (NUMBER_IS_NAN(x)) return 0;
325   }
326   return %NumberAnd(x, y);
327 }
328
329
330 // Strong mode BIT_AND throws if an implicit conversion would be performed
331 function BIT_AND_STRONG(y) {
332   if (IS_NUMBER(this) && IS_NUMBER(y)) {
333     return %NumberAnd(this, y);
334   }
335   throw %make_type_error(kStrongImplicitConversion);
336 }
337
338
339 // ECMA-262, section 11.10, page 57.
340 function BIT_XOR(y) {
341   var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
342   if (!IS_NUMBER(y)) y = %non_number_to_number(y);
343   return %NumberXor(x, y);
344 }
345
346
347 // Strong mode BIT_XOR throws if an implicit conversion would be performed
348 function BIT_XOR_STRONG(y) {
349   if (IS_NUMBER(this) && IS_NUMBER(y)) {
350     return %NumberXor(this, y);
351   }
352   throw %make_type_error(kStrongImplicitConversion);
353 }
354
355
356 // ECMA-262, section 11.7.1, page 51.
357 function SHL(y) {
358   var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
359   if (!IS_NUMBER(y)) y = %non_number_to_number(y);
360   return %NumberShl(x, y);
361 }
362
363
364 // Strong mode SHL throws if an implicit conversion would be performed
365 function SHL_STRONG(y) {
366   if (IS_NUMBER(this) && IS_NUMBER(y)) {
367     return %NumberShl(this, y);
368   }
369   throw %make_type_error(kStrongImplicitConversion);
370 }
371
372
373 // ECMA-262, section 11.7.2, page 51.
374 function SAR(y) {
375   var x;
376   if (IS_NUMBER(this)) {
377     x = this;
378     if (!IS_NUMBER(y)) y = %non_number_to_number(y);
379   } else {
380     x = %non_number_to_number(this);
381     // Make sure to convert the right operand to a number before
382     // bailing out in the fast case, but after converting the
383     // left operand. This ensures that valueOf methods on the right
384     // operand are always executed.
385     if (!IS_NUMBER(y)) y = %non_number_to_number(y);
386     // Optimize for the case where we end up shifting a value
387     // that doesn't convert to a number. This is common in
388     // certain benchmarks.
389     if (NUMBER_IS_NAN(x)) return 0;
390   }
391   return %NumberSar(x, y);
392 }
393
394
395 // Strong mode SAR throws if an implicit conversion would be performed
396 function SAR_STRONG(y) {
397   if (IS_NUMBER(this) && IS_NUMBER(y)) {
398     return %NumberSar(this, y);
399   }
400   throw %make_type_error(kStrongImplicitConversion);
401 }
402
403
404 // ECMA-262, section 11.7.3, page 52.
405 function SHR(y) {
406   var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
407   if (!IS_NUMBER(y)) y = %non_number_to_number(y);
408   return %NumberShr(x, y);
409 }
410
411
412 // Strong mode SHR throws if an implicit conversion would be performed
413 function SHR_STRONG(y) {
414   if (IS_NUMBER(this) && IS_NUMBER(y)) {
415     return %NumberShr(this, y);
416   }
417   throw %make_type_error(kStrongImplicitConversion);
418 }
419
420
421 /* -----------------------------
422    - - -   H e l p e r s   - - -
423    -----------------------------
424 */
425
426 // ECMA-262, section 11.8.7, page 54.
427 function IN(x) {
428   if (!IS_SPEC_OBJECT(x)) {
429     throw %make_type_error(kInvalidInOperatorUse, this, x);
430   }
431   if (%_IsNonNegativeSmi(this)) {
432     if (IS_ARRAY(x) && %_HasFastPackedElements(x)) {
433       return this < x.length;
434     }
435     return %HasElement(x, this);
436   }
437   return %HasProperty(x, %to_name(this));
438 }
439
440
441 function CALL_NON_FUNCTION() {
442   var delegate = %GetFunctionDelegate(this);
443   if (!IS_FUNCTION(delegate)) {
444     var callsite = %RenderCallSite();
445     if (callsite == "") callsite = typeof this;
446     throw %make_type_error(kCalledNonCallable, callsite);
447   }
448   return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
449 }
450
451
452 function CALL_NON_FUNCTION_AS_CONSTRUCTOR() {
453   var delegate = %GetConstructorDelegate(this);
454   if (!IS_FUNCTION(delegate)) {
455     var callsite = %RenderCallSite();
456     if (callsite == "") callsite = typeof this;
457     throw %make_type_error(kCalledNonCallable, callsite);
458   }
459   return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
460 }
461
462
463 function CALL_FUNCTION_PROXY() {
464   var arity = %_ArgumentsLength() - 1;
465   var proxy = %_Arguments(arity);  // The proxy comes in as an additional arg.
466   var trap = %GetCallTrap(proxy);
467   return %Apply(trap, this, arguments, 0, arity);
468 }
469
470
471 function CALL_FUNCTION_PROXY_AS_CONSTRUCTOR () {
472   var proxy = this;
473   var trap = %GetConstructTrap(proxy);
474   return %Apply(trap, this, arguments, 0, %_ArgumentsLength());
475 }
476
477
478 function APPLY_PREPARE(args) {
479   var length;
480   // First check whether length is a positive Smi and args is an
481   // array. This is the fast case. If this fails, we do the slow case
482   // that takes care of more eventualities.
483   if (IS_ARRAY(args)) {
484     length = args.length;
485     if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength &&
486         IS_SPEC_FUNCTION(this)) {
487       return length;
488     }
489   }
490
491   length = (args == null) ? 0 : TO_UINT32(args.length);
492
493   // We can handle any number of apply arguments if the stack is
494   // big enough, but sanity check the value to avoid overflow when
495   // multiplying with pointer size.
496   if (length > kSafeArgumentsLength) throw %make_range_error(kStackOverflow);
497
498   if (!IS_SPEC_FUNCTION(this)) {
499     throw %make_type_error(kApplyNonFunction, %to_string_fun(this), typeof this);
500   }
501
502   // Make sure the arguments list has the right type.
503   if (args != null && !IS_SPEC_OBJECT(args)) {
504     throw %make_type_error(kWrongArgs, "Function.prototype.apply");
505   }
506
507   // Return the length which is the number of arguments to copy to the
508   // stack. It is guaranteed to be a small integer at this point.
509   return length;
510 }
511
512
513 function REFLECT_APPLY_PREPARE(args) {
514   var length;
515   // First check whether length is a positive Smi and args is an
516   // array. This is the fast case. If this fails, we do the slow case
517   // that takes care of more eventualities.
518   if (IS_ARRAY(args)) {
519     length = args.length;
520     if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength &&
521         IS_SPEC_FUNCTION(this)) {
522       return length;
523     }
524   }
525
526   if (!IS_SPEC_FUNCTION(this)) {
527     throw %make_type_error(kCalledNonCallable, %to_string_fun(this));
528   }
529
530   if (!IS_SPEC_OBJECT(args)) {
531     throw %make_type_error(kWrongArgs, "Reflect.apply");
532   }
533
534   length = %to_length_fun(args.length);
535
536   // We can handle any number of apply arguments if the stack is
537   // big enough, but sanity check the value to avoid overflow when
538   // multiplying with pointer size.
539   if (length > kSafeArgumentsLength) throw %make_range_error(kStackOverflow);
540
541   // Return the length which is the number of arguments to copy to the
542   // stack. It is guaranteed to be a small integer at this point.
543   return length;
544 }
545
546
547 function REFLECT_CONSTRUCT_PREPARE(
548     args, newTarget) {
549   var length;
550   var ctorOk = IS_SPEC_FUNCTION(this) && %IsConstructor(this);
551   var newTargetOk = IS_SPEC_FUNCTION(newTarget) && %IsConstructor(newTarget);
552
553   // First check whether length is a positive Smi and args is an
554   // array. This is the fast case. If this fails, we do the slow case
555   // that takes care of more eventualities.
556   if (IS_ARRAY(args)) {
557     length = args.length;
558     if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength &&
559         ctorOk && newTargetOk) {
560       return length;
561     }
562   }
563
564   if (!ctorOk) {
565     if (!IS_SPEC_FUNCTION(this)) {
566       throw %make_type_error(kCalledNonCallable, %to_string_fun(this));
567     } else {
568       throw %make_type_error(kNotConstructor, %to_string_fun(this));
569     }
570   }
571
572   if (!newTargetOk) {
573     if (!IS_SPEC_FUNCTION(newTarget)) {
574       throw %make_type_error(kCalledNonCallable, %to_string_fun(newTarget));
575     } else {
576       throw %make_type_error(kNotConstructor, %to_string_fun(newTarget));
577     }
578   }
579
580   if (!IS_SPEC_OBJECT(args)) {
581     throw %make_type_error(kWrongArgs, "Reflect.construct");
582   }
583
584   length = %to_length_fun(args.length);
585
586   // We can handle any number of apply arguments if the stack is
587   // big enough, but sanity check the value to avoid overflow when
588   // multiplying with pointer size.
589   if (length > kSafeArgumentsLength) throw %make_range_error(kStackOverflow);
590
591   // Return the length which is the number of arguments to copy to the
592   // stack. It is guaranteed to be a small integer at this point.
593   return length;
594 }
595
596
597 function CONCAT_ITERABLE_TO_ARRAY(iterable) {
598   return %concat_iterable_to_array(this, iterable);
599 };
600
601
602 function STACK_OVERFLOW(length) {
603   throw %make_range_error(kStackOverflow);
604 }
605
606
607 // Convert the receiver to a number - forward to ToNumber.
608 function TO_NUMBER() {
609   return %to_number_fun(this);
610 }
611
612
613 // Convert the receiver to a string - forward to ToString.
614 function TO_STRING() {
615   return %to_string_fun(this);
616 }
617
618
619 // Convert the receiver to a string or symbol - forward to ToName.
620 function TO_NAME() {
621   return %to_name(this);
622 }
623
624
625 /* -------------------------------------
626    - - -   C o n v e r s i o n s   - - -
627    -------------------------------------
628 */
629
630 // ECMA-262, section 9.1, page 30. Use null/undefined for no hint,
631 // (1) for number hint, and (2) for string hint.
632 function ToPrimitive(x, hint) {
633   if (!IS_SPEC_OBJECT(x)) return x;
634   if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT;
635   return (hint == NUMBER_HINT) ? DefaultNumber(x) : DefaultString(x);
636 }
637
638
639 // ECMA-262, section 9.2, page 30
640 function ToBoolean(x) {
641   if (IS_BOOLEAN(x)) return x;
642   if (IS_STRING(x)) return x.length != 0;
643   if (x == null) return false;
644   if (IS_NUMBER(x)) return !((x == 0) || NUMBER_IS_NAN(x));
645   return true;
646 }
647
648
649 // ECMA-262, section 9.3, page 31.
650 function ToNumber(x) {
651   if (IS_NUMBER(x)) return x;
652   if (IS_STRING(x)) {
653     return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x)
654                                     : %StringToNumber(x);
655   }
656   if (IS_BOOLEAN(x)) return x ? 1 : 0;
657   if (IS_UNDEFINED(x)) return NAN;
658   // Types that can't be converted to number are caught in DefaultNumber.
659   return (IS_NULL(x)) ? 0 : ToNumber(DefaultNumber(x));
660 }
661
662 function NonNumberToNumber(x) {
663   if (IS_STRING(x)) {
664     return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x)
665                                     : %StringToNumber(x);
666   }
667   if (IS_BOOLEAN(x)) return x ? 1 : 0;
668   if (IS_UNDEFINED(x)) return NAN;
669   // Types that can't be converted to number are caught in DefaultNumber.
670   return (IS_NULL(x)) ? 0 : ToNumber(DefaultNumber(x));
671 }
672
673
674 // ECMA-262, section 9.8, page 35.
675 function ToString(x) {
676   if (IS_STRING(x)) return x;
677   if (IS_NUMBER(x)) return %_NumberToString(x);
678   if (IS_BOOLEAN(x)) return x ? 'true' : 'false';
679   if (IS_UNDEFINED(x)) return 'undefined';
680   // Types that can't be converted to string are caught in DefaultString.
681   return (IS_NULL(x)) ? 'null' : ToString(DefaultString(x));
682 }
683
684 function NonStringToString(x) {
685   if (IS_NUMBER(x)) return %_NumberToString(x);
686   if (IS_BOOLEAN(x)) return x ? 'true' : 'false';
687   if (IS_UNDEFINED(x)) return 'undefined';
688   // Types that can't be converted to string are caught in DefaultString.
689   return (IS_NULL(x)) ? 'null' : ToString(DefaultString(x));
690 }
691
692
693 // ES6 symbols
694 function ToName(x) {
695   return IS_SYMBOL(x) ? x : ToString(x);
696 }
697
698
699 // ECMA-262, section 9.4, page 34.
700 function ToInteger(x) {
701   if (%_IsSmi(x)) return x;
702   return %NumberToInteger(ToNumber(x));
703 }
704
705
706 // ES6, draft 08-24-14, section 7.1.15
707 function ToLength(arg) {
708   arg = ToInteger(arg);
709   if (arg < 0) return 0;
710   return arg < GlobalNumber.MAX_SAFE_INTEGER ? arg
711                                              : GlobalNumber.MAX_SAFE_INTEGER;
712 }
713
714
715 // ES5, section 9.12
716 function SameValue(x, y) {
717   if (typeof x != typeof y) return false;
718   if (IS_NUMBER(x)) {
719     if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
720     // x is +0 and y is -0 or vice versa.
721     if (x === 0 && y === 0 && %_IsMinusZero(x) != %_IsMinusZero(y)) {
722       return false;
723     }
724   }
725   if (IS_SIMD_VALUE(x)) return %SimdSameValue(x, y);
726   return x === y;
727 }
728
729
730 // ES6, section 7.2.4
731 function SameValueZero(x, y) {
732   if (typeof x != typeof y) return false;
733   if (IS_NUMBER(x)) {
734     if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
735   }
736   if (IS_SIMD_VALUE(x)) return %SimdSameValueZero(x, y);
737   return x === y;
738 }
739
740
741 function ConcatIterableToArray(target, iterable) {
742    var index = target.length;
743    for (var element of iterable) {
744      %AddElement(target, index++, element);
745    }
746    return target;
747 }
748
749
750 /* ---------------------------------
751    - - -   U t i l i t i e s   - - -
752    ---------------------------------
753 */
754
755 // Returns if the given x is a primitive value - not an object or a
756 // function.
757 function IsPrimitive(x) {
758   // Even though the type of null is "object", null is still
759   // considered a primitive value. IS_SPEC_OBJECT handles this correctly
760   // (i.e., it will return false if x is null).
761   return !IS_SPEC_OBJECT(x);
762 }
763
764
765 // ES6, draft 10-14-14, section 22.1.3.1.1
766 function IsConcatSpreadable(O) {
767   if (!IS_SPEC_OBJECT(O)) return false;
768   var spreadable = O[symbolIsConcatSpreadable];
769   if (IS_UNDEFINED(spreadable)) return IS_ARRAY(O);
770   return ToBoolean(spreadable);
771 }
772
773
774 // ECMA-262, section 8.6.2.6, page 28.
775 function DefaultNumber(x) {
776   var valueOf = x.valueOf;
777   if (IS_SPEC_FUNCTION(valueOf)) {
778     var v = %_CallFunction(x, valueOf);
779     if (IS_SYMBOL(v)) throw MakeTypeError(kSymbolToNumber);
780     if (IS_SIMD_VALUE(x)) throw MakeTypeError(kSimdToNumber);
781     if (IsPrimitive(v)) return v;
782   }
783   var toString = x.toString;
784   if (IS_SPEC_FUNCTION(toString)) {
785     var s = %_CallFunction(x, toString);
786     if (IsPrimitive(s)) return s;
787   }
788   throw MakeTypeError(kCannotConvertToPrimitive);
789 }
790
791 // ECMA-262, section 8.6.2.6, page 28.
792 function DefaultString(x) {
793   if (!IS_SYMBOL_WRAPPER(x)) {
794     if (IS_SYMBOL(x)) throw MakeTypeError(kSymbolToString);
795     var toString = x.toString;
796     if (IS_SPEC_FUNCTION(toString)) {
797       var s = %_CallFunction(x, toString);
798       if (IsPrimitive(s)) return s;
799     }
800
801     var valueOf = x.valueOf;
802     if (IS_SPEC_FUNCTION(valueOf)) {
803       var v = %_CallFunction(x, valueOf);
804       if (IsPrimitive(v)) return v;
805     }
806   }
807   throw MakeTypeError(kCannotConvertToPrimitive);
808 }
809
810 function ToPositiveInteger(x, rangeErrorIndex) {
811   var i = TO_INTEGER_MAP_MINUS_ZERO(x);
812   if (i < 0) throw MakeRangeError(rangeErrorIndex);
813   return i;
814 }
815
816 //----------------------------------------------------------------------------
817
818 // NOTE: Setting the prototype for Array must take place as early as
819 // possible due to code generation for array literals.  When
820 // generating code for a array literal a boilerplate array is created
821 // that is cloned when running the code.  It is essential that the
822 // boilerplate gets the right prototype.
823 %FunctionSetPrototype(GlobalArray, new GlobalArray(0));
824
825 // ----------------------------------------------------------------------------
826 // Exports
827
828 $defaultString = DefaultString;
829 $NaN = %GetRootNaN();
830 $nonNumberToNumber = NonNumberToNumber;
831 $nonStringToString = NonStringToString;
832 $sameValue = SameValue;
833 $sameValueZero = SameValueZero;
834 $toInteger = ToInteger;
835 $toLength = ToLength;
836 $toName = ToName;
837 $toNumber = ToNumber;
838 $toPositiveInteger = ToPositiveInteger;
839 $toPrimitive = ToPrimitive;
840 $toString = ToString;
841
842 %InstallToContext([
843   "add_builtin", ADD,
844   "add_strong_builtin", ADD_STRONG,
845   "apply_prepare_builtin", APPLY_PREPARE,
846   "bit_and_builtin", BIT_AND,
847   "bit_and_strong_builtin", BIT_AND_STRONG,
848   "bit_or_builtin", BIT_OR,
849   "bit_or_strong_builtin", BIT_OR_STRONG,
850   "bit_xor_builtin", BIT_XOR,
851   "bit_xor_strong_builtin", BIT_XOR_STRONG,
852   "call_function_proxy_as_constructor_builtin", CALL_FUNCTION_PROXY_AS_CONSTRUCTOR,
853   "call_function_proxy_builtin", CALL_FUNCTION_PROXY,
854   "call_non_function_as_constructor_builtin", CALL_NON_FUNCTION_AS_CONSTRUCTOR,
855   "call_non_function_builtin", CALL_NON_FUNCTION,
856   "compare_builtin", COMPARE,
857   "compare_strong_builtin", COMPARE_STRONG,
858   "concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY,
859   "div_builtin", DIV,
860   "div_strong_builtin", DIV_STRONG,
861   "equals_builtin", EQUALS,
862   "in_builtin", IN,
863   "mod_builtin", MOD,
864   "mod_strong_builtin", MOD_STRONG,
865   "mul_builtin", MUL,
866   "mul_strong_builtin", MUL_STRONG,
867   "reflect_apply_prepare_builtin", REFLECT_APPLY_PREPARE,
868   "reflect_construct_prepare_builtin", REFLECT_CONSTRUCT_PREPARE,
869   "sar_builtin", SAR,
870   "sar_strong_builtin", SAR_STRONG,
871   "shl_builtin", SHL,
872   "shl_strong_builtin", SHL_STRONG,
873   "shr_builtin", SHR,
874   "shr_strong_builtin", SHR_STRONG,
875   "stack_overflow_builtin", STACK_OVERFLOW,
876   "string_add_left_builtin", STRING_ADD_LEFT,
877   "string_add_right_builtin", STRING_ADD_RIGHT,
878   "sub_builtin", SUB,
879   "sub_strong_builtin", SUB_STRONG,
880   "to_name_builtin", TO_NAME,
881   "to_string_builtin", TO_STRING,
882 ]);
883
884 %InstallToContext([
885   "concat_iterable_to_array", ConcatIterableToArray,
886   "non_number_to_number", NonNumberToNumber,
887   "non_string_to_string", NonStringToString,
888   "to_integer_fun", ToInteger,
889   "to_length_fun", ToLength,
890   "to_name", ToName,
891   "to_number_fun", ToNumber,
892   "to_primitive", ToPrimitive,
893   "to_string_fun", ToString,
894 ]);
895
896 utils.Export(function(to) {
897   to.ToBoolean = ToBoolean;
898   to.ToLength = ToLength;
899   to.ToName = ToName;
900   to.ToNumber = ToNumber;
901   to.ToPrimitive = ToPrimitive;
902   to.ToString = ToString;
903 });
904
905 })