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