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

Side by Side Diff: src/runtime/runtime-object.cc

Issue 1172683003: Use the LookupIterator for SetElement and friends (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years, 6 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/runtime/runtime-literals.cc ('k') | test/cctest/test-api.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/debug.h" 9 #include "src/debug.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 125
126 JSObject::ValidateElements(js_object); 126 JSObject::ValidateElements(js_object);
127 if (js_object->HasExternalArrayElements() || 127 if (js_object->HasExternalArrayElements() ||
128 js_object->HasFixedTypedArrayElements()) { 128 js_object->HasFixedTypedArrayElements()) {
129 if (!value->IsNumber() && !value->IsUndefined()) { 129 if (!value->IsNumber() && !value->IsUndefined()) {
130 ASSIGN_RETURN_ON_EXCEPTION(isolate, value, 130 ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
131 Execution::ToNumber(isolate, value), Object); 131 Execution::ToNumber(isolate, value), Object);
132 } 132 }
133 } 133 }
134 134
135 MaybeHandle<Object> result = JSObject::SetElement( 135 MaybeHandle<Object> result =
136 js_object, index, value, NONE, language_mode, true, SET_PROPERTY); 136 JSObject::SetElement(js_object, index, value, language_mode);
137 JSObject::ValidateElements(js_object); 137 JSObject::ValidateElements(js_object);
138 138
139 return result.is_null() ? result : value; 139 return result.is_null() ? result : value;
140 } 140 }
141 141
142 if (key->IsName()) { 142 if (key->IsName()) {
143 Handle<Name> name = Handle<Name>::cast(key); 143 Handle<Name> name = Handle<Name>::cast(key);
144 if (name->AsArrayIndex(&index)) { 144 if (name->AsArrayIndex(&index)) {
145 // TODO(verwaest): Support non-JSObject receivers. 145 // TODO(verwaest): Support non-JSObject receivers.
146 if (!object->IsJSObject()) return value; 146 if (!object->IsJSObject()) return value;
147 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 147 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
148 if (js_object->HasExternalArrayElements()) { 148 if (js_object->HasExternalArrayElements()) {
149 if (!value->IsNumber() && !value->IsUndefined()) { 149 if (!value->IsNumber() && !value->IsUndefined()) {
150 ASSIGN_RETURN_ON_EXCEPTION( 150 ASSIGN_RETURN_ON_EXCEPTION(
151 isolate, value, Execution::ToNumber(isolate, value), Object); 151 isolate, value, Execution::ToNumber(isolate, value), Object);
152 } 152 }
153 } 153 }
154 return JSObject::SetElement(js_object, index, value, NONE, language_mode, 154 return JSObject::SetElement(js_object, index, value, language_mode);
155 true, SET_PROPERTY);
156 } else { 155 } else {
157 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); 156 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
158 return Object::SetProperty(object, name, value, language_mode); 157 return Object::SetProperty(object, name, value, language_mode);
159 } 158 }
160 } 159 }
161 160
162 // Call-back into JavaScript to convert the key to a string. 161 // Call-back into JavaScript to convert the key to a string.
163 Handle<Object> converted; 162 Handle<Object> converted;
164 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, 163 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
165 Execution::ToString(isolate, key), Object); 164 Execution::ToString(isolate, key), Object);
166 Handle<String> name = Handle<String>::cast(converted); 165 Handle<String> name = Handle<String>::cast(converted);
167 166
168 if (name->AsArrayIndex(&index)) { 167 if (name->AsArrayIndex(&index)) {
169 // TODO(verwaest): Support non-JSObject receivers. 168 // TODO(verwaest): Support non-JSObject receivers.
170 if (!object->IsJSObject()) return value; 169 if (!object->IsJSObject()) return value;
171 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 170 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
172 return JSObject::SetElement(js_object, index, value, NONE, language_mode, 171 return JSObject::SetElement(js_object, index, value, language_mode);
173 true, SET_PROPERTY);
174 } 172 }
175 return Object::SetProperty(object, name, value, language_mode); 173 return Object::SetProperty(object, name, value, language_mode);
176 } 174 }
177 175
178 176
179 MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object, 177 MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object,
180 Handle<Object> key, 178 Handle<Object> key,
181 Handle<Object> value, 179 Handle<Object> value,
182 PropertyAttributes attrs) { 180 PropertyAttributes attrs) {
183 Isolate* isolate = js_object->GetIsolate(); 181 Isolate* isolate = js_object->GetIsolate();
184 // Check if the given key is an array index. 182 // Check if the given key is an array index.
185 uint32_t index = 0; 183 uint32_t index = 0;
186 if (key->ToArrayIndex(&index)) { 184 if (key->ToArrayIndex(&index)) {
187 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters 185 return JSObject::SetOwnElementIgnoreAttributes(js_object, index, value,
188 // of a string using [] notation. We need to support this too in 186 attrs);
189 // JavaScript.
190 // In the case of a String object we just need to redirect the assignment to
191 // the underlying string if the index is in range. Since the underlying
192 // string does nothing with the assignment then we can ignore such
193 // assignments.
194 if (js_object->IsStringObjectWithCharacterAt(index)) {
195 return value;
196 }
197
198 return JSObject::SetElement(js_object, index, value, attrs, SLOPPY, false,
199 DEFINE_PROPERTY);
200 } 187 }
201 188
189 Handle<Name> name;
202 if (key->IsName()) { 190 if (key->IsName()) {
203 Handle<Name> name = Handle<Name>::cast(key); 191 name = Handle<Name>::cast(key);
204 if (name->AsArrayIndex(&index)) { 192 } else {
205 return JSObject::SetElement(js_object, index, value, attrs, SLOPPY, false, 193 // Call-back into JavaScript to convert the key to a string.
206 DEFINE_PROPERTY); 194 Handle<Object> converted;
207 } else { 195 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
208 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); 196 Execution::ToString(isolate, key), Object);
209 return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value, 197 name = Handle<String>::cast(converted);
210 attrs);
211 }
212 } 198 }
213 199
214 // Call-back into JavaScript to convert the key to a string.
215 Handle<Object> converted;
216 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
217 Execution::ToString(isolate, key), Object);
218 Handle<String> name = Handle<String>::cast(converted);
219
220 if (name->AsArrayIndex(&index)) { 200 if (name->AsArrayIndex(&index)) {
221 return JSObject::SetElement(js_object, index, value, attrs, SLOPPY, false, 201 return JSObject::SetOwnElementIgnoreAttributes(js_object, index, value,
222 DEFINE_PROPERTY); 202 attrs);
223 } else { 203 } else {
204 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
224 return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value, 205 return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
225 attrs); 206 attrs);
226 } 207 }
227 } 208 }
228 209
229 210
230 MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate, 211 MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate,
231 Handle<Object> obj) { 212 Handle<Object> obj) {
232 // We don't expect access checks to be needed on JSProxy objects. 213 // We don't expect access checks to be needed on JSProxy objects.
233 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); 214 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 Runtime::GetObjectProperty(isolate, receiver_obj, key_obj)); 598 Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
618 return *result; 599 return *result;
619 } 600 }
620 601
621 602
622 RUNTIME_FUNCTION(Runtime_AddNamedProperty) { 603 RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
623 HandleScope scope(isolate); 604 HandleScope scope(isolate);
624 RUNTIME_ASSERT(args.length() == 4); 605 RUNTIME_ASSERT(args.length() == 4);
625 606
626 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 607 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
627 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); 608 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
628 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); 609 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
629 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); 610 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
630 611
631 #ifdef DEBUG 612 #ifdef DEBUG
632 uint32_t index = 0; 613 uint32_t index = 0;
633 DCHECK(!key->ToArrayIndex(&index)); 614 DCHECK(!name->ToArrayIndex(&index));
634 LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR); 615 LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
635 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); 616 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
636 if (!maybe.IsJust()) return isolate->heap()->exception(); 617 if (!maybe.IsJust()) return isolate->heap()->exception();
637 RUNTIME_ASSERT(!it.IsFound()); 618 RUNTIME_ASSERT(!it.IsFound());
638 #endif 619 #endif
639 620
640 Handle<Object> result; 621 Handle<Object> result;
641 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 622 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
642 isolate, result, 623 isolate, result,
643 JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attrs)); 624 JSObject::SetOwnPropertyIgnoreAttributes(object, name, value, attrs));
644 return *result; 625 return *result;
645 } 626 }
646 627
647
648 RUNTIME_FUNCTION(Runtime_SetProperty) {
649 HandleScope scope(isolate);
650 RUNTIME_ASSERT(args.length() == 4);
651
652 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
653 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
654 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
655 CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode_arg, 3);
656 LanguageMode language_mode = language_mode_arg;
657
658 Handle<Object> result;
659 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
660 isolate, result,
661 Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
662 return *result;
663 }
664
665 628
666 // Adds an element to an array. 629 // Adds an element to an array.
667 // This is used to create an indexed data property into an array. 630 // This is used to create an indexed data property into an array.
668 RUNTIME_FUNCTION(Runtime_AddElement) { 631 RUNTIME_FUNCTION(Runtime_AddElement) {
669 HandleScope scope(isolate); 632 HandleScope scope(isolate);
670 RUNTIME_ASSERT(args.length() == 4); 633 RUNTIME_ASSERT(args.length() == 3);
671 634
672 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 635 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
673 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); 636 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
674 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); 637 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
675 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
676 638
677 uint32_t index = 0; 639 uint32_t index = 0;
678 key->ToArrayIndex(&index); 640 CHECK(key->ToArrayIndex(&index));
641
642 #ifdef DEBUG
643 LookupIterator it(isolate, object, index,
644 LookupIterator::OWN_SKIP_INTERCEPTOR);
645 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
646 if (!maybe.IsJust()) return isolate->heap()->exception();
647 RUNTIME_ASSERT(!it.IsFound());
648
649 if (object->IsJSArray()) {
650 Handle<JSArray> array = Handle<JSArray>::cast(object);
651 RUNTIME_ASSERT(!JSArray::WouldChangeReadOnlyLength(array, index));
652 }
653 #endif
679 654
680 Handle<Object> result; 655 Handle<Object> result;
681 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 656 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
682 isolate, result, JSObject::SetElement(object, index, value, attrs, SLOPPY, 657 isolate, result,
683 false, DEFINE_PROPERTY)); 658 JSObject::SetOwnElementIgnoreAttributes(object, index, value, NONE));
684 return *result; 659 return *result;
685 } 660 }
686 661
687 662
688 RUNTIME_FUNCTION(Runtime_AppendElement) { 663 RUNTIME_FUNCTION(Runtime_AppendElement) {
689 HandleScope scope(isolate); 664 HandleScope scope(isolate);
690 RUNTIME_ASSERT(args.length() == 2); 665 RUNTIME_ASSERT(args.length() == 2);
691 666
692 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); 667 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
693 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); 668 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
694 669
695 int index = Smi::cast(array->length())->value(); 670 uint32_t index;
671 CHECK(array->length()->ToArrayIndex(&index));
696 672
697 Handle<Object> result; 673 Handle<Object> result;
698 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 674 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
699 isolate, result, JSObject::SetElement(array, index, value, NONE, SLOPPY, 675 isolate, result, JSObject::AddDataElement(array, index, value, NONE));
700 false, DEFINE_PROPERTY));
701 return *array; 676 return *array;
702 } 677 }
703 678
704 679
680 RUNTIME_FUNCTION(Runtime_SetProperty) {
681 HandleScope scope(isolate);
682 RUNTIME_ASSERT(args.length() == 4);
683
684 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
685 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
686 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
687 CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode_arg, 3);
688 LanguageMode language_mode = language_mode_arg;
689
690 Handle<Object> result;
691 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
692 isolate, result,
693 Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
694 return *result;
695 }
696
697
705 RUNTIME_FUNCTION(Runtime_DeleteProperty) { 698 RUNTIME_FUNCTION(Runtime_DeleteProperty) {
706 HandleScope scope(isolate); 699 HandleScope scope(isolate);
707 DCHECK(args.length() == 3); 700 DCHECK(args.length() == 3);
708 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); 701 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
709 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); 702 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
710 CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2); 703 CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2);
711 Handle<Object> result; 704 Handle<Object> result;
712 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 705 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
713 isolate, result, JSReceiver::DeleteProperty(object, key, language_mode)); 706 isolate, result, JSReceiver::DeleteProperty(object, key, language_mode));
714 return *result; 707 return *result;
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
1368 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); 1361 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1369 1362
1370 LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); 1363 LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
1371 if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) { 1364 if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) {
1372 if (!isolate->MayAccess(js_object)) { 1365 if (!isolate->MayAccess(js_object)) {
1373 return isolate->heap()->undefined_value(); 1366 return isolate->heap()->undefined_value();
1374 } 1367 }
1375 it.Next(); 1368 it.Next();
1376 } 1369 }
1377 1370
1378 // Take special care when attributes are different and there is already
1379 // a property.
1380 if (it.state() == LookupIterator::ACCESSOR) {
1381 // Use IgnoreAttributes version since a readonly property may be
1382 // overridden and SetProperty does not allow this.
1383 Handle<Object> result;
1384 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1385 isolate, result,
1386 JSObject::SetOwnPropertyIgnoreAttributes(
1387 js_object, name, obj_value, attrs, JSObject::DONT_FORCE_FIELD));
1388 return *result;
1389 }
1390
1391 Handle<Object> result; 1371 Handle<Object> result;
1392 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 1372 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1393 isolate, result, 1373 isolate, result,
1394 Runtime::DefineObjectProperty(js_object, name, obj_value, attrs)); 1374 Runtime::DefineObjectProperty(js_object, name, obj_value, attrs));
1395 return *result; 1375 return *result;
1396 } 1376 }
1397 1377
1398 1378
1399 // Return property without being observable by accessors or interceptors. 1379 // Return property without being observable by accessors or interceptors.
1400 RUNTIME_FUNCTION(Runtime_GetDataProperty) { 1380 RUNTIME_FUNCTION(Runtime_GetDataProperty) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); 1522 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1543 1523
1544 RETURN_FAILURE_ON_EXCEPTION( 1524 RETURN_FAILURE_ON_EXCEPTION(
1545 isolate, 1525 isolate,
1546 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(), 1526 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
1547 setter, attrs)); 1527 setter, attrs));
1548 return isolate->heap()->undefined_value(); 1528 return isolate->heap()->undefined_value();
1549 } 1529 }
1550 } // namespace internal 1530 } // namespace internal
1551 } // namespace v8 1531 } // namespace v8
OLDNEW
« no previous file with comments | « src/runtime/runtime-literals.cc ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698