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 15(function(global, utils) { 16 17%CheckIsBootstrapping(); 18 19var FLAG_harmony_species; 20var GlobalArray = global.Array; 21var GlobalBoolean = global.Boolean; 22var GlobalString = global.String; 23var MakeRangeError; 24var MakeTypeError; 25var speciesSymbol; 26 27utils.Import(function(from) { 28 MakeRangeError = from.MakeRangeError; 29 MakeTypeError = from.MakeTypeError; 30 speciesSymbol = from.species_symbol; 31}); 32 33utils.ImportFromExperimental(function(from) { 34 FLAG_harmony_species = from.FLAG_harmony_species; 35}); 36 37// ---------------------------------------------------------------------------- 38 39/* ----------------------------- 40 - - - H e l p e r s - - - 41 ----------------------------- 42*/ 43 44function CONCAT_ITERABLE_TO_ARRAY(iterable) { 45 return %concat_iterable_to_array(this, iterable); 46}; 47 48 49/* ------------------------------------- 50 - - - C o n v e r s i o n s - - - 51 ------------------------------------- 52*/ 53 54// ES5, section 9.12 55function SameValue(x, y) { 56 if (typeof x != typeof y) return false; 57 if (IS_NUMBER(x)) { 58 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; 59 // x is +0 and y is -0 or vice versa. 60 if (x === 0 && y === 0 && %_IsMinusZero(x) != %_IsMinusZero(y)) { 61 return false; 62 } 63 } 64 if (IS_SIMD_VALUE(x)) return %SimdSameValue(x, y); 65 return x === y; 66} 67 68 69// ES6, section 7.2.4 70function SameValueZero(x, y) { 71 if (typeof x != typeof y) return false; 72 if (IS_NUMBER(x)) { 73 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; 74 } 75 if (IS_SIMD_VALUE(x)) return %SimdSameValueZero(x, y); 76 return x === y; 77} 78 79 80function ConcatIterableToArray(target, iterable) { 81 var index = target.length; 82 for (var element of iterable) { 83 AddIndexedProperty(target, index++, element); 84 } 85 return target; 86} 87 88 89/* --------------------------------- 90 - - - U t i l i t i e s - - - 91 --------------------------------- 92*/ 93 94 95// This function should be called rather than %AddElement in contexts where the 96// argument might not be less than 2**32-1. ES2015 ToLength semantics mean that 97// this is a concern at basically all callsites. 98function AddIndexedProperty(obj, index, value) { 99 if (index === TO_UINT32(index) && index !== kMaxUint32) { 100 %AddElement(obj, index, value); 101 } else { 102 %AddNamedProperty(obj, TO_STRING(index), value, NONE); 103 } 104} 105%SetForceInlineFlag(AddIndexedProperty); 106 107 108function ToPositiveInteger(x, rangeErrorIndex) { 109 var i = TO_INTEGER_MAP_MINUS_ZERO(x); 110 if (i < 0) throw MakeRangeError(rangeErrorIndex); 111 return i; 112} 113 114 115function MaxSimple(a, b) { 116 return a > b ? a : b; 117} 118 119 120function MinSimple(a, b) { 121 return a > b ? b : a; 122} 123 124 125%SetForceInlineFlag(MaxSimple); 126%SetForceInlineFlag(MinSimple); 127 128 129// ES2015 7.3.20 130// For the fallback with --harmony-species off, there are two possible choices: 131// - "conservative": return defaultConstructor 132// - "not conservative": return object.constructor 133// This fallback path is only needed in the transition to ES2015, and the 134// choice is made simply to preserve the previous behavior so that we don't 135// have a three-step upgrade: old behavior, unspecified intermediate behavior, 136// and ES2015. 137// In some cases, we were "conservative" (e.g., ArrayBuffer, RegExp), and in 138// other cases we were "not conservative (e.g., TypedArray, Promise). 139function SpeciesConstructor(object, defaultConstructor, conservative) { 140 if (FLAG_harmony_species) { 141 var constructor = object.constructor; 142 if (IS_UNDEFINED(constructor)) { 143 return defaultConstructor; 144 } 145 if (!IS_RECEIVER(constructor)) { 146 throw MakeTypeError(kConstructorNotReceiver); 147 } 148 var species = constructor[speciesSymbol]; 149 if (IS_NULL_OR_UNDEFINED(species)) { 150 return defaultConstructor; 151 } 152 if (%IsConstructor(species)) { 153 return species; 154 } 155 throw MakeTypeError(kSpeciesNotConstructor); 156 } else { 157 return conservative ? defaultConstructor : object.constructor; 158 } 159} 160 161//---------------------------------------------------------------------------- 162 163// NOTE: Setting the prototype for Array must take place as early as 164// possible due to code generation for array literals. When 165// generating code for a array literal a boilerplate array is created 166// that is cloned when running the code. It is essential that the 167// boilerplate gets the right prototype. 168%FunctionSetPrototype(GlobalArray, new GlobalArray(0)); 169 170// ---------------------------------------------------------------------------- 171// Exports 172 173utils.Export(function(to) { 174 to.AddIndexedProperty = AddIndexedProperty; 175 to.MaxSimple = MaxSimple; 176 to.MinSimple = MinSimple; 177 to.SameValue = SameValue; 178 to.SameValueZero = SameValueZero; 179 to.ToPositiveInteger = ToPositiveInteger; 180 to.SpeciesConstructor = SpeciesConstructor; 181}); 182 183%InstallToContext([ 184 "concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY, 185]); 186 187%InstallToContext([ 188 "concat_iterable_to_array", ConcatIterableToArray, 189]); 190 191}) 192