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.
5 // This files contains runtime support implemented in JavaScript.
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'.
12 // The following declarations are shared with other native JS files.
13 // They are all declared at this one spot to avoid redeclaration errors.
16 var $nonNumberToNumber;
17 var $nonStringToString;
24 var $toPositiveInteger;
28 (function(global, utils) {
30 %CheckIsBootstrapping();
32 var GlobalArray = global.Array;
33 var GlobalBoolean = global.Boolean;
34 var GlobalString = global.String;
35 var GlobalNumber = global.Number;
37 // ----------------------------------------------------------------------------
39 /* -----------------------------------
40 - - - C o m p a r i s o n - - -
41 -----------------------------------
44 // ECMA-262 Section 11.9.3.
46 if (IS_STRING(this) && IS_STRING(y)) return %StringEquals(this, y);
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
57 return %NumberEquals(x, %to_number_fun(y));
59 y = %to_primitive(y, NO_HINT);
61 } else if (IS_STRING(x)) {
63 if (IS_STRING(y)) return %StringEquals(x, y);
64 if (IS_NUMBER(y)) return %NumberEquals(%to_number_fun(x), y);
66 return %NumberEquals(%to_number_fun(x), %to_number_fun(y));
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);
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);
80 return %NumberEquals(%to_number_fun(x), %to_number_fun(y));
82 if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal
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);
93 if (IS_SPEC_OBJECT(y)) return %_ObjectEquals(x, y) ? 0 : 1;
94 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal
96 y = %to_number_fun(y);
97 } else if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) {
98 return 1; // not equal
100 x = %to_primitive(x, NO_HINT);
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) {
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;
116 } else if (IS_NUMBER(this)) {
117 if (IS_NUMBER(x)) return %NumberCompare(this, x, ncr);
118 if (IS_UNDEFINED(x)) return ncr;
120 } else if (IS_UNDEFINED(this)) {
121 if (!IS_UNDEFINED(x)) {
122 %to_primitive(x, NUMBER_HINT);
125 } else if (IS_UNDEFINED(x)) {
126 %to_primitive(this, NUMBER_HINT);
129 left = %to_primitive(this, NUMBER_HINT);
132 right = %to_primitive(x, NUMBER_HINT);
133 if (IS_STRING(left) && IS_STRING(right)) {
134 return %_StringCompare(left, right);
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);
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);
148 throw %make_type_error(kStrongImplicitConversion);
153 /* -----------------------------------
154 - - - A r i t h m e t i c - - -
155 -----------------------------------
158 // ECMA-262, section 11.6.1, page 50.
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);
164 // Default implementation.
165 var a = %to_primitive(this, NO_HINT);
166 var b = %to_primitive(x, NO_HINT);
169 return %_StringAdd(a, %to_string_fun(b));
170 } else if (IS_STRING(b)) {
171 return %_StringAdd(%non_string_to_string(a), b);
173 return %NumberAdd(%to_number_fun(a), %to_number_fun(b));
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);
183 throw %make_type_error(kStrongImplicitConversion);
187 // Left operand (this) is already a string.
188 function STRING_ADD_LEFT(y) {
190 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) {
194 ? %_NumberToString(y)
195 : %to_string_fun(%to_primitive(y, NO_HINT));
198 return %_StringAdd(this, y);
202 // Right operand (y) is already a string.
203 function STRING_ADD_RIGHT(y) {
206 if (IS_STRING_WRAPPER(x) && %_IsStringWrapperSafeForDefaultValueOf(x)) {
210 ? %_NumberToString(x)
211 : %to_string_fun(%to_primitive(x, NO_HINT));
214 return %_StringAdd(x, y);
218 // ECMA-262, section 11.6.2, page 50.
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);
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);
231 throw %make_type_error(kStrongImplicitConversion);
235 // ECMA-262, section 11.5.1, page 48.
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);
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);
248 throw %make_type_error(kStrongImplicitConversion);
252 // ECMA-262, section 11.5.2, page 49.
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);
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);
265 throw %make_type_error(kStrongImplicitConversion);
269 // ECMA-262, section 11.5.3, page 49.
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);
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);
282 throw %make_type_error(kStrongImplicitConversion);
286 /* -------------------------------------------
287 - - - B i t o p e r a t i o n s - - -
288 -------------------------------------------
291 // ECMA-262, section 11.10, page 57.
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);
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);
304 throw %make_type_error(kStrongImplicitConversion);
308 // ECMA-262, section 11.10, page 57.
309 function BIT_AND(y) {
311 if (IS_NUMBER(this)) {
313 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
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;
326 return %NumberAnd(x, y);
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);
335 throw %make_type_error(kStrongImplicitConversion);
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);
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);
352 throw %make_type_error(kStrongImplicitConversion);
356 // ECMA-262, section 11.7.1, page 51.
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);
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);
369 throw %make_type_error(kStrongImplicitConversion);
373 // ECMA-262, section 11.7.2, page 51.
376 if (IS_NUMBER(this)) {
378 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
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;
391 return %NumberSar(x, y);
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);
400 throw %make_type_error(kStrongImplicitConversion);
404 // ECMA-262, section 11.7.3, page 52.
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);
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);
417 throw %make_type_error(kStrongImplicitConversion);
421 /* -----------------------------
422 - - - H e l p e r s - - -
423 -----------------------------
426 // ECMA-262, section 11.8.7, page 54.
428 if (!IS_SPEC_OBJECT(x)) {
429 throw %make_type_error(kInvalidInOperatorUse, this, x);
431 if (%_IsNonNegativeSmi(this)) {
432 if (IS_ARRAY(x) && %_HasFastPackedElements(x)) {
433 return this < x.length;
435 return %HasElement(x, this);
437 return %HasProperty(x, %to_name(this));
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);
448 return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
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);
459 return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
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);
471 function CALL_FUNCTION_PROXY_AS_CONSTRUCTOR () {
473 var trap = %GetConstructTrap(proxy);
474 return %Apply(trap, this, arguments, 0, %_ArgumentsLength());
478 function APPLY_PREPARE(args) {
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)) {
491 length = (args == null) ? 0 : TO_UINT32(args.length);
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);
498 if (!IS_SPEC_FUNCTION(this)) {
499 throw %make_type_error(kApplyNonFunction, %to_string_fun(this), typeof this);
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");
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.
513 function REFLECT_APPLY_PREPARE(args) {
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)) {
526 if (!IS_SPEC_FUNCTION(this)) {
527 throw %make_type_error(kCalledNonCallable, %to_string_fun(this));
530 if (!IS_SPEC_OBJECT(args)) {
531 throw %make_type_error(kWrongArgs, "Reflect.apply");
534 length = %to_length_fun(args.length);
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);
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.
547 function REFLECT_CONSTRUCT_PREPARE(
550 var ctorOk = IS_SPEC_FUNCTION(this) && %IsConstructor(this);
551 var newTargetOk = IS_SPEC_FUNCTION(newTarget) && %IsConstructor(newTarget);
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) {
565 if (!IS_SPEC_FUNCTION(this)) {
566 throw %make_type_error(kCalledNonCallable, %to_string_fun(this));
568 throw %make_type_error(kNotConstructor, %to_string_fun(this));
573 if (!IS_SPEC_FUNCTION(newTarget)) {
574 throw %make_type_error(kCalledNonCallable, %to_string_fun(newTarget));
576 throw %make_type_error(kNotConstructor, %to_string_fun(newTarget));
580 if (!IS_SPEC_OBJECT(args)) {
581 throw %make_type_error(kWrongArgs, "Reflect.construct");
584 length = %to_length_fun(args.length);
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);
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.
597 function CONCAT_ITERABLE_TO_ARRAY(iterable) {
598 return %concat_iterable_to_array(this, iterable);
602 function STACK_OVERFLOW(length) {
603 throw %make_range_error(kStackOverflow);
607 // Convert the receiver to a number - forward to ToNumber.
608 function TO_NUMBER() {
609 return %to_number_fun(this);
613 // Convert the receiver to a string - forward to ToString.
614 function TO_STRING() {
615 return %to_string_fun(this);
619 // Convert the receiver to a string or symbol - forward to ToName.
621 return %to_name(this);
625 /* -------------------------------------
626 - - - C o n v e r s i o n s - - -
627 -------------------------------------
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);
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));
649 // ECMA-262, section 9.3, page 31.
650 function ToNumber(x) {
651 if (IS_NUMBER(x)) return x;
653 return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x)
654 : %StringToNumber(x);
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));
662 function NonNumberToNumber(x) {
664 return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x)
665 : %StringToNumber(x);
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));
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));
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));
695 return IS_SYMBOL(x) ? x : ToString(x);
699 // ECMA-262, section 9.4, page 34.
700 function ToInteger(x) {
701 if (%_IsSmi(x)) return x;
702 return %NumberToInteger(ToNumber(x));
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;
716 function SameValue(x, y) {
717 if (typeof x != typeof y) return false;
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)) {
725 if (IS_SIMD_VALUE(x)) return %SimdSameValue(x, y);
730 // ES6, section 7.2.4
731 function SameValueZero(x, y) {
732 if (typeof x != typeof y) return false;
734 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
736 if (IS_SIMD_VALUE(x)) return %SimdSameValueZero(x, y);
741 function ConcatIterableToArray(target, iterable) {
742 var index = target.length;
743 for (var element of iterable) {
744 %AddElement(target, index++, element);
750 /* ---------------------------------
751 - - - U t i l i t i e s - - -
752 ---------------------------------
755 // Returns if the given x is a primitive value - not an object or a
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);
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);
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;
783 var toString = x.toString;
784 if (IS_SPEC_FUNCTION(toString)) {
785 var s = %_CallFunction(x, toString);
786 if (IsPrimitive(s)) return s;
788 throw MakeTypeError(kCannotConvertToPrimitive);
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;
801 var valueOf = x.valueOf;
802 if (IS_SPEC_FUNCTION(valueOf)) {
803 var v = %_CallFunction(x, valueOf);
804 if (IsPrimitive(v)) return v;
807 throw MakeTypeError(kCannotConvertToPrimitive);
810 function ToPositiveInteger(x, rangeErrorIndex) {
811 var i = TO_INTEGER_MAP_MINUS_ZERO(x);
812 if (i < 0) throw MakeRangeError(rangeErrorIndex);
816 //----------------------------------------------------------------------------
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));
825 // ----------------------------------------------------------------------------
828 $defaultString = DefaultString;
829 $NaN = %GetRootNaN();
830 $nonNumberToNumber = NonNumberToNumber;
831 $nonStringToString = NonStringToString;
832 $sameValue = SameValue;
833 $sameValueZero = SameValueZero;
834 $toInteger = ToInteger;
835 $toLength = ToLength;
837 $toNumber = ToNumber;
838 $toPositiveInteger = ToPositiveInteger;
839 $toPrimitive = ToPrimitive;
840 $toString = ToString;
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,
860 "div_strong_builtin", DIV_STRONG,
861 "equals_builtin", EQUALS,
864 "mod_strong_builtin", MOD_STRONG,
866 "mul_strong_builtin", MUL_STRONG,
867 "reflect_apply_prepare_builtin", REFLECT_APPLY_PREPARE,
868 "reflect_construct_prepare_builtin", REFLECT_CONSTRUCT_PREPARE,
870 "sar_strong_builtin", SAR_STRONG,
872 "shl_strong_builtin", SHL_STRONG,
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,
879 "sub_strong_builtin", SUB_STRONG,
880 "to_name_builtin", TO_NAME,
881 "to_string_builtin", TO_STRING,
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,
891 "to_number_fun", ToNumber,
892 "to_primitive", ToPrimitive,
893 "to_string_fun", ToString,
896 utils.Export(function(to) {
897 to.ToBoolean = ToBoolean;
898 to.ToLength = ToLength;
900 to.ToNumber = ToNumber;
901 to.ToPrimitive = ToPrimitive;
902 to.ToString = ToString;