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 |