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 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 } | 447 } |
448 | 448 |
449 Handle<Object> result; | 449 Handle<Object> result; |
450 if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { | 450 if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { |
451 // Fast Elements Path | 451 // Fast Elements Path |
452 result = array->GetElementsAccessor()->Pop(array); | 452 result = array->GetElementsAccessor()->Pop(array); |
453 } else { | 453 } else { |
454 // Use Slow Lookup otherwise | 454 // Use Slow Lookup otherwise |
455 uint32_t new_length = len - 1; | 455 uint32_t new_length = len - 1; |
456 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 456 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
457 isolate, result, Object::GetElement(isolate, array, new_length)); | 457 isolate, result, JSReceiver::GetElement(isolate, array, new_length)); |
458 JSArray::SetLength(array, new_length); | 458 JSArray::SetLength(array, new_length); |
459 } | 459 } |
460 return *result; | 460 return *result; |
461 } | 461 } |
462 | 462 |
463 | 463 |
464 BUILTIN(ArrayShift) { | 464 BUILTIN(ArrayShift) { |
465 HandleScope scope(isolate); | 465 HandleScope scope(isolate); |
466 Heap* heap = isolate->heap(); | 466 Heap* heap = isolate->heap(); |
467 Handle<Object> receiver = args.receiver(); | 467 Handle<Object> receiver = args.receiver(); |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 | 1009 |
1010 | 1010 |
1011 bool IterateElementsSlow(Isolate* isolate, Handle<JSReceiver> receiver, | 1011 bool IterateElementsSlow(Isolate* isolate, Handle<JSReceiver> receiver, |
1012 uint32_t length, ArrayConcatVisitor* visitor) { | 1012 uint32_t length, ArrayConcatVisitor* visitor) { |
1013 for (uint32_t i = 0; i < length; ++i) { | 1013 for (uint32_t i = 0; i < length; ++i) { |
1014 HandleScope loop_scope(isolate); | 1014 HandleScope loop_scope(isolate); |
1015 Maybe<bool> maybe = JSReceiver::HasElement(receiver, i); | 1015 Maybe<bool> maybe = JSReceiver::HasElement(receiver, i); |
1016 if (!maybe.IsJust()) return false; | 1016 if (!maybe.IsJust()) return false; |
1017 if (maybe.FromJust()) { | 1017 if (maybe.FromJust()) { |
1018 Handle<Object> element_value; | 1018 Handle<Object> element_value; |
1019 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_value, | 1019 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
1020 Object::GetElement(isolate, receiver, i), | 1020 isolate, element_value, JSReceiver::GetElement(isolate, receiver, i), |
1021 false); | 1021 false); |
1022 if (!visitor->visit(i, element_value)) return false; | 1022 if (!visitor->visit(i, element_value)) return false; |
1023 } | 1023 } |
1024 } | 1024 } |
1025 visitor->increase_index_offset(length); | 1025 visitor->increase_index_offset(length); |
1026 return true; | 1026 return true; |
1027 } | 1027 } |
1028 | 1028 |
1029 | 1029 |
1030 /** | 1030 /** |
1031 * A helper function that visits "array" elements of a JSReceiver in numerical | 1031 * A helper function that visits "array" elements of a JSReceiver in numerical |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1080 Handle<Object> element_value(elements->get(j), isolate); | 1080 Handle<Object> element_value(elements->get(j), isolate); |
1081 if (!element_value->IsTheHole()) { | 1081 if (!element_value->IsTheHole()) { |
1082 if (!visitor->visit(j, element_value)) return false; | 1082 if (!visitor->visit(j, element_value)) return false; |
1083 } else { | 1083 } else { |
1084 Maybe<bool> maybe = JSReceiver::HasElement(array, j); | 1084 Maybe<bool> maybe = JSReceiver::HasElement(array, j); |
1085 if (!maybe.IsJust()) return false; | 1085 if (!maybe.IsJust()) return false; |
1086 if (maybe.FromJust()) { | 1086 if (maybe.FromJust()) { |
1087 // Call GetElement on array, not its prototype, or getters won't | 1087 // Call GetElement on array, not its prototype, or getters won't |
1088 // have the correct receiver. | 1088 // have the correct receiver. |
1089 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 1089 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
1090 isolate, element_value, Object::GetElement(isolate, array, j), | 1090 isolate, element_value, |
1091 false); | 1091 JSReceiver::GetElement(isolate, array, j), false); |
1092 if (!visitor->visit(j, element_value)) return false; | 1092 if (!visitor->visit(j, element_value)) return false; |
1093 } | 1093 } |
1094 } | 1094 } |
1095 } | 1095 } |
1096 break; | 1096 break; |
1097 } | 1097 } |
1098 case FAST_HOLEY_DOUBLE_ELEMENTS: | 1098 case FAST_HOLEY_DOUBLE_ELEMENTS: |
1099 case FAST_DOUBLE_ELEMENTS: { | 1099 case FAST_DOUBLE_ELEMENTS: { |
1100 // Empty array is FixedArray but not FixedDoubleArray. | 1100 // Empty array is FixedArray but not FixedDoubleArray. |
1101 if (length == 0) break; | 1101 if (length == 0) break; |
(...skipping 15 matching lines...) Expand all Loading... |
1117 isolate->factory()->NewNumber(double_value); | 1117 isolate->factory()->NewNumber(double_value); |
1118 if (!visitor->visit(j, element_value)) return false; | 1118 if (!visitor->visit(j, element_value)) return false; |
1119 } else { | 1119 } else { |
1120 Maybe<bool> maybe = JSReceiver::HasElement(array, j); | 1120 Maybe<bool> maybe = JSReceiver::HasElement(array, j); |
1121 if (!maybe.IsJust()) return false; | 1121 if (!maybe.IsJust()) return false; |
1122 if (maybe.FromJust()) { | 1122 if (maybe.FromJust()) { |
1123 // Call GetElement on array, not its prototype, or getters won't | 1123 // Call GetElement on array, not its prototype, or getters won't |
1124 // have the correct receiver. | 1124 // have the correct receiver. |
1125 Handle<Object> element_value; | 1125 Handle<Object> element_value; |
1126 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 1126 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
1127 isolate, element_value, Object::GetElement(isolate, array, j), | 1127 isolate, element_value, |
1128 false); | 1128 JSReceiver::GetElement(isolate, array, j), false); |
1129 if (!visitor->visit(j, element_value)) return false; | 1129 if (!visitor->visit(j, element_value)) return false; |
1130 } | 1130 } |
1131 } | 1131 } |
1132 } | 1132 } |
1133 break; | 1133 break; |
1134 } | 1134 } |
1135 | 1135 |
1136 case DICTIONARY_ELEMENTS: { | 1136 case DICTIONARY_ELEMENTS: { |
1137 // CollectElementIndices() can't be called when there's a JSProxy | 1137 // CollectElementIndices() can't be called when there's a JSProxy |
1138 // on the prototype chain. | 1138 // on the prototype chain. |
1139 for (PrototypeIterator iter(isolate, array); !iter.IsAtEnd(); | 1139 for (PrototypeIterator iter(isolate, array); !iter.IsAtEnd(); |
1140 iter.Advance()) { | 1140 iter.Advance()) { |
1141 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | 1141 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
1142 return IterateElementsSlow(isolate, array, length, visitor); | 1142 return IterateElementsSlow(isolate, array, length, visitor); |
1143 } | 1143 } |
1144 } | 1144 } |
1145 Handle<SeededNumberDictionary> dict(array->element_dictionary()); | 1145 Handle<SeededNumberDictionary> dict(array->element_dictionary()); |
1146 List<uint32_t> indices(dict->Capacity() / 2); | 1146 List<uint32_t> indices(dict->Capacity() / 2); |
1147 // Collect all indices in the object and the prototypes less | 1147 // Collect all indices in the object and the prototypes less |
1148 // than length. This might introduce duplicates in the indices list. | 1148 // than length. This might introduce duplicates in the indices list. |
1149 CollectElementIndices(array, length, &indices); | 1149 CollectElementIndices(array, length, &indices); |
1150 indices.Sort(&compareUInt32); | 1150 indices.Sort(&compareUInt32); |
1151 int j = 0; | 1151 int j = 0; |
1152 int n = indices.length(); | 1152 int n = indices.length(); |
1153 while (j < n) { | 1153 while (j < n) { |
1154 HandleScope loop_scope(isolate); | 1154 HandleScope loop_scope(isolate); |
1155 uint32_t index = indices[j]; | 1155 uint32_t index = indices[j]; |
1156 Handle<Object> element; | 1156 Handle<Object> element; |
1157 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 1157 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
1158 isolate, element, Object::GetElement(isolate, array, index), false); | 1158 isolate, element, JSReceiver::GetElement(isolate, array, index), |
| 1159 false); |
1159 if (!visitor->visit(index, element)) return false; | 1160 if (!visitor->visit(index, element)) return false; |
1160 // Skip to next different index (i.e., omit duplicates). | 1161 // Skip to next different index (i.e., omit duplicates). |
1161 do { | 1162 do { |
1162 j++; | 1163 j++; |
1163 } while (j < n && indices[j] == index); | 1164 } while (j < n && indices[j] == index); |
1164 } | 1165 } |
1165 break; | 1166 break; |
1166 } | 1167 } |
1167 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 1168 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
1168 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { | 1169 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { |
1169 for (uint32_t index = 0; index < length; index++) { | 1170 for (uint32_t index = 0; index < length; index++) { |
1170 HandleScope loop_scope(isolate); | 1171 HandleScope loop_scope(isolate); |
1171 Handle<Object> element; | 1172 Handle<Object> element; |
1172 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 1173 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
1173 isolate, element, Object::GetElement(isolate, array, index), false); | 1174 isolate, element, JSReceiver::GetElement(isolate, array, index), |
| 1175 false); |
1174 if (!visitor->visit(index, element)) return false; | 1176 if (!visitor->visit(index, element)) return false; |
1175 } | 1177 } |
1176 break; | 1178 break; |
1177 } | 1179 } |
1178 case NO_ELEMENTS: | 1180 case NO_ELEMENTS: |
1179 break; | 1181 break; |
1180 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS: | 1182 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS: |
1181 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1183 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
1182 #undef TYPED_ARRAY_CASE | 1184 #undef TYPED_ARRAY_CASE |
1183 case FAST_STRING_WRAPPER_ELEMENTS: | 1185 case FAST_STRING_WRAPPER_ELEMENTS: |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1527 if (!details.IsEnumerable()) continue; | 1529 if (!details.IsEnumerable()) continue; |
1528 if (details.kind() == kData) { | 1530 if (details.kind() == kData) { |
1529 if (details.location() == kDescriptor) { | 1531 if (details.location() == kDescriptor) { |
1530 prop_value = handle(descriptors->GetValue(i), isolate); | 1532 prop_value = handle(descriptors->GetValue(i), isolate); |
1531 } else { | 1533 } else { |
1532 Representation representation = details.representation(); | 1534 Representation representation = details.representation(); |
1533 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | 1535 FieldIndex index = FieldIndex::ForDescriptor(*map, i); |
1534 prop_value = JSObject::FastPropertyAt(from, representation, index); | 1536 prop_value = JSObject::FastPropertyAt(from, representation, index); |
1535 } | 1537 } |
1536 } else { | 1538 } else { |
1537 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, prop_value, | 1539 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
1538 Object::GetProperty(from, next_key), | 1540 isolate, prop_value, JSReceiver::GetProperty(from, next_key), |
1539 Nothing<bool>()); | 1541 Nothing<bool>()); |
1540 stable = from->map() == *map; | 1542 stable = from->map() == *map; |
1541 } | 1543 } |
1542 } else { | 1544 } else { |
1543 // If the map did change, do a slower lookup. We are still guaranteed that | 1545 // If the map did change, do a slower lookup. We are still guaranteed that |
1544 // the object has a simple shape, and that the key is a name. | 1546 // the object has a simple shape, and that the key is a name. |
1545 LookupIterator it(from, next_key, from, | 1547 LookupIterator it(from, next_key, from, |
1546 LookupIterator::OWN_SKIP_INTERCEPTOR); | 1548 LookupIterator::OWN_SKIP_INTERCEPTOR); |
1547 if (!it.IsFound()) continue; | 1549 if (!it.IsFound()) continue; |
1548 DCHECK(it.state() == LookupIterator::DATA || | 1550 DCHECK(it.state() == LookupIterator::DATA || |
1549 it.state() == LookupIterator::ACCESSOR); | 1551 it.state() == LookupIterator::ACCESSOR); |
(...skipping 2181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3731 while (callable->IsJSBoundFunction()) { | 3733 while (callable->IsJSBoundFunction()) { |
3732 callable = | 3734 callable = |
3733 handle(Handle<JSBoundFunction>::cast(callable)->bound_target_function(), | 3735 handle(Handle<JSBoundFunction>::cast(callable)->bound_target_function(), |
3734 isolate); | 3736 isolate); |
3735 } | 3737 } |
3736 DCHECK(callable->IsCallable()); | 3738 DCHECK(callable->IsCallable()); |
3737 // Get the "prototype" of {callable}; raise an error if it's not a receiver. | 3739 // Get the "prototype" of {callable}; raise an error if it's not a receiver. |
3738 Handle<Object> prototype; | 3740 Handle<Object> prototype; |
3739 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 3741 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
3740 isolate, prototype, | 3742 isolate, prototype, |
3741 Object::GetProperty(callable, isolate->factory()->prototype_string())); | 3743 JSReceiver::GetProperty(Handle<JSReceiver>::cast(callable), |
| 3744 isolate->factory()->prototype_string())); |
3742 if (!prototype->IsJSReceiver()) { | 3745 if (!prototype->IsJSReceiver()) { |
3743 THROW_NEW_ERROR_RETURN_FAILURE( | 3746 THROW_NEW_ERROR_RETURN_FAILURE( |
3744 isolate, | 3747 isolate, |
3745 NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype)); | 3748 NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype)); |
3746 } | 3749 } |
3747 // Return whether or not {prototype} is in the prototype chain of {object}. | 3750 // Return whether or not {prototype} is in the prototype chain of {object}. |
3748 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object); | 3751 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object); |
3749 Maybe<bool> result = | 3752 Maybe<bool> result = |
3750 JSReceiver::HasInPrototypeChain(isolate, receiver, prototype); | 3753 JSReceiver::HasInPrototypeChain(isolate, receiver, prototype); |
3751 MAYBE_RETURN(result, isolate->heap()->exception()); | 3754 MAYBE_RETURN(result, isolate->heap()->exception()); |
(...skipping 22 matching lines...) Expand all Loading... |
3774 isolate->factory()->Symbol_string())); | 3777 isolate->factory()->Symbol_string())); |
3775 } | 3778 } |
3776 | 3779 |
3777 | 3780 |
3778 // ES6 19.1.3.6 Object.prototype.toString | 3781 // ES6 19.1.3.6 Object.prototype.toString |
3779 BUILTIN(ObjectProtoToString) { | 3782 BUILTIN(ObjectProtoToString) { |
3780 HandleScope scope(isolate); | 3783 HandleScope scope(isolate); |
3781 Handle<Object> object = args.at<Object>(0); | 3784 Handle<Object> object = args.at<Object>(0); |
3782 Handle<String> result; | 3785 Handle<String> result; |
3783 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 3786 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
3784 isolate, result, JSObject::ObjectProtoToString(isolate, object)); | 3787 isolate, result, Object::ObjectProtoToString(isolate, object)); |
3785 return *result; | 3788 return *result; |
3786 } | 3789 } |
3787 | 3790 |
3788 | 3791 |
3789 // ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case. | 3792 // ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case. |
3790 BUILTIN(ArrayBufferConstructor) { | 3793 BUILTIN(ArrayBufferConstructor) { |
3791 HandleScope scope(isolate); | 3794 HandleScope scope(isolate); |
3792 Handle<JSFunction> target = args.target<JSFunction>(); | 3795 Handle<JSFunction> target = args.target<JSFunction>(); |
3793 DCHECK(*target == target->native_context()->array_buffer_fun() || | 3796 DCHECK(*target == target->native_context()->array_buffer_fun() || |
3794 *target == target->native_context()->shared_array_buffer_fun()); | 3797 *target == target->native_context()->shared_array_buffer_fun()); |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4533 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 4536 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
4534 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 4537 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
4535 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 4538 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
4536 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 4539 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
4537 #undef DEFINE_BUILTIN_ACCESSOR_C | 4540 #undef DEFINE_BUILTIN_ACCESSOR_C |
4538 #undef DEFINE_BUILTIN_ACCESSOR_A | 4541 #undef DEFINE_BUILTIN_ACCESSOR_A |
4539 | 4542 |
4540 | 4543 |
4541 } // namespace internal | 4544 } // namespace internal |
4542 } // namespace v8 | 4545 } // namespace v8 |
OLD | NEW |