OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 keys.push(key); | 60 keys.push(key); |
61 } | 61 } |
62 } | 62 } |
63 } | 63 } |
64 } | 64 } |
65 keys.sort(function(a, b) { return a - b; }); | 65 keys.sort(function(a, b) { return a - b; }); |
66 return keys; | 66 return keys; |
67 } | 67 } |
68 | 68 |
69 | 69 |
| 70 function SparseJoinWithSeparator(array, len, convert, separator) { |
| 71 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); |
| 72 var totalLength = 0; |
| 73 var elements = new InternalArray(keys.length * 2); |
| 74 var previousKey = -1; |
| 75 for (var i = 0; i < keys.length; i++) { |
| 76 var key = keys[i]; |
| 77 if (key != previousKey) { // keys may contain duplicates. |
| 78 var e = array[key]; |
| 79 if (!IS_STRING(e)) e = convert(e); |
| 80 elements[i * 2] = key; |
| 81 elements[i * 2 + 1] = e; |
| 82 previousKey = key; |
| 83 } |
| 84 } |
| 85 return %SparseJoinWithSeparator(elements, len, separator); |
| 86 } |
| 87 |
| 88 |
70 // Optimized for sparse arrays if separator is ''. | 89 // Optimized for sparse arrays if separator is ''. |
71 function SparseJoin(array, len, convert) { | 90 function SparseJoin(array, len, convert) { |
72 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); | 91 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); |
73 var last_key = -1; | 92 var last_key = -1; |
74 var keys_length = keys.length; | 93 var keys_length = keys.length; |
75 | 94 |
76 var elements = new InternalArray(keys_length); | 95 var elements = new InternalArray(keys_length); |
77 var elements_length = 0; | 96 var elements_length = 0; |
78 | 97 |
79 for (var i = 0; i < keys_length; i++) { | 98 for (var i = 0; i < keys_length; i++) { |
(...skipping 23 matching lines...) Expand all Loading... |
103 var is_array = IS_ARRAY(array); | 122 var is_array = IS_ARRAY(array); |
104 | 123 |
105 if (is_array) { | 124 if (is_array) { |
106 // If the array is cyclic, return the empty string for already | 125 // If the array is cyclic, return the empty string for already |
107 // visited arrays. | 126 // visited arrays. |
108 if (!%PushIfAbsent(visited_arrays, array)) return ''; | 127 if (!%PushIfAbsent(visited_arrays, array)) return ''; |
109 } | 128 } |
110 | 129 |
111 // Attempt to convert the elements. | 130 // Attempt to convert the elements. |
112 try { | 131 try { |
113 if (UseSparseVariant(array, length, is_array) && (separator.length == 0)) { | 132 if (UseSparseVariant(array, length, is_array)) { |
114 return SparseJoin(array, length, convert); | 133 if (separator.length == 0) { |
| 134 return SparseJoin(array, length, convert); |
| 135 } else { |
| 136 return SparseJoinWithSeparator(array, length, convert, separator); |
| 137 } |
115 } | 138 } |
116 | 139 |
117 // Fast case for one-element arrays. | 140 // Fast case for one-element arrays. |
118 if (length == 1) { | 141 if (length == 1) { |
119 var e = array[0]; | 142 var e = array[0]; |
120 if (IS_STRING(e)) return e; | 143 if (IS_STRING(e)) return e; |
121 return convert(e); | 144 return convert(e); |
122 } | 145 } |
123 | 146 |
124 // Construct an array for the elements. | 147 // Construct an array for the elements. |
125 var elements = new InternalArray(length); | 148 var elements = new InternalArray(length); |
126 | 149 |
127 // We pull the empty separator check outside the loop for speed! | 150 // We pull the empty separator check outside the loop for speed! |
128 if (separator.length == 0) { | 151 if (separator.length == 0) { |
129 var elements_length = 0; | 152 var elements_length = 0; |
130 for (var i = 0; i < length; i++) { | 153 for (var i = 0; i < length; i++) { |
131 var e = array[i]; | 154 var e = array[i]; |
132 if (!IS_UNDEFINED(e)) { | 155 if (!IS_STRING(e)) e = convert(e); |
133 if (!IS_STRING(e)) e = convert(e); | 156 elements[elements_length++] = e; |
134 elements[elements_length++] = e; | |
135 } | |
136 } | 157 } |
137 elements.length = elements_length; | 158 elements.length = elements_length; |
138 var result = %_FastAsciiArrayJoin(elements, ''); | 159 var result = %_FastAsciiArrayJoin(elements, ''); |
139 if (!IS_UNDEFINED(result)) return result; | 160 if (!IS_UNDEFINED(result)) return result; |
140 return %StringBuilderConcat(elements, elements_length, ''); | 161 return %StringBuilderConcat(elements, elements_length, ''); |
141 } | 162 } |
142 // Non-empty separator case. | 163 // Non-empty separator case. |
143 // If the first element is a number then use the heuristic that the | 164 // If the first element is a number then use the heuristic that the |
144 // remaining elements are also likely to be numbers. | 165 // remaining elements are also likely to be numbers. |
145 if (!IS_NUMBER(array[0])) { | 166 if (!IS_NUMBER(array[0])) { |
146 for (var i = 0; i < length; i++) { | 167 for (var i = 0; i < length; i++) { |
147 var e = array[i]; | 168 var e = array[i]; |
148 if (!IS_STRING(e)) e = convert(e); | 169 if (!IS_STRING(e)) e = convert(e); |
149 elements[i] = e; | 170 elements[i] = e; |
150 } | 171 } |
151 } else { | 172 } else { |
152 for (var i = 0; i < length; i++) { | 173 for (var i = 0; i < length; i++) { |
153 var e = array[i]; | 174 var e = array[i]; |
154 if (IS_NUMBER(e)) elements[i] = %_NumberToString(e); | 175 if (IS_NUMBER(e)) { |
155 else { | 176 e = %_NumberToString(e); |
156 if (!IS_STRING(e)) e = convert(e); | 177 } else if (!IS_STRING(e)) { |
| 178 e = convert(e); |
| 179 } |
157 elements[i] = e; | 180 elements[i] = e; |
158 } | |
159 } | 181 } |
160 } | 182 } |
161 var result = %_FastAsciiArrayJoin(elements, separator); | 183 var result = %_FastAsciiArrayJoin(elements, separator); |
162 if (!IS_UNDEFINED(result)) return result; | 184 if (!IS_UNDEFINED(result)) return result; |
163 | 185 |
164 return %StringBuilderJoin(elements, length, separator); | 186 return %StringBuilderJoin(elements, length, separator); |
165 } finally { | 187 } finally { |
166 // Make sure to remove the last element of the visited array no | 188 // Make sure to remove the last element of the visited array no |
167 // matter what happens. | 189 // matter what happens. |
168 if (is_array) visited_arrays.length = visited_arrays.length - 1; | 190 if (is_array) visited_arrays.length = visited_arrays.length - 1; |
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 InternalArray.prototype.join = getFunction("join", ArrayJoin); | 1262 InternalArray.prototype.join = getFunction("join", ArrayJoin); |
1241 InternalArray.prototype.pop = getFunction("pop", ArrayPop); | 1263 InternalArray.prototype.pop = getFunction("pop", ArrayPop); |
1242 InternalArray.prototype.push = getFunction("push", ArrayPush); | 1264 InternalArray.prototype.push = getFunction("push", ArrayPush); |
1243 InternalArray.prototype.toString = function() { | 1265 InternalArray.prototype.toString = function() { |
1244 return "Internal Array, length " + this.length; | 1266 return "Internal Array, length " + this.length; |
1245 }; | 1267 }; |
1246 } | 1268 } |
1247 | 1269 |
1248 | 1270 |
1249 SetupArray(); | 1271 SetupArray(); |
OLD | NEW |