OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 (function(global, utils, extrasUtils) { | 5 (function(global, utils, extrasUtils) { |
6 | 6 |
7 "use strict"; | 7 "use strict"; |
8 | 8 |
9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
10 | 10 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
67 var result = ObjectDefineProperty(array, i, { | 67 var result = ObjectDefineProperty(array, i, { |
68 value: value, writable: true, configurable: true, enumerable: true | 68 value: value, writable: true, configurable: true, enumerable: true |
69 }); | 69 }); |
70 if (!result) throw MakeTypeError(kStrictCannotAssign, i); | 70 if (!result) throw MakeTypeError(kStrictCannotAssign, i); |
71 } else { | 71 } else { |
72 AddIndexedProperty(array, i, value); | 72 AddIndexedProperty(array, i, value); |
73 } | 73 } |
74 } | 74 } |
75 | 75 |
76 | 76 |
77 // Global list of arrays visited during toString, toLocaleString and | |
78 // join invocations. | |
79 var visited_arrays = new InternalArray(); | |
80 | |
81 | |
82 // Gets a sorted array of array keys. Useful for operations on sparse | 77 // Gets a sorted array of array keys. Useful for operations on sparse |
83 // arrays. Dupes have not been removed. | 78 // arrays. Dupes have not been removed. |
84 function GetSortedArrayKeys(array, indices) { | 79 function GetSortedArrayKeys(array, indices) { |
85 var keys = new InternalArray(); | 80 var keys = new InternalArray(); |
86 if (IS_NUMBER(indices)) { | 81 if (IS_NUMBER(indices)) { |
87 // It's an interval | 82 // It's an interval |
88 var limit = indices; | 83 var limit = indices; |
89 for (var i = 0; i < limit; ++i) { | 84 for (var i = 0; i < limit; ++i) { |
90 var e = array[i]; | 85 var e = array[i]; |
91 if (!IS_UNDEFINED(e) || i in array) { | 86 if (!IS_UNDEFINED(e) || i in array) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 var e = array[key]; | 138 var e = array[key]; |
144 if (!IS_STRING(e)) e = convert(e); | 139 if (!IS_STRING(e)) e = convert(e); |
145 elements[elements_length++] = e; | 140 elements[elements_length++] = e; |
146 last_key = key; | 141 last_key = key; |
147 } | 142 } |
148 } | 143 } |
149 return %StringBuilderConcat(elements, elements_length, ''); | 144 return %StringBuilderConcat(elements, elements_length, ''); |
150 } | 145 } |
151 | 146 |
152 | 147 |
148 function StringBuilderJoin(elements, length, separator) { | |
149 length = MinSimple(elements.length, length); | |
150 if (length == 0) return ""; | |
151 var result = elements[0]; | |
152 for (var i = 1; i < length; i++) { | |
153 result = result + separator + elements[i]; | |
154 } | |
155 return result; | |
156 } | |
157 | |
158 | |
153 function UseSparseVariant(array, length, is_array, touched) { | 159 function UseSparseVariant(array, length, is_array, touched) { |
154 // Only use the sparse variant on arrays that are likely to be sparse and the | 160 // Only use the sparse variant on arrays that are likely to be sparse and the |
155 // number of elements touched in the operation is relatively small compared to | 161 // number of elements touched in the operation is relatively small compared to |
156 // the overall size of the array. | 162 // the overall size of the array. |
157 if (!is_array || length < 1000 || %IsObserved(array) || | 163 if (!is_array || length < 1000 || %IsObserved(array) || |
158 %HasComplexElements(array)) { | 164 %HasComplexElements(array)) { |
159 return false; | 165 return false; |
160 } | 166 } |
161 if (!%_IsSmi(length)) { | 167 if (!%_IsSmi(length)) { |
162 return true; | 168 return true; |
163 } | 169 } |
164 var elements_threshold = length >> 2; // No more than 75% holes | 170 var elements_threshold = length >> 2; // No more than 75% holes |
165 var estimated_elements = %EstimateNumberOfElements(array); | 171 var estimated_elements = %EstimateNumberOfElements(array); |
166 return (estimated_elements < elements_threshold) && | 172 return (estimated_elements < elements_threshold) && |
167 (touched > estimated_elements * 4); | 173 (touched > estimated_elements * 4); |
168 } | 174 } |
169 | 175 |
176 function Stack() { | |
177 this.length = 0; | |
178 this.values = new InternalArray(); | |
179 } | |
180 | |
181 Stack.prototype.length = null; | |
adamk
2016/03/10 19:53:54
Please add a comment noting that these are to mask
| |
182 Stack.prototype.values = null; | |
183 | |
184 function StackPush(stack, value) { | |
185 stack.values[stack.length++] = value; | |
186 } | |
187 | |
188 function StackPop(stack) { | |
189 stack.values[--stack.length] = null | |
190 } | |
191 | |
192 function StackHas(stack, v) { | |
193 var length = stack.length; | |
194 var values = stack.values; | |
195 for (var i = 0; i < length; i++) { | |
196 if (values[i] === v) return true; | |
197 } | |
198 return false; | |
199 } | |
200 | |
201 // Global list of arrays visited during toString, toLocaleString and | |
202 // join invocations. | |
203 var visited_arrays = new Stack(); | |
170 | 204 |
171 function Join(array, length, separator, convert) { | 205 function Join(array, length, separator, convert) { |
172 if (length == 0) return ''; | 206 if (length == 0) return ''; |
173 | 207 |
174 var is_array = IS_ARRAY(array); | 208 var is_array = IS_ARRAY(array); |
175 | 209 |
176 if (is_array) { | 210 if (is_array) { |
177 // If the array is cyclic, return the empty string for already | 211 // If the array is cyclic, return the empty string for already |
178 // visited arrays. | 212 // visited arrays. |
179 if (!%PushIfAbsent(visited_arrays, array)) return ''; | 213 if (StackHas(visited_arrays, array)) return ''; |
214 StackPush(visited_arrays, array); | |
180 } | 215 } |
181 | 216 |
182 // Attempt to convert the elements. | 217 // Attempt to convert the elements. |
183 try { | 218 try { |
184 if (UseSparseVariant(array, length, is_array, length)) { | 219 if (UseSparseVariant(array, length, is_array, length)) { |
185 %NormalizeElements(array); | 220 %NormalizeElements(array); |
186 if (separator.length == 0) { | 221 if (separator.length == 0) { |
187 return SparseJoin(array, length, convert); | 222 return SparseJoin(array, length, convert); |
188 } else { | 223 } else { |
189 return SparseJoinWithSeparatorJS(array, length, convert, separator); | 224 return SparseJoinWithSeparatorJS(array, length, convert, separator); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 for (var i = 1; i < length; i++) { | 263 for (var i = 1; i < length; i++) { |
229 e = array[i]; | 264 e = array[i]; |
230 if (IS_NUMBER(e)) { | 265 if (IS_NUMBER(e)) { |
231 e = %_NumberToString(e); | 266 e = %_NumberToString(e); |
232 } else if (!IS_STRING(e)) { | 267 } else if (!IS_STRING(e)) { |
233 e = convert(e); | 268 e = convert(e); |
234 } | 269 } |
235 elements[i] = e; | 270 elements[i] = e; |
236 } | 271 } |
237 } | 272 } |
238 return %StringBuilderJoin(elements, length, separator); | 273 return StringBuilderJoin(elements, length, separator); |
239 } finally { | 274 } finally { |
240 // Make sure to remove the last element of the visited array no | 275 // Make sure to remove the last element of the visited array no |
241 // matter what happens. | 276 // matter what happens. |
242 if (is_array) visited_arrays.length = visited_arrays.length - 1; | 277 if (is_array) StackPop(visited_arrays); |
243 } | 278 } |
244 } | 279 } |
245 | 280 |
246 | 281 |
247 function ConvertToString(x) { | 282 function ConvertToString(x) { |
248 if (IS_NULL_OR_UNDEFINED(x)) { | 283 if (IS_NULL_OR_UNDEFINED(x)) { |
249 return ''; | 284 return ''; |
250 } else { | 285 } else { |
251 return TO_STRING(x); | 286 return TO_STRING(x); |
252 } | 287 } |
(...skipping 1699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1952 to.InnerArrayIncludes = InnerArrayIncludes; | 1987 to.InnerArrayIncludes = InnerArrayIncludes; |
1953 to.InnerArrayIndexOf = InnerArrayIndexOf; | 1988 to.InnerArrayIndexOf = InnerArrayIndexOf; |
1954 to.InnerArrayJoin = InnerArrayJoin; | 1989 to.InnerArrayJoin = InnerArrayJoin; |
1955 to.InnerArrayLastIndexOf = InnerArrayLastIndexOf; | 1990 to.InnerArrayLastIndexOf = InnerArrayLastIndexOf; |
1956 to.InnerArrayReduce = InnerArrayReduce; | 1991 to.InnerArrayReduce = InnerArrayReduce; |
1957 to.InnerArrayReduceRight = InnerArrayReduceRight; | 1992 to.InnerArrayReduceRight = InnerArrayReduceRight; |
1958 to.InnerArraySome = InnerArraySome; | 1993 to.InnerArraySome = InnerArraySome; |
1959 to.InnerArraySort = InnerArraySort; | 1994 to.InnerArraySort = InnerArraySort; |
1960 to.InnerArrayToLocaleString = InnerArrayToLocaleString; | 1995 to.InnerArrayToLocaleString = InnerArrayToLocaleString; |
1961 to.PackedArrayReverse = PackedArrayReverse; | 1996 to.PackedArrayReverse = PackedArrayReverse; |
1997 to.Stack = Stack; | |
1998 to.StackHas = StackHas; | |
1999 to.StackPush = StackPush; | |
2000 to.StackPop = StackPop; | |
1962 }); | 2001 }); |
1963 | 2002 |
1964 %InstallToContext([ | 2003 %InstallToContext([ |
1965 "array_pop", ArrayPop, | 2004 "array_pop", ArrayPop, |
1966 "array_push", ArrayPush, | 2005 "array_push", ArrayPush, |
1967 "array_shift", ArrayShift, | 2006 "array_shift", ArrayShift, |
1968 "array_splice", ArraySplice, | 2007 "array_splice", ArraySplice, |
1969 "array_slice", ArraySlice, | 2008 "array_slice", ArraySlice, |
1970 "array_unshift", ArrayUnshift, | 2009 "array_unshift", ArrayUnshift, |
1971 ]); | 2010 ]); |
1972 | 2011 |
1973 }); | 2012 }); |
OLD | NEW |