Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: src/builtins.cc

Issue 1775973002: Add GetProperty/GetElement to JSReceiver and use it where possible (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/bootstrapper.cc ('k') | src/contexts.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/bootstrapper.cc ('k') | src/contexts.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698