OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |