Chromium Code Reviews| 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 #include "src/builtins.h" | 5 #include "src/builtins.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
| 9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
| (...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 874 case SLOW_STRING_WRAPPER_ELEMENTS: | 874 case SLOW_STRING_WRAPPER_ELEMENTS: |
| 875 UNREACHABLE(); | 875 UNREACHABLE(); |
| 876 return 0; | 876 return 0; |
| 877 } | 877 } |
| 878 // As an estimate, we assume that the prototype doesn't contain any | 878 // As an estimate, we assume that the prototype doesn't contain any |
| 879 // inherited elements. | 879 // inherited elements. |
| 880 return element_count; | 880 return element_count; |
| 881 } | 881 } |
| 882 | 882 |
| 883 | 883 |
| 884 template <class ExternalArrayClass, class ElementType> | |
| 885 bool IterateTypedArrayElements(Isolate* isolate, Handle<JSObject> receiver, | |
| 886 bool elements_are_ints, | |
| 887 bool elements_are_guaranteed_smis, | |
| 888 ArrayConcatVisitor* visitor) { | |
| 889 Handle<ExternalArrayClass> array( | |
| 890 ExternalArrayClass::cast(receiver->elements())); | |
| 891 uint32_t len = static_cast<uint32_t>(array->length()); | |
| 892 | |
| 893 DCHECK(visitor != NULL); | |
| 894 if (elements_are_ints) { | |
| 895 if (elements_are_guaranteed_smis) { | |
| 896 for (uint32_t j = 0; j < len; j++) { | |
| 897 HandleScope loop_scope(isolate); | |
| 898 Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))), | |
| 899 isolate); | |
| 900 if (!visitor->visit(j, e)) return false; | |
| 901 } | |
| 902 } else { | |
| 903 for (uint32_t j = 0; j < len; j++) { | |
| 904 HandleScope loop_scope(isolate); | |
| 905 int64_t val = static_cast<int64_t>(array->get_scalar(j)); | |
| 906 if (Smi::IsValid(static_cast<intptr_t>(val))) { | |
| 907 Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate); | |
| 908 if (!visitor->visit(j, e)) return false; | |
| 909 } else { | |
| 910 Handle<Object> e = | |
| 911 isolate->factory()->NewNumber(static_cast<ElementType>(val)); | |
| 912 if (!visitor->visit(j, e)) return false; | |
| 913 } | |
| 914 } | |
| 915 } | |
| 916 } else { | |
| 917 for (uint32_t j = 0; j < len; j++) { | |
| 918 HandleScope loop_scope(isolate); | |
| 919 Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j)); | |
| 920 if (!visitor->visit(j, e)) return false; | |
| 921 } | |
| 922 } | |
| 923 return true; | |
| 924 } | |
| 925 | |
| 926 | |
| 927 // Used for sorting indices in a List<uint32_t>. | 884 // Used for sorting indices in a List<uint32_t>. |
| 928 int compareUInt32(const uint32_t* ap, const uint32_t* bp) { | 885 int compareUInt32(const uint32_t* ap, const uint32_t* bp) { |
| 929 uint32_t a = *ap; | 886 uint32_t a = *ap; |
| 930 uint32_t b = *bp; | 887 uint32_t b = *bp; |
| 931 return (a == b) ? 0 : (a < b) ? -1 : 1; | 888 return (a == b) ? 0 : (a < b) ? -1 : 1; |
| 932 } | 889 } |
| 933 | 890 |
| 934 | 891 |
| 935 void CollectElementIndices(Handle<JSObject> object, uint32_t range, | 892 void CollectElementIndices(Handle<JSObject> object, uint32_t range, |
| 936 List<uint32_t>* indices) { | 893 List<uint32_t>* indices) { |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1091 isolate, val, Runtime::GetObjectProperty(isolate, receiver, key), | 1048 isolate, val, Runtime::GetObjectProperty(isolate, receiver, key), |
| 1092 false); | 1049 false); |
| 1093 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, val, | 1050 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, val, |
| 1094 Object::ToLength(isolate, val), false); | 1051 Object::ToLength(isolate, val), false); |
| 1095 // TODO(caitp): Support larger element indexes (up to 2^53-1). | 1052 // TODO(caitp): Support larger element indexes (up to 2^53-1). |
| 1096 if (!val->ToUint32(&length)) { | 1053 if (!val->ToUint32(&length)) { |
| 1097 length = 0; | 1054 length = 0; |
| 1098 } | 1055 } |
| 1099 } | 1056 } |
| 1100 | 1057 |
| 1101 if (!(receiver->IsJSArray() || receiver->IsJSTypedArray())) { | 1058 if (!receiver->IsJSArray()) { |
| 1102 // For classes which are not known to be safe to access via elements alone, | 1059 // For classes which are not known to be safe to access via elements alone, |
| 1103 // use the slow case. | 1060 // use the slow case. |
| 1104 return IterateElementsSlow(isolate, receiver, length, visitor); | 1061 return IterateElementsSlow(isolate, receiver, length, visitor); |
| 1105 } | 1062 } |
| 1106 Handle<JSObject> array = Handle<JSObject>::cast(receiver); | 1063 Handle<JSObject> array = Handle<JSObject>::cast(receiver); |
| 1107 | 1064 |
| 1108 switch (array->GetElementsKind()) { | 1065 switch (array->GetElementsKind()) { |
| 1109 case FAST_SMI_ELEMENTS: | 1066 case FAST_SMI_ELEMENTS: |
| 1110 case FAST_ELEMENTS: | 1067 case FAST_ELEMENTS: |
| 1111 case FAST_HOLEY_SMI_ELEMENTS: | 1068 case FAST_HOLEY_SMI_ELEMENTS: |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1165 Handle<Object> element_value; | 1122 Handle<Object> element_value; |
| 1166 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 1123 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 1167 isolate, element_value, Object::GetElement(isolate, array, j), | 1124 isolate, element_value, Object::GetElement(isolate, array, j), |
| 1168 false); | 1125 false); |
| 1169 if (!visitor->visit(j, element_value)) return false; | 1126 if (!visitor->visit(j, element_value)) return false; |
| 1170 } | 1127 } |
| 1171 } | 1128 } |
| 1172 } | 1129 } |
| 1173 break; | 1130 break; |
| 1174 } | 1131 } |
| 1132 | |
| 1175 case DICTIONARY_ELEMENTS: { | 1133 case DICTIONARY_ELEMENTS: { |
| 1176 // CollectElementIndices() can't be called when there's a JSProxy | 1134 // CollectElementIndices() can't be called when there's a JSProxy |
| 1177 // on the prototype chain. | 1135 // on the prototype chain. |
| 1178 for (PrototypeIterator iter(isolate, array); !iter.IsAtEnd(); | 1136 for (PrototypeIterator iter(isolate, array); !iter.IsAtEnd(); |
| 1179 iter.Advance()) { | 1137 iter.Advance()) { |
| 1180 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | 1138 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
| 1181 return IterateElementsSlow(isolate, array, length, visitor); | 1139 return IterateElementsSlow(isolate, array, length, visitor); |
| 1182 } | 1140 } |
| 1183 } | 1141 } |
| 1184 Handle<SeededNumberDictionary> dict(array->element_dictionary()); | 1142 Handle<SeededNumberDictionary> dict(array->element_dictionary()); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1196 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 1154 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 1197 isolate, element, Object::GetElement(isolate, array, index), false); | 1155 isolate, element, Object::GetElement(isolate, array, index), false); |
| 1198 if (!visitor->visit(index, element)) return false; | 1156 if (!visitor->visit(index, element)) return false; |
| 1199 // Skip to next different index (i.e., omit duplicates). | 1157 // Skip to next different index (i.e., omit duplicates). |
| 1200 do { | 1158 do { |
| 1201 j++; | 1159 j++; |
| 1202 } while (j < n && indices[j] == index); | 1160 } while (j < n && indices[j] == index); |
| 1203 } | 1161 } |
| 1204 break; | 1162 break; |
| 1205 } | 1163 } |
| 1206 case UINT8_CLAMPED_ELEMENTS: { | |
| 1207 Handle<FixedUint8ClampedArray> pixels( | |
| 1208 FixedUint8ClampedArray::cast(array->elements())); | |
| 1209 for (uint32_t j = 0; j < length; j++) { | |
| 1210 Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate); | |
| 1211 visitor->visit(j, e); | |
| 1212 } | |
| 1213 break; | |
| 1214 } | |
| 1215 case INT8_ELEMENTS: { | |
| 1216 if (!IterateTypedArrayElements<FixedInt8Array, int8_t>( | |
| 1217 isolate, array, true, true, visitor)) | |
| 1218 return false; | |
| 1219 break; | |
| 1220 } | |
| 1221 case UINT8_ELEMENTS: { | |
| 1222 if (!IterateTypedArrayElements<FixedUint8Array, uint8_t>( | |
| 1223 isolate, array, true, true, visitor)) | |
| 1224 return false; | |
| 1225 break; | |
| 1226 } | |
| 1227 case INT16_ELEMENTS: { | |
| 1228 if (!IterateTypedArrayElements<FixedInt16Array, int16_t>( | |
| 1229 isolate, array, true, true, visitor)) | |
| 1230 return false; | |
| 1231 break; | |
| 1232 } | |
| 1233 case UINT16_ELEMENTS: { | |
| 1234 if (!IterateTypedArrayElements<FixedUint16Array, uint16_t>( | |
| 1235 isolate, array, true, true, visitor)) | |
| 1236 return false; | |
| 1237 break; | |
| 1238 } | |
| 1239 case INT32_ELEMENTS: { | |
| 1240 if (!IterateTypedArrayElements<FixedInt32Array, int32_t>( | |
| 1241 isolate, array, true, false, visitor)) | |
| 1242 return false; | |
| 1243 break; | |
| 1244 } | |
| 1245 case UINT32_ELEMENTS: { | |
| 1246 if (!IterateTypedArrayElements<FixedUint32Array, uint32_t>( | |
| 1247 isolate, array, true, false, visitor)) | |
| 1248 return false; | |
| 1249 break; | |
| 1250 } | |
| 1251 case FLOAT32_ELEMENTS: { | |
| 1252 if (!IterateTypedArrayElements<FixedFloat32Array, float>( | |
| 1253 isolate, array, false, false, visitor)) | |
| 1254 return false; | |
| 1255 break; | |
| 1256 } | |
| 1257 case FLOAT64_ELEMENTS: { | |
| 1258 if (!IterateTypedArrayElements<FixedFloat64Array, double>( | |
| 1259 isolate, array, false, false, visitor)) | |
| 1260 return false; | |
| 1261 break; | |
| 1262 } | |
| 1263 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 1164 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 1264 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { | 1165 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { |
| 1265 for (uint32_t index = 0; index < length; index++) { | 1166 for (uint32_t index = 0; index < length; index++) { |
| 1266 HandleScope loop_scope(isolate); | 1167 HandleScope loop_scope(isolate); |
| 1267 Handle<Object> element; | 1168 Handle<Object> element; |
| 1268 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 1169 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 1269 isolate, element, Object::GetElement(isolate, array, index), false); | 1170 isolate, element, Object::GetElement(isolate, array, index), false); |
| 1270 if (!visitor->visit(index, element)) return false; | 1171 if (!visitor->visit(index, element)) return false; |
| 1271 } | 1172 } |
| 1272 break; | 1173 break; |
| 1273 } | 1174 } |
| 1274 case NO_ELEMENTS: | 1175 case NO_ELEMENTS: |
| 1275 break; | 1176 break; |
| 1177 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS: | |
| 1178 TYPED_ARRAYS(TYPED_ARRAY_CASE) | |
| 1179 #undef TYPED_ARRAY_CASE | |
| 1276 case FAST_STRING_WRAPPER_ELEMENTS: | 1180 case FAST_STRING_WRAPPER_ELEMENTS: |
| 1277 case SLOW_STRING_WRAPPER_ELEMENTS: | 1181 case SLOW_STRING_WRAPPER_ELEMENTS: |
| 1278 // |array| is guaranteed to be an array or typed array. | 1182 // |array| is guaranteed to be an array or typed array. |
|
adamk
2016/02/20 02:39:32
This comment is now out of date.
| |
| 1279 UNREACHABLE(); | 1183 UNREACHABLE(); |
| 1280 break; | 1184 break; |
| 1281 } | 1185 } |
| 1282 visitor->increase_index_offset(length); | 1186 visitor->increase_index_offset(length); |
| 1283 return true; | 1187 return true; |
| 1284 } | 1188 } |
| 1285 | 1189 |
| 1286 | 1190 |
| 1287 bool HasConcatSpreadableModifier(Isolate* isolate, Handle<JSArray> obj) { | 1191 bool HasConcatSpreadableModifier(Isolate* isolate, Handle<JSArray> obj) { |
| 1288 DCHECK(isolate->IsFastArrayConstructorPrototypeChainIntact()); | 1192 DCHECK(isolate->IsFastArrayConstructorPrototypeChainIntact()); |
| (...skipping 3273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4562 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 4466 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
| 4563 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 4467 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 4564 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 4468 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
| 4565 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 4469 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 4566 #undef DEFINE_BUILTIN_ACCESSOR_C | 4470 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 4567 #undef DEFINE_BUILTIN_ACCESSOR_A | 4471 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 4568 | 4472 |
| 4569 | 4473 |
| 4570 } // namespace internal | 4474 } // namespace internal |
| 4571 } // namespace v8 | 4475 } // namespace v8 |
| OLD | NEW |