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

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

Issue 1221303019: Fix keyed access of primitive objects in the runtime. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix Created 5 years, 5 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-debug.cc ('k') | test/cctest/test-heap.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"
11 #include "src/runtime/runtime.h" 11 #include "src/runtime/runtime.h"
12 #include "src/runtime/runtime-utils.h" 12 #include "src/runtime/runtime-utils.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 // Returns a single character string where first character equals
18 // string->Get(index).
19 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
20 DCHECK_LT(index, static_cast<uint32_t>(string->length()));
21 Factory* factory = string->GetIsolate()->factory();
22 return factory->LookupSingleCharacterStringFromCode(
23 String::Flatten(string)->Get(index));
24 }
25
26
27 MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
28 Handle<Object> object,
29 uint32_t index,
30 LanguageMode language_mode) {
31 // Handle [] indexing on Strings
32 if (object->IsString() &&
33 index < static_cast<uint32_t>(String::cast(*object)->length())) {
34 Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
35 if (!result->IsUndefined()) return result;
36 }
37
38 return Object::GetElement(isolate, object, index, language_mode);
39 }
40
41 17
42 MaybeHandle<Name> Runtime::ToName(Isolate* isolate, Handle<Object> key) { 18 MaybeHandle<Name> Runtime::ToName(Isolate* isolate, Handle<Object> key) {
43 if (key->IsName()) { 19 if (key->IsName()) {
44 return Handle<Name>::cast(key); 20 return Handle<Name>::cast(key);
45 } else { 21 } else {
46 Handle<Object> converted; 22 Handle<Object> converted;
47 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, 23 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
48 Execution::ToString(isolate, key), Name); 24 Execution::ToString(isolate, key), Name);
49 return Handle<Name>::cast(converted); 25 return Handle<Name>::cast(converted);
50 } 26 }
51 } 27 }
52 28
53 29
54 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate, 30 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
55 Handle<Object> object, 31 Handle<Object> object,
56 Handle<Object> key, 32 Handle<Object> key,
57 LanguageMode language_mode) { 33 LanguageMode language_mode) {
58 if (object->IsUndefined() || object->IsNull()) { 34 if (object->IsUndefined() || object->IsNull()) {
59 THROW_NEW_ERROR( 35 THROW_NEW_ERROR(
60 isolate, 36 isolate,
61 NewTypeError(MessageTemplate::kNonObjectPropertyLoad, key, object), 37 NewTypeError(MessageTemplate::kNonObjectPropertyLoad, key, object),
62 Object); 38 Object);
63 } 39 }
64 40
65 // Check if the given key is an array index. 41 // Check if the given key is an array index.
66 uint32_t index = 0; 42 uint32_t index = 0;
67 if (key->ToArrayIndex(&index)) { 43 if (key->ToArrayIndex(&index)) {
68 return GetElementOrCharAt(isolate, object, index, language_mode); 44 return Object::GetElement(isolate, object, index, language_mode);
69 } 45 }
70 46
71 // Convert the key to a name - possibly by calling back into JavaScript. 47 // Convert the key to a name - possibly by calling back into JavaScript.
72 Handle<Name> name; 48 Handle<Name> name;
73 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object); 49 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
74 50
75 // Check if the name is trivially convertible to an index and get 51 // Check if the name is trivially convertible to an index and get
76 // the element if so. 52 // the element if so.
77 // TODO(verwaest): Make sure GetProperty(LookupIterator*) can handle this, and 53 // TODO(verwaest): Make sure GetProperty(LookupIterator*) can handle this, and
78 // remove the special casing here. 54 // remove the special casing here.
79 if (name->AsArrayIndex(&index)) { 55 if (name->AsArrayIndex(&index)) {
80 return GetElementOrCharAt(isolate, object, index); 56 return Object::GetElement(isolate, object, index);
81 } else { 57 } else {
82 return Object::GetProperty(object, name, language_mode); 58 return Object::GetProperty(object, name, language_mode);
83 } 59 }
84 } 60 }
85 61
86 62
87 MaybeHandle<Object> Runtime::KeyedGetObjectProperty( 63 MaybeHandle<Object> Runtime::KeyedGetObjectProperty(
88 Isolate* isolate, Handle<Object> receiver_obj, Handle<Object> key_obj, 64 Isolate* isolate, Handle<Object> receiver_obj, Handle<Object> key_obj,
89 LanguageMode language_mode) { 65 LanguageMode language_mode) {
90 // Fast cases for getting named properties of the receiver JSObject 66 // Fast cases for getting named properties of the receiver JSObject
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 } else { 122 } else {
147 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) || 123 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
148 !IsFastElementsKind(elements_kind)); 124 !IsFastElementsKind(elements_kind));
149 } 125 }
150 } 126 }
151 } else if (receiver_obj->IsString() && key_obj->IsSmi()) { 127 } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
152 // Fast case for string indexing using [] with a smi index. 128 // Fast case for string indexing using [] with a smi index.
153 Handle<String> str = Handle<String>::cast(receiver_obj); 129 Handle<String> str = Handle<String>::cast(receiver_obj);
154 int index = Handle<Smi>::cast(key_obj)->value(); 130 int index = Handle<Smi>::cast(key_obj)->value();
155 if (index >= 0 && index < str->length()) { 131 if (index >= 0 && index < str->length()) {
156 return GetCharAt(str, index); 132 Factory* factory = isolate->factory();
133 return factory->LookupSingleCharacterStringFromCode(
134 String::Flatten(str)->Get(index));
157 } 135 }
158 } 136 }
159 137
160 // Fall back to GetObjectProperty. 138 // Fall back to GetObjectProperty.
161 return GetObjectProperty(isolate, receiver_obj, key_obj, language_mode); 139 return GetObjectProperty(isolate, receiver_obj, key_obj, language_mode);
162 } 140 }
163 141
164 142
165 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate, 143 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
166 Handle<JSReceiver> receiver, 144 Handle<JSReceiver> receiver,
(...skipping 20 matching lines...) Expand all
187 if (object->IsUndefined() || object->IsNull()) { 165 if (object->IsUndefined() || object->IsNull()) {
188 THROW_NEW_ERROR( 166 THROW_NEW_ERROR(
189 isolate, 167 isolate,
190 NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object), 168 NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
191 Object); 169 Object);
192 } 170 }
193 171
194 // Check if the given key is an array index. 172 // Check if the given key is an array index.
195 uint32_t index = 0; 173 uint32_t index = 0;
196 if (key->ToArrayIndex(&index)) { 174 if (key->ToArrayIndex(&index)) {
197 // TODO(verwaest): Support other objects as well. 175 return Object::SetElement(isolate, object, index, value, language_mode);
198 if (!object->IsJSReceiver()) return value;
199 return JSReceiver::SetElement(Handle<JSReceiver>::cast(object), index,
200 value, language_mode);
201 } 176 }
202 177
203 Handle<Name> name; 178 Handle<Name> name;
204 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object); 179 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
205 180
206 LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name); 181 LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name);
207 // TODO(verwaest): Support other objects as well.
208 if (it.IsElement() && !object->IsJSReceiver()) return value;
209 return Object::SetProperty(&it, value, language_mode, 182 return Object::SetProperty(&it, value, language_mode,
210 Object::MAY_BE_STORE_FROM_KEYED); 183 Object::MAY_BE_STORE_FROM_KEYED);
211 } 184 }
212 185
213 186
214 MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate, 187 MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate,
215 Handle<Object> obj) { 188 Handle<Object> obj) {
216 // We don't expect access checks to be needed on JSProxy objects. 189 // We don't expect access checks to be needed on JSProxy objects.
217 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); 190 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
218 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); 191 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
(...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); 1403 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1431 1404
1432 RETURN_FAILURE_ON_EXCEPTION( 1405 RETURN_FAILURE_ON_EXCEPTION(
1433 isolate, 1406 isolate,
1434 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(), 1407 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
1435 setter, attrs)); 1408 setter, attrs));
1436 return isolate->heap()->undefined_value(); 1409 return isolate->heap()->undefined_value();
1437 } 1410 }
1438 } // namespace internal 1411 } // namespace internal
1439 } // namespace v8 1412 } // namespace v8
OLDNEW
« no previous file with comments | « src/runtime/runtime-debug.cc ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698